aboutsummaryrefslogtreecommitdiff
path: root/src/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bus.c')
-rw-r--r--src/bus.c96
1 files changed, 78 insertions, 18 deletions
diff --git a/src/bus.c b/src/bus.c
index eb1a862..2c3f614 100644
--- a/src/bus.c
+++ b/src/bus.c
@@ -35,50 +35,110 @@ extern char* ide_device_glob[];
int scanbus_sysfs(nndevice_t** device)
{
- char tmpstr[128];
const char* scsi_path = "/sys/class/scsi_disk";
- DIR *pdir;
- struct dirent *pdent;
- DIR *pbdir;
- struct dirent *pbent;
+ char tmpstr[128];
+ int i = 0;
+ int fd = -1;
+ FILE* fp = NULL;
+ DIR* pbase;
+ DIR* pblock;
+ struct dirent* pbaseent;
+ struct dirent* pblockent;
- /* scan for scsi devices via sysfs */
+ /* scan for scsi devices (and with libata enabled ... ide devices too) via sysfs */
if((access(scsi_path, F_OK)) != 0)
{
COM(self, "Sysfs not available\n");
return 1;
}
- pdir = opendir(scsi_path);
- if(!pdir)
+ pbase = opendir(scsi_path);
+ if(!pbase)
{
COM(self, "fatal opendir: %s\n", strerror(errno));
exit(1);
}
- while((pdent = readdir(pdir)))
+ while((pbaseent = readdir(pbase)))
{
- if(!strncasecmp(pdent->d_name, ".", 1) || !strncasecmp(pdent->d_name, "..", 2))
+ device[i] = (nndevice_t*)malloc(sizeof(nndevice_t));
+ if(device[i] == NULL)
+ {
+ perror("device");
+ exit(1);
+ }
+
+ if(!strncasecmp(pbaseent->d_name, ".", 1) || !strncasecmp(pbaseent->d_name, "..", 2))
continue;
- sprintf(tmpstr, "%s/%s/device/block", scsi_path, pdent->d_name);
- pbdir = opendir(tmpstr);
- if(!pbdir)
+ /* set model */
+ snprintf(tmpstr, sizeof(tmpstr), "%s/%s/device/model", scsi_path, pbaseent->d_name);
+ fp = fopen(tmpstr, "r");
+ if(fp == NULL)
+ {
+ COM(self, "Could not retrieve model information from %s: %s\n", tmpstr, strerror(errno));
+ }
+ else
+ {
+ fgets(device[i]->model, sizeof(device[i]->model), fp);
+ device[i]->model[strlen(device[i]->model) - 1] = 0;
+
+ fclose(fp);
+ }
+
+ /* set vendor */
+ snprintf(tmpstr, sizeof(tmpstr), "%s/%s/device/vendor", scsi_path, pbaseent->d_name);
+ fp = fopen(tmpstr, "r");
+ if(fp == NULL)
+ {
+ COM(self, "Could not retrieve vendor information from %s: %s\n", tmpstr, strerror(errno));
+ }
+ else
+ {
+ fgets(device[i]->vendor, sizeof(device[i]->model), fp);
+ /* Why does sysfs not terminate the string after the last character? Kernel 2.6 bug?
+ Here we are checking for the space character and terminating it manually. */
+ device[i]->vendor[strind(device[i]->vendor, ' ')] = 0;
+ fclose(fp);
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr), "%s/%s/device/block", scsi_path, pbaseent->d_name);
+ pblock = opendir(tmpstr);
+ if(!pblock)
{
COM(self, "fatal opendir: %s\n", strerror(errno));
exit(1);
}
- while((pbent = readdir(pbdir)))
+ while((pblockent = readdir(pblock)))
{
- if(!strncasecmp(pbent->d_name, ".", 1) || !strncasecmp(pbent->d_name, "..", 2))
+ if(!strncasecmp(pblockent->d_name, ".", 1) || !strncasecmp(pblockent->d_name, "..", 2))
continue;
- printf("%s - %s\n", pdent->d_name, pbent->d_name);
+ /* set path */
+ snprintf(device[i]->path, sizeof(device[i]->path), "/dev/%s", pblockent->d_name);
}
- closedir(pbdir);
+ closedir(pblock);
+
+ /* set number of blocks */
+ fd = open(device[i]->path, O_RDONLY | O_NONBLOCK);
+ if(fd >= 0)
+ {
+ if((ioctl(fd, BLKGETSIZE, &device[i]->blks)) != 0)
+ {
+ COM(self, "ioctl: could not retrieve block count for %s\n", device[i]->path);
+ device[i]->blks = 0;
+ }
+ close(fd);
+ }
+
+ device[i]->blksz = 512;
+ device[i]->sz = device[i]->blks * device[i]->blksz;
+
+ COM(self, "%s %s %s %llu\n", device[i]->vendor, device[i]->path, device[i]->model, (device[i]->blks * device[i]->blksz));
+ ++i;
}
- closedir(pdir);
+ closedir(pbase);
return 0;
}