mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
317 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70d023b076 | ||
|
|
ca39c9c308 | ||
|
|
fc4d3f63b0 | ||
|
|
3df2108b0d | ||
|
|
829c418d67 | ||
|
|
06e9880c8e | ||
|
|
bb4cb10e89 | ||
|
|
23c0cecaa8 | ||
|
|
19b460b239 | ||
|
|
0f8bb24ca8 | ||
|
|
321d2901de | ||
|
|
f5a97b8269 | ||
|
|
73d4626134 | ||
|
|
7ac41f9950 | ||
|
|
dcff25a925 | ||
|
|
7a2b0b8f66 | ||
|
|
ae034822c5 | ||
|
|
d8cadda3b9 | ||
|
|
afd087d414 | ||
|
|
9b4b38f56e | ||
|
|
5224fbd6f9 | ||
|
|
d16a8f6c7f | ||
|
|
0dc1f4c6f3 | ||
|
|
cb775df09e | ||
|
|
b92e0455e1 | ||
|
|
3910144405 | ||
|
|
4bb812ad49 | ||
|
|
b498c58013 | ||
|
|
f9d0bb8481 | ||
|
|
ab6b27eba7 | ||
|
|
9cf9f8e1e0 | ||
|
|
ad1f07b3c4 | ||
|
|
ddea7b1078 | ||
|
|
5eb8d60e6d | ||
|
|
395b1c9375 | ||
|
|
2f2112335c | ||
|
|
30eb606ed5 | ||
|
|
f18eef3284 | ||
|
|
e246d654f3 | ||
|
|
447d245551 | ||
|
|
fee722471c | ||
|
|
630f4ba107 | ||
|
|
2fccfaab19 | ||
|
|
2b18a4c138 | ||
|
|
6609ccbf87 | ||
|
|
d863533752 | ||
|
|
bf5af9aef8 | ||
|
|
161e5120d4 | ||
|
|
3b997a9bcb | ||
|
|
00f0cabaec | ||
|
|
5cf6fb3b12 | ||
|
|
9ed5048148 | ||
|
|
c3744b25f2 | ||
|
|
49741b61b7 | ||
|
|
9a91b2a928 | ||
|
|
4c9e7e01fa | ||
|
|
6a31fd8d73 | ||
|
|
719a95aa9d | ||
|
|
1313107c5c | ||
|
|
cf1bc9810d | ||
|
|
622cf39be6 | ||
|
|
3aff3ed137 | ||
|
|
10d97b3191 | ||
|
|
56b85e035b | ||
|
|
c768e2231b | ||
|
|
9a8d8f46a5 | ||
|
|
d9dbbb9a45 | ||
|
|
74cf4cb26d | ||
|
|
41456fac8a | ||
|
|
dde83c27b4 | ||
|
|
20e5a0d562 | ||
|
|
22e4276ed1 | ||
|
|
25d2460ae3 | ||
|
|
31a9937081 | ||
|
|
d431c61873 | ||
|
|
5f29d118df | ||
|
|
0c5ae3a8ac | ||
|
|
e89a5e9b13 | ||
|
|
bcca26e838 | ||
|
|
41b3a8ed8b | ||
|
|
cd65f11c4f | ||
|
|
8ba5d1a70c | ||
|
|
38cb824673 | ||
|
|
d4b96c26ce | ||
|
|
7bf2e3db23 | ||
|
|
87bf834dd3 | ||
|
|
8fe40b84bd | ||
|
|
565e5f6827 | ||
|
|
6eb457eaba | ||
|
|
a276ba2dd4 | ||
|
|
71c2f88155 | ||
|
|
3c88587b2e | ||
|
|
12a0a583f6 | ||
|
|
39da66f979 | ||
|
|
22776f84cb | ||
|
|
17b7d09bf2 | ||
|
|
f2859424cb | ||
|
|
56a66d78ff | ||
|
|
e26cb21e6b | ||
|
|
1c59bb3cef | ||
|
|
536a1fbe5f | ||
|
|
ce22916610 | ||
|
|
da17f99b20 | ||
|
|
c07b181396 | ||
|
|
2904d675a4 | ||
|
|
54491d2751 | ||
|
|
42d12b45d3 | ||
|
|
75efc921b0 | ||
|
|
d6de2f198e | ||
|
|
1a81342089 | ||
|
|
0cc0424119 | ||
|
|
f00bbe33e4 | ||
|
|
0f3f6bf6bf | ||
|
|
243f1b1c71 | ||
|
|
c6900474ef | ||
|
|
dae24f5ffc | ||
|
|
c695781753 | ||
|
|
d9cf7c911f | ||
|
|
50e837b1c4 | ||
|
|
501bf7b589 | ||
|
|
69fbfd400c | ||
|
|
30e4b6e84b | ||
|
|
2122247aca | ||
|
|
bd933c1250 | ||
|
|
1ce9e1e5ca | ||
|
|
b6540b96ba | ||
|
|
97777f559a | ||
|
|
c0dcf3238b | ||
|
|
a08e13a0fb | ||
|
|
5e361387d0 | ||
|
|
cbf36952d8 | ||
|
|
029b6b14c5 | ||
|
|
cd0f3036f6 | ||
|
|
9abbe32c2e | ||
|
|
54645c195c | ||
|
|
710fe413fe | ||
|
|
71adb516de | ||
|
|
6ac6c7e4b7 | ||
|
|
f26508204b | ||
|
|
9e13b6a0b4 | ||
|
|
527fb951de | ||
|
|
f8653f2af3 | ||
|
|
2fa407885c | ||
|
|
b3cfa712ca | ||
|
|
f25273d7f1 | ||
|
|
26e8e602a8 | ||
|
|
7280a913a1 | ||
|
|
7ff00ca82f | ||
|
|
f7b1873805 | ||
|
|
c2bebf63ed | ||
|
|
d74a1b005c | ||
|
|
4f1a3eda10 | ||
|
|
c9e7b8844b | ||
|
|
219f2f0538 | ||
|
|
78c9360178 | ||
|
|
0023f65fd7 | ||
|
|
57d9263ca5 | ||
|
|
e11a0319b3 | ||
|
|
c039c96449 | ||
|
|
aa092ccf6a | ||
|
|
2a876d901d | ||
|
|
a797c4d7d3 | ||
|
|
7a3bc1bf27 | ||
|
|
00674c7475 | ||
|
|
eb5f06f2a6 | ||
|
|
8e32390716 | ||
|
|
b95be30e3f | ||
|
|
d183a15cbb | ||
|
|
96829a9ff0 | ||
|
|
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
.gitattributes
vendored
2
.gitattributes
vendored
@@ -5,3 +5,5 @@
|
||||
# # Derived from the regexp in emacs' lisp/add-log.el.
|
||||
# [diff "texinfo"]
|
||||
# funcname = "^@node[ \t][ \t]*\\([^,][^,]*\\)"
|
||||
|
||||
gl/lib/*.diff -whitespace
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,9 +1,9 @@
|
||||
*.1
|
||||
*.I[12]
|
||||
*.[EIOX]
|
||||
*.o
|
||||
*/.deps
|
||||
*~
|
||||
._bootmp
|
||||
.gdb-history
|
||||
.kludge-stamp
|
||||
.tarball-version
|
||||
@@ -48,15 +48,18 @@ lib/arpa
|
||||
lib/binary-io.h
|
||||
lib/charset.alias
|
||||
lib/configmake.h
|
||||
lib/glthread
|
||||
lib/libcoreutils.a
|
||||
lib/printf.c
|
||||
lib/progname.c
|
||||
lib/progname.h
|
||||
lib/selinux
|
||||
lib/unistr
|
||||
lib/uniwidth
|
||||
m4/.cvsignore
|
||||
m4/.gitignore
|
||||
maint.mk
|
||||
man/*.1
|
||||
po/*.gmo
|
||||
po/*.po
|
||||
po/.gitignore
|
||||
@@ -72,3 +75,5 @@ src/version.c
|
||||
src/version.h
|
||||
stamp-h1
|
||||
tests/*/*.log
|
||||
tests/t?
|
||||
tests/test-suite.log
|
||||
|
||||
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
|
||||
8.1
|
||||
|
||||
3
.x-sc_prohibit_fail_0
Normal file
3
.x-sc_prohibit_fail_0
Normal file
@@ -0,0 +1,3 @@
|
||||
\.mk$
|
||||
/Makefile\.am$
|
||||
^tests/test-lib\.sh$
|
||||
3
.x-sc_prohibit_magic_number_exit
Normal file
3
.x-sc_prohibit_magic_number_exit
Normal file
@@ -0,0 +1,3 @@
|
||||
configure.ac
|
||||
*.m4
|
||||
ChangeLog*
|
||||
7
.x-sc_prohibit_tab_based_indentation
Normal file
7
.x-sc_prohibit_tab_based_indentation
Normal file
@@ -0,0 +1,7 @@
|
||||
^GNUMakefile$
|
||||
Makefile\.am$
|
||||
\.mk$
|
||||
^tests/pr/
|
||||
ChangeLog.*
|
||||
^man/help2man$
|
||||
^gl/lib/.*\.c\.diff$
|
||||
@@ -9,3 +9,4 @@ m4/lib-prefix.m4
|
||||
m4/po.m4
|
||||
aclocal.m4
|
||||
src/c99-to-c89.diff
|
||||
^gl/lib/.*\.c\.diff$
|
||||
|
||||
3
AUTHORS
3
AUTHORS
@@ -46,11 +46,12 @@ md5sum: Ulrich Drepper, Scott Miller, David Madore
|
||||
mkdir: David MacKenzie
|
||||
mkfifo: David MacKenzie
|
||||
mknod: David MacKenzie
|
||||
mktemp: Jim Meyering
|
||||
mktemp: Jim Meyering, Eric Blake
|
||||
mv: Mike Parker, David MacKenzie, Jim Meyering
|
||||
nice: David MacKenzie
|
||||
nl: Scott Bartram, David MacKenzie
|
||||
nohup: Jim Meyering
|
||||
nproc: Giuseppe Scrivano
|
||||
od: Jim Meyering
|
||||
paste: David M. Ihnat, David MacKenzie
|
||||
pathchk: Paul Eggert, David MacKenzie, Jim Meyering
|
||||
|
||||
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.
|
||||
|
||||
16
Makefile.am
16
Makefile.am
@@ -47,8 +47,11 @@ syntax_check_exceptions = \
|
||||
.x-sc_po_check \
|
||||
.x-sc_program_name \
|
||||
.x-sc_prohibit_atoi_atof \
|
||||
.x-sc_prohibit_fail_0 \
|
||||
.x-sc_prohibit_magic_number_exit \
|
||||
.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 +100,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 +123,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 +139,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); \
|
||||
|
||||
273
NEWS
273
NEWS
@@ -1,5 +1,278 @@
|
||||
GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
* Noteworthy changes in release 8.2 (2009-12-11) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
id's use of mgetgroups no longer writes beyond the end of a malloc'd buffer
|
||||
[bug introduced in coreutils-8.1]
|
||||
|
||||
id no longer crashes on systems without supplementary group support.
|
||||
[bug introduced in coreutils-8.1]
|
||||
|
||||
rm once again handles zero-length arguments properly.
|
||||
The rewrite to make rm use fts introduced a regression whereby
|
||||
a command like "rm a '' b" would fail to remove "a" and "b", due to
|
||||
the presence of the empty string argument.
|
||||
[bug introduced in coreutils-8.0]
|
||||
|
||||
sort is now immune to the signal handling of its parent.
|
||||
Specifically sort now doesn't exit with an error message
|
||||
if it uses helper processes for compression and its parent
|
||||
ignores CHLD signals. [bug introduced in coreutils-6.9]
|
||||
|
||||
tail without -f no longer access uninitialized memory
|
||||
[bug introduced in coreutils-7.6]
|
||||
|
||||
timeout is now immune to the signal handling of its parent.
|
||||
Specifically timeout now doesn't exit with an error message
|
||||
if its parent ignores CHLD signals. [bug introduced in coreutils-7.6]
|
||||
|
||||
a user running "make distcheck" in the coreutils source directory,
|
||||
with TMPDIR unset or set to the name of a world-writable directory,
|
||||
and with a malicious user on the same system
|
||||
was vulnerable to arbitrary code execution
|
||||
[bug introduced in coreutils-5.0]
|
||||
|
||||
|
||||
* Noteworthy changes in release 8.1 (2009-11-18) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
chcon no longer exits immediately just because SELinux is disabled.
|
||||
Even then, chcon may still be useful.
|
||||
[bug introduced in coreutils-8.0]
|
||||
|
||||
chcon, chgrp, chmod, chown and du now diagnose an ostensible directory cycle
|
||||
and arrange to exit nonzero. Before, they would silently ignore the
|
||||
offending directory and all "contents."
|
||||
|
||||
env -u A=B now fails, rather than silently adding A to the
|
||||
environment. Likewise, printenv A=B silently ignores the invalid
|
||||
name. [the bugs date back to the initial implementation]
|
||||
|
||||
ls --color now handles files with capabilities correctly. Previously
|
||||
files with capabilities were often not colored, and also sometimes, files
|
||||
without capabilites were colored in error. [bug introduced in coreutils-7.0]
|
||||
|
||||
md5sum now prints checksums atomically so that concurrent
|
||||
processes will not intersperse their output.
|
||||
This also affected sum, sha1sum, sha224sum, sha384sum and sha512sum.
|
||||
[the bug dates back to the initial implementation]
|
||||
|
||||
mktemp no longer leaves a temporary file behind if it was unable to
|
||||
output the name of the file to stdout.
|
||||
[the bug dates back to the initial implementation]
|
||||
|
||||
nice -n -1 PROGRAM now runs PROGRAM even when its internal setpriority
|
||||
call fails with errno == EACCES.
|
||||
[the bug dates back to the initial implementation]
|
||||
|
||||
nice, nohup, and su now refuse to execute the subsidiary program if
|
||||
they detect write failure in printing an otherwise non-fatal warning
|
||||
message to stderr.
|
||||
|
||||
stat -f recognizes more file system types: afs, cifs, anon-inode FS,
|
||||
btrfs, cgroupfs, cramfs-wend, debugfs, futexfs, hfs, inotifyfs, minux3,
|
||||
nilfs, securityfs, selinux, xenfs
|
||||
|
||||
tail -f (inotify-enabled) now avoids a race condition.
|
||||
Before, any data appended in the tiny interval between the initial
|
||||
read-to-EOF and the inotify watch initialization would be ignored
|
||||
initially (until more data was appended), or forever, if the file
|
||||
were first renamed or unlinked or never modified.
|
||||
[The race was introduced in coreutils-7.5]
|
||||
|
||||
tail -F (inotify-enabled) now consistently tails a file that has been
|
||||
replaced via renaming. That operation provokes either of two sequences
|
||||
of inotify events. The less common sequence is now handled as well.
|
||||
[The bug came with the implementation change in coreutils-7.5]
|
||||
|
||||
timeout now doesn't exit unless the command it is monitoring does,
|
||||
for any specified signal. [bug introduced in coreutils-7.0].
|
||||
|
||||
** Changes in behavior
|
||||
|
||||
chroot, env, nice, and su fail with status 125, rather than 1, on
|
||||
internal error such as failure to parse command line arguments; this
|
||||
is for consistency with stdbuf and timeout, and avoids ambiguity
|
||||
with the invoked command failing with status 1. Likewise, nohup
|
||||
fails with status 125 instead of 127.
|
||||
|
||||
du (due to a change in gnulib's fts) can now traverse NFSv4 automounted
|
||||
directories in which the stat'd device number of the mount point differs
|
||||
during a traversal. Before, it would fail, because such a mismatch would
|
||||
usually represent a serious error or a subversion attempt.
|
||||
|
||||
echo and printf now interpret \e as the Escape character (0x1B).
|
||||
|
||||
rm -f /read-only-fs/nonexistent now succeeds and prints no diagnostic
|
||||
on systems with an unlinkat syscall that sets errno to EROFS in that case.
|
||||
Before, it would fail with a "Read-only file system" diagnostic.
|
||||
Also, "rm /read-only-fs/nonexistent" now reports "file not found" rather
|
||||
than the less precise "Read-only file system" error.
|
||||
|
||||
** New programs
|
||||
|
||||
nproc: Print the number of processing units available to a process.
|
||||
|
||||
** New features
|
||||
|
||||
env and printenv now accept the option --null (-0), as a means to
|
||||
avoid ambiguity with newlines embedded in the environment.
|
||||
|
||||
md5sum --check now also accepts openssl-style checksums.
|
||||
So do sha1sum, sha224sum, sha384sum and sha512sum.
|
||||
|
||||
mktemp now accepts the option --suffix to provide a known suffix
|
||||
after the substitution in the template. Additionally, uses such as
|
||||
"mktemp fileXXXXXX.txt" are able to infer an appropriate --suffix.
|
||||
|
||||
touch now accepts the option --no-dereference (-h), as a means to
|
||||
change symlink timestamps on platforms with enough support.
|
||||
|
||||
|
||||
* 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
|
||||
|
||||
2
README
2
README
@@ -11,7 +11,7 @@ The programs that can be built with this package are:
|
||||
csplit cut date dd df dir dircolors dirname du echo env expand expr
|
||||
factor false fmt fold groups head hostid hostname id install join kill
|
||||
link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
|
||||
od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
|
||||
nproc od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
|
||||
runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf
|
||||
sleep sort split stat stdbuf stty su sum sync tac tail tee test timeout
|
||||
touch tr true truncate tsort tty uname unexpand uniq unlink uptime users
|
||||
|
||||
@@ -35,7 +35,7 @@ which are extracted from other source packages:
|
||||
|
||||
And there you are! Just
|
||||
|
||||
$ ./configure #[--enable-gcc-warnings]
|
||||
$ ./configure --quiet #[--enable-gcc-warnings] [*]
|
||||
$ make
|
||||
$ make check
|
||||
|
||||
@@ -48,6 +48,12 @@ should output no difference.
|
||||
|
||||
Enjoy!
|
||||
|
||||
[*] The --enable-gcc-warnings option is useful only with glibc
|
||||
and with a very recent version of gcc. You'll probably also have
|
||||
to use recent system headers. If you configure with this option,
|
||||
and spot a problem, please be sure to send the report to the bug
|
||||
reporting address of this package, and not to that of gnulib, even
|
||||
if the problem seems to originate in a gnulib-provided file.
|
||||
-----
|
||||
|
||||
Copyright (C) 2002-2009 Free Software Foundation, Inc.
|
||||
@@ -64,7 +70,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:
|
||||
|
||||
@@ -7,19 +7,18 @@ Here are most of the steps we (maintainers) follow when making a release.
|
||||
* Run ./configure && make maintainer-clean
|
||||
|
||||
* Ensure that the desired versions of autoconf, automake, bison, etc.
|
||||
are in your PATH. See HACKING for the complete list.
|
||||
are in your PATH. See the buildreq list in bootstrap.conf for
|
||||
the complete list.
|
||||
|
||||
* Ensure that you're on "master" with no uncommitted diffs.
|
||||
This should produce no output: git checkout master; git diff
|
||||
|
||||
* 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?
|
||||
|
||||
* Pre-release testing:
|
||||
Ensure that make check syntax-check succeeds.
|
||||
On at least one SELinux-enabled (enforcing) and one non-SELinux system,
|
||||
run all tests, both root-only and regular.
|
||||
Run *all* non-root tests, including expensive and very expensive ones i.e.,
|
||||
@@ -30,19 +29,17 @@ FIXME: enable excluded programs like arch? to get their manual pages?
|
||||
|
||||
* Run "make distcheck"
|
||||
|
||||
* Manually set the date, version number, and [stable/alpha/beta] on
|
||||
line 3 of NEWS, then do e.g.,:
|
||||
* Set the date, version number, and release type [stable/alpha/beta] on
|
||||
line 3 of NEWS, commit that, and tag the release by running e.g.,
|
||||
|
||||
v=7.3
|
||||
git commit -F <(printf 'version '$v'\n\n* NEWS: Record release date.\n') -a
|
||||
git tag -s -m "coreutils $v" v$v HEAD
|
||||
build-aux/do-release-commit-and-tag 8.1 beta
|
||||
|
||||
* Run the following to create release tarballs. Your choice selects the
|
||||
corresponding upload-to destination in the emitted gnupload command.
|
||||
The different destinations are specified in cfg.mk. See the definitions
|
||||
of gnu_ftp_host-{alpha,beta,major}.
|
||||
of gnu_ftp_host-{alpha,beta,stable}.
|
||||
|
||||
# "TYPE" must be major, beta or alpha
|
||||
# "TYPE" must be stable, beta or alpha
|
||||
make TYPE
|
||||
|
||||
* Test the tarball. copy it to a few odd-ball systems and ensure that
|
||||
@@ -53,19 +50,22 @@ FIXME: enable excluded programs like arch? to get their manual pages?
|
||||
|
||||
Once all the builds and tests have passed,
|
||||
|
||||
* Run the gnupload command that was suggested by your "make major" run above.
|
||||
* Run the gnupload command that was suggested by your "make stable" run above.
|
||||
|
||||
* Wait a few minutes (maybe up to 30?) and then use the release URLs to
|
||||
download all tarball/signature pairs and use gpg --verify to ensure
|
||||
that they're all valid.
|
||||
|
||||
* Push the new tag:
|
||||
git push origin tag v<JUST_RELEASED_VERSION_NUMBER>
|
||||
|
||||
v=$(cat .prev-version)
|
||||
git push origin tag v$v
|
||||
|
||||
* Send the gpg-signed announcement mail, e.g.,
|
||||
|
||||
To: info-gnu@gnu.org, coreutils-announce@gnu.org
|
||||
Cc: coordinator@translationproject.org, bug-coreutils@gnu.org
|
||||
Subject: coreutils-7.1 released [stable]
|
||||
Subject: coreutils-8.0 released [beta]
|
||||
|
||||
* Approve the announcement here:
|
||||
http://lists.gnu.org/mailman/admindb/coreutils-announce
|
||||
@@ -74,25 +74,21 @@ Once all the builds and tests have passed,
|
||||
From here:
|
||||
https://savannah.gnu.org/projects/coreutils/
|
||||
click on the "submit news", then write something like the following:
|
||||
(If there is no such button, then enable "News" for the project via
|
||||
the Main -> "Select Features" menu item, or via this link:
|
||||
https://savannah.gnu.org/project/admin/editgroupfeatures.php?group=coreutils)
|
||||
|
||||
Subject: coreutils-7.2 released [stable]
|
||||
Subject: coreutils-0.0 released [beta]
|
||||
The announcement is here:
|
||||
http://article.gmane.org/gmane.comp.gnu.core-utils.announce/49
|
||||
http://article.gmane.org/gmane.comp.gnu.core-utils.announce/54
|
||||
|
||||
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.
|
||||
by running this:
|
||||
|
||||
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.
|
||||
build-aux/gnu-web-doc-update
|
||||
|
||||
23
THANKS
23
THANKS
@@ -52,6 +52,7 @@ Andy Longton alongton@metamark.com
|
||||
Anthony Thyssen anthony@griffith.edu.au
|
||||
Antonio Rendas ajrendas@yahoo.com
|
||||
Ariel Faigon ariel@cthulhu.engr.sgi.com
|
||||
Arjan Opmeer arjan.opmeer@gmail.com
|
||||
Arne H. Juul arnej@solan.unit.no
|
||||
Arne Henrik Juul arnej@imf.unit.no
|
||||
Arnold Robbins arnold@skeeve.com
|
||||
@@ -66,8 +67,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 +80,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 +188,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
|
||||
@@ -207,6 +211,7 @@ Geoff Whale geoffw@cse.unsw.EDU.AU
|
||||
Gerald Pfeifer gerald@pfeifer.com
|
||||
Gerhard Poul gpoul@gnu.org
|
||||
Germano Leichsenring germano@jedi.cs.kobe-u.ac.jp
|
||||
Gilles Espinasse g.esp@free.fr
|
||||
Glen Lenker glen.lenker@gmail.com
|
||||
Göran Uddeborg goeran@uddeborg.se
|
||||
Guochun Shi gshi@ncsa.uiuc.edu
|
||||
@@ -243,12 +248,14 @@ Ian Turner vectro@pipeline.com
|
||||
Iida Yosiaki iida@gnu.org
|
||||
Ilya N. Golubev gin@mo.msk.ru
|
||||
Ingo Saitz ingo@debian.org
|
||||
Ivan Labath labath3@st.fmph.uniba.sk
|
||||
Ivo Timmermans ivo@debian.org
|
||||
James james@albion.glarp.com
|
||||
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
|
||||
@@ -258,6 +265,7 @@ Jan Engelhardt jengelh@medozas.de
|
||||
Jan Fedak J.Fedak@sh.cvut.cz
|
||||
Jan Moringen jan.moringen@uni-bielefeld.de
|
||||
Jan Nieuwenhuizen janneke@gnu.org
|
||||
Jan-Pawel Wrozstinski jpwroz@gmail.com
|
||||
Janos Farkas chexum@shadow.banki.hu
|
||||
Jarkko Hietaniemi jhi@epsilon.hut.fi
|
||||
Jarod Wilson jwilson@redhat.com
|
||||
@@ -326,12 +334,14 @@ Kirk Kelsey kirk.kelsey@0x4b.net
|
||||
Kristin E Thomas kristint@us.ibm.com
|
||||
Kjetil Torgrim Homme kjetilho@ifi.uio.no
|
||||
Kristoffer Rose kris@diku.dk
|
||||
Ladislav Hagara ladislav.hagara@unob.cz
|
||||
Larry McVoy lm@sgi.com
|
||||
Lars Hecking lhecking@nmrc.ucc.ie
|
||||
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
|
||||
@@ -363,6 +373,7 @@ Martin martin@dresden.nacamar.de
|
||||
Martin Buck martin.buck@ascom.ch
|
||||
Martin Gallant martyg@goodbit.net
|
||||
Martin Hippe martin.hippe@schlund.de
|
||||
Martin Jacobs martin.jacobs@arcor.de
|
||||
Martin Michlmayr tbm@cyrius.com
|
||||
Martin Mitchell martin@debian.org
|
||||
Martin P.J. Zinser zinser@decus.de
|
||||
@@ -370,6 +381,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,12 +397,13 @@ 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
|
||||
Michael michael@aplatform.com
|
||||
Michael ??? michael@roka.net
|
||||
Michael Bacarella mbac@netgraft.com>
|
||||
Michael Bacarella mbac@netgraft.com
|
||||
Michael Deutschmann michael@talamasca.ocis.net
|
||||
Michael Elizabeth Chastain mec.gnu@mindspring.com
|
||||
Michael Gaughen mgaughen@polyserve.com
|
||||
@@ -439,6 +452,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 +500,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
|
||||
@@ -514,6 +529,7 @@ Samuli Karkkainen Samuli.Karkkainen@hut.fi
|
||||
Sander van Malssen svm@kozmix.ow.nl
|
||||
Santiago Vila Doncel sanvila@unex.es
|
||||
Savochkin Andrey Vladimirovich saw@msu.ru
|
||||
Scott Harrison scott.gnu.2009@scottrix.co.uk
|
||||
Scott Lurndal slurn@griffin.engr.sgi.com
|
||||
Sébastien Maret smaret@umich.edu
|
||||
Sergei Steshenko sergstesh@yahoo.com
|
||||
@@ -530,6 +546,7 @@ Stephen Smoogen smooge@mindspring.com
|
||||
Steve McConnel steve@acadcomp.sil.org
|
||||
Steve McIntyre steve@einval.com
|
||||
Steve Ward planet36@gmail.com
|
||||
Steven Drake sbd@users.sourceforge.net
|
||||
Steven G. Johnson stevenj@alum.mit.edu
|
||||
Steven Mocking ufo@quicknet.nl
|
||||
Steven Parkes smparkes@smparkes.net
|
||||
@@ -560,6 +577,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 +620,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
|
||||
|
||||
|
||||
1
TODO
1
TODO
@@ -12,7 +12,6 @@ Modify chmod so that it does not change an inode's st_ctime
|
||||
Discussed more recently on <http://bugs.debian.org/497514>.
|
||||
|
||||
document the following in coreutils.texi:
|
||||
mktemp
|
||||
[
|
||||
pinky
|
||||
|
||||
|
||||
79
bootstrap
79
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,10 @@ gnulib_modules=
|
||||
# Any gnulib files needed that are not in modules.
|
||||
gnulib_files=
|
||||
|
||||
# A function to be called after everything else in this script.
|
||||
# Override it via your own definition in bootstrap.conf.
|
||||
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 +152,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".
|
||||
@@ -271,10 +314,20 @@ get_version() {
|
||||
$app --version >/dev/null 2>&1 || return 1
|
||||
|
||||
$app --version 2>&1 |
|
||||
sed -n 's/[^0-9.]*\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/p
|
||||
sed -n '# extract version within line
|
||||
s/.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
|
||||
t done
|
||||
|
||||
# extract version at start of line
|
||||
s/^\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
|
||||
t done
|
||||
|
||||
d
|
||||
|
||||
:done
|
||||
#the following essentially does s/5.005/5.5/
|
||||
s/\.0*\([1-9]\)/.\1/g
|
||||
p
|
||||
q'
|
||||
}
|
||||
|
||||
@@ -374,7 +427,7 @@ case ${GNULIB_SRCDIR--} in
|
||||
git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
git submodule init
|
||||
GNULIB_SRCDIR=`cd $GNULIB_SRCDIR && pwd`
|
||||
git config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
|
||||
git_modules_config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule update || exit $?
|
||||
GNULIB_SRCDIR=gnulib
|
||||
@@ -420,11 +473,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 +743,10 @@ find "$m4_base" "$source_base" \
|
||||
|
||||
# Reconfigure, getting other files.
|
||||
|
||||
# Skip autoheader if it's not needed.
|
||||
grep -E '^[ ]*AC_CONFIG_HEADERS?\>' configure.ac >/dev/null ||
|
||||
AUTOHEADER=true
|
||||
|
||||
for command in \
|
||||
libtool \
|
||||
"${ACLOCAL-aclocal} --force -I m4" \
|
||||
@@ -758,14 +815,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
|
||||
@@ -73,11 +71,14 @@ gnulib_modules="
|
||||
diacrit
|
||||
dirfd
|
||||
dirname
|
||||
do-release-commit-and-tag
|
||||
dup2
|
||||
environ
|
||||
error
|
||||
euidaccess
|
||||
exclude
|
||||
exitfail
|
||||
faccessat
|
||||
fchdir
|
||||
fcntl
|
||||
fcntl-safer
|
||||
@@ -90,12 +91,14 @@ gnulib_modules="
|
||||
fnmatch-gnu
|
||||
fopen-safer
|
||||
fprintftime
|
||||
freopen
|
||||
freopen-safer
|
||||
fseeko
|
||||
fsusage
|
||||
fsync
|
||||
ftello
|
||||
ftruncate
|
||||
fts
|
||||
gendocs
|
||||
getdate
|
||||
getgroups
|
||||
gethrxtime
|
||||
@@ -113,6 +116,7 @@ gnulib_modules="
|
||||
git-version-gen
|
||||
gitlog-to-changelog
|
||||
gnu-make
|
||||
gnu-web-doc-update
|
||||
gnumakefile
|
||||
gnupload
|
||||
group-member
|
||||
@@ -126,11 +130,14 @@ gnulib_modules="
|
||||
inttostr
|
||||
inttypes
|
||||
isapipe
|
||||
isblank
|
||||
lchmod
|
||||
lchown
|
||||
lib-ignore
|
||||
linebuffer
|
||||
link
|
||||
link-follow
|
||||
linkat
|
||||
long-options
|
||||
lstat
|
||||
maintainer-makefile
|
||||
@@ -153,6 +160,7 @@ gnulib_modules="
|
||||
modechange
|
||||
mountlist
|
||||
mpsort
|
||||
nproc
|
||||
obstack
|
||||
pathmax
|
||||
perl
|
||||
@@ -175,9 +183,9 @@ gnulib_modules="
|
||||
readutmp
|
||||
realloc
|
||||
regex
|
||||
rename-dest-slash
|
||||
remove
|
||||
rename
|
||||
rmdir
|
||||
rmdir-errno
|
||||
root-dev-ino
|
||||
rpmatch
|
||||
safe-read
|
||||
@@ -196,20 +204,23 @@ gnulib_modules="
|
||||
stdlib-safer
|
||||
stpcpy
|
||||
stpncpy
|
||||
strdup
|
||||
strdup-posix
|
||||
strftime
|
||||
strpbrk
|
||||
strsignal
|
||||
strtoimax
|
||||
strtoumax
|
||||
strverscmp
|
||||
symlink
|
||||
sys_stat
|
||||
timespec
|
||||
tzset
|
||||
uname
|
||||
unicodeio
|
||||
unistd-safer
|
||||
unlink-busy
|
||||
unlinkdir
|
||||
unlocked-io
|
||||
unsetenv
|
||||
update-copyright
|
||||
uptime
|
||||
useless-if-before-free
|
||||
@@ -221,7 +232,6 @@ gnulib_modules="
|
||||
verify
|
||||
verror
|
||||
version-etc-fsf
|
||||
warnings
|
||||
wcwidth
|
||||
winsz-ioctl
|
||||
winsz-termios
|
||||
@@ -234,6 +244,7 @@ gnulib_modules="
|
||||
xnanosleep
|
||||
xprintf
|
||||
xprintf-posix
|
||||
xreadlink
|
||||
xstrtod
|
||||
xstrtoimax
|
||||
xstrtol
|
||||
@@ -290,7 +301,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 +326,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
63
cfg.mk
63
cfg.mk
@@ -14,24 +14,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Use alpha.gnu.org for alpha and beta releases.
|
||||
# Use ftp.gnu.org for major releases.
|
||||
gnu_ftp_host-alpha = alpha.gnu.org
|
||||
gnu_ftp_host-beta = alpha.gnu.org
|
||||
gnu_ftp_host-major = ftp.gnu.org
|
||||
gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
|
||||
|
||||
# Used in maint.mk's web-manual rule
|
||||
manual_title = Core GNU utilities
|
||||
|
||||
url_dir_list = \
|
||||
ftp://$(gnu_rel_host)/gnu/coreutils
|
||||
|
||||
# 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 +29,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 = 2a36ca50a949f959645d9bfac8ec83ce
|
||||
|
||||
# Ensure that the list of O_ symbols used to compute O_FULLBLOCK is complete.
|
||||
dd = $(srcdir)/src/dd.c
|
||||
@@ -191,6 +181,18 @@ sc_no_exec_perl_coreutils:
|
||||
exit 1; } || :; \
|
||||
fi
|
||||
|
||||
# Don't use "readlink" or "readlinkat" directly
|
||||
sc_prohibit_readlink:
|
||||
@re='\<readlink(at)? \(' \
|
||||
msg='do not use readlink(at); use via xreadlink or areadlink*' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Don't use address of "stat" or "lstat" functions
|
||||
sc_prohibit_stat_macro_address:
|
||||
@re='\<l?stat '':|&l?stat\>' \
|
||||
msg='stat() and lstat() may be function-like macros' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Ensure that date's --help output stays in sync with the info
|
||||
# documentation for GNU strftime. The only exception is %N,
|
||||
# which date accepts but GNU strftime does not.
|
||||
@@ -206,4 +208,41 @@ 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)
|
||||
|
||||
# Ensure that each file that contains fail=1 also contains fail=0.
|
||||
# Otherwise, setting file=1 in the environment would make tests fail unexpectedly.
|
||||
sc_prohibit_fail_0:
|
||||
@re='\<fail=0\>' \
|
||||
msg='fail=0 initialization' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
# Ensure that "stdio--.h" is used where appropriate.
|
||||
sc_require_stdio_safer:
|
||||
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
|
||||
files=$$(grep -l '\bfreopen \?(' $$($(VC_LIST_EXCEPT) \
|
||||
| grep '\.[ch]$$')); \
|
||||
test -n "$$files" && grep -LE 'include "stdio--.h"' $$files \
|
||||
| grep . && \
|
||||
{ echo '$(ME): the above files should use "stdio--.h"' \
|
||||
1>&2; exit 1; } || :; \
|
||||
else :; \
|
||||
fi
|
||||
|
||||
# Prefer xnanosleep over other less-precise sleep methods
|
||||
sc_prohibit_sleep:
|
||||
@re='\<(nano|u)?sleep \(' \
|
||||
msg='prefer xnanosleep over other sleep interfaces' \
|
||||
$(_prohibit_regexp)
|
||||
|
||||
include $(srcdir)/dist-check.mk
|
||||
|
||||
42
configure.ac
42
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,14 +101,12 @@ 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])
|
||||
|
||||
gl_WARN_ADD([-fdiagnostics-show-option])
|
||||
gl_WARN_ADD([-funit-at-a-time])
|
||||
|
||||
AC_SUBST([WARN_CFLAGS])
|
||||
|
||||
@@ -116,17 +114,25 @@ if test "$gl_gcc_warnings" = yes; then
|
||||
AC_DEFINE([_FORTIFY_SOURCE], [2],
|
||||
[enable compile-time and run-time bounds-checking, and some warnings])
|
||||
AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks])
|
||||
|
||||
# We use a slightly smaller set of warning options for lib/.
|
||||
# Remove the following and save the result in GNULIB_WARN_CFLAGS.
|
||||
nw=
|
||||
nw="$nw -Wuninitialized"
|
||||
nw="$nw -Wunused-macros"
|
||||
nw="$nw -Wmissing-prototypes"
|
||||
nw="$nw -Wold-style-definition"
|
||||
gl_MANYWARN_COMPLEMENT([GNULIB_WARN_CFLAGS], [$WARN_CFLAGS], [$nw])
|
||||
AC_SUBST([GNULIB_WARN_CFLAGS])
|
||||
fi
|
||||
|
||||
AC_FUNC_FORK
|
||||
|
||||
optional_bin_progs=
|
||||
AC_CHECK_FUNCS([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 +174,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 +203,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 +380,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
|
||||
@@ -423,8 +429,10 @@ CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/src/Makefile.am'
|
||||
AC_SUBST([CONFIG_STATUS_DEPENDENCIES])
|
||||
############################################################################
|
||||
|
||||
# As long as "grep 'PRI[diouxX]' po/*.pot" reports matches in
|
||||
# translatable strings, we must use need-formatstring-macros here.
|
||||
AM_GNU_GETTEXT([external], [need-formatstring-macros])
|
||||
AM_GNU_GETTEXT_VERSION([0.15])
|
||||
AM_GNU_GETTEXT_VERSION([0.17])
|
||||
|
||||
# For a test of uniq: it uses the $LOCALE_FR envvar.
|
||||
gt_LOCALE_FR
|
||||
|
||||
@@ -4,14 +4,15 @@ bin=bin-$$$$
|
||||
|
||||
write_loser = printf '\#!%s\necho $$0: bad path 1>&2; exit 1\n' '$(SHELL)'
|
||||
|
||||
TMPDIR ?= /tmp
|
||||
t=$(TMPDIR)/$(PACKAGE)/test
|
||||
tmpdir = $(abs_top_builddir)/tests/torture
|
||||
|
||||
t=$(tmpdir)/$(PACKAGE)/test
|
||||
pfx=$(t)/i
|
||||
|
||||
# More than once, tainted build and source directory names would
|
||||
# have caused at least one "make check" test to apply "chmod 700"
|
||||
# to all directories under $HOME. Make sure it doesn't happen again.
|
||||
tp := $(shell echo "$(TMPDIR)/$(PACKAGE)-$$$$")
|
||||
tp = $(tmpdir)/taint
|
||||
t_prefix = $(tp)/a
|
||||
t_taint = '$(t_prefix) b'
|
||||
fake_home = $(tp)/home
|
||||
@@ -30,10 +31,11 @@ taint-distcheck: $(DIST_ARCHIVES)
|
||||
touch $(fake_home)/f
|
||||
mkdir -p $(fake_home)/d/e
|
||||
ls -lR $(fake_home) $(t_prefix) > $(tp)/.ls-before
|
||||
HOME=$(fake_home); export HOME; \
|
||||
cd $(t_taint)/$(distdir) \
|
||||
&& ./configure \
|
||||
&& $(MAKE) \
|
||||
&& HOME=$(fake_home) $(MAKE) check \
|
||||
&& $(MAKE) check \
|
||||
&& ls -lR $(fake_home) $(t_prefix) > $(tp)/.ls-after \
|
||||
&& diff $(tp)/.ls-before $(tp)/.ls-after \
|
||||
&& test -d $(t_prefix)
|
||||
@@ -52,6 +54,7 @@ endef
|
||||
# Install, then verify that all binaries and man pages are in place.
|
||||
# Note that neither the binary, ginstall, nor the ].1 man page is installed.
|
||||
define my-instcheck
|
||||
echo running my-instcheck; \
|
||||
$(MAKE) prefix=$(pfx) install \
|
||||
&& test ! -f $(pfx)/bin/ginstall \
|
||||
&& { fail=0; \
|
||||
@@ -70,6 +73,7 @@ endef
|
||||
|
||||
define coreutils-path-check
|
||||
{ \
|
||||
echo running coreutils-path-check; \
|
||||
if test -f $(srcdir)/src/true.c; then \
|
||||
fail=1; \
|
||||
mkdir $(bin) \
|
||||
@@ -117,7 +121,7 @@ my-distcheck: $(DIST_ARCHIVES) $(local-check)
|
||||
mkdir -p $(t)
|
||||
GZIP=$(GZIP_ENV) $(AMTAR) -C $(t) -zxf $(distdir).tar.gz
|
||||
cd $(t)/$(distdir) \
|
||||
&& ./configure --enable-gcc-warnings --disable-nls \
|
||||
&& ./configure --quiet --enable-gcc-warnings --disable-nls \
|
||||
&& $(MAKE) AM_MAKEFLAGS='$(null_AM_MAKEFLAGS)' \
|
||||
&& $(MAKE) dvi \
|
||||
&& $(install-transform-check) \
|
||||
@@ -128,6 +132,7 @@ my-distcheck: $(DIST_ARCHIVES) $(local-check)
|
||||
&& $(AMTAR) -zxf - ) < $(distdir).tar.gz
|
||||
diff -ur $(t)/$(distdir).old $(t)/$(distdir)
|
||||
-rm -rf $(t)
|
||||
rmdir $(tmpdir)/$(PACKAGE) $(tmpdir)
|
||||
@echo "========================"; \
|
||||
echo "$(distdir).tar.gz is ready for distribution"; \
|
||||
echo "========================"
|
||||
|
||||
@@ -48,8 +48,10 @@ _W = (^|[^A-Za-z0-9_])
|
||||
W_ = ([^A-Za-z0-9_]|$$)
|
||||
|
||||
syntax_checks = \
|
||||
sc-avoid-builtin \
|
||||
sc-avoid-io \
|
||||
sc-avoid-non-zero \
|
||||
sc-avoid-path \
|
||||
sc-avoid-timezone \
|
||||
sc-avoid-zeroes \
|
||||
sc-exponent-grouping \
|
||||
@@ -70,9 +72,18 @@ check-texinfo: $(syntax_checks)
|
||||
$(PERL) -e 1 2> /dev/null && { $(PERL) -ne \
|
||||
'/\bPOSIX\b/ && !/\@acronym{POSIX}/ && !/^\* / || /{posix}/ and print,exit 1' \
|
||||
$(srcdir)/*.texi 2> /dev/null || fail=1; }; \
|
||||
$(EGREP) -i '$(_W)builtins?$(W_)' $(srcdir)/*.texi && fail=1; \
|
||||
exit $$fail
|
||||
|
||||
sc-avoid-builtin:
|
||||
$(AM_V_GEN)$(EGREP) -i '$(_W)builtins?$(W_)' $(srcdir)/*.texi \
|
||||
&& exit 1 || :
|
||||
|
||||
sc-avoid-path:
|
||||
$(AM_V_GEN)fail=0; \
|
||||
$(EGREP) -i '$(_W)path(name)?s?$(W_)' $(srcdir)/*.texi \
|
||||
| $(EGREP) -v 'search path|@vindex PATH$$|@env[{]PATH[}]' && fail=1; \
|
||||
| $(EGREP) -v \
|
||||
'PATH=|path search|search path|@vindex PATH$$|@env[{]PATH[}]' \
|
||||
&& fail=1; \
|
||||
exit $$fail
|
||||
|
||||
# Use `time zone', not `timezone'.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -129,7 +129,7 @@ mbs_align_pad (char *dest, const char* dest_end, size_t n_spaces)
|
||||
|
||||
size_t
|
||||
mbsalign (const char *src, char *dest, size_t dest_size,
|
||||
size_t *width, mbs_align_t align, int flags)
|
||||
size_t *width, mbs_align_t align, int flags _UNUSED_PARAMETER_)
|
||||
{
|
||||
size_t ret = -1;
|
||||
size_t src_size = strlen (src) + 1;
|
||||
@@ -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:
|
||||
*/
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
/* mgetgroups.c -- return a list of the groups a user is in
|
||||
|
||||
Copyright (C) 2007-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/>. */
|
||||
|
||||
/* Extracted from coreutils' src/id.c. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "mgetgroups.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#if HAVE_GETGROUPLIST
|
||||
# include <grp.h>
|
||||
#endif
|
||||
#include "getugroups.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
|
||||
static GETGROUPS_T *
|
||||
realloc_groupbuf (GETGROUPS_T *g, size_t num)
|
||||
{
|
||||
if (xalloc_oversized (num, sizeof (*g)))
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return realloc (g, num * sizeof (*g));
|
||||
}
|
||||
|
||||
/* Like getugroups, but store the result in malloc'd storage.
|
||||
Set *GROUPS to the malloc'd list of all group IDs of which USERNAME
|
||||
is a member. If GID is not -1, store it first. GID should be the
|
||||
group ID (pw_gid) obtained from getpwuid, in case USERNAME is not
|
||||
listed in the groups database (e.g., /etc/groups). Upon failure,
|
||||
don't modify *GROUPS, set errno, and return -1. Otherwise, return
|
||||
the number of groups. */
|
||||
|
||||
int
|
||||
mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
|
||||
{
|
||||
int max_n_groups;
|
||||
int ng;
|
||||
GETGROUPS_T *g;
|
||||
|
||||
#if HAVE_GETGROUPLIST
|
||||
/* We prefer to use getgrouplist if available, because it has better
|
||||
performance characteristics.
|
||||
|
||||
In glibc 2.3.2, getgrouplist is buggy. If you pass a zero as the
|
||||
length of the output buffer, getgrouplist will still write to the
|
||||
buffer. Contrary to what some versions of the getgrouplist
|
||||
manpage say, this doesn't happen with nonzero buffer sizes.
|
||||
Therefore our usage here just avoids a zero sized buffer. */
|
||||
if (username)
|
||||
{
|
||||
enum { N_GROUPS_INIT = 10 };
|
||||
max_n_groups = N_GROUPS_INIT;
|
||||
|
||||
g = realloc_groupbuf (NULL, max_n_groups);
|
||||
if (g == NULL)
|
||||
return -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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 (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));
|
||||
|
||||
/* If we failed to count groups with NULL for a buffer,
|
||||
try again with a non-NULL one, just in case. */
|
||||
if (max_n_groups < 0)
|
||||
max_n_groups = 5;
|
||||
|
||||
g = realloc_groupbuf (NULL, max_n_groups);
|
||||
if (g == NULL)
|
||||
return -1;
|
||||
|
||||
ng = (username
|
||||
? getugroups (max_n_groups, g, username, gid)
|
||||
: getgroups (max_n_groups, g));
|
||||
|
||||
if (ng < 0)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (g);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*groups = g;
|
||||
return ng;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Get a list of all group IDs associated with a specified user ID.
|
||||
Copyright (C) 2007, 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 <sys/types.h>
|
||||
|
||||
int mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups);
|
||||
@@ -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;
|
||||
|
||||
82
gl/lib/regcomp.c.diff
Normal file
82
gl/lib/regcomp.c.diff
Normal file
@@ -0,0 +1,82 @@
|
||||
diff --git c/lib/regcomp.c i/lib/regcomp.c
|
||||
index 6472ff6..665b2ab 100644
|
||||
--- c/lib/regcomp.c
|
||||
+++ i/lib/regcomp.c
|
||||
@@ -18,6 +18,8 @@
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
+#include "intprops.h"
|
||||
+#include "verify.h"
|
||||
static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
|
||||
size_t length, reg_syntax_t syntax);
|
||||
static void re_compile_fastmap_iter (regex_t *bufp,
|
||||
@@ -541,7 +543,7 @@ regerror (errcode, preg, errbuf, errbuf_size)
|
||||
size_t errbuf_size;
|
||||
#else /* size_t might promote */
|
||||
size_t
|
||||
-regerror (int errcode, const regex_t *_Restrict_ preg,
|
||||
+regerror (int errcode, const regex_t *_Restrict_ preg _UNUSED_PARAMETER_,
|
||||
char *_Restrict_ errbuf, size_t errbuf_size)
|
||||
#endif
|
||||
{
|
||||
@@ -1375,7 +1377,7 @@ calc_first (void *extra, bin_tree_t *node)
|
||||
|
||||
/* Pass 2: compute NEXT on the tree. Preorder visit. */
|
||||
static reg_errcode_t
|
||||
-calc_next (void *extra, bin_tree_t *node)
|
||||
+calc_next (void *extra _UNUSED_PARAMETER_, bin_tree_t *node)
|
||||
{
|
||||
switch (node->token.type)
|
||||
{
|
||||
@@ -2571,7 +2573,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
|
||||
/* This loop is actually executed only when end != REG_MISSING,
|
||||
to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have
|
||||
already created the start+1-th copy. */
|
||||
- if ((Idx) -1 < 0 || end != REG_MISSING)
|
||||
+ verify (! TYPE_SIGNED (Idx));
|
||||
+ if (end != REG_MISSING)
|
||||
for (i = start + 2; i <= end; ++i)
|
||||
{
|
||||
elem = duplicate_tree (elem, dfa);
|
||||
@@ -2731,7 +2734,8 @@ static reg_errcode_t
|
||||
internal_function
|
||||
build_collating_symbol (bitset_t sbcset,
|
||||
# ifdef RE_ENABLE_I18N
|
||||
- re_charset_t *mbcset, Idx *coll_sym_alloc,
|
||||
+ re_charset_t *mbcset _UNUSED_PARAMETER_,
|
||||
+ Idx *coll_sym_alloc _UNUSED_PARAMETER_,
|
||||
# endif
|
||||
const unsigned char *name)
|
||||
{
|
||||
@@ -3309,7 +3313,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
||||
|
||||
static reg_errcode_t
|
||||
parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
|
||||
- re_token_t *token, int token_len, re_dfa_t *dfa,
|
||||
+ re_token_t *token, int token_len,
|
||||
+ re_dfa_t *dfa _UNUSED_PARAMETER_,
|
||||
reg_syntax_t syntax, bool accept_hyphen)
|
||||
{
|
||||
#ifdef RE_ENABLE_I18N
|
||||
@@ -3396,8 +3401,9 @@ parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
|
||||
|
||||
static reg_errcode_t
|
||||
#ifdef RE_ENABLE_I18N
|
||||
-build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
|
||||
- Idx *equiv_class_alloc, const unsigned char *name)
|
||||
+build_equiv_class (bitset_t sbcset, re_charset_t *mbcset _UNUSED_PARAMETER_,
|
||||
+ Idx *equiv_class_alloc _UNUSED_PARAMETER_,
|
||||
+ const unsigned char *name)
|
||||
#else /* not RE_ENABLE_I18N */
|
||||
build_equiv_class (bitset_t sbcset, const unsigned char *name)
|
||||
#endif /* not RE_ENABLE_I18N */
|
||||
@@ -3798,7 +3804,7 @@ free_token (re_token_t *node)
|
||||
and its children. */
|
||||
|
||||
static reg_errcode_t
|
||||
-free_tree (void *extra, bin_tree_t *node)
|
||||
+free_tree (void *extra _UNUSED_PARAMETER_, bin_tree_t *node)
|
||||
{
|
||||
free_token (&node->token);
|
||||
return REG_NOERROR;
|
||||
25
gl/lib/regex_internal.c.diff
Normal file
25
gl/lib/regex_internal.c.diff
Normal file
@@ -0,0 +1,25 @@
|
||||
diff --git a/lib/regex_internal.c b/lib/regex_internal.c
|
||||
index 904b88e..61c8d9d 100644
|
||||
--- a/lib/regex_internal.c
|
||||
+++ b/lib/regex_internal.c
|
||||
@@ -18,6 +18,8 @@
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
+#include "verify.h"
|
||||
+#include "intprops.h"
|
||||
static void re_string_construct_common (const char *str, Idx len,
|
||||
re_string_t *pstr,
|
||||
RE_TRANSLATE_TYPE trans, bool icase,
|
||||
@@ -1390,7 +1392,10 @@ static void
|
||||
internal_function
|
||||
re_node_set_remove_at (re_node_set *set, Idx idx)
|
||||
{
|
||||
- if (idx < 0 || idx >= set->nelem)
|
||||
+ verify (! TYPE_SIGNED (Idx));
|
||||
+ /* if (idx < 0)
|
||||
+ return; */
|
||||
+ if (idx >= set->nelem)
|
||||
return;
|
||||
--set->nelem;
|
||||
for (; idx < set->nelem; idx++)
|
||||
14
gl/lib/regex_internal.h.diff
Normal file
14
gl/lib/regex_internal.h.diff
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git i/lib/regex_internal.h w/lib/regex_internal.h
|
||||
index 859832f..3c7fe06 100644
|
||||
--- i/lib/regex_internal.h
|
||||
+++ w/lib/regex_internal.h
|
||||
@@ -826,7 +826,8 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx)
|
||||
|
||||
static int
|
||||
internal_function __attribute ((pure))
|
||||
-re_string_elem_size_at (const re_string_t *pstr, Idx idx)
|
||||
+re_string_elem_size_at (const re_string_t *pstr _UNUSED_PARAMETER_,
|
||||
+ Idx idx _UNUSED_PARAMETER_)
|
||||
{
|
||||
# ifdef _LIBC
|
||||
const unsigned char *p, *extra;
|
||||
45
gl/lib/regexec.c.diff
Normal file
45
gl/lib/regexec.c.diff
Normal file
@@ -0,0 +1,45 @@
|
||||
diff --git a/lib/regexec.c b/lib/regexec.c
|
||||
index 21a8166..7762437 100644
|
||||
--- a/lib/regexec.c
|
||||
+++ b/lib/regexec.c
|
||||
@@ -18,6 +18,8 @@
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
+#include "verify.h"
|
||||
+#include "intprops.h"
|
||||
static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
|
||||
Idx n) internal_function;
|
||||
static void match_ctx_clean (re_match_context_t *mctx) internal_function;
|
||||
@@ -378,8 +380,11 @@ re_search_2_stub (struct re_pattern_buffer *bufp,
|
||||
Idx len = length1 + length2;
|
||||
char *s = NULL;
|
||||
|
||||
- if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
|
||||
- return -2;
|
||||
+ verify (! TYPE_SIGNED (Idx));
|
||||
+ if (BE (len < length1, 0))
|
||||
+ return -2;
|
||||
+ /* if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
|
||||
+ return -2; */
|
||||
|
||||
/* Concatenate the strings. */
|
||||
if (length2 > 0)
|
||||
@@ -431,11 +436,14 @@ re_search_stub (struct re_pattern_buffer *bufp,
|
||||
Idx last_start = start + range;
|
||||
|
||||
/* Check for out-of-range. */
|
||||
- if (BE (start < 0 || start > length, 0))
|
||||
- return -1;
|
||||
+ verify (! TYPE_SIGNED (Idx));
|
||||
+ /* if (BE (start < 0, 0))
|
||||
+ return -1; */
|
||||
+ if (BE (start > length, 0))
|
||||
+ return -1;
|
||||
if (BE (length < last_start || (0 <= range && last_start < start), 0))
|
||||
last_start = length;
|
||||
- else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
|
||||
+ else if (BE (/* last_start < 0 || */ (range < 0 && start <= last_start), 0))
|
||||
last_start = 0;
|
||||
|
||||
__libc_lock_lock (dfa->lock);
|
||||
@@ -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)
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
/* tempname.c - generate the name of a temporary file.
|
||||
|
||||
Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2005, 2006, 2007, 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/>. */
|
||||
|
||||
/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */
|
||||
|
||||
#if !_LIBC
|
||||
# include <config.h>
|
||||
# include "tempname.h"
|
||||
# include "randint.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(Val) errno = (Val)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifndef P_tmpdir
|
||||
# define P_tmpdir "/tmp"
|
||||
#endif
|
||||
#ifndef TMP_MAX
|
||||
# define TMP_MAX 238328
|
||||
#endif
|
||||
#ifndef __GT_FILE
|
||||
# define __GT_FILE 0
|
||||
# define __GT_BIGFILE 1
|
||||
# define __GT_DIR 2
|
||||
# define __GT_NOCREATE 3
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#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 __gen_tempname gen_tempname
|
||||
# define __getpid getpid
|
||||
# define __gettimeofday gettimeofday
|
||||
# define __mkdir mkdir
|
||||
# define __lxstat64(version, file, buf) lstat (file, buf)
|
||||
# define __xstat64(version, file, buf) stat (file, buf)
|
||||
#endif
|
||||
|
||||
#if ! (HAVE___SECURE_GETENV || _LIBC)
|
||||
# define __secure_getenv getenv
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
/* Return nonzero if DIR is an existent directory. */
|
||||
static int
|
||||
direxists (const char *dir)
|
||||
{
|
||||
struct_stat64 buf;
|
||||
return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
|
||||
}
|
||||
|
||||
/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
|
||||
non-null and exists, uses it; otherwise uses the first of $TMPDIR,
|
||||
P_tmpdir, /tmp that exists. Copies into TMPL a template suitable
|
||||
for use with mk[s]temp. Will fail (-1) if DIR is non-null and
|
||||
doesn't exist, none of the searched dirs exists, or there's not
|
||||
enough space in TMPL. */
|
||||
int
|
||||
__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
|
||||
int try_tmpdir)
|
||||
{
|
||||
const char *d;
|
||||
size_t dlen, plen;
|
||||
|
||||
if (!pfx || !pfx[0])
|
||||
{
|
||||
pfx = "file";
|
||||
plen = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
plen = strlen (pfx);
|
||||
if (plen > 5)
|
||||
plen = 5;
|
||||
}
|
||||
|
||||
if (try_tmpdir)
|
||||
{
|
||||
d = __secure_getenv ("TMPDIR");
|
||||
if (d != NULL && direxists (d))
|
||||
dir = d;
|
||||
else if (dir != NULL && direxists (dir))
|
||||
/* nothing */ ;
|
||||
else
|
||||
dir = NULL;
|
||||
}
|
||||
if (dir == NULL)
|
||||
{
|
||||
if (direxists (P_tmpdir))
|
||||
dir = P_tmpdir;
|
||||
else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
|
||||
dir = "/tmp";
|
||||
else
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dlen = strlen (dir);
|
||||
while (dlen > 1 && dir[dlen - 1] == '/')
|
||||
dlen--; /* remove trailing slashes */
|
||||
|
||||
/* check we have room for "${dir}/${pfx}XXXXXX\0" */
|
||||
if (tmpl_len < dlen + 1 + plen + 6 + 1)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
|
||||
return 0;
|
||||
}
|
||||
#endif /* _LIBC */
|
||||
|
||||
static inline bool
|
||||
check_x_suffix (char const *s, size_t len)
|
||||
{
|
||||
return strspn (s, "X") == len;
|
||||
}
|
||||
|
||||
/* These are the characters used in temporary file names. */
|
||||
static const char letters[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
/* Generate a temporary file name based on TMPL. TMPL must end in a
|
||||
a sequence of at least X_SUFFIX_LEN "X"s. The name constructed
|
||||
does not exist at the time of the call to __gen_tempname. TMPL is
|
||||
overwritten with the result.
|
||||
|
||||
KIND may be one of:
|
||||
__GT_NOCREATE: simply verify that the name does not exist
|
||||
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().
|
||||
__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)
|
||||
{
|
||||
size_t len;
|
||||
char *XXXXXX;
|
||||
unsigned int count;
|
||||
int fd = -1;
|
||||
int save_errno = errno;
|
||||
struct_stat64 st;
|
||||
struct randint_source *rand_src;
|
||||
|
||||
/* A lower bound on the number of temporary files to attempt to
|
||||
generate. The maximum total number of temporary file names that
|
||||
can exist for a given template is 62**6. It should never be
|
||||
necessary to try all these combinations. Instead if a reasonable
|
||||
number of names is tried (we define reasonable as 62**3) fail to
|
||||
give the system administrator the chance to remove the problems. */
|
||||
#define ATTEMPTS_MIN (62 * 62 * 62)
|
||||
|
||||
/* The number of times to attempt to generate a temporary file. To
|
||||
conform to POSIX, this must be no smaller than TMP_MAX. */
|
||||
#if ATTEMPTS_MIN < TMP_MAX
|
||||
unsigned int attempts = TMP_MAX;
|
||||
#else
|
||||
unsigned int attempts = ATTEMPTS_MIN;
|
||||
#endif
|
||||
|
||||
len = strlen (tmpl);
|
||||
if (len < x_suffix_len || ! check_x_suffix (&tmpl[len - x_suffix_len],
|
||||
x_suffix_len))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rand_src = randint_all_new (NULL, 8);
|
||||
if (! rand_src)
|
||||
return -1;
|
||||
|
||||
/* This is where the Xs start. */
|
||||
XXXXXX = &tmpl[len - x_suffix_len];
|
||||
|
||||
for (count = 0; count < attempts; ++count)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < x_suffix_len; i++)
|
||||
{
|
||||
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_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_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");
|
||||
}
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
goto done;
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
{
|
||||
fd = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
randint_all_free (rand_src);
|
||||
|
||||
/* We got out of the loop because we ran out of combinations to try. */
|
||||
__set_errno (EEXIST);
|
||||
return -1;
|
||||
|
||||
done:
|
||||
{
|
||||
int saved_errno = errno;
|
||||
randint_all_free (rand_src);
|
||||
__set_errno (saved_errno);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
__gen_tempname (char *tmpl, int kind)
|
||||
{
|
||||
return gen_tempname_len (tmpl, kind, 6);
|
||||
}
|
||||
193
gl/lib/tempname.c.diff
Normal file
193
gl/lib/tempname.c.diff
Normal file
@@ -0,0 +1,193 @@
|
||||
diff --git c/lib/tempname.c i/lib/tempname.c
|
||||
index 2da5afe..562955a 100644
|
||||
--- c/lib/tempname.c
|
||||
+++ i/lib/tempname.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#if !_LIBC
|
||||
# include <config.h>
|
||||
# include "tempname.h"
|
||||
+# include "randint.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -49,6 +50,7 @@
|
||||
# error report this to bug-gnulib@gnu.org
|
||||
#endif
|
||||
|
||||
+#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -179,14 +181,21 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
|
||||
}
|
||||
#endif /* _LIBC */
|
||||
|
||||
+static inline bool
|
||||
+check_x_suffix (char const *s, size_t len)
|
||||
+{
|
||||
+ return len <= strspn (s, "X");
|
||||
+}
|
||||
+
|
||||
/* These are the characters used in temporary file names. */
|
||||
static const char letters[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
/* Generate a temporary file name based on TMPL. TMPL must match the
|
||||
- rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
|
||||
+ rules for mk[s]temp (i.e. end in at least X_SUFFIX_LEN "X"s,
|
||||
+ possibly with a suffix).
|
||||
The name constructed does not exist at the time of the call to
|
||||
- __gen_tempname. TMPL is overwritten with the result.
|
||||
+ this function. TMPL is overwritten with the result.
|
||||
|
||||
KIND may be one of:
|
||||
__GT_NOCREATE: simply verify that the name does not exist
|
||||
@@ -197,23 +206,24 @@ static const char letters[] =
|
||||
|
||||
We use a clever algorithm to get hard-to-predict names. */
|
||||
int
|
||||
-__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
+gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
|
||||
+ size_t x_suffix_len)
|
||||
{
|
||||
- int len;
|
||||
+ size_t len;
|
||||
char *XXXXXX;
|
||||
- static uint64_t value;
|
||||
- uint64_t random_time_bits;
|
||||
unsigned int count;
|
||||
int fd = -1;
|
||||
int save_errno = errno;
|
||||
struct_stat64 st;
|
||||
+ struct randint_source *rand_src;
|
||||
|
||||
/* A lower bound on the number of temporary files to attempt to
|
||||
generate. The maximum total number of temporary file names that
|
||||
can exist for a given template is 62**6. It should never be
|
||||
necessary to try all these combinations. Instead if a reasonable
|
||||
number of names is tried (we define reasonable as 62**3) fail to
|
||||
- give the system administrator the chance to remove the problems. */
|
||||
+ give the system administrator the chance to remove the problems.
|
||||
+ This value requires that X_SUFFIX_LEN be at least 3. */
|
||||
#define ATTEMPTS_MIN (62 * 62 * 62)
|
||||
|
||||
/* The number of times to attempt to generate a temporary file. To
|
||||
@@ -225,43 +235,28 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
#endif
|
||||
|
||||
len = strlen (tmpl);
|
||||
- if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6))
|
||||
+ if (len < x_suffix_len + suffixlen
|
||||
+ || ! check_x_suffix (&tmpl[len - x_suffix_len - suffixlen],
|
||||
+ x_suffix_len))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This is where the Xs start. */
|
||||
- XXXXXX = &tmpl[len - 6 - suffixlen];
|
||||
+ XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
|
||||
|
||||
/* Get some more or less random data. */
|
||||
-#ifdef RANDOM_BITS
|
||||
- RANDOM_BITS (random_time_bits);
|
||||
-#else
|
||||
- {
|
||||
- struct timeval tv;
|
||||
- __gettimeofday (&tv, NULL);
|
||||
- random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
|
||||
- }
|
||||
-#endif
|
||||
- value += random_time_bits ^ __getpid ();
|
||||
+ rand_src = randint_all_new (NULL, 8);
|
||||
+ if (! rand_src)
|
||||
+ return -1;
|
||||
|
||||
- for (count = 0; count < attempts; value += 7777, ++count)
|
||||
+ for (count = 0; count < attempts; ++count)
|
||||
{
|
||||
- uint64_t v = value;
|
||||
-
|
||||
- /* Fill in the random bits. */
|
||||
- XXXXXX[0] = letters[v % 62];
|
||||
- v /= 62;
|
||||
- XXXXXX[1] = letters[v % 62];
|
||||
- v /= 62;
|
||||
- XXXXXX[2] = letters[v % 62];
|
||||
- v /= 62;
|
||||
- XXXXXX[3] = letters[v % 62];
|
||||
- v /= 62;
|
||||
- XXXXXX[4] = letters[v % 62];
|
||||
- v /= 62;
|
||||
- XXXXXX[5] = letters[v % 62];
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < x_suffix_len; i++)
|
||||
+ XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
@@ -276,7 +271,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
break;
|
||||
|
||||
case __GT_NOCREATE:
|
||||
- /* This case is backward from the other three. __gen_tempname
|
||||
+ /* 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. */
|
||||
@@ -285,11 +280,15 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
- return 0;
|
||||
+ fd = 0;
|
||||
+ goto done;
|
||||
}
|
||||
else
|
||||
- /* Give up now. */
|
||||
- return -1;
|
||||
+ {
|
||||
+ /* Give up now. */
|
||||
+ fd = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -301,13 +300,32 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
if (fd >= 0)
|
||||
{
|
||||
__set_errno (save_errno);
|
||||
- return fd;
|
||||
+ goto done;
|
||||
}
|
||||
else if (errno != EEXIST)
|
||||
- return -1;
|
||||
+ {
|
||||
+ fd = -1;
|
||||
+ goto done;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ randint_all_free (rand_src);
|
||||
+
|
||||
/* We got out of the loop because we ran out of combinations to try. */
|
||||
__set_errno (EEXIST);
|
||||
return -1;
|
||||
+
|
||||
+ done:
|
||||
+ {
|
||||
+ int saved_errno = errno;
|
||||
+ randint_all_free (rand_src);
|
||||
+ __set_errno (saved_errno);
|
||||
+ }
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
|
||||
+{
|
||||
+ return gen_tempname_len (tmpl, suffixlen, flags, kind, 6);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* Create a temporary file or directory.
|
||||
|
||||
Copyright (C) 2006, 2007, 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/>. */
|
||||
|
||||
/* header written by Eric Blake */
|
||||
|
||||
/* In gnulib, always prefer large files. GT_FILE maps to
|
||||
__GT_BIGFILE, not __GT_FILE, for a reason. */
|
||||
#define GT_FILE 1
|
||||
#define GT_DIR 2
|
||||
#define GT_NOCREATE 3
|
||||
|
||||
/* Generate a temporary file name based on TMPL. TMPL must match the
|
||||
rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
|
||||
does not exist at the time of the call to gen_tempname. TMPL is
|
||||
overwritten with the result.
|
||||
|
||||
KIND may be one of:
|
||||
GT_NOCREATE: simply verify that the name does not exist
|
||||
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.
|
||||
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);
|
||||
12
gl/lib/tempname.h.diff
Normal file
12
gl/lib/tempname.h.diff
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git c/lib/tempname.h i/lib/tempname.h
|
||||
index cd69e7d..9757db2 100644
|
||||
--- c/lib/tempname.h
|
||||
+++ i/lib/tempname.h
|
||||
@@ -46,5 +46,7 @@
|
||||
|
||||
We use a clever algorithm to get hard-to-predict names. */
|
||||
extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
|
||||
+extern int gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
|
||||
+ size_t x_suffix_len);
|
||||
|
||||
#endif /* GL_TEMPNAME_H */
|
||||
@@ -1,41 +0,0 @@
|
||||
/* a wrapper for frepoen
|
||||
Copyright (C) 2008-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 "xfreopen.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include "error.h"
|
||||
#include "exitfail.h"
|
||||
#include "quote.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
|
||||
void
|
||||
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")))));
|
||||
error (exit_failure, errno, _("failed to reopen %s with mode %s"),
|
||||
quote_n (0, f), quote_n (1, mode));
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
#include <stdio.h>
|
||||
void xfreopen (char const *filename, char const *mode, FILE *fp);
|
||||
@@ -1,11 +0,0 @@
|
||||
#serial 3
|
||||
dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_MGETGROUPS],
|
||||
[
|
||||
AC_CHECK_FUNCS([getgrouplist])
|
||||
AC_LIBOBJ([mgetgroups])
|
||||
])
|
||||
9
gl/modules/link-tests.diff
Normal file
9
gl/modules/link-tests.diff
Normal file
@@ -0,0 +1,9 @@
|
||||
diff --git i/modules/link-tests w/modules/link-tests
|
||||
index d8e7b1a..aca0e74 100644
|
||||
--- i/modules/link-tests
|
||||
+++ w/modules/link-tests
|
||||
@@ -12,3 +12,4 @@ configure.ac:
|
||||
Makefile.am:
|
||||
TESTS += test-link
|
||||
check_PROGRAMS += test-link
|
||||
+test_link_LDADD = $(LDADD) @LIBINTL@
|
||||
@@ -1,24 +0,0 @@
|
||||
Description:
|
||||
Return the group IDs of a user in malloc'd storage.
|
||||
|
||||
Files:
|
||||
lib/mgetgroups.c
|
||||
lib/mgetgroups.h
|
||||
m4/mgetgroups.m4
|
||||
|
||||
Depends-on:
|
||||
getugroups
|
||||
xalloc
|
||||
|
||||
configure.ac:
|
||||
gl_MGETGROUPS
|
||||
|
||||
Makefile.am:
|
||||
|
||||
Include:
|
||||
|
||||
License:
|
||||
LGPL
|
||||
|
||||
Maintainer:
|
||||
Jim Meyering
|
||||
9
gl/modules/rename-tests.diff
Normal file
9
gl/modules/rename-tests.diff
Normal file
@@ -0,0 +1,9 @@
|
||||
diff --git a/modules/rename-tests b/modules/rename-tests
|
||||
index be1b423..fea330a 100644
|
||||
--- a/modules/rename-tests
|
||||
+++ b/modules/rename-tests
|
||||
@@ -14,3 +14,4 @@ configure.ac:
|
||||
Makefile.am:
|
||||
TESTS += test-rename
|
||||
check_PROGRAMS += test-rename
|
||||
+test_rename_LDADD = $(LDADD) @LIBINTL@
|
||||
@@ -1,25 +0,0 @@
|
||||
Description:
|
||||
a wrapper for frepoen
|
||||
|
||||
Files:
|
||||
lib/xfreopen.c
|
||||
lib/xfreopen.h
|
||||
|
||||
Depends-on:
|
||||
error
|
||||
exitfail
|
||||
quote
|
||||
|
||||
configure.ac:
|
||||
|
||||
Makefile.am:
|
||||
lib_SOURCES += xfreopen.c xfreopen.h
|
||||
|
||||
Include:
|
||||
"xfreopen.h"
|
||||
|
||||
License:
|
||||
LGPL
|
||||
|
||||
Maintainer:
|
||||
Jim Meyering
|
||||
2
gnulib
2
gnulib
Submodule gnulib updated: 3ef64012bf...63983c0aac
@@ -1 +1,3 @@
|
||||
include gnulib.mk
|
||||
|
||||
AM_CFLAGS = $(GNULIB_WARN_CFLAGS) # $(WERROR_CFLAGS)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
include gnulib.mk
|
||||
|
||||
AM_CFLAGS += $(WARN_CFLAGS) # $(WERROR_CFLAGS)
|
||||
AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
|
||||
|
||||
libcoreutils_a_SOURCES += \
|
||||
buffer-lcm.c buffer-lcm.h \
|
||||
|
||||
@@ -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)
|
||||
@@ -137,6 +130,6 @@ main (int argc, char **argv)
|
||||
|
||||
ok = euidaccess_stat (&st, mode);
|
||||
printf ("%s: %s\n", file, ok ? "y" : "n");
|
||||
exit (0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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=
|
||||
|
||||
50
lib/xfts.c
50
lib/xfts.c
@@ -21,13 +21,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
|
||||
#include "quote.h"
|
||||
#include "xalloc.h"
|
||||
#include "xfts.h"
|
||||
|
||||
@@ -35,29 +31,35 @@
|
||||
|
||||
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. */
|
||||
bool invalid_arg = false;
|
||||
for (; *argv; ++argv)
|
||||
{
|
||||
if (**argv == '\0')
|
||||
invalid_arg = true;
|
||||
}
|
||||
if (invalid_arg)
|
||||
error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
|
||||
else
|
||||
xalloc_die ();
|
||||
/* This can fail in two ways: out of memory or with errno==EINVAL,
|
||||
which indicates it was called with invalid bit_flags. */
|
||||
assert (errno != EINVAL);
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
return fts;
|
||||
}
|
||||
|
||||
/* When fts_read returns FTS_DC to indicate a directory cycle,
|
||||
it may or may not indicate a real problem. When a program like
|
||||
chgrp performs a recursive traversal that requires traversing
|
||||
symbolic links, it is *not* a problem. However, when invoked
|
||||
with "-P -R", it deserves a warning. The fts_options member
|
||||
records the options that control this aspect of fts's behavior,
|
||||
so test that. */
|
||||
bool
|
||||
cycle_warning_required (FTS const *fts, FTSENT const *ent)
|
||||
{
|
||||
#define ISSET(Fts,Opt) ((Fts)->fts_options & (Opt))
|
||||
/* When dereferencing no symlinks, or when dereferencing only
|
||||
those listed on the command line and we're not processing
|
||||
a command-line argument, then a cycle is a serious problem. */
|
||||
return ((ISSET (fts, FTS_PHYSICAL) && !ISSET (fts, FTS_COMFOLLOW))
|
||||
|| (ISSET (fts, FTS_PHYSICAL) && ISSET (fts, FTS_COMFOLLOW)
|
||||
&& ent->fts_level != FTS_ROOTLEVEL));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include <stdbool.h>
|
||||
#include "fts_.h"
|
||||
|
||||
FTS *
|
||||
xfts_open (char * const *, int options,
|
||||
int (*) (const FTSENT **, const FTSENT **));
|
||||
int (*) (const FTSENT **, const FTSENT **));
|
||||
|
||||
bool
|
||||
cycle_warning_required (FTS const *fts, FTSENT const *ent);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#serial 24
|
||||
#serial 26
|
||||
# Check declarations for this package.
|
||||
|
||||
dnl Copyright (C) 1997-2001, 2003-2006, 2008-2009 Free Software
|
||||
@@ -35,15 +35,7 @@ AC_DEFUN([gl_CHECK_DECLS],
|
||||
getpwuid,
|
||||
ttyname], , , $headers)
|
||||
|
||||
AC_CHECK_DECLS([isblank], [], [], [#include <ctype.h>])
|
||||
|
||||
AC_CHECK_DECLS_ONCE([free])
|
||||
AC_CHECK_DECLS_ONCE([getenv])
|
||||
AC_CHECK_DECLS_ONCE([geteuid])
|
||||
AC_CHECK_DECLS_ONCE([getlogin])
|
||||
AC_CHECK_DECLS_ONCE([getuid])
|
||||
AC_CHECK_DECLS_ONCE([lseek])
|
||||
AC_CHECK_DECLS_ONCE([malloc])
|
||||
AC_CHECK_DECLS_ONCE([memchr])
|
||||
AC_CHECK_DECLS_ONCE([realloc])
|
||||
])
|
||||
|
||||
@@ -30,7 +30,9 @@ AC_DEFUN([cu_GMP],
|
||||
LIB_GMP=$ac_cv_search___gmpz_init
|
||||
AC_DEFINE([HAVE_GMP], [1],
|
||||
[Define if you have GNU libgmp (or replacement)])
|
||||
}])
|
||||
}],
|
||||
[AC_MSG_WARN([libgmp development library was not found or not usable.])
|
||||
AC_MSG_WARN([AC_PACKAGE_NAME will be built without GMP support.])])
|
||||
LIBS=$cu_saved_libs
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -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
|
||||
@@ -89,33 +89,40 @@ AC_DEFUN([coreutils_MACROS],
|
||||
tcgetpgrp \
|
||||
)
|
||||
|
||||
# for cp.c
|
||||
AC_CHECK_FUNCS_ONCE([utimensat])
|
||||
|
||||
dnl This can't use AC_REQUIRE; I'm not quite sure why.
|
||||
cu_PREREQ_STAT_PROG
|
||||
|
||||
# for dd.c and shred.c
|
||||
coreutils_saved_libs=$LIBS
|
||||
LIB_FDATASYNC=
|
||||
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.])
|
||||
AC_MSG_WARN([AC_PACKAGE_NAME will be built without capability support.])
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([libcap support disabled by user])
|
||||
fi
|
||||
AC_SUBST([LIB_CAP])
|
||||
|
||||
# See if linking `seq' requires -lm.
|
||||
|
||||
@@ -51,10 +51,11 @@ $ac_includes_default
|
||||
|
||||
# SCO-ODT-3.0 is reported to need -lufc for crypt.
|
||||
# NetBSD needs -lcrypt for crypt.
|
||||
LIB_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
|
||||
])
|
||||
|
||||
15
m4/xattr.m4
15
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])
|
||||
@@ -22,13 +22,16 @@ AC_DEFUN([gl_FUNC_XATTR],
|
||||
use_xattr=1
|
||||
else
|
||||
use_xattr=0
|
||||
AC_MSG_WARN([libattr development library was not found or not usable.])
|
||||
AC_MSG_WARN([AC_PACKAGE_NAME will be built without xattr support.])
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([USE_XATTR], [$use_xattr],
|
||||
[Define if you want extended attribute support.])
|
||||
[Define if you want extended attribute support.])
|
||||
LIB_XATTR=
|
||||
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])
|
||||
|
||||
1
man/.gitignore
vendored
1
man/.gitignore
vendored
@@ -48,6 +48,7 @@ mv.1
|
||||
nice.1
|
||||
nl.1
|
||||
nohup.1
|
||||
nproc.1
|
||||
od.1
|
||||
paste.1
|
||||
pathchk.1
|
||||
|
||||
@@ -80,6 +80,7 @@ mv.1: $(common_dep) $(srcdir)/mv.x ../src/mv.c
|
||||
nice.1: $(common_dep) $(srcdir)/nice.x ../src/nice.c
|
||||
nl.1: $(common_dep) $(srcdir)/nl.x ../src/nl.c
|
||||
nohup.1: $(common_dep) $(srcdir)/nohup.x ../src/nohup.c
|
||||
nproc.1: $(common_dep) $(srcdir)/nproc.x ../src/nproc.c
|
||||
od.1: $(common_dep) $(srcdir)/od.x ../src/od.c
|
||||
paste.1: $(common_dep) $(srcdir)/paste.x ../src/paste.c
|
||||
pathchk.1: $(common_dep) $(srcdir)/pathchk.x ../src/pathchk.c
|
||||
|
||||
@@ -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]/)
|
||||
|
||||
4
man/nproc.x
Normal file
4
man/nproc.x
Normal file
@@ -0,0 +1,4 @@
|
||||
[NAME]
|
||||
nproc \- print the number of processing units available
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
@@ -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,13 +20,14 @@ 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
|
||||
lib/version-etc.c
|
||||
lib/xalloc-die.c
|
||||
lib/xfreopen.c
|
||||
lib/xfts.c
|
||||
lib/xmemcoll.c
|
||||
lib/xmemxfrm.c
|
||||
lib/xprintf.c
|
||||
@@ -87,6 +88,7 @@ src/mv.c
|
||||
src/nice.c
|
||||
src/nl.c
|
||||
src/nohup.c
|
||||
src/nproc.c
|
||||
src/od.c
|
||||
src/operand2sig.c
|
||||
src/paste.c
|
||||
|
||||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@@ -56,6 +56,7 @@ mv
|
||||
nice
|
||||
nl
|
||||
nohup
|
||||
nproc
|
||||
od
|
||||
paste
|
||||
pathchk
|
||||
|
||||
443
src/Makefile.am
443
src/Makefile.am
@@ -24,25 +24,115 @@ no_install__progs = \
|
||||
arch hostname su
|
||||
|
||||
build_if_possible__progs = \
|
||||
chroot df hostid nice pinky stdbuf libstdbuf.so stty su uname uptime users who
|
||||
chroot \
|
||||
df \
|
||||
hostid \
|
||||
libstdbuf.so \
|
||||
nice \
|
||||
pinky \
|
||||
stdbuf \
|
||||
stty \
|
||||
su \
|
||||
uptime \
|
||||
users \
|
||||
who
|
||||
|
||||
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
|
||||
|
||||
EXTRA_PROGRAMS = \
|
||||
$(no_install__progs) \
|
||||
$(build_if_possible__progs) \
|
||||
[ chcon chgrp chown chmod cp dd dircolors du \
|
||||
ginstall link ln dir vdir ls mkdir \
|
||||
mkfifo mknod mktemp \
|
||||
mv nohup readlink rm rmdir shred stat sync touch unlink \
|
||||
cat cksum comm csplit cut expand fmt fold head join groups md5sum \
|
||||
nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \
|
||||
shuf sort split sum tac tail tr tsort unexpand uniq wc \
|
||||
basename date dirname echo env expr factor false \
|
||||
id kill logname pathchk printenv printf pwd \
|
||||
runcon seq sleep tee \
|
||||
test timeout true truncate tty whoami yes \
|
||||
base64
|
||||
[ \
|
||||
base64 \
|
||||
basename \
|
||||
cat \
|
||||
chcon \
|
||||
chgrp \
|
||||
chmod \
|
||||
chown \
|
||||
cksum \
|
||||
comm \
|
||||
cp \
|
||||
csplit \
|
||||
cut \
|
||||
date \
|
||||
dd \
|
||||
dir \
|
||||
dircolors \
|
||||
dirname \
|
||||
du \
|
||||
echo \
|
||||
env \
|
||||
expand \
|
||||
expr \
|
||||
factor \
|
||||
false \
|
||||
fmt \
|
||||
fold \
|
||||
ginstall \
|
||||
groups \
|
||||
head \
|
||||
id \
|
||||
join \
|
||||
kill \
|
||||
link \
|
||||
ln \
|
||||
logname \
|
||||
ls \
|
||||
md5sum \
|
||||
mkdir \
|
||||
mkfifo \
|
||||
mknod \
|
||||
mktemp \
|
||||
mv \
|
||||
nl \
|
||||
nproc \
|
||||
nohup \
|
||||
od \
|
||||
paste \
|
||||
pathchk \
|
||||
pr \
|
||||
printenv \
|
||||
printf \
|
||||
ptx \
|
||||
pwd \
|
||||
readlink \
|
||||
rm \
|
||||
rmdir \
|
||||
runcon \
|
||||
seq \
|
||||
sha1sum \
|
||||
sha224sum \
|
||||
sha256sum \
|
||||
sha384sum \
|
||||
sha512sum \
|
||||
shred \
|
||||
shuf \
|
||||
sleep \
|
||||
sort \
|
||||
split \
|
||||
stat \
|
||||
sum \
|
||||
sync \
|
||||
tac \
|
||||
tail \
|
||||
tee \
|
||||
test \
|
||||
timeout \
|
||||
touch \
|
||||
tr \
|
||||
true \
|
||||
truncate \
|
||||
tsort \
|
||||
tty \
|
||||
uname \
|
||||
unexpand \
|
||||
uniq \
|
||||
unlink \
|
||||
vdir \
|
||||
wc \
|
||||
whoami \
|
||||
yes
|
||||
|
||||
bin_PROGRAMS = $(OPTIONAL_BIN_PROGS)
|
||||
|
||||
@@ -50,20 +140,20 @@ noinst_PROGRAMS = setuidgid getlimits
|
||||
|
||||
pkglib_PROGRAMS = $(OPTIONAL_PKGLIB_PROGS)
|
||||
|
||||
noinst_HEADERS = \
|
||||
chown-core.h \
|
||||
copy.h \
|
||||
cp-hash.h \
|
||||
dircolors.h \
|
||||
fs.h \
|
||||
group-list.h \
|
||||
ls.h \
|
||||
operand2sig.h \
|
||||
prog-fprintf.h \
|
||||
remove.h \
|
||||
system.h \
|
||||
wheel-size.h \
|
||||
wheel.h \
|
||||
noinst_HEADERS = \
|
||||
chown-core.h \
|
||||
copy.h \
|
||||
cp-hash.h \
|
||||
dircolors.h \
|
||||
fs.h \
|
||||
group-list.h \
|
||||
ls.h \
|
||||
operand2sig.h \
|
||||
prog-fprintf.h \
|
||||
remove.h \
|
||||
system.h \
|
||||
wheel-size.h \
|
||||
wheel.h \
|
||||
uname.h
|
||||
|
||||
EXTRA_DIST = dcgen dircolors.hin tac-pipe.c \
|
||||
@@ -87,99 +177,218 @@ nodist_libver_a_SOURCES = version.c version.h
|
||||
# replacement functions defined in libcoreutils.a.
|
||||
LDADD = libver.a ../lib/libcoreutils.a $(LIBINTL) ../lib/libcoreutils.a
|
||||
|
||||
# First, list all programs, to make listing per-program libraries easier.
|
||||
# See [ below.
|
||||
arch_LDADD = $(LDADD)
|
||||
base64_LDADD = $(LDADD)
|
||||
basename_LDADD = $(LDADD)
|
||||
cat_LDADD = $(LDADD)
|
||||
chcon_LDADD = $(LDADD)
|
||||
chgrp_LDADD = $(LDADD)
|
||||
chmod_LDADD = $(LDADD)
|
||||
chown_LDADD = $(LDADD)
|
||||
chroot_LDADD = $(LDADD)
|
||||
cksum_LDADD = $(LDADD)
|
||||
comm_LDADD = $(LDADD)
|
||||
nproc_LDADD = $(LDADD)
|
||||
cp_LDADD = $(LDADD)
|
||||
csplit_LDADD = $(LDADD)
|
||||
cut_LDADD = $(LDADD)
|
||||
date_LDADD = $(LDADD)
|
||||
dd_LDADD = $(LDADD)
|
||||
df_LDADD = $(LDADD)
|
||||
# See dir_LDADD below
|
||||
dircolors_LDADD = $(LDADD)
|
||||
dirname_LDADD = $(LDADD)
|
||||
du_LDADD = $(LDADD)
|
||||
echo_LDADD = $(LDADD)
|
||||
env_LDADD = $(LDADD)
|
||||
expand_LDADD = $(LDADD)
|
||||
expr_LDADD = $(LDADD)
|
||||
factor_LDADD = $(LDADD)
|
||||
false_LDADD = $(LDADD)
|
||||
fmt_LDADD = $(LDADD)
|
||||
fold_LDADD = $(LDADD)
|
||||
getlimits_LDADD = $(LDADD)
|
||||
ginstall_LDADD = $(LDADD)
|
||||
groups_LDADD = $(LDADD)
|
||||
head_LDADD = $(LDADD)
|
||||
hostid_LDADD = $(LDADD)
|
||||
hostname_LDADD = $(LDADD)
|
||||
id_LDADD = $(LDADD)
|
||||
join_LDADD = $(LDADD)
|
||||
kill_LDADD = $(LDADD)
|
||||
link_LDADD = $(LDADD)
|
||||
ln_LDADD = $(LDADD)
|
||||
logname_LDADD = $(LDADD)
|
||||
ls_LDADD = $(LDADD)
|
||||
md5sum_LDADD = $(LDADD)
|
||||
mkdir_LDADD = $(LDADD)
|
||||
mkfifo_LDADD = $(LDADD)
|
||||
mknod_LDADD = $(LDADD)
|
||||
mktemp_LDADD = $(LDADD)
|
||||
mv_LDADD = $(LDADD)
|
||||
nice_LDADD = $(LDADD)
|
||||
nl_LDADD = $(LDADD)
|
||||
nohup_LDADD = $(LDADD)
|
||||
od_LDADD = $(LDADD)
|
||||
paste_LDADD = $(LDADD)
|
||||
pathchk_LDADD = $(LDADD)
|
||||
pinky_LDADD = $(LDADD)
|
||||
pr_LDADD = $(LDADD)
|
||||
printenv_LDADD = $(LDADD)
|
||||
printf_LDADD = $(LDADD)
|
||||
ptx_LDADD = $(LDADD)
|
||||
pwd_LDADD = $(LDADD)
|
||||
readlink_LDADD = $(LDADD)
|
||||
rm_LDADD = $(LDADD)
|
||||
rmdir_LDADD = $(LDADD)
|
||||
runcon_LDADD = $(LDADD)
|
||||
seq_LDADD = $(LDADD)
|
||||
setuidgid_LDADD = $(LDADD)
|
||||
sha1sum_LDADD = $(LDADD)
|
||||
sha224sum_LDADD = $(LDADD)
|
||||
sha256sum_LDADD = $(LDADD)
|
||||
sha384sum_LDADD = $(LDADD)
|
||||
sha512sum_LDADD = $(LDADD)
|
||||
shred_LDADD = $(LDADD)
|
||||
shuf_LDADD = $(LDADD)
|
||||
sleep_LDADD = $(LDADD)
|
||||
sort_LDADD = $(LDADD)
|
||||
split_LDADD = $(LDADD)
|
||||
stat_LDADD = $(LDADD)
|
||||
stdbuf_LDADD = $(LDADD)
|
||||
stty_LDADD = $(LDADD)
|
||||
su_LDADD = $(LDADD)
|
||||
sum_LDADD = $(LDADD)
|
||||
sync_LDADD = $(LDADD)
|
||||
tac_LDADD = $(LDADD)
|
||||
tail_LDADD = $(LDADD)
|
||||
tee_LDADD = $(LDADD)
|
||||
test_LDADD = $(LDADD)
|
||||
timeout_LDADD = $(LDADD)
|
||||
touch_LDADD = $(LDADD)
|
||||
tr_LDADD = $(LDADD)
|
||||
true_LDADD = $(LDADD)
|
||||
truncate_LDADD = $(LDADD)
|
||||
tsort_LDADD = $(LDADD)
|
||||
tty_LDADD = $(LDADD)
|
||||
uname_LDADD = $(LDADD)
|
||||
unexpand_LDADD = $(LDADD)
|
||||
uniq_LDADD = $(LDADD)
|
||||
unlink_LDADD = $(LDADD)
|
||||
uptime_LDADD = $(LDADD)
|
||||
users_LDADD = $(LDADD)
|
||||
# See vdir_LDADD below
|
||||
wc_LDADD = $(LDADD)
|
||||
who_LDADD = $(LDADD)
|
||||
whoami_LDADD = $(LDADD)
|
||||
yes_LDADD = $(LDADD)
|
||||
|
||||
# for eaccess in lib/euidaccess.c.
|
||||
chcon_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
cp_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
|
||||
ginstall_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
|
||||
mkdir_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mkfifo_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mknod_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
mv_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
|
||||
runcon_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
pathchk_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
rm_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
test_LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
# This is for the '[' program. Automake transliterates '[' to '_'.
|
||||
__LDADD = $(LDADD) $(LIB_EACCESS)
|
||||
# Synonyms. Recall that Automake transliterates '[' to '_'.
|
||||
__LDADD = $(test_LDADD)
|
||||
dir_LDADD = $(ls_LDADD)
|
||||
vdir_LDADD = $(ls_LDADD)
|
||||
|
||||
# for clock_gettime and fdatasync
|
||||
dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
|
||||
dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
|
||||
id_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
|
||||
mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME)
|
||||
pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
|
||||
shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME)
|
||||
tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
|
||||
# Shared files
|
||||
copy_LDADD =
|
||||
cp_LDADD += $(copy_LDADD)
|
||||
ginstall_LDADD += $(copy_LDADD)
|
||||
mv_LDADD += $(copy_LDADD)
|
||||
|
||||
## If necessary, add -lm to resolve use of pow in lib/strtod.c.
|
||||
sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME)
|
||||
remove_LDADD =
|
||||
mv_LDADD += $(remove_LDADD)
|
||||
rm_LDADD += $(remove_LDADD)
|
||||
|
||||
# for get_date and gettime
|
||||
date_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
touch_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
# for eaccess, euidaccess
|
||||
copy_LDADD += $(LIB_EACCESS)
|
||||
remove_LDADD += $(LIB_EACCESS)
|
||||
test_LDADD += $(LIB_EACCESS)
|
||||
|
||||
# If necessary, add -lm to resolve use of pow in lib/strtod.c.
|
||||
# If necessary, add -liconv to resolve use of iconv in lib/unicodeio.c.
|
||||
printf_LDADD = $(LDADD) $(POW_LIB) $(LIBICONV)
|
||||
# for selinux use
|
||||
chcon_LDADD += $(LIB_SELINUX)
|
||||
copy_LDADD += $(LIB_SELINUX)
|
||||
ginstall_LDADD += $(LIB_SELINUX)
|
||||
id_LDADD += $(LIB_SELINUX)
|
||||
ls_LDADD += $(LIB_SELINUX)
|
||||
mkdir_LDADD += $(LIB_SELINUX)
|
||||
mkfifo_LDADD += $(LIB_SELINUX)
|
||||
mknod_LDADD += $(LIB_SELINUX)
|
||||
runcon_LDADD += $(LIB_SELINUX)
|
||||
stat_LDADD += $(LIB_SELINUX)
|
||||
|
||||
# If necessary, add -lm to resolve use of pow in lib/strtod.c.
|
||||
seq_LDADD = $(LDADD) $(POW_LIB)
|
||||
# for gettime, settime, utimecmp, utimens
|
||||
copy_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
date_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
ginstall_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
ls_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
pr_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
touch_LDADD += $(LIB_CLOCK_GETTIME)
|
||||
|
||||
# If necessary, add libraries to resolve the `pow' reference in lib/strtod.c
|
||||
# and the `nanosleep' reference in lib/xnanosleep.c.
|
||||
nanosec_libs = $(LDADD) $(POW_LIB) $(LIB_NANOSLEEP)
|
||||
# for gethrxtime, randint, randread, gen_tempname
|
||||
dd_LDADD += $(LIB_GETHRXTIME)
|
||||
mktemp_LDADD += $(LIB_GETHRXTIME)
|
||||
shred_LDADD += $(LIB_GETHRXTIME)
|
||||
shuf_LDADD += $(LIB_GETHRXTIME)
|
||||
sort_LDADD += $(LIB_GETHRXTIME)
|
||||
|
||||
# for cap_get_file
|
||||
ls_LDADD += $(LIB_CAP)
|
||||
|
||||
# for fdatasync
|
||||
dd_LDADD += $(LIB_FDATASYNC)
|
||||
shred_LDADD += $(LIB_FDATASYNC)
|
||||
|
||||
# for strtod, strtold
|
||||
printf_LDADD += $(POW_LIB)
|
||||
seq_LDADD += $(POW_LIB)
|
||||
sleep_LDADD += $(POW_LIB)
|
||||
sort_LDADD += $(POW_LIB)
|
||||
tail_LDADD += $(POW_LIB)
|
||||
uptime_LDADD += $(POW_LIB)
|
||||
|
||||
# for xnanosleep
|
||||
sleep_LDADD += $(LIB_NANOSLEEP)
|
||||
sort_LDADD += $(LIB_NANOSLEEP)
|
||||
tail_LDADD += $(LIB_NANOSLEEP)
|
||||
|
||||
# for various GMP functions
|
||||
expr_LDADD = $(LDADD) $(LIB_GMP)
|
||||
expr_LDADD += $(LIB_GMP)
|
||||
factor_LDADD += $(LIB_GMP)
|
||||
|
||||
# for various GMP functions
|
||||
factor_LDADD = $(LDADD) $(LIB_GMP)
|
||||
# for getloadavg
|
||||
uptime_LDADD += $(GETLOADAVG_LIBS)
|
||||
|
||||
sleep_LDADD = $(nanosec_libs)
|
||||
tail_LDADD = $(nanosec_libs)
|
||||
# for crypt
|
||||
su_LDADD += $(LIB_CRYPT)
|
||||
|
||||
# If necessary, add -lm to resolve use of pow in lib/strtod.c.
|
||||
uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS)
|
||||
|
||||
su_LDADD = $(LDADD) $(LIB_CRYPT)
|
||||
|
||||
dir_LDADD += $(LIB_ACL)
|
||||
# for various ACL functions
|
||||
copy_LDADD += $(LIB_ACL)
|
||||
ls_LDADD += $(LIB_ACL)
|
||||
vdir_LDADD += $(LIB_ACL)
|
||||
cp_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
||||
mv_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
||||
ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
||||
|
||||
stat_LDADD = $(LDADD) $(LIB_SELINUX)
|
||||
# for various xattr functions
|
||||
copy_LDADD += $(LIB_XATTR)
|
||||
|
||||
# Append $(LIBICONV) to each program that uses proper_name_utf8.
|
||||
# for print_unicode_char, proper_name_utf8
|
||||
cat_LDADD += $(LIBICONV)
|
||||
cp_LDADD += $(LIBICONV)
|
||||
df_LDADD += $(LIBICONV)
|
||||
du_LDADD += $(LIBICONV)
|
||||
getlimits_LDADD += $(LIBICONV)
|
||||
printf_LDADD += $(LIBICONV)
|
||||
ptx_LDADD += $(LIBICONV)
|
||||
split_LDADD += $(LIBICONV)
|
||||
stdbuf_LDADD += $(LIBICONV)
|
||||
timeout_LDADD += $(LIBICONV)
|
||||
truncate_LDADD += $(LIBICONV)
|
||||
|
||||
# programs that use getaddrinfo (e.g., via canon_host)
|
||||
pinky_LDADD = $(LDADD) $(GETADDRINFO_LIB)
|
||||
who_LDADD = $(LDADD) $(GETADDRINFO_LIB)
|
||||
# for canon_host
|
||||
pinky_LDADD += $(GETADDRINFO_LIB)
|
||||
who_LDADD += $(GETADDRINFO_LIB)
|
||||
|
||||
# for gethostname, uname
|
||||
hostname_LDADD += $(GETHOSTNAME_LIB)
|
||||
uname_LDADD += $(GETHOSTNAME_LIB)
|
||||
|
||||
$(PROGRAMS): ../lib/libcoreutils.a
|
||||
|
||||
@@ -274,6 +483,7 @@ rmdir_SOURCES = rmdir.c prog-fprintf.c
|
||||
|
||||
uname_SOURCES = uname.c uname-uname.c
|
||||
arch_SOURCES = uname.c uname-arch.c
|
||||
nproc_SOURCES = nproc.c
|
||||
|
||||
md5sum_SOURCES = md5sum.c
|
||||
md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS)
|
||||
@@ -330,6 +540,59 @@ wheel.h: wheel-gen.pl Makefile.am
|
||||
# Tell automake to exempt then from that installcheck test.
|
||||
AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = false test
|
||||
|
||||
# Compare fs.h with the list of file system names/magic-numbers in the
|
||||
# Linux statfs man page. This target prints any new name/number pairs.
|
||||
# Also compare against /usr/include/linux/magic.h
|
||||
.PHONY: fs-magic-compare
|
||||
fs-magic-compare: fs-magic fs-kernel-magic fs-def
|
||||
join -v1 -t@ fs-magic fs-def
|
||||
join -v1 -t@ fs-kernel-magic fs-def
|
||||
|
||||
CLEANFILES += fs-def
|
||||
fs-def: fs.h
|
||||
grep '^# *define ' $< > $@-t && mv $@-t $@
|
||||
|
||||
# Massage bits of the statfs man page and definitions from
|
||||
# /usr/include/linux/magic.h to be in a form consistent with what's in fs.h.
|
||||
fs_normalize_perl_subst = \
|
||||
-e 's/MINIX_SUPER_MAGIC\b/MINIX/;' \
|
||||
-e 's/MINIX_SUPER_MAGIC2\b/MINIX_30/;' \
|
||||
-e 's/MINIX2_SUPER_MAGIC\b/MINIX_V2/;' \
|
||||
-e 's/MINIX2_SUPER_MAGIC2\b/MINIX_V2_30/;' \
|
||||
-e 's/MINIX3_SUPER_MAGIC\b/MINIX_V3/;' \
|
||||
-e 's/CIFS_MAGIC_NUMBER/CIFS/;' \
|
||||
-e 's/(_SUPER)?_MAGIC//;' \
|
||||
-e 's/\s+0x(\S+)/" 0x" . uc $$1/e;' \
|
||||
-e 's/(\s+0x)(\X{3})\b/$${1}0$$2/;' \
|
||||
-e 's/(\s+0x)(\X{6})\b/$${1}00$$2/;' \
|
||||
-e 's/(\s+0x)(\X{7})\b/$${1}0$$2/;' \
|
||||
-e 's/^\s+//;' \
|
||||
-e 's/^\#define\s+//;' \
|
||||
-e 's/^_(XIAFS)/$$1/;' \
|
||||
-e 's/^USBDEVICE/USBDEVFS/;' \
|
||||
-e 's/NTFS_SB/NTFS/;' \
|
||||
-e 's/^/\# define S_MAGIC_/;' \
|
||||
-e 's,\s*/\* .*? \*/,,;'
|
||||
|
||||
CLEANFILES += fs-magic
|
||||
fs-magic: Makefile
|
||||
man statfs \
|
||||
|perl -ne '/File system types:/.../Nobody kno/ and print' \
|
||||
|grep 0x | perl -p \
|
||||
$(fs_normalize_perl_subst) \
|
||||
| grep -Ev 'S_MAGIC_EXT[34]|STACK_END' \
|
||||
| LC_ALL=C sort \
|
||||
> $@-t && mv $@-t $@
|
||||
|
||||
CLEANFILES += fs-kernel-magic
|
||||
fs-kernel-magic: Makefile
|
||||
perl -ne '/^#define.*0x/ and print' /usr/include/linux/magic.h \
|
||||
| perl -p \
|
||||
$(fs_normalize_perl_subst) \
|
||||
| grep -Ev 'S_MAGIC_EXT[34]|STACK_END' \
|
||||
| LC_ALL=C sort \
|
||||
> $@-t && mv $@-t $@
|
||||
|
||||
BUILT_SOURCES += fs.h
|
||||
fs.h: stat.c extract-magic
|
||||
$(AM_V_GEN)rm -f $@
|
||||
@@ -385,21 +648,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 +716,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);
|
||||
|
||||
|
||||
316
src/chcon.c
316
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,10 +263,18 @@ 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;
|
||||
|
||||
case FTS_DC: /* directory that causes cycles */
|
||||
if (cycle_warning_required (fts, ent))
|
||||
{
|
||||
emit_cycle_warning (file_full_name);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -280,11 +289,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 +319,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 +346,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 +354,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 +388,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 +420,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 +521,17 @@ 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 (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,24 +546,24 @@ 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);
|
||||
}
|
||||
|
||||
if (reference_file && component_specified)
|
||||
{
|
||||
error (0, 0, _("conflicting security context specifiers given"));
|
||||
usage (1);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
333
src/chmod.c
333
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,15 +219,24 @@ 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;
|
||||
break;
|
||||
|
||||
case FTS_DC: /* directory that causes cycles */
|
||||
if (cycle_warning_required (fts, ent))
|
||||
{
|
||||
emit_cycle_warning (file_full_name);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -238,63 +248,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 +330,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 +358,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 +366,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 +388,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 +418,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 +518,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 +546,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);
|
||||
}
|
||||
|
||||
354
src/chown-core.c
354
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,10 +312,18 @@ 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;
|
||||
|
||||
case FTS_DC: /* directory that causes cycles */
|
||||
if (cycle_warning_required (fts, ent))
|
||||
{
|
||||
emit_cycle_warning (file_full_name);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -325,9 +334,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 +346,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 +379,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 +481,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 +502,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 */
|
||||
|
||||
165
src/chown.c
165
src/chown.c
@@ -14,18 +14,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
| user
|
||||
| unchanged explicit
|
||||
-------------|-------------------------+-------------------------|
|
||||
g unchanged | --- | chown u |
|
||||
r |-------------------------+-------------------------|
|
||||
o explicit | chgrp g or chown .g | chown u.g |
|
||||
u |-------------------------+-------------------------|
|
||||
p from passwd| --- | chown u. |
|
||||
|-------------------------+-------------------------|
|
||||
|
||||
Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
@@ -85,14 +74,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 +141,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 +182,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 +272,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 +282,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 +293,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);
|
||||
|
||||
|
||||
26
src/chroot.c
26
src/chroot.c
@@ -91,7 +91,7 @@ set_additional_groups (char const *groups)
|
||||
}
|
||||
|
||||
if (n_gids == n_gids_allocated)
|
||||
gids = x2nrealloc (gids, &n_gids_allocated, sizeof *gids);
|
||||
gids = X2NREALLOC (gids, &n_gids_allocated);
|
||||
gids[n_gids++] = value;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -160,11 +160,11 @@ main (int argc, char **argv)
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
initialize_exit_failure (EXIT_FAILURE);
|
||||
initialize_exit_failure (EXIT_CANCELED);
|
||||
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)
|
||||
{
|
||||
@@ -177,29 +177,29 @@ main (int argc, char **argv)
|
||||
groups = optarg;
|
||||
break;
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_CANCELED);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= optind)
|
||||
{
|
||||
error (0, 0, _("missing operand"));
|
||||
usage (EXIT_FAILURE);
|
||||
usage (EXIT_CANCELED);
|
||||
}
|
||||
|
||||
if (chroot (argv[optind]) != 0)
|
||||
error (EXIT_FAILURE, errno, _("cannot change root directory to %s"),
|
||||
argv[optind]);
|
||||
error (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
|
||||
argv[optind]);
|
||||
|
||||
if (chdir ("/"))
|
||||
error (EXIT_FAILURE, errno, _("cannot chdir to root directory"));
|
||||
error (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
|
||||
|
||||
if (argc == optind + 1)
|
||||
{
|
||||
/* 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;
|
||||
@@ -223,7 +223,7 @@ main (int argc, char **argv)
|
||||
char const *err = parse_user_spec (userspec, &uid, &gid, &user, &group);
|
||||
|
||||
if (err)
|
||||
error (EXIT_FAILURE, errno, "%s", err);
|
||||
error (EXIT_CANCELED, errno, "%s", err);
|
||||
|
||||
free (user);
|
||||
free (group);
|
||||
@@ -254,7 +254,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
if (fail)
|
||||
exit (EXIT_FAILURE);
|
||||
exit (EXIT_CANCELED);
|
||||
|
||||
/* Execute the given command. */
|
||||
execvp (argv[0], argv);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
2158
src/copy.c
2158
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);
|
||||
}
|
||||
|
||||
|
||||
300
src/dircolors.c
300
src/dircolors.c
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "dircolors.h"
|
||||
@@ -27,6 +26,7 @@
|
||||
#include "error.h"
|
||||
#include "obstack.h"
|
||||
#include "quote.h"
|
||||
#include "stdio--.h"
|
||||
#include "xstrndup.h"
|
||||
|
||||
/* The official name of this program (e.g., no `g' prefix). */
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user