--- lsraid.c	2004-02-25 10:53:06.000000000 -0500
+++ lsraid.c	2004-02-26 15:24:25.000000000 -0500
@@ -56,10 +56,6 @@
 #define LSRAID_VERSION "0.7.0"
 
 /* Imagine the fun when we get to different major,minor sizes :-) */
-#define MAJORBITS 8
-#define MINORBITS 8
-#define MAJORS (1 << MAJORBITS)
-#define MINORS (1 << MINORBITS)
 
 /* Debugging for device scanning */
 #define SCAN_DEBUG 0
@@ -73,6 +69,7 @@
 typedef struct _LSRDir     LSRDir;
 typedef struct _LSRArray   LSRArray;
 typedef struct _LSRDisk    LSRDisk;
+typedef struct  _LSRDevtable LSRDevtable;
 
 
 
@@ -95,6 +92,13 @@
     LSR_DEV_SCAN     = 1 << 4
 } LSRFlags;
 
+struct  _LSRDevtable
+{
+	int major;
+	int minor;
+	char* name;
+	LSRDevtable* next, *prev;
+};
 
 
 /*
@@ -108,8 +112,7 @@
     struct list_head o_disks;   /* Disk names from parse_options */
     struct list_head arrays;    /* Anchor for list of arrays (a_list) */
     struct list_head disks;     /* Anchor for list of disks (d_list) */
-    char ***devtable;           /* Table of known device names
-                                   (major, minor) -> name */
+	LSRDevtable* devtable;
 };
 
 struct _LSRNamEnt
@@ -159,6 +162,8 @@
 /*
  * Prototypes
  */
+static char* getname(LSRContext* ctxt, int major, int minor);
+static int add_devtable(LSRContext* ctxt, int major, int minor, char* name);
 static void print_usage(int rc);
 static void print_usage_long();
 static void print_version();
@@ -213,7 +218,54 @@
 /*
  * Functions
  */
+static char* getname(LSRContext* ctxt, int major, int minor)
+{
+	LSRDevtable* head=ctxt->devtable;
+	ctxt->devtable=ctxt->devtable->next;
+	while(ctxt->devtable->name!="")
+	{
+		if(ctxt->devtable->minor==minor)
+			if(ctxt->devtable->major==major)
+				break;
+		ctxt->devtable=ctxt->devtable->next;
+	}
+	if(ctxt->devtable->name!="")
+	{
+		LSRDevtable* temp = ctxt->devtable;
+		ctxt->devtable=head;
+		return temp->name;
+	}
+	else
+	{
+		return NULL;
+	}
+}
 
+static int add_devtable(LSRContext* ctxt, int major, int minor, char* name)
+{	
+	int rc=0;
+	if(ctxt->devtable)
+	{
+		LSRDevtable* temp = (LSRDevtable*)malloc(sizeof(LSRDevtable));
+		if (!temp)
+		{
+			rc = -ENOMEM;
+		}
+		else
+		{
+			temp->major=major;
+			temp->minor=minor;
+			temp->name=name;
+			ctxt->devtable->prev->next=temp;
+			temp->prev=ctxt->devtable->prev;
+			temp->next=ctxt->devtable;
+			ctxt->devtable->prev=temp;
+		}
+	}
+	else
+		rc = -ENOMEM;
+	return(rc);
+}
 
 static void print_version()
 {
@@ -258,13 +310,17 @@
         INIT_LIST_HEAD(&ctxt->o_arrays);
         INIT_LIST_HEAD(&ctxt->disks);
         INIT_LIST_HEAD(&ctxt->arrays);
-        ctxt->devtable = (char ***)malloc(MAJORS * sizeof(char **));
+        ctxt->devtable = (LSRDevtable*)malloc(sizeof(LSRDevtable));
         if (!ctxt->devtable)
         {
             free(ctxt);
             return(NULL);
         }
-        memset(ctxt->devtable, 0, MAJORS * sizeof(char **));
+        ctxt->devtable->major=0;
+        ctxt->devtable->minor=0;
+        ctxt->devtable->name="";
+        ctxt->devtable->next=ctxt->devtable;
+        ctxt->devtable->prev=ctxt->devtable;
     }
     return(ctxt);
 }  /* alloc_context() */
@@ -973,14 +1029,14 @@
         {
             fprintf(stderr,
                     "lsraid: Unable to allocate memory for information on device \"%s\": %s\n",
-                    ctxt->devtable[major][minor],
+			getname(ctxt,major,minor),
                     strerror(errno));
             return;
         }
     }
     proc_name[0] = '\0';
 
-    dev_base = strrchr(ctxt->devtable[major][minor], '/');
+    dev_base = strrchr(getname(ctxt,major,minor), '/');
     if ((dev_base == NULL) ||
         (dev_base[1] == '\0'))
         return;
@@ -1013,11 +1069,11 @@
     {
         fprintf(stderr,
                 "lsraid: Unable to allocate memory for information on device \"%s\": %s\n",
-                ctxt->devtable[major][minor],
+		getname(ctxt,major,minor),
                 strerror(errno));
         return;
     }
-    ent->name = ctxt->devtable[major][minor];
+    ent->name = getname(ctxt,major,minor);
 
     /* Should we add MD_MAJOR devices to o_disks too? */
     if (major == MD_MAJOR)
@@ -1058,45 +1114,26 @@
 
         if (*name && major)
         {
-            if (!ctxt->devtable[major])
-            {
-                ctxt->devtable[major] =
-                    (char **)malloc(MINORS * sizeof(char *));
-                if (!ctxt->devtable[major])
-                {
-                    rc = -ENOMEM;
-                    break;
-                }
-                memset(ctxt->devtable[major], 0,
-                       MINORS * sizeof(char *));
-            }
-
-            if (ctxt->devtable[major][minor])
+            if(getname(ctxt,major,minor))
                 continue;
 
-            /*
-             * This is all '/dev' specific.  If it isn't found there,
-             * it is going to fall back to /dev scanning (think 
-             * /dev/usb/disk1 or something in devfs).  This heuristic
-             * should probably check whatever devfs puts together
-             * for 'hda1 in /proc/partitions', but I don't know what
-             * devfs does, and I don't much care right now.
-             */
-            ctxt->devtable[major][minor] =
-                (char *)malloc((strlen(name) + strlen("/dev/") + 1) *
-                               sizeof(char));
-            if (!ctxt->devtable[major][minor])
+            char* tempstr = (char *)malloc((strlen(name) + strlen("/dev/") + 1) *
+                           sizeof(char));
+            if(!tempstr)
                 continue;
-            sprintf(ctxt->devtable[major][minor], "/dev/%s", name);
-
-            rc = stat(ctxt->devtable[major][minor], &stat_buf);
-            if ((rc != 0) && (!S_ISBLK(stat_buf.st_mode)))
-            {
-                free(ctxt->devtable[major][minor]);
-                ctxt->devtable[major][minor] = NULL;
-            }
-            else if (ctxt->flags & LSR_DEV_SCAN)
-                maybe_add_device(ctxt, major, minor);
+            sprintf(tempstr, "/dev/%s", name);
+	
+            rc = stat(tempstr, &stat_buf);
+        	if ((rc != 0) && (!S_ISBLK(stat_buf.st_mode)))
+        	{
+            	free(tempstr);
+            	tempstr= NULL;
+        	}
+        	else if (ctxt->flags & LSR_DEV_SCAN)
+        	{
+                if(add_devtable(ctxt,major,minor,tempstr)==0)
+                	maybe_add_device(ctxt, major, minor);
+        	}
         }
     }
 
@@ -1241,26 +1278,15 @@
         {
             major = major(stat_buf.st_rdev);
             minor = minor(stat_buf.st_rdev);
-            if (!ctxt->devtable[major])
+            if(getname(ctxt,major,minor))
+                continue;
+
+            char* tempstr = (char *)malloc((strlen(name) + 1) * sizeof(char));
+            if(tempstr)
             {
-                ctxt->devtable[major] =
-                    (char **)malloc(MINORS * sizeof(char *));
-                if (!ctxt->devtable[major])
-                {
-                    /* FIXME: what error if any? rc = -ENOMEM; */
-                    continue;
-                }
-                memset(ctxt->devtable[major], 0,
-                       MINORS * sizeof(char *));
+                strcpy(tempstr, name);
+                add_devtable(ctxt,major,minor,tempstr);  
             }
-
-            if (ctxt->devtable[major][minor])
-                continue;
-            
-            ctxt->devtable[major][minor] =
-                (char *)malloc((strlen(name) + 1) * sizeof(char));
-            if (ctxt->devtable[major][minor])
-                strcpy(ctxt->devtable[major][minor], name);
         }
     }
 
@@ -1298,14 +1324,14 @@
     if (!major)
         return(-EINVAL);
 
-    if (ctxt->devtable[major] && ctxt->devtable[major][minor])
+    if(getname(ctxt,major,minor))
         goto out;
 
     if (!loaded_partitions)
     {
         load_partitions(ctxt);
         loaded_partitions = 1;
-        if (ctxt->devtable[major] && ctxt->devtable[major][minor])
+        if(getname(ctxt,major,minor))
             goto out;
     }
 
@@ -1313,15 +1339,15 @@
     {
         scan_slash_dev(ctxt);
         scanned_dev = 1;
-        if (ctxt->devtable[major] && ctxt->devtable[major][minor])
+        if(getname(ctxt,major,minor))
             goto out;
     }
 
     rc = -ENOENT;
 
 out:
-    if (ctxt->devtable[major])
-        *name = ctxt->devtable[major][minor];
+    if(getname(ctxt,major,minor))
+        *name=getname(ctxt,major,minor);
     return(rc);
 }  /* find_device() */
 
@@ -1398,7 +1424,6 @@
 
 static void clean_context(LSRContext *ctxt)
 {
-    int i;
     struct list_head *pos, *n;
     LSRArray *array;
     LSRDisk *disk;
@@ -1426,10 +1451,13 @@
     }
     if (ctxt->devtable)
     {
-        for (i = 0; i < MAJORS; i++)
-            if (ctxt->devtable[i])
-                free(ctxt->devtable[i]);
-        free(ctxt->devtable);
+        LSRDevtable* head=ctxt->devtable;
+        do
+        {
+            LSRDevtable* temp=ctxt->devtable;
+            ctxt->devtable=ctxt->devtable->next;
+            free(temp);
+        }while(ctxt->devtable != head);
     }
     free(ctxt);
 }  /* clean_context() */
@@ -2613,6 +2641,7 @@
  * Main program
  */
 
+#ifndef TESTING	/*for FNST testing*/
 int main(int argc, char *argv[])
 {
     int i;
@@ -2653,3 +2682,4 @@
     clean_context(ctxt);
     return(0);
 }  /* main() */
+#endif /*TESTING*/
