diff --git a/src/xslurm/xslurm.c b/src/xslurm/xslurm.c
new file mode 100644
index 0000000000000000000000000000000000000000..c7132e54495b42bc8b5b4d8b788a06e12f4d4341
--- /dev/null
+++ b/src/xslurm/xslurm.c
@@ -0,0 +1,480 @@
+/*****************************************************************************\
+ *  xslurm - user tool to view SLURM state and manage their SLURM jobs.
+ *****************************************************************************
+ *  Copyright (C) 2003 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Moe Jette <jette1@llnl.gov>
+ *  UCRL-CODE-2002-040.
+ *  
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://www.llnl.gov/linux/slurm/>.
+ *  
+ *  SLURM is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *  
+ *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+ *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ *  details.
+ *  
+ *  You should have received a copy of the GNU General Public License along
+ *  with SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+\*****************************************************************************/
+
+/*
+Build and test procedure:
+
+gcc -I /usr/include/gtk-1.2 -I /usr/include/glib-1.2 -I /usr/lib/glib/include -c xslurm.c
+gcc -lgtk -lgdk -lglib -lgdk_pixbuf -lgobject-2.0 -lgmodule-1.2 -lm -lslurm -L/usr/X11R6/lib -lX11 -lXext -o xslurm xslurm.o
+./xslurm
+*/
+
+#include <pwd.h>
+#include <sys/types.h>
+
+#include <slurm/slurm.h>
+#include <gtk/gtk.h>
+
+static inline void 	_cat_if_room(char *str1, char *str2, int size1);
+static void		_complete(GtkWidget *widget, gpointer data);
+static void		_help(GtkWidget *widget, gpointer data);
+static void 		_help_complete(GtkWidget *widget, gpointer data);
+static GtkWidget *	_make_button_widget(void);
+static GtkWidget *	_make_job_table(void);
+static GtkWidget *	_make_job_widget(void);
+static GtkWidget *	_make_part_table(void);
+static GtkWidget *	_make_part_widget(void);
+static void 		_part_details(GtkWidget *widget, gpointer data);
+static inline char *	_root_str(uint16_t root);
+static inline char *	_shared_str(uint16_t shared);
+static void		_sprint_part_details(char *string, int size, 
+					     partition_info_t *part_ptr);
+static void		_submit(GtkWidget *widget, gpointer data);
+static void		_refresh(GtkWidget *widget, gpointer data);
+
+GtkWidget *help_widget = NULL;	/* help window widget */
+
+partition_info_msg_t *old_part_info_ptr = NULL;
+
+/*
+ * Main window set-up and support
+ */
+
+int main (int argc, char **argv)
+{
+	GtkWidget *window;
+        GtkWidget *box_vert, *box_parts, *box_jobs, *box_bottom;
+
+	/* main window set-up */
+	gtk_init(&argc, &argv);
+	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_title(GTK_WINDOW(window), "xslurm");
+	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
+			 GTK_SIGNAL_FUNC(_complete), NULL);
+	gtk_signal_connect(GTK_OBJECT(window), "destroy",
+			 GTK_SIGNAL_FUNC(_complete), NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+	gtk_widget_set_usize(window, 500, 300);
+
+	/* Vertical box container */
+	box_vert = gtk_vbox_new(FALSE, 0);
+
+	/* Partition state info */
+	box_parts = _make_part_widget();
+	gtk_box_pack_start(GTK_BOX(box_vert), box_parts, TRUE, TRUE, 0);
+	gtk_widget_show(box_parts);
+
+	/* Job state info */
+	box_jobs = _make_job_widget();
+	gtk_box_pack_start(GTK_BOX(box_vert), box_jobs, TRUE, TRUE, 0);
+	gtk_widget_show(box_jobs);
+
+	/* bottom of window button set-up */
+	box_bottom = _make_button_widget();
+	gtk_box_pack_start(GTK_BOX(box_vert), box_bottom, FALSE, FALSE, 0);
+	gtk_widget_show(box_bottom);
+
+	gtk_container_add(GTK_CONTAINER(window), box_vert);
+	gtk_widget_show(box_vert);
+	gtk_widget_show(window);
+
+	gtk_main();
+
+	return 0;
+}
+
+
+/*
+ * Partition info set-up and support
+ */
+
+/* _make_part_widget - build scrollable list of partitions */
+static GtkWidget *_make_part_widget(void)
+{
+        GtkWidget *box_parts, *part_table;
+
+	box_parts = gtk_scrolled_window_new(NULL, NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(box_parts), 10);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(box_parts),
+			GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+	part_table = _make_part_table();
+	gtk_scrolled_window_add_with_viewport(
+			GTK_SCROLLED_WINDOW(box_parts), part_table);
+	gtk_widget_show(part_table);
+
+	return box_parts;
+}
+
+static GtkWidget *_make_part_table(void)
+{
+	partition_info_msg_t *part_info_ptr = NULL;
+	partition_info_t *part_ptr = NULL;
+	GtkWidget *part_button, *part_label, *part_table;
+	int error_code, i;
+	char part_desc[128];
+
+	/* Read partition info */
+	if (old_part_info_ptr) {
+		error_code = slurm_load_partitions (
+				old_part_info_ptr->last_update,
+				&part_info_ptr);
+		if (error_code == SLURM_SUCCESS) {
+			slurm_free_partition_info_msg (old_part_info_ptr);
+		}
+		else if (slurm_get_errno () == SLURM_NO_CHANGE_IN_DATA) {
+			part_info_ptr = old_part_info_ptr;
+			error_code = SLURM_SUCCESS;
+		}
+	}
+	else
+		error_code = slurm_load_partitions ((time_t) NULL, 
+						    &part_info_ptr);
+	old_part_info_ptr = part_info_ptr;
+
+	part_table = gtk_vbox_new(FALSE, 0);
+	part_label = gtk_label_new(
+	  "Partition State #Nodes etc. (make into sort buttons)");
+	/* 123456789 12345 123456 */
+	gtk_label_set_justify(GTK_LABEL(part_label), GTK_JUSTIFY_LEFT);
+	gtk_box_pack_start(GTK_BOX(part_table), part_label, 
+			FALSE, FALSE, 0);
+	gtk_widget_show(part_label);
+	if (error_code) {
+		slurm_perror ("slurm_load_partitions error");
+		return part_table;
+	}
+
+	part_ptr = part_info_ptr->partition_array;
+	for (i=0; i<part_info_ptr->record_count; i++) {
+		sprintf(part_desc, "%8.8s", 
+			part_ptr->name);
+		part_ptr++;
+		part_button = gtk_button_new_with_label(part_desc);
+		gtk_signal_connect(GTK_OBJECT(part_button), "clicked",
+			GTK_SIGNAL_FUNC(_part_details), (gpointer) i);
+		gtk_box_pack_start(GTK_BOX(part_table), part_button, 
+			FALSE, FALSE, 0);
+		gtk_widget_show(part_button);
+	}
+	return part_table;
+}
+
+/* _part_details - Report details of a particular partition in a dialog box */
+static void _part_details(GtkWidget *widget, gpointer data)
+{
+	GtkWidget *window, *box_vert, *button, *part_label;
+	char part_details[1024];
+	partition_info_t *part_ptr = NULL;
+
+//	if (help_widget) /* Destroy old help window if one exists */
+//		gtk_widget_destroy(help_widget);
+	window = gtk_window_new(GTK_WINDOW_DIALOG);
+	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
+			 GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_signal_connect(GTK_OBJECT(window), "destroy",
+			 GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+
+	/* Vertical box container */
+	box_vert = gtk_vbox_new(FALSE, 0);
+
+	/* build partition details */
+	part_ptr = old_part_info_ptr->partition_array;
+	part_ptr += (int)data;
+	sprintf(part_details, "xslurm part %s", part_ptr->name);
+	gtk_window_set_title(GTK_WINDOW(window), part_details);
+	_sprint_part_details(part_details, sizeof(part_details), part_ptr);
+	part_label = gtk_label_new(part_details);
+
+	gtk_label_set_line_wrap(GTK_LABEL(part_label), TRUE);
+	gtk_box_pack_start(GTK_BOX(box_vert), part_label, 
+			TRUE, TRUE, 0);
+	gtk_widget_show(part_label);
+
+	/* put quit button at bottom of window */
+	button = gtk_button_new_with_label("Quit");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_box_pack_start(GTK_BOX(box_vert), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	gtk_container_add(GTK_CONTAINER(window), box_vert);
+	gtk_widget_show(box_vert);
+	gtk_widget_show(window);
+}
+
+static void _sprint_part_details(char *string, int size, 
+				 partition_info_t *part_ptr)
+{
+	char next_line[128];
+
+	strcpy(string, "");
+
+	sprintf(next_line, "PartitionName=%s\n", part_ptr->name);
+	_cat_if_room(string, next_line, size);
+
+	sprintf(next_line, "TotalNodes=%d\n", part_ptr->total_nodes);
+	_cat_if_room(string, next_line, size);
+
+	sprintf(next_line, "TotalCPUs=%d\n", part_ptr->total_cpus);
+	_cat_if_room(string, next_line, size);
+
+	sprintf(next_line, "RootOnly=%s\n", _root_str(part_ptr->root_only));
+	_cat_if_room(string, next_line, size);
+
+	sprintf(next_line, "Default=%s\n", _root_str(part_ptr->default_part));
+	_cat_if_room(string, next_line, size);
+
+	sprintf(next_line, "Shared=%s\n", _shared_str(part_ptr->shared));
+	_cat_if_room(string, next_line, size);
+
+	_cat_if_room(string, "\n", size);
+}
+
+static inline void _cat_if_room(char *str1, char *str2, int size1) 
+{
+	if ((strlen(str1) + strlen(str2) + 1) < size1)
+		strcat(str1, str2);
+}
+
+static inline char *_root_str(uint16_t root) 
+{
+	if (root)
+		return "YES";
+	else
+		return "NO";
+}
+
+static inline char *_shared_str(uint16_t shared) 
+{
+#if 0
+	if (shared == SHARED_YES)	/* undefined in slurm.h */
+		return "FORCE"
+#endif
+	if (shared)
+		return "YES";
+	else
+		return "NO";
+}
+
+
+
+/*
+ * Job info set-up and support
+ */
+
+/* _make_job_widget - build scrollable list of jobs */
+static GtkWidget *_make_job_widget(void)
+{
+        GtkWidget *box_jobs, *job_table;
+
+	box_jobs = gtk_scrolled_window_new(NULL, NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(box_jobs), 10);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(box_jobs),
+			GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+	job_table = _make_job_table();
+	gtk_scrolled_window_add_with_viewport(
+			GTK_SCROLLED_WINDOW(box_jobs), job_table);
+	gtk_widget_show(job_table);
+
+	return box_jobs;
+}
+
+static GtkWidget *_make_job_table(void)
+{
+	static job_info_msg_t *old_job_buffer_ptr = NULL;
+	job_info_msg_t * job_buffer_ptr = NULL;
+	job_info_t *job_ptr = NULL;
+	struct passwd *user_info = NULL;
+	GtkWidget *job_button, *job_label, *job_table;
+	int error_code, i;
+	char job_desc[128], user_name[18];
+
+	/* Read job info, find job count */
+	if (old_job_buffer_ptr) {
+		error_code = slurm_load_jobs (old_job_buffer_ptr->last_update, 
+					&job_buffer_ptr);
+		if (error_code == SLURM_SUCCESS)
+			slurm_free_job_info_msg (old_job_buffer_ptr);
+		else if (slurm_get_errno () == SLURM_NO_CHANGE_IN_DATA) {
+			job_buffer_ptr = old_job_buffer_ptr;
+			error_code = SLURM_SUCCESS;
+		}
+	}
+	else
+		error_code = slurm_load_jobs ((time_t) NULL, &job_buffer_ptr);
+	old_job_buffer_ptr = job_buffer_ptr;
+
+	job_table = gtk_vbox_new(FALSE, 0);
+	job_label = gtk_label_new(
+	  "JobId    User     Name     etc. (make into sort buttons)");
+	/* 12345678 12345678 12345678 */
+	gtk_label_set_justify(GTK_LABEL(job_label), GTK_JUSTIFY_LEFT);
+	gtk_box_pack_start(GTK_BOX(job_table), job_label, 
+			FALSE, FALSE, 0);
+	gtk_widget_show(job_label);
+	if (error_code) {
+		slurm_perror ("slurm_load_jobs error");
+		return job_table;
+	}
+
+	job_ptr = job_buffer_ptr->job_array ;
+	for (i=0; i<job_buffer_ptr->record_count; i++) {
+		user_info = getpwuid((uid_t) job_ptr->user_id);
+		if (user_info && user_info->pw_name[0])
+			sprintf ( user_name, "%.16s", user_info->pw_name);
+		else
+			sprintf ( user_name, "(%u)", job_ptr->user_id);
+		sprintf(job_desc, "%8d %8.8s %8.8s", 
+			job_ptr->job_id, user_name, job_ptr->name);
+		job_ptr++;
+		job_button = gtk_button_new_with_label(job_desc);
+		gtk_signal_connect(GTK_OBJECT(job_button), "clicked",
+			GTK_SIGNAL_FUNC(_help), NULL);
+		gtk_box_pack_start(GTK_BOX(job_table), job_button, 
+			FALSE, FALSE, 0);
+		gtk_widget_show(job_button);
+	}
+	return job_table;
+}
+
+
+/*
+ * Button set-up and support
+ */
+
+/* _make_button_widget - build the button widget */
+static GtkWidget *_make_button_widget(void)
+{
+        GtkWidget *box_bottom, *button;
+
+	box_bottom = gtk_hbox_new(TRUE, 10);
+	gtk_container_set_border_width(GTK_CONTAINER(box_bottom), 10);
+
+	button = gtk_button_new_with_label("Refresh");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_refresh), NULL);
+	gtk_box_pack_start(GTK_BOX(box_bottom), button, TRUE, TRUE, 0);
+	gtk_widget_show(button);
+
+	button = gtk_button_new_with_label("Submit");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_submit), NULL);
+	gtk_box_pack_start(GTK_BOX(box_bottom), button, TRUE, TRUE, 0);
+	gtk_widget_show(button);
+
+	button = gtk_button_new_with_label("Help");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_help), NULL);
+	gtk_box_pack_start(GTK_BOX(box_bottom), button, TRUE, TRUE, 0);
+	gtk_widget_show(button);
+
+	button = gtk_button_new_with_label("Quit");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_complete), NULL);
+	gtk_box_pack_start(GTK_BOX(box_bottom), button, TRUE, TRUE, 0);
+	gtk_widget_show(button);
+
+	return box_bottom;
+}
+
+/* _complete - Program termination */
+static void _complete(GtkWidget *widget, gpointer data) 
+{
+	gtk_main_quit();
+}
+
+/* _help_complete - Remove help dialog box */
+static void _help_complete(GtkWidget *widget, gpointer data)
+{
+	gtk_widget_destroy(help_widget);
+	help_widget = NULL;
+}
+
+/* _help - Pop-up help dialog box */
+static void _help(GtkWidget *widget, gpointer data)
+{
+	GtkWidget *box_vert, *button, *help_label;
+
+	if (help_widget) /* Destroy old help window if one exists */
+		gtk_widget_destroy(help_widget);
+	help_widget = gtk_window_new(GTK_WINDOW_DIALOG);
+	gtk_window_set_title(GTK_WINDOW(help_widget), "xslurm help");
+	gtk_signal_connect(GTK_OBJECT(help_widget), "delete_event",
+			 GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_signal_connect(GTK_OBJECT(help_widget), "destroy",
+			 GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(help_widget), 10);
+
+	/* Vertical box container */
+	box_vert = gtk_vbox_new(FALSE, 0);
+
+	/* put help info here */
+	help_label = gtk_label_new(
+		"xslurm graphically reports SLURM partition, node and job "  \
+	 	"status. It can also be used to submit a job and to modify " \
+	 	"some state information given appropriate authorization.\n\n"\
+		"The top box lists basic partition information. Click "      \
+		"on one of the partition buttons to get more complete "      \
+		"information about that partition. Click on one of the "     \
+		"header buttons to sort by that field's value.\n\n"          \
+		"The second box lists basic job information. Click on one "  \
+		"of the job buttons to get more complete information "       \
+		"about that job. Click on one of the header buttons to "     \
+		"sort by that field's value.\n\n"                            \
+		"See http://www.llnl.gov/linux/slurm/ for more "             \
+		"informationabout SLURM.\n\n" );
+
+	gtk_label_set_line_wrap(GTK_LABEL(help_label), TRUE);
+	gtk_box_pack_start(GTK_BOX(box_vert), help_label, 
+			TRUE, TRUE, 0);
+	gtk_widget_show(help_label);
+
+	/* put quit button at bottom of window */
+	button = gtk_button_new_with_label("Quit");
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			GTK_SIGNAL_FUNC(_help_complete), NULL);
+	gtk_box_pack_start(GTK_BOX(box_vert), button, FALSE, FALSE, 0);
+	gtk_widget_show(button);
+
+	gtk_container_add(GTK_CONTAINER(help_widget), box_vert);
+	gtk_widget_show(box_vert);
+	gtk_widget_show(help_widget);
+}
+
+/* _refresh - Re-read SLURM configuration and present new state */
+static void _refresh(GtkWidget *widget, gpointer data)
+{
+	g_print("refresh now\n");
+}
+
+/* _submit - Submit a job to slurm now */
+static void _submit(GtkWidget *widget, gpointer data)
+{
+	g_print("submit job now\n");
+}