diff --git a/src/common/bits_bytes.c b/src/common/bits_bytes.c
index 785d42e7f3160c11cef4b766f2b94a415b2b5682..4fc74c3e533cb717fa64636464ba5352a26f148a 100644
--- a/src/common/bits_bytes.c
+++ b/src/common/bits_bytes.c
@@ -11,6 +11,7 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdarg.h>
diff --git a/src/common/pack.c b/src/common/pack.c
index 79f47cfdefe73b684c84803c0c87933f31298b7a..475af624c6950764c781897f3a270b21ff9cd736 100644
--- a/src/common/pack.c
+++ b/src/common/pack.c
@@ -11,6 +11,7 @@
 #include <netinet/in.h>
 #include <string.h>
 #include "pack.h"
+#include "xmalloc.h"
 	
 	
 /*
@@ -98,15 +99,18 @@ _packstr(char *valp, uint32_t size_val, void **bufp, int *lenp)
 
 }
 
+
 /*
  * Given 'bufp' pointing to a network byte order 32-bit integer
  * (size) and an arbitrary data string, return a pointer to the 
  * data string in 'valp'.  Also return the sizes of 'valp' in bytes. 
  * Advance bufp and decrement lenp by 4 bytes (size of memory 
  * size records) plus the actual buffer size.
+ * NOTE: valp is set to point into the buffer bufp, a copy of 
+ *	the data is not made
  */
 void
-_unpackstr(char **valp, uint32_t *size_valp, void **bufp, int *lenp)
+_unpackstr_ptr(char **valp, uint32_t *size_valp, void **bufp, int *lenp)
 {
 	uint32_t nl;
 
@@ -125,3 +129,35 @@ _unpackstr(char **valp, uint32_t *size_valp, void **bufp, int *lenp)
 
 }
 	
+
+/*
+ * Given 'bufp' pointing to a network byte order 32-bit integer
+ * (size) and an arbitrary data string, return a pointer to the 
+ * data string in 'valp'.  Also return the sizes of 'valp' in bytes. 
+ * Advance bufp and decrement lenp by 4 bytes (size of memory 
+ * size records) plus the actual buffer size.
+ * NOTE: valp is set to point into a newly created buffer, 
+ *	the caller is responsible for calling xfree on *valp
+ *	if non-NULL (set to NULL on zero size buffer value)
+ */
+void
+_unpackstr_xmalloc(char **valp, uint32_t *size_valp, void **bufp, int *lenp)
+{
+	uint32_t nl;
+
+	memcpy(&nl, *bufp, sizeof(nl));
+	*size_valp = ntohl(nl);
+	(size_t)*bufp += sizeof(nl);
+	(size_t)*lenp -= sizeof(nl);
+
+	if (*size_valp > 0) {
+		*valp = xmalloc(*size_valp);
+		memcpy (*valp, *bufp, *size_valp);
+		(size_t)*bufp += *size_valp;
+		(size_t)*lenp -= *size_valp;
+	}
+	else
+		*valp = NULL;
+
+}
+	
diff --git a/src/common/pack.h b/src/common/pack.h
index 2e19c4f4743bb01b73cff2113d117c029a6f1032..ed0b90b2f600aaa7e388dc23e17a121fc1f33b1c 100644
--- a/src/common/pack.h
+++ b/src/common/pack.h
@@ -24,7 +24,8 @@ void	_pack16(uint16_t val, void **bufp, int *lenp);
 void	_unpack16(uint16_t *valp, void **bufp, int *lenp);
 
 void	_packstr(char *valp, uint32_t size_val, void **bufp, int *lenp);
-void	_unpackstr(char **valp, uint32_t *size_valp, void **bufp, int *lenp);
+void	_unpackstr_ptr(char **valp, uint32_t *size_valp, void **bufp, int *lenp);
+void	_unpackstr_xmalloc(char **valp, uint32_t *size_valp, void **bufp, int *lenp);
 
 #define pack32(val,bufp,lenp) do {			\
 	assert(sizeof(val) == sizeof(uint32_t)); 	\
@@ -69,13 +70,22 @@ void	_unpackstr(char **valp, uint32_t *size_valp, void **bufp, int *lenp);
 	_packstr(valp,size_val,bufp,lenp);		\
 } while (0)
 
-#define unpackstr(valp,size_valp,bufp,lenp) do {	\
+#define unpackstr_ptr(valp,size_valp,bufp,lenp) do {	\
 	assert(valp != NULL);				\
 	assert(sizeof(size_valp) == sizeof(uint32_t *));\
 	assert((bufp) != NULL && *(bufp) != NULL);	\
         assert((lenp) != NULL);				\
         assert(*(lenp) >= sizeof(uint32_t));		\
-	_unpackstr(valp,size_valp,bufp,lenp);		\
+	_unpackstr_ptr(valp,size_valp,bufp,lenp);	\
+} while (0)
+
+#define unpackstr_xmalloc(valp,size_valp,bufp,lenp) do {\
+	assert(valp != NULL);				\
+	assert(sizeof(size_valp) == sizeof(uint32_t *));\
+	assert((bufp) != NULL && *(bufp) != NULL);	\
+        assert((lenp) != NULL);				\
+        assert(*(lenp) >= sizeof(uint32_t));		\
+	_unpackstr_xmalloc(valp,size_valp,bufp,lenp);	\
 } while (0)
 
 #endif /* _PACK_INCLUDED */
diff --git a/src/common/slurm.h b/src/common/slurm.h
index 651a2dd86aef4c7fc66972d3666f378c86407c47..e88739974d8810865f9bdec874b49a6f81588082 100644
--- a/src/common/slurm.h
+++ b/src/common/slurm.h
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "bitstring.h"
 #include "xmalloc.h"
+#include "pack.h"
 
 #define DEBUG_SYSTEM 1
 
@@ -61,11 +62,11 @@ extern char *backup_controller;	/* name of computer acting as slurm backup contr
 #define NODE_MAGIC   0x0de575ed
 #define NO_VAL   (-9812)
 struct config_record {
-	unsigned magic;		/* magic cookie to test data integrity */
-	int cpus;		/* count of cpus running on the node */
-	int real_memory;	/* megabytes of real memory on the node */
-	int tmp_disk;		/* megabytes of total storage in TMP_FS file system */
-	int weight;		/* arbitrary priority of node for scheduling work on */
+	uint32_t magic;		/* magic cookie to test data integrity */
+	uint32_t cpus;		/* count of cpus running on the node */
+	uint32_t real_memory;	/* megabytes of real memory on the node */
+	uint32_t tmp_disk;	/* megabytes of total storage in TMP_FS file system */
+	uint32_t weight;	/* arbitrary priority of node for scheduling work on */
 	char *feature;		/* arbitrary list of features associated with a node */
 	char *nodes;		/* names of nodes in partition configuration record */
 	bitstr_t *node_bitmap;	/* bitmap of nodes in configuration record */
@@ -78,8 +79,7 @@ extern List config_list;	/* list of config_record entries */
 enum node_states {
 	STATE_DOWN,		/* node is not responding */
 	STATE_UNKNOWN,		/* node's initial state, unknown */
-	STATE_IDLE,		/* node idle and available for use */
-	STATE_STAGE_IN,		/* node has been allocated, job not yet running */
+	STATE_IDLE,		/* node unassigned to job */
 	STATE_BUSY,		/* node has been allocated, job currently */
 	STATE_DRAINED,		/* node idle and not to be allocated future work */
 	STATE_DRAINING,		/* node in use, but not to be allocated future work */
@@ -93,11 +93,11 @@ extern time_t last_node_update;		/* time of last update to node records */
 struct node_record {
 	unsigned magic;			/* magic cookie to test data integrity */
 	char name[MAX_NAME_LEN];	/* name of the node. a null name indicates defunct node */
-	enum node_states node_state;	/* state of the node, negative if down */
+	int node_state;			/* enum node_states, negative if down */
 	time_t last_response;		/* last response from the node */
-	int cpus;			/* actual count of cpus running on the node */
-	int real_memory;		/* actual megabytes of real memory on the node */
-	int tmp_disk;			/* actual megabytes of total disk in TMP_FS */
+	uint32_t cpus;			/* actual count of cpus running on the node */
+	uint32_t real_memory;		/* actual megabytes of real memory on the node */
+	uint32_t tmp_disk;		/* actual megabytes of total disk in TMP_FS */
 	struct config_record *config_ptr;	/* configuration specification for this node */
 	struct part_record *partition_ptr;	/* partition for this node */
 };
@@ -111,16 +111,17 @@ extern struct node_record default_node_record;
 
 /* NOTE: change PART_STRUCT_VERSION value whenever the contents of PART_STRUCT_FORMAT change */
 #define PART_STRUCT_VERSION 1
-#define PART_STRUCT_FORMAT "PartitionName=%s MaxNodes=%d MaxTime=%d Nodes=%s Key=%s Default=%s AllowGroups=%s Shared=%s State=%s #TotalNodes=%d TotalCPUs=%d\n"
+#define	INFINITE (0xffffffff)
+#define PART_STRUCT_FORMAT "PartitionName=%s MaxNodes=%u MaxTime=%u Nodes=%s Key=%s Default=%s AllowGroups=%s Shared=%s State=%s #TotalNodes=%d TotalCPUs=%d\n"
 #define PART_MAGIC 0xaefe8495
 extern time_t last_part_update;	/* time of last update to part records */
 struct part_record {
-	unsigned magic;		/* magic cookie to test data integrity */
+	uint32_t magic;		/* magic cookie to test data integrity */
 	char name[MAX_NAME_LEN];/* name of the partition */
-	int max_time;		/* minutes, -1 if unlimited */
-	int max_nodes;		/* per job, -1 if unlimited */
-	int total_nodes;	/* total number of nodes in the partition */
-	int total_cpus;		/* total number of cpus in the partition */
+	uint32_t max_time;	/* minutes, 0xffffffff if unlimited */
+	uint32_t max_nodes;	/* per job, 0xffffffff if unlimited */
+	uint32_t total_nodes;	/* total number of nodes in the partition */
+	uint32_t total_cpus;	/* total number of cpus in the partition */
 	unsigned key:1;		/* 1 if slurm distributed key is required for use of partition */
 	unsigned shared:2;	/* 1 if more than one job can execute on a node, 2 if required */
 	unsigned state_up:1;	/* 1 if state is up, 0 if down */
@@ -165,36 +166,36 @@ extern char *job_state_string[];
 extern int job_count;			/* number of jobs in the system */
 
 struct job_details {
-	unsigned magic;			/* magic cookie to test data integrity */
-	int num_procs;			/* minimum number of processors */
-	int num_nodes;			/* minimum number of nodes */
+	uint32_t magic;			/* magic cookie to test data integrity */
+	uint32_t num_procs;		/* minimum number of processors */
+	uint32_t num_nodes;		/* minimum number of nodes */
 	char *nodes;			/* required nodes */
 	char *features;			/* required features */
-	int shared;			/* desires shared nodes, 1=true, 0=false */
-	int contiguous;			/* requires contiguous nodes, 1=true, 0=false */
-	int min_procs;			/* minimum processors per node, MB */
-	int min_memory;			/* minimum memory per node, MB */
-	int min_tmp_disk;		/* minimum temporary disk per node, MB */
+	unsigned shared:2;		/* 1 if more than one job can execute on a node */
+	unsigned contiguous:1;		/* requires contiguous nodes, 1=true, 0=false */
+	uint32_t min_procs;		/* minimum processors per node, MB */
+	uint32_t min_memory;		/* minimum memory per node, MB */
+	uint32_t min_tmp_disk;		/* minimum temporary disk per node, MB */
 	enum task_dist dist;		/* distribution of tasks, 0=fill, 0=cyclic */
 	char *job_script;		/* name of job script to execute */
-	int procs_per_task;		/* processors required per task */
-	int total_procs;		/* total number of allocated processors, for accounting */
+	uint32_t procs_per_task;	/* processors required per task */
+	uint32_t total_procs;		/* total number of allocated processors, for accounting */
 	char *node_list;		/* comma separated assigned node list (by task) */
 	time_t submit_time;		/* time of submission */
 };
 
 struct job_record {
 	char job_id[MAX_ID_LEN];	/* job ID */
-	unsigned magic;			/* magic cookie to test data integrity */
+	uint32_t magic;			/* magic cookie to test data integrity */
 	char name[MAX_NAME_LEN];	/* name of the job */
 	char partition[MAX_NAME_LEN];	/* name of the partition */
-	uid_t user_id;			/* user the job runs as */
+	uint32_t user_id;		/* user the job runs as */
 	enum job_states job_state;	/* state of the job */
 	char *nodes;			/* comma delimited list of nodes allocated to job */
-	int time_limit;			/* maximum run time in minutes, -1 if unlimited */
+	uint32_t time_limit;		/* maximum run time in minutes, 0xffffffff if unlimited */
 	time_t start_time;		/* time execution begins, actual or expected*/
 	time_t end_time;		/* time of termination, actual or expected */
-	int priority;			/* relative priority of the job */
+	uint32_t priority;		/* relative priority of the job */
 	struct job_details *details;	/* job details (set until job terminates) */
 };
 
@@ -221,26 +222,26 @@ extern void  allocate_nodes (unsigned *bitmap);
 extern int bitmap2node_name (bitstr_t *bitmap, char **node_list);
 
 /*
- * block_or_cyclic - map string into integer
+ * block_or_cycle - map string into integer
  * input: in_string: pointer to string containing "BLOCK" or "CYCLE"
  * output: returns 1 for "BLOCK", 0 for "CYCLE", -1 otherwise
  */
-extern enum task_dist block_or_cyclic (char *in_string);
+extern enum task_dist block_or_cycle (char *in_string);
 
 /*
- * build_node_list - build a node_list for a job laying out the actual
- *	task distributions on the nodes
+ * build_node_list - build a node_list for a job including processor 
+ *	count on the node (e.g. "lx01[4],lx02[4],...")
  * input: bitmap - bitmap of nodes to use
- *	dist - distribution of tasks, BLOCK or CYCLE
- *	procs_per_task - how many processor each task will consume
  *	node_list - place to store node list
  *	total_procs - place to store count of total processors allocated
  * output: node_list - comma separated list of nodes on which the tasks 
- *		are to be initiated (ordered)
+ *		are to be initiated
  *	total_procs - count of total processors allocated
+ * global: node_record_table_ptr - pointer to global node table
+ * NOTE: the storage at node_list must be xfreed by the caller
  */
-extern void build_node_list (bitstr_t *bitmap, enum task_dist dist, 
-		int procs_per_task, char **node_list, int *total_procs);
+extern void  build_node_list (bitstr_t *bitmap, char **node_list, 
+	uint32_t *total_procs);
 
 /*
  * count_cpus - report how many cpus are associated with the identified nodes 
@@ -451,6 +452,15 @@ extern int init_node_conf ();
  */
 extern int init_part_conf ();
 
+/* 
+ * init_slurm_conf - initialize or re-initialize the slurm configuration  
+ *	values. this should be called before calling read_slurm_conf.  
+ * output: return value - 0 if no error, otherwise an error code
+ * globals: control_machine - name of primary slurmctld machine
+ *	backup_controller - name of backup slurmctld machine
+ */
+extern int init_slurm_conf ();
+
 /* 
  * is_key_valid - determine if supplied key is valid
  * input: key - a slurm key acquired by user root
@@ -478,6 +488,16 @@ extern int  is_key_valid (int key);
  */
 extern int job_allocate (char *job_specs, char **new_job_id, char **node_list);
 
+/* 
+ * job_cancel - cancel the specified job
+ * input: job_id - id of the job to be cancelled
+ * output: returns 0 on success, EINVAL if specification is invalid
+ *	EAGAIN of job available for cancellation now 
+ * global: job_list - pointer global job list
+ *	last_job_update - time of last job table update
+ */
+extern int job_cancel (char * job_id);
+
 /*
  * job_create - parse the suppied job specification and create job_records for it
  * input: job_specs - job specifications
@@ -605,6 +625,38 @@ extern int node_name2bitmap (char *node_names, bitstr_t **bitmap);
  */
 extern int  node_name2list (char *node_names, char **node_list, int *node_count);
 
+/* 
+ * pack_all_node - dump all configuration and node information for all nodes in 
+ *	machine independent form (for network transmission)
+ * input: buffer_ptr - location into which a pointer to the data is to be stored.
+ *                     the data buffer is actually allocated by dump_node and the 
+ *                     calling function must xfree the storage.
+ *         buffer_size - location into which the size of the created buffer is in bytes
+ *         update_time - dump new data only if partition records updated since time 
+ *                       specified, otherwise return empty buffer
+ * output: buffer_ptr - the pointer is set to the allocated buffer.
+ *         buffer_size - set to size of the buffer in bytes
+ *         update_time - set to time partition records last updated
+ *         returns 0 if no error, errno otherwise
+ * global: node_record_table_ptr - pointer to global node table
+ * NOTE: the caller must xfree the buffer at *buffer_ptr when no longer required
+ */
+extern int pack_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time);
+
+/* 
+ * pack_node - dump all configuration information about a specific node in 
+ *	machine independent form (for network transmission)
+ * input:  dump_node_ptr - pointer to node for which information is requested
+ *	buf_ptr - buffer for node information 
+ *	buf_len - byte size of buffer
+ * output: buf_ptr - advanced to end of data written
+ *	buf_len - byte size remaining in buffer
+ *	return 0 if no error, 1 if out_line buffer too small
+ * NOTE: if you make any changes here be sure to increment the value of NODE_STRUCT_VERSION
+ *	and make the corresponding changes to load_node_config in api/node_info.c
+ */
+extern int pack_node (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len); 
+
 /* 
  * parse_job_specs - pick the appropriate fields out of a job request specification
  * input: job_specs - string containing the specification
@@ -648,13 +700,29 @@ extern int read_buffer (char *buffer, int *buffer_offset, int buffer_size,
 			char **line);
 
 /*
- * read_SLURM_CONF - load the slurm configuration from the specified file 
- * call init_SLURM_CONF before ever calling read_SLURM_CONF.  
- * read_SLURM_CONF can be called more than once if so desired.
- * input: file_name - name of the file containing slurm configuration information
+ * read_slurm_conf - load the slurm configuration from the specified file. 
+ * read_slurm_conf can be called more than once if so desired.
+ * input: file_name - name of the file containing overall slurm configuration information
  * output: return - 0 if no error, otherwise an error code
+ * global: control_machine - primary machine on which slurmctld runs
+ * 	backup_controller - backup machine on which slurmctld runs
+ *	default_part_loc - pointer to default partition
+ * NOTE: call init_slurm_conf before ever calling read_slurm_conf.  
+ */
+extern int  read_slurm_conf (char *file_name);
+
+/* 
+ * rehash - build a hash table of the node_record entries. this is a large hash table 
+ * to permit the immediate finding of a record based only upon its name without regards 
+ * to the number. there should be no need for a search. the algorithm is optimized for 
+ * node names with a base-ten sequence number suffix. if you have a large cluster and 
+ * use a different naming convention, this function and/or the hash_index function 
+ * should be re-written.
+ * global: node_record_table_ptr - pointer to global node table
+ *         hash_table - table of hash indecies
+ * NOTE: allocates memory for hash_table
  */
-extern int read_SLURM_CONF (char *file_name);
+extern void rehash ();
 
 /* 
  * report_leftover - report any un-parsed (non-whitespace) characters on the
@@ -743,7 +811,8 @@ extern int update_part (char *partition_name, char *spec);
  * output: returns 0 if no error, enoent if no such node, einval if values too low
  */
 extern int validate_node_specs (char *node_name,
-				int cpus, int real_memory, int tmp_disk);
+				uint32_t cpus, uint32_t real_memory, 
+				uint32_t tmp_disk);
 
 /* 
  * write_buffer - write the specified line to the specified buffer, 
diff --git a/src/common/slurmlib.h b/src/common/slurmlib.h
index e7769030ddce6cefa3e714e8b5283ac98b20e902..e0dff66dc766fb69d32f1e3459528abc7f336b0c 100644
--- a/src/common/slurmlib.h
+++ b/src/common/slurmlib.h
@@ -87,6 +87,24 @@ extern int slurm_load_build ();
  */
 extern int slurm_load_build_name (char *req_name, char *next_name, char *value);
 
+/*
+ * slurm_submit - submit/queue a job with supplied contraints. 
+ * input: spec - specification of the job's constraints
+ *	job_id - place to store id of submitted job
+ * output: job_id - the job's id
+ *	returns 0 if no error, EINVAL if the request is invalid
+ * NOTE: required specification include: Script=<script_path_name>
+ *	User=<uid>
+ * NOTE: optional specifications include: Contiguous=<YES|NO> 
+ *	Distribution=<BLOCK|CYCLE> Features=<features> Groups=<groups>
+ *	JobId=<id> JobName=<name> Key=<key> MinProcs=<count> 
+ *	MinRealMemory=<MB> MinTmpDisk=<MB> Partition=<part_name>
+ *	Priority=<integer> ProcsPerTask=<count> ReqNodes=<node_list>
+ *	Shared=<YES|NO> TimeLimit=<minutes> TotalNodes=<count>
+ *	TotalProcs=<count>
+ */
+extern int slurm_submit (char *spec, char **job_id);
+
 /*
  * load_job - load the supplied job information buffer for use by info gathering 
  *	APIs if job records have changed since the time specified.