aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Arun Prakash Jana <engineerarun@gmail.com>2018-08-16 20:08:26 +0530
committerGravatar Arun Prakash Jana <engineerarun@gmail.com>2018-08-16 20:14:07 +0530
commit70df4fb3c20930aa97b1b2b593619d16aa9ebab1 (patch)
treee045529306ba173adbcd87cfd9385654586074c9
parentf0ca1e778544d852ef04cf637d64ea1f94e43ddc (diff)
downloadnnn-70df4fb3c20930aa97b1b2b593619d16aa9ebab1.tar.gz
Use symbol @/ to denote symbolic link to directory
-rw-r--r--README.md1
-rw-r--r--nnn.c49
2 files changed, 25 insertions, 25 deletions
diff --git a/README.md b/README.md
index 4f0f72d..39bc8f1 100644
--- a/README.md
+++ b/README.md
@@ -289,6 +289,7 @@ The following indicators are used in the detail view:
| <code>&#124;</code> | Fifo |
| `=` | Socket |
| `@` | Symbolic Link |
+| `@/` | Symbolic Link to directory |
| `b` | Block Device |
| `c` | Character Device |
diff --git a/nnn.c b/nnn.c
index 0e5e5ea..1016d66 100644
--- a/nnn.c
+++ b/nnn.c
@@ -160,6 +160,7 @@ disabledbg()
#define DESCRIPTOR_LEN 32
#define _ALIGNMENT 0x10
#define _ALIGNMENT_MASK 0xF
+#define SYMLINK_TO_DIR 0x1
/* Macros to define process spawn behaviour as flags */
#define F_NONE 0x00 /* no flag set */
@@ -202,6 +203,7 @@ disabledbg()
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned char uchar;
+typedef unsigned short ushort;
/* STRUCTURES */
@@ -212,7 +214,8 @@ typedef struct entry {
off_t size;
blkcnt_t blocks; /* number of 512B blocks allocated */
mode_t mode;
- uint nlen; /* Length of file name; can be uchar (< NAME_MAX + 1) */
+ ushort nlen; /* Length of file name; can be uchar (< NAME_MAX + 1) */
+ uchar flags; /* Flags specific to the file */
} __attribute__ ((packed, aligned(_ALIGNMENT))) *pEntry;
/* Bookmark */
@@ -1560,9 +1563,12 @@ printent_long(struct entry *ent, int sel, uint namecols)
printw("%s%-16.16s %8.8s/ %s/\n", CURSYM(sel), buf, coolsize(ent->blocks << 9), pname);
else
printw("%s%-16.16s / %s/\n", CURSYM(sel), buf, pname);
- } else if (S_ISLNK(ent->mode))
- printw("%s%-16.16s @ %s@\n", CURSYM(sel), buf, pname);
- else if (S_ISSOCK(ent->mode))
+ } else if (S_ISLNK(ent->mode)) {
+ if (ent->flags & SYMLINK_TO_DIR)
+ printw("%s%-16.16s @/ %s@\n", CURSYM(sel), buf, pname);
+ else
+ printw("%s%-16.16s @ %s@\n", CURSYM(sel), buf, pname);
+ } else if (S_ISSOCK(ent->mode))
printw("%s%-16.16s = %s=\n", CURSYM(sel), buf, pname);
else if (S_ISFIFO(ent->mode))
printw("%s%-16.16s | %s|\n", CURSYM(sel), buf, pname);
@@ -1752,19 +1758,6 @@ xgetgrgid(gid_t gid)
return grp->gr_name;
}
-static bool
-istgtdir(const char *tgtpath)
-{
- if (tgtpath) {
- struct stat tgtsb;
- int r = stat(tgtpath, &tgtsb);
- if ((r == 0) && (tgtsb.st_mode & S_IFMT) == S_IFDIR)
- return TRUE;
- }
-
- return FALSE;
-}
-
/*
* Follows the stat(1) output closely
*/
@@ -1785,19 +1778,16 @@ show_stats(char *fpath, char *fname, struct stat *sb)
/* Show file name or 'symlink' -> 'target' */
if (perms[0] == 'l') {
/* Note that MAX_CMD_LEN > PATH_MAX */
- char *tgt = realpath(fpath, g_buf);
- if (tgt) {
- char ch[] = {'\'', '\0', '\0'};
- if (istgtdir(g_buf)) {
- ch[1] = ch[0];
- ch[0] = '/';
- }
+ ssize_t len = readlink(fpath, g_buf, MAX_CMD_LEN);
+
+ if (len != -1) {
+ g_buf[len] = '\0';
/*
* We pass g_buf but unescape() operates on g_buf too!
* Read the API notes for information on how this works.
*/
- dprintf(fd, " -> '%s%s", unescape(g_buf, 0), ch);
+ dprintf(fd, " -> '%s'", unescape(g_buf, 0));
}
}
@@ -2210,6 +2200,15 @@ dentfill(char *path, struct entry **dents,
}
}
+ /* Flag if this is a symlink to a dir */
+ if (S_ISLNK(sb.st_mode))
+ if (!fstatat(fd, namep, &sb, 0)) {
+ if (S_ISDIR(sb.st_mode))
+ dentp->flags |= SYMLINK_TO_DIR;
+ else
+ dentp->flags &= ~SYMLINK_TO_DIR;
+ }
+
++n;
}