#include #include #include #include #include #include #include #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; newtOpenWindow(21, 7, 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 (scsiDeviceAvailable()) return 0; do { if (forceConfig) forceConfig = 0; else { scsiChoicePanel(&hasscsi); if (!hasscsi) return 0; } rc = loadDeviceDriver(DRIVER_SCSI, dl); 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 scsiDeviceInfo ** 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 scsiDeviceInfo * sdi; int id = 0; /*sdi = malloc(sizeof(*sdi));*/ sdi = malloc(16384); 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++); else if (strstr(start, "Sequential-Access")) sprintf(typebuf, "st%c", tapeNum++); else if (strstr(start, "CD-ROM")) sprintf(typebuf, "scd%c", cdromNum++); 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; *sdiPtr = sdi; return 0; }