home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
install
/
.#install.c.1.44
< prev
next >
Wrap
Text File
|
1997-10-01
|
10KB
|
457 lines
/*
* install.c
*
* This is the first half of the install. It does just enough to get the
* second half going. It, and everything it needs, has to fit on one floppy
* along with a kernel and modules. Needless to say, it's a bit tight.
*
* Erik Troan (ewt@redhat.com)
*
* Copyright 1997 Red Hat Software
*
* This software may be freely redistributed under the terms of the GNU
* public license.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <alloca.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h> /* for ntohl */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/wait.h>
#include <unistd.h>
#include <zlib.h>
#include "devices.h"
#include "fs.h"
#include "install.h"
#include "kbd.h"
#include "kickstart.h"
#include "log.h"
#include "methods.h"
#include "mono.h"
#include "net.h"
#include "newt.h"
#include "perror.h"
#include "run.h"
#include "windows.h"
#include "pcmcia-probing/pcmcia-probe.h"
int testing = 0;
int expert = 0;
int kickstart = 0;
int debug = 1;
/* librpm.a provides this */
int cpioInstallArchive(gzFile stream, void * mappings,
int numMappings, void * cb, void * cbData,
char ** failedFile);
char * welcomeText =
"Welcome to Red Hat Linux!\n"
"\n"
"This installation process is outlined in detail in the Official Red "
"Hat Linux User's Guide available from Red Hat Software. If you have "
"access to this manual, you should read the installation section before "
"continuing.\n\n"
"If you have purchased Official Red Hat Linux, be sure to register your "
"purchase through our web site, http://www.redhat.com."
;
void welcome(void) {
if (!testing && !kickstart)
newtWinMessage("Red Hat Linux", "Ok", welcomeText);
}
void mountFloppy() {
if (!testing) {
logMessage("mounting ext2 fs on floppy");
doMount("fd0", "/tmp/bootdisk", "ext2", 1, 0);
logMessage("floppy filesystem mounted on /tmp/bootdisk");
}
}
#if 0
void showmtab(void) {
char buf[5000];
int fd, i;
fd = open("/proc/mounts", O_RDONLY);
if (fd < 0) {
newtWinMessage("Error", "Ok", perrorstr("open /proc/mounts"));
return;
}
i = read(fd, buf, sizeof(buf) - 1);
if (i < 1) {
close(fd);
newtWinMessage("Error", "Ok", perrorstr("read /proc/mounts"));
return;
}
close(fd);
buf[i] = '\0';
newtWinMessage("/proc/mounts", "Ok", buf);
}
#endif
int expandPcmciaArchive() {
gzFile stream;
char * failedFile;
int rc;
stream = gzopen("/tmp/image/pcmcia.cgz", "r");
if (!stream) {
logMessage("gzopen failed to read pcmcia.cgz: %s", strerror(errno));
return INST_ERROR;
}
rc = cpioInstallArchive(stream, NULL, 0, NULL, NULL, &failedFile);
if (rc) {
logMessage("cpio expansion failed on file %s, error %d\n",
failedFile, rc);
gzclose(stream);
return INST_ERROR;
}
gzclose(stream);
return 0;
}
#ifdef __i386__
int setupPCMCIA(char ** arg) {
int rc;
struct driversLoaded * dl = NULL;
int status;
char * probeOutput;
static char pcic[20];
/* just probe and if pcmcia controller exists we load support
automatically */
probeOutput = pcmciaProbeController();
if (probeOutput == NULL)
return 0;
rc = loadFloppyRoot(NULL,
"PCMCIA support requires a second disk. Please remove "
"the boot disk currently in your drive and replace it with "
"the Red Hat Supplementary Install disk.");
if (rc) return rc;
if (testing) {
sleep(2);
return 0;
}
winStatus(35, 3, "PCMCIA", "Loading PCMCIA support...");
chdir("/modules");
unlink("53c7,8xx.o.gz");
unlink("3c59x.o.gz");
unlink("cdrom.o.gz");
unlink("aztcd.o.gz");
unlink("cdu31a.o.gz");
unlink("cm206.o.gz");
unlink("de4x5.o.gz");
unlink("sbpcd.o.gz");
unlink("sjcd.o.gz");
unlink("sonycd535.o.gz");
unlink("optcd.o.gz");
unlink("gscd.o.gz");
unlink("aic7xxx.o.gz");
unlink("eata_dma.o.gz");
unlink("eata_pio.o.gz");
unlink("pas_16.o.gz");
unlink("ultrastor.o.gz");
unlink("u14-34f.o.gz");
chdir("/");
expandPcmciaArchive();
newtPopWindow();
logMessage("pcmcia probe returned: %s", probeOutput);
if (strstr(probeOutput, "TCIC")) {
strcpy(pcic, "tcic");
} else
strcpy(pcic, "i82365");
logMessage("pcmcia pcic type: %s", pcic);
winStatus(40, 3, "PCMCIA", "Starting PCMCIA services...");
loadModule("pcmcia_core", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
loadModule(pcic, DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
loadModule("ds", DRIVER_PCMCIA, DRIVER_MINOR_NONE, &dl);
*arg = pcic;
if (!fork()) {
if (!fork()) {
execl("/sbin/cardmgr", "/sbin/cardmgr", NULL);
exit(-1);
}
exit(-1);
}
wait(&status);
/* if cardmgr a chance to get going */
sleep(5);
newtPopWindow();
return 0;
}
#endif
void doSuspend(void) {
pid_t pid;
int status;
if (testing) {
newtFinished();
exit(1);
} else if (access("/bin/sh", X_OK)) {
return;
}
newtSuspend();
if (!(pid = fork())) {
printf("\n\nType <exit> to return to the install program.\n\n");
execl("/bin/sh", "-/bin/sh", NULL);
perror("error execing /bin/sh");
sleep(5);
exit(1);
}
waitpid(pid, &status, 0);
newtResume();
}
void main(int argc, char ** argv) {
char ** argptr;
struct installMethod * method;
int rc;
char * pcmciaArg = NULL;
int isRescue = 0;
int isSerial;
int force = 0;
struct stat sb;
char * childArgs[20];
struct netInterface intf;
struct netConfig netc;
struct driversLoaded * dl = NULL;
char * ksPath;
char * file, * ksFile = NULL;
char * server;
memset(&intf, 0, sizeof(intf));
memset(&netc, 0, sizeof(netc));
argptr = argv + 1;
while (*argptr) {
if (!strcmp(*argptr, "--test")) {
testing = 1;
} else if (!strcmp(*argptr, "--force")) {
force = 1;
} else if (!strcmp(*argptr, "--rescue")) {
isRescue = 1;
} else if (!strcmp(*argptr, "--kickstart") ||
!strcmp(*argptr, "--ks")) {
kickstart = 1;
} else if (!strcmp(*argptr, "--expert")) {
expert = 1;
}
argptr++;
}
if (!testing && !force && (getpid() > 50)) {
fprintf(stderr, "you're running me on a live system! that's ");
fprintf(stderr, "incredibly stupid.\n");
exit(1);
}
openLog();
/* see if we're on a serial console -- if so, don't setup a keymap */
if (fstat(0, &sb)) {
logMessage("error stat'ing stdin: %s", strerror(errno));
return;
}
if (!S_ISCHR(sb.st_mode)) {
logMessage("stdin isn't a character device!!! ack!");
return;
}
isSerial = (major(sb.st_rdev) == 4 && minor(sb.st_dev) >= 64) ||
(major(sb.st_rdev) == 5 && minor(sb.st_dev) >= 64);
if (!isRescue)
logMessage("welcome to the Red Hat install "
"(first stage, version " VERSION " built " __DATE__ " "
__TIME__")");
if (!kickstart)
setenv("NEWT_MONO", "1", 1);
newtInit();
newtCls();
newtSetSuspendCallback(doSuspend);
newtDrawRootText(0, 0, "Welcome to Red Hat Linux");
setColorState();
newtFinished();
newtInit();
newtCls();
newtDrawRootText(0, 0, "Welcome to Red Hat Linux");
if (!isRescue)
welcome();
newtPushHelpLine(NULL);
#ifndef __sparc__
/* kickstart installs do this later */
if (!isSerial && !kickstart) setupKeyboard();
#endif
#ifdef __i386__
/* this blocks on kickstart installs, but there is nothing to
be done about it */
do {
rc = setupPCMCIA(&pcmciaArg);
} while (rc);
#endif
if (isRescue) {
do {
rc = floppyRoot(NULL, &netc, &intf, &dl);
} while (rc);
} else if (kickstart) {
if ((bringUpNetworking(&intf, &netc, &dl))) {
kickstart = 0;
} else if (!(server = getenv("BOOTP_SERVER"))) {
newtWinMessage("Kickstart Error", "Ok", "No kickstart "
"configuration file server can be found.");
kickstart = 0;
} else {
if (!(file = getenv("BOOTP_BOOTFILE")) || !strlen(file))
file = "/kickstartdir/";
ksPath = alloca(strlen(server) + strlen(file) +
strlen(netc.hostname) + 50);
strcpy(ksPath, server);
strcat(ksPath, ":");
strcat(ksPath, file);
if (ksPath[strlen(ksPath) - 1] == '/') {
ksPath[strlen(ksPath) - 1] = '\0';
file = alloca(30);
sprintf(file, "%02X%02X%02X%02X.kickstart",
(ntohl(intf.ip) & 0xFF000000) >> 24,
(ntohl(intf.ip) & 0x00FF0000) >> 16,
(ntohl(intf.ip) & 0x0000FF00) >> 8,
(ntohl(intf.ip) & 0x000000FF) >> 0);
} else {
file = strrchr(ksPath, '/');
if (!file) {
file = ksPath;
ksPath = "/";
} else {
*file++ = '\0';
}
}
logMessage("ks server: %s file: %s", ksPath, file);
loadFilesystem("nfs", &dl);
if ((rc = doMount(ksPath, "/tmp/ks", "nfs", 1, 0))) {
newtWinMessage("Error", "Ok",
"I could not mount the kickstart path %s.\n",
ksPath);
kickstart = 0;
} else {
ksFile = alloca(strlen(file) + 20);
sprintf(ksFile, "/tmp/ks/%s", file);
if (ksReadCommands(ksFile))
kickstart = 0;
else
kickstart = 1;
}
}
}
if (!isRescue)
while ((rc = chooseInstallMethod(&method, &netc, &intf, &dl)));
if (intf.isConfigured) {
writeNetInterfaceConfig("/tmp", &intf);
writeNetConfig("/tmp", &netc, &intf, 1);
}
if (dl) writeModuleConf("/tmp", dl, 0);
newtFinished();
closeLog();
if (testing) exit(0);
argptr = childArgs;
*argptr++ = "/usr/bin/runinstall2";
if (isRescue)
*argptr++ = "--rescue";
else {
*argptr++ = "--method";
*argptr++ = method->abbrev;
}
if (expert)
*argptr++ = "--expert";
if (pcmciaArg) {
*argptr++ = "--pcmcia";
*argptr++ = pcmciaArg;
}
if (kickstart) {
*argptr++ = "--ks";
*argptr++ = ksFile;
}
*argptr++ = NULL;
execv(childArgs[0], childArgs);
rc = errno;
openLog();
logMessage("error in exec of second stage loader :-(");
logMessage("\terror:%s", strerror(rc));
while (1) ;
exit(0);
}