new file mode 100644
--- /dev/null
+++ b/clplaner.c
@@ -0,0 +1,173 @@
+/**
+ * test/demos/clplaner.c
+ * Copyright (C) 2008 Markus Broeker
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+
+#define MAXLOOP 25
+#define MAXLINE 80
+
+#ifndef MAXTEAM
+#define MAXTEAM 32
+#endif
+
+#define getrandom(max) (1+(int)((float)(max)*rand()/RAND_MAX))
+
+void swap (int *v, int i, int j)
+{
+ int temp;
+
+ if (i == j)
+ return;
+
+ temp = v[i];
+
+ v[i] = v[j];
+ v[j] = temp;
+}
+
+void cleanup (char **first, char **second)
+{
+ int i;
+
+ i = 0;
+ while (first[i] != NULL)
+ free (first[i++]);
+
+ i = 0;
+ while (second[i] != NULL)
+ free (second[i++]);
+}
+
+unsigned int time_seed ()
+{
+ time_t now = time (NULL);
+
+ unsigned char *p = (unsigned char *)&now;
+ unsigned int seed = 0;
+
+ size_t i;
+
+ for (i = 0; i < sizeof (now); i++)
+ seed = seed * (UCHAR_MAX + 2U) + p[i];
+
+ return seed;
+}
+
+int getTeams (FILE * f, char **first, int *first_idx, char **second, int *second_idx)
+{
+ int i;
+ char buffer[MAXLINE + 1];
+ char *ptr;
+
+ i = 0;
+ while ((i < MAXTEAM) && fgets (buffer, MAXLINE, f) != NULL) {
+ if ((first[i] = malloc (MAXLINE + 1)) == NULL) {
+ perror ("malloc");
+ break;
+ }
+ if ((ptr = strchr (buffer, '\n')))
+ *ptr = '\0';
+
+ strncpy (first[i], buffer, MAXLINE);
+ first_idx[i] = i;
+
+ if (fgets (buffer, MAXLINE, f) == NULL) {
+ printf ("You need 2, 4, 6, ..., or %d teams in your file\n", 2 * MAXTEAM);
+ second[i] = first[i + 1] = NULL;
+ cleanup (first, second);
+ fclose (f);
+ exit (EXIT_FAILURE);
+ }
+
+ if ((second[i] = malloc (MAXLINE + 1)) == NULL) {
+ perror ("malloc");
+ break;
+ }
+ if ((ptr = strchr (buffer, '\n')))
+ *ptr = '\0';
+
+ strncpy (second[i], buffer, MAXLINE);
+ second_idx[i] = i;
+ i++;
+ }
+
+ first[i] = second[i] = NULL;
+
+ return i;
+}
+
+void shakeTeamIdx (int *first_idx, int *second_idx, int teams)
+{
+ int i, j, k;
+
+ /*
+ * swap the index MAXLOOP times...
+ */
+ for (i = 0; i < MAXLOOP; i++) {
+ for (j = 0; j < teams; j++) {
+ k = getrandom (teams - 1);
+ swap (second_idx, j, k);
+
+ k = getrandom (teams - 1);
+ swap (first_idx, j, k);
+ }
+ }
+
+ /*
+ * avoid group clashes
+ */
+ for (i = 0; i < teams - 1; i++) {
+ if (first_idx[i] == second_idx[i])
+ swap (first_idx, i, i + 1);
+ }
+
+ if (first_idx[i] == second_idx[i])
+ swap (first_idx, i, i - 1);
+}
+
+int main (int argc, char **argv)
+{
+ FILE *f;
+
+ char *first[MAXTEAM + 1];
+ char *second[MAXTEAM + 1];
+
+ int first_idx[MAXTEAM];
+ int second_idx[MAXTEAM];
+
+ int i, teams;
+
+ if (argc != 2) {
+ printf ("Usage: %s FILE\n\n", argv[0]);
+ printf ("One Team per line, seperated by newline, n=2, 4, ..., or %d\n", 2 * MAXTEAM);
+ printf ("Team n is the Groupwinner, n+1 is the Runners Up\n");
+ printf ("Report bugs to mbroeker@largo.homelinux.org\n");
+ return EXIT_FAILURE;
+ }
+
+ if ((f = fopen (argv[1], "r")) == NULL) {
+ perror ("fopen");
+ return EXIT_FAILURE;
+ }
+
+ srand (time_seed ());
+
+ teams = getTeams (f, first, first_idx, second, second_idx);
+ shakeTeamIdx (first_idx, second_idx, teams);
+
+ for (i = 0; i < teams; i++)
+ printf ("%30s vs %s\n", second[second_idx[i]], first[first_idx[i]]);
+
+ cleanup (first, second);
+
+ if (f != NULL)
+ fclose (f);
+
+ return EXIT_SUCCESS;
+}