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



On Mon, Jun 25, 2001 at 06:27:58PM -0700, Ramiro Estrugo wrote:
> I tried your patch on a non scsi machine, and it crashed the hardware
> view when I typed "hardware:" into the Location bar.
> 
> Can you debug this some more ?  Ill look at the patch after that.
> 
> Thanks for your patience.
> 
> -re

Oops.  This version of the patch should no longer crash on IDE (or
SCSI!) machines.  Feedback from users with odd hardware
(e.g. IDE+SCSI) is welcome, as I've only tested this on machines I
have access to.  Thanks,
	ed

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 -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/27 02:26: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 @@
 	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;                   /* device size, in bytes */
+        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 @@
                                                        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,136 @@
 }
 
 
+/* 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 (e.g. RedHat) have long
+                                         * lines in /proc/partitions
+                                         */
+
+        for (;;) {
+                if (fgets (buf, sizeof buf, fp) != NULL) {
+                        /* test for lines that are SCSI -- and disks, as opposed to
+                         * partitions
+                         */
+                        if (buf[22] == 's' && (buf[25] == ' ' || buf[25] == '\n')) {
+                                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);
+                memset (device, 0, sizeof *device);
+                device->next = NULL;
+
+                /* get info for all devices */
+                while ( feof (fp_scsi) == 0 ) {
+
+                        if (device == NULL) {
+                                device = g_new (NautilusScsiInfo, 1);
+                                memset (device, 0, sizeof *device);
+                                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 = 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: the IDE code computes disk size differently. */
+                size_mb = scsi_dev->size / 1000.0;
+                if (scsi_dev->size > 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 +547,7 @@
 	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 +647,51 @@
                         }
                 }
                 closedir(directory);
+        }
+
+        /* Display SCSI disks and CD devices.
+         * by Ed McKenzie <eem12 cornell edu>
+         */
+        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]