home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
install
/
scsi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-09
|
8KB
|
359 lines
#include <alloca.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <newt.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "devices.h"
#include "hd.h"
#include "install.h"
#include "log.h"
#include "scsi.h"
static int scsiChoicePanel(int * addSCSI);
static int scsiChoicePanel(int * addSCSI) {
newtComponent label, f, answer;
newtComponent yes, no;
newtCenteredWindow(35, 9, "SCSI Configuration");
label = newtLabel(2, 2, "Do you have any SCSI adapters?");
yes = newtButton(5, 5, "Yes");
no = newtButton(22, 5, "No");
f = newtForm(NULL, NULL, 0);
newtFormAddComponents(f, label, yes, no, NULL);
newtFormSetCurrent(f, no);
answer = newtRunForm(f);
if (answer == f)
answer = newtFormGetCurrent(f);
newtFormDestroy(f);
newtPopWindow();
if (answer == no)
*addSCSI = 0;
else
*addSCSI = 1;
return 0;
}
int setupSCSIInterfaces(int forceConfig, struct driversLoaded ** dl) {
int rc;
int hasscsi;
/* if this fails, autoprobe didn't work but we should keep going */
rc = loadDeviceDriver(DRIVER_SCSI, dl, 1);
if (!rc || kickstart) return 0;
/* we may have something already available as well */
if (scsiDeviceAvailable()) return 0;
do {
if (forceConfig)
forceConfig = 0;
else {
scsiChoicePanel(&hasscsi);
if (!hasscsi) return 0;
}
rc = loadDeviceDriver(DRIVER_SCSI, dl, 0);
if (rc == INST_ERROR) return INST_ERROR;
} while (rc);
return 0;
}
int scsiDeviceAvailable(void) {
int fd;
char buf[80];
int i;
fd = open("/proc/scsi/scsi", O_RDONLY);
if (fd < 0) {
logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
return 0;
}
i = read(fd, buf, sizeof(buf) - 1);
if (i < 1) {
logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
return 0;
}
close(fd);
buf[i] = '\0';
logMessage("/proc/scsi/scsi: %s", buf);
if (strstr(buf, "devices: none")) {
logMessage("no scsi devices are available");
return 0;
}
logMessage("scsi devices are available");
return 1;
}
#define SCSISCSI_TOP 0
#define SCSISCSI_HOST 1
#define SCSISCSI_VENDOR 2
#define SCSISCSI_TYPE 3
int scsiGetDevices(struct deviceInfo ** sdiPtr) {
int fd;
char buf[16384];
char linebuf[80];
char typebuf[10];
int i, state = SCSISCSI_TOP;
char * start, * chptr, * next;
char driveName = 'a';
char cdromNum = '0';
char tapeNum = '0';
int numMatches = 0;
struct deviceInfo * sdi;
int id = 0;
/* FIXME: this should be big enough */
sdi = malloc(sizeof(*sdi) * 65);
fd = open("/proc/scsi/scsi", O_RDONLY);
if (fd < 0) {
logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
return 1;
}
i = read(fd, buf, sizeof(buf) - 1);
if (i < 1) {
logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
return 1;
}
close(fd);
buf[i] = '\0';
start = buf;
while (*start) {
chptr = start;
while (*chptr != '\n') chptr++;
*chptr = '\0';
next = chptr + 1;
switch (state) {
case SCSISCSI_TOP:
if (strcmp("Attached devices: ", start)) {
logMessage("unexpected line in /proc/scsi/scsi: %s", start);
free(sdi);
return INST_ERROR;
}
state = SCSISCSI_HOST;
break;
case SCSISCSI_HOST:
if (strncmp("Host: ", start, 6)) {
logMessage("unexpected line in /proc/scsi/scsi: %s", start);
free(sdi);
return INST_ERROR;
}
start = strstr(start, "Id: ");
if (!start) {
logMessage("Id: missing in /proc/scsi/scsi");
return INST_ERROR;
}
start += 4;
id = strtol(start, NULL, 10);
state = SCSISCSI_VENDOR;
break;
case SCSISCSI_VENDOR:
if (strncmp(" Vendor: ", start, 10)) {
logMessage("unexpected line in /proc/scsi/scsi: %s", start);
free(sdi);
return INST_ERROR;
}
start += 10;
chptr = strstr(start, "Model:");
if (!chptr) {
logMessage("Model missing in /proc/scsi/scsi");
free(sdi);
return INST_ERROR;
}
chptr--;
while (*chptr == ' ') chptr--;
*(chptr + 1) = '\0';
strcpy(linebuf, start);
*linebuf = toupper(*linebuf);
chptr = linebuf + 1;
while (*chptr) {
*chptr = tolower(*chptr);
chptr++;
}
start = strstr(start + strlen(linebuf) + 1, "Model:");
start += 7;
chptr = strstr(start, "Rev:");
if (!chptr) {
logMessage("Rev missing in /proc/scsi/scsi");
free(sdi);
return INST_ERROR;
}
chptr--;
while (*chptr == ' ') chptr--;
*(chptr + 1) = '\0';
strcat(linebuf, " ");
strcat(linebuf, start);
state = SCSISCSI_TYPE;
break;
case SCSISCSI_TYPE:
if (strncmp(" Type:", start, 7)) {
logMessage("unexpected line in /proc/scsi/scsi: %s", start);
free(sdi);
return INST_ERROR;
}
*typebuf = '\0';
if (strstr(start, "Direct-Access")) {
sprintf(typebuf, "sd%c", driveName++);
sdi[numMatches].type = DEVICE_HD;
} else if (strstr(start, "Sequential-Access")) {
sprintf(typebuf, "st%c", tapeNum++);
sdi[numMatches].type = DEVICE_TAPE;
} else if (strstr(start, "CD-ROM")) {
sprintf(typebuf, "scd%c", cdromNum++);
sdi[numMatches].type = DEVICE_CDROM;
}
if (*typebuf) {
/*sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 2));*/
sdi[numMatches].deviceName = strdup(typebuf);
sdi[numMatches].info = strdup(linebuf);
sdi[numMatches].bus = 0;
sdi[numMatches++].id = id;
}
state = SCSISCSI_HOST;
}
start = next;
}
sdi[numMatches].deviceName = NULL;
sdi[numMatches].info = NULL;
sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 1));
*sdiPtr = sdi;
return 0;
}
/* normal string handling doesn't work here as the syslog can contain
binary 0's! though I don't know why :-( */
int ideGetDevices(struct deviceInfo ** idiPtr) {
struct deviceInfo * idi;
struct stat sb;
char * filename = testing ? "/var/log/dmesg" : "/tmp/syslog";
char * buf, * end;
char * absend;
int numMatches = 0;
int fd;
int base = testing ? 0 : 3;
idi = malloc(sizeof(*idi) * 9);
if (stat(filename, &sb)) {
newtWinMessage("Error", "Ok", "Failed to stat %s: %s\n", filename,
strerror(errno));
return 0;
}
if ((fd = open(filename, O_RDONLY)) < 0) {
newtWinMessage("Error", "Ok", "Failed to open %s: %s\n", filename,
strerror(errno));
return INST_ERROR;
}
buf = alloca(sb.st_size);
read(fd, buf, sb.st_size);
close(fd);
absend = buf + sb.st_size;
while (buf && buf < absend) {
if (buf[0 + base] == 'h' && buf[1 + base] == 'd' &&
buf[3 + base] == ':') {
idi[numMatches].deviceName = malloc(4);
strcpy(idi[numMatches].deviceName, "hda");
idi[numMatches].deviceName[2] = buf[2 + base];
buf += 5 + base;
end = buf;
while (*end != '\n' && *end != ',') end++;
if (*end == ',') {
idi[numMatches].info = malloc(end - buf + 1);
strncpy(idi[numMatches].info, buf, end - buf);
idi[numMatches].info[end - buf] = '\0';
/* see if this is a cdrom or not */
while (*end != '\n' &&
strncmp(end, "CDROM", 5) &&
strncmp(end, "TAPE", 4) &&
strncmp(end, "FLOPPY", 6) &&
strncmp(end, "CHS", 3))
end++;
if (!strncmp(end, "CDROM", 5))
idi[numMatches].type = DEVICE_CDROM;
else if (!strncmp(end, "TAPE", 4))
idi[numMatches].type = DEVICE_TAPE;
else if (!strncmp(end, "FLOPPY", 6))
idi[numMatches].type = DEVICE_FD;
else if (!strncmp(end, "CHS", 3))
idi[numMatches].type = DEVICE_HD;
else
idi[numMatches].type = DEVICE_NONE;
/* we could do better here */
idi[numMatches].bus = idi[numMatches].id = 0;
if (idi[numMatches].type != DEVICE_NONE)
numMatches++;
}
}
end = memchr(buf, '\n', absend - buf);
if (!end)
buf = NULL;
else
buf = end + 1;
}
idi[numMatches].deviceName = NULL;
idi[numMatches].info = NULL;
idi = realloc(idi, sizeof(*idi) * (numMatches + 1));
*idiPtr = idi;
return 0;
}