Use symbol @/ to denote symbolic link to directory

This commit is contained in:
Arun Prakash Jana 2018-08-16 20:08:26 +05:30
parent f0ca1e7785
commit 70df4fb3c2
No known key found for this signature in database
GPG Key ID: A75979F35C080412
2 changed files with 25 additions and 25 deletions

View File

@ -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 |

49
nnn.c
View File

@ -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;
}