mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
148 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca1e31f3c5 | ||
|
|
3c40fdfba6 | ||
|
|
3a97d664b9 | ||
|
|
addb62da92 | ||
|
|
569df689e3 | ||
|
|
df0c0381ab | ||
|
|
f8726e05c4 | ||
|
|
95c01c656e | ||
|
|
8a7f66feb4 | ||
|
|
30a227673e | ||
|
|
dd8db19cc7 | ||
|
|
569e387b8a | ||
|
|
9ca7d6b49e | ||
|
|
d4c7114bce | ||
|
|
ce1069c215 | ||
|
|
a033e28737 | ||
|
|
b7aaa0da8b | ||
|
|
36edf7bad2 | ||
|
|
242689c7f9 | ||
|
|
30c65cd49c | ||
|
|
ca9e212cf8 | ||
|
|
efcee783e4 | ||
|
|
fb59d72f0a | ||
|
|
a037e838e1 | ||
|
|
ade8dd2096 | ||
|
|
0cce690850 | ||
|
|
82124c3c06 | ||
|
|
38f1c2006e | ||
|
|
8a1edc971f | ||
|
|
70253e9179 | ||
|
|
b18b6912e8 | ||
|
|
fbfca3c675 | ||
|
|
7a404d10f5 | ||
|
|
8c92bb3441 | ||
|
|
32f987af12 | ||
|
|
fee8694886 | ||
|
|
3a169f4c5d | ||
|
|
29ec834c3b | ||
|
|
9837344837 | ||
|
|
5d4f09d83a | ||
|
|
c48003a53c | ||
|
|
a2883947bc | ||
|
|
99f59aaaf8 | ||
|
|
6504d7e193 | ||
|
|
2bad8c0dea | ||
|
|
fe6f4e305c | ||
|
|
a77fb35364 | ||
|
|
94eca76776 | ||
|
|
20761ce686 | ||
|
|
df84346ebc | ||
|
|
71bac0dac3 | ||
|
|
d41dbb187f | ||
|
|
cca83fafa6 | ||
|
|
eb1299481a | ||
|
|
255a6a201e | ||
|
|
f6f78f093b | ||
|
|
21b617b78b | ||
|
|
ebbf0a1f0f | ||
|
|
398749b0cc | ||
|
|
e5dba03d2f | ||
|
|
c756343503 | ||
|
|
722287e443 | ||
|
|
9966c92dd4 | ||
|
|
4f73ecaf7d | ||
|
|
880a6e7723 | ||
|
|
bd11475627 | ||
|
|
aa2f797c7d | ||
|
|
ebc7aacf7b | ||
|
|
15223b0c3b | ||
|
|
b64d9b6d9e | ||
|
|
0bbb9d7785 | ||
|
|
f1e1e89e81 | ||
|
|
1c0ec3541c | ||
|
|
f0ff8c73fe | ||
|
|
e8591fd39f | ||
|
|
a863644397 | ||
|
|
f6d1f70183 | ||
|
|
af6436559c | ||
|
|
fd9750b0ff | ||
|
|
a8d26b3ce1 | ||
|
|
a4a864da36 | ||
|
|
9547a78bda | ||
|
|
494fed0271 | ||
|
|
61cc6fbc27 | ||
|
|
f68f5f23c6 | ||
|
|
cdfb703c5d | ||
|
|
15f26e296b | ||
|
|
467cc9bb43 | ||
|
|
d54376db68 | ||
|
|
af054f80b2 | ||
|
|
c392c4b8ef | ||
|
|
471f219ac7 | ||
|
|
a5e224d793 | ||
|
|
526a057602 | ||
|
|
70eadcb4e6 | ||
|
|
305bbd99b2 | ||
|
|
c45b4237bc | ||
|
|
c692280926 | ||
|
|
3346c0afbc | ||
|
|
a23afe7b72 | ||
|
|
82f09f4762 | ||
|
|
370fa0fa42 | ||
|
|
e0e8429c24 | ||
|
|
1422cabf93 | ||
|
|
84b5844d21 | ||
|
|
1a94ac4a05 | ||
|
|
1b2d2635ee | ||
|
|
fa3e9cb9af | ||
|
|
228c8e9eec | ||
|
|
1ce27f74ec | ||
|
|
b2c30136dc | ||
|
|
e3b14643f4 | ||
|
|
e579a697b2 | ||
|
|
68c9b31834 | ||
|
|
856ba44297 | ||
|
|
8f7d8e3bc3 | ||
|
|
0b1dcf33f5 | ||
|
|
a977dbbe78 | ||
|
|
a4e123abd3 | ||
|
|
c1e158489d | ||
|
|
12a104b45e | ||
|
|
e3ccc324d3 | ||
|
|
a10ba58f3c | ||
|
|
56300b1dc2 | ||
|
|
0a859a6cb0 | ||
|
|
450df0f26d | ||
|
|
98ec4beba5 | ||
|
|
6c497c6c2d | ||
|
|
9e59f8c47c | ||
|
|
72f98388c3 | ||
|
|
f296cf4052 | ||
|
|
359fa92f2a | ||
|
|
31fa922e57 | ||
|
|
59a6ddfca3 | ||
|
|
de619c8fa5 | ||
|
|
847359b11d | ||
|
|
d6639ee63b | ||
|
|
be8531206b | ||
|
|
899c1d00fa | ||
|
|
e2808a3999 | ||
|
|
ddfcccce51 | ||
|
|
1130e181ee | ||
|
|
5e778f7c8d | ||
|
|
2bc0f3caaa | ||
|
|
831acb987e | ||
|
|
1d651b954f | ||
|
|
99e607b910 | ||
|
|
04a31ad99d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
*.1
|
||||
*.I[12]
|
||||
*.[EIOX]
|
||||
*.o
|
||||
@@ -57,6 +56,7 @@ lib/uniwidth
|
||||
m4/.cvsignore
|
||||
m4/.gitignore
|
||||
maint.mk
|
||||
man/*.1
|
||||
po/*.gmo
|
||||
po/*.po
|
||||
po/.gitignore
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "gnulib"]
|
||||
path = gnulib
|
||||
url = git://git.sv.gnu.org/gnulib.git
|
||||
path = gnulib
|
||||
url = git://git.sv.gnu.org/gnulib.git
|
||||
|
||||
@@ -1 +1 @@
|
||||
7.4
|
||||
7.6
|
||||
|
||||
6
.x-sc_prohibit_tab_based_indentation
Normal file
6
.x-sc_prohibit_tab_based_indentation
Normal file
@@ -0,0 +1,6 @@
|
||||
^GNUMakefile$
|
||||
Makefile\.am$
|
||||
\.mk$
|
||||
^tests/pr/
|
||||
ChangeLog.*
|
||||
^man/help2man$
|
||||
33
HACKING
33
HACKING
@@ -233,21 +233,26 @@ Try to make the summary line fit one of the following forms:
|
||||
maint: change-description
|
||||
|
||||
|
||||
Use SPACE-only indentation in new files.
|
||||
========================================
|
||||
In any new file, eliminate all leading TABs (e.g., via running GNU indent
|
||||
with --no-tabs) and put these lines at the end of the file:
|
||||
Use SPACE-only indentation in all[*] files
|
||||
==========================================
|
||||
We use space-only indentation in nearly all files.
|
||||
If you use Emacs and your coreutils working directory name matches,
|
||||
this code enables the right mode:
|
||||
|
||||
;; In coreutils, indent with spaces everywhere (not TABs).
|
||||
;; Exceptions: Makefile and ChangeLog modes.
|
||||
(add-hook 'find-file-hook '(lambda ()
|
||||
(if (and buffer-file-name
|
||||
(string-match "/coreutils\\>" (buffer-file-name))
|
||||
(not (string-equal mode-name "Change Log"))
|
||||
(not (string-equal mode-name "Makefile")))
|
||||
(setq indent-tabs-mode nil))))
|
||||
|
||||
[*] Makefile and ChangeLog files are exempt, of course.
|
||||
|
||||
[FIXME: suggest vim syntax to do same thing, if it can be done safely.
|
||||
Most distros now "set nomodeline" by default for a good reason. ]
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
Do not change TABs to spaces or vice versa in any existing file.
|
||||
|
||||
|
||||
Send patches to the address listed in --help output
|
||||
===================================================
|
||||
@@ -437,8 +442,8 @@ Miscellaneous useful git commands
|
||||
its SHA1 and then tag it or cherry-pick it onto an existing branch.
|
||||
For example, run this:
|
||||
git fsck --lost-found HEAD && cd .git/lost-found/commit \
|
||||
&& for i in *; do git show $i|grep SOME_IDENTIFYING_STRING \
|
||||
&& echo $i; done
|
||||
&& for i in *; do git show $i|grep SOME_IDENTIFYING_STRING \
|
||||
&& echo $i; done
|
||||
The "git fsck ..." command creates the .git/lost-found/... hierarchy
|
||||
listing all unreachable objects. Then the for loop
|
||||
print SHA1s for commits that match via log or patch.
|
||||
|
||||
14
Makefile.am
14
Makefile.am
@@ -49,6 +49,7 @@ syntax_check_exceptions = \
|
||||
.x-sc_prohibit_atoi_atof \
|
||||
.x-sc_prohibit_stat_st_blocks \
|
||||
.x-sc_prohibit_strcmp \
|
||||
.x-sc_prohibit_tab_based_indentation \
|
||||
.x-sc_require_config_h \
|
||||
.x-sc_require_config_h_first \
|
||||
.x-sc_space_tab \
|
||||
@@ -97,20 +98,20 @@ rm_subst = \
|
||||
|
||||
BUILT_SOURCES = .version
|
||||
.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
$(AM_V_GEN)echo $(VERSION) > $@-t && mv $@-t $@
|
||||
|
||||
# Arrange so that .tarball-version appears only in the distribution
|
||||
# tarball, and never in a checked-out repository.
|
||||
# The perl substitution is to change some key uses of "rm" to "/bin/rm".
|
||||
# See the rm_subst comment for details.
|
||||
dist-hook: gen-ChangeLog
|
||||
echo $(VERSION) > $(distdir)/.tarball-version
|
||||
perl -pi -e '$(rm_subst)' $(distdir)/src/Makefile.in
|
||||
$(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version
|
||||
$(AM_V_at)perl -pi -e '$(rm_subst)' $(distdir)/src/Makefile.in
|
||||
|
||||
gen_start_date = 2008-02-08
|
||||
.PHONY: gen-ChangeLog
|
||||
gen-ChangeLog:
|
||||
if test -d .git; then \
|
||||
$(AM_V_GEN)if test -d .git; then \
|
||||
$(top_srcdir)/build-aux/gitlog-to-changelog \
|
||||
--since=$(gen_start_date) > $(distdir)/cl-t; \
|
||||
rm -f $(distdir)/ChangeLog; \
|
||||
@@ -120,11 +121,12 @@ gen-ChangeLog:
|
||||
ALL_RECURSIVE_TARGETS += distcheck-hook
|
||||
distcheck-hook: check-ls-dircolors
|
||||
$(MAKE) my-distcheck
|
||||
$(MAKE) taint-distcheck
|
||||
|
||||
DISTCLEANFILES = VERSION
|
||||
MAINTAINERCLEANFILES = THANKS-to-translators
|
||||
THANKS-to-translators: po/LINGUAS THANKStt.in
|
||||
( \
|
||||
$(AM_V_GEN)( \
|
||||
cat $(srcdir)/THANKStt.in; \
|
||||
for lang in `cat $(srcdir)/po/LINGUAS`; do \
|
||||
echo http://translationproject.org/team/$$lang.html; \
|
||||
@@ -135,7 +137,7 @@ THANKS-to-translators: po/LINGUAS THANKStt.in
|
||||
# remain in sync.
|
||||
.PHONY: check-ls-dircolors
|
||||
check-ls-dircolors:
|
||||
dc=$$(sed -n '/static.*ls_codes\[/,/};'/p \
|
||||
$(AM_V_GEN)dc=$$(sed -n '/static.*ls_codes\[/,/};'/p \
|
||||
$(srcdir)/src/dircolors.c \
|
||||
|sed -n '/^ *"/p'|tr , '\n'|sed 's/^ *//' \
|
||||
|sed -n 's/^"\(..\)"/\1/p'|sort -u); \
|
||||
|
||||
141
NEWS
141
NEWS
@@ -1,5 +1,146 @@
|
||||
GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
* Noteworthy changes in release 8.0 (2009-10-06) [beta]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
cp --preserve=xattr and --archive now preserve extended attributes even
|
||||
when the source file doesn't have write access.
|
||||
[bug introduced in coreutils-7.1]
|
||||
|
||||
touch -t [[CC]YY]MMDDhhmm[.ss] now accepts a timestamp string ending in .60,
|
||||
to accommodate leap seconds.
|
||||
[the bug dates back to the initial implementation]
|
||||
|
||||
ls --color now reverts to the color of a base file type consistently
|
||||
when the color of a more specific type is disabled.
|
||||
[bug introduced in coreutils-5.90]
|
||||
|
||||
ls -LR exits with status 2, not 0, when it encounters a cycle
|
||||
|
||||
ls -is is now consistent with ls -lis in ignoring values returned
|
||||
from a failed stat/lstat. For example ls -Lis now prints "?", not "0",
|
||||
for the inode number and allocated size of a dereferenced dangling symlink.
|
||||
|
||||
tail --follow --pid now avoids a race condition where data written
|
||||
just before the process dies might not have been output by tail.
|
||||
Also, tail no longer delays at all when the specified pid is not live.
|
||||
[The race was introduced in coreutils-7.5,
|
||||
and the unnecessary delay was present since textutils-1.22o]
|
||||
|
||||
** Portability
|
||||
|
||||
On Solaris 9, many commands would mistakenly treat file/ the same as
|
||||
file. Now, even on such a system, path resolution obeys the POSIX
|
||||
rules that a trailing slash ensures that the preceeding name is a
|
||||
directory or a symlink to a directory.
|
||||
|
||||
** Changes in behavior
|
||||
|
||||
id no longer prints SELinux " context=..." when the POSIXLY_CORRECT
|
||||
environment variable is set.
|
||||
|
||||
readlink -f now ignores a trailing slash when deciding if the
|
||||
last component (possibly via a dangling symlink) can be created,
|
||||
since mkdir will succeed in that case.
|
||||
|
||||
** New features
|
||||
|
||||
ln now accepts the options --logical (-L) and --physical (-P),
|
||||
added by POSIX 2008. The default behavior is -P on systems like
|
||||
GNU/Linux where link(2) creates hard links to symlinks, and -L on
|
||||
BSD systems where link(2) follows symlinks.
|
||||
|
||||
stat: without -f, a command-line argument of "-" now means standard input.
|
||||
With --file-system (-f), an argument of "-" is now rejected.
|
||||
If you really must operate on a file named "-", specify it as
|
||||
"./-" or use "--" to separate options from arguments.
|
||||
|
||||
** Improvements
|
||||
|
||||
rm: rewrite to use gnulib's fts
|
||||
This makes rm -rf significantly faster (400-500%) in some pathological
|
||||
cases, and slightly slower (20%) in at least one pathological case.
|
||||
|
||||
rm -r deletes deep hierarchies more efficiently. Before, execution time
|
||||
was quadratic in the depth of the hierarchy, now it is merely linear.
|
||||
However, this improvement is not as pronounced as might be expected for
|
||||
very deep trees, because prior to this change, for any relative name
|
||||
length longer than 8KiB, rm -r would sacrifice official conformance to
|
||||
avoid the disproportionate quadratic performance penalty. Leading to
|
||||
another improvement:
|
||||
|
||||
rm -r is now slightly more standards-conformant when operating on
|
||||
write-protected files with relative names longer than 8KiB.
|
||||
|
||||
|
||||
* Noteworthy changes in release 7.6 (2009-09-11) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
cp, mv now ignore failure to preserve a symlink time stamp, when it is
|
||||
due to their running on a kernel older than what was implied by headers
|
||||
and libraries tested at configure time.
|
||||
[bug introduced in coreutils-7.5]
|
||||
|
||||
cp --reflink --preserve now preserves attributes when cloning a file.
|
||||
[bug introduced in coreutils-7.5]
|
||||
|
||||
cp --preserve=xattr no longer leaks resources on each preservation failure.
|
||||
[bug introduced in coreutils-7.1]
|
||||
|
||||
dd now exits with non-zero status when it encounters a write error while
|
||||
printing a summary to stderr.
|
||||
[bug introduced in coreutils-6.11]
|
||||
|
||||
dd cbs=N conv=unblock would fail to print a final newline when the size
|
||||
of the input was not a multiple of N bytes.
|
||||
[the non-conforming behavior dates back to the initial implementation]
|
||||
|
||||
df no longer requires that each command-line argument be readable
|
||||
[bug introduced in coreutils-7.3]
|
||||
|
||||
ls -i now prints consistent inode numbers also for mount points.
|
||||
This makes ls -i DIR less efficient on systems with dysfunctional readdir,
|
||||
because ls must stat every file in order to obtain a guaranteed-valid
|
||||
inode number. [bug introduced in coreutils-6.0]
|
||||
|
||||
tail -f (inotify-enabled) now flushes any initial output before blocking.
|
||||
Before, this would print nothing and wait: stdbuf -o 4K tail -f /etc/passwd
|
||||
Note that this bug affects tail -f only when its standard output is buffered,
|
||||
which is relatively unusual.
|
||||
[bug introduced in coreutils-7.5]
|
||||
|
||||
tail -f once again works with standard input. inotify-enabled tail -f
|
||||
would fail when operating on a nameless stdin. I.e., tail -f < /etc/passwd
|
||||
would say "tail: cannot watch `-': No such file or directory", yet the
|
||||
relatively baroque tail -f /dev/stdin < /etc/passwd would work. Now, the
|
||||
offending usage causes tail to revert to its conventional sleep-based
|
||||
(i.e., not inotify-based) implementation.
|
||||
[bug introduced in coreutils-7.5]
|
||||
|
||||
** Portability
|
||||
|
||||
ln, link: link f z/ would mistakenly succeed on Solaris 10, given an
|
||||
existing file, f, and nothing named "z". ln -T f z/ has the same problem.
|
||||
Each would mistakenly create "z" as a link to "f". Now, even on such a
|
||||
system, each command reports the error, e.g.,
|
||||
link: cannot create link `z/' to `f': Not a directory
|
||||
|
||||
** New features
|
||||
|
||||
cp --reflink accepts a new "auto" parameter which falls back to
|
||||
a standard copy if creating a copy-on-write clone is not possible.
|
||||
|
||||
** Changes in behavior
|
||||
|
||||
tail -f now ignores "-" when stdin is a pipe or FIFO.
|
||||
tail-with-no-args now ignores -f unconditionally when stdin is a pipe or FIFO.
|
||||
Before, it would ignore -f only when no file argument was specified,
|
||||
and then only when POSIXLY_CORRECT was set. Now, :|tail -f - terminates
|
||||
immediately. Before, it would block indefinitely.
|
||||
|
||||
|
||||
* Noteworthy changes in release 7.5 (2009-08-20) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
@@ -64,7 +64,3 @@ GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Local Variables:
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
@@ -14,8 +14,7 @@ Here are most of the steps we (maintainers) follow when making a release.
|
||||
|
||||
* Make sure your local gnulib directory is up to date.
|
||||
|
||||
* Run bootstrap, (assuming your local copy of gnulib is in /gnulib):
|
||||
./bootstrap --gnulib-srcdir=/gnulib
|
||||
* Run bootstrap: ./bootstrap
|
||||
|
||||
FIXME: enable excluded programs like arch? to get their manual pages?
|
||||
|
||||
@@ -82,17 +81,8 @@ Once all the builds and tests have passed,
|
||||
Then go here to approve it:
|
||||
https://savannah.gnu.org/news/approve.php?group=coreutils
|
||||
|
||||
* For non-alpha releases, update the on-line manual at
|
||||
* After each non-alpha release, update the on-line manual accessible via
|
||||
|
||||
http://www.gnu.org/software/coreutils/manual/
|
||||
|
||||
Run `make web-manual', then copy the contents of doc/manual
|
||||
into a CVS checkout of the coreutils manual repository.
|
||||
Also edit coreutils.html (FIXME? why?) before doing a CVS commit.
|
||||
|
||||
CVS_RSH=ssh \
|
||||
cvs -d:ext:$USER@cvs.savannah.gnu.org:/web/coreutils co coreutils
|
||||
|
||||
Be sure to "cvs add -ko" any files that "cvs status" marks with "?".
|
||||
That is necessary whenever a new texinfo node is added. Each becomes
|
||||
a new file in html_node that must then be "cvs add"ed.
|
||||
by running the gnu-web-doc-update script.
|
||||
|
||||
13
THANKS
13
THANKS
@@ -66,8 +66,9 @@ Barry Kelly http://barrkel.blogspot.com/
|
||||
Bauke Jan Douma bjdouma@xs4all.nl
|
||||
Ben Elliston bje@air.net.au
|
||||
Ben Harris bjh21@netbsd.org
|
||||
Benjamin Cutler cutlerbc@simla.colostate.edu
|
||||
Bengt Martensson bengt@mathematik.uni-Bremen.de
|
||||
Benjamin Cutler cutlerbc@simla.colostate.edu
|
||||
Benno Schulenberg bensberg@justemail.net
|
||||
Bernard Giroud bernard.giroud@creditlyonnais.ch
|
||||
Bernd Eckenfels ecki@debian.org
|
||||
Bernd Leibing bernd.leibing@rz.uni-ulm.de
|
||||
@@ -78,6 +79,7 @@ Bernhard Rosenkraenzer bero@redhat.de
|
||||
Bernhard Voelker bernhard.voelker@siemens-enterprise.com
|
||||
Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
|
||||
Bert Wesarg bert.wesarg@googlemail.com
|
||||
Bill Brelsford wb@k2di.net
|
||||
Bill Peters peters@gaffel.as.arizona.edu
|
||||
Bjorn Helgaas helgaas@rsn.hp.com
|
||||
Bob McCracken kerouac@ravenet.com
|
||||
@@ -185,6 +187,7 @@ Felix Rauch Valenti frauch@cse.unsw.edu.au
|
||||
Ferdinand fw@scenic.mine.nu
|
||||
Fletcher Mattox fletcher@cs.utexas.edu
|
||||
Florent Bayle florent@sarcelle.net
|
||||
Florian Schlichting fschlich@cis.fu-berlin.de
|
||||
Florin Iucha fiucha@hsys.mic.ro
|
||||
Francesco Montorsi fr_m@hotmail.com
|
||||
François Pinard pinard@iro.umontreal.ca
|
||||
@@ -249,6 +252,7 @@ James Antill jmanti%essex.ac.uk@seralph21.essex.ac.uk
|
||||
James Lemley James.Lemley@acxiom.com
|
||||
James Hunt jamesodhunt@hotmail.com
|
||||
James Ralston ralston@pobox.com
|
||||
James R. Van Zandt jrvz@comcast.net
|
||||
James Sneeringer jvs@ocslink.com
|
||||
James Tanis jtt@soscorp.com
|
||||
James Youngman jay@gnu.org
|
||||
@@ -332,6 +336,7 @@ Leah Q eequor@earthlink.net
|
||||
Lehti Rami rammer@cs.tut.fi
|
||||
Leonard N. Zubkoff lnz@dandelion.com
|
||||
Leonardo Milano lmilano@udel.edu
|
||||
Lluís Batlle viriketo@gmail.com
|
||||
Lorne Baker lbaker@nitro.avint.net
|
||||
Luke Hassell lukehassell@yahoo.com
|
||||
Luke Kendall lukekendall@optushome.com.au
|
||||
@@ -370,6 +375,7 @@ Marty Leisner leisner@sdsp.mc.xerox.com
|
||||
Masami Takikawa takikawm@CS.ORST.EDU
|
||||
Mate Wierdl mw@moni.msci.memphis.edu
|
||||
Matej Vela mvela@public.srce.hr
|
||||
Matias A. Fonzo selk@dragora.org
|
||||
Matt Kraai kraai@ftbfs.org
|
||||
Matt Perry matt@primefactor.com
|
||||
Matt Pham mattvpham@gmail.com
|
||||
@@ -385,6 +391,7 @@ Matthew Swift swift@alum.mit.edu
|
||||
Matthew Woehlke mw_triad@users.sourceforge.net
|
||||
Matthias Urlichs smurf@noris.de
|
||||
Matti Aarnio matti.aarnio@zmailer.org
|
||||
Mathias Brodala info@noctus.net
|
||||
Mattias Wadenstein maswan@acc.umu.se
|
||||
Max Chang maxchang@ucla.edu
|
||||
Meelis Roos mroos@tartu.cyber.ee
|
||||
@@ -439,6 +446,7 @@ Olatunji Oluwabukunmi Ruwase tjruwase@stanford.edu
|
||||
Olav Morkrid olav@funcom.com
|
||||
Ole Laursen olau@hardworking.dk
|
||||
Oliver Kiddle okiddle@yahoo.co.uk
|
||||
Olivier Fourdan ofourdan@redhat.com
|
||||
Ørn E. Hansen oehansen@daimi.aau.dk
|
||||
Oskar Liljeblad osk@hem.passagen.se
|
||||
Otavio Salvador otavio@ossystems.com.br
|
||||
@@ -486,6 +494,7 @@ Ralph Loader loader@maths.ox.ac.uk
|
||||
Raul Miller moth@magenta.com
|
||||
Raúl Núñez de Arenas Coronado raul@pleyades.net
|
||||
Reuben Thomas rrt@sc3d.org
|
||||
Yang Ren ryang@redhat.com
|
||||
Richard A Downing richard.downing@bcs.org.uk
|
||||
Richard Braakman dark@xs4all.nl
|
||||
Richard Dawe rich@phekda.freeserve.co.uk
|
||||
@@ -560,6 +569,7 @@ Tim Waugh twaugh@redhat
|
||||
Tobias Stoeckmann tobias@bugol.de
|
||||
Toby Peterson toby@opendarwin.org
|
||||
Todd A. Jacobs tjacobs@codegnome.org
|
||||
Tom Fitzhenry tom@tom-fitzhenry.me.uk
|
||||
Tom Haynes thomas@netapp.com
|
||||
Tom Quinn trq@dionysos.thphys.ox.ac.uk
|
||||
Tomas Pospisek tpo@sourcepole.ch
|
||||
@@ -602,6 +612,7 @@ Wis Macomson wis.macomson@intel.com
|
||||
Wojciech Purczynski cliph@isec.pl
|
||||
Wolfram Kleff kleff@cs.uni-bonn.de
|
||||
Won-kyu Park wkpark@chem.skku.ac.kr
|
||||
Yanko Kaneti yaneti@declera.com
|
||||
Yann Dirson dirson@debian.org
|
||||
Zvi Har'El rl@math.technion.ac.il
|
||||
|
||||
|
||||
64
bootstrap
64
bootstrap
@@ -34,7 +34,7 @@ bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
|
||||
bt2=${bt}2
|
||||
|
||||
usage() {
|
||||
echo >&2 "\
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTION]...
|
||||
Bootstrap this package from the checked-out sources.
|
||||
|
||||
@@ -56,7 +56,7 @@ For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
|
||||
are honored.
|
||||
|
||||
Running without arguments will suffice in most cases.
|
||||
"
|
||||
EOF
|
||||
}
|
||||
|
||||
# Configuration.
|
||||
@@ -70,6 +70,9 @@ gnulib_modules=
|
||||
# Any gnulib files needed that are not in modules.
|
||||
gnulib_files=
|
||||
|
||||
# A function to be called after everything else in this script.
|
||||
bootstrap_epilogue() { :; }
|
||||
|
||||
# The command to download all .po files for a specified domain into
|
||||
# a specified directory. Fill in the first %s is the domain name, and
|
||||
# the second with the destination directory. Use rsync's -L and -r
|
||||
@@ -148,6 +151,45 @@ copy=false
|
||||
# on which version control system (if any) is used in the source directory.
|
||||
vc_ignore=auto
|
||||
|
||||
# find_tool ENVVAR NAMES...
|
||||
# -------------------------
|
||||
# Search for a required program. Use the value of ENVVAR, if set,
|
||||
# otherwise find the first of the NAMES that can be run (i.e.,
|
||||
# supports --version). If found, set ENVVAR to the program name,
|
||||
# die otherwise.
|
||||
find_tool ()
|
||||
{
|
||||
# Find sha1sum, named gsha1sum on MacPorts.
|
||||
find_tool_envvar=$1
|
||||
shift
|
||||
find_tool_names=$@
|
||||
eval "find_tool_res=\$$find_tool_envvar"
|
||||
if test x"$find_tool_res" = x; then
|
||||
for i
|
||||
do
|
||||
if ($i --version </dev/null) >/dev/null 2>&1; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
find_tool_error_prefix="\$$find_tool_envvar: "
|
||||
fi
|
||||
if test x"$find_tool_res" = x; then
|
||||
echo >&2 "$0: one of these is required: $find_tool_names"
|
||||
exit 1
|
||||
fi
|
||||
($find_tool_res --version </dev/null) >/dev/null 2>&1 || {
|
||||
echo >&2 "$0: ${find_tool_error_prefix}cannot run $find_tool_res --version"
|
||||
exit 1
|
||||
}
|
||||
eval "$find_tool_envvar=\$find_tool_res"
|
||||
eval "export $find_tool_envvar"
|
||||
}
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts.
|
||||
find_tool SHA1SUM sha1sum gsha1sum
|
||||
|
||||
# Override the default configuration, if necessary.
|
||||
# Make sure that bootstrap.conf is sourced from the current directory
|
||||
# if we were invoked as "sh bootstrap".
|
||||
@@ -420,11 +462,11 @@ update_po_files() {
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! ${SHA1SUM-sha1sum} -c --status "$cksum_file" \
|
||||
! $SHA1SUM -c --status "$cksum_file" \
|
||||
< "$new_po" > /dev/null; then
|
||||
echo "updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& ${SHA1SUM-sha1sum} < "$new_po" > "$cksum_file"
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -690,6 +732,10 @@ find "$m4_base" "$source_base" \
|
||||
|
||||
# Reconfigure, getting other files.
|
||||
|
||||
# Skip autoheader if it's not needed.
|
||||
grep '^[ ]*AC_CONFIG_HEADERS\>' configure.ac >/dev/null ||
|
||||
AUTOHEADER=true
|
||||
|
||||
for command in \
|
||||
libtool \
|
||||
"${ACLOCAL-aclocal} --force -I m4" \
|
||||
@@ -758,14 +804,6 @@ if test $with_gettext = yes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Horrible, coreutils-specific kludges.
|
||||
# Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
|
||||
m=gnulib-tests/gnulib.mk
|
||||
sed 's,\.\./\.\.,..,g' $m > $m-t
|
||||
mv -f $m-t $m
|
||||
bootstrap_epilogue
|
||||
|
||||
echo "$0: done. Now you can run './configure'."
|
||||
|
||||
# Local Variables:
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
avoided_gnulib_modules='
|
||||
--avoid=canonicalize-lgpl
|
||||
--avoid=dummy
|
||||
--avoid=lock
|
||||
'
|
||||
|
||||
# These modules are obsolete and can probably be removed soon,
|
||||
@@ -31,7 +30,6 @@ obsolete_gnulib_modules='
|
||||
memcpy
|
||||
memmove
|
||||
memset
|
||||
rename
|
||||
strcspn
|
||||
strtod
|
||||
strtol
|
||||
@@ -78,6 +76,7 @@ gnulib_modules="
|
||||
euidaccess
|
||||
exclude
|
||||
exitfail
|
||||
faccessat
|
||||
fchdir
|
||||
fcntl
|
||||
fcntl-safer
|
||||
@@ -90,12 +89,13 @@ gnulib_modules="
|
||||
fnmatch-gnu
|
||||
fopen-safer
|
||||
fprintftime
|
||||
freopen
|
||||
fseeko
|
||||
fsusage
|
||||
fsync
|
||||
ftello
|
||||
ftruncate
|
||||
fts
|
||||
gendocs
|
||||
getdate
|
||||
getgroups
|
||||
gethrxtime
|
||||
@@ -113,6 +113,7 @@ gnulib_modules="
|
||||
git-version-gen
|
||||
gitlog-to-changelog
|
||||
gnu-make
|
||||
gnu-web-doc-update
|
||||
gnumakefile
|
||||
gnupload
|
||||
group-member
|
||||
@@ -130,7 +131,9 @@ gnulib_modules="
|
||||
lchown
|
||||
lib-ignore
|
||||
linebuffer
|
||||
link
|
||||
link-follow
|
||||
linkat
|
||||
long-options
|
||||
lstat
|
||||
maintainer-makefile
|
||||
@@ -175,9 +178,9 @@ gnulib_modules="
|
||||
readutmp
|
||||
realloc
|
||||
regex
|
||||
rename
|
||||
rename-dest-slash
|
||||
rmdir
|
||||
rmdir-errno
|
||||
root-dev-ino
|
||||
rpmatch
|
||||
safe-read
|
||||
@@ -196,19 +199,20 @@ gnulib_modules="
|
||||
stdlib-safer
|
||||
stpcpy
|
||||
stpncpy
|
||||
strdup
|
||||
strdup-posix
|
||||
strftime
|
||||
strpbrk
|
||||
strsignal
|
||||
strtoimax
|
||||
strtoumax
|
||||
strverscmp
|
||||
symlink
|
||||
sys_stat
|
||||
timespec
|
||||
tzset
|
||||
unicodeio
|
||||
unistd-safer
|
||||
unlink-busy
|
||||
unlinkdir
|
||||
unlocked-io
|
||||
update-copyright
|
||||
uptime
|
||||
@@ -290,7 +294,6 @@ if test $gettext_external = 1; then
|
||||
m4/glibc2.m4
|
||||
m4/intdiv0.m4
|
||||
m4/lcmessage.m4
|
||||
m4/lock.m4
|
||||
m4/uintmax_t.m4
|
||||
m4/ulonglong.m4
|
||||
m4/visibility.m4
|
||||
@@ -316,4 +319,12 @@ tar -
|
||||
"
|
||||
|
||||
# Automake requires that ChangeLog exist.
|
||||
touch ChangeLog
|
||||
touch ChangeLog || exit 1
|
||||
|
||||
bootstrap_epilogue()
|
||||
{
|
||||
# Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
|
||||
m=gnulib-tests/gnulib.mk
|
||||
sed 's,\.\./\.\.,..,g' $m > $m-t
|
||||
mv -f $m-t $m
|
||||
}
|
||||
|
||||
442
build-aux/cvsu
442
build-aux/cvsu
@@ -27,20 +27,20 @@ use Time::Local;
|
||||
use strict;
|
||||
|
||||
use vars qw($list_types %messages %options @batch_list $batch_cmd
|
||||
$no_recurse $explain_type $find_mode $short_print
|
||||
$no_cvsignore $nolinks $file $single_filename $curr_dir
|
||||
@common_ignores $ignore_rx %entries %subdirs %removed);
|
||||
$no_recurse $explain_type $find_mode $short_print
|
||||
$no_cvsignore $nolinks $file $single_filename $curr_dir
|
||||
@common_ignores $ignore_rx %entries %subdirs %removed);
|
||||
|
||||
use constant SUBDIR_FOUND => 1;
|
||||
use constant SUBDIR_CVS => 2;
|
||||
|
||||
# This list comes from the CVS manual.
|
||||
use constant STANDARD_IGNORES =>
|
||||
('RCS', 'SCCS', 'CVS', 'CVS.adm', 'RCSLOG', 'cvslog.*', 'tags',
|
||||
'TAGS', '.make.state', '.nse_depinfo', '*~', '#*', '.#*', ',*',
|
||||
"_\$*", "*\$", '*.old', '*.bak', '*.BAK', '*.orig', '*.rej',
|
||||
'.del-*', '*.a', '*.olb', '*.o', '*.obj', '*.so', '*.exe',
|
||||
'*.Z', '*.elc', '*.ln', 'core');
|
||||
('RCS', 'SCCS', 'CVS', 'CVS.adm', 'RCSLOG', 'cvslog.*', 'tags',
|
||||
'TAGS', '.make.state', '.nse_depinfo', '*~', '#*', '.#*', ',*',
|
||||
"_\$*", "*\$", '*.old', '*.bak', '*.BAK', '*.orig', '*.rej',
|
||||
'.del-*', '*.a', '*.olb', '*.o', '*.obj', '*.so', '*.exe',
|
||||
'*.Z', '*.elc', '*.ln', 'core');
|
||||
|
||||
# 3-letter month names in POSIX locale, for fast date decoding
|
||||
my %months = (
|
||||
@@ -62,20 +62,20 @@ my %months = (
|
||||
sub usage ()
|
||||
{
|
||||
print "Usage:\n" .
|
||||
" cvsu [OPTIONS] [FILE] ...\n" .
|
||||
"Options:\n" .
|
||||
" --local Disable recursion\n" .
|
||||
" --explain Verbosely print status of files\n" .
|
||||
" --find Emulate find - filenames only\n" .
|
||||
" --short Don't print paths\n" .
|
||||
" --ignore Don't read .cvsignore\n" .
|
||||
" --messages List known file types and long messages\n" .
|
||||
" --nolinks Disable recognizing hard and soft links\n" .
|
||||
" --types=[^]LIST Print only file types [not] from LIST\n" .
|
||||
" --batch=COMMAND Execute this command on files\n" .
|
||||
" --help Print this usage information\n" .
|
||||
" --version Print version number\n" .
|
||||
"Abbreviations and short options are supported\n";
|
||||
" cvsu [OPTIONS] [FILE] ...\n" .
|
||||
"Options:\n" .
|
||||
" --local Disable recursion\n" .
|
||||
" --explain Verbosely print status of files\n" .
|
||||
" --find Emulate find - filenames only\n" .
|
||||
" --short Don't print paths\n" .
|
||||
" --ignore Don't read .cvsignore\n" .
|
||||
" --messages List known file types and long messages\n" .
|
||||
" --nolinks Disable recognizing hard and soft links\n" .
|
||||
" --types=[^]LIST Print only file types [not] from LIST\n" .
|
||||
" --batch=COMMAND Execute this command on files\n" .
|
||||
" --help Print this usage information\n" .
|
||||
" --version Print version number\n" .
|
||||
"Abbreviations and short options are supported\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
@@ -90,11 +90,11 @@ sub version ()
|
||||
sub adjust_types ()
|
||||
{
|
||||
if ($list_types =~ m{^\^(.*)$}) {
|
||||
$list_types = "";
|
||||
foreach (keys %messages) {
|
||||
$list_types .= $_
|
||||
if (index ($1, $_) < 0);
|
||||
}
|
||||
$list_types = "";
|
||||
foreach (keys %messages) {
|
||||
$list_types .= $_
|
||||
if (index ($1, $_) < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +104,12 @@ sub list_messages ()
|
||||
my $default_mark;
|
||||
print "Recognizable file types are:\n";
|
||||
foreach (sort keys %messages) {
|
||||
if (index($list_types, $_) >= 0) {
|
||||
$default_mark = "*";
|
||||
} else {
|
||||
$default_mark = " ";
|
||||
}
|
||||
print " $default_mark $_ $messages{$_}\n";
|
||||
if (index($list_types, $_) >= 0) {
|
||||
$default_mark = "*";
|
||||
} else {
|
||||
$default_mark = " ";
|
||||
}
|
||||
print " $default_mark $_ $messages{$_}\n";
|
||||
}
|
||||
print "* indicates file types listed by default\n";
|
||||
exit 0;
|
||||
@@ -124,28 +124,28 @@ sub init_ignores ()
|
||||
push @common_ignores, STANDARD_IGNORES;
|
||||
|
||||
unless (defined($HOME)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
my $home_cvsignore = "${HOME}/.cvsignore";
|
||||
|
||||
if (-f "$home_cvsignore") {
|
||||
|
||||
unless (open (CVSIGNORE, "< $home_cvsignore")) {
|
||||
error ("couldn't open $home_cvsignore: $!");
|
||||
}
|
||||
unless (open (CVSIGNORE, "< $home_cvsignore")) {
|
||||
error ("couldn't open $home_cvsignore: $!");
|
||||
}
|
||||
|
||||
while (<CVSIGNORE>) {
|
||||
push (@common_ignores, split);
|
||||
}
|
||||
while (<CVSIGNORE>) {
|
||||
push (@common_ignores, split);
|
||||
}
|
||||
|
||||
close (CVSIGNORE);
|
||||
close (CVSIGNORE);
|
||||
}
|
||||
|
||||
my $CVSIGNOREENV = $ENV{"CVSIGNORE"};
|
||||
|
||||
unless (defined($CVSIGNOREENV)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
my @ignores_var = split (/ /, $CVSIGNOREENV);
|
||||
@@ -157,15 +157,15 @@ sub init_ignores ()
|
||||
# Newline is added at the end.
|
||||
sub error ($)
|
||||
{
|
||||
print STDERR "cvsu: ERROR: " . shift(@_) . "\n";
|
||||
exit 1;
|
||||
print STDERR "cvsu: ERROR: " . shift(@_) . "\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# execute commands from @exec_list with $exec_cmd
|
||||
sub do_batch ()
|
||||
{
|
||||
my @cmd_list = split (' ', $batch_cmd);
|
||||
system (@cmd_list, @batch_list);
|
||||
my @cmd_list = split (' ', $batch_cmd);
|
||||
system (@cmd_list, @batch_list);
|
||||
}
|
||||
|
||||
# print files status
|
||||
@@ -177,34 +177,34 @@ sub file_status ($)
|
||||
my $pathfile;
|
||||
|
||||
return
|
||||
if $ignore_rx ne '' && $type =~ /[?SLD]/ && $file =~ /$ignore_rx/;
|
||||
if $ignore_rx ne '' && $type =~ /[?SLD]/ && $file =~ /$ignore_rx/;
|
||||
|
||||
return
|
||||
if (index($list_types, $type) < 0);
|
||||
if (index($list_types, $type) < 0);
|
||||
|
||||
$pathfile = $curr_dir . $file;
|
||||
|
||||
if (defined($batch_cmd)) {
|
||||
push (@batch_list, $pathfile);
|
||||
# 1000 items in the command line might be too much for HP-UX
|
||||
if ($#batch_list > 1000) {
|
||||
do_batch();
|
||||
undef @batch_list;
|
||||
}
|
||||
push (@batch_list, $pathfile);
|
||||
# 1000 items in the command line might be too much for HP-UX
|
||||
if ($#batch_list > 1000) {
|
||||
do_batch();
|
||||
undef @batch_list;
|
||||
}
|
||||
}
|
||||
|
||||
if ($short_print) {
|
||||
$item = $file;
|
||||
$item = $file;
|
||||
} else {
|
||||
$item = $pathfile;
|
||||
$item = $pathfile;
|
||||
}
|
||||
|
||||
if ($find_mode) {
|
||||
print "$item\n";
|
||||
print "$item\n";
|
||||
} else {
|
||||
$type = $messages{$type}
|
||||
if ($explain_type);
|
||||
print "$type $item\n";
|
||||
$type = $messages{$type}
|
||||
if ($explain_type);
|
||||
print "$type $item\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,28 +219,28 @@ sub load_entries ($)
|
||||
my %ent = ();
|
||||
|
||||
unless (open (ENTRIES, "< $entries_file")) {
|
||||
error ("couldn't open $entries_file: $!");
|
||||
error ("couldn't open $entries_file: $!");
|
||||
}
|
||||
while (<ENTRIES>) {
|
||||
chomp;
|
||||
$ent{$_} = 1;
|
||||
chomp;
|
||||
$ent{$_} = 1;
|
||||
}
|
||||
close (ENTRIES);
|
||||
|
||||
if (open (ENTRIES, "< $entries_log_file")) {
|
||||
while (<ENTRIES>) {
|
||||
chomp;
|
||||
if ( m{^A (.+)} ) {
|
||||
$ent{$1} = 1;
|
||||
} elsif ( m{^R (.+)} ) {
|
||||
delete $ent{$1};
|
||||
} else {
|
||||
# Note: "cvs commit" helps even when you are offline
|
||||
error ("$entries_log_file:$.: unrecognizable line, " .
|
||||
"try \"cvs commit\"");
|
||||
}
|
||||
}
|
||||
close (ENTRIES);
|
||||
while (<ENTRIES>) {
|
||||
chomp;
|
||||
if ( m{^A (.+)} ) {
|
||||
$ent{$1} = 1;
|
||||
} elsif ( m{^R (.+)} ) {
|
||||
delete $ent{$1};
|
||||
} else {
|
||||
# Note: "cvs commit" helps even when you are offline
|
||||
error ("$entries_log_file:$.: unrecognizable line, " .
|
||||
"try \"cvs commit\"");
|
||||
}
|
||||
}
|
||||
close (ENTRIES);
|
||||
}
|
||||
|
||||
return keys %ent;
|
||||
@@ -260,28 +260,28 @@ sub process_arg ($)
|
||||
local $single_filename = 0;
|
||||
|
||||
if ( $arg eq "" or -d $arg ) {
|
||||
$curr_dir = $arg;
|
||||
my $real_curr_dir = $curr_dir eq "" ? "." : $curr_dir;
|
||||
$curr_dir = $arg;
|
||||
my $real_curr_dir = $curr_dir eq "" ? "." : $curr_dir;
|
||||
|
||||
error ("$real_curr_dir is not a directory")
|
||||
unless ( -d $real_curr_dir );
|
||||
error ("$real_curr_dir is not a directory")
|
||||
unless ( -d $real_curr_dir );
|
||||
|
||||
# Scan present files.
|
||||
file_status (".");
|
||||
opendir (DIR, $real_curr_dir) ||
|
||||
error ("couldn't open directory $real_curr_dir: $!");
|
||||
foreach (readdir (DIR)) {
|
||||
$found_files {$_} = 1;
|
||||
}
|
||||
closedir (DIR);
|
||||
# Scan present files.
|
||||
file_status (".");
|
||||
opendir (DIR, $real_curr_dir) ||
|
||||
error ("couldn't open directory $real_curr_dir: $!");
|
||||
foreach (readdir (DIR)) {
|
||||
$found_files {$_} = 1;
|
||||
}
|
||||
closedir (DIR);
|
||||
} else {
|
||||
$single_filename = basename $arg;
|
||||
$curr_dir = dirname $arg;
|
||||
$found_files{$single_filename} = 1 if lstat $arg;
|
||||
$single_filename = basename $arg;
|
||||
$curr_dir = dirname $arg;
|
||||
$found_files{$single_filename} = 1 if lstat $arg;
|
||||
}
|
||||
|
||||
$curr_dir .= "/"
|
||||
unless ( $curr_dir eq "" || $curr_dir =~ m{/$} );
|
||||
unless ( $curr_dir eq "" || $curr_dir =~ m{/$} );
|
||||
|
||||
# Scan CVS/Entries.
|
||||
my %entries = ();
|
||||
@@ -289,118 +289,118 @@ sub process_arg ($)
|
||||
my %removed = ();
|
||||
|
||||
foreach ( load_entries ("${curr_dir}CVS/Entries") ) {
|
||||
if ( m{^D/([^/]+)/} ) {
|
||||
$subdirs{$1} = SUBDIR_FOUND if !$single_filename;
|
||||
} elsif ( m{^/([^/]+)/([^/])[^/]*/([^/]*)/} ) {
|
||||
if ( !$single_filename or $single_filename eq $1 ) {
|
||||
$entries{$1} = $3;
|
||||
$removed{$1} = 1
|
||||
if $2 eq '-';
|
||||
}
|
||||
} elsif ( m{^D$} ) {
|
||||
next;
|
||||
} else {
|
||||
error ("${curr_dir}CVS/Entries: unrecognizable line");
|
||||
}
|
||||
if ( m{^D/([^/]+)/} ) {
|
||||
$subdirs{$1} = SUBDIR_FOUND if !$single_filename;
|
||||
} elsif ( m{^/([^/]+)/([^/])[^/]*/([^/]*)/} ) {
|
||||
if ( !$single_filename or $single_filename eq $1 ) {
|
||||
$entries{$1} = $3;
|
||||
$removed{$1} = 1
|
||||
if $2 eq '-';
|
||||
}
|
||||
} elsif ( m{^D$} ) {
|
||||
next;
|
||||
} else {
|
||||
error ("${curr_dir}CVS/Entries: unrecognizable line");
|
||||
}
|
||||
}
|
||||
|
||||
if ( $single_filename && !$entries{$single_filename} &&
|
||||
!$found_files{$single_filename} ) {
|
||||
error ("nothing known about $arg");
|
||||
!$found_files{$single_filename} ) {
|
||||
error ("nothing known about $arg");
|
||||
}
|
||||
|
||||
# Scan .cvsignore if any
|
||||
unless ($no_cvsignore) {
|
||||
my (@ignore_list) = ();
|
||||
my (@ignore_list) = ();
|
||||
|
||||
if (-f "${curr_dir}.cvsignore") {
|
||||
open (CVSIGNORE, "< ${curr_dir}.cvsignore")
|
||||
|| error ("couldn't open ${curr_dir}.cvsignore: $!");
|
||||
while (<CVSIGNORE>) {
|
||||
push (@ignore_list, split);
|
||||
}
|
||||
close (CVSIGNORE);
|
||||
}
|
||||
if (-f "${curr_dir}.cvsignore") {
|
||||
open (CVSIGNORE, "< ${curr_dir}.cvsignore")
|
||||
|| error ("couldn't open ${curr_dir}.cvsignore: $!");
|
||||
while (<CVSIGNORE>) {
|
||||
push (@ignore_list, split);
|
||||
}
|
||||
close (CVSIGNORE);
|
||||
}
|
||||
|
||||
my ($iter);
|
||||
foreach $iter (@ignore_list, @common_ignores) {
|
||||
if ($iter eq '!') {
|
||||
$ignore_rx = ''
|
||||
} else {
|
||||
if ($ignore_rx eq '') {
|
||||
$ignore_rx = '^(';
|
||||
} else {
|
||||
$ignore_rx .= '|';
|
||||
}
|
||||
$ignore_rx .= glob_to_rx ($iter);
|
||||
}
|
||||
}
|
||||
$ignore_rx .= ')$'
|
||||
if $ignore_rx ne '';
|
||||
my ($iter);
|
||||
foreach $iter (@ignore_list, @common_ignores) {
|
||||
if ($iter eq '!') {
|
||||
$ignore_rx = ''
|
||||
} else {
|
||||
if ($ignore_rx eq '') {
|
||||
$ignore_rx = '^(';
|
||||
} else {
|
||||
$ignore_rx .= '|';
|
||||
}
|
||||
$ignore_rx .= glob_to_rx ($iter);
|
||||
}
|
||||
}
|
||||
$ignore_rx .= ')$'
|
||||
if $ignore_rx ne '';
|
||||
}
|
||||
|
||||
# File is missing
|
||||
foreach $file (sort keys %entries) {
|
||||
unless ($found_files{$file}) {
|
||||
if ($removed{$file}) {
|
||||
file_status("R");
|
||||
} else {
|
||||
file_status("U");
|
||||
}
|
||||
}
|
||||
unless ($found_files{$file}) {
|
||||
if ($removed{$file}) {
|
||||
file_status("R");
|
||||
} else {
|
||||
file_status("U");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach $file (sort keys %found_files) {
|
||||
next if ($file eq '.' || $file eq '..');
|
||||
lstat ($curr_dir . $file) ||
|
||||
error ("lstat() failed on $curr_dir . $file");
|
||||
if (! $nolinks && -l _) {
|
||||
file_status ("L");
|
||||
} elsif (-d _) {
|
||||
if ($file eq 'CVS') {
|
||||
file_status ("C");
|
||||
} elsif ($subdirs{$file}) {
|
||||
$subdirs{$file} = SUBDIR_CVS;
|
||||
} else {
|
||||
file_status ("D"); # Unknown directory
|
||||
}
|
||||
} elsif (! (-f _) && ! (-l _)) {
|
||||
file_status ("S"); # This must be something very special
|
||||
} elsif (! $nolinks && (stat _) [3] > 1 ) {
|
||||
file_status ("H"); # Hard link
|
||||
} elsif (! $entries{$file}) {
|
||||
file_status ("?");
|
||||
} elsif ($entries{$file} =~ /^Initial |^dummy /) {
|
||||
file_status ("A");
|
||||
} elsif ($entries{$file} =~ /^Result of merge/) {
|
||||
file_status ("G");
|
||||
} elsif ($entries{$file} !~
|
||||
/^(...) (...) (..) (..):(..):(..) (....)$/) {
|
||||
error ("Invalid timestamp for $curr_dir$file: $entries{$file}");
|
||||
} else {
|
||||
my $cvtime = timegm($6, $5, $4, $3, $months{$2}, $7 - 1900);
|
||||
my $mtime = (stat _) [9];
|
||||
if ($cvtime == $mtime) {
|
||||
file_status ("F");
|
||||
} elsif ($cvtime < $mtime) {
|
||||
file_status ("M");
|
||||
} else {
|
||||
file_status ("O");
|
||||
}
|
||||
}
|
||||
next if ($file eq '.' || $file eq '..');
|
||||
lstat ($curr_dir . $file) ||
|
||||
error ("lstat() failed on $curr_dir . $file");
|
||||
if (! $nolinks && -l _) {
|
||||
file_status ("L");
|
||||
} elsif (-d _) {
|
||||
if ($file eq 'CVS') {
|
||||
file_status ("C");
|
||||
} elsif ($subdirs{$file}) {
|
||||
$subdirs{$file} = SUBDIR_CVS;
|
||||
} else {
|
||||
file_status ("D"); # Unknown directory
|
||||
}
|
||||
} elsif (! (-f _) && ! (-l _)) {
|
||||
file_status ("S"); # This must be something very special
|
||||
} elsif (! $nolinks && (stat _) [3] > 1 ) {
|
||||
file_status ("H"); # Hard link
|
||||
} elsif (! $entries{$file}) {
|
||||
file_status ("?");
|
||||
} elsif ($entries{$file} =~ /^Initial |^dummy /) {
|
||||
file_status ("A");
|
||||
} elsif ($entries{$file} =~ /^Result of merge/) {
|
||||
file_status ("G");
|
||||
} elsif ($entries{$file} !~
|
||||
/^(...) (...) (..) (..):(..):(..) (....)$/) {
|
||||
error ("Invalid timestamp for $curr_dir$file: $entries{$file}");
|
||||
} else {
|
||||
my $cvtime = timegm($6, $5, $4, $3, $months{$2}, $7 - 1900);
|
||||
my $mtime = (stat _) [9];
|
||||
if ($cvtime == $mtime) {
|
||||
file_status ("F");
|
||||
} elsif ($cvtime < $mtime) {
|
||||
file_status ("M");
|
||||
} else {
|
||||
file_status ("O");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now do directories.
|
||||
unless ($no_recurse) {
|
||||
my $save_curr_dir = $curr_dir;
|
||||
foreach $file (sort keys %subdirs) {
|
||||
if ($subdirs{$file} == SUBDIR_FOUND) {
|
||||
$curr_dir = $save_curr_dir;
|
||||
file_status ("X");
|
||||
} elsif ($subdirs{$file} == SUBDIR_CVS) {
|
||||
process_arg ($save_curr_dir . $file)
|
||||
}
|
||||
}
|
||||
my $save_curr_dir = $curr_dir;
|
||||
foreach $file (sort keys %subdirs) {
|
||||
if ($subdirs{$file} == SUBDIR_FOUND) {
|
||||
$curr_dir = $save_curr_dir;
|
||||
file_status ("X");
|
||||
} elsif ($subdirs{$file} == SUBDIR_CVS) {
|
||||
process_arg ($save_curr_dir . $file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,13 +423,13 @@ sub glob_to_rx ($)
|
||||
# Find parts in square brackets and copy them literally
|
||||
# Text outside brackets is processed by glob_to_rx_simple()
|
||||
while ($expr ne '') {
|
||||
if ($expr =~ /^(.*?)(\[.*?\])(.*)/) {
|
||||
$expr = $3;
|
||||
$result .= glob_to_rx_simple ($1) . $2;
|
||||
} else {
|
||||
$result .= glob_to_rx_simple ($expr);
|
||||
last;
|
||||
}
|
||||
if ($expr =~ /^(.*?)(\[.*?\])(.*)/) {
|
||||
$expr = $3;
|
||||
$result .= glob_to_rx_simple ($1) . $2;
|
||||
} else {
|
||||
$result .= glob_to_rx_simple ($expr);
|
||||
last;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -441,21 +441,21 @@ sub Main ()
|
||||
|
||||
# long status messages
|
||||
%messages = (
|
||||
"?" => "Unlisted file",
|
||||
"." => "Known directory",
|
||||
"F" => "Up-to-date file",
|
||||
"C" => "CVS admin directory",
|
||||
"M" => "Modified file",
|
||||
"S" => "Special file",
|
||||
"D" => "Unlisted directory",
|
||||
"L" => "Symbolic link",
|
||||
"H" => "Hard link",
|
||||
"U" => "Lost file",
|
||||
"X" => "Lost directory",
|
||||
"A" => "Newly added",
|
||||
"O" => "Older copy",
|
||||
"G" => "Result of merge",
|
||||
"R" => "Removed file"
|
||||
"?" => "Unlisted file",
|
||||
"." => "Known directory",
|
||||
"F" => "Up-to-date file",
|
||||
"C" => "CVS admin directory",
|
||||
"M" => "Modified file",
|
||||
"S" => "Special file",
|
||||
"D" => "Unlisted directory",
|
||||
"L" => "Symbolic link",
|
||||
"H" => "Hard link",
|
||||
"U" => "Lost file",
|
||||
"X" => "Lost directory",
|
||||
"A" => "Newly added",
|
||||
"O" => "Older copy",
|
||||
"G" => "Result of merge",
|
||||
"R" => "Removed file"
|
||||
);
|
||||
|
||||
undef @batch_list; # List of files for batch processing
|
||||
@@ -471,17 +471,17 @@ sub Main ()
|
||||
my $want_ver = 0; # Print version and exit
|
||||
|
||||
my %options = (
|
||||
"types=s" => \$list_types,
|
||||
"batch=s" => \$batch_cmd,
|
||||
"local" => \$no_recurse,
|
||||
"explain" => \$explain_type,
|
||||
"find" => \$find_mode,
|
||||
"short" => \$short_print,
|
||||
"ignore" => \$no_cvsignore,
|
||||
"messages" => \$want_msg,
|
||||
"nolinks" => \$nolinks,
|
||||
"help" => \$want_help,
|
||||
"version" => \$want_ver
|
||||
"types=s" => \$list_types,
|
||||
"batch=s" => \$batch_cmd,
|
||||
"local" => \$no_recurse,
|
||||
"explain" => \$explain_type,
|
||||
"find" => \$find_mode,
|
||||
"short" => \$short_print,
|
||||
"ignore" => \$no_cvsignore,
|
||||
"messages" => \$want_msg,
|
||||
"nolinks" => \$nolinks,
|
||||
"help" => \$want_help,
|
||||
"version" => \$want_ver
|
||||
);
|
||||
|
||||
GetOptions(%options);
|
||||
@@ -493,19 +493,19 @@ sub Main ()
|
||||
version() if $want_ver;
|
||||
|
||||
unless ($no_cvsignore) {
|
||||
init_ignores();
|
||||
init_ignores();
|
||||
}
|
||||
|
||||
if ($#ARGV < 0) {
|
||||
@ARGV = ("");
|
||||
@ARGV = ("");
|
||||
}
|
||||
|
||||
foreach (@ARGV) {
|
||||
process_arg ($_);
|
||||
process_arg ($_);
|
||||
}
|
||||
|
||||
if ($#batch_list >= 0) {
|
||||
do_batch();
|
||||
do_batch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
cfg.mk
18
cfg.mk
@@ -25,13 +25,13 @@ gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
|
||||
manual_title = Core GNU utilities
|
||||
|
||||
url_dir_list = \
|
||||
ftp://$(gnu_rel_host)/gnu/coreutils
|
||||
ftp://$(gnu_rel_host)/gnu/$(PACKAGE)
|
||||
|
||||
# The GnuPG ID of the key used to sign the tarballs.
|
||||
gpg_key_ID = B9AB9A16
|
||||
|
||||
# Tests not to run as part of "make distcheck".
|
||||
local-checks-to-skip = strftime-check
|
||||
local-checks-to-skip =
|
||||
|
||||
# Tools used to bootstrap this package, used for "announcement".
|
||||
bootstrap-tools = autoconf,automake,gnulib,bison
|
||||
@@ -39,7 +39,7 @@ bootstrap-tools = autoconf,automake,gnulib,bison
|
||||
# Now that we have better tests, make this the default.
|
||||
export VERBOSE = yes
|
||||
|
||||
old_NEWS_hash = 8ed224902e335a80ec8340cd0d594d7f
|
||||
old_NEWS_hash = 0d22ab4ad3fedd9cf283b256b61e8080
|
||||
|
||||
# Ensure that the list of O_ symbols used to compute O_FULLBLOCK is complete.
|
||||
dd = $(srcdir)/src/dd.c
|
||||
@@ -206,4 +206,16 @@ sc_strftime_check:
|
||||
rm -f $@-src $@-info; \
|
||||
fi
|
||||
|
||||
# Indent only with spaces.
|
||||
sc_prohibit_tab_based_indentation:
|
||||
@re='^ * ' \
|
||||
msg='TAB in indentation; use only spaces' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Don't use "indent-tabs-mode: nil" anymore. No longer needed.
|
||||
sc_prohibit_emacs__indent_tabs_mode__setting:
|
||||
@re='^( *[*#] *)?indent-tabs-mode:' \
|
||||
msg='use of emacs indent-tabs-mode: setting' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
include $(srcdir)/dist-check.mk
|
||||
|
||||
27
configure.ac
27
configure.ac
@@ -24,8 +24,8 @@ AC_PREREQ([2.61])
|
||||
# indicates that it is built from the 219th delta (in _some_ repository)
|
||||
# following the v6.9 tag, and that 58ddd is a prefix of the commit SHA1.
|
||||
AC_INIT([GNU coreutils],
|
||||
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
[bug-coreutils@gnu.org])
|
||||
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
[bug-coreutils@gnu.org])
|
||||
|
||||
AC_CONFIG_SRCDIR([src/ls.c])
|
||||
|
||||
@@ -47,7 +47,7 @@ coreutils_MACROS
|
||||
|
||||
AC_ARG_ENABLE([gcc-warnings],
|
||||
[AS_HELP_STRING([--enable-gcc-warnings],
|
||||
[turn on lots of GCC warnings (for developers)])],
|
||||
[turn on lots of GCC warnings (for developers)])],
|
||||
[case $enableval in
|
||||
yes|no) ;;
|
||||
*) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;;
|
||||
@@ -101,9 +101,6 @@ if test "$gl_gcc_warnings" = yes; then
|
||||
gl_WARN_ADD([-Wno-pointer-sign]) # Too many warnings for now
|
||||
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
|
||||
|
||||
# Offenders in pre-fts remove.c; FIXME: remove upon remove.c rewrite
|
||||
gl_WARN_ADD([-Wno-jump-misses-init])
|
||||
|
||||
# In spite of excluding -Wlogical-op above, it is enabled, as of
|
||||
# gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c
|
||||
gl_WARN_ADD([-Wno-logical-op])
|
||||
@@ -122,11 +119,11 @@ AC_FUNC_FORK
|
||||
|
||||
optional_bin_progs=
|
||||
AC_CHECK_FUNCS([uname],
|
||||
gl_ADD_PROG([optional_bin_progs], [uname]))
|
||||
gl_ADD_PROG([optional_bin_progs], [uname]))
|
||||
AC_CHECK_FUNCS([chroot],
|
||||
gl_ADD_PROG([optional_bin_progs], [chroot]))
|
||||
gl_ADD_PROG([optional_bin_progs], [chroot]))
|
||||
AC_CHECK_FUNCS([gethostid],
|
||||
gl_ADD_PROG([optional_bin_progs], [hostid]))
|
||||
gl_ADD_PROG([optional_bin_progs], [hostid]))
|
||||
|
||||
gl_WINSIZE_IN_PTEM
|
||||
|
||||
@@ -168,9 +165,9 @@ int main()
|
||||
[# If we have tzset, assume the worst when cross-compiling.
|
||||
utils_cv_localtime_cache=yes])
|
||||
else
|
||||
# If we lack tzset, report that localtime does not cache TZ,
|
||||
# since we can't invalidate the cache if we don't have tzset.
|
||||
utils_cv_localtime_cache=no
|
||||
# If we lack tzset, report that localtime does not cache TZ,
|
||||
# since we can't invalidate the cache if we don't have tzset.
|
||||
utils_cv_localtime_cache=no
|
||||
fi])dnl
|
||||
AC_MSG_RESULT([$utils_cv_localtime_cache])
|
||||
if test $utils_cv_localtime_cache = yes; then
|
||||
@@ -197,7 +194,7 @@ AC_CACHE_CHECK([for 3-argument setpriority function],
|
||||
[AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/resource.h>
|
||||
]],
|
||||
[[setpriority (0, 0, 0);]])],
|
||||
[utils_cv_func_setpriority=yes],
|
||||
@@ -374,8 +371,8 @@ case $t in
|
||||
$no_install_progs_default) ;;
|
||||
*) AC_MSG_ERROR([[internal error: g'l_INCLUDE_EXCLUDE_PROG's 2nd arg, $t,
|
||||
does not match the list of default-not-installed programs
|
||||
($no_install_progs_default) also recorded in $mk]],
|
||||
1) ;;
|
||||
($no_install_progs_default) also recorded in $mk]],
|
||||
1) ;;
|
||||
esac
|
||||
|
||||
# Given the name of a variable containing a space-separated list of
|
||||
|
||||
@@ -176,198 +176,198 @@ Free Documentation License''.
|
||||
@cindex file utilities
|
||||
|
||||
@menu
|
||||
* Introduction:: Caveats, overview, and authors.
|
||||
* Common options:: Common options.
|
||||
* Output of entire files:: cat tac nl od
|
||||
* Formatting file contents:: fmt pr fold
|
||||
* Output of parts of files:: head tail split csplit
|
||||
* Summarizing files:: wc sum cksum md5sum sha1sum sha2
|
||||
* Operating on sorted files:: sort shuf uniq comm ptx tsort
|
||||
* Operating on fields within a line:: cut paste join
|
||||
* Operating on characters:: tr expand unexpand
|
||||
* Directory listing:: ls dir vdir dircolors
|
||||
* Basic operations:: cp dd install mv rm shred
|
||||
* Special file types:: ln mkdir rmdir mkfifo mknod
|
||||
* Changing file attributes:: chgrp chmod chown touch
|
||||
* Disk usage:: df du stat sync truncate
|
||||
* Printing text:: echo printf yes
|
||||
* Conditions:: false true test expr
|
||||
* Redirection:: tee
|
||||
* File name manipulation:: dirname basename pathchk
|
||||
* Working context:: pwd stty printenv tty
|
||||
* User information:: id logname whoami groups users who
|
||||
* System context:: date uname hostname hostid uptime
|
||||
* SELinux context:: chcon runcon
|
||||
* Modified command invocation:: chroot env nice nohup stdbuf su timeout
|
||||
* Process control:: kill
|
||||
* Delaying:: sleep
|
||||
* Numeric operations:: factor seq
|
||||
* File permissions:: Access modes.
|
||||
* Date input formats:: Specifying date strings.
|
||||
* Opening the software toolbox:: The software tools philosophy.
|
||||
* GNU Free Documentation License:: Copying and sharing this manual.
|
||||
* Concept index:: General index.
|
||||
* Introduction:: Caveats, overview, and authors
|
||||
* Common options:: Common options
|
||||
* Output of entire files:: cat tac nl od base64
|
||||
* Formatting file contents:: fmt pr fold
|
||||
* Output of parts of files:: head tail split csplit
|
||||
* Summarizing files:: wc sum cksum md5sum sha1sum sha2
|
||||
* Operating on sorted files:: sort shuf uniq comm ptx tsort
|
||||
* Operating on fields:: cut paste join
|
||||
* Operating on characters:: tr expand unexpand
|
||||
* Directory listing:: ls dir vdir dircolors
|
||||
* Basic operations:: cp dd install mv rm shred
|
||||
* Special file types:: mkdir rmdir unlink mkfifo mknod ln link readlink
|
||||
* Changing file attributes:: chgrp chmod chown touch
|
||||
* Disk usage:: df du stat sync truncate
|
||||
* Printing text:: echo printf yes
|
||||
* Conditions:: false true test expr
|
||||
* Redirection:: tee
|
||||
* File name manipulation:: dirname basename pathchk
|
||||
* Working context:: pwd stty printenv tty
|
||||
* User information:: id logname whoami groups users who
|
||||
* System context:: date arch uname hostname hostid uptime
|
||||
* SELinux context:: chcon runcon
|
||||
* Modified command invocation:: chroot env nice nohup stdbuf su timeout
|
||||
* Process control:: kill
|
||||
* Delaying:: sleep
|
||||
* Numeric operations:: factor seq
|
||||
* File permissions:: Access modes
|
||||
* Date input formats:: Specifying date strings
|
||||
* Opening the software toolbox:: The software tools philosophy
|
||||
* GNU Free Documentation License:: Copying and sharing this manual
|
||||
* Concept index:: General index
|
||||
|
||||
@detailmenu
|
||||
--- The Detailed Node Listing ---
|
||||
|
||||
Common Options
|
||||
|
||||
* Exit status:: Indicating program success or failure.
|
||||
* Backup options:: Backup options
|
||||
* Block size:: Block size
|
||||
* Signal specifications:: Specifying signals
|
||||
* Exit status:: Indicating program success or failure
|
||||
* Backup options:: Backup options
|
||||
* Block size:: Block size
|
||||
* Signal specifications:: Specifying signals
|
||||
* Disambiguating names and IDs:: chgrp and chown owner and group syntax
|
||||
* Random sources:: Sources of random data
|
||||
* Target directory:: Target directory
|
||||
* Trailing slashes:: Trailing slashes
|
||||
* Traversing symlinks:: Traversing symlinks to directories
|
||||
* Treating / specially:: Treating / specially
|
||||
* Standards conformance:: Standards conformance
|
||||
* Random sources:: Sources of random data
|
||||
* Target directory:: Target directory
|
||||
* Trailing slashes:: Trailing slashes
|
||||
* Traversing symlinks:: Traversing symlinks to directories
|
||||
* Treating / specially:: Treating / specially
|
||||
* Standards conformance:: Standards conformance
|
||||
|
||||
Output of entire files
|
||||
|
||||
* cat invocation:: Concatenate and write files.
|
||||
* tac invocation:: Concatenate and write files in reverse.
|
||||
* nl invocation:: Number lines and write files.
|
||||
* od invocation:: Write files in octal or other formats.
|
||||
* base64 invocation:: Transform data into printable data.
|
||||
* cat invocation:: Concatenate and write files
|
||||
* tac invocation:: Concatenate and write files in reverse
|
||||
* nl invocation:: Number lines and write files
|
||||
* od invocation:: Write files in octal or other formats
|
||||
* base64 invocation:: Transform data into printable data
|
||||
|
||||
Formatting file contents
|
||||
|
||||
* fmt invocation:: Reformat paragraph text.
|
||||
* pr invocation:: Paginate or columnate files for printing.
|
||||
* fold invocation:: Wrap input lines to fit in specified width.
|
||||
* fmt invocation:: Reformat paragraph text
|
||||
* pr invocation:: Paginate or columnate files for printing
|
||||
* fold invocation:: Wrap input lines to fit in specified width
|
||||
|
||||
Output of parts of files
|
||||
|
||||
* head invocation:: Output the first part of files.
|
||||
* tail invocation:: Output the last part of files.
|
||||
* split invocation:: Split a file into fixed-size pieces.
|
||||
* csplit invocation:: Split a file into context-determined pieces.
|
||||
* head invocation:: Output the first part of files
|
||||
* tail invocation:: Output the last part of files
|
||||
* split invocation:: Split a file into fixed-size pieces
|
||||
* csplit invocation:: Split a file into context-determined pieces
|
||||
|
||||
Summarizing files
|
||||
|
||||
* wc invocation:: Print newline, word, and byte counts.
|
||||
* sum invocation:: Print checksum and block counts.
|
||||
* cksum invocation:: Print CRC checksum and byte counts.
|
||||
* md5sum invocation:: Print or check MD5 digests.
|
||||
* sha1sum invocation:: Print or check SHA-1 digests.
|
||||
* sha2 utilities:: Print or check SHA-2 digests.
|
||||
* wc invocation:: Print newline, word, and byte counts
|
||||
* sum invocation:: Print checksum and block counts
|
||||
* cksum invocation:: Print CRC checksum and byte counts
|
||||
* md5sum invocation:: Print or check MD5 digests
|
||||
* sha1sum invocation:: Print or check SHA-1 digests
|
||||
* sha2 utilities:: Print or check SHA-2 digests
|
||||
|
||||
Operating on sorted files
|
||||
|
||||
* sort invocation:: Sort text files.
|
||||
* shuf invocation:: Shuffle text files.
|
||||
* uniq invocation:: Uniquify files.
|
||||
* comm invocation:: Compare two sorted files line by line.
|
||||
* ptx invocation:: Produce a permuted index of file contents.
|
||||
* tsort invocation:: Topological sort.
|
||||
* sort invocation:: Sort text files
|
||||
* shuf invocation:: Shuffle text files
|
||||
* uniq invocation:: Uniquify files
|
||||
* comm invocation:: Compare two sorted files line by line
|
||||
* ptx invocation:: Produce a permuted index of file contents
|
||||
* tsort invocation:: Topological sort
|
||||
|
||||
@command{ptx}: Produce permuted indexes
|
||||
|
||||
* General options in ptx:: Options which affect general program behavior.
|
||||
* Charset selection in ptx:: Underlying character set considerations.
|
||||
* Input processing in ptx:: Input fields, contexts, and keyword selection.
|
||||
* Output formatting in ptx:: Types of output format, and sizing the fields.
|
||||
* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
|
||||
* General options in ptx:: Options which affect general program behavior
|
||||
* Charset selection in ptx:: Underlying character set considerations
|
||||
* Input processing in ptx:: Input fields, contexts, and keyword selection
|
||||
* Output formatting in ptx:: Types of output format, and sizing the fields
|
||||
* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
|
||||
|
||||
Operating on fields within a line
|
||||
Operating on fields
|
||||
|
||||
* cut invocation:: Print selected parts of lines.
|
||||
* paste invocation:: Merge lines of files.
|
||||
* join invocation:: Join lines on a common field.
|
||||
* cut invocation:: Print selected parts of lines
|
||||
* paste invocation:: Merge lines of files
|
||||
* join invocation:: Join lines on a common field
|
||||
|
||||
Operating on characters
|
||||
|
||||
* tr invocation:: Translate, squeeze, and/or delete characters.
|
||||
* expand invocation:: Convert tabs to spaces.
|
||||
* unexpand invocation:: Convert spaces to tabs.
|
||||
* tr invocation:: Translate, squeeze, and/or delete characters
|
||||
* expand invocation:: Convert tabs to spaces
|
||||
* unexpand invocation:: Convert spaces to tabs
|
||||
|
||||
@command{tr}: Translate, squeeze, and/or delete characters
|
||||
|
||||
* Character sets:: Specifying sets of characters.
|
||||
* Translating:: Changing one set of characters to another.
|
||||
* Squeezing:: Squeezing repeats and deleting.
|
||||
* Character sets:: Specifying sets of characters
|
||||
* Translating:: Changing one set of characters to another
|
||||
* Squeezing:: Squeezing repeats and deleting
|
||||
|
||||
Directory listing
|
||||
|
||||
* ls invocation:: List directory contents
|
||||
* dir invocation:: Briefly list directory contents
|
||||
* vdir invocation:: Verbosely list directory contents
|
||||
* dircolors invocation:: Color setup for @command{ls}
|
||||
* ls invocation:: List directory contents
|
||||
* dir invocation:: Briefly list directory contents
|
||||
* vdir invocation:: Verbosely list directory contents
|
||||
* dircolors invocation:: Color setup for @command{ls}
|
||||
|
||||
@command{ls}: List directory contents
|
||||
|
||||
* Which files are listed:: Which files are listed
|
||||
* What information is listed:: What information is listed
|
||||
* Sorting the output:: Sorting the output
|
||||
* More details about version sort:: More details about version sort
|
||||
* General output formatting:: General output formatting
|
||||
* Formatting the file names:: Formatting the file names
|
||||
* Which files are listed:: Which files are listed
|
||||
* What information is listed:: What information is listed
|
||||
* Sorting the output:: Sorting the output
|
||||
* Details about version sort:: More details about version sort
|
||||
* General output formatting:: General output formatting
|
||||
* Formatting the file names:: Formatting the file names
|
||||
|
||||
Basic operations
|
||||
|
||||
* cp invocation:: Copy files and directories
|
||||
* dd invocation:: Convert and copy a file
|
||||
* install invocation:: Copy files and set attributes
|
||||
* mv invocation:: Move (rename) files
|
||||
* rm invocation:: Remove files or directories
|
||||
* shred invocation:: Remove files more securely
|
||||
* cp invocation:: Copy files and directories
|
||||
* dd invocation:: Convert and copy a file
|
||||
* install invocation:: Copy files and set attributes
|
||||
* mv invocation:: Move (rename) files
|
||||
* rm invocation:: Remove files or directories
|
||||
* shred invocation:: Remove files more securely
|
||||
|
||||
Special file types
|
||||
|
||||
* link invocation:: Make a hard link via the link syscall
|
||||
* ln invocation:: Make links between files
|
||||
* mkdir invocation:: Make directories
|
||||
* mkfifo invocation:: Make FIFOs (named pipes)
|
||||
* mknod invocation:: Make block or character special files
|
||||
* readlink invocation:: Print value of a symlink or canonical file name
|
||||
* rmdir invocation:: Remove empty directories
|
||||
* unlink invocation:: Remove files via unlink syscall
|
||||
* link invocation:: Make a hard link via the link syscall
|
||||
* ln invocation:: Make links between files
|
||||
* mkdir invocation:: Make directories
|
||||
* mkfifo invocation:: Make FIFOs (named pipes)
|
||||
* mknod invocation:: Make block or character special files
|
||||
* readlink invocation:: Print value of a symlink or canonical file name
|
||||
* rmdir invocation:: Remove empty directories
|
||||
* unlink invocation:: Remove files via unlink syscall
|
||||
|
||||
Changing file attributes
|
||||
|
||||
* chown invocation:: Change file owner and group
|
||||
* chgrp invocation:: Change group ownership
|
||||
* chmod invocation:: Change access permissions
|
||||
* touch invocation:: Change file timestamps
|
||||
* chown invocation:: Change file owner and group
|
||||
* chgrp invocation:: Change group ownership
|
||||
* chmod invocation:: Change access permissions
|
||||
* touch invocation:: Change file timestamps
|
||||
|
||||
Disk usage
|
||||
|
||||
* df invocation:: Report file system disk space usage
|
||||
* du invocation:: Estimate file space usage
|
||||
* stat invocation:: Report file or file system status
|
||||
* sync invocation:: Synchronize data on disk with memory
|
||||
* truncate invocation:: Shrink or extend the size of a file
|
||||
* df invocation:: Report file system disk space usage
|
||||
* du invocation:: Estimate file space usage
|
||||
* stat invocation:: Report file or file system status
|
||||
* sync invocation:: Synchronize data on disk with memory
|
||||
* truncate invocation:: Shrink or extend the size of a file
|
||||
|
||||
Printing text
|
||||
|
||||
* echo invocation:: Print a line of text
|
||||
* printf invocation:: Format and print data
|
||||
* yes invocation:: Print a string until interrupted
|
||||
* echo invocation:: Print a line of text
|
||||
* printf invocation:: Format and print data
|
||||
* yes invocation:: Print a string until interrupted
|
||||
|
||||
Conditions
|
||||
|
||||
* false invocation:: Do nothing, unsuccessfully
|
||||
* true invocation:: Do nothing, successfully
|
||||
* test invocation:: Check file types and compare values
|
||||
* expr invocation:: Evaluate expressions
|
||||
* false invocation:: Do nothing, unsuccessfully
|
||||
* true invocation:: Do nothing, successfully
|
||||
* test invocation:: Check file types and compare values
|
||||
* expr invocation:: Evaluate expressions
|
||||
|
||||
@command{test}: Check file types and compare values
|
||||
|
||||
* File type tests:: File type tests
|
||||
* Access permission tests:: Access permission tests
|
||||
* File characteristic tests:: File characteristic tests
|
||||
* String tests:: String tests
|
||||
* Numeric tests:: Numeric tests
|
||||
* File type tests:: File type tests
|
||||
* Access permission tests:: Access permission tests
|
||||
* File characteristic tests:: File characteristic tests
|
||||
* String tests:: String tests
|
||||
* Numeric tests:: Numeric tests
|
||||
|
||||
@command{expr}: Evaluate expression
|
||||
|
||||
* String expressions:: + : match substr index length
|
||||
* Numeric expressions:: + - * / %
|
||||
* Relations for expr:: | & < <= = == != >= >
|
||||
* Examples of expr:: Examples of using @command{expr}
|
||||
* String expressions:: + : match substr index length
|
||||
* Numeric expressions:: + - * / %
|
||||
* Relations for expr:: | & < <= = == != >= >
|
||||
* Examples of expr:: Examples of using @command{expr}
|
||||
|
||||
Redirection
|
||||
|
||||
@@ -388,13 +388,13 @@ Working context
|
||||
|
||||
@command{stty}: Print or change terminal characteristics
|
||||
|
||||
* Control:: Control settings
|
||||
* Input:: Input settings
|
||||
* Output:: Output settings
|
||||
* Local:: Local settings
|
||||
* Combination:: Combination settings
|
||||
* Characters:: Special characters
|
||||
* Special:: Special settings
|
||||
* Control:: Control settings
|
||||
* Input:: Input settings
|
||||
* Output:: Output settings
|
||||
* Local:: Local settings
|
||||
* Combination:: Combination settings
|
||||
* Characters:: Special characters
|
||||
* Special:: Special settings
|
||||
|
||||
User information
|
||||
|
||||
@@ -420,10 +420,10 @@ System context
|
||||
* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY]
|
||||
* Literal conversion specifiers:: %[%nt]
|
||||
* Padding and other flags:: Pad with zeros, spaces, etc.
|
||||
* Setting the time:: Changing the system clock.
|
||||
* Options for date:: Instead of the current time.
|
||||
* Date input formats:: Specifying date strings.
|
||||
* Examples of date:: Examples.
|
||||
* Setting the time:: Changing the system clock
|
||||
* Options for date:: Instead of the current time
|
||||
* Date input formats:: Specifying date strings
|
||||
* Examples of date:: Examples
|
||||
|
||||
SELinux context
|
||||
|
||||
@@ -455,23 +455,23 @@ Numeric operations
|
||||
|
||||
File permissions
|
||||
|
||||
* Mode Structure:: Structure of file mode bits.
|
||||
* Symbolic Modes:: Mnemonic representation of file mode bits.
|
||||
* Numeric Modes:: File mode bits as octal numbers.
|
||||
* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories.
|
||||
* Mode Structure:: Structure of file mode bits
|
||||
* Symbolic Modes:: Mnemonic representation of file mode bits
|
||||
* Numeric Modes:: File mode bits as octal numbers
|
||||
* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories
|
||||
|
||||
Date input formats
|
||||
|
||||
* General date syntax:: Common rules.
|
||||
* Calendar date items:: 19 Dec 1994.
|
||||
* Time of day items:: 9:20pm.
|
||||
* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}.
|
||||
* Day of week items:: Monday and others.
|
||||
* Relative items in date strings:: next tuesday, 2 years ago.
|
||||
* Pure numbers in date strings:: 19931219, 1440.
|
||||
* Seconds since the Epoch:: @@1078100502.
|
||||
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
|
||||
* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al.
|
||||
* General date syntax:: Common rules
|
||||
* Calendar date items:: 19 Dec 1994
|
||||
* Time of day items:: 9:20pm
|
||||
* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}
|
||||
* Day of week items:: Monday and others
|
||||
* Relative items in date strings:: next tuesday, 2 years ago
|
||||
* Pure numbers in date strings:: 19931219, 1440
|
||||
* Seconds since the Epoch:: @@1078100502
|
||||
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0"
|
||||
* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al
|
||||
|
||||
Opening the software toolbox
|
||||
|
||||
@@ -485,7 +485,7 @@ Opening the software toolbox
|
||||
|
||||
Copying This Manual
|
||||
|
||||
* GNU Free Documentation License:: Copying and sharing this manual.
|
||||
* GNU Free Documentation License:: Copying and sharing this manual
|
||||
|
||||
@end detailmenu
|
||||
@end menu
|
||||
@@ -618,15 +618,8 @@ from the shell.
|
||||
@end macro
|
||||
|
||||
@macro multiplierSuffixes{varName}
|
||||
@ignore
|
||||
Appending @samp{b} multiplies @var{\varName\} by 512,
|
||||
@samp{kB} by 1000, @samp{K} by 1024,
|
||||
@samp{MB} by 1000*1000, @samp{M} by 1024*1024,
|
||||
@samp{GB} by 1000*1000*1000, @samp{G} by 1024*1024*1024,
|
||||
and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
|
||||
@end ignore
|
||||
@var{\varName\} is a number which may have one of the following
|
||||
multiplicative suffixes:
|
||||
@var{\varName\} may be, or may be an integer optionally followed by,
|
||||
one of the following multiplicative suffixes:
|
||||
@example
|
||||
@samp{b} => 512 ("blocks")
|
||||
@samp{KB} => 1000 (KiloBytes)
|
||||
@@ -641,8 +634,8 @@ and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
|
||||
|
||||
@c FIXME: same as above, but no ``blocks'' line.
|
||||
@macro multiplierSuffixesNoBlocks{varName}
|
||||
@var{\varName\} is a number which may have one of the following
|
||||
multiplicative suffixes:
|
||||
@var{\varName\} may be, or may be an integer optionally followed by,
|
||||
one of the following multiplicative suffixes:
|
||||
@example
|
||||
@samp{KB} => 1000 (KiloBytes)
|
||||
@samp{K} => 1024 (KibiBytes)
|
||||
@@ -752,8 +745,8 @@ However, some of the programs documented here do produce
|
||||
other exit status values and a few associate different
|
||||
meanings with the values @samp{0} and @samp{1}.
|
||||
Here are some of the exceptions:
|
||||
@command{chroot}, @command{env}, @command{expr},
|
||||
@command{nice}, @command{nohup}, @command{printenv}, @command{sort},
|
||||
@command{chroot}, @command{env}, @command{expr}, @command{nice},
|
||||
@command{nohup}, @command{printenv}, @command{sort}, @command{stdbuf},
|
||||
@command{su}, @command{test}, @command{timeout}, @command{tty}.
|
||||
|
||||
|
||||
@@ -2122,14 +2115,6 @@ The program accepts the following options. Also see @ref{Common options}.
|
||||
|
||||
@table @samp
|
||||
|
||||
@item -C
|
||||
@itemx --compare
|
||||
@opindex -C
|
||||
@opindex --compare
|
||||
Compare each pair of source and destination files, and if the destination has
|
||||
identical content and any specified owner, group, permissions, and possibly
|
||||
SELinux context, then do not modify the destination at all.
|
||||
|
||||
@item -c
|
||||
@itemx --crown-margin
|
||||
@opindex -c
|
||||
@@ -2790,9 +2775,10 @@ growing.
|
||||
The option values @samp{descriptor} and @samp{name} may be specified only
|
||||
with the long form of the option, not with @option{-f}.
|
||||
|
||||
@vindex POSIXLY_CORRECT
|
||||
If @env{POSIXLY_CORRECT} is set, the @option{-f} option is ignored if
|
||||
The @option{-f} option is ignored if
|
||||
no @var{file} operand is specified and standard input is a FIFO or a pipe.
|
||||
Likewise, the @option{-f} option has no effect for any
|
||||
operand specified as @samp{-}, when standard input is a FIFO or a pipe.
|
||||
|
||||
@item -F
|
||||
@opindex -F
|
||||
@@ -5250,8 +5236,8 @@ the way the linker handled archive files, which has since been solved
|
||||
in different ways.
|
||||
|
||||
|
||||
@node Operating on fields within a line
|
||||
@chapter Operating on fields within a line
|
||||
@node Operating on fields
|
||||
@chapter Operating on fields
|
||||
|
||||
@menu
|
||||
* cut invocation:: Print selected parts of lines.
|
||||
@@ -6127,8 +6113,9 @@ Exit status:
|
||||
1 minor problems (e.g., failure to access a file or directory not
|
||||
specified as a command line argument. This happens when listing a
|
||||
directory in which entries are actively being removed or renamed.)
|
||||
2 serious trouble (e.g., memory exhausted, invalid option or failure
|
||||
to access file or directory specified as a command line argument)
|
||||
2 serious trouble (e.g., memory exhausted, invalid option, failure
|
||||
to access a file or directory specified as a command line argument
|
||||
or a directory loop)
|
||||
@end display
|
||||
|
||||
Also see @ref{Common options}.
|
||||
@@ -6137,7 +6124,7 @@ Also see @ref{Common options}.
|
||||
* Which files are listed::
|
||||
* What information is listed::
|
||||
* Sorting the output::
|
||||
* More details about version sort::
|
||||
* Details about version sort::
|
||||
* General output formatting::
|
||||
* Formatting file timestamps::
|
||||
* Formatting the file names::
|
||||
@@ -6667,7 +6654,7 @@ directories, since not doing any sorting can be noticeably faster.
|
||||
@opindex version@r{, sorting option for @command{ls}}
|
||||
Sort by version name and number, lowest first. It behaves like a default
|
||||
sort, except that each sequence of decimal digits is treated numerically
|
||||
as an index/version number. (@xref{More details about version sort}.)
|
||||
as an index/version number. (@xref{Details about version sort}.)
|
||||
|
||||
@item -X
|
||||
@itemx --sort=extension
|
||||
@@ -6680,8 +6667,8 @@ after the last @samp{.}); files with no extension are sorted first.
|
||||
@end table
|
||||
|
||||
|
||||
@node More details about version sort
|
||||
@subsection More details about version sort
|
||||
@node Details about version sort
|
||||
@subsection Details about version sort
|
||||
|
||||
The version sort takes into account the fact that file names frequently include
|
||||
indices or version numbers. Standard sorting functions usually do not produce
|
||||
@@ -7445,12 +7432,10 @@ may preserve the group ownership of a file only if they happen to be
|
||||
a member of the desired group.
|
||||
@itemx timestamps
|
||||
Preserve the times of last access and last modification, when possible.
|
||||
In general, it is not possible to preserve these attributes
|
||||
On older systems, it is not possible to preserve these attributes
|
||||
when the affected file is a symbolic link.
|
||||
However, FreeBSD now provides the @code{lutimes} function, which makes
|
||||
it possible even for symbolic links. However, this implementation does
|
||||
not yet take advantage of that.
|
||||
@c FIXME: once we provide lutimes support, update the above.
|
||||
However, many systems now provide the @code{utimensat} function,
|
||||
which makes it possible even for symbolic links.
|
||||
@itemx links
|
||||
Preserve in the destination files
|
||||
any links between corresponding source files.
|
||||
@@ -7543,15 +7528,31 @@ Also, it is not portable to use @option{-R} to copy symbolic links
|
||||
unless you also specify @option{-P}, as @acronym{POSIX} allows
|
||||
implementations that dereference symbolic links by default.
|
||||
|
||||
@item --reflink
|
||||
@opindex --reflink
|
||||
@item --reflink[=@var{when}]
|
||||
@opindex --reflink[=@var{when}]
|
||||
@cindex COW
|
||||
@cindex clone
|
||||
@cindex copy on write
|
||||
Perform a lightweight, copy-on-write (COW) copy.
|
||||
Copying with this option can succeed only on some relatively new file systems.
|
||||
Copying with this option can succeed only on some file systems.
|
||||
Once it has succeeded, beware that the source and destination files
|
||||
share the same disk data blocks as long as they remain unmodified.
|
||||
Thus, if a disk I/O error affects data blocks of one of the files,
|
||||
the other suffers the exact same fate.
|
||||
|
||||
The @var{when} value can be one of the following:
|
||||
|
||||
@table @samp
|
||||
@item always
|
||||
The default behavior: if the copy-on-write operation is not supported
|
||||
then report the failure for each file and exit with a failure status.
|
||||
|
||||
@item auto
|
||||
If the copy-on-write operation is not supported then fall back
|
||||
to the standard copy behaviour.
|
||||
@end table
|
||||
|
||||
|
||||
@item --remove-destination
|
||||
@opindex --remove-destination
|
||||
Remove each existing destination file before attempting to open it
|
||||
@@ -7768,8 +7769,8 @@ input newline with a space and padding with spaces as necessary.
|
||||
|
||||
@item unblock
|
||||
@opindex unblock
|
||||
Replace trailing spaces in each @samp{cbs}-sized input block with a
|
||||
newline.
|
||||
Remove any trailing spaces in each @samp{cbs}-sized input block,
|
||||
and append a newline.
|
||||
|
||||
The @samp{block} and @samp{unblock} conversions are mutually exclusive.
|
||||
|
||||
@@ -8058,6 +8059,14 @@ The program accepts the following options. Also see @ref{Common options}.
|
||||
|
||||
@optBackup
|
||||
|
||||
@item -C
|
||||
@itemx --compare
|
||||
@opindex -C
|
||||
@opindex --compare
|
||||
Compare each pair of source and destination files, and if the destination has
|
||||
identical content and any specified owner, group, permissions, and possibly
|
||||
SELinux context, then do not modify the destination at all.
|
||||
|
||||
@item -c
|
||||
@opindex -c
|
||||
Ignored; for compatibility with old Unix versions of @command{install}.
|
||||
@@ -8745,6 +8754,11 @@ On a @acronym{GNU} system, this command acts like @samp{ln --directory
|
||||
not specified by @acronym{POSIX}, and the @command{link} command is
|
||||
more portable in practice.
|
||||
|
||||
If @var{filename} is a symbolic link, it is unspecified whether
|
||||
@var{linkname} will be a hard link to the symbolic link or to the
|
||||
target of the symbolic link. Use @command{ln -P} or @command{ln -L}
|
||||
to specify which behavior is desired.
|
||||
|
||||
@exitstatus
|
||||
|
||||
|
||||
@@ -8800,8 +8814,10 @@ A @dfn{hard link} is another name for an existing file; the link and the
|
||||
original are indistinguishable. Technically speaking, they share the
|
||||
same inode, and the inode contains all the information about a
|
||||
file---indeed, it is not incorrect to say that the inode @emph{is} the
|
||||
file. On all existing implementations, you cannot make a hard link to
|
||||
a directory, and hard links cannot cross file system boundaries. (These
|
||||
file. Most systems prohibit making a hard link to
|
||||
a directory; on those where it is allowed, only the super-user can do
|
||||
so (and with caution, since creating a cycle will cause problems to many
|
||||
other utilities). Hard links cannot cross file system boundaries. (These
|
||||
restrictions are not mandated by @acronym{POSIX}, however.)
|
||||
|
||||
@cindex dereferencing symbolic links
|
||||
@@ -8813,9 +8829,13 @@ refers to a different file, by name. When most operations (opening,
|
||||
reading, writing, and so on) are passed the symbolic link file, the
|
||||
kernel automatically @dfn{dereferences} the link and operates on the
|
||||
target of the link. But some operations (e.g., removing) work on the
|
||||
link file itself, rather than on its target. The owner, group, and
|
||||
mode of a symlink are not significant to file access performed through
|
||||
the link. @xref{Symbolic Links,,,
|
||||
link file itself, rather than on its target. The owner and group of a
|
||||
symlink are not significant to file access performed through
|
||||
the link, but do have implications on deleting a symbolic link from a
|
||||
directory with the restricted deletion bit set. On the GNU system,
|
||||
the mode of a symlink has no significance and cannot be changed, but
|
||||
on some BSD systems, the mode can be changed and will affect whether
|
||||
the symlink will be traversed in file name resolution. @xref{Symbolic Links,,,
|
||||
libc, The GNU C Library Reference Manual}.
|
||||
|
||||
Symbolic links can contain arbitrary strings; a @dfn{dangling symlink}
|
||||
@@ -8870,6 +8890,14 @@ Remove existing destination files.
|
||||
@cindex prompting, and @command{ln}
|
||||
Prompt whether to remove existing destination files.
|
||||
|
||||
@item -L
|
||||
@itemx --logical
|
||||
@opindex -L
|
||||
@opindex --logical
|
||||
If @option{-s} is not in effect, and the source file is a symbolic
|
||||
link, create the hard link to the file referred to by the symbolic
|
||||
link, rather than the symbolic link itself.
|
||||
|
||||
@item -n
|
||||
@itemx --no-dereference
|
||||
@opindex -n
|
||||
@@ -8891,6 +8919,17 @@ just like a directory.
|
||||
This option is weaker than the @option{--no-target-directory}
|
||||
(@option{-T}) option, so it has no effect if both options are given.
|
||||
|
||||
@item -P
|
||||
@itemx --physical
|
||||
@opindex -P
|
||||
@opindex --physical
|
||||
If @option{-s} is not in effect, and the source file is a symbolic
|
||||
link, create the hard link to the symbolic link itself. On platforms
|
||||
where this is not supported by the kernel, this option creates a
|
||||
symbolic link with identical contents; since symbolic link contents
|
||||
cannot be edited, any file name resolution performed through either
|
||||
link will be the same as if a hard link had been created.
|
||||
|
||||
@item -s
|
||||
@itemx --symbolic
|
||||
@opindex -s
|
||||
@@ -8912,6 +8951,15 @@ Print the name of each file after linking it successfully.
|
||||
|
||||
@end table
|
||||
|
||||
@cindex hard links to symbolic links
|
||||
@cindex symbolic links and @command{ln}
|
||||
If @option{-L} and @option{-P} are both given, the last one takes
|
||||
precedence. If @option{-s} is also given, @option{-L} and @option{-P}
|
||||
are silently ignored. If neither option is given, then this
|
||||
implementation defaults to @option{-P} if the system @code{link} supports
|
||||
hard links to symbolic links (such as the GNU system), and @option{-L}
|
||||
if @code{link} follows symbolic links (such as on BSD).
|
||||
|
||||
@exitstatus
|
||||
|
||||
Examples:
|
||||
@@ -9196,7 +9244,8 @@ The program accepts the following options. Also see @ref{Common options}.
|
||||
@opindex --canonicalize
|
||||
Activate canonicalize mode.
|
||||
If any component of the file name except the last one is missing or unavailable,
|
||||
@command{readlink} produces no output and exits with a nonzero exit code.
|
||||
@command{readlink} produces no output and exits with a nonzero exit
|
||||
code. A trailing slash is ignored.
|
||||
|
||||
@item -e
|
||||
@itemx --canonicalize-existing
|
||||
@@ -9204,7 +9253,8 @@ If any component of the file name except the last one is missing or unavailable,
|
||||
@opindex --canonicalize-existing
|
||||
Activate canonicalize mode.
|
||||
If any component is missing or unavailable, @command{readlink} produces
|
||||
no output and exits with a nonzero exit code.
|
||||
no output and exits with a nonzero exit code. A trailing slash
|
||||
requires that the name resolve to a directory.
|
||||
|
||||
@item -m
|
||||
@itemx --canonicalize-missing
|
||||
@@ -9908,6 +9958,7 @@ If the year is specified with only two digits, then @var{cc}
|
||||
is 20 for years in the range 0 @dots{} 68, and 19 for years in
|
||||
69 @dots{} 99. If no digits of the year are specified,
|
||||
the argument is interpreted as a date in the current year.
|
||||
Note that @var{ss} may be @samp{60}, to accommodate leap seconds.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -12817,9 +12868,13 @@ running it if no user is specified. Synopsis:
|
||||
id [@var{option}]@dots{} [@var{username}]
|
||||
@end example
|
||||
|
||||
@vindex POSIXLY_CORRECT
|
||||
By default, it prints the real user ID, real group ID, effective user ID
|
||||
if different from the real user ID, effective group ID if different from
|
||||
the real group ID, and supplemental group IDs.
|
||||
In addition, if SELinux
|
||||
is enabled and the @env{POSIXLY_CORRECT} environment variable is not set,
|
||||
then print @samp{context=@var{c}}, where @var{c} is the security context.
|
||||
|
||||
Each of these numeric values is preceded by an identifying string and
|
||||
followed by the corresponding user or group name in parentheses.
|
||||
|
||||
@@ -219,7 +219,7 @@ mbsalign (const char *src, char *dest, size_t dest_size,
|
||||
|
||||
dest = mbs_align_pad (dest, dest_end, start_spaces);
|
||||
dest = mempcpy(dest, str_to_print, MIN (n_used_bytes, dest_end - dest));
|
||||
dest = mbs_align_pad (dest, dest_end, end_spaces);
|
||||
mbs_align_pad (dest, dest_end, end_spaces);
|
||||
}
|
||||
|
||||
mbsalign_cleanup:
|
||||
@@ -229,8 +229,3 @@ mbsalign_cleanup:
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -76,45 +76,45 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
|
||||
|
||||
g = realloc_groupbuf (NULL, max_n_groups);
|
||||
if (g == NULL)
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
GETGROUPS_T *h;
|
||||
int last_n_groups = max_n_groups;
|
||||
{
|
||||
GETGROUPS_T *h;
|
||||
int last_n_groups = max_n_groups;
|
||||
|
||||
/* getgrouplist updates max_n_groups to num required. */
|
||||
ng = getgrouplist (username, gid, g, &max_n_groups);
|
||||
/* getgrouplist updates max_n_groups to num required. */
|
||||
ng = getgrouplist (username, gid, g, &max_n_groups);
|
||||
|
||||
/* Some systems (like Darwin) have a bug where they
|
||||
never increase max_n_groups. */
|
||||
if (ng < 0 && last_n_groups == max_n_groups)
|
||||
max_n_groups *= 2;
|
||||
/* Some systems (like Darwin) have a bug where they
|
||||
never increase max_n_groups. */
|
||||
if (ng < 0 && last_n_groups == max_n_groups)
|
||||
max_n_groups *= 2;
|
||||
|
||||
if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (g);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
g = h;
|
||||
if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (g);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
g = h;
|
||||
|
||||
if (0 <= ng)
|
||||
{
|
||||
*groups = g;
|
||||
/* On success some systems just return 0 from getgrouplist,
|
||||
so return max_n_groups rather than ng. */
|
||||
return max_n_groups;
|
||||
}
|
||||
}
|
||||
if (0 <= ng)
|
||||
{
|
||||
*groups = g;
|
||||
/* On success some systems just return 0 from getgrouplist,
|
||||
so return max_n_groups rather than ng. */
|
||||
return max_n_groups;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else no username, so fall through and use getgroups. */
|
||||
#endif
|
||||
|
||||
max_n_groups = (username
|
||||
? getugroups (0, NULL, username, gid)
|
||||
: getgroups (0, NULL));
|
||||
? getugroups (0, NULL, username, gid)
|
||||
: getgroups (0, NULL));
|
||||
|
||||
/* If we failed to count groups with NULL for a buffer,
|
||||
try again with a non-NULL one, just in case. */
|
||||
@@ -126,8 +126,8 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
|
||||
return -1;
|
||||
|
||||
ng = (username
|
||||
? getugroups (max_n_groups, g, username, gid)
|
||||
: getgroups (max_n_groups, g));
|
||||
? getugroups (max_n_groups, g, username, gid)
|
||||
: getgroups (max_n_groups, g));
|
||||
|
||||
if (ng < 0)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
/* This index operation is more efficient on many processors */
|
||||
#define ind(mm, x) \
|
||||
(* (uint32_t *) ((char *) (mm) \
|
||||
+ ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
|
||||
+ ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
|
||||
|
||||
/*
|
||||
* The central step. This uses two temporaries, x and y. mm is the
|
||||
@@ -191,18 +191,18 @@ isaac_init (struct isaac_state *s, uint32_t const *seed, size_t seedsize)
|
||||
isaac_mix (s, seed);
|
||||
/* Second and subsequent passes (extension to ISAAC) */
|
||||
while (seedsize -= ISAAC_BYTES)
|
||||
{
|
||||
seed += ISAAC_WORDS;
|
||||
for (i = 0; i < ISAAC_WORDS; i++)
|
||||
s->mm[i] += seed[i];
|
||||
isaac_mix (s, s->mm);
|
||||
}
|
||||
{
|
||||
seed += ISAAC_WORDS;
|
||||
for (i = 0; i < ISAAC_WORDS; i++)
|
||||
s->mm[i] += seed[i];
|
||||
isaac_mix (s, s->mm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The no seed case (as in reference ISAAC code) */
|
||||
for (i = 0; i < ISAAC_WORDS; i++)
|
||||
s->mm[i] = 0;
|
||||
s->mm[i] = 0;
|
||||
}
|
||||
|
||||
/* Final pass */
|
||||
@@ -252,7 +252,7 @@ isaac_seed_data (struct isaac_state *s, void const *buffer, size_t size)
|
||||
{
|
||||
p = (unsigned char *) s->mm + s->c;
|
||||
for (i = 0; i < avail; i++)
|
||||
p[i] ^= buf[i];
|
||||
p[i] ^= buf[i];
|
||||
buf += avail;
|
||||
size -= avail;
|
||||
isaac_mix (s, s->mm);
|
||||
|
||||
112
gl/lib/randint.c
112
gl/lib/randint.c
@@ -128,75 +128,75 @@ randint_genmax (struct randint_source *s, randint genmax)
|
||||
for (;;)
|
||||
{
|
||||
if (randmax < genmax)
|
||||
{
|
||||
/* Calculate how many input bytes will be needed, and read
|
||||
the bytes. */
|
||||
{
|
||||
/* Calculate how many input bytes will be needed, and read
|
||||
the bytes. */
|
||||
|
||||
size_t i = 0;
|
||||
randint rmax = randmax;
|
||||
unsigned char buf[sizeof randnum];
|
||||
size_t i = 0;
|
||||
randint rmax = randmax;
|
||||
unsigned char buf[sizeof randnum];
|
||||
|
||||
do
|
||||
{
|
||||
rmax = shift_left (rmax) + UCHAR_MAX;
|
||||
i++;
|
||||
}
|
||||
while (rmax < genmax);
|
||||
do
|
||||
{
|
||||
rmax = shift_left (rmax) + UCHAR_MAX;
|
||||
i++;
|
||||
}
|
||||
while (rmax < genmax);
|
||||
|
||||
randread (source, buf, i);
|
||||
randread (source, buf, i);
|
||||
|
||||
/* Increase RANDMAX by appending random bytes to RANDNUM and
|
||||
UCHAR_MAX to RANDMAX until RANDMAX is no less than
|
||||
GENMAX. This may lose up to CHAR_BIT bits of information
|
||||
if shift_right (RANDINT_MAX) < GENMAX, but it is not
|
||||
worth the programming hassle of saving these bits since
|
||||
GENMAX is rarely that large in practice. */
|
||||
/* Increase RANDMAX by appending random bytes to RANDNUM and
|
||||
UCHAR_MAX to RANDMAX until RANDMAX is no less than
|
||||
GENMAX. This may lose up to CHAR_BIT bits of information
|
||||
if shift_right (RANDINT_MAX) < GENMAX, but it is not
|
||||
worth the programming hassle of saving these bits since
|
||||
GENMAX is rarely that large in practice. */
|
||||
|
||||
i = 0;
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
randnum = shift_left (randnum) + buf[i];
|
||||
randmax = shift_left (randmax) + UCHAR_MAX;
|
||||
i++;
|
||||
}
|
||||
while (randmax < genmax);
|
||||
}
|
||||
do
|
||||
{
|
||||
randnum = shift_left (randnum) + buf[i];
|
||||
randmax = shift_left (randmax) + UCHAR_MAX;
|
||||
i++;
|
||||
}
|
||||
while (randmax < genmax);
|
||||
}
|
||||
|
||||
if (randmax == genmax)
|
||||
{
|
||||
s->randnum = s->randmax = 0;
|
||||
return randnum;
|
||||
}
|
||||
{
|
||||
s->randnum = s->randmax = 0;
|
||||
return randnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GENMAX < RANDMAX, so attempt to generate a random number
|
||||
by taking RANDNUM modulo GENMAX+1. This will choose
|
||||
fairly so long as RANDNUM falls within an integral
|
||||
multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
|
||||
so discard this attempt and try again.
|
||||
{
|
||||
/* GENMAX < RANDMAX, so attempt to generate a random number
|
||||
by taking RANDNUM modulo GENMAX+1. This will choose
|
||||
fairly so long as RANDNUM falls within an integral
|
||||
multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
|
||||
so discard this attempt and try again.
|
||||
|
||||
Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
|
||||
zero and there is no need to worry about dividing by
|
||||
zero. */
|
||||
Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
|
||||
zero and there is no need to worry about dividing by
|
||||
zero. */
|
||||
|
||||
randint excess_choices = randmax - genmax;
|
||||
randint unusable_choices = excess_choices % choices;
|
||||
randint last_usable_choice = randmax - unusable_choices;
|
||||
randint reduced_randnum = randnum % choices;
|
||||
randint excess_choices = randmax - genmax;
|
||||
randint unusable_choices = excess_choices % choices;
|
||||
randint last_usable_choice = randmax - unusable_choices;
|
||||
randint reduced_randnum = randnum % choices;
|
||||
|
||||
if (randnum <= last_usable_choice)
|
||||
{
|
||||
s->randnum = randnum / choices;
|
||||
s->randmax = excess_choices / choices;
|
||||
return reduced_randnum;
|
||||
}
|
||||
if (randnum <= last_usable_choice)
|
||||
{
|
||||
s->randnum = randnum / choices;
|
||||
s->randmax = excess_choices / choices;
|
||||
return reduced_randnum;
|
||||
}
|
||||
|
||||
/* Retry, but retain the randomness from the fact that RANDNUM fell
|
||||
into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
|
||||
randnum = reduced_randnum;
|
||||
randmax = unusable_choices - 1;
|
||||
}
|
||||
/* Retry, but retain the randomness from the fact that RANDNUM fell
|
||||
into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
|
||||
randnum = reduced_randnum;
|
||||
randmax = unusable_choices - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,21 +79,21 @@ randperm_new (struct randint_source *r, size_t h, size_t n)
|
||||
|
||||
default:
|
||||
{
|
||||
size_t i;
|
||||
size_t i;
|
||||
|
||||
v = xnmalloc (n, sizeof *v);
|
||||
for (i = 0; i < n; i++)
|
||||
v[i] = i;
|
||||
v = xnmalloc (n, sizeof *v);
|
||||
for (i = 0; i < n; i++)
|
||||
v[i] = i;
|
||||
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
size_t j = i + randint_choose (r, n - i);
|
||||
size_t t = v[i];
|
||||
v[i] = v[j];
|
||||
v[j] = t;
|
||||
}
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
size_t j = i + randint_choose (r, n - i);
|
||||
size_t t = v[i];
|
||||
v[i] = v[j];
|
||||
v[j] = t;
|
||||
}
|
||||
|
||||
v = xnrealloc (v, h, sizeof *v);
|
||||
v = xnrealloc (v, h, sizeof *v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ struct randread_source
|
||||
/* Up to a buffer's worth of pseudorandom data. */
|
||||
union
|
||||
{
|
||||
uint32_t w[ISAAC_WORDS];
|
||||
unsigned char b[ISAAC_BYTES];
|
||||
uint32_t w[ISAAC_WORDS];
|
||||
unsigned char b[ISAAC_BYTES];
|
||||
} data;
|
||||
} isaac;
|
||||
} buf;
|
||||
@@ -115,8 +115,8 @@ randread_error (void const *file_name)
|
||||
{
|
||||
if (file_name)
|
||||
error (exit_failure, errno,
|
||||
_(errno == 0 ? "%s: end of file" : "%s: read error"),
|
||||
quotearg_colon (file_name));
|
||||
_(errno == 0 ? "%s: end of file" : "%s: read error"),
|
||||
quotearg_colon (file_name));
|
||||
abort ();
|
||||
}
|
||||
|
||||
@@ -155,18 +155,18 @@ randread_new (char const *name, size_t bytes_bound)
|
||||
struct randread_source *s;
|
||||
|
||||
if (name)
|
||||
if (! (source = fopen_safer (name, "rb")))
|
||||
return NULL;
|
||||
if (! (source = fopen_safer (name, "rb")))
|
||||
return NULL;
|
||||
|
||||
s = simple_new (source, name);
|
||||
|
||||
if (source)
|
||||
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
|
||||
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
|
||||
else
|
||||
{
|
||||
s->buf.isaac.buffered = 0;
|
||||
isaac_seed (&s->buf.isaac.state);
|
||||
}
|
||||
{
|
||||
s->buf.isaac.buffered = 0;
|
||||
isaac_seed (&s->buf.isaac.state);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -206,7 +206,7 @@ readsource (struct randread_source *s, unsigned char *p, size_t size)
|
||||
p += inbytes;
|
||||
size -= inbytes;
|
||||
if (size == 0)
|
||||
break;
|
||||
break;
|
||||
errno = (ferror (s->source) ? fread_errno : 0);
|
||||
s->handler (s->handler_arg);
|
||||
}
|
||||
@@ -224,34 +224,34 @@ readisaac (struct isaac *isaac, unsigned char *p, size_t size)
|
||||
for (;;)
|
||||
{
|
||||
if (size <= inbytes)
|
||||
{
|
||||
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);
|
||||
isaac->buffered = inbytes - size;
|
||||
return;
|
||||
}
|
||||
{
|
||||
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);
|
||||
isaac->buffered = inbytes - size;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, inbytes);
|
||||
p += inbytes;
|
||||
size -= inbytes;
|
||||
|
||||
/* If P is aligned, write to *P directly to avoid the overhead
|
||||
of copying from the buffer. */
|
||||
of copying from the buffer. */
|
||||
if (ALIGNED_POINTER (p, uint32_t))
|
||||
{
|
||||
uint32_t *wp = (uint32_t *) p;
|
||||
while (ISAAC_BYTES <= size)
|
||||
{
|
||||
isaac_refill (&isaac->state, wp);
|
||||
wp += ISAAC_WORDS;
|
||||
size -= ISAAC_BYTES;
|
||||
if (size == 0)
|
||||
{
|
||||
isaac->buffered = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = (unsigned char *) wp;
|
||||
}
|
||||
{
|
||||
uint32_t *wp = (uint32_t *) p;
|
||||
while (ISAAC_BYTES <= size)
|
||||
{
|
||||
isaac_refill (&isaac->state, wp);
|
||||
wp += ISAAC_WORDS;
|
||||
size -= ISAAC_BYTES;
|
||||
if (size == 0)
|
||||
{
|
||||
isaac->buffered = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = (unsigned char *) wp;
|
||||
}
|
||||
|
||||
isaac_refill (&isaac->state, isaac->data.w);
|
||||
inbytes = ISAAC_BYTES;
|
||||
|
||||
@@ -34,12 +34,12 @@ get_root_dev_ino (struct dev_ino *root_d_i);
|
||||
do \
|
||||
{ \
|
||||
if (STREQ (Dirname, "/")) \
|
||||
error (0, 0, _("it is dangerous to operate recursively on %s"), \
|
||||
quote (Dirname)); \
|
||||
error (0, 0, _("it is dangerous to operate recursively on %s"), \
|
||||
quote (Dirname)); \
|
||||
else \
|
||||
error (0, 0, \
|
||||
_("it is dangerous to operate recursively on %s (same as %s)"), \
|
||||
quote_n (0, Dirname), quote_n (1, "/")); \
|
||||
error (0, 0, \
|
||||
_("it is dangerous to operate recursively on %s (same as %s)"), \
|
||||
quote_n (0, Dirname), quote_n (1, "/")); \
|
||||
error (0, 0, _("use --no-preserve-root to override this failsafe")); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
# define TMP_MAX 238328
|
||||
#endif
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
# define __GT_BIGFILE 1
|
||||
# define __GT_FILE 1
|
||||
# define __GT_DIR 2
|
||||
# define __GT_NOCREATE 3
|
||||
#endif
|
||||
@@ -61,12 +60,9 @@
|
||||
|
||||
#if _LIBC
|
||||
# define struct_stat64 struct stat64
|
||||
# define small_open __open
|
||||
# define large_open __open64
|
||||
#else
|
||||
# define struct_stat64 struct stat
|
||||
# define small_open open
|
||||
# define large_open open
|
||||
# define __open open
|
||||
# define __gen_tempname gen_tempname
|
||||
# define __getpid getpid
|
||||
# define __gettimeofday gettimeofday
|
||||
@@ -96,7 +92,7 @@ direxists (const char *dir)
|
||||
enough space in TMPL. */
|
||||
int
|
||||
__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
|
||||
int try_tmpdir)
|
||||
int try_tmpdir)
|
||||
{
|
||||
const char *d;
|
||||
size_t dlen, plen;
|
||||
@@ -110,30 +106,30 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
|
||||
{
|
||||
plen = strlen (pfx);
|
||||
if (plen > 5)
|
||||
plen = 5;
|
||||
plen = 5;
|
||||
}
|
||||
|
||||
if (try_tmpdir)
|
||||
{
|
||||
d = __secure_getenv ("TMPDIR");
|
||||
if (d != NULL && direxists (d))
|
||||
dir = d;
|
||||
dir = d;
|
||||
else if (dir != NULL && direxists (dir))
|
||||
/* nothing */ ;
|
||||
/* nothing */ ;
|
||||
else
|
||||
dir = NULL;
|
||||
dir = NULL;
|
||||
}
|
||||
if (dir == NULL)
|
||||
{
|
||||
if (direxists (P_tmpdir))
|
||||
dir = P_tmpdir;
|
||||
dir = P_tmpdir;
|
||||
else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
|
||||
dir = "/tmp";
|
||||
dir = "/tmp";
|
||||
else
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dlen = strlen (dir);
|
||||
@@ -169,15 +165,14 @@ static const char letters[] =
|
||||
|
||||
KIND may be one of:
|
||||
__GT_NOCREATE: simply verify that the name does not exist
|
||||
at the time of the call.
|
||||
at the time of the call.
|
||||
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
|
||||
and return a read-write fd. The file is mode 0600.
|
||||
__GT_BIGFILE: same as __GT_FILE but use open64().
|
||||
and return a read-write fd. The file is mode 0600.
|
||||
__GT_DIR: create a directory, which will be mode 0700.
|
||||
|
||||
We use a clever algorithm to get hard-to-predict names. */
|
||||
int
|
||||
gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
|
||||
gen_tempname_len (char *tmpl, int flags, int kind, size_t x_suffix_len)
|
||||
{
|
||||
size_t len;
|
||||
char *XXXXXX;
|
||||
@@ -205,7 +200,7 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
|
||||
|
||||
len = strlen (tmpl);
|
||||
if (len < x_suffix_len || ! check_x_suffix (&tmpl[len - x_suffix_len],
|
||||
x_suffix_len))
|
||||
x_suffix_len))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
@@ -223,60 +218,58 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < x_suffix_len; i++)
|
||||
{
|
||||
XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
|
||||
}
|
||||
{
|
||||
XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
|
||||
}
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case __GT_FILE:
|
||||
fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
break;
|
||||
{
|
||||
case __GT_FILE:
|
||||
fd = __open (tmpl,
|
||||
(flags & ~0777) | O_RDWR | O_CREAT | O_EXCL,
|
||||
S_IRUSR | S_IWUSR);
|
||||
break;
|
||||
|
||||
case __GT_BIGFILE:
|
||||
fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
break;
|
||||
case __GT_DIR:
|
||||
fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
break;
|
||||
|
||||
case __GT_DIR:
|
||||
fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
break;
|
||||
case __GT_NOCREATE:
|
||||
/* This case is backward from the other three. This function
|
||||
succeeds if __xstat fails because the name does not exist.
|
||||
Note the continue to bypass the common logic at the bottom
|
||||
of the loop. */
|
||||
if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
fd = 0;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give up now. */
|
||||
fd = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case __GT_NOCREATE:
|
||||
/* This case is backward from the other three. This function
|
||||
succeeds if __xstat fails because the name does not exist.
|
||||
Note the continue to bypass the common logic at the bottom
|
||||
of the loop. */
|
||||
if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
fd = 0;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give up now. */
|
||||
fd = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
assert (! "invalid KIND in __gen_tempname");
|
||||
}
|
||||
default:
|
||||
assert (! "invalid KIND in __gen_tempname");
|
||||
}
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
goto done;
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
{
|
||||
fd = -1;
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
fd = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
randint_all_free (rand_src);
|
||||
@@ -295,7 +288,7 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
|
||||
}
|
||||
|
||||
int
|
||||
__gen_tempname (char *tmpl, int kind)
|
||||
__gen_tempname (char *tmpl, int flags, int kind)
|
||||
{
|
||||
return gen_tempname_len (tmpl, kind, 6);
|
||||
return gen_tempname_len (tmpl, flags, kind, 6);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,13 @@
|
||||
|
||||
KIND may be one of:
|
||||
GT_NOCREATE: simply verify that the name does not exist
|
||||
at the time of the call.
|
||||
at the time of the call.
|
||||
GT_FILE: create a large file using open(O_CREAT|O_EXCL)
|
||||
and return a read-write fd. The file is mode 0600.
|
||||
and return a read-write fd. The file is mode 0600.
|
||||
GT_DIR: create a directory, which will be mode 0700.
|
||||
|
||||
We use a clever algorithm to get hard-to-predict names. */
|
||||
#include <stddef.h>
|
||||
extern int gen_tempname (char *tmpl, int kind);
|
||||
extern int gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len);
|
||||
extern int gen_tempname (char *tmpl, int flags, int kind);
|
||||
extern int gen_tempname_len (char *tmpl, int flags, int kind,
|
||||
size_t x_suffix_len);
|
||||
|
||||
@@ -31,11 +31,11 @@ xfreopen (char const *filename, char const *mode, FILE *fp)
|
||||
if (!freopen (filename, mode, fp))
|
||||
{
|
||||
char const *f = (filename ? filename
|
||||
: (fp == stdin ? _("stdin")
|
||||
: (fp == stdout ? _("stdout")
|
||||
: (fp == stderr ? _("stderr")
|
||||
: _("unknown stream")))));
|
||||
: (fp == stdin ? _("stdin")
|
||||
: (fp == stdout ? _("stdout")
|
||||
: (fp == stderr ? _("stderr")
|
||||
: _("unknown stream")))));
|
||||
error (exit_failure, errno, _("failed to reopen %s with mode %s"),
|
||||
quote_n (0, f), quote_n (1, mode));
|
||||
quote_n (0, f), quote_n (1, mode));
|
||||
}
|
||||
}
|
||||
|
||||
2
gnulib
2
gnulib
Submodule gnulib updated: 3ef64012bf...6f6420cc97
@@ -34,22 +34,22 @@ buffer_lcm (size_t a, size_t b, size_t lcm_max)
|
||||
else
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
/* Return lcm (A, B) if it is in range; otherwise, fall back
|
||||
on A. */
|
||||
{
|
||||
/* Return lcm (A, B) if it is in range; otherwise, fall back
|
||||
on A. */
|
||||
|
||||
size_t lcm, m, n, q, r;
|
||||
size_t lcm, m, n, q, r;
|
||||
|
||||
/* N = gcd (A, B). */
|
||||
for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
|
||||
continue;
|
||||
/* N = gcd (A, B). */
|
||||
for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
|
||||
continue;
|
||||
|
||||
/* LCM = lcm (A, B), if in range. */
|
||||
q = a / n;
|
||||
lcm = q * b;
|
||||
if (lcm <= lcm_max && lcm / b == q)
|
||||
return lcm;
|
||||
}
|
||||
/* LCM = lcm (A, B), if in range. */
|
||||
q = a / n;
|
||||
lcm = q * b;
|
||||
if (lcm <= lcm_max && lcm / b == q)
|
||||
return lcm;
|
||||
}
|
||||
|
||||
size = a;
|
||||
}
|
||||
|
||||
@@ -25,13 +25,6 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
# define X_OK 1
|
||||
# define W_OK 2
|
||||
# define R_OK 4
|
||||
#endif
|
||||
|
||||
#include "group-member.h"
|
||||
#include "stat-macros.h"
|
||||
|
||||
@@ -57,8 +50,8 @@ euidaccess_stat (struct stat const *st, int mode)
|
||||
mode &= 7;
|
||||
else
|
||||
mode = ((mode & R_OK ? 4 : 0)
|
||||
+ (mode & W_OK ? 2 : 0)
|
||||
+ (mode & X_OK ? 1 : 0));
|
||||
+ (mode & W_OK ? 2 : 0)
|
||||
+ (mode & X_OK ? 1 : 0));
|
||||
|
||||
if (mode == 0)
|
||||
return true; /* The file exists. */
|
||||
@@ -68,7 +61,7 @@ euidaccess_stat (struct stat const *st, int mode)
|
||||
/* The super-user can read and write any file, and execute any file
|
||||
that anyone can execute. */
|
||||
if (euid == 0 && ((mode & X_OK) == 0
|
||||
|| (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
|
||||
|| (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
|
||||
return true;
|
||||
|
||||
/* Convert the file's permission bits to traditional form. */
|
||||
@@ -84,14 +77,14 @@ euidaccess_stat (struct stat const *st, int mode)
|
||||
granted = st->st_mode;
|
||||
else
|
||||
granted = ( (st->st_mode & S_IRUSR ? 4 << 6 : 0)
|
||||
+ (st->st_mode & S_IWUSR ? 2 << 6 : 0)
|
||||
+ (st->st_mode & S_IXUSR ? 1 << 6 : 0)
|
||||
+ (st->st_mode & S_IRGRP ? 4 << 3 : 0)
|
||||
+ (st->st_mode & S_IWGRP ? 2 << 3 : 0)
|
||||
+ (st->st_mode & S_IXGRP ? 1 << 3 : 0)
|
||||
+ (st->st_mode & S_IROTH ? 4 << 0 : 0)
|
||||
+ (st->st_mode & S_IWOTH ? 2 << 0 : 0)
|
||||
+ (st->st_mode & S_IXOTH ? 1 << 0 : 0));
|
||||
+ (st->st_mode & S_IWUSR ? 2 << 6 : 0)
|
||||
+ (st->st_mode & S_IXUSR ? 1 << 6 : 0)
|
||||
+ (st->st_mode & S_IRGRP ? 4 << 3 : 0)
|
||||
+ (st->st_mode & S_IWGRP ? 2 << 3 : 0)
|
||||
+ (st->st_mode & S_IXGRP ? 1 << 3 : 0)
|
||||
+ (st->st_mode & S_IROTH ? 4 << 0 : 0)
|
||||
+ (st->st_mode & S_IWOTH ? 2 << 0 : 0)
|
||||
+ (st->st_mode & S_IXOTH ? 1 << 0 : 0));
|
||||
|
||||
if (euid == st->st_uid)
|
||||
granted >>= 6;
|
||||
@@ -99,7 +92,7 @@ euidaccess_stat (struct stat const *st, int mode)
|
||||
{
|
||||
gid_t egid = getegid ();
|
||||
if (egid == st->st_gid || group_member (st->st_gid))
|
||||
granted >>= 3;
|
||||
granted >>= 3;
|
||||
}
|
||||
|
||||
if ((mode & ~granted) == 0)
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/* fdopendir implementation derived from glibc.
|
||||
|
||||
Copyright (C) 2006, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if _LIBC
|
||||
# include <dirstream.h>
|
||||
# include <not-cancel.h>
|
||||
|
||||
#else
|
||||
|
||||
# if __GNUC__ < 3
|
||||
# define __builtin_expect(expr, expected_val) expr
|
||||
# endif
|
||||
|
||||
# include "openat.h"
|
||||
# define stat64 stat
|
||||
# define dirent64 dirent
|
||||
# define __fxstat64(V, fd, sb) fstat(fd, sb)
|
||||
# define __fcntl fcntl
|
||||
# define __set_errno(Val) do { errno = (Val); } while (0)
|
||||
# define __libc_lock_init(NAME) ((NAME) = 0, 0)
|
||||
# define close_not_cancel_no_status(fd) close (fd)
|
||||
# ifdef __i386__
|
||||
# define internal_function __attribute ((regparm (3), stdcall))
|
||||
# else
|
||||
# define internal_function
|
||||
# endif
|
||||
|
||||
struct __dirstream
|
||||
{
|
||||
int fd; /* File descriptor. */
|
||||
|
||||
char *data; /* Directory block. */
|
||||
size_t allocation; /* Space allocated for the block. */
|
||||
size_t size; /* Total valid data in the block. */
|
||||
size_t offset; /* Current offset into the block. */
|
||||
|
||||
off_t filepos; /* Position of next entry to read. */
|
||||
int lock;
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef _STATBUF_ST_BLKSIZE
|
||||
|
||||
static DIR *
|
||||
internal_function
|
||||
__alloc_dir (int fd, bool close_fd)
|
||||
{
|
||||
if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
|
||||
goto lose;
|
||||
|
||||
size_t allocation;
|
||||
#ifdef _STATBUF_ST_BLKSIZE
|
||||
if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
|
||||
1))
|
||||
allocation = statp->st_blksize;
|
||||
else
|
||||
#endif
|
||||
allocation = (BUFSIZ < sizeof (struct dirent64)
|
||||
? sizeof (struct dirent64) : BUFSIZ);
|
||||
|
||||
const int pad = -sizeof (DIR) % __alignof__ (struct dirent64);
|
||||
|
||||
DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation + pad);
|
||||
if (dirp == NULL)
|
||||
lose:
|
||||
{
|
||||
if (close_fd)
|
||||
{
|
||||
int save_errno = errno;
|
||||
close_not_cancel_no_status (fd);
|
||||
__set_errno (save_errno);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
memset (dirp, '\0', sizeof (DIR));
|
||||
dirp->data = (char *) (dirp + 1) + pad;
|
||||
dirp->allocation = allocation;
|
||||
dirp->fd = fd;
|
||||
|
||||
__libc_lock_init (dirp->lock);
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
||||
DIR *
|
||||
fdopendir (int fd)
|
||||
{
|
||||
#if 0
|
||||
struct stat64 statbuf;
|
||||
|
||||
if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
|
||||
return NULL;
|
||||
if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
|
||||
{
|
||||
__set_errno (ENOTDIR);
|
||||
return NULL;
|
||||
}
|
||||
/* Make sure the descriptor allows for reading. */
|
||||
int flags = __fcntl (fd, F_GETFL);
|
||||
if (__builtin_expect (flags == -1, 0))
|
||||
return NULL;
|
||||
if (__builtin_expect ((flags & O_ACCMODE) == O_WRONLY, 0))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return __alloc_dir (fd, false);
|
||||
}
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
size_t
|
||||
memxfrm (char *restrict dest, size_t destsize,
|
||||
char *restrict src, size_t srcsize)
|
||||
char *restrict src, size_t srcsize)
|
||||
{
|
||||
#if HAVE_STRXFRM
|
||||
|
||||
@@ -59,33 +59,33 @@ memxfrm (char *restrict dest, size_t destsize,
|
||||
errno = 0;
|
||||
result += strxfrm (dest + di, src + si, destsize - di) + 1;
|
||||
if (errno != 0)
|
||||
break;
|
||||
break;
|
||||
if (result <= result0)
|
||||
{
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
{
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == destsize + 1 && si + slen == srcsize)
|
||||
{
|
||||
/* The destination is exactly the right size, but strxfrm wants
|
||||
room for a trailing null. Work around the problem with a
|
||||
temporary buffer. */
|
||||
size_t bufsize = destsize - di + 1;
|
||||
char stackbuf[4000];
|
||||
char *buf = stackbuf;
|
||||
if (sizeof stackbuf < bufsize)
|
||||
{
|
||||
buf = malloc (bufsize);
|
||||
if (! buf)
|
||||
break;
|
||||
}
|
||||
strxfrm (buf, src + si, bufsize);
|
||||
memcpy (dest + di, buf, destsize - di);
|
||||
if (sizeof stackbuf < bufsize)
|
||||
free (buf);
|
||||
errno = 0;
|
||||
}
|
||||
{
|
||||
/* The destination is exactly the right size, but strxfrm wants
|
||||
room for a trailing null. Work around the problem with a
|
||||
temporary buffer. */
|
||||
size_t bufsize = destsize - di + 1;
|
||||
char stackbuf[4000];
|
||||
char *buf = stackbuf;
|
||||
if (sizeof stackbuf < bufsize)
|
||||
{
|
||||
buf = malloc (bufsize);
|
||||
if (! buf)
|
||||
break;
|
||||
}
|
||||
strxfrm (buf, src + si, bufsize);
|
||||
memcpy (dest + di, buf, destsize - di);
|
||||
if (sizeof stackbuf < bufsize)
|
||||
free (buf);
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
di = (result < destsize ? result : destsize);
|
||||
si += slen + 1;
|
||||
|
||||
@@ -77,28 +77,28 @@ fraccompare (char const *a, char const *b, char decimal_point)
|
||||
if (*a == decimal_point && *b == decimal_point)
|
||||
{
|
||||
while (*++a == *++b)
|
||||
if (! ISDIGIT (*a))
|
||||
return 0;
|
||||
if (! ISDIGIT (*a))
|
||||
return 0;
|
||||
if (ISDIGIT (*a) && ISDIGIT (*b))
|
||||
return *a - *b;
|
||||
return *a - *b;
|
||||
if (ISDIGIT (*a))
|
||||
goto a_trailing_nonzero;
|
||||
goto a_trailing_nonzero;
|
||||
if (ISDIGIT (*b))
|
||||
goto b_trailing_nonzero;
|
||||
goto b_trailing_nonzero;
|
||||
return 0;
|
||||
}
|
||||
else if (*a++ == decimal_point)
|
||||
{
|
||||
a_trailing_nonzero:
|
||||
while (*a == NUMERIC_ZERO)
|
||||
a++;
|
||||
a++;
|
||||
return ISDIGIT (*a);
|
||||
}
|
||||
else if (*b++ == decimal_point)
|
||||
{
|
||||
b_trailing_nonzero:
|
||||
while (*b == NUMERIC_ZERO)
|
||||
b++;
|
||||
b++;
|
||||
return - ISDIGIT (*b);
|
||||
}
|
||||
return 0;
|
||||
@@ -113,7 +113,7 @@ fraccompare (char const *a, char const *b, char decimal_point)
|
||||
|
||||
static inline int
|
||||
numcompare (char const *a, char const *b,
|
||||
int decimal_point, int thousands_sep)
|
||||
int decimal_point, int thousands_sep)
|
||||
{
|
||||
unsigned char tmpa = *a;
|
||||
unsigned char tmpb = *b;
|
||||
@@ -124,119 +124,119 @@ numcompare (char const *a, char const *b,
|
||||
if (tmpa == NEGATION_SIGN)
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep);
|
||||
if (tmpb != NEGATION_SIGN)
|
||||
{
|
||||
if (tmpa == decimal_point)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpa))
|
||||
return -1;
|
||||
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
|
||||
tmpb = *++b;
|
||||
if (tmpb == decimal_point)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
return - ISDIGIT (tmpb);
|
||||
}
|
||||
{
|
||||
if (tmpa == decimal_point)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpa))
|
||||
return -1;
|
||||
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
|
||||
tmpb = *++b;
|
||||
if (tmpb == decimal_point)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
return - ISDIGIT (tmpb);
|
||||
}
|
||||
do
|
||||
tmpb = *++b;
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep);
|
||||
|
||||
while (tmpa == tmpb && ISDIGIT (tmpa))
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
}
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
}
|
||||
|
||||
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return fraccompare (b, a, decimal_point);
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return fraccompare (b, a, decimal_point);
|
||||
|
||||
tmp = tmpb - tmpa;
|
||||
|
||||
for (log_a = 0; ISDIGIT (tmpa); ++log_a)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
|
||||
for (log_b = 0; ISDIGIT (tmpb); ++log_b)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
|
||||
if (log_a != log_b)
|
||||
return log_a < log_b ? 1 : -1;
|
||||
return log_a < log_b ? 1 : -1;
|
||||
|
||||
if (!log_a)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
else if (tmpb == NEGATION_SIGN)
|
||||
{
|
||||
do
|
||||
tmpb = *++b;
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep);
|
||||
if (tmpb == decimal_point)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == NUMERIC_ZERO);
|
||||
if (ISDIGIT (tmpb))
|
||||
return 1;
|
||||
return 1;
|
||||
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep)
|
||||
tmpa = *++a;
|
||||
tmpa = *++a;
|
||||
if (tmpa == decimal_point)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == NUMERIC_ZERO);
|
||||
return ISDIGIT (tmpa);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep)
|
||||
tmpa = *++a;
|
||||
tmpa = *++a;
|
||||
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
|
||||
tmpb = *++b;
|
||||
tmpb = *++b;
|
||||
|
||||
while (tmpa == tmpb && ISDIGIT (tmpa))
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
}
|
||||
{
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
}
|
||||
|
||||
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return fraccompare (a, b, decimal_point);
|
||||
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
|
||||
return fraccompare (a, b, decimal_point);
|
||||
|
||||
tmp = tmpa - tmpb;
|
||||
|
||||
for (log_a = 0; ISDIGIT (tmpa); ++log_a)
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
do
|
||||
tmpa = *++a;
|
||||
while (tmpa == thousands_sep);
|
||||
|
||||
for (log_b = 0; ISDIGIT (tmpb); ++log_b)
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
do
|
||||
tmpb = *++b;
|
||||
while (tmpb == thousands_sep);
|
||||
|
||||
if (log_a != log_b)
|
||||
return log_a < log_b ? -1 : 1;
|
||||
return log_a < log_b ? -1 : 1;
|
||||
|
||||
if (!log_a)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
int
|
||||
strnumcmp (char const *a, char const *b,
|
||||
int decimal_point, int thousands_sep)
|
||||
int decimal_point, int thousands_sep)
|
||||
{
|
||||
return numcompare (a, b, decimal_point, thousands_sep);
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@ function mkdir_len
|
||||
( cd $root &&
|
||||
perl -e 'my $len='$n'-length "'$root'";$i=100;$d="z"x$i;
|
||||
while ($i+2 < $len) {
|
||||
$len -= $i + 1;
|
||||
mkdir $d,0700 or die "$!\n";
|
||||
chdir $d} $d="z"x($len-1);
|
||||
mkdir $d or die "mkdir_len: $d: $!\n"' )
|
||||
$len -= $i + 1;
|
||||
mkdir $d,0700 or die "$!\n";
|
||||
chdir $d} $d="z"x($len-1);
|
||||
mkdir $d or die "mkdir_len: $d: $!\n"' )
|
||||
}
|
||||
|
||||
size_list=
|
||||
|
||||
26
lib/xfts.c
26
lib/xfts.c
@@ -35,28 +35,28 @@
|
||||
|
||||
FTS *
|
||||
xfts_open (char * const *argv, int options,
|
||||
int (*compar) (const FTSENT **, const FTSENT **))
|
||||
int (*compar) (const FTSENT **, const FTSENT **))
|
||||
{
|
||||
FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
|
||||
if (fts == NULL)
|
||||
{
|
||||
/* This can fail in three ways: out of memory, invalid bit_flags,
|
||||
and one or more of the FILES is an empty string. We could try
|
||||
to decipher that errno==EINVAL means invalid bit_flags and
|
||||
errno==ENOENT means there's an empty string, but that seems wrong.
|
||||
Ideally, fts_open would return a proper error indicator. For now,
|
||||
we'll presume that the bit_flags are valid and just check for
|
||||
empty strings. */
|
||||
and one or more of the FILES is an empty string. We could try
|
||||
to decipher that errno==EINVAL means invalid bit_flags and
|
||||
errno==ENOENT means there's an empty string, but that seems wrong.
|
||||
Ideally, fts_open would return a proper error indicator. For now,
|
||||
we'll presume that the bit_flags are valid and just check for
|
||||
empty strings. */
|
||||
bool invalid_arg = false;
|
||||
for (; *argv; ++argv)
|
||||
{
|
||||
if (**argv == '\0')
|
||||
invalid_arg = true;
|
||||
}
|
||||
{
|
||||
if (**argv == '\0')
|
||||
invalid_arg = true;
|
||||
}
|
||||
if (invalid_arg)
|
||||
error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
|
||||
error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
|
||||
else
|
||||
xalloc_die ();
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
return fts;
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
FTS *
|
||||
xfts_open (char * const *, int options,
|
||||
int (*) (const FTSENT **, const FTSENT **));
|
||||
int (*) (const FTSENT **, const FTSENT **));
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
size_t
|
||||
xmemxfrm (char *restrict dest, size_t destsize,
|
||||
char *restrict src, size_t srcsize)
|
||||
char *restrict src, size_t srcsize)
|
||||
{
|
||||
size_t translated_size = memxfrm (dest, destsize, src, srcsize);
|
||||
|
||||
@@ -54,8 +54,8 @@ xmemxfrm (char *restrict dest, size_t destsize,
|
||||
error (0, errno, _("string transformation failed"));
|
||||
error (0, 0, _("set LC_ALL='C' to work around the problem"));
|
||||
error (exit_failure, 0,
|
||||
_("the untransformed string was %s"),
|
||||
quotearg_n_style_mem (0, locale_quoting_style, src, srcsize));
|
||||
_("the untransformed string was %s"),
|
||||
quotearg_n_style_mem (0, locale_quoting_style, src, srcsize));
|
||||
}
|
||||
|
||||
return translated_size;
|
||||
|
||||
@@ -36,8 +36,8 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
|
||||
gl_no_install_progs_default=`echo '$2'|sed 's/,/ /g'`
|
||||
AC_ARG_ENABLE([install-program],
|
||||
[AS_HELP_STRING([--enable-install-program=PROG_LIST],
|
||||
[install the programs in PROG_LIST (comma-separated,
|
||||
default: none)])],
|
||||
[install the programs in PROG_LIST (comma-separated,
|
||||
default: none)])],
|
||||
[gl_do_install_prog=$enableval],
|
||||
[gl_do_install_prog=]
|
||||
)
|
||||
@@ -46,8 +46,8 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
|
||||
# use --enable-no-install-program=A,B
|
||||
AC_ARG_ENABLE([no-install-program],
|
||||
[AS_HELP_STRING([--enable-no-install-program=PROG_LIST],
|
||||
[do NOT install the programs in PROG_LIST
|
||||
(comma-separated, default: $2)])],
|
||||
[do NOT install the programs in PROG_LIST
|
||||
(comma-separated, default: $2)])],
|
||||
[gl_no_install_prog=$enableval],
|
||||
[gl_no_install_prog=]
|
||||
)
|
||||
@@ -78,7 +78,7 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
|
||||
# Warn about a request not to install a program that is
|
||||
# already on the default-no-install list.
|
||||
case " $gl_no_install_progs_default " in
|
||||
*" $gl_i "*) gl_msg="by default, '$gl_i' is not installed" ;;
|
||||
*" $gl_i "*) gl_msg="by default, '$gl_i' is not installed" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ AC_DEFUN([coreutils_MACROS],
|
||||
|
||||
# By default, argmatch should fail calling usage (1).
|
||||
AC_DEFINE([ARGMATCH_DIE], [usage (1)],
|
||||
[Define to the function xargmatch calls on failures.])
|
||||
[Define to the function xargmatch calls on failures.])
|
||||
AC_DEFINE([ARGMATCH_DIE_DECL], [void usage (int _e)],
|
||||
[Define to the declaration of the xargmatch failure function.])
|
||||
[Define to the declaration of the xargmatch failure function.])
|
||||
|
||||
# used by ls
|
||||
AC_REQUIRE([gl_CLOCK_TIME])
|
||||
@@ -52,13 +52,13 @@ AC_DEFUN([coreutils_MACROS],
|
||||
AC_CHECK_FUNCS([matchpathcon_init_prefix], [],
|
||||
[
|
||||
case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in
|
||||
no:*) # SELinux disabled
|
||||
;;
|
||||
*:no) # SELinux disabled
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found])
|
||||
AC_MSG_WARN([The install utility may run slowly])
|
||||
no:*) # SELinux disabled
|
||||
;;
|
||||
*:no) # SELinux disabled
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found])
|
||||
AC_MSG_WARN([The install utility may run slowly])
|
||||
esac
|
||||
])
|
||||
LIBS=$coreutils_saved_libs
|
||||
@@ -98,24 +98,32 @@ AC_DEFUN([coreutils_MACROS],
|
||||
# for dd.c and shred.c
|
||||
coreutils_saved_libs=$LIBS
|
||||
AC_SEARCH_LIBS([fdatasync], [rt posix4],
|
||||
[test "$ac_cv_search_fdatasync" = "none required" ||
|
||||
LIB_FDATASYNC=$ac_cv_search_fdatasync])
|
||||
[test "$ac_cv_search_fdatasync" = "none required" ||
|
||||
LIB_FDATASYNC=$ac_cv_search_fdatasync])
|
||||
AC_SUBST([LIB_FDATASYNC])
|
||||
AC_CHECK_FUNCS([fdatasync])
|
||||
LIBS=$coreutils_saved_libs
|
||||
|
||||
# Check whether libcap is usable -- for ls --color support
|
||||
LIB_CAP=
|
||||
AC_ARG_ENABLE([libcap],
|
||||
AC_HELP_STRING([--disable-libcap], [disable libcap support]),
|
||||
AC_MSG_WARN([libcap support disabled by user]),
|
||||
[AC_CHECK_LIB([cap], [cap_get_file],
|
||||
AC_HELP_STRING([--disable-libcap], [disable libcap support]))
|
||||
if test "X$enable_libcap" != "Xno"; then
|
||||
AC_CHECK_LIB([cap], [cap_get_file],
|
||||
[AC_CHECK_HEADER([sys/capability.h],
|
||||
[LIB_CAP=-lcap
|
||||
AC_DEFINE([HAVE_CAP], [1], [libcap usability])],
|
||||
[AC_MSG_WARN([header sys/capability.h was not found, support for libcap will not be built])]
|
||||
)],
|
||||
[AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])])
|
||||
])
|
||||
[LIB_CAP=-lcap
|
||||
AC_DEFINE([HAVE_CAP], [1], [libcap usability])]
|
||||
)])
|
||||
if test "X$LIB_CAP" = "X"; then
|
||||
if test "X$enable_libcap" = "Xyes"; then
|
||||
AC_MSG_ERROR([libcap library was not found or not usable])
|
||||
else
|
||||
AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([libcap support disabled by user])
|
||||
fi
|
||||
AC_SUBST([LIB_CAP])
|
||||
|
||||
# See if linking `seq' requires -lm.
|
||||
|
||||
@@ -53,8 +53,8 @@ $ac_includes_default
|
||||
# NetBSD needs -lcrypt for crypt.
|
||||
cu_saved_libs="$LIBS"
|
||||
AC_SEARCH_LIBS([crypt], [ufc crypt],
|
||||
[test "$ac_cv_search_crypt" = "none required" ||
|
||||
LIB_CRYPT="$ac_cv_search_crypt"])
|
||||
[test "$ac_cv_search_crypt" = "none required" ||
|
||||
LIB_CRYPT="$ac_cv_search_crypt"])
|
||||
LIBS="$cu_saved_libs"
|
||||
AC_SUBST([LIB_CRYPT])
|
||||
])
|
||||
|
||||
@@ -57,30 +57,30 @@ AC_INCLUDES_DEFAULT
|
||||
{ AC_CHECK_MEMBERS([struct statvfs.f_basetype],,, [$statvfs_includes])
|
||||
test $ac_cv_member_struct_statvfs_f_basetype = yes ||
|
||||
{ AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,, [$statvfs_includes])
|
||||
test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
|
||||
{ test $ac_cv_member_struct_statfs_f_fstypename != yes &&
|
||||
{ AC_CHECK_MEMBERS([struct statvfs.f_type],,, [$statvfs_includes])
|
||||
test $ac_cv_member_struct_statvfs_f_type = yes; }; }; }; }
|
||||
test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
|
||||
{ test $ac_cv_member_struct_statfs_f_fstypename != yes &&
|
||||
{ AC_CHECK_MEMBERS([struct statvfs.f_type],,, [$statvfs_includes])
|
||||
test $ac_cv_member_struct_statvfs_f_type = yes; }; }; }; }
|
||||
then
|
||||
AC_CHECK_MEMBERS([struct statvfs.f_namemax],,, [$statvfs_includes])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[$statvfs_includes],
|
||||
[static statvfs s;
|
||||
return (s.s_fsid ^ 0) == 0;])],
|
||||
[$statvfs_includes],
|
||||
[static statvfs s;
|
||||
return (s.s_fsid ^ 0) == 0;])],
|
||||
[AC_DEFINE([STRUCT_STATVFS_F_FSID_IS_INTEGER], [1],
|
||||
[Define to 1 if the f_fsid member of struct statvfs is an integer.])])
|
||||
[Define to 1 if the f_fsid member of struct statvfs is an integer.])])
|
||||
else
|
||||
AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type],,,
|
||||
[$statfs_includes])
|
||||
if test $ac_cv_header_OS_h != yes; then
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[$statfs_includes],
|
||||
[static statfs s;
|
||||
return (s.s_fsid ^ 0) == 0;])],
|
||||
[AC_DEFINE([STRUCT_STATFS_F_FSID_IS_INTEGER], [1],
|
||||
[Define to 1 if the f_fsid member of struct statfs is an integer.])])
|
||||
[AC_LANG_PROGRAM(
|
||||
[$statfs_includes],
|
||||
[static statfs s;
|
||||
return (s.s_fsid ^ 0) == 0;])],
|
||||
[AC_DEFINE([STRUCT_STATFS_F_FSID_IS_INTEGER], [1],
|
||||
[Define to 1 if the f_fsid member of struct statfs is an integer.])])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
12
m4/xattr.m4
12
m4/xattr.m4
@@ -11,9 +11,9 @@
|
||||
AC_DEFUN([gl_FUNC_XATTR],
|
||||
[
|
||||
AC_ARG_ENABLE([xattr],
|
||||
AC_HELP_STRING([--disable-xattr],
|
||||
[do not support extended attributes]),
|
||||
[use_xattr=$enableval], [use_xattr=yes])
|
||||
AC_HELP_STRING([--disable-xattr],
|
||||
[do not support extended attributes]),
|
||||
[use_xattr=$enableval], [use_xattr=yes])
|
||||
|
||||
if test "$use_xattr" = "yes"; then
|
||||
AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h])
|
||||
@@ -24,11 +24,11 @@ AC_DEFUN([gl_FUNC_XATTR],
|
||||
use_xattr=0
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([USE_XATTR], [$use_xattr],
|
||||
[Define if you want extended attribute support.])
|
||||
[Define if you want extended attribute support.])
|
||||
xattr_saved_LIBS=$LIBS
|
||||
AC_SEARCH_LIBS([attr_copy_file], [attr],
|
||||
[test "$ac_cv_search_attr_copy_file" = "none required" ||
|
||||
LIB_XATTR=$ac_cv_search_attr_copy_file])
|
||||
[test "$ac_cv_search_attr_copy_file" = "none required" ||
|
||||
LIB_XATTR=$ac_cv_search_attr_copy_file])
|
||||
AC_CHECK_FUNCS([attr_copy_file])
|
||||
LIBS=$xattr_saved_LIBS
|
||||
AC_SUBST([LIB_XATTR])
|
||||
|
||||
@@ -373,6 +373,7 @@ my $PAT_AUTHOR = _('Written +by');
|
||||
my $PAT_OPTIONS = _('Options');
|
||||
my $PAT_EXAMPLES = _('Examples');
|
||||
my $PAT_FREE_SOFTWARE = _('This +is +free +software');
|
||||
my $PAT_INFO = _('For +complete +documentation');
|
||||
|
||||
# Start a new paragraph (if required) for these.
|
||||
s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR)/$1\n\n$2/og;
|
||||
@@ -392,6 +393,11 @@ while (length)
|
||||
$sect = _('EXAMPLES');
|
||||
next;
|
||||
}
|
||||
# Skip any texinfo reference as that's handled separately
|
||||
if (s/($PAT_INFO).*\n//o)
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Copyright section
|
||||
if (/^Copyright +[(\xa9]/)
|
||||
|
||||
@@ -504,17 +504,17 @@ Changes in release 4.0:
|
||||
* ls accepts new options:
|
||||
--indicator-style=none (no indicators, the default)
|
||||
--indicator-style=classify (all indicators)
|
||||
(equivalent to -F or --classify)
|
||||
(equivalent to -F or --classify)
|
||||
--indicator-style=file-type (file type indicators)
|
||||
(equivalent to -p or --file-type)
|
||||
(equivalent to -p or --file-type)
|
||||
|
||||
--quoting-style=literal (do not quote output)
|
||||
--quoting-style=shell (minimally quote output for the shell)
|
||||
--quoting-style=shell-always (always quote output with '' for the shell)
|
||||
--quoting-style=c (quote output as for a C-language string)
|
||||
(equivalent to -Q or --quote-name)
|
||||
(equivalent to -Q or --quote-name)
|
||||
--quoting-style=escape (like c but omit enclosing "")
|
||||
(equivalent to -b or --escape)
|
||||
(equivalent to -b or --escape)
|
||||
|
||||
--show-control-chars is the opposite of --hide-control-chars
|
||||
This option can be useful if output is to a terminal,
|
||||
|
||||
@@ -20,6 +20,8 @@ lib/regcomp.c
|
||||
lib/root-dev-ino.h
|
||||
lib/rpmatch.c
|
||||
lib/set-mode-acl.c
|
||||
lib/siglist.h
|
||||
lib/strsignal.c
|
||||
lib/unicodeio.c
|
||||
lib/userspec.c
|
||||
lib/verror.c
|
||||
|
||||
@@ -385,21 +385,21 @@ pr = progs-readme
|
||||
check: check-README check-duplicate-no-install
|
||||
.PHONY: check-README
|
||||
check-README:
|
||||
rm -rf $(pr) $(pm)
|
||||
echo $(all_programs) \
|
||||
$(AM_V_GEN)rm -rf $(pr) $(pm)
|
||||
$(AM_V_at)echo $(all_programs) \
|
||||
| tr -s ' ' '\n' | sed -e 's,$(EXEEXT)$$,,;s/ginstall/install/' \
|
||||
| sed /libstdbuf/d \
|
||||
| $(ASSORT) -u > $(pm) && \
|
||||
sed -n '/^The programs .* are:/,/^[a-zA-Z]/p' $(top_srcdir)/README \
|
||||
| sed -n '/^ */s///p' | tr -s ' ' '\n' > $(pr)
|
||||
diff $(pm) $(pr) && rm -rf $(pr) $(pm)
|
||||
$(AM_V_at)diff $(pm) $(pr) && rm -rf $(pr) $(pm)
|
||||
|
||||
# Ensure that a by-default-not-installed program (listed in
|
||||
# $(no_install__progs) is not also listed in $(EXTRA_PROGRAMS), because
|
||||
# if that were to happen, it *would* be installed by default.
|
||||
.PHONY: check-duplicate-no-install
|
||||
check-duplicate-no-install: tr
|
||||
test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`"
|
||||
$(AM_V_GEN)test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`"
|
||||
|
||||
# Ensure that the list of programs and author names is accurate.
|
||||
# We need a UTF8 locale. If a lack of locale support or a missing
|
||||
@@ -453,7 +453,7 @@ sc_tight_scope: $(bin_PROGRAMS)
|
||||
( printf 'main\nusage\n_.*\n'; \
|
||||
grep -h -A1 '^extern .*[^;]$$' $$src \
|
||||
| grep -vE '^(extern |--)' | sed 's/ .*//'; \
|
||||
perl -ne '/^extern \S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
|
||||
perl -ne '/^extern (?:enum )?\S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
|
||||
) | $(ASSORT) -u | sed 's/^/^/;s/$$/$$/' > $$t; \
|
||||
nm -e *.$(OBJEXT) \
|
||||
| sed -n 's/.* T //p' \
|
||||
|
||||
150
src/base64.c
150
src/base64.c
@@ -53,7 +53,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -80,8 +80,8 @@ The data are encoded as described for the base64 alphabet in RFC 3548.\n\
|
||||
When decoding, the input may contain newlines in addition to the bytes of\n\
|
||||
the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\
|
||||
from any other non-alphabet bytes in the encoded stream.\n"),
|
||||
stdout);
|
||||
emit_bug_reporting_address ();
|
||||
stdout);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
|
||||
exit (status);
|
||||
@@ -99,7 +99,7 @@ from any other non-alphabet bytes in the encoded stream.\n"),
|
||||
|
||||
static void
|
||||
wrap_write (const char *buffer, size_t len,
|
||||
uintmax_t wrap_column, size_t *current_column, FILE *out)
|
||||
uintmax_t wrap_column, size_t *current_column, FILE *out)
|
||||
{
|
||||
size_t written;
|
||||
|
||||
@@ -107,28 +107,28 @@ wrap_write (const char *buffer, size_t len,
|
||||
{
|
||||
/* Simple write. */
|
||||
if (fwrite (buffer, 1, len, stdout) < len)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
}
|
||||
else
|
||||
for (written = 0; written < len;)
|
||||
{
|
||||
uintmax_t cols_remaining = wrap_column - *current_column;
|
||||
size_t to_write = MIN (cols_remaining, SIZE_MAX);
|
||||
to_write = MIN (to_write, len - written);
|
||||
uintmax_t cols_remaining = wrap_column - *current_column;
|
||||
size_t to_write = MIN (cols_remaining, SIZE_MAX);
|
||||
to_write = MIN (to_write, len - written);
|
||||
|
||||
if (to_write == 0)
|
||||
{
|
||||
if (fputs ("\n", out) < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
*current_column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
*current_column += to_write;
|
||||
written += to_write;
|
||||
}
|
||||
if (to_write == 0)
|
||||
{
|
||||
if (fputs ("\n", out) < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
*current_column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
*current_column += to_write;
|
||||
written += to_write;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,21 +146,21 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column)
|
||||
|
||||
sum = 0;
|
||||
do
|
||||
{
|
||||
n = fread (inbuf + sum, 1, BLOCKSIZE - sum, in);
|
||||
sum += n;
|
||||
}
|
||||
{
|
||||
n = fread (inbuf + sum, 1, BLOCKSIZE - sum, in);
|
||||
sum += n;
|
||||
}
|
||||
while (!feof (in) && !ferror (in) && sum < BLOCKSIZE);
|
||||
|
||||
if (sum > 0)
|
||||
{
|
||||
/* Process input one block at a time. Note that BLOCKSIZE %
|
||||
3 == 0, so that no base64 pads will appear in output. */
|
||||
base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum));
|
||||
{
|
||||
/* Process input one block at a time. Note that BLOCKSIZE %
|
||||
3 == 0, so that no base64 pads will appear in output. */
|
||||
base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum));
|
||||
|
||||
wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column,
|
||||
¤t_column, out);
|
||||
}
|
||||
wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column,
|
||||
¤t_column, out);
|
||||
}
|
||||
}
|
||||
while (!feof (in) && !ferror (in) && sum == BLOCKSIZE);
|
||||
|
||||
@@ -190,43 +190,43 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
|
||||
|
||||
sum = 0;
|
||||
do
|
||||
{
|
||||
n = fread (inbuf + sum, 1, B64BLOCKSIZE - sum, in);
|
||||
{
|
||||
n = fread (inbuf + sum, 1, B64BLOCKSIZE - sum, in);
|
||||
|
||||
if (ignore_garbage)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; n > 0 && i < n;)
|
||||
if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=')
|
||||
i++;
|
||||
else
|
||||
memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i);
|
||||
}
|
||||
if (ignore_garbage)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; n > 0 && i < n;)
|
||||
if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=')
|
||||
i++;
|
||||
else
|
||||
memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i);
|
||||
}
|
||||
|
||||
sum += n;
|
||||
sum += n;
|
||||
|
||||
if (ferror (in))
|
||||
error (EXIT_FAILURE, errno, _("read error"));
|
||||
}
|
||||
if (ferror (in))
|
||||
error (EXIT_FAILURE, errno, _("read error"));
|
||||
}
|
||||
while (sum < B64BLOCKSIZE && !feof (in));
|
||||
|
||||
/* The following "loop" is usually iterated just once.
|
||||
However, when it processes the final input buffer, we want
|
||||
to iterate it one additional time, but with an indicator
|
||||
telling it to flush what is in CTX. */
|
||||
However, when it processes the final input buffer, we want
|
||||
to iterate it one additional time, but with an indicator
|
||||
telling it to flush what is in CTX. */
|
||||
for (k = 0; k < 1 + !!feof (in); k++)
|
||||
{
|
||||
if (k == 1 && ctx.i == 0)
|
||||
break;
|
||||
n = BLOCKSIZE;
|
||||
ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
|
||||
{
|
||||
if (k == 1 && ctx.i == 0)
|
||||
break;
|
||||
n = BLOCKSIZE;
|
||||
ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
|
||||
|
||||
if (fwrite (outbuf, 1, n, out) < n)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
if (fwrite (outbuf, 1, n, out) < n)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
|
||||
if (!ok)
|
||||
error (EXIT_FAILURE, 0, _("invalid input"));
|
||||
}
|
||||
if (!ok)
|
||||
error (EXIT_FAILURE, 0, _("invalid input"));
|
||||
}
|
||||
}
|
||||
while (!feof (in));
|
||||
}
|
||||
@@ -257,26 +257,26 @@ main (int argc, char **argv)
|
||||
switch (opt)
|
||||
{
|
||||
case 'd':
|
||||
decode = true;
|
||||
break;
|
||||
decode = true;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (xstrtoumax (optarg, NULL, 0, &wrap_column, NULL) != LONGINT_OK)
|
||||
error (EXIT_FAILURE, 0, _("invalid wrap size: %s"),
|
||||
quotearg (optarg));
|
||||
break;
|
||||
if (xstrtoumax (optarg, NULL, 0, &wrap_column, NULL) != LONGINT_OK)
|
||||
error (EXIT_FAILURE, 0, _("invalid wrap size: %s"),
|
||||
quotearg (optarg));
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ignore_garbage = true;
|
||||
break;
|
||||
ignore_garbage = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (argc - optind > 1)
|
||||
@@ -296,7 +296,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
input_fh = fopen (infile, "r");
|
||||
if (input_fh == NULL)
|
||||
error (EXIT_FAILURE, errno, "%s", infile);
|
||||
error (EXIT_FAILURE, errno, "%s", infile);
|
||||
}
|
||||
|
||||
if (decode)
|
||||
@@ -307,9 +307,9 @@ main (int argc, char **argv)
|
||||
if (fclose (input_fh) == EOF)
|
||||
{
|
||||
if (STREQ (infile, "-"))
|
||||
error (EXIT_FAILURE, errno, _("closing standard input"));
|
||||
error (EXIT_FAILURE, errno, _("closing standard input"));
|
||||
else
|
||||
error (EXIT_FAILURE, errno, "%s", infile);
|
||||
error (EXIT_FAILURE, errno, "%s", infile);
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
|
||||
@@ -44,14 +44,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s NAME [SUFFIX]\n\
|
||||
or: %s OPTION\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Print NAME with any leading directory components removed.\n\
|
||||
If specified, also remove a trailing SUFFIX.\n\
|
||||
@@ -65,8 +65,8 @@ Examples:\n\
|
||||
%s /usr/bin/sort Output \"sort\".\n\
|
||||
%s include/stdio.h .h Output \"stdio\".\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
|
||||
@@ -43,21 +43,21 @@ diff -upr src/remove.c src/remove.c
|
||||
&& ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
|
||||
&& dirent_type != DT_LNK)
|
||||
@@ -889,6 +890,7 @@ prompt (int fd_cwd, Dirstack_state const
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+ {
|
||||
char const *quoted_name = quote (full_filename (filename));
|
||||
|
||||
if (write_protected < 0)
|
||||
@@ -928,6 +930,7 @@ prompt (int fd_cwd, Dirstack_state const
|
||||
: _("%s: remove %s %s? ")),
|
||||
program_name, file_type (sbuf), quoted_name);
|
||||
}
|
||||
: _("%s: remove %s %s? ")),
|
||||
program_name, file_type (sbuf), quoted_name);
|
||||
}
|
||||
+ }
|
||||
|
||||
if (!yesno ())
|
||||
return RM_USER_DECLINED;
|
||||
return RM_USER_DECLINED;
|
||||
@@ -1547,6 +1550,7 @@ rm_1 (Dirstack_state *ds, char const *fi
|
||||
return RM_ERROR;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ diff -upr src/remove.c src/remove.c
|
||||
|
||||
+ {
|
||||
enum RM_status status = remove_entry (AT_FDCWD, ds, filename,
|
||||
DT_UNKNOWN, &st, x);
|
||||
DT_UNKNOWN, &st, x);
|
||||
if (status == RM_NONEMPTY_DIR)
|
||||
@@ -1587,6 +1592,8 @@ rm_1 (Dirstack_state *ds, char const *fi
|
||||
ds_clear (ds);
|
||||
@@ -87,7 +87,7 @@ diff -upr src/rm.c src/rm.c
|
||||
--- src/rm.c 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ src/rm.c 1970-01-01 00:00:00.000000000 +0000
|
||||
@@ -354,6 +354,7 @@ main (int argc, char **argv)
|
||||
quote ("/"));
|
||||
quote ("/"));
|
||||
}
|
||||
|
||||
+ {
|
||||
@@ -96,7 +96,7 @@ diff -upr src/rm.c src/rm.c
|
||||
|
||||
@@ -367,7 +368,10 @@ main (int argc, char **argv)
|
||||
if (!yesno ())
|
||||
exit (EXIT_SUCCESS);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
+ {
|
||||
enum RM_status status = rm (n_files, file, &x);
|
||||
@@ -109,37 +109,37 @@ diff -upr src/seq.c src/seq.c
|
||||
--- src/seq.c 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ src/seq.c 1970-01-01 00:00:00.000000000 +0000
|
||||
@@ -163,6 +163,7 @@ scan_arg (const char *arg)
|
||||
: (decimal_point == arg /* .# -> 0.# */
|
||||
|| ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */
|
||||
}
|
||||
: (decimal_point == arg /* .# -> 0.# */
|
||||
|| ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */
|
||||
}
|
||||
+ {
|
||||
char const *e = strchr (arg, 'e');
|
||||
if (! e)
|
||||
e = strchr (arg, 'E');
|
||||
e = strchr (arg, 'E');
|
||||
@@ -171,6 +172,7 @@ scan_arg (const char *arg)
|
||||
long exponent = strtol (e + 1, NULL, 10);
|
||||
ret.precision += exponent < 0 ? -exponent : 0;
|
||||
}
|
||||
long exponent = strtol (e + 1, NULL, 10);
|
||||
ret.precision += exponent < 0 ? -exponent : 0;
|
||||
}
|
||||
+ }
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -346,6 +348,7 @@ get_default_format (operand first, opera
|
||||
size_t last_width = last.width + (prec - last.precision);
|
||||
if (last.precision && prec == 0)
|
||||
last_width--; /* don't include space for '.' */
|
||||
size_t last_width = last.width + (prec - last.precision);
|
||||
if (last.precision && prec == 0)
|
||||
last_width--; /* don't include space for '.' */
|
||||
+ {
|
||||
size_t width = MAX (first_width, last_width);
|
||||
if (width <= INT_MAX)
|
||||
{
|
||||
size_t width = MAX (first_width, last_width);
|
||||
if (width <= INT_MAX)
|
||||
{
|
||||
@@ -353,6 +356,7 @@ get_default_format (operand first, opera
|
||||
sprintf (format_buf, "%%0%d.%dLf", w, prec);
|
||||
return format_buf;
|
||||
}
|
||||
sprintf (format_buf, "%%0%d.%dLf", w, prec);
|
||||
return format_buf;
|
||||
}
|
||||
+ }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
@@ -441,6 +445,7 @@ main (int argc, char **argv)
|
||||
if (format_str)
|
||||
{
|
||||
@@ -147,10 +147,10 @@ diff -upr src/seq.c src/seq.c
|
||||
+ {
|
||||
char const *f = long_double_format (format_str, &layout);
|
||||
if (! f)
|
||||
{
|
||||
{
|
||||
@@ -448,6 +453,7 @@ main (int argc, char **argv)
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
format_str = f;
|
||||
+ }
|
||||
}
|
||||
@@ -160,11 +160,11 @@ diff -upr src/shred.c src/shred.c
|
||||
--- src/shred.c 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ src/shred.c 1970-01-01 00:00:00.000000000 +0000
|
||||
@@ -468,7 +468,7 @@ dopass (int fd, char const *qname, off_t
|
||||
out. Thus, it shouldn't give up on bad blocks. This
|
||||
code works because lim is always a multiple of
|
||||
SECTOR_SIZE, except at the end. */
|
||||
out. Thus, it shouldn't give up on bad blocks. This
|
||||
code works because lim is always a multiple of
|
||||
SECTOR_SIZE, except at the end. */
|
||||
- verify (sizeof r % SECTOR_SIZE == 0);
|
||||
+ { verify (sizeof r % SECTOR_SIZE == 0); }
|
||||
if (errnum == EIO && 0 <= size && (soff | SECTOR_MASK) < lim)
|
||||
{
|
||||
size_t soff1 = (soff | SECTOR_MASK) + 1;
|
||||
if (errnum == EIO && 0 <= size && (soff | SECTOR_MASK) < lim)
|
||||
{
|
||||
size_t soff1 = (soff | SECTOR_MASK) + 1;
|
||||
|
||||
626
src/cat.c
626
src/cat.c
@@ -83,13 +83,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [FILE]...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Concatenate FILE(s), or standard input, to standard output.\n\
|
||||
\n\
|
||||
@@ -118,8 +118,8 @@ Examples:\n\
|
||||
%s f - g Output f's contents, then standard input, then g's contents.\n\
|
||||
%s Copy standard input to standard output.\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ next_line_num (void)
|
||||
do
|
||||
{
|
||||
if ((*endp)++ < '9')
|
||||
return;
|
||||
return;
|
||||
*endp-- = '0';
|
||||
}
|
||||
while (endp >= line_num_start);
|
||||
@@ -168,23 +168,23 @@ simple_cat (
|
||||
|
||||
n_read = safe_read (input_desc, buf, bufsize);
|
||||
if (n_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* End of this file? */
|
||||
|
||||
if (n_read == 0)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
/* Write this block out. */
|
||||
|
||||
{
|
||||
/* The following is ok, since we know that 0 < n_read. */
|
||||
size_t n = n_read;
|
||||
if (full_write (STDOUT_FILENO, buf, n) != n)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
/* The following is ok, since we know that 0 < n_read. */
|
||||
size_t n = n_read;
|
||||
if (full_write (STDOUT_FILENO, buf, n) != n)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,227 +274,227 @@ cat (
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
|
||||
{
|
||||
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
|
||||
|
||||
if (outbuf + outsize <= bpout)
|
||||
{
|
||||
char *wp = outbuf;
|
||||
size_t remaining_bytes;
|
||||
do
|
||||
{
|
||||
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
wp += outsize;
|
||||
remaining_bytes = bpout - wp;
|
||||
}
|
||||
while (outsize <= remaining_bytes);
|
||||
if (outbuf + outsize <= bpout)
|
||||
{
|
||||
char *wp = outbuf;
|
||||
size_t remaining_bytes;
|
||||
do
|
||||
{
|
||||
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
wp += outsize;
|
||||
remaining_bytes = bpout - wp;
|
||||
}
|
||||
while (outsize <= remaining_bytes);
|
||||
|
||||
/* Move the remaining bytes to the beginning of the
|
||||
buffer. */
|
||||
/* Move the remaining bytes to the beginning of the
|
||||
buffer. */
|
||||
|
||||
memmove (outbuf, wp, remaining_bytes);
|
||||
bpout = outbuf + remaining_bytes;
|
||||
}
|
||||
memmove (outbuf, wp, remaining_bytes);
|
||||
bpout = outbuf + remaining_bytes;
|
||||
}
|
||||
|
||||
/* Is INBUF empty? */
|
||||
/* Is INBUF empty? */
|
||||
|
||||
if (bpin > eob)
|
||||
{
|
||||
bool input_pending = false;
|
||||
if (bpin > eob)
|
||||
{
|
||||
bool input_pending = false;
|
||||
#ifdef FIONREAD
|
||||
int n_to_read = 0;
|
||||
int n_to_read = 0;
|
||||
|
||||
/* Is there any input to read immediately?
|
||||
If not, we are about to wait,
|
||||
so write all buffered output before waiting. */
|
||||
/* Is there any input to read immediately?
|
||||
If not, we are about to wait,
|
||||
so write all buffered output before waiting. */
|
||||
|
||||
if (use_fionread
|
||||
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
|
||||
{
|
||||
/* Ultrix returns EOPNOTSUPP on NFS;
|
||||
HP-UX returns ENOTTY on pipes.
|
||||
SunOS returns EINVAL and
|
||||
More/BSD returns ENODEV on special files
|
||||
like /dev/null.
|
||||
Irix-5 returns ENOSYS on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY
|
||||
|| errno == EINVAL || errno == ENODEV
|
||||
|| errno == ENOSYS)
|
||||
use_fionread = false;
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot do ioctl on %s"), quote (infile));
|
||||
newlines2 = newlines;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n_to_read != 0)
|
||||
input_pending = true;
|
||||
if (use_fionread
|
||||
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
|
||||
{
|
||||
/* Ultrix returns EOPNOTSUPP on NFS;
|
||||
HP-UX returns ENOTTY on pipes.
|
||||
SunOS returns EINVAL and
|
||||
More/BSD returns ENODEV on special files
|
||||
like /dev/null.
|
||||
Irix-5 returns ENOSYS on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY
|
||||
|| errno == EINVAL || errno == ENODEV
|
||||
|| errno == ENOSYS)
|
||||
use_fionread = false;
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot do ioctl on %s"), quote (infile));
|
||||
newlines2 = newlines;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n_to_read != 0)
|
||||
input_pending = true;
|
||||
#endif
|
||||
|
||||
if (!input_pending)
|
||||
write_pending (outbuf, &bpout);
|
||||
if (!input_pending)
|
||||
write_pending (outbuf, &bpout);
|
||||
|
||||
/* Read more input into INBUF. */
|
||||
/* Read more input into INBUF. */
|
||||
|
||||
n_read = safe_read (input_desc, inbuf, insize);
|
||||
if (n_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return false;
|
||||
}
|
||||
if (n_read == 0)
|
||||
{
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return true;
|
||||
}
|
||||
n_read = safe_read (input_desc, inbuf, insize);
|
||||
if (n_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return false;
|
||||
}
|
||||
if (n_read == 0)
|
||||
{
|
||||
write_pending (outbuf, &bpout);
|
||||
newlines2 = newlines;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Update the pointers and insert a sentinel at the buffer
|
||||
end. */
|
||||
/* Update the pointers and insert a sentinel at the buffer
|
||||
end. */
|
||||
|
||||
bpin = inbuf;
|
||||
eob = bpin + n_read;
|
||||
*eob = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It was a real (not a sentinel) newline. */
|
||||
bpin = inbuf;
|
||||
eob = bpin + n_read;
|
||||
*eob = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It was a real (not a sentinel) newline. */
|
||||
|
||||
/* Was the last line empty?
|
||||
(i.e. have two or more consecutive newlines been read?) */
|
||||
/* Was the last line empty?
|
||||
(i.e. have two or more consecutive newlines been read?) */
|
||||
|
||||
if (++newlines > 0)
|
||||
{
|
||||
if (newlines >= 2)
|
||||
{
|
||||
/* Limit this to 2 here. Otherwise, with lots of
|
||||
consecutive newlines, the counter could wrap
|
||||
around at INT_MAX. */
|
||||
newlines = 2;
|
||||
if (++newlines > 0)
|
||||
{
|
||||
if (newlines >= 2)
|
||||
{
|
||||
/* Limit this to 2 here. Otherwise, with lots of
|
||||
consecutive newlines, the counter could wrap
|
||||
around at INT_MAX. */
|
||||
newlines = 2;
|
||||
|
||||
/* Are multiple adjacent empty lines to be substituted
|
||||
by single ditto (-s), and this was the second empty
|
||||
line? */
|
||||
if (squeeze_blank)
|
||||
{
|
||||
ch = *bpin++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Are multiple adjacent empty lines to be substituted
|
||||
by single ditto (-s), and this was the second empty
|
||||
line? */
|
||||
if (squeeze_blank)
|
||||
{
|
||||
ch = *bpin++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Are line numbers to be written at empty lines (-n)? */
|
||||
/* Are line numbers to be written at empty lines (-n)? */
|
||||
|
||||
if (number & !number_nonblank)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = stpcpy (bpout, line_num_print);
|
||||
}
|
||||
}
|
||||
if (number && !number_nonblank)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = stpcpy (bpout, line_num_print);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a currency symbol if requested (-e). */
|
||||
/* Output a currency symbol if requested (-e). */
|
||||
|
||||
if (show_ends)
|
||||
*bpout++ = '$';
|
||||
if (show_ends)
|
||||
*bpout++ = '$';
|
||||
|
||||
/* Output the newline. */
|
||||
/* Output the newline. */
|
||||
|
||||
*bpout++ = '\n';
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
*bpout++ = '\n';
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
while (ch == '\n');
|
||||
|
||||
/* Are we at the beginning of a line, and line numbers are requested? */
|
||||
|
||||
if (newlines >= 0 && number)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = stpcpy (bpout, line_num_print);
|
||||
}
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = stpcpy (bpout, line_num_print);
|
||||
}
|
||||
|
||||
/* Here CH cannot contain a newline character. */
|
||||
|
||||
/* The loops below continue until a newline character is found,
|
||||
which means that the buffer is empty or that a proper newline
|
||||
has been found. */
|
||||
which means that the buffer is empty or that a proper newline
|
||||
has been found. */
|
||||
|
||||
/* If quoting, i.e. at least one of -v, -e, or -t specified,
|
||||
scan for chars that need conversion. */
|
||||
scan for chars that need conversion. */
|
||||
if (show_nonprinting)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (ch >= 32)
|
||||
{
|
||||
if (ch < 127)
|
||||
*bpout++ = ch;
|
||||
else if (ch == 127)
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = '?';
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = 'M';
|
||||
*bpout++ = '-';
|
||||
if (ch >= 128 + 32)
|
||||
{
|
||||
if (ch < 128 + 127)
|
||||
*bpout++ = ch - 128;
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = '?';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch - 128 + 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch == '\t' && !show_tabs)
|
||||
*bpout++ = '\t';
|
||||
else if (ch == '\n')
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch + 64;
|
||||
}
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (ch >= 32)
|
||||
{
|
||||
if (ch < 127)
|
||||
*bpout++ = ch;
|
||||
else if (ch == 127)
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = '?';
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = 'M';
|
||||
*bpout++ = '-';
|
||||
if (ch >= 128 + 32)
|
||||
{
|
||||
if (ch < 128 + 127)
|
||||
*bpout++ = ch - 128;
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = '?';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch - 128 + 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch == '\t' && !show_tabs)
|
||||
*bpout++ = '\t';
|
||||
else if (ch == '\n')
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch + 64;
|
||||
}
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not quoting, neither of -v, -e, or -t specified. */
|
||||
for (;;)
|
||||
{
|
||||
if (ch == '\t' && show_tabs)
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch + 64;
|
||||
}
|
||||
else if (ch != '\n')
|
||||
*bpout++ = ch;
|
||||
else
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
{
|
||||
/* Not quoting, neither of -v, -e, or -t specified. */
|
||||
for (;;)
|
||||
{
|
||||
if (ch == '\t' && show_tabs)
|
||||
{
|
||||
*bpout++ = '^';
|
||||
*bpout++ = ch + 64;
|
||||
}
|
||||
else if (ch != '\n')
|
||||
*bpout++ = ch;
|
||||
else
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,62 +573,62 @@ main (int argc, char **argv)
|
||||
/* Parse command line options. */
|
||||
|
||||
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
number = true;
|
||||
number_nonblank = true;
|
||||
break;
|
||||
{
|
||||
case 'b':
|
||||
number = true;
|
||||
number_nonblank = true;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
show_ends = true;
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
case 'e':
|
||||
show_ends = true;
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
number = true;
|
||||
break;
|
||||
case 'n':
|
||||
number = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
squeeze_blank = true;
|
||||
break;
|
||||
case 's':
|
||||
squeeze_blank = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
show_tabs = true;
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
case 't':
|
||||
show_tabs = true;
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
/* We provide the -u feature unconditionally. */
|
||||
break;
|
||||
case 'u':
|
||||
/* We provide the -u feature unconditionally. */
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
case 'v':
|
||||
show_nonprinting = true;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
show_nonprinting = true;
|
||||
show_ends = true;
|
||||
show_tabs = true;
|
||||
break;
|
||||
case 'A':
|
||||
show_nonprinting = true;
|
||||
show_ends = true;
|
||||
show_tabs = true;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
show_ends = true;
|
||||
break;
|
||||
case 'E':
|
||||
show_ends = true;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
show_tabs = true;
|
||||
break;
|
||||
case 'T':
|
||||
show_tabs = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get device, i-node number, and optimal blocksize of output. */
|
||||
@@ -657,11 +657,11 @@ main (int argc, char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (! (number | show_ends | squeeze_blank))
|
||||
if (! (number || show_ends || squeeze_blank))
|
||||
{
|
||||
file_open_mode |= O_BINARY;
|
||||
if (O_BINARY && ! isatty (STDOUT_FILENO))
|
||||
xfreopen (NULL, "wb", stdout);
|
||||
xfreopen (NULL, "wb", stdout);
|
||||
}
|
||||
|
||||
/* Check if any of the input files are the same as the output file. */
|
||||
@@ -674,104 +674,104 @@ main (int argc, char **argv)
|
||||
do
|
||||
{
|
||||
if (argind < argc)
|
||||
infile = argv[argind];
|
||||
infile = argv[argind];
|
||||
|
||||
if (STREQ (infile, "-"))
|
||||
{
|
||||
have_read_stdin = true;
|
||||
input_desc = STDIN_FILENO;
|
||||
if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
{
|
||||
have_read_stdin = true;
|
||||
input_desc = STDIN_FILENO;
|
||||
if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_desc = open (infile, file_open_mode);
|
||||
if (input_desc < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
{
|
||||
input_desc = open (infile, file_open_mode);
|
||||
if (input_desc < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fstat (input_desc, &stat_buf) < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
goto contin;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
goto contin;
|
||||
}
|
||||
insize = io_blksize (stat_buf);
|
||||
|
||||
/* Compare the device and i-node numbers of this input file with
|
||||
the corresponding values of the (output file associated with)
|
||||
stdout, and skip this input file if they coincide. Input
|
||||
files cannot be redirected to themselves. */
|
||||
the corresponding values of the (output file associated with)
|
||||
stdout, and skip this input file if they coincide. Input
|
||||
files cannot be redirected to themselves. */
|
||||
|
||||
if (check_redirection
|
||||
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
|
||||
&& (input_desc != STDIN_FILENO))
|
||||
{
|
||||
error (0, 0, _("%s: input file is output file"), infile);
|
||||
ok = false;
|
||||
goto contin;
|
||||
}
|
||||
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
|
||||
&& (input_desc != STDIN_FILENO))
|
||||
{
|
||||
error (0, 0, _("%s: input file is output file"), infile);
|
||||
ok = false;
|
||||
goto contin;
|
||||
}
|
||||
|
||||
/* Select which version of `cat' to use. If any format-oriented
|
||||
options were given use `cat'; otherwise use `simple_cat'. */
|
||||
options were given use `cat'; otherwise use `simple_cat'. */
|
||||
|
||||
if (! (number | show_ends | show_nonprinting
|
||||
| show_tabs | squeeze_blank))
|
||||
{
|
||||
insize = MAX (insize, outsize);
|
||||
inbuf = xmalloc (insize + page_size - 1);
|
||||
if (! (number || show_ends || show_nonprinting
|
||||
|| show_tabs || squeeze_blank))
|
||||
{
|
||||
insize = MAX (insize, outsize);
|
||||
inbuf = xmalloc (insize + page_size - 1);
|
||||
|
||||
ok &= simple_cat (ptr_align (inbuf, page_size), insize);
|
||||
}
|
||||
ok &= simple_cat (ptr_align (inbuf, page_size), insize);
|
||||
}
|
||||
else
|
||||
{
|
||||
inbuf = xmalloc (insize + 1 + page_size - 1);
|
||||
{
|
||||
inbuf = xmalloc (insize + 1 + page_size - 1);
|
||||
|
||||
/* Why are
|
||||
(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
|
||||
bytes allocated for the output buffer?
|
||||
/* Why are
|
||||
(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
|
||||
bytes allocated for the output buffer?
|
||||
|
||||
A test whether output needs to be written is done when the input
|
||||
buffer empties or when a newline appears in the input. After
|
||||
output is written, at most (OUTSIZE - 1) bytes will remain in the
|
||||
buffer. Now INSIZE bytes of input is read. Each input character
|
||||
may grow by a factor of 4 (by the prepending of M-^). If all
|
||||
characters do, and no newlines appear in this block of input, we
|
||||
will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
|
||||
If the last character in the preceding block of input was a
|
||||
newline, a line number may be written (according to the given
|
||||
options) as the first thing in the output buffer. (Done after the
|
||||
new input is read, but before processing of the input begins.)
|
||||
A line number requires seldom more than LINE_COUNTER_BUF_LEN
|
||||
positions.
|
||||
A test whether output needs to be written is done when the input
|
||||
buffer empties or when a newline appears in the input. After
|
||||
output is written, at most (OUTSIZE - 1) bytes will remain in the
|
||||
buffer. Now INSIZE bytes of input is read. Each input character
|
||||
may grow by a factor of 4 (by the prepending of M-^). If all
|
||||
characters do, and no newlines appear in this block of input, we
|
||||
will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
|
||||
If the last character in the preceding block of input was a
|
||||
newline, a line number may be written (according to the given
|
||||
options) as the first thing in the output buffer. (Done after the
|
||||
new input is read, but before processing of the input begins.)
|
||||
A line number requires seldom more than LINE_COUNTER_BUF_LEN
|
||||
positions.
|
||||
|
||||
Align the output buffer to a page size boundary, for efficency on
|
||||
some paging implementations, so add PAGE_SIZE - 1 bytes to the
|
||||
request to make room for the alignment. */
|
||||
Align the output buffer to a page size boundary, for efficency on
|
||||
some paging implementations, so add PAGE_SIZE - 1 bytes to the
|
||||
request to make room for the alignment. */
|
||||
|
||||
outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
|
||||
+ page_size - 1);
|
||||
outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
|
||||
+ page_size - 1);
|
||||
|
||||
ok &= cat (ptr_align (inbuf, page_size), insize,
|
||||
ptr_align (outbuf, page_size), outsize, show_nonprinting,
|
||||
show_tabs, number, number_nonblank, show_ends,
|
||||
squeeze_blank);
|
||||
ok &= cat (ptr_align (inbuf, page_size), insize,
|
||||
ptr_align (outbuf, page_size), outsize, show_nonprinting,
|
||||
show_tabs, number, number_nonblank, show_ends,
|
||||
squeeze_blank);
|
||||
|
||||
free (outbuf);
|
||||
}
|
||||
free (outbuf);
|
||||
}
|
||||
|
||||
free (inbuf);
|
||||
|
||||
contin:
|
||||
if (!STREQ (infile, "-") && close (input_desc) < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
while (++argind < argc);
|
||||
|
||||
|
||||
310
src/chcon.c
310
src/chcon.c
@@ -22,6 +22,7 @@
|
||||
#include "system.h"
|
||||
#include "dev-ino.h"
|
||||
#include "error.h"
|
||||
#include "ignore-value.h"
|
||||
#include "quote.h"
|
||||
#include "quotearg.h"
|
||||
#include "root-dev-ino.h"
|
||||
@@ -97,7 +98,7 @@ compute_context_from_mask (security_context_t context, context_t *ret)
|
||||
if (!new_context)
|
||||
{
|
||||
error (0, errno, _("failed to create security context: %s"),
|
||||
quotearg_colon (context));
|
||||
quotearg_colon (context));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -105,13 +106,13 @@ compute_context_from_mask (security_context_t context, context_t *ret)
|
||||
do \
|
||||
{ \
|
||||
if (specified_ ## comp \
|
||||
&& context_ ## comp ## _set ((C), specified_ ## comp)) \
|
||||
&& context_ ## comp ## _set ((C), specified_ ## comp)) \
|
||||
{ \
|
||||
error (0, errno, \
|
||||
_("failed to set %s security context component to %s"), \
|
||||
#comp, quote (specified_ ## comp)); \
|
||||
error (0, errno, \
|
||||
_("failed to set %s security context component to %s"), \
|
||||
#comp, quote (specified_ ## comp)); \
|
||||
ok = false; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -147,35 +148,35 @@ change_file_context (int fd, char const *file)
|
||||
if (specified_context == NULL)
|
||||
{
|
||||
int status = (affect_symlink_referent
|
||||
? getfileconat (fd, file, &file_context)
|
||||
: lgetfileconat (fd, file, &file_context));
|
||||
? getfileconat (fd, file, &file_context)
|
||||
: lgetfileconat (fd, file, &file_context));
|
||||
|
||||
if (status < 0 && errno != ENODATA)
|
||||
{
|
||||
error (0, errno, _("failed to get security context of %s"),
|
||||
quote (file));
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("failed to get security context of %s"),
|
||||
quote (file));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the file doesn't have a context, and we're not setting all of
|
||||
the context components, there isn't really an obvious default.
|
||||
Thus, we just give up. */
|
||||
the context components, there isn't really an obvious default.
|
||||
Thus, we just give up. */
|
||||
if (file_context == NULL)
|
||||
{
|
||||
error (0, 0, _("can't apply partial context to unlabeled file %s"),
|
||||
quote (file));
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("can't apply partial context to unlabeled file %s"),
|
||||
quote (file));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (compute_context_from_mask (file_context, &context))
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: this should be done exactly once, in main. */
|
||||
context = context_new (specified_context);
|
||||
if (!context)
|
||||
abort ();
|
||||
abort ();
|
||||
}
|
||||
|
||||
context_string = context_str (context);
|
||||
@@ -183,15 +184,15 @@ change_file_context (int fd, char const *file)
|
||||
if (file_context == NULL || ! STREQ (context_string, file_context))
|
||||
{
|
||||
int fail = (affect_symlink_referent
|
||||
? setfileconat (fd, file, context_string)
|
||||
: lsetfileconat (fd, file, context_string));
|
||||
? setfileconat (fd, file, context_string)
|
||||
: lsetfileconat (fd, file, context_string));
|
||||
|
||||
if (fail)
|
||||
{
|
||||
errors = 1;
|
||||
error (0, errno, _("failed to change context of %s to %s"),
|
||||
quote_n (0, file), quote_n (1, context_string));
|
||||
}
|
||||
{
|
||||
errors = 1;
|
||||
error (0, errno, _("failed to change context of %s to %s"),
|
||||
quote_n (0, file), quote_n (1, context_string));
|
||||
}
|
||||
}
|
||||
|
||||
context_free (context);
|
||||
@@ -216,41 +217,41 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
{
|
||||
case FTS_D:
|
||||
if (recurse)
|
||||
{
|
||||
if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp))
|
||||
{
|
||||
/* This happens e.g., with "chcon -R --preserve-root ... /"
|
||||
and with "chcon -RH --preserve-root ... symlink-to-root". */
|
||||
ROOT_DEV_INO_WARN (file_full_name);
|
||||
/* Tell fts not to traverse into this hierarchy. */
|
||||
fts_set (fts, ent, FTS_SKIP);
|
||||
/* Ensure that we do not process "/" on the second visit. */
|
||||
ent = fts_read (fts);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
{
|
||||
if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp))
|
||||
{
|
||||
/* This happens e.g., with "chcon -R --preserve-root ... /"
|
||||
and with "chcon -RH --preserve-root ... symlink-to-root". */
|
||||
ROOT_DEV_INO_WARN (file_full_name);
|
||||
/* Tell fts not to traverse into this hierarchy. */
|
||||
fts_set (fts, ent, FTS_SKIP);
|
||||
/* Ensure that we do not process "/" on the second visit. */
|
||||
ignore_ptr (fts_read (fts));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FTS_DP:
|
||||
if (! recurse)
|
||||
return true;
|
||||
return true;
|
||||
break;
|
||||
|
||||
case FTS_NS:
|
||||
/* For a top-level file or directory, this FTS_NS (stat failed)
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
if (ent->fts_level == 0 && ent->fts_number == 0)
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
@@ -262,7 +263,7 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
|
||||
case FTS_DNR:
|
||||
error (0, ent->fts_errno, _("cannot read directory %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
@@ -280,11 +281,11 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
if (ok)
|
||||
{
|
||||
if (verbose)
|
||||
printf (_("changing security context of %s\n"),
|
||||
quote (file_full_name));
|
||||
printf (_("changing security context of %s\n"),
|
||||
quote (file_full_name));
|
||||
|
||||
if (change_file_context (fts->fts_cwd_fd, file) != 0)
|
||||
ok = false;
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( ! recurse)
|
||||
@@ -310,23 +311,24 @@ process_files (char **files, int bit_flags)
|
||||
|
||||
ent = fts_read (fts);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ok &= process_file (fts, ent);
|
||||
}
|
||||
|
||||
/* Ignore failure, since the only way it can do so is in failing to
|
||||
return to the original directory, and since we're about to exit,
|
||||
that doesn't matter. */
|
||||
fts_close (fts);
|
||||
if (fts_close (fts) != 0)
|
||||
{
|
||||
error (0, errno, _("fts_close failed"));
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -336,7 +338,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -344,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\
|
||||
or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\
|
||||
or: %s [OPTION]... --reference=RFILE FILE...\n\
|
||||
"),
|
||||
program_name, program_name, program_name);
|
||||
program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
Change the security context of each FILE to CONTEXT.\n\
|
||||
With --reference, change the security context of each FILE to that of RFILE.\n\
|
||||
@@ -378,7 +380,7 @@ one takes effect.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -410,97 +412,97 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
recurse = true;
|
||||
break;
|
||||
case 'R':
|
||||
recurse = true;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
/* ignore */
|
||||
break;
|
||||
case 'f':
|
||||
/* ignore */
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
specified_user = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
case 'u':
|
||||
specified_user = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
specified_role = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
case 'r':
|
||||
specified_role = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
specified_type = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
case 't':
|
||||
specified_type = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
specified_range = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
case 'l':
|
||||
specified_range = optarg;
|
||||
component_specified = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse)
|
||||
{
|
||||
if (bit_flags == FTS_PHYSICAL)
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
affect_symlink_referent = false;
|
||||
}
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
affect_symlink_referent = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dereference == 0)
|
||||
error (EXIT_FAILURE, 0, _("-R -h requires -P"));
|
||||
affect_symlink_referent = true;
|
||||
}
|
||||
{
|
||||
if (dereference == 0)
|
||||
error (EXIT_FAILURE, 0, _("-R -h requires -P"));
|
||||
affect_symlink_referent = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -511,17 +513,21 @@ main (int argc, char **argv)
|
||||
if (argc - optind < (reference_file || component_specified ? 1 : 2))
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (is_selinux_enabled () != 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s may be used only on a SELinux kernel"), program_name);
|
||||
|
||||
if (reference_file)
|
||||
{
|
||||
if (getfilecon (reference_file, &ref_context) < 0)
|
||||
error (EXIT_FAILURE, errno, _("failed to get security context of %s"),
|
||||
quote (reference_file));
|
||||
error (EXIT_FAILURE, errno, _("failed to get security context of %s"),
|
||||
quote (reference_file));
|
||||
|
||||
specified_context = ref_context;
|
||||
}
|
||||
@@ -536,8 +542,8 @@ main (int argc, char **argv)
|
||||
specified_context = argv[optind++];
|
||||
context = context_new (specified_context);
|
||||
if (!context)
|
||||
error (EXIT_FAILURE, 0, _("invalid context: %s"),
|
||||
quotearg_colon (specified_context));
|
||||
error (EXIT_FAILURE, 0, _("invalid context: %s"),
|
||||
quotearg_colon (specified_context));
|
||||
context_free (context);
|
||||
}
|
||||
|
||||
@@ -547,13 +553,13 @@ main (int argc, char **argv)
|
||||
usage (1);
|
||||
}
|
||||
|
||||
if (recurse & preserve_root)
|
||||
if (recurse && preserve_root)
|
||||
{
|
||||
static struct dev_ino dev_ino_buf;
|
||||
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
|
||||
if (root_dev_ino == NULL)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
142
src/chgrp.c
142
src/chgrp.c
@@ -84,15 +84,15 @@ parse_group (const char *name)
|
||||
{
|
||||
struct group *grp = getgrnam (name);
|
||||
if (grp)
|
||||
gid = grp->gr_gid;
|
||||
gid = grp->gr_gid;
|
||||
else
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK
|
||||
&& tmp <= GID_T_MAX))
|
||||
error (EXIT_FAILURE, 0, _("invalid group: %s"), quote (name));
|
||||
gid = tmp;
|
||||
}
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK
|
||||
&& tmp <= GID_T_MAX))
|
||||
error (EXIT_FAILURE, 0, _("invalid group: %s"), quote (name));
|
||||
gid = tmp;
|
||||
}
|
||||
endgrent (); /* Save a file descriptor. */
|
||||
}
|
||||
|
||||
@@ -104,14 +104,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... GROUP FILE...\n\
|
||||
or: %s [OPTION]... --reference=RFILE FILE...\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Change the group of each FILE to GROUP.\n\
|
||||
With --reference, change the group of each FILE to that of RFILE.\n\
|
||||
@@ -157,8 +157,8 @@ Examples:\n\
|
||||
%s staff /u Change the group of /u to \"staff\".\n\
|
||||
%s -hR staff /u Change the group of /u and subfiles to \"staff\".\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -191,75 +191,75 @@ main (int argc, char **argv)
|
||||
chopt_init (&chopt);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
chopt.recurse = true;
|
||||
break;
|
||||
case 'R':
|
||||
chopt.recurse = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
chopt.verbosity = V_changes_only;
|
||||
break;
|
||||
case 'c':
|
||||
chopt.verbosity = V_changes_only;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
chopt.force_silent = true;
|
||||
break;
|
||||
case 'f':
|
||||
chopt.force_silent = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
chopt.verbosity = V_high;
|
||||
break;
|
||||
case 'v':
|
||||
chopt.verbosity = V_high;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (chopt.recurse)
|
||||
{
|
||||
if (bit_flags == FTS_PHYSICAL)
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
dereference = 0;
|
||||
}
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
dereference = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -270,9 +270,9 @@ main (int argc, char **argv)
|
||||
if (argc - optind < (reference_file ? 1 : 2))
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -280,8 +280,8 @@ main (int argc, char **argv)
|
||||
{
|
||||
struct stat ref_stats;
|
||||
if (stat (reference_file, &ref_stats))
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
|
||||
gid = ref_stats.st_gid;
|
||||
chopt.group_name = gid_to_name (ref_stats.st_gid);
|
||||
@@ -293,19 +293,19 @@ main (int argc, char **argv)
|
||||
gid = parse_group (group_name);
|
||||
}
|
||||
|
||||
if (chopt.recurse & preserve_root)
|
||||
if (chopt.recurse && preserve_root)
|
||||
{
|
||||
static struct dev_ino dev_ino_buf;
|
||||
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
|
||||
if (chopt.root_dev_ino == NULL)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
}
|
||||
|
||||
bit_flags |= FTS_DEFER_STAT;
|
||||
ok = chown_files (argv + optind, bit_flags,
|
||||
(uid_t) -1, gid,
|
||||
(uid_t) -1, (gid_t) -1, &chopt);
|
||||
(uid_t) -1, gid,
|
||||
(uid_t) -1, (gid_t) -1, &chopt);
|
||||
|
||||
chopt_free (&chopt);
|
||||
|
||||
|
||||
324
src/chmod.c
324
src/chmod.c
@@ -25,6 +25,7 @@
|
||||
#include "dev-ino.h"
|
||||
#include "error.h"
|
||||
#include "filemode.h"
|
||||
#include "ignore-value.h"
|
||||
#include "modechange.h"
|
||||
#include "quote.h"
|
||||
#include "quotearg.h"
|
||||
@@ -115,16 +116,16 @@ mode_changed (char const *file, mode_t old_mode, mode_t new_mode)
|
||||
if (new_mode & (S_ISUID | S_ISGID | S_ISVTX))
|
||||
{
|
||||
/* The new mode contains unusual bits that the call to chmod may
|
||||
have silently cleared. Check whether they actually changed. */
|
||||
have silently cleared. Check whether they actually changed. */
|
||||
|
||||
struct stat new_stats;
|
||||
|
||||
if (stat (file, &new_stats) != 0)
|
||||
{
|
||||
if (! force_silent)
|
||||
error (0, errno, _("getting new attributes of %s"), quote (file));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
if (! force_silent)
|
||||
error (0, errno, _("getting new attributes of %s"), quote (file));
|
||||
return false;
|
||||
}
|
||||
|
||||
new_mode = new_stats.st_mode;
|
||||
}
|
||||
@@ -137,7 +138,7 @@ mode_changed (char const *file, mode_t old_mode, mode_t new_mode)
|
||||
|
||||
static void
|
||||
describe_change (const char *file, mode_t mode,
|
||||
enum Change_status changed)
|
||||
enum Change_status changed)
|
||||
{
|
||||
char perms[12]; /* "-rwxrwxrwx" ls-style modes. */
|
||||
const char *fmt;
|
||||
@@ -145,7 +146,7 @@ describe_change (const char *file, mode_t mode,
|
||||
if (changed == CH_NOT_APPLIED)
|
||||
{
|
||||
printf (_("neither symbolic link %s nor referent has been changed\n"),
|
||||
quote (file));
|
||||
quote (file));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ describe_change (const char *file, mode_t mode,
|
||||
abort ();
|
||||
}
|
||||
printf (fmt, quote (file),
|
||||
(unsigned long int) (mode & CHMOD_MODE_BITS), &perms[1]);
|
||||
(unsigned long int) (mode & CHMOD_MODE_BITS), &perms[1]);
|
||||
}
|
||||
|
||||
/* Change the mode of FILE.
|
||||
@@ -191,21 +192,21 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
|
||||
case FTS_NS:
|
||||
/* For a top-level file or directory, this FTS_NS (stat failed)
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
if (ent->fts_level == 0 && ent->fts_number == 0)
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
if (! force_silent)
|
||||
error (0, ent->fts_errno, _("cannot access %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
@@ -218,14 +219,14 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
case FTS_DNR:
|
||||
if (! force_silent)
|
||||
error (0, ent->fts_errno, _("cannot read directory %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
case FTS_SLNONE:
|
||||
if (! force_silent)
|
||||
error (0, 0, _("cannot operate on dangling symlink %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
|
||||
default:
|
||||
@@ -238,63 +239,63 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
/* Tell fts not to traverse into this hierarchy. */
|
||||
fts_set (fts, ent, FTS_SKIP);
|
||||
/* Ensure that we do not process "/" on the second visit. */
|
||||
ent = fts_read (fts);
|
||||
ok = false;
|
||||
ignore_ptr (fts_read (fts));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
old_mode = file_stats->st_mode;
|
||||
new_mode = mode_adjust (old_mode, S_ISDIR (old_mode) != 0, umask_value,
|
||||
change, NULL);
|
||||
change, NULL);
|
||||
|
||||
if (! S_ISLNK (old_mode))
|
||||
{
|
||||
if (chmodat (fts->fts_cwd_fd, file, new_mode) == 0)
|
||||
chmod_succeeded = true;
|
||||
else
|
||||
{
|
||||
if (! force_silent)
|
||||
error (0, errno, _("changing permissions of %s"),
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (chmodat (fts->fts_cwd_fd, file, new_mode) == 0)
|
||||
chmod_succeeded = true;
|
||||
else
|
||||
{
|
||||
if (! force_silent)
|
||||
error (0, errno, _("changing permissions of %s"),
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (verbosity != V_off)
|
||||
{
|
||||
bool changed = (chmod_succeeded
|
||||
&& mode_changed (file, old_mode, new_mode));
|
||||
&& mode_changed (file, old_mode, new_mode));
|
||||
|
||||
if (changed || verbosity == V_high)
|
||||
{
|
||||
enum Change_status ch_status =
|
||||
(!ok ? CH_FAILED
|
||||
: !chmod_succeeded ? CH_NOT_APPLIED
|
||||
: !changed ? CH_NO_CHANGE_REQUESTED
|
||||
: CH_SUCCEEDED);
|
||||
describe_change (file_full_name, new_mode, ch_status);
|
||||
}
|
||||
{
|
||||
enum Change_status ch_status =
|
||||
(!ok ? CH_FAILED
|
||||
: !chmod_succeeded ? CH_NOT_APPLIED
|
||||
: !changed ? CH_NO_CHANGE_REQUESTED
|
||||
: CH_SUCCEEDED);
|
||||
describe_change (file_full_name, new_mode, ch_status);
|
||||
}
|
||||
}
|
||||
|
||||
if (chmod_succeeded & diagnose_surprises)
|
||||
if (chmod_succeeded && diagnose_surprises)
|
||||
{
|
||||
mode_t naively_expected_mode =
|
||||
mode_adjust (old_mode, S_ISDIR (old_mode) != 0, 0, change, NULL);
|
||||
mode_adjust (old_mode, S_ISDIR (old_mode) != 0, 0, change, NULL);
|
||||
if (new_mode & ~naively_expected_mode)
|
||||
{
|
||||
char new_perms[12];
|
||||
char naively_expected_perms[12];
|
||||
strmode (new_mode, new_perms);
|
||||
strmode (naively_expected_mode, naively_expected_perms);
|
||||
new_perms[10] = naively_expected_perms[10] = '\0';
|
||||
error (0, 0,
|
||||
_("%s: new permissions are %s, not %s"),
|
||||
quotearg_colon (file_full_name),
|
||||
new_perms + 1, naively_expected_perms + 1);
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
char new_perms[12];
|
||||
char naively_expected_perms[12];
|
||||
strmode (new_mode, new_perms);
|
||||
strmode (naively_expected_mode, naively_expected_perms);
|
||||
new_perms[10] = naively_expected_perms[10] = '\0';
|
||||
error (0, 0,
|
||||
_("%s: new permissions are %s, not %s"),
|
||||
quotearg_colon (file_full_name),
|
||||
new_perms + 1, naively_expected_perms + 1);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! recurse)
|
||||
@@ -320,24 +321,25 @@ process_files (char **files, int bit_flags)
|
||||
|
||||
ent = fts_read (fts);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
if (! force_silent)
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
if (! force_silent)
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ok &= process_file (fts, ent);
|
||||
}
|
||||
|
||||
/* Ignore failure, since the only way it can do so is in failing to
|
||||
return to the original directory, and since we're about to exit,
|
||||
that doesn't matter. */
|
||||
fts_close (fts);
|
||||
if (fts_close (fts) != 0)
|
||||
{
|
||||
error (0, errno, _("fts_close failed"));
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -347,7 +349,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -355,7 +357,7 @@ Usage: %s [OPTION]... MODE[,MODE]... FILE...\n\
|
||||
or: %s [OPTION]... OCTAL-MODE FILE...\n\
|
||||
or: %s [OPTION]... --reference=RFILE FILE...\n\
|
||||
"),
|
||||
program_name, program_name, program_name);
|
||||
program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
Change the mode of each FILE to MODE.\n\
|
||||
\n\
|
||||
@@ -377,7 +379,7 @@ Change the mode of each FILE to MODE.\n\
|
||||
\n\
|
||||
Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -407,99 +409,99 @@ main (int argc, char **argv)
|
||||
recurse = force_silent = diagnose_surprises = false;
|
||||
|
||||
while ((c = getopt_long (argc, argv,
|
||||
"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::",
|
||||
long_options, NULL))
|
||||
!= -1)
|
||||
"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::",
|
||||
long_options, NULL))
|
||||
!= -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'g':
|
||||
case 'o':
|
||||
case 'a':
|
||||
case ',':
|
||||
case '+':
|
||||
case '=':
|
||||
/* Support nonportable uses like "chmod -w", but diagnose
|
||||
surprises due to umask confusion. Even though "--", "--r",
|
||||
etc., are valid modes, there is no "case '-'" here since
|
||||
getopt_long reserves leading "--" for long options. */
|
||||
{
|
||||
/* Allocate a mode string (e.g., "-rwx") by concatenating
|
||||
the argument containing this option. If a previous mode
|
||||
string was given, concatenate the previous string, a
|
||||
comma, and the new string (e.g., "-s,-rwx"). */
|
||||
{
|
||||
case 'r':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'g':
|
||||
case 'o':
|
||||
case 'a':
|
||||
case ',':
|
||||
case '+':
|
||||
case '=':
|
||||
/* Support nonportable uses like "chmod -w", but diagnose
|
||||
surprises due to umask confusion. Even though "--", "--r",
|
||||
etc., are valid modes, there is no "case '-'" here since
|
||||
getopt_long reserves leading "--" for long options. */
|
||||
{
|
||||
/* Allocate a mode string (e.g., "-rwx") by concatenating
|
||||
the argument containing this option. If a previous mode
|
||||
string was given, concatenate the previous string, a
|
||||
comma, and the new string (e.g., "-s,-rwx"). */
|
||||
|
||||
char const *arg = argv[optind - 1];
|
||||
size_t arg_len = strlen (arg);
|
||||
size_t mode_comma_len = mode_len + !!mode_len;
|
||||
size_t new_mode_len = mode_comma_len + arg_len;
|
||||
if (mode_alloc <= new_mode_len)
|
||||
{
|
||||
mode_alloc = new_mode_len + 1;
|
||||
mode = X2REALLOC (mode, &mode_alloc);
|
||||
}
|
||||
mode[mode_len] = ',';
|
||||
strcpy (mode + mode_comma_len, arg);
|
||||
mode_len = new_mode_len;
|
||||
char const *arg = argv[optind - 1];
|
||||
size_t arg_len = strlen (arg);
|
||||
size_t mode_comma_len = mode_len + !!mode_len;
|
||||
size_t new_mode_len = mode_comma_len + arg_len;
|
||||
if (mode_alloc <= new_mode_len)
|
||||
{
|
||||
mode_alloc = new_mode_len + 1;
|
||||
mode = X2REALLOC (mode, &mode_alloc);
|
||||
}
|
||||
mode[mode_len] = ',';
|
||||
strcpy (mode + mode_comma_len, arg);
|
||||
mode_len = new_mode_len;
|
||||
|
||||
diagnose_surprises = true;
|
||||
}
|
||||
break;
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
recurse = true;
|
||||
break;
|
||||
case 'c':
|
||||
verbosity = V_changes_only;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbosity = V_high;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
diagnose_surprises = true;
|
||||
}
|
||||
break;
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
recurse = true;
|
||||
break;
|
||||
case 'c':
|
||||
verbosity = V_changes_only;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbosity = V_high;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (reference_file)
|
||||
{
|
||||
if (mode)
|
||||
{
|
||||
error (0, 0, _("cannot combine mode and --reference options"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("cannot combine mode and --reference options"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mode)
|
||||
mode = argv[optind++];
|
||||
mode = argv[optind++];
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
if (!mode || mode != argv[optind - 1])
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -507,27 +509,27 @@ main (int argc, char **argv)
|
||||
{
|
||||
change = mode_create_from_ref (reference_file);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
}
|
||||
else
|
||||
{
|
||||
change = mode_compile (mode);
|
||||
if (!change)
|
||||
{
|
||||
error (0, 0, _("invalid mode: %s"), quote (mode));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("invalid mode: %s"), quote (mode));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
umask_value = umask (0);
|
||||
}
|
||||
|
||||
if (recurse & preserve_root)
|
||||
if (recurse && preserve_root)
|
||||
{
|
||||
static struct dev_ino dev_ino_buf;
|
||||
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
|
||||
if (root_dev_ino == NULL)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -535,7 +537,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
ok = process_files (argv + optind,
|
||||
FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
|
||||
FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
|
||||
|
||||
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
346
src/chown-core.c
346
src/chown-core.c
@@ -25,6 +25,7 @@
|
||||
#include "system.h"
|
||||
#include "chown-core.h"
|
||||
#include "error.h"
|
||||
#include "ignore-value.h"
|
||||
#include "quote.h"
|
||||
#include "root-dev-ino.h"
|
||||
#include "xfts.h"
|
||||
@@ -83,8 +84,8 @@ gid_to_name (gid_t gid)
|
||||
char buf[INT_BUFSIZE_BOUND (intmax_t)];
|
||||
struct group *grp = getgrgid (gid);
|
||||
return xstrdup (grp ? grp->gr_name
|
||||
: TYPE_SIGNED (gid_t) ? imaxtostr (gid, buf)
|
||||
: umaxtostr (gid, buf));
|
||||
: TYPE_SIGNED (gid_t) ? imaxtostr (gid, buf)
|
||||
: umaxtostr (gid, buf));
|
||||
}
|
||||
|
||||
/* Convert the numeric user-id, UID, to a string stored in xmalloc'd memory,
|
||||
@@ -97,8 +98,8 @@ uid_to_name (uid_t uid)
|
||||
char buf[INT_BUFSIZE_BOUND (intmax_t)];
|
||||
struct passwd *pwd = getpwuid (uid);
|
||||
return xstrdup (pwd ? pwd->pw_name
|
||||
: TYPE_SIGNED (uid_t) ? imaxtostr (uid, buf)
|
||||
: umaxtostr (uid, buf));
|
||||
: TYPE_SIGNED (uid_t) ? imaxtostr (uid, buf)
|
||||
: umaxtostr (uid, buf));
|
||||
}
|
||||
|
||||
/* Tell the user how/if the user and group of FILE have been changed.
|
||||
@@ -107,7 +108,7 @@ uid_to_name (uid_t uid)
|
||||
|
||||
static void
|
||||
describe_change (const char *file, enum Change_status changed,
|
||||
char const *user, char const *group)
|
||||
char const *user, char const *group)
|
||||
{
|
||||
const char *fmt;
|
||||
char const *spec;
|
||||
@@ -116,22 +117,22 @@ describe_change (const char *file, enum Change_status changed,
|
||||
if (changed == CH_NOT_APPLIED)
|
||||
{
|
||||
printf (_("neither symbolic link %s nor referent has been changed\n"),
|
||||
quote (file));
|
||||
quote (file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (user)
|
||||
{
|
||||
if (group)
|
||||
{
|
||||
spec_allocated = xmalloc (strlen (user) + 1 + strlen (group) + 1);
|
||||
stpcpy (stpcpy (stpcpy (spec_allocated, user), ":"), group);
|
||||
spec = spec_allocated;
|
||||
}
|
||||
{
|
||||
spec_allocated = xmalloc (strlen (user) + 1 + strlen (group) + 1);
|
||||
stpcpy (stpcpy (stpcpy (spec_allocated, user), ":"), group);
|
||||
spec = spec_allocated;
|
||||
}
|
||||
else
|
||||
{
|
||||
spec = user;
|
||||
}
|
||||
{
|
||||
spec = user;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -142,18 +143,18 @@ describe_change (const char *file, enum Change_status changed,
|
||||
{
|
||||
case CH_SUCCEEDED:
|
||||
fmt = (user ? _("changed ownership of %s to %s\n")
|
||||
: group ? _("changed group of %s to %s\n")
|
||||
: _("no change to ownership of %s\n"));
|
||||
: group ? _("changed group of %s to %s\n")
|
||||
: _("no change to ownership of %s\n"));
|
||||
break;
|
||||
case CH_FAILED:
|
||||
fmt = (user ? _("failed to change ownership of %s to %s\n")
|
||||
: group ? _("failed to change group of %s to %s\n")
|
||||
: _("failed to change ownership of %s\n"));
|
||||
: group ? _("failed to change group of %s to %s\n")
|
||||
: _("failed to change ownership of %s\n"));
|
||||
break;
|
||||
case CH_NO_CHANGE_REQUESTED:
|
||||
fmt = (user ? _("ownership of %s retained as %s\n")
|
||||
: group ? _("group of %s retained as %s\n")
|
||||
: _("ownership of %s retained\n"));
|
||||
: group ? _("group of %s retained as %s\n")
|
||||
: _("ownership of %s retained\n"));
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
@@ -184,9 +185,9 @@ describe_change (const char *file, enum Change_status changed,
|
||||
|
||||
static enum RCH_status
|
||||
restricted_chown (int cwd_fd, char const *file,
|
||||
struct stat const *orig_st,
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid)
|
||||
struct stat const *orig_st,
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid)
|
||||
{
|
||||
enum RCH_status status = RC_ok;
|
||||
struct stat st;
|
||||
@@ -199,15 +200,15 @@ restricted_chown (int cwd_fd, char const *file,
|
||||
if (! S_ISREG (orig_st->st_mode))
|
||||
{
|
||||
if (S_ISDIR (orig_st->st_mode))
|
||||
open_flags |= O_DIRECTORY;
|
||||
open_flags |= O_DIRECTORY;
|
||||
else
|
||||
return RC_do_ordinary_chown;
|
||||
return RC_do_ordinary_chown;
|
||||
}
|
||||
|
||||
fd = openat (cwd_fd, file, O_RDONLY | open_flags);
|
||||
if (! (0 <= fd
|
||||
|| (errno == EACCES && S_ISREG (orig_st->st_mode)
|
||||
&& 0 <= (fd = openat (cwd_fd, file, O_WRONLY | open_flags)))))
|
||||
|| (errno == EACCES && S_ISREG (orig_st->st_mode)
|
||||
&& 0 <= (fd = openat (cwd_fd, file, O_WRONLY | open_flags)))))
|
||||
return (errno == EACCES ? RC_do_ordinary_chown : RC_error);
|
||||
|
||||
if (fstat (fd, &st) != 0)
|
||||
@@ -215,18 +216,18 @@ restricted_chown (int cwd_fd, char const *file,
|
||||
else if (! SAME_INODE (*orig_st, st))
|
||||
status = RC_inode_changed;
|
||||
else if ((required_uid == (uid_t) -1 || required_uid == st.st_uid)
|
||||
&& (required_gid == (gid_t) -1 || required_gid == st.st_gid))
|
||||
&& (required_gid == (gid_t) -1 || required_gid == st.st_gid))
|
||||
{
|
||||
if (fchown (fd, uid, gid) == 0)
|
||||
{
|
||||
status = (close (fd) == 0
|
||||
? RC_ok : RC_error);
|
||||
return status;
|
||||
}
|
||||
{
|
||||
status = (close (fd) == 0
|
||||
? RC_ok : RC_error);
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = RC_error;
|
||||
}
|
||||
{
|
||||
status = RC_error;
|
||||
}
|
||||
}
|
||||
|
||||
{ /* FIXME: remove these curly braces when we assume C99. */
|
||||
@@ -245,9 +246,9 @@ restricted_chown (int cwd_fd, char const *file,
|
||||
Return true if successful. */
|
||||
static bool
|
||||
change_file_owner (FTS *fts, FTSENT *ent,
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt)
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt)
|
||||
{
|
||||
char const *file_full_name = ent->fts_path;
|
||||
char const *file = ent->fts_accpath;
|
||||
@@ -261,44 +262,44 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
{
|
||||
case FTS_D:
|
||||
if (chopt->recurse)
|
||||
{
|
||||
if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
|
||||
{
|
||||
/* This happens e.g., with "chown -R --preserve-root 0 /"
|
||||
and with "chown -RH --preserve-root 0 symlink-to-root". */
|
||||
ROOT_DEV_INO_WARN (file_full_name);
|
||||
/* Tell fts not to traverse into this hierarchy. */
|
||||
fts_set (fts, ent, FTS_SKIP);
|
||||
/* Ensure that we do not process "/" on the second visit. */
|
||||
ent = fts_read (fts);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
{
|
||||
if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
|
||||
{
|
||||
/* This happens e.g., with "chown -R --preserve-root 0 /"
|
||||
and with "chown -RH --preserve-root 0 symlink-to-root". */
|
||||
ROOT_DEV_INO_WARN (file_full_name);
|
||||
/* Tell fts not to traverse into this hierarchy. */
|
||||
fts_set (fts, ent, FTS_SKIP);
|
||||
/* Ensure that we do not process "/" on the second visit. */
|
||||
ignore_ptr (fts_read (fts));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case FTS_DP:
|
||||
if (! chopt->recurse)
|
||||
return true;
|
||||
return true;
|
||||
break;
|
||||
|
||||
case FTS_NS:
|
||||
/* For a top-level file or directory, this FTS_NS (stat failed)
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
indicator is determined at the time of the initial fts_open call.
|
||||
With programs like chmod, chown, and chgrp, that modify
|
||||
permissions, it is possible that the file in question is
|
||||
accessible when control reaches this point. So, if this is
|
||||
the first time we've seen the FTS_NS for this file, tell
|
||||
fts_read to stat it "again". */
|
||||
if (ent->fts_level == 0 && ent->fts_number == 0)
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
ent->fts_number = 1;
|
||||
fts_set (fts, ent, FTS_AGAIN);
|
||||
return true;
|
||||
}
|
||||
if (! chopt->force_silent)
|
||||
error (0, ent->fts_errno, _("cannot access %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
@@ -311,7 +312,7 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
case FTS_DNR:
|
||||
if (! chopt->force_silent)
|
||||
error (0, ent->fts_errno, _("cannot read directory %s"),
|
||||
quote (file_full_name));
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
@@ -325,9 +326,9 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
file_stats = NULL;
|
||||
}
|
||||
else if (required_uid == (uid_t) -1 && required_gid == (gid_t) -1
|
||||
&& chopt->verbosity == V_off
|
||||
&& ! chopt->root_dev_ino
|
||||
&& ! chopt->affect_symlink_referent)
|
||||
&& chopt->verbosity == V_off
|
||||
&& ! chopt->root_dev_ino
|
||||
&& ! chopt->affect_symlink_referent)
|
||||
{
|
||||
do_chown = true;
|
||||
file_stats = ent->fts_statp;
|
||||
@@ -337,25 +338,25 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
file_stats = ent->fts_statp;
|
||||
|
||||
/* If this is a symlink and we're dereferencing them,
|
||||
stat it to get info on the referent. */
|
||||
stat it to get info on the referent. */
|
||||
if (chopt->affect_symlink_referent && S_ISLNK (file_stats->st_mode))
|
||||
{
|
||||
if (fstatat (fts->fts_cwd_fd, file, &stat_buf, 0) != 0)
|
||||
{
|
||||
if (! chopt->force_silent)
|
||||
error (0, errno, _("cannot dereference %s"),
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
if (fstatat (fts->fts_cwd_fd, file, &stat_buf, 0) != 0)
|
||||
{
|
||||
if (! chopt->force_silent)
|
||||
error (0, errno, _("cannot dereference %s"),
|
||||
quote (file_full_name));
|
||||
ok = false;
|
||||
}
|
||||
|
||||
file_stats = &stat_buf;
|
||||
}
|
||||
file_stats = &stat_buf;
|
||||
}
|
||||
|
||||
do_chown = (ok
|
||||
&& (required_uid == (uid_t) -1
|
||||
|| required_uid == file_stats->st_uid)
|
||||
&& (required_gid == (gid_t) -1
|
||||
|| required_gid == file_stats->st_gid));
|
||||
&& (required_uid == (uid_t) -1
|
||||
|| required_uid == file_stats->st_uid)
|
||||
&& (required_gid == (gid_t) -1
|
||||
|| required_gid == file_stats->st_gid));
|
||||
}
|
||||
|
||||
/* This happens when chown -LR --preserve-root encounters a symlink-to-/. */
|
||||
@@ -370,89 +371,89 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
if (do_chown)
|
||||
{
|
||||
if ( ! chopt->affect_symlink_referent)
|
||||
{
|
||||
ok = (lchownat (fts->fts_cwd_fd, file, uid, gid) == 0);
|
||||
{
|
||||
ok = (lchownat (fts->fts_cwd_fd, file, uid, gid) == 0);
|
||||
|
||||
/* Ignore any error due to lack of support; POSIX requires
|
||||
this behavior for top-level symbolic links with -h, and
|
||||
implies that it's required for all symbolic links. */
|
||||
if (!ok && errno == EOPNOTSUPP)
|
||||
{
|
||||
ok = true;
|
||||
symlink_changed = false;
|
||||
}
|
||||
}
|
||||
/* Ignore any error due to lack of support; POSIX requires
|
||||
this behavior for top-level symbolic links with -h, and
|
||||
implies that it's required for all symbolic links. */
|
||||
if (!ok && errno == EOPNOTSUPP)
|
||||
{
|
||||
ok = true;
|
||||
symlink_changed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If possible, avoid a race condition with --from=O:G and without the
|
||||
(-h) --no-dereference option. If fts's stat call determined
|
||||
that the uid/gid of FILE matched the --from=O:G-selected
|
||||
owner and group IDs, blindly using chown(2) here could lead
|
||||
chown(1) or chgrp(1) mistakenly to dereference a *symlink*
|
||||
to an arbitrary file that an attacker had moved into the
|
||||
place of FILE during the window between the stat and
|
||||
chown(2) calls. If FILE is a regular file or a directory
|
||||
that can be opened, this race condition can be avoided safely. */
|
||||
{
|
||||
/* If possible, avoid a race condition with --from=O:G and without the
|
||||
(-h) --no-dereference option. If fts's stat call determined
|
||||
that the uid/gid of FILE matched the --from=O:G-selected
|
||||
owner and group IDs, blindly using chown(2) here could lead
|
||||
chown(1) or chgrp(1) mistakenly to dereference a *symlink*
|
||||
to an arbitrary file that an attacker had moved into the
|
||||
place of FILE during the window between the stat and
|
||||
chown(2) calls. If FILE is a regular file or a directory
|
||||
that can be opened, this race condition can be avoided safely. */
|
||||
|
||||
enum RCH_status err
|
||||
= restricted_chown (fts->fts_cwd_fd, file, file_stats, uid, gid,
|
||||
required_uid, required_gid);
|
||||
switch (err)
|
||||
{
|
||||
case RC_ok:
|
||||
break;
|
||||
enum RCH_status err
|
||||
= restricted_chown (fts->fts_cwd_fd, file, file_stats, uid, gid,
|
||||
required_uid, required_gid);
|
||||
switch (err)
|
||||
{
|
||||
case RC_ok:
|
||||
break;
|
||||
|
||||
case RC_do_ordinary_chown:
|
||||
ok = (chownat (fts->fts_cwd_fd, file, uid, gid) == 0);
|
||||
break;
|
||||
case RC_do_ordinary_chown:
|
||||
ok = (chownat (fts->fts_cwd_fd, file, uid, gid) == 0);
|
||||
break;
|
||||
|
||||
case RC_error:
|
||||
ok = false;
|
||||
break;
|
||||
case RC_error:
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
case RC_inode_changed:
|
||||
/* FIXME: give a diagnostic in this case? */
|
||||
case RC_excluded:
|
||||
do_chown = false;
|
||||
ok = false;
|
||||
break;
|
||||
case RC_inode_changed:
|
||||
/* FIXME: give a diagnostic in this case? */
|
||||
case RC_excluded:
|
||||
do_chown = false;
|
||||
ok = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* On some systems (e.g., GNU/Linux 2.4.x),
|
||||
the chown function resets the `special' permission bits.
|
||||
Do *not* restore those bits; doing so would open a window in
|
||||
which a malicious user, M, could subvert a chown command run
|
||||
by some other user and operating on files in a directory
|
||||
where M has write access. */
|
||||
the chown function resets the `special' permission bits.
|
||||
Do *not* restore those bits; doing so would open a window in
|
||||
which a malicious user, M, could subvert a chown command run
|
||||
by some other user and operating on files in a directory
|
||||
where M has write access. */
|
||||
|
||||
if (do_chown && !ok && ! chopt->force_silent)
|
||||
error (0, errno, (uid != (uid_t) -1
|
||||
? _("changing ownership of %s")
|
||||
: _("changing group of %s")),
|
||||
quote (file_full_name));
|
||||
error (0, errno, (uid != (uid_t) -1
|
||||
? _("changing ownership of %s")
|
||||
: _("changing group of %s")),
|
||||
quote (file_full_name));
|
||||
}
|
||||
|
||||
if (chopt->verbosity != V_off)
|
||||
{
|
||||
bool changed =
|
||||
((do_chown & ok & symlink_changed)
|
||||
&& ! ((uid == (uid_t) -1 || uid == file_stats->st_uid)
|
||||
&& (gid == (gid_t) -1 || gid == file_stats->st_gid)));
|
||||
((do_chown && ok && symlink_changed)
|
||||
&& ! ((uid == (uid_t) -1 || uid == file_stats->st_uid)
|
||||
&& (gid == (gid_t) -1 || gid == file_stats->st_gid)));
|
||||
|
||||
if (changed || chopt->verbosity == V_high)
|
||||
{
|
||||
enum Change_status ch_status =
|
||||
(!ok ? CH_FAILED
|
||||
: !symlink_changed ? CH_NOT_APPLIED
|
||||
: !changed ? CH_NO_CHANGE_REQUESTED
|
||||
: CH_SUCCEEDED);
|
||||
describe_change (file_full_name, ch_status,
|
||||
chopt->user_name, chopt->group_name);
|
||||
}
|
||||
{
|
||||
enum Change_status ch_status =
|
||||
(!ok ? CH_FAILED
|
||||
: !symlink_changed ? CH_NOT_APPLIED
|
||||
: !changed ? CH_NO_CHANGE_REQUESTED
|
||||
: CH_SUCCEEDED);
|
||||
describe_change (file_full_name, ch_status,
|
||||
chopt->user_name, chopt->group_name);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! chopt->recurse)
|
||||
@@ -472,18 +473,18 @@ change_file_owner (FTS *fts, FTSENT *ent,
|
||||
Return true if successful. */
|
||||
extern bool
|
||||
chown_files (char **files, int bit_flags,
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt)
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
/* Use lstat and stat only if they're needed. */
|
||||
int stat_flags = ((required_uid != (uid_t) -1 || required_gid != (gid_t) -1
|
||||
|| chopt->affect_symlink_referent
|
||||
|| chopt->verbosity != V_off)
|
||||
? 0
|
||||
: FTS_NOSTAT);
|
||||
|| chopt->affect_symlink_referent
|
||||
|| chopt->verbosity != V_off)
|
||||
? 0
|
||||
: FTS_NOSTAT);
|
||||
|
||||
FTS *fts = xfts_open (files, bit_flags | stat_flags, NULL);
|
||||
|
||||
@@ -493,25 +494,26 @@ chown_files (char **files, int bit_flags,
|
||||
|
||||
ent = fts_read (fts);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
if (! chopt->force_silent)
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
if (! chopt->force_silent)
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ok &= change_file_owner (fts, ent, uid, gid,
|
||||
required_uid, required_gid, chopt);
|
||||
required_uid, required_gid, chopt);
|
||||
}
|
||||
|
||||
/* Ignore failure, since the only way it can do so is in failing to
|
||||
return to the original directory, and since we're about to exit,
|
||||
that doesn't matter. */
|
||||
fts_close (fts);
|
||||
if (fts_close (fts) != 0)
|
||||
{
|
||||
error (0, errno, _("fts_close failed"));
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ uid_to_name (uid_t);
|
||||
|
||||
bool
|
||||
chown_files (char **files, int bit_flags,
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt);
|
||||
uid_t uid, gid_t gid,
|
||||
uid_t required_uid, gid_t required_gid,
|
||||
struct Chown_option const *chopt);
|
||||
|
||||
#endif /* CHOWN_CORE_H */
|
||||
|
||||
152
src/chown.c
152
src/chown.c
@@ -85,14 +85,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [OWNER][:[GROUP]] FILE...\n\
|
||||
or: %s [OPTION]... --reference=RFILE FILE...\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\
|
||||
With --reference, change the owner and group of each FILE to those of RFILE.\n\
|
||||
@@ -152,8 +152,8 @@ Examples:\n\
|
||||
%s root:staff /u Likewise, but also change its group to \"staff\".\n\
|
||||
%s -hR root /u Change the owner of /u and subfiles to \"root\".\n\
|
||||
"),
|
||||
program_name, program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -193,86 +193,86 @@ main (int argc, char **argv)
|
||||
chopt_init (&chopt);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
{
|
||||
case 'H': /* Traverse command-line symlinks-to-directories. */
|
||||
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
case 'L': /* Traverse all symlinks-to-directories. */
|
||||
bit_flags = FTS_LOGICAL;
|
||||
break;
|
||||
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
case 'P': /* Traverse no symlinks-to-directories. */
|
||||
bit_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
case 'h': /* --no-dereference: affect symlinks */
|
||||
dereference = 0;
|
||||
break;
|
||||
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
case DEREFERENCE_OPTION: /* --dereference: affect the referent
|
||||
of each symlink */
|
||||
dereference = 1;
|
||||
break;
|
||||
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
case NO_PRESERVE_ROOT:
|
||||
preserve_root = false;
|
||||
break;
|
||||
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
case PRESERVE_ROOT:
|
||||
preserve_root = true;
|
||||
break;
|
||||
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
case REFERENCE_FILE_OPTION:
|
||||
reference_file = optarg;
|
||||
break;
|
||||
|
||||
case FROM_OPTION:
|
||||
{
|
||||
char *u_dummy, *g_dummy;
|
||||
const char *e = parse_user_spec (optarg,
|
||||
&required_uid, &required_gid,
|
||||
&u_dummy, &g_dummy);
|
||||
if (e)
|
||||
error (EXIT_FAILURE, 0, "%s: %s", e, quote (optarg));
|
||||
break;
|
||||
}
|
||||
case FROM_OPTION:
|
||||
{
|
||||
char *u_dummy, *g_dummy;
|
||||
const char *e = parse_user_spec (optarg,
|
||||
&required_uid, &required_gid,
|
||||
&u_dummy, &g_dummy);
|
||||
if (e)
|
||||
error (EXIT_FAILURE, 0, "%s: %s", e, quote (optarg));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'R':
|
||||
chopt.recurse = true;
|
||||
break;
|
||||
case 'R':
|
||||
chopt.recurse = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
chopt.verbosity = V_changes_only;
|
||||
break;
|
||||
case 'c':
|
||||
chopt.verbosity = V_changes_only;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
chopt.force_silent = true;
|
||||
break;
|
||||
case 'f':
|
||||
chopt.force_silent = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
chopt.verbosity = V_high;
|
||||
break;
|
||||
case 'v':
|
||||
chopt.verbosity = V_high;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (chopt.recurse)
|
||||
{
|
||||
if (bit_flags == FTS_PHYSICAL)
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
dereference = 0;
|
||||
}
|
||||
{
|
||||
if (dereference == 1)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("-R --dereference requires either -H or -L"));
|
||||
dereference = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -283,9 +283,9 @@ main (int argc, char **argv)
|
||||
if (argc - optind < (reference_file ? 1 : 2))
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -293,8 +293,8 @@ main (int argc, char **argv)
|
||||
{
|
||||
struct stat ref_stats;
|
||||
if (stat (reference_file, &ref_stats))
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote (reference_file));
|
||||
|
||||
uid = ref_stats.st_uid;
|
||||
gid = ref_stats.st_gid;
|
||||
@@ -304,32 +304,32 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
const char *e = parse_user_spec (argv[optind], &uid, &gid,
|
||||
&chopt.user_name, &chopt.group_name);
|
||||
&chopt.user_name, &chopt.group_name);
|
||||
if (e)
|
||||
error (EXIT_FAILURE, 0, "%s: %s", e, quote (argv[optind]));
|
||||
|
||||
/* If a group is specified but no user, set the user name to the
|
||||
empty string so that diagnostics say "ownership :GROUP"
|
||||
rather than "group GROUP". */
|
||||
empty string so that diagnostics say "ownership :GROUP"
|
||||
rather than "group GROUP". */
|
||||
if (!chopt.user_name && chopt.group_name)
|
||||
chopt.user_name = bad_cast ("");
|
||||
|
||||
optind++;
|
||||
}
|
||||
|
||||
if (chopt.recurse & preserve_root)
|
||||
if (chopt.recurse && preserve_root)
|
||||
{
|
||||
static struct dev_ino dev_ino_buf;
|
||||
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
|
||||
if (chopt.root_dev_ino == NULL)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
}
|
||||
|
||||
bit_flags |= FTS_DEFER_STAT;
|
||||
ok = chown_files (argv + optind, bit_flags,
|
||||
uid, gid,
|
||||
required_uid, required_gid, &chopt);
|
||||
uid, gid,
|
||||
required_uid, required_gid, &chopt);
|
||||
|
||||
chopt_free (&chopt);
|
||||
|
||||
|
||||
10
src/chroot.c
10
src/chroot.c
@@ -118,7 +118,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -142,7 +142,7 @@ Run COMMAND with root directory set to NEWROOT.\n\
|
||||
\n\
|
||||
If no command is given, run ``${SHELL} -i'' (default: /bin/sh).\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -164,7 +164,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
|
||||
while ((c = getopt_long (argc, argv, "+", long_opts, NULL)) != -1)
|
||||
{
|
||||
@@ -189,7 +189,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (chroot (argv[optind]) != 0)
|
||||
error (EXIT_FAILURE, errno, _("cannot change root directory to %s"),
|
||||
argv[optind]);
|
||||
argv[optind]);
|
||||
|
||||
if (chdir ("/"))
|
||||
error (EXIT_FAILURE, errno, _("cannot chdir to root directory"));
|
||||
@@ -199,7 +199,7 @@ main (int argc, char **argv)
|
||||
/* No command. Run an interactive shell. */
|
||||
char *shell = getenv ("SHELL");
|
||||
if (shell == NULL)
|
||||
shell = bad_cast ("/bin/sh");
|
||||
shell = bad_cast ("/bin/sh");
|
||||
argv[0] = shell;
|
||||
argv[1] = bad_cast ("-i");
|
||||
argv[2] = NULL;
|
||||
|
||||
38
src/cksum.c
38
src/cksum.c
@@ -58,8 +58,8 @@
|
||||
The i bit in GEN is set if X^i is a summand of G(X) except X^32. */
|
||||
|
||||
# define GEN (BIT (26) | BIT (23) | BIT (22) | BIT (16) | BIT (12) \
|
||||
| BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \
|
||||
| BIT (4) | BIT (2) | BIT (1) | BIT (0))
|
||||
| BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \
|
||||
| BIT (4) | BIT (2) | BIT (1) | BIT (0))
|
||||
|
||||
static uint_fast32_t r[8];
|
||||
|
||||
@@ -96,9 +96,9 @@ main (void)
|
||||
for (i = 0; i < 51; i++)
|
||||
{
|
||||
printf (",\n 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x",
|
||||
crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2),
|
||||
crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4),
|
||||
crc_remainder (i * 5 + 5));
|
||||
crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2),
|
||||
crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4),
|
||||
crc_remainder (i * 5 + 5));
|
||||
}
|
||||
printf ("\n};\n");
|
||||
exit (EXIT_SUCCESS);
|
||||
@@ -193,16 +193,16 @@ cksum (const char *file, bool print_name)
|
||||
fp = stdin;
|
||||
have_read_stdin = true;
|
||||
if (O_BINARY && ! isatty (STDIN_FILENO))
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = fopen (file, (O_BINARY ? "rb" : "r"));
|
||||
if (fp == NULL)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0)
|
||||
@@ -210,19 +210,19 @@ cksum (const char *file, bool print_name)
|
||||
unsigned char *cp = buf;
|
||||
|
||||
if (length + bytes_read < length)
|
||||
error (EXIT_FAILURE, 0, _("%s: file too long"), file);
|
||||
error (EXIT_FAILURE, 0, _("%s: file too long"), file);
|
||||
length += bytes_read;
|
||||
while (bytes_read--)
|
||||
crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
|
||||
crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
|
||||
if (feof (fp))
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ferror (fp))
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
if (!STREQ (file, "-"))
|
||||
fclose (fp);
|
||||
fclose (fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -255,21 +255,21 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [FILE]...\n\
|
||||
or: %s [OPTION]\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Print CRC checksum and byte counts of each FILE.\n\
|
||||
\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -289,7 +289,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
@@ -301,7 +301,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
ok = true;
|
||||
for (i = optind; i < argc; i++)
|
||||
ok &= cksum (argv[i], true);
|
||||
ok &= cksum (argv[i], true);
|
||||
}
|
||||
|
||||
if (have_read_stdin && fclose (stdin) == EOF)
|
||||
|
||||
209
src/comm.c
209
src/comm.c
@@ -23,6 +23,7 @@
|
||||
#include "system.h"
|
||||
#include "linebuffer.h"
|
||||
#include "error.h"
|
||||
#include "hard-locale.h"
|
||||
#include "quote.h"
|
||||
#include "stdio--.h"
|
||||
#include "memcmp2.h"
|
||||
@@ -96,13 +97,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... FILE1 FILE2\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Compare sorted files FILE1 and FILE2 line by line.\n\
|
||||
"), stdout);
|
||||
@@ -139,8 +140,8 @@ Examples:\n\
|
||||
%s -12 file1 file2 Print only lines present in both file1 and file2.\n\
|
||||
%s -3 file1 file2 Print lines in file1 not in file2, and vice versa.\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -157,26 +158,26 @@ writeline (struct linebuffer const *line, FILE *stream, int class)
|
||||
{
|
||||
case 1:
|
||||
if (!only_file_1)
|
||||
return;
|
||||
return;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (!only_file_2)
|
||||
return;
|
||||
return;
|
||||
/* Print a delimiter if we are printing lines from file 1. */
|
||||
if (only_file_1)
|
||||
fputs (delimiter, stream);
|
||||
fputs (delimiter, stream);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (!both)
|
||||
return;
|
||||
return;
|
||||
/* Print a delimiter if we are printing lines from file 1. */
|
||||
if (only_file_1)
|
||||
fputs (delimiter, stream);
|
||||
fputs (delimiter, stream);
|
||||
/* Print a delimiter if we are printing lines from file 2. */
|
||||
if (only_file_2)
|
||||
fputs (delimiter, stream);
|
||||
fputs (delimiter, stream);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,35 +197,35 @@ writeline (struct linebuffer const *line, FILE *stream, int class)
|
||||
|
||||
static void
|
||||
check_order (struct linebuffer const *prev,
|
||||
struct linebuffer const *current,
|
||||
int whatfile)
|
||||
struct linebuffer const *current,
|
||||
int whatfile)
|
||||
{
|
||||
|
||||
if (check_input_order != CHECK_ORDER_DISABLED
|
||||
&& ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable))
|
||||
{
|
||||
if (!issued_disorder_warning[whatfile - 1])
|
||||
{
|
||||
int order;
|
||||
{
|
||||
int order;
|
||||
|
||||
if (hard_LC_COLLATE)
|
||||
order = xmemcoll (prev->buffer, prev->length - 1,
|
||||
current->buffer, current->length - 1);
|
||||
else
|
||||
order = memcmp2 (prev->buffer, prev->length - 1,
|
||||
current->buffer, current->length - 1);
|
||||
if (hard_LC_COLLATE)
|
||||
order = xmemcoll (prev->buffer, prev->length - 1,
|
||||
current->buffer, current->length - 1);
|
||||
else
|
||||
order = memcmp2 (prev->buffer, prev->length - 1,
|
||||
current->buffer, current->length - 1);
|
||||
|
||||
if (0 < order)
|
||||
{
|
||||
error ((check_input_order == CHECK_ORDER_ENABLED
|
||||
? EXIT_FAILURE : 0),
|
||||
0, _("file %d is not in sorted order"), whatfile);
|
||||
if (0 < order)
|
||||
{
|
||||
error ((check_input_order == CHECK_ORDER_ENABLED
|
||||
? EXIT_FAILURE : 0),
|
||||
0, _("file %d is not in sorted order"), whatfile);
|
||||
|
||||
/* If we get to here, the message was just a warning, but we
|
||||
want only to issue it once. */
|
||||
issued_disorder_warning[whatfile - 1] = true;
|
||||
}
|
||||
}
|
||||
/* If we get to here, the message was just a warning, but we
|
||||
want only to issue it once. */
|
||||
issued_disorder_warning[whatfile - 1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,20 +261,20 @@ compare_files (char **infiles)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
initbuffer (&lba[i][j]);
|
||||
all_line[i][j] = &lba[i][j];
|
||||
}
|
||||
{
|
||||
initbuffer (&lba[i][j]);
|
||||
all_line[i][j] = &lba[i][j];
|
||||
}
|
||||
alt[i][0] = 0;
|
||||
alt[i][1] = 0;
|
||||
alt[i][2] = 0;
|
||||
streams[i] = (STREQ (infiles[i], "-") ? stdin : fopen (infiles[i], "r"));
|
||||
if (!streams[i])
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
|
||||
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
|
||||
if (ferror (streams[i]))
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
}
|
||||
|
||||
while (thisline[0] || thisline[1])
|
||||
@@ -284,69 +285,69 @@ compare_files (char **infiles)
|
||||
/* Compare the next available lines of the two files. */
|
||||
|
||||
if (!thisline[0])
|
||||
order = 1;
|
||||
order = 1;
|
||||
else if (!thisline[1])
|
||||
order = -1;
|
||||
order = -1;
|
||||
else
|
||||
{
|
||||
if (hard_LC_COLLATE)
|
||||
order = xmemcoll (thisline[0]->buffer, thisline[0]->length - 1,
|
||||
thisline[1]->buffer, thisline[1]->length - 1);
|
||||
else
|
||||
{
|
||||
size_t len = min (thisline[0]->length, thisline[1]->length) - 1;
|
||||
order = memcmp (thisline[0]->buffer, thisline[1]->buffer, len);
|
||||
if (order == 0)
|
||||
order = (thisline[0]->length < thisline[1]->length
|
||||
? -1
|
||||
: thisline[0]->length != thisline[1]->length);
|
||||
}
|
||||
}
|
||||
{
|
||||
if (hard_LC_COLLATE)
|
||||
order = xmemcoll (thisline[0]->buffer, thisline[0]->length - 1,
|
||||
thisline[1]->buffer, thisline[1]->length - 1);
|
||||
else
|
||||
{
|
||||
size_t len = min (thisline[0]->length, thisline[1]->length) - 1;
|
||||
order = memcmp (thisline[0]->buffer, thisline[1]->buffer, len);
|
||||
if (order == 0)
|
||||
order = (thisline[0]->length < thisline[1]->length
|
||||
? -1
|
||||
: thisline[0]->length != thisline[1]->length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the line that is lesser. */
|
||||
if (order == 0)
|
||||
writeline (thisline[1], stdout, 3);
|
||||
writeline (thisline[1], stdout, 3);
|
||||
else
|
||||
{
|
||||
seen_unpairable = true;
|
||||
if (order <= 0)
|
||||
writeline (thisline[0], stdout, 1);
|
||||
else
|
||||
writeline (thisline[1], stdout, 2);
|
||||
}
|
||||
{
|
||||
seen_unpairable = true;
|
||||
if (order <= 0)
|
||||
writeline (thisline[0], stdout, 1);
|
||||
else
|
||||
writeline (thisline[1], stdout, 2);
|
||||
}
|
||||
|
||||
/* Step the file the line came from.
|
||||
If the files match, step both files. */
|
||||
If the files match, step both files. */
|
||||
if (0 <= order)
|
||||
fill_up[1] = true;
|
||||
fill_up[1] = true;
|
||||
if (order <= 0)
|
||||
fill_up[0] = true;
|
||||
fill_up[0] = true;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
if (fill_up[i])
|
||||
{
|
||||
/* Rotate the buffers for this file. */
|
||||
alt[i][2] = alt[i][1];
|
||||
alt[i][1] = alt[i][0];
|
||||
alt[i][0] = (alt[i][0] + 1) & 0x03;
|
||||
if (fill_up[i])
|
||||
{
|
||||
/* Rotate the buffers for this file. */
|
||||
alt[i][2] = alt[i][1];
|
||||
alt[i][1] = alt[i][0];
|
||||
alt[i][0] = (alt[i][0] + 1) & 0x03;
|
||||
|
||||
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
|
||||
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
|
||||
|
||||
if (thisline[i])
|
||||
check_order (all_line[i][alt[i][1]], thisline[i], i + 1);
|
||||
if (thisline[i])
|
||||
check_order (all_line[i][alt[i][1]], thisline[i], i + 1);
|
||||
|
||||
/* If this is the end of the file we may need to re-check
|
||||
the order of the previous two lines, since we might have
|
||||
discovered an unpairable match since we checked before. */
|
||||
else if (all_line[i][alt[i][2]]->buffer)
|
||||
check_order (all_line[i][alt[i][2]],
|
||||
all_line[i][alt[i][1]], i + 1);
|
||||
/* If this is the end of the file we may need to re-check
|
||||
the order of the previous two lines, since we might have
|
||||
discovered an unpairable match since we checked before. */
|
||||
else if (all_line[i][alt[i][2]]->buffer)
|
||||
check_order (all_line[i][alt[i][2]],
|
||||
all_line[i][alt[i][1]], i + 1);
|
||||
|
||||
if (ferror (streams[i]))
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
if (ferror (streams[i]))
|
||||
error (EXIT_FAILURE, errno, "%s", infiles[i]);
|
||||
|
||||
fill_up[i] = false;
|
||||
}
|
||||
fill_up[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
@@ -380,50 +381,50 @@ main (int argc, char **argv)
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
only_file_1 = false;
|
||||
break;
|
||||
only_file_1 = false;
|
||||
break;
|
||||
|
||||
case '2':
|
||||
only_file_2 = false;
|
||||
break;
|
||||
only_file_2 = false;
|
||||
break;
|
||||
|
||||
case '3':
|
||||
both = false;
|
||||
break;
|
||||
both = false;
|
||||
break;
|
||||
|
||||
case NOCHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_DISABLED;
|
||||
break;
|
||||
check_input_order = CHECK_ORDER_DISABLED;
|
||||
break;
|
||||
|
||||
case CHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_ENABLED;
|
||||
break;
|
||||
check_input_order = CHECK_ORDER_ENABLED;
|
||||
break;
|
||||
|
||||
case OUTPUT_DELIMITER_OPTION:
|
||||
if (delimiter && !STREQ (delimiter, optarg))
|
||||
error (EXIT_FAILURE, 0, _("multiple delimiters specified"));
|
||||
delimiter = optarg;
|
||||
if (!*delimiter)
|
||||
{
|
||||
error (EXIT_FAILURE, 0, _("empty %s not allowed"),
|
||||
quote ("--output-delimiter"));
|
||||
}
|
||||
break;
|
||||
if (delimiter && !STREQ (delimiter, optarg))
|
||||
error (EXIT_FAILURE, 0, _("multiple delimiters specified"));
|
||||
delimiter = optarg;
|
||||
if (!*delimiter)
|
||||
{
|
||||
error (EXIT_FAILURE, 0, _("empty %s not allowed"),
|
||||
quote ("--output-delimiter"));
|
||||
}
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argc - optind < 2)
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
2160
src/copy.c
2160
src/copy.c
File diff suppressed because it is too large
Load Diff
26
src/copy.h
26
src/copy.h
@@ -43,6 +43,19 @@ enum Sparse_type
|
||||
SPARSE_ALWAYS
|
||||
};
|
||||
|
||||
/* Control creation of COW files. */
|
||||
enum Reflink_type
|
||||
{
|
||||
/* Default to a standard copy. */
|
||||
REFLINK_NEVER,
|
||||
|
||||
/* Try a COW copy and fall back to a standard copy. */
|
||||
REFLINK_AUTO,
|
||||
|
||||
/* Require a COW copy and fail if not available. */
|
||||
REFLINK_ALWAYS
|
||||
};
|
||||
|
||||
/* This type is used to help mv (via copy.c) distinguish these cases. */
|
||||
enum Interactive
|
||||
{
|
||||
@@ -73,6 +86,11 @@ enum Dereference_symlink
|
||||
|| (Mode) == SPARSE_AUTO \
|
||||
|| (Mode) == SPARSE_ALWAYS)
|
||||
|
||||
# define VALID_REFLINK_MODE(Mode) \
|
||||
((Mode) == REFLINK_NEVER \
|
||||
|| (Mode) == REFLINK_AUTO \
|
||||
|| (Mode) == REFLINK_ALWAYS)
|
||||
|
||||
/* These options control how files are copied by at least the
|
||||
following programs: mv (when rename doesn't work), cp, install.
|
||||
So, if you add a new member, be sure to initialize it in
|
||||
@@ -219,8 +237,8 @@ struct cp_options
|
||||
such a symlink) and returns false. */
|
||||
bool open_dangling_dest_symlink;
|
||||
|
||||
/* If true, attempt to clone the file instead of copying it. */
|
||||
bool reflink;
|
||||
/* Control creation of COW files. */
|
||||
enum Reflink_type reflink_mode;
|
||||
|
||||
/* This is a set of destination name/inode/dev triples. Each such triple
|
||||
represents a file we have created corresponding to a source file name
|
||||
@@ -252,8 +270,8 @@ int rpl_rename (const char *, const char *);
|
||||
# endif
|
||||
|
||||
bool copy (char const *src_name, char const *dst_name,
|
||||
bool nonexistent_dst, const struct cp_options *options,
|
||||
bool *copy_into_self, bool *rename_succeeded);
|
||||
bool nonexistent_dst, const struct cp_options *options,
|
||||
bool *copy_into_self, bool *rename_succeeded);
|
||||
|
||||
void dest_info_init (struct cp_options *);
|
||||
void src_info_init (struct cp_options *);
|
||||
|
||||
@@ -148,9 +148,9 @@ extern void
|
||||
hash_init (void)
|
||||
{
|
||||
src_to_dest = hash_initialize (INITIAL_TABLE_SIZE, NULL,
|
||||
src_to_dest_hash,
|
||||
src_to_dest_compare,
|
||||
src_to_dest_free);
|
||||
src_to_dest_hash,
|
||||
src_to_dest_compare,
|
||||
src_to_dest_free);
|
||||
if (src_to_dest == NULL)
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
516
src/csplit.c
516
src/csplit.c
@@ -346,7 +346,7 @@ record_line_starts (struct buffer_record *b)
|
||||
{
|
||||
line_end = memchr (line_start, '\n', bytes_left);
|
||||
if (line_end == NULL)
|
||||
break;
|
||||
break;
|
||||
line_length = line_end - line_start + 1;
|
||||
keep_new_line (b, line_start, line_length);
|
||||
bytes_left -= line_length;
|
||||
@@ -358,12 +358,12 @@ record_line_starts (struct buffer_record *b)
|
||||
if (bytes_left)
|
||||
{
|
||||
if (have_read_eof)
|
||||
{
|
||||
keep_new_line (b, line_start, bytes_left);
|
||||
lines++;
|
||||
}
|
||||
{
|
||||
keep_new_line (b, line_start, bytes_left);
|
||||
lines++;
|
||||
}
|
||||
else
|
||||
save_to_hold_area (xmemdup (line_start, bytes_left), bytes_left);
|
||||
save_to_hold_area (xmemdup (line_start, bytes_left), bytes_left);
|
||||
}
|
||||
|
||||
b->num_lines = lines;
|
||||
@@ -438,7 +438,7 @@ save_buffer (struct buffer_record *buf)
|
||||
else
|
||||
{
|
||||
for (p = head; p->next; p = p->next)
|
||||
/* Do nothing. */ ;
|
||||
/* Do nothing. */ ;
|
||||
p->next = buf;
|
||||
}
|
||||
}
|
||||
@@ -481,25 +481,25 @@ load_buffer (void)
|
||||
|
||||
/* First check the `holding' area for a partial line. */
|
||||
if (hold_count)
|
||||
{
|
||||
memcpy (p, hold_area, hold_count);
|
||||
p += hold_count;
|
||||
b->bytes_used += hold_count;
|
||||
bytes_avail -= hold_count;
|
||||
hold_count = 0;
|
||||
}
|
||||
{
|
||||
memcpy (p, hold_area, hold_count);
|
||||
p += hold_count;
|
||||
b->bytes_used += hold_count;
|
||||
bytes_avail -= hold_count;
|
||||
hold_count = 0;
|
||||
}
|
||||
|
||||
b->bytes_used += read_input (p, bytes_avail);
|
||||
|
||||
lines_found = record_line_starts (b);
|
||||
if (!lines_found)
|
||||
free_buffer (b);
|
||||
free_buffer (b);
|
||||
|
||||
if (lines_found || have_read_eof)
|
||||
break;
|
||||
break;
|
||||
|
||||
if (xalloc_oversized (2, b->bytes_alloc))
|
||||
xalloc_die ();
|
||||
xalloc_die ();
|
||||
bytes_wanted = 2 * b->bytes_alloc;
|
||||
free_buffer (b);
|
||||
free (b);
|
||||
@@ -563,13 +563,13 @@ remove_line (void)
|
||||
/* Go on to the next line record. */
|
||||
head->curr_line = l->next;
|
||||
if (head->curr_line == NULL || head->curr_line->used == 0)
|
||||
{
|
||||
/* Go on to the next data block.
|
||||
but first record the current one so we can free it
|
||||
once the line we're returning has been processed. */
|
||||
prev_buf = head;
|
||||
head = head->next;
|
||||
}
|
||||
{
|
||||
/* Go on to the next data block.
|
||||
but first record the current one so we can free it
|
||||
once the line we're returning has been processed. */
|
||||
prev_buf = head;
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
@@ -592,23 +592,23 @@ find_line (uintmax_t linenum)
|
||||
for (b = head;;)
|
||||
{
|
||||
if (linenum < b->start_line + b->num_lines)
|
||||
{
|
||||
/* The line is in this buffer. */
|
||||
struct line *l;
|
||||
size_t offset; /* How far into the buffer the line is. */
|
||||
{
|
||||
/* The line is in this buffer. */
|
||||
struct line *l;
|
||||
size_t offset; /* How far into the buffer the line is. */
|
||||
|
||||
l = b->line_start;
|
||||
offset = linenum - b->start_line;
|
||||
/* Find the control record. */
|
||||
while (offset >= CTRL_SIZE)
|
||||
{
|
||||
l = l->next;
|
||||
offset -= CTRL_SIZE;
|
||||
}
|
||||
return &l->starts[offset];
|
||||
}
|
||||
l = b->line_start;
|
||||
offset = linenum - b->start_line;
|
||||
/* Find the control record. */
|
||||
while (offset >= CTRL_SIZE)
|
||||
{
|
||||
l = l->next;
|
||||
offset -= CTRL_SIZE;
|
||||
}
|
||||
return &l->starts[offset];
|
||||
}
|
||||
if (b->next == NULL && !load_buffer ())
|
||||
return NULL;
|
||||
return NULL;
|
||||
b = b->next; /* Try the next data block. */
|
||||
}
|
||||
}
|
||||
@@ -657,12 +657,12 @@ write_to_file (uintmax_t last_line, bool ignore, int argnum)
|
||||
{
|
||||
line = remove_line ();
|
||||
if (line == NULL)
|
||||
{
|
||||
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
|
||||
cleanup_fatal ();
|
||||
}
|
||||
{
|
||||
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (!ignore)
|
||||
save_line_to_file (line);
|
||||
save_line_to_file (line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ handle_line_error (const struct control *p, uintmax_t repetition)
|
||||
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
|
||||
fprintf (stderr, _("%s: %s: line number out of range"),
|
||||
program_name, quote (umaxtostr (p->lines_required, buf)));
|
||||
program_name, quote (umaxtostr (p->lines_required, buf)));
|
||||
if (repetition)
|
||||
fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
|
||||
else
|
||||
@@ -717,7 +717,7 @@ process_line_count (const struct control *p, uintmax_t repetition)
|
||||
{
|
||||
line = remove_line ();
|
||||
if (line == NULL)
|
||||
handle_line_error (p, repetition);
|
||||
handle_line_error (p, repetition);
|
||||
save_line_to_file (line);
|
||||
}
|
||||
|
||||
@@ -734,7 +734,7 @@ static void
|
||||
regexp_error (struct control *p, uintmax_t repetition, bool ignore)
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: match not found"),
|
||||
program_name, quote (global_argv[p->argnum]));
|
||||
program_name, quote (global_argv[p->argnum]));
|
||||
|
||||
if (repetition)
|
||||
{
|
||||
@@ -774,75 +774,75 @@ process_regexp (struct control *p, uintmax_t repetition)
|
||||
if (p->offset >= 0)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
line = find_line (++current_line);
|
||||
if (line == NULL)
|
||||
{
|
||||
if (p->repeat_forever)
|
||||
{
|
||||
if (!ignore)
|
||||
{
|
||||
dump_rest_of_file ();
|
||||
close_output_file ();
|
||||
}
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
regexp_error (p, repetition, ignore);
|
||||
}
|
||||
line_len = line->len;
|
||||
if (line->str[line_len - 1] == '\n')
|
||||
line_len--;
|
||||
ret = re_search (&p->re_compiled, line->str, line_len,
|
||||
0, line_len, NULL);
|
||||
if (ret == -2)
|
||||
{
|
||||
error (0, 0, _("error in regular expression search"));
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
line = remove_line ();
|
||||
if (!ignore)
|
||||
save_line_to_file (line);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
{
|
||||
line = find_line (++current_line);
|
||||
if (line == NULL)
|
||||
{
|
||||
if (p->repeat_forever)
|
||||
{
|
||||
if (!ignore)
|
||||
{
|
||||
dump_rest_of_file ();
|
||||
close_output_file ();
|
||||
}
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
regexp_error (p, repetition, ignore);
|
||||
}
|
||||
line_len = line->len;
|
||||
if (line->str[line_len - 1] == '\n')
|
||||
line_len--;
|
||||
ret = re_search (&p->re_compiled, line->str, line_len,
|
||||
0, line_len, NULL);
|
||||
if (ret == -2)
|
||||
{
|
||||
error (0, 0, _("error in regular expression search"));
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
line = remove_line ();
|
||||
if (!ignore)
|
||||
save_line_to_file (line);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Buffer the lines. */
|
||||
for (;;)
|
||||
{
|
||||
line = find_line (++current_line);
|
||||
if (line == NULL)
|
||||
{
|
||||
if (p->repeat_forever)
|
||||
{
|
||||
if (!ignore)
|
||||
{
|
||||
dump_rest_of_file ();
|
||||
close_output_file ();
|
||||
}
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
regexp_error (p, repetition, ignore);
|
||||
}
|
||||
line_len = line->len;
|
||||
if (line->str[line_len - 1] == '\n')
|
||||
line_len--;
|
||||
ret = re_search (&p->re_compiled, line->str, line_len,
|
||||
0, line_len, NULL);
|
||||
if (ret == -2)
|
||||
{
|
||||
error (0, 0, _("error in regular expression search"));
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (ret != -1)
|
||||
break;
|
||||
}
|
||||
{
|
||||
line = find_line (++current_line);
|
||||
if (line == NULL)
|
||||
{
|
||||
if (p->repeat_forever)
|
||||
{
|
||||
if (!ignore)
|
||||
{
|
||||
dump_rest_of_file ();
|
||||
close_output_file ();
|
||||
}
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
regexp_error (p, repetition, ignore);
|
||||
}
|
||||
line_len = line->len;
|
||||
if (line->str[line_len - 1] == '\n')
|
||||
line_len--;
|
||||
ret = re_search (&p->re_compiled, line->str, line_len,
|
||||
0, line_len, NULL);
|
||||
if (ret == -2)
|
||||
{
|
||||
error (0, 0, _("error in regular expression search"));
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (ret != -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Account for any offset from this regexp. */
|
||||
@@ -868,17 +868,17 @@ split_file (void)
|
||||
{
|
||||
uintmax_t j;
|
||||
if (controls[i].regexpr)
|
||||
{
|
||||
for (j = 0; (controls[i].repeat_forever
|
||||
|| j <= controls[i].repeat); j++)
|
||||
process_regexp (&controls[i], j);
|
||||
}
|
||||
{
|
||||
for (j = 0; (controls[i].repeat_forever
|
||||
|| j <= controls[i].repeat); j++)
|
||||
process_regexp (&controls[i], j);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; (controls[i].repeat_forever
|
||||
|| j <= controls[i].repeat); j++)
|
||||
process_line_count (&controls[i], j);
|
||||
}
|
||||
{
|
||||
for (j = 0; (controls[i].repeat_forever
|
||||
|| j <= controls[i].repeat); j++)
|
||||
process_line_count (&controls[i], j);
|
||||
}
|
||||
}
|
||||
|
||||
create_output_file ();
|
||||
@@ -946,7 +946,7 @@ delete_all_files (bool in_signal_handler)
|
||||
{
|
||||
const char *name = make_filename (i);
|
||||
if (unlink (name) != 0 && !in_signal_handler)
|
||||
error (0, errno, "%s", name);
|
||||
error (0, errno, "%s", name);
|
||||
}
|
||||
|
||||
files_created = 0;
|
||||
@@ -961,41 +961,41 @@ close_output_file (void)
|
||||
if (output_stream)
|
||||
{
|
||||
if (ferror (output_stream))
|
||||
{
|
||||
error (0, 0, _("write error for %s"), quote (output_filename));
|
||||
output_stream = NULL;
|
||||
cleanup_fatal ();
|
||||
}
|
||||
{
|
||||
error (0, 0, _("write error for %s"), quote (output_filename));
|
||||
output_stream = NULL;
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (fclose (output_stream) != 0)
|
||||
{
|
||||
error (0, errno, "%s", output_filename);
|
||||
output_stream = NULL;
|
||||
cleanup_fatal ();
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", output_filename);
|
||||
output_stream = NULL;
|
||||
cleanup_fatal ();
|
||||
}
|
||||
if (bytes_written == 0 && elide_empty_files)
|
||||
{
|
||||
sigset_t oldset;
|
||||
bool unlink_ok;
|
||||
int unlink_errno;
|
||||
{
|
||||
sigset_t oldset;
|
||||
bool unlink_ok;
|
||||
int unlink_errno;
|
||||
|
||||
/* Remove the output file in a critical section, to avoid races. */
|
||||
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
|
||||
unlink_ok = (unlink (output_filename) == 0);
|
||||
unlink_errno = errno;
|
||||
files_created -= unlink_ok;
|
||||
sigprocmask (SIG_SETMASK, &oldset, NULL);
|
||||
/* Remove the output file in a critical section, to avoid races. */
|
||||
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
|
||||
unlink_ok = (unlink (output_filename) == 0);
|
||||
unlink_errno = errno;
|
||||
files_created -= unlink_ok;
|
||||
sigprocmask (SIG_SETMASK, &oldset, NULL);
|
||||
|
||||
if (! unlink_ok)
|
||||
error (0, unlink_errno, "%s", output_filename);
|
||||
}
|
||||
if (! unlink_ok)
|
||||
error (0, unlink_errno, "%s", output_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!suppress_count)
|
||||
{
|
||||
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!suppress_count)
|
||||
{
|
||||
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
|
||||
}
|
||||
}
|
||||
output_stream = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1062,11 +1062,11 @@ parse_repeat_count (int argnum, struct control *p, char *str)
|
||||
else
|
||||
{
|
||||
if (xstrtoumax (str + 1, NULL, 10, &val, "") != LONGINT_OK)
|
||||
{
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s}: integer required between `{' and `}'"),
|
||||
global_argv[argnum]);
|
||||
}
|
||||
{
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s}: integer required between `{' and `}'"),
|
||||
global_argv[argnum]);
|
||||
}
|
||||
p->repeat = val;
|
||||
}
|
||||
|
||||
@@ -1091,7 +1091,7 @@ extract_regexp (int argnum, bool ignore, char const *str)
|
||||
closing_delim = strrchr (str + 1, delim);
|
||||
if (closing_delim == NULL)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s: closing delimiter `%c' missing"), str, delim);
|
||||
_("%s: closing delimiter `%c' missing"), str, delim);
|
||||
|
||||
len = closing_delim - str - 1;
|
||||
p = new_control_record ();
|
||||
@@ -1132,44 +1132,44 @@ parse_patterns (int argc, int start, char **argv)
|
||||
for (i = start; i < argc; i++)
|
||||
{
|
||||
if (*argv[i] == '/' || *argv[i] == '%')
|
||||
{
|
||||
p = extract_regexp (i, *argv[i] == '%', argv[i]);
|
||||
}
|
||||
{
|
||||
p = extract_regexp (i, *argv[i] == '%', argv[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new_control_record ();
|
||||
p->argnum = i;
|
||||
{
|
||||
p = new_control_record ();
|
||||
p->argnum = i;
|
||||
|
||||
if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
|
||||
error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
|
||||
if (val == 0)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s: line number must be greater than zero"),
|
||||
argv[i]);
|
||||
if (val < last_val)
|
||||
{
|
||||
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("line number %s is smaller than preceding line number, %s"),
|
||||
quote (argv[i]), umaxtostr (last_val, buf));
|
||||
}
|
||||
if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
|
||||
error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
|
||||
if (val == 0)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s: line number must be greater than zero"),
|
||||
argv[i]);
|
||||
if (val < last_val)
|
||||
{
|
||||
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("line number %s is smaller than preceding line number, %s"),
|
||||
quote (argv[i]), umaxtostr (last_val, buf));
|
||||
}
|
||||
|
||||
if (val == last_val)
|
||||
error (0, 0,
|
||||
_("warning: line number %s is the same as preceding line number"),
|
||||
quote (argv[i]));
|
||||
if (val == last_val)
|
||||
error (0, 0,
|
||||
_("warning: line number %s is the same as preceding line number"),
|
||||
quote (argv[i]));
|
||||
|
||||
last_val = val;
|
||||
last_val = val;
|
||||
|
||||
p->lines_required = val;
|
||||
}
|
||||
p->lines_required = val;
|
||||
}
|
||||
|
||||
if (i + 1 < argc && *argv[i + 1] == '{')
|
||||
{
|
||||
/* We have a repeat count. */
|
||||
i++;
|
||||
parse_repeat_count (i, p, argv[i]);
|
||||
}
|
||||
{
|
||||
/* We have a repeat count. */
|
||||
i++;
|
||||
parse_repeat_count (i, p, argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,22 +1181,22 @@ get_format_flags (char **format_ptr)
|
||||
for (; **format_ptr; (*format_ptr)++)
|
||||
{
|
||||
switch (**format_ptr)
|
||||
{
|
||||
case '-':
|
||||
break;
|
||||
{
|
||||
case '-':
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case ' ':
|
||||
count |= 1;
|
||||
break;
|
||||
case '+':
|
||||
case ' ':
|
||||
count |= 1;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
count |= 2; /* Allow for 0x prefix preceding an `x' conversion. */
|
||||
break;
|
||||
case '#':
|
||||
count |= 2; /* Allow for 0x prefix preceding an `x' conversion. */
|
||||
break;
|
||||
|
||||
default:
|
||||
return count;
|
||||
}
|
||||
default:
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -1208,7 +1208,7 @@ get_format_width (char **format_ptr)
|
||||
|
||||
if (ISDIGIT (**format_ptr)
|
||||
&& (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
|
||||
|| SIZE_MAX < val))
|
||||
|| SIZE_MAX < val))
|
||||
error (EXIT_FAILURE, 0, _("invalid format width"));
|
||||
|
||||
/* Allow for enough octal digits to represent the value of UINT_MAX,
|
||||
@@ -1229,8 +1229,8 @@ get_format_prec (char **format_ptr)
|
||||
{
|
||||
unsigned long int val;
|
||||
if (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
|
||||
|| SIZE_MAX < val)
|
||||
error (EXIT_FAILURE, 0, _("invalid format precision"));
|
||||
|| SIZE_MAX < val)
|
||||
error (EXIT_FAILURE, 0, _("invalid format precision"));
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -1257,10 +1257,10 @@ get_format_conv_type (char **format_ptr)
|
||||
default:
|
||||
if (isprint (ch))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid conversion specifier in suffix: %c"), ch);
|
||||
_("invalid conversion specifier in suffix: %c"), ch);
|
||||
else
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid conversion specifier in suffix: \\%.3o"), ch);
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid conversion specifier in suffix: \\%.3o"), ch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,30 +1275,30 @@ max_out (char *format)
|
||||
if (*format++ != '%')
|
||||
out_count++;
|
||||
else if (*format == '%')
|
||||
{
|
||||
format++;
|
||||
out_count++;
|
||||
}
|
||||
{
|
||||
format++;
|
||||
out_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (percent)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("too many %% conversion specifications in suffix"));
|
||||
percent = true;
|
||||
out_count += get_format_flags (&format);
|
||||
{
|
||||
size_t width = get_format_width (&format);
|
||||
size_t prec = get_format_prec (&format);
|
||||
{
|
||||
if (percent)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("too many %% conversion specifications in suffix"));
|
||||
percent = true;
|
||||
out_count += get_format_flags (&format);
|
||||
{
|
||||
size_t width = get_format_width (&format);
|
||||
size_t prec = get_format_prec (&format);
|
||||
|
||||
out_count += MAX (width, prec);
|
||||
}
|
||||
get_format_conv_type (&format);
|
||||
}
|
||||
out_count += MAX (width, prec);
|
||||
}
|
||||
get_format_conv_type (&format);
|
||||
}
|
||||
}
|
||||
|
||||
if (! percent)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("missing %% conversion specification in suffix"));
|
||||
_("missing %% conversion specification in suffix"));
|
||||
|
||||
return out_count;
|
||||
}
|
||||
@@ -1328,47 +1328,47 @@ main (int argc, char **argv)
|
||||
switch (optc)
|
||||
{
|
||||
case 'f':
|
||||
prefix = optarg;
|
||||
break;
|
||||
prefix = optarg;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
suffix = optarg;
|
||||
break;
|
||||
suffix = optarg;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
remove_files = false;
|
||||
break;
|
||||
remove_files = false;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|
||||
|| val > INT_MAX)
|
||||
error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
|
||||
digits = val;
|
||||
break;
|
||||
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|
||||
|| val > INT_MAX)
|
||||
error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
|
||||
digits = val;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'q':
|
||||
suppress_count = true;
|
||||
break;
|
||||
suppress_count = true;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
elide_empty_files = true;
|
||||
break;
|
||||
elide_empty_files = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argc - optind < 2)
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -1385,22 +1385,22 @@ main (int argc, char **argv)
|
||||
int i;
|
||||
static int const sig[] =
|
||||
{
|
||||
/* The usual suspects. */
|
||||
SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
|
||||
/* The usual suspects. */
|
||||
SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
|
||||
#ifdef SIGPOLL
|
||||
SIGPOLL,
|
||||
SIGPOLL,
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
SIGPROF,
|
||||
SIGPROF,
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
SIGVTALRM,
|
||||
SIGVTALRM,
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
SIGXCPU,
|
||||
SIGXCPU,
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
SIGXFSZ,
|
||||
SIGXFSZ,
|
||||
#endif
|
||||
};
|
||||
enum { nsigs = ARRAY_CARDINALITY (sig) };
|
||||
@@ -1410,9 +1410,9 @@ main (int argc, char **argv)
|
||||
sigemptyset (&caught_signals);
|
||||
for (i = 0; i < nsigs; i++)
|
||||
{
|
||||
sigaction (sig[i], NULL, &act);
|
||||
if (act.sa_handler != SIG_IGN)
|
||||
sigaddset (&caught_signals, sig[i]);
|
||||
sigaction (sig[i], NULL, &act);
|
||||
if (act.sa_handler != SIG_IGN)
|
||||
sigaddset (&caught_signals, sig[i]);
|
||||
}
|
||||
|
||||
act.sa_handler = interrupt_handler;
|
||||
@@ -1421,7 +1421,7 @@ main (int argc, char **argv)
|
||||
|
||||
for (i = 0; i < nsigs; i++)
|
||||
if (sigismember (&caught_signals, sig[i]))
|
||||
sigaction (sig[i], &act, NULL);
|
||||
sigaction (sig[i], &act, NULL);
|
||||
}
|
||||
|
||||
split_file ();
|
||||
@@ -1440,13 +1440,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... FILE PATTERN...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Output pieces of FILE separated by PATTERN(s) to files `xx00', `xx01', ...,\n\
|
||||
and output byte counts of each piece to standard output.\n\
|
||||
@@ -1481,7 +1481,7 @@ Read standard input if FILE is -. Each PATTERN may be:\n\
|
||||
\n\
|
||||
A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
570
src/cut.c
570
src/cut.c
@@ -60,11 +60,11 @@
|
||||
do \
|
||||
{ \
|
||||
if (low == 0 || high == 0) \
|
||||
FATAL_ERROR (_("fields and positions are numbered from 1")); \
|
||||
FATAL_ERROR (_("fields and positions are numbered from 1")); \
|
||||
if (n_rp >= n_rp_allocated) \
|
||||
{ \
|
||||
(rp) = X2NREALLOC (rp, &n_rp_allocated); \
|
||||
} \
|
||||
{ \
|
||||
(rp) = X2NREALLOC (rp, &n_rp_allocated); \
|
||||
} \
|
||||
rp[n_rp].lo = (low); \
|
||||
rp[n_rp].hi = (high); \
|
||||
++n_rp; \
|
||||
@@ -183,13 +183,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s OPTION... [FILE]...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Print selected parts of lines from each FILE to standard output.\n\
|
||||
\n\
|
||||
@@ -235,7 +235,7 @@ Each range is one of:\n\
|
||||
\n\
|
||||
With no FILE, or when FILE is -, read standard input.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -347,7 +347,7 @@ set_fields (const char *fieldstr)
|
||||
bool rhs_specified = false;
|
||||
bool dash_found = false; /* True if a '-' is found in this field. */
|
||||
bool field_found = false; /* True if at least one field spec
|
||||
has been processed. */
|
||||
has been processed. */
|
||||
|
||||
struct range_pair *rp = NULL;
|
||||
size_t n_rp = 0;
|
||||
@@ -361,139 +361,139 @@ set_fields (const char *fieldstr)
|
||||
for (;;)
|
||||
{
|
||||
if (*fieldstr == '-')
|
||||
{
|
||||
in_digits = false;
|
||||
/* Starting a range. */
|
||||
if (dash_found)
|
||||
FATAL_ERROR (_("invalid byte or field list"));
|
||||
dash_found = true;
|
||||
fieldstr++;
|
||||
{
|
||||
in_digits = false;
|
||||
/* Starting a range. */
|
||||
if (dash_found)
|
||||
FATAL_ERROR (_("invalid byte or field list"));
|
||||
dash_found = true;
|
||||
fieldstr++;
|
||||
|
||||
initial = (lhs_specified ? value : 1);
|
||||
value = 0;
|
||||
}
|
||||
initial = (lhs_specified ? value : 1);
|
||||
value = 0;
|
||||
}
|
||||
else if (*fieldstr == ',' ||
|
||||
isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
|
||||
{
|
||||
in_digits = false;
|
||||
/* Ending the string, or this field/byte sublist. */
|
||||
if (dash_found)
|
||||
{
|
||||
dash_found = false;
|
||||
isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
|
||||
{
|
||||
in_digits = false;
|
||||
/* Ending the string, or this field/byte sublist. */
|
||||
if (dash_found)
|
||||
{
|
||||
dash_found = false;
|
||||
|
||||
if (!lhs_specified && !rhs_specified)
|
||||
FATAL_ERROR (_("invalid range with no endpoint: -"));
|
||||
if (!lhs_specified && !rhs_specified)
|
||||
FATAL_ERROR (_("invalid range with no endpoint: -"));
|
||||
|
||||
/* A range. Possibilities: -n, m-n, n-.
|
||||
In any case, `initial' contains the start of the range. */
|
||||
if (!rhs_specified)
|
||||
{
|
||||
/* `n-'. From `initial' to end of line. */
|
||||
eol_range_start = initial;
|
||||
field_found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* `m-n' or `-n' (1-n). */
|
||||
if (value < initial)
|
||||
FATAL_ERROR (_("invalid decreasing range"));
|
||||
/* A range. Possibilities: -n, m-n, n-.
|
||||
In any case, `initial' contains the start of the range. */
|
||||
if (!rhs_specified)
|
||||
{
|
||||
/* `n-'. From `initial' to end of line. */
|
||||
eol_range_start = initial;
|
||||
field_found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* `m-n' or `-n' (1-n). */
|
||||
if (value < initial)
|
||||
FATAL_ERROR (_("invalid decreasing range"));
|
||||
|
||||
/* Is there already a range going to end of line? */
|
||||
if (eol_range_start != 0)
|
||||
{
|
||||
/* Yes. Is the new sequence already contained
|
||||
in the old one? If so, no processing is
|
||||
necessary. */
|
||||
if (initial < eol_range_start)
|
||||
{
|
||||
/* No, the new sequence starts before the
|
||||
old. Does the old range going to end of line
|
||||
extend into the new range? */
|
||||
if (eol_range_start <= value)
|
||||
{
|
||||
/* Yes. Simply move the end of line marker. */
|
||||
eol_range_start = initial;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No. A simple range, before and disjoint from
|
||||
the range going to end of line. Fill it. */
|
||||
ADD_RANGE_PAIR (rp, initial, value);
|
||||
}
|
||||
/* Is there already a range going to end of line? */
|
||||
if (eol_range_start != 0)
|
||||
{
|
||||
/* Yes. Is the new sequence already contained
|
||||
in the old one? If so, no processing is
|
||||
necessary. */
|
||||
if (initial < eol_range_start)
|
||||
{
|
||||
/* No, the new sequence starts before the
|
||||
old. Does the old range going to end of line
|
||||
extend into the new range? */
|
||||
if (eol_range_start <= value)
|
||||
{
|
||||
/* Yes. Simply move the end of line marker. */
|
||||
eol_range_start = initial;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No. A simple range, before and disjoint from
|
||||
the range going to end of line. Fill it. */
|
||||
ADD_RANGE_PAIR (rp, initial, value);
|
||||
}
|
||||
|
||||
/* In any case, some fields were selected. */
|
||||
field_found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is no range going to end of line. */
|
||||
ADD_RANGE_PAIR (rp, initial, value);
|
||||
field_found = true;
|
||||
}
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A simple field number, not a range. */
|
||||
ADD_RANGE_PAIR (rp, value, value);
|
||||
value = 0;
|
||||
field_found = true;
|
||||
}
|
||||
/* In any case, some fields were selected. */
|
||||
field_found = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is no range going to end of line. */
|
||||
ADD_RANGE_PAIR (rp, initial, value);
|
||||
field_found = true;
|
||||
}
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A simple field number, not a range. */
|
||||
ADD_RANGE_PAIR (rp, value, value);
|
||||
value = 0;
|
||||
field_found = true;
|
||||
}
|
||||
|
||||
if (*fieldstr == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (*fieldstr == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fieldstr++;
|
||||
lhs_specified = false;
|
||||
rhs_specified = false;
|
||||
}
|
||||
fieldstr++;
|
||||
lhs_specified = false;
|
||||
rhs_specified = false;
|
||||
}
|
||||
else if (ISDIGIT (*fieldstr))
|
||||
{
|
||||
/* Record beginning of digit string, in case we have to
|
||||
complain about it. */
|
||||
static char const *num_start;
|
||||
if (!in_digits || !num_start)
|
||||
num_start = fieldstr;
|
||||
in_digits = true;
|
||||
{
|
||||
/* Record beginning of digit string, in case we have to
|
||||
complain about it. */
|
||||
static char const *num_start;
|
||||
if (!in_digits || !num_start)
|
||||
num_start = fieldstr;
|
||||
in_digits = true;
|
||||
|
||||
if (dash_found)
|
||||
rhs_specified = 1;
|
||||
else
|
||||
lhs_specified = 1;
|
||||
if (dash_found)
|
||||
rhs_specified = 1;
|
||||
else
|
||||
lhs_specified = 1;
|
||||
|
||||
/* Detect overflow. */
|
||||
if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
|
||||
{
|
||||
/* In case the user specified -c$(echo 2^64|bc),22,
|
||||
complain only about the first number. */
|
||||
/* Determine the length of the offending number. */
|
||||
size_t len = strspn (num_start, "0123456789");
|
||||
char *bad_num = xstrndup (num_start, len);
|
||||
if (operating_mode == byte_mode)
|
||||
error (0, 0,
|
||||
_("byte offset %s is too large"), quote (bad_num));
|
||||
else
|
||||
error (0, 0,
|
||||
_("field number %s is too large"), quote (bad_num));
|
||||
free (bad_num);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
/* Detect overflow. */
|
||||
if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
|
||||
{
|
||||
/* In case the user specified -c$(echo 2^64|bc),22,
|
||||
complain only about the first number. */
|
||||
/* Determine the length of the offending number. */
|
||||
size_t len = strspn (num_start, "0123456789");
|
||||
char *bad_num = xstrndup (num_start, len);
|
||||
if (operating_mode == byte_mode)
|
||||
error (0, 0,
|
||||
_("byte offset %s is too large"), quote (bad_num));
|
||||
else
|
||||
error (0, 0,
|
||||
_("field number %s is too large"), quote (bad_num));
|
||||
free (bad_num);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fieldstr++;
|
||||
}
|
||||
fieldstr++;
|
||||
}
|
||||
else
|
||||
FATAL_ERROR (_("invalid byte or field list"));
|
||||
FATAL_ERROR (_("invalid byte or field list"));
|
||||
}
|
||||
|
||||
max_range_endpoint = 0;
|
||||
for (i = 0; i < n_rp; i++)
|
||||
{
|
||||
if (rp[i].hi > max_range_endpoint)
|
||||
max_range_endpoint = rp[i].hi;
|
||||
max_range_endpoint = rp[i].hi;
|
||||
}
|
||||
|
||||
/* Allocate an array large enough so that it may be indexed by
|
||||
@@ -511,14 +511,14 @@ set_fields (const char *fieldstr)
|
||||
size_t rsi_candidate;
|
||||
|
||||
/* Record the range-start indices, i.e., record each start
|
||||
index that is not part of any other (lo..hi] range. */
|
||||
index that is not part of any other (lo..hi] range. */
|
||||
rsi_candidate = complement ? rp[i].hi + 1 : rp[i].lo;
|
||||
if (output_delimiter_specified
|
||||
&& !is_printable_field (rsi_candidate))
|
||||
mark_range_start (rsi_candidate);
|
||||
&& !is_printable_field (rsi_candidate))
|
||||
mark_range_start (rsi_candidate);
|
||||
|
||||
for (j = rp[i].lo; j <= rp[i].hi; j++)
|
||||
mark_printable_field (j);
|
||||
mark_printable_field (j);
|
||||
}
|
||||
|
||||
if (output_delimiter_specified
|
||||
@@ -550,32 +550,32 @@ cut_bytes (FILE *stream)
|
||||
c = getc (stream);
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
putchar ('\n');
|
||||
byte_idx = 0;
|
||||
print_delimiter = false;
|
||||
}
|
||||
{
|
||||
putchar ('\n');
|
||||
byte_idx = 0;
|
||||
print_delimiter = false;
|
||||
}
|
||||
else if (c == EOF)
|
||||
{
|
||||
if (byte_idx > 0)
|
||||
putchar ('\n');
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (byte_idx > 0)
|
||||
putchar ('\n');
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool range_start;
|
||||
bool *rs = output_delimiter_specified ? &range_start : NULL;
|
||||
if (print_kth (++byte_idx, rs))
|
||||
{
|
||||
if (rs && *rs && print_delimiter)
|
||||
{
|
||||
fwrite (output_delimiter_string, sizeof (char),
|
||||
output_delimiter_length, stdout);
|
||||
}
|
||||
print_delimiter = true;
|
||||
putchar (c);
|
||||
}
|
||||
}
|
||||
{
|
||||
bool range_start;
|
||||
bool *rs = output_delimiter_specified ? &range_start : NULL;
|
||||
if (print_kth (++byte_idx, rs))
|
||||
{
|
||||
if (rs && *rs && print_delimiter)
|
||||
{
|
||||
fwrite (output_delimiter_string, sizeof (char),
|
||||
output_delimiter_length, stdout);
|
||||
}
|
||||
print_delimiter = true;
|
||||
putchar (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,98 +606,98 @@ cut_fields (FILE *stream)
|
||||
while (1)
|
||||
{
|
||||
if (field_idx == 1 && buffer_first_field)
|
||||
{
|
||||
ssize_t len;
|
||||
size_t n_bytes;
|
||||
{
|
||||
ssize_t len;
|
||||
size_t n_bytes;
|
||||
|
||||
len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0,
|
||||
GETNLINE_NO_LIMIT, delim, '\n', stream);
|
||||
if (len < 0)
|
||||
{
|
||||
free (field_1_buffer);
|
||||
field_1_buffer = NULL;
|
||||
if (ferror (stream) || feof (stream))
|
||||
break;
|
||||
xalloc_die ();
|
||||
}
|
||||
len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0,
|
||||
GETNLINE_NO_LIMIT, delim, '\n', stream);
|
||||
if (len < 0)
|
||||
{
|
||||
free (field_1_buffer);
|
||||
field_1_buffer = NULL;
|
||||
if (ferror (stream) || feof (stream))
|
||||
break;
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
n_bytes = len;
|
||||
assert (n_bytes != 0);
|
||||
n_bytes = len;
|
||||
assert (n_bytes != 0);
|
||||
|
||||
/* If the first field extends to the end of line (it is not
|
||||
delimited) and we are printing all non-delimited lines,
|
||||
print this one. */
|
||||
if (to_uchar (field_1_buffer[n_bytes - 1]) != delim)
|
||||
{
|
||||
if (suppress_non_delimited)
|
||||
{
|
||||
/* Empty. */
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
|
||||
/* Make sure the output line is newline terminated. */
|
||||
if (field_1_buffer[n_bytes - 1] != '\n')
|
||||
putchar ('\n');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (print_kth (1, NULL))
|
||||
{
|
||||
/* Print the field, but not the trailing delimiter. */
|
||||
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
|
||||
found_any_selected_field = true;
|
||||
}
|
||||
++field_idx;
|
||||
}
|
||||
/* If the first field extends to the end of line (it is not
|
||||
delimited) and we are printing all non-delimited lines,
|
||||
print this one. */
|
||||
if (to_uchar (field_1_buffer[n_bytes - 1]) != delim)
|
||||
{
|
||||
if (suppress_non_delimited)
|
||||
{
|
||||
/* Empty. */
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
|
||||
/* Make sure the output line is newline terminated. */
|
||||
if (field_1_buffer[n_bytes - 1] != '\n')
|
||||
putchar ('\n');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (print_kth (1, NULL))
|
||||
{
|
||||
/* Print the field, but not the trailing delimiter. */
|
||||
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
|
||||
found_any_selected_field = true;
|
||||
}
|
||||
++field_idx;
|
||||
}
|
||||
|
||||
if (c != EOF)
|
||||
{
|
||||
if (print_kth (field_idx, NULL))
|
||||
{
|
||||
if (found_any_selected_field)
|
||||
{
|
||||
fwrite (output_delimiter_string, sizeof (char),
|
||||
output_delimiter_length, stdout);
|
||||
}
|
||||
found_any_selected_field = true;
|
||||
{
|
||||
if (print_kth (field_idx, NULL))
|
||||
{
|
||||
if (found_any_selected_field)
|
||||
{
|
||||
fwrite (output_delimiter_string, sizeof (char),
|
||||
output_delimiter_length, stdout);
|
||||
}
|
||||
found_any_selected_field = true;
|
||||
|
||||
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
|
||||
{
|
||||
putchar (c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
|
||||
{
|
||||
/* Empty. */
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
|
||||
{
|
||||
putchar (c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
|
||||
{
|
||||
/* Empty. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
c = getc (stream);
|
||||
if (c != EOF)
|
||||
{
|
||||
ungetc (c, stream);
|
||||
c = '\n';
|
||||
}
|
||||
}
|
||||
{
|
||||
c = getc (stream);
|
||||
if (c != EOF)
|
||||
{
|
||||
ungetc (c, stream);
|
||||
c = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (c == delim)
|
||||
++field_idx;
|
||||
++field_idx;
|
||||
else if (c == '\n' || c == EOF)
|
||||
{
|
||||
if (found_any_selected_field
|
||||
|| !(suppress_non_delimited && field_idx == 1))
|
||||
putchar ('\n');
|
||||
if (c == EOF)
|
||||
break;
|
||||
field_idx = 1;
|
||||
found_any_selected_field = false;
|
||||
}
|
||||
{
|
||||
if (found_any_selected_field
|
||||
|| !(suppress_non_delimited && field_idx == 1))
|
||||
putchar ('\n');
|
||||
if (c == EOF)
|
||||
break;
|
||||
field_idx = 1;
|
||||
found_any_selected_field = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,10 +727,10 @@ cut_file (char const *file)
|
||||
{
|
||||
stream = fopen (file, "r");
|
||||
if (stream == NULL)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cut_stream (stream);
|
||||
@@ -777,60 +777,60 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'b':
|
||||
case 'c':
|
||||
/* Build the byte list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
FATAL_ERROR (_("only one type of list may be specified"));
|
||||
operating_mode = byte_mode;
|
||||
spec_list_string = optarg;
|
||||
break;
|
||||
{
|
||||
case 'b':
|
||||
case 'c':
|
||||
/* Build the byte list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
FATAL_ERROR (_("only one type of list may be specified"));
|
||||
operating_mode = byte_mode;
|
||||
spec_list_string = optarg;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
/* Build the field list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
FATAL_ERROR (_("only one type of list may be specified"));
|
||||
operating_mode = field_mode;
|
||||
spec_list_string = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
/* Build the field list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
FATAL_ERROR (_("only one type of list may be specified"));
|
||||
operating_mode = field_mode;
|
||||
spec_list_string = optarg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
/* New delimiter. */
|
||||
/* Interpret -d '' to mean `use the NUL byte as the delimiter.' */
|
||||
if (optarg[0] != '\0' && optarg[1] != '\0')
|
||||
FATAL_ERROR (_("the delimiter must be a single character"));
|
||||
delim = optarg[0];
|
||||
delim_specified = true;
|
||||
break;
|
||||
case 'd':
|
||||
/* New delimiter. */
|
||||
/* Interpret -d '' to mean `use the NUL byte as the delimiter.' */
|
||||
if (optarg[0] != '\0' && optarg[1] != '\0')
|
||||
FATAL_ERROR (_("the delimiter must be a single character"));
|
||||
delim = optarg[0];
|
||||
delim_specified = true;
|
||||
break;
|
||||
|
||||
case OUTPUT_DELIMITER_OPTION:
|
||||
output_delimiter_specified = true;
|
||||
/* Interpret --output-delimiter='' to mean
|
||||
`use the NUL byte as the delimiter.' */
|
||||
output_delimiter_length = (optarg[0] == '\0'
|
||||
? 1 : strlen (optarg));
|
||||
output_delimiter_string = xstrdup (optarg);
|
||||
break;
|
||||
case OUTPUT_DELIMITER_OPTION:
|
||||
output_delimiter_specified = true;
|
||||
/* Interpret --output-delimiter='' to mean
|
||||
`use the NUL byte as the delimiter.' */
|
||||
output_delimiter_length = (optarg[0] == '\0'
|
||||
? 1 : strlen (optarg));
|
||||
output_delimiter_string = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
break;
|
||||
case 'n':
|
||||
break;
|
||||
|
||||
case 's':
|
||||
suppress_non_delimited = true;
|
||||
break;
|
||||
case 's':
|
||||
suppress_non_delimited = true;
|
||||
break;
|
||||
|
||||
case COMPLEMENT_OPTION:
|
||||
complement = true;
|
||||
break;
|
||||
case COMPLEMENT_OPTION:
|
||||
complement = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (operating_mode == undefined_mode)
|
||||
@@ -847,19 +847,19 @@ main (int argc, char **argv)
|
||||
if (output_delimiter_specified)
|
||||
{
|
||||
range_start_ht = hash_initialize (HT_RANGE_START_INDEX_INITIAL_CAPACITY,
|
||||
NULL, hash_int,
|
||||
hash_compare_ints, NULL);
|
||||
NULL, hash_int,
|
||||
hash_compare_ints, NULL);
|
||||
if (range_start_ht == NULL)
|
||||
xalloc_die ();
|
||||
xalloc_die ();
|
||||
|
||||
}
|
||||
|
||||
if (! set_fields (spec_list_string))
|
||||
{
|
||||
if (operating_mode == field_mode)
|
||||
FATAL_ERROR (_("missing list of fields"));
|
||||
FATAL_ERROR (_("missing list of fields"));
|
||||
else
|
||||
FATAL_ERROR (_("missing list of positions"));
|
||||
FATAL_ERROR (_("missing list of positions"));
|
||||
}
|
||||
|
||||
if (!delim_specified)
|
||||
|
||||
322
src/date.c
322
src/date.c
@@ -118,14 +118,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [+FORMAT]\n\
|
||||
or: %s [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Display the current time in the given FORMAT, or set the system date.\n\
|
||||
\n\
|
||||
@@ -236,7 +236,7 @@ then an optional modifier, which is either\n\
|
||||
E to use the locale's alternate representations if available, or\n\
|
||||
O to use the locale's alternate numeric symbols if available.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -264,9 +264,9 @@ batch_convert (const char *input_filename, const char *format)
|
||||
{
|
||||
in_stream = fopen (input_filename, "r");
|
||||
if (in_stream == NULL)
|
||||
{
|
||||
error (EXIT_FAILURE, errno, "%s", quote (input_filename));
|
||||
}
|
||||
{
|
||||
error (EXIT_FAILURE, errno, "%s", quote (input_filename));
|
||||
}
|
||||
}
|
||||
|
||||
line = NULL;
|
||||
@@ -276,22 +276,22 @@ batch_convert (const char *input_filename, const char *format)
|
||||
{
|
||||
ssize_t line_length = getline (&line, &buflen, in_stream);
|
||||
if (line_length < 0)
|
||||
{
|
||||
/* FIXME: detect/handle error here. */
|
||||
break;
|
||||
}
|
||||
{
|
||||
/* FIXME: detect/handle error here. */
|
||||
break;
|
||||
}
|
||||
|
||||
if (! get_date (&when, line, NULL))
|
||||
{
|
||||
if (line[line_length - 1] == '\n')
|
||||
line[line_length - 1] = '\0';
|
||||
error (0, 0, _("invalid date %s"), quote (line));
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
if (line[line_length - 1] == '\n')
|
||||
line[line_length - 1] = '\0';
|
||||
error (0, 0, _("invalid date %s"), quote (line));
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok &= show_date (format, when);
|
||||
}
|
||||
{
|
||||
ok &= show_date (format, when);
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose (in_stream) == EOF)
|
||||
@@ -326,138 +326,138 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
char const *new_format = NULL;
|
||||
|
||||
switch (optc)
|
||||
{
|
||||
case 'd':
|
||||
datestr = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
batch_file = optarg;
|
||||
break;
|
||||
case RFC_3339_OPTION:
|
||||
{
|
||||
static char const rfc_3339_format[][32] =
|
||||
{
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%d %H:%M:%S%:z",
|
||||
"%Y-%m-%d %H:%M:%S.%N%:z"
|
||||
};
|
||||
enum Time_spec i =
|
||||
XARGMATCH ("--rfc-3339", optarg,
|
||||
time_spec_string + 2, time_spec + 2);
|
||||
new_format = rfc_3339_format[i];
|
||||
break;
|
||||
}
|
||||
case 'I':
|
||||
{
|
||||
static char const iso_8601_format[][32] =
|
||||
{
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%dT%H:%M:%S%z",
|
||||
"%Y-%m-%dT%H:%M:%S,%N%z",
|
||||
"%Y-%m-%dT%H%z",
|
||||
"%Y-%m-%dT%H:%M%z"
|
||||
};
|
||||
enum Time_spec i =
|
||||
(optarg
|
||||
? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec)
|
||||
: TIME_SPEC_DATE);
|
||||
new_format = iso_8601_format[i];
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
reference = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
new_format = rfc_2822_format;
|
||||
break;
|
||||
case 's':
|
||||
set_datestr = optarg;
|
||||
set_date = true;
|
||||
break;
|
||||
case 'u':
|
||||
/* POSIX says that `date -u' is equivalent to setting the TZ
|
||||
environment variable, so this option should do nothing other
|
||||
than setting TZ. */
|
||||
if (putenv (bad_cast ("TZ=UTC0")) != 0)
|
||||
xalloc_die ();
|
||||
TZSET;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'd':
|
||||
datestr = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
batch_file = optarg;
|
||||
break;
|
||||
case RFC_3339_OPTION:
|
||||
{
|
||||
static char const rfc_3339_format[][32] =
|
||||
{
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%d %H:%M:%S%:z",
|
||||
"%Y-%m-%d %H:%M:%S.%N%:z"
|
||||
};
|
||||
enum Time_spec i =
|
||||
XARGMATCH ("--rfc-3339", optarg,
|
||||
time_spec_string + 2, time_spec + 2);
|
||||
new_format = rfc_3339_format[i];
|
||||
break;
|
||||
}
|
||||
case 'I':
|
||||
{
|
||||
static char const iso_8601_format[][32] =
|
||||
{
|
||||
"%Y-%m-%d",
|
||||
"%Y-%m-%dT%H:%M:%S%z",
|
||||
"%Y-%m-%dT%H:%M:%S,%N%z",
|
||||
"%Y-%m-%dT%H%z",
|
||||
"%Y-%m-%dT%H:%M%z"
|
||||
};
|
||||
enum Time_spec i =
|
||||
(optarg
|
||||
? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec)
|
||||
: TIME_SPEC_DATE);
|
||||
new_format = iso_8601_format[i];
|
||||
break;
|
||||
}
|
||||
case 'r':
|
||||
reference = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
new_format = rfc_2822_format;
|
||||
break;
|
||||
case 's':
|
||||
set_datestr = optarg;
|
||||
set_date = true;
|
||||
break;
|
||||
case 'u':
|
||||
/* POSIX says that `date -u' is equivalent to setting the TZ
|
||||
environment variable, so this option should do nothing other
|
||||
than setting TZ. */
|
||||
if (putenv (bad_cast ("TZ=UTC0")) != 0)
|
||||
xalloc_die ();
|
||||
TZSET;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (new_format)
|
||||
{
|
||||
if (format)
|
||||
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
|
||||
format = new_format;
|
||||
}
|
||||
{
|
||||
if (format)
|
||||
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
|
||||
format = new_format;
|
||||
}
|
||||
}
|
||||
|
||||
option_specified_date = ((datestr ? 1 : 0)
|
||||
+ (batch_file ? 1 : 0)
|
||||
+ (reference ? 1 : 0));
|
||||
+ (batch_file ? 1 : 0)
|
||||
+ (reference ? 1 : 0));
|
||||
|
||||
if (option_specified_date > 1)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the options to specify dates for printing are mutually exclusive"));
|
||||
_("the options to specify dates for printing are mutually exclusive"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (set_date && option_specified_date)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the options to print and set the time may not be used together"));
|
||||
_("the options to print and set the time may not be used together"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
if (optind + 1 < argc)
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argv[optind][0] == '+')
|
||||
{
|
||||
if (format)
|
||||
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
|
||||
format = argv[optind++] + 1;
|
||||
}
|
||||
{
|
||||
if (format)
|
||||
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
|
||||
format = argv[optind++] + 1;
|
||||
}
|
||||
else if (set_date || option_specified_date)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the argument %s lacks a leading `+';\n"
|
||||
"when using an option to specify date(s), any non-option\n"
|
||||
"argument must be a format string beginning with `+'"),
|
||||
quote (argv[optind]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0,
|
||||
_("the argument %s lacks a leading `+';\n"
|
||||
"when using an option to specify date(s), any non-option\n"
|
||||
"argument must be a format string beginning with `+'"),
|
||||
quote (argv[optind]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!format)
|
||||
{
|
||||
format = DATE_FMT_LANGINFO ();
|
||||
if (! *format)
|
||||
{
|
||||
/* Do not wrap the following literal format string with _(...).
|
||||
For example, suppose LC_ALL is unset, LC_TIME="POSIX",
|
||||
and LANG="ko_KR". In that case, POSIX says that LC_TIME
|
||||
determines the format and contents of date and time strings
|
||||
written by date, which means "date" must generate output
|
||||
using the POSIX locale; but adding _() would cause "date"
|
||||
to use a Korean translation of the format. */
|
||||
format = "%a %b %e %H:%M:%S %Z %Y";
|
||||
}
|
||||
{
|
||||
/* Do not wrap the following literal format string with _(...).
|
||||
For example, suppose LC_ALL is unset, LC_TIME="POSIX",
|
||||
and LANG="ko_KR". In that case, POSIX says that LC_TIME
|
||||
determines the format and contents of date and time strings
|
||||
written by date, which means "date" must generate output
|
||||
using the POSIX locale; but adding _() would cause "date"
|
||||
to use a Korean translation of the format. */
|
||||
format = "%a %b %e %H:%M:%S %Z %Y";
|
||||
}
|
||||
}
|
||||
|
||||
if (batch_file != NULL)
|
||||
@@ -468,55 +468,55 @@ main (int argc, char **argv)
|
||||
ok = true;
|
||||
|
||||
if (!option_specified_date && !set_date)
|
||||
{
|
||||
if (optind < argc)
|
||||
{
|
||||
/* Prepare to set system clock to the specified date/time
|
||||
given in the POSIX-format. */
|
||||
set_date = true;
|
||||
datestr = argv[optind];
|
||||
valid_date = posixtime (&when.tv_sec,
|
||||
datestr,
|
||||
(PDS_TRAILING_YEAR
|
||||
| PDS_CENTURY | PDS_SECONDS));
|
||||
when.tv_nsec = 0; /* FIXME: posixtime should set this. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare to print the current date/time. */
|
||||
gettime (&when);
|
||||
}
|
||||
}
|
||||
{
|
||||
if (optind < argc)
|
||||
{
|
||||
/* Prepare to set system clock to the specified date/time
|
||||
given in the POSIX-format. */
|
||||
set_date = true;
|
||||
datestr = argv[optind];
|
||||
valid_date = posixtime (&when.tv_sec,
|
||||
datestr,
|
||||
(PDS_TRAILING_YEAR
|
||||
| PDS_CENTURY | PDS_SECONDS));
|
||||
when.tv_nsec = 0; /* FIXME: posixtime should set this. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare to print the current date/time. */
|
||||
gettime (&when);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* (option_specified_date || set_date) */
|
||||
if (reference != NULL)
|
||||
{
|
||||
if (stat (reference, &refstats) != 0)
|
||||
error (EXIT_FAILURE, errno, "%s", reference);
|
||||
when = get_stat_mtime (&refstats);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (set_datestr)
|
||||
datestr = set_datestr;
|
||||
valid_date = get_date (&when, datestr, NULL);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* (option_specified_date || set_date) */
|
||||
if (reference != NULL)
|
||||
{
|
||||
if (stat (reference, &refstats) != 0)
|
||||
error (EXIT_FAILURE, errno, "%s", reference);
|
||||
when = get_stat_mtime (&refstats);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (set_datestr)
|
||||
datestr = set_datestr;
|
||||
valid_date = get_date (&when, datestr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (! valid_date)
|
||||
error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
|
||||
error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
|
||||
|
||||
if (set_date)
|
||||
{
|
||||
/* Set the system clock to the specified date, then regardless of
|
||||
the success of that operation, format and print that date. */
|
||||
if (settime (&when) != 0)
|
||||
{
|
||||
error (0, errno, _("cannot set date"));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
{
|
||||
/* Set the system clock to the specified date, then regardless of
|
||||
the success of that operation, format and print that date. */
|
||||
if (settime (&when) != 0)
|
||||
{
|
||||
error (0, errno, _("cannot set date"));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
ok &= show_date (format, when);
|
||||
}
|
||||
|
||||
558
src/df.c
558
src/df.c
@@ -24,7 +24,6 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "canonicalize.h"
|
||||
#include "error.h"
|
||||
#include "fsusage.h"
|
||||
#include "human.h"
|
||||
@@ -158,22 +157,22 @@ print_header (void)
|
||||
else if (human_output_opts & human_autoscale)
|
||||
{
|
||||
if (human_output_opts & human_base_1024)
|
||||
printf (_(" Size Used Avail Use%%"));
|
||||
printf (_(" Size Used Avail Use%%"));
|
||||
else
|
||||
printf (_(" Size Used Avail Use%%"));
|
||||
printf (_(" Size Used Avail Use%%"));
|
||||
}
|
||||
else if (posix_format)
|
||||
printf (_(" %s-blocks Used Available Capacity"),
|
||||
umaxtostr (output_block_size, buf));
|
||||
umaxtostr (output_block_size, buf));
|
||||
else
|
||||
{
|
||||
int opts = (human_suppress_point_zero
|
||||
| human_autoscale | human_SI
|
||||
| (human_output_opts
|
||||
& (human_group_digits | human_base_1024 | human_B)));
|
||||
| human_autoscale | human_SI
|
||||
| (human_output_opts
|
||||
& (human_group_digits | human_base_1024 | human_B)));
|
||||
|
||||
/* Prefer the base that makes the human-readable value more exact,
|
||||
if there is a difference. */
|
||||
if there is a difference. */
|
||||
|
||||
uintmax_t q1000 = output_block_size;
|
||||
uintmax_t q1024 = output_block_size;
|
||||
@@ -181,21 +180,21 @@ print_header (void)
|
||||
bool divisible_by_1024;
|
||||
|
||||
do
|
||||
{
|
||||
divisible_by_1000 = q1000 % 1000 == 0; q1000 /= 1000;
|
||||
divisible_by_1024 = q1024 % 1024 == 0; q1024 /= 1024;
|
||||
}
|
||||
{
|
||||
divisible_by_1000 = q1000 % 1000 == 0; q1000 /= 1000;
|
||||
divisible_by_1024 = q1024 % 1024 == 0; q1024 /= 1024;
|
||||
}
|
||||
while (divisible_by_1000 & divisible_by_1024);
|
||||
|
||||
if (divisible_by_1000 < divisible_by_1024)
|
||||
opts |= human_base_1024;
|
||||
opts |= human_base_1024;
|
||||
if (divisible_by_1024 < divisible_by_1000)
|
||||
opts &= ~human_base_1024;
|
||||
opts &= ~human_base_1024;
|
||||
if (! (opts & human_base_1024))
|
||||
opts |= human_B;
|
||||
opts |= human_B;
|
||||
|
||||
printf (_(" %4s-blocks Used Available Use%%"),
|
||||
human_readable (output_block_size, buf, opts, 1, 1));
|
||||
human_readable (output_block_size, buf, opts, 1, 1));
|
||||
}
|
||||
|
||||
printf (_(" Mounted on\n"));
|
||||
@@ -250,16 +249,16 @@ known_value (uintmax_t n)
|
||||
|
||||
static char const *
|
||||
df_readable (bool negative, uintmax_t n, char *buf,
|
||||
uintmax_t input_units, uintmax_t output_units)
|
||||
uintmax_t input_units, uintmax_t output_units)
|
||||
{
|
||||
if (! known_value (n) && !negative)
|
||||
return "-";
|
||||
else
|
||||
{
|
||||
char *p = human_readable (negative ? -n : n, buf + negative,
|
||||
human_output_opts, input_units, output_units);
|
||||
human_output_opts, input_units, output_units);
|
||||
if (negative)
|
||||
*--p = '-';
|
||||
*--p = '-';
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -273,7 +272,7 @@ df_readable (bool negative, uintmax_t n, char *buf,
|
||||
how the negation flag is used. */
|
||||
static void
|
||||
add_uint_with_neg_flag (uintmax_t *dest, bool *dest_neg,
|
||||
uintmax_t src, bool src_neg)
|
||||
uintmax_t src, bool src_neg)
|
||||
{
|
||||
if (LOG_EQ (*dest_neg, src_neg))
|
||||
{
|
||||
@@ -314,9 +313,9 @@ add_uint_with_neg_flag (uintmax_t *dest, bool *dest_neg,
|
||||
|
||||
static void
|
||||
show_dev (char const *disk, char const *mount_point,
|
||||
char const *stat_file, char const *fstype,
|
||||
bool me_dummy, bool me_remote,
|
||||
const struct fs_usage *force_fsu)
|
||||
char const *stat_file, char const *fstype,
|
||||
bool me_dummy, bool me_remote,
|
||||
const struct fs_usage *force_fsu)
|
||||
{
|
||||
struct fs_usage fsu;
|
||||
char buf[3][LONGEST_HUMAN_READABLE + 2];
|
||||
@@ -333,10 +332,10 @@ show_dev (char const *disk, char const *mount_point,
|
||||
bool negate_used;
|
||||
double pct = -1;
|
||||
|
||||
if (me_remote & show_local_fs)
|
||||
if (me_remote && show_local_fs)
|
||||
return;
|
||||
|
||||
if (me_dummy & !show_all_fs & !show_listed_fs)
|
||||
if (me_dummy && !show_all_fs && !show_listed_fs)
|
||||
return;
|
||||
|
||||
if (!selected_fstype (fstype) || excluded_fstype (fstype))
|
||||
@@ -379,18 +378,18 @@ show_dev (char const *disk, char const *mount_point,
|
||||
size_t disk_name_len = strlen (disk);
|
||||
size_t fstype_len = strlen (fstype);
|
||||
if (disk_name_len + fstype_len < 18)
|
||||
printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
|
||||
printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
|
||||
else if (!posix_format)
|
||||
printf ("%s\n%18s ", disk, fstype);
|
||||
printf ("%s\n%18s ", disk, fstype);
|
||||
else
|
||||
printf ("%s %s", disk, fstype);
|
||||
printf ("%s %s", disk, fstype);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen (disk) > 20 && !posix_format)
|
||||
printf ("%s\n%20s", disk, "");
|
||||
printf ("%s\n%20s", disk, "");
|
||||
else
|
||||
printf ("%-20s", disk);
|
||||
printf ("%-20s", disk);
|
||||
}
|
||||
|
||||
if (inode_format)
|
||||
@@ -404,44 +403,44 @@ show_dev (char const *disk, char const *mount_point,
|
||||
available_to_root = available;
|
||||
|
||||
if (known_value (total))
|
||||
grand_fsu.fsu_files += total;
|
||||
grand_fsu.fsu_files += total;
|
||||
if (known_value (available))
|
||||
grand_fsu.fsu_ffree += available;
|
||||
grand_fsu.fsu_ffree += available;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (human_output_opts & human_autoscale)
|
||||
width = 5 + ! (human_output_opts & human_base_1024);
|
||||
width = 5 + ! (human_output_opts & human_base_1024);
|
||||
else
|
||||
{
|
||||
width = 9;
|
||||
if (posix_format)
|
||||
{
|
||||
uintmax_t b;
|
||||
col1_adjustment = -3;
|
||||
for (b = output_block_size; 9 < b; b /= 10)
|
||||
col1_adjustment++;
|
||||
}
|
||||
}
|
||||
{
|
||||
width = 9;
|
||||
if (posix_format)
|
||||
{
|
||||
uintmax_t b;
|
||||
col1_adjustment = -3;
|
||||
for (b = output_block_size; 9 < b; b /= 10)
|
||||
col1_adjustment++;
|
||||
}
|
||||
}
|
||||
use_width = ((posix_format
|
||||
&& ! (human_output_opts & human_autoscale))
|
||||
? 8 : 4);
|
||||
&& ! (human_output_opts & human_autoscale))
|
||||
? 8 : 4);
|
||||
input_units = fsu.fsu_blocksize;
|
||||
output_units = output_block_size;
|
||||
total = fsu.fsu_blocks;
|
||||
available = fsu.fsu_bavail;
|
||||
negate_available = (fsu.fsu_bavail_top_bit_set
|
||||
& known_value (available));
|
||||
&& known_value (available));
|
||||
available_to_root = fsu.fsu_bfree;
|
||||
|
||||
if (known_value (total))
|
||||
grand_fsu.fsu_blocks += input_units * total;
|
||||
grand_fsu.fsu_blocks += input_units * total;
|
||||
if (known_value (available_to_root))
|
||||
grand_fsu.fsu_bfree += input_units * available_to_root;
|
||||
grand_fsu.fsu_bfree += input_units * available_to_root;
|
||||
if (known_value (available))
|
||||
add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
|
||||
&grand_fsu.fsu_bavail_top_bit_set,
|
||||
input_units * available, negate_available);
|
||||
add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
|
||||
&grand_fsu.fsu_bavail_top_bit_set,
|
||||
input_units * available, negate_available);
|
||||
}
|
||||
|
||||
used = UINTMAX_MAX;
|
||||
@@ -453,20 +452,20 @@ show_dev (char const *disk, char const *mount_point,
|
||||
}
|
||||
|
||||
printf (" %*s %*s %*s ",
|
||||
width + col1_adjustment,
|
||||
df_readable (false, total,
|
||||
buf[0], input_units, output_units),
|
||||
width, df_readable (negate_used, used,
|
||||
buf[1], input_units, output_units),
|
||||
width, df_readable (negate_available, available,
|
||||
buf[2], input_units, output_units));
|
||||
width + col1_adjustment,
|
||||
df_readable (false, total,
|
||||
buf[0], input_units, output_units),
|
||||
width, df_readable (negate_used, used,
|
||||
buf[1], input_units, output_units),
|
||||
width, df_readable (negate_available, available,
|
||||
buf[2], input_units, output_units));
|
||||
|
||||
if (! known_value (used) || ! known_value (available))
|
||||
;
|
||||
else if (!negate_used
|
||||
&& used <= TYPE_MAXIMUM (uintmax_t) / 100
|
||||
&& used + available != 0
|
||||
&& (used + available < used) == negate_available)
|
||||
&& used <= TYPE_MAXIMUM (uintmax_t) / 100
|
||||
&& used + available != 0
|
||||
&& (used + available < used) == negate_available)
|
||||
{
|
||||
uintmax_t u100 = used * 100;
|
||||
uintmax_t nonroot_total = used + available;
|
||||
@@ -475,23 +474,23 @@ show_dev (char const *disk, char const *mount_point,
|
||||
else
|
||||
{
|
||||
/* The calculation cannot be done easily with integer
|
||||
arithmetic. Fall back on floating point. This can suffer
|
||||
from minor rounding errors, but doing it exactly requires
|
||||
multiple precision arithmetic, and it's not worth the
|
||||
aggravation. */
|
||||
arithmetic. Fall back on floating point. This can suffer
|
||||
from minor rounding errors, but doing it exactly requires
|
||||
multiple precision arithmetic, and it's not worth the
|
||||
aggravation. */
|
||||
double u = negate_used ? - (double) - used : used;
|
||||
double a = negate_available ? - (double) - available : available;
|
||||
double nonroot_total = u + a;
|
||||
if (nonroot_total)
|
||||
{
|
||||
long int lipct = pct = u * 100 / nonroot_total;
|
||||
double ipct = lipct;
|
||||
{
|
||||
long int lipct = pct = u * 100 / nonroot_total;
|
||||
double ipct = lipct;
|
||||
|
||||
/* Like `pct = ceil (dpct);', but avoid ceil so that
|
||||
the math library needn't be linked. */
|
||||
if (ipct - 1 < pct && pct <= ipct + 1)
|
||||
pct = ipct + (ipct < pct);
|
||||
}
|
||||
/* Like `pct = ceil (dpct);', but avoid ceil so that
|
||||
the math library needn't be linked. */
|
||||
if (ipct - 1 < pct && pct <= ipct + 1)
|
||||
pct = ipct + (ipct < pct);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 <= pct)
|
||||
@@ -503,12 +502,12 @@ show_dev (char const *disk, char const *mount_point,
|
||||
{
|
||||
#ifdef HIDE_AUTOMOUNT_PREFIX
|
||||
/* Don't print the first directory name in MOUNT_POINT if it's an
|
||||
artifact of an automounter. This is a bit too aggressive to be
|
||||
the default. */
|
||||
artifact of an automounter. This is a bit too aggressive to be
|
||||
the default. */
|
||||
if (strncmp ("/auto/", mount_point, 6) == 0)
|
||||
mount_point += 5;
|
||||
mount_point += 5;
|
||||
else if (strncmp ("/tmp_mnt/", mount_point, 9) == 0)
|
||||
mount_point += 8;
|
||||
mount_point += 8;
|
||||
#endif
|
||||
printf (" %s", mount_point);
|
||||
}
|
||||
@@ -537,10 +536,10 @@ find_mount_point (const char *file, const struct stat *file_stat)
|
||||
{
|
||||
last_stat = *file_stat;
|
||||
if (chdir (file) < 0)
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (file));
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (file));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* FILE is some other kind of file; use its directory. */
|
||||
@@ -551,17 +550,17 @@ find_mount_point (const char *file, const struct stat *file_stat)
|
||||
free (xdir);
|
||||
|
||||
if (chdir (dir) < 0)
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (dir));
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (dir));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stat (".", &last_stat) < 0)
|
||||
{
|
||||
error (0, errno, _("cannot stat current directory (now %s)"),
|
||||
quote (dir));
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot stat current directory (now %s)"),
|
||||
quote (dir));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now walk up FILE's parents until we find another file system or /,
|
||||
@@ -571,18 +570,18 @@ find_mount_point (const char *file, const struct stat *file_stat)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat ("..", &st) < 0)
|
||||
{
|
||||
error (0, errno, _("cannot stat %s"), quote (".."));
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot stat %s"), quote (".."));
|
||||
goto done;
|
||||
}
|
||||
if (st.st_dev != last_stat.st_dev || st.st_ino == last_stat.st_ino)
|
||||
/* cwd is the mount point. */
|
||||
break;
|
||||
/* cwd is the mount point. */
|
||||
break;
|
||||
if (chdir ("..") < 0)
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (".."));
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot change to directory %s"), quote (".."));
|
||||
goto done;
|
||||
}
|
||||
last_stat = st;
|
||||
}
|
||||
|
||||
@@ -595,7 +594,7 @@ done:
|
||||
int save_errno = errno;
|
||||
if (restore_cwd (&cwd) != 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to return to initial working directory"));
|
||||
_("failed to return to initial working directory"));
|
||||
free_cwd (&cwd);
|
||||
errno = save_errno;
|
||||
}
|
||||
@@ -618,8 +617,8 @@ show_disk (char const *disk)
|
||||
if (best_match)
|
||||
{
|
||||
show_dev (best_match->me_devname, best_match->me_mountdir, NULL,
|
||||
best_match->me_type, best_match->me_dummy,
|
||||
best_match->me_remote, NULL);
|
||||
best_match->me_type, best_match->me_dummy,
|
||||
best_match->me_remote, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -641,12 +640,12 @@ show_point (const char *point, const struct stat *statp)
|
||||
if (*point == '/')
|
||||
{
|
||||
/* Find the best match: prefer non-dummies, and then prefer the
|
||||
last match if there are ties. */
|
||||
last match if there are ties. */
|
||||
|
||||
for (me = mount_list; me; me = me->me_next)
|
||||
if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
best_match = me;
|
||||
if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
best_match = me;
|
||||
}
|
||||
|
||||
/* Calculate the real absolute file name for POINT, and use that to find
|
||||
@@ -657,87 +656,87 @@ show_point (const char *point, const struct stat *statp)
|
||||
char *resolved = canonicalize_file_name (point);
|
||||
|
||||
if (resolved && resolved[0] == '/')
|
||||
{
|
||||
size_t resolved_len = strlen (resolved);
|
||||
size_t best_match_len = 0;
|
||||
{
|
||||
size_t resolved_len = strlen (resolved);
|
||||
size_t best_match_len = 0;
|
||||
|
||||
for (me = mount_list; me; me = me->me_next)
|
||||
if (!STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
{
|
||||
size_t len = strlen (me->me_mountdir);
|
||||
if (best_match_len <= len && len <= resolved_len
|
||||
&& (len == 1 /* root file system */
|
||||
|| ((len == resolved_len || resolved[len] == '/')
|
||||
&& strncmp (me->me_mountdir, resolved, len) == 0)))
|
||||
{
|
||||
best_match = me;
|
||||
best_match_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (me = mount_list; me; me = me->me_next)
|
||||
if (!STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
{
|
||||
size_t len = strlen (me->me_mountdir);
|
||||
if (best_match_len <= len && len <= resolved_len
|
||||
&& (len == 1 /* root file system */
|
||||
|| ((len == resolved_len || resolved[len] == '/')
|
||||
&& strncmp (me->me_mountdir, resolved, len) == 0)))
|
||||
{
|
||||
best_match = me;
|
||||
best_match_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (resolved);
|
||||
|
||||
if (best_match
|
||||
&& (stat (best_match->me_mountdir, &disk_stats) != 0
|
||||
|| disk_stats.st_dev != statp->st_dev))
|
||||
best_match = NULL;
|
||||
&& (stat (best_match->me_mountdir, &disk_stats) != 0
|
||||
|| disk_stats.st_dev != statp->st_dev))
|
||||
best_match = NULL;
|
||||
}
|
||||
|
||||
if (! best_match)
|
||||
for (me = mount_list; me; me = me->me_next)
|
||||
{
|
||||
if (me->me_dev == (dev_t) -1)
|
||||
{
|
||||
if (stat (me->me_mountdir, &disk_stats) == 0)
|
||||
me->me_dev = disk_stats.st_dev;
|
||||
else
|
||||
{
|
||||
/* Report only I/O errors. Other errors might be
|
||||
caused by shadowed mount points, which means POINT
|
||||
can't possibly be on this file system. */
|
||||
if (errno == EIO)
|
||||
{
|
||||
error (0, errno, "%s", quote (me->me_mountdir));
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
if (me->me_dev == (dev_t) -1)
|
||||
{
|
||||
if (stat (me->me_mountdir, &disk_stats) == 0)
|
||||
me->me_dev = disk_stats.st_dev;
|
||||
else
|
||||
{
|
||||
/* Report only I/O errors. Other errors might be
|
||||
caused by shadowed mount points, which means POINT
|
||||
can't possibly be on this file system. */
|
||||
if (errno == EIO)
|
||||
{
|
||||
error (0, errno, "%s", quote (me->me_mountdir));
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* So we won't try and fail repeatedly. */
|
||||
me->me_dev = (dev_t) -2;
|
||||
}
|
||||
}
|
||||
/* So we won't try and fail repeatedly. */
|
||||
me->me_dev = (dev_t) -2;
|
||||
}
|
||||
}
|
||||
|
||||
if (statp->st_dev == me->me_dev
|
||||
&& !STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
{
|
||||
/* Skip bogus mtab entries. */
|
||||
if (stat (me->me_mountdir, &disk_stats) != 0
|
||||
|| disk_stats.st_dev != me->me_dev)
|
||||
me->me_dev = (dev_t) -2;
|
||||
else
|
||||
best_match = me;
|
||||
}
|
||||
if (statp->st_dev == me->me_dev
|
||||
&& !STREQ (me->me_type, "lofs")
|
||||
&& (!best_match || best_match->me_dummy || !me->me_dummy))
|
||||
{
|
||||
/* Skip bogus mtab entries. */
|
||||
if (stat (me->me_mountdir, &disk_stats) != 0
|
||||
|| disk_stats.st_dev != me->me_dev)
|
||||
me->me_dev = (dev_t) -2;
|
||||
else
|
||||
best_match = me;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match)
|
||||
show_dev (best_match->me_devname, best_match->me_mountdir, point,
|
||||
best_match->me_type, best_match->me_dummy, best_match->me_remote,
|
||||
NULL);
|
||||
best_match->me_type, best_match->me_dummy, best_match->me_remote,
|
||||
NULL);
|
||||
else
|
||||
{
|
||||
/* We couldn't find the mount entry corresponding to POINT. Go ahead and
|
||||
print as much info as we can; methods that require the device to be
|
||||
present will fail at a later point. */
|
||||
print as much info as we can; methods that require the device to be
|
||||
present will fail at a later point. */
|
||||
|
||||
/* Find the actual mount point. */
|
||||
char *mp = find_mount_point (point, statp);
|
||||
if (mp)
|
||||
{
|
||||
show_dev (NULL, mp, NULL, NULL, false, false, NULL);
|
||||
free (mp);
|
||||
}
|
||||
{
|
||||
show_dev (NULL, mp, NULL, NULL, false, false, NULL);
|
||||
free (mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,7 +763,7 @@ show_all_entries (void)
|
||||
|
||||
for (me = mount_list; me; me = me->me_next)
|
||||
show_dev (me->me_devname, me->me_mountdir, NULL, me->me_type,
|
||||
me->me_dummy, me->me_remote, NULL);
|
||||
me->me_dummy, me->me_remote, NULL);
|
||||
}
|
||||
|
||||
/* Add FSTYPE to the list of file system types to display. */
|
||||
@@ -798,7 +797,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
|
||||
@@ -833,11 +832,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
fputs (_("\n\
|
||||
SIZE may be (or may be an integer optionally followed by) one of following:\n\
|
||||
kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_blocksize_note ("DF");
|
||||
emit_size_note ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -872,93 +869,93 @@ main (int argc, char **argv)
|
||||
{
|
||||
int oi = -1;
|
||||
int c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options,
|
||||
&oi);
|
||||
&oi);
|
||||
if (c == -1)
|
||||
break;
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
show_all_fs = true;
|
||||
break;
|
||||
case 'B':
|
||||
{
|
||||
enum strtol_error e = human_options (optarg, &human_output_opts,
|
||||
&output_block_size);
|
||||
if (e != LONGINT_OK)
|
||||
xstrtol_fatal (e, oi, c, long_options, optarg);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
inode_format = true;
|
||||
break;
|
||||
case 'h':
|
||||
human_output_opts = human_autoscale | human_SI | human_base_1024;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'H':
|
||||
human_output_opts = human_autoscale | human_SI;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'k':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024;
|
||||
break;
|
||||
case 'l':
|
||||
show_local_fs = true;
|
||||
break;
|
||||
case 'm': /* obsolescent */
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024 * 1024;
|
||||
break;
|
||||
case 'T':
|
||||
print_type = true;
|
||||
break;
|
||||
case 'P':
|
||||
posix_format = true;
|
||||
break;
|
||||
case SYNC_OPTION:
|
||||
require_sync = true;
|
||||
break;
|
||||
case NO_SYNC_OPTION:
|
||||
require_sync = false;
|
||||
break;
|
||||
{
|
||||
case 'a':
|
||||
show_all_fs = true;
|
||||
break;
|
||||
case 'B':
|
||||
{
|
||||
enum strtol_error e = human_options (optarg, &human_output_opts,
|
||||
&output_block_size);
|
||||
if (e != LONGINT_OK)
|
||||
xstrtol_fatal (e, oi, c, long_options, optarg);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
inode_format = true;
|
||||
break;
|
||||
case 'h':
|
||||
human_output_opts = human_autoscale | human_SI | human_base_1024;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'H':
|
||||
human_output_opts = human_autoscale | human_SI;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'k':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024;
|
||||
break;
|
||||
case 'l':
|
||||
show_local_fs = true;
|
||||
break;
|
||||
case 'm': /* obsolescent */
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024 * 1024;
|
||||
break;
|
||||
case 'T':
|
||||
print_type = true;
|
||||
break;
|
||||
case 'P':
|
||||
posix_format = true;
|
||||
break;
|
||||
case SYNC_OPTION:
|
||||
require_sync = true;
|
||||
break;
|
||||
case NO_SYNC_OPTION:
|
||||
require_sync = false;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
/* Accept -F as a synonym for -t for compatibility with Solaris. */
|
||||
case 't':
|
||||
add_fs_type (optarg);
|
||||
break;
|
||||
case 'F':
|
||||
/* Accept -F as a synonym for -t for compatibility with Solaris. */
|
||||
case 't':
|
||||
add_fs_type (optarg);
|
||||
break;
|
||||
|
||||
case 'v': /* For SysV compatibility. */
|
||||
/* ignore */
|
||||
break;
|
||||
case 'x':
|
||||
add_excluded_fs_type (optarg);
|
||||
break;
|
||||
case 'v': /* For SysV compatibility. */
|
||||
/* ignore */
|
||||
break;
|
||||
case 'x':
|
||||
add_excluded_fs_type (optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
print_grand_total = true;
|
||||
break;
|
||||
case 'c':
|
||||
print_grand_total = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (human_output_opts == -1)
|
||||
{
|
||||
if (posix_format)
|
||||
{
|
||||
human_output_opts = 0;
|
||||
output_block_size = (getenv ("POSIXLY_CORRECT") ? 512 : 1024);
|
||||
}
|
||||
{
|
||||
human_output_opts = 0;
|
||||
output_block_size = (getenv ("POSIXLY_CORRECT") ? 512 : 1024);
|
||||
}
|
||||
else
|
||||
human_options (getenv ("DF_BLOCK_SIZE"),
|
||||
&human_output_opts, &output_block_size);
|
||||
human_options (getenv ("DF_BLOCK_SIZE"),
|
||||
&human_output_opts, &output_block_size);
|
||||
}
|
||||
|
||||
/* Fail if the same file system type was both selected and excluded. */
|
||||
@@ -967,18 +964,18 @@ main (int argc, char **argv)
|
||||
struct fs_type_list *fs_incl;
|
||||
for (fs_incl = fs_select_list; fs_incl; fs_incl = fs_incl->fs_next)
|
||||
{
|
||||
struct fs_type_list *fs_excl;
|
||||
for (fs_excl = fs_exclude_list; fs_excl; fs_excl = fs_excl->fs_next)
|
||||
{
|
||||
if (STREQ (fs_incl->fs_name, fs_excl->fs_name))
|
||||
{
|
||||
error (0, 0,
|
||||
_("file system type %s both selected and excluded"),
|
||||
quote (fs_incl->fs_name));
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct fs_type_list *fs_excl;
|
||||
for (fs_excl = fs_exclude_list; fs_excl; fs_excl = fs_excl->fs_next)
|
||||
{
|
||||
if (STREQ (fs_incl->fs_name, fs_excl->fs_name))
|
||||
{
|
||||
error (0, 0,
|
||||
_("file system type %s both selected and excluded"),
|
||||
quote (fs_incl->fs_name));
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match)
|
||||
exit (EXIT_FAILURE);
|
||||
@@ -989,38 +986,41 @@ main (int argc, char **argv)
|
||||
int i;
|
||||
|
||||
/* Open each of the given entries to make sure any corresponding
|
||||
partition is automounted. This must be done before reading the
|
||||
file system table. */
|
||||
partition is automounted. This must be done before reading the
|
||||
file system table. */
|
||||
stats = xnmalloc (argc - optind, sizeof *stats);
|
||||
for (i = optind; i < argc; ++i)
|
||||
{
|
||||
int fd = open (argv[i], O_RDONLY | O_NOCTTY);
|
||||
if (fd < 0 || fstat (fd, &stats[i - optind]))
|
||||
{
|
||||
error (0, errno, "%s", quote (argv[i]));
|
||||
exit_status = EXIT_FAILURE;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
if (0 <= fd)
|
||||
close (fd);
|
||||
}
|
||||
{
|
||||
/* Prefer to open with O_NOCTTY and use fstat, but fall back
|
||||
on using "stat", in case the file is unreadable. */
|
||||
int fd = open (argv[i], O_RDONLY | O_NOCTTY);
|
||||
if ((fd < 0 || fstat (fd, &stats[i - optind]))
|
||||
&& stat (argv[i], &stats[i - optind]))
|
||||
{
|
||||
error (0, errno, "%s", quote (argv[i]));
|
||||
exit_status = EXIT_FAILURE;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
if (0 <= fd)
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
mount_list =
|
||||
read_file_system_list ((fs_select_list != NULL
|
||||
|| fs_exclude_list != NULL
|
||||
|| print_type
|
||||
|| show_local_fs));
|
||||
|| fs_exclude_list != NULL
|
||||
|| print_type
|
||||
|| show_local_fs));
|
||||
|
||||
if (mount_list == NULL)
|
||||
{
|
||||
/* Couldn't read the table of mounted file systems.
|
||||
Fail if df was invoked with no file name arguments;
|
||||
Otherwise, merely give a warning and proceed. */
|
||||
Fail if df was invoked with no file name arguments;
|
||||
Otherwise, merely give a warning and proceed. */
|
||||
int status = (optind < argc ? 0 : EXIT_FAILURE);
|
||||
const char *warning = (optind < argc ? _("Warning: ") : "");
|
||||
error (status, errno, "%s%s", warning,
|
||||
_("cannot read table of mounted file systems"));
|
||||
_("cannot read table of mounted file systems"));
|
||||
}
|
||||
|
||||
if (require_sync)
|
||||
@@ -1034,8 +1034,8 @@ main (int argc, char **argv)
|
||||
show_listed_fs = true;
|
||||
|
||||
for (i = optind; i < argc; ++i)
|
||||
if (argv[i])
|
||||
show_entry (argv[i], &stats[i - optind]);
|
||||
if (argv[i])
|
||||
show_entry (argv[i], &stats[i - optind]);
|
||||
}
|
||||
else
|
||||
show_all_entries ();
|
||||
@@ -1043,7 +1043,7 @@ main (int argc, char **argv)
|
||||
if (print_grand_total)
|
||||
{
|
||||
if (inode_format)
|
||||
grand_fsu.fsu_blocks = 1;
|
||||
grand_fsu.fsu_blocks = 1;
|
||||
show_dev ("total", NULL, NULL, NULL, false, false, &grand_fsu);
|
||||
}
|
||||
|
||||
|
||||
298
src/dircolors.c
298
src/dircolors.c
@@ -112,7 +112,7 @@ If FILE is specified, read it to determine which colors to use for which\n\
|
||||
file types and extensions. Otherwise, a precompiled database is used.\n\
|
||||
For details on the format of these files, run `dircolors --print-database'.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
|
||||
exit (status);
|
||||
@@ -198,29 +198,29 @@ append_quoted (const char *str)
|
||||
while (*str != '\0')
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case '\'':
|
||||
APPEND_CHAR ('\'');
|
||||
APPEND_CHAR ('\\');
|
||||
APPEND_CHAR ('\'');
|
||||
need_backslash = true;
|
||||
break;
|
||||
{
|
||||
case '\'':
|
||||
APPEND_CHAR ('\'');
|
||||
APPEND_CHAR ('\\');
|
||||
APPEND_CHAR ('\'');
|
||||
need_backslash = true;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
case '^':
|
||||
need_backslash = !need_backslash;
|
||||
break;
|
||||
case '\\':
|
||||
case '^':
|
||||
need_backslash = !need_backslash;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
case '=':
|
||||
if (need_backslash)
|
||||
APPEND_CHAR ('\\');
|
||||
/* Fall through */
|
||||
case ':':
|
||||
case '=':
|
||||
if (need_backslash)
|
||||
APPEND_CHAR ('\\');
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
need_backslash = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
need_backslash = true;
|
||||
break;
|
||||
}
|
||||
|
||||
APPEND_CHAR (*str);
|
||||
++str;
|
||||
@@ -261,106 +261,106 @@ dc_parse_stream (FILE *fp, const char *filename)
|
||||
++line_number;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (getline (&input_line, &input_line_size, fp) <= 0)
|
||||
{
|
||||
free (input_line);
|
||||
break;
|
||||
}
|
||||
line = input_line;
|
||||
}
|
||||
{
|
||||
if (getline (&input_line, &input_line_size, fp) <= 0)
|
||||
{
|
||||
free (input_line);
|
||||
break;
|
||||
}
|
||||
line = input_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next_G_line == G_line + sizeof G_line)
|
||||
break;
|
||||
line = next_G_line;
|
||||
next_G_line += strlen (next_G_line) + 1;
|
||||
}
|
||||
{
|
||||
if (next_G_line == G_line + sizeof G_line)
|
||||
break;
|
||||
line = next_G_line;
|
||||
next_G_line += strlen (next_G_line) + 1;
|
||||
}
|
||||
|
||||
parse_line (line, &keywd, &arg);
|
||||
|
||||
if (keywd == NULL)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (arg == NULL)
|
||||
{
|
||||
error (0, 0, _("%s:%lu: invalid line; missing second token"),
|
||||
filename, (unsigned long int) line_number);
|
||||
ok = false;
|
||||
free (keywd);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("%s:%lu: invalid line; missing second token"),
|
||||
filename, (unsigned long int) line_number);
|
||||
ok = false;
|
||||
free (keywd);
|
||||
continue;
|
||||
}
|
||||
|
||||
unrecognized = false;
|
||||
if (c_strcasecmp (keywd, "TERM") == 0)
|
||||
{
|
||||
if (STREQ (arg, term))
|
||||
state = ST_TERMSURE;
|
||||
else if (state != ST_TERMSURE)
|
||||
state = ST_TERMNO;
|
||||
}
|
||||
{
|
||||
if (STREQ (arg, term))
|
||||
state = ST_TERMSURE;
|
||||
else if (state != ST_TERMSURE)
|
||||
state = ST_TERMNO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == ST_TERMSURE)
|
||||
state = ST_TERMYES; /* Another TERM can cancel */
|
||||
{
|
||||
if (state == ST_TERMSURE)
|
||||
state = ST_TERMYES; /* Another TERM can cancel */
|
||||
|
||||
if (state != ST_TERMNO)
|
||||
{
|
||||
if (keywd[0] == '.')
|
||||
{
|
||||
APPEND_CHAR ('*');
|
||||
append_quoted (keywd);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else if (keywd[0] == '*')
|
||||
{
|
||||
append_quoted (keywd);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else if (c_strcasecmp (keywd, "OPTIONS") == 0
|
||||
|| c_strcasecmp (keywd, "COLOR") == 0
|
||||
|| c_strcasecmp (keywd, "EIGHTBIT") == 0)
|
||||
{
|
||||
/* Ignore. */
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
if (state != ST_TERMNO)
|
||||
{
|
||||
if (keywd[0] == '.')
|
||||
{
|
||||
APPEND_CHAR ('*');
|
||||
append_quoted (keywd);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else if (keywd[0] == '*')
|
||||
{
|
||||
append_quoted (keywd);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else if (c_strcasecmp (keywd, "OPTIONS") == 0
|
||||
|| c_strcasecmp (keywd, "COLOR") == 0
|
||||
|| c_strcasecmp (keywd, "EIGHTBIT") == 0)
|
||||
{
|
||||
/* Ignore. */
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; slack_codes[i] != NULL; ++i)
|
||||
if (c_strcasecmp (keywd, slack_codes[i]) == 0)
|
||||
break;
|
||||
for (i = 0; slack_codes[i] != NULL; ++i)
|
||||
if (c_strcasecmp (keywd, slack_codes[i]) == 0)
|
||||
break;
|
||||
|
||||
if (slack_codes[i] != NULL)
|
||||
{
|
||||
APPEND_TWO_CHAR_STRING (ls_codes[i]);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else
|
||||
{
|
||||
unrecognized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unrecognized = true;
|
||||
}
|
||||
}
|
||||
if (slack_codes[i] != NULL)
|
||||
{
|
||||
APPEND_TWO_CHAR_STRING (ls_codes[i]);
|
||||
APPEND_CHAR ('=');
|
||||
append_quoted (arg);
|
||||
APPEND_CHAR (':');
|
||||
}
|
||||
else
|
||||
{
|
||||
unrecognized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unrecognized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (unrecognized && (state == ST_TERMSURE || state == ST_TERMYES))
|
||||
{
|
||||
error (0, 0, _("%s:%lu: unrecognized keyword %s"),
|
||||
(filename ? quote (filename) : _("<internal>")),
|
||||
(unsigned long int) line_number, keywd);
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("%s:%lu: unrecognized keyword %s"),
|
||||
(filename ? quote (filename) : _("<internal>")),
|
||||
(unsigned long int) line_number, keywd);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
free (keywd);
|
||||
free (arg);
|
||||
@@ -411,23 +411,23 @@ main (int argc, char **argv)
|
||||
switch (optc)
|
||||
{
|
||||
case 'b': /* Bourne shell syntax. */
|
||||
syntax = SHELL_SYNTAX_BOURNE;
|
||||
break;
|
||||
syntax = SHELL_SYNTAX_BOURNE;
|
||||
break;
|
||||
|
||||
case 'c': /* C shell syntax. */
|
||||
syntax = SHELL_SYNTAX_C;
|
||||
break;
|
||||
syntax = SHELL_SYNTAX_C;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
print_database = true;
|
||||
break;
|
||||
print_database = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
@@ -438,7 +438,7 @@ main (int argc, char **argv)
|
||||
if (print_database && syntax != SHELL_SYNTAX_UNKNOWN)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the options to output dircolors' internal database and\n\
|
||||
_("the options to output dircolors' internal database and\n\
|
||||
to select a shell syntax are mutually exclusive"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
@@ -447,9 +447,9 @@ to select a shell syntax are mutually exclusive"));
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (argv[!print_database]));
|
||||
if (print_database)
|
||||
fprintf (stderr, "%s\n",
|
||||
_("file operands cannot be combined with "
|
||||
"--print-database (-p)"));
|
||||
fprintf (stderr, "%s\n",
|
||||
_("file operands cannot be combined with "
|
||||
"--print-database (-p)"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -457,51 +457,51 @@ to select a shell syntax are mutually exclusive"));
|
||||
{
|
||||
char const *p = G_line;
|
||||
while (p < G_line + sizeof G_line)
|
||||
{
|
||||
puts (p);
|
||||
p += strlen (p) + 1;
|
||||
}
|
||||
{
|
||||
puts (p);
|
||||
p += strlen (p) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If shell syntax was not explicitly specified, try to guess it. */
|
||||
if (syntax == SHELL_SYNTAX_UNKNOWN)
|
||||
{
|
||||
syntax = guess_shell_syntax ();
|
||||
if (syntax == SHELL_SYNTAX_UNKNOWN)
|
||||
{
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("no SHELL environment variable, and no shell type option given"));
|
||||
}
|
||||
}
|
||||
{
|
||||
syntax = guess_shell_syntax ();
|
||||
if (syntax == SHELL_SYNTAX_UNKNOWN)
|
||||
{
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("no SHELL environment variable, and no shell type option given"));
|
||||
}
|
||||
}
|
||||
|
||||
obstack_init (&lsc_obstack);
|
||||
if (argc == 0)
|
||||
ok = dc_parse_stream (NULL, NULL);
|
||||
ok = dc_parse_stream (NULL, NULL);
|
||||
else
|
||||
ok = dc_parse_file (argv[0]);
|
||||
ok = dc_parse_file (argv[0]);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
size_t len = obstack_object_size (&lsc_obstack);
|
||||
char *s = obstack_finish (&lsc_obstack);
|
||||
const char *prefix;
|
||||
const char *suffix;
|
||||
{
|
||||
size_t len = obstack_object_size (&lsc_obstack);
|
||||
char *s = obstack_finish (&lsc_obstack);
|
||||
const char *prefix;
|
||||
const char *suffix;
|
||||
|
||||
if (syntax == SHELL_SYNTAX_BOURNE)
|
||||
{
|
||||
prefix = "LS_COLORS='";
|
||||
suffix = "';\nexport LS_COLORS\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = "setenv LS_COLORS '";
|
||||
suffix = "'\n";
|
||||
}
|
||||
fputs (prefix, stdout);
|
||||
fwrite (s, 1, len, stdout);
|
||||
fputs (suffix, stdout);
|
||||
}
|
||||
if (syntax == SHELL_SYNTAX_BOURNE)
|
||||
{
|
||||
prefix = "LS_COLORS='";
|
||||
suffix = "';\nexport LS_COLORS\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = "setenv LS_COLORS '";
|
||||
suffix = "'\n";
|
||||
}
|
||||
fputs (prefix, stdout);
|
||||
fwrite (s, 1, len, stdout);
|
||||
fputs (suffix, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
|
||||
@@ -69,7 +69,7 @@ TERM xterm-debian
|
||||
RESET 0 # reset to "normal" color
|
||||
DIR 01;34 # directory
|
||||
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
|
||||
# numerical value, the color is as for the file pointed to.)
|
||||
# numerical value, the color is as for the file pointed to.)
|
||||
MULTIHARDLINK 00 # regular file with more than one link
|
||||
FIFO 40;33 # pipe
|
||||
SOCK 01;35 # socket
|
||||
@@ -116,6 +116,7 @@ EXEC 01;32
|
||||
.Z 01;31
|
||||
.dz 01;31
|
||||
.gz 01;31
|
||||
.lz 01;31
|
||||
.xz 01;31
|
||||
.bz2 01;31
|
||||
.bz 01;31
|
||||
@@ -175,6 +176,8 @@ EXEC 01;32
|
||||
.xcf 01;35
|
||||
.xwd 01;35
|
||||
.yuv 01;35
|
||||
.cgm 01;35
|
||||
.emf 01;35
|
||||
|
||||
# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
|
||||
.axv 01;35
|
||||
|
||||
@@ -39,14 +39,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s NAME\n\
|
||||
or: %s OPTION\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Print NAME with its trailing /component removed; if NAME contains no /'s,\n\
|
||||
output `.' (meaning the current directory).\n\
|
||||
@@ -60,8 +60,8 @@ Examples:\n\
|
||||
%s /usr/bin/sort Output \"/usr/bin\".\n\
|
||||
%s stdio.h Output \".\".\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
emit_bug_reporting_address ();
|
||||
program_name, program_name);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
|
||||
568
src/du.c
568
src/du.c
@@ -262,7 +262,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -330,11 +330,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
fputs (_("\n\
|
||||
SIZE may be (or may be an integer optionally followed by) one of following:\n\
|
||||
kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_blocksize_note ("DU");
|
||||
emit_size_note ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -396,7 +394,7 @@ static void
|
||||
hash_init (void)
|
||||
{
|
||||
htab = hash_initialize (INITIAL_TABLE_SIZE, NULL,
|
||||
entry_hash, entry_compare, free);
|
||||
entry_hash, entry_compare, free);
|
||||
if (htab == NULL)
|
||||
xalloc_die ();
|
||||
}
|
||||
@@ -427,7 +425,7 @@ print_only_size (uintmax_t n_bytes)
|
||||
{
|
||||
char buf[LONGEST_HUMAN_READABLE + 1];
|
||||
fputs (human_readable (n_bytes, buf, human_output_opts,
|
||||
1, output_block_size), stdout);
|
||||
1, output_block_size), stdout);
|
||||
}
|
||||
|
||||
/* Print size (and optionally time) indicated by *PDUI, followed by STRING. */
|
||||
@@ -492,7 +490,7 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
|
||||
case FTS_DNR:
|
||||
/* Don't return just yet, since although the directory is not readable,
|
||||
we were able to stat it, so we do have a size. */
|
||||
we were able to stat it, so we do have a size. */
|
||||
error (0, ent->fts_errno, _("cannot read directory %s"), quote (file));
|
||||
ok = false;
|
||||
break;
|
||||
@@ -512,25 +510,25 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
via a hard link, then don't let it contribute to the sums. */
|
||||
if (skip
|
||||
|| (!opt_count_all
|
||||
&& ! S_ISDIR (sb->st_mode)
|
||||
&& 1 < sb->st_nlink
|
||||
&& ! hash_ins (sb->st_ino, sb->st_dev)))
|
||||
&& ! S_ISDIR (sb->st_mode)
|
||||
&& 1 < sb->st_nlink
|
||||
&& ! hash_ins (sb->st_ino, sb->st_dev)))
|
||||
{
|
||||
/* Note that we must not simply return here.
|
||||
We still have to update prev_level and maybe propagate
|
||||
some sums up the hierarchy. */
|
||||
We still have to update prev_level and maybe propagate
|
||||
some sums up the hierarchy. */
|
||||
duinfo_init (&dui);
|
||||
print = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
duinfo_set (&dui,
|
||||
(apparent_size
|
||||
? sb->st_size
|
||||
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
|
||||
(time_type == time_mtime ? get_stat_mtime (sb)
|
||||
: time_type == time_atime ? get_stat_atime (sb)
|
||||
: get_stat_ctime (sb)));
|
||||
(apparent_size
|
||||
? sb->st_size
|
||||
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
|
||||
(time_type == time_mtime ? get_stat_mtime (sb)
|
||||
: time_type == time_atime ? get_stat_atime (sb)
|
||||
: get_stat_ctime (sb)));
|
||||
}
|
||||
|
||||
level = ent->fts_level;
|
||||
@@ -544,44 +542,44 @@ process_file (FTS *fts, FTSENT *ent)
|
||||
else
|
||||
{
|
||||
if (level == prev_level)
|
||||
{
|
||||
/* This is usually the most common case. Do nothing. */
|
||||
}
|
||||
{
|
||||
/* This is usually the most common case. Do nothing. */
|
||||
}
|
||||
else if (level > prev_level)
|
||||
{
|
||||
/* Descending the hierarchy.
|
||||
Clear the accumulators for *all* levels between prev_level
|
||||
and the current one. The depth may change dramatically,
|
||||
e.g., from 1 to 10. */
|
||||
size_t i;
|
||||
{
|
||||
/* Descending the hierarchy.
|
||||
Clear the accumulators for *all* levels between prev_level
|
||||
and the current one. The depth may change dramatically,
|
||||
e.g., from 1 to 10. */
|
||||
size_t i;
|
||||
|
||||
if (n_alloc <= level)
|
||||
{
|
||||
dulvl = xnrealloc (dulvl, level, 2 * sizeof *dulvl);
|
||||
n_alloc = level * 2;
|
||||
}
|
||||
if (n_alloc <= level)
|
||||
{
|
||||
dulvl = xnrealloc (dulvl, level, 2 * sizeof *dulvl);
|
||||
n_alloc = level * 2;
|
||||
}
|
||||
|
||||
for (i = prev_level + 1; i <= level; i++)
|
||||
{
|
||||
duinfo_init (&dulvl[i].ent);
|
||||
duinfo_init (&dulvl[i].subdir);
|
||||
}
|
||||
}
|
||||
for (i = prev_level + 1; i <= level; i++)
|
||||
{
|
||||
duinfo_init (&dulvl[i].ent);
|
||||
duinfo_init (&dulvl[i].subdir);
|
||||
}
|
||||
}
|
||||
else /* level < prev_level */
|
||||
{
|
||||
/* Ascending the hierarchy.
|
||||
Process a directory only after all entries in that
|
||||
directory have been processed. When the depth decreases,
|
||||
propagate sums from the children (prev_level) to the parent.
|
||||
Here, the current level is always one smaller than the
|
||||
previous one. */
|
||||
assert (level == prev_level - 1);
|
||||
duinfo_add (&dui_to_print, &dulvl[prev_level].ent);
|
||||
if (!opt_separate_dirs)
|
||||
duinfo_add (&dui_to_print, &dulvl[prev_level].subdir);
|
||||
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].ent);
|
||||
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].subdir);
|
||||
}
|
||||
{
|
||||
/* Ascending the hierarchy.
|
||||
Process a directory only after all entries in that
|
||||
directory have been processed. When the depth decreases,
|
||||
propagate sums from the children (prev_level) to the parent.
|
||||
Here, the current level is always one smaller than the
|
||||
previous one. */
|
||||
assert (level == prev_level - 1);
|
||||
duinfo_add (&dui_to_print, &dulvl[prev_level].ent);
|
||||
if (!opt_separate_dirs)
|
||||
duinfo_add (&dui_to_print, &dulvl[prev_level].subdir);
|
||||
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].ent);
|
||||
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].subdir);
|
||||
}
|
||||
}
|
||||
|
||||
prev_level = level;
|
||||
@@ -623,29 +621,30 @@ du_files (char **files, int bit_flags)
|
||||
FTS *fts = xfts_open (files, bit_flags, NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
FTSENT *ent;
|
||||
{
|
||||
FTSENT *ent;
|
||||
|
||||
ent = fts_read (fts);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
FTS_CROSS_CHECK (fts);
|
||||
ent = fts_read (fts);
|
||||
if (ent == NULL)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
/* FIXME: try to give a better message */
|
||||
error (0, errno, _("fts_read failed"));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
FTS_CROSS_CHECK (fts);
|
||||
|
||||
ok &= process_file (fts, ent);
|
||||
}
|
||||
ok &= process_file (fts, ent);
|
||||
}
|
||||
|
||||
/* Ignore failure, since the only way it can do so is in failing to
|
||||
return to the original directory, and since we're about to exit,
|
||||
that doesn't matter. */
|
||||
fts_close (fts);
|
||||
if (fts_close (fts) != 0)
|
||||
{
|
||||
error (0, errno, _("fts_close failed"));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
@@ -683,168 +682,168 @@ main (int argc, char **argv)
|
||||
exclude = new_exclude ();
|
||||
|
||||
human_options (getenv ("DU_BLOCK_SIZE"),
|
||||
&human_output_opts, &output_block_size);
|
||||
&human_output_opts, &output_block_size);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int oi = -1;
|
||||
int c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPSX:",
|
||||
long_options, &oi);
|
||||
long_options, &oi);
|
||||
if (c == -1)
|
||||
break;
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
{
|
||||
#if DU_DEBUG
|
||||
case 'd':
|
||||
fts_debug = true;
|
||||
break;
|
||||
case 'd':
|
||||
fts_debug = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case '0':
|
||||
opt_nul_terminate_output = true;
|
||||
break;
|
||||
case '0':
|
||||
opt_nul_terminate_output = true;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
opt_all = true;
|
||||
break;
|
||||
case 'a':
|
||||
opt_all = true;
|
||||
break;
|
||||
|
||||
case APPARENT_SIZE_OPTION:
|
||||
apparent_size = true;
|
||||
break;
|
||||
case APPARENT_SIZE_OPTION:
|
||||
apparent_size = true;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
apparent_size = true;
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'b':
|
||||
apparent_size = true;
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
print_grand_total = true;
|
||||
break;
|
||||
case 'c':
|
||||
print_grand_total = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
human_output_opts = human_autoscale | human_SI | human_base_1024;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case 'h':
|
||||
human_output_opts = human_autoscale | human_SI | human_base_1024;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
|
||||
case HUMAN_SI_OPTION:
|
||||
human_output_opts = human_autoscale | human_SI;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
case HUMAN_SI_OPTION:
|
||||
human_output_opts = human_autoscale | human_SI;
|
||||
output_block_size = 1;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024;
|
||||
break;
|
||||
case 'k':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024;
|
||||
break;
|
||||
|
||||
case MAX_DEPTH_OPTION: /* --max-depth=N */
|
||||
{
|
||||
unsigned long int tmp_ulong;
|
||||
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
|
||||
&& tmp_ulong <= SIZE_MAX)
|
||||
{
|
||||
max_depth_specified = true;
|
||||
max_depth = tmp_ulong;
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, 0, _("invalid maximum depth %s"),
|
||||
quote (optarg));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MAX_DEPTH_OPTION: /* --max-depth=N */
|
||||
{
|
||||
unsigned long int tmp_ulong;
|
||||
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
|
||||
&& tmp_ulong <= SIZE_MAX)
|
||||
{
|
||||
max_depth_specified = true;
|
||||
max_depth = tmp_ulong;
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, 0, _("invalid maximum depth %s"),
|
||||
quote (optarg));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MEGABYTES_LONG_OPTION: /* FIXME: remove in 2009 */
|
||||
error (0, 0,
|
||||
_("the --megabytes option is deprecated; use -m instead"));
|
||||
/* fall through */
|
||||
case 'm':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024 * 1024;
|
||||
break;
|
||||
case MEGABYTES_LONG_OPTION: /* FIXME: remove in 2009 */
|
||||
error (0, 0,
|
||||
_("the --megabytes option is deprecated; use -m instead"));
|
||||
/* fall through */
|
||||
case 'm':
|
||||
human_output_opts = 0;
|
||||
output_block_size = 1024 * 1024;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
opt_count_all = true;
|
||||
break;
|
||||
case 'l':
|
||||
opt_count_all = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
opt_summarize_only = true;
|
||||
break;
|
||||
case 's':
|
||||
opt_summarize_only = true;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
bit_flags |= FTS_XDEV;
|
||||
break;
|
||||
case 'x':
|
||||
bit_flags |= FTS_XDEV;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
{
|
||||
enum strtol_error e = human_options (optarg, &human_output_opts,
|
||||
&output_block_size);
|
||||
if (e != LONGINT_OK)
|
||||
xstrtol_fatal (e, oi, c, long_options, optarg);
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
{
|
||||
enum strtol_error e = human_options (optarg, &human_output_opts,
|
||||
&output_block_size);
|
||||
if (e != LONGINT_OK)
|
||||
xstrtol_fatal (e, oi, c, long_options, optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H': /* NOTE: before 2008-12, -H was equivalent to --si. */
|
||||
case 'D':
|
||||
symlink_deref_bits = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
case 'H': /* NOTE: before 2008-12, -H was equivalent to --si. */
|
||||
case 'D':
|
||||
symlink_deref_bits = FTS_COMFOLLOW | FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'L': /* --dereference */
|
||||
symlink_deref_bits = FTS_LOGICAL;
|
||||
break;
|
||||
case 'L': /* --dereference */
|
||||
symlink_deref_bits = FTS_LOGICAL;
|
||||
break;
|
||||
|
||||
case 'P': /* --no-dereference */
|
||||
symlink_deref_bits = FTS_PHYSICAL;
|
||||
break;
|
||||
case 'P': /* --no-dereference */
|
||||
symlink_deref_bits = FTS_PHYSICAL;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
opt_separate_dirs = true;
|
||||
break;
|
||||
case 'S':
|
||||
opt_separate_dirs = true;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
if (add_exclude_file (add_exclude, exclude, optarg,
|
||||
EXCLUDE_WILDCARDS, '\n'))
|
||||
{
|
||||
error (0, errno, "%s", quotearg_colon (optarg));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
if (add_exclude_file (add_exclude, exclude, optarg,
|
||||
EXCLUDE_WILDCARDS, '\n'))
|
||||
{
|
||||
error (0, errno, "%s", quotearg_colon (optarg));
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILES0_FROM_OPTION:
|
||||
files_from = optarg;
|
||||
break;
|
||||
case FILES0_FROM_OPTION:
|
||||
files_from = optarg;
|
||||
break;
|
||||
|
||||
case EXCLUDE_OPTION:
|
||||
add_exclude (exclude, optarg, EXCLUDE_WILDCARDS);
|
||||
break;
|
||||
case EXCLUDE_OPTION:
|
||||
add_exclude (exclude, optarg, EXCLUDE_WILDCARDS);
|
||||
break;
|
||||
|
||||
case TIME_OPTION:
|
||||
opt_time = true;
|
||||
time_type =
|
||||
(optarg
|
||||
? XARGMATCH ("--time", optarg, time_args, time_types)
|
||||
: time_mtime);
|
||||
break;
|
||||
case TIME_OPTION:
|
||||
opt_time = true;
|
||||
time_type =
|
||||
(optarg
|
||||
? XARGMATCH ("--time", optarg, time_args, time_types)
|
||||
: time_mtime);
|
||||
break;
|
||||
|
||||
case TIME_STYLE_OPTION:
|
||||
time_style = optarg;
|
||||
break;
|
||||
case TIME_STYLE_OPTION:
|
||||
time_style = optarg;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
ok = false;
|
||||
}
|
||||
default:
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
if (opt_all & opt_summarize_only)
|
||||
if (opt_all && opt_summarize_only)
|
||||
{
|
||||
error (0, 0, _("cannot both summarize and show all entries"));
|
||||
usage (EXIT_FAILURE);
|
||||
@@ -853,7 +852,7 @@ main (int argc, char **argv)
|
||||
if (opt_summarize_only && max_depth_specified && max_depth == 0)
|
||||
{
|
||||
error (0, 0,
|
||||
_("warning: summarizing is the same as using --max-depth=0"));
|
||||
_("warning: summarizing is the same as using --max-depth=0"));
|
||||
}
|
||||
|
||||
if (opt_summarize_only && max_depth_specified && max_depth != 0)
|
||||
@@ -870,48 +869,48 @@ main (int argc, char **argv)
|
||||
if (opt_time)
|
||||
{
|
||||
if (! time_style)
|
||||
{
|
||||
time_style = getenv ("TIME_STYLE");
|
||||
{
|
||||
time_style = getenv ("TIME_STYLE");
|
||||
|
||||
/* Ignore TIMESTYLE="locale", for compatibility with ls. */
|
||||
if (! time_style || STREQ (time_style, "locale"))
|
||||
time_style = "long-iso";
|
||||
else if (*time_style == '+')
|
||||
{
|
||||
/* Ignore anything after a newline, for compatibility
|
||||
with ls. */
|
||||
char *p = strchr (time_style, '\n');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ignore "posix-" prefix, for compatibility with ls. */
|
||||
static char const posix_prefix[] = "posix-";
|
||||
while (strncmp (time_style, posix_prefix, sizeof posix_prefix - 1)
|
||||
== 0)
|
||||
time_style += sizeof posix_prefix - 1;
|
||||
}
|
||||
}
|
||||
/* Ignore TIMESTYLE="locale", for compatibility with ls. */
|
||||
if (! time_style || STREQ (time_style, "locale"))
|
||||
time_style = "long-iso";
|
||||
else if (*time_style == '+')
|
||||
{
|
||||
/* Ignore anything after a newline, for compatibility
|
||||
with ls. */
|
||||
char *p = strchr (time_style, '\n');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ignore "posix-" prefix, for compatibility with ls. */
|
||||
static char const posix_prefix[] = "posix-";
|
||||
while (strncmp (time_style, posix_prefix, sizeof posix_prefix - 1)
|
||||
== 0)
|
||||
time_style += sizeof posix_prefix - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*time_style == '+')
|
||||
time_format = time_style + 1;
|
||||
time_format = time_style + 1;
|
||||
else
|
||||
{
|
||||
switch (XARGMATCH ("time style", time_style,
|
||||
time_style_args, time_style_types))
|
||||
{
|
||||
case full_iso_time_style:
|
||||
time_format = "%Y-%m-%d %H:%M:%S.%N %z";
|
||||
break;
|
||||
case full_iso_time_style:
|
||||
time_format = "%Y-%m-%d %H:%M:%S.%N %z";
|
||||
break;
|
||||
|
||||
case long_iso_time_style:
|
||||
time_format = "%Y-%m-%d %H:%M";
|
||||
break;
|
||||
case long_iso_time_style:
|
||||
time_format = "%Y-%m-%d %H:%M";
|
||||
break;
|
||||
|
||||
case iso_time_style:
|
||||
time_format = "%Y-%m-%d";
|
||||
break;
|
||||
case iso_time_style:
|
||||
time_format = "%Y-%m-%d";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -920,18 +919,18 @@ main (int argc, char **argv)
|
||||
if (files_from)
|
||||
{
|
||||
/* When using --files0-from=F, you may not specify any files
|
||||
on the command-line. */
|
||||
on the command-line. */
|
||||
if (optind < argc)
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (argv[optind]));
|
||||
fprintf (stderr, "%s\n",
|
||||
_("file operands cannot be combined with --files0-from"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (argv[optind]));
|
||||
fprintf (stderr, "%s\n",
|
||||
_("file operands cannot be combined with --files0-from"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (! (STREQ (files_from, "-") || freopen (files_from, "r", stdin)))
|
||||
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
|
||||
quote (files_from));
|
||||
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
|
||||
quote (files_from));
|
||||
|
||||
ai = argv_iter_init_stream (stdin);
|
||||
}
|
||||
@@ -956,64 +955,63 @@ main (int argc, char **argv)
|
||||
enum argv_iter_err ai_err;
|
||||
char *file_name = argv_iter (ai, &ai_err);
|
||||
if (ai_err == AI_ERR_EOF)
|
||||
break;
|
||||
break;
|
||||
if (!file_name)
|
||||
{
|
||||
switch (ai_err)
|
||||
{
|
||||
case AI_ERR_READ:
|
||||
error (0, errno, _("%s: read error"), quote (files_from));
|
||||
skip_file = true;
|
||||
continue;
|
||||
{
|
||||
switch (ai_err)
|
||||
{
|
||||
case AI_ERR_READ:
|
||||
error (0, errno, _("%s: read error"), quote (files_from));
|
||||
continue;
|
||||
|
||||
case AI_ERR_MEM:
|
||||
xalloc_die ();
|
||||
case AI_ERR_MEM:
|
||||
xalloc_die ();
|
||||
|
||||
default:
|
||||
assert (!"unexpected error code from argv_iter");
|
||||
}
|
||||
}
|
||||
default:
|
||||
assert (!"unexpected error code from argv_iter");
|
||||
}
|
||||
}
|
||||
if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-"))
|
||||
{
|
||||
/* Give a better diagnostic in an unusual case:
|
||||
printf - | du --files0-from=- */
|
||||
error (0, 0, _("when reading file names from stdin, "
|
||||
"no file name of %s allowed"),
|
||||
quote (file_name));
|
||||
skip_file = true;
|
||||
}
|
||||
{
|
||||
/* Give a better diagnostic in an unusual case:
|
||||
printf - | du --files0-from=- */
|
||||
error (0, 0, _("when reading file names from stdin, "
|
||||
"no file name of %s allowed"),
|
||||
quote (file_name));
|
||||
skip_file = true;
|
||||
}
|
||||
|
||||
/* Report and skip any empty file names before invoking fts.
|
||||
This works around a glitch in fts, which fails immediately
|
||||
(without looking at the other file names) when given an empty
|
||||
file name. */
|
||||
This works around a glitch in fts, which fails immediately
|
||||
(without looking at the other file names) when given an empty
|
||||
file name. */
|
||||
if (!file_name[0])
|
||||
{
|
||||
/* Diagnose a zero-length file name. When it's one
|
||||
among many, knowing the record number may help.
|
||||
FIXME: currently print the record number only with
|
||||
--files0-from=FILE. Maybe do it for argv, too? */
|
||||
if (files_from == NULL)
|
||||
error (0, 0, "%s", _("invalid zero-length file name"));
|
||||
else
|
||||
{
|
||||
/* Using the standard `filename:line-number:' prefix here is
|
||||
not totally appropriate, since NUL is the separator, not NL,
|
||||
but it might be better than nothing. */
|
||||
unsigned long int file_number = argv_iter_n_args (ai);
|
||||
error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),
|
||||
file_number, _("invalid zero-length file name"));
|
||||
}
|
||||
skip_file = true;
|
||||
}
|
||||
{
|
||||
/* Diagnose a zero-length file name. When it's one
|
||||
among many, knowing the record number may help.
|
||||
FIXME: currently print the record number only with
|
||||
--files0-from=FILE. Maybe do it for argv, too? */
|
||||
if (files_from == NULL)
|
||||
error (0, 0, "%s", _("invalid zero-length file name"));
|
||||
else
|
||||
{
|
||||
/* Using the standard `filename:line-number:' prefix here is
|
||||
not totally appropriate, since NUL is the separator, not NL,
|
||||
but it might be better than nothing. */
|
||||
unsigned long int file_number = argv_iter_n_args (ai);
|
||||
error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),
|
||||
file_number, _("invalid zero-length file name"));
|
||||
}
|
||||
skip_file = true;
|
||||
}
|
||||
|
||||
if (skip_file)
|
||||
ok = false;
|
||||
ok = false;
|
||||
else
|
||||
{
|
||||
temp_argv[0] = file_name;
|
||||
ok &= du_files (temp_argv, bit_flags);
|
||||
}
|
||||
{
|
||||
temp_argv[0] = file_name;
|
||||
ok &= du_files (temp_argv, bit_flags);
|
||||
}
|
||||
}
|
||||
|
||||
argv_iter_free (ai);
|
||||
|
||||
216
src/echo.c
216
src/echo.c
@@ -37,7 +37,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -50,13 +50,13 @@ Echo the STRING(s) to standard output.\n\
|
||||
-n do not output the trailing newline\n\
|
||||
"), stdout);
|
||||
fputs (_(DEFAULT_ECHO_TO_XPG
|
||||
? N_("\
|
||||
? N_("\
|
||||
-e enable interpretation of backslash escapes (default)\n\
|
||||
-E disable interpretation of backslash escapes\n")
|
||||
: N_("\
|
||||
: N_("\
|
||||
-e enable interpretation of backslash escapes\n\
|
||||
-E disable interpretation of backslash escapes (default)\n")),
|
||||
stdout);
|
||||
stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
fputs (_("\
|
||||
@@ -77,7 +77,7 @@ If -e is in effect, the following sequences are recognized:\n\
|
||||
\\v vertical tab\n\
|
||||
"), stdout);
|
||||
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -128,14 +128,14 @@ main (int argc, char **argv)
|
||||
if (allow_options && argc == 2)
|
||||
{
|
||||
if (STREQ (argv[1], "--help"))
|
||||
usage (EXIT_SUCCESS);
|
||||
usage (EXIT_SUCCESS);
|
||||
|
||||
if (STREQ (argv[1], "--version"))
|
||||
{
|
||||
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
|
||||
(char *) NULL);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
{
|
||||
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
|
||||
(char *) NULL);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
--argc;
|
||||
@@ -144,45 +144,45 @@ main (int argc, char **argv)
|
||||
if (allow_options)
|
||||
while (argc > 0 && *argv[0] == '-')
|
||||
{
|
||||
char const *temp = argv[0] + 1;
|
||||
size_t i;
|
||||
char const *temp = argv[0] + 1;
|
||||
size_t i;
|
||||
|
||||
/* If it appears that we are handling options, then make sure that
|
||||
all of the options specified are actually valid. Otherwise, the
|
||||
string should just be echoed. */
|
||||
/* If it appears that we are handling options, then make sure that
|
||||
all of the options specified are actually valid. Otherwise, the
|
||||
string should just be echoed. */
|
||||
|
||||
for (i = 0; temp[i]; i++)
|
||||
switch (temp[i])
|
||||
{
|
||||
case 'e': case 'E': case 'n':
|
||||
break;
|
||||
default:
|
||||
goto just_echo;
|
||||
}
|
||||
for (i = 0; temp[i]; i++)
|
||||
switch (temp[i])
|
||||
{
|
||||
case 'e': case 'E': case 'n':
|
||||
break;
|
||||
default:
|
||||
goto just_echo;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
goto just_echo;
|
||||
if (i == 0)
|
||||
goto just_echo;
|
||||
|
||||
/* All of the options in TEMP are valid options to ECHO.
|
||||
Handle them. */
|
||||
while (*temp)
|
||||
switch (*temp++)
|
||||
{
|
||||
case 'e':
|
||||
do_v9 = true;
|
||||
break;
|
||||
/* All of the options in TEMP are valid options to ECHO.
|
||||
Handle them. */
|
||||
while (*temp)
|
||||
switch (*temp++)
|
||||
{
|
||||
case 'e':
|
||||
do_v9 = true;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
do_v9 = false;
|
||||
break;
|
||||
case 'E':
|
||||
do_v9 = false;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
display_return = false;
|
||||
break;
|
||||
}
|
||||
case 'n':
|
||||
display_return = false;
|
||||
break;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
just_echo:
|
||||
@@ -190,77 +190,77 @@ just_echo:
|
||||
if (do_v9)
|
||||
{
|
||||
while (argc > 0)
|
||||
{
|
||||
char const *s = argv[0];
|
||||
unsigned char c;
|
||||
{
|
||||
char const *s = argv[0];
|
||||
unsigned char c;
|
||||
|
||||
while ((c = *s++))
|
||||
{
|
||||
if (c == '\\' && *s)
|
||||
{
|
||||
switch (c = *s++)
|
||||
{
|
||||
case 'a': c = '\a'; break;
|
||||
case 'b': c = '\b'; break;
|
||||
case 'c': exit (EXIT_SUCCESS);
|
||||
case 'f': c = '\f'; break;
|
||||
case 'n': c = '\n'; break;
|
||||
case 'r': c = '\r'; break;
|
||||
case 't': c = '\t'; break;
|
||||
case 'v': c = '\v'; break;
|
||||
case 'x':
|
||||
{
|
||||
unsigned char ch = *s;
|
||||
if (! isxdigit (ch))
|
||||
goto not_an_escape;
|
||||
s++;
|
||||
c = hextobin (ch);
|
||||
ch = *s;
|
||||
if (isxdigit (ch))
|
||||
{
|
||||
s++;
|
||||
c = c * 16 + hextobin (ch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
c = 0;
|
||||
if (! ('0' <= *s && *s <= '7'))
|
||||
break;
|
||||
c = *s++;
|
||||
/* Fall through. */
|
||||
case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
c -= '0';
|
||||
if ('0' <= *s && *s <= '7')
|
||||
c = c * 8 + (*s++ - '0');
|
||||
if ('0' <= *s && *s <= '7')
|
||||
c = c * 8 + (*s++ - '0');
|
||||
break;
|
||||
case '\\': break;
|
||||
while ((c = *s++))
|
||||
{
|
||||
if (c == '\\' && *s)
|
||||
{
|
||||
switch (c = *s++)
|
||||
{
|
||||
case 'a': c = '\a'; break;
|
||||
case 'b': c = '\b'; break;
|
||||
case 'c': exit (EXIT_SUCCESS);
|
||||
case 'f': c = '\f'; break;
|
||||
case 'n': c = '\n'; break;
|
||||
case 'r': c = '\r'; break;
|
||||
case 't': c = '\t'; break;
|
||||
case 'v': c = '\v'; break;
|
||||
case 'x':
|
||||
{
|
||||
unsigned char ch = *s;
|
||||
if (! isxdigit (ch))
|
||||
goto not_an_escape;
|
||||
s++;
|
||||
c = hextobin (ch);
|
||||
ch = *s;
|
||||
if (isxdigit (ch))
|
||||
{
|
||||
s++;
|
||||
c = c * 16 + hextobin (ch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
c = 0;
|
||||
if (! ('0' <= *s && *s <= '7'))
|
||||
break;
|
||||
c = *s++;
|
||||
/* Fall through. */
|
||||
case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
c -= '0';
|
||||
if ('0' <= *s && *s <= '7')
|
||||
c = c * 8 + (*s++ - '0');
|
||||
if ('0' <= *s && *s <= '7')
|
||||
c = c * 8 + (*s++ - '0');
|
||||
break;
|
||||
case '\\': break;
|
||||
|
||||
not_an_escape:
|
||||
default: putchar ('\\'); break;
|
||||
}
|
||||
}
|
||||
putchar (c);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc > 0)
|
||||
putchar (' ');
|
||||
}
|
||||
not_an_escape:
|
||||
default: putchar ('\\'); break;
|
||||
}
|
||||
}
|
||||
putchar (c);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc > 0)
|
||||
putchar (' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (argc > 0)
|
||||
{
|
||||
fputs (argv[0], stdout);
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc > 0)
|
||||
putchar (' ');
|
||||
}
|
||||
{
|
||||
fputs (argv[0], stdout);
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc > 0)
|
||||
putchar (' ');
|
||||
}
|
||||
}
|
||||
|
||||
if (display_return)
|
||||
|
||||
78
src/env.c
78
src/env.c
@@ -20,24 +20,24 @@
|
||||
-
|
||||
-i
|
||||
--ignore-environment
|
||||
Construct a new environment from scratch; normally the
|
||||
environment is inherited from the parent process, except as
|
||||
modified by other options.
|
||||
Construct a new environment from scratch; normally the
|
||||
environment is inherited from the parent process, except as
|
||||
modified by other options.
|
||||
|
||||
-u variable
|
||||
--unset=variable
|
||||
Unset variable VARIABLE (remove it from the environment).
|
||||
If VARIABLE was not set, does nothing.
|
||||
Unset variable VARIABLE (remove it from the environment).
|
||||
If VARIABLE was not set, does nothing.
|
||||
|
||||
variable=value (an arg containing a "=" character)
|
||||
Set the environment variable VARIABLE to value VALUE. VALUE
|
||||
may be of zero length ("variable="). Setting a variable to a
|
||||
zero-length value is different from unsetting it.
|
||||
Set the environment variable VARIABLE to value VALUE. VALUE
|
||||
may be of zero length ("variable="). Setting a variable to a
|
||||
zero-length value is different from unsetting it.
|
||||
|
||||
--
|
||||
Indicate that the following argument is the program
|
||||
to invoke. This is necessary when the program's name
|
||||
begins with "-" or contains a "=".
|
||||
Indicate that the following argument is the program
|
||||
to invoke. This is necessary when the program's name
|
||||
begins with "-" or contains a "=".
|
||||
|
||||
The first remaining argument specifies a program to invoke;
|
||||
it is searched for according to the specification of the PATH
|
||||
@@ -51,29 +51,29 @@
|
||||
Examples:
|
||||
|
||||
If the environment passed to "env" is
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
|
||||
|
||||
env - foo
|
||||
runs "foo" in a null environment.
|
||||
runs "foo" in a null environment.
|
||||
|
||||
env foo
|
||||
runs "foo" in the environment
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
|
||||
runs "foo" in the environment
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
|
||||
|
||||
env DISPLAY=gnu:0 nemacs
|
||||
runs "nemacs" in the environment
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 }
|
||||
runs "nemacs" in the environment
|
||||
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 }
|
||||
|
||||
env - LOGNAME=foo /hacks/hack bar baz
|
||||
runs the "hack" program on arguments "bar" and "baz" in an
|
||||
environment in which the only variable is "LOGNAME". Note that
|
||||
the "-" option clears out the PATH variable, so one should be
|
||||
careful to specify in which directory to find the program to
|
||||
call.
|
||||
runs the "hack" program on arguments "bar" and "baz" in an
|
||||
environment in which the only variable is "LOGNAME". Note that
|
||||
the "-" option clears out the PATH variable, so one should be
|
||||
careful to specify in which directory to find the program to
|
||||
call.
|
||||
|
||||
env -u EDITOR LOGNAME=foo PATH=/energy -- e=mc2 bar baz
|
||||
runs the program "/energy/e=mc2" with environment
|
||||
{ LOGNAME=foo PATH=/energy }
|
||||
runs the program "/energy/e=mc2" with environment
|
||||
{ LOGNAME=foo PATH=/energy }
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -107,12 +107,12 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Set each NAME to VALUE in the environment and run COMMAND.\n\
|
||||
\n\
|
||||
@@ -125,7 +125,7 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
|
||||
\n\
|
||||
A mere - implies -i. If no COMMAND, print the resulting environment.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -148,17 +148,17 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'i':
|
||||
ignore_environment = true;
|
||||
break;
|
||||
case 'u':
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'i':
|
||||
ignore_environment = true;
|
||||
break;
|
||||
case 'u':
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc && STREQ (argv[optind], "-"))
|
||||
@@ -186,7 +186,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
char *const *e = environ;
|
||||
while (*e)
|
||||
puts (*e++);
|
||||
puts (*e++);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
270
src/expand.c
270
src/expand.c
@@ -23,10 +23,10 @@
|
||||
--tabs=tab1[,tab2[,...]]
|
||||
-t tab1[,tab2[,...]]
|
||||
-tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1
|
||||
columns apart instead of the default 8. Otherwise,
|
||||
set the tabs at columns tab1, tab2, etc. (numbered from
|
||||
0); replace any tabs beyond the tab stops given with
|
||||
single spaces.
|
||||
columns apart instead of the default 8. Otherwise,
|
||||
set the tabs at columns tab1, tab2, etc. (numbered from
|
||||
0); replace any tabs beyond the tab stops given with
|
||||
single spaces.
|
||||
--initial
|
||||
-i Only convert initial tabs on each line to spaces.
|
||||
|
||||
@@ -97,13 +97,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [FILE]...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Convert tabs in each FILE to spaces, writing to standard output.\n\
|
||||
With no FILE, or when FILE is -, read standard input.\n\
|
||||
@@ -121,7 +121,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -150,38 +150,38 @@ parse_tab_stops (char const *stops)
|
||||
for (; *stops; stops++)
|
||||
{
|
||||
if (*stops == ',' || isblank (to_uchar (*stops)))
|
||||
{
|
||||
if (have_tabval)
|
||||
add_tab_stop (tabval);
|
||||
have_tabval = false;
|
||||
}
|
||||
{
|
||||
if (have_tabval)
|
||||
add_tab_stop (tabval);
|
||||
have_tabval = false;
|
||||
}
|
||||
else if (ISDIGIT (*stops))
|
||||
{
|
||||
if (!have_tabval)
|
||||
{
|
||||
tabval = 0;
|
||||
have_tabval = true;
|
||||
num_start = stops;
|
||||
}
|
||||
{
|
||||
if (!have_tabval)
|
||||
{
|
||||
tabval = 0;
|
||||
have_tabval = true;
|
||||
num_start = stops;
|
||||
}
|
||||
|
||||
/* Detect overflow. */
|
||||
if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
|
||||
{
|
||||
size_t len = strspn (num_start, "0123456789");
|
||||
char *bad_num = xstrndup (num_start, len);
|
||||
error (0, 0, _("tab stop is too large %s"), quote (bad_num));
|
||||
free (bad_num);
|
||||
ok = false;
|
||||
stops = num_start + len - 1;
|
||||
}
|
||||
}
|
||||
/* Detect overflow. */
|
||||
if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
|
||||
{
|
||||
size_t len = strspn (num_start, "0123456789");
|
||||
char *bad_num = xstrndup (num_start, len);
|
||||
error (0, 0, _("tab stop is too large %s"), quote (bad_num));
|
||||
free (bad_num);
|
||||
ok = false;
|
||||
stops = num_start + len - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, 0, _("tab size contains invalid character(s): %s"),
|
||||
quote (stops));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("tab size contains invalid character(s): %s"),
|
||||
quote (stops));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
@@ -203,9 +203,9 @@ validate_tab_stops (uintmax_t const *tabs, size_t entries)
|
||||
for (i = 0; i < entries; i++)
|
||||
{
|
||||
if (tabs[i] == 0)
|
||||
error (EXIT_FAILURE, 0, _("tab size cannot be 0"));
|
||||
error (EXIT_FAILURE, 0, _("tab size cannot be 0"));
|
||||
if (tabs[i] <= prev_tab)
|
||||
error (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
|
||||
error (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
|
||||
prev_tab = tabs[i];
|
||||
}
|
||||
}
|
||||
@@ -224,33 +224,33 @@ next_file (FILE *fp)
|
||||
if (fp)
|
||||
{
|
||||
if (ferror (fp))
|
||||
{
|
||||
error (0, errno, "%s", prev_file);
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", prev_file);
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
if (STREQ (prev_file, "-"))
|
||||
clearerr (fp); /* Also clear EOF. */
|
||||
clearerr (fp); /* Also clear EOF. */
|
||||
else if (fclose (fp) != 0)
|
||||
{
|
||||
error (0, errno, "%s", prev_file);
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", prev_file);
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
while ((file = *file_list++) != NULL)
|
||||
{
|
||||
if (STREQ (file, "-"))
|
||||
{
|
||||
have_read_stdin = true;
|
||||
prev_file = file;
|
||||
return stdin;
|
||||
}
|
||||
{
|
||||
have_read_stdin = true;
|
||||
prev_file = file;
|
||||
return stdin;
|
||||
}
|
||||
fp = fopen (file, "r");
|
||||
if (fp)
|
||||
{
|
||||
prev_file = file;
|
||||
return fp;
|
||||
}
|
||||
{
|
||||
prev_file = file;
|
||||
return fp;
|
||||
}
|
||||
error (0, errno, "%s", file);
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
@@ -279,7 +279,7 @@ expand (void)
|
||||
|
||||
|
||||
/* The following variables have valid values only when CONVERT
|
||||
is true: */
|
||||
is true: */
|
||||
|
||||
/* Column of next input character. */
|
||||
uintmax_t column = 0;
|
||||
@@ -291,68 +291,68 @@ expand (void)
|
||||
/* Convert a line of text. */
|
||||
|
||||
do
|
||||
{
|
||||
while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
|
||||
continue;
|
||||
{
|
||||
while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
|
||||
continue;
|
||||
|
||||
if (convert)
|
||||
{
|
||||
if (c == '\t')
|
||||
{
|
||||
/* Column the next input tab stop is on. */
|
||||
uintmax_t next_tab_column;
|
||||
if (convert)
|
||||
{
|
||||
if (c == '\t')
|
||||
{
|
||||
/* Column the next input tab stop is on. */
|
||||
uintmax_t next_tab_column;
|
||||
|
||||
if (tab_size)
|
||||
next_tab_column = column + (tab_size - column % tab_size);
|
||||
else
|
||||
for (;;)
|
||||
if (tab_index == first_free_tab)
|
||||
{
|
||||
next_tab_column = column + 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uintmax_t tab = tab_list[tab_index++];
|
||||
if (column < tab)
|
||||
{
|
||||
next_tab_column = tab;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tab_size)
|
||||
next_tab_column = column + (tab_size - column % tab_size);
|
||||
else
|
||||
for (;;)
|
||||
if (tab_index == first_free_tab)
|
||||
{
|
||||
next_tab_column = column + 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uintmax_t tab = tab_list[tab_index++];
|
||||
if (column < tab)
|
||||
{
|
||||
next_tab_column = tab;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (next_tab_column < column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
if (next_tab_column < column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
|
||||
while (++column < next_tab_column)
|
||||
if (putchar (' ') < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
while (++column < next_tab_column)
|
||||
if (putchar (' ') < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
|
||||
c = ' ';
|
||||
}
|
||||
else if (c == '\b')
|
||||
{
|
||||
/* Go back one column, and force recalculation of the
|
||||
next tab stop. */
|
||||
column -= !!column;
|
||||
tab_index -= !!tab_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
column++;
|
||||
if (!column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
}
|
||||
c = ' ';
|
||||
}
|
||||
else if (c == '\b')
|
||||
{
|
||||
/* Go back one column, and force recalculation of the
|
||||
next tab stop. */
|
||||
column -= !!column;
|
||||
tab_index -= !!tab_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
column++;
|
||||
if (!column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
}
|
||||
|
||||
convert &= convert_entire_line | !! isblank (c);
|
||||
}
|
||||
convert &= convert_entire_line || !! isblank (c);
|
||||
}
|
||||
|
||||
if (c < 0)
|
||||
return;
|
||||
if (c < 0)
|
||||
return;
|
||||
|
||||
if (putchar (c) < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
}
|
||||
if (putchar (c) < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
}
|
||||
while (c != '\n');
|
||||
}
|
||||
}
|
||||
@@ -379,35 +379,35 @@ main (int argc, char **argv)
|
||||
while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'i':
|
||||
convert_entire_line = false;
|
||||
break;
|
||||
{
|
||||
case 'i':
|
||||
convert_entire_line = false;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
parse_tab_stops (optarg);
|
||||
break;
|
||||
case 't':
|
||||
parse_tab_stops (optarg);
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (optarg)
|
||||
parse_tab_stops (optarg - 1);
|
||||
else
|
||||
{
|
||||
char tab_stop[2];
|
||||
tab_stop[0] = c;
|
||||
tab_stop[1] = '\0';
|
||||
parse_tab_stops (tab_stop);
|
||||
}
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (optarg)
|
||||
parse_tab_stops (optarg - 1);
|
||||
else
|
||||
{
|
||||
char tab_stop[2];
|
||||
tab_stop[0] = c;
|
||||
tab_stop[1] = '\0';
|
||||
parse_tab_stops (tab_stop);
|
||||
}
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
validate_tab_stops (tab_list, first_free_tab);
|
||||
|
||||
334
src/expr.c
334
src/expr.c
@@ -55,7 +55,7 @@ static void integer_overflow (char) ATTRIBUTE_NORETURN;
|
||||
#else
|
||||
/* Approximate gmp.h well enough for expr.c's purposes. */
|
||||
typedef intmax_t mpz_t[1];
|
||||
static void mpz_clear (mpz_t z) {}
|
||||
static void mpz_clear (mpz_t z) { (void) z; }
|
||||
static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
|
||||
static int
|
||||
mpz_init_set_str (mpz_t z, char *s, int base)
|
||||
@@ -89,7 +89,7 @@ mpz_mul (mpz_t r, mpz_t a0, mpz_t b0)
|
||||
intmax_t b = b0[0];
|
||||
intmax_t val = a * b;
|
||||
if (! (a == 0 || b == 0
|
||||
|| ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
|
||||
|| ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
|
||||
integer_overflow ('*');
|
||||
r[0] = val;
|
||||
}
|
||||
@@ -116,6 +116,7 @@ mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0)
|
||||
static char *
|
||||
mpz_get_str (char const *str, int base, mpz_t z)
|
||||
{
|
||||
(void) str; (void) base;
|
||||
char buf[INT_BUFSIZE_BOUND (intmax_t)];
|
||||
return xstrdup (imaxtostr (z[0], buf));
|
||||
}
|
||||
@@ -137,6 +138,7 @@ mpz_get_ui (mpz_t z)
|
||||
static int
|
||||
mpz_out_str (FILE *stream, int base, mpz_t z)
|
||||
{
|
||||
(void) base;
|
||||
char buf[INT_BUFSIZE_BOUND (intmax_t)];
|
||||
return fputs (imaxtostr (z[0], buf), stream) != EOF;
|
||||
}
|
||||
@@ -196,14 +198,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s EXPRESSION\n\
|
||||
or: %s OPTION\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
putchar ('\n');
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
@@ -231,7 +233,7 @@ separates increasing precedence groups. EXPRESSION may be:\n\
|
||||
ARG1 - ARG2 arithmetic difference of ARG1 and ARG2\n\
|
||||
"), stdout);
|
||||
/* Tell xgettext that the "% A" below is not a printf-style
|
||||
format string: xgettext:no-c-format */
|
||||
format string: xgettext:no-c-format */
|
||||
fputs (_("\
|
||||
\n\
|
||||
ARG1 * ARG2 arithmetic product of ARG1 and ARG2\n\
|
||||
@@ -265,7 +267,7 @@ Pattern matches return the string matched between \\( and \\) or null; if\n\
|
||||
Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null\n\
|
||||
or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -309,7 +311,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
/* The above handles --help and --version.
|
||||
Since there is no other invocation of getopt, handle `--' here. */
|
||||
if (argc > 1 && STREQ (argv[1], "--"))
|
||||
@@ -398,20 +400,20 @@ null (VALUE *v)
|
||||
return mpz_sgn (v->u.i) == 0;
|
||||
case string:
|
||||
{
|
||||
char const *cp = v->u.s;
|
||||
if (*cp == '\0')
|
||||
return true;
|
||||
char const *cp = v->u.s;
|
||||
if (*cp == '\0')
|
||||
return true;
|
||||
|
||||
cp += (*cp == '-');
|
||||
cp += (*cp == '-');
|
||||
|
||||
do
|
||||
{
|
||||
if (*cp != '0')
|
||||
return false;
|
||||
}
|
||||
while (*++cp);
|
||||
do
|
||||
{
|
||||
if (*cp != '0')
|
||||
return false;
|
||||
}
|
||||
while (*++cp);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
@@ -442,10 +444,10 @@ tostring (VALUE *v)
|
||||
{
|
||||
case integer:
|
||||
{
|
||||
char *s = mpz_get_str (NULL, 10, v->u.i);
|
||||
mpz_clear (v->u.i);
|
||||
v->u.s = s;
|
||||
v->type = string;
|
||||
char *s = mpz_get_str (NULL, 10, v->u.i);
|
||||
mpz_clear (v->u.i);
|
||||
v->u.s = s;
|
||||
v->type = string;
|
||||
}
|
||||
break;
|
||||
case string:
|
||||
@@ -466,15 +468,15 @@ toarith (VALUE *v)
|
||||
return true;
|
||||
case string:
|
||||
{
|
||||
char *s = v->u.s;
|
||||
char *s = v->u.s;
|
||||
|
||||
if (! looks_like_integer (s))
|
||||
return false;
|
||||
if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
|
||||
error (EXPR_FAILURE, ERANGE, "%s", s);
|
||||
free (s);
|
||||
v->type = integer;
|
||||
return true;
|
||||
if (! looks_like_integer (s))
|
||||
return false;
|
||||
if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
|
||||
error (EXPR_FAILURE, ERANGE, "%s", s);
|
||||
free (s);
|
||||
v->type = integer;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
abort ();
|
||||
@@ -493,7 +495,7 @@ getsize (mpz_t i)
|
||||
{
|
||||
unsigned long int ul = mpz_get_ui (i);
|
||||
if (ul < SIZE_MAX)
|
||||
return ul;
|
||||
return ul;
|
||||
}
|
||||
return SIZE_MAX - 1;
|
||||
}
|
||||
@@ -575,25 +577,25 @@ docolon (VALUE *sv, VALUE *pv)
|
||||
{
|
||||
/* Were \(...\) used? */
|
||||
if (re_buffer.re_nsub > 0)
|
||||
{
|
||||
sv->u.s[re_regs.end[1]] = '\0';
|
||||
v = str_value (sv->u.s + re_regs.start[1]);
|
||||
}
|
||||
{
|
||||
sv->u.s[re_regs.end[1]] = '\0';
|
||||
v = str_value (sv->u.s + re_regs.start[1]);
|
||||
}
|
||||
else
|
||||
v = int_value (matchlen);
|
||||
v = int_value (matchlen);
|
||||
}
|
||||
else if (matchlen == -1)
|
||||
{
|
||||
/* Match failed -- return the right kind of null. */
|
||||
if (re_buffer.re_nsub > 0)
|
||||
v = str_value ("");
|
||||
v = str_value ("");
|
||||
else
|
||||
v = int_value (0);
|
||||
v = int_value (0);
|
||||
}
|
||||
else
|
||||
error (EXPR_FAILURE,
|
||||
(matchlen == -2 ? errno : EOVERFLOW),
|
||||
_("error in regular expression matcher"));
|
||||
(matchlen == -2 ? errno : EOVERFLOW),
|
||||
_("error in regular expression matcher"));
|
||||
|
||||
if (0 < re_regs.num_regs)
|
||||
{
|
||||
@@ -622,7 +624,7 @@ eval7 (bool evaluate)
|
||||
{
|
||||
v = eval (evaluate);
|
||||
if (!nextarg (")"))
|
||||
syntax_error ();
|
||||
syntax_error ();
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -649,7 +651,7 @@ eval6 (bool evaluate)
|
||||
if (nextarg ("+"))
|
||||
{
|
||||
if (nomoreargs ())
|
||||
syntax_error ();
|
||||
syntax_error ();
|
||||
return str_value (*args++);
|
||||
}
|
||||
else if (nextarg ("length"))
|
||||
@@ -665,12 +667,12 @@ eval6 (bool evaluate)
|
||||
l = eval6 (evaluate);
|
||||
r = eval6 (evaluate);
|
||||
if (evaluate)
|
||||
{
|
||||
v = docolon (l, r);
|
||||
freev (l);
|
||||
}
|
||||
{
|
||||
v = docolon (l, r);
|
||||
freev (l);
|
||||
}
|
||||
else
|
||||
v = l;
|
||||
v = l;
|
||||
freev (r);
|
||||
return v;
|
||||
}
|
||||
@@ -698,25 +700,25 @@ eval6 (bool evaluate)
|
||||
llen = strlen (l->u.s);
|
||||
|
||||
if (!toarith (i1) || !toarith (i2))
|
||||
v = str_value ("");
|
||||
v = str_value ("");
|
||||
else
|
||||
{
|
||||
size_t pos = getsize (i1->u.i);
|
||||
size_t len = getsize (i2->u.i);
|
||||
{
|
||||
size_t pos = getsize (i1->u.i);
|
||||
size_t len = getsize (i2->u.i);
|
||||
|
||||
if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX)
|
||||
v = str_value ("");
|
||||
else
|
||||
{
|
||||
size_t vlen = MIN (len, llen - pos + 1);
|
||||
char *vlim;
|
||||
v = xmalloc (sizeof *v);
|
||||
v->type = string;
|
||||
v->u.s = xmalloc (vlen + 1);
|
||||
vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen);
|
||||
*vlim = '\0';
|
||||
}
|
||||
}
|
||||
if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX)
|
||||
v = str_value ("");
|
||||
else
|
||||
{
|
||||
size_t vlen = MIN (len, llen - pos + 1);
|
||||
char *vlim;
|
||||
v = xmalloc (sizeof *v);
|
||||
v->type = string;
|
||||
v->u.s = xmalloc (vlen + 1);
|
||||
vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen);
|
||||
*vlim = '\0';
|
||||
}
|
||||
}
|
||||
freev (l);
|
||||
freev (i1);
|
||||
freev (i2);
|
||||
@@ -743,18 +745,18 @@ eval5 (bool evaluate)
|
||||
while (1)
|
||||
{
|
||||
if (nextarg (":"))
|
||||
{
|
||||
r = eval6 (evaluate);
|
||||
if (evaluate)
|
||||
{
|
||||
v = docolon (l, r);
|
||||
freev (l);
|
||||
l = v;
|
||||
}
|
||||
freev (r);
|
||||
}
|
||||
{
|
||||
r = eval6 (evaluate);
|
||||
if (evaluate)
|
||||
{
|
||||
v = docolon (l, r);
|
||||
freev (l);
|
||||
l = v;
|
||||
}
|
||||
freev (r);
|
||||
}
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,25 +776,25 @@ eval4 (bool evaluate)
|
||||
while (1)
|
||||
{
|
||||
if (nextarg ("*"))
|
||||
fxn = multiply;
|
||||
fxn = multiply;
|
||||
else if (nextarg ("/"))
|
||||
fxn = divide;
|
||||
fxn = divide;
|
||||
else if (nextarg ("%"))
|
||||
fxn = mod;
|
||||
fxn = mod;
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
r = eval5 (evaluate);
|
||||
if (evaluate)
|
||||
{
|
||||
if (!toarith (l) || !toarith (r))
|
||||
error (EXPR_INVALID, 0, _("non-numeric argument"));
|
||||
if (fxn != multiply && mpz_sgn (r->u.i) == 0)
|
||||
error (EXPR_INVALID, 0, _("division by zero"));
|
||||
((fxn == multiply ? mpz_mul
|
||||
: fxn == divide ? mpz_tdiv_q
|
||||
: mpz_tdiv_r)
|
||||
(l->u.i, l->u.i, r->u.i));
|
||||
}
|
||||
{
|
||||
if (!toarith (l) || !toarith (r))
|
||||
error (EXPR_INVALID, 0, _("non-numeric argument"));
|
||||
if (fxn != multiply && mpz_sgn (r->u.i) == 0)
|
||||
error (EXPR_INVALID, 0, _("division by zero"));
|
||||
((fxn == multiply ? mpz_mul
|
||||
: fxn == divide ? mpz_tdiv_q
|
||||
: mpz_tdiv_r)
|
||||
(l->u.i, l->u.i, r->u.i));
|
||||
}
|
||||
freev (r);
|
||||
}
|
||||
}
|
||||
@@ -813,18 +815,18 @@ eval3 (bool evaluate)
|
||||
while (1)
|
||||
{
|
||||
if (nextarg ("+"))
|
||||
fxn = plus;
|
||||
fxn = plus;
|
||||
else if (nextarg ("-"))
|
||||
fxn = minus;
|
||||
fxn = minus;
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
r = eval4 (evaluate);
|
||||
if (evaluate)
|
||||
{
|
||||
if (!toarith (l) || !toarith (r))
|
||||
error (EXPR_INVALID, 0, _("non-numeric argument"));
|
||||
(fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
|
||||
}
|
||||
{
|
||||
if (!toarith (l) || !toarith (r))
|
||||
error (EXPR_INVALID, 0, _("non-numeric argument"));
|
||||
(fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
|
||||
}
|
||||
freev (r);
|
||||
}
|
||||
}
|
||||
@@ -844,62 +846,62 @@ eval2 (bool evaluate)
|
||||
{
|
||||
VALUE *r;
|
||||
enum
|
||||
{
|
||||
less_than, less_equal, equal, not_equal, greater_equal, greater_than
|
||||
} fxn;
|
||||
{
|
||||
less_than, less_equal, equal, not_equal, greater_equal, greater_than
|
||||
} fxn;
|
||||
bool val = false;
|
||||
|
||||
if (nextarg ("<"))
|
||||
fxn = less_than;
|
||||
fxn = less_than;
|
||||
else if (nextarg ("<="))
|
||||
fxn = less_equal;
|
||||
fxn = less_equal;
|
||||
else if (nextarg ("=") || nextarg ("=="))
|
||||
fxn = equal;
|
||||
fxn = equal;
|
||||
else if (nextarg ("!="))
|
||||
fxn = not_equal;
|
||||
fxn = not_equal;
|
||||
else if (nextarg (">="))
|
||||
fxn = greater_equal;
|
||||
fxn = greater_equal;
|
||||
else if (nextarg (">"))
|
||||
fxn = greater_than;
|
||||
fxn = greater_than;
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
r = eval3 (evaluate);
|
||||
|
||||
if (evaluate)
|
||||
{
|
||||
int cmp;
|
||||
tostring (l);
|
||||
tostring (r);
|
||||
{
|
||||
int cmp;
|
||||
tostring (l);
|
||||
tostring (r);
|
||||
|
||||
if (looks_like_integer (l->u.s) && looks_like_integer (r->u.s))
|
||||
cmp = strintcmp (l->u.s, r->u.s);
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
cmp = strcoll (l->u.s, r->u.s);
|
||||
if (looks_like_integer (l->u.s) && looks_like_integer (r->u.s))
|
||||
cmp = strintcmp (l->u.s, r->u.s);
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
cmp = strcoll (l->u.s, r->u.s);
|
||||
|
||||
if (errno)
|
||||
{
|
||||
error (0, errno, _("string comparison failed"));
|
||||
error (0, 0, _("set LC_ALL='C' to work around the problem"));
|
||||
error (EXPR_INVALID, 0,
|
||||
_("the strings compared were %s and %s"),
|
||||
quotearg_n_style (0, locale_quoting_style, l->u.s),
|
||||
quotearg_n_style (1, locale_quoting_style, r->u.s));
|
||||
}
|
||||
}
|
||||
if (errno)
|
||||
{
|
||||
error (0, errno, _("string comparison failed"));
|
||||
error (0, 0, _("set LC_ALL='C' to work around the problem"));
|
||||
error (EXPR_INVALID, 0,
|
||||
_("the strings compared were %s and %s"),
|
||||
quotearg_n_style (0, locale_quoting_style, l->u.s),
|
||||
quotearg_n_style (1, locale_quoting_style, r->u.s));
|
||||
}
|
||||
}
|
||||
|
||||
switch (fxn)
|
||||
{
|
||||
case less_than: val = (cmp < 0); break;
|
||||
case less_equal: val = (cmp <= 0); break;
|
||||
case equal: val = (cmp == 0); break;
|
||||
case not_equal: val = (cmp != 0); break;
|
||||
case greater_equal: val = (cmp >= 0); break;
|
||||
case greater_than: val = (cmp > 0); break;
|
||||
default: abort ();
|
||||
}
|
||||
}
|
||||
switch (fxn)
|
||||
{
|
||||
case less_than: val = (cmp < 0); break;
|
||||
case less_equal: val = (cmp <= 0); break;
|
||||
case equal: val = (cmp == 0); break;
|
||||
case not_equal: val = (cmp != 0); break;
|
||||
case greater_equal: val = (cmp >= 0); break;
|
||||
case greater_than: val = (cmp > 0); break;
|
||||
default: abort ();
|
||||
}
|
||||
}
|
||||
|
||||
freev (l);
|
||||
freev (r);
|
||||
@@ -922,19 +924,19 @@ eval1 (bool evaluate)
|
||||
while (1)
|
||||
{
|
||||
if (nextarg ("&"))
|
||||
{
|
||||
r = eval2 (evaluate & ~ null (l));
|
||||
if (null (l) || null (r))
|
||||
{
|
||||
freev (l);
|
||||
freev (r);
|
||||
l = int_value (0);
|
||||
}
|
||||
else
|
||||
freev (r);
|
||||
}
|
||||
{
|
||||
r = eval2 (evaluate && !null (l));
|
||||
if (null (l) || null (r))
|
||||
{
|
||||
freev (l);
|
||||
freev (r);
|
||||
l = int_value (0);
|
||||
}
|
||||
else
|
||||
freev (r);
|
||||
}
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -953,22 +955,22 @@ eval (bool evaluate)
|
||||
while (1)
|
||||
{
|
||||
if (nextarg ("|"))
|
||||
{
|
||||
r = eval1 (evaluate & null (l));
|
||||
if (null (l))
|
||||
{
|
||||
freev (l);
|
||||
l = r;
|
||||
if (null (l))
|
||||
{
|
||||
freev (l);
|
||||
l = int_value (0);
|
||||
}
|
||||
}
|
||||
else
|
||||
freev (r);
|
||||
}
|
||||
{
|
||||
r = eval1 (evaluate && null (l));
|
||||
if (null (l))
|
||||
{
|
||||
freev (l);
|
||||
l = r;
|
||||
if (null (l))
|
||||
{
|
||||
freev (l);
|
||||
l = int_value (0);
|
||||
}
|
||||
}
|
||||
else
|
||||
freev (r);
|
||||
}
|
||||
else
|
||||
return l;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,10 +114,10 @@ EOF
|
||||
while (defined (my $line = <FH>))
|
||||
{
|
||||
$line =~ /^[ \t]+case S_MAGIC_/
|
||||
or next;
|
||||
or next;
|
||||
$line =~ m!^[ \t]+case (S_MAGIC_\w+): /\* (0x[0-9A-Fa-f]+) \*/$!
|
||||
or (warn "$ME:$file:$.: malformed case S_MAGIC_... line"),
|
||||
$fail = 1, next;
|
||||
or (warn "$ME:$file:$.: malformed case S_MAGIC_... line"),
|
||||
$fail = 1, next;
|
||||
my $name = $1;
|
||||
my $value = $2;
|
||||
print "# define $name $value\n";
|
||||
|
||||
172
src/factor.c
172
src/factor.c
@@ -26,7 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if HAVE_GMP
|
||||
#include <gmp.h>
|
||||
# include <gmp.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
@@ -110,7 +110,7 @@ factor_using_division (mpz_t t, unsigned int limit)
|
||||
{
|
||||
mpz_tdiv_qr_ui (q, r, t, 3);
|
||||
if (mpz_cmp_ui (r, 0) != 0)
|
||||
break;
|
||||
break;
|
||||
mpz_set (t, q);
|
||||
emit_ul_factor (3);
|
||||
}
|
||||
@@ -119,7 +119,7 @@ factor_using_division (mpz_t t, unsigned int limit)
|
||||
{
|
||||
mpz_tdiv_qr_ui (q, r, t, 5);
|
||||
if (mpz_cmp_ui (r, 0) != 0)
|
||||
break;
|
||||
break;
|
||||
mpz_set (t, q);
|
||||
emit_ul_factor (5);
|
||||
}
|
||||
@@ -131,21 +131,21 @@ factor_using_division (mpz_t t, unsigned int limit)
|
||||
{
|
||||
mpz_tdiv_qr_ui (q, r, t, f);
|
||||
if (mpz_cmp_ui (r, 0) != 0)
|
||||
{
|
||||
f += addv[ai];
|
||||
if (mpz_cmp_ui (q, f) < 0)
|
||||
break;
|
||||
ai = (ai + 1) & 7;
|
||||
failures++;
|
||||
if (failures > limit)
|
||||
break;
|
||||
}
|
||||
{
|
||||
f += addv[ai];
|
||||
if (mpz_cmp_ui (q, f) < 0)
|
||||
break;
|
||||
ai = (ai + 1) & 7;
|
||||
failures++;
|
||||
if (failures > limit)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_swap (t, q);
|
||||
emit_ul_factor (f);
|
||||
failures = 0;
|
||||
}
|
||||
{
|
||||
mpz_swap (t, q);
|
||||
emit_ul_factor (f);
|
||||
failures = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mpz_clear (q);
|
||||
@@ -184,67 +184,67 @@ S2:
|
||||
mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);
|
||||
c++;
|
||||
if (c == 20)
|
||||
{
|
||||
c = 0;
|
||||
mpz_gcd (g, P, n);
|
||||
if (mpz_cmp_ui (g, 1) != 0)
|
||||
goto S4;
|
||||
mpz_set (y, x);
|
||||
}
|
||||
{
|
||||
c = 0;
|
||||
mpz_gcd (g, P, n);
|
||||
if (mpz_cmp_ui (g, 1) != 0)
|
||||
goto S4;
|
||||
mpz_set (y, x);
|
||||
}
|
||||
|
||||
k--;
|
||||
if (k > 0)
|
||||
goto S2;
|
||||
goto S2;
|
||||
|
||||
mpz_gcd (g, P, n);
|
||||
if (mpz_cmp_ui (g, 1) != 0)
|
||||
goto S4;
|
||||
goto S4;
|
||||
|
||||
mpz_set (x1, x);
|
||||
k = l;
|
||||
l = 2 * l;
|
||||
for (i = 0; i < k; i++)
|
||||
{
|
||||
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
|
||||
}
|
||||
{
|
||||
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
|
||||
}
|
||||
mpz_set (y, x);
|
||||
c = 0;
|
||||
goto S2;
|
||||
S4:
|
||||
do
|
||||
{
|
||||
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
|
||||
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
|
||||
}
|
||||
{
|
||||
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
|
||||
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
|
||||
}
|
||||
while (mpz_cmp_ui (g, 1) == 0);
|
||||
|
||||
mpz_div (n, n, g); /* divide by g, before g is overwritten */
|
||||
|
||||
if (!mpz_probab_prime_p (g, 3))
|
||||
{
|
||||
do
|
||||
{
|
||||
mp_limb_t a_limb;
|
||||
mpn_random (&a_limb, (mp_size_t) 1);
|
||||
a_int = (int) a_limb;
|
||||
}
|
||||
while (a_int == -2 || a_int == 0);
|
||||
{
|
||||
do
|
||||
{
|
||||
mp_limb_t a_limb;
|
||||
mpn_random (&a_limb, (mp_size_t) 1);
|
||||
a_int = (int) a_limb;
|
||||
}
|
||||
while (a_int == -2 || a_int == 0);
|
||||
|
||||
debug ("[composite factor--restarting pollard-rho] ");
|
||||
factor_using_pollard_rho (g, a_int);
|
||||
}
|
||||
debug ("[composite factor--restarting pollard-rho] ");
|
||||
factor_using_pollard_rho (g, a_int);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_factor (g);
|
||||
}
|
||||
{
|
||||
emit_factor (g);
|
||||
}
|
||||
mpz_mod (x, x, n);
|
||||
mpz_mod (x1, x1, n);
|
||||
mpz_mod (y, y, n);
|
||||
if (mpz_probab_prime_p (n, 3))
|
||||
{
|
||||
emit_factor (n);
|
||||
break;
|
||||
}
|
||||
{
|
||||
emit_factor (n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mpz_clear (g);
|
||||
@@ -309,15 +309,15 @@ factor_wheel (uintmax_t n0, size_t max_n_factors, uintmax_t *factors)
|
||||
{
|
||||
q = n / d;
|
||||
while (n == q * d)
|
||||
{
|
||||
assert (n_factors < max_n_factors);
|
||||
factors[n_factors++] = d;
|
||||
n = q;
|
||||
q = n / d;
|
||||
}
|
||||
{
|
||||
assert (n_factors < max_n_factors);
|
||||
factors[n_factors++] = d;
|
||||
n = q;
|
||||
q = n / d;
|
||||
}
|
||||
d += *(w++);
|
||||
if (w == WHEEL_END)
|
||||
w = WHEEL_START;
|
||||
w = WHEEL_START;
|
||||
}
|
||||
while (d <= q);
|
||||
|
||||
@@ -407,13 +407,13 @@ print_factors_multi (mpz_t t)
|
||||
factor_using_division (t, division_limit);
|
||||
|
||||
if (mpz_cmp_ui (t, 1) != 0)
|
||||
{
|
||||
debug ("[is number prime?] ");
|
||||
if (mpz_probab_prime_p (t, 3))
|
||||
emit_factor (t);
|
||||
else
|
||||
factor_using_pollard_rho (t, 1);
|
||||
}
|
||||
{
|
||||
debug ("[is number prime?] ");
|
||||
if (mpz_probab_prime_p (t, 3))
|
||||
emit_factor (t);
|
||||
else
|
||||
factor_using_pollard_rho (t, 1);
|
||||
}
|
||||
}
|
||||
|
||||
mpz_clear (t);
|
||||
@@ -443,11 +443,11 @@ print_factors (char const *s)
|
||||
mpz_t t;
|
||||
mpz_init (t);
|
||||
if (gmp_sscanf (s, "%Zd", t) == 1)
|
||||
{
|
||||
debug ("[%s]", _("using arbitrary-precision arithmetic"));
|
||||
print_factors_multi (t);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
debug ("[%s]", _("using arbitrary-precision arithmetic"));
|
||||
print_factors_multi (t);
|
||||
return true;
|
||||
}
|
||||
err = LONGINT_INVALID;
|
||||
}
|
||||
#endif
|
||||
@@ -487,14 +487,14 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [NUMBER]...\n\
|
||||
or: %s OPTION\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
program_name, program_name);
|
||||
fputs (_("\
|
||||
Print the prime factors of each specified integer NUMBER. If none\n\
|
||||
are specified on the command line, read them from standard input.\n\
|
||||
@@ -502,7 +502,7 @@ are specified on the command line, read them from standard input.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -518,9 +518,9 @@ do_stdin (void)
|
||||
for (;;)
|
||||
{
|
||||
size_t token_length = readtoken (stdin, DELIM, sizeof (DELIM) - 1,
|
||||
&tokenbuffer);
|
||||
&tokenbuffer);
|
||||
if (token_length == (size_t) -1)
|
||||
break;
|
||||
break;
|
||||
ok &= print_factors (tokenbuffer.buffer);
|
||||
}
|
||||
free (tokenbuffer.buffer);
|
||||
@@ -545,18 +545,18 @@ main (int argc, char **argv)
|
||||
while ((c = getopt_long (argc, argv, "", long_options, NULL)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case VERBOSE_OPTION:
|
||||
verbose = true;
|
||||
break;
|
||||
{
|
||||
case VERBOSE_OPTION:
|
||||
verbose = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= optind)
|
||||
@@ -566,8 +566,8 @@ main (int argc, char **argv)
|
||||
int i;
|
||||
ok = true;
|
||||
for (i = optind; i < argc; i++)
|
||||
if (! print_factors (argv[i]))
|
||||
ok = false;
|
||||
if (! print_factors (argv[i]))
|
||||
ok = false;
|
||||
}
|
||||
#if HAVE_GMP
|
||||
free (factor);
|
||||
|
||||
296
src/fmt.c
296
src/fmt.c
@@ -263,7 +263,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [-WIDTH] [OPTION]... [FILE]...\n"), program_name);
|
||||
@@ -281,7 +281,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
reattaching the prefix to reformatted lines\n\
|
||||
-s, --split-only split long lines, but do not refill\n\
|
||||
"),
|
||||
stdout);
|
||||
stdout);
|
||||
fputs (_("\
|
||||
-t, --tagged-paragraph indentation of first line different from second\n\
|
||||
-u, --uniform-spacing one space between words, two after sentences\n\
|
||||
@@ -292,8 +292,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
fputs (_("\
|
||||
\n\
|
||||
With no FILE, or when FILE is -, read standard input.\n"),
|
||||
stdout);
|
||||
emit_bug_reporting_address ();
|
||||
stdout);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -345,40 +345,40 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
while ((optchar = getopt_long (argc, argv, "0123456789cstuw:p:",
|
||||
long_options, NULL))
|
||||
!= -1)
|
||||
long_options, NULL))
|
||||
!= -1)
|
||||
switch (optchar)
|
||||
{
|
||||
default:
|
||||
if (ISDIGIT (optchar))
|
||||
error (0, 0, _("invalid option -- %c; -WIDTH is recognized\
|
||||
if (ISDIGIT (optchar))
|
||||
error (0, 0, _("invalid option -- %c; -WIDTH is recognized\
|
||||
only when it is the first\noption; use -w N instead"),
|
||||
optchar);
|
||||
usage (EXIT_FAILURE);
|
||||
optchar);
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
case 'c':
|
||||
crown = true;
|
||||
break;
|
||||
crown = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
split = true;
|
||||
break;
|
||||
split = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
tagged = true;
|
||||
break;
|
||||
tagged = true;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
uniform = true;
|
||||
break;
|
||||
uniform = true;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
max_width_option = optarg;
|
||||
break;
|
||||
max_width_option = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
set_prefix (optarg);
|
||||
break;
|
||||
set_prefix (optarg);
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
@@ -389,12 +389,12 @@ main (int argc, char **argv)
|
||||
if (max_width_option)
|
||||
{
|
||||
/* Limit max_width to MAXCHARS / 2; otherwise, the resulting
|
||||
output can be quite ugly. */
|
||||
output can be quite ugly. */
|
||||
unsigned long int tmp;
|
||||
if (! (xstrtoul (max_width_option, NULL, 10, &tmp, "") == LONGINT_OK
|
||||
&& tmp <= MAXCHARS / 2))
|
||||
error (EXIT_FAILURE, 0, _("invalid width: %s"),
|
||||
quote (max_width_option));
|
||||
&& tmp <= MAXCHARS / 2))
|
||||
error (EXIT_FAILURE, 0, _("invalid width: %s"),
|
||||
quote (max_width_option));
|
||||
max_width = tmp;
|
||||
}
|
||||
|
||||
@@ -405,31 +405,31 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
for (; optind < argc; optind++)
|
||||
{
|
||||
char *file = argv[optind];
|
||||
if (STREQ (file, "-"))
|
||||
fmt (stdin);
|
||||
else
|
||||
{
|
||||
FILE *in_stream;
|
||||
in_stream = fopen (file, "r");
|
||||
if (in_stream != NULL)
|
||||
{
|
||||
fmt (in_stream);
|
||||
if (fclose (in_stream) == EOF)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot open %s for reading"),
|
||||
quote (file));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
char *file = argv[optind];
|
||||
if (STREQ (file, "-"))
|
||||
fmt (stdin);
|
||||
else
|
||||
{
|
||||
FILE *in_stream;
|
||||
in_stream = fopen (file, "r");
|
||||
if (in_stream != NULL)
|
||||
{
|
||||
fmt (in_stream);
|
||||
if (fclose (in_stream) == EOF)
|
||||
{
|
||||
error (0, errno, "%s", file);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot open %s for reading"),
|
||||
quote (file));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
@@ -488,9 +488,9 @@ set_other_indent (bool same_paragraph)
|
||||
else if (tagged)
|
||||
{
|
||||
if (same_paragraph && in_column != first_indent)
|
||||
{
|
||||
other_indent = in_column;
|
||||
}
|
||||
{
|
||||
other_indent = in_column;
|
||||
}
|
||||
|
||||
/* Only one line: use the secondary indent from last time if it
|
||||
splits, or 0 if there have been no multi-line paragraphs in the
|
||||
@@ -498,7 +498,7 @@ set_other_indent (bool same_paragraph)
|
||||
pick a new secondary indent. */
|
||||
|
||||
else if (other_indent == first_indent)
|
||||
other_indent = first_indent == 0 ? DEF_INDENT : 0;
|
||||
other_indent = first_indent == 0 ? DEF_INDENT : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -532,15 +532,15 @@ get_paragraph (FILE *f)
|
||||
/* Scan (and copy) blank lines, and lines not introduced by the prefix. */
|
||||
|
||||
while (c == '\n' || c == EOF
|
||||
|| next_prefix_indent < prefix_lead_space
|
||||
|| in_column < next_prefix_indent + prefix_full_length)
|
||||
|| next_prefix_indent < prefix_lead_space
|
||||
|| in_column < next_prefix_indent + prefix_full_length)
|
||||
{
|
||||
c = copy_rest (f, c);
|
||||
if (c == EOF)
|
||||
{
|
||||
next_char = EOF;
|
||||
return false;
|
||||
}
|
||||
{
|
||||
next_char = EOF;
|
||||
return false;
|
||||
}
|
||||
putchar ('\n');
|
||||
c = get_prefix (f);
|
||||
}
|
||||
@@ -563,29 +563,29 @@ get_paragraph (FILE *f)
|
||||
else if (crown)
|
||||
{
|
||||
if (same_para (c))
|
||||
{
|
||||
do
|
||||
{ /* for each line till the end of the para */
|
||||
c = get_line (f, c);
|
||||
}
|
||||
while (same_para (c) && in_column == other_indent);
|
||||
}
|
||||
{
|
||||
do
|
||||
{ /* for each line till the end of the para */
|
||||
c = get_line (f, c);
|
||||
}
|
||||
while (same_para (c) && in_column == other_indent);
|
||||
}
|
||||
}
|
||||
else if (tagged)
|
||||
{
|
||||
if (same_para (c) && in_column != first_indent)
|
||||
{
|
||||
do
|
||||
{ /* for each line till the end of the para */
|
||||
c = get_line (f, c);
|
||||
}
|
||||
while (same_para (c) && in_column == other_indent);
|
||||
}
|
||||
{
|
||||
do
|
||||
{ /* for each line till the end of the para */
|
||||
c = get_line (f, c);
|
||||
}
|
||||
while (same_para (c) && in_column == other_indent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (same_para (c) && in_column == other_indent)
|
||||
c = get_line (f, c);
|
||||
c = get_line (f, c);
|
||||
}
|
||||
(word_limit - 1)->period = (word_limit - 1)->final = true;
|
||||
next_char = c;
|
||||
@@ -607,11 +607,11 @@ copy_rest (FILE *f, int c)
|
||||
{
|
||||
put_space (next_prefix_indent);
|
||||
for (s = prefix; out_column != in_column && *s; out_column++)
|
||||
putchar (*s++);
|
||||
putchar (*s++);
|
||||
if (c != EOF && c != '\n')
|
||||
put_space (in_column - out_column);
|
||||
put_space (in_column - out_column);
|
||||
if (c == EOF && in_column >= next_prefix_indent + prefix_length)
|
||||
putchar ('\n');
|
||||
putchar ('\n');
|
||||
}
|
||||
while (c != '\n' && c != EOF)
|
||||
{
|
||||
@@ -629,8 +629,8 @@ static bool
|
||||
same_para (int c)
|
||||
{
|
||||
return (next_prefix_indent == prefix_indent
|
||||
&& in_column >= next_prefix_indent + prefix_full_length
|
||||
&& c != '\n' && c != EOF);
|
||||
&& in_column >= next_prefix_indent + prefix_full_length
|
||||
&& c != '\n' && c != EOF);
|
||||
}
|
||||
|
||||
/* Read a line from input file F, given first non-blank character C
|
||||
@@ -658,15 +658,15 @@ get_line (FILE *f, int c)
|
||||
|
||||
word_limit->text = wptr;
|
||||
do
|
||||
{
|
||||
if (wptr == end_of_parabuf)
|
||||
{
|
||||
set_other_indent (true);
|
||||
flush_paragraph ();
|
||||
}
|
||||
*wptr++ = c;
|
||||
c = getc (f);
|
||||
}
|
||||
{
|
||||
if (wptr == end_of_parabuf)
|
||||
{
|
||||
set_other_indent (true);
|
||||
flush_paragraph ();
|
||||
}
|
||||
*wptr++ = c;
|
||||
c = getc (f);
|
||||
}
|
||||
while (c != EOF && !isspace (c));
|
||||
in_column += word_limit->length = wptr - word_limit->text;
|
||||
check_punctuation (word_limit);
|
||||
@@ -677,15 +677,15 @@ get_line (FILE *f, int c)
|
||||
c = get_space (f, c);
|
||||
word_limit->space = in_column - start;
|
||||
word_limit->final = (c == EOF
|
||||
|| (word_limit->period
|
||||
&& (c == '\n' || word_limit->space > 1)));
|
||||
|| (word_limit->period
|
||||
&& (c == '\n' || word_limit->space > 1)));
|
||||
if (c == '\n' || c == EOF || uniform)
|
||||
word_limit->space = word_limit->final ? 2 : 1;
|
||||
word_limit->space = word_limit->final ? 2 : 1;
|
||||
if (word_limit == end_of_word)
|
||||
{
|
||||
set_other_indent (true);
|
||||
flush_paragraph ();
|
||||
}
|
||||
{
|
||||
set_other_indent (true);
|
||||
flush_paragraph ();
|
||||
}
|
||||
word_limit++;
|
||||
}
|
||||
while (c != '\n' && c != EOF);
|
||||
@@ -710,13 +710,13 @@ get_prefix (FILE *f)
|
||||
const char *p;
|
||||
next_prefix_indent = in_column;
|
||||
for (p = prefix; *p != '\0'; p++)
|
||||
{
|
||||
unsigned char pc = *p;
|
||||
if (c != pc)
|
||||
return c;
|
||||
in_column++;
|
||||
c = getc (f);
|
||||
}
|
||||
{
|
||||
unsigned char pc = *p;
|
||||
if (c != pc)
|
||||
return c;
|
||||
in_column++;
|
||||
c = getc (f);
|
||||
}
|
||||
c = get_space (f, c);
|
||||
}
|
||||
return c;
|
||||
@@ -731,14 +731,14 @@ get_space (FILE *f, int c)
|
||||
for (;;)
|
||||
{
|
||||
if (c == ' ')
|
||||
in_column++;
|
||||
in_column++;
|
||||
else if (c == '\t')
|
||||
{
|
||||
tabs = true;
|
||||
in_column = (in_column / TABWIDTH + 1) * TABWIDTH;
|
||||
}
|
||||
{
|
||||
tabs = true;
|
||||
in_column = (in_column / TABWIDTH + 1) * TABWIDTH;
|
||||
}
|
||||
else
|
||||
return c;
|
||||
return c;
|
||||
c = getc (f);
|
||||
}
|
||||
}
|
||||
@@ -794,12 +794,12 @@ flush_paragraph (void)
|
||||
for (w = word->next_break; w != word_limit; w = w->next_break)
|
||||
{
|
||||
if (w->best_cost - w->next_break->best_cost < best_break)
|
||||
{
|
||||
split_point = w;
|
||||
best_break = w->best_cost - w->next_break->best_cost;
|
||||
}
|
||||
{
|
||||
split_point = w;
|
||||
best_break = w->best_cost - w->next_break->best_cost;
|
||||
}
|
||||
if (best_break <= MAXCOST - LINE_CREDIT)
|
||||
best_break += LINE_CREDIT;
|
||||
best_break += LINE_CREDIT;
|
||||
}
|
||||
put_paragraph (split_point);
|
||||
|
||||
@@ -848,30 +848,30 @@ fmt_paragraph (void)
|
||||
w = start;
|
||||
len += w->length;
|
||||
do
|
||||
{
|
||||
w++;
|
||||
{
|
||||
w++;
|
||||
|
||||
/* Consider breaking before w. */
|
||||
/* Consider breaking before w. */
|
||||
|
||||
wcost = line_cost (w, len) + w->best_cost;
|
||||
if (start == word && last_line_length > 0)
|
||||
wcost += RAGGED_COST (len - last_line_length);
|
||||
if (wcost < best)
|
||||
{
|
||||
best = wcost;
|
||||
start->next_break = w;
|
||||
start->line_length = len;
|
||||
}
|
||||
wcost = line_cost (w, len) + w->best_cost;
|
||||
if (start == word && last_line_length > 0)
|
||||
wcost += RAGGED_COST (len - last_line_length);
|
||||
if (wcost < best)
|
||||
{
|
||||
best = wcost;
|
||||
start->next_break = w;
|
||||
start->line_length = len;
|
||||
}
|
||||
|
||||
/* This is a kludge to keep us from computing `len' as the
|
||||
sum of the sentinel length and some non-zero number.
|
||||
Since the sentinel w->length may be INT_MAX, adding
|
||||
to that would give a negative result. */
|
||||
if (w == word_limit)
|
||||
break;
|
||||
/* This is a kludge to keep us from computing `len' as the
|
||||
sum of the sentinel length and some non-zero number.
|
||||
Since the sentinel w->length may be INT_MAX, adding
|
||||
to that would give a negative result. */
|
||||
if (w == word_limit)
|
||||
break;
|
||||
|
||||
len += (w - 1)->space + w->length; /* w > start >= word */
|
||||
}
|
||||
len += (w - 1)->space + w->length; /* w > start >= word */
|
||||
}
|
||||
while (len < max_width);
|
||||
start->best_cost = best + base_cost (start);
|
||||
}
|
||||
@@ -892,16 +892,16 @@ base_cost (WORD *this)
|
||||
if (this > word)
|
||||
{
|
||||
if ((this - 1)->period)
|
||||
{
|
||||
if ((this - 1)->final)
|
||||
cost -= SENTENCE_BONUS;
|
||||
else
|
||||
cost += NOBREAK_COST;
|
||||
}
|
||||
{
|
||||
if ((this - 1)->final)
|
||||
cost -= SENTENCE_BONUS;
|
||||
else
|
||||
cost += NOBREAK_COST;
|
||||
}
|
||||
else if ((this - 1)->punct)
|
||||
cost -= PUNCT_BONUS;
|
||||
cost -= PUNCT_BONUS;
|
||||
else if (this > word + 1 && (this - 2)->final)
|
||||
cost += WIDOW_COST ((this - 1)->length);
|
||||
cost += WIDOW_COST ((this - 1)->length);
|
||||
}
|
||||
|
||||
if (this->paren)
|
||||
@@ -997,11 +997,11 @@ put_space (int space)
|
||||
{
|
||||
tab_target = space_target / TABWIDTH * TABWIDTH;
|
||||
if (out_column + 1 < tab_target)
|
||||
while (out_column < tab_target)
|
||||
{
|
||||
putchar ('\t');
|
||||
out_column = (out_column / TABWIDTH + 1) * TABWIDTH;
|
||||
}
|
||||
while (out_column < tab_target)
|
||||
{
|
||||
putchar ('\t');
|
||||
out_column = (out_column / TABWIDTH + 1) * TABWIDTH;
|
||||
}
|
||||
}
|
||||
while (out_column < space_target)
|
||||
{
|
||||
|
||||
196
src/fold.c
196
src/fold.c
@@ -60,13 +60,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [FILE]...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Wrap input lines in each FILE (standard input by default), writing to\n\
|
||||
standard output.\n\
|
||||
@@ -82,7 +82,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -97,16 +97,16 @@ adjust_column (size_t column, char c)
|
||||
if (!count_bytes)
|
||||
{
|
||||
if (c == '\b')
|
||||
{
|
||||
if (column > 0)
|
||||
column--;
|
||||
}
|
||||
{
|
||||
if (column > 0)
|
||||
column--;
|
||||
}
|
||||
else if (c == '\r')
|
||||
column = 0;
|
||||
column = 0;
|
||||
else if (c == '\t')
|
||||
column += TAB_WIDTH - column % TAB_WIDTH;
|
||||
column += TAB_WIDTH - column % TAB_WIDTH;
|
||||
else /* if (isprint (c)) */
|
||||
column++;
|
||||
column++;
|
||||
}
|
||||
else
|
||||
column++;
|
||||
@@ -145,71 +145,71 @@ fold_file (char const *filename, size_t width)
|
||||
while ((c = getc (istream)) != EOF)
|
||||
{
|
||||
if (offset_out + 1 >= allocated_out)
|
||||
line_out = X2REALLOC (line_out, &allocated_out);
|
||||
line_out = X2REALLOC (line_out, &allocated_out);
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
line_out[offset_out++] = c;
|
||||
fwrite (line_out, sizeof (char), offset_out, stdout);
|
||||
column = offset_out = 0;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
line_out[offset_out++] = c;
|
||||
fwrite (line_out, sizeof (char), offset_out, stdout);
|
||||
column = offset_out = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
rescan:
|
||||
column = adjust_column (column, c);
|
||||
|
||||
if (column > width)
|
||||
{
|
||||
/* This character would make the line too long.
|
||||
Print the line plus a newline, and make this character
|
||||
start the next line. */
|
||||
if (break_spaces)
|
||||
{
|
||||
bool found_blank = false;
|
||||
size_t logical_end = offset_out;
|
||||
{
|
||||
/* This character would make the line too long.
|
||||
Print the line plus a newline, and make this character
|
||||
start the next line. */
|
||||
if (break_spaces)
|
||||
{
|
||||
bool found_blank = false;
|
||||
size_t logical_end = offset_out;
|
||||
|
||||
/* Look for the last blank. */
|
||||
while (logical_end)
|
||||
{
|
||||
--logical_end;
|
||||
if (isblank (to_uchar (line_out[logical_end])))
|
||||
{
|
||||
found_blank = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Look for the last blank. */
|
||||
while (logical_end)
|
||||
{
|
||||
--logical_end;
|
||||
if (isblank (to_uchar (line_out[logical_end])))
|
||||
{
|
||||
found_blank = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_blank)
|
||||
{
|
||||
size_t i;
|
||||
if (found_blank)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Found a blank. Don't output the part after it. */
|
||||
logical_end++;
|
||||
fwrite (line_out, sizeof (char), (size_t) logical_end,
|
||||
stdout);
|
||||
putchar ('\n');
|
||||
/* Move the remainder to the beginning of the next line.
|
||||
The areas being copied here might overlap. */
|
||||
memmove (line_out, line_out + logical_end,
|
||||
offset_out - logical_end);
|
||||
offset_out -= logical_end;
|
||||
for (column = i = 0; i < offset_out; i++)
|
||||
column = adjust_column (column, line_out[i]);
|
||||
goto rescan;
|
||||
}
|
||||
}
|
||||
/* Found a blank. Don't output the part after it. */
|
||||
logical_end++;
|
||||
fwrite (line_out, sizeof (char), (size_t) logical_end,
|
||||
stdout);
|
||||
putchar ('\n');
|
||||
/* Move the remainder to the beginning of the next line.
|
||||
The areas being copied here might overlap. */
|
||||
memmove (line_out, line_out + logical_end,
|
||||
offset_out - logical_end);
|
||||
offset_out -= logical_end;
|
||||
for (column = i = 0; i < offset_out; i++)
|
||||
column = adjust_column (column, line_out[i]);
|
||||
goto rescan;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset_out == 0)
|
||||
{
|
||||
line_out[offset_out++] = c;
|
||||
continue;
|
||||
}
|
||||
if (offset_out == 0)
|
||||
{
|
||||
line_out[offset_out++] = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
line_out[offset_out++] = '\n';
|
||||
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
column = offset_out = 0;
|
||||
goto rescan;
|
||||
}
|
||||
line_out[offset_out++] = '\n';
|
||||
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
column = offset_out = 0;
|
||||
goto rescan;
|
||||
}
|
||||
|
||||
line_out[offset_out++] = c;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ fold_file (char const *filename, size_t width)
|
||||
{
|
||||
error (0, saved_errno, "%s", filename);
|
||||
if (!STREQ (filename, "-"))
|
||||
fclose (istream);
|
||||
fclose (istream);
|
||||
return false;
|
||||
}
|
||||
if (!STREQ (filename, "-") && fclose (istream) == EOF)
|
||||
@@ -258,44 +258,44 @@ main (int argc, char **argv)
|
||||
char optargbuf[2];
|
||||
|
||||
switch (optc)
|
||||
{
|
||||
case 'b': /* Count bytes rather than columns. */
|
||||
count_bytes = true;
|
||||
break;
|
||||
{
|
||||
case 'b': /* Count bytes rather than columns. */
|
||||
count_bytes = true;
|
||||
break;
|
||||
|
||||
case 's': /* Break at word boundaries. */
|
||||
break_spaces = true;
|
||||
break;
|
||||
case 's': /* Break at word boundaries. */
|
||||
break_spaces = true;
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (optarg)
|
||||
optarg--;
|
||||
else
|
||||
{
|
||||
optargbuf[0] = optc;
|
||||
optargbuf[1] = '\0';
|
||||
optarg = optargbuf;
|
||||
}
|
||||
/* Fall through. */
|
||||
case 'w': /* Line width. */
|
||||
{
|
||||
unsigned long int tmp_ulong;
|
||||
if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK
|
||||
&& 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid number of columns: %s"), quote (optarg));
|
||||
width = tmp_ulong;
|
||||
}
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (optarg)
|
||||
optarg--;
|
||||
else
|
||||
{
|
||||
optargbuf[0] = optc;
|
||||
optargbuf[1] = '\0';
|
||||
optarg = optargbuf;
|
||||
}
|
||||
/* Fall through. */
|
||||
case 'w': /* Line width. */
|
||||
{
|
||||
unsigned long int tmp_ulong;
|
||||
if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK
|
||||
&& 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid number of columns: %s"), quote (optarg));
|
||||
width = tmp_ulong;
|
||||
}
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc == optind)
|
||||
@@ -304,7 +304,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
ok = true;
|
||||
for (i = optind; i < argc; i++)
|
||||
ok &= fold_file (argv[i], width);
|
||||
ok &= fold_file (argv[i], width);
|
||||
}
|
||||
|
||||
if (have_read_stdin && fclose (stdin) == EOF)
|
||||
|
||||
@@ -73,7 +73,7 @@ Output platform dependent limits in a format useful for shell scripts.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -172,9 +172,3 @@ main (int argc, char **argv)
|
||||
print_int (INTMAX);
|
||||
print_int (UINTMAX);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -113,9 +113,3 @@ print_group (gid_t gid, bool use_name)
|
||||
printf ("%s", grp->gr_name);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -58,7 +58,7 @@ the current process (which may differ if the groups database has changed).\n"),
|
||||
stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -124,9 +124,3 @@ main (int argc, char **argv)
|
||||
|
||||
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
678
src/head.c
678
src/head.c
@@ -102,13 +102,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [FILE]...\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Print the first 10 lines of each FILE to standard output.\n\
|
||||
With more than one FILE, precede each with a header giving the file name.\n\
|
||||
@@ -138,7 +138,7 @@ K may have a multiplier suffix:\n\
|
||||
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
|
||||
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -186,15 +186,15 @@ copy_fd (int src_fd, FILE *o_stream, uintmax_t n_bytes)
|
||||
size_t n_to_read = MIN (buf_size, n_bytes);
|
||||
size_t n_read = safe_read (src_fd, buf, n_to_read);
|
||||
if (n_read == SAFE_READ_ERROR)
|
||||
return COPY_FD_READ_ERROR;
|
||||
return COPY_FD_READ_ERROR;
|
||||
|
||||
n_bytes -= n_read;
|
||||
|
||||
if (n_read == 0 && n_bytes != 0)
|
||||
return COPY_FD_UNEXPECTED_EOF;
|
||||
return COPY_FD_UNEXPECTED_EOF;
|
||||
|
||||
if (fwrite (buf, 1, n_read, o_stream) < n_read)
|
||||
return COPY_FD_WRITE_ERROR;
|
||||
return COPY_FD_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return COPY_FD_OK;
|
||||
@@ -229,7 +229,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
|
||||
{
|
||||
char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
|
||||
umaxtostr (n_elide_0, umax_buf));
|
||||
umaxtostr (n_elide_0, umax_buf));
|
||||
}
|
||||
|
||||
/* Two cases to consider...
|
||||
@@ -255,54 +255,54 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
|
||||
b[1] = b[0] + n_to_read;
|
||||
|
||||
for (i = false; ! eof ; i = !i)
|
||||
{
|
||||
size_t n_read = full_read (fd, b[i], n_to_read);
|
||||
size_t delta = 0;
|
||||
if (n_read < n_to_read)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
{
|
||||
size_t n_read = full_read (fd, b[i], n_to_read);
|
||||
size_t delta = 0;
|
||||
if (n_read < n_to_read)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* reached EOF */
|
||||
if (n_read <= n_elide)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
/* The input is no larger than the number of bytes
|
||||
to elide. So there's nothing to output, and
|
||||
we're done. */
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = n_elide - n_read;
|
||||
}
|
||||
}
|
||||
eof = true;
|
||||
}
|
||||
/* reached EOF */
|
||||
if (n_read <= n_elide)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
/* The input is no larger than the number of bytes
|
||||
to elide. So there's nothing to output, and
|
||||
we're done. */
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = n_elide - n_read;
|
||||
}
|
||||
}
|
||||
eof = true;
|
||||
}
|
||||
|
||||
/* Output any (but maybe just part of the) elided data from
|
||||
the previous round. */
|
||||
if ( ! first)
|
||||
{
|
||||
/* Don't bother checking for errors here.
|
||||
If there's a failure, the test of the following
|
||||
fwrite or in close_stdout will catch it. */
|
||||
fwrite (b[!i] + READ_BUFSIZE, 1, n_elide - delta, stdout);
|
||||
}
|
||||
first = false;
|
||||
/* Output any (but maybe just part of the) elided data from
|
||||
the previous round. */
|
||||
if ( ! first)
|
||||
{
|
||||
/* Don't bother checking for errors here.
|
||||
If there's a failure, the test of the following
|
||||
fwrite or in close_stdout will catch it. */
|
||||
fwrite (b[!i] + READ_BUFSIZE, 1, n_elide - delta, stdout);
|
||||
}
|
||||
first = false;
|
||||
|
||||
if (n_elide < n_read
|
||||
&& fwrite (b[i], 1, n_read - n_elide, stdout) < n_read - n_elide)
|
||||
{
|
||||
error (0, errno, _("write error"));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n_elide < n_read
|
||||
&& fwrite (b[i], 1, n_read - n_elide, stdout) < n_read - n_elide)
|
||||
{
|
||||
error (0, errno, _("write error"));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free (b[0]);
|
||||
return ok;
|
||||
@@ -310,7 +310,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
|
||||
else
|
||||
{
|
||||
/* Read blocks of size READ_BUFSIZE, until we've read at least n_elide
|
||||
bytes. Then, for each new buffer we read, also write an old one. */
|
||||
bytes. Then, for each new buffer we read, also write an old one. */
|
||||
|
||||
bool ok = true;
|
||||
bool eof = false;
|
||||
@@ -326,74 +326,74 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
|
||||
|
||||
buffered_enough = false;
|
||||
for (i = 0, i_next = 1; !eof; i = i_next, i_next = (i_next + 1) % n_bufs)
|
||||
{
|
||||
if (b[i] == NULL)
|
||||
b[i] = xmalloc (READ_BUFSIZE);
|
||||
n_read = full_read (fd, b[i], READ_BUFSIZE);
|
||||
if (n_read < READ_BUFSIZE)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
ok = false;
|
||||
goto free_mem;
|
||||
}
|
||||
eof = true;
|
||||
}
|
||||
{
|
||||
if (b[i] == NULL)
|
||||
b[i] = xmalloc (READ_BUFSIZE);
|
||||
n_read = full_read (fd, b[i], READ_BUFSIZE);
|
||||
if (n_read < READ_BUFSIZE)
|
||||
{
|
||||
if (errno != 0)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
ok = false;
|
||||
goto free_mem;
|
||||
}
|
||||
eof = true;
|
||||
}
|
||||
|
||||
if (i + 1 == n_bufs)
|
||||
buffered_enough = true;
|
||||
if (i + 1 == n_bufs)
|
||||
buffered_enough = true;
|
||||
|
||||
if (buffered_enough)
|
||||
{
|
||||
if (fwrite (b[i_next], 1, n_read, stdout) < n_read)
|
||||
{
|
||||
error (0, errno, _("write error"));
|
||||
ok = false;
|
||||
goto free_mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buffered_enough)
|
||||
{
|
||||
if (fwrite (b[i_next], 1, n_read, stdout) < n_read)
|
||||
{
|
||||
error (0, errno, _("write error"));
|
||||
ok = false;
|
||||
goto free_mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Output any remainder: rem bytes from b[i] + n_read. */
|
||||
if (rem)
|
||||
{
|
||||
if (buffered_enough)
|
||||
{
|
||||
size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
|
||||
if (rem < n_bytes_left_in_b_i)
|
||||
{
|
||||
fwrite (b[i] + n_read, 1, rem, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite (b[i] + n_read, 1, n_bytes_left_in_b_i, stdout);
|
||||
fwrite (b[i_next], 1, rem - n_bytes_left_in_b_i, stdout);
|
||||
}
|
||||
}
|
||||
else if (i + 1 == n_bufs)
|
||||
{
|
||||
/* This happens when n_elide < file_size < n_elide_round.
|
||||
{
|
||||
if (buffered_enough)
|
||||
{
|
||||
size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
|
||||
if (rem < n_bytes_left_in_b_i)
|
||||
{
|
||||
fwrite (b[i] + n_read, 1, rem, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite (b[i] + n_read, 1, n_bytes_left_in_b_i, stdout);
|
||||
fwrite (b[i_next], 1, rem - n_bytes_left_in_b_i, stdout);
|
||||
}
|
||||
}
|
||||
else if (i + 1 == n_bufs)
|
||||
{
|
||||
/* This happens when n_elide < file_size < n_elide_round.
|
||||
|
||||
|READ_BUF.|
|
||||
| | rem |
|
||||
|---------!---------!---------!---------|
|
||||
|---- n_elide ---------|
|
||||
| | x |
|
||||
| |y |
|
||||
|---- file size -----------|
|
||||
| |n_read|
|
||||
|---- n_elide_round ----------|
|
||||
*/
|
||||
size_t y = READ_BUFSIZE - rem;
|
||||
size_t x = n_read - y;
|
||||
fwrite (b[i_next], 1, x, stdout);
|
||||
}
|
||||
}
|
||||
|READ_BUF.|
|
||||
| | rem |
|
||||
|---------!---------!---------!---------|
|
||||
|---- n_elide ---------|
|
||||
| | x |
|
||||
| |y |
|
||||
|---- file size -----------|
|
||||
| |n_read|
|
||||
|---- n_elide_round ----------|
|
||||
*/
|
||||
size_t y = READ_BUFSIZE - rem;
|
||||
size_t x = n_read - y;
|
||||
fwrite (b[i_next], 1, x, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
free_mem:;
|
||||
for (i = 0; i < n_bufs; i++)
|
||||
free (b[i]);
|
||||
free (b[i]);
|
||||
free (b);
|
||||
|
||||
return ok;
|
||||
@@ -424,31 +424,31 @@ elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide)
|
||||
enum Copy_fd_status err;
|
||||
|
||||
if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) == -1
|
||||
|| (end_pos = lseek (fd, (off_t) 0, SEEK_END)) == -1)
|
||||
{
|
||||
error (0, errno, _("cannot lseek %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
|| (end_pos = lseek (fd, (off_t) 0, SEEK_END)) == -1)
|
||||
{
|
||||
error (0, errno, _("cannot lseek %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Be careful here. The current position may actually be
|
||||
beyond the end of the file. */
|
||||
beyond the end of the file. */
|
||||
bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
|
||||
|
||||
if (bytes_remaining <= n_elide)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
/* Seek back to `current' position, then copy the required
|
||||
number of bytes from fd. */
|
||||
number of bytes from fd. */
|
||||
if (lseek (fd, (off_t) 0, current_pos) == -1)
|
||||
{
|
||||
error (0, errno, _("%s: cannot lseek back to original position"),
|
||||
quote (filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("%s: cannot lseek back to original position"),
|
||||
quote (filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = copy_fd (fd, stdout, bytes_remaining - n_elide);
|
||||
if (err == COPY_FD_OK)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
diagnose_copy_fd_failure (err, filename);
|
||||
return false;
|
||||
@@ -488,20 +488,20 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
|
||||
{
|
||||
n_read = safe_read (fd, tmp->buffer, BUFSIZ);
|
||||
if (n_read == 0 || n_read == SAFE_READ_ERROR)
|
||||
break;
|
||||
break;
|
||||
tmp->nbytes = n_read;
|
||||
tmp->nlines = 0;
|
||||
tmp->next = NULL;
|
||||
|
||||
/* Count the number of newlines just read. */
|
||||
{
|
||||
char const *buffer_end = tmp->buffer + n_read;
|
||||
char const *p = tmp->buffer;
|
||||
while ((p = memchr (p, '\n', buffer_end - p)))
|
||||
{
|
||||
++p;
|
||||
++tmp->nlines;
|
||||
}
|
||||
char const *buffer_end = tmp->buffer + n_read;
|
||||
char const *p = tmp->buffer;
|
||||
while ((p = memchr (p, '\n', buffer_end - p)))
|
||||
{
|
||||
++p;
|
||||
++tmp->nlines;
|
||||
}
|
||||
}
|
||||
total_lines += tmp->nlines;
|
||||
|
||||
@@ -509,29 +509,29 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
|
||||
one to it. This is because when reading from a pipe, `n_read' can
|
||||
often be very small. */
|
||||
if (tmp->nbytes + last->nbytes < BUFSIZ)
|
||||
{
|
||||
memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
|
||||
last->nbytes += tmp->nbytes;
|
||||
last->nlines += tmp->nlines;
|
||||
}
|
||||
{
|
||||
memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
|
||||
last->nbytes += tmp->nbytes;
|
||||
last->nlines += tmp->nlines;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there's not enough room, link the new buffer onto the end of
|
||||
the list, then either free up the oldest buffer for the next
|
||||
read if that would leave enough lines, or else malloc a new one.
|
||||
Some compaction mechanism is possible but probably not
|
||||
worthwhile. */
|
||||
last = last->next = tmp;
|
||||
if (n_elide < total_lines - first->nlines)
|
||||
{
|
||||
fwrite (first->buffer, 1, first->nbytes, stdout);
|
||||
tmp = first;
|
||||
total_lines -= first->nlines;
|
||||
first = first->next;
|
||||
}
|
||||
else
|
||||
tmp = xmalloc (sizeof (LBUFFER));
|
||||
}
|
||||
{
|
||||
/* If there's not enough room, link the new buffer onto the end of
|
||||
the list, then either free up the oldest buffer for the next
|
||||
read if that would leave enough lines, or else malloc a new one.
|
||||
Some compaction mechanism is possible but probably not
|
||||
worthwhile. */
|
||||
last = last->next = tmp;
|
||||
if (n_elide < total_lines - first->nlines)
|
||||
{
|
||||
fwrite (first->buffer, 1, first->nbytes, stdout);
|
||||
tmp = first;
|
||||
total_lines -= first->nlines;
|
||||
first = first->next;
|
||||
}
|
||||
else
|
||||
tmp = xmalloc (sizeof (LBUFFER));
|
||||
}
|
||||
}
|
||||
|
||||
free (tmp);
|
||||
@@ -564,11 +564,11 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
|
||||
char const *buffer_end = tmp->buffer + tmp->nbytes;
|
||||
char const *p = tmp->buffer;
|
||||
while (n && (p = memchr (p, '\n', buffer_end - p)))
|
||||
{
|
||||
++p;
|
||||
++tmp->nlines;
|
||||
--n;
|
||||
}
|
||||
{
|
||||
++p;
|
||||
++tmp->nlines;
|
||||
--n;
|
||||
}
|
||||
fwrite (tmp->buffer, 1, p - tmp->buffer, stdout);
|
||||
}
|
||||
|
||||
@@ -595,8 +595,8 @@ free_lbuffers:
|
||||
in a less efficient implementation or a messy interface. */
|
||||
static bool
|
||||
elide_tail_lines_seekable (const char *pretty_filename, int fd,
|
||||
uintmax_t n_lines,
|
||||
off_t start_pos, off_t end_pos)
|
||||
uintmax_t n_lines,
|
||||
off_t start_pos, off_t end_pos)
|
||||
{
|
||||
char buffer[BUFSIZ];
|
||||
size_t bytes_read;
|
||||
@@ -614,7 +614,7 @@ elide_tail_lines_seekable (const char *pretty_filename, int fd,
|
||||
{
|
||||
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
|
||||
error (0, errno, _("%s: cannot seek to offset %s"),
|
||||
pretty_filename, offtostr (pos, offset_buf));
|
||||
pretty_filename, offtostr (pos, offset_buf));
|
||||
return false;
|
||||
}
|
||||
bytes_read = safe_read (fd, buffer, bytes_read);
|
||||
@@ -634,72 +634,72 @@ elide_tail_lines_seekable (const char *pretty_filename, int fd,
|
||||
|
||||
size_t n = bytes_read;
|
||||
while (n)
|
||||
{
|
||||
char const *nl;
|
||||
nl = memrchr (buffer, '\n', n);
|
||||
if (nl == NULL)
|
||||
break;
|
||||
n = nl - buffer;
|
||||
if (n_lines-- == 0)
|
||||
{
|
||||
/* Found it. */
|
||||
/* If necessary, restore the file pointer and copy
|
||||
input to output up to position, POS. */
|
||||
if (start_pos < pos)
|
||||
{
|
||||
enum Copy_fd_status err;
|
||||
if (lseek (fd, start_pos, SEEK_SET) < 0)
|
||||
{
|
||||
/* Failed to reposition file pointer. */
|
||||
error (0, errno,
|
||||
"%s: unable to restore file pointer to initial offset",
|
||||
quote (pretty_filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
char const *nl;
|
||||
nl = memrchr (buffer, '\n', n);
|
||||
if (nl == NULL)
|
||||
break;
|
||||
n = nl - buffer;
|
||||
if (n_lines-- == 0)
|
||||
{
|
||||
/* Found it. */
|
||||
/* If necessary, restore the file pointer and copy
|
||||
input to output up to position, POS. */
|
||||
if (start_pos < pos)
|
||||
{
|
||||
enum Copy_fd_status err;
|
||||
if (lseek (fd, start_pos, SEEK_SET) < 0)
|
||||
{
|
||||
/* Failed to reposition file pointer. */
|
||||
error (0, errno,
|
||||
"%s: unable to restore file pointer to initial offset",
|
||||
quote (pretty_filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
err = copy_fd (fd, stdout, pos - start_pos);
|
||||
if (err != COPY_FD_OK)
|
||||
{
|
||||
diagnose_copy_fd_failure (err, pretty_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
err = copy_fd (fd, stdout, pos - start_pos);
|
||||
if (err != COPY_FD_OK)
|
||||
{
|
||||
diagnose_copy_fd_failure (err, pretty_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the initial portion of the buffer
|
||||
in which we found the desired newline byte.
|
||||
Don't bother testing for failure for such a small amount.
|
||||
Any failure will be detected upon close. */
|
||||
fwrite (buffer, 1, n + 1, stdout);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* Output the initial portion of the buffer
|
||||
in which we found the desired newline byte.
|
||||
Don't bother testing for failure for such a small amount.
|
||||
Any failure will be detected upon close. */
|
||||
fwrite (buffer, 1, n + 1, stdout);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough newlines in that bufferfull. */
|
||||
if (pos == start_pos)
|
||||
{
|
||||
/* Not enough lines in the file. */
|
||||
return true;
|
||||
}
|
||||
{
|
||||
/* Not enough lines in the file. */
|
||||
return true;
|
||||
}
|
||||
pos -= BUFSIZ;
|
||||
if (lseek (fd, pos, SEEK_SET) < 0)
|
||||
{
|
||||
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
|
||||
error (0, errno, _("%s: cannot seek to offset %s"),
|
||||
pretty_filename, offtostr (pos, offset_buf));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
|
||||
error (0, errno, _("%s: cannot seek to offset %s"),
|
||||
pretty_filename, offtostr (pos, offset_buf));
|
||||
return false;
|
||||
}
|
||||
|
||||
bytes_read = safe_read (fd, buffer, BUFSIZ);
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (pretty_filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (pretty_filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* FIXME: is this dead code?
|
||||
Consider the test, pos == start_pos, above. */
|
||||
Consider the test, pos == start_pos, above. */
|
||||
if (bytes_read == 0)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,24 +713,24 @@ elide_tail_lines_file (const char *filename, int fd, uintmax_t n_elide)
|
||||
if (!presume_input_pipe)
|
||||
{
|
||||
/* Find the offset, OFF, of the Nth newline from the end,
|
||||
but not counting the last byte of the file.
|
||||
If found, write from current position to OFF, inclusive.
|
||||
Otherwise, just return true. */
|
||||
but not counting the last byte of the file.
|
||||
If found, write from current position to OFF, inclusive.
|
||||
Otherwise, just return true. */
|
||||
|
||||
off_t start_pos = lseek (fd, (off_t) 0, SEEK_CUR);
|
||||
off_t end_pos = lseek (fd, (off_t) 0, SEEK_END);
|
||||
if (0 <= start_pos && start_pos < end_pos)
|
||||
{
|
||||
/* If the file is empty, we're done. */
|
||||
if (end_pos == 0)
|
||||
return true;
|
||||
{
|
||||
/* If the file is empty, we're done. */
|
||||
if (end_pos == 0)
|
||||
return true;
|
||||
|
||||
return elide_tail_lines_seekable (filename, fd, n_elide,
|
||||
start_pos, end_pos);
|
||||
}
|
||||
return elide_tail_lines_seekable (filename, fd, n_elide,
|
||||
start_pos, end_pos);
|
||||
}
|
||||
|
||||
/* lseek failed or the end offset precedes start.
|
||||
Fall through. */
|
||||
Fall through. */
|
||||
}
|
||||
|
||||
return elide_tail_lines_pipe (filename, fd, n_elide);
|
||||
@@ -746,17 +746,17 @@ head_bytes (const char *filename, int fd, uintmax_t bytes_to_write)
|
||||
{
|
||||
size_t bytes_read;
|
||||
if (bytes_to_write < bytes_to_read)
|
||||
bytes_to_read = bytes_to_write;
|
||||
bytes_to_read = bytes_to_write;
|
||||
bytes_read = safe_read (fd, buffer, bytes_to_read);
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
break;
|
||||
if (fwrite (buffer, 1, bytes_read, stdout) < bytes_read)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
bytes_to_write -= bytes_read;
|
||||
}
|
||||
return true;
|
||||
@@ -773,31 +773,31 @@ head_lines (const char *filename, int fd, uintmax_t lines_to_write)
|
||||
size_t bytes_to_write = 0;
|
||||
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("error reading %s"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
break;
|
||||
while (bytes_to_write < bytes_read)
|
||||
if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
|
||||
{
|
||||
off_t n_bytes_past_EOL = bytes_read - bytes_to_write;
|
||||
/* If we have read more data than that on the specified number
|
||||
of lines, try to seek back to the position we would have
|
||||
gotten to had we been reading one byte at a time. */
|
||||
if (lseek (fd, -n_bytes_past_EOL, SEEK_CUR) < 0)
|
||||
{
|
||||
int e = errno;
|
||||
struct stat st;
|
||||
if (fstat (fd, &st) != 0 || S_ISREG (st.st_mode))
|
||||
error (0, e, _("cannot reposition file pointer for %s"),
|
||||
quote (filename));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
|
||||
{
|
||||
off_t n_bytes_past_EOL = bytes_read - bytes_to_write;
|
||||
/* If we have read more data than that on the specified number
|
||||
of lines, try to seek back to the position we would have
|
||||
gotten to had we been reading one byte at a time. */
|
||||
if (lseek (fd, -n_bytes_past_EOL, SEEK_CUR) < 0)
|
||||
{
|
||||
int e = errno;
|
||||
struct stat st;
|
||||
if (fstat (fd, &st) != 0 || S_ISREG (st.st_mode))
|
||||
error (0, e, _("cannot reposition file pointer for %s"),
|
||||
quote (filename));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fwrite (buffer, 1, bytes_to_write, stdout) < bytes_to_write)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -812,13 +812,13 @@ head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
|
||||
if (elide_from_end)
|
||||
{
|
||||
if (count_lines)
|
||||
{
|
||||
return elide_tail_lines_file (filename, fd, n_units);
|
||||
}
|
||||
{
|
||||
return elide_tail_lines_file (filename, fd, n_units);
|
||||
}
|
||||
else
|
||||
{
|
||||
return elide_tail_bytes_file (filename, fd, n_units);
|
||||
}
|
||||
{
|
||||
return elide_tail_bytes_file (filename, fd, n_units);
|
||||
}
|
||||
}
|
||||
if (count_lines)
|
||||
return head_lines (filename, fd, n_units);
|
||||
@@ -828,7 +828,7 @@ head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
|
||||
|
||||
static bool
|
||||
head_file (const char *filename, uintmax_t n_units, bool count_lines,
|
||||
bool elide_from_end)
|
||||
bool elide_from_end)
|
||||
{
|
||||
int fd;
|
||||
bool ok;
|
||||
@@ -840,16 +840,16 @@ head_file (const char *filename, uintmax_t n_units, bool count_lines,
|
||||
fd = STDIN_FILENO;
|
||||
filename = _("standard input");
|
||||
if (O_BINARY && ! isatty (STDIN_FILENO))
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = open (filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
{
|
||||
error (0, errno, _("cannot open %s for reading"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot open %s for reading"), quote (filename));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ok = head (filename, fd, n_units, count_lines, elide_from_end);
|
||||
@@ -878,16 +878,16 @@ string_to_integer (bool count_lines, const char *n_string)
|
||||
if (s_err == LONGINT_OVERFLOW)
|
||||
{
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("%s: %s is so large that it is not representable"), n_string,
|
||||
count_lines ? _("number of lines") : _("number of bytes"));
|
||||
_("%s: %s is so large that it is not representable"), n_string,
|
||||
count_lines ? _("number of lines") : _("number of bytes"));
|
||||
}
|
||||
|
||||
if (s_err != LONGINT_OK)
|
||||
{
|
||||
error (EXIT_FAILURE, 0, "%s: %s", n_string,
|
||||
(count_lines
|
||||
? _("invalid number of lines")
|
||||
: _("invalid number of bytes")));
|
||||
(count_lines
|
||||
? _("invalid number of lines")
|
||||
: _("invalid number of bytes")));
|
||||
}
|
||||
|
||||
return n;
|
||||
@@ -937,7 +937,7 @@ main (int argc, char **argv)
|
||||
char multiplier_char = 0;
|
||||
|
||||
/* Old option syntax; a dash, one or more digits, and one or
|
||||
more option letters. Move past the number. */
|
||||
more option letters. Move past the number. */
|
||||
do ++a;
|
||||
while (ISDIGIT (*a));
|
||||
|
||||
@@ -946,44 +946,44 @@ main (int argc, char **argv)
|
||||
|
||||
/* Parse any appended option letters. */
|
||||
for (; *a; a++)
|
||||
{
|
||||
switch (*a)
|
||||
{
|
||||
case 'c':
|
||||
count_lines = false;
|
||||
multiplier_char = 0;
|
||||
break;
|
||||
{
|
||||
switch (*a)
|
||||
{
|
||||
case 'c':
|
||||
count_lines = false;
|
||||
multiplier_char = 0;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
case 'k':
|
||||
case 'm':
|
||||
count_lines = false;
|
||||
multiplier_char = *a;
|
||||
break;
|
||||
case 'b':
|
||||
case 'k':
|
||||
case 'm':
|
||||
count_lines = false;
|
||||
multiplier_char = *a;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
count_lines = true;
|
||||
break;
|
||||
case 'l':
|
||||
count_lines = true;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
header_mode = never;
|
||||
break;
|
||||
case 'q':
|
||||
header_mode = never;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
header_mode = always;
|
||||
break;
|
||||
case 'v':
|
||||
header_mode = always;
|
||||
break;
|
||||
|
||||
default:
|
||||
error (0, 0, _("invalid trailing option -- %c"), *a);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
default:
|
||||
error (0, 0, _("invalid trailing option -- %c"), *a);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the multiplier character (if any) onto the end of
|
||||
the digit string. Then add NUL byte if necessary. */
|
||||
the digit string. Then add NUL byte if necessary. */
|
||||
*end_n_string = multiplier_char;
|
||||
if (multiplier_char)
|
||||
*(++end_n_string) = 0;
|
||||
*(++end_n_string) = 0;
|
||||
|
||||
n_units = string_to_integer (count_lines, n_string);
|
||||
|
||||
@@ -994,47 +994,47 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
while ((c = getopt_long (argc, argv, "c:n:qv0123456789", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case PRESUME_INPUT_PIPE_OPTION:
|
||||
presume_input_pipe = true;
|
||||
break;
|
||||
{
|
||||
case PRESUME_INPUT_PIPE_OPTION:
|
||||
presume_input_pipe = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
count_lines = false;
|
||||
elide_from_end = (*optarg == '-');
|
||||
if (elide_from_end)
|
||||
++optarg;
|
||||
n_units = string_to_integer (count_lines, optarg);
|
||||
break;
|
||||
case 'c':
|
||||
count_lines = false;
|
||||
elide_from_end = (*optarg == '-');
|
||||
if (elide_from_end)
|
||||
++optarg;
|
||||
n_units = string_to_integer (count_lines, optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
count_lines = true;
|
||||
elide_from_end = (*optarg == '-');
|
||||
if (elide_from_end)
|
||||
++optarg;
|
||||
n_units = string_to_integer (count_lines, optarg);
|
||||
break;
|
||||
case 'n':
|
||||
count_lines = true;
|
||||
elide_from_end = (*optarg == '-');
|
||||
if (elide_from_end)
|
||||
++optarg;
|
||||
n_units = string_to_integer (count_lines, optarg);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
header_mode = never;
|
||||
break;
|
||||
case 'q':
|
||||
header_mode = never;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
header_mode = always;
|
||||
break;
|
||||
case 'v':
|
||||
header_mode = always;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
if (ISDIGIT (c))
|
||||
error (0, 0, _("invalid trailing option -- %c"), c);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
if (ISDIGIT (c))
|
||||
error (0, 0, _("invalid trailing option -- %c"), c);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (header_mode == always
|
||||
@@ -1045,12 +1045,12 @@ main (int argc, char **argv)
|
||||
{
|
||||
char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
|
||||
error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
|
||||
umaxtostr (n_units, umax_buf));
|
||||
umaxtostr (n_units, umax_buf));
|
||||
}
|
||||
|
||||
file_list = (optind < argc
|
||||
? (char const *const *) &argv[optind]
|
||||
: default_file_list);
|
||||
? (char const *const *) &argv[optind]
|
||||
: default_file_list);
|
||||
|
||||
if (O_BINARY && ! isatty (STDOUT_FILENO))
|
||||
xfreopen (NULL, "wb", stdout);
|
||||
|
||||
@@ -38,7 +38,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -48,7 +48,7 @@ Print the numeric identifier (in hexadecimal) for the current host.\n\
|
||||
"), program_name);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -63,7 +63,7 @@ Print or set the hostname of the current system.\n\
|
||||
program_name, program_name);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
@@ -92,10 +92,10 @@ main (int argc, char **argv)
|
||||
/* Set hostname to operand. */
|
||||
char const *name = argv[optind];
|
||||
if (sethostname (name, strlen (name)) != 0)
|
||||
error (EXIT_FAILURE, errno, _("cannot set name to %s"), quote (name));
|
||||
error (EXIT_FAILURE, errno, _("cannot set name to %s"), quote (name));
|
||||
#else
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot set hostname; this system lacks the functionality"));
|
||||
_("cannot set hostname; this system lacks the functionality"));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
hostname = xgethostname ();
|
||||
if (hostname == NULL)
|
||||
error (EXIT_FAILURE, errno, _("cannot determine hostname"));
|
||||
error (EXIT_FAILURE, errno, _("cannot determine hostname"));
|
||||
printf ("%s\n", hostname);
|
||||
}
|
||||
|
||||
|
||||
127
src/id.c
127
src/id.c
@@ -76,7 +76,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... [USERNAME]\n"), program_name);
|
||||
@@ -98,7 +98,7 @@ or (when USERNAME omitted) for the current user.\n\
|
||||
\n\
|
||||
Without any OPTION, print some useful set of identified information.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -129,39 +129,39 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'a':
|
||||
/* Ignore -a, for compatibility with SVR4. */
|
||||
break;
|
||||
{
|
||||
case 'a':
|
||||
/* Ignore -a, for compatibility with SVR4. */
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
/* politely decline if we're not on a selinux-enabled kernel. */
|
||||
if (!selinux_enabled)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("--context (-Z) works only on an SELinux-enabled kernel"));
|
||||
/* politely decline if we're not on a selinux-enabled kernel. */
|
||||
if (!selinux_enabled)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("--context (-Z) works only on an SELinux-enabled kernel"));
|
||||
just_context = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
just_group = true;
|
||||
break;
|
||||
case 'n':
|
||||
use_name = true;
|
||||
break;
|
||||
case 'r':
|
||||
use_real = true;
|
||||
break;
|
||||
case 'u':
|
||||
just_user = true;
|
||||
break;
|
||||
case 'G':
|
||||
just_group_list = true;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
case 'g':
|
||||
just_group = true;
|
||||
break;
|
||||
case 'n':
|
||||
use_name = true;
|
||||
break;
|
||||
case 'r':
|
||||
use_real = true;
|
||||
break;
|
||||
case 'u':
|
||||
just_user = true;
|
||||
break;
|
||||
case 'G':
|
||||
just_group_list = true;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (1 < argc - optind)
|
||||
@@ -172,7 +172,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (argc - optind == 1 && just_context)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot print security context when user specified"));
|
||||
_("cannot print security context when user specified"));
|
||||
|
||||
/* If we are on a selinux-enabled kernel and no user is specified,
|
||||
get our context. Otherwise, leave the context variable alone -
|
||||
@@ -187,15 +187,15 @@ main (int argc, char **argv)
|
||||
if (just_user + just_group + just_group_list + just_context > 1)
|
||||
error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
|
||||
|
||||
if (just_user + just_group + just_group_list == 0 && (use_real | use_name))
|
||||
if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot print only names or real IDs in default format"));
|
||||
_("cannot print only names or real IDs in default format"));
|
||||
|
||||
if (argc - optind == 1)
|
||||
{
|
||||
struct passwd *pwd = getpwnam (argv[optind]);
|
||||
if (pwd == NULL)
|
||||
error (EXIT_FAILURE, 0, _("%s: No such user"), argv[optind]);
|
||||
error (EXIT_FAILURE, 0, _("%s: No such user"), argv[optind]);
|
||||
ruid = euid = pwd->pw_uid;
|
||||
rgid = egid = pwd->pw_gid;
|
||||
}
|
||||
@@ -214,12 +214,12 @@ main (int argc, char **argv)
|
||||
else if (just_group)
|
||||
{
|
||||
if (!print_group (use_real ? rgid : egid, use_name))
|
||||
ok = false;
|
||||
ok = false;
|
||||
}
|
||||
else if (just_group_list)
|
||||
{
|
||||
if (!print_group_list (argv[optind], ruid, rgid, egid, use_name))
|
||||
ok = false;
|
||||
ok = false;
|
||||
}
|
||||
else if (just_context)
|
||||
{
|
||||
@@ -245,11 +245,11 @@ print_user (uid_t uid)
|
||||
{
|
||||
pwd = getpwuid (uid);
|
||||
if (pwd == NULL)
|
||||
{
|
||||
error (0, 0, _("cannot find name for user ID %lu"),
|
||||
(unsigned long int) uid);
|
||||
ok = false;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("cannot find name for user ID %lu"),
|
||||
(unsigned long int) uid);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pwd == NULL)
|
||||
@@ -281,7 +281,7 @@ print_full_info (const char *username)
|
||||
printf (_(" euid=%lu"), (unsigned long int) euid);
|
||||
pwd = getpwuid (euid);
|
||||
if (pwd)
|
||||
printf ("(%s)", pwd->pw_name);
|
||||
printf ("(%s)", pwd->pw_name);
|
||||
}
|
||||
|
||||
if (egid != rgid)
|
||||
@@ -289,7 +289,7 @@ print_full_info (const char *username)
|
||||
printf (_(" egid=%lu"), (unsigned long int) egid);
|
||||
grp = getgrgid (egid);
|
||||
if (grp)
|
||||
printf ("(%s)", grp->gr_name);
|
||||
printf ("(%s)", grp->gr_name);
|
||||
}
|
||||
|
||||
#if HAVE_GETGROUPS
|
||||
@@ -298,36 +298,39 @@ print_full_info (const char *username)
|
||||
int i;
|
||||
|
||||
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
|
||||
&groups);
|
||||
&groups);
|
||||
if (n_groups < 0)
|
||||
{
|
||||
if (username)
|
||||
{
|
||||
error (0, errno, _("failed to get groups for user %s"),
|
||||
quote (username));
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, errno, _("failed to get groups for the current process"));
|
||||
}
|
||||
ok = false;
|
||||
return;
|
||||
if (username)
|
||||
{
|
||||
error (0, errno, _("failed to get groups for user %s"),
|
||||
quote (username));
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, errno, _("failed to get groups for the current process"));
|
||||
}
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (n_groups > 0)
|
||||
fputs (_(" groups="), stdout);
|
||||
for (i = 0; i < n_groups; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
putchar (',');
|
||||
printf ("%lu", (unsigned long int) groups[i]);
|
||||
grp = getgrgid (groups[i]);
|
||||
if (grp)
|
||||
printf ("(%s)", grp->gr_name);
|
||||
if (i > 0)
|
||||
putchar (',');
|
||||
printf ("%lu", (unsigned long int) groups[i]);
|
||||
grp = getgrgid (groups[i]);
|
||||
if (grp)
|
||||
printf ("(%s)", grp->gr_name);
|
||||
}
|
||||
free (groups);
|
||||
}
|
||||
#endif /* HAVE_GETGROUPS */
|
||||
if (context != NULL)
|
||||
|
||||
/* POSIX mandates the precise output format, and that it not include
|
||||
any context=... part, so skip that if POSIXLY_CORRECT is set. */
|
||||
if (context != NULL && ! getenv ("POSIXLY_CORRECT"))
|
||||
printf (_(" context=%s"), context);
|
||||
}
|
||||
|
||||
410
src/install.c
410
src/install.c
@@ -74,18 +74,18 @@ static bool use_default_selinux_context = true;
|
||||
static bool change_timestamps (struct stat const *from_sb, char const *to);
|
||||
static bool change_attributes (char const *name);
|
||||
static bool copy_file (const char *from, const char *to,
|
||||
const struct cp_options *x);
|
||||
const struct cp_options *x);
|
||||
static bool install_file_in_file_parents (char const *from, char *to,
|
||||
struct cp_options *x);
|
||||
struct cp_options *x);
|
||||
static bool install_file_in_dir (const char *from, const char *to_dir,
|
||||
const struct cp_options *x);
|
||||
const struct cp_options *x);
|
||||
static bool install_file_in_file (const char *from, const char *to,
|
||||
const struct cp_options *x);
|
||||
const struct cp_options *x);
|
||||
static void get_ids (void);
|
||||
static void strip (char const *name);
|
||||
static void announce_mkdir (char const *dir, void *options);
|
||||
static int make_ancestor (char const *dir, char const *component,
|
||||
void *options);
|
||||
void *options);
|
||||
void usage (int status);
|
||||
|
||||
/* The user name that will own the files, or NULL to make the owner
|
||||
@@ -195,7 +195,7 @@ extra_mode (mode_t input)
|
||||
/* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */
|
||||
static bool
|
||||
need_copy (const char *src_name, const char *dest_name,
|
||||
const struct cp_options *x)
|
||||
const struct cp_options *x)
|
||||
{
|
||||
struct stat src_sb, dest_sb;
|
||||
int src_fd, dest_fd;
|
||||
@@ -229,20 +229,20 @@ need_copy (const char *src_name, const char *dest_name,
|
||||
bool scontext_match;
|
||||
|
||||
if (getfilecon (src_name, &file_scontext) == -1)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (getfilecon (dest_name, &to_scontext) == -1)
|
||||
{
|
||||
freecon (file_scontext);
|
||||
return true;
|
||||
}
|
||||
{
|
||||
freecon (file_scontext);
|
||||
return true;
|
||||
}
|
||||
|
||||
scontext_match = STREQ (file_scontext, to_scontext);
|
||||
|
||||
freecon (file_scontext);
|
||||
freecon (to_scontext);
|
||||
if (!scontext_match)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* compare files content */
|
||||
@@ -269,7 +269,7 @@ cp_option_init (struct cp_options *x)
|
||||
{
|
||||
cp_options_default (x);
|
||||
x->copy_as_regular = true;
|
||||
x->reflink = false;
|
||||
x->reflink_mode = REFLINK_NEVER;
|
||||
x->dereference = DEREF_ALWAYS;
|
||||
x->unlink_dest_before_opening = true;
|
||||
x->unlink_dest_after_failed_open = false;
|
||||
@@ -328,37 +328,37 @@ setdefaultfilecon (char const *file)
|
||||
if (first_call && IS_ABSOLUTE_FILE_NAME (file))
|
||||
{
|
||||
/* Calling matchpathcon_init_prefix (NULL, "/first_component/")
|
||||
is an optimization to minimize the expense of the following
|
||||
matchpathcon call. Do it only once, just before the first
|
||||
matchpathcon call. We *could* call matchpathcon_fini after
|
||||
the final matchpathcon call, but that's not necessary, since
|
||||
by then we're about to exit, and besides, the buffers it
|
||||
would free are still reachable. */
|
||||
is an optimization to minimize the expense of the following
|
||||
matchpathcon call. Do it only once, just before the first
|
||||
matchpathcon call. We *could* call matchpathcon_fini after
|
||||
the final matchpathcon call, but that's not necessary, since
|
||||
by then we're about to exit, and besides, the buffers it
|
||||
would free are still reachable. */
|
||||
char const *p0;
|
||||
char const *p = file + 1;
|
||||
while (ISSLASH (*p))
|
||||
++p;
|
||||
++p;
|
||||
|
||||
/* Record final leading slash, for when FILE starts with two or more. */
|
||||
p0 = p - 1;
|
||||
|
||||
if (*p)
|
||||
{
|
||||
char *prefix;
|
||||
do
|
||||
{
|
||||
++p;
|
||||
}
|
||||
while (*p && !ISSLASH (*p));
|
||||
{
|
||||
char *prefix;
|
||||
do
|
||||
{
|
||||
++p;
|
||||
}
|
||||
while (*p && !ISSLASH (*p));
|
||||
|
||||
prefix = malloc (p - p0 + 2);
|
||||
if (prefix)
|
||||
{
|
||||
stpcpy (stpncpy (prefix, p0, p - p0), "/");
|
||||
matchpathcon_init_prefix (NULL, prefix);
|
||||
free (prefix);
|
||||
}
|
||||
}
|
||||
prefix = malloc (p - p0 + 2);
|
||||
if (prefix)
|
||||
{
|
||||
stpcpy (stpncpy (prefix, p0, p - p0), "/");
|
||||
matchpathcon_init_prefix (NULL, prefix);
|
||||
free (prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
first_call = false;
|
||||
|
||||
@@ -368,14 +368,14 @@ setdefaultfilecon (char const *file)
|
||||
STREQ (scontext, "<<none>>"))
|
||||
{
|
||||
if (scontext != NULL)
|
||||
freecon (scontext);
|
||||
freecon (scontext);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
|
||||
error (0, errno,
|
||||
_("warning: %s: failed to change context to %s"),
|
||||
quotearg_colon (file), scontext);
|
||||
_("warning: %s: failed to change context to %s"),
|
||||
quotearg_colon (file), scontext);
|
||||
|
||||
freecon (scontext);
|
||||
return;
|
||||
@@ -414,11 +414,11 @@ static int
|
||||
process_dir (char *dir, struct savewd *wd, void *options)
|
||||
{
|
||||
return (make_dir_parents (dir, wd,
|
||||
make_ancestor, options,
|
||||
dir_mode, announce_mkdir,
|
||||
dir_mode_bits, owner_id, group_id, false)
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE);
|
||||
make_ancestor, options,
|
||||
dir_mode, announce_mkdir,
|
||||
dir_mode_bits, owner_id, group_id, false)
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -462,131 +462,131 @@ main (int argc, char **argv)
|
||||
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options,
|
||||
NULL)) != -1)
|
||||
NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
break;
|
||||
case 'C':
|
||||
copy_only_if_needed = true;
|
||||
break;
|
||||
case 's':
|
||||
strip_files = true;
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
break;
|
||||
case 'C':
|
||||
copy_only_if_needed = true;
|
||||
break;
|
||||
case 's':
|
||||
strip_files = true;
|
||||
#ifdef SIGCHLD
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
break;
|
||||
case STRIP_PROGRAM_OPTION:
|
||||
strip_program = xstrdup (optarg);
|
||||
strip_program_specified = true;
|
||||
break;
|
||||
case 'd':
|
||||
dir_arg = true;
|
||||
break;
|
||||
case 'D':
|
||||
mkdir_and_install = true;
|
||||
break;
|
||||
case 'v':
|
||||
x.verbose = true;
|
||||
break;
|
||||
case 'g':
|
||||
group_name = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
owner_name = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
x.preserve_timestamps = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
break;
|
||||
case STRIP_PROGRAM_OPTION:
|
||||
strip_program = xstrdup (optarg);
|
||||
strip_program_specified = true;
|
||||
break;
|
||||
case 'd':
|
||||
dir_arg = true;
|
||||
break;
|
||||
case 'D':
|
||||
mkdir_and_install = true;
|
||||
break;
|
||||
case 'v':
|
||||
x.verbose = true;
|
||||
break;
|
||||
case 'g':
|
||||
group_name = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
owner_name = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
x.preserve_timestamps = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
|
||||
case PRESERVE_CONTEXT_OPTION_DEPRECATED:
|
||||
error (0, 0, _("WARNING: --preserve_context is deprecated; "
|
||||
"use --preserve-context instead"));
|
||||
/* fall through */
|
||||
case PRESERVE_CONTEXT_OPTION:
|
||||
if ( ! selinux_enabled)
|
||||
{
|
||||
error (0, 0, _("WARNING: ignoring --preserve-context; "
|
||||
"this kernel is not SELinux-enabled"));
|
||||
break;
|
||||
}
|
||||
x.preserve_security_context = true;
|
||||
use_default_selinux_context = false;
|
||||
break;
|
||||
case 'Z':
|
||||
if ( ! selinux_enabled)
|
||||
{
|
||||
error (0, 0, _("WARNING: ignoring --context (-Z); "
|
||||
"this kernel is not SELinux-enabled"));
|
||||
break;
|
||||
}
|
||||
scontext = optarg;
|
||||
use_default_selinux_context = false;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
case PRESERVE_CONTEXT_OPTION_DEPRECATED:
|
||||
error (0, 0, _("WARNING: --preserve_context is deprecated; "
|
||||
"use --preserve-context instead"));
|
||||
/* fall through */
|
||||
case PRESERVE_CONTEXT_OPTION:
|
||||
if ( ! selinux_enabled)
|
||||
{
|
||||
error (0, 0, _("WARNING: ignoring --preserve-context; "
|
||||
"this kernel is not SELinux-enabled"));
|
||||
break;
|
||||
}
|
||||
x.preserve_security_context = true;
|
||||
use_default_selinux_context = false;
|
||||
break;
|
||||
case 'Z':
|
||||
if ( ! selinux_enabled)
|
||||
{
|
||||
error (0, 0, _("WARNING: ignoring --context (-Z); "
|
||||
"this kernel is not SELinux-enabled"));
|
||||
break;
|
||||
}
|
||||
scontext = optarg;
|
||||
use_default_selinux_context = false;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for invalid combinations of arguments. */
|
||||
if (dir_arg & strip_files)
|
||||
if (dir_arg && strip_files)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("the strip option may not be used when installing a directory"));
|
||||
_("the strip option may not be used when installing a directory"));
|
||||
if (dir_arg && target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("target directory not allowed when installing a directory"));
|
||||
_("target directory not allowed when installing a directory"));
|
||||
|
||||
if (x.preserve_security_context && scontext != NULL)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot force target context to %s and preserve it"),
|
||||
quote (scontext));
|
||||
_("cannot force target context to %s and preserve it"),
|
||||
quote (scontext));
|
||||
|
||||
if (backup_suffix_string)
|
||||
simple_backup_suffix = xstrdup (backup_suffix_string);
|
||||
|
||||
x.backup_type = (make_backups
|
||||
? xget_version (_("backup type"),
|
||||
version_control_string)
|
||||
: no_backups);
|
||||
? xget_version (_("backup type"),
|
||||
version_control_string)
|
||||
: no_backups);
|
||||
|
||||
if (scontext && setfscreatecon (scontext) < 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
|
||||
n_files = argc - optind;
|
||||
file = argv + optind;
|
||||
@@ -594,39 +594,39 @@ main (int argc, char **argv)
|
||||
if (n_files <= ! (dir_arg || target_directory))
|
||||
{
|
||||
if (n_files <= 0)
|
||||
error (0, 0, _("missing file operand"));
|
||||
error (0, 0, _("missing file operand"));
|
||||
else
|
||||
error (0, 0, _("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
error (0, 0, _("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (no_target_directory)
|
||||
{
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory (-t) "
|
||||
"and --no-target-directory (-T)"));
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory (-t) "
|
||||
"and --no-target-directory (-T)"));
|
||||
if (2 < n_files)
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (! (dir_arg || target_directory))
|
||||
{
|
||||
if (2 <= n_files && target_directory_operand (file[n_files - 1]))
|
||||
target_directory = file[--n_files];
|
||||
target_directory = file[--n_files];
|
||||
else if (2 < n_files)
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
}
|
||||
|
||||
if (specified_mode)
|
||||
{
|
||||
struct mode_change *change = mode_compile (specified_mode);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
|
||||
error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
|
||||
mode = mode_adjust (0, false, 0, change, NULL);
|
||||
dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
|
||||
free (change);
|
||||
@@ -634,25 +634,25 @@ main (int argc, char **argv)
|
||||
|
||||
if (strip_program_specified && !strip_files)
|
||||
error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
|
||||
"not specified"));
|
||||
"not specified"));
|
||||
|
||||
if (copy_only_if_needed && x.preserve_timestamps)
|
||||
{
|
||||
error (0, 0, _("options --compare (-C) and --preserve-timestamps are "
|
||||
"mutually exclusive"));
|
||||
"mutually exclusive"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (copy_only_if_needed && strip_files)
|
||||
{
|
||||
error (0, 0, _("options --compare (-C) and --strip are mutually "
|
||||
"exclusive"));
|
||||
"exclusive"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (copy_only_if_needed && extra_mode (mode))
|
||||
error (0, 0, _("the --compare (-C) option is ignored when you"
|
||||
" specify a mode with non-permission bits"));
|
||||
" specify a mode with non-permission bits"));
|
||||
|
||||
get_ids ();
|
||||
|
||||
@@ -661,24 +661,24 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
/* FIXME: it's a little gross that this initialization is
|
||||
required by copy.c::copy. */
|
||||
required by copy.c::copy. */
|
||||
hash_init ();
|
||||
|
||||
if (!target_directory)
|
||||
{
|
||||
if (! (mkdir_and_install
|
||||
? install_file_in_file_parents (file[0], file[1], &x)
|
||||
: install_file_in_file (file[0], file[1], &x)))
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
? install_file_in_file_parents (file[0], file[1], &x)
|
||||
: install_file_in_file (file[0], file[1], &x)))
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
dest_info_init (&x);
|
||||
for (i = 0; i < n_files; i++)
|
||||
if (! install_file_in_dir (file[i], target_directory, &x))
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
int i;
|
||||
dest_info_init (&x);
|
||||
for (i = 0; i < n_files; i++)
|
||||
if (! install_file_in_dir (file[i], target_directory, &x))
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
exit (exit_status);
|
||||
@@ -689,7 +689,7 @@ main (int argc, char **argv)
|
||||
|
||||
static bool
|
||||
install_file_in_file_parents (char const *from, char *to,
|
||||
struct cp_options *x)
|
||||
struct cp_options *x)
|
||||
{
|
||||
bool save_working_directory =
|
||||
! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
|
||||
@@ -712,12 +712,12 @@ install_file_in_file_parents (char const *from, char *to,
|
||||
int restore_errno = errno;
|
||||
savewd_finish (&wd);
|
||||
if (EXIT_SUCCESS < restore_result)
|
||||
return false;
|
||||
return false;
|
||||
if (restore_result < 0 && status == EXIT_SUCCESS)
|
||||
{
|
||||
error (0, restore_errno, _("cannot create directory %s"), to);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, restore_errno, _("cannot create directory %s"), to);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
|
||||
@@ -729,7 +729,7 @@ install_file_in_file_parents (char const *from, char *to,
|
||||
|
||||
static bool
|
||||
install_file_in_file (const char *from, const char *to,
|
||||
const struct cp_options *x)
|
||||
const struct cp_options *x)
|
||||
{
|
||||
struct stat from_sb;
|
||||
if (x->preserve_timestamps && stat (from, &from_sb) != 0)
|
||||
@@ -753,7 +753,7 @@ install_file_in_file (const char *from, const char *to,
|
||||
|
||||
static bool
|
||||
install_file_in_dir (const char *from, const char *to_dir,
|
||||
const struct cp_options *x)
|
||||
const struct cp_options *x)
|
||||
{
|
||||
const char *from_base = last_component (from);
|
||||
char *to = file_name_concat (to_dir, from_base, NULL);
|
||||
@@ -856,9 +856,9 @@ strip (char const *name)
|
||||
break;
|
||||
default: /* Parent. */
|
||||
if (waitpid (pid, &status, 0) < 0)
|
||||
error (EXIT_FAILURE, errno, _("waiting for strip"));
|
||||
error (EXIT_FAILURE, errno, _("waiting for strip"));
|
||||
else if (! WIFEXITED (status) || WEXITSTATUS (status))
|
||||
error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
|
||||
error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -875,15 +875,15 @@ get_ids (void)
|
||||
{
|
||||
pw = getpwnam (owner_name);
|
||||
if (pw == NULL)
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|
||||
|| UID_T_MAX < tmp)
|
||||
error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
|
||||
owner_id = tmp;
|
||||
}
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|
||||
|| UID_T_MAX < tmp)
|
||||
error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
|
||||
owner_id = tmp;
|
||||
}
|
||||
else
|
||||
owner_id = pw->pw_uid;
|
||||
owner_id = pw->pw_uid;
|
||||
endpwent ();
|
||||
}
|
||||
else
|
||||
@@ -893,15 +893,15 @@ get_ids (void)
|
||||
{
|
||||
gr = getgrnam (group_name);
|
||||
if (gr == NULL)
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|
||||
|| GID_T_MAX < tmp)
|
||||
error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
|
||||
group_id = tmp;
|
||||
}
|
||||
{
|
||||
unsigned long int tmp;
|
||||
if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|
||||
|| GID_T_MAX < tmp)
|
||||
error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
|
||||
group_id = tmp;
|
||||
}
|
||||
else
|
||||
group_id = gr->gr_gid;
|
||||
group_id = gr->gr_gid;
|
||||
endgrent ();
|
||||
}
|
||||
else
|
||||
@@ -934,7 +934,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -943,7 +943,7 @@ Usage: %s [OPTION]... [-T] SOURCE DEST\n\
|
||||
or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
|
||||
or: %s [OPTION]... -d DIRECTORY...\n\
|
||||
"),
|
||||
program_name, program_name, program_name, program_name);
|
||||
program_name, program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
\n\
|
||||
This install program copies files (often just compiled) into destination\n\
|
||||
@@ -1005,7 +1005,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
|
||||
existing, nil numbered if numbered backups exist, simple otherwise\n\
|
||||
simple, never always make simple backups\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
549
src/join.c
549
src/join.c
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "system.h"
|
||||
#include "error.h"
|
||||
#include "hard-locale.h"
|
||||
#include "linebuffer.h"
|
||||
#include "memcasecmp.h"
|
||||
#include "quote.h"
|
||||
@@ -161,13 +162,13 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... FILE1 FILE2\n\
|
||||
"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
For each pair of input lines with identical join fields, write a line to\n\
|
||||
standard output. The default join field is the first, delimited\n\
|
||||
@@ -208,7 +209,7 @@ Note, comparisons honor the rules specified by `LC_COLLATE'.\n\
|
||||
If the input is not sorted and some lines cannot be joined, a\n\
|
||||
warning message will be given.\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -242,26 +243,26 @@ xfields (struct line *line)
|
||||
{
|
||||
char *sep;
|
||||
for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
|
||||
extract_field (line, ptr, sep - ptr);
|
||||
extract_field (line, ptr, sep - ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip leading blanks before the first field. */
|
||||
while (isblank (to_uchar (*ptr)))
|
||||
if (++ptr == lim)
|
||||
return;
|
||||
if (++ptr == lim)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
char *sep;
|
||||
for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++)
|
||||
continue;
|
||||
extract_field (line, ptr, sep - ptr);
|
||||
if (sep == lim)
|
||||
return;
|
||||
for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++)
|
||||
continue;
|
||||
}
|
||||
{
|
||||
char *sep;
|
||||
for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++)
|
||||
continue;
|
||||
extract_field (line, ptr, sep - ptr);
|
||||
if (sep == lim)
|
||||
return;
|
||||
for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++)
|
||||
continue;
|
||||
}
|
||||
while (ptr != lim);
|
||||
}
|
||||
|
||||
@@ -283,7 +284,7 @@ freeline (struct line *line)
|
||||
|
||||
static int
|
||||
keycmp (struct line const *line1, struct line const *line2,
|
||||
size_t jf_1, size_t jf_2)
|
||||
size_t jf_1, size_t jf_2)
|
||||
{
|
||||
/* Start of field to compare in each file. */
|
||||
char *beg1;
|
||||
@@ -329,7 +330,7 @@ keycmp (struct line const *line1, struct line const *line2,
|
||||
else
|
||||
{
|
||||
if (hard_LC_COLLATE)
|
||||
return xmemcoll (beg1, len1, beg2, len2);
|
||||
return xmemcoll (beg1, len1, beg2, len2);
|
||||
diff = memcmp (beg1, beg2, MIN (len1, len2));
|
||||
}
|
||||
|
||||
@@ -351,26 +352,26 @@ keycmp (struct line const *line1, struct line const *line2,
|
||||
|
||||
static void
|
||||
check_order (const struct line *prev,
|
||||
const struct line *current,
|
||||
int whatfile)
|
||||
const struct line *current,
|
||||
int whatfile)
|
||||
{
|
||||
if (check_input_order != CHECK_ORDER_DISABLED
|
||||
&& ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable))
|
||||
{
|
||||
if (!issued_disorder_warning[whatfile-1])
|
||||
{
|
||||
size_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
|
||||
if (keycmp (prev, current, join_field, join_field) > 0)
|
||||
{
|
||||
error ((check_input_order == CHECK_ORDER_ENABLED
|
||||
? EXIT_FAILURE : 0),
|
||||
0, _("file %d is not in sorted order"), whatfile);
|
||||
{
|
||||
size_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
|
||||
if (keycmp (prev, current, join_field, join_field) > 0)
|
||||
{
|
||||
error ((check_input_order == CHECK_ORDER_ENABLED
|
||||
? EXIT_FAILURE : 0),
|
||||
0, _("file %d is not in sorted order"), whatfile);
|
||||
|
||||
/* If we get to here, the message was just a warning, but we
|
||||
want only to issue it once. */
|
||||
issued_disorder_warning[whatfile-1] = true;
|
||||
}
|
||||
}
|
||||
/* If we get to here, the message was just a warning, but we
|
||||
want only to issue it once. */
|
||||
issued_disorder_warning[whatfile-1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +412,7 @@ get_line (FILE *fp, struct line **linep, int which)
|
||||
if (! readlinebuffer (&line->buf, fp))
|
||||
{
|
||||
if (ferror (fp))
|
||||
error (EXIT_FAILURE, errno, _("read error"));
|
||||
error (EXIT_FAILURE, errno, _("read error"));
|
||||
freeline (line);
|
||||
return false;
|
||||
}
|
||||
@@ -433,10 +434,10 @@ free_spareline (void)
|
||||
for (i = 0; i < ARRAY_CARDINALITY (spareline); i++)
|
||||
{
|
||||
if (spareline[i])
|
||||
{
|
||||
freeline (spareline[i]);
|
||||
free (spareline[i]);
|
||||
}
|
||||
{
|
||||
freeline (spareline[i]);
|
||||
free (spareline[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +459,7 @@ getseq (FILE *fp, struct seq *seq, int whichfile)
|
||||
size_t i;
|
||||
seq->lines = X2NREALLOC (seq->lines, &seq->alloc);
|
||||
for (i = seq->count; i < seq->alloc; i++)
|
||||
seq->lines[i] = NULL;
|
||||
seq->lines[i] = NULL;
|
||||
}
|
||||
|
||||
if (get_line (fp, &seq->lines[seq->count], whichfile))
|
||||
@@ -487,9 +488,9 @@ delseq (struct seq *seq)
|
||||
for (i = 0; i < seq->alloc; i++)
|
||||
if (seq->lines[i])
|
||||
{
|
||||
if (seq->lines[i]->buf.buffer)
|
||||
freeline (seq->lines[i]);
|
||||
free (seq->lines[i]);
|
||||
if (seq->lines[i]->buf.buffer)
|
||||
freeline (seq->lines[i]);
|
||||
free (seq->lines[i]);
|
||||
}
|
||||
free (seq->lines);
|
||||
}
|
||||
@@ -507,9 +508,9 @@ prfield (size_t n, struct line const *line)
|
||||
{
|
||||
len = line->fields[n].len;
|
||||
if (len)
|
||||
fwrite (line->fields[n].beg, 1, len, stdout);
|
||||
fwrite (line->fields[n].beg, 1, len, stdout);
|
||||
else if (empty_filler)
|
||||
fputs (empty_filler, stdout);
|
||||
fputs (empty_filler, stdout);
|
||||
}
|
||||
else if (empty_filler)
|
||||
fputs (empty_filler, stdout);
|
||||
@@ -530,34 +531,34 @@ prjoin (struct line const *line1, struct line const *line2)
|
||||
|
||||
o = outlist;
|
||||
while (1)
|
||||
{
|
||||
size_t field;
|
||||
struct line const *line;
|
||||
{
|
||||
size_t field;
|
||||
struct line const *line;
|
||||
|
||||
if (o->file == 0)
|
||||
{
|
||||
if (line1 == &uni_blank)
|
||||
{
|
||||
line = line2;
|
||||
field = join_field_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = line1;
|
||||
field = join_field_1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line = (o->file == 1 ? line1 : line2);
|
||||
field = o->field;
|
||||
}
|
||||
prfield (field, line);
|
||||
o = o->next;
|
||||
if (o == NULL)
|
||||
break;
|
||||
putchar (output_separator);
|
||||
}
|
||||
if (o->file == 0)
|
||||
{
|
||||
if (line1 == &uni_blank)
|
||||
{
|
||||
line = line2;
|
||||
field = join_field_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = line1;
|
||||
field = join_field_1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
line = (o->file == 1 ? line1 : line2);
|
||||
field = o->field;
|
||||
}
|
||||
prfield (field, line);
|
||||
o = o->next;
|
||||
if (o == NULL)
|
||||
break;
|
||||
putchar (output_separator);
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
else
|
||||
@@ -565,34 +566,34 @@ prjoin (struct line const *line1, struct line const *line2)
|
||||
size_t i;
|
||||
|
||||
if (line1 == &uni_blank)
|
||||
{
|
||||
struct line const *t;
|
||||
t = line1;
|
||||
line1 = line2;
|
||||
line2 = t;
|
||||
}
|
||||
{
|
||||
struct line const *t;
|
||||
t = line1;
|
||||
line1 = line2;
|
||||
line2 = t;
|
||||
}
|
||||
prfield (join_field_1, line1);
|
||||
for (i = 0; i < join_field_1 && i < line1->nfields; ++i)
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line1);
|
||||
}
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line1);
|
||||
}
|
||||
for (i = join_field_1 + 1; i < line1->nfields; ++i)
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line1);
|
||||
}
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line1);
|
||||
}
|
||||
|
||||
for (i = 0; i < join_field_2 && i < line2->nfields; ++i)
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line2);
|
||||
}
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line2);
|
||||
}
|
||||
for (i = join_field_2 + 1; i < line2->nfields; ++i)
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line2);
|
||||
}
|
||||
{
|
||||
putchar (output_separator);
|
||||
prfield (i, line2);
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
@@ -619,75 +620,75 @@ join (FILE *fp1, FILE *fp2)
|
||||
{
|
||||
size_t i;
|
||||
diff = keycmp (seq1.lines[0], seq2.lines[0],
|
||||
join_field_1, join_field_2);
|
||||
join_field_1, join_field_2);
|
||||
if (diff < 0)
|
||||
{
|
||||
if (print_unpairables_1)
|
||||
prjoin (seq1.lines[0], &uni_blank);
|
||||
advance_seq (fp1, &seq1, true, 1);
|
||||
seen_unpairable = true;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
if (print_unpairables_1)
|
||||
prjoin (seq1.lines[0], &uni_blank);
|
||||
advance_seq (fp1, &seq1, true, 1);
|
||||
seen_unpairable = true;
|
||||
continue;
|
||||
}
|
||||
if (diff > 0)
|
||||
{
|
||||
if (print_unpairables_2)
|
||||
prjoin (&uni_blank, seq2.lines[0]);
|
||||
advance_seq (fp2, &seq2, true, 2);
|
||||
seen_unpairable = true;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
if (print_unpairables_2)
|
||||
prjoin (&uni_blank, seq2.lines[0]);
|
||||
advance_seq (fp2, &seq2, true, 2);
|
||||
seen_unpairable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Keep reading lines from file1 as long as they continue to
|
||||
match the current line from file2. */
|
||||
eof1 = false;
|
||||
do
|
||||
if (!advance_seq (fp1, &seq1, false, 1))
|
||||
{
|
||||
eof1 = true;
|
||||
++seq1.count;
|
||||
break;
|
||||
}
|
||||
if (!advance_seq (fp1, &seq1, false, 1))
|
||||
{
|
||||
eof1 = true;
|
||||
++seq1.count;
|
||||
break;
|
||||
}
|
||||
while (!keycmp (seq1.lines[seq1.count - 1], seq2.lines[0],
|
||||
join_field_1, join_field_2));
|
||||
join_field_1, join_field_2));
|
||||
|
||||
/* Keep reading lines from file2 as long as they continue to
|
||||
match the current line from file1. */
|
||||
eof2 = false;
|
||||
do
|
||||
if (!advance_seq (fp2, &seq2, false, 2))
|
||||
{
|
||||
eof2 = true;
|
||||
++seq2.count;
|
||||
break;
|
||||
}
|
||||
if (!advance_seq (fp2, &seq2, false, 2))
|
||||
{
|
||||
eof2 = true;
|
||||
++seq2.count;
|
||||
break;
|
||||
}
|
||||
while (!keycmp (seq1.lines[0], seq2.lines[seq2.count - 1],
|
||||
join_field_1, join_field_2));
|
||||
join_field_1, join_field_2));
|
||||
|
||||
if (print_pairables)
|
||||
{
|
||||
for (i = 0; i < seq1.count - 1; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < seq2.count - 1; ++j)
|
||||
prjoin (seq1.lines[i], seq2.lines[j]);
|
||||
}
|
||||
}
|
||||
{
|
||||
for (i = 0; i < seq1.count - 1; ++i)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < seq2.count - 1; ++j)
|
||||
prjoin (seq1.lines[i], seq2.lines[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!eof1)
|
||||
{
|
||||
SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]);
|
||||
seq1.count = 1;
|
||||
}
|
||||
{
|
||||
SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]);
|
||||
seq1.count = 1;
|
||||
}
|
||||
else
|
||||
seq1.count = 0;
|
||||
seq1.count = 0;
|
||||
|
||||
if (!eof2)
|
||||
{
|
||||
SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]);
|
||||
seq2.count = 1;
|
||||
}
|
||||
{
|
||||
SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]);
|
||||
seq2.count = 1;
|
||||
}
|
||||
else
|
||||
seq2.count = 0;
|
||||
seq2.count = 0;
|
||||
}
|
||||
|
||||
/* If the user did not specify --check-order, and the we read the
|
||||
@@ -703,29 +704,29 @@ join (FILE *fp1, FILE *fp2)
|
||||
if ((print_unpairables_1 || checktail) && seq1.count)
|
||||
{
|
||||
if (print_unpairables_1)
|
||||
prjoin (seq1.lines[0], &uni_blank);
|
||||
prjoin (seq1.lines[0], &uni_blank);
|
||||
seen_unpairable = true;
|
||||
while (get_line (fp1, linep, 1))
|
||||
{
|
||||
if (print_unpairables_1)
|
||||
prjoin (*linep, &uni_blank);
|
||||
if (issued_disorder_warning[0] && !print_unpairables_1)
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (print_unpairables_1)
|
||||
prjoin (*linep, &uni_blank);
|
||||
if (issued_disorder_warning[0] && !print_unpairables_1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((print_unpairables_2 || checktail) && seq2.count)
|
||||
{
|
||||
if (print_unpairables_2)
|
||||
prjoin (&uni_blank, seq2.lines[0]);
|
||||
prjoin (&uni_blank, seq2.lines[0]);
|
||||
seen_unpairable = true;
|
||||
while (get_line (fp2, linep, 2))
|
||||
{
|
||||
if (print_unpairables_2)
|
||||
prjoin (&uni_blank, *linep);
|
||||
if (issued_disorder_warning[1] && !print_unpairables_2)
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (print_unpairables_2)
|
||||
prjoin (&uni_blank, *linep);
|
||||
if (issued_disorder_warning[1] && !print_unpairables_2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free (*linep);
|
||||
@@ -792,9 +793,9 @@ decode_field_spec (const char *s, int *file_index, size_t *field_index)
|
||||
case '0':
|
||||
if (s[1])
|
||||
{
|
||||
/* `0' must be all alone -- no `.FIELD'. */
|
||||
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
|
||||
}
|
||||
/* `0' must be all alone -- no `.FIELD'. */
|
||||
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
|
||||
}
|
||||
*file_index = 0;
|
||||
*field_index = 0;
|
||||
break;
|
||||
@@ -802,18 +803,18 @@ decode_field_spec (const char *s, int *file_index, size_t *field_index)
|
||||
case '1':
|
||||
case '2':
|
||||
if (s[1] != '.')
|
||||
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
|
||||
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
|
||||
*file_index = s[0] - '0';
|
||||
*field_index = string_to_join_field (s + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid file number in field spec: %s"), quote (s));
|
||||
_("invalid file number in field spec: %s"), quote (s));
|
||||
|
||||
/* Tell gcc -W -Wall that we can't get beyond this point.
|
||||
This avoids a warning (otherwise legit) that the caller's copies
|
||||
of *file_index and *field_index might be used uninitialized. */
|
||||
This avoids a warning (otherwise legit) that the caller's copies
|
||||
of *file_index and *field_index might be used uninitialized. */
|
||||
abort ();
|
||||
|
||||
break;
|
||||
@@ -853,7 +854,7 @@ set_join_field (size_t *var, size_t val)
|
||||
unsigned long int var1 = *var + 1;
|
||||
unsigned long int val1 = val + 1;
|
||||
error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"),
|
||||
var1, val1);
|
||||
var1, val1);
|
||||
}
|
||||
*var = val;
|
||||
}
|
||||
@@ -881,8 +882,8 @@ enum operand_status
|
||||
|
||||
static void
|
||||
add_file_name (char *name, char *names[2],
|
||||
int operand_status[2], int joption_count[2], int *nfiles,
|
||||
int *prev_optc_status, int *optc_status)
|
||||
int operand_status[2], int joption_count[2], int *nfiles,
|
||||
int *prev_optc_status, int *optc_status)
|
||||
{
|
||||
int n = *nfiles;
|
||||
|
||||
@@ -891,30 +892,30 @@ add_file_name (char *name, char *names[2],
|
||||
bool op0 = (operand_status[0] == MUST_BE_OPERAND);
|
||||
char *arg = names[op0];
|
||||
switch (operand_status[op0])
|
||||
{
|
||||
case MUST_BE_OPERAND:
|
||||
error (0, 0, _("extra operand %s"), quote (name));
|
||||
usage (EXIT_FAILURE);
|
||||
{
|
||||
case MUST_BE_OPERAND:
|
||||
error (0, 0, _("extra operand %s"), quote (name));
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
case MIGHT_BE_J1_ARG:
|
||||
joption_count[0]--;
|
||||
set_join_field (&join_field_1, string_to_join_field (arg));
|
||||
break;
|
||||
case MIGHT_BE_J1_ARG:
|
||||
joption_count[0]--;
|
||||
set_join_field (&join_field_1, string_to_join_field (arg));
|
||||
break;
|
||||
|
||||
case MIGHT_BE_J2_ARG:
|
||||
joption_count[1]--;
|
||||
set_join_field (&join_field_2, string_to_join_field (arg));
|
||||
break;
|
||||
case MIGHT_BE_J2_ARG:
|
||||
joption_count[1]--;
|
||||
set_join_field (&join_field_2, string_to_join_field (arg));
|
||||
break;
|
||||
|
||||
case MIGHT_BE_O_ARG:
|
||||
add_field_list (arg);
|
||||
break;
|
||||
}
|
||||
case MIGHT_BE_O_ARG:
|
||||
add_field_list (arg);
|
||||
break;
|
||||
}
|
||||
if (!op0)
|
||||
{
|
||||
operand_status[0] = operand_status[1];
|
||||
names[0] = names[1];
|
||||
}
|
||||
{
|
||||
operand_status[0] = operand_status[1];
|
||||
names[0] = names[1];
|
||||
}
|
||||
n = 1;
|
||||
}
|
||||
|
||||
@@ -954,110 +955,110 @@ main (int argc, char **argv)
|
||||
check_input_order = CHECK_ORDER_DEFAULT;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:",
|
||||
longopts, NULL))
|
||||
!= -1)
|
||||
longopts, NULL))
|
||||
!= -1)
|
||||
{
|
||||
optc_status = MUST_BE_OPERAND;
|
||||
|
||||
switch (optc)
|
||||
{
|
||||
case 'v':
|
||||
print_pairables = false;
|
||||
/* Fall through. */
|
||||
{
|
||||
case 'v':
|
||||
print_pairables = false;
|
||||
/* Fall through. */
|
||||
|
||||
case 'a':
|
||||
{
|
||||
unsigned long int val;
|
||||
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|
||||
|| (val != 1 && val != 2))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid field number: %s"), quote (optarg));
|
||||
if (val == 1)
|
||||
print_unpairables_1 = true;
|
||||
else
|
||||
print_unpairables_2 = true;
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
{
|
||||
unsigned long int val;
|
||||
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|
||||
|| (val != 1 && val != 2))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid field number: %s"), quote (optarg));
|
||||
if (val == 1)
|
||||
print_unpairables_1 = true;
|
||||
else
|
||||
print_unpairables_2 = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (empty_filler && ! STREQ (empty_filler, optarg))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("conflicting empty-field replacement strings"));
|
||||
empty_filler = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
if (empty_filler && ! STREQ (empty_filler, optarg))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("conflicting empty-field replacement strings"));
|
||||
empty_filler = optarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ignore_case = true;
|
||||
break;
|
||||
case 'i':
|
||||
ignore_case = true;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
set_join_field (&join_field_1, string_to_join_field (optarg));
|
||||
break;
|
||||
case '1':
|
||||
set_join_field (&join_field_1, string_to_join_field (optarg));
|
||||
break;
|
||||
|
||||
case '2':
|
||||
set_join_field (&join_field_2, string_to_join_field (optarg));
|
||||
break;
|
||||
case '2':
|
||||
set_join_field (&join_field_2, string_to_join_field (optarg));
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
|
||||
&& optarg == argv[optind - 1] + 2)
|
||||
{
|
||||
/* The argument was either "-j1" or "-j2". */
|
||||
bool is_j2 = (optarg[0] == '2');
|
||||
joption_count[is_j2]++;
|
||||
optc_status = MIGHT_BE_J1_ARG + is_j2;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_join_field (&join_field_1, string_to_join_field (optarg));
|
||||
set_join_field (&join_field_2, join_field_1);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
|
||||
&& optarg == argv[optind - 1] + 2)
|
||||
{
|
||||
/* The argument was either "-j1" or "-j2". */
|
||||
bool is_j2 = (optarg[0] == '2');
|
||||
joption_count[is_j2]++;
|
||||
optc_status = MIGHT_BE_J1_ARG + is_j2;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_join_field (&join_field_1, string_to_join_field (optarg));
|
||||
set_join_field (&join_field_2, join_field_1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
add_field_list (optarg);
|
||||
optc_status = MIGHT_BE_O_ARG;
|
||||
break;
|
||||
case 'o':
|
||||
add_field_list (optarg);
|
||||
optc_status = MIGHT_BE_O_ARG;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
{
|
||||
unsigned char newtab = optarg[0];
|
||||
if (! newtab)
|
||||
error (EXIT_FAILURE, 0, _("empty tab"));
|
||||
if (optarg[1])
|
||||
{
|
||||
if (STREQ (optarg, "\\0"))
|
||||
newtab = '\0';
|
||||
else
|
||||
error (EXIT_FAILURE, 0, _("multi-character tab %s"),
|
||||
quote (optarg));
|
||||
}
|
||||
if (0 <= tab && tab != newtab)
|
||||
error (EXIT_FAILURE, 0, _("incompatible tabs"));
|
||||
tab = newtab;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
unsigned char newtab = optarg[0];
|
||||
if (! newtab)
|
||||
error (EXIT_FAILURE, 0, _("empty tab"));
|
||||
if (optarg[1])
|
||||
{
|
||||
if (STREQ (optarg, "\\0"))
|
||||
newtab = '\0';
|
||||
else
|
||||
error (EXIT_FAILURE, 0, _("multi-character tab %s"),
|
||||
quote (optarg));
|
||||
}
|
||||
if (0 <= tab && tab != newtab)
|
||||
error (EXIT_FAILURE, 0, _("incompatible tabs"));
|
||||
tab = newtab;
|
||||
}
|
||||
break;
|
||||
|
||||
case NOCHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_DISABLED;
|
||||
break;
|
||||
case NOCHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_DISABLED;
|
||||
break;
|
||||
|
||||
case CHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_ENABLED;
|
||||
break;
|
||||
case CHECK_ORDER_OPTION:
|
||||
check_input_order = CHECK_ORDER_ENABLED;
|
||||
break;
|
||||
|
||||
case 1: /* Non-option argument. */
|
||||
add_file_name (optarg, names, operand_status, joption_count,
|
||||
&nfiles, &prev_optc_status, &optc_status);
|
||||
break;
|
||||
case 1: /* Non-option argument. */
|
||||
add_file_name (optarg, names, operand_status, joption_count,
|
||||
&nfiles, &prev_optc_status, &optc_status);
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
prev_optc_status = optc_status;
|
||||
}
|
||||
@@ -1066,14 +1067,14 @@ main (int argc, char **argv)
|
||||
prev_optc_status = MUST_BE_OPERAND;
|
||||
while (optind < argc)
|
||||
add_file_name (argv[optind++], names, operand_status, joption_count,
|
||||
&nfiles, &prev_optc_status, &optc_status);
|
||||
&nfiles, &prev_optc_status, &optc_status);
|
||||
|
||||
if (nfiles != 2)
|
||||
{
|
||||
if (nfiles == 0)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -1082,8 +1083,8 @@ main (int argc, char **argv)
|
||||
for (i = 0; i < 2; i++)
|
||||
if (joption_count[i] != 0)
|
||||
{
|
||||
set_join_field (&join_field_1, i);
|
||||
set_join_field (&join_field_2, i);
|
||||
set_join_field (&join_field_1, i);
|
||||
set_join_field (&join_field_2, i);
|
||||
}
|
||||
|
||||
if (join_field_1 == SIZE_MAX)
|
||||
|
||||
174
src/kill.c
174
src/kill.c
@@ -52,8 +52,8 @@
|
||||
# endif
|
||||
# if HAVE_DECL_SYS_SIGLIST || defined sys_siglist
|
||||
# define strsignal(signum) (0 <= (signum) && (signum) <= SIGNUM_BOUND \
|
||||
? sys_siglist[signum] \
|
||||
: 0)
|
||||
? sys_siglist[signum] \
|
||||
: 0)
|
||||
# endif
|
||||
# ifndef strsignal
|
||||
# define strsignal(signum) 0
|
||||
@@ -81,7 +81,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -89,7 +89,7 @@ Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\
|
||||
or: %s -l [SIGNAL]...\n\
|
||||
or: %s -t [SIGNAL]...\n\
|
||||
"),
|
||||
program_name, program_name, program_name);
|
||||
program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
Send signals to processes, or list signals.\n\
|
||||
\n\
|
||||
@@ -111,7 +111,7 @@ or the exit status of a process terminated by a signal.\n\
|
||||
PID is an integer; if negative it identifies a process group.\n\
|
||||
"), stdout);
|
||||
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -122,11 +122,11 @@ PID is an integer; if negative it identifies a process group.\n\
|
||||
|
||||
static void
|
||||
print_table_row (unsigned int num_width, int signum,
|
||||
unsigned int name_width, char const *signame)
|
||||
unsigned int name_width, char const *signame)
|
||||
{
|
||||
char const *description = strsignal (signum);
|
||||
printf ("%*d %-*s %s\n", num_width, signum, name_width, signame,
|
||||
description ? description : "?");
|
||||
description ? description : "?");
|
||||
}
|
||||
|
||||
/* Print a list of signal names. If TABLE, print a table.
|
||||
@@ -147,51 +147,51 @@ list_signals (bool table, char *const *argv)
|
||||
/* Compute the maximum width of a signal number. */
|
||||
unsigned int num_width = 1;
|
||||
for (signum = 1; signum <= SIGNUM_BOUND / 10; signum *= 10)
|
||||
num_width++;
|
||||
num_width++;
|
||||
|
||||
/* Compute the maximum width of a signal name. */
|
||||
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
|
||||
if (sig2str (signum, signame) == 0)
|
||||
{
|
||||
size_t len = strlen (signame);
|
||||
if (name_width < len)
|
||||
name_width = len;
|
||||
}
|
||||
if (sig2str (signum, signame) == 0)
|
||||
{
|
||||
size_t len = strlen (signame);
|
||||
if (name_width < len)
|
||||
name_width = len;
|
||||
}
|
||||
|
||||
if (argv)
|
||||
for (; *argv; argv++)
|
||||
{
|
||||
signum = operand2sig (*argv, signame);
|
||||
if (signum < 0)
|
||||
status = EXIT_FAILURE;
|
||||
else
|
||||
print_table_row (num_width, signum, name_width, signame);
|
||||
}
|
||||
for (; *argv; argv++)
|
||||
{
|
||||
signum = operand2sig (*argv, signame);
|
||||
if (signum < 0)
|
||||
status = EXIT_FAILURE;
|
||||
else
|
||||
print_table_row (num_width, signum, name_width, signame);
|
||||
}
|
||||
else
|
||||
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
|
||||
if (sig2str (signum, signame) == 0)
|
||||
print_table_row (num_width, signum, name_width, signame);
|
||||
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
|
||||
if (sig2str (signum, signame) == 0)
|
||||
print_table_row (num_width, signum, name_width, signame);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argv)
|
||||
for (; *argv; argv++)
|
||||
{
|
||||
signum = operand2sig (*argv, signame);
|
||||
if (signum < 0)
|
||||
status = EXIT_FAILURE;
|
||||
else
|
||||
{
|
||||
if (ISDIGIT (**argv))
|
||||
puts (signame);
|
||||
else
|
||||
printf ("%d\n", signum);
|
||||
}
|
||||
}
|
||||
for (; *argv; argv++)
|
||||
{
|
||||
signum = operand2sig (*argv, signame);
|
||||
if (signum < 0)
|
||||
status = EXIT_FAILURE;
|
||||
else
|
||||
{
|
||||
if (ISDIGIT (**argv))
|
||||
puts (signame);
|
||||
else
|
||||
printf ("%d\n", signum);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
|
||||
if (sig2str (signum, signame) == 0)
|
||||
puts (signame);
|
||||
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
|
||||
if (sig2str (signum, signame) == 0)
|
||||
puts (signame);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -213,15 +213,15 @@ send_signals (int signum, char *const *argv)
|
||||
pid_t pid = n;
|
||||
|
||||
if (errno == ERANGE || pid != n || arg == endp || *endp)
|
||||
{
|
||||
error (0, 0, _("%s: invalid process id"), arg);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("%s: invalid process id"), arg);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
else if (kill (pid, signum) != 0)
|
||||
{
|
||||
error (0, errno, "%s", arg);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", arg);
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
while ((arg = *++argv));
|
||||
|
||||
@@ -246,61 +246,61 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
switch (optc)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (optind != 2)
|
||||
{
|
||||
/* This option is actually a process-id. */
|
||||
optind--;
|
||||
goto no_more_options;
|
||||
}
|
||||
/* Fall through. */
|
||||
if (optind != 2)
|
||||
{
|
||||
/* This option is actually a process-id. */
|
||||
optind--;
|
||||
goto no_more_options;
|
||||
}
|
||||
/* Fall through. */
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E':
|
||||
case 'F': case 'G': case 'H': case 'I': case 'J':
|
||||
case 'K': case 'L': case 'M': case 'N': case 'O':
|
||||
case 'P': case 'Q': case 'R': case 'S': case 'T':
|
||||
case 'U': case 'V': case 'W': case 'X': case 'Y':
|
||||
case 'Z':
|
||||
if (! optarg)
|
||||
optarg = argv[optind - 1] + strlen (argv[optind - 1]);
|
||||
if (optarg != argv[optind - 1] + 2)
|
||||
{
|
||||
error (0, 0, _("invalid option -- %c"), optc);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
optarg--;
|
||||
/* Fall through. */
|
||||
if (! optarg)
|
||||
optarg = argv[optind - 1] + strlen (argv[optind - 1]);
|
||||
if (optarg != argv[optind - 1] + 2)
|
||||
{
|
||||
error (0, 0, _("invalid option -- %c"), optc);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
optarg--;
|
||||
/* Fall through. */
|
||||
case 'n': /* -n is not documented, but is for Bash compatibility. */
|
||||
case 's':
|
||||
if (0 <= signum)
|
||||
{
|
||||
error (0, 0, _("%s: multiple signals specified"), optarg);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
signum = operand2sig (optarg, signame);
|
||||
if (signum < 0)
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
if (0 <= signum)
|
||||
{
|
||||
error (0, 0, _("%s: multiple signals specified"), optarg);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
signum = operand2sig (optarg, signame);
|
||||
if (signum < 0)
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
table = true;
|
||||
/* Fall through. */
|
||||
table = true;
|
||||
/* Fall through. */
|
||||
case 'l':
|
||||
if (list)
|
||||
{
|
||||
error (0, 0, _("multiple -l or -t options specified"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
list = true;
|
||||
break;
|
||||
if (list)
|
||||
{
|
||||
error (0, 0, _("multiple -l or -t options specified"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
list = true;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
no_more_options:;
|
||||
|
||||
@@ -319,6 +319,6 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
return (list
|
||||
? list_signals (table, optind < argc ? argv + optind : NULL)
|
||||
: send_signals (signum, argv + optind));
|
||||
? list_signals (table, optind < argc ? argv + optind : NULL)
|
||||
: send_signals (signum, argv + optind));
|
||||
}
|
||||
|
||||
14
src/link.c
14
src/link.c
@@ -40,7 +40,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -48,10 +48,10 @@ Usage: %s FILE1 FILE2\n\
|
||||
or: %s OPTION\n"), program_name, program_name);
|
||||
fputs (_("Call the link function to create a link named FILE2\
|
||||
to an existing FILE1.\n\n"),
|
||||
stdout);
|
||||
stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -68,16 +68,16 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
if (argc < optind + 2)
|
||||
{
|
||||
if (argc < optind + 1)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[optind]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[optind]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (link (argv[optind], argv[optind + 1]) != 0)
|
||||
error (EXIT_FAILURE, errno, _("cannot create link %s to %s"),
|
||||
quote_n (0, argv[optind + 1]), quote_n (1, argv[optind]));
|
||||
quote_n (0, argv[optind + 1]), quote_n (1, argv[optind]));
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
461
src/ln.c
461
src/ln.c
@@ -39,30 +39,15 @@
|
||||
proper_name ("Mike Parker"), \
|
||||
proper_name ("David MacKenzie")
|
||||
|
||||
#ifndef ENABLE_HARD_LINK_TO_SYMLINK_WARNING
|
||||
# define ENABLE_HARD_LINK_TO_SYMLINK_WARNING 0
|
||||
#endif
|
||||
|
||||
/* In being careful not even to try to make hard links to directories,
|
||||
we have to know whether link(2) follows symlinks. If it does, then
|
||||
we have to *stat* the `source' to see if the resulting link would be
|
||||
to a directory. Otherwise, we have to use *lstat* so that we allow
|
||||
users to make hard links to symlinks-that-point-to-directories. */
|
||||
|
||||
#if LINK_FOLLOWS_SYMLINKS
|
||||
# define STAT_LIKE_LINK(File, Stat_buf) \
|
||||
stat (File, Stat_buf)
|
||||
#else
|
||||
# define STAT_LIKE_LINK(File, Stat_buf) \
|
||||
lstat (File, Stat_buf)
|
||||
#endif
|
||||
|
||||
/* FIXME: document */
|
||||
static enum backup_type backup_type;
|
||||
|
||||
/* If true, make symbolic links; otherwise, make hard links. */
|
||||
static bool symbolic_link;
|
||||
|
||||
/* If true, hard links are logical rather than physical. */
|
||||
static bool logical = !!LINK_FOLLOWS_SYMLINKS;
|
||||
|
||||
/* If true, ask the user before removing existing files. */
|
||||
static bool interactive;
|
||||
|
||||
@@ -75,7 +60,7 @@ static bool verbose;
|
||||
/* If true, allow the superuser to *attempt* to make hard links
|
||||
to directories. However, it appears that this option is not useful
|
||||
in practice, since even the superuser is prohibited from hard-linking
|
||||
directories on most (all?) existing systems. */
|
||||
directories on most existing systems (Solaris being an exception). */
|
||||
static bool hard_dir_link;
|
||||
|
||||
/* If nonzero, and the specified destination is a symbolic link to a
|
||||
@@ -103,6 +88,8 @@ static struct option const long_options[] =
|
||||
{"interactive", no_argument, NULL, 'i'},
|
||||
{"suffix", required_argument, NULL, 'S'},
|
||||
{"target-directory", required_argument, NULL, 't'},
|
||||
{"logical", no_argument, NULL, 'L'},
|
||||
{"physical", no_argument, NULL, 'P'},
|
||||
{"symbolic", no_argument, NULL, 's'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{GETOPT_HELP_OPTION_DECL},
|
||||
@@ -147,46 +134,40 @@ do_link (const char *source, const char *dest)
|
||||
bool source_is_dir = false;
|
||||
bool ok;
|
||||
|
||||
/* Use stat here instead of lstat.
|
||||
On SVR4, link does not follow symlinks, so this check disallows
|
||||
making hard links to symlinks that point to directories. Big deal.
|
||||
On other systems, link follows symlinks, so this check is right. */
|
||||
if (!symbolic_link)
|
||||
{
|
||||
if (STAT_LIKE_LINK (source, &source_stats) != 0)
|
||||
{
|
||||
error (0, errno, _("accessing %s"), quote (source));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ENABLE_HARD_LINK_TO_SYMLINK_WARNING
|
||||
&& S_ISLNK (source_stats.st_mode))
|
||||
{
|
||||
error (0, 0, _("%s: warning: making a hard link to a symbolic link\
|
||||
is not portable"),
|
||||
quote (source));
|
||||
}
|
||||
/* Which stat to use depends on whether linkat will follow the
|
||||
symlink. We can't use the shorter
|
||||
(logical ? stat : lstat) (source, &source_stats)
|
||||
since stat might be a function-like macro. */
|
||||
if ((logical ? stat (source, &source_stats)
|
||||
: lstat (source, &source_stats))
|
||||
!= 0)
|
||||
{
|
||||
error (0, errno, _("accessing %s"), quote (source));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISDIR (source_stats.st_mode))
|
||||
{
|
||||
source_is_dir = true;
|
||||
if (! hard_dir_link)
|
||||
{
|
||||
error (0, 0, _("%s: hard link not allowed for directory"),
|
||||
quote (source));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
source_is_dir = true;
|
||||
if (! hard_dir_link)
|
||||
{
|
||||
error (0, 0, _("%s: hard link not allowed for directory"),
|
||||
quote (source));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remove_existing_files || interactive || backup_type != no_backups)
|
||||
{
|
||||
dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
|
||||
if (!dest_lstat_ok && errno != ENOENT)
|
||||
{
|
||||
error (0, errno, _("accessing %s"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("accessing %s"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the current target was created as a hard link to another
|
||||
@@ -196,8 +177,8 @@ do_link (const char *source, const char *dest)
|
||||
&& seen_file (dest_set, dest, &dest_stats))
|
||||
{
|
||||
error (0, 0,
|
||||
_("will not overwrite just-created %s with %s"),
|
||||
quote_n (0, dest), quote_n (1, source));
|
||||
_("will not overwrite just-created %s with %s"),
|
||||
quote_n (0, dest), quote_n (1, source));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -208,77 +189,80 @@ do_link (const char *source, const char *dest)
|
||||
anything and fail right here. */
|
||||
if ((remove_existing_files
|
||||
/* Ensure that "ln --backup f f" fails here, with the
|
||||
"... same file" diagnostic, below. Otherwise, subsequent
|
||||
code would give a misleading "file not found" diagnostic.
|
||||
This case is different than the others handled here, since
|
||||
the command in question doesn't use --force. */
|
||||
"... same file" diagnostic, below. Otherwise, subsequent
|
||||
code would give a misleading "file not found" diagnostic.
|
||||
This case is different than the others handled here, since
|
||||
the command in question doesn't use --force. */
|
||||
|| (!symbolic_link && backup_type != no_backups))
|
||||
&& dest_lstat_ok
|
||||
/* Allow `ln -sf --backup k k' to succeed in creating the
|
||||
self-referential symlink, but don't allow the hard-linking
|
||||
equivalent: `ln -f k k' (with or without --backup) to get
|
||||
beyond this point, because the error message you'd get is
|
||||
misleading. */
|
||||
self-referential symlink, but don't allow the hard-linking
|
||||
equivalent: `ln -f k k' (with or without --backup) to get
|
||||
beyond this point, because the error message you'd get is
|
||||
misleading. */
|
||||
&& (backup_type == no_backups || !symbolic_link)
|
||||
&& (!symbolic_link || stat (source, &source_stats) == 0)
|
||||
&& SAME_INODE (source_stats, dest_stats)
|
||||
/* The following detects whether removing DEST will also remove
|
||||
SOURCE. If the file has only one link then both are surely
|
||||
the same link. Otherwise check whether they point to the same
|
||||
name in the same directory. */
|
||||
SOURCE. If the file has only one link then both are surely
|
||||
the same link. Otherwise check whether they point to the same
|
||||
name in the same directory. */
|
||||
&& (source_stats.st_nlink == 1 || same_name (source, dest)))
|
||||
{
|
||||
error (0, 0, _("%s and %s are the same file"),
|
||||
quote_n (0, source), quote_n (1, dest));
|
||||
quote_n (0, source), quote_n (1, dest));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dest_lstat_ok)
|
||||
{
|
||||
if (S_ISDIR (dest_stats.st_mode))
|
||||
{
|
||||
error (0, 0, _("%s: cannot overwrite directory"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, 0, _("%s: cannot overwrite directory"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
if (interactive)
|
||||
{
|
||||
fprintf (stderr, _("%s: replace %s? "), program_name, quote (dest));
|
||||
if (!yesno ())
|
||||
return true;
|
||||
remove_existing_files = true;
|
||||
}
|
||||
{
|
||||
fprintf (stderr, _("%s: replace %s? "), program_name, quote (dest));
|
||||
if (!yesno ())
|
||||
return true;
|
||||
remove_existing_files = true;
|
||||
}
|
||||
|
||||
if (backup_type != no_backups)
|
||||
{
|
||||
dest_backup = find_backup_file_name (dest, backup_type);
|
||||
if (rename (dest, dest_backup) != 0)
|
||||
{
|
||||
int rename_errno = errno;
|
||||
free (dest_backup);
|
||||
dest_backup = NULL;
|
||||
if (rename_errno != ENOENT)
|
||||
{
|
||||
error (0, rename_errno, _("cannot backup %s"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
dest_backup = find_backup_file_name (dest, backup_type);
|
||||
if (rename (dest, dest_backup) != 0)
|
||||
{
|
||||
int rename_errno = errno;
|
||||
free (dest_backup);
|
||||
dest_backup = NULL;
|
||||
if (rename_errno != ENOENT)
|
||||
{
|
||||
error (0, rename_errno, _("cannot backup %s"), quote (dest));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
|
||||
== 0);
|
||||
ok = ((symbolic_link ? symlink (source, dest)
|
||||
: linkat (AT_FDCWD, source, AT_FDCWD, dest,
|
||||
logical ? AT_SYMLINK_FOLLOW : 0))
|
||||
== 0);
|
||||
|
||||
/* If the attempt to create a link failed and we are removing or
|
||||
backing up destinations, unlink the destination and try again.
|
||||
|
||||
POSIX 1003.1-2004 requires that ln -f A B must unlink B even on
|
||||
failure (e.g., when A does not exist). This is counterintuitive,
|
||||
and we submitted a defect report
|
||||
<http://www.opengroup.org/austin/mailarchives/ag-review/msg01794.html>
|
||||
(2004-06-24). If the committee does not fix the standard we'll
|
||||
have to change the behavior of ln -f, at least if POSIXLY_CORRECT
|
||||
is set. In the meantime ln -f A B will not unlink B unless the
|
||||
attempt to link A to B failed because B already existed.
|
||||
On the surface, POSIX describes an algorithm that states that
|
||||
'ln -f A B' will call unlink() on B before ever attempting
|
||||
link() on A. But strictly following this has the counterintuitive
|
||||
effect of losing the contents of B, if A does not exist.
|
||||
Fortunately, POSIX 2008 clarified that an application is free
|
||||
to fail early if it can prove that continuing onwards cannot
|
||||
succeed, so we are justified in trying link() before blindly
|
||||
removing B, thus sometimes calling link() a second time during
|
||||
a successful 'ln -f A B'.
|
||||
|
||||
Try to unlink DEST even if we may have backed it up successfully.
|
||||
In some unusual cases (when DEST and DEST_BACKUP are hard-links
|
||||
@@ -289,50 +273,52 @@ do_link (const char *source, const char *dest)
|
||||
if (!ok && errno == EEXIST && (remove_existing_files || dest_backup))
|
||||
{
|
||||
if (unlink (dest) != 0)
|
||||
{
|
||||
error (0, errno, _("cannot remove %s"), quote (dest));
|
||||
free (dest_backup);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, _("cannot remove %s"), quote (dest));
|
||||
free (dest_backup);
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
|
||||
== 0);
|
||||
ok = ((symbolic_link ? symlink (source, dest)
|
||||
: linkat (AT_FDCWD, source, AT_FDCWD, dest,
|
||||
logical ? AT_SYMLINK_FOLLOW : 0))
|
||||
== 0);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
/* Right after creating a hard link, do this: (note dest name and
|
||||
source_stats, which are also the just-linked-destinations stats) */
|
||||
source_stats, which are also the just-linked-destinations stats) */
|
||||
record_file (dest_set, dest, &source_stats);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
if (dest_backup)
|
||||
printf ("%s ~ ", quote (dest_backup));
|
||||
printf ("%s %c> %s\n", quote_n (0, dest), (symbolic_link ? '-' : '='),
|
||||
quote_n (1, source));
|
||||
}
|
||||
{
|
||||
if (dest_backup)
|
||||
printf ("%s ~ ", quote (dest_backup));
|
||||
printf ("%s %c> %s\n", quote_n (0, dest), (symbolic_link ? '-' : '='),
|
||||
quote_n (1, source));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, errno,
|
||||
(symbolic_link
|
||||
? (errno != ENAMETOOLONG && *source
|
||||
? _("creating symbolic link %s")
|
||||
: _("creating symbolic link %s -> %s"))
|
||||
: (errno == EMLINK && !source_is_dir
|
||||
? _("creating hard link to %.0s%s")
|
||||
: (errno == EDQUOT || errno == EEXIST || errno == ENOSPC
|
||||
|| errno == EROFS)
|
||||
? _("creating hard link %s")
|
||||
: _("creating hard link %s => %s"))),
|
||||
quote_n (0, dest), quote_n (1, source));
|
||||
(symbolic_link
|
||||
? (errno != ENAMETOOLONG && *source
|
||||
? _("creating symbolic link %s")
|
||||
: _("creating symbolic link %s -> %s"))
|
||||
: (errno == EMLINK && !source_is_dir
|
||||
? _("creating hard link to %.0s%s")
|
||||
: (errno == EDQUOT || errno == EEXIST || errno == ENOSPC
|
||||
|| errno == EROFS)
|
||||
? _("creating hard link %s")
|
||||
: _("creating hard link %s => %s"))),
|
||||
quote_n (0, dest), quote_n (1, source));
|
||||
|
||||
if (dest_backup)
|
||||
{
|
||||
if (rename (dest_backup, dest) != 0)
|
||||
error (0, errno, _("cannot un-backup %s"), quote (dest));
|
||||
}
|
||||
{
|
||||
if (rename (dest_backup, dest) != 0)
|
||||
error (0, errno, _("cannot un-backup %s"), quote (dest));
|
||||
}
|
||||
}
|
||||
|
||||
free (dest_backup);
|
||||
@@ -344,7 +330,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -353,7 +339,7 @@ Usage: %s [OPTION]... [-T] TARGET LINK_NAME (1st form)\n\
|
||||
or: %s [OPTION]... TARGET... DIRECTORY (3rd form)\n\
|
||||
or: %s [OPTION]... -t DIRECTORY TARGET... (4th form)\n\
|
||||
"),
|
||||
program_name, program_name, program_name, program_name);
|
||||
program_name, program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
In the 1st form, create a link to TARGET with the name LINK_NAME.\n\
|
||||
In the 2nd form, create a link to TARGET in the current directory.\n\
|
||||
@@ -376,9 +362,11 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
-f, --force remove existing destination files\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
-i, --interactive prompt whether to remove destinations\n\
|
||||
-L, --logical make hard links to symbolic link references\n\
|
||||
-n, --no-dereference treat destination that is a symlink to a\n\
|
||||
directory as if it were a normal file\n\
|
||||
-i, --interactive prompt whether to remove destinations\n\
|
||||
-P, --physical make hard links directly to symbolic links\n\
|
||||
-s, --symbolic make symbolic links instead of hard links\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
@@ -397,13 +385,18 @@ The version control method may be selected via the --backup option or through\n\
|
||||
the VERSION_CONTROL environment variable. Here are the values:\n\
|
||||
\n\
|
||||
"), stdout);
|
||||
printf (_("\
|
||||
Using -s ignores -L and -P. Otherwise, the last option specified controls\n\
|
||||
behavior when the source is a symbolic link, defaulting to %s.\n\
|
||||
\n\
|
||||
"), LINK_FOLLOWS_SYMLINKS ? "-L" : "-P");
|
||||
fputs (_("\
|
||||
none, off never make backups (even if --backup is given)\n\
|
||||
numbered, t make numbered backups\n\
|
||||
existing, nil numbered if numbered backups exist, simple otherwise\n\
|
||||
simple, never always make simple backups\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -436,64 +429,70 @@ main (int argc, char **argv)
|
||||
symbolic_link = remove_existing_files = interactive = verbose
|
||||
= hard_dir_link = false;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "bdfinst:vFS:T", long_options, NULL))
|
||||
!= -1)
|
||||
while ((c = getopt_long (argc, argv, "bdfinst:vFLPS:T", long_options, NULL))
|
||||
!= -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
case 'F':
|
||||
hard_dir_link = true;
|
||||
break;
|
||||
case 'f':
|
||||
remove_existing_files = true;
|
||||
interactive = false;
|
||||
break;
|
||||
case 'i':
|
||||
remove_existing_files = false;
|
||||
interactive = true;
|
||||
break;
|
||||
case 'n':
|
||||
dereference_dest_dir_symlinks = false;
|
||||
break;
|
||||
case 's':
|
||||
symbolic_link = true;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
case 'F':
|
||||
hard_dir_link = true;
|
||||
break;
|
||||
case 'f':
|
||||
remove_existing_files = true;
|
||||
interactive = false;
|
||||
break;
|
||||
case 'i':
|
||||
remove_existing_files = false;
|
||||
interactive = true;
|
||||
break;
|
||||
case 'L':
|
||||
logical = true;
|
||||
break;
|
||||
case 'n':
|
||||
dereference_dest_dir_symlinks = false;
|
||||
break;
|
||||
case 'P':
|
||||
logical = false;
|
||||
break;
|
||||
case 's':
|
||||
symbolic_link = true;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n_files = argc - optind;
|
||||
@@ -508,75 +507,75 @@ main (int argc, char **argv)
|
||||
if (no_target_directory)
|
||||
{
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory "
|
||||
"and --no-target-directory"));
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory "
|
||||
"and --no-target-directory"));
|
||||
if (n_files != 2)
|
||||
{
|
||||
if (n_files < 2)
|
||||
error (0, 0,
|
||||
_("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
else
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
if (n_files < 2)
|
||||
error (0, 0,
|
||||
_("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
else
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (!target_directory)
|
||||
{
|
||||
if (n_files < 2)
|
||||
target_directory = ".";
|
||||
target_directory = ".";
|
||||
else if (2 <= n_files && target_directory_operand (file[n_files - 1]))
|
||||
target_directory = file[--n_files];
|
||||
target_directory = file[--n_files];
|
||||
else if (2 < n_files)
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
}
|
||||
|
||||
if (backup_suffix_string)
|
||||
simple_backup_suffix = xstrdup (backup_suffix_string);
|
||||
|
||||
backup_type = (make_backups
|
||||
? xget_version (_("backup type"), version_control_string)
|
||||
: no_backups);
|
||||
? xget_version (_("backup type"), version_control_string)
|
||||
: no_backups);
|
||||
|
||||
if (target_directory)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Create the data structure we'll use to record which hard links we
|
||||
create. Used to ensure that ln detects an obscure corner case that
|
||||
might result in user data loss. Create it only if needed. */
|
||||
create. Used to ensure that ln detects an obscure corner case that
|
||||
might result in user data loss. Create it only if needed. */
|
||||
if (2 <= n_files
|
||||
&& remove_existing_files
|
||||
/* Don't bother trying to protect symlinks, since ln clobbering
|
||||
a just-created symlink won't ever lead to real data loss. */
|
||||
&& ! symbolic_link
|
||||
/* No destination hard link can be clobbered when making
|
||||
numbered backups. */
|
||||
&& backup_type != numbered_backups)
|
||||
&& remove_existing_files
|
||||
/* Don't bother trying to protect symlinks, since ln clobbering
|
||||
a just-created symlink won't ever lead to real data loss. */
|
||||
&& ! symbolic_link
|
||||
/* No destination hard link can be clobbered when making
|
||||
numbered backups. */
|
||||
&& backup_type != numbered_backups)
|
||||
|
||||
{
|
||||
dest_set = hash_initialize (DEST_INFO_INITIAL_CAPACITY,
|
||||
NULL,
|
||||
triple_hash,
|
||||
triple_compare,
|
||||
triple_free);
|
||||
if (dest_set == NULL)
|
||||
xalloc_die ();
|
||||
}
|
||||
{
|
||||
dest_set = hash_initialize (DEST_INFO_INITIAL_CAPACITY,
|
||||
NULL,
|
||||
triple_hash,
|
||||
triple_compare,
|
||||
triple_free);
|
||||
if (dest_set == NULL)
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
ok = true;
|
||||
for (i = 0; i < n_files; ++i)
|
||||
{
|
||||
char *dest_base;
|
||||
char *dest = file_name_concat (target_directory,
|
||||
last_component (file[i]),
|
||||
&dest_base);
|
||||
strip_trailing_slashes (dest_base);
|
||||
ok &= do_link (file[i], dest);
|
||||
free (dest);
|
||||
}
|
||||
{
|
||||
char *dest_base;
|
||||
char *dest = file_name_concat (target_directory,
|
||||
last_component (file[i]),
|
||||
&dest_base);
|
||||
strip_trailing_slashes (dest_base);
|
||||
ok &= do_link (file[i], dest);
|
||||
free (dest);
|
||||
}
|
||||
}
|
||||
else
|
||||
ok = do_link (file[0], file[1]);
|
||||
|
||||
@@ -34,7 +34,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]\n"), program_name);
|
||||
@@ -44,7 +44,7 @@ Print the name of the current user.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ main (int argc, char **argv)
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
usage, AUTHORS, (char const *) NULL);
|
||||
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
|
||||
426
src/md5sum.c
426
src/md5sum.c
@@ -147,7 +147,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -156,26 +156,26 @@ Print or check %s (%d-bit) checksums.\n\
|
||||
With no FILE, or when FILE is -, read standard input.\n\
|
||||
\n\
|
||||
"),
|
||||
program_name,
|
||||
DIGEST_TYPE_STRING,
|
||||
DIGEST_BITS);
|
||||
program_name,
|
||||
DIGEST_TYPE_STRING,
|
||||
DIGEST_BITS);
|
||||
if (O_BINARY)
|
||||
fputs (_("\
|
||||
fputs (_("\
|
||||
-b, --binary read in binary mode (default unless reading tty stdin)\n\
|
||||
"), stdout);
|
||||
else
|
||||
fputs (_("\
|
||||
fputs (_("\
|
||||
-b, --binary read in binary mode\n\
|
||||
"), stdout);
|
||||
printf (_("\
|
||||
-c, --check read %s sums from the FILEs and check them\n"),
|
||||
DIGEST_TYPE_STRING);
|
||||
DIGEST_TYPE_STRING);
|
||||
if (O_BINARY)
|
||||
fputs (_("\
|
||||
fputs (_("\
|
||||
-t, --text read in text mode (default if reading tty stdin)\n\
|
||||
"), stdout);
|
||||
else
|
||||
fputs (_("\
|
||||
fputs (_("\
|
||||
-t, --text read in text mode (default)\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
@@ -194,8 +194,8 @@ The sums are computed as described in %s. When checking, the input\n\
|
||||
should be a former output of this program. The default mode is to print\n\
|
||||
a line with checksum, a character indicating type (`*' for binary, ` ' for\n\
|
||||
text), and name for each FILE.\n"),
|
||||
DIGEST_REFERENCE);
|
||||
emit_bug_reporting_address ();
|
||||
DIGEST_REFERENCE);
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
|
||||
exit (status);
|
||||
@@ -249,7 +249,7 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name
|
||||
|
||||
static bool
|
||||
split_3 (char *s, size_t s_len,
|
||||
unsigned char **hex_digest, int *binary, char **file_name)
|
||||
unsigned char **hex_digest, int *binary, char **file_name)
|
||||
{
|
||||
size_t i;
|
||||
bool escaped_filename = false;
|
||||
@@ -264,12 +264,12 @@ split_3 (char *s, size_t s_len,
|
||||
if (strncmp (s + i, DIGEST_TYPE_STRING, algo_name_len) == 0)
|
||||
{
|
||||
if (strncmp (s + i + algo_name_len, " (", 2) == 0)
|
||||
{
|
||||
*binary = 0;
|
||||
return bsd_split_3 (s + i + algo_name_len + 2,
|
||||
s_len - (i + algo_name_len + 2),
|
||||
hex_digest, file_name);
|
||||
}
|
||||
{
|
||||
*binary = 0;
|
||||
return bsd_split_3 (s + i + algo_name_len + 2,
|
||||
s_len - (i + algo_name_len + 2),
|
||||
hex_digest, file_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore this line if it is too short.
|
||||
@@ -306,45 +306,45 @@ split_3 (char *s, size_t s_len,
|
||||
if (escaped_filename)
|
||||
{
|
||||
/* Translate each `\n' string in the file name to a NEWLINE,
|
||||
and each `\\' string to a backslash. */
|
||||
and each `\\' string to a backslash. */
|
||||
|
||||
char *dst = &s[i];
|
||||
|
||||
while (i < s_len)
|
||||
{
|
||||
switch (s[i])
|
||||
{
|
||||
case '\\':
|
||||
if (i == s_len - 1)
|
||||
{
|
||||
/* A valid line does not end with a backslash. */
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
switch (s[i++])
|
||||
{
|
||||
case 'n':
|
||||
*dst++ = '\n';
|
||||
break;
|
||||
case '\\':
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
default:
|
||||
/* Only `\' or `n' may follow a backslash. */
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
{
|
||||
switch (s[i])
|
||||
{
|
||||
case '\\':
|
||||
if (i == s_len - 1)
|
||||
{
|
||||
/* A valid line does not end with a backslash. */
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
switch (s[i++])
|
||||
{
|
||||
case 'n':
|
||||
*dst++ = '\n';
|
||||
break;
|
||||
case '\\':
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
default:
|
||||
/* Only `\' or `n' may follow a backslash. */
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
/* The file name may not contain a NUL. */
|
||||
return false;
|
||||
break;
|
||||
case '\0':
|
||||
/* The file name may not contain a NUL. */
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
*dst++ = s[i++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
*dst++ = s[i++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
return true;
|
||||
@@ -388,21 +388,21 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
|
||||
have_read_stdin = true;
|
||||
fp = stdin;
|
||||
if (O_BINARY && *binary)
|
||||
{
|
||||
if (*binary < 0)
|
||||
*binary = ! isatty (STDIN_FILENO);
|
||||
if (*binary)
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
{
|
||||
if (*binary < 0)
|
||||
*binary = ! isatty (STDIN_FILENO);
|
||||
if (*binary)
|
||||
xfreopen (NULL, "rb", stdin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
|
||||
if (fp == NULL)
|
||||
{
|
||||
error (0, errno, "%s", filename);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
err = DIGEST_STREAM (fp, bin_result);
|
||||
@@ -410,7 +410,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
|
||||
{
|
||||
error (0, errno, "%s", filename);
|
||||
if (fp != stdin)
|
||||
fclose (fp);
|
||||
fclose (fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -448,10 +448,10 @@ digest_check (const char *checkfile_name)
|
||||
{
|
||||
checkfile_stream = fopen (checkfile_name, "r");
|
||||
if (checkfile_stream == NULL)
|
||||
{
|
||||
error (0, errno, "%s", checkfile_name);
|
||||
return false;
|
||||
}
|
||||
{
|
||||
error (0, errno, "%s", checkfile_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
line_number = 0;
|
||||
@@ -466,82 +466,82 @@ digest_check (const char *checkfile_name)
|
||||
|
||||
++line_number;
|
||||
if (line_number == 0)
|
||||
error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
|
||||
checkfile_name);
|
||||
error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
|
||||
checkfile_name);
|
||||
|
||||
line_length = getline (&line, &line_chars_allocated, checkfile_stream);
|
||||
if (line_length <= 0)
|
||||
break;
|
||||
break;
|
||||
|
||||
/* Ignore comment lines, which begin with a '#' character. */
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* Remove any trailing newline. */
|
||||
if (line[line_length - 1] == '\n')
|
||||
line[--line_length] = '\0';
|
||||
line[--line_length] = '\0';
|
||||
|
||||
if (! (split_3 (line, line_length, &hex_digest, &binary, &filename)
|
||||
&& ! (is_stdin && STREQ (filename, "-"))
|
||||
&& hex_digits (hex_digest)))
|
||||
{
|
||||
if (warn)
|
||||
{
|
||||
error (0, 0,
|
||||
_("%s: %" PRIuMAX
|
||||
": improperly formatted %s checksum line"),
|
||||
checkfile_name, line_number,
|
||||
DIGEST_TYPE_STRING);
|
||||
}
|
||||
}
|
||||
&& ! (is_stdin && STREQ (filename, "-"))
|
||||
&& hex_digits (hex_digest)))
|
||||
{
|
||||
if (warn)
|
||||
{
|
||||
error (0, 0,
|
||||
_("%s: %" PRIuMAX
|
||||
": improperly formatted %s checksum line"),
|
||||
checkfile_name, line_number,
|
||||
DIGEST_TYPE_STRING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char bin2hex[] = { '0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f' };
|
||||
bool ok;
|
||||
{
|
||||
static const char bin2hex[] = { '0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f' };
|
||||
bool ok;
|
||||
|
||||
++n_properly_formatted_lines;
|
||||
++n_properly_formatted_lines;
|
||||
|
||||
ok = digest_file (filename, &binary, bin_buffer);
|
||||
ok = digest_file (filename, &binary, bin_buffer);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
++n_open_or_read_failures;
|
||||
if (!status_only)
|
||||
{
|
||||
printf (_("%s: FAILED open or read\n"), filename);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t digest_bin_bytes = digest_hex_bytes / 2;
|
||||
size_t cnt;
|
||||
/* Compare generated binary number with text representation
|
||||
in check file. Ignore case of hex digits. */
|
||||
for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
|
||||
{
|
||||
if (tolower (hex_digest[2 * cnt])
|
||||
!= bin2hex[bin_buffer[cnt] >> 4]
|
||||
|| (tolower (hex_digest[2 * cnt + 1])
|
||||
!= (bin2hex[bin_buffer[cnt] & 0xf])))
|
||||
break;
|
||||
}
|
||||
if (cnt != digest_bin_bytes)
|
||||
++n_mismatched_checksums;
|
||||
if (!ok)
|
||||
{
|
||||
++n_open_or_read_failures;
|
||||
if (!status_only)
|
||||
{
|
||||
printf (_("%s: FAILED open or read\n"), filename);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t digest_bin_bytes = digest_hex_bytes / 2;
|
||||
size_t cnt;
|
||||
/* Compare generated binary number with text representation
|
||||
in check file. Ignore case of hex digits. */
|
||||
for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
|
||||
{
|
||||
if (tolower (hex_digest[2 * cnt])
|
||||
!= bin2hex[bin_buffer[cnt] >> 4]
|
||||
|| (tolower (hex_digest[2 * cnt + 1])
|
||||
!= (bin2hex[bin_buffer[cnt] & 0xf])))
|
||||
break;
|
||||
}
|
||||
if (cnt != digest_bin_bytes)
|
||||
++n_mismatched_checksums;
|
||||
|
||||
if (!status_only)
|
||||
{
|
||||
if (cnt != digest_bin_bytes)
|
||||
printf ("%s: %s\n", filename, _("FAILED"));
|
||||
else if (!quiet)
|
||||
printf ("%s: %s\n", filename, _("OK"));
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!status_only)
|
||||
{
|
||||
if (cnt != digest_bin_bytes)
|
||||
printf ("%s: %s\n", filename, _("FAILED"));
|
||||
else if (!quiet)
|
||||
printf ("%s: %s\n", filename, _("OK"));
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!feof (checkfile_stream) && !ferror (checkfile_stream));
|
||||
|
||||
@@ -563,39 +563,39 @@ digest_check (const char *checkfile_name)
|
||||
{
|
||||
/* Warn if no tests are found. */
|
||||
error (0, 0, _("%s: no properly formatted %s checksum lines found"),
|
||||
checkfile_name, DIGEST_TYPE_STRING);
|
||||
checkfile_name, DIGEST_TYPE_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!status_only)
|
||||
{
|
||||
if (n_open_or_read_failures != 0)
|
||||
error (0, 0,
|
||||
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" listed file could not be read",
|
||||
"WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" listed files could not be read",
|
||||
select_plural (n_properly_formatted_lines)),
|
||||
n_open_or_read_failures, n_properly_formatted_lines);
|
||||
{
|
||||
if (n_open_or_read_failures != 0)
|
||||
error (0, 0,
|
||||
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" listed file could not be read",
|
||||
"WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" listed files could not be read",
|
||||
select_plural (n_properly_formatted_lines)),
|
||||
n_open_or_read_failures, n_properly_formatted_lines);
|
||||
|
||||
if (n_mismatched_checksums != 0)
|
||||
{
|
||||
uintmax_t n_computed_checksums =
|
||||
(n_properly_formatted_lines - n_open_or_read_failures);
|
||||
error (0, 0,
|
||||
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" computed checksum did NOT match",
|
||||
"WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" computed checksums did NOT match",
|
||||
select_plural (n_computed_checksums)),
|
||||
n_mismatched_checksums, n_computed_checksums);
|
||||
}
|
||||
}
|
||||
if (n_mismatched_checksums != 0)
|
||||
{
|
||||
uintmax_t n_computed_checksums =
|
||||
(n_properly_formatted_lines - n_open_or_read_failures);
|
||||
error (0, 0,
|
||||
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" computed checksum did NOT match",
|
||||
"WARNING: %" PRIuMAX " of %" PRIuMAX
|
||||
" computed checksums did NOT match",
|
||||
select_plural (n_computed_checksums)),
|
||||
n_mismatched_checksums, n_computed_checksums);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (n_properly_formatted_lines != 0
|
||||
&& n_mismatched_checksums == 0
|
||||
&& n_open_or_read_failures == 0);
|
||||
&& n_mismatched_checksums == 0
|
||||
&& n_open_or_read_failures == 0);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -622,33 +622,33 @@ main (int argc, char **argv)
|
||||
switch (opt)
|
||||
{
|
||||
case 'b':
|
||||
binary = 1;
|
||||
break;
|
||||
binary = 1;
|
||||
break;
|
||||
case 'c':
|
||||
do_check = true;
|
||||
break;
|
||||
do_check = true;
|
||||
break;
|
||||
case STATUS_OPTION:
|
||||
status_only = true;
|
||||
warn = false;
|
||||
quiet = false;
|
||||
break;
|
||||
status_only = true;
|
||||
warn = false;
|
||||
quiet = false;
|
||||
break;
|
||||
case 't':
|
||||
binary = 0;
|
||||
break;
|
||||
binary = 0;
|
||||
break;
|
||||
case 'w':
|
||||
status_only = false;
|
||||
warn = true;
|
||||
quiet = false;
|
||||
break;
|
||||
status_only = false;
|
||||
warn = true;
|
||||
quiet = false;
|
||||
break;
|
||||
case QUIET_OPTION:
|
||||
status_only = false;
|
||||
warn = false;
|
||||
quiet = true;
|
||||
break;
|
||||
status_only = false;
|
||||
warn = false;
|
||||
quiet = true;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
|
||||
@@ -657,25 +657,25 @@ main (int argc, char **argv)
|
||||
if (0 <= binary && do_check)
|
||||
{
|
||||
error (0, 0, _("the --binary and --text options are meaningless when "
|
||||
"verifying checksums"));
|
||||
"verifying checksums"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (status_only & !do_check)
|
||||
if (status_only && !do_check)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the --status option is meaningful only when verifying checksums"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (warn & !do_check)
|
||||
if (warn && !do_check)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the --warn option is meaningful only when verifying checksums"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (quiet & !do_check)
|
||||
if (quiet && !do_check)
|
||||
{
|
||||
error (0, 0,
|
||||
_("the --quiet option is meaningful only when verifying checksums"));
|
||||
@@ -693,53 +693,53 @@ main (int argc, char **argv)
|
||||
char *file = argv[optind];
|
||||
|
||||
if (do_check)
|
||||
ok &= digest_check (file);
|
||||
ok &= digest_check (file);
|
||||
else
|
||||
{
|
||||
int file_is_binary = binary;
|
||||
{
|
||||
int file_is_binary = binary;
|
||||
|
||||
if (! digest_file (file, &file_is_binary, bin_buffer))
|
||||
ok = false;
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
if (! digest_file (file, &file_is_binary, bin_buffer))
|
||||
ok = false;
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Output a leading backslash if the file name contains
|
||||
a newline or backslash. */
|
||||
if (strchr (file, '\n') || strchr (file, '\\'))
|
||||
putchar ('\\');
|
||||
/* Output a leading backslash if the file name contains
|
||||
a newline or backslash. */
|
||||
if (strchr (file, '\n') || strchr (file, '\\'))
|
||||
putchar ('\\');
|
||||
|
||||
for (i = 0; i < (digest_hex_bytes / 2); ++i)
|
||||
printf ("%02x", bin_buffer[i]);
|
||||
for (i = 0; i < (digest_hex_bytes / 2); ++i)
|
||||
printf ("%02x", bin_buffer[i]);
|
||||
|
||||
putchar (' ');
|
||||
if (file_is_binary)
|
||||
putchar ('*');
|
||||
else
|
||||
putchar (' ');
|
||||
putchar (' ');
|
||||
if (file_is_binary)
|
||||
putchar ('*');
|
||||
else
|
||||
putchar (' ');
|
||||
|
||||
/* Translate each NEWLINE byte to the string, "\\n",
|
||||
and each backslash to "\\\\". */
|
||||
for (i = 0; i < strlen (file); ++i)
|
||||
{
|
||||
switch (file[i])
|
||||
{
|
||||
case '\n':
|
||||
fputs ("\\n", stdout);
|
||||
break;
|
||||
/* Translate each NEWLINE byte to the string, "\\n",
|
||||
and each backslash to "\\\\". */
|
||||
for (i = 0; i < strlen (file); ++i)
|
||||
{
|
||||
switch (file[i])
|
||||
{
|
||||
case '\n':
|
||||
fputs ("\\n", stdout);
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
fputs ("\\\\", stdout);
|
||||
break;
|
||||
case '\\':
|
||||
fputs ("\\\\", stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
putchar (file[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
default:
|
||||
putchar (file[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (have_read_stdin && fclose (stdin) == EOF)
|
||||
|
||||
74
src/mkdir.c
74
src/mkdir.c
@@ -51,7 +51,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... DIRECTORY...\n"), program_name);
|
||||
@@ -71,7 +71,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -129,10 +129,10 @@ process_dir (char *dir, struct savewd *wd, void *options)
|
||||
{
|
||||
struct mkdir_options const *o = options;
|
||||
return (make_dir_parents (dir, wd, o->make_ancestor_function, options,
|
||||
o->mode, announce_mkdir,
|
||||
o->mode_bits, (uid_t) -1, (gid_t) -1, true)
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE);
|
||||
o->mode, announce_mkdir,
|
||||
o->mode_bits, (uid_t) -1, (gid_t) -1, true)
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -159,24 +159,24 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "pm:vZ:", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'p':
|
||||
options.make_ancestor_function = make_ancestor;
|
||||
break;
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'v': /* --verbose */
|
||||
options.created_directory_format = _("created directory %s");
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'p':
|
||||
options.make_ancestor_function = make_ancestor;
|
||||
break;
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'v': /* --verbose */
|
||||
options.created_directory_format = _("created directory %s");
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
@@ -187,8 +187,8 @@ main (int argc, char **argv)
|
||||
|
||||
if (scontext && setfscreatecon (scontext) < 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
|
||||
if (options.make_ancestor_function || specified_mode)
|
||||
{
|
||||
@@ -197,19 +197,19 @@ main (int argc, char **argv)
|
||||
options.ancestor_mode = (S_IRWXUGO & ~umask_value) | (S_IWUSR | S_IXUSR);
|
||||
|
||||
if (specified_mode)
|
||||
{
|
||||
struct mode_change *change = mode_compile (specified_mode);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, 0, _("invalid mode %s"),
|
||||
quote (specified_mode));
|
||||
options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change,
|
||||
&options.mode_bits);
|
||||
free (change);
|
||||
}
|
||||
{
|
||||
struct mode_change *change = mode_compile (specified_mode);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, 0, _("invalid mode %s"),
|
||||
quote (specified_mode));
|
||||
options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change,
|
||||
&options.mode_bits);
|
||||
free (change);
|
||||
}
|
||||
else
|
||||
options.mode = S_IRWXUGO & ~umask_value;
|
||||
options.mode = S_IRWXUGO & ~umask_value;
|
||||
}
|
||||
|
||||
exit (savewd_process_files (argc - optind, argv + optind,
|
||||
process_dir, &options));
|
||||
process_dir, &options));
|
||||
}
|
||||
|
||||
42
src/mkfifo.c
42
src/mkfifo.c
@@ -46,7 +46,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... NAME...\n"), program_name);
|
||||
@@ -65,7 +65,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -90,18 +90,18 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
@@ -112,27 +112,27 @@ main (int argc, char **argv)
|
||||
|
||||
if (scontext && setfscreatecon (scontext) < 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
|
||||
newmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if (specified_mode)
|
||||
{
|
||||
struct mode_change *change = mode_compile (specified_mode);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, 0, _("invalid mode"));
|
||||
error (EXIT_FAILURE, 0, _("invalid mode"));
|
||||
newmode = mode_adjust (newmode, false, umask (0), change, NULL);
|
||||
free (change);
|
||||
if (newmode & ~S_IRWXUGO)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("mode must specify only file permission bits"));
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("mode must specify only file permission bits"));
|
||||
}
|
||||
|
||||
for (; optind < argc; ++optind)
|
||||
if (mkfifo (argv[optind], newmode) != 0)
|
||||
{
|
||||
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
|
||||
exit_status = EXIT_FAILURE;
|
||||
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
|
||||
exit_status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
exit (exit_status);
|
||||
|
||||
94
src/mknod.c
94
src/mknod.c
@@ -47,11 +47,11 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... NAME TYPE [MAJOR MINOR]\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
fputs (_("\
|
||||
Create the special file NAME of the given TYPE.\n\
|
||||
\n\
|
||||
@@ -81,7 +81,7 @@ otherwise, as decimal. TYPE may be:\n\
|
||||
p create a FIFO\n\
|
||||
"), stdout);
|
||||
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -107,18 +107,18 @@ main (int argc, char **argv)
|
||||
while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'm':
|
||||
specified_mode = optarg;
|
||||
break;
|
||||
case 'Z':
|
||||
scontext = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
newmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
@@ -126,47 +126,47 @@ main (int argc, char **argv)
|
||||
{
|
||||
struct mode_change *change = mode_compile (specified_mode);
|
||||
if (!change)
|
||||
error (EXIT_FAILURE, 0, _("invalid mode"));
|
||||
error (EXIT_FAILURE, 0, _("invalid mode"));
|
||||
newmode = mode_adjust (newmode, false, umask (0), change, NULL);
|
||||
free (change);
|
||||
if (newmode & ~S_IRWXUGO)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("mode must specify only file permission bits"));
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("mode must specify only file permission bits"));
|
||||
}
|
||||
|
||||
/* If the number of arguments is 0 or 1,
|
||||
or (if it's 2 or more and the second one starts with `p'), then there
|
||||
must be exactly two operands. Otherwise, there must be four. */
|
||||
expected_operands = (argc <= optind
|
||||
|| (optind + 1 < argc && argv[optind + 1][0] == 'p')
|
||||
? 2 : 4);
|
||||
|| (optind + 1 < argc && argv[optind + 1][0] == 'p')
|
||||
? 2 : 4);
|
||||
|
||||
if (argc - optind < expected_operands)
|
||||
{
|
||||
if (argc <= optind)
|
||||
error (0, 0, _("missing operand"));
|
||||
error (0, 0, _("missing operand"));
|
||||
else
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
|
||||
if (expected_operands == 4 && argc - optind == 2)
|
||||
fprintf (stderr, "%s\n",
|
||||
_("Special files require major and minor device numbers."));
|
||||
fprintf (stderr, "%s\n",
|
||||
_("Special files require major and minor device numbers."));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (expected_operands < argc - optind)
|
||||
{
|
||||
error (0, 0, _("extra operand %s"),
|
||||
quote (argv[optind + expected_operands]));
|
||||
quote (argv[optind + expected_operands]));
|
||||
if (expected_operands == 2 && argc - optind == 4)
|
||||
fprintf (stderr, "%s\n",
|
||||
_("Fifos do not have major and minor device numbers."));
|
||||
fprintf (stderr, "%s\n",
|
||||
_("Fifos do not have major and minor device numbers."));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (scontext && setfscreatecon (scontext) < 0)
|
||||
error (EXIT_FAILURE, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (scontext));
|
||||
|
||||
/* Only check the first character, to allow mnemonic usage like
|
||||
`mknod /dev/rst0 character 18 0'. */
|
||||
@@ -192,35 +192,35 @@ main (int argc, char **argv)
|
||||
|
||||
block_or_character:
|
||||
{
|
||||
char const *s_major = argv[optind + 2];
|
||||
char const *s_minor = argv[optind + 3];
|
||||
uintmax_t i_major, i_minor;
|
||||
dev_t device;
|
||||
char const *s_major = argv[optind + 2];
|
||||
char const *s_minor = argv[optind + 3];
|
||||
uintmax_t i_major, i_minor;
|
||||
dev_t device;
|
||||
|
||||
if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
|
||||
|| i_major != (major_t) i_major)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid major device number %s"), quote (s_major));
|
||||
if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
|
||||
|| i_major != (major_t) i_major)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid major device number %s"), quote (s_major));
|
||||
|
||||
if (xstrtoumax (s_minor, NULL, 0, &i_minor, NULL) != LONGINT_OK
|
||||
|| i_minor != (minor_t) i_minor)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid minor device number %s"), quote (s_minor));
|
||||
if (xstrtoumax (s_minor, NULL, 0, &i_minor, NULL) != LONGINT_OK
|
||||
|| i_minor != (minor_t) i_minor)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid minor device number %s"), quote (s_minor));
|
||||
|
||||
device = makedev (i_major, i_minor);
|
||||
device = makedev (i_major, i_minor);
|
||||
#ifdef NODEV
|
||||
if (device == NODEV)
|
||||
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
|
||||
if (device == NODEV)
|
||||
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
|
||||
#endif
|
||||
|
||||
if (mknod (argv[optind], newmode | node_type, device) != 0)
|
||||
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
|
||||
if (mknod (argv[optind], newmode | node_type, device) != 0)
|
||||
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p': /* `pipe' */
|
||||
if (mkfifo (argv[optind], newmode) != 0)
|
||||
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
|
||||
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
12
src/mktemp.c
12
src/mktemp.c
@@ -95,7 +95,7 @@ If TEMPLATE is not specified, use tmp.XXXXXXXXXX.\n\
|
||||
fputs ("\n", stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
|
||||
exit (status);
|
||||
@@ -114,13 +114,13 @@ count_trailing_X_s (const char *s)
|
||||
static int
|
||||
mkstemp_len (char *tmpl, size_t suff_len, bool dry_run)
|
||||
{
|
||||
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
|
||||
return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
|
||||
}
|
||||
|
||||
static int
|
||||
mkdtemp_len (char *tmpl, size_t suff_len, bool dry_run)
|
||||
{
|
||||
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
|
||||
return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -286,9 +286,3 @@ main (int argc, char **argv)
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
257
src/mv.c
257
src/mv.c
@@ -94,7 +94,7 @@ rm_option_init (struct rm_options *x)
|
||||
x->root_dev_ino = get_root_dev_ino (&dev_ino_buf);
|
||||
if (x->root_dev_ino == NULL)
|
||||
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
|
||||
quote ("/"));
|
||||
quote ("/"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ cp_option_init (struct cp_options *x)
|
||||
|
||||
cp_options_default (x);
|
||||
x->copy_as_regular = false; /* FIXME: maybe make this an option */
|
||||
x->reflink = false;
|
||||
x->reflink_mode = REFLINK_NEVER;
|
||||
x->dereference = DEREF_NEVER;
|
||||
x->unlink_dest_before_opening = false;
|
||||
x->unlink_dest_after_failed_open = false;
|
||||
@@ -167,67 +167,70 @@ do_move (const char *source, const char *dest, const struct cp_options *x)
|
||||
{
|
||||
char const *dir_to_remove;
|
||||
if (copy_into_self)
|
||||
{
|
||||
/* In general, when copy returns with copy_into_self set, SOURCE is
|
||||
the same as, or a parent of DEST. In this case we know it's a
|
||||
parent. It doesn't make sense to move a directory into itself, and
|
||||
besides in some situations doing so would give highly nonintuitive
|
||||
results. Run this `mkdir b; touch a c; mv * b' in an empty
|
||||
directory. Here's the result of running echo `find b -print`:
|
||||
b b/a b/b b/b/a b/c. Notice that only file `a' was copied
|
||||
into b/b. Handle this by giving a diagnostic, removing the
|
||||
copied-into-self directory, DEST (`b/b' in the example),
|
||||
and failing. */
|
||||
{
|
||||
/* In general, when copy returns with copy_into_self set, SOURCE is
|
||||
the same as, or a parent of DEST. In this case we know it's a
|
||||
parent. It doesn't make sense to move a directory into itself, and
|
||||
besides in some situations doing so would give highly nonintuitive
|
||||
results. Run this `mkdir b; touch a c; mv * b' in an empty
|
||||
directory. Here's the result of running echo `find b -print`:
|
||||
b b/a b/b b/b/a b/c. Notice that only file `a' was copied
|
||||
into b/b. Handle this by giving a diagnostic, removing the
|
||||
copied-into-self directory, DEST (`b/b' in the example),
|
||||
and failing. */
|
||||
|
||||
dir_to_remove = NULL;
|
||||
ok = false;
|
||||
}
|
||||
dir_to_remove = NULL;
|
||||
ok = false;
|
||||
}
|
||||
else if (rename_succeeded)
|
||||
{
|
||||
/* No need to remove anything. SOURCE was successfully
|
||||
renamed to DEST. Or the user declined to rename a file. */
|
||||
dir_to_remove = NULL;
|
||||
}
|
||||
{
|
||||
/* No need to remove anything. SOURCE was successfully
|
||||
renamed to DEST. Or the user declined to rename a file. */
|
||||
dir_to_remove = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This may mean SOURCE and DEST referred to different devices.
|
||||
It may also conceivably mean that even though they referred
|
||||
to the same device, rename wasn't implemented for that device.
|
||||
{
|
||||
/* This may mean SOURCE and DEST referred to different devices.
|
||||
It may also conceivably mean that even though they referred
|
||||
to the same device, rename wasn't implemented for that device.
|
||||
|
||||
E.g., (from Joel N. Weber),
|
||||
[...] there might someday be cases where you can't rename
|
||||
but you can copy where the device name is the same, especially
|
||||
on Hurd. Consider an ftpfs with a primitive ftp server that
|
||||
supports uploading, downloading and deleting, but not renaming.
|
||||
E.g., (from Joel N. Weber),
|
||||
[...] there might someday be cases where you can't rename
|
||||
but you can copy where the device name is the same, especially
|
||||
on Hurd. Consider an ftpfs with a primitive ftp server that
|
||||
supports uploading, downloading and deleting, but not renaming.
|
||||
|
||||
Also, note that comparing device numbers is not a reliable
|
||||
check for `can-rename'. Some systems can be set up so that
|
||||
files from many different physical devices all have the same
|
||||
st_dev field. This is a feature of some NFS mounting
|
||||
configurations.
|
||||
Also, note that comparing device numbers is not a reliable
|
||||
check for `can-rename'. Some systems can be set up so that
|
||||
files from many different physical devices all have the same
|
||||
st_dev field. This is a feature of some NFS mounting
|
||||
configurations.
|
||||
|
||||
We reach this point if SOURCE has been successfully copied
|
||||
to DEST. Now we have to remove SOURCE.
|
||||
We reach this point if SOURCE has been successfully copied
|
||||
to DEST. Now we have to remove SOURCE.
|
||||
|
||||
This function used to resort to copying only when rename
|
||||
failed and set errno to EXDEV. */
|
||||
This function used to resort to copying only when rename
|
||||
failed and set errno to EXDEV. */
|
||||
|
||||
dir_to_remove = source;
|
||||
}
|
||||
dir_to_remove = source;
|
||||
}
|
||||
|
||||
if (dir_to_remove != NULL)
|
||||
{
|
||||
struct rm_options rm_options;
|
||||
enum RM_status status;
|
||||
{
|
||||
struct rm_options rm_options;
|
||||
enum RM_status status;
|
||||
char const *dir[2];
|
||||
|
||||
rm_option_init (&rm_options);
|
||||
rm_options.verbose = x->verbose;
|
||||
rm_option_init (&rm_options);
|
||||
rm_options.verbose = x->verbose;
|
||||
dir[0] = dir_to_remove;
|
||||
dir[1] = NULL;
|
||||
|
||||
status = rm (1, &dir_to_remove, &rm_options);
|
||||
assert (VALID_STATUS (status));
|
||||
if (status == RM_ERROR)
|
||||
ok = false;
|
||||
}
|
||||
status = rm ((void*) dir, &rm_options);
|
||||
assert (VALID_STATUS (status));
|
||||
if (status == RM_ERROR)
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
@@ -239,7 +242,7 @@ do_move (const char *source, const char *dest, const struct cp_options *x)
|
||||
|
||||
static bool
|
||||
movefile (char *source, char *dest, bool dest_is_dir,
|
||||
const struct cp_options *x)
|
||||
const struct cp_options *x)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
@@ -275,7 +278,7 @@ usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
@@ -283,7 +286,7 @@ Usage: %s [OPTION]... [-T] SOURCE DEST\n\
|
||||
or: %s [OPTION]... SOURCE... DIRECTORY\n\
|
||||
or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
|
||||
"),
|
||||
program_name, program_name, program_name);
|
||||
program_name, program_name, program_name);
|
||||
fputs (_("\
|
||||
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\
|
||||
\n\
|
||||
@@ -327,7 +330,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
|
||||
existing, nil numbered if numbered backups exist, simple otherwise\n\
|
||||
simple, never always make simple backups\n\
|
||||
"), stdout);
|
||||
emit_bug_reporting_address ();
|
||||
emit_ancillary_info ();
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
@@ -364,59 +367,59 @@ main (int argc, char **argv)
|
||||
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
|
||||
|
||||
while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL))
|
||||
!= -1)
|
||||
!= -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
x.interactive = I_ALWAYS_YES;
|
||||
break;
|
||||
case 'i':
|
||||
x.interactive = I_ASK_USER;
|
||||
break;
|
||||
case 'n':
|
||||
x.interactive = I_ALWAYS_NO;
|
||||
break;
|
||||
case STRIP_TRAILING_SLASHES_OPTION:
|
||||
remove_trailing_slashes = true;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
case 'u':
|
||||
x.update = true;
|
||||
break;
|
||||
case 'v':
|
||||
x.verbose = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
case 'b':
|
||||
make_backups = true;
|
||||
if (optarg)
|
||||
version_control_string = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
x.interactive = I_ALWAYS_YES;
|
||||
break;
|
||||
case 'i':
|
||||
x.interactive = I_ASK_USER;
|
||||
break;
|
||||
case 'n':
|
||||
x.interactive = I_ALWAYS_NO;
|
||||
break;
|
||||
case STRIP_TRAILING_SLASHES_OPTION:
|
||||
remove_trailing_slashes = true;
|
||||
break;
|
||||
case 't':
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (stat (optarg, &st) != 0)
|
||||
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (optarg));
|
||||
}
|
||||
target_directory = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
no_target_directory = true;
|
||||
break;
|
||||
case 'u':
|
||||
x.update = true;
|
||||
break;
|
||||
case 'v':
|
||||
x.verbose = true;
|
||||
break;
|
||||
case 'S':
|
||||
make_backups = true;
|
||||
backup_suffix_string = optarg;
|
||||
break;
|
||||
case_GETOPT_HELP_CHAR;
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
n_files = argc - optind;
|
||||
@@ -425,39 +428,39 @@ main (int argc, char **argv)
|
||||
if (n_files <= !target_directory)
|
||||
{
|
||||
if (n_files <= 0)
|
||||
error (0, 0, _("missing file operand"));
|
||||
error (0, 0, _("missing file operand"));
|
||||
else
|
||||
error (0, 0, _("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
error (0, 0, _("missing destination file operand after %s"),
|
||||
quote (file[0]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (no_target_directory)
|
||||
{
|
||||
if (target_directory)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory (-t) "
|
||||
"and --no-target-directory (-T)"));
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("cannot combine --target-directory (-t) "
|
||||
"and --no-target-directory (-T)"));
|
||||
if (2 < n_files)
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
error (0, 0, _("extra operand %s"), quote (file[2]));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (!target_directory)
|
||||
{
|
||||
assert (2 <= n_files);
|
||||
if (target_directory_operand (file[n_files - 1]))
|
||||
target_directory = file[--n_files];
|
||||
target_directory = file[--n_files];
|
||||
else if (2 < n_files)
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
|
||||
quote (file[n_files - 1]));
|
||||
}
|
||||
|
||||
if (make_backups && x.interactive == I_ALWAYS_NO)
|
||||
{
|
||||
error (0, 0,
|
||||
_("options --backup and --no-clobber are mutually exclusive"));
|
||||
_("options --backup and --no-clobber are mutually exclusive"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -465,9 +468,9 @@ main (int argc, char **argv)
|
||||
simple_backup_suffix = xstrdup (backup_suffix_string);
|
||||
|
||||
x.backup_type = (make_backups
|
||||
? xget_version (_("backup type"),
|
||||
version_control_string)
|
||||
: no_backups);
|
||||
? xget_version (_("backup type"),
|
||||
version_control_string)
|
||||
: no_backups);
|
||||
|
||||
hash_init ();
|
||||
|
||||
@@ -476,14 +479,14 @@ main (int argc, char **argv)
|
||||
int i;
|
||||
|
||||
/* Initialize the hash table only if we'll need it.
|
||||
The problem it is used to detect can arise only if there are
|
||||
two or more files to move. */
|
||||
The problem it is used to detect can arise only if there are
|
||||
two or more files to move. */
|
||||
if (2 <= n_files)
|
||||
dest_info_init (&x);
|
||||
dest_info_init (&x);
|
||||
|
||||
ok = true;
|
||||
for (i = 0; i < n_files; ++i)
|
||||
ok &= movefile (file[i], target_directory, true, &x);
|
||||
ok &= movefile (file[i], target_directory, true, &x);
|
||||
}
|
||||
else
|
||||
ok = movefile (file[0], file[1], false, &x);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user