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:
Nathan Whitehorn 2012-12-30 14:35:00 +00:00
parent 4f5fcf8d00
commit 934f522a9f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244859
25 changed files with 1 additions and 6370 deletions

View file

@ -23,7 +23,4 @@ SUBDIR+= ndiscvt
.endif
SUBDIR+= sicontrol
SUBDIR+= spkrtest
.if ${MK_SYSINSTALL} != "no"
SUBDIR+= sade
.endif
SUBDIR+= zzz

View file

@ -17,9 +17,6 @@ SUBDIR+= mptable
SUBDIR+= ndiscvt
.endif
SUBDIR+= pnpinfo
.if ${MK_SYSINSTALL} != "no"
SUBDIR+= sade
.endif
SUBDIR+= sicontrol
SUBDIR+= spkrtest
SUBDIR+= zzz

View file

@ -2,6 +2,3 @@
SUBDIR+= eeprom
SUBDIR+= ofwdump
.if ${MK_SYSINSTALL} != "no"
SUBDIR+= sade
.endif

View file

@ -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}

View file

@ -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>

View file

@ -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);
}
}
}
}

View file

@ -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;
}

View file

@ -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 */

View file

@ -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);
}
}

View file

@ -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
}

View file

@ -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.

View file

@ -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'.

View file

@ -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

View file

@ -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; \
}

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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();
}