summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorMatt Wilson <msw@redhat.com>1999-10-18 15:24:59 +0000
committerMatt Wilson <msw@redhat.com>1999-10-18 15:24:59 +0000
commit6ec33ea754b1a8267fa8857ac14d205d6a4944f8 (patch)
tree33e2842cfa73ad0a13771025651ccef3a1bf65da /loader
parentf11c2e3344b4dfe293f4492f23c8083b5aa8c29e (diff)
downloadanaconda-6ec33ea754b1a8267fa8857ac14d205d6a4944f8.tar.gz
anaconda-6ec33ea754b1a8267fa8857ac14d205d6a4944f8.tar.xz
anaconda-6ec33ea754b1a8267fa8857ac14d205d6a4944f8.zip
1) handle update images
2) fixed serial check to handle pty's for japanese
Diffstat (limited to 'loader')
-rw-r--r--loader/loader.c131
1 files changed, 124 insertions, 7 deletions
diff --git a/loader/loader.c b/loader/loader.c
index 789d1da46..00f3da940 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/sysmacros.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <zlib.h>
@@ -142,8 +143,10 @@ static void spawnShell(int flags) {
pid_t pid;
int fd;
- if (FL_SERIAL(flags))
+ if (FL_SERIAL(flags)) {
+ logMessage("not spawning a shell over a serial connection");
return;
+ }
if (!FL_TESTING(flags)) {
fd = open("/dev/tty2", O_RDWR);
if (fd < 0) {
@@ -162,7 +165,7 @@ static void spawnShell(int flags) {
close(fd);
setsid();
if (ioctl(0, TIOCSCTTY, NULL)) {
- perror("could not set new controlling tty");
+ logMessage("could not set new controlling tty");
}
execl("/bin/sh", "-/bin/sh", NULL);
@@ -1452,6 +1455,8 @@ static int parseCmdLineFlags(int flags, char * cmdLine, char ** ksSource) {
LOADER_FLAGS_MODDISK;
else if (!strcasecmp(argv[i], "text"))
flags |= LOADER_FLAGS_TEXT;
+ else if (!strcasecmp(argv[i], "updates"))
+ flags |= LOADER_FLAGS_UPDATES;
else if (!strcasecmp(argv[i], "isa"))
flags |= LOADER_FLAGS_ISA;
else if (!strcasecmp(argv[i], "dd"))
@@ -1637,6 +1642,108 @@ void readExtraModInfo(moduleInfoSet modInfo) {
}
}
+/* Recursive */
+int copyDirectory(char * from, char * to) {
+ DIR * dir;
+ struct dirent * ent;
+ int fd, outfd;
+ char buf[4096];
+ int i;
+ struct stat sb;
+ char filespec[256];
+ char filespec2[256];
+ char link[1024];
+
+ mkdir(to, 0755);
+
+ if (!(dir = opendir(from))) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("Failed to read directory %s: %s"),
+ from, strerror(errno));
+ return 1;
+ }
+
+ errno = 0;
+ while ((ent = readdir(dir))) {
+ if (ent->d_name[0] == '.') continue;
+
+ sprintf(filespec, "%s/%s", from, ent->d_name);
+ sprintf(filespec2, "%s/%s", to, ent->d_name);
+
+ lstat(filespec, &sb);
+
+ if (S_ISDIR(sb.st_mode)) {
+ logMessage("recursively copying %s", filespec);
+ if (copyDirectory(filespec, filespec2)) return 1;
+ } else if (S_ISLNK(sb.st_mode)) {
+ i = readlink(filespec, link, sizeof(link) - 1);
+ link[i] = '\0';
+ if (symlink(link, filespec2)) {
+ logMessage("failed to symlink %s to %s: %s",
+ filespec2, link, strerror(errno));
+ }
+ } else {
+ fd = open(filespec, O_RDONLY);
+ if (fd < 0) {
+ logMessage("failed to open %s: %s", filespec,
+ strerror(errno));
+ return 1;
+ }
+ outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644);
+ if (outfd < 0) {
+ logMessage("failed to create %s: %s", filespec2,
+ strerror(errno));
+ } else {
+ fchmod(outfd, sb.st_mode & 07777);
+
+ while ((i = read(fd, buf, sizeof(buf))) > 0)
+ write(outfd, buf, i);
+ close(outfd);
+ }
+
+ close(fd);
+ }
+
+ errno = 0;
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+void loadUpdates(struct knownDevices *kd, moduleList modLoaded,
+ moduleDeps modDeps, int flags) {
+ int done = 0;
+ int rc;
+
+ do {
+ rc = newtWinChoice(_("Devices"), _("OK"), _("Cancel"),
+ _("Insert your updates disk and press \"OK\" to continue."));
+
+ if (rc == 2) return;
+
+ devMakeInode("fd0", "/tmp/fd0");
+ if (doPwMount("/tmp/fd0", "/tmp/update-disk", "ext2", 1, 0, NULL,
+ NULL)) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("Failed to mount floppy disk."));
+ } else {
+ /* Copy everything to /tmp/updates so .so files don't get run
+ from /dev/fd0. We could (and probably should) get smarter about
+ this at some point. */
+ winStatus(40, 3, _("Updates"), _("Reading anaconda updates..."));
+ if (!copyDirectory("/tmp/update-disk", "/tmp/updates")) done = 1;
+ newtPopWindow();
+ umount("/tmp/update-disk");
+ }
+ } while (!done);
+
+ chdir("/tmp/updates");
+
+ return;
+}
+
#ifdef __sparc__
/* Don't load the large ufs module if it will not be needed
to save some memory on lowmem SPARCs. */
@@ -1694,6 +1801,7 @@ int main(int argc, char ** argv) {
struct moduleInfo * mi;
char twelve = 12;
char * ksFile = NULL, * ksSource = NULL;
+ struct stat sb;
struct poptOption optionTable[] = {
{ "cmdline", '\0', POPT_ARG_STRING, &cmdLine, 0 },
{ "ksfile", '\0', POPT_ARG_STRING, &ksFile, 0 },
@@ -1710,9 +1818,10 @@ int main(int argc, char ** argv) {
return ourInsmodCommand(argc, argv);
#ifdef INCLUDE_KON
- else if (!strcmp(argv[0] + strlen(argv[0]) - 3, "kon"))
- return kon_main(argc, argv);
- else if (!strcmp(argv[0] + strlen(argv[0]) - 8, "continue"))
+ else if (!strcmp(argv[0] + strlen(argv[0]) - 3, "kon")) {
+ i = kon_main(argc, argv);
+ return i;
+ } else if (!strcmp(argv[0] + strlen(argv[0]) - 8, "continue"))
startKon = 0;
#endif
@@ -1723,8 +1832,13 @@ int main(int argc, char ** argv) {
return probe_main(argc, argv);
#endif
- if (ioctl (0, TIOCLINUX, &twelve) < 0)
- flags |= LOADER_FLAGS_SERIAL;
+ /* The fstat checks disallows serial console if we're running through
+ a pty. This is handy for Japanese. */
+ fstat(0, &sb);
+ if (major(sb.st_rdev) != 3) {
+ if (ioctl (0, TIOCLINUX, &twelve) < 0)
+ flags |= LOADER_FLAGS_SERIAL;
+ }
optCon = poptGetContext(NULL, argc, argv, optionTable, 0);
@@ -1872,6 +1986,9 @@ int main(int argc, char ** argv) {
manualDeviceCheck(modInfo, modLoaded, modDeps, &kd, flags);
}
+ if (FL_UPDATES(flags))
+ loadUpdates(&kd, modLoaded, modDeps, flags);
+
loadUfs(&kd, modLoaded, modDeps, flags);
if (!FL_TESTING(flags)) {