home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / scsi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-10  |  8.8 KB  |  393 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 <dirent.h>
  9. #include <sys/stat.h>
  10. #include <unistd.h>
  11.  
  12. #include "devices.h"
  13. #include "hd.h"
  14. #include "intl.h"
  15. #include "install.h"
  16. #include "log.h"
  17. #include "scsi.h"
  18.  
  19. static int scsiChoicePanel(int * addSCSI);
  20.  
  21. static int scsiChoicePanel(int * addSCSI) {
  22.     int rc;
  23.     DIR * dir;
  24.     struct dirent * ent;
  25.     char buffer[4000];
  26.     int foundSome;
  27.  
  28.     dir = opendir("/proc/scsi"), foundSome = 0;
  29.     if (dir) {
  30.     strcpy(buffer, _("I have found the following types of SCSI "
  31.         "adapters on your system:\n\n"));
  32.     errno = 0;
  33.     while ((ent = readdir(dir))) {
  34.         if (*ent->d_name == '.') continue;
  35.         if (!strcmp("scsi", ent->d_name)) continue;
  36.  
  37.         strcat(buffer, "\t");
  38.         strcat(buffer, getModuleDescription(ent->d_name));
  39.         strcat(buffer, "\n");
  40.         foundSome = 1;
  41.     }
  42.  
  43.     closedir(dir);
  44.  
  45.     strcat(buffer, 
  46.         _("\nDo you have any more SCSI adapters on your system?"));
  47.     } 
  48.  
  49.     if (!foundSome) {
  50.     strcpy(buffer, _("Do you have any SCSI adapters?"));
  51.     }
  52.  
  53.     rc = newtWinTernary(_("SCSI Configuration"), _("No"), _("Yes"), 
  54.             _("Back"), buffer);
  55.  
  56.     if (rc == 3)
  57.     return INST_CANCEL;
  58.     else if (rc == 2)
  59.     *addSCSI = 1;
  60.     else
  61.     *addSCSI = 0;
  62.  
  63.     return 0;
  64. }
  65.  
  66.  
  67. int setupSCSIInterfaces(int forceConfig, struct driversLoaded ** dl,
  68.             int automatic, int dir) {
  69.     int rc;
  70.     int hasscsi = 1;
  71.  
  72.     /* First of all, autodetect all the SCSI devices we can. */
  73.     rc = loadDeviceDriver(DRIVER_SCSI, dl, DEVICE_JUSTPROBE | DEVICE_NOPAUSE);
  74.     if (automatic) return dir < 0 ? INST_CANCEL : INST_OKAY;
  75.     if (rc == INST_CANCEL) return INST_CANCEL;
  76.  
  77. #if defined(__sparc__) || defined(__alpha__)
  78.     rc = dir < 0 ? INST_CANCEL : INST_OKAY;
  79. #else
  80.     /* There could be undetected (ISA) SCSI adapters sitting around
  81.        still (or we could be in expert mode where we don't autodetect
  82.        these things. So, give the user a chance for manual configuration
  83.        now. */
  84.  
  85.     while (hasscsi) {
  86.     if (forceConfig) {
  87.         forceConfig = 0;
  88.         hasscsi = 1;
  89.     } else {
  90.         if (scsiChoicePanel(&hasscsi) == INST_CANCEL) return INST_CANCEL;
  91.     }
  92.  
  93.     if (hasscsi) {
  94.         rc = loadDeviceDriver(DRIVER_SCSI, dl, DEVICE_NOPROBE);
  95.         if (rc == INST_ERROR) hasscsi = 0;    /* break out */
  96.     } else {
  97.         rc = 0;
  98.     }
  99.     } 
  100. #endif
  101.  
  102.     return rc;
  103. }
  104.  
  105. int scsiDeviceAvailable(void) {
  106.     int fd;
  107.     char buf[80];
  108.     int i;
  109.  
  110.     fd = open("/proc/scsi/scsi", O_RDONLY);
  111.     if (fd < 0) {
  112.     logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
  113.     return 0;
  114.     }
  115.     
  116.     i = read(fd, buf, sizeof(buf) - 1);
  117.     if (i < 1) {
  118.     logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
  119.     return 0;
  120.     }
  121.     close(fd);
  122.     buf[i] = '\0';
  123.  
  124.     logMessage("/proc/scsi/scsi: %s", buf);
  125.  
  126.     if (strstr(buf, "devices: none")) {
  127.     logMessage("no scsi devices are available");
  128.     return 0;
  129.     }
  130.  
  131.     logMessage("scsi devices are available");
  132.     return 1;
  133. }
  134.  
  135. #define SCSISCSI_TOP    0
  136. #define SCSISCSI_HOST     1
  137. #define SCSISCSI_VENDOR 2
  138. #define SCSISCSI_TYPE     3
  139.  
  140. int scsiGetDevices(struct deviceInfo ** sdiPtr) {
  141.     int fd;
  142.     char buf[16384];
  143.     char linebuf[80];
  144.     char typebuf[10];
  145.     int i, state = SCSISCSI_TOP;
  146.     char * start, * chptr, * next, *end;
  147.     char driveName = 'a';
  148.     char cdromNum = '0';
  149.     char tapeNum = '0';
  150.     int numMatches = 0;
  151.     struct deviceInfo * sdi;
  152.     int id = 0;
  153.  
  154.     /* FIXME: this should be big enough */
  155.     sdi = malloc(sizeof(*sdi) * 65);
  156.  
  157.     fd = open("/proc/scsi/scsi", O_RDONLY);
  158.     if (fd < 0) {
  159.     logMessage("failed to open /proc/scsi/scsi: %s", strerror(errno));
  160.     return 1;
  161.     }
  162.     
  163.     i = read(fd, buf, sizeof(buf) - 1);
  164.     if (i < 1) {
  165.     logMessage("failed to read /proc/scsi/scsi: %s", strerror(errno));
  166.     return 1;
  167.     }
  168.     close(fd);
  169.     buf[i] = '\0';
  170.  
  171.     start = buf;
  172.     while (*start) {
  173.     chptr = start;
  174.      while (*chptr != '\n') chptr++;
  175.     *chptr = '\0';
  176.     next = chptr + 1;
  177.  
  178.     switch (state) {
  179.       case SCSISCSI_TOP:
  180.         if (strcmp("Attached devices: ", start)) {
  181.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  182.         free(sdi);
  183.         return INST_ERROR;
  184.         }
  185.         state = SCSISCSI_HOST;
  186.         break;
  187.  
  188.       case SCSISCSI_HOST:
  189.         if (strncmp("Host: ", start, 6)) {
  190.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  191.         free(sdi);
  192.         return INST_ERROR;
  193.         }
  194.  
  195.         start = strstr(start, "Id: ");
  196.         if (!start) {
  197.         logMessage("Id: missing in /proc/scsi/scsi");
  198.         return INST_ERROR;
  199.         }
  200.         start += 4;
  201.  
  202.         id = strtol(start, NULL, 10);
  203.  
  204.         state = SCSISCSI_VENDOR;
  205.         break;
  206.  
  207.       case SCSISCSI_VENDOR:
  208.         if (strncmp("  Vendor: ", start, 10)) {
  209.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  210.         free(sdi);
  211.         return INST_ERROR;
  212.         }
  213.  
  214.         start += 10;
  215.         end = chptr = strstr(start, "Model:");
  216.         if (!chptr) {
  217.         logMessage("Model missing in /proc/scsi/scsi");
  218.         free(sdi);
  219.         return INST_ERROR;
  220.         }
  221.  
  222.         chptr--;
  223.         while (*chptr == ' ') chptr--;
  224.         *(chptr + 1) = '\0';
  225.  
  226.         strcpy(linebuf, start);
  227.         *linebuf = toupper(*linebuf);
  228.         chptr = linebuf + 1;
  229.         while (*chptr) {
  230.         *chptr = tolower(*chptr);
  231.         chptr++;
  232.         }
  233.  
  234.         start = end;  /* beginning of "Model:" */
  235.         start += 7;
  236.         
  237.         chptr = strstr(start, "Rev:");
  238.         if (!chptr) {
  239.         logMessage("Rev missing in /proc/scsi/scsi");
  240.         free(sdi);
  241.         return INST_ERROR;
  242.         }
  243.        
  244.         chptr--;
  245.         while (*chptr == ' ') chptr--;
  246.         *(chptr + 1) = '\0';
  247.  
  248.         strcat(linebuf, " ");
  249.         strcat(linebuf, start);
  250.  
  251.         state = SCSISCSI_TYPE;
  252.  
  253.         break;
  254.  
  255.       case SCSISCSI_TYPE:
  256.         if (strncmp("  Type:", start, 7)) {
  257.         logMessage("unexpected line in /proc/scsi/scsi: %s", start);
  258.         free(sdi);
  259.         return INST_ERROR;
  260.         }
  261.         *typebuf = '\0';
  262.         if (strstr(start, "Direct-Access")) {
  263.         sprintf(typebuf, "sd%c", driveName++);
  264.         sdi[numMatches].type = DEVICE_HD;
  265.         } else if (strstr(start, "Sequential-Access")) {
  266.         sprintf(typebuf, "st%c", tapeNum++);
  267.         sdi[numMatches].type = DEVICE_TAPE;
  268.         } else if (strstr(start, "CD-ROM")) {
  269.         sprintf(typebuf, "scd%c", cdromNum++);
  270.         sdi[numMatches].type = DEVICE_CDROM;
  271.         }
  272.  
  273.         if (*typebuf) {
  274.         /*sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 2));*/
  275.         sdi[numMatches].deviceName = strdup(typebuf);
  276.         sdi[numMatches].info = strdup(linebuf);
  277.         sdi[numMatches].bus = 0;
  278.         sdi[numMatches++].id = id;
  279.         }
  280.  
  281.         state = SCSISCSI_HOST;
  282.     }
  283.  
  284.     start = next;
  285.     }
  286.  
  287.     sdi[numMatches].deviceName = NULL;
  288.     sdi[numMatches].info = NULL;
  289.  
  290.     sdi = realloc(sdi, sizeof(*sdi) * (numMatches + 1));
  291.  
  292.     *sdiPtr = sdi;
  293.  
  294.     return 0;
  295. }
  296.  
  297. /* normal string handling doesn't work here as the syslog can contain 
  298.    binary 0's! */
  299. int ideGetDevices(struct deviceInfo ** idiPtr) {
  300.     struct deviceInfo * idi;
  301.     struct stat sb;
  302.     char * filename;
  303.     char * buf, * end;
  304.     char * absend;
  305.     int numMatches = 0;
  306.     int fd;
  307.     int base = testing ? 0 : 3;
  308.  
  309.     if (!access("/var/log/dmesg", R_OK))
  310.     filename = "/var/log/dmesg";
  311.     else
  312.     filename = "/tmp/syslog";
  313.  
  314.     idi = malloc(sizeof(*idi) * 9);
  315.  
  316.     if (stat(filename, &sb)) {
  317.     newtWinMessage("Error", "Ok", "Failed to stat %s: %s\n", filename,
  318.             strerror(errno));
  319.     return 0;
  320.     }
  321.  
  322.     if ((fd = open(filename, O_RDONLY)) < 0) {
  323.     newtWinMessage("Error", "Ok", "Failed to open %s: %s\n", filename,
  324.             strerror(errno));
  325.     return INST_ERROR;
  326.     }
  327.    
  328.     buf = alloca(sb.st_size);
  329.     read(fd, buf, sb.st_size);
  330.     close(fd);
  331.  
  332.     absend = buf + sb.st_size;
  333.  
  334.     while (buf && buf < absend) {
  335.     if (buf[0 + base] == 'h' && buf[1 + base] == 'd' && 
  336.         buf[3 + base] == ':') {
  337.         idi[numMatches].deviceName = malloc(4);
  338.         strcpy(idi[numMatches].deviceName, "hda");
  339.         idi[numMatches].deviceName[2] = buf[2 + base];
  340.  
  341.         buf += 5 + base;
  342.         end = buf;
  343.         while (*end != '\n' && *end != ',') end++;
  344.  
  345.         if (*end == ',') {
  346.         idi[numMatches].info = malloc(end - buf + 1);
  347.         strncpy(idi[numMatches].info, buf, end - buf);
  348.         idi[numMatches].info[end - buf] = '\0';
  349.  
  350.         /* see if this is a cdrom or not */
  351.         while (*end != '\n' && 
  352.                 strncmp(end, "CDROM", 5) &&
  353.                 strncmp(end, "TAPE", 4) &&
  354.                 strncmp(end, "FLOPPY", 6) &&
  355.                 strncmp(end, "CHS", 3))
  356.                 end++;
  357.  
  358.         if (!strncmp(end, "CDROM", 5)) 
  359.             idi[numMatches].type = DEVICE_CDROM;
  360.         else if (!strncmp(end, "TAPE", 4)) 
  361.             idi[numMatches].type = DEVICE_TAPE;
  362.         else if (!strncmp(end, "FLOPPY", 6)) 
  363.             idi[numMatches].type = DEVICE_FD;
  364.         else if (!strncmp(end, "CHS", 3)) 
  365.             idi[numMatches].type = DEVICE_HD;
  366.         else
  367.             idi[numMatches].type = DEVICE_NONE;
  368.  
  369.         /* we could do better here */
  370.         idi[numMatches].bus = idi[numMatches].id = 0;
  371.  
  372.         if (idi[numMatches].type != DEVICE_NONE)
  373.             numMatches++;
  374.         }
  375.     }
  376.  
  377.     end = memchr(buf, '\n', absend - buf);
  378.     if (!end)
  379.        buf = NULL;
  380.     else
  381.        buf = end + 1;
  382.     }
  383.    
  384.     idi[numMatches].deviceName = NULL;
  385.     idi[numMatches].info = NULL;
  386.  
  387.     idi = realloc(idi, sizeof(*idi) * (numMatches + 1));
  388.  
  389.     *idiPtr = idi;
  390.  
  391.     return 0;
  392. }
  393.