[Nautilus-list] [PATCH] SCSI support in hardware view



Hello all,

This patch adds SCSI support to the hardware view component.  There are
some FIXME's -- IMO a few things could be done better, but it does work
everywhere I've tried it :)  Testing and comments appreciated...

-- 
Ed McKenzie
<eem12 cornell edu>
Index: nautilus/components/hardware/nautilus-hardware-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/components/hardware/nautilus-hardware-view.c,v
retrieving revision 1.32
diff -u -p -r1.32 nautilus-hardware-view.c
--- nautilus/components/hardware/nautilus-hardware-view.c	2001/05/04 03:12:42	1.32
+++ nautilus/components/hardware/nautilus-hardware-view.c	2001/06/03 11:31:31
@@ -19,6 +19,7 @@
  *
  *  Author: Andy Hertzfeld <andy eazel com>
  *          Shane Butler <shane_b bigfoot com>
+ *          Ed McKenzie <eem12 cornell edu>
  *
  */
 
@@ -59,6 +60,20 @@ enum {
 	TARGET_COLOR,
 };
 
+typedef enum { Scsi_Disk, Scsi_CDROM, Scsi_Tape, Scsi_Other } ScsiDeviceType;
+
+typedef struct _NautilusScsiInfo {
+        gchar   dev_name;               /* device name: a, b, c, ... */
+        guint8  host, channel, id, lun; /* physical location */
+        gchar   vendor[9], model[17], rev[5];
+                                        /* vendor identification */
+        guint32 size_blocks;            /* device size, blocks (Kb) */
+        struct _NautilusScsiInfo*
+                next;                   /* list */
+        ScsiDeviceType
+                dev_type;               /* SCSI device class */
+} NautilusScsiInfo;
+
 static GtkTargetEntry hardware_dnd_target_table[] = {
 	{ "application/x-color", 0, TARGET_COLOR },
 };
@@ -77,6 +92,11 @@ static void hardware_view_load_location_
                                                        const char                *location,
                                                        NautilusHardwareView      *hardware_view);
 
+guint32     next_scsi_device_size                     (FILE* fp);
+NautilusScsiInfo* 
+            get_scsi_info                             (void);
+void        done_scsi_info                            (NautilusScsiInfo* list);
+
 EEL_DEFINE_CLASS_BOILERPLATE (NautilusHardwareView, nautilus_hardware_view, GTK_TYPE_EVENT_BOX)
 
 #define HARDWARE_DEFAULT_BACKGROUND_COLOR  "rgb:DDDD/DDDD/BBBB"
@@ -341,6 +361,131 @@ get_IDE_description (const char *device)
 }
 
 
+/* Get the device size of the next SCSI disk in the partition table. */
+guint32
+next_scsi_device_size(FILE* fp) {
+        char buf[256];                  /* sar-enabled kernels have long lines in
+                                         * /proc/partitions!
+                                         */
+
+        for (;;) {
+                if (fgets(buf, sizeof buf, fp) != NULL) {
+                        /* if SCSI device, and it's a disk (not a partition...) */
+                        if (buf[22] == 's' && buf[25] == ' ') {
+                                return strtol(buf+11, NULL, 10);
+                        }
+                }
+                if (feof(fp) != 0) {
+                        return 0;
+                }
+        }
+}
+
+/* Scan all SCSI devices visible in /proc/scsi/scsi, and return a list of device info.
+ */
+NautilusScsiInfo*
+get_scsi_info (void) {
+        FILE    *fp_scsi, *fp_part;
+        NautilusScsiInfo
+                *device, *list_head;
+        gchar   buf[64];
+
+        list_head = NULL;
+        
+        fp_scsi = fopen ("/proc/scsi/scsi", "r");
+        fp_part = fopen ("/proc/partitions", "r");
+       
+        /* give up if we can't get all the relevant info */
+        if (fp_scsi != NULL && fp_part != NULL) {
+                
+                device = list_head = g_new(NautilusScsiInfo, 1);
+
+                /* get info for all devices */
+                while ( feof (fp_scsi) == 0 ) {
+
+                        if (device == NULL) {
+                                device = g_new(NautilusScsiInfo, 1);
+                                device->next = list_head;
+                                list_head = device;
+                        }
+                        
+                        if ( fgets(buf, sizeof buf, fp_scsi) != NULL ) {
+                                if (strncmp("Host:", buf, 5) == 0) {
+                                        device->host    = strtol(buf+10, NULL, 10);
+                                        device->channel = strtol(buf+21, NULL, 10);
+                                        device->id      = strtol(buf+28, NULL, 10);
+                                        device->lun     = strtol(buf+36, NULL, 10);
+                                } else if (strncmp("Vendor:", buf+2, 7) == 0) {
+                                        strncpy(device->vendor, buf+10, sizeof device->vendor-1);
+                                        strncpy(device->model, buf+26, sizeof device->model-1);
+                                        strncpy(device->rev, buf+48, sizeof device->rev-1);
+                                } else if (strncmp("Type:", buf+2, 5) == 0) {
+                                        if (strncmp("Direct-Access", buf+10, 13) == 0) {
+                                                device->dev_type = Scsi_Disk;
+                                        } else if (strncmp("CD-ROM", buf+10, 6) == 0) {
+                                                device->dev_type = Scsi_CDROM;
+                                        } else if (strncmp("Sequential-Access", buf+10, 17) == 0) {
+                                                device->dev_type = Scsi_Tape;
+                                        } else {
+                                                device->dev_type = Scsi_Other;
+                                        }
+
+                                        /* We're done with the /proc/scsi/scsi part of the
+                                         * scanning, so get the device size from
+                                         * /proc/partitions
+                                         */
+                                        device->size_blocks = next_scsi_device_size(fp_part);
+                                        
+                                        /* Next item */
+                                        device = NULL;
+                                }
+                        } else {
+                                list_head = device->next;
+                                g_free(device);
+                        }
+                }
+        }
+
+        if (fp_scsi != NULL) {
+                fclose (fp_scsi);
+        }
+        if (fp_part != NULL) {
+                fclose (fp_part);
+        }
+
+        return list_head;
+}
+
+static char*
+get_SCSI_description (NautilusScsiInfo* scsi_dev) {
+        GString* str_description;
+        char* str_size;
+        static char* description;
+        float size_mb;
+
+        str_description = g_string_new ("");
+        g_string_append (str_description, scsi_dev->vendor);
+        g_string_append (str_description, " ");
+        g_string_append (str_description, scsi_dev->model);
+        if (scsi_dev->dev_type == Scsi_Disk) {
+                g_string_append (str_description, "\n");
+
+                /* FIXME: share size computation with IDE code */
+                size_mb = scsi_dev->size_blocks / 1000.0;
+                if (scsi_dev->size_blocks > 1000) {
+                        str_size = g_strdup_printf ("%.1f GB", (size_mb/1000.0));
+                } else {
+                        str_size = g_strdup_printf ("%.1f MB", size_mb);
+                }
+                g_string_append (str_description, str_size);
+        }
+
+        description = str_description->str;
+        g_string_free (str_description, FALSE);
+        
+        return description;
+}
+
 /* shared utility to allocate a title for a form */
 
 static void
@@ -397,6 +542,7 @@ setup_overview_form (NautilusHardwareVie
 	DIR *directory;
         struct dirent* entry;
         char *device, *proc_file, *ide_media;
+        NautilusScsiInfo *scsi_info, *scsi_dev;
 	
 	/* allocate a vbox as the container */	
 	view->details->form = gtk_vbox_new(FALSE,0);
@@ -496,6 +642,57 @@ setup_overview_form (NautilusHardwareVie
                         }
                 }
                 closedir(directory);
+        }
+
+        /* Display SCSI disks and CD devices.
+         * by Ed McKenzie <eem12 cornell edu>
+         *
+         * SCSI device info is only supported on Linux 2.2 and 2.4 with /proc mounted.
+         * Additionally, we make the assumption that the device ordering for disks in
+         * /proc/scsi/scsi is the same as the partition ordering for /dev/sd? in
+         * /proc/partitions.  Both files must be present for get_scsi_info to return
+         * useful information.
+         */
+        scsi_info = get_scsi_info();
+        if (scsi_info) {
+                scsi_dev = scsi_info;
+                while (scsi_dev != NULL) {
+                        temp_box = gtk_vbox_new(FALSE, 4);
+	                add_element_to_table (table, temp_box, element_index++);
+                        gtk_widget_show(temp_box);
+                        
+                        switch (scsi_dev->dev_type) {
+                                case Scsi_Disk:
+                                        file_name = nautilus_pixmap_file("i-harddisk.png");
+                                        break;
+                                case Scsi_CDROM:
+                                        file_name = nautilus_pixmap_file("CD_drive.png");
+                                        break;
+                                /* FIXME: i-harddisk is a filler icon */
+                                case Scsi_Tape:
+                                case Scsi_Other:
+                                        file_name = nautilus_pixmap_file("i-harddisk.png");
+                                        break;
+                        }
+
+        		pixmap_widget = eel_image_new (file_name);
+	        	gtk_box_pack_start (GTK_BOX(temp_box), pixmap_widget, 0, 0, 0);
+		        gtk_widget_show(pixmap_widget);
+        		g_free(file_name);
+                                
+        		temp_text = get_SCSI_description(scsi_dev);
+	        	temp_widget = eel_label_new (temp_text);
+		        eel_label_make_larger (EEL_LABEL (temp_widget), 2);
+        		eel_label_set_justify (EEL_LABEL (temp_widget), GTK_JUSTIFY_CENTER);
+
+	        	g_free(temp_text);
+                        gtk_box_pack_start(GTK_BOX(temp_box), temp_widget, 0, 0, 0);
+                        gtk_widget_show(temp_widget);
+
+                        scsi_info = scsi_dev;
+                        scsi_dev = scsi_dev->next;
+                        g_free(scsi_info);
+                }
         }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]