home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
install
/
latemethods.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-14
|
29KB
|
1,113 lines
#include <alloca.h>
#include <errno.h>
#include <fcntl.h>
#include <newt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/mtio.h>
#include <unistd.h>
#include "hd.h"
#include "fs.h"
#include "ftp.h"
#include "install.h"
#include "log.h"
#include "methods.h"
#include "net.h"
#include "scsi.h"
#include "windows.h"
struct ftpinfo {
char * address;
char * login;
char * password;
char * prefix;
char * proxy;
int sock;
struct pkgSet ps;
};
struct hdinfo {
char * device;
char * type;
char * dir;
};
struct tapeCatalogEntry {
char * filename;
int size;
};
struct tapeinfo {
int fd;
int offset;
int curr;
int catalogEntries;
struct tapeCatalogEntry * catalog;
};
/* This was split into two pieces to keep the initial install program small */
static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename);
static int ftpinstFinishTransfer(struct ftpinfo * fi);
static int ftpinstGetMappedFile(struct installMethod * method, char * name,
char ** realName, int isPreskel);
static int imageGetFile(struct installMethod * method, char * name,
char ** realName, int isPreskel);
static int singleimageSetSymlinks(struct installMethod * method,
struct partitionTable table,
struct netConfig * netc,
struct netInterface * intf,
struct driversLoaded ** dl);
static int hdSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl);
static int hdPrepareMedia(struct installMethod * method,
struct fstab * fstab);
static int hdGetPackageSet(struct installMethod * method,
struct pkgSet * ps);
static int hdGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs);
static int ftpSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl);
static int ftpGetPackageSet(struct installMethod * method,
struct pkgSet * ps);
static int ftpGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs);
static int imageGetPackageSet(struct installMethod * method,
struct pkgSet * ps);
static int imageGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs);
static int tapeSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl);
static int tapeGetPackageSet(struct installMethod * method,
struct pkgSet * ps);
static int tapeGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs);
static int tapeGetMappedFile(struct installMethod * method, char * name,
char ** realName, int isPreskel);
#ifdef __i386__
static int smbSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl);
static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr,
char ** pwptr);
static int smbGetPackageSet(struct installMethod * method,
struct pkgSet * ps);
static int smbGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs);
#endif
static struct installMethod methods[] = {
{ "Local CDROM", "cdrom", 0, NULL, singleimageSetSymlinks,
imageGetFile,
imageGetPackageSet, imageGetComponentSet, NULL, NULL },
{ "NFS image", "nfs", 0, NULL, singleimageSetSymlinks,
imageGetFile,
imageGetPackageSet, imageGetComponentSet, NULL, NULL },
{ "hard drive", "hd", 0, NULL, hdSetup, imageGetFile,
hdGetPackageSet, hdGetComponentSet, hdPrepareMedia, NULL },
{ "FTP", "ftp", 1, NULL, ftpSetup, ftpinstGetMappedFile,
ftpGetPackageSet, ftpGetComponentSet, NULL, NULL },
#ifdef __i386__
{ "SMB image", "smb", 0, NULL, smbSetup,
imageGetFile,
smbGetPackageSet, smbGetComponentSet, NULL, NULL },
#endif
{ "SCSI Tape", "tape", 1, NULL, tapeSetup, tapeGetMappedFile,
tapeGetPackageSet, tapeGetComponentSet, NULL },
} ;
static int numMethods = sizeof(methods) / sizeof(struct installMethod);
struct installMethod * findInstallMethod(char * argptr) {
int i;
for (i = 0; i < numMethods; i++)
if (!strcmp(argptr, methods[i].abbrev)) return (methods + i);
return NULL;
}
static int imageGetFile(struct installMethod * method, char * name,
char ** realName, int isPreskel) {
static char buf[300];
if (!strcmp(name, "hdlist") || !strcmp(name, "rpmconvert"))
strcpy(buf, "/tmp/rhimage/RedHat/base/");
else
strcpy(buf, "/tmp/rhimage/RedHat/RPMS/");
strcat(buf, name);
*realName = buf;
return 0;
}
static int hdSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl) {
newtComponent okay, cancel, form, text, listbox, label, answer, dirEntry;
int i, j;
char buf[80];
struct partition * part = NULL;
char * type;
char * dir;
char * dest;
char * defaultDevice;
char * defaultDir;
int done = 0;
struct hdinfo * hdi;
if (method->data) {
hdi = method->data;
defaultDir = strdup(hdi->dir);
defaultDevice = hdi->device;
} else {
defaultDir = strdup("/");
defaultDevice = "";
}
while (!done) {
newtCenteredWindow(64, 17, "Select Partition");
text = newtTextbox(1, 1, 62, 4, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text, "What partition and directory on that "
"partition hold the RedHat/RPMS and "
"RedHat/base directories?");
okay = newtButton(15, 13, "Ok");
cancel = newtButton(38, 13, "Cancel");
form = newtForm(NULL, NULL, 0);
listbox = newtListbox(7, 5, 5, NEWT_LISTBOX_RETURNEXIT);
label =
newtLabel(5, 4, " Device Begin End Size (k)");
for (i = 0, j = 0; i < table.count; i++) {
if (table.parts[i].type == PART_EXT2 ||
table.parts[i].type == PART_DOS) {
sprintf(buf, "/dev/%-5s %9d %9d %9d", table.parts[i].device,
table.parts[i].begin, table.parts[i].end,
table.parts[i].size);
newtListboxAddEntry(listbox, buf, &table.parts[i]);
if (!strcmp(table.parts[i].device, defaultDevice)) {
newtListboxSetCurrent(listbox, j);
}
j++;
}
}
newtFormAddComponent(form,
newtLabel(1, 11, "Directory holding Red Hat:"));
dirEntry = newtEntry(28, 11, defaultDir, 28, &dir, NEWT_ENTRY_SCROLL);
newtFormAddComponents(form, text, label, listbox, dirEntry,
okay, cancel, NULL);
answer = newtRunForm(form);
if (answer != cancel) {
part = newtListboxGetCurrent(listbox);
}
dir = strdup(dir);
free(defaultDir);
defaultDir = dir;
defaultDevice = part->device;
newtFormDestroy(form);
newtPopWindow();
if (answer == cancel) return INST_CANCEL;
switch (part->type) {
case PART_EXT2: type = "ext2"; break;
case PART_DOS: type = "msdos"; break;
default: continue;
}
if (doMount(part->device, "/tmp/hdimage", type, 1, 0))
continue;
unlink("/tmp/rhimage");
/* the physical device is mounted on /tmp/hdimage, but all
access are through /tmp/rhimage which points to the RedHat
directory in /tmp/hdimage */
dest = alloca(strlen(dir) + 20);
sprintf(dest, "/tmp/hdimage/%s", dir);
if (symlink(dest, "/tmp/rhimage")) {
newtWinMessage("Error", "Ok", "Failed to create /tmp/rhimage "
"symlink: %s", strerror(errno));
umount("/tmp/hdimage");
continue;
}
if (access("/tmp/rhimage/RedHat/base/hdlist", R_OK)) {
newtWinMessage("Error", "Ok",
"Device %s does not appear to contain "
"a Red Hat installation tree.", part->device);
umount("/tmp/hdimage");
continue;
}
if (method->data) {
hdi = method->data;
free(hdi->dir);
}
hdi = malloc(sizeof(*hdi));
hdi->device = part->device;
hdi->type = type;
hdi->dir = strdup(dir);
method->data = hdi;
done = 1;
umount("/tmp/hdimage");
}
return 0;
}
static int hdGetPackageSet(struct installMethod * method,
struct pkgSet * ps) {
struct hdinfo * hdi = method->data;
int rc;
if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
return INST_ERROR;
rc = psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps);
umount("/tmp/hdimage");
return rc;
}
static int hdGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs) {
struct hdinfo * hdi = method->data;
int rc;
if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
return INST_ERROR;
rc = psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
umount("/tmp/hdimage");
return rc;
}
static int hdPrepareMedia(struct installMethod * method,
struct fstab * fstab) {
struct hdinfo * hdi = method->data;
int i;
char * buf;
for (i = 0; i < fstab->numEntries; i++) {
if (fstab->entries[i].isMounted &&
!strcmp(fstab->entries[i].device, hdi->device)) break;
}
if (i < fstab->numEntries) {
logMessage("device %s is already mounted -- using symlink",
fstab->entries[i].device);
buf = alloca(strlen(fstab->entries[i].mntpoint) + 10);
sprintf(buf, "/mnt/%s", fstab->entries[i].mntpoint);
rmdir("/tmp/hdimage");
if (symlink(buf, "/tmp/hdimage")) {
logMessage("failed to create symlink %s: %s\n",
buf, strerror(errno));
newtWinMessage("Error", "Ok",
"Failed to create symlink for package source.");
return INST_ERROR;
}
} else {
logMessage("mounting device which contains packages");
if (doMount(hdi->device, "/tmp/hdimage", hdi->type, 1, 0))
return INST_ERROR;
}
return 0;
}
static int imageGetPackageSet(struct installMethod * method,
struct pkgSet * ps) {
return psFromHeaderListFile("/tmp/rhimage/RedHat/base/hdlist", ps);
}
static int imageGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs) {
return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
}
static int singleimageSetSymlinks(struct installMethod * method,
struct partitionTable table,
struct netConfig * netc,
struct netInterface * intf,
struct driversLoaded ** dl) {
logMessage("making symlink from /tmp/rhimage to image");
symlink("rhimage", "/tmp/image");
return 0;
}
/* returns a socket file descriptor, a ftpFinishTransfer() must occur after
this call */
static int ftpinstStartTransfer(struct ftpinfo * fi, char * filename) {
char * buf;
newtComponent form;
int fd;
logMessage("ftping %s to a fd", filename);
newtCenteredWindow(60, 3, "Retrieving");
buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
sprintf(buf, "Retrieving %s...", filename);
form = newtForm(NULL, NULL, 0);
newtFormAddComponent(form, newtLabel(1, 1, buf));
newtDrawForm(form);
newtRefresh();
strcpy(buf, fi->prefix);
strcat(buf, "/RedHat/");
strcat(buf, filename);
fd = ftpGetFileDesc(fi->sock, buf);
return fd;
}
static int ftpinstFinishTransfer(struct ftpinfo * fi) {
newtPopWindow();
return ftpGetFileDone(fi->sock);
}
static int ftpinstGetFile(struct ftpinfo * fi, char * filename, char * dest) {
char * buf;
newtComponent form;
int fd, rc;
logMessage("ftping %s as %s", filename, dest);
newtCenteredWindow(60, 3, "Retrieving");
buf = alloca(strlen(fi->prefix) + strlen(filename) + 30);
sprintf(buf, "Retrieving %s...", filename);
form = newtForm(NULL, NULL, 0);
newtFormAddComponent(form, newtLabel(1, 1, buf));
newtDrawForm(form);
newtRefresh();
fd = open(dest, O_WRONLY | O_CREAT, 0644);
if (fd < 0) {
newtWinMessage("Error", "Ok", "open of %s failed: %s\n", dest,
strerror(errno));
return INST_ERROR;
}
strcpy(buf, fi->prefix);
strcat(buf, "/RedHat/");
strcat(buf, filename);
rc = ftpGetFile(fi->sock, buf, fd);
close(fd);
newtFormDestroy(form);
newtPopWindow();
if (rc) {
newtWinMessage("ftp", "Ok", "I cannot get file %s: %s\n", buf,
ftpStrerror(rc));
return INST_ERROR;
}
return 0;
}
static int ftpMainSetupPanel(struct ftpinfo * fi, char * doSecondarySetup) {
newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text, cb;
char * site, * dir;
if (fi->address) {
site = fi->address;
dir = fi->prefix;
} else {
site = "";
dir = "";
}
if (fi->login || fi->password || fi->login)
*doSecondarySetup = 'X';
else
*doSecondarySetup = ' ';
newtCenteredWindow(50, 17, "FTP Setup");
form = newtForm(NULL, NULL, 0);
okay = newtButton(10, 13, "Ok");
cancel = newtButton(30, 13, "Cancel");
text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"Please enter the following information:\n"
"\n"
" o the name or IP number of your FTP server\n"
" o the directory on that server containing\n"
" Red Hat Linux for your architecure\n");
newtFormAddComponent(form, newtLabel(3, 8, "FTP site name :"));
newtFormAddComponent(form, newtLabel(3, 9, "Red Hat directory:"));
siteEntry = newtEntry(22, 8, site, 24, &site, NEWT_ENTRY_SCROLL);
dirEntry = newtEntry(22, 9, dir, 24, &dir, NEWT_ENTRY_SCROLL);
cb = newtCheckbox(3, 11, "Use non-anonymous ftp or a proxy server",
*doSecondarySetup, NULL, doSecondarySetup);
newtFormAddComponents(form, text, siteEntry, dirEntry, cb, okay, cancel,
NULL);
answer = newtRunForm(form);
if (answer == cancel) {
newtFormDestroy(form);
newtPopWindow();
return INST_CANCEL;
}
if (fi->address) free(fi->address);
fi->address = strdup(site);
if (fi->prefix) free(fi->prefix);
fi->prefix = strdup(dir);
newtFormDestroy(form);
newtPopWindow();
return 0;
}
static int ftpSecondarySetupPanel(struct ftpinfo * fi) {
newtComponent form, okay, cancel, answer, text, accountEntry;
newtComponent passwordEntry, proxyEntry;
char * account, * password, * proxy;
newtCenteredWindow(50, 15, "Further FTP Setup");
form = newtForm(NULL, NULL, 0);
okay = newtButton(10, 11, "Ok");
cancel = newtButton(30, 11, "Cancel");
text = newtTextbox(1, 1, 47, 8, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"If you are using non anonymous ftp, enter the account "
"name and password you wish to use below. If you are "
"using an FTP proxy enter the name of the FTP proxy server "
"to use.");
newtFormAddComponent(form, newtLabel(3, 6, "Account name :"));
newtFormAddComponent(form, newtLabel(3, 7, "Password :"));
newtFormAddComponent(form, newtLabel(3, 9, "FTP Proxy :"));
accountEntry = newtEntry(18, 6, fi->login, 24, &account, NEWT_ENTRY_SCROLL);
passwordEntry = newtEntry(18, 7, NULL, 24, &password,
NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN);
proxyEntry = newtEntry(18, 9, fi->proxy, 24, &proxy, NEWT_ENTRY_SCROLL);
newtFormAddComponents(form, text, accountEntry, passwordEntry, proxyEntry,
okay, cancel, NULL);
answer = newtRunForm(form);
if (answer == cancel) {
newtFormDestroy(form);
newtPopWindow();
return INST_CANCEL;
}
if (fi->login) free(fi->login);
if (strlen(account))
fi->login = strdup(account);
else
fi->login = NULL;
if (fi->password) free(fi->password);
if (strlen(password))
fi->password = strdup(password);
else
fi->password = NULL;
if (fi->proxy) free(fi->proxy);
if (strlen(proxy))
fi->proxy = strdup(proxy);
else
fi->proxy = NULL;
newtFormDestroy(form);
newtPopWindow();
return 0;
}
static int ftpSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl) {
struct ftpinfo fi;
enum { FTP_SETUP_NET, FTP_SETUP_FTP1, FTP_SETUP_FTP2, FTP_SETUP_CHECK,
FTP_SETUP_DONE } step = FTP_SETUP_NET;
int rc, fd;
char doMore;
memset(&fi, 0, sizeof(fi));
if (method->data)
memcpy(&fi, method->data, sizeof(fi));
else
memset(&fi, 0, sizeof(fi));
while (step != FTP_SETUP_DONE) {
switch (step) {
case FTP_SETUP_NET:
rc = bringUpNetworking(intf, netc, dl);
if (rc) return rc;
step = FTP_SETUP_FTP1;
break;
case FTP_SETUP_FTP1:
rc = ftpMainSetupPanel(&fi, &doMore);
if (rc == INST_ERROR)
return rc;
else if (rc)
step = FTP_SETUP_NET;
else if (doMore == ' ')
step = FTP_SETUP_CHECK;
else
step = FTP_SETUP_FTP2;
break;
case FTP_SETUP_FTP2:
rc = ftpSecondarySetupPanel(&fi);
if (rc == INST_ERROR)
return rc;
else if (rc)
step = FTP_SETUP_FTP1;
else
step = FTP_SETUP_CHECK;
break;
case FTP_SETUP_CHECK:
if ((fi.sock = ftpOpen(fi.address, fi.login,
fi.password ? fi.password : "rhinstall@",
fi.proxy, -1)) < 0) {
newtWinMessage("ftp", "Ok", "I cannot log into machine: %s\n",
ftpStrerror(fi.sock));
step = FTP_SETUP_FTP1;
break;
}
fd = ftpinstStartTransfer(&fi, "base/hdlist");
if (fd < 0) {
newtPopWindow();
ftpClose(fi.sock);
step = FTP_SETUP_FTP1;
break;
}
if (psFromHeaderListDesc(fd, &fi.ps, 1)) {
ftpClose(fi.sock);
step = FTP_SETUP_FTP1;
break;
}
ftpinstFinishTransfer(&fi);
if (ftpinstGetFile(&fi, "base/comps", "/tmp/comps")) {
ftpClose(fi.sock);
step = FTP_SETUP_FTP1;
break;
}
step = FTP_SETUP_DONE;
break;
case FTP_SETUP_DONE:
break;
}
}
if (method->data) free(method->data);
method->data = malloc(sizeof(fi));
memcpy(method->data, &fi, sizeof(fi));
return 0;
}
static int ftpGetPackageSet(struct installMethod * method,
struct pkgSet * ps) {
struct ftpinfo * fi = method->data;
*ps = fi->ps;
return 0;
}
static int ftpGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs) {
return psReadComponentsFile("/tmp/comps", ps, cs);
}
static int ftpinstGetMappedFile(struct installMethod * method, char * name,
char ** realName, int isPreskel) {
static char sbuf[300];
char * buf;
int rc;
struct ftpinfo * fi = method->data;
if (isPreskel)
strcpy(sbuf, "/mnt/");
else
strcpy(sbuf, "/mnt/var/tmp/");
strcat(sbuf, name);
*realName = sbuf;
buf = alloca(strlen(name) + 30);
if (!strcmp(name, "hdlist") || !strcmp(name, "rpmconvert"))
strcpy(buf, "base/");
else
strcpy(buf, "RPMS/");
strcat(buf, name);
rc = ftpinstGetFile(fi, buf, *realName);
if (!rc) return 0;
/* Try again, and relogin */
ftpClose(fi->sock);
if ((fi->sock = ftpOpen(fi->address, fi->login,
fi->password ? fi->password : "rhinstall@",
fi->proxy, -1))
< 0) {
newtWinMessage("ftp", "Ok", "I cannot log into machine: %s\n",
ftpStrerror(fi->sock));
free(fi);
return INST_ERROR;
}
return ftpinstGetFile(fi, buf, *realName);
}
int tapeOp(int fd, int cmd, int count, int reportErr) {
struct mtop mtcmd;
mtcmd.mt_op = cmd;
mtcmd.mt_count = count;
if (ioctl(fd, MTIOCTOP, &mtcmd)) {
if (reportErr)
newtWinMessage("Tape Error", "Ok", "tape ioctl %d failed: %s",
cmd, strerror(errno));
return 1;
}
return 0;
}
static int tapeSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl) {
int rc;
int fd;
int catalogAlloced;
struct tapeinfo * info;
char magic[5];
int foundit = 0;
char catalogBuf[16384];
char * chptr, * start, * next;
int offset = 0;
/* eventually we should support devices other then /dev/nst0 */
if ((rc = setupSCSIInterfaces(1, dl))) return rc;
if ((rc = devMakeInode("nst0", "/tmp/nst0"))) return rc;
if ((fd = open("/tmp/nst0", O_RDONLY)) < 0) {
devRemoveInode("/tmp/nst0");
if (errno == ENODEV) {
newtWinMessage("Error", "Ok", "I couldn't find any SCSI tape drives.");
} else {
errorWindow("Error opening device nst0: %s");
}
return INST_ERROR;
}
winStatus(45, 3, "Tape", "Looking for Red Hat tape image...");
/* now, let's see if we can find the file on the tape */
if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) {
if (!strcmp(magic, "1234\n")) {
logMessage("found magic on first try");
foundit = 1;
}
} else if (rc < 0) {
newtWinMessage("Error", "Ok", "Error reading from tape: %s", strerror(errno));
}
if (!foundit) {
logMessage("seeking to next file");
if (tapeOp(fd, MTFSF, 1, 0)) {
logMessage("failed to find beginning of next file: %s",
strerror(errno));
} else {
if ((rc = read(fd, magic, sizeof(magic))) == sizeof(magic)) {
if (!strcmp(magic, "1234\n")) {
logMessage("found magic on second try");
foundit = 1;
offset = 1;
}
}
}
}
if (!foundit) {
errorWindow("I can't find the Red Hat tape installation image"
"on that tape.");
close(fd);
newtPopWindow();
return INST_ERROR;
}
if ((rc = read(fd, catalogBuf, sizeof(catalogBuf) - 1)) < 0) {
errorWindow("Error reading file catalog from tape: %s");
newtPopWindow();
close(fd);
return INST_ERROR;
}
newtPopWindow();
info = malloc(sizeof(*info));
info->fd = fd;
info->offset = offset;
info->curr = -1;
method->data = info;
/* read in the catalog */
catalogAlloced = 20;
info->catalog = malloc(sizeof(*info->catalog) * catalogAlloced);
info->catalogEntries = 0;
start = catalogBuf;
while (strncmp(start, "--done--", 8)) {
chptr = strchr(start, '\n');
next = chptr + 1;
*chptr = '\0';
while (*chptr != ' ') chptr--;
*chptr = '\0';
chptr++;
if (info->catalogEntries == catalogAlloced) {
catalogAlloced += 20;
info->catalog = realloc(info->catalog,
sizeof(*info->catalog) * catalogAlloced);
}
info->catalog[info->catalogEntries].filename = strdup(start);
info->catalog[info->catalogEntries].size = strtoul(chptr, NULL, 10);
info->catalogEntries++;
start = next;
}
return 0;
}
static int tapeGetPackageSet(struct installMethod * method,
struct pkgSet * ps) {
struct tapeinfo * info = method->data;
if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR;
info->curr++;
return psFromHeaderListDesc(info->fd, ps, 1);
}
static int tapeCopyFile(struct tapeinfo * info, char * tapename, char * out) {
int outfd;
char buf[4096];
int i;
int total, amount;
int done = 0;
/* let's figure out where we need to go */
for (i = 0; i < info->catalogEntries; i++) {
if (!strcmp(tapename, info->catalog[i].filename)) break;
}
if (i < 0) {
newtWinMessage("Error", "Ok", "I can't find file %s on the tape", tapename);
return INST_ERROR;
}
if (i < info->curr) {
newtWinMessage("Error", "Ok", "The tape is not positioned properly");
return INST_ERROR;
} else {
logMessage("skipping %d files on the tape to get to %s",
i - info->curr, tapename);
while (i > info->curr) {
if (tapeOp(info->fd, MTFSF, 1, 1)) return INST_ERROR;
logMessage("skipped file");
info->curr++;
}
}
if ((outfd = open(out, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0) {
newtWinMessage("Error", "Ok", "failed to create %s: %s", out,
strerror(errno));
return INST_ERROR;
}
total = 0;
while (!done) {
amount = read(info->fd, buf, sizeof(buf));
if (amount < 0)
break;
if (((total + amount) > info->catalog[i].size)) {
done = 1;
amount = info->catalog[i].size - total;
}
if (write(outfd, buf, amount) != amount) {
newtWinMessage("Error", "Ok", "failed to write to %s: %s", out,
strerror(errno));
close(outfd);
return INST_ERROR;
}
total += amount;
}
if (i < 0) {
newtWinMessage("Error", "Ok", "failed to read from tape: %s", out,
strerror(errno));
close(outfd);
return INST_ERROR;
}
close(outfd);
return 0;
}
static int tapeGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs) {
struct tapeinfo * info = method->data;
int rc;
if ((rc = tapeCopyFile(info, "comps", "/tmp/comps"))) return rc;
return psReadComponentsFile("/tmp/comps", ps, cs);
}
static int tapeGetMappedFile(struct installMethod * method, char * name,
char ** realName, int isPreskel) {
static char sbuf[300];
int rc;
struct tapeinfo * info = method->data;
if (isPreskel)
strcpy(sbuf, "/mnt/");
else
strcpy(sbuf, "/mnt/var/tmp/");
strcat(sbuf, name);
*realName = sbuf;
return (rc = tapeCopyFile(info, name, sbuf));
}
#ifdef __i386__
static int smbSetup(struct installMethod * method, struct partitionTable table,
struct netConfig * netc, struct netInterface * intf,
struct driversLoaded ** dl) {
char * host = NULL, * dir = NULL, * acct = NULL, * pass = NULL;
char * buf;
static int moduleLoaded = 0;
enum { SMB_STEP_NET, SMB_STEP_INFO, SMB_STEP_MOUNT, SMB_STEP_DONE }
step = SMB_STEP_NET;
int rc;
while (step != SMB_STEP_DONE) {
switch (step) {
case SMB_STEP_NET:
rc = bringUpNetworking(intf, netc, dl);
if (rc) return rc;
step = SMB_STEP_INFO;
break;
case SMB_STEP_INFO:
rc = smbGetSetup(&host, &dir, &acct, &pass);
if (rc == INST_CANCEL)
step = SMB_STEP_NET;
else if (rc == INST_ERROR)
return INST_ERROR;
else
step = SMB_STEP_MOUNT;
break;
case SMB_STEP_MOUNT:
if (!strlen(host) || !strlen(dir))
rc = INST_ERROR;
else {
buf = malloc(strlen(host) + strlen(dir) + 10);
strcpy(buf, host);
strcat(buf, ":");
strcat(buf, dir);
if (!moduleLoaded) {
rc = loadModule("smbfs", DRIVER_FS, DRIVER_MINOR_NONE, dl);
if (rc) return rc;
moduleLoaded = 1;
}
rc = doPwMount(buf, "/tmp/rhimage", "smb", 1, 0, acct, pass);
free(buf);
}
if (rc) {
step = SMB_STEP_INFO;
newtWinMessage("Error", "Ok",
"I could not mount that directory from the server");
} else {
if (access("/tmp/rhimage/RedHat", R_OK)) {
step = SMB_STEP_INFO;
newtWinMessage("Error", "Ok", "That directory does not seem "
"to contain a Red Hat installation tree.");
umount("/tmp/rhimage");
} else
step = SMB_STEP_DONE;
}
break;
case SMB_STEP_DONE:
break;
}
}
free(host);
free(dir);
return 0;
}
static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr,
char ** pwptr) {
newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text;
newtComponent acctEntry, passEntry;
char * site, * dir, * acct, * pass;
if (*hostptr) {
site = *hostptr;
dir = *dirptr;
acct = *acctptr;
pass = *pwptr;
} else {
site = "";
dir = "";
acct = "";
pass = "";
}
newtCenteredWindow(50, 16, "SMB Setup");
form = newtForm(NULL, NULL, 0);
okay = newtButton(10, 12, "Ok");
cancel = newtButton(30, 12, "Cancel");
text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text,
"Please enter the following information:\n"
"\n"
" o the name or IP number of your SMB server\n"
" o the volume to share which contains\n"
" Red Hat Linux for your architecture");
newtFormAddComponent(form, newtLabel(3, 7, "SMB server name :"));
newtFormAddComponent(form, newtLabel(3, 8, "Share volume :"));
newtFormAddComponent(form, newtLabel(3, 9, "Account name :"));
newtFormAddComponent(form, newtLabel(3, 10, "Password :"));
siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL);
dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL);
acctEntry = newtEntry(22, 9, "guest", 24, &acct, NEWT_ENTRY_SCROLL);
passEntry = newtEntry(22, 10, pass, 24, &pass,
NEWT_ENTRY_SCROLL | NEWT_ENTRY_HIDDEN);
newtFormAddComponents(form, text, siteEntry, dirEntry, acctEntry,
passEntry, okay, cancel, NULL);
answer = newtRunForm(form);
if (answer == cancel) {
newtFormDestroy(form);
newtPopWindow();
return INST_CANCEL;
}
*hostptr = strdup(site);
*dirptr = strdup(dir);
*acctptr = strdup(acct);
*pwptr = strdup(pass);
newtFormDestroy(form);
newtPopWindow();
return 0;
}
static int smbGetPackageSet(struct installMethod * method,
struct pkgSet * ps) {
return psUsingDirectory("/tmp/rhimage/RedHat/RPMS", ps);
}
static int smbGetComponentSet(struct installMethod * method,
struct pkgSet * ps,
struct componentSet * cs) {
return psReadComponentsFile("/tmp/rhimage/RedHat/base/comps", ps, cs);
}
#endif