From 84caf6b44dfe003b9b0604247877e3733c023feb Mon Sep 17 00:00:00 2001
From: stateless <stateless@archlinux.us>
Date: Sat, 15 Jun 2013 15:17:57 +0100
Subject: [PATCH] Add readlink

---
 Makefile   |    1 +
 readlink.1 |   25 +++++++++++++++++++++++++
 readlink.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)
 create mode 100644 readlink.1
 create mode 100644 readlink.c

diff --git a/Makefile b/Makefile
index a7a653d..d567b1f 100644
--- a/Makefile
+++ b/Makefile
@@ -51,6 +51,7 @@ SRC = \
 	paste.c    \
 	printenv.c \
 	pwd.c      \
+	readlink.c \
 	renice.c   \
 	rm.c       \
 	rmdir.c    \
diff --git a/readlink.1 b/readlink.1
new file mode 100644
index 0000000..2a0476a
--- /dev/null
+++ b/readlink.1
@@ -0,0 +1,25 @@
+.TH READLINK 1 sbase\-VERSION
+.SH NAME
+readlink \- print value of a symbolic link or canonical file name
+.SH SYNOPSIS
+.B readlink
+.RB [ \-fn ]
+.IR file
+.SH DESCRIPTION
+The readlink utility when invoked with the pathname of a symbolic link as
+its argument dereferences the symbolic link and prints the name of target
+on standard output.  If the -f option is not specified and readlink is
+invoked with an argument other than the pathname of a symbolic link, it
+exits with a nonzero exit code without printing anything.
+.SH OPTIONS
+.TP
+.B \-f
+Canonicalize by following every symlink in every component of the
+given path recursively. The argument does not need to be a symbolic
+link.
+.TP
+.B \-n
+Do not output the trailing newline.
+.SH SEE ALSO
+.IR readlink (2),
+.IR realpath (3)
diff --git a/readlink.c b/readlink.c
new file mode 100644
index 0000000..cb86134
--- /dev/null
+++ b/readlink.c
@@ -0,0 +1,55 @@
+/* See LICENSE file for copyright and license details. */
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [-fn] file\n", argv0);
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	char buf[PATH_MAX];
+	bool nflag = false;
+	bool fflag = false;
+
+	ARGBEGIN {
+	case 'f':
+		fflag = true;
+		break;
+	case 'n':
+		nflag = true;
+		break;
+	default:
+		usage();
+	} ARGEND;
+
+	if (argc != 1)
+		usage();
+
+	if (strlen(argv[0]) > PATH_MAX - 1)
+		exit(1);
+
+	if (fflag) {
+		if (realpath(argv[0], buf) == NULL)
+			exit(1);
+	} else {
+		if (readlink(argv[0], buf, sizeof(buf)) < 0)
+			exit(1);
+	}
+
+	printf("%s", buf);
+	if (!nflag)
+		putchar('\n');
+
+	return 0;
+}
-- 
1.7.10.4

