Your message dated Mon, 26 Apr 1999 00:49:56 +0200 with message-id <[EMAIL PROTECTED]> and subject line new hwtools 0.4 has caused the attached bug report to be marked as done.
This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what I'm talking about this indicates a serious mail system misconfiguration somewhere. Please contact me immediately.) Ian Jackson (administrator, Debian bugs database) Received: (at submit) by bugs.debian.org; 4 Apr 1998 21:48:18 +0000 Received: (qmail 7923 invoked from network); 4 Apr 1998 21:48:18 -0000 Received: from mail.cs.utexas.edu ([EMAIL PROTECTED]) by debian.novare.net with SMTP; 4 Apr 1998 21:48:18 -0000 Received: from nevermore.csres.utexas.edu (dial-73-9.ots.utexas.edu [128.83.254.73]) by mail.cs.utexas.edu (8.8.5/8.8.5) with ESMTP id PAA16081 for <[EMAIL PROTECTED]>; Sat, 4 Apr 1998 15:48:00 -0600 (CST) Received: from rlb by nevermore.csres.utexas.edu with local (Exim 1.891 #1) id 0yLan8-0002sx-00 (Debian); Sat, 4 Apr 1998 15:47:58 -0600 To: [EMAIL PROTECTED] Subject: hwtools: patch -- many scsidev buffer overrun fixes, etc. From: Rob Browning <[EMAIL PROTECTED]> Date: 04 Apr 1998 15:47:58 -0600 Message-ID: <[EMAIL PROTECTED]> Lines: 989 X-Mailer: Gnus v5.6.2/Emacs 20.2 Package: hwtools Version: 0.3-4 I just sent these to Christoph, but I recall him saying something about being in transition right now, so I wanted to make sure these patches ended up somplace safe for now. Christoph Lameter <[EMAIL PROTECTED]> writes: > Definitely. > > On 15 Feb 1998, Rob Browning wrote: > > > > > I needed scsidev and friends here, and I found that the current > > version segfaults on an unstable system. So I cleaned up the source a > > bit, fixed a few bugs, and got rid of a bunch of warnings that popped > > up under -Wall. It seems to work fine now. > > > > Would you be interested in the patches? Sorry this took so long, but I've been busy, and I had to migrate my changes into your new upstream version. The diffs follow. I had to modify configure.in in the scsidev directory, but I included the diffs to the generated configure file, so you don't need to re-run autoconf unless you just want to. There are also some stylistic changes here (in debian/rules, etc.) that you can feel free to ignore if you don't like them. I had to change a few important things in debian/rules, though, so be careful what you ignore. The biggest change is to scsidev.c. There were potential buffer overruns everywhere. I managed to eliminate many of them completely, but for a couple I had to just make the buffer *really* large and hope for the best because in those cases I couldn't find any documentation for what the potential maximum size was. Oh, and the patch looks bigger than it really is because I turned on -Wall, and cleaned up all the resulting errors. This meant rearranging the order of the functions so that they'd be defined before use. Let me know if you have any questions, and thanks... diff -ru hwtools-0.3/debian/rules hwtools-0.3.fixed/debian/rules --- hwtools-0.3/debian/rules Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/debian/rules Sat Apr 4 11:20:16 1998 @@ -15,25 +15,28 @@ package=hwtools +kernel_headers = /usr/src/linux/include + build: $(checkdir) - cd irqtune;make kvers sbin - cd memtest86;make - cd scanport/src;gcc -s -O2 -o scanport scanport.c;gcc -s -O2 -o inb inb.c - cd scsiinfo-1.7;make - cd scsidev-1.5;./configure prefix=/usr;make - cd qic02;make + cd irqtune && make kvers sbin + cd memtest86 && make + cd scanport/src && \ + gcc -s -O2 -o scanport scanport.c;gcc -s -O2 -o inb inb.c + cd scsiinfo-1.7 && make KERNEL_INCLUDES=-I${kernel_headers} + cd scsidev-1.5 && ./configure --prefix=/usr && make + cd qic02 && make touch build clean: $(checkdir) -rm -f build - -cd memtest86;make clean - -cd irqtune;make clean - -cd scanport/src;rm scanport inb - -cd scsiinfo-1.7;make clean - -cd scsidev-1.5;make clean - -cd qic02;make clean + -cd memtest86 && make clean + -cd irqtune && make clean + -cd scanport/src && rm scanport inb + -cd scsiinfo-1.7 && make clean + -cd scsidev-1.5 && make clean + -cd qic02 && make clean -rm `find . -name "*~"` -rm -rf debian/tmp debian/files* debian/substvars @@ -56,7 +59,13 @@ cd qic*;make install DESTDIR=../debian/tmp cp memtest86/image debian/tmp/usr/lib/hwtools/memtest86.bin cd irqtune;make install DESTDIR=../../debian/tmp - cd scsidev-1.5;make install prefix=../debian/tmp/usr DESTDIR=../debian/tmp + + cd scsidev-1.5 && \ + make install prefix=../debian/tmp/usr DESTDIR=../debian/tmp +# scsidev has to be on the root filesystem to do any good at startup + install -d debian/tmp/bin + mv debian/tmp/usr/bin/scsidev debian/tmp/bin + install -d debian/tmp/usr/doc/$(package)/scsiinfo # Dos executables cp scanport/dos/*.exe debian/tmp/usr/lib/hwtools diff -ru hwtools-0.3/qic02/Makefile hwtools-0.3.fixed/qic02/Makefile --- hwtools-0.3/qic02/Makefile Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/qic02/Makefile Sat Apr 4 11:16:19 1998 @@ -29,4 +29,4 @@ -rm -f qic02conf qic02conf: qic02conf.c - gcc -O2 -Wall -s -N -o $@ $< + gcc -I/usr/src/linux/include -O2 -Wall -s -N -o $@ $< diff -ru hwtools-0.3/scsidev-1.5/Makefile.in hwtools-0.3.fixed/scsidev-1.5/Makefile.in --- hwtools-0.3/scsidev-1.5/Makefile.in Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/scsidev-1.5/Makefile.in Sat Apr 4 11:25:02 1998 @@ -27,7 +27,7 @@ manext = 8 #### End of system configuration section. #### [EMAIL PROTECTED]@ -g # -DDEBUG [EMAIL PROTECTED]@ -Wall -g # -DDEBUG World: scsidev diff -ru hwtools-0.3/scsidev-1.5/configure hwtools-0.3.fixed/scsidev-1.5/configure --- hwtools-0.3/scsidev-1.5/configure Sat Mar 29 09:55:44 1997 +++ hwtools-0.3.fixed/scsidev-1.5/configure Sat Apr 4 11:14:21 1998 @@ -825,7 +825,7 @@ fi echo "$ac_t""$CPP" 1>&6 -for ac_hdr in linux/scsi.h scsi/scsi.h /usr/src/linux/drivers/scsi/scsi.h +for ac_hdr in linux/scsi.h scsi/scsi.h /usr/src/linux/drivers/scsi/scsi.h /usr/src/linux/include/scsi/scsi.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 diff -ru hwtools-0.3/scsidev-1.5/configure.in hwtools-0.3.fixed/scsidev-1.5/configure.in --- hwtools-0.3/scsidev-1.5/configure.in Sat Mar 29 09:47:03 1997 +++ hwtools-0.3.fixed/scsidev-1.5/configure.in Sat Apr 4 11:14:12 1998 @@ -4,6 +4,6 @@ AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_CONST -AC_CHECK_HEADERS(linux/scsi.h scsi/scsi.h /usr/src/linux/drivers/scsi/scsi.h) +AC_CHECK_HEADERS(linux/scsi.h scsi/scsi.h /usr/src/linux/drivers/scsi/scsi.h /usr/src/linux/include/scsi/scsi.h) AC_PROG_INSTALL AC_OUTPUT(Makefile) diff -ru hwtools-0.3/scsidev-1.5/scsidev.c hwtools-0.3.fixed/scsidev-1.5/scsidev.c --- hwtools-0.3/scsidev-1.5/scsidev.c Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/scsidev-1.5/scsidev.c Sat Apr 4 13:52:30 1998 @@ -1,5 +1,4 @@ #include <stdio.h> -#include <sys/vfs.h> #include <sys/sysmacros.h> #include <fcntl.h> #include <linux/major.h> @@ -8,6 +7,13 @@ #include <errno.h> #include <strings.h> +#include <sys/ioctl.h> +#include <sys/param.h> +#include <assert.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> + static char rcsid[] ="$Id: scsidev.c,v 1.2 1997/03/29 15:45:50 eric Exp $"; #include "config.h" @@ -69,6 +75,7 @@ * Used to maintain a list of the nodes that we have seen * which we know to be OK and active. */ +void register_dev(char * name, int major, int minor, int hnum, int hid, int chan, int id, int lun, int part, struct regnames * alias) @@ -77,6 +84,7 @@ char * pnt; rpnt = (struct regnames *) malloc(sizeof(struct regnames)); + assert(rpnt != 0); pnt = strrchr(name, '/'); rpnt->name = strdup(pnt + 1); rpnt->major = major; @@ -105,8 +113,6 @@ */ void sanitize_sdev() { - struct dirent * de; - char filename[60]; DIR * sdir; struct regnames * rpnt; struct stat statbuf; @@ -118,9 +124,9 @@ * changed. */ sdir = opendir("/dev/scsi"); - while(1==1) + while(1) { - de = readdir(sdir); + struct dirent * de = readdir(sdir); if(de == NULL) break; /* * OK, we have the name. See whether this is something @@ -135,6 +141,9 @@ } if( rpnt == NULL ) { + char *filename = malloc((strlen("/dev/scsi/") + + strlen(de->d_name) + 1) * sizeof(char)); + assert(filename != NULL); strcpy(filename, "/dev/scsi/"); strcat(filename, de->d_name); status = stat(filename, &statbuf); @@ -154,6 +163,7 @@ chown(filename, statbuf.st_uid, statbuf.st_gid); } + free(filename); } } closedir(sdir); @@ -163,8 +173,6 @@ void flush_sdev() { - struct dirent * de; - char filename[60]; DIR * sdir; /* * Next, delete all of the existing entries in the /dev/scsi directory. @@ -172,18 +180,23 @@ * changed. */ sdir = opendir("/dev/scsi"); - while(1==1) + while(1) { - de = readdir(sdir); + char *filename = NULL; + struct dirent *de = readdir(sdir); if(de == NULL) break; if(de->d_name[0] != 's' && de->d_name[0] != 'r') continue; + filename = malloc((strlen("/dev/scsi/") + strlen(de->d_name) + 1) * + sizeof(char)); + assert(filename != NULL); strcpy(filename, "/dev/scsi/"); strcat(filename, de->d_name); unlink(filename); + free(filename); + filename = NULL; } closedir(sdir); - printf("Flushed old /dev/scsi entries...\n", de->d_name); - + printf("Flushed old /dev/scsi entries...\n"); } /* @@ -260,18 +273,19 @@ { int chan; int fd; - char hostname[60]; + char hostname[512]; /* Make it huge, it's just stack space... + If anyone knows an upper limit on the return from + SCSI_IOCTL_PROBE_HOST, then use that. Until then + this is still potentially dangerous. */ int newmode; - int recreate; int h_id; int id[2]; int lun; int minor = 0; - int uid, gid; struct stat statbuf; int scsi_id; - char scsidev[64]; - char linkto[64]; + char scsidev[MAXPATHLEN]; /* This isn't ideal, but it'll do for now. */ + char linkto[MAXPATHLEN]; /* This isn't ideal, but it'll do for now. */ int status; status = stat("/tmp/testdev", &statbuf); @@ -284,7 +298,7 @@ if(status == -1) return; - while(1==1) + while(1) { status = mknod("/tmp/testdev",0600 | devtype , makedev(major,minor)); @@ -477,139 +491,34 @@ unlink("/tmp/testdev"); } - -/* - * Build a /dev/scsi tree that contains the correct device entries. - */ - -usage() -{ - fprintf(stderr,"scsidev v1.3\n"); - fprintf(stderr,"Usage: scsidev [-f] [-l] [-v] [-m mode]\n"); -} - -main(int argc, char * argv[]) -{ - char c; - int force = 0; - int show_serial = 0; - struct stat statbuf; - struct regnames * rpnt; - int status; - - status = stat("/dev/scsi", &statbuf); - if( status == -1 - || !S_ISDIR(statbuf.st_mode)) - { - fprintf(stderr,"/dev/scsi either does not exist, or is not a directory\n"); - exit(0); - } - while ((c = getopt(argc, argv, "flvsm:")) != EOF) - { - switch (c) - { - case 'f': - force = 1; - break; - case 'm': - filemode = strtoul(optarg, 0, 0); - break; - case 'l': - use_symlink = 1; - break; - case 's': - show_serial = 1; - break; - case 'v': - verbose++; - break; - default: - usage(); - exit(1); - break; - } - } - - if( force ) flush_sdev(); - -#ifdef DEBUG - register_dev("/dev/scsi/sdh4-334c0i0l0", 8, 0, 6, 0x334, 0, 0, 0, -1, NULL); - register_dev("/dev/scsi/sdh4-334c0i0l0p1", 8, 1, 6, 0x334, 0, 0, 0, 1, NULL); - register_dev("/dev/scsi/sdh4-334c0i0l0p2",8, 2,6, 0x334, 0, 0, 0, 2, NULL); - register_dev("/dev/scsi/sdh4-334c0i0l0p3",8, 3,6, 0x334, 0, 0, 0, 3, NULL); - register_dev("/dev/scsi/sgh4-334c0i0l0", 21, 0,6, 0x334, 0, 0, 0, -1, NULL); - register_dev("/dev/scsi/sgh4-334c0i2l0", 21, 1,6, 0x334, 0, 2, 0, -1, NULL); - register_dev("/dev/scsi/sgh4-334c0i5l0", 21, 2,6, 0x334, 0, 5, 0, -1, NULL); - register_dev("/dev/scsi/srh4-334c0i2l0", 11, 0,6, 0x334, 0, 2, 0, -1, NULL); - register_dev("/dev/scsi/sth4-334c0i5l0", 9, 0,6, 0x334, 0, 5, 0, -1, NULL); - register_dev("/dev/scsi/rsth4-334c0i5l0", 9,128,6, 0x334, 0, 5, 0, -1, NULL); -#else - build_sdev(SCSI_DISK_MAJOR, O_RDONLY, S_IFBLK, 'd'); - build_sdev(SCSI_CDROM_MAJOR, O_RDONLY, S_IFBLK, 'r'); - build_sdev(SCSI_TAPE_MAJOR, O_RDONLY, S_IFCHR, 't'); - build_sdev(SCSI_GENERIC_MAJOR, O_RDWR, S_IFCHR, 'g'); -#endif - - if( show_serial ) - { - for (rpnt = reglist; rpnt; rpnt = rpnt->next) - { - if( rpnt->partition != -1 ) continue; - if( rpnt->major == SCSI_TAPE_MAJOR - && (rpnt->minor & 0x80) != 0 ) continue; - - if( rpnt->serial == NULL ) get_serial_number(rpnt); - if( rpnt->serial == no_serial ) - printf("Device %s has no serial number\n", rpnt->name); - else - printf("Serial number of %s: \"%s\"\n", rpnt->name, rpnt->serial); - } - } - /* - * Now, read the configuration file and see whether there - * are any special device names we want to try and match. - */ - build_special(); - - if( !force ) - { - sanitize_sdev(); - } - -} - -char * get_string (char * pnt, char **result) +char * +get_string (char * pnt, char **result) { char quote = 0; - while (*pnt == ' ' || *pnt == '\t') pnt++; - - if( *pnt == '"' ) - { - quote = *pnt++; - } + while (*pnt && (*pnt == ' ' || *pnt == '\t')) pnt++; - if( *pnt == '\'' ) - { - quote = *pnt++; - } - - *result = pnt; - - if( quote != 0 ) - { - while( *pnt != quote ) pnt++; - *pnt++ = 0; - } - else - { - while( *pnt != ',' && *pnt != ' ' && *pnt != '\t' ) pnt++; - *pnt++ = 0; - } - - while (*pnt == ' ' || *pnt == '\t') pnt++; - if(*pnt == ',') pnt++; - while (*pnt == ' ' || *pnt == '\t') pnt++; + if(*pnt) { + if( *pnt == '"' ) quote = *pnt++; + if( *pnt == '\'' ) quote = *pnt++; + + *result = pnt; + + if( quote != 0 ) + { + while( *pnt && *pnt != quote ) pnt++; + *pnt++ = 0; + } + else + { + while( *pnt && *pnt != ',' && *pnt != ' ' && *pnt != '\t' ) pnt++; + *pnt++ = 0; + } + + while (*pnt && (*pnt == ' ' || *pnt == '\t')) pnt++; + if(*pnt == ',') pnt++; + while (*pnt && (*pnt == ' ' || *pnt == '\t')) pnt++; + } return pnt; } @@ -666,6 +575,175 @@ } /* + * Note that this does the same thing as an inquiry, but + * it also grabs the serial number too. Some devices complain + * if you ask for the serial number, so we have a version with and + * without. + */ +void +get_serial_number(struct regnames * rpnt) +{ +#ifdef DEBUG + /* + * Fill in some entries, just so I can test this on a non-scsi system. + */ + if(rpnt->id == 0 ) rpnt->serial = strdup("DX908FK"); + else rpnt->serial = no_serial; +#else + int status, i; + unsigned char *cmd; + unsigned char * pagestart; + unsigned char buffer[2048]; /* Doubled from 1024. Just trying to be sure. */ + char path[MAXPATHLEN]; /* This isn't ideal, but it'll do for now. */ + int infile; + struct regnames * rpnt1; + + memset(buffer, 0, sizeof(buffer)); + + *( (int *) buffer ) = 0; /* length of input data */ + + /* length of buffer = buffer size - 2 (for these length bytes) + - 6 (for the cmd length) */ + *(((int *) buffer) + 1) = sizeof(buffer)/sizeof(*buffer) - (2 + 6); + + cmd = (char *) ( ((int *) buffer) + 2 ); + + cmd[0] = 0x12; /* INQUIRY */ + cmd[1] = 0x01; /* lun=0, evpd=1 */ + cmd[2] = 0x80; /* page code = 0x80, serial number */ + cmd[3] = 0x00; /* (reserved) */ + cmd[4] = 0xff; /* allocation length */ + cmd[5] = 0x00; /* control */ + + strcpy(path, "/dev/scsi/"); + strcat(path, rpnt->name); + infile = open(path, O_RDONLY); + if( infile == -1 ) return; + status = ioctl( infile, 1 /* SCSI_IOCTL_SEND_COMMAND */, buffer ); + close(infile); + + if(status) rpnt->serial = no_serial; + + pagestart = buffer + 8; + + rpnt->serial = (char *) malloc(pagestart[3] + 1); + memcpy(rpnt->serial, pagestart+4, pagestart[3]); + + /* + * NULL terminate and trim trailing whitespace. + */ + rpnt->serial[pagestart[3]] = '\0'; + for(i = pagestart[3] - 1; i >= 0 && rpnt->serial[i] == ' '; i-- ) + rpnt->serial[i] = '\0'; + + /* + * Copy information to identical nodes to avoid excessive probing. + */ + for( rpnt1 = reglist; rpnt1; rpnt1 = rpnt1->next ) + { + if( rpnt1 == rpnt ) continue; + if( rpnt1->alias != NULL ) continue; + if( rpnt1->id != rpnt->id ) continue; + if( rpnt1->chan != rpnt->chan ) continue; + if( rpnt1->hostnum != rpnt->hostnum ) continue; + if( rpnt1->hostid != rpnt->hostid ) continue; + if( rpnt1->serial == NULL ) rpnt1->serial = rpnt->serial; + } +#endif +} + +void +inquire(struct regnames * rpnt) +{ +#ifdef DEBUG + /* + * Fill in some entries just so that I can test this. + */ + if(rpnt->id == 0 ) { + rpnt->manufacturer = strdup("CONNER"); + rpnt->model=strdup("CFP4207S"); + } else if(rpnt->id == 2 ) { + rpnt->manufacturer = strdup("HP"); + rpnt->model=strdup("C4324/C4325"); + } else if(rpnt->id == 5 ) { + rpnt->manufacturer = strdup("WANGTEK"); + rpnt->model=strdup("5150ES"); + } +#else + int status, i; + char c; + unsigned char *cmd; + unsigned char * pagestart; + unsigned char buffer[2048]; /* Doubled from 1024. Just trying to be sure. */ + char path[MAXPATHLEN]; /* This isn't ideal, but it'll do for now. */ + struct regnames * rpnt1; + int infile; + + memset(buffer, 0, sizeof(buffer)); + + *( (int *) buffer ) = 0; /* length of input data */ + + /* length of buffer = buffer size - 2 (for these length bytes) + - 6 (for the cmd length) */ + *(((int *) buffer) + 1) = sizeof(buffer)/sizeof(*buffer) - (2 + 6); + + cmd = (char *) ( ((int *) buffer) + 2 ); + + cmd[0] = 0x12; /* INQUIRY */ + cmd[1] = 0x00; /* lun=0, evpd=0 */ + cmd[2] = 0x00; /* page code = 0 */ + cmd[3] = 0x00; /* (reserved) */ + cmd[4] = 0xff; /* allocation length */ + cmd[5] = 0x00; /* control */ + + strcpy(path, "/dev/scsi/"); + strcat(path, rpnt->name); + infile = open(path, O_RDONLY); + if( infile == -1 ) return; + + status = ioctl( infile, 1 /* SCSI_IOCTL_SEND_COMMAND */, buffer ); + + close(infile); + + if(status) return; + + pagestart = buffer + 8; + + for( i = 15; i >= 8 && pagestart[i] == ' '; i-- ) + pagestart[i] = 0; + + c = pagestart[16]; + pagestart[16] = 0; + rpnt->manufacturer = strdup(pagestart+8); + pagestart[16] = c; + + for( i = 31; i >= 16 && pagestart[i] == ' '; i-- ) + pagestart[i] = 0; + c = pagestart[32]; + pagestart[32] = 0; + rpnt->model = strdup(pagestart+16); + pagestart[32] = c; + + /* + * Copy information to identical nodes to avoid excessive probing. + */ + for( rpnt1 = reglist; rpnt1; rpnt1 = rpnt1->next ) + { + if( rpnt1 == rpnt ) continue; + if( rpnt1->alias != NULL ) continue; + if( rpnt1->id != rpnt->id ) continue; + if( rpnt1->chan != rpnt->chan ) continue; + if( rpnt1->hostnum != rpnt->hostnum ) continue; + if( rpnt1->hostid != rpnt->hostid ) continue; + if( rpnt1->manufacturer == NULL ) + rpnt1->manufacturer = rpnt->manufacturer; + if( rpnt1->model == NULL ) rpnt1->model = rpnt->model; + } + return; +#endif +} + +/* * The configuration file is designed to be something that can match * any number of fields. Thus we need to be able to specify a large * number of different things in the hope that we can uniquely match @@ -683,14 +761,16 @@ * NAME="string" * DEVTYPE="disk", "tape", "generic", or "cdrom". */ +void build_special() { FILE * configfile; - char buffer[256]; + char * buffer = NULL; + char * buffer_length = 0; char * pnt; char * pnt1; struct regnames * rpnt, *match; - char scsidev[64]; + char scsidev[MAXPATHLEN]; /* This isn't ideal, but it'll do for now. */ int type; int lun, chan, id, part, hostid, hostnum; @@ -704,9 +784,9 @@ configfile = fopen("/etc/scsi.alias", "r"); #endif line = 0; - while(1==1) + while(1) { - fgets(buffer, sizeof(buffer), configfile); + if(getline(&buffer, &buffer_length, configfile) == -1) break; line++; if( feof(configfile)) break; @@ -737,7 +817,7 @@ if( *pnt == '\0' ) continue; if( *pnt == '#' ) continue; - while(1==1) + while(1) { pnt1 = pnt; while (*pnt1 != '=' && *pnt1 != '\0') pnt1++; @@ -790,7 +870,7 @@ } else { - fprintf(stderr,"Unrecognized specifier \"%s\" on line\n", pnt, + fprintf(stderr,"Unrecognized specifier \"%s\" on line %d\n", pnt, line); break; } @@ -832,6 +912,7 @@ match = NULL; for (rpnt = reglist; rpnt; rpnt = rpnt->next) { + /* * Check the integers first. Some of the strings we have to * request, and we want to avoid this if possible. @@ -966,168 +1047,112 @@ fprintf(stderr,"Unable to match device for line %d\n", line); } } - fclose(configfile); + if(buffer) free(buffer); } -/* - * Note that this does the same thing as an inquiry, but - * it also grabs the serial number too. Some devices complain - * if you ask for the serial number, so we have a version with and - * without. - */ -int get_serial_number(struct regnames * rpnt) -{ -#ifdef DEBUG - /* - * Fill in some entries, just so I can test this on a non-scsi system. - */ - if(rpnt->id == 0 ) rpnt->serial = strdup("DX908FK"); - else rpnt->serial = no_serial; -#else - int status, i; - unsigned char *cmd; - unsigned char * pagestart; - unsigned char buffer[1024]; - char path[64]; - int infile; - struct regnames * rpnt1; - - memset(buffer, 0, sizeof(buffer)); - - *( (int *) buffer ) = 0; /* length of input data */ - *( ((int *) buffer) + 1 ) = 1024; /* length of output buffer */ - - cmd = (char *) ( ((int *) buffer) + 2 ); - - cmd[0] = 0x12; /* INQUIRY */ - cmd[1] = 0x01; /* lun=0, evpd=1 */ - cmd[2] = 0x80; /* page code = 0x80, serial number */ - cmd[3] = 0x00; /* (reserved) */ - cmd[4] = 0xff; /* allocation length */ - cmd[5] = 0x00; /* control */ - - strcpy(path, "/dev/scsi/"); - strcat(path, rpnt->name); - infile = open(path, O_RDONLY); - if( infile == -1 ) return; - status = ioctl( infile, 1 /* SCSI_IOCTL_SEND_COMMAND */, buffer ); - close(infile); - - if(status) rpnt->serial = no_serial; - - pagestart = buffer + 8; - rpnt->serial = (char *) malloc(pagestart[3] + 1); - memcpy(rpnt->serial, pagestart+4, pagestart[3]); - /* - * NULL terminate and trim trailing whitespace. - */ - rpnt->serial[pagestart[3]] = '\0'; - for(i = pagestart[3] - 1; i >= 0 && rpnt->serial[i] == ' '; i-- ) - rpnt->serial[i] = '\0'; +/* + * Build a /dev/scsi tree that contains the correct device entries. + */ - /* - * Copy information to identical nodes to avoid excessive probing. - */ - for( rpnt1 = reglist; rpnt1; rpnt1 = rpnt1->next ) - { - if( rpnt1 == rpnt ) continue; - if( rpnt1->alias != NULL ) continue; - if( rpnt1->id != rpnt->id ) continue; - if( rpnt1->chan != rpnt->chan ) continue; - if( rpnt1->hostnum != rpnt->hostnum ) continue; - if( rpnt1->hostid != rpnt->hostid ) continue; - if( rpnt1->serial == NULL ) rpnt1->serial = rpnt->serial; - } -#endif +void +usage() +{ + fprintf(stderr,"scsidev v1.5\n"); + fprintf(stderr,"Usage: scsidev [-f] [-l] [-v] [-m mode]\n"); } -int inquire(struct regnames * rpnt) +int +main(int argc, char * argv[]) { -#ifdef DEBUG - /* - * Fill in some entries just so that I can test this. - */ - if(rpnt->id == 0 ) { - rpnt->manufacturer = strdup("CONNER"); - rpnt->model=strdup("CFP4207S"); - } else if(rpnt->id == 2 ) { - rpnt->manufacturer = strdup("HP"); - rpnt->model=strdup("C4324/C4325"); - } else if(rpnt->id == 5 ) { - rpnt->manufacturer = strdup("WANGTEK"); - rpnt->model=strdup("5150ES"); - } -#else - int status, i; char c; - unsigned char *cmd; - unsigned char * pagestart; - unsigned char tmp; - unsigned char buffer[1024]; - char path[64]; - struct regnames * rpnt1; - int infile; - - memset(buffer, 0, sizeof(buffer)); - - *( (int *) buffer ) = 0; /* length of input data */ - *( ((int *) buffer) + 1 ) = 1024; /* length of output buffer */ - - cmd = (char *) ( ((int *) buffer) + 2 ); - - cmd[0] = 0x12; /* INQUIRY */ - cmd[1] = 0x00; /* lun=0, evpd=0 */ - cmd[2] = 0x00; /* page code = 0 */ - cmd[3] = 0x00; /* (reserved) */ - cmd[4] = 0xff; /* allocation length */ - cmd[5] = 0x00; /* control */ - - strcpy(path, "/dev/scsi/"); - strcat(path, rpnt->name); - infile = open(path, O_RDONLY); - if( infile == -1 ) return; - - status = ioctl( infile, 1 /* SCSI_IOCTL_SEND_COMMAND */, buffer ); - - close(infile); - - if(status) return; + int force = 0; + int show_serial = 0; + struct stat statbuf; + struct regnames * rpnt; + int status; - pagestart = buffer + 8; + status = stat("/dev/scsi", &statbuf); + if( status == -1 + || !S_ISDIR(statbuf.st_mode)) + { + fprintf(stderr,"/dev/scsi either does not exist, or is not a directory\n"); + exit(0); + } + while ((c = getopt(argc, argv, "flvsm:")) != EOF) + { + switch (c) + { + case 'f': + force = 1; + break; + case 'm': + filemode = strtoul(optarg, 0, 0); + break; + case 'l': + use_symlink = 1; + break; + case 's': + show_serial = 1; + break; + case 'v': + verbose++; + break; + default: + usage(); + exit(1); + break; + } + } - for( i = 15; i >= 8 && pagestart[i] == ' '; i-- ) - pagestart[i] = 0; + if( force ) flush_sdev(); - c = pagestart[16]; - pagestart[16] = 0; - rpnt->manufacturer = strdup(pagestart+8); - pagestart[16] = c; +#ifdef DEBUG + register_dev("/dev/scsi/sdh4-334c0i0l0", 8, 0, 6, 0x334, 0, 0, 0, -1, NULL); + register_dev("/dev/scsi/sdh4-334c0i0l0p1", 8, 1, 6, 0x334, 0, 0, 0, 1, NULL); + register_dev("/dev/scsi/sdh4-334c0i0l0p2",8, 2,6, 0x334, 0, 0, 0, 2, NULL); + register_dev("/dev/scsi/sdh4-334c0i0l0p3",8, 3,6, 0x334, 0, 0, 0, 3, NULL); + register_dev("/dev/scsi/sgh4-334c0i0l0", 21, 0,6, 0x334, 0, 0, 0, -1, NULL); + register_dev("/dev/scsi/sgh4-334c0i2l0", 21, 1,6, 0x334, 0, 2, 0, -1, NULL); + register_dev("/dev/scsi/sgh4-334c0i5l0", 21, 2,6, 0x334, 0, 5, 0, -1, NULL); + register_dev("/dev/scsi/srh4-334c0i2l0", 11, 0,6, 0x334, 0, 2, 0, -1, NULL); + register_dev("/dev/scsi/sth4-334c0i5l0", 9, 0,6, 0x334, 0, 5, 0, -1, NULL); + register_dev("/dev/scsi/rsth4-334c0i5l0", 9,128,6, 0x334, 0, 5, 0, -1, NULL); +#else + build_sdev(SCSI_DISK_MAJOR, O_RDONLY, S_IFBLK, 'd'); + build_sdev(SCSI_CDROM_MAJOR, O_RDONLY, S_IFBLK, 'r'); + build_sdev(SCSI_TAPE_MAJOR, O_RDONLY, S_IFCHR, 't'); + build_sdev(SCSI_GENERIC_MAJOR, O_RDWR, S_IFCHR, 'g'); +#endif - for( i = 31; i >= 16 && pagestart[i] == ' '; i-- ) - pagestart[i] = 0; - c = pagestart[32]; - pagestart[32] = 0; - rpnt->model = strdup(pagestart+16); - pagestart[32] = c; + if( show_serial ) + { + for (rpnt = reglist; rpnt; rpnt = rpnt->next) + { + if( rpnt->partition != -1 ) continue; + if( rpnt->major == SCSI_TAPE_MAJOR + && (rpnt->minor & 0x80) != 0 ) continue; + if( rpnt->serial == NULL ) get_serial_number(rpnt); + if( rpnt->serial == no_serial ) + printf("Device %s has no serial number\n", rpnt->name); + else + printf("Serial number of %s: \"%s\"\n", rpnt->name, rpnt->serial); + } + } /* - * Copy information to identical nodes to avoid excessive probing. + * Now, read the configuration file and see whether there + * are any special device names we want to try and match. */ - for( rpnt1 = reglist; rpnt1; rpnt1 = rpnt1->next ) + build_special(); + + if( !force ) { - if( rpnt1 == rpnt ) continue; - if( rpnt1->alias != NULL ) continue; - if( rpnt1->id != rpnt->id ) continue; - if( rpnt1->chan != rpnt->chan ) continue; - if( rpnt1->hostnum != rpnt->hostnum ) continue; - if( rpnt1->hostid != rpnt->hostid ) continue; - if( rpnt1->manufacturer == NULL ) - rpnt1->manufacturer = rpnt->manufacturer; - if( rpnt1->model == NULL ) rpnt1->model = rpnt->model; + sanitize_sdev(); } - return; -#endif + + return 0; } + diff -ru hwtools-0.3/scsiinfo-1.7/Makefile hwtools-0.3.fixed/scsiinfo-1.7/Makefile --- hwtools-0.3/scsiinfo-1.7/Makefile Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/scsiinfo-1.7/Makefile Sat Apr 4 11:09:13 1998 @@ -1,4 +1,4 @@ -CFLAGS=-O2 -fomit-frame-pointer -Wall -fno-strength-reduce -D_GNU_SOURCE +CFLAGS=${KERNEL_INCLUDES} -O2 -fomit-frame-pointer -Wall -fno-strength-reduce -D_GNU_SOURCE #CFLAGS=-g -Wall -fno-strength-reduce LDFLAGS=-s diff -ru hwtools-0.3/scsiinfo-1.7/scsiformat.c hwtools-0.3.fixed/scsiinfo-1.7/scsiformat.c --- hwtools-0.3/scsiinfo-1.7/scsiformat.c Sat Apr 4 13:45:19 1998 +++ hwtools-0.3.fixed/scsiinfo-1.7/scsiformat.c Sat Apr 4 12:25:46 1998 @@ -736,7 +736,7 @@ if (!par_deflistform) { fprintf(fh, "\nUser supplied defect logical blocks:\n"); for (i = off = 0; off < par_defectlen; i++, off += 4) { - fprintf(fh, " %9lu", ntohl(par_defects[i])); + fprintf(fh, " %9u", ntohl(par_defects[i])); if ((i & 7) == 7) { fprintf(fh, "\n"); flag = 1; @@ -747,7 +747,7 @@ fprintf(fh, "\nUser supplied defects in Cylinder:Head:%s format:\n", par_deflistform == 5 ? "PhysicalSector" : "BytesFromIndex"); for (i = off = 0; off < par_defectlen; i += 2, off += 8) { - sprintf(buffer, " %lu:%lu:%ld", ntohl(par_defects[i]) >> 8, + sprintf(buffer, " %u:%u:%ld", ntohl(par_defects[i]) >> 8, ntohl(par_defects[i]) & 255, (long) ntohl(par_defects[i + 1])); fprintf(fh, "%20s", buffer); if ((i & 3) == 3) { -- Rob Browning <[EMAIL PROTECTED]> PGP fingerprint = E8 0E 0D 04 F5 21 A0 94 53 2B 97 F5 D6 4E 39 30