Skip to content

Commit

Permalink
[ncls] implement -L option / symlink handling #2006
Browse files Browse the repository at this point in the history
  • Loading branch information
dankamongmen committed Dec 19, 2021
1 parent 70936ad commit b03fc1e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 25 deletions.
2 changes: 1 addition & 1 deletion doc/man/man1/ncls.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ncls - List paths with rendering of multimedia

**-l**: use a long listing format.

**-L**: when showing file information for a symbolic link, show information for the file the link references rather than for the link itself.
**-L**: dereference symbolic links

**-R**: list subdirectories recursively.

Expand Down
2 changes: 1 addition & 1 deletion src/demo/demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ usage(const char* exe, int status){
ncplane_set_fg_rgb8(n, 0xff, 0xff, 0x80);
ncplane_printf(n, " -p:");
ncplane_set_fg_rgb8(n, 0xff, 0xff, 0xff);
ncplane_printf(n, " data file path (default: %s)\n", NOTCURSES_SHARE);
ncplane_printf(n, " data file path (default: %s)\n", notcurses_data_dir());
ncplane_printf(n, "\nspecify demos via their first letter. repetitions are allowed.\n");
ncplane_set_fg_rgb8(n, 0x80, 0xff, 0x80);
ncplane_printf(n, " default spec: %s\n\n", DEFAULT_DEMO);
Expand Down
50 changes: 27 additions & 23 deletions src/ls/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ struct lsContext {
int handle_path(int dirfd, const std::string& dir, const char* p, const lsContext& ctx, bool toplevel);

// handle a single inode of arbitrary type
int handle_inode(const std::string& dir, const char* p, const struct stat* st, const lsContext& ctx){
(void)st; // FIXME handle symlink (dereflinks)
(void)ctx; // FIXME handle symlink (dereflinks)
int handle_inode(const std::string& dir, const char* p){
pthread_mutex_lock(&mtx);
work.emplace(job{dir, p});
pthread_mutex_unlock(&mtx);
Expand All @@ -85,12 +83,12 @@ int handle_inode(const std::string& dir, const char* p, const struct stat* st, c
// otherwise, if |ctx->recursedirs| or |toplevel| is set, we will recurse,
// passing false for toplevel (but preserving |ctx|).
int handle_dir(int dirfd, const std::string& pdir, const char* p,
const struct stat* st, const lsContext& ctx, bool toplevel){
const lsContext& ctx, bool toplevel){
if(ctx.directories){
return handle_inode(pdir, p, st, ctx);
return handle_inode(pdir, p);
}
if(!ctx.recursedirs && !toplevel){
return handle_inode(pdir, p, st, ctx);
return handle_inode(pdir, p);
}
if((strcmp(p, ".") == 0 || strcmp(p, "..") == 0) && !toplevel){
return 0;
Expand Down Expand Up @@ -130,36 +128,42 @@ int handle_dir(int dirfd, const std::string& pdir, const char* p,
return r;
}

int handle_deref(const char* p, const struct stat* st, const lsContext& ctx){
(void)p;
(void)st;
(void)ctx; // FIXME dereference and rerun on target
return 0;
}

// handle some path |p|, either absolute or relative to |dirfd|. |toplevel| is
// true iff the path was directly listed on the command line.
// true iff the path was directly listed on the command line. we rely on lstat()
// and fstatat() to resolve symbolic links for us.
int handle_path(int dirfd, const std::string& pdir, const char* p, const lsContext& ctx, bool toplevel){
struct stat st;
#ifndef __MINGW32__
if(fstatat(dirfd, p, &st, AT_NO_AUTOMOUNT)){
int flags = AT_NO_AUTOMOUNT;
if(!ctx.dereflinks){
flags |= AT_SYMLINK_NOFOLLOW;
}
if(fstatat(dirfd, p, &st, flags)){
std::cerr << "Error running fstatat(" << p << "): " << strerror(errno) << std::endl;
return -1;
}
#else
if(stat(path_join(pdir, p).c_str(), &st)){
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
return -1;
if(ctx.dereflinks){
if(lstat(path_join(pdir, p).c_str(), &st)){
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
return -1;
}
}else{
if(stat(path_join(pdir, p).c_str(), &st)){
std::cerr << "Error running stat(" << p << "): " << strerror(errno) << std::endl;
return -1;
}
}
#endif
if((st.st_mode & S_IFMT) == S_IFDIR){
return handle_dir(dirfd, pdir, p, &st, ctx, toplevel);
return handle_dir(dirfd, pdir, p, ctx, toplevel);
}else if((st.st_mode & S_IFMT) == S_IFLNK){
if(toplevel && ctx.dereflinks){
return handle_deref(p, &st, ctx);
}
pthread_mutex_lock(&outmtx);
std::cout << path_join(pdir, p) << '\n';
pthread_mutex_unlock(&outmtx);
return 0;
}
return handle_inode(pdir, p, &st, ctx);
return handle_inode(pdir, p);
}

// return long-term return code
Expand Down

0 comments on commit b03fc1e

Please sign in to comment.