diff --git a/.monadid b/.monadid
index 10463cb685b34acfeb014eb028dbe2708d827404..583d88cb7514d3f0654d66f8cb9d0d22691bef26 100644
--- a/.monadid
+++ b/.monadid
@@ -1,2 +1,4 @@
+monad identification file
 This file is used for monad directory identification
-monad Build Date: Mon Aug 29 23:31:01 CDT 2011
+Built by toole1 on linux3.ews.illinois.edu
+Build Date: Wed Aug 31 15:03:31 CDT 2011
diff --git a/monad b/monad
index 805156291d2498e5168ea1e62dde4baa128e7f4f..dcb89998b99cf8259971939df3626d56325e0a75 100755
Binary files a/monad and b/monad differ
diff --git a/util.cpp b/util.cpp
index 84572d39f18b1a0c48ce004b88f122d3b1b3f236..11f02a9fdbf1cc48215df51514b54fcb33138ca6 100644
--- a/util.cpp
+++ b/util.cpp
@@ -186,7 +186,6 @@ bool exists(const string & path)
 	// Try stat-ing it
 	struct stat st;
 	if (stat(path.c_str(), &st) != 0) return false;
-
 	// Check for read permission
 	if ((st.st_mode & S_IRUSR) == 0) return false;
 
@@ -204,7 +203,6 @@ mode_t permissions(const string & path)
 	// Try stat-ing it
 	struct stat st;
 	if (stat(path.c_str(), &st) != 0) return -1;
-
 	// Check for read permission
 	if ((st.st_mode & S_IRUSR) == 0) return -1;
 
@@ -296,8 +294,10 @@ void protectDir(const string & dir)
 
 // Originally from Simon Biber
 // http://bytes.com/topic/c/answers/545614-list-files-current-directory
-vector<string> getFilesInDir(const string & dir)
+vector<string> get_files_in_dir(const string & dir)
 {
+	EXIT_IF_ERROR(dir == "" || dir[dir.length()-1] != '/', "Directory name must end in a '/'");
+	
 	vector<string> files;
 	DIR * dirp = opendir(dir.c_str());
 	if (dirp == NULL) return files;
@@ -305,7 +305,9 @@ vector<string> getFilesInDir(const string & dir)
 	struct dirent * ent = readdir(dirp);
 	while (ent != NULL)
 	{
-		// TODO (toole1) finish this
+		string file = ent->d_name;
+		if (file != "." && file != "..")
+			files.push_back(dir + file);
 		ent = readdir(dirp);
 	}
 
@@ -313,6 +315,28 @@ vector<string> getFilesInDir(const string & dir)
 	return files;
 }
 
+bool is_symlink(const string & file)
+{
+	// Try lstat-ing it
+	struct stat st;
+	if (lstat(file.c_str(), &st) != 0) return -1;
+	// Check for read permission
+	if ((st.st_mode & S_IRUSR) == 0) return false;
+
+	// & with symlink bit
+	return (S_ISLNK(st.st_mode)) != 0;
+}
+
+string get_symlink_target(const string & symlink)
+{
+	const size_t buf_size = 4096;
+	char buf[buf_size+1]; // TODO (toole1): hack-y value
+	ssize_t len = readlink(symlink.c_str(), buf, buf_size);
+	EXIT_IF_ERROR(len < 0 || static_cast<size_t>(len) == buf_size, "Error getting target of symlink " + symlink);
+	buf[len] = '\0';
+	return string(buf);
+}
+
 void linkDirs(const string & sourceFolder, const string & destFolder, const vector<string> & dirs)
 {
 	assertExists(destFolder);
diff --git a/util.h b/util.h
index 0fcb14e5c5a9bdf034ba79843d953b0c31c14242..6cc422f4f6e4de5304e72808f7722ae394d7bd77 100644
--- a/util.h
+++ b/util.h
@@ -1,6 +1,7 @@
 #ifndef UTIL_H
 #define UTIL_H
 
+#include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -90,7 +91,9 @@ void copyFiles(const string & sourceFolder, const string & destFolder, const vec
 void protectFiles(const string & folder, const vector<string> & files);
 void protectDir(const string & dir);
 void linkDirs(const string & sourceFolder, const string & destFolder, const vector<string> & dirs);
-vector<string> getFilesInDir(const string & dir);
+vector<string> get_files_in_dir(const string & dir);
+bool is_symlink(const string & file);
+string get_symlink_target(const string & symlink);
 
 // STRING REPLACEMENT
 bool   replaceFirst(string & str, const string & toreplace, const string & with);