home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / install / scsi.c < prev    next >
C/C++ Source or Header  |  1997-10-09  |  8KB  |  359 lines

  1. #include <alloca.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <newt.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/stat.h>
  9. #include <unistd.h>
  10.  
  11. #include "devices.h"
  12. #include "hd.h"
  13. #include "install.h"
  14. #include "log.h"
  15. #include "scsi.h"
  16.  
  17. static int scsiChoicePanel(int * addSCSI);
  18.  
  19. static int scsiChoicePanel(int * addSCSI) {
  20.     newtComponent label, f, answer;
  21.     newtComponent yes, no;
  22.  
  23.     newtCenteredWindow(35, 9, "SCSI Configuration");
  24.  
  25.     label = newtLabel(2, 2, "Do you have any SCSI adapters?");
  26.  
  27.     yes = newtButton(5, 5, "Yes");
  28.     no = newtButton(22, 5, "No");
  29.  
  30.     f = newtForm(NULL, NULL, 0);
  31.     newtFormAddComponents(f, label, yes, no, NULL);
  32.     newtFormSetCurrent(f, no);
  33.     
  34.     answer = newtRunForm(f);
  35.     if (answer == f) 
  36.     answer = newtFormGetCurrent(f);
  37.  
  38.     newtFormDestroy(f);
  39.     newtPopWindow();
  40.  
  41.     if (answer == no) 
  42.     *addSCSI = 0;
  43.     else
  44.     *addSCSI = 1;
  45.  
  46.     return 0;
  47. }
  48.  
  49.  
  50. int setupSCSIInterfaces(int forceConfig, struct driversLoaded ** dl) {
  51.     int rc;
  52.     int hasscsi;
  53.  
  54.     /* if this fails, autoprobe didn't work but we should keep going */
  55.     rc = loadDeviceDriver(DRIVER_SCSI, dl, 1);
  56.     if (!rc || kickstart) return 0;
  57.  
  58.     /* we may have something already available as well */
  59.     if (scsiDeviceAvailable()) return 0;
  60.  
  61.     do {
  62.     if (forceConfig)
  63.         forceConfig = 0;
  64.     else {
  65.         scsiChoicePanel(&hasscsi);
  66.         if (!hasscsi) return 0;
  67.     }
  68.  
  69.         rc = loadDeviceDriver(DRIVER_SCSI, dl, 0);
  70.     if (rc == INST_ERROR) return INST_ERROR;
  71.     } while (rc);
  72.  
  73.     return 0;
  74. }
  75.  
  76. int scsiDeviceAvailable(void) {
  77.     int fd;
  78.     char buf[80];
  79.     int i;
  80.  
  81.     fd = open("/proc/scsi/scsi", O_RDONLY);
  82.     if (fd < 0) {
  83.     logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
  84.     return 0;
  85.     }
  86.     
  87.     i = read(fd, buf, sizeof(buf) - 1);
  88.     if (i < 1) {
  89.     logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
  90.     return 0;
  91.     }
  92.     close(fd);
  93.     buf[i] = '\0';
  94.  
  95.     logMessage("/proc/scsi/scsi: %s", buf);
  96.  
  97.     if (strstr(buf, "devices: none")) {
  98.     logMessage("no scsi devices are available");
  99.     return 0;
  100.     }
  101.  
  102.     logMessage("scsi devices are available");
  103.     return 1;
  104. }
  105.  
  106. #define SCSISCSI_TOP    0
  107. #define SCSISCSI_HOST     1
  108. #define SCSISCSI_VENDOR 2
  109. #define SCSISCSI_TYPE     3
  110.  
  111. int scsiGetDevices(struct deviceInfo ** sdiPtr) {
  112.     int fd;
  113.     char buf[16384];
  114.     char linebuf[80];
  115.     char typebuf[10];
  116.     int i, state = SCSISCSI_TOP;
  117.     char * start, * chptr, * next;
  118.     char driveName = 'a';
  119.     char cdromNum = '0';
  120.     char tapeNum = '0';
  121.     int numMatches = 0;
  122.     struct deviceInfo * sdi;
  123.     int id = 0;
  124.  
  125.     /* FIXME: this should be big enough */
  126.     sdi = malloc(sizeof(*sdi) * 65);
  127.  
  128.     fd = open("/proc/scsi/scsi", O_RDONLY);
  129.     if (fd < 0) {
  130.     logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
  131.     return 1;
  132.     }
  133.     
  134.     i = read(fd, buf, sizeof(buf) - 1);
  135.     if (i < 1) {
  136.     logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
  137.     return 1;
  138.     }
  139.     close(fd);
  140.     buf[i] = '\0';
  141.  
  142.     start = buf;
  143.     while (*start) {
  144.     chptr = start;
  145.      while (*chptr != '\n') chptr++;
  146.     *chptr = '\0';
  147.     next = chptr + 1;
  148.  
  149.     switch (state) {
  150.       case SCSISCSI_TOP:
  151.         if (strcmp("Attached devices: ", start)) {
  152.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  153.         free(sdi);
  154.         return INST_ERROR;
  155.         }
  156.         state = SCSISCSI_HOST;
  157.         break;
  158.  
  159.       case SCSISCSI_HOST:
  160.         if (strncmp("Host: ", start, 6)) {
  161.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  162.         free(sdi);
  163.         return INST_ERROR;
  164.         }
  165.  
  166.         start = strstr(start, "Id: ");
  167.         if (!start) {
  168.         logMessage("Id: missing in /proc/scsi/scsi");
  169.         return INST_ERROR;
  170.         }
  171.         start += 4;
  172.  
  173.         id = strtol(start, NULL, 10);
  174.  
  175.         state = SCSISCSI_VENDOR;
  176.         break;
  177.  
  178.       case SCSISCSI_VENDOR:
  179.         if (strncmp("  Vendor: ", start, 10)) {
  180.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  181.         free(sdi);
  182.         return INST_ERROR;
  183.         }
  184.  
  185.         start += 10;
  186.         chptr = strstr(start, "Model:");
  187.         if (!chptr) {
  188.         logMessage("Model missing in /proc/scsi/scsi");
  189.         free(sdi);
  190.         return INST_ERROR;
  191.         }
  192.  
  193.         chptr--;
  194.         while (*chptr == ' ') chptr--;
  195.         *(chptr + 1) = '\0';
  196.  
  197.         strcpy(linebuf, start);
  198.         *linebuf = toupper(*linebuf);
  199.         chptr = linebuf + 1;
  200.         while (*chptr) {
  201.         *chptr = tolower(*chptr);
  202.         chptr++;
  203.         }
  204.  
  205.         start = strstr(start + strlen(linebuf) + 1, "Model:");
  206.         start += 7;
  207.         
  208.         chptr = strstr(start, "Rev:");
  209.         if (!chptr) {
  210.         logMessage("Rev missing in /proc/scsi/scsi");
  211.         free(sdi);
  212.         return INST_ERROR;
  213.         }
  214.        
  215.         chptr--;
  216.         while (*chptr == ' ') chptr--;
  217.         *(chptr + 1) = '\0';
  218.  
  219.         strcat(linebuf, " ");
  220.         strcat(linebuf, start);
  221.  
  222.         state = SCSISCSI_TYPE;
  223.  
  224.         break;
  225.  
  226.       case SCSISCSI_TYPE:
  227.         if (strncmp("  Type:", start, 7)) {
  228.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  229.         free(sdi);
  230.         return INST_ERROR;
  231.         }
  232.         *typebuf = '\0';
  233.         if (strstr(start, "Direct-Access")) {
  234.         sprintf(typebuf, "sd%c", driveName++);
  235.         sdi[numMatches].type = DEVICE_HD;
  236.         } else if (strstr(start, "Sequential-Access")) {
  237.         sprintf(typebuf, "st%c", tapeNum++);
  238.         sdi[numMatches].type = DEVICE_TAPE;
  239.         } else if (strstr(start, "CD-ROM")) {
  240.         sprintf(typebuf, "scd%c", cdromNum++);
  241.         sdi[numMatches].type = DEVICE_CDROM;
  242.         }
  243.  
  244.         if (*typebuf) {
  245.         /*sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 2));*/
  246.         sdi[numMatches].deviceName = strdup(typebuf);
  247.         sdi[numMatches].info = strdup(linebuf);
  248.         sdi[numMatches].bus = 0;
  249.         sdi[numMatches++].id = id;
  250.         }
  251.  
  252.         state = SCSISCSI_HOST;
  253.     }
  254.  
  255.     start = next;
  256.     }
  257.  
  258.     sdi[numMatches].deviceName = NULL;
  259.     sdi[numMatches].info = NULL;
  260.  
  261.     sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 1));
  262.  
  263.     *sdiPtr = sdi;
  264.  
  265.     return 0;
  266. }
  267.  
  268. /* normal string handling doesn't work here as the syslog can contain 
  269.    binary 0's! though I don't know why :-( */
  270. int ideGetDevices(struct deviceInfo ** idiPtr) {
  271.     struct deviceInfo * idi;
  272.     struct stat sb;
  273.     char * filename = testing ? "/var/log/dmesg" : "/tmp/syslog";
  274.     char * buf, * end;
  275.     char * absend;
  276.     int numMatches = 0;
  277.     int fd;
  278.     int base = testing ? 0 : 3;
  279.  
  280.     idi = malloc(sizeof(*idi) * 9);
  281.  
  282.     if (stat(filename, &sb)) {
  283.     newtWinMessage("Error", "Ok", "Failed to stat %s: %s\n", filename,
  284.             strerror(errno));
  285.     return 0;
  286.     }
  287.  
  288.     if ((fd = open(filename, O_RDONLY)) < 0) {
  289.     newtWinMessage("Error", "Ok", "Failed to open %s: %s\n", filename,
  290.             strerror(errno));
  291.     return INST_ERROR;
  292.     }
  293.    
  294.     buf = alloca(sb.st_size);
  295.     read(fd, buf, sb.st_size);
  296.     close(fd);
  297.  
  298.     absend = buf + sb.st_size;
  299.  
  300.     while (buf && buf < absend) {
  301.     if (buf[0 + base] == 'h' && buf[1 + base] == 'd' && 
  302.         buf[3 + base] == ':') {
  303.         idi[numMatches].deviceName = malloc(4);
  304.         strcpy(idi[numMatches].deviceName, "hda");
  305.         idi[numMatches].deviceName[2] = buf[2 + base];
  306.  
  307.         buf += 5 + base;
  308.         end = buf;
  309.         while (*end != '\n' && *end != ',') end++;
  310.  
  311.         if (*end == ',') {
  312.         idi[numMatches].info = malloc(end - buf + 1);
  313.         strncpy(idi[numMatches].info, buf, end - buf);
  314.         idi[numMatches].info[end - buf] = '\0';
  315.  
  316.         /* see if this is a cdrom or not */
  317.         while (*end != '\n' && 
  318.                 strncmp(end, "CDROM", 5) &&
  319.                 strncmp(end, "TAPE", 4) &&
  320.                 strncmp(end, "FLOPPY", 6) &&
  321.                 strncmp(end, "CHS", 3))
  322.                 end++;
  323.  
  324.         if (!strncmp(end, "CDROM", 5)) 
  325.             idi[numMatches].type = DEVICE_CDROM;
  326.         else if (!strncmp(end, "TAPE", 4)) 
  327.             idi[numMatches].type = DEVICE_TAPE;
  328.         else if (!strncmp(end, "FLOPPY", 6)) 
  329.             idi[numMatches].type = DEVICE_FD;
  330.         else if (!strncmp(end, "CHS", 3)) 
  331.             idi[numMatches].type = DEVICE_HD;
  332.         else
  333.             idi[numMatches].type = DEVICE_NONE;
  334.  
  335.         /* we could do better here */
  336.         idi[numMatches].bus = idi[numMatches].id = 0;
  337.  
  338.         if (idi[numMatches].type != DEVICE_NONE)
  339.             numMatches++;
  340.         }
  341.     }
  342.  
  343.     end = memchr(buf, '\n', absend - buf);
  344.     if (!end)
  345.        buf = NULL;
  346.     else
  347.        buf = end + 1;
  348.     }
  349.    
  350.     idi[numMatches].deviceName = NULL;
  351.     idi[numMatches].info = NULL;
  352.  
  353.     idi = realloc(idi, sizeof(*idi) * (numMatches + 1));
  354.  
  355.     *idiPtr = idi;
  356.  
  357.     return 0;
  358. }
  359.