diff -Nurp xmms-1.2.11/libxmms/xmmsctrl.c xmms-1.2.11-straitm/libxmms/xmmsctrl.c
--- xmms-1.2.11/libxmms/xmmsctrl.c	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/libxmms/xmmsctrl.c	2008-01-23 17:52:01.000000000 -0600
@@ -398,11 +398,23 @@ void xmms_remote_stop(int session)
 	remote_cmd(session, CMD_STOP);
 }
 
+// added by straitm
+void xmms_remote_stopafter(gint session)
+{
+	remote_cmd(session, CMD_STOP_AFTER);
+}
+
 void xmms_remote_play_pause(int session)
 {
 	remote_cmd(session, CMD_PLAY_PAUSE);
 }
 
+// added by straitm
+void xmms_remote_playlist_next_chunk(gint session)
+{
+	remote_cmd(session, CMD_PLAYLIST_NEXT_CHUNK);
+}
+
 gboolean xmms_remote_is_playing(int session)
 {
 	return remote_get_gboolean(session, CMD_IS_PLAYING);
diff -Nurp xmms-1.2.11/libxmms/xmmsctrl.h xmms-1.2.11-straitm/libxmms/xmmsctrl.h
--- xmms-1.2.11/libxmms/xmmsctrl.h	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/libxmms/xmmsctrl.h	2008-01-23 17:51:51.000000000 -0600
@@ -34,6 +34,7 @@ void xmms_remote_playlist_delete(gint se
 void xmms_remote_play(gint session);
 void xmms_remote_pause(gint session);
 void xmms_remote_stop(gint session);
+void xmms_remote_stopafter(gint session); // added by straitm
 gboolean xmms_remote_is_playing(gint session);
 gboolean xmms_remote_is_paused(gint session);
 gint xmms_remote_get_playlist_pos(gint session);
@@ -65,6 +66,7 @@ void xmms_remote_toggle_aot(gint session
 void xmms_remote_eject(gint session);
 void xmms_remote_playlist_prev(gint session);
 void xmms_remote_playlist_next(gint session);
+void xmms_remote_playlist_next_chunk(gint session); // added by straitm
 void xmms_remote_playlist_add_url_string(gint session, gchar * string);
 gboolean xmms_remote_is_running(gint session);
 void xmms_remote_toggle_repeat(gint session);
diff -Nurp xmms-1.2.11/xmms/controlsocket.c xmms-1.2.11-straitm/xmms/controlsocket.c
--- xmms-1.2.11/xmms/controlsocket.c	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/xmms/controlsocket.c	2008-01-23 17:53:03.000000000 -0600
@@ -503,6 +503,10 @@ void check_ctrlsocket(void)
 				input_stop();
 				mainwin_clear_song_info();
 				break;
+			case CMD_STOP_AFTER: // added by straitm
+				input_stopafter();
+				mainwin_clear_song_info();
+				break;
 			case CMD_PLAY_PAUSE:
 				if (get_input_playing())
 					input_pause();
@@ -559,6 +563,9 @@ void check_ctrlsocket(void)
 			case CMD_PLAYLIST_NEXT:
 				playlist_next();
 				break;
+			case CMD_PLAYLIST_NEXT_CHUNK: // added by straitm
+				playlist_next_chunk();
+				break;
 			case CMD_TOGGLE_REPEAT:
 				mainwin_repeat_pushed(!cfg.repeat);
 				tbutton_set_toggled(mainwin_repeat, GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(mainwin_options_menu, "/Repeat"))->active);
diff -Nurp xmms-1.2.11/xmms/controlsocket.h xmms-1.2.11-straitm/xmms/controlsocket.h
--- xmms-1.2.11/xmms/controlsocket.h	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/xmms/controlsocket.h	2008-01-23 17:33:01.000000000 -0600
@@ -31,6 +31,7 @@ gint ctrlsocket_get_session_id(void);
 enum
 {
 	CMD_GET_VERSION, CMD_PLAYLIST_ADD, CMD_PLAY, CMD_PAUSE, CMD_STOP,
+	CMD_STOP_AFTER, // added by straitm
 	CMD_IS_PLAYING, CMD_IS_PAUSED, CMD_GET_PLAYLIST_POS,
 	CMD_SET_PLAYLIST_POS, CMD_GET_PLAYLIST_LENGTH, CMD_PLAYLIST_CLEAR,
 	CMD_GET_OUTPUT_TIME, CMD_JUMP_TO_TIME, CMD_GET_VOLUME,
@@ -39,6 +40,7 @@ enum
 	CMD_GET_EQ_DATA, CMD_SET_EQ_DATA, CMD_PL_WIN_TOGGLE,
 	CMD_EQ_WIN_TOGGLE, CMD_SHOW_PREFS_BOX, CMD_TOGGLE_AOT,
 	CMD_SHOW_ABOUT_BOX, CMD_EJECT, CMD_PLAYLIST_PREV, CMD_PLAYLIST_NEXT,
+	CMD_PLAYLIST_NEXT_CHUNK, // added by straitm
 	CMD_PING, CMD_GET_BALANCE, CMD_TOGGLE_REPEAT, CMD_TOGGLE_SHUFFLE,
 	CMD_MAIN_WIN_TOGGLE, CMD_PLAYLIST_ADD_URL_STRING,
 	CMD_IS_EQ_WIN, CMD_IS_PL_WIN, CMD_IS_MAIN_WIN, CMD_PLAYLIST_DELETE,
diff -Nurp xmms-1.2.11/xmms/input.c xmms-1.2.11-straitm/xmms/input.c
--- xmms-1.2.11/xmms/input.c	2005-05-14 19:01:21.000000000 -0500
+++ xmms-1.2.11-straitm/xmms/input.c	2008-01-23 17:44:15.000000000 -0600
@@ -309,6 +309,17 @@ void input_stop(void)
 	ip_data->playing = FALSE;
 }
 
+// added by straitm
+void input_stopafter(void)
+{
+	if(ip_data->playing && get_current_input_plugin())
+	{
+		int sleeptime = playlist_get_current_length()-input_get_time();
+		xmms_usleep(sleeptime*1000);
+		input_stop();
+	}
+}
+
 void input_pause(void)
 {
 	if (get_input_playing() && get_current_input_plugin())
diff -Nurp xmms-1.2.11/xmms/main.c xmms-1.2.11-straitm/xmms/main.c
--- xmms-1.2.11/xmms/main.c	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/xmms/main.c	2008-01-23 17:53:35.000000000 -0600
@@ -3742,6 +3742,7 @@ static struct option long_options[] =
 	{"pause", 0, NULL, 'u'},
 	{"play-pause", 0, NULL, 't'},
 	{"stop", 0, NULL, 's'},
+	{"stopafter", 0, NULL, 'a'}, // added by straitm
 	{"fwd", 0, NULL, 'f'},
 	{"enqueue", 0, NULL, 'e'},
 	{"queue", 0, NULL, 'Q'},
@@ -3778,12 +3779,18 @@ void display_usage(void)
 	fprintf(stderr, "\n  -s, --stop			");
 	/* I18N: -s, --stop switch */
 	fprintf(stderr, _("Stop current song"));
+	fprintf(stderr, "\n-a, --stopafter              "); // added by straitm
+	/* -a, --stopafter switch */
+	fprintf(stderr, _("Stop after current song"));
 	fprintf(stderr, "\n  -t, --play-pause		");
 	/* I18N: -t, --play-pause switch */
 	fprintf(stderr, _("Pause if playing, play otherwise"));
 	fprintf(stderr, "\n  -f, --fwd			");
 	/* I18N: -f, --fwd switch */
 	fprintf(stderr, _("Skip forward in playlist"));
+	fprintf(stderr, "\n-f, --fwd            "); // added by straitm
+	/* -g, --ffwd switch */
+	fprintf(stderr, _("Skip forward to next chunk in playlist"));
 	fprintf(stderr, "\n  -e, --enqueue			");
 	/* I18N: -e, --enqueue switch */
 	fprintf(stderr, _("Don't clear the playlist"));
@@ -3825,7 +3832,8 @@ void display_usage(void)
 struct cmdlineopt {
 	GList *filenames;
 	int session;
-	gboolean play, stop, pause, fwd, rew, play_pause;
+	// modifed by straitm
+	gboolean play, stop, stopafter, pause, fwd, ffwd, rew, play_pause;
 	gboolean toggle_shuffle, toggle_repeat, toggle_advance;
 	gboolean enqueue, queue, mainwin, remote, quit;
 	char *shuffle, *repeat, *advance;
@@ -3839,7 +3847,8 @@ void parse_cmd_line(int argc, char **arg
 
 	memset(opt, 0, sizeof(struct cmdlineopt));
 	opt->session = -1;
-	while ((c = getopt_long(argc, argv, "hn:rpusfeQS::R::A::mi:vtq", long_options, NULL)) != -1)
+	// modified by straitm
+	while ((c = getopt_long(argc, argv, "hn:rpagusfeQS::R::A::mi:vtq", long_options, NULL)) != -1)
 	{
 		switch (c)
 		{
@@ -3861,9 +3870,15 @@ void parse_cmd_line(int argc, char **arg
 			case 's':
 				opt->stop = TRUE;
 				break;
+			case 'a': // added by straitm
+				opt->stopafter = TRUE;
+				break;
 			case 'f':
 				opt->fwd = TRUE;
 				break;
+			case 'g': // added by straitm
+				opt->ffwd = TRUE;
+				break;
 			case 't':
 				opt->play_pause = TRUE;
 				break;
@@ -3968,8 +3983,12 @@ void handle_cmd_line_options(struct cmdl
 		xmms_remote_pause(opt->session);
 	if (opt->stop)
 		xmms_remote_stop(opt->session);
+	if (opt->stopafter)
+		xmms_remote_stopafter(opt->session); // added by straitm
 	if (opt->fwd)
 		xmms_remote_playlist_next(opt->session);
+	if (opt->ffwd)
+		xmms_remote_playlist_next_chunk(opt->session); //added by straitm
 	if (opt->play_pause)
 		xmms_remote_play_pause(opt->session);
 	if (opt->toggle_shuffle)
diff -Nurp xmms-1.2.11/xmms/playlist.c xmms-1.2.11-straitm/xmms/playlist.c
--- xmms-1.2.11/xmms/playlist.c	2007-11-16 15:51:30.000000000 -0600
+++ xmms-1.2.11-straitm/xmms/playlist.c	2008-01-23 17:49:40.000000000 -0600
@@ -712,6 +712,13 @@ void playlist_next(void)
 	}
 }
 
+void playlist_next_chunk(void)
+{
+	playlist_next();
+	while(playlist_position->chunkpos)
+		playlist_next();
+}
+
 void playlist_prev(void)
 {
 	GList *plist_pos_list;
@@ -1673,21 +1680,70 @@ void playlist_reverse(void)
 	PL_UNLOCK();
 }
 
+static void swap(int * a, int * b)
+{
+	int tmp = *a;
+	*a = *b;
+	*b = tmp;
+}
+
 static GList *playlist_shuffle_list(GList *list)
 {
+#define CHUNK_SIZE 4
+
 	/* Caller should hold playlist mutex */
+	int len = g_list_length(list);
+	int i;
+	int offset = random()%CHUNK_SIZE;
+	int slen = len/CHUNK_SIZE + (len%CHUNK_SIZE ? 1 : 0);
+	int scramble[slen];
+	GList *newlist = NULL;
+
+	fprintf(stderr, "shuffling %d songs\n", len);
+
+	if (!len)
+		return NULL;
+
+	for(i = 0; i < slen; i++)
+		scramble[i] = i;
+
+	for(i = 0; i < slen - 1; i++)
+	{
+		int r = random()%(slen - i - 1) + 1;
+		swap(&scramble[i], &scramble[i + r]);	
+	}		
+
+	for(i = 0; i < slen; i++)
+	{
+		PlaylistEntry * foo;
+		int j, n = scramble[i]*CHUNK_SIZE;
+
+		for(j = 0; j < CHUNK_SIZE; j++)
+		{
+		    if(n+j < len)
+		    {
+			fprintf(stderr, "%d\t", (n+j+offset)%len);
+			foo = (PlaylistEntry *)g_list_nth_data(list, (n+j+offset)%len);
+
+			foo->chunkpos = j;
+
+			newlist = g_list_append(newlist, foo);
+		    }
+		}
+	}
+
+	fprintf(stderr, "done shuffling\n");
+
+	return newlist;
+
+#if 0
 	/*
 	 * Note that this doesn't make a copy of the original list.
 	 * The pointer to the original list is not valid after this
 	 * fuction is run.
 	 */
-	int len = g_list_length(list);
-	int i, j;
 	GList *node, **ptrs;
 
-	if (!len)
-		return NULL;
-
 	ptrs = g_new(GList *, len);
 
 	for (node = list, i = 0; i < len; node = g_list_next(node), i++)
@@ -1711,6 +1767,8 @@ static GList *playlist_shuffle_list(GLis
 	g_free(ptrs);
 
 	return list;
+#endif
+
 }
 
 void playlist_random(void)
diff -Nurp xmms-1.2.11/xmms/playlist.h xmms-1.2.11-straitm/xmms/playlist.h
--- xmms-1.2.11/xmms/playlist.h	2007-11-16 15:51:30.000000000 -0600
+++ xmms-1.2.11-straitm/xmms/playlist.h	2008-01-23 17:50:33.000000000 -0600
@@ -26,6 +26,7 @@ typedef struct
         gchar *title;
         gint length;
         gboolean selected;
+	gint chunkpos;
 }
 PlaylistEntry;
 
@@ -44,6 +45,7 @@ void playlist_play(void);
 void playlist_set_info(gchar * title, gint length, gint rate, gint freq, gint nch);
 void playlist_check_pos_current(void);
 void playlist_next(void);
+void playlist_next_chunk(void);
 void playlist_prev(void);
 void playlist_queue_selected(void);
 void playlist_queue_position(gint pos);
diff -Nurp xmms-1.2.11/xmms.1.in xmms-1.2.11-straitm/xmms.1.in
--- xmms-1.2.11/xmms.1.in	2006-07-16 08:40:04.000000000 -0500
+++ xmms-1.2.11-straitm/xmms.1.in	2008-01-23 18:14:17.000000000 -0600
@@ -15,7 +15,10 @@ XMMS \- an audio player for X.
 other kinds of media files.  By default XMMS can play MPEG audio, Ogg
 Vorbis, RIFF wav, most module formats and a few other formats.  XMMS
 can be extended through plugins to play a number of other audio and
-video formats.
+video formats.  You are running a version of XMMS modified by Matthew
+Strait.  The rand button no longer randomizes
+completely, but rather randomizes into 2 song chunks.
+The \-a and \-g options have been added.
 .SH OPTIONS
 XMMS accepts the following options:
 .TP
@@ -37,12 +40,18 @@ Pause current song.
 .B \-s, \-\-stop
 Stop current song.
 .TP
+.B \-a, \-\-stopafter
+Stop after the current song.
+.TP
 .B \-t, \-\-play\-pause
 Pause if playing, play otherwise.
 .TP
 .B \-f, \-\-fwd
 Skip forward in playlist.
 .TP
+.B \-g, \-\-ffwd
+Skip forward to the next chunk in playlist.
+.TP
 .B \-e, \-\-enqueue
 Don't clear the playlist.
 .TP
