summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--COPYING2
-rw-r--r--ChangeLog23
-rw-r--r--Makefile.am7
-rw-r--r--README11
-rw-r--r--configure.ac2
-rw-r--r--doc/ncdu.pod511
-rw-r--r--ncdu.1490
-rw-r--r--src/browser.c35
-rw-r--r--src/browser.h2
-rw-r--r--src/delete.c2
-rw-r--r--src/delete.h2
-rw-r--r--src/dir.h7
-rw-r--r--src/dir_common.c4
-rw-r--r--src/dir_export.c2
-rw-r--r--src/dir_import.c2
-rw-r--r--src/dir_mem.c2
-rw-r--r--src/dir_scan.c4
-rw-r--r--src/dirlist.c7
-rw-r--r--src/dirlist.h4
-rw-r--r--src/exclude.c5
-rw-r--r--src/exclude.h2
-rw-r--r--src/global.h8
-rw-r--r--src/help.c2
-rw-r--r--src/help.h2
-rw-r--r--src/main.c99
-rw-r--r--src/path.c2
-rw-r--r--src/path.h2
-rw-r--r--src/quit.c2
-rw-r--r--src/quit.h2
-rw-r--r--src/shell.c2
-rw-r--r--src/shell.h2
-rw-r--r--src/util.c8
-rw-r--r--src/util.h4
34 files changed, 674 insertions, 588 deletions
diff --git a/.gitignore b/.gitignore
index 4533894..67914d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,6 @@ missing
*.o
stamp-h1
ncdu
-ncdu.1
*~
*.swp
static/*
diff --git a/COPYING b/COPYING
index 701ae4f..79c0405 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2007-2022 Yoran Heling
+Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/ChangeLog b/ChangeLog
index 87ea9eb..5401c82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+1.19 - 2023-09-11
+ - Fix typo in --exclude-from argument
+ - Add --(enable|disable)-natsort options
+ - Add indicator to apparent size/disk usage selection in the footer
+
+1.18.1 - 2023-02-12
+ - Fix build on non-Linux platforms
+
+1.18 - 2022-12-06
+ - Fix 'dark-bg' color scheme to actually have a dark background
+ - Backport configuration file support from 2.x
+ - Backport many new CLI options from 2.x
+ - Negation of existing flags: --no-si, --no-confirm-quit, --no-follow-symlinks, --include-caches, --include-kernfs
+ - --[no-]extended in addition to -e
+ - --one-file-system and --cross-file-system in addition to -x
+ - --slow-ui-updates, --fast-ui-updates in addition to -q
+ - Column visibility options: --(show|hide)-(hidden|itemcount|mtime|graph|percent)
+ - Sorting: --sort, --[no-]group-directories-first
+ - Feature selection: --(enable|disable)-(shell|delete|refresh)
+ - Deletion confirmation: --[no-]confirm-delete
+ - Hidden file visibility: --show-hidden, --hide-hidden
+ - Size display: --apparent-size, --disk-usage
+
1.17 - 2022-04-28
- Add 'dark-bg' color scheme and use that by default
- Use natural sort order when sorting by file name
diff --git a/Makefile.am b/Makefile.am
index 71c12d4..430dd56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,12 +37,7 @@ noinst_HEADERS=\
man_MANS=ncdu.1
-EXTRA_DIST=ncdu.1 doc/ncdu.pod
-
-# Don't "clean" ncdu.1, it should be in the tarball so that pod2man isn't a
-# build dependency for those who use the tarball.
-ncdu.1: $(srcdir)/doc/ncdu.pod
- pod2man --center "ncdu manual" --release "@PACKAGE@-@VERSION@" "$(srcdir)/doc/ncdu.pod" >ncdu.1
+EXTRA_DIST=ncdu.1
# This target exists more for documentation purposes than actual use; some
# dependencies have minor ncdu-specific changes.
diff --git a/README b/README
index 2804f35..98196c1 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-ncdu 1.17
+ncdu 1.19
=========
DESCRIPTION
@@ -25,15 +25,14 @@ INSTALL
make
make install
- If you're building directly from the git repository, make sure you have perl
- (or rather, pod2man), pkg-config and GNU autoconf/automake installed, then
- run 'autoreconf -i', and you're ready to continue with the usual ./configure
- and make route.
+ If you're building directly from the git repository, make sure you have
+ pkg-config and GNU autoconf/automake installed, then run 'autoreconf -i',
+ and you're ready to continue with the usual ./configure and make route.
COPYING
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/configure.ac b/configure.ac
index 1f6e94d..c1b0b1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
-AC_INIT([ncdu],[1.17],[projects@yorhel.nl])
+AC_INIT([ncdu],[1.19],[projects@yorhel.nl])
AC_CONFIG_SRCDIR([src/global.h])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign std-options subdir-objects])
diff --git a/doc/ncdu.pod b/doc/ncdu.pod
deleted file mode 100644
index f0c28bd..0000000
--- a/doc/ncdu.pod
+++ /dev/null
@@ -1,511 +0,0 @@
-=head1 NAME
-
-B<ncdu> - NCurses Disk Usage
-
-
-=head1 SYNOPSIS
-
-B<ncdu> [I<options>] I<dir>
-
-
-=head1 DESCRIPTION
-
-ncdu (NCurses Disk Usage) is a curses-based version of the well-known 'du', and
-provides a fast way to see what directories are using your disk space.
-
-
-=head1 OPTIONS
-
-=head2 Mode Selection
-
-=over
-
-=item B<-h>, B<--help>
-
-Print a short help message and quit.
-
-=item B<-v>, B<-V>, B<--version>
-
-Print ncdu version and quit.
-
-=item B<-f> I<FILE>
-
-Load the given file, which has earlier been created with the C<-o> option. If
-I<FILE> is equivalent to C<->, the file is read from standard input.
-
-For the sake of preventing a screw-up, the current version of ncdu will assume
-that the directory information in the imported file does not represent the
-filesystem on which the file is being imported. That is, the refresh, file
-deletion and shell spawning options in the browser will be disabled.
-
-=item I<dir>
-
-Scan the given directory.
-
-=item B<-o> I<FILE>
-
-Export all necessary information to I<FILE> instead of opening the browser
-interface. If I<FILE> is C<->, the data is written to standard output. See the
-examples section below for some handy use cases.
-
-Be warned that the exported data may grow quite large when exporting a
-directory with many files. 10.000 files will get you an export in the order of
-600 to 700 KiB uncompressed, or a little over 100 KiB when compressed with
-gzip. This scales linearly, so be prepared to handle a few tens of megabytes
-when dealing with millions of files.
-
-=item B<-e>, B<--extended>, B<--no-extended>
-
-Enable/disable extended information mode. This will, in addition to the usual
-file information, also read the ownership, permissions and last modification
-time for each file. This will result in higher memory usage (by roughly ~30%)
-and in a larger output file when exporting.
-
-When using the file export/import function, this flag will need to be added
-both when exporting (to make sure the information is added to the export), and
-when importing (to read this extra information in memory). This flag has no
-effect when importing a file that has been exported without the extended
-information.
-
-This enables viewing and sorting by the latest child mtime, or modified time,
-using 'm' and 'M', respectively.
-
-=back
-
-=head2 Scan Options
-
-These options affect the scanning progress, and have no effect when importing
-directory information from a file.
-
-=over
-
-=item B<-x>, B<--one-file-system>
-
-Do not cross filesystem boundaries, i.e. only count files and directories on
-the same filesystem as the directory being scanned.
-
-=item B<--cross-file-system>
-
-Do cross filesystem boundaries. This is the default, but can be specified to
-overrule a previously given C<-x>.
-
-=item B<--exclude> I<PATTERN>
-
-Exclude files that match I<PATTERN>. The files will still be displayed by
-default, but are not counted towards the disk usage statistics. This argument
-can be added multiple times to add more patterns.
-
-=item B<-X> I<FILE>, B<--exclude-from> I<FILE>
-
-Exclude files that match any pattern in I<FILE>. Patterns should be separated
-by a newline.
-
-=item B<--include-caches>, B<--exclude-caches>
-
-Include (default) or exclude directories containing CACHEDIR.TAG. The
-directories will still be displayed, but their contents will not be scanned or
-counted towards the disk usage statistics.
-L<http://www.brynosaurus.com/cachedir/>
-
-=item B<-L>, B<--follow-symlinks>, B<--no-follow-symlinks>
-
-Follow (or not) symlinks and count the size of the file they point to. As of
-ncdu 1.14, this option will not follow symlinks to directories and will count
-each symlinked file as a unique file (i.e. unlike how hard links are handled).
-This is subject to change in later versions.
-
-=item B<--exclude-firmlinks>, B<--follow-firmlinks>
-
-(MacOS only) Exclude or follow firmlinks.
-
-=item B<--include-kernfs>, B<--exclude-kernfs>
-
-(Linux only) Include (default) or exclude Linux pseudo filesystems, e.g. /proc
-(procfs), /sys (sysfs).
-
-The complete list of currently known pseudo filesystems is: binfmt, bpf, cgroup,
-cgroup2, debug, devpts, proc, pstore, security, selinux, sys, trace.
-
-=back
-
-=head2 Interface options
-
-=over
-
-=item B<-0>
-
-Don't give any feedback while scanning a directory or importing a file, other
-than when a fatal error occurs. Ncurses will not be initialized until the scan
-is complete. When exporting the data with C<-o>, ncurses will not be
-initialized at all. This option is the default when exporting to standard
-output.
-
-=item B<-1>
-
-Similar to C<-0>, but does give feedback on the scanning progress with a single
-line of output. This option is the default when exporting to a file.
-
-In some cases, the ncurses browser interface which you'll see after the
-scan/import is complete may look garbled when using this option. If you're not
-exporting to a file, C<-2> is probably a better choice.
-
-=item B<-2>
-
-Provide a full-screen ncurses interface while scanning a directory or importing
-a file. This is the only interface that provides feedback on any non-fatal
-errors while scanning.
-
-=item B<-q>, B<--slow-ui-updates>, B<--fast-ui-updates>
-
-Change the UI update interval while scanning or importing. Ncdu will update the
-screen 10 times a second by default (C<--fast-ui-updates>), this can be
-decreased to once every 2 seconds with C<-q> or C<--slow-ui-updates>. This
-feature can be used to save bandwidth over remote connections. This option has
-no effect when C<-0> is used.
-
-=item B<-r>
-
-Read-only mode. This will disable the built-in file deletion feature. This
-option has no effect when C<-o> is used, because there will not be a browser
-interface in that case. It has no effect when C<-f> is used, either, because
-the deletion feature is disabled in that case anyway.
-
-WARNING: This option will only prevent deletion through the file browser. It is
-still possible to spawn a shell from ncdu and delete or modify files from
-there. To disable that feature as well, pass the C<-r> option twice (see
-C<-rr>).
-
-=item B<-rr>
-
-In addition to C<-r>, this will also disable the shell spawning feature of the
-file browser.
-
-=item B<--si>, B<--no-si>
-
-List sizes using base 10 prefixes, that is, powers of 1000 (KB, MB, etc), as
-defined in the International System of Units (SI), instead of the usual base 2
-prefixes, that is, powers of 1024 (KiB, MiB, etc).
-
-=item B<--disk-usage>, B<--apparent-size>
-
-Select whether to display disk usage (default) or apparent sizes. Can also be
-toggled in the browser with the 'a' key.
-
-=item B<--show-hidden>, B<--hide-hidden>
-
-Show (default) or hide "hidden" and excluded files. Can also be toggled in the
-browser with the 'e' key.
-
-=item B<--show-itemcount>, B<--hide-itemcount>
-
-Show or hide (default) the item counts column. Can also be toggled in the
-browser with the 'c' key.
-
-=item B<--show-mtime>, B<--hide-mtime>
-
-Show or hide (default) the last modification time column. Can also be toggled
-in the browser with the 'm' key. This option is ignored when not in extended
-mode (see C<-e>).
-
-=item B<--show-graph>, B<--hide-graph>
-
-Show (default) or hide the relative size bar column. Can also be toggled in the
-browser with the 'g' key.
-
-=item B<--show-percent>, B<--hide-percent>
-
-Show (default) or hide the relative size percent column. Can also be toggled in
-the browser with the 'g' key.
-
-=item B<--sort> I<COLUMN>
-
-Change the default column to sort on. Accepted values are I<disk-usage> (the
-default), I<name>, I<apparent-size>, I<itemcount> or I<mtime>. The latter only
-makes sense in extended mode, see C<-e>.
-
-The column can be suffixed with I<-asc> or I<-desc> to set the order to
-ascending or descending, respectively. e.g. C<--sort=name-desc> will sort by
-name in descending order.
-
-=item B<--group-directories-first>, B<--no-group-directories-first>
-
-Sort (or not) directories before files.
-
-=item B<--confirm-quit>, B<--no-confirm-quit>
-
-Require a confirmation before quitting ncdu. Very helpful when you accidentally
-press 'q' during or after a very long scan.
-
-=item B<--confirm-delete>, B<--no-confirm-delete>
-
-Require a confirmation before deleting a file or directory. Enabled by default,
-but can be disabled if you're absolutely sure you won't accidentally press 'd'.
-
-=item B<--color> I<SCHEME>
-
-Select a color scheme. The following schemes are recognized: I<off> to disable
-colors, I<dark> for a color scheme intended for dark backgrounds and I<dark-bg>
-for a variation of the I<dark> color scheme that also works in terminals with a
-light background.
-
-The default is I<dark-bg> unless the C<NO_COLOR> environment variable is set.
-
-=back
-
-
-=head1 KEYS
-
-=over
-
-=item B<?>
-
-Show help + keys + about screen
-
-=item B<up>, B<down>, B<j>, B<k>
-
-Cycle through the items
-
-=item B<right>, B<enter>, B<l>
-
-Open selected directory
-
-=item B<left>, B<< < >>, B<h>
-
-Go to parent directory
-
-=item B<n>
-
-Order by filename (press again for descending order)
-
-=item B<s>
-
-Order by filesize (press again for descending order)
-
-=item B<C>
-
-Order by number of items (press again for descending order)
-
-=item B<a>
-
-Toggle between showing disk usage and showing apparent size.
-
-=item B<M>
-
-Order by latest child mtime, or modified time. (press again for descending order)
-Requires the -e flag.
-
-=item B<d>
-
-Delete the selected file or directory. An error message will be shown when the
-contents of the directory do not match or do not exist anymore on the
-filesystem.
-
-=item B<t>
-
-Toggle dirs before files when sorting.
-
-=item B<g>
-
-Toggle between showing percentage, graph, both, or none. Percentage is relative
-to the size of the current directory, graph is relative to the largest item in
-the current directory.
-
-=item B<c>
-
-Toggle display of child item counts.
-
-=item B<m>
-
-Toggle display of latest child mtime, or modified time. Requires the -e flag.
-
-=item B<e>
-
-Show/hide 'hidden' or 'excluded' files and directories. Please note that even
-though you can't see the hidden files and directories, they are still there and
-they are still included in the directory sizes. If you suspect that the totals
-shown at the bottom of the screen are not correct, make sure you haven't
-enabled this option.
-
-=item B<i>
-
-Show information about the current selected item.
-
-=item B<r>
-
-Refresh/recalculate the current directory.
-
-=item B<b>
-
-Spawn shell in current directory.
-
-Ncdu will determine your preferred shell from the C<NCDU_SHELL> or C<SHELL>
-variable (in that order), or will call C</bin/sh> if neither are set. This
-allows you to also configure another command to be run when he 'b' key is
-pressed. For example, to spawn the L<vifm(1)> file manager instead of a shell,
-run ncdu as follows:
-
- export NCDU_SHELL=vifm
- ncdu
-
-Ncdu will set the C<NCDU_LEVEL> environment variable or increment it before
-spawning the shell. This variable allows you to detect when your shell is
-running from within ncdu, which can be useful to avoid nesting multiple
-instances of ncdu. Ncdu itself does not (currently) warn when attempting to run
-nested instances.
-
-=item B<q>
-
-Quit
-
-=back
-
-
-=head1 FILE FLAGS
-
-Entries in the browser interface may be prefixed by a one-character flag. These
-flags have the following meaning:
-
-=over
-
-=item B<!>
-
-An error occurred while reading this directory.
-
-=item B<.>
-
-An error occurred while reading a subdirectory, so the indicated size may not be
-correct.
-
-=item B<< < >>
-
-File or directory is excluded from the statistics by using exclude patterns.
-
-=item B<< > >>
-
-Directory is on another filesystem.
-
-=item B<^>
-
-Directory is excluded from the statistics due to being a Linux pseudo filesystem.
-
-=item B<@>
-
-This is neither a file nor a folder (symlink, socket, ...).
-
-=item B<H>
-
-Same file was already counted (hard link).
-
-=item B<e>
-
-Empty directory.
-
-=back
-
-
-=head1 EXAMPLES
-
-To scan and browse the directory you're currently in, all you need is a simple:
-
- ncdu
-
-If you want to scan a full filesystem, your root filesystem, for example, then
-you'll want to use C<-x>:
-
- ncdu -x /
-
-Since scanning a large directory may take a while, you can scan a directory and
-export the results for later viewing:
-
- ncdu -1xo- / | gzip >export.gz
- # ...some time later:
- zcat export.gz | ncdu -f-
-
-To export from a cron job, make sure to replace C<-1> with C<-0> to suppress
-any unnecessary output.
-
-You can also export a directory and browse it once scanning is done:
-
- ncdu -o- | tee export.file | ./ncdu -f-
-
-The same is possible with gzip compression, but is a bit kludgey:
-
- ncdu -o- | gzip | tee export.gz | gunzip | ./ncdu -f-
-
-To scan a system remotely, but browse through the files locally:
-
- ssh -C user@system ncdu -o- / | ./ncdu -f-
-
-The C<-C> option to ssh enables compression, which will be very useful over
-slow links. Remote scanning and local viewing has two major advantages when
-compared to running ncdu directly on the remote system: You can browse through
-the scanned directory on the local system without any network latency, and ncdu
-does not keep the entire directory structure in memory when exporting, so you
-won't consume much memory on the remote system.
-
-
-=head1 HARD LINKS
-
-Every disk usage analysis utility has its own way of (not) counting hard links.
-There does not seem to be any universally agreed method of handling hard links,
-and it is even inconsistent among different versions of ncdu. This section
-explains what each version of ncdu does.
-
-ncdu 1.5 and below does not support any hard link detection at all: each link
-is considered a separate inode and its size is counted for every link. This
-means that the displayed directory sizes are incorrect when analyzing
-directories which contain hard links.
-
-ncdu 1.6 has basic hard link detection: When a link to a previously encountered
-inode is detected, the link is considered to have a file size of zero bytes.
-Its size is not counted again, and the link is indicated in the browser
-interface with a 'H' mark. The displayed directory sizes are only correct when
-all links to an inode reside within that directory. When this is not the case,
-the sizes may or may not be correct, depending on which links were considered
-as "duplicate" and which as "original". The indicated size of the topmost
-directory (that is, the one specified on the command line upon starting ncdu)
-is always correct.
-
-ncdu 1.7 and later has improved hard link detection. Each file that has more
-than two links has the "H" mark visible in the browser interface. Each hard
-link is counted exactly once for every directory it appears in. The indicated
-size of each directory is therefore, correctly, the sum of the sizes of all
-unique inodes that can be found in that directory. Note, however, that this may
-not always be same as the space that will be reclaimed after deleting the
-directory, as some inodes may still be accessible from hard links outside it.
-
-
-=head1 BUGS
-
-Directory hard links are not supported. They will not be detected as being hard
-links, and will thus be scanned and counted multiple times.
-
-Some minor glitches may appear when displaying filenames that contain multibyte
-or multicolumn characters.
-
-All sizes are internally represented as a signed 64bit integer. If you have a
-directory larger than 8 EiB minus one byte, ncdu will clip its size to 8 EiB
-minus one byte. When deleting items in a directory with a clipped size, the
-resulting sizes will be incorrect.
-
-Item counts are stored in a signed 32-bit integer without overflow detection.
-If you have a directory with more than 2 billion files, quite literally
-anything can happen.
-
-On macOS 10.15 and later, running ncdu on the root directory without
-`--exclude-firmlinks` may cause directories to be scanned and counted multiple
-times. Firmlink cycles are currently (1.16) not detected, so it may also cause
-ncdu to get stuck in an infinite loop and eventually run out of memory.
-
-Please report any other bugs you may find at the bug tracker, which can be
-found on the web site at https://dev.yorhel.nl/ncdu
-
-
-=head1 AUTHOR
-
-Written by Yoran Heling <projects@yorhel.nl>.
-
-
-=head1 SEE ALSO
-
-L<du(1)>
diff --git a/ncdu.1 b/ncdu.1
new file mode 100644
index 0000000..6990604
--- /dev/null
+++ b/ncdu.1
@@ -0,0 +1,490 @@
+.\" SPDX-FileCopyrightText: Yoran Heling <projects@yorhel.nl>
+.\" SPDX-License-Identifier: MIT
+.Dd January 21, 2024
+.Dt NCDU 1
+.Os
+.Sh NAME
+.Nm ncdu
+.Nd NCurses Disk Usage
+.Sh SYNOPSIS
+.Nm
+.Op Fl f Ar file
+.Op Fl o Ar file
+.Op Fl e , \-extended , \-no\-extended
+.Op Fl \-ignore\-config
+.Op Fl x , \-one\-file\-system , \-cross\-file\-system
+.Op Fl \-exclude Ar pattern
+.Op Fl X , \-exclude\-from Ar file
+.Op Fl \-include\-caches , \-exclude\-caches
+.Op Fl L , \-follow\-symlinks , \-no\-follow\-symlinks
+.Op Fl \-include\-kernfs , \-exclude\-kernfs
+.Op Fl \-exclude\-firmlinks, \-follow\-firmlinks
+.Op Fl 0 , 1 , 2
+.Op Fl q , \-slow\-ui\-updates , \-fast\-ui\-updates
+.Op Fl \-enable\-shell , \-disable\-shell
+.Op Fl \-enable\-delete , \-disable\-delete
+.Op Fl \-enable\-refresh , \-disable\-refresh
+.Op Fl r
+.Op Fl \-si , \-no\-si
+.Op Fl \-disk\-usage , \-apparent\-size
+.Op Fl \-show\-hidden , \-hide\-hidden
+.Op Fl \-show\-itemcount , \-hide\-itemcount
+.Op Fl \-show\-mtime , \-hide\-mtime
+.Op Fl \-show\-graph , \-hide\-graph
+.Op Fl \-show\-percent , \-hide\-percent
+.Op Fl \-sort Ar column
+.Op Fl \-enable\-natsort , \-disable\-natsort
+.Op Fl \-group\-directories\-first , \-no\-group\-directories\-first
+.Op Fl \-confirm\-quit , \-no\-confirm\-quit
+.Op Fl \-confirm\-delete , \-no\-confirm\-delete
+.Op Fl \-color Ar off | dark | dark-bg
+.Op Ar path
+.Nm
+.Op Fl h , \-help
+.Nm
+.Op Fl v , V , \-version
+.Sh DESCRIPTION
+.Nm
+(NCurses Disk Usage) is an interactive curses-based version of the well-known
+.Xr du 1 ,
+and provides a fast way to see what directories are using your disk space.
+.Sh OPTIONS
+.Ss Mode Selection
+.Bl -tag -width Ds
+.It Fl h , \-help
+Print a short help message and quit.
+.It Fl v , V , \-version
+Print version and quit.
+.It Fl f Ar file
+Load the given file, which has earlier been created with the
+.Fl o
+flag.
+If
+.Ar file
+is equivalent to '\-', the file is read from standard input.
+.Pp
+For the sake of preventing a screw-up, the current version of
+.Nm
+will assume that the directory information in the imported file does not
+represent the filesystem on which the file is being imported.
+That is, the refresh, file deletion and shell spawning options in the browser
+will be disabled.
+.It Ar dir
+Scan the given directory.
+.It Fl o Ar file
+Export all necessary information to
+.Ar file
+instead of opening the browser interface.
+If
+.Ar file
+is '\-', the data is written to standard output.
+See the examples section below for some handy use cases.
+.Pp
+Be warned that the exported data may grow quite large when exporting a
+directory with many files.
+10.000 files will get you an export in the order of 600 to 700 KiB
+uncompressed, or a little over 100 KiB when compressed with gzip.
+This scales linearly, so be prepared to handle a few tens of megabytes when
+dealing with millions of files.
+.It Fl e , \-extended , \-no\-extended
+Enable/disable extended information mode.
+This will, in addition to the usual file information, also read the ownership,
+permissions and last modification time for each file.
+This will result in higher memory usage (by roughly ~30%) and in a larger
+output file when exporting.
+.Pp
+When using the file export/import function, this flag should be added both when
+exporting (to make sure the information is added to the export) and when
+importing (to read this extra information in memory).
+This flag has no effect when importing a file that has been exported without
+the extended information.
+.Pp
+This enables viewing and sorting by the latest child mtime, or modified time,
+using 'm' and 'M', respectively.
+.It Fl \-ignore\-config
+Do not attempt to load any configuration files.
+.El
+.Ss Scan Options
+These options affect the scanning progress, they have no effect when importing
+directory information from a file.
+.Bl -tag -width Ds
+.It Fl x , \-one\-file\-system
+Do not cross filesystem boundaries, i.e. only count files and directories on
+the same filesystem as the directory being scanned.
+.It Fl \-cross\-file\-system
+Do cross filesystem boundaries.
+This is the default, but can be specified to overrule a previously configured
+.Fl x .
+.It Fl \-exclude Ar pattern
+Exclude files that match
+.Ar pattern .
+The files are still displayed by default, but are not counted towards the disk
+usage statistics.
+This argument can be added multiple times to add more patterns.
+.It Fl X , \-exclude\-from Ar file
+Exclude files that match any pattern in
+.Ar file .
+Patterns should be separated by a newline.
+.It Fl \-include\-caches , \-exclude\-caches
+Include (default) or exclude directories containing
+.Pa CACHEDIR.TAG .
+Excluded cache directories are still displayed, but their contents will not be
+scanned or counted towards the disk usage statistics.
+.Lk https://bford.info/cachedir/
+.It Fl L , \-follow\-symlinks , \-no\-follow\-symlinks
+Follow (or not) symlinks and count the size of the file they point to.
+This option does not follow symlinks to directories and will cause each
+symlinked file to count as a unique file.
+This is different from how hard links are handled.
+The exact counting behavior of this flag is subject to change in the future.
+.It Fl \-include\-kernfs , \-exclude\-kernfs
+(Linux only) Include (default) or exclude Linux pseudo filesystems such as
+.Pa /proc
+(procfs) and
+.Pa /sys
+(sysfs).
+.Pp
+The complete list of currently known pseudo filesystems is: binfmt, bpf, cgroup,
+cgroup2, debug, devpts, proc, pstore, security, selinux, sys, trace.
+.Op Fl \-exclude\-firmlinks, \-follow\-firmlinks
+(MacOS only) Exclude or follow firmlinks.
+.El
+.Ss Interface Options
+.Bl -tag -width Ds
+.It Fl 0
+Don't give any feedback while scanning a directory or importing a file, except
+when a fatal error occurs.
+Ncurses will not be initialized until the scan is complete.
+When exporting the data with
+.Fl o ,
+ncurses will not be initialized at all.
+This option is the default when exporting to standard output.
+.It Fl 1
+Similar to
+.Fl 0 ,
+but does give feedback on the scanning progress with a single line of output.
+This option is the default when exporting to a file.
+.Pp
+In some cases, the ncurses browser interface which you'll see after the
+scan/import is complete may look garbled when using this option.
+If you're not exporting to a file,
+.Fl 2
+is usually a better choice.
+.It Fl 2
+Show a full-screen ncurses interface while scanning a directory or importing
+a file.
+This is the only interface that provides feedback on any non-fatal errors while
+scanning.
+.It Fl q , \-slow\-ui\-updates , \-fast\-ui\-updates
+Change the UI update interval while scanning or importing.
+.Nm
+updates the screen 10 times a second by default (with
+.Fl \-fast\-ui\-updates
+), this can be decreased to once every 2 seconds with
+.Fl q
+or
+.Fl \-slow\-ui\-updates .
+This option can be used to save bandwidth over remote connections.
+This option has no effect in combination with
+.Fl 0 .
+.It Fl \-enable\-shell , \-disable\-shell
+Enable or disable shell spawning from the file browser.
+This feature is enabled by default when scanning a live directory and disabled
+when importing from file.
+.It Fl \-enable\-delete , \-disable\-delete
+Enable or disable the built-in file deletion feature.
+This feature is enabled by default when scanning a live directory and disabled
+when importing from file.
+Explicitly disabling the deletion feature can work as a safeguard to prevent
+accidental data loss.
+.It Fl \-enable\-refresh , \-disable\-refresh
+Enable or disable directory refreshing from the file browser.
+This feature is enabled by default when scanning a live directory and disabled
+when importing from file.
+.It Fl r
+Read-only mode.
+When given once, this is an alias for
+.Fl \-disable\-delete ,
+when given twice it will also add
+.Fl \-disable\-shell ,
+thus ensuring that there is no way to modify the file system from within
+.Nm .
+.It Fl \-si , \-no\-si
+List sizes using base 10 prefixes, that is, powers of 1000 (KB, MB, etc), as
+defined in the International System of Units (SI), instead of the usual base 2
+prefixes (KiB, MiB, etc).
+.It Fl \-disk\-usage , \-apparent\-size
+Select whether to display disk usage (default) or apparent sizes.
+Can also be toggled in the file browser with the 'a' key.
+.It Fl \-show\-hidden , \-hide\-hidden
+Show (default) or hide "hidden" and excluded files.
+Can also be toggled in the file browser with the 'e' key.
+.It Fl \-show\-itemcount , \-hide\-itemcount
+Show or hide (default) the item counts column.
+Can also be toggled in the file browser with the 'c' key.
+.It Fl \-show\-mtime , \-hide\-mtime
+Show or hide (default) the last modification time column.
+Can also be toggled in the file browser with the 'm' key.
+This option is ignored when not in extended mode, see
+.Fl e .
+.It Fl \-show\-graph , \-hide\-graph
+Show (default) or hide the relative size bar column.
+Can also be toggled in the file browser with the 'g' key.
+.It Fl \-show\-percent , \-hide\-percent
+Show (default) or hide the relative size percent column.
+Can also be toggled in the file browser with the 'g' key.
+.It Fl \-sort Ar column
+Change the default column to sort on.
+Accepted values are
+.Ar disk\-usage
+(the default),
+.Ar name , apparent\-size , itemcount
+or
+.Ar mtime .
+The latter only makes sense in extended mode, see
+.Fl e .
+.Pp
+The column name can be suffixed with
+.Li \-asc
+or
+.Li \-desc
+to change the order to ascending or descending, respectively.
+For example,
+.Li \-\-sort=name\-desc
+to sort by name in descending order.
+.It Fl \-enable\-natsort , \-disable\-natsort
+Enable (default) or disable natural sort when sorting by file name.
+.It Fl \-group\-directories\-first , \-no\-group\-directories\-first
+Sort (or not) directories before files.
+.It Fl \-confirm\-quit , \-no\-confirm\-quit
+Require a confirmation before quitting ncdu.
+Can be helpful when you accidentally press 'q' during or after a very long scan.
+.It Fl \-confirm\-delete , \-no\-confirm\-delete
+Require a confirmation before deleting a file or directory.
+Enabled by default, but can be disabled if you're absolutely sure you won't
+accidentally press 'd'.
+.It Fl \-color Ar off | dark | dark-bg
+Set the color scheme.
+The following schemes are recognized:
+.Ar off
+to disable colors,
+.Ar dark
+for a color scheme intended for dark backgrounds and
+.Ar dark\-bg
+for a variation of the
+.Ar dark
+color scheme that also works in terminals with a light background.
+.Pp
+The default is
+.Ar dark\-bg
+unless the
+.Ev NO_COLOR
+environment variable is set.
+.El
+.Sh CONFIGURATION
+.Nm
+can be configured by placing command-line options in
+.Pa /etc/ncdu.conf
+or
+.Pa $HOME/.config/ncdu/config .
+If both files exist, the system configuration will be loaded before the user
+configuration, allowing users to override options set in the system
+configuration.
+Options given on the command line will override options set in the
+configuration files.
+The files will not be read at all when
+.Fl \-ignore\-config
+is given on the command line.
+.Pp
+The configuration file format is simply one command line option per line.
+Lines starting with '#' are ignored.
+Example configuration file:
+.Bd -literal -offset indent
+# Always enable extended mode
+\-e
+
+# Disable file deletion
+\-\-disable\-delete
+
+# Exclude .git directories
+\-\-exclude .git
+.Ed
+.Sh KEYS
+.Bl -tag -width Ds
+.It ?
+Open help + keys + about screen
+.It up , down , j , k
+Cycle through the items
+.It right, enter, l
+Open selected directory
+.It left, <, h
+Go to parent directory
+.It n
+Order by filename (press again for descending order)
+.It s
+Order by filesize (press again for descending order)
+.It C
+Order by number of items (press again for descending order)
+.It a
+Toggle between showing disk usage and showing apparent size.
+.It M
+Order by latest child mtime, or modified time (press again for descending
+order).
+Requires the
+.Fl e
+flag.
+.It d
+Delete the selected file or directory.
+An error message will be shown when the contents of the directory do not match
+or do not exist anymore on the filesystem.
+.It t
+Toggle dirs before files when sorting.
+.It g
+Toggle between showing percentage, graph, both, or none.
+Percentage is relative to the size of the current directory, graph is relative
+to the largest item in the current directory.
+.It c
+Toggle display of child item counts.
+.It m
+Toggle display of latest child mtime, or modified time.
+Requires the
+.Fl e
+flag.
+.It e
+Show/hide 'hidden' or 'excluded' files and directories.
+Be aware that even if you can't see the hidden files and directories, they are
+still there and they are still included in the directory sizes.
+If you suspect that the totals shown at the bottom of the screen are not
+correct, make sure you haven't enabled this option.
+.It i
+Show information about the current selected item.
+.It r
+Refresh/recalculate the current directory.
+.It b
+Spawn shell in current directory.
+.Pp
+.Nm
+determines your preferred shell from the
+.Ev NCDU_SHELL
+or
+.Ev SHELL
+environment variable (in that order), or calls
+.Pa /bin/sh
+if neither are set.
+This allows you to also configure another command to be run when he 'b' key is
+pressed.
+For example, to spawn the
+.Xr vifm 1
+file manager instead of a shell, run
+.Nm
+as follows:
+.Dl NCDU_SHELL=vifm ncdu
+The
+.Ev NCDU_LEVEL
+environment variable is set or incremented before spawning the shell, allowing
+you to detect if your shell is running from within
+.Nm .
+This can be useful to avoid nesting multiple instances, although
+.Nm
+itself does not (currently) warn about or prevent this situation.
+.It q
+Quit
+.El
+.Sh FILE FLAGS
+Entries in the browser interface may be prefixed by a one\-character flag.
+These flags have the following meaning:
+.Bl -tag -width Ds
+.It !
+An error occurred while reading this directory.
+.It \.
+An error occurred while reading a subdirectory, so the indicated size may not
+be correct.
+.It <
+File or directory is excluded from the statistics by using exclude patterns.
+.It >
+Directory is on another filesystem.
+.It ^
+Directory is excluded from the statistics due to being a Linux pseudo
+filesystem.
+.It @
+This is neither a file nor a folder (symlink, socket, ...).
+.It H
+Same file was already counted (hard link).
+.It e
+Empty directory.
+.El
+.Sh EXAMPLES
+To scan and browse the directory you're currently in, all you need is a simple:
+.Dl ncdu
+If you want to scan a full filesystem, for example your root filesystem, then
+you'll want to use
+.Fl x :
+.Dl ncdu \-x /
+.Pp
+Since scanning a large directory may take a while, you can scan a directory and
+export the results for later viewing:
+.Bd -literal -offset indent
+ncdu \-1xo\- / | gzip >export.gz
+# ...some time later:
+zcat export.gz | ncdu \-f\-
+.Ed
+To export from a cron job, make sure to replace
+.Fl 1
+with
+.Fl 0
+to suppress any unnecessary output.
+.Pp
+You can also export a directory and browse it once scanning is done:
+.Dl ncdu \-o\- | tee export.file | ./ncdu \-f\-
+The same is possible with gzip compression, but is a bit kludgey:
+.Dl ncdu \-o\- | gzip | tee export.gz | gunzip | ./ncdu \-f\-
+.Pp
+To scan a system remotely, but browse through the files locally:
+.Dl ssh \-C user@system ncdu \-o\- / | ./ncdu \-f\-
+The
+.Fl C
+option to ssh enables compression, which will be very useful over slow links.
+Remote scanning and local viewing has two major advantages when
+compared to running
+.Nm
+directly on the remote system: You can browse through the scanned directory on
+the local system without any network latency, and
+.Nm
+does not keep the entire directory structure in memory when exporting, so this
+won't consume much memory on the remote system.
+.Sh BUGS
+Directory hard links are not supported. They are not detected as being hard
+links, and will thus get scanned and counted multiple times.
+.Pp
+Some minor glitches may appear when displaying filenames that contain multibyte
+or multicolumn characters.
+.Pp
+All sizes are internally represented as a signed 64bit integer.
+If you have a directory larger than 8 EiB minus one byte, ncdu will clip its
+size to 8 EiB minus one byte.
+When deleting or refreshing items in a directory with a clipped size, the
+resulting sizes will be incorrect.
+Item counts are stored in a 32-bit integer without overflow detection.
+If you have a directory with more than 2 billion files, quite literally
+anything can happen.
+.Pp
+On macOS 10.15 and later, running ncdu on the root directory without
+.Fl \-exclude\-firmlinks
+may cause directories to be scanned and counted multiple times.
+Firmlink cycles are not detected, so it may also cause
+.Nm
+to get stuck in an infinite loop and eventually run out of memory.
+.Pp
+Please report any other bugs you may find at the bug tracker, which can be
+found on the web site at
+.Lk https://dev.yorhel.nl/ncdu
+.Sh SEE ALSO
+.Xr du 1 ,
+.Xr tree 1 .
+.Pp
+.Nm
+has a website:
+.Lk https://dev.yorhel.nl/ncdu
+.Sh AUTHORS
+Written by
+.An Yorhel Aq Mt projects@yorhel.nl
diff --git a/src/browser.c b/src/browser.c
index 91d7757..92960e7 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -272,7 +272,7 @@ void browse_draw(void) {
addstrc(UIC_HD, " for help");
if(dir_import_active)
mvaddstr(0, wincols-10, "[imported]");
- else if(read_only)
+ else if(!can_delete)
mvaddstr(0, wincols-11, "[read-only]");
/* second line - the path */
@@ -289,15 +289,18 @@ void browse_draw(void) {
mvhline(winrows-1, 0, ' ', wincols);
if(t) {
if(!show_as) attron(A_BOLD);
- mvaddstr(winrows-1, 0, " Total disk usage: ");
+ mvaddchc(UIC_HD, winrows-1, 0, show_as ? ' ' : '*');
+ addstr("Total disk usage: ");
if(!show_as) attroff(A_BOLD);
printsize(UIC_HD, t->parent->size);
if(show_as) attron(A_BOLD);
- addstrc(UIC_HD, " Apparent size: ");
+ addstrc(UIC_HD, " ");
+ addchc(UIC_HD, show_as ? '*' : ' ');
+ addstrc(UIC_HD, "Apparent size: ");
if(show_as) attroff(A_BOLD);
uic_set(UIC_NUM_HD);
printsize(UIC_HD, t->parent->asize);
- addstrc(UIC_HD, " Items: ");
+ addstrc(UIC_HD, " Items: ");
uic_set(UIC_NUM_HD);
printw("%d", t->parent->items);
} else
@@ -323,7 +326,7 @@ void browse_draw(void) {
if(message) {
nccreate(6, 60, "Message");
ncaddstr(2, 2, message);
- ncaddstr(4, 34, "Press any key to continue");
+ ncaddstr(4, 33, "Press any key to continue");
}
/* draw information window */
@@ -488,8 +491,8 @@ int browse_key(int ch) {
/* and other stuff */
case 'r':
- if(dir_import_active) {
- message = "Directory imported from file, won't refresh.";
+ if(!can_refresh) {
+ message = "Directory refresh feature disabled.";
break;
}
if(dirlist_par) {
@@ -527,14 +530,12 @@ int browse_key(int ch) {
info_show = 0;
break;
case 'd':
- if(read_only >= 1 || dir_import_active) {
- message = read_only >= 1
- ? "File deletion disabled in read-only mode."
- : "File deletion not available for imported directories.";
- break;
- }
if(sel == NULL || sel == dirlist_parent)
break;
+ if(!can_delete) {
+ message = "Deletion feature disabled.";
+ break;
+ }
info_show = 0;
if((t = dirlist_get(1)) == sel)
if((t = dirlist_get(-1)) == sel || t == dirlist_parent)
@@ -542,10 +543,8 @@ int browse_key(int ch) {
delete_init(sel, t);
break;
case 'b':
- if(read_only >= 2 || dir_import_active) {
- message = read_only >= 2
- ? "Shell feature disabled in read-only mode."
- : "Shell feature not available for imported directories.";
+ if(!can_shell) {
+ message = "Shell feature disabled.";
break;
}
shell_init();
diff --git a/src/browser.h b/src/browser.h
index b23ddf2..8bdea7c 100644
--- a/src/browser.h
+++ b/src/browser.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/delete.c b/src/delete.c
index 8fe1dc8..ac495b0 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/delete.h b/src/delete.h
index 527dd9d..30ac3cf 100644
--- a/src/delete.h
+++ b/src/delete.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/dir.h b/src/dir.h
index 7dc9757..2c4669e 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -107,16 +107,13 @@ extern int (*dir_process)(void);
/* Scanning a live directory */
extern int dir_scan_smfs;
+extern int exclude_kernfs;
void dir_scan_init(const char *path);
/* Importing a file */
extern int dir_import_active;
int dir_import_init(const char *fn);
-#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
-extern int exclude_kernfs;
-#endif
-
/* The currently configured output functions. */
extern struct dir_output dir_output;
diff --git a/src/dir_common.c b/src/dir_common.c
index 0a77260..cf9def7 100644
--- a/src/dir_common.c
+++ b/src/dir_common.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -35,7 +35,7 @@ int (*dir_process)(void);
char *dir_curpath; /* Full path of the last seen item. */
struct dir_output dir_output;
char *dir_fatalerr; /* Error message on a fatal error. (NULL if there was no fatal error) */
-int dir_ui; /* User interface to use */
+int dir_ui = -1; /* User interface to use */
static int confirm_quit_while_scanning_stage_1_passed; /* Additional check before quitting */
static char *lasterr; /* Path where the last error occurred. */
static int curpathl; /* Allocated length of dir_curpath */
diff --git a/src/dir_export.c b/src/dir_export.c
index b458ba4..b6c2be4 100644
--- a/src/dir_export.c
+++ b/src/dir_export.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/dir_import.c b/src/dir_import.c
index b76e3a7..eb3e91d 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/dir_mem.c b/src/dir_mem.c
index ed6afc8..4a648f1 100644
--- a/src/dir_mem.c
+++ b/src/dir_mem.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/dir_scan.c b/src/dir_scan.c
index 7c1bc77..3418c99 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -51,6 +51,7 @@
int dir_scan_smfs; /* Stay on the same filesystem */
+int exclude_kernfs; /* Exclude Linux pseudo filesystems */
static uint64_t curdev; /* current device we're scanning on */
@@ -61,7 +62,6 @@ static unsigned int buf_nlink;
#if HAVE_LINUX_MAGIC_H && HAVE_SYS_STATFS_H && HAVE_STATFS
-int exclude_kernfs; /* Exclude Linux pseudo filesystems */
static int is_kernfs(unsigned long type) {
if(
diff --git a/src/dirlist.c b/src/dirlist.c
index c897ce6..37287ad 100644
--- a/src/dirlist.c
+++ b/src/dirlist.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -39,7 +39,8 @@ int64_t dirlist_maxs = 0,
int dirlist_sort_desc = 1,
dirlist_sort_col = DL_COL_SIZE,
dirlist_sort_df = 0,
- dirlist_hidden = 0;
+ dirlist_hidden = 0,
+ dirlist_natsort = 1;
/* private state vars */
static struct dir *parent_alloc, *head, *head_real, *selected, *top = NULL;
@@ -80,7 +81,7 @@ static int dirlist_cmp(struct dir *x, struct dir *y) {
*
* Note that the method used below is supposed to be fast, not readable :-)
*/
-#define CMP_NAME strnatcmp(x->name, y->name)
+#define CMP_NAME (dirlist_natsort ? strnatcmp(x->name, y->name) : strcmp(x->name, y->name))
#define CMP_SIZE (x->size > y->size ? 1 : (x->size == y->size ? 0 : -1))
#define CMP_ASIZE (x->asize > y->asize ? 1 : (x->asize == y->asize ? 0 : -1))
#define CMP_ITEMS (x->items > y->items ? 1 : (x->items == y->items ? 0 : -1))
diff --git a/src/dirlist.h b/src/dirlist.h
index 702b1c7..902106d 100644
--- a/src/dirlist.h
+++ b/src/dirlist.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -78,6 +78,8 @@ extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df;
/* set with dirlist_set_hidden() */
extern int dirlist_hidden;
+extern int dirlist_natsort;
+
/* maximum size of an item in the opened dir */
extern int64_t dirlist_maxs, dirlist_maxa;
diff --git a/src/exclude.c b/src/exclude.c
index c1c018d..3207259 100644
--- a/src/exclude.c
+++ b/src/exclude.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -46,8 +46,7 @@ void exclude_add(char *pat) {
n = &((*n)->next);
*n = (struct exclude *) xcalloc(1, sizeof(struct exclude));
- (*n)->pattern = (char *) xmalloc(strlen(pat)+1);
- strcpy((*n)->pattern, pat);
+ (*n)->pattern = xstrdup(pat);
}
diff --git a/src/exclude.h b/src/exclude.h
index 4d4a1a7..c852f6e 100644
--- a/src/exclude.h
+++ b/src/exclude.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/global.h b/src/global.h
index 573e685..9899e7e 100644
--- a/src/global.h
+++ b/src/global.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -95,8 +95,10 @@ struct dir_ext {
/* program state */
extern int pstate;
-/* read-only flag, 1+ = disable deletion, 2+ = also disable shell */
-extern int read_only;
+/* enabled features */
+extern int can_delete;
+extern int can_shell;
+extern int can_refresh;
/* minimum screen update interval when calculating, in ms */
extern long update_delay;
/* filter directories with CACHEDIR.TAG */
diff --git a/src/help.c b/src/help.c
index 9471d0b..714c157 100644
--- a/src/help.c
+++ b/src/help.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/help.h b/src/help.h
index 12e0fef..13d3388 100644
--- a/src/help.h
+++ b/src/help.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/main.c b/src/main.c
index 30619ec..6ddae96 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -35,7 +35,9 @@
int pstate;
-int read_only = 0;
+int can_delete = -1;
+int can_shell = -1;
+int can_refresh = -1;
long update_delay = 100;
int cachedir_tags = 0;
int extended_info = 0;
@@ -197,7 +199,14 @@ static int arg_option(void) {
else if(OPT("--cross-file-system")) dir_scan_smfs = 0;
else if(OPT("-e") || OPT("--extended")) extended_info = 1;
else if(OPT("--no-extended")) extended_info = 0;
- else if(OPT("-r")) read_only++;
+ else if(OPT("-r") && !can_delete) can_shell = 0;
+ else if(OPT("-r")) can_delete = 0;
+ else if(OPT("--enable-shell")) can_shell = 1;
+ else if(OPT("--disable-shell")) can_shell = 0;
+ else if(OPT("--enable-delete")) can_delete = 1;
+ else if(OPT("--disable-delete")) can_delete = 0;
+ else if(OPT("--enable-refresh")) can_refresh = 1;
+ else if(OPT("--disable-refresh")) can_refresh = 0;
else if(OPT("--show-hidden")) dirlist_hidden = 0;
else if(OPT("--hide-hidden")) dirlist_hidden = 1;
else if(OPT("--show-itemcount")) show_items = 1;
@@ -210,6 +219,8 @@ static int arg_option(void) {
else if(OPT("--hide-percent")) graph &= 1;
else if(OPT("--group-directories-first")) dirlist_sort_df = 1;
else if(OPT("--no-group-directories-first")) dirlist_sort_df = 0;
+ else if(OPT("--enable-natsort")) dirlist_natsort = 1;
+ else if(OPT("--disable-natsort")) dirlist_natsort = 0;
else if(OPT("--sort")) {
arg = ARG;
tmp = strrchr(arg, '-');
@@ -243,7 +254,7 @@ static int arg_option(void) {
else if(OPT("-L") || OPT("--follow-symlinks")) follow_symlinks = 1;
else if(OPT("--no-follow-symlinks")) follow_symlinks = 0;
else if(OPT("--exclude")) exclude_add(ARG);
- else if(OPT("-X") || OPT("--exclude-form")) {
+ else if(OPT("-X") || OPT("--exclude-from")) {
arg = ARG;
if(exclude_addfile(arg)) die("Can't open %s: %s\n", arg, strerror(errno));
} else if(OPT("--exclude-caches")) cachedir_tags = 1;
@@ -294,16 +305,81 @@ static void arg_help(void) {
}
+static void config_read(const char *fn) {
+ FILE *f;
+ char buf[1024], *line, *tmp, **args = NULL, **argsi;
+ int r, len, argslen = 0, argssize = 0;
+
+ if((f = fopen(fn, "r")) == NULL) {
+ if(errno == ENOENT || errno == ENOTDIR) return;
+ die("Error opening %s: %s.\nRun with --ignore-config to skip reading config files.\n", fn, strerror(errno));
+ }
+
+ while(fgets(buf, 1024, f) != NULL) {
+ line = buf;
+ while(*line == ' ' || *line == '\t') line++;
+ len = strlen(line);
+ while(len > 0 && (line[len-1] == ' ' || line[len-1] == '\t' || line[len-1] == '\r' || line[len-1] == '\n')) len -= 1;
+ line[len] = 0;
+ if(len == 0 || *line == '#') continue;
+
+ /* Reserve at least 3 spots, one for the option, one for a possible argument and one for the final NULL. */
+ if(argslen+3 >= argssize) {
+ argssize = argssize ? argssize*2 : 32;
+ args = xrealloc(args, sizeof(char *)*argssize);
+ }
+ for(tmp=line; *tmp && *tmp != ' ' && *tmp != '\t' && *tmp != '='; tmp++);
+ while(*tmp && (*tmp == ' ' || *tmp == '\t')) {
+ *tmp = 0;
+ tmp++;
+ }
+ args[argslen++] = xstrdup(line);
+ if(*tmp) args[argslen++] = xstrdup(tmp);
+ }
+ if(ferror(f))
+ die("Error reading from %s: %s\nRun with --ignore-config to skip reading config files.\n", fn, strerror(errno));
+ fclose(f);
+ if(!argslen) return;
+
+ args[argslen] = NULL;
+ memset(&argparser_state, 0, sizeof(struct argparser));
+ argparser_state.argv = args;
+ argparser_state.argc = argslen;
+
+ while((r = argparser_next(&argparser_state)) > 0)
+ if(r == 2 || !arg_option())
+ die("Unknown option in config file '%s': %s.\nRun with --ignore-config to skip reading config files.\n", fn, argparser_state.last);
+
+ for(argsi=args; argsi && *argsi; argsi++) free(*argsi);
+ free(args);
+}
+
+
+static void config_load(int argc, char **argv) {
+ char *env, buf[1024];
+ int r;
+
+ for(r=0; r<argc; r++)
+ if(strcmp(argv[r], "--ignore-config") == 0) return;
+
+ config_read("/etc/ncdu.conf");
+
+ if((env = getenv("XDG_CONFIG_HOME")) != NULL) {
+ r = snprintf(buf, 1024, "%s/ncdu/config", env);
+ if(r > 0 && r < 1024) config_read(buf);
+ } else if((env = getenv("HOME")) != NULL) {
+ r = snprintf(buf, 1024, "%s/.config/ncdu/config", env);
+ if(r > 0 && r < 1024) config_read(buf);
+ }
+}
+
+
static void argv_parse(int argc, char **argv) {
int r;
char *export = NULL;
char *import = NULL;
char *dir = NULL;
- uic_theme = getenv("NO_COLOR") ? 0 : 2;
- dir_ui = -1;
- si = 0;
-
memset(&argparser_state, 0, sizeof(struct argparser));
argparser_state.argv = argv;
argparser_state.argc = argc;
@@ -317,6 +393,7 @@ static void argv_parse(int argc, char **argv) {
} else if(OPT("-h") || OPT("-?") || OPT("--help")) arg_help();
else if(OPT("-o")) export = ARG;
else if(OPT("-f")) import = ARG;
+ else if(OPT("--ignore-config")) {}
else if(!arg_option()) die("Unknown option '%s'.\n", argparser_state.last);
}
@@ -340,6 +417,10 @@ static void argv_parse(int argc, char **argv) {
* feedback when exporting to stdout. */
if(dir_ui == -1)
dir_ui = export && strcmp(export, "-") == 0 ? 0 : export ? 1 : 2;
+
+ if(can_delete == -1) can_delete = import ? 0 : 1;
+ if(can_shell == -1) can_shell = import ? 0 : 1;
+ if(can_refresh == -1) can_refresh = import ? 0 : 1;
}
@@ -392,6 +473,8 @@ void close_nc(void) {
int main(int argc, char **argv) {
read_locale();
+ uic_theme = getenv("NO_COLOR") ? 0 : 2;
+ config_load(argc, argv);
argv_parse(argc, argv);
if(dir_ui == 2)
diff --git a/src/path.c b/src/path.c
index aaea32d..7061e0d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/path.h b/src/path.h
index d07d83c..500c52f 100644
--- a/src/path.h
+++ b/src/path.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/quit.c b/src/quit.c
index bcc82c5..e3186d8 100644
--- a/src/quit.c
+++ b/src/quit.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2015-2022 Yoran Heling
+ Copyright (c) 2015-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/quit.h b/src/quit.h
index e431656..0763cda 100644
--- a/src/quit.h
+++ b/src/quit.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2015-2022 Yoran Heling
+ Copyright (c) 2015-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/src/shell.c b/src/shell.c
index c2cfff0..e762ed1 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Shell support: Copyright (c) 2014 Thomas Jarosch
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/shell.h b/src/shell.h
index 4e0c236..cfafeeb 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Shell support: Copyright (c) 2014 Thomas Jarosch
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/util.c b/src/util.c
index ed20b69..4979c26 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -449,3 +449,9 @@ void addparentstats(struct dir *d, int64_t size, int64_t asize, uint64_t mtime,
void *xmalloc(size_t size) { wrap_oom(malloc(size)) }
void *xcalloc(size_t n, size_t size) { wrap_oom(calloc(n, size)) }
void *xrealloc(void *mem, size_t size) { wrap_oom(realloc(mem, size)) }
+
+char *xstrdup(const char *str) {
+ char *r = xmalloc(strlen(str)+1);
+ strcpy(r, str);
+ return r;
+}
diff --git a/src/util.h b/src/util.h
index 516c5e7..2e4cbcb 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
/* ncdu - NCurses Disk Usage
- Copyright (c) 2007-2022 Yoran Heling
+ Copyright (c) 2007-2023 Yoran Heling
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -188,5 +188,7 @@ void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
void *xrealloc(void *, size_t);
+char *xstrdup(const char *);
+
#endif