+/**
+ * Stat either a symlink or its referent, depending on the settings of
+ * copy_links, copy_unsafe_links, etc.
+ *
+ * @retval -1 on error
+ *
+ * @retval 0 for success
+ *
+ * @post If @p path is a symlink, then @p linkbuf (of size @c
+ * MAXPATHLEN) contains the symlink target.
+ *
+ * @post @p buffer contains information about the link or the
+ * referrent as appropriate, if they exist.
+ **/
+int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf)
+{
+#if SUPPORT_LINKS
+ if (copy_links) {
+ return do_stat(path, buffer);
+ }
+ if (do_lstat(path, buffer) == -1) {
+ return -1;
+ }
+ if (S_ISLNK(buffer->st_mode)) {
+ int l;
+ l = readlink((char *) path, linkbuf, MAXPATHLEN - 1);
+ if (l == -1)
+ return -1;
+ linkbuf[l] = 0;
+ if (copy_unsafe_links && (topsrcname[0] != '\0') &&
+ unsafe_symlink(linkbuf, topsrcname)) {
+ return do_stat(path, buffer);
+ }
+ }
+ return 0;
+#else
+ return do_stat(path, buffer);
+#endif
+}
+
+int link_stat(const char *path, STRUCT_STAT * buffer)