Replace sade the extracted piece of sysinstall with sade the extracted
piece of bsdinstall (although this time with a symlink instead of duplicated source code). Discussed on: freebsd-geom MFC after: 3 months
This commit is contained in:
parent
4f5fcf8d00
commit
934f522a9f
@ -23,7 +23,4 @@ SUBDIR+= ndiscvt
|
||||
.endif
|
||||
SUBDIR+= sicontrol
|
||||
SUBDIR+= spkrtest
|
||||
.if ${MK_SYSINSTALL} != "no"
|
||||
SUBDIR+= sade
|
||||
.endif
|
||||
SUBDIR+= zzz
|
||||
|
@ -17,9 +17,6 @@ SUBDIR+= mptable
|
||||
SUBDIR+= ndiscvt
|
||||
.endif
|
||||
SUBDIR+= pnpinfo
|
||||
.if ${MK_SYSINSTALL} != "no"
|
||||
SUBDIR+= sade
|
||||
.endif
|
||||
SUBDIR+= sicontrol
|
||||
SUBDIR+= spkrtest
|
||||
SUBDIR+= zzz
|
||||
|
@ -2,6 +2,3 @@
|
||||
|
||||
SUBDIR+= eeprom
|
||||
SUBDIR+= ofwdump
|
||||
.if ${MK_SYSINSTALL} != "no"
|
||||
SUBDIR+= sade
|
||||
.endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
BINDIR= /usr/libexec/bsdinstall
|
||||
PROG= partedit
|
||||
LINKS= ${BINDIR}/partedit ${BINDIR}/autopart
|
||||
LINKS= ${BINDIR}/partedit ${BINDIR}/autopart ${BINDIR}/partedit /usr/sbin/sade
|
||||
LDADD= -lgeom -lncursesw -lutil -ldialog -lm
|
||||
|
||||
PARTEDIT_ARCH= ${MACHINE}
|
||||
|
@ -1,27 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MACHINE_CPUARCH} != "ia64"
|
||||
_wizard= wizard.c
|
||||
.endif
|
||||
|
||||
PROG= sade
|
||||
MAN= sade.8
|
||||
SRCS= command.c devices.c \
|
||||
disks.c dmenu.c \
|
||||
globals.c install.c \
|
||||
label.c main.c menus.c misc.c \
|
||||
msg.c system.c termcap.c \
|
||||
variable.c ${_wizard}
|
||||
WARNS?= 3
|
||||
|
||||
# command.c
|
||||
|
||||
.if ${MACHINE} == "pc98"
|
||||
CFLAGS+= -DPC98
|
||||
.endif
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/dialog -I.
|
||||
|
||||
DPADD= ${LIBDIALOG} ${LIBNCURSESW} ${LIBM} ${LIBUTIL} ${LIBDISK}
|
||||
LDADD= -ldialog -lncursesw -lm -lutil -ldisk
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
#define MAX_NUM_COMMANDS 10
|
||||
|
||||
typedef struct {
|
||||
char key[FILENAME_MAX];
|
||||
struct {
|
||||
enum { CMD_SHELL, CMD_FUNCTION } type;
|
||||
void *ptr, *data;
|
||||
} cmds[MAX_NUM_COMMANDS];
|
||||
int ncmds;
|
||||
} Command;
|
||||
|
||||
#define MAX_CMDS 200
|
||||
static Command *commandStack[MAX_CMDS];
|
||||
int numCommands;
|
||||
|
||||
/* Nuke the command stack */
|
||||
void
|
||||
command_clear(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < numCommands; i++)
|
||||
for (j = 0; j < commandStack[i]->ncmds; j++)
|
||||
if (commandStack[i]->cmds[j].type == CMD_SHELL)
|
||||
free(commandStack[i]->cmds[j].ptr);
|
||||
free(commandStack[i]);
|
||||
numCommands = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
addit(char *key, int type, void *cmd, void *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* First, look for the key already present and add a command to it if found */
|
||||
for (i = 0; i < numCommands; i++) {
|
||||
if (!strcmp(commandStack[i]->key, key)) {
|
||||
if (commandStack[i]->ncmds == MAX_NUM_COMMANDS)
|
||||
msgFatal("More than %d commands stacked up behind %s??", MAX_NUM_COMMANDS, key);
|
||||
commandStack[i]->cmds[commandStack[i]->ncmds].type = type;
|
||||
commandStack[i]->cmds[commandStack[i]->ncmds].ptr = cmd;
|
||||
commandStack[i]->cmds[commandStack[i]->ncmds].data = data;
|
||||
++(commandStack[i]->ncmds);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (numCommands == MAX_CMDS)
|
||||
msgFatal("More than %d commands accumulated??", MAX_CMDS);
|
||||
|
||||
/* If we fell to here, it's a new key */
|
||||
commandStack[numCommands] = safe_malloc(sizeof(Command));
|
||||
strcpy(commandStack[numCommands]->key, key);
|
||||
commandStack[numCommands]->ncmds = 1;
|
||||
commandStack[numCommands]->cmds[0].type = type;
|
||||
commandStack[numCommands]->cmds[0].ptr = cmd;
|
||||
commandStack[numCommands]->cmds[0].data = data;
|
||||
++numCommands;
|
||||
}
|
||||
|
||||
/* Add a shell command under a given key */
|
||||
void
|
||||
command_shell_add(char *key, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *cmd;
|
||||
|
||||
cmd = (char *)safe_malloc(256);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(cmd, 256, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
addit(key, CMD_SHELL, cmd, NULL);
|
||||
}
|
||||
|
||||
/* Add a shell command under a given key */
|
||||
void
|
||||
command_func_add(char *key, commandFunc func, void *data)
|
||||
{
|
||||
addit(key, CMD_FUNCTION, func, data);
|
||||
}
|
||||
|
||||
static int
|
||||
sort_compare(Command *p1, Command *p2)
|
||||
{
|
||||
if (!p1 && !p2)
|
||||
return 0;
|
||||
else if (!p1 && p2) /* NULL has a "greater" value for commands */
|
||||
return 1;
|
||||
else if (p1 && !p2)
|
||||
return -1;
|
||||
else
|
||||
return strcmp(p1->key, p2->key);
|
||||
}
|
||||
|
||||
void
|
||||
command_sort(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
commandStack[numCommands] = NULL;
|
||||
/* Just do a crude bubble sort since the list is small */
|
||||
for (i = 0; i < numCommands; i++) {
|
||||
for (j = 0; j < numCommands; j++) {
|
||||
if (sort_compare(commandStack[j], commandStack[j + 1]) > 0) {
|
||||
Command *tmp = commandStack[j];
|
||||
|
||||
commandStack[j] = commandStack[j + 1];
|
||||
commandStack[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Run all accumulated commands in sorted order */
|
||||
void
|
||||
command_execute(void)
|
||||
{
|
||||
int i, j, ret;
|
||||
commandFunc func;
|
||||
|
||||
for (i = 0; i < numCommands; i++) {
|
||||
for (j = 0; j < commandStack[i]->ncmds; j++) {
|
||||
/* If it's a shell command, run system on it */
|
||||
if (commandStack[i]->cmds[j].type == CMD_SHELL) {
|
||||
msgNotify("Doing %s", (char *)commandStack[i]->cmds[j].ptr);
|
||||
ret = vsystem("%s", (char *)commandStack[i]->cmds[j].ptr);
|
||||
if (isDebug())
|
||||
msgDebug("Command `%s' returns status %d\n",
|
||||
(char *)commandStack[i]->cmds[j].ptr, ret);
|
||||
}
|
||||
else {
|
||||
/* It's a function pointer - call it with the key and
|
||||
the data */
|
||||
func = (commandFunc)commandStack[i]->cmds[j].ptr;
|
||||
if (isDebug())
|
||||
msgDebug("%p: Execute(%s, %s)\n",
|
||||
func, commandStack[i]->key,
|
||||
(char *)commandStack[i]->cmds[j].data);
|
||||
ret = (*func)(commandStack[i]->key, commandStack[i]->cmds[j].data);
|
||||
if (isDebug())
|
||||
msgDebug("Function @ %p returns status %d\n",
|
||||
commandStack[i]->cmds[j].ptr, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,344 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <libdisk.h>
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/* how much to bias minor number for a given /dev/<ct#><un#>s<s#> slice */
|
||||
#define SLICE_DELTA (0x10000)
|
||||
|
||||
static Device *Devices[DEV_MAX];
|
||||
static int numDevs;
|
||||
|
||||
#define DEVICE_ENTRY(type, name, descr, max) { type, name, descr, max }
|
||||
|
||||
#define DISK(name, descr, max) \
|
||||
DEVICE_ENTRY(DEVICE_TYPE_DISK, name, descr, max)
|
||||
|
||||
static struct _devname {
|
||||
DeviceType type;
|
||||
char *name;
|
||||
char *description;
|
||||
int max;
|
||||
} device_names[] = {
|
||||
DISK("da%d", "SCSI disk device", 16),
|
||||
DISK("ad%d", "ATA/IDE disk device", 16),
|
||||
DISK("ar%d", "ATA/IDE RAID device", 16),
|
||||
DISK("afd%d", "ATAPI/IDE floppy device", 4),
|
||||
DISK("mlxd%d", "Mylex RAID disk", 4),
|
||||
DISK("amrd%d", "AMI MegaRAID drive", 4),
|
||||
DISK("idad%d", "Compaq RAID array", 4),
|
||||
DISK("twed%d", "3ware ATA RAID array", 4),
|
||||
DISK("aacd%d", "Adaptec FSA RAID array", 4),
|
||||
DISK("ipsd%d", "IBM ServeRAID RAID array", 4),
|
||||
DISK("mfid%d", "LSI MegaRAID SAS array", 4),
|
||||
{ 0, NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
Device *
|
||||
new_device(char *name)
|
||||
{
|
||||
Device *dev;
|
||||
|
||||
dev = safe_malloc(sizeof(Device));
|
||||
bzero(dev, sizeof(Device));
|
||||
if (name)
|
||||
SAFE_STRCPY(dev->name, name);
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* Stubs for unimplemented strategy routines */
|
||||
Boolean
|
||||
dummyInit(Device *dev)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FILE *
|
||||
dummyGet(Device *dev, char *dist, Boolean probe)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dummyShutdown(Device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
deviceTry(struct _devname dev, char *try, int i)
|
||||
{
|
||||
int fd;
|
||||
char unit[80];
|
||||
|
||||
snprintf(unit, sizeof unit, dev.name, i);
|
||||
snprintf(try, FILENAME_MAX, "/dev/%s", unit);
|
||||
if (isDebug())
|
||||
msgDebug("deviceTry: attempting to open %s\n", try);
|
||||
fd = open(try, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
if (isDebug())
|
||||
msgDebug("deviceTry: open of %s succeeded.\n", try);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Register a new device in the devices array */
|
||||
Device *
|
||||
deviceRegister(char *name, char *desc, char *devname, DeviceType type,
|
||||
Boolean (*init)(Device *), FILE * (*get)(Device *, char *, Boolean),
|
||||
void (*shutdown)(Device *), void *private)
|
||||
{
|
||||
Device *newdev = NULL;
|
||||
|
||||
if (numDevs == DEV_MAX)
|
||||
msgFatal("Too many devices found!");
|
||||
else {
|
||||
newdev = new_device(name);
|
||||
newdev->description = desc;
|
||||
newdev->devname = devname;
|
||||
newdev->type = type;
|
||||
newdev->init = init ? init : dummyInit;
|
||||
newdev->get = get ? get : dummyGet;
|
||||
newdev->shutdown = shutdown ? shutdown : dummyShutdown;
|
||||
newdev->private = private;
|
||||
Devices[numDevs] = newdev;
|
||||
Devices[++numDevs] = NULL;
|
||||
}
|
||||
return newdev;
|
||||
}
|
||||
|
||||
/* Reset the registered device chain */
|
||||
void
|
||||
deviceReset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numDevs; i++) {
|
||||
DEVICE_SHUTDOWN(Devices[i]);
|
||||
|
||||
/* XXX this potentially leaks Devices[i]->private if it's being
|
||||
* used to point to something dynamic, but you're not supposed
|
||||
* to call this routine at such times that some open instance
|
||||
* has its private ptr pointing somewhere anyway. XXX
|
||||
*/
|
||||
free(Devices[i]);
|
||||
}
|
||||
Devices[numDevs = 0] = NULL;
|
||||
}
|
||||
|
||||
/* Get all device information for devices we have attached */
|
||||
void
|
||||
deviceGetAll(void)
|
||||
{
|
||||
int i, j;
|
||||
char **names;
|
||||
|
||||
msgNotify("Probing devices, please wait (this can take a while)...");
|
||||
|
||||
/* Next, try to find all the types of devices one might need
|
||||
* during the second stage of the installation.
|
||||
*/
|
||||
for (i = 0; device_names[i].name; i++) {
|
||||
for (j = 0; j < device_names[i].max; j++) {
|
||||
char try[FILENAME_MAX];
|
||||
|
||||
switch(device_names[i].type) {
|
||||
case DEVICE_TYPE_DISK:
|
||||
deviceTry(device_names[i], try, j);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, go get the disks and look for DOS partitions to register */
|
||||
if ((names = Disk_Names()) != NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; names[i]; i++) {
|
||||
Disk *d;
|
||||
|
||||
/* Ignore memory disks */
|
||||
if (!strncmp(names[i], "md", 2))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Due to unknown reasons, Disk_Names() returns SCSI CDROM as a
|
||||
* valid disk. This is main reason why sysinstall presents SCSI
|
||||
* CDROM to available disks in Fdisk/Label menu. In addition,
|
||||
* adding a blank SCSI CDROM to the menu generates floating point
|
||||
* exception in sparc64. Disk_Names() just extracts sysctl
|
||||
* "kern.disks". Why GEOM treats SCSI CDROM as a disk is beyond
|
||||
* me and that should be investigated.
|
||||
* For temporary workaround, ignore SCSI CDROM device.
|
||||
*/
|
||||
if (!strncmp(names[i], "cd", 2))
|
||||
continue;
|
||||
|
||||
d = Open_Disk(names[i]);
|
||||
if (!d) {
|
||||
msgDebug("Unable to open disk %s\n", names[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
deviceRegister(names[i], names[i], d->name, DEVICE_TYPE_DISK,
|
||||
dummyInit, dummyGet, dummyShutdown, d);
|
||||
if (isDebug())
|
||||
msgDebug("Found a disk device named %s\n", names[i]);
|
||||
|
||||
#if 0
|
||||
/* Look for existing DOS partitions to register as "DOS media devices" */
|
||||
for (c1 = d->chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == fat || c1->type == efi || c1->type == extended) {
|
||||
Device *dev;
|
||||
char devname[80];
|
||||
|
||||
/* Got one! */
|
||||
snprintf(devname, sizeof devname, "/dev/%s", c1->name);
|
||||
dev = deviceRegister(c1->name, c1->name, strdup(devname), DEVICE_TYPE_DOS,
|
||||
mediaInitDOS, mediaGetDOS, mediaShutdownDOS, NULL);
|
||||
dev->private = c1;
|
||||
if (isDebug())
|
||||
msgDebug("Found a DOS partition %s on drive %s\n", c1->name, d->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
free(names);
|
||||
}
|
||||
dlg_clear();
|
||||
}
|
||||
|
||||
/* Rescan all devices, after closing previous set - convenience function */
|
||||
void
|
||||
deviceRescan(void)
|
||||
{
|
||||
deviceReset();
|
||||
deviceGetAll();
|
||||
}
|
||||
|
||||
/*
|
||||
* Find all devices that match the criteria, allowing "wildcarding" as well
|
||||
* by allowing NULL or ANY values to match all. The array returned is static
|
||||
* and may be used until the next invocation of deviceFind().
|
||||
*/
|
||||
Device **
|
||||
deviceFind(char *name, DeviceType class)
|
||||
{
|
||||
static Device *found[DEV_MAX];
|
||||
int i, j;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < numDevs; i++) {
|
||||
if ((!name || !strcmp(Devices[i]->name, name))
|
||||
&& (class == DEVICE_TYPE_ANY || class == Devices[i]->type))
|
||||
found[j++] = Devices[i];
|
||||
}
|
||||
found[j] = NULL;
|
||||
return j ? found : NULL;
|
||||
}
|
||||
|
||||
Device **
|
||||
deviceFindDescr(char *name, char *desc, DeviceType class)
|
||||
{
|
||||
static Device *found[DEV_MAX];
|
||||
int i, j;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < numDevs; i++) {
|
||||
if ((!name || !strcmp(Devices[i]->name, name)) &&
|
||||
(!desc || !strcmp(Devices[i]->description, desc)) &&
|
||||
(class == DEVICE_TYPE_ANY || class == Devices[i]->type))
|
||||
found[j++] = Devices[i];
|
||||
}
|
||||
found[j] = NULL;
|
||||
return j ? found : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
deviceCount(Device **devs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!devs)
|
||||
return 0;
|
||||
for (i = 0; devs[i]; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a menu listing all the devices of a certain type in the system.
|
||||
* The passed-in menu is expected to be a "prototype" from which the new
|
||||
* menu is cloned.
|
||||
*/
|
||||
DMenu *
|
||||
deviceCreateMenu(DMenu *menu, DeviceType type, int (*hook)(dialogMenuItem *d))
|
||||
{
|
||||
Device **devs;
|
||||
int numdevs;
|
||||
DMenu *tmp = NULL;
|
||||
int i, j;
|
||||
|
||||
devs = deviceFind(NULL, type);
|
||||
numdevs = deviceCount(devs);
|
||||
if (!numdevs)
|
||||
return NULL;
|
||||
tmp = (DMenu *)safe_malloc(sizeof(DMenu) + (sizeof(dialogMenuItem) * (numdevs + 1)));
|
||||
bcopy(menu, tmp, sizeof(DMenu));
|
||||
for (i = 0; devs[i]; i++) {
|
||||
tmp->items[i].prompt = devs[i]->name;
|
||||
for (j = 0; j < numDevs; j++) {
|
||||
if (devs[i] == Devices[j]) {
|
||||
tmp->items[i].title = Devices[j]->description;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == numDevs)
|
||||
tmp->items[i].title = "<unknown device type>";
|
||||
tmp->items[i].fire = hook;
|
||||
}
|
||||
tmp->items[i].title = NULL;
|
||||
return tmp;
|
||||
}
|
@ -1,972 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <libdisk.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/disklabel.h>
|
||||
|
||||
#ifdef WITH_SLICES
|
||||
enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_GIG, UNIT_SIZE };
|
||||
|
||||
#ifdef PC98
|
||||
#define SUBTYPE_FREEBSD 50324
|
||||
#define SUBTYPE_FAT 37218
|
||||
#else
|
||||
#define SUBTYPE_FREEBSD 165
|
||||
#define SUBTYPE_FAT 6
|
||||
#endif
|
||||
#define SUBTYPE_EFI 239
|
||||
|
||||
#ifdef PC98
|
||||
#define OTHER_SLICE_VALUES \
|
||||
"Other popular values are 37218 for a\n" \
|
||||
"DOS FAT partition.\n\n"
|
||||
#else
|
||||
#define OTHER_SLICE_VALUES \
|
||||
"Other popular values are 6 for a\n" \
|
||||
"DOS FAT partition, 131 for a Linux ext2fs partition, or\n" \
|
||||
"130 for a Linux swap partition.\n\n"
|
||||
#endif
|
||||
#define NON_FREEBSD_NOTE \
|
||||
"Note: If you choose a non-FreeBSD partition type, it will not\n" \
|
||||
"be formatted or otherwise prepared, it will simply reserve space\n" \
|
||||
"for you to use another tool, such as DOS format, to later format\n" \
|
||||
"and actually use the partition."
|
||||
|
||||
/* Where we start displaying chunk information on the screen */
|
||||
#define CHUNK_START_ROW 5
|
||||
|
||||
/* Where we keep track of MBR chunks */
|
||||
#define CHUNK_INFO_ENTRIES 16
|
||||
static struct chunk *chunk_info[CHUNK_INFO_ENTRIES];
|
||||
static int current_chunk;
|
||||
|
||||
static void diskPartitionNonInteractive(Device *dev);
|
||||
#if !defined(__ia64__)
|
||||
static u_char * bootalloc(char *name, size_t *size);
|
||||
#endif
|
||||
|
||||
static void
|
||||
record_chunks(Disk *d)
|
||||
{
|
||||
struct chunk *c1 = NULL;
|
||||
int i = 0;
|
||||
daddr_t last_free = 0;
|
||||
|
||||
if (!d->chunks)
|
||||
msgFatal("No chunk list found for %s!", d->name);
|
||||
|
||||
for (c1 = d->chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused && c1->size > last_free) {
|
||||
last_free = c1->size;
|
||||
current_chunk = i;
|
||||
}
|
||||
chunk_info[i++] = c1;
|
||||
}
|
||||
chunk_info[i] = NULL;
|
||||
if (current_chunk >= i)
|
||||
current_chunk = i - 1;
|
||||
}
|
||||
|
||||
static daddr_t Total;
|
||||
|
||||
static void
|
||||
check_geometry(Disk *d)
|
||||
{
|
||||
int sg;
|
||||
|
||||
#ifdef PC98
|
||||
if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
|
||||
#else
|
||||
if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
|
||||
#endif
|
||||
{
|
||||
dlg_clear();
|
||||
sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
|
||||
"computers with modern BIOS versions. If this disk is to be used\n"
|
||||
"on an old machine it is recommended that it does not have more\n"
|
||||
"than 65535 cylinders, more than 255 heads, or more than\n"
|
||||
#ifdef PC98
|
||||
"255"
|
||||
#else
|
||||
"63"
|
||||
#endif
|
||||
" sectors per track.\n"
|
||||
"\n"
|
||||
"Would you like to keep using the current geometry?\n",
|
||||
d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
|
||||
if (sg == 1) {
|
||||
Sanitize_Bios_Geom(d);
|
||||
msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
|
||||
"\n"
|
||||
"If you are not sure about this, please consult the Hardware Guide\n"
|
||||
"in the Documentation submenu or use the (G)eometry command to\n"
|
||||
"change it. Remember: you need to enter whatever your BIOS thinks\n"
|
||||
"the geometry is! For IDE, it's what you were told in the BIOS\n"
|
||||
"setup. For SCSI, it's the translation mode your controller is\n"
|
||||
"using. Do NOT use a ``physical geometry''.\n",
|
||||
d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_chunks(Disk *d, int u)
|
||||
{
|
||||
int row;
|
||||
int i;
|
||||
daddr_t sz;
|
||||
char *szstr;
|
||||
|
||||
szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
|
||||
(u == UNIT_KILO ? "KB" : "ST")));
|
||||
|
||||
Total = 0;
|
||||
for (i = 0; chunk_info[i]; i++)
|
||||
Total += chunk_info[i]->size;
|
||||
attrset(A_NORMAL);
|
||||
mvaddstr(0, 0, "Disk name:\t");
|
||||
clrtobot();
|
||||
attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
|
||||
attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
|
||||
mvprintw(1, 0,
|
||||
"DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
|
||||
d->bios_cyl, d->bios_hd, d->bios_sect,
|
||||
(intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
|
||||
(intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
|
||||
mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
|
||||
"Offset", "Size", szstr, "End", "Name", "PType", "Desc",
|
||||
"Subtype", "Flags");
|
||||
for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
|
||||
switch(u) {
|
||||
default: /* fall thru */
|
||||
case UNIT_BLOCKS:
|
||||
sz = chunk_info[i]->size;
|
||||
break;
|
||||
case UNIT_KILO:
|
||||
sz = chunk_info[i]->size / (1024/512);
|
||||
break;
|
||||
case UNIT_MEG:
|
||||
sz = chunk_info[i]->size / (1024/512) / 1024;
|
||||
break;
|
||||
case UNIT_GIG:
|
||||
sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
|
||||
break;
|
||||
}
|
||||
if (i == current_chunk)
|
||||
attrset(ATTR_SELECTED);
|
||||
mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
|
||||
(intmax_t)chunk_info[i]->offset, (intmax_t)sz,
|
||||
(intmax_t)chunk_info[i]->end, chunk_info[i]->name,
|
||||
chunk_info[i]->type,
|
||||
slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
|
||||
chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
|
||||
if (i == current_chunk)
|
||||
attrset(A_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_command_summary(void)
|
||||
{
|
||||
mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
|
||||
mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
|
||||
mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
|
||||
mvprintw(18, 0, "T = Change Type U = Undo All Changes W = Write Changes Q = Finish");
|
||||
mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
|
||||
move(0, 0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
static void
|
||||
getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
|
||||
u_char **bootmenu, size_t *bootmenu_size)
|
||||
{
|
||||
static u_char *boot0;
|
||||
static size_t boot0_size;
|
||||
static u_char *boot05;
|
||||
static size_t boot05_size;
|
||||
|
||||
char str[80];
|
||||
char *cp;
|
||||
int i = 0;
|
||||
|
||||
dlg_clr_result();
|
||||
cp = variable_get(VAR_BOOTMGR);
|
||||
if (!cp) {
|
||||
/* Figure out what kind of IPL the user wants */
|
||||
sprintf(str, "Install Boot Manager for drive %s?", dname);
|
||||
MenuIPLType.title = str;
|
||||
i = dmenuOpen(&MenuIPLType);
|
||||
} else {
|
||||
if (!strncmp(cp, "boot", 4))
|
||||
dlg_add_result(MenuIPLType.items[0].prompt);
|
||||
else
|
||||
dlg_add_result(MenuIPLType.items[1].prompt);
|
||||
}
|
||||
if (cp || i) {
|
||||
if (!strcmp(dialog_vars.input_result, MenuIPLType.items[0].prompt)) {
|
||||
if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
|
||||
*bootipl = boot0;
|
||||
*bootipl_size = boot0_size;
|
||||
if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
|
||||
*bootmenu = boot05;
|
||||
*bootmenu_size = boot05_size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*bootipl = NULL;
|
||||
*bootipl_size = 0;
|
||||
*bootmenu = NULL;
|
||||
*bootmenu_size = 0;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
|
||||
{
|
||||
#if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
|
||||
static u_char *mbr, *boot0;
|
||||
static size_t mbr_size, boot0_size;
|
||||
char str[80];
|
||||
char *cp;
|
||||
int i = 0;
|
||||
|
||||
dlg_clr_result();
|
||||
cp = variable_get(VAR_BOOTMGR);
|
||||
if (!cp) {
|
||||
/* Figure out what kind of MBR the user wants */
|
||||
sprintf(str, "Install Boot Manager for drive %s?", dname);
|
||||
MenuMBRType.title = str;
|
||||
i = dmenuOpen(&MenuMBRType);
|
||||
}
|
||||
else {
|
||||
if (!strcmp(cp, "standard"))
|
||||
dlg_add_result(MenuMBRType.items[0].prompt);
|
||||
if (!strncmp(cp, "boot", 4))
|
||||
dlg_add_result(MenuMBRType.items[1].prompt);
|
||||
else
|
||||
dlg_add_result(MenuMBRType.items[2].prompt);
|
||||
}
|
||||
if (cp || i) {
|
||||
if (!strcmp(dialog_vars.input_result, MenuMBRType.items[0].prompt)) {
|
||||
if (!mbr) mbr = bootalloc("mbr", &mbr_size);
|
||||
*bootCode = mbr;
|
||||
*bootCodeSize = mbr_size;
|
||||
return;
|
||||
} else if (!strcmp(dialog_vars.input_result, MenuMBRType.items[1].prompt)) {
|
||||
if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
|
||||
*bootCode = boot0;
|
||||
*bootCodeSize = boot0_size;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*bootCode = NULL;
|
||||
*bootCodeSize = 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* WITH_SLICES */
|
||||
|
||||
#ifdef WITH_SLICES
|
||||
void
|
||||
diskPartition(Device *dev)
|
||||
{
|
||||
char *cp, *p;
|
||||
int rv, key = 0;
|
||||
int i;
|
||||
Boolean chunking;
|
||||
char *msg = NULL;
|
||||
#ifdef PC98
|
||||
u_char *bootipl;
|
||||
size_t bootipl_size;
|
||||
u_char *bootmenu;
|
||||
size_t bootmenu_size;
|
||||
#else
|
||||
u_char *mbrContents;
|
||||
size_t mbrSize;
|
||||
#endif
|
||||
WINDOW *w = savescr();
|
||||
Disk *d = (Disk *)dev->private;
|
||||
int size_unit;
|
||||
|
||||
size_unit = UNIT_BLOCKS;
|
||||
chunking = TRUE;
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Flush both the dialog and curses library views of the screen
|
||||
since we don't always know who called us */
|
||||
dlg_clear(), clear();
|
||||
current_chunk = 0;
|
||||
|
||||
/* Set up the chunk array */
|
||||
record_chunks(d);
|
||||
|
||||
/* Give the user a chance to sanitize the disk geometry, if necessary */
|
||||
check_geometry(d);
|
||||
|
||||
while (chunking) {
|
||||
char *val, geometry[80];
|
||||
|
||||
/* Now print our overall state */
|
||||
if (d)
|
||||
print_chunks(d, size_unit);
|
||||
print_command_summary();
|
||||
if (msg) {
|
||||
attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
|
||||
beep();
|
||||
msg = NULL;
|
||||
}
|
||||
else {
|
||||
move(23, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
|
||||
/* Get command character */
|
||||
key = getch();
|
||||
switch (toupper(key)) {
|
||||
case '\014': /* ^L (redraw) */
|
||||
clear();
|
||||
msg = NULL;
|
||||
break;
|
||||
|
||||
case '\020': /* ^P */
|
||||
case KEY_UP:
|
||||
case '-':
|
||||
if (current_chunk != 0)
|
||||
--current_chunk;
|
||||
break;
|
||||
|
||||
case '\016': /* ^N */
|
||||
case KEY_DOWN:
|
||||
case '+':
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (chunk_info[current_chunk + 1])
|
||||
++current_chunk;
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
current_chunk = 0;
|
||||
break;
|
||||
|
||||
case KEY_END:
|
||||
while (chunk_info[current_chunk + 1])
|
||||
++current_chunk;
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
case '?':
|
||||
systemDisplayHelp("slice");
|
||||
clear();
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
case 'F': /* Undocumented magic Dangerously Dedicated mode */
|
||||
#if !defined(__i386__) && !defined(__amd64__)
|
||||
rv = 1;
|
||||
#else /* The rest is only relevant on x86 */
|
||||
cp = variable_get(VAR_DEDICATE_DISK);
|
||||
if (cp && !strcasecmp(cp, "always"))
|
||||
rv = 1;
|
||||
else if (toupper(key) == 'A')
|
||||
rv = 0;
|
||||
else {
|
||||
rv = msgYesNo("Do you want to do this with a true partition entry\n"
|
||||
"so as to remain cooperative with any future possible\n"
|
||||
"operating systems on the drive(s)?\n"
|
||||
"(See also the section about ``dangerously dedicated''\n"
|
||||
"disks in the FreeBSD FAQ.)");
|
||||
if (rv == -1)
|
||||
rv = 0;
|
||||
}
|
||||
#endif
|
||||
All_FreeBSD(d, rv);
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
record_chunks(d);
|
||||
clear();
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (chunk_info[current_chunk]->type != unused)
|
||||
msg = "Slice in use, delete it first or move to an unused one.";
|
||||
else {
|
||||
char *val, tmp[20], name[16], *cp;
|
||||
daddr_t size;
|
||||
int subtype;
|
||||
chunk_e partitiontype;
|
||||
#ifdef PC98
|
||||
snprintf(name, sizeof (name), "%s", "FreeBSD");
|
||||
val = msgGetInput(name,
|
||||
"Please specify the name for new FreeBSD slice.");
|
||||
if (val)
|
||||
strncpy(name, val, sizeof (name));
|
||||
#else
|
||||
name[0] = '\0';
|
||||
#endif
|
||||
snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
|
||||
val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
|
||||
"or append a trailing `M' for megabytes (e.g. 20M).");
|
||||
if (val && (size = strtoimax(val, &cp, 0)) > 0) {
|
||||
if (*cp && toupper(*cp) == 'M')
|
||||
size *= ONE_MEG;
|
||||
else if (*cp && toupper(*cp) == 'G')
|
||||
size *= ONE_GIG;
|
||||
sprintf(tmp, "%d", SUBTYPE_FREEBSD);
|
||||
val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
|
||||
"Pressing Enter will choose the default, a native FreeBSD\n"
|
||||
"slice (type %u). "
|
||||
OTHER_SLICE_VALUES
|
||||
NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
|
||||
if (val && (subtype = strtol(val, NULL, 0)) > 0) {
|
||||
if (subtype == SUBTYPE_FREEBSD)
|
||||
partitiontype = freebsd;
|
||||
else if (subtype == SUBTYPE_FAT)
|
||||
partitiontype = fat;
|
||||
else if (subtype == SUBTYPE_EFI)
|
||||
partitiontype = efi;
|
||||
else
|
||||
#ifdef PC98
|
||||
partitiontype = pc98;
|
||||
#else
|
||||
partitiontype = mbr;
|
||||
#endif
|
||||
Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
|
||||
(chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
record_chunks(d);
|
||||
}
|
||||
}
|
||||
clear();
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DC:
|
||||
case 'D':
|
||||
if (chunk_info[current_chunk]->type == unused)
|
||||
msg = "Slice is already unused!";
|
||||
else {
|
||||
Delete_Chunk(d, chunk_info[current_chunk]);
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
record_chunks(d);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (chunk_info[current_chunk]->type == unused)
|
||||
msg = "Slice is currently unused (use create instead)";
|
||||
else {
|
||||
char *val, tmp[20];
|
||||
int subtype;
|
||||
chunk_e partitiontype;
|
||||
|
||||
sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
|
||||
val = msgGetInput(tmp, "New partition type:\n\n"
|
||||
"Pressing Enter will use the current type. To choose a native\n"
|
||||
"FreeBSD slice enter %u. "
|
||||
OTHER_SLICE_VALUES
|
||||
NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
|
||||
if (val && (subtype = strtol(val, NULL, 0)) > 0) {
|
||||
if (subtype == SUBTYPE_FREEBSD)
|
||||
partitiontype = freebsd;
|
||||
else if (subtype == SUBTYPE_FAT)
|
||||
partitiontype = fat;
|
||||
else if (subtype == SUBTYPE_EFI)
|
||||
partitiontype = efi;
|
||||
else
|
||||
#ifdef PC98
|
||||
partitiontype = pc98;
|
||||
#else
|
||||
partitiontype = mbr;
|
||||
#endif
|
||||
chunk_info[current_chunk]->type = partitiontype;
|
||||
chunk_info[current_chunk]->subtype = subtype;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
|
||||
val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
|
||||
"Don't forget to use the two slash (/) separator characters!\n"
|
||||
"It's not possible to parse the field without them.");
|
||||
if (val) {
|
||||
long nc, nh, ns;
|
||||
nc = strtol(val, &val, 0);
|
||||
nh = strtol(val + 1, &val, 0);
|
||||
ns = strtol(val + 1, 0, 0);
|
||||
Set_Bios_Geom(d, nc, nh, ns);
|
||||
}
|
||||
clear();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
/* Clear active states so we won't have two */
|
||||
for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
|
||||
chunk_info[i]->flags &= !CHUNK_ACTIVE;
|
||||
|
||||
/* Set Bootable */
|
||||
chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
if (!variable_cmp(DISK_LABELLED, "written")) {
|
||||
msgConfirm("You've already written this information out - you\n"
|
||||
"can't undo it.");
|
||||
}
|
||||
else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
|
||||
char cp[BUFSIZ];
|
||||
|
||||
sstrncpy(cp, d->name, sizeof cp);
|
||||
Free_Disk(dev->private);
|
||||
d = Open_Disk(cp);
|
||||
if (!d)
|
||||
msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
|
||||
dev->private = d;
|
||||
variable_unset(DISK_PARTITIONED);
|
||||
variable_unset(DISK_LABELLED);
|
||||
if (d)
|
||||
record_chunks(d);
|
||||
}
|
||||
clear();
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
if (!msgNoYes("WARNING: You are about to modify an EXISTING installation.\n"
|
||||
"You should simply type Q when you are finished\n"
|
||||
"here and write to the disk from the label editor.\n\n"
|
||||
"Are you absolutely sure you want to continue?")) {
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* Don't trash the IPL if the first (and therefore only) chunk
|
||||
* is marked for a truly dedicated disk (i.e., the disklabel
|
||||
* starts at sector 0), even in cases where the user has
|
||||
* requested a FreeBSD Boot Manager -- both would be fatal in
|
||||
* this case.
|
||||
*/
|
||||
/*
|
||||
* Don't offer to update the IPL on this disk if the first
|
||||
* "real" chunk looks like a FreeBSD "all disk" partition,
|
||||
* or the disk is entirely FreeBSD.
|
||||
*/
|
||||
if ((d->chunks->part->type != freebsd) ||
|
||||
(d->chunks->part->offset > 1))
|
||||
getBootMgr(d->name, &bootipl, &bootipl_size,
|
||||
&bootmenu, &bootmenu_size);
|
||||
else {
|
||||
bootipl = NULL;
|
||||
bootipl_size = 0;
|
||||
bootmenu = NULL;
|
||||
bootmenu_size = 0;
|
||||
}
|
||||
Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
|
||||
#else
|
||||
/*
|
||||
* Don't trash the MBR if the first (and therefore only) chunk
|
||||
* is marked for a truly dedicated disk (i.e., the disklabel
|
||||
* starts at sector 0), even in cases where the user has
|
||||
* requested booteasy or a "standard" MBR -- both would be
|
||||
* fatal in this case.
|
||||
*/
|
||||
/*
|
||||
* Don't offer to update the MBR on this disk if the first
|
||||
* "real" chunk looks like a FreeBSD "all disk" partition,
|
||||
* or the disk is entirely FreeBSD.
|
||||
*/
|
||||
if ((d->chunks->part->type != freebsd) ||
|
||||
(d->chunks->part->offset > 1))
|
||||
getBootMgr(d->name, &mbrContents, &mbrSize);
|
||||
else {
|
||||
mbrContents = NULL;
|
||||
mbrSize = 0;
|
||||
}
|
||||
Set_Boot_Mgr(d, mbrContents, mbrSize);
|
||||
#endif
|
||||
|
||||
if (DITEM_STATUS(diskPartitionWrite(dev)) != DITEM_SUCCESS)
|
||||
msgConfirm("Disk partition write returned an error status!");
|
||||
else
|
||||
msgConfirm("Wrote FDISK partition information out successfully.");
|
||||
}
|
||||
clear();
|
||||
break;
|
||||
|
||||
case '|':
|
||||
if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
|
||||
"No seat belts whatsoever are provided!")) {
|
||||
clear();
|
||||
refresh();
|
||||
slice_wizard(d);
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
record_chunks(d);
|
||||
}
|
||||
else
|
||||
msg = "Wise choice!";
|
||||
clear();
|
||||
break;
|
||||
|
||||
case '\033': /* ESC */
|
||||
case 'Q':
|
||||
chunking = FALSE;
|
||||
#ifdef PC98
|
||||
/*
|
||||
* Don't trash the IPL if the first (and therefore only) chunk
|
||||
* is marked for a truly dedicated disk (i.e., the disklabel
|
||||
* starts at sector 0), even in cases where the user has requested
|
||||
* a FreeBSD Boot Manager -- both would be fatal in this case.
|
||||
*/
|
||||
/*
|
||||
* Don't offer to update the IPL on this disk if the first "real"
|
||||
* chunk looks like a FreeBSD "all disk" partition, or the disk is
|
||||
* entirely FreeBSD.
|
||||
*/
|
||||
if ((d->chunks->part->type != freebsd) ||
|
||||
(d->chunks->part->offset > 1)) {
|
||||
if (variable_cmp(DISK_PARTITIONED, "written")) {
|
||||
getBootMgr(d->name, &bootipl, &bootipl_size,
|
||||
&bootmenu, &bootmenu_size);
|
||||
if (bootipl != NULL && bootmenu != NULL)
|
||||
Set_Boot_Mgr(d, bootipl, bootipl_size,
|
||||
bootmenu, bootmenu_size);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Don't trash the MBR if the first (and therefore only) chunk
|
||||
* is marked for a truly dedicated disk (i.e., the disklabel
|
||||
* starts at sector 0), even in cases where the user has requested
|
||||
* booteasy or a "standard" MBR -- both would be fatal in this case.
|
||||
*/
|
||||
/*
|
||||
* Don't offer to update the MBR on this disk if the first "real"
|
||||
* chunk looks like a FreeBSD "all disk" partition, or the disk is
|
||||
* entirely FreeBSD.
|
||||
*/
|
||||
if ((d->chunks->part->type != freebsd) ||
|
||||
(d->chunks->part->offset > 1)) {
|
||||
if (variable_cmp(DISK_PARTITIONED, "written")) {
|
||||
getBootMgr(d->name, &mbrContents, &mbrSize);
|
||||
if (mbrContents != NULL)
|
||||
Set_Boot_Mgr(d, mbrContents, mbrSize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
size_unit = (size_unit + 1) % UNIT_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
beep();
|
||||
msg = "Type F1 or ? for help";
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = CheckRules(d);
|
||||
if (p) {
|
||||
char buf[FILENAME_MAX];
|
||||
DIALOG_VARS save_vars;
|
||||
|
||||
dlg_save_vars(&save_vars);
|
||||
dialog_vars.help_line = "Press F1 to read more about disk slices.";
|
||||
dialog_vars.help_file = systemHelpFile("partition", buf);
|
||||
if (!variable_get(VAR_NO_WARN))
|
||||
xdialog_msgbox("Disk slicing warning:", p, -1, -1, 1);
|
||||
free(p);
|
||||
dlg_restore_vars(&save_vars);
|
||||
}
|
||||
restorescr(w);
|
||||
}
|
||||
#endif /* WITH_SLICES */
|
||||
|
||||
#if !defined(__ia64__)
|
||||
static u_char *
|
||||
bootalloc(char *name, size_t *size)
|
||||
{
|
||||
char buf[FILENAME_MAX];
|
||||
struct stat sb;
|
||||
|
||||
snprintf(buf, sizeof buf, "/boot/%s", name);
|
||||
if (stat(buf, &sb) != -1) {
|
||||
int fd;
|
||||
|
||||
fd = open(buf, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
u_char *cp;
|
||||
|
||||
cp = malloc(sb.st_size);
|
||||
if (read(fd, cp, sb.st_size) != sb.st_size) {
|
||||
free(cp);
|
||||
close(fd);
|
||||
msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
if (size != NULL)
|
||||
*size = sb.st_size;
|
||||
return cp;
|
||||
}
|
||||
msgDebug("bootalloc: couldn't open %s\n", buf);
|
||||
}
|
||||
else
|
||||
msgDebug("bootalloc: can't stat %s\n", buf);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !__ia64__ */
|
||||
|
||||
#ifdef WITH_SLICES
|
||||
static int
|
||||
partitionHook(dialogMenuItem *selected)
|
||||
{
|
||||
Device **devs = NULL;
|
||||
|
||||
devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
|
||||
if (!devs) {
|
||||
msgConfirm("Unable to find disk %s!", selected->prompt);
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
diskPartition(devs[0]);
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
diskPartitionEditor(dialogMenuItem *self)
|
||||
{
|
||||
DMenu *menu;
|
||||
Device **devs;
|
||||
|
||||
devs = deviceFind(variable_get(VAR_DISK), DEVICE_TYPE_DISK);
|
||||
if (devs == NULL) {
|
||||
msgConfirm("No disks found! Please verify that your disk controller is being\n"
|
||||
"properly probed at boot time. See the Hardware Guide on the\n"
|
||||
"Documentation menu for clues on diagnosing this type of problem.");
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
else {
|
||||
/* No disks are selected, fall-back case now */
|
||||
int cnt = deviceCount(devs);
|
||||
|
||||
if (cnt == 1) {
|
||||
if (variable_get(VAR_NONINTERACTIVE) &&
|
||||
!variable_get(VAR_DISKINTERACTIVE))
|
||||
diskPartitionNonInteractive(devs[0]);
|
||||
else
|
||||
diskPartition(devs[0]);
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
else {
|
||||
int result;
|
||||
|
||||
menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook);
|
||||
if (!menu) {
|
||||
msgConfirm("No devices suitable for installation found!\n\n"
|
||||
"Please verify that your disk controller (and attached drives)\n"
|
||||
"were detected properly. This can be done by pressing the\n"
|
||||
"[Scroll Lock] key and using the Arrow keys to move back to\n"
|
||||
"the boot messages. Press [Scroll Lock] again to return.");
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
|
||||
result = dmenuOpen(menu) ? DITEM_SUCCESS : DITEM_FAILURE;
|
||||
free(menu);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
#endif /* WITH_SLICES */
|
||||
|
||||
int
|
||||
diskPartitionWrite(Device *dev)
|
||||
{
|
||||
Disk *d = (Disk *)dev->private;
|
||||
#if !defined(__ia64__)
|
||||
static u_char *boot1;
|
||||
#endif
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
static u_char *boot2;
|
||||
#endif
|
||||
|
||||
if (!variable_cmp(DISK_PARTITIONED, "written"))
|
||||
return DITEM_SUCCESS;
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
if (!boot1) boot1 = bootalloc("boot1", NULL);
|
||||
if (!boot2) boot2 = bootalloc("boot2", NULL);
|
||||
Set_Boot_Blocks(d, boot1, boot2);
|
||||
#elif !defined(__ia64__)
|
||||
if (!boot1) boot1 = bootalloc("boot1", NULL);
|
||||
Set_Boot_Blocks(d, boot1, NULL);
|
||||
#endif
|
||||
|
||||
msgNotify("Writing partition information to drive %s", d->name);
|
||||
if (!Fake && Write_Disk(d)) {
|
||||
msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
|
||||
/* Now it's not "yes", but "written" */
|
||||
variable_set2(DISK_PARTITIONED, "written", 0);
|
||||
return DITEM_SUCCESS | DITEM_RESTORE;
|
||||
}
|
||||
|
||||
#ifdef WITH_SLICES
|
||||
/* Partition a disk based wholly on which variables are set */
|
||||
static void
|
||||
diskPartitionNonInteractive(Device *dev)
|
||||
{
|
||||
char *cp;
|
||||
int i, all_disk = 0;
|
||||
daddr_t sz;
|
||||
#ifdef PC98
|
||||
u_char *bootipl;
|
||||
size_t bootipl_size;
|
||||
u_char *bootmenu;
|
||||
size_t bootmenu_size;
|
||||
#else
|
||||
u_char *mbrContents;
|
||||
size_t mbrSize;
|
||||
#endif
|
||||
Disk *d = (Disk *)dev->private;
|
||||
|
||||
record_chunks(d);
|
||||
cp = variable_get(VAR_GEOMETRY);
|
||||
if (cp) {
|
||||
if (!strcasecmp(cp, "sane")) {
|
||||
#ifdef PC98
|
||||
if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
|
||||
#else
|
||||
if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
|
||||
#endif
|
||||
{
|
||||
msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
|
||||
d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
|
||||
Sanitize_Bios_Geom(d);
|
||||
msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
|
||||
d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
|
||||
}
|
||||
} else {
|
||||
msgDebug("Setting geometry from script to: %s\n", cp);
|
||||
d->bios_cyl = strtol(cp, &cp, 0);
|
||||
d->bios_hd = strtol(cp + 1, &cp, 0);
|
||||
d->bios_sect = strtol(cp + 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
cp = variable_get(VAR_PARTITION);
|
||||
if (cp) {
|
||||
if (!strcmp(cp, "free")) {
|
||||
/* Do free disk space case */
|
||||
for (i = 0; chunk_info[i]; i++) {
|
||||
/* If a chunk is at least 10MB in size, use it. */
|
||||
if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
|
||||
Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
|
||||
freebsd, 3,
|
||||
(chunk_info[i]->flags & CHUNK_ALIGN),
|
||||
"FreeBSD");
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!chunk_info[i]) {
|
||||
msgConfirm("Unable to find any free space on this disk!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cp, "all")) {
|
||||
/* Do all disk space case */
|
||||
msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
|
||||
|
||||
All_FreeBSD(d, FALSE);
|
||||
}
|
||||
else if (!strcmp(cp, "exclusive")) {
|
||||
/* Do really-all-the-disk-space case */
|
||||
msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
|
||||
|
||||
All_FreeBSD(d, all_disk = TRUE);
|
||||
}
|
||||
else if ((sz = strtoimax(cp, &cp, 0))) {
|
||||
/* Look for sz bytes free */
|
||||
if (*cp && toupper(*cp) == 'M')
|
||||
sz *= ONE_MEG;
|
||||
else if (*cp && toupper(*cp) == 'G')
|
||||
sz *= ONE_GIG;
|
||||
for (i = 0; chunk_info[i]; i++) {
|
||||
/* If a chunk is at least sz MB, use it. */
|
||||
if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
|
||||
Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
|
||||
(chunk_info[i]->flags & CHUNK_ALIGN),
|
||||
"FreeBSD");
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!chunk_info[i]) {
|
||||
msgConfirm("Unable to find %jd free blocks on this disk!",
|
||||
(intmax_t)sz);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cp, "existing")) {
|
||||
/* Do existing FreeBSD case */
|
||||
for (i = 0; chunk_info[i]; i++) {
|
||||
if (chunk_info[i]->type == freebsd)
|
||||
break;
|
||||
}
|
||||
if (!chunk_info[i]) {
|
||||
msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
|
||||
return;
|
||||
}
|
||||
if (!all_disk) {
|
||||
#ifdef PC98
|
||||
getBootMgr(d->name, &bootipl, &bootipl_size,
|
||||
&bootmenu, &bootmenu_size);
|
||||
Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
|
||||
#else
|
||||
getBootMgr(d->name, &mbrContents, &mbrSize);
|
||||
Set_Boot_Mgr(d, mbrContents, mbrSize);
|
||||
#endif
|
||||
}
|
||||
variable_set2(DISK_PARTITIONED, "yes", 0);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_SLICES */
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <errno.h>
|
||||
|
||||
#define MAX_MENU 15
|
||||
|
||||
static int
|
||||
menu_height(DMenu *menu, int n)
|
||||
{
|
||||
int max;
|
||||
char *t;
|
||||
|
||||
max = MAX_MENU;
|
||||
if (StatusLine > 24)
|
||||
max += StatusLine - 24;
|
||||
for (t = menu->prompt; *t; t++) {
|
||||
if (*t == '\n')
|
||||
--max;
|
||||
}
|
||||
return n > max ? max : n;
|
||||
}
|
||||
|
||||
/* Traverse over an internal menu */
|
||||
Boolean
|
||||
dmenuOpen(DMenu *menu)
|
||||
{
|
||||
int n, rval = 0;
|
||||
|
||||
/* Count up all the items */
|
||||
for (n = 0; menu->items[n].title; n++)
|
||||
;
|
||||
|
||||
while (1) {
|
||||
char buf[FILENAME_MAX];
|
||||
DIALOG_VARS save_vars;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
/* Any helpful hints, put 'em up! */
|
||||
dlg_save_vars(&save_vars);
|
||||
dialog_vars.help_line = menu->helpline;
|
||||
dialog_vars.help_file = systemHelpFile(menu->helpfile, buf);
|
||||
dlg_clear();
|
||||
/* Pop up that dialog! */
|
||||
if (menu->type & DMENU_NORMAL_TYPE) {
|
||||
rval = xdialog_menu(menu->title, menu->prompt,
|
||||
-1, -1, menu_height(menu, n), n, menu->items);
|
||||
} else if (menu->type & DMENU_RADIO_TYPE) {
|
||||
rval = xdialog_radiolist(menu->title, menu->prompt,
|
||||
-1, -1, menu_height(menu, n), n, menu->items);
|
||||
} else {
|
||||
msgFatal("Menu: `%s' is of an unknown type\n", menu->title);
|
||||
}
|
||||
dlg_restore_vars(&save_vars);
|
||||
if (rval) {
|
||||
restorescr(w);
|
||||
return FALSE;
|
||||
} else if (menu->type & DMENU_SELECTION_RETURNS) {
|
||||
restorescr(w);
|
||||
return TRUE;
|
||||
} else
|
||||
delwin(w);
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/*
|
||||
* Various global variables and an initialization hook to set them to
|
||||
* whatever values we feel are appropriate.
|
||||
*/
|
||||
|
||||
int DebugFD; /* Where diagnostic output goes */
|
||||
Boolean Fake; /* Only pretend to be useful */
|
||||
Boolean DialogActive; /* Is libdialog initialized? */
|
||||
Boolean ColorDisplay; /* Are we on a color display? */
|
||||
Boolean OnVTY; /* Are we on a VTY? */
|
||||
Boolean Restarting; /* Are we restarting sysinstall? */
|
||||
Variable *VarHead; /* The head of the variable chain */
|
||||
int BootMgr; /* Which boot manager we're using */
|
||||
int StatusLine; /* Where to stick our status messages */
|
||||
jmp_buf BailOut; /* Beam me up, scotty! The natives are pissed! */
|
||||
|
||||
Chunk *HomeChunk;
|
||||
Chunk *RootChunk;
|
||||
Chunk *SwapChunk;
|
||||
Chunk *TmpChunk;
|
||||
Chunk *UsrChunk;
|
||||
Chunk *VarChunk;
|
||||
#ifdef __ia64__
|
||||
Chunk *EfiChunk;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Yes, I know some of these are already automatically initialized as
|
||||
* globals. I simply find it clearer to set everything explicitly.
|
||||
*/
|
||||
void
|
||||
globalsInit(void)
|
||||
{
|
||||
DebugFD = -1;
|
||||
ColorDisplay = FALSE;
|
||||
Fake = FALSE;
|
||||
Restarting = FALSE;
|
||||
OnVTY = FALSE;
|
||||
DialogActive = FALSE;
|
||||
VarHead = NULL;
|
||||
|
||||
HomeChunk = NULL;
|
||||
RootChunk = NULL;
|
||||
SwapChunk = NULL;
|
||||
TmpChunk = NULL;
|
||||
UsrChunk = NULL;
|
||||
VarChunk = NULL;
|
||||
#ifdef __ia64__
|
||||
EfiChunk = NULL;
|
||||
#endif
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
This is the FreeBSD DiskLabel Editor.
|
||||
|
||||
NOTE: If you're entering this editor from the update procedure then
|
||||
you probably shouldn't (C)reate anything at all but rather use only
|
||||
the (M)ount command to check and mount existing partitions for
|
||||
upgrading.
|
||||
|
||||
If you would like the label editor to do most of the following for
|
||||
you, simply type `A' for automatic partitioning of the disk.
|
||||
|
||||
If you wish to create partitions manually you may do so by moving the
|
||||
highlighted selection bar with the arrow keys over the FreeBSD
|
||||
partition(s) displayed at the top of the screen. Typing (C)reate
|
||||
while a partition with available free space is selected will allow you
|
||||
to create a BSD partition inside of it using some or all of its
|
||||
available space.
|
||||
|
||||
Typing (M)ount over an existing partition entry (displayed in the
|
||||
middle of the screen) will allow you to set a mount point for it
|
||||
without initializing it. If you want it initialized, use the (T)oggle
|
||||
command to flip the Newfs flag. When Newfs is set to "Y", the
|
||||
filesystem in question will be ERASED and rebuilt from scratch!
|
||||
|
||||
|
||||
You should use this editor to create at least the following
|
||||
filesystems:
|
||||
|
||||
Name Purpose Min Size? Optional?
|
||||
---- ------- --------- ---------
|
||||
/ Root filesystem 118MB No
|
||||
swap Swap space 2 * MEM No
|
||||
/usr System & user files 128MB or more Yes
|
||||
|
||||
Note: If you do not create a /usr filesystem then your / filesystem
|
||||
will need to be bigger - at least 240MB. This is not recommended as
|
||||
any media errors that may occur during disk I/O to user files will
|
||||
corrupt the filesystem containing vital system files as well. It is
|
||||
for this reason that / is generally kept on its own filesystem, where
|
||||
it should be considered essentially "read only" in your administration
|
||||
of it.
|
||||
|
||||
Swap space is a little tricker, and the rule of "2 * MEM" is simply a
|
||||
best-guess approximation and not necessarily accurate for your
|
||||
intended usage of the system. If you intend to use the system heavily
|
||||
in a server or multi-user application, you may be well advised to
|
||||
increase this size. You may also create swap space on multiple drives
|
||||
for a larger "total" swap and this is, in fact, recommended if you
|
||||
have multiple, fast drives for which such load-balancing can only help
|
||||
overall I/O performance.
|
||||
|
||||
The /usr filesystem should be sized according to what kind of
|
||||
distributions you're trying to load and how many packages you intend
|
||||
to install in locations like /usr/local. You can also make /usr/local
|
||||
a separate filesystem if you don't want to risk filling up your /usr
|
||||
by mistake.
|
||||
|
||||
Another useful filesystem to create is /var, which contains mail, news
|
||||
printer spool files and other temporary items. It is a popular
|
||||
candidate for a separate partition and should be sized according to
|
||||
your estimates of the amount of mail, news or spooled print jobs that
|
||||
may be stored there.
|
||||
|
||||
WARNING: If you do not create a separate filesystem for /var, space
|
||||
for such files will be allocated out of the root (/) filesystem
|
||||
instead. You may therefore wish to make the / partition bigger if you
|
||||
expect a lot of mail or news and do not want to make /var its own
|
||||
partition.
|
||||
|
||||
If you're new to this installation, you might also want to read the
|
||||
following explanation of how FreeBSD's new "slice" paradigm for
|
||||
looking at disk storage works:
|
||||
|
||||
|
||||
In FreeBSD's new system, a device name can be broken up into up to 3
|
||||
parts. Take a typical name like ``/dev/da0s1a'':
|
||||
|
||||
The first three characters represent the drive name. If we had
|
||||
a system with two SCSI drives on it then we'd see /dev/da0 and
|
||||
/dev/da1 as the device entries representing the entire drives.
|
||||
|
||||
Next you have the "slice" (or "FDISK Partition") number,
|
||||
as seen in the Partition Editor. Assuming that our da0
|
||||
contained two slices, a FreeBSD slice and a DOS slice, that
|
||||
would give us /dev/da0s1 and /dev/da0s2 as device entries pointing
|
||||
to the entire slices.
|
||||
|
||||
Next, if a slice is a FreeBSD slice, you can have a number of
|
||||
(confusingly named) "partitions" inside of it.
|
||||
|
||||
These partitions are where various filesystems or swap areas live,
|
||||
and using our hypothetical two-SCSI-disk machine again, we might
|
||||
have something like the following layout on da0:
|
||||
|
||||
Name Mountpoint
|
||||
---- ----------
|
||||
da0s1a /
|
||||
da0s1b <swap space>
|
||||
da0s1e /usr
|
||||
|
||||
Once you understand all this, then the purpose of the label editor
|
||||
becomes fairly clear: You're carving up the FreeBSD slices displayed
|
||||
at the top of the screen into smaller pieces, which are displayed in
|
||||
the middle of the screen, and then assigning FreeBSD file system names
|
||||
(mount points) to them.
|
||||
|
||||
You can also use the label editor to mount existing partitions/slices
|
||||
into your filesystem hierarchy, as is frequently done for DOS FAT
|
||||
slices. For FreeBSD partitions, you can also toggle the "newfs" state
|
||||
so that the partitions are either (re)created from scratch or simply
|
||||
checked and mounted (the contents are preserved).
|
||||
|
||||
If you set (S)oftUpdates on a filesystem, it will cause the
|
||||
"Soft Updates" policy to be in effect for it. This basically causes
|
||||
both metadata and data blocks to be written asynchronously to disk,
|
||||
but with extra state information which causes the metadata and any
|
||||
related data blocks to be committed in a single transaction. This
|
||||
results in async metadata update speeds (which are considerably
|
||||
faster than the default sync) without the potential for data loss
|
||||
which could occur if you simply mounted the filesystem with purely
|
||||
"async" update policy and then had a power failure. If you wish
|
||||
to later turn the softupdates policy back off, use the command
|
||||
"tunefs -n disable devicename". NOTE: It is probably not wise
|
||||
to use this on your root filesystem unless you have a large
|
||||
(e.g. non-standard size) root. The reason is that smaller filesystems
|
||||
with significant activity can temporarily overflow if the soft updates
|
||||
policy results in free'd blocks not being "garbage collected" as fast
|
||||
as they're being requested.
|
||||
|
||||
The UNIX File System (UFS) on FreeBSD supports two different on-disk
|
||||
layouts: UFS1 and UFS2. UFS1 was the default file system in use
|
||||
through FreeBSD 5.0-RELEASE; as of FreeBSD 5.1-RELEASE, the default
|
||||
is now UFS2, with the exception of the PC98 platform. UFS2 provides
|
||||
sparse inode allocation (faster fsck), 64-bit storage pointers (larger
|
||||
maximum size), and native extended attributes (required for ACLs, MAC,
|
||||
and other advanced security and file system services). The selection
|
||||
of UFS1 or UFS2 must be made when the file system is created--later
|
||||
conversion is not currently possible. UFS2 is the recommended file
|
||||
system, but if disks are to be used on older FreeBSD systems, UFS1
|
||||
improves portability. When dual-booting between FreeBSD 4.x or
|
||||
earlier and FreeBSD 5.x, UFS1 file systems will be accessible from
|
||||
both. To toggle a file system to UFS1, press '1'. To restore it to
|
||||
UFS2, press '2'.
|
||||
|
||||
WARNING: FreeBSD on i386 is currently unable to boot from root file
|
||||
systems larger than 1.5TB.
|
||||
|
||||
To add additional flags to the newfs command line for UFS file
|
||||
systems, press 'N'. These options will be specified before the
|
||||
device argument of the command line, but after any other options
|
||||
placed there by sysinstall, such as the UFS version and soft
|
||||
updates flag; as such, arguments provided may override existing
|
||||
settings. To completely replace the newfs command used by
|
||||
sysinstall, press 'Z' to convert a partition to a Custom
|
||||
partition type. Sysinstall will prompt you with the newfs
|
||||
command line that it would have used based on existing settings
|
||||
prior to the change, but allow you to modify any aspect of the
|
||||
command line. Once a partition has been converted to a custom
|
||||
partition in the label editor, you will need to restart the
|
||||
labeling process or delete and recreate the partition to restore
|
||||
it to a non-custom state. Custom partitions are represented by
|
||||
the letters "CST" instead of "UFS" or "FAT.
|
||||
|
||||
When you're done, type `Q' to exit.
|
||||
|
||||
No actual changes will be made to the disk until you (C)ommit from the
|
||||
Install menu or (W)rite directly from this one. You're working with
|
||||
what is essentially a copy of the disk label(s), both here and in the
|
||||
FDISK Partition Editor, and the actual on-disk labels won't be
|
||||
affected by any changes you make until you explicitly say so.
|
@ -1,57 +0,0 @@
|
||||
This is the Main Slice (``FDISK'' or PC-style Partition) Editor.
|
||||
|
||||
Possible commands are printed at the bottom and the Master Boot Record
|
||||
contents are shown at the top. You can move up and down with the
|
||||
arrow keys and (C)reate a new slice whenever the highlighted
|
||||
selection bar is over a slice whose type is marked as "unused."
|
||||
|
||||
You are expected to leave this screen with at least one slice
|
||||
marked "FreeBSD." Note that unlike Linux, you don't need to create
|
||||
multiple FreeBSD FDISK partition entries for different things like
|
||||
swap, file systems, etc. The usual convention is to create ONE
|
||||
FreeBSD slice (FDISK partition) per drive and then subsection this slice
|
||||
into swap and file systems with the Label editor.
|
||||
|
||||
No actual changes will be made to the disk until you (C)ommit from the
|
||||
Install menu or use the (W)rite option here! You're working with what
|
||||
is essentially a copy of the disk label(s), both here and in the Label
|
||||
Editor.
|
||||
|
||||
If you want to use the entire disk for FreeBSD, type `A'. Slices will
|
||||
be aligned to fictitious cylinder boundaries and space will be reserved
|
||||
in front of the FreeBSD slice for a [future] possible boot manager.
|
||||
|
||||
For the truly dedicated disk case, type `F'. You'll be asked whether or
|
||||
not you wish to keep the disk (potentially) compatible with other
|
||||
operating systems, i.e. the information in the FDISK table should be
|
||||
kept valid. A truly dedicated disk can be achieved by selecting `No'.
|
||||
In that case, all BIOS geometry considerations will no longer be in
|
||||
effect and you can safely ignore any ``The detected geometry is
|
||||
invalid'' warning messages you may later see. It is also not necessary
|
||||
in this case to set a slice bootable or install an MBR boot manager as
|
||||
both things are then irrelevant. The FreeBSD slice will start at
|
||||
absolute sector 0 of the disk (so that FreeBSD's disk label is identical
|
||||
to the Master Boot Record) and extend to the very last sector of the
|
||||
disk medium. Needless to say, such a disk cannot have any sort of a
|
||||
boot manager, `disk manager', or anything else that has to interact with
|
||||
the BIOS. This option is therefore only considered safe for SCSI disks
|
||||
and most IDE disks and is primarily intended for people who are going to
|
||||
set up a dedicated FreeBSD server or workstation, not a typical `home PC'.
|
||||
|
||||
If you select the default of `Yes' at the compatibility, slices will be
|
||||
aligned to fictitious cylinder boundaries and space will be reserved
|
||||
in front of the FreeBSD slice for a [future] possible boot manager.
|
||||
This is pretty much equivalent to having chosen `A' originally.
|
||||
|
||||
The flags field has the following legend:
|
||||
|
||||
'=' -- This slice is properly aligned.
|
||||
'A' -- This slice is marked active.
|
||||
'R' -- This slice contains the root (/) filesystem
|
||||
|
||||
If no slice is marked Active, you will need to either install
|
||||
a Boot Manager (the option for which will be presented later in the
|
||||
installation) or set one Active before leaving this screen.
|
||||
|
||||
To leave the slice editor, type `Q'.
|
||||
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/param.h>
|
||||
#define MSDOSFS
|
||||
#include <sys/mount.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
#undef MSDOSFS
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <libdisk.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
#define TERMCAP_FILE "/usr/share/misc/termcap"
|
||||
|
||||
Boolean
|
||||
checkLabels(Boolean whinge)
|
||||
{
|
||||
Boolean status;
|
||||
|
||||
/* Don't allow whinging if noWarn is set */
|
||||
if (variable_get(VAR_NO_WARN))
|
||||
whinge = FALSE;
|
||||
|
||||
status = TRUE;
|
||||
HomeChunk = RootChunk = SwapChunk = NULL;
|
||||
TmpChunk = UsrChunk = VarChunk = NULL;
|
||||
#ifdef __ia64__
|
||||
EfiChunk = NULL;
|
||||
#endif
|
||||
|
||||
/* We don't need to worry about root/usr/swap if we're already multiuser */
|
||||
return status;
|
||||
}
|
||||
|
||||
#define QUEUE_YES 1
|
||||
#define QUEUE_NO 0
|
||||
static int
|
||||
performNewfs(PartInfo *pi, char *dname, int queue)
|
||||
{
|
||||
char buffer[LINE_MAX];
|
||||
|
||||
if (pi->do_newfs) {
|
||||
switch(pi->newfs_type) {
|
||||
case NEWFS_UFS:
|
||||
snprintf(buffer, LINE_MAX, "%s %s %s %s %s",
|
||||
NEWFS_UFS_CMD,
|
||||
pi->newfs_data.newfs_ufs.softupdates ? "-U" : "",
|
||||
pi->newfs_data.newfs_ufs.ufs1 ? "-O1" : "-O2",
|
||||
pi->newfs_data.newfs_ufs.user_options,
|
||||
dname);
|
||||
break;
|
||||
|
||||
case NEWFS_MSDOS:
|
||||
snprintf(buffer, LINE_MAX, "%s %s", NEWFS_MSDOS_CMD,
|
||||
dname);
|
||||
break;
|
||||
|
||||
case NEWFS_CUSTOM:
|
||||
snprintf(buffer, LINE_MAX, "%s %s",
|
||||
pi->newfs_data.newfs_custom.command, dname);
|
||||
break;
|
||||
}
|
||||
|
||||
if (queue == QUEUE_YES) {
|
||||
command_shell_add(pi->mountpoint, "%s", buffer);
|
||||
return (0);
|
||||
} else
|
||||
return (vsystem("%s", buffer));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Go newfs and/or mount all the filesystems we've been asked to */
|
||||
int
|
||||
installFilesystems(Device *dev)
|
||||
{
|
||||
Disk *disk = (Disk *)dev->private;
|
||||
Chunk *c1, *c2;
|
||||
PartInfo *root;
|
||||
char dname[80];
|
||||
Boolean upgrade = FALSE;
|
||||
|
||||
/* If we've already done this, bail out */
|
||||
if (!variable_cmp(DISK_LABELLED, "written"))
|
||||
return DITEM_SUCCESS;
|
||||
|
||||
upgrade = !variable_cmp(SYSTEM_STATE, "upgrade");
|
||||
if (!checkLabels(TRUE))
|
||||
return DITEM_FAILURE;
|
||||
|
||||
root = (RootChunk != NULL) ? (PartInfo *)RootChunk->private_data : NULL;
|
||||
|
||||
command_clear();
|
||||
|
||||
/* Now buzz through the rest of the partitions and mount them too */
|
||||
if (!disk->chunks) {
|
||||
msgConfirm("No chunk list found for %s!", disk->name);
|
||||
return DITEM_FAILURE | DITEM_RESTORE;
|
||||
}
|
||||
for (c1 = disk->chunks->part; c1; c1 = c1->next) {
|
||||
#ifdef __ia64__
|
||||
if (c1->type == part) {
|
||||
c2 = c1;
|
||||
{
|
||||
#elif defined(__powerpc__)
|
||||
if (c1->type == apple) {
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
#else
|
||||
if (c1->type == freebsd) {
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
#endif
|
||||
if (c2->type == part && c2->subtype != FS_SWAP && c2->private_data) {
|
||||
PartInfo *tmp = (PartInfo *)c2->private_data;
|
||||
|
||||
/* Already did root */
|
||||
if (c2 == RootChunk)
|
||||
continue;
|
||||
|
||||
sprintf(dname, "/dev/%s", c2->name);
|
||||
|
||||
if (tmp->do_newfs && (!upgrade ||
|
||||
!msgNoYes("You are upgrading - are you SURE you"
|
||||
" want to newfs /dev/%s?", c2->name)))
|
||||
performNewfs(tmp, dname, QUEUE_YES);
|
||||
else
|
||||
command_shell_add(tmp->mountpoint,
|
||||
"fsck_ffs -y /dev/%s", c2->name);
|
||||
command_func_add(tmp->mountpoint, Mount, c2->name);
|
||||
}
|
||||
else if (c2->type == part && c2->subtype == FS_SWAP) {
|
||||
char fname[80];
|
||||
int i;
|
||||
|
||||
if (c2 == SwapChunk)
|
||||
continue;
|
||||
sprintf(fname, "/dev/%s", c2->name);
|
||||
i = (Fake || swapon(fname));
|
||||
if (!i) {
|
||||
dlg_clear();
|
||||
msgNotify("Added %s as an additional swap device", fname);
|
||||
}
|
||||
else {
|
||||
msgConfirm("Unable to add %s as a swap device: %s", fname, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c1->type == fat && c1->private_data &&
|
||||
(root->do_newfs || upgrade)) {
|
||||
char name[FILENAME_MAX];
|
||||
|
||||
sprintf(name, "/%s", ((PartInfo *)c1->private_data)->mountpoint);
|
||||
Mkdir(name);
|
||||
}
|
||||
#if defined(__ia64__)
|
||||
else if (c1->type == efi && c1->private_data) {
|
||||
PartInfo *pi = (PartInfo *)c1->private_data;
|
||||
|
||||
sprintf(dname, "/dev/%s", c1->name);
|
||||
|
||||
if (pi->do_newfs && (!upgrade ||
|
||||
!msgNoYes("You are upgrading - are you SURE you want to "
|
||||
"newfs /dev/%s?", c1->name)))
|
||||
performNewfs(pi, dname, QUEUE_YES);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
command_sort();
|
||||
command_execute();
|
||||
dlg_clear();
|
||||
return DITEM_SUCCESS | DITEM_RESTORE;
|
||||
}
|
||||
|
||||
static char *
|
||||
getRelname(void)
|
||||
{
|
||||
static char buf[64];
|
||||
size_t sz = (sizeof buf) - 1;
|
||||
|
||||
if (sysctlbyname("kern.osrelease", buf, &sz, NULL, 0) != -1) {
|
||||
buf[sz] = '\0';
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
/* Initialize various user-settable values to their defaults */
|
||||
int
|
||||
installVarDefaults(dialogMenuItem *self)
|
||||
{
|
||||
|
||||
/* Set default startup options */
|
||||
variable_set2(VAR_RELNAME, getRelname(), 0);
|
||||
variable_set2(SYSTEM_STATE, "update", 0);
|
||||
variable_set2(VAR_NEWFS_ARGS, "-b 16384 -f 2048", 0);
|
||||
variable_set2(VAR_CONSTERM, "NO", 0);
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Load the environment up from various system configuration files */
|
||||
void
|
||||
installEnvironment(void)
|
||||
{
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1997 FreeBSD, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY PAUL TRAINA ``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 PAUL TRAINA OR HIS KILLER RATS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* The structure */
|
||||
typedef struct _qelement {
|
||||
struct _qelement *q_forw;
|
||||
struct _qelement *q_back;
|
||||
} qelement;
|
||||
|
||||
#define INITQUE(Xhead) { \
|
||||
(Xhead).q_forw = &(Xhead); \
|
||||
(Xhead).q_back = &(Xhead); \
|
||||
}
|
||||
|
||||
#define EMPTYQUE(Xhead) \
|
||||
((Xhead).q_forw == &(Xhead))
|
||||
|
||||
#define INSQUEUE(elem, pred) { \
|
||||
register qelement *Xe = (qelement *) (elem); \
|
||||
register qelement *Xp = (qelement *) (pred); \
|
||||
Xp->q_forw = (Xe->q_forw = (Xe->q_back = Xp)->q_forw)->q_back = Xe; \
|
||||
}
|
||||
|
||||
#define REMQUE(elem) { \
|
||||
register qelement *Xe = (qelement *) (elem); \
|
||||
(Xe->q_back->q_forw = Xe->q_forw)->q_back = Xe->q_back; \
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <sys/signal.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
const char *StartName; /* Initial contents of argv[0] */
|
||||
const char *ProgName = "sade";
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Record name to be able to restart */
|
||||
StartName = argv[0];
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* We don't work too well when running as non-root anymore */
|
||||
if (geteuid() != 0) {
|
||||
fprintf(stderr, "Error: This utility should only be run as root.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
{
|
||||
/* XXX */
|
||||
char *p = getenv("TERM");
|
||||
if (p && strcmp(p, "cons25") == 0)
|
||||
setenv("TERM", "cons25w", 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set up whatever things need setting up */
|
||||
systemInitialize(argc, argv);
|
||||
|
||||
/* Set default flag and variable values */
|
||||
installVarDefaults(NULL);
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-fake")) {
|
||||
variable_set2(VAR_DEBUG, "YES", 0);
|
||||
Fake = TRUE;
|
||||
msgConfirm("I'll be just faking it from here on out, OK?");
|
||||
}
|
||||
if (argc > 1 && !strcmp(argv[1], "-restart"))
|
||||
Restarting = TRUE;
|
||||
|
||||
/* Try to preserve our scroll-back buffer */
|
||||
if (OnVTY) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
putchar('\n');
|
||||
}
|
||||
/* Move stderr aside */
|
||||
if (DebugFD)
|
||||
dup2(DebugFD, 2);
|
||||
|
||||
/* Initialize driver modules, if we haven't already done so (ie,
|
||||
the user hit Ctrl-C -> Restart. */
|
||||
if (!pvariable_get("modulesInitialize")) {
|
||||
pvariable_set("modulesInitialize=1");
|
||||
}
|
||||
|
||||
/* Probe for all relevant devices on the system */
|
||||
deviceGetAll();
|
||||
|
||||
/* First, see if we have any arguments to process (and argv[0] counts if it's not "sysinstall") */
|
||||
|
||||
status = setjmp(BailOut);
|
||||
if (status) {
|
||||
msgConfirm("A signal %d was caught - I'm saving what I can and shutting\n"
|
||||
"down. If you can reproduce the problem, please turn Debug on\n"
|
||||
"in the Options menu for the extra information it provides\n"
|
||||
"in debugging problems like this.", status);
|
||||
;
|
||||
}
|
||||
|
||||
/* Begin user dialog at outer menu */
|
||||
dlg_clear();
|
||||
while (1) {
|
||||
dmenuOpen(&MenuMain);
|
||||
if (getpid() != 1
|
||||
|| !msgNoYes("Are you sure you wish to exit?")
|
||||
)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shut down curses */
|
||||
endwin();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/* All the system menus go here.
|
||||
*
|
||||
* Hardcoded things like version number strings will disappear from
|
||||
* these menus just as soon as I add the code for doing inline variable
|
||||
* expansion.
|
||||
*/
|
||||
|
||||
DMenu MenuDiskDevices = {
|
||||
DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
|
||||
"Select Drive(s)",
|
||||
"Please select the drive on which you wish to perform this\n"
|
||||
"operation. If you are attempting to install a boot partition\n"
|
||||
"on a drive other than the first one or have multiple operating\n"
|
||||
"systems on your machine, you will have the option to install a boot\n"
|
||||
"manager later. To select a drive, use the arrow keys to move to it\n"
|
||||
"and press [SPACE] or [ENTER].\n\n"
|
||||
"Use [TAB] to get to the buttons and leave this menu.",
|
||||
"Press F1 for important information regarding disk geometry!",
|
||||
"drives",
|
||||
{ { NULL, NULL, NULL } },
|
||||
};
|
||||
|
||||
DMenu MenuMain = {
|
||||
DMENU_NORMAL_TYPE,
|
||||
"Disklabel and partitioning utility",
|
||||
"This is a utility for partitioning and/or labelling your disks.",
|
||||
"DISKUTIL",
|
||||
"main",
|
||||
{
|
||||
#ifdef WITH_SLICES
|
||||
{ "1 Partition", "Managing disk partitions", diskPartitionEditor },
|
||||
#endif
|
||||
{ "2 Label", "Label allocated disk partitions", diskLabelEditor },
|
||||
{ NULL, NULL, NULL }
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
#ifdef PC98
|
||||
/* IPL type menu */
|
||||
DMenu MenuIPLType = {
|
||||
DMENU_RADIO_TYPE | DMENU_SELECTION_RETURNS,
|
||||
"overwrite me", /* will be disk specific label */
|
||||
"If you want a FreeBSD Boot Manager, select \"BootMgr\". If you would\n"
|
||||
"prefer your Boot Manager to remain untouched then select \"None\".\n\n",
|
||||
"Press F1 to read about drive setup",
|
||||
"drives",
|
||||
{ { "BootMgr", "Install the FreeBSD Boot Manager", NULL },
|
||||
{ "None", "Leave the IPL untouched", NULL },
|
||||
{ NULL, NULL, NULL } },
|
||||
};
|
||||
#else
|
||||
/* MBR type menu */
|
||||
DMenu MenuMBRType = {
|
||||
DMENU_RADIO_TYPE | DMENU_SELECTION_RETURNS,
|
||||
"overwrite me", /* will be disk specific label */
|
||||
"FreeBSD comes with a boot manager that allows you to easily\n"
|
||||
"select between FreeBSD and any other operating systems on your machine\n"
|
||||
"at boot time. If you have more than one drive and want to boot\n"
|
||||
"from the second one, the boot manager will also make it possible\n"
|
||||
"to do so (limitations in the PC BIOS usually prevent this otherwise).\n"
|
||||
"If you have other operating systems installed and would like a choice when\n"
|
||||
"booting, choose \"BootMgr\". If you would prefer to keep your existing\n"
|
||||
"boot manager, select \"None\".\n",
|
||||
"",
|
||||
"drives",
|
||||
{ { "Standard", "Install a standard MBR (non-interactive boot manager)", NULL },
|
||||
{ "BootMgr", "Install the FreeBSD boot manager", NULL },
|
||||
{ "None", "Do not install a boot manager", NULL },
|
||||
{ NULL, NULL, NULL } }
|
||||
};
|
||||
#endif /* PC98 */
|
||||
#endif /* __i386__ */
|
@ -1,426 +0,0 @@
|
||||
/*
|
||||
* Miscellaneous support routines..
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <fs/msdosfs/msdosfsmount.h>
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/* Quick check to see if a file is readable */
|
||||
Boolean
|
||||
file_readable(char *fname)
|
||||
{
|
||||
if (!access(fname, F_OK))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* sane strncpy() function */
|
||||
char *
|
||||
sstrncpy(char *dst, const char *src, int size)
|
||||
{
|
||||
dst[size] = '\0';
|
||||
return strncpy(dst, src, size);
|
||||
}
|
||||
|
||||
/* Clip the whitespace off the end of a string */
|
||||
char *
|
||||
string_prune(char *str)
|
||||
{
|
||||
int len = str ? strlen(str) : 0;
|
||||
|
||||
while (len && isspace(str[len - 1]))
|
||||
str[--len] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* run the whitespace off the front of a string */
|
||||
char *
|
||||
string_skipwhite(char *str)
|
||||
{
|
||||
while (*str && isspace(*str))
|
||||
++str;
|
||||
return str;
|
||||
}
|
||||
|
||||
Boolean
|
||||
directory_exists(const char *dirname)
|
||||
{
|
||||
DIR *tptr;
|
||||
|
||||
if (!dirname)
|
||||
return FALSE;
|
||||
if (!strlen(dirname))
|
||||
return FALSE;
|
||||
|
||||
tptr = opendir(dirname);
|
||||
if (!tptr)
|
||||
return (FALSE);
|
||||
|
||||
closedir(tptr);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* A free guaranteed to take NULL ptrs */
|
||||
void
|
||||
safe_free(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* A malloc that checks errors */
|
||||
void *
|
||||
safe_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if (size <= 0)
|
||||
msgFatal("Invalid malloc size of %ld!", (long)size);
|
||||
ptr = malloc(size);
|
||||
if (!ptr)
|
||||
msgFatal("Out of memory!");
|
||||
bzero(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int
|
||||
Mkdir(char *ipath)
|
||||
{
|
||||
struct stat sb;
|
||||
int final;
|
||||
char *p, *path;
|
||||
|
||||
if (file_readable(ipath) || Fake)
|
||||
return DITEM_SUCCESS;
|
||||
|
||||
path = strcpy(alloca(strlen(ipath) + 1), ipath);
|
||||
if (isDebug())
|
||||
msgDebug("mkdir(%s)\n", path);
|
||||
p = path;
|
||||
if (p[0] == '/') /* Skip leading '/'. */
|
||||
++p;
|
||||
for (final = FALSE; !final; ++p) {
|
||||
if (p[0] == '\0' || (p[0] == '/' && p[1] == '\0'))
|
||||
final = TRUE;
|
||||
else if (p[0] != '/')
|
||||
continue;
|
||||
*p = '\0';
|
||||
if (stat(path, &sb)) {
|
||||
if (errno != ENOENT) {
|
||||
msgConfirm("Couldn't stat directory %s: %s", path, strerror(errno));
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
if (isDebug())
|
||||
msgDebug("mkdir(%s..)\n", path);
|
||||
if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
|
||||
msgConfirm("Couldn't create directory %s: %s", path,strerror(errno));
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
}
|
||||
*p = '/';
|
||||
}
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Mount(char *mountp, void *dev)
|
||||
{
|
||||
struct ufs_args ufsargs;
|
||||
char device[80];
|
||||
char mountpoint[FILENAME_MAX];
|
||||
|
||||
if (Fake)
|
||||
return DITEM_SUCCESS;
|
||||
|
||||
if (*((char *)dev) != '/') {
|
||||
sprintf(device, "/dev/%s", (char *)dev);
|
||||
sprintf(mountpoint, "%s", mountp);
|
||||
}
|
||||
else {
|
||||
strcpy(device, dev);
|
||||
strcpy(mountpoint, mountp);
|
||||
}
|
||||
memset(&ufsargs,0,sizeof ufsargs);
|
||||
|
||||
if (Mkdir(mountpoint)) {
|
||||
msgConfirm("Unable to make directory mountpoint for %s!", mountpoint);
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
if (isDebug())
|
||||
msgDebug("mount %s %s\n", device, mountpoint);
|
||||
|
||||
ufsargs.fspec = device;
|
||||
if (mount("ufs", mountpoint, 0,
|
||||
(caddr_t)&ufsargs) == -1) {
|
||||
msgConfirm("Error mounting %s on %s : %s", device, mountpoint, strerror(errno));
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
WINDOW *
|
||||
savescr(void)
|
||||
{
|
||||
WINDOW *w;
|
||||
|
||||
w = dupwin(newscr);
|
||||
return w;
|
||||
}
|
||||
|
||||
void
|
||||
restorescr(WINDOW *w)
|
||||
{
|
||||
touchwin(w);
|
||||
wrefresh(w);
|
||||
delwin(w);
|
||||
}
|
||||
|
||||
static int
|
||||
xdialog_count_rows(const char *p)
|
||||
{
|
||||
int rows = 0;
|
||||
|
||||
while ((p = strchr(p, '\n')) != NULL) {
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
break;
|
||||
rows++;
|
||||
}
|
||||
|
||||
return rows ? rows : 1;
|
||||
}
|
||||
|
||||
static int
|
||||
xdialog_count_columns(const char *p)
|
||||
{
|
||||
int len;
|
||||
int max_len = 0;
|
||||
const char *q;
|
||||
|
||||
for (; (q = strchr(p, '\n')) != NULL; p = q + 1) {
|
||||
len = q - p;
|
||||
max_len = MAX(max_len, len);
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
max_len = MAX(max_len, len);
|
||||
return max_len;
|
||||
}
|
||||
|
||||
int
|
||||
xdialog_menu(const char *title, const char *cprompt, int height, int width,
|
||||
int menu_height, int item_no, dialogMenuItem *ditems)
|
||||
{
|
||||
int i, result, choice = 0;
|
||||
DIALOG_LISTITEM *listitems;
|
||||
DIALOG_VARS save_vars;
|
||||
|
||||
dlg_save_vars(&save_vars);
|
||||
|
||||
/* initialize list items */
|
||||
listitems = dlg_calloc(DIALOG_LISTITEM, item_no + 1);
|
||||
assert_ptr(listitems, "xdialog_menu");
|
||||
for (i = 0; i < item_no; i++) {
|
||||
listitems[i].name = ditems[i].prompt;
|
||||
listitems[i].text = ditems[i].title;
|
||||
}
|
||||
|
||||
/* calculate height */
|
||||
if (height < 0)
|
||||
height = xdialog_count_rows(cprompt) + menu_height + 4 + 2;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
|
||||
/* calculate width */
|
||||
if (width < 0) {
|
||||
int tag_x = 0;
|
||||
|
||||
for (i = 0; i < item_no; i++) {
|
||||
int j, l;
|
||||
|
||||
l = strlen(listitems[i].name);
|
||||
for (j = 0; j < item_no; j++) {
|
||||
int k = strlen(listitems[j].text);
|
||||
tag_x = MAX(tag_x, l + k + 2);
|
||||
}
|
||||
}
|
||||
width = MAX(xdialog_count_columns(cprompt), title != NULL ? xdialog_count_columns(title) : 0);
|
||||
width = MAX(width, tag_x + 4) + 4;
|
||||
}
|
||||
width = MAX(width, 24);
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
|
||||
/* show menu */
|
||||
dialog_vars.default_item = listitems[choice].name;
|
||||
result = dlg_menu(title, cprompt, height, width,
|
||||
menu_height, item_no, listitems, &choice, NULL);
|
||||
switch (result) {
|
||||
case DLG_EXIT_ESC:
|
||||
result = -1;
|
||||
break;
|
||||
case DLG_EXIT_OK:
|
||||
if (ditems[choice].fire != NULL) {
|
||||
int status;
|
||||
WINDOW *save;
|
||||
|
||||
save = savescr();
|
||||
status = ditems[choice].fire(ditems + choice);
|
||||
restorescr(save);
|
||||
}
|
||||
result = 0;
|
||||
break;
|
||||
case DLG_EXIT_CANCEL:
|
||||
default:
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
free(listitems);
|
||||
dlg_restore_vars(&save_vars);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
xdialog_radiolist(const char *title, const char *cprompt, int height, int width,
|
||||
int menu_height, int item_no, dialogMenuItem *ditems)
|
||||
{
|
||||
int i, result, choice = 0;
|
||||
DIALOG_LISTITEM *listitems;
|
||||
DIALOG_VARS save_vars;
|
||||
|
||||
dlg_save_vars(&save_vars);
|
||||
|
||||
/* initialize list items */
|
||||
listitems = dlg_calloc(DIALOG_LISTITEM, item_no + 1);
|
||||
assert_ptr(listitems, "xdialog_menu");
|
||||
for (i = 0; i < item_no; i++) {
|
||||
listitems[i].name = ditems[i].prompt;
|
||||
listitems[i].text = ditems[i].title;
|
||||
listitems[i].state = i == choice;
|
||||
}
|
||||
|
||||
/* calculate height */
|
||||
if (height < 0)
|
||||
height = xdialog_count_rows(cprompt) + menu_height + 4 + 2;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
|
||||
/* calculate width */
|
||||
if (width < 0) {
|
||||
int check_x = 0;
|
||||
|
||||
for (i = 0; i < item_no; i++) {
|
||||
int j, l;
|
||||
|
||||
l = strlen(listitems[i].name);
|
||||
for (j = 0; j < item_no; j++) {
|
||||
int k = strlen(listitems[j].text);
|
||||
check_x = MAX(check_x, l + k + 6);
|
||||
}
|
||||
}
|
||||
width = MAX(xdialog_count_columns(cprompt), title != NULL ? xdialog_count_columns(title) : 0);
|
||||
width = MAX(width, check_x + 4) + 4;
|
||||
}
|
||||
width = MAX(width, 24);
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
|
||||
/* show menu */
|
||||
dialog_vars.default_item = listitems[choice].name;
|
||||
result = dlg_checklist(title, cprompt, height, width,
|
||||
menu_height, item_no, listitems, NULL, FLAG_RADIO, &choice);
|
||||
switch (result) {
|
||||
case DLG_EXIT_ESC:
|
||||
result = -1;
|
||||
break;
|
||||
case DLG_EXIT_OK:
|
||||
if (ditems[choice].fire != NULL) {
|
||||
int status;
|
||||
WINDOW *save;
|
||||
|
||||
save = savescr();
|
||||
status = ditems[choice].fire(ditems + choice);
|
||||
restorescr(save);
|
||||
}
|
||||
result = 0;
|
||||
break;
|
||||
case DLG_EXIT_CANCEL:
|
||||
default:
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* save result */
|
||||
if (result == 0)
|
||||
dlg_add_result(listitems[choice].name);
|
||||
free(listitems);
|
||||
dlg_restore_vars(&save_vars);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
xdialog_msgbox(const char *title, const char *cprompt,
|
||||
int height, int width, int pauseopt)
|
||||
{
|
||||
/* calculate height */
|
||||
if (height < 0)
|
||||
height = 2 + xdialog_count_rows(cprompt) + 2 + !!pauseopt;
|
||||
if (height > LINES)
|
||||
height = LINES;
|
||||
|
||||
/* calculate width */
|
||||
if (width < 0) {
|
||||
width = title != NULL ? xdialog_count_columns(title) : 0;
|
||||
width = MAX(width, xdialog_count_columns(cprompt)) + 4;
|
||||
}
|
||||
if (pauseopt)
|
||||
width = MAX(width, 10);
|
||||
if (width > COLS)
|
||||
width = COLS;
|
||||
|
||||
return dialog_msgbox(title, cprompt, height, width, pauseopt);
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <stdarg.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/consio.h>
|
||||
|
||||
Boolean
|
||||
isDebug(void)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
return (cp = variable_get(VAR_DEBUG)) && strcmp(cp, "no");
|
||||
}
|
||||
|
||||
/* Whack up an informational message on the status line, in stand-out */
|
||||
void
|
||||
msgYap(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int attrs;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
attrs = getattrs(stdscr);
|
||||
attrset(A_REVERSE);
|
||||
mvaddstr(StatusLine, 0, errstr);
|
||||
attrset(attrs);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/* Whack up an informational message on the status line */
|
||||
void
|
||||
msgInfo(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int i, attrs;
|
||||
char line[81];
|
||||
|
||||
attrs = getattrs(stdscr);
|
||||
/* NULL is a special convention meaning "erase the old stuff" */
|
||||
if (!fmt) {
|
||||
move(StatusLine, 0);
|
||||
clrtoeol();
|
||||
return;
|
||||
}
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
memset(line, ' ', 80);
|
||||
for (i = 0; i < 80; i++) {
|
||||
if (errstr[i])
|
||||
line[i] = errstr[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
line[80] = '\0';
|
||||
attrset(ATTR_TITLE);
|
||||
mvaddstr(StatusLine, 0, line);
|
||||
attrset(attrs);
|
||||
move(StatusLine, 79);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/* Whack up a warning on the status line */
|
||||
void
|
||||
msgWarn(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int attrs;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
strcpy(errstr, "Warning: ");
|
||||
va_start(args, fmt);
|
||||
vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
attrs = getattrs(stdscr);
|
||||
beep();
|
||||
attrset(ATTR_TITLE);
|
||||
mvaddstr(StatusLine, 0, errstr);
|
||||
attrset(attrs);
|
||||
refresh();
|
||||
if (OnVTY && isDebug())
|
||||
msgDebug("Warning message `%s'\n", errstr);
|
||||
}
|
||||
|
||||
/* Whack up an error on the status line */
|
||||
void
|
||||
msgError(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int attrs;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
strcpy(errstr, "Error: ");
|
||||
va_start(args, fmt);
|
||||
vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
beep();
|
||||
attrs = getattrs(stdscr);
|
||||
attrset(ATTR_TITLE);
|
||||
mvaddstr(StatusLine, 0, errstr);
|
||||
attrset(attrs);
|
||||
refresh();
|
||||
if (OnVTY && isDebug())
|
||||
msgDebug("Error message `%s'\n", errstr);
|
||||
}
|
||||
|
||||
/* Whack up a fatal error on the status line */
|
||||
void
|
||||
msgFatal(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int attrs;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
strcpy(errstr, "Fatal Error: ");
|
||||
va_start(args, fmt);
|
||||
vsnprintf((char *)(errstr + strlen(errstr)), FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
beep();
|
||||
attrs = getattrs(stdscr);
|
||||
attrset(ATTR_TITLE);
|
||||
mvaddstr(StatusLine, 0, errstr);
|
||||
addstr(" - ");
|
||||
addstr("PRESS ANY KEY TO ");
|
||||
if (getpid() == 1)
|
||||
addstr("REBOOT");
|
||||
else
|
||||
addstr("QUIT");
|
||||
attrset(attrs);
|
||||
refresh();
|
||||
if (OnVTY)
|
||||
msgDebug("Fatal error `%s'!\n", errstr);
|
||||
getch();
|
||||
}
|
||||
|
||||
/* Put up a message in a popup confirmation box */
|
||||
void
|
||||
msgConfirm(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (OnVTY) {
|
||||
ioctl(0, VT_ACTIVATE, 1);
|
||||
msgInfo(NULL);
|
||||
}
|
||||
dialog_vars.help_line = "Press Enter or Space";
|
||||
xdialog_msgbox("Message", errstr, -1, -1, 1);
|
||||
dialog_vars.help_line = NULL;
|
||||
|
||||
restorescr(w);
|
||||
}
|
||||
|
||||
/* Put up a message in a popup information box */
|
||||
void
|
||||
msgNotify(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (isDebug())
|
||||
msgDebug("Notify: %s\n", errstr);
|
||||
xdialog_msgbox(NULL, errstr, -1, -1, 0);
|
||||
}
|
||||
|
||||
/* Put up a message in a popup yes/no box and return 0 for YES, 1 for NO */
|
||||
int
|
||||
msgYesNo(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int ret;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (OnVTY) {
|
||||
ioctl(0, VT_ACTIVATE, 1); /* Switch back */
|
||||
msgInfo(NULL);
|
||||
}
|
||||
if (variable_get(VAR_NONINTERACTIVE))
|
||||
return 0; /* If non-interactive, return YES all the time */
|
||||
ret = dialog_yesno("User Confirmation Requested", errstr, -1, -1);
|
||||
restorescr(w);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Put up a message in a popup no/yes box and return 0 for YES, 1 for NO */
|
||||
int
|
||||
msgNoYes(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
int ret;
|
||||
WINDOW *w = savescr();
|
||||
DIALOG_VARS save_vars;
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (OnVTY) {
|
||||
ioctl(0, VT_ACTIVATE, 1); /* Switch back */
|
||||
msgInfo(NULL);
|
||||
}
|
||||
if (variable_get(VAR_NONINTERACTIVE))
|
||||
return 1; /* If non-interactive, return NO all the time */
|
||||
dlg_save_vars(&save_vars);
|
||||
dialog_vars.defaultno = TRUE;
|
||||
ret = dialog_yesno("User Confirmation Requested", errstr, -1, -1);
|
||||
dlg_restore_vars(&save_vars);
|
||||
restorescr(w);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Put up a message in an input box and return the value */
|
||||
char *
|
||||
msgGetInput(char *buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
static char input_buffer[256];
|
||||
int rval;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (buf)
|
||||
SAFE_STRCPY(input_buffer, buf);
|
||||
else
|
||||
input_buffer[0] = '\0';
|
||||
if (OnVTY) {
|
||||
ioctl(0, VT_ACTIVATE, 1); /* Switch back */
|
||||
msgInfo(NULL);
|
||||
}
|
||||
rval = dialog_inputbox("Value Required", errstr, -1, -1, input_buffer, 0);
|
||||
restorescr(w);
|
||||
if (!rval)
|
||||
return dialog_vars.input_result;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Write something to the debugging port */
|
||||
void
|
||||
msgDebug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *dbg;
|
||||
|
||||
if (DebugFD == -1)
|
||||
return;
|
||||
dbg = (char *)alloca(FILENAME_MAX);
|
||||
strcpy(dbg, "DEBUG: ");
|
||||
va_start(args, fmt);
|
||||
vsnprintf((char *)(dbg + strlen(dbg)), FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
write(DebugFD, dbg, strlen(dbg));
|
||||
}
|
||||
|
||||
/* Tell the user there's some output to go look at */
|
||||
void
|
||||
msgWeHaveOutput(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *errstr;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
errstr = (char *)alloca(FILENAME_MAX);
|
||||
va_start(args, fmt);
|
||||
vsnprintf(errstr, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
msgDebug("Notify: %s\n", errstr);
|
||||
dlg_clear();
|
||||
sleep(2);
|
||||
xdialog_msgbox(NULL, errstr, -1, -1, 0);
|
||||
restorescr(w);
|
||||
}
|
||||
|
||||
/* Simple versions of msgConfirm() and msgNotify() for calling from scripts */
|
||||
int
|
||||
msgSimpleConfirm(const char *str)
|
||||
{
|
||||
msgConfirm("%s", str);
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
msgSimpleNotify(const char *str)
|
||||
{
|
||||
msgNotify("%s", str);
|
||||
return DITEM_SUCCESS;
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
.\" Copyright (c) 1997
|
||||
.\" Jordan Hubbard <jkh@FreeBSD.org>. All rights reserved.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY Jordan Hubbard AND CONTRIBUTORS ``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 Jordan Hubbard OR CONTRIBUTORS 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 8, 2006
|
||||
.Dt SADE 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sade
|
||||
.Nd sysadmins disk editor
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is used for various disk administration tasks on
|
||||
.Fx
|
||||
systems.
|
||||
.Pp
|
||||
It is generally invoked without arguments for the default
|
||||
behavior, where the main menu is presented.
|
||||
.Sh NOTES
|
||||
The
|
||||
.Nm
|
||||
utility aims to provide a handy tool for disk management
|
||||
tasks on an already installed system.
|
||||
The goal is to save
|
||||
some of the useful functionality of the old
|
||||
.Xr sysinstall 8
|
||||
which
|
||||
will be removed from the system in favor of the new installer.
|
||||
.Sh SEE ALSO
|
||||
.Xr sysinstall 8
|
||||
.Sh HISTORY
|
||||
This version of
|
||||
.Nm
|
||||
first appeared in
|
||||
.Fx 6.3 .
|
||||
The code is extracted from the
|
||||
.Xr sysinstall 8
|
||||
utility.
|
||||
.Sh AUTHORS
|
||||
.An Jordan K. Hubbard Aq jkh@FreeBSD.org
|
||||
.Sh BUGS
|
||||
The utility misses a lot of nice features, such as tools for
|
||||
manipulating
|
||||
.Xr gmirror 8
|
||||
or
|
||||
.Xr gvinum 8
|
||||
stuff.
|
||||
These will be added later.
|
@ -1,465 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SADE_H_INCLUDE
|
||||
#define _SADE_H_INCLUDE
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dialog.h>
|
||||
|
||||
/*** Defines ***/
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
#define WITH_SYSCONS
|
||||
#define WITH_MICE
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
#define WITH_SLICES
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
#define WITH_LINUX
|
||||
#endif
|
||||
|
||||
/* device limits */
|
||||
#define DEV_NAME_MAX 128 /* The maximum length of a device name */
|
||||
#define DEV_MAX 100 /* The maximum number of devices we'll deal with */
|
||||
#define IO_ERROR -2 /* Status code for I/O error rather than normal EOF */
|
||||
|
||||
/*
|
||||
* I make some pretty gross assumptions about having a max of 50 chunks
|
||||
* total - 8 slices and 42 partitions. I can't easily display many more
|
||||
* than that on the screen at once!
|
||||
*
|
||||
* For 2.1 I'll revisit this and try to make it more dynamic, but since
|
||||
* this will catch 99.99% of all possible cases, I'm not too worried.
|
||||
*/
|
||||
#define MAX_CHUNKS 40
|
||||
|
||||
/* Internal environment variable names */
|
||||
#define DISK_PARTITIONED "_diskPartitioned"
|
||||
#define DISK_LABELLED "_diskLabelled"
|
||||
#define DISK_SELECTED "_diskSelected"
|
||||
#define SYSTEM_STATE "_systemState"
|
||||
#define RUNNING_ON_ROOT "_runningOnRoot"
|
||||
|
||||
/* Ones that can be tweaked from config files */
|
||||
#define VAR_BLANKTIME "blanktime"
|
||||
#define VAR_BOOTMGR "bootManager"
|
||||
#define VAR_DEBUG "debug"
|
||||
#define VAR_DISK "disk"
|
||||
#define VAR_DISKINTERACTIVE "diskInteractive"
|
||||
#define VAR_DEDICATE_DISK "dedicateDisk"
|
||||
#define VAR_COMMAND "command"
|
||||
#define VAR_CONFIG_FILE "configFile"
|
||||
#define VAR_GEOMETRY "geometry"
|
||||
#define VAR_INSTALL_CFG "installConfig"
|
||||
#define VAR_INSTALL_ROOT "installRoot"
|
||||
#define VAR_LABEL "label"
|
||||
#define VAR_LABEL_COUNT "labelCount"
|
||||
#define VAR_NEWFS_ARGS "newfsArgs"
|
||||
#define VAR_NO_CONFIRM "noConfirm"
|
||||
#define VAR_NO_ERROR "noError"
|
||||
#define VAR_NO_WARN "noWarn"
|
||||
#define VAR_NO_USR "noUsr"
|
||||
#define VAR_NO_TMP "noTmp"
|
||||
#define VAR_NO_HOME "noHome"
|
||||
#define VAR_NONINTERACTIVE "nonInteractive"
|
||||
#define VAR_PARTITION "partition"
|
||||
#define VAR_RELNAME "releaseName"
|
||||
#define VAR_ROOT_SIZE "rootSize"
|
||||
#define VAR_SWAP_SIZE "swapSize"
|
||||
#define VAR_TAPE_BLOCKSIZE "tapeBlocksize"
|
||||
#define VAR_UFS_PATH "ufs"
|
||||
#define VAR_USR_SIZE "usrSize"
|
||||
#define VAR_VAR_SIZE "varSize"
|
||||
#define VAR_TMP_SIZE "tmpSize"
|
||||
#define VAR_TERM "TERM"
|
||||
#define VAR_CONSTERM "_consterm"
|
||||
|
||||
#define DEFAULT_TAPE_BLOCKSIZE "20"
|
||||
|
||||
/* One MB worth of blocks */
|
||||
#define ONE_MEG 2048
|
||||
#define ONE_GIG (ONE_MEG * 1024)
|
||||
|
||||
/* Which selection attributes to use */
|
||||
#define ATTR_SELECTED (ColorDisplay ? item_selected_attr : item_attr)
|
||||
#define ATTR_TITLE button_active_attr
|
||||
|
||||
/* Handy strncpy() macro */
|
||||
#define SAFE_STRCPY(to, from) sstrncpy((to), (from), sizeof (to) - 1)
|
||||
|
||||
/*** Types ***/
|
||||
typedef int Boolean;
|
||||
typedef struct disk Disk;
|
||||
typedef struct chunk Chunk;
|
||||
|
||||
/* special return codes for `fire' actions */
|
||||
#define DITEM_STATUS(flag) ((flag) & 0x0000FFFF)
|
||||
#define DITEM_SUCCESS 0
|
||||
#define DITEM_FAILURE 1
|
||||
|
||||
/* flags - returned in upper 16 bits of return status */
|
||||
#define DITEM_LEAVE_MENU (1 << 16)
|
||||
#define DITEM_RESTORE (1 << 19)
|
||||
|
||||
/* for use in describing more exotic behaviors */
|
||||
typedef struct _dmenu_item {
|
||||
char *prompt;
|
||||
char *title;
|
||||
int (*fire)(struct _dmenu_item *self);
|
||||
} dialogMenuItem;
|
||||
|
||||
/* Bitfields for menu options */
|
||||
#define DMENU_NORMAL_TYPE 0x1 /* Normal dialog menu */
|
||||
#define DMENU_RADIO_TYPE 0x2 /* Radio dialog menu */
|
||||
#define DMENU_SELECTION_RETURNS 0x8 /* Immediate return on item selection */
|
||||
|
||||
typedef struct _dmenu {
|
||||
int type; /* What sort of menu we are */
|
||||
char *title; /* Our title */
|
||||
char *prompt; /* Our prompt */
|
||||
char *helpline; /* Line of help at bottom */
|
||||
char *helpfile; /* Help file for "F1" */
|
||||
dialogMenuItem items[]; /* Array of menu items */
|
||||
} DMenu;
|
||||
|
||||
/* An rc.conf variable */
|
||||
typedef struct _variable {
|
||||
struct _variable *next;
|
||||
char *name;
|
||||
char *value;
|
||||
int dirty;
|
||||
} Variable;
|
||||
|
||||
#define NO_ECHO_OBJ(type) ((type) | (DITEM_NO_ECHO << 16))
|
||||
#define TYPE_OF_OBJ(type) ((type) & 0xff)
|
||||
#define ATTR_OF_OBJ(type) ((type) >> 16)
|
||||
|
||||
/* A screen layout structure */
|
||||
typedef struct _layout {
|
||||
int y; /* x & Y co-ordinates */
|
||||
int x;
|
||||
int len; /* The size of the dialog on the screen */
|
||||
int maxlen; /* How much the user can type in ... */
|
||||
char *prompt; /* The string for the prompt */
|
||||
char *help; /* The display for the help line */
|
||||
void *var; /* The var to set when this changes */
|
||||
int type; /* The type of the dialog to create */
|
||||
void *obj; /* The obj pointer returned by libdialog */
|
||||
} Layout;
|
||||
|
||||
typedef enum {
|
||||
DEVICE_TYPE_NONE,
|
||||
DEVICE_TYPE_DISK,
|
||||
DEVICE_TYPE_DOS,
|
||||
DEVICE_TYPE_UFS,
|
||||
DEVICE_TYPE_ANY,
|
||||
} DeviceType;
|
||||
|
||||
/* A "device" from sade's point of view */
|
||||
typedef struct _device {
|
||||
char name[DEV_NAME_MAX];
|
||||
char *description;
|
||||
char *devname;
|
||||
DeviceType type;
|
||||
Boolean (*init)(struct _device *dev);
|
||||
FILE * (*get)(struct _device *dev, char *file, Boolean probe);
|
||||
void (*shutdown)(struct _device *dev);
|
||||
void *private;
|
||||
unsigned int flags;
|
||||
unsigned int volume;
|
||||
} Device;
|
||||
|
||||
/* Some internal representations of partitions */
|
||||
typedef enum {
|
||||
PART_NONE,
|
||||
PART_SLICE,
|
||||
PART_SWAP,
|
||||
PART_FILESYSTEM,
|
||||
PART_FAT,
|
||||
PART_EFI
|
||||
} PartType;
|
||||
|
||||
#define NEWFS_UFS_CMD "newfs"
|
||||
#define NEWFS_MSDOS_CMD "newfs_msdos"
|
||||
|
||||
enum newfs_type { NEWFS_UFS, NEWFS_MSDOS, NEWFS_CUSTOM };
|
||||
#define NEWFS_UFS_STRING "UFS"
|
||||
#define NEWFS_MSDOS_STRING "FAT"
|
||||
#define NEWFS_CUSTOM_STRING "CST"
|
||||
|
||||
/* The longest set of custom command line arguments we'll pass. */
|
||||
#define NEWFS_CMD_ARGS_MAX 256
|
||||
|
||||
typedef struct _part_info {
|
||||
char mountpoint[FILENAME_MAX];
|
||||
|
||||
/* Is invocation of newfs desired? */
|
||||
Boolean do_newfs;
|
||||
|
||||
enum newfs_type newfs_type;
|
||||
union {
|
||||
struct {
|
||||
char user_options[NEWFS_CMD_ARGS_MAX];
|
||||
Boolean acls; /* unused */
|
||||
Boolean multilabel; /* unused */
|
||||
Boolean softupdates;
|
||||
Boolean ufs1;
|
||||
} newfs_ufs;
|
||||
struct {
|
||||
/* unused */
|
||||
} newfs_msdos;
|
||||
struct {
|
||||
char command[NEWFS_CMD_ARGS_MAX];
|
||||
} newfs_custom;
|
||||
} newfs_data;
|
||||
} PartInfo;
|
||||
|
||||
/* An option */
|
||||
typedef struct _opt {
|
||||
char *name;
|
||||
char *desc;
|
||||
enum { OPT_IS_STRING, OPT_IS_INT, OPT_IS_FUNC, OPT_IS_VAR } type;
|
||||
void *data;
|
||||
void *aux;
|
||||
char *(*check)(void);
|
||||
} Option;
|
||||
|
||||
typedef int (*commandFunc)(char *key, void *data);
|
||||
|
||||
#define EXTRAS_FIELD_LEN 128
|
||||
|
||||
/*** Externs ***/
|
||||
extern jmp_buf BailOut; /* Used to get the heck out */
|
||||
extern int DebugFD; /* Where diagnostic output goes */
|
||||
extern Boolean Fake; /* Don't actually modify anything - testing */
|
||||
extern Boolean Restarting; /* Are we restarting sysinstall? */
|
||||
extern Boolean SystemWasInstalled; /* Did we install it? */
|
||||
extern Boolean RunningAsInit; /* Are we running stand-alone? */
|
||||
extern Boolean DialogActive; /* Is the dialog() stuff up? */
|
||||
extern Boolean ColorDisplay; /* Are we on a color display? */
|
||||
extern Boolean OnVTY; /* On a syscons VTY? */
|
||||
extern Variable *VarHead; /* The head of the variable chain */
|
||||
extern int BootMgr; /* Which boot manager to use */
|
||||
extern int StatusLine; /* Where to print our status messages */
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
#ifdef PC98
|
||||
extern DMenu MenuIPLType; /* Type of IPL to write on the disk */
|
||||
#else
|
||||
extern DMenu MenuMBRType; /* Type of MBR to write on the disk */
|
||||
#endif
|
||||
#endif
|
||||
extern DMenu MenuMain; /* New main menu */
|
||||
extern DMenu MenuDiskDevices; /* Disk type devices */
|
||||
extern const char * StartName; /* Which name we were started as */
|
||||
extern const char * ProgName; /* Program's proper name */
|
||||
|
||||
/* Important chunks. */
|
||||
extern Chunk *HomeChunk;
|
||||
extern Chunk *RootChunk;
|
||||
extern Chunk *SwapChunk;
|
||||
extern Chunk *TmpChunk;
|
||||
extern Chunk *UsrChunk;
|
||||
extern Chunk *VarChunk;
|
||||
#ifdef __ia64__
|
||||
extern Chunk *EfiChunk;
|
||||
#endif
|
||||
|
||||
/* Stuff from libdialog which isn't properly declared outside */
|
||||
extern void display_helpfile(void);
|
||||
extern void display_helpline(WINDOW *w, int y, int width);
|
||||
|
||||
/*** Prototypes ***/
|
||||
|
||||
/* command.c */
|
||||
extern void command_clear(void);
|
||||
extern void command_sort(void);
|
||||
extern void command_execute(void);
|
||||
extern void command_shell_add(char *key, const char *fmt, ...) __printflike(2, 3);
|
||||
extern void command_func_add(char *key, commandFunc func, void *data);
|
||||
|
||||
/* devices.c */
|
||||
extern DMenu *deviceCreateMenu(DMenu *menu, DeviceType type, int (*hook)(dialogMenuItem *d));
|
||||
extern void deviceGetAll(void);
|
||||
extern void deviceReset(void);
|
||||
extern void deviceRescan(void);
|
||||
extern Device **deviceFind(char *name, DeviceType type);
|
||||
extern Device **deviceFindDescr(char *name, char *desc, DeviceType class);
|
||||
extern int deviceCount(Device **devs);
|
||||
extern Device *new_device(char *name);
|
||||
extern Device *deviceRegister(char *name, char *desc, char *devicename, DeviceType type,
|
||||
Boolean (*init)(Device *mediadev),
|
||||
FILE * (*get)(Device *dev, char *file, Boolean probe),
|
||||
void (*shutDown)(Device *mediadev),
|
||||
void *private);
|
||||
extern Boolean dummyInit(Device *dev);
|
||||
extern FILE *dummyGet(Device *dev, char *dist, Boolean probe);
|
||||
extern void dummyShutdown(Device *dev);
|
||||
|
||||
/* disks.c */
|
||||
#ifdef WITH_SLICES
|
||||
extern void diskPartition(Device *dev);
|
||||
extern int diskPartitionEditor(dialogMenuItem *self);
|
||||
#endif
|
||||
extern int diskPartitionWrite(Device *dev);
|
||||
|
||||
/* dispatch.c */
|
||||
extern int dispatchCommand(char *command);
|
||||
extern int dispatch_load_floppy(dialogMenuItem *self);
|
||||
extern int dispatch_load_file_int(int);
|
||||
extern int dispatch_load_file(dialogMenuItem *self);
|
||||
|
||||
/* dmenu.c */
|
||||
extern int dmenuSetValue(dialogMenuItem *tmp);
|
||||
extern Boolean dmenuOpen(DMenu *menu);
|
||||
extern int dmenuRadioCheck(dialogMenuItem *item);
|
||||
|
||||
/* dos.c */
|
||||
extern Boolean mediaCloseDOS(Device *dev, FILE *fp);
|
||||
extern Boolean mediaInitDOS(Device *dev);
|
||||
extern FILE *mediaGetDOS(Device *dev, char *file, Boolean probe);
|
||||
extern void mediaShutdownDOS(Device *dev);
|
||||
|
||||
/* globals.c */
|
||||
extern void globalsInit(void);
|
||||
|
||||
/* install.c */
|
||||
extern Boolean checkLabels(Boolean whinge);
|
||||
extern int installCommit(dialogMenuItem *self);
|
||||
extern int installCustomCommit(dialogMenuItem *self);
|
||||
extern int installFilesystems(Device *dev);
|
||||
extern int installVarDefaults(dialogMenuItem *self);
|
||||
extern void installEnvironment(void);
|
||||
extern Boolean copySelf(void);
|
||||
|
||||
/* kget.c */
|
||||
extern int kget(char *out);
|
||||
|
||||
/* label.c */
|
||||
extern int diskLabelEditor(dialogMenuItem *self);
|
||||
extern int diskLabelCommit(Device *dev);
|
||||
|
||||
/* misc.c */
|
||||
extern Boolean file_readable(char *fname);
|
||||
extern Boolean directory_exists(const char *dirname);
|
||||
extern char *string_prune(char *str);
|
||||
extern char *string_skipwhite(char *str);
|
||||
extern void safe_free(void *ptr);
|
||||
extern void *safe_malloc(size_t size);
|
||||
extern int Mkdir(char *);
|
||||
extern int Mount(char *, void *data);
|
||||
|
||||
extern WINDOW *savescr(void);
|
||||
extern void restorescr(WINDOW *w);
|
||||
extern char *sstrncpy(char *dst, const char *src, int size);
|
||||
|
||||
extern int xdialog_menu(const char *title, const char *cprompt,
|
||||
int height, int width, int menu_height,
|
||||
int item_no, dialogMenuItem *ditems);
|
||||
extern int xdialog_radiolist(const char *title, const char *cprompt,
|
||||
int height, int width, int menu_height,
|
||||
int item_no, dialogMenuItem *ditems);
|
||||
extern int xdialog_msgbox(const char *title, const char *cprompt,
|
||||
int height, int width, int pauseopt);
|
||||
|
||||
/* msg.c */
|
||||
extern Boolean isDebug(void);
|
||||
extern void msgInfo(const char *fmt, ...) __printf0like(1, 2);
|
||||
extern void msgYap(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgWarn(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgDebug(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgError(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgFatal(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgConfirm(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgNotify(const char *fmt, ...) __printflike(1, 2);
|
||||
extern void msgWeHaveOutput(const char *fmt, ...) __printflike(1, 2);
|
||||
extern int msgYesNo(const char *fmt, ...) __printflike(1, 2);
|
||||
extern int msgNoYes(const char *fmt, ...) __printflike(1, 2);
|
||||
extern char *msgGetInput(char *buf, const char *fmt, ...) __printflike(2, 3);
|
||||
extern int msgSimpleConfirm(const char *);
|
||||
extern int msgSimpleNotify(const char *);
|
||||
|
||||
/* pccard.c */
|
||||
extern void pccardInitialize(void);
|
||||
|
||||
/* system.c */
|
||||
extern void systemInitialize(int argc, char **argv);
|
||||
extern void systemShutdown(int status);
|
||||
extern int execExecute(char *cmd, char *name);
|
||||
extern int systemExecute(char *cmd);
|
||||
extern void systemSuspendDialog(void);
|
||||
extern void systemResumeDialog(void);
|
||||
extern int systemDisplayHelp(char *file);
|
||||
extern char *systemHelpFile(char *file, char *buf);
|
||||
extern void systemChangeFont(const u_char font[]);
|
||||
extern void systemChangeLang(char *lang);
|
||||
extern void systemChangeTerminal(char *color, const u_char c_termcap[], char *mono, const u_char m_termcap[]);
|
||||
extern void systemChangeScreenmap(const u_char newmap[]);
|
||||
extern int vsystem(const char *fmt, ...) __printflike(1, 2);
|
||||
|
||||
/* termcap.c */
|
||||
extern int set_termcap(void);
|
||||
|
||||
/* variable.c */
|
||||
extern void variable_set(char *var, int dirty);
|
||||
extern void variable_set2(char *name, char *value, int dirty);
|
||||
extern char *variable_get(char *var);
|
||||
extern int variable_cmp(char *var, char *value);
|
||||
extern void variable_unset(char *var);
|
||||
extern char *variable_get_value(char *var, char *prompt, int dirty);
|
||||
extern int variable_check(char *data);
|
||||
extern int variable_check2(char *data);
|
||||
extern int dump_variables(dialogMenuItem *self);
|
||||
extern void free_variables(void);
|
||||
extern void pvariable_set(char *var);
|
||||
extern char *pvariable_get(char *var);
|
||||
|
||||
/* wizard.c */
|
||||
extern void slice_wizard(Disk *d);
|
||||
|
||||
/*
|
||||
* Macros. Please find a better place for us!
|
||||
*/
|
||||
#define DEVICE_INIT(d) ((d) != NULL ? (d)->init((d)) : (Boolean)0)
|
||||
#define DEVICE_GET(d, b, f) ((d) != NULL ? (d)->get((d), (b), (f)) : NULL)
|
||||
#define DEVICE_SHUTDOWN(d) ((d) != NULL ? (d)->shutdown((d)) : (void)0)
|
||||
|
||||
#endif
|
||||
/* _SYSINSTALL_H_INCLUDE */
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Jordan Hubbard
|
||||
*
|
||||
* My contributions are in the public domain.
|
||||
*
|
||||
* Parts of this file are also blatently stolen from Poul-Henning Kamp's
|
||||
* previous version of sysinstall, and as such fall under his "BEERWARE license"
|
||||
* so buy him a beer if you like it! Buy him a beer for me, too!
|
||||
* Heck, get him completely drunk and send me pictures! :-)
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/* Where we stick our temporary expanded doc file */
|
||||
#define DOC_TMP_DIR "/tmp/.doc"
|
||||
#define DOC_TMP_FILE "/tmp/.doc/doc.tmp"
|
||||
|
||||
/*
|
||||
* Handle interrupt signals - this probably won't work in all cases
|
||||
* due to our having bogotified the internal state of dialog or curses,
|
||||
* but we'll give it a try.
|
||||
*/
|
||||
static int
|
||||
intr_continue(dialogMenuItem *self)
|
||||
{
|
||||
return DITEM_LEAVE_MENU;
|
||||
}
|
||||
|
||||
static int
|
||||
intr_restart(dialogMenuItem *self)
|
||||
{
|
||||
int ret, fd, fdmax;
|
||||
|
||||
free_variables();
|
||||
fdmax = getdtablesize();
|
||||
for (fd = 3; fd < fdmax; fd++)
|
||||
close(fd);
|
||||
ret = execl(StartName, StartName, "-restart", (char *)NULL);
|
||||
msgDebug("execl failed (%s)\n", strerror(errno));
|
||||
/* NOTREACHED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static dialogMenuItem intrmenu[] = {
|
||||
{ "Restart", "Restart the program", intr_restart },
|
||||
{ "Continue", "Continue without restarting", intr_continue },
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
handle_intr(int sig)
|
||||
{
|
||||
WINDOW *save = savescr();
|
||||
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
if (OnVTY) {
|
||||
ioctl(0, VT_ACTIVATE, 1); /* Switch back */
|
||||
msgInfo(NULL);
|
||||
}
|
||||
(void)xdialog_menu("Installation interrupt",
|
||||
"Do you want to abort the installation?",
|
||||
-1, -1, 2, 2, intrmenu);
|
||||
restorescr(save);
|
||||
}
|
||||
|
||||
/* Expand a file into a convenient location, nuking it each time */
|
||||
static char *
|
||||
expand(char *fname)
|
||||
{
|
||||
char *gunzip = "/usr/bin/gunzip";
|
||||
|
||||
if (!directory_exists(DOC_TMP_DIR)) {
|
||||
Mkdir(DOC_TMP_DIR);
|
||||
if (chown(DOC_TMP_DIR, 0, 0) < 0)
|
||||
return NULL;
|
||||
if (chmod(DOC_TMP_DIR, S_IRWXU) < 0)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
unlink(DOC_TMP_FILE);
|
||||
if (!file_readable(fname) || vsystem("%s < %s > %s", gunzip, fname, DOC_TMP_FILE))
|
||||
return NULL;
|
||||
return DOC_TMP_FILE;
|
||||
}
|
||||
|
||||
/* Initialize system defaults */
|
||||
void
|
||||
systemInitialize(int argc, char **argv)
|
||||
{
|
||||
size_t i;
|
||||
int boothowto;
|
||||
sigset_t signalset;
|
||||
|
||||
signal(SIGINT, SIG_IGN);
|
||||
globalsInit();
|
||||
|
||||
i = sizeof(boothowto);
|
||||
if (!sysctlbyname("debug.boothowto", &boothowto, &i, NULL, 0) &&
|
||||
(i == sizeof(boothowto)) && (boothowto & RB_VERBOSE))
|
||||
variable_set2(VAR_DEBUG, "YES", 0);
|
||||
|
||||
if (set_termcap() == -1) {
|
||||
printf("Can't find terminal entry\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* XXX - libdialog has particularly bad return value checking */
|
||||
init_dialog(stdin, stdout);
|
||||
|
||||
/* If we haven't crashed I guess dialog is running ! */
|
||||
DialogActive = TRUE;
|
||||
|
||||
/* Make sure HOME is set for those utilities that need it */
|
||||
signal(SIGINT, handle_intr);
|
||||
/*
|
||||
* Make sure we can be interrupted even if we were re-executed
|
||||
* from an interrupt.
|
||||
*/
|
||||
sigemptyset(&signalset);
|
||||
sigaddset(&signalset, SIGINT);
|
||||
sigprocmask(SIG_UNBLOCK, &signalset, NULL);
|
||||
|
||||
(void)vsystem("rm -rf %s", DOC_TMP_DIR);
|
||||
}
|
||||
|
||||
/* Run some general command */
|
||||
int
|
||||
systemExecute(char *command)
|
||||
{
|
||||
int status;
|
||||
struct termios foo;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
dlg_clear();
|
||||
end_dialog();
|
||||
DialogActive = FALSE;
|
||||
if (tcgetattr(0, &foo) != -1) {
|
||||
foo.c_cc[VERASE] = '\010';
|
||||
tcsetattr(0, TCSANOW, &foo);
|
||||
}
|
||||
if (!Fake)
|
||||
status = system(command);
|
||||
else {
|
||||
status = 0;
|
||||
msgDebug("systemExecute: Faked execution of `%s'\n", command);
|
||||
}
|
||||
DialogActive = TRUE;
|
||||
restorescr(w);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* suspend/resume libdialog/curses screen */
|
||||
static WINDOW *oldW;
|
||||
|
||||
void
|
||||
systemSuspendDialog(void)
|
||||
{
|
||||
|
||||
oldW = savescr();
|
||||
dlg_clear();
|
||||
end_dialog();
|
||||
DialogActive = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
systemResumeDialog(void)
|
||||
{
|
||||
|
||||
DialogActive = TRUE;
|
||||
restorescr(oldW);
|
||||
}
|
||||
|
||||
/* Display a help file in a filebox */
|
||||
int
|
||||
systemDisplayHelp(char *file)
|
||||
{
|
||||
char *fname = NULL;
|
||||
char buf[FILENAME_MAX];
|
||||
int ret = 0;
|
||||
WINDOW *w = savescr();
|
||||
|
||||
fname = systemHelpFile(file, buf);
|
||||
if (!fname) {
|
||||
snprintf(buf, FILENAME_MAX, "The %s file is not provided on this particular floppy image.", file);
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
xdialog_msgbox("Sorry!", buf, -1, -1, 1);
|
||||
ret = 1;
|
||||
}
|
||||
else {
|
||||
dialog_vars.help_line = NULL;
|
||||
dialog_vars.help_file = NULL;
|
||||
dialog_textbox(file, fname, LINES, COLS);
|
||||
}
|
||||
restorescr(w);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
systemHelpFile(char *file, char *buf)
|
||||
{
|
||||
if (!file)
|
||||
return NULL;
|
||||
if (file[0] == '/')
|
||||
return file;
|
||||
snprintf(buf, FILENAME_MAX, "/stand/help/%s.hlp.gz", file);
|
||||
if (file_readable(buf))
|
||||
return expand(buf);
|
||||
snprintf(buf, FILENAME_MAX, "/stand/help/%s.hlp", file);
|
||||
if (file_readable(buf))
|
||||
return expand(buf);
|
||||
snprintf(buf, FILENAME_MAX, "/stand/help/%s.TXT.gz", file);
|
||||
if (file_readable(buf))
|
||||
return expand(buf);
|
||||
snprintf(buf, FILENAME_MAX, "/stand/help/%s.TXT", file);
|
||||
if (file_readable(buf))
|
||||
return expand(buf);
|
||||
snprintf(buf, FILENAME_MAX, "/usr/src/usr.sbin/%s/help/%s.hlp", ProgName,
|
||||
file);
|
||||
if (file_readable(buf))
|
||||
return buf;
|
||||
snprintf(buf, FILENAME_MAX, "/usr/src/usr.sbin/%s/help/%s.TXT", ProgName,
|
||||
file);
|
||||
if (file_readable(buf))
|
||||
return buf;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
vsystem(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int pstat;
|
||||
pid_t pid;
|
||||
int omask;
|
||||
sig_t intsave, quitsave;
|
||||
char *cmd;
|
||||
int i;
|
||||
struct stat sb;
|
||||
|
||||
cmd = (char *)alloca(FILENAME_MAX);
|
||||
cmd[0] = '\0';
|
||||
va_start(args, fmt);
|
||||
vsnprintf(cmd, FILENAME_MAX, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
omask = sigblock(sigmask(SIGCHLD));
|
||||
if (Fake) {
|
||||
msgDebug("vsystem: Faked execution of `%s'\n", cmd);
|
||||
return 0;
|
||||
}
|
||||
if (isDebug())
|
||||
msgDebug("Executing command `%s'\n", cmd);
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
(void)sigsetmask(omask);
|
||||
i = 127;
|
||||
}
|
||||
else if (!pid) { /* Junior */
|
||||
(void)sigsetmask(omask);
|
||||
if (DebugFD != -1) {
|
||||
dup2(DebugFD, 0);
|
||||
dup2(DebugFD, 1);
|
||||
dup2(DebugFD, 2);
|
||||
}
|
||||
else {
|
||||
close(1); open("/dev/null", O_WRONLY);
|
||||
dup2(1, 2);
|
||||
}
|
||||
if (stat("/stand/sh", &sb) == 0)
|
||||
execl("/stand/sh", "/stand/sh", "-c", cmd, (char *)NULL);
|
||||
else
|
||||
execl("/bin/sh", "/bin/sh", "-c", cmd, (char *)NULL);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
intsave = signal(SIGINT, SIG_IGN);
|
||||
quitsave = signal(SIGQUIT, SIG_IGN);
|
||||
pid = waitpid(pid, &pstat, 0);
|
||||
(void)sigsetmask(omask);
|
||||
(void)signal(SIGINT, intsave);
|
||||
(void)signal(SIGQUIT, quitsave);
|
||||
i = (pid == -1) ? -1 : WEXITSTATUS(pstat);
|
||||
if (isDebug())
|
||||
msgDebug("Command `%s' returns status of %d\n", cmd, i);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1994, Paul Richards.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software may be used, modified, copied, distributed, and sold, in both
|
||||
* source and binary form provided that the above copyright and these terms
|
||||
* are retained, verbatim, as the first lines of this file. Under no
|
||||
* circumstances is the author responsible for the proper functioning of this
|
||||
* software, nor does the author assume any responsibility for damages
|
||||
* incurred with its use.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/consio.h>
|
||||
|
||||
#define VTY_STATUS_LINE 24
|
||||
#define TTY_STATUS_LINE 23
|
||||
|
||||
static void
|
||||
prompt_term(char **termp)
|
||||
{
|
||||
char str[80];
|
||||
|
||||
printf("\nPlease set your TERM variable before running this program.\n");
|
||||
printf("Defaulting to an ANSI compatible terminal - please press RETURN\n");
|
||||
fgets(str, sizeof(str), stdin); /* Just to make it interactive */
|
||||
*termp = (char *)"ansi";
|
||||
}
|
||||
|
||||
int
|
||||
set_termcap(void)
|
||||
{
|
||||
char *term;
|
||||
int stat;
|
||||
struct winsize ws;
|
||||
|
||||
term = getenv("TERM");
|
||||
stat = ioctl(STDERR_FILENO, GIO_COLOR, &ColorDisplay);
|
||||
|
||||
if (isDebug())
|
||||
DebugFD = open("sade.debug", O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||
else
|
||||
DebugFD = -1;
|
||||
if (DebugFD < 0)
|
||||
DebugFD = open("/dev/null", O_RDWR, 0);
|
||||
|
||||
if (!OnVTY || (stat < 0)) {
|
||||
if (!term) {
|
||||
char *term;
|
||||
|
||||
prompt_term(&term);
|
||||
if (setenv("TERM", term, 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
if (DebugFD < 0)
|
||||
DebugFD = open("/dev/null", O_RDWR, 0);
|
||||
}
|
||||
else {
|
||||
int i, on;
|
||||
|
||||
if (getpid() == 1) {
|
||||
DebugFD = open("/dev/ttyv1", O_WRONLY);
|
||||
if (DebugFD != -1) {
|
||||
on = 1;
|
||||
i = ioctl(DebugFD, TIOCCONS, (char *)&on);
|
||||
msgDebug("ioctl(%d, TIOCCONS, NULL) = %d (%s)\n",
|
||||
DebugFD, i, !i ? "success" : strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
if (!term) {
|
||||
if (setenv("TERM", "cons25w", 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (ColorDisplay) {
|
||||
if (!term) {
|
||||
if (setenv("TERM", "xterm", 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!term) {
|
||||
if (setenv("TERM", "vt100", 1) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ioctl(0, TIOCGWINSZ, &ws) == -1) {
|
||||
msgDebug("Unable to get terminal size - errno %d\n", errno);
|
||||
ws.ws_row = 0;
|
||||
}
|
||||
StatusLine = ws.ws_row ? ws.ws_row - 1: (OnVTY ? VTY_STATUS_LINE : TTY_STATUS_LINE);
|
||||
return 0;
|
||||
}
|
@ -1,324 +0,0 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Copyright (c) 1995
|
||||
* Jordan Hubbard. All rights reserved.
|
||||
* Copyright (c) 2001
|
||||
* Murray Stokely. All rights reserved.
|
||||
*
|
||||
* 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,
|
||||
* verbatim and that no modifications are made prior to this
|
||||
* point in the file.
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``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 JORDAN HUBBARD OR HIS PETS 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, LIFE 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
|
||||
/* Routines for dealing with variable lists */
|
||||
|
||||
static void
|
||||
make_variable(char *var, char *value, int dirty)
|
||||
{
|
||||
Variable *vp;
|
||||
|
||||
/* Trim leading and trailing whitespace */
|
||||
var = string_skipwhite(string_prune(var));
|
||||
|
||||
if (!var || !*var)
|
||||
return;
|
||||
|
||||
|
||||
/* Now search to see if it's already in the list */
|
||||
for (vp = VarHead; vp; vp = vp->next) {
|
||||
if (!strcmp(vp->name, var)) {
|
||||
if (vp->dirty && !dirty)
|
||||
return;
|
||||
setenv(var, value, 1);
|
||||
free(vp->value);
|
||||
vp->value = strdup(value);
|
||||
if (dirty != -1)
|
||||
vp->dirty = dirty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setenv(var, value, 1);
|
||||
/* No? Create a new one */
|
||||
vp = (Variable *)safe_malloc(sizeof(Variable));
|
||||
vp->name = strdup(var);
|
||||
vp->value = strdup(value);
|
||||
if (dirty == -1)
|
||||
dirty = 0;
|
||||
vp->dirty = dirty;
|
||||
vp->next = VarHead;
|
||||
VarHead = vp;
|
||||
}
|
||||
|
||||
void
|
||||
variable_set(char *var, int dirty)
|
||||
{
|
||||
char tmp[1024], *cp;
|
||||
|
||||
if (!var)
|
||||
msgFatal("NULL variable name & value passed.");
|
||||
else if (!*var)
|
||||
msgDebug("Warning: Zero length name & value passed to variable_set()\n");
|
||||
SAFE_STRCPY(tmp, var);
|
||||
if ((cp = strchr(tmp, '=')) == NULL)
|
||||
msgFatal("Invalid variable format: %s", var);
|
||||
*(cp++) = '\0';
|
||||
make_variable(tmp, string_skipwhite(cp), dirty);
|
||||
}
|
||||
|
||||
void
|
||||
variable_set2(char *var, char *value, int dirty)
|
||||
{
|
||||
if (!var || !value)
|
||||
msgFatal("Null name or value passed to set_variable2(%s) = %s!",
|
||||
var ? var : "", value ? value : "");
|
||||
else if (!*var || !*value)
|
||||
msgDebug("Warning: Zero length name or value passed to variable_set2(%s) = %s\n",
|
||||
var, value);
|
||||
make_variable(var, value, dirty);
|
||||
}
|
||||
|
||||
char *
|
||||
variable_get(char *var)
|
||||
{
|
||||
return getenv(var);
|
||||
}
|
||||
|
||||
int
|
||||
variable_cmp(char *var, char *value)
|
||||
{
|
||||
char *val;
|
||||
|
||||
if ((val = variable_get(var)))
|
||||
return strcmp(val, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
variable_unset(char *var)
|
||||
{
|
||||
Variable *vp;
|
||||
char name[512], *cp;
|
||||
|
||||
if ((cp = strchr(var, '=')) != NULL)
|
||||
sstrncpy(name, var, cp - var);
|
||||
else
|
||||
SAFE_STRCPY(name, var);
|
||||
unsetenv(name);
|
||||
/* Now search to see if it's in our list, if we have one.. */
|
||||
if (!VarHead)
|
||||
return;
|
||||
else if (!VarHead->next && !strcmp(VarHead->name, name)) {
|
||||
safe_free(VarHead->name);
|
||||
safe_free(VarHead->value);
|
||||
free(VarHead);
|
||||
VarHead = NULL;
|
||||
}
|
||||
else {
|
||||
for (vp = VarHead; vp; vp = vp->next) {
|
||||
if (!strcmp(vp->name, name)) {
|
||||
Variable *save = vp->next;
|
||||
|
||||
safe_free(vp->name);
|
||||
safe_free(vp->value);
|
||||
*vp = *save;
|
||||
safe_free(save);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Prompt user for the name of a variable */
|
||||
char *
|
||||
variable_get_value(char *var, char *prompt, int dirty)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp = variable_get(var);
|
||||
if (cp && variable_get(VAR_NONINTERACTIVE))
|
||||
return cp;
|
||||
else if ((cp = msgGetInput(cp, "%s", prompt)) != NULL)
|
||||
variable_set2(var, cp, dirty);
|
||||
else
|
||||
cp = NULL;
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* Check if value passed in data (in the form "variable=value") is
|
||||
* valid, and it's status compared to the value of variable stored in
|
||||
* env
|
||||
*
|
||||
* Possible return values :
|
||||
* -3: Invalid line, the data string is NOT set as an env variable
|
||||
* -2: Invalid line, the data string is set as an env variable
|
||||
* -1: Invalid line
|
||||
* 0: Valid line, is NOT equal to env version
|
||||
* 1: Valid line, is equal to env version
|
||||
* 2: Valid line, value empty - e.g. foo=""
|
||||
* 3: Valid line, does not exist in env
|
||||
*/
|
||||
int
|
||||
variable_check2(char *data)
|
||||
{
|
||||
char *cp, *cp2, *cp3, tmp[256];
|
||||
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
SAFE_STRCPY(tmp, data);
|
||||
if ((cp = strchr(tmp, '=')) != NULL) {
|
||||
*(cp++) = '\0';
|
||||
if (*cp == '"') { /* smash quotes if present */
|
||||
++cp;
|
||||
if ((cp3 = strchr(cp, '"')) != NULL)
|
||||
*cp3 = '\0';
|
||||
}
|
||||
else if ((cp3 = strchr(cp, ',')) != NULL)
|
||||
*cp3 = '\0';
|
||||
cp2 = variable_get(tmp);
|
||||
if (cp2 != NULL) {
|
||||
if (*cp == '\0')
|
||||
return 2;
|
||||
else
|
||||
return strcmp(cp, cp2) == 0 ? 1 : 0;
|
||||
}
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
return variable_get(tmp) != NULL ? -2 : -3;
|
||||
}
|
||||
|
||||
/* Check if the value passed in data (in the form "variable=value") is
|
||||
equal to the value of variable stored in env */
|
||||
int
|
||||
variable_check(char *data)
|
||||
{
|
||||
int ret;
|
||||
ret = variable_check2(data);
|
||||
|
||||
switch(ret) {
|
||||
case -2:
|
||||
case 1:
|
||||
case 2:
|
||||
return TRUE;
|
||||
/* NOT REACHED */
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dump_variables(dialogMenuItem *unused)
|
||||
{
|
||||
FILE *fp;
|
||||
Variable *vp;
|
||||
|
||||
if (isDebug())
|
||||
msgDebug("Writing %s variables to file..\n", ProgName);
|
||||
|
||||
fp = fopen("/etc/sade.vars", "w");
|
||||
if (!fp) {
|
||||
msgConfirm("Unable to write to /etc/%s.vars: %s",
|
||||
ProgName, strerror(errno));
|
||||
return DITEM_FAILURE;
|
||||
}
|
||||
|
||||
for (vp = VarHead; vp; vp = vp->next)
|
||||
fprintf(fp, "%s=\"%s\" (%d)\n", vp->name, vp->value, vp->dirty);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return DITEM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Free all of the variables, useful to really start over as when the
|
||||
user selects "restart" from the interrupt menu. */
|
||||
void
|
||||
free_variables(void)
|
||||
{
|
||||
Variable *vp;
|
||||
|
||||
/* Free the variables from our list, if we have one.. */
|
||||
if (!VarHead)
|
||||
return;
|
||||
else if (!VarHead->next) {
|
||||
unsetenv(VarHead->name);
|
||||
safe_free(VarHead->name);
|
||||
safe_free(VarHead->value);
|
||||
free(VarHead);
|
||||
VarHead = NULL;
|
||||
}
|
||||
else {
|
||||
for (vp = VarHead; vp; ) {
|
||||
Variable *save = vp;
|
||||
unsetenv(vp->name);
|
||||
safe_free(vp->name);
|
||||
safe_free(vp->value);
|
||||
vp = vp->next;
|
||||
safe_free(save);
|
||||
}
|
||||
VarHead = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Persistent variables. The variables modified by these functions
|
||||
* are not cleared between invocations of sysinstall. This is useful
|
||||
* to allow the user to completely restart sysinstall, without having
|
||||
* it load all of the modules again from the installation media which
|
||||
* are still in memory.
|
||||
*/
|
||||
|
||||
void
|
||||
pvariable_set(char *var)
|
||||
{
|
||||
char *p;
|
||||
char tmp[1024];
|
||||
|
||||
if (!var)
|
||||
msgFatal("NULL variable name & value passed.");
|
||||
else if (!*var)
|
||||
msgDebug("Warning: Zero length name & value passed to variable_set()\n");
|
||||
/* Add a trivial namespace to whatever name the caller chooses. */
|
||||
SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
|
||||
if (strchr(var, '=') == NULL)
|
||||
msgFatal("Invalid variable format: %s", var);
|
||||
strlcat(tmp, var, 1024);
|
||||
p = strchr(tmp, '=');
|
||||
*p = '\0';
|
||||
setenv(tmp, p + 1, 1);
|
||||
}
|
||||
|
||||
char *
|
||||
pvariable_get(char *var)
|
||||
{
|
||||
char tmp[1024];
|
||||
|
||||
SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
|
||||
strlcat(tmp, var, 1024);
|
||||
return getenv(tmp);
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "sade.h"
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <libdisk.h>
|
||||
|
||||
static int
|
||||
scan_block(int fd, daddr_t block)
|
||||
{
|
||||
u_char foo[512];
|
||||
|
||||
if (-1 == lseek(fd,block * 512,SEEK_SET))
|
||||
err(1,"lseek");
|
||||
if (512 != read(fd,foo, 512))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Scan_Disk(Disk *d)
|
||||
{
|
||||
char device[64];
|
||||
u_long l;
|
||||
int i,j,fd;
|
||||
|
||||
strcpy(device,"/dev/");
|
||||
strcat(device,d->name);
|
||||
|
||||
fd = open(device,O_RDWR);
|
||||
if (fd < 0) {
|
||||
msgWarn("open(%s) failed", device);
|
||||
return;
|
||||
}
|
||||
for(i=-1,l=0;;l++) {
|
||||
j = scan_block(fd,l);
|
||||
if (j != i) {
|
||||
if (i == -1) {
|
||||
printf("%c: %lu.",j ? 'B' : 'G', l);
|
||||
fflush(stdout);
|
||||
} else if (i == 0) {
|
||||
printf(".%lu\nB: %lu.",l-1,l);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
printf(".%lu\nG: %lu.",l-1,l);
|
||||
fflush(stdout);
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
slice_wizard(Disk *d)
|
||||
{
|
||||
Disk *db;
|
||||
char myprompt[BUFSIZ];
|
||||
char input[BUFSIZ];
|
||||
char *p,*q=0;
|
||||
char **cp,*cmds[200];
|
||||
int ncmd,i;
|
||||
|
||||
systemSuspendDialog();
|
||||
sprintf(myprompt,"%s> ", d->name);
|
||||
while(1) {
|
||||
printf("--==##==--\n");
|
||||
Debug_Disk(d);
|
||||
p = CheckRules(d);
|
||||
if (p) {
|
||||
printf("%s",p);
|
||||
free(p);
|
||||
}
|
||||
printf("%s", myprompt);
|
||||
fflush(stdout);
|
||||
q = p = fgets(input,sizeof(input),stdin);
|
||||
if(!p)
|
||||
break;
|
||||
for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
|
||||
if (**cp != '\0')
|
||||
cp++;
|
||||
ncmd = cp - cmds;
|
||||
if(!ncmd)
|
||||
continue;
|
||||
if (!strcasecmp(*cmds,"quit")) { break; }
|
||||
if (!strcasecmp(*cmds,"exit")) { break; }
|
||||
if (!strcasecmp(*cmds,"q")) { break; }
|
||||
if (!strcasecmp(*cmds,"x")) { break; }
|
||||
if (!strcasecmp(*cmds,"delete") && ncmd == 2) {
|
||||
printf("delete = %d\n",
|
||||
Delete_Chunk(d,
|
||||
(struct chunk *)strtol(cmds[1],0,0)));
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"allfreebsd")) {
|
||||
All_FreeBSD(d, 0);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"dedicate")) {
|
||||
All_FreeBSD(d, 1);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"bios") && ncmd == 4) {
|
||||
Set_Bios_Geom(d,
|
||||
strtol(cmds[1],0,0),
|
||||
strtol(cmds[2],0,0),
|
||||
strtol(cmds[3],0,0));
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"list")) {
|
||||
cp = Disk_Names();
|
||||
printf("Disks:");
|
||||
for(i=0;cp[i];i++) {
|
||||
printf(" %s",cp[i]);
|
||||
free(cp[i]);
|
||||
}
|
||||
free(cp);
|
||||
continue;
|
||||
}
|
||||
#ifdef PC98
|
||||
if (!strcasecmp(*cmds,"create") && ncmd == 7) {
|
||||
printf("Create=%d\n",
|
||||
Create_Chunk(d,
|
||||
strtol(cmds[1],0,0),
|
||||
strtol(cmds[2],0,0),
|
||||
strtol(cmds[3],0,0),
|
||||
strtol(cmds[4],0,0),
|
||||
strtol(cmds[5],0,0),
|
||||
cmds[6]));
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (!strcasecmp(*cmds,"create") && ncmd == 6) {
|
||||
printf("Create=%d\n",
|
||||
Create_Chunk(d,
|
||||
strtol(cmds[1],0,0),
|
||||
strtol(cmds[2],0,0),
|
||||
strtol(cmds[3],0,0),
|
||||
strtol(cmds[4],0,0),
|
||||
strtol(cmds[5],0,0), ""));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!strcasecmp(*cmds,"read")) {
|
||||
db = d;
|
||||
if (ncmd > 1)
|
||||
d = Open_Disk(cmds[1]);
|
||||
else
|
||||
d = Open_Disk(d->name);
|
||||
if (d)
|
||||
Free_Disk(db);
|
||||
else
|
||||
d = db;
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"scan")) {
|
||||
Scan_Disk(d);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"write")) {
|
||||
printf("Write=%d\n",
|
||||
Fake ? 0 : Write_Disk(d));
|
||||
q = strdup(d->name);
|
||||
Free_Disk(d);
|
||||
d = Open_Disk(q);
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(*cmds,"help"))
|
||||
printf("\007ERROR\n");
|
||||
printf("CMDS:\n");
|
||||
printf("allfreebsd\t\t");
|
||||
printf("dedicate\t\t");
|
||||
printf("bios cyl hd sect\n");
|
||||
printf("collapse [pointer]\t\t");
|
||||
#ifdef PC98
|
||||
printf("create offset size enum subtype flags name\n");
|
||||
#else
|
||||
printf("create offset size enum subtype flags\n");
|
||||
#endif
|
||||
printf("subtype(part): swap=1, ffs=7\t\t");
|
||||
printf("delete pointer\n");
|
||||
printf("list\t\t");
|
||||
printf("quit\n");
|
||||
printf("read [disk]\t\t");
|
||||
printf("scan\n");
|
||||
printf("write\t\t");
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
systemResumeDialog();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user