Actually add the ln file

diff --git a/utils/ln.c b/utils/ln.c
new file mode 100644
index 0000000..64ef94c
--- /dev/null
+++ b/utils/ln.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <linux/limits.h>
+
+int main(int argc, char *argv[])
+{
+	int c, s, f;
+	char *p, *target;
+	struct stat sb;
+
+	s = f = 0;
+	do {
+		c = getopt(argc, argv, "sf");
+		if (c == EOF)
+			break;
+
+		switch (c) {
+
+		case 's':
+			s = 1;
+			break;
+		case 'f':
+			f = 1;
+			break;
+		case '?':
+			fprintf(stderr, "%s: invalid option -%c\n",
+				argv[0], optopt);
+			return 1;
+		}
+
+	} while (1);
+
+	if (optind == argc) {
+		fprintf(stderr, "Usage: %s [-s] [-f] target link\n",
+			argv[0]);
+		return 1;
+	}
+
+	memset(&sb, 0, sizeof(struct stat));
+	if (stat(argv[argc - 1], &sb) < 0 && argc - optind > 2) {
+		if (!(S_ISDIR(sb.st_mode))) {
+			fprintf(stderr,
+				"multiple targets and %s is not a directory\n",
+				argv[argc - 1]);
+			return 1;
+		}
+	}
+
+	target = malloc(PATH_MAX);
+	if (!target) {
+		perror("malloc");
+		return 1;
+	}
+
+	for (c = optind; c < argc - 1; c++) {
+
+		p = strrchr(argv[c], '/');
+		p++;
+
+		if (S_ISDIR(sb.st_mode))
+			snprintf(target, PATH_MAX, "%s/%s",
+				 argv[argc - 1], p);
+		else
+			snprintf(target, PATH_MAX, "%s", argv[argc - 1]);
+
+		if (f)
+			unlink(target);
+
+		if (s) {
+			if (symlink(argv[c], target) == -1)
+				perror(target);
+		} else {
+			if (link(argv[c], target) == -1)
+				perror(target);
+		}
+	}
+
+	return 0;
+}