--- numactl-0.9.6/libnuma.c	2006-06-12 10:43:30.000000000 +0200
+++ numactl/libnuma.c	2006-06-10 03:10:40.000000000 +0200
@@ -398,35 +398,58 @@
 
 static unsigned long *node_cpu_mask[NUMA_NUM_NODES];  
 
-static void bad_cpumap(int ncpus, unsigned *mask)
+static void bad_cpumap(int ncpus, unsigned long *mask)
 {
 	int n;
 	for (n = 0; n < ncpus; n++)
-		set_bit(n, (unsigned long *)mask);
+		set_bit(n, mask);
 }
 
-static int strcount(char *s, int c)
+int numa_parse_bitmap(char *line, unsigned long *mask, int ncpus)
 {
-	int n = 0;
-	for (; *s; s++) 
-		if (*s == c)
-			n++;
-	return n;
+	int i;
+	char *p = strchr(line, '\n'); 
+	if (!p)
+		return -1;
+
+	for (i = 0; p > line;i++) {
+		char *oldp, *endp; 
+		oldp = p;
+		if (*p == ',') 
+			--p;
+		while (p > line && *p != ',')
+			--p;
+		/* Eat two 32bit fields at a time to get longs */
+		if (sizeof(unsigned long) == 8) {
+			oldp--;
+			memmove(p, p+1, oldp-p+1);
+			while (p > line && *p != ',')
+				--p;
+		}
+		if (*p == ',')
+			p++;
+		if (i >= CPU_LONGS(ncpus))
+			return -1;
+		mask[i] = strtoul(p, &endp, 16);
+		if (endp != oldp)
+			return -1;
+		p--;
+	}
+	return 0;
 }
 
 /* This would be better with some locking, but I don't want to make libnuma
    dependent on pthreads right now. The races are relatively harmless. */
 int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) 
 {
+	int err = 0;
 	char fn[64];
 	FILE *f; 
 	char *line = NULL; 
 	size_t len = 0; 
-	char *p;
 	int buflen_needed;
-	unsigned *mask;
+	unsigned long *mask;
 	int ncpus = number_of_configured_cpus();
-	int i;
 
 	buflen_needed = CPU_BYTES(ncpus);
 	if ((unsigned)node > maxnode || bufferlen < buflen_needed) { 
@@ -442,7 +465,7 @@
 
 	mask = malloc(buflen_needed);
 	if (!mask) 
-		mask = (unsigned *)buffer; 
+		mask = (unsigned long *)buffer; 
 	memset(mask, 0, buflen_needed); 
 
 	sprintf(fn, "/sys/devices/system/node/node%d/cpumap", node); 
@@ -452,51 +475,28 @@
 		   "/sys not mounted or invalid. Assuming one node: %s",
 			  strerror(errno)); 
 		bad_cpumap(ncpus, mask);
-		goto out;
+		err = -1;
 	} 
-	fclose(f);
-	p = strchr(line, '\n'); 
-	if (!p) {
+	if (f)
+		fclose(f);
+
+	if (line && numa_parse_bitmap(line, mask, ncpus) < 0) {
 		numa_warn(W_cpumap, "Cannot parse cpumap. Assuming one node");
 		bad_cpumap(ncpus, mask);
-		goto out;
-	}
-	for (i = 0; p > line;i++) {
-		char *oldp, *endp; 
-		oldp = p;
-		if (*p == ',') 
-			--p;
-		while (p > line && *p != ',')
-			--p;
-		p++;
-		if (i >= CPU_LONGS(ncpus) * (sizeof(long)/sizeof(unsigned))) {
-			numa_warn(W_cpumap, 
-   "cpumap too long, has %d longs. ncpus %d, Assuming one node", 
-			  strcount(line, ',')+1, ncpus);
-			bad_cpumap(ncpus, mask);
-			goto out;
-		}
-		mask[i] = strtoul(p, &endp, 16);
-		if (endp != oldp) {
-			numa_warn(W_cpumap, "Cannot parse cpumap. Assuming one node");
-			bad_cpumap(ncpus, mask); 
-			goto out;
-		}
-		p--;
+		err = -1;
 	}
 
- out:
 	free(line);
 	memcpy(buffer, mask, buflen_needed);
 
 	/* slightly racy, see above */ 
 	if (node_cpu_mask[node]) {
-		if (mask != (unsigned *)buffer)
+		if (mask != buffer)
 			free(mask); 	       
 	} else {
-		node_cpu_mask[node] = (unsigned long *)mask; 
+		node_cpu_mask[node] = mask; 
 	} 
-	return 0; 
+	return err; 
 } 
 
 make_internal_alias(numa_node_to_cpus);
