diff --git a/src/slurmctld/buffer.c b/src/slurmctld/buffer.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd91e6a307e4710a4b257ff607440b107432bf14
--- /dev/null
+++ b/src/slurmctld/buffer.c
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+/* seemingly unused buffer functions */
+
+/* 
+ * read_buffer - read a line from the specified buffer
+ * input: buffer - pointer to read buffer, must be allocated by alloc()
+ *        buffer_offset - byte offset in buffer, read location
+ *        buffer_size - byte size of buffer
+ *        line - pointer to location to be loaded with pointer to the line
+ * output: buffer_offset - incremented by  size of size plus the value size itself
+ *         line - set to pointer to the line
+ *         returns 0 if no error or EFAULT on end of buffer, EINVAL on bad tag 
+ */
+int 
+read_buffer (char *buffer, int *buffer_offset, int buffer_size, char **line) 
+{
+	if ((*buffer_offset) >= buffer_size)
+		return EFAULT;
+	line[0] = &buffer[*buffer_offset];
+	(*buffer_offset) += (strlen (line[0]) + 1);
+
+	if ((*buffer_offset) > buffer_size)
+		return EFAULT;
+	return 0;
+}
+
+/* 
+ * write_buffer - write the specified line to the specified buffer, 
+ *               enlarging the buffer as needed
+ * input: buffer - pointer to write buffer, must be allocated by alloc()
+ *        buffer_offset - byte offset in buffer, write location
+ *        buffer_size - byte size of buffer
+ *        line - pointer to data to be writen
+ * output: buffer - value is written here, buffer may be relocated by xrealloc()
+ *         buffer_offset - incremented by value_size
+ *         returns 0 if no error or errno otherwise 
+ */
+int 
+write_buffer (char **buffer, int *buffer_offset, int *buffer_size, char *line) 
+{
+	int line_size;
+
+	line_size = strlen (line) + 1;
+	if ((*buffer_offset + line_size) >= *buffer_size) {
+		(*buffer_size) += line_size + 8096;
+		if (buffer[0])
+			xrealloc (buffer[0], *buffer_size);
+		else
+			buffer[0] = xmalloc(*buffer_size);
+	}
+
+	memcpy (buffer[0] + (*buffer_offset), line, line_size);
+	(*buffer_offset) += line_size;
+	return 0;
+}
+
+
diff --git a/src/slurmctld/parse_spec.c b/src/slurmctld/parse_spec.c
new file mode 100644
index 0000000000000000000000000000000000000000..7fe6329e2ed61204c6702a268d1aaa00aeb26678
--- /dev/null
+++ b/src/slurmctld/parse_spec.c
@@ -0,0 +1,204 @@
+/* $Id$ */
+
+/* slurm_parser() functionality - split out from bits_bytes.c  and
+ * moved into slurmctld/ srcdir
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "log.h"
+#include "xmalloc.h"
+
+#define BUF_SIZE 1024
+#define SEPCHARS " \n\t"
+
+/* 
+ * slurm_parser - parse the supplied specification into keyword/value pairs
+ *	only the keywords supplied will be searched for. the supplied specification
+ *	is altered, overwriting the keyword and value pairs with spaces.
+ * input: spec - pointer to the string of specifications
+ *	sets of three values (as many sets as required): keyword, type, value 
+ *	keyword - string with the keyword to search for including equal sign 
+ *		(e.g. "name=")
+ *	type - char with value 'd' for int, 'f' for float, 's' for string
+ *	value - pointer to storage location for value (char **) for type 's'
+ * output: spec - everything read is overwritten by speces
+ *	value - set to read value (unchanged if keyword not found)
+ *	return - 0 if no error, otherwise errno code
+ * NOTE: terminate with a keyword value of "END"
+ * NOTE: values of type (char *) are xfreed if non-NULL. caller must xfree any 
+ *	returned value
+ */
+int
+slurm_parser (char *spec, ...)
+{
+	va_list ap;
+	char *keyword, **str_ptr;
+	int error_code, *int_ptr, type;
+	float *float_ptr;
+	
+	error_code = 0;
+	va_start(ap, spec);
+	while (error_code == 0) {
+		keyword = va_arg(ap, char *);
+		if (strcmp (keyword, "END") == 0)
+			break;
+		type = va_arg(ap, int);
+		switch (type) {
+		case 'd':
+			int_ptr = va_arg(ap, int *);
+			error_code = load_integer(int_ptr, keyword, spec);
+			break;
+		case 'f':
+			float_ptr = va_arg(ap, float *);
+			error_code = load_float(float_ptr, keyword, spec);
+			break;
+		case 's':
+			str_ptr = va_arg(ap, char **);
+			error_code = load_string(str_ptr, keyword, spec);
+			break;
+		default:
+			fatal ("parse_spec: invalid type %c", type);
+		}
+	}
+	va_end(ap);
+	return error_code;
+}
+
+
+/*
+ * load_float - location into which result is stored
+ *        keyword - string to search for
+ *        in_line - string to search for keyword
+ * output: *destination - set to value, no change if value not found
+ *         in_line - the keyword and value (if present) are overwritten by spaces
+ *         return value - 0 if no error, otherwise an error code
+ * NOTE: in_line is overwritten, do not use a constant
+ */
+int 
+load_float (float *destination, char *keyword, char *in_line) 
+{
+	char scratch[BUF_SIZE];	/* scratch area for parsing the input line */
+	char *str_ptr1, *str_ptr2, *str_ptr3;
+	int i, str_len1, str_len2;
+
+	str_ptr1 = (char *) strstr (in_line, keyword);
+	if (str_ptr1 != NULL) {
+		str_len1 = strlen (keyword);
+		strcpy (scratch, str_ptr1 + str_len1);
+		if ((scratch[0] < '0') && (scratch[0] > '9')) {
+			error ("load_float: bad value for keyword %s\n", keyword);
+			return EINVAL;
+		}
+		str_ptr2 = (char *) strtok_r (scratch, SEPCHARS, &str_ptr3);
+		str_len2 = strlen (str_ptr2);
+		*destination = (float) strtod (scratch, (char **) NULL);
+		for (i = 0; i < (str_len1 + str_len2); i++) {
+			str_ptr1[i] = ' ';
+		}
+	}
+	return 0;
+}
+
+
+/*
+ * load_integer - parse a string for a keyword, value pair  
+ * input: *destination - location into which result is stored
+ *        keyword - string to search for
+ *        in_line - string to search for keyword
+ * output: *destination - set to value, no change if value not found, 
+ *             set to 1 if keyword found without value, 
+ *             set to -1 if keyword followed by "unlimited"
+ *         in_line - the keyword and value (if present) are overwritten by spaces
+ *         return value - 0 if no error, otherwise an error code
+ * NOTE: in_line is overwritten, do not use a constant
+ */
+int 
+load_integer (int *destination, char *keyword, char *in_line) 
+{
+	char scratch[BUF_SIZE];	/* scratch area for parsing the input line */
+	char *str_ptr1, *str_ptr2, *str_ptr3;
+	int i, str_len1, str_len2;
+
+	str_ptr1 = (char *) strstr (in_line, keyword);
+	if (str_ptr1 != NULL) {
+		str_len1 = strlen (keyword);
+		strcpy (scratch, str_ptr1 + str_len1);
+		if ((scratch[0] == (char) NULL) || 
+		    (isspace ((int) scratch[0]))) {	/* keyword with no value set */
+			*destination = 1;
+			str_len2 = 0;
+		}
+		else {
+			str_ptr2 =
+				(char *) strtok_r (scratch, SEPCHARS, &str_ptr3);
+			str_len2 = strlen (str_ptr2);
+			if (strcmp (str_ptr2, "UNLIMITED") == 0)
+				*destination = -1;
+			else if ((str_ptr2[0] >= '0') && (str_ptr2[0] <= '9')) {
+				*destination =
+					(int) strtol (scratch, (char **) NULL, 10);
+			}
+			else {
+				error ("load_integer: bad value for keyword %s\n",
+					keyword);
+				return EINVAL;
+			}
+		}
+
+		for (i = 0; i < (str_len1 + str_len2); i++) {
+			str_ptr1[i] = ' ';
+		}
+	}
+	return 0;
+}
+
+
+/*
+ * load_string - parse a string for a keyword, value pair  
+ * input: *destination - location into which result is stored
+ *        keyword - string to search for
+ *        in_line - string to search for keyword
+ * output: *destination - set to value, no change if value not found, 
+ *	     if *destination had previous value, that memory location is automatically freed
+ *         in_line - the keyword and value (if present) are overwritten by spaces
+ *         return value - 0 if no error, otherwise an error code
+ * NOTE: destination must be free when no longer required
+ * NOTE: if destination is non-NULL at function call time, it will be freed 
+ * NOTE: in_line is overwritten, do not use a constant
+ */
+int 
+load_string (char **destination, char *keyword, char *in_line) 
+{
+	char scratch[BUF_SIZE];	/* scratch area for parsing the input line */
+	char *str_ptr1, *str_ptr2, *str_ptr3;
+	int i, str_len1, str_len2;
+
+	str_ptr1 = (char *) strstr (in_line, keyword);
+	if (str_ptr1 != NULL) {
+		str_len1 = strlen (keyword);
+		strcpy (scratch, str_ptr1 + str_len1);
+		if ((scratch[0] == (char) NULL) || 
+		    (isspace ((int) scratch[0]))) {	/* keyword with no value set */
+			error ("load_string: keyword %s lacks value\n",
+				keyword);
+			return EINVAL;
+		}
+		str_ptr2 = (char *) strtok_r (scratch, SEPCHARS, &str_ptr3);
+		str_len2 = strlen (str_ptr2);
+		if (destination[0] != NULL)
+			xfree (destination[0]);
+		destination[0] = (char *) xmalloc (str_len2 + 1);
+		strcpy (destination[0], str_ptr2);
+		for (i = 0; i < (str_len1 + str_len2); i++) {
+			str_ptr1[i] = ' ';
+		}
+	}
+	return 0;
+}
+
+
diff --git a/src/slurmctld/util.c b/src/slurmctld/util.c
new file mode 100644
index 0000000000000000000000000000000000000000..38aa4513627546f527e52677a3f8280f66e7a1b1
--- /dev/null
+++ b/src/slurmctld/util.c
@@ -0,0 +1,38 @@
+/* $Id$ */
+
+/* generic utility functions used by slurmctld:
+ *
+ */
+
+#include <string.h>
+
+#include <src/slurmctld/util.h>
+
+/*
+ * block_or_cycle - map string into integer
+ * input: in_string: pointer to string containing "BLOCK" or "CYCLE"
+ * output: returns DIST_BLOCK for "BLOCK", DIST_CYCLE for "CYCLE", -1 otherwise
+ */
+enum task_dist
+block_or_cycle (char *in_string)
+{
+	if (strcmp (in_string, "BLOCK") == 0) return DIST_BLOCK;
+	if (strcmp (in_string, "CYCLE")  == 0) return DIST_CYCLE;
+	return -1;
+}
+
+/*
+ * yes_or_no - map string into integer
+ * input: in_string: pointer to string containing "YES" or "NO"
+ * output: returns 1 for "YES", 0 for "NO", -1 otherwise
+ */
+int
+yes_or_no (char *in_string)
+{
+	if (strcmp (in_string, "YES") == 0) return 1;
+	if (strcmp (in_string, "NO")  == 0) return 0;
+	return -1;
+}
+
+
+
diff --git a/src/slurmctld/util.h b/src/slurmctld/util.h
new file mode 100644
index 0000000000000000000000000000000000000000..4edfc38542a0e416c15abd4b805d0e9cabd3007e
--- /dev/null
+++ b/src/slurmctld/util.h
@@ -0,0 +1,12 @@
+/* $Id$ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include "slurmctld.h"
+
+enum task_dist block_or_cycle (char *in_string);
+int yes_or_no (char *in_string);
+
+
+#endif /* !_UTIL_H */