Compare commits

...

123 Commits

Author SHA1 Message Date
Jim Meyering
8c8f0df4f0 [HAVE_INTTYPES_H]: Include <inttypes.h>. 2000-12-23 10:43:33 +00:00
Jim Meyering
69e09f0559 *** empty log message *** 2000-12-22 22:45:32 +00:00
Jim Meyering
1a18604b2e (isaac_seed_machdep) [_ARCH_PPC]: Disable the code
that would use the PPC mfspr `asm' code.
2000-12-22 22:44:30 +00:00
Jim Meyering
eae1c2b69c . 2000-12-19 11:06:05 +00:00
Jim Meyering
4c038111f8 *** empty log message *** 2000-12-19 10:51:39 +00:00
Jim Meyering
a82d4c2b3d . 2000-12-19 10:50:31 +00:00
Jim Meyering
0cba2d7f5b *** empty log message *** 2000-12-19 10:37:30 +00:00
Jim Meyering
a87ae161be . 2000-12-19 10:25:15 +00:00
Jim Meyering
275b1879c3 . 2000-12-19 10:25:15 +00:00
Jim Meyering
66cf2ad8ce *** empty log message *** 2000-12-19 09:23:47 +00:00
Jim Meyering
0966c0f860 . 2000-12-19 09:23:09 +00:00
Jim Meyering
83a6c55c74 (UINTMAX_MAX): New macro, taken from C99. 2000-12-19 09:22:24 +00:00
Jim Meyering
3c46adfe19 adjust indentation 2000-12-19 09:21:42 +00:00
Jim Meyering
0787040b75 *** empty log message *** 2000-12-19 09:16:39 +00:00
Jim Meyering
bf86c62a33 Include physmem.h.
(SORTALLOC, mergealloc, LINEALLOC): Remove.
(sortalloc): Default to zero at program startup.
(SORTALLOC_MIN, SORTALLOC_DEFAULT_MIN): New macros.
(usage, main): Add support for new -S SIZE option.
(specify_sort_size, default_sort_size): New functions.
(initlines): Do not let alloc exceed limit.
(findlines): Likewise.
(checkfp, mergefps, sort): Use sortalloc to size everything
else, instead of relying on precomputed sizes.
2000-12-19 09:16:28 +00:00
Jim Meyering
915dacbb85 New "sort" option -S SIZE. 2000-12-19 08:40:54 +00:00
Jim Meyering
b6b86da148 *** empty log message *** 2000-12-19 08:36:53 +00:00
Jim Meyering
de38d76a18 (libfetish_a_SOURCES): Add physmem.c.
(noinst_HEADERS): Add physmem.h.
2000-12-19 08:36:39 +00:00
Jim Meyering
166c00189a (__xstrtol): Add undocumented suffixes 'g' and
't' for compatibility with Solaris 8 sort.
2000-12-19 08:35:20 +00:00
Jim Meyering
bca787f7c4 *** empty log message *** 2000-12-19 08:22:18 +00:00
Jim Meyering
258f00968a *** empty log message *** 2000-12-19 08:16:25 +00:00
Jim Meyering
bc40f9fcef (locale_charset): Add support for Win32. 2000-12-19 08:16:09 +00:00
Jim Meyering
d81418fd5e . 2000-12-18 23:43:27 +00:00
Jim Meyering
85ab4b9988 *** empty log message *** 2000-12-18 23:04:34 +00:00
Jim Meyering
f75f8a4b1d Add support for BeOS. 2000-12-18 23:04:28 +00:00
Jim Meyering
dfada44550 these macros take arguments 2000-12-17 09:26:55 +00:00
Jim Meyering
5d4c822ef7 *** empty log message *** 2000-12-17 09:23:05 +00:00
Jim Meyering
55f51356fb (jm_AC_DOS): New file and macro. 2000-12-17 09:22:56 +00:00
Jim Meyering
3f6afc4a7a (jm_MACROS): Require jm_AC_DOS. 2000-12-17 09:22:17 +00:00
Jim Meyering
dc87bf344c *** empty log message *** 2000-12-17 00:19:05 +00:00
Jim Meyering
7a41a27413 *** empty log message *** 2000-12-17 00:18:50 +00:00
Jim Meyering
8dc25234e0 *** empty log message *** 2000-12-17 00:17:26 +00:00
Jim Meyering
24ad4ecf29 *** empty log message *** 2000-12-17 00:17:03 +00:00
Jim Meyering
c9f0363bea . 2000-12-17 00:15:02 +00:00
Jim Meyering
c44bd5683d Update from master repository. 2000-12-17 00:14:40 +00:00
Jim Meyering
ae8bf0e8f1 . 2000-12-16 23:35:38 +00:00
Jim Meyering
fbba4d8d5e *** empty log message *** 2000-12-16 22:27:18 +00:00
Jim Meyering
2b64713ac6 *** empty log message *** 2000-12-16 22:26:23 +00:00
Jim Meyering
2464a2cd9d [!SHELLS_FILE && __DJGPP__]: Define
SHELLS_FILE to a file name that's useful on djgpp systems.
Include stdlib.h.
(ADDITIONAL_DEFAULT_SHELLS): Define.
(default_shells): Prepend ADDITIONAL_DEFAULT_SHELLS.
Based mostly on a patch from Prashant TR.
2000-12-16 22:25:44 +00:00
Jim Meyering
96e6715ebe . 2000-12-16 18:53:08 +00:00
Jim Meyering
72d973cb61 (uint_to_string): New function.
(uid_to_name): Use it.
(gid_to_name): Use it.
Rename locals, user/group, to uid/gid.
2000-12-16 18:52:58 +00:00
Jim Meyering
39d300f12b (enum Change_status): Start with 1. 2000-12-16 18:47:43 +00:00
Jim Meyering
76f8538bf6 . 2000-12-16 14:49:25 +00:00
Jim Meyering
71411370e7 *** empty log message *** 2000-12-16 13:41:40 +00:00
Jim Meyering
eb24d1f55c *** empty log message *** 2000-12-16 13:40:37 +00:00
Jim Meyering
608b347584 This bug had a serious impact on chown: `chown N:M FILE' (for integer
N and M) would have treated it like `chown N:N FILE'.
(parse_user_spec): Fix typo: s/u/g/.
2000-12-16 13:28:13 +00:00
Jim Meyering
6c4cbe6b5f (main): Rename local, group, to gid. 2000-12-16 13:10:05 +00:00
Jim Meyering
ad31d9b60c tweak a comment 2000-12-16 13:01:24 +00:00
Jim Meyering
8e2ee9a689 (main): Rename locals, user/group, to uid/gid. 2000-12-16 12:57:14 +00:00
Jim Meyering
067af316b6 *** empty log message *** 2000-12-16 09:23:52 +00:00
Jim Meyering
c0ab7dc021 *** empty log message *** 2000-12-16 09:23:32 +00:00
Jim Meyering
8233adab59 Use group-names. 2000-12-16 09:23:10 +00:00
Jim Meyering
be74434bbd Use group-names. 2000-12-16 09:21:20 +00:00
Jim Meyering
bbc027cf8b *** empty log message *** 2000-12-16 09:19:34 +00:00
Jim Meyering
43da73f064 Don't assume that creating a file gives it group $g1. 2000-12-16 09:11:24 +00:00
Jim Meyering
ffc1ef87ea . 2000-12-16 08:20:57 +00:00
Jim Meyering
66e2135f07 (TESTS): Add recurse. 2000-12-16 08:20:11 +00:00
Jim Meyering
e6a5c51ed7 Add ISO-8859-3, BIG5HKSCS, GB18030, JOHAB, VISCII,
CP874, CP949, CP950, CP1250, CP1253, CP1254, CP1255, CP1256, CP1257
to the list of canonical encodings. Rename EUC-CN to GB2312.
2000-12-15 23:43:55 +00:00
Jim Meyering
d952853f74 *** empty log message *** 2000-12-15 14:49:48 +00:00
Jim Meyering
3ebf224b28 *** empty log message *** 2000-12-15 14:45:50 +00:00
Jim Meyering
9be2faa156 *** empty log message *** 2000-12-15 13:32:24 +00:00
Jim Meyering
a8fff5ee1f *** empty log message *** 2000-12-15 13:31:21 +00:00
Jim Meyering
4ab4534292 . 2000-12-15 13:30:32 +00:00
Jim Meyering
0e81b6b48e (main): Reflect renaming: s/dereference/change_symlinks/. 2000-12-15 13:29:56 +00:00
Jim Meyering
694c6b3a86 (enum Dereference_symlink): rename member: s/change_symlinks/dereference/ 2000-12-15 13:27:03 +00:00
Jim Meyering
9724aab7a6 Declare lstat.
Rename change_symlinks member to `dereference' and use the DEREF_*
enum values.
(describe_change): Merge the chgrp and chown switch statements.
Use xmalloc to form the `user:group' string.
(change_file_owner): Record (and later, use) is_symlink and is_directory
from the lstat stats, in order to control whether we operate on symlinks
and whether (with -R) we traverse symlinks to directories.
When dereferencing, use open/fchown (rather than chown) on symlinks.
2000-12-15 13:24:47 +00:00
Jim Meyering
b6ca14a123 changed messages to match those chgrp now produces 2000-12-15 08:42:35 +00:00
Jim Meyering
976f3796be *** empty log message *** 2000-12-14 15:01:55 +00:00
Jim Meyering
1c643649b0 *** empty log message *** 2000-12-14 15:01:24 +00:00
Jim Meyering
3337b5a092 *** empty log message *** 2000-12-14 14:52:15 +00:00
Jim Meyering
b41ab84baa *** empty log message *** 2000-12-13 22:25:42 +00:00
Jim Meyering
af996c06d0 *** empty log message *** 2000-12-13 07:54:44 +00:00
Jim Meyering
2a21b4cf40 *** empty log message *** 2000-12-10 23:25:43 +00:00
Jim Meyering
3614a52150 *** empty log message *** 2000-12-10 12:50:40 +00:00
Jim Meyering
d2be99eb17 add envvar and lang checks 2000-12-10 09:20:52 +00:00
Jim Meyering
fca6110993 *** empty log message *** 2000-12-10 09:20:35 +00:00
Jim Meyering
9bb0e5cdb7 *** empty log message *** 2000-12-10 08:07:38 +00:00
Jim Meyering
cf302e3bc9 give a better diagnostic when only the group is being changed 2000-12-10 08:04:50 +00:00
Jim Meyering
b50fed9980 . 2000-12-09 22:18:02 +00:00
Jim Meyering
baf047f89a *** empty log message *** 2000-12-09 22:17:31 +00:00
Jim Meyering
a65f9eef4a *** empty log message *** 2000-12-09 22:16:57 +00:00
Jim Meyering
9c149c3b6c . 2000-12-09 22:07:28 +00:00
Jim Meyering
d64368c699 *** empty log message *** 2000-12-09 22:06:03 +00:00
Jim Meyering
97e76d3e24 (jm_MACROS): Remove jm_SYS_OFF_T_PRINTF_FORMAT. 2000-12-09 22:05:54 +00:00
Jim Meyering
a157495002 . 2000-12-09 22:05:28 +00:00
Jim Meyering
3c805daf45 . 2000-12-09 20:55:41 +00:00
Jim Meyering
8f55fdc385 (chopt_free): don't free anything 2000-12-09 20:54:23 +00:00
Jim Meyering
26f88f15c8 *** empty log message *** 2000-12-09 20:44:39 +00:00
Jim Meyering
6820c8729e *** empty log message *** 2000-12-09 20:39:17 +00:00
Jim Meyering
78169b6a2f *** empty log message *** 2000-12-09 20:38:12 +00:00
Jim Meyering
5a795ec749 Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
Remove decl of xstat.
(describe_change): Remove function.
(change_file_group): Likewise.
(change_dir_group): Likewise.
(parse_group): Don't set global, groupname, here...
(main): ... instead, initialize `chopt.group_name' here.
Initialize chopt and update uses of the now-members.
Set group_name also when it's obtained via a --reference=FILE option.
Call change_file_owner (with -1 for uids), not change_file_group.
2000-12-09 20:38:01 +00:00
Jim Meyering
d26ef4e978 add 3 more prototypes 2000-12-09 20:31:56 +00:00
Jim Meyering
40d911bc45 Include <pwd.h>, <grp.h>, and "xalloc.h".
[!_POSIX_VERSION]: Declare getgrnam and getgrgid.
(gid_to_name): New function.
(uid_to_name): Likewise.
(chopt_free): Likewise.
2000-12-09 20:31:34 +00:00
Jim Meyering
748db39d02 Don't include pwd.h or grp.h -- no longer needed.
Include chown-core.h.
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
(describe_change): Remove function.
(change_file_owner): Likewise.
(change_dir_owner): Likewise.
(main): Initialize chopt and update uses of the now-members.
Set user_name and group_name also when they're obtained via a
--reference=FILE option.
Pass `chopt' to change_file_owner.
2000-12-09 20:29:32 +00:00
Jim Meyering
4db97b7a7d *** empty log message *** 2000-12-09 14:47:06 +00:00
Jim Meyering
f8b26d3ade *** empty log message *** 2000-12-09 14:46:34 +00:00
Jim Meyering
5c8eb8ec36 *** empty log message *** 2000-12-09 14:08:07 +00:00
Jim Meyering
64f7bff756 *** empty log message *** 2000-12-09 13:50:13 +00:00
Jim Meyering
040db4c3fe *** empty log message *** 2000-12-09 13:48:03 +00:00
Jim Meyering
34ef74b11c *** empty log message *** 2000-12-09 13:44:37 +00:00
Jim Meyering
de4a3dfb26 *** empty log message *** 2000-12-09 13:44:10 +00:00
Jim Meyering
108881a3b2 *** empty log message *** 2000-12-09 13:38:51 +00:00
Jim Meyering
7d5f893b7f *** empty log message *** 2000-12-09 12:47:51 +00:00
Jim Meyering
8d977c3978 *** empty log message *** 2000-12-09 10:15:26 +00:00
Jim Meyering
73f1bc31d7 (change_file_owner): Restore special file permission
bits, since calling chown resets them on some systems.
Reported by Matt Perry.
2000-12-09 10:15:17 +00:00
Jim Meyering
497d1d9e97 *** empty log message *** 2000-12-09 10:14:52 +00:00
Jim Meyering
764dd3149e Don't make the success of the test depend
on the order in which directory entries are processed.
2000-12-08 20:31:47 +00:00
Jim Meyering
b2b9bed164 *** empty log message *** 2000-12-08 20:31:15 +00:00
Jim Meyering
9580e7cc87 *** empty log message *** 2000-12-08 18:32:11 +00:00
Jim Meyering
a05267197a (mbsnwidth): Don't loop endlessly when called with an
invalid mulitbyte sequence and with the MBSW_ACCEPT_INVALID flag set.
2000-12-08 18:31:38 +00:00
Jim Meyering
a90e5f5a69 *** empty log message *** 2000-12-08 08:06:33 +00:00
Jim Meyering
1f47a082c4 Include xalloc.h.
(main): Use dir_name rather than the underlying dir_name_r.
The former now handles cwd-relative names with drive-letter prefixes.
2000-12-08 07:55:05 +00:00
Jim Meyering
7b55b7aa13 *** empty log message *** 2000-12-07 14:14:18 +00:00
Jim Meyering
bcc94017bc convert a > expression to the equivalent < one 2000-12-07 14:13:51 +00:00
Jim Meyering
b615d79ac3 (ISSLASH): Define.
(strip_trailing_slashes): Use ISSLASH rather than comparing against `/'.
From Prashant TR.
2000-12-07 14:13:13 +00:00
Jim Meyering
04f549820f convert a > expression to the equivalent < one 2000-12-07 14:11:52 +00:00
Jim Meyering
ded8b14afb *** empty log message *** 2000-12-07 14:10:33 +00:00
Jim Meyering
4504b81f3b (FILESYSTEM_PREFIX_LEN): Define.
(dir_name_r): Declare this function as static.
[BACKSLASH_IS_PATH_SEPARATOR]: Fix a bug that'd
manifest itself on a name containing a mix of slashes and
backslashes.
Make this function work with names starting with a DOS-style
drive letter and colon prefix.
(dir_name): Append `.' if necessary.
Based mostly on patches from Prashant TR and Eli Zaretskii.
2000-12-07 14:10:21 +00:00
Jim Meyering
222412dbf1 (dir_name_r): Remove prototype. 2000-12-07 11:50:35 +00:00
Jim Meyering
71751f757d *** empty log message *** 2000-12-07 10:07:28 +00:00
Jim Meyering
8c8424d0c2 (address_base): Declare to be static. 2000-12-07 10:07:08 +00:00
Jim Meyering
e42f27d147 (address_base, address_pad_len): New var.
(output_address_fmt_string, address_fmt_buffer, address_pad): Remove.
(flag_pseudo_start): Now int, not long int.
(pseudo_offset): Now off_t, not long int.
(n_specs, n_specs_allocated): Now size_t, not unsigned int.
(format_address, format_address_none, format_address_std,
format_address_label): Now accepts an extra char argument (an extra
char to print if nonzero), and prints instead of returning a string.
All callers changed.
(bytes_per_block): Now size_t, not int.
(format_address_none): Do not even print the extra char argument.
This simplifies the callers.
(format_address_std, format_address_label): Print off_t ourself
instead of trying to use autoconfigured format.  This is faster and
more portable.
(format_address_paren): New function.
(dump): Remove unnecessary cast.
(expand_address_fmt): Remove.
(main): Use size_t, off_t, etc. instead of builtin types where this is
advisable.  Adjust to above changes.  Remove unnecessary cast.
2000-12-07 10:05:09 +00:00
Jim Meyering
d1cca1ee9c *** empty log message *** 2000-12-06 11:06:43 +00:00
46 changed files with 2000 additions and 728 deletions

1
THANKS
View File

@@ -198,6 +198,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
Matt Perry matt@primefactor.com
Matthew Braun matthew@ans.net
Matthew Clarke Matthew_Clarke@mindlink.bc.ca
Matthew S. Levine mslevine@theory.lcs.mit.edu

View File

@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
\def\texinfoversion{2000-11-09.08}
\def\texinfoversion{2000-12-11.07}
%
% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
% Free Software Foundation, Inc.
@@ -704,20 +704,35 @@ where each line of input produces a line of output.}
% if you have multiple lines of stuff to put here, you'll need to
% make the vbox yourself of the appropriate size.
\ifx#1l%
\llap{#2\hskip\inmarginspacing}%
\llap{\ignorespaces #2\hskip\inmarginspacing}%
\else
\rlap{\hskip\hsize\hskip\inmarginspacing#2}%
\rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
\fi
\null
}%
}}
\def\inleftmargin{\doinmargin l}
\def\inrightmargin{\doinmargin r}
\def\inmargin{% not perfect, but better than nothing.
\ifodd\pageno
\let\temp=\inleftmargin
%
% @inmargin{TEXT [, RIGHT-TEXT]}
% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
% else use TEXT for both).
%
\def\inmargin#1{\parseinmargin #1,,\finish}
\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
\setbox0 = \hbox{\ignorespaces #2}%
\ifdim\wd0 > 0pt
\def\lefttext{#1}% have both texts
\def\righttext{#2}%
\else
\let\temp=\inrightmargin
\def\lefttext{#1}% have only one text
\def\righttext{#1}%
\fi
%
\ifodd\pageno
\def\temp{\inleftmargin\lefttext}%
\else
\def\temp{\inrightmargin\righttext}%
\fi
\temp
}
@@ -4304,6 +4319,7 @@ width0pt\relax} \fi
\gobble
}
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins.
%
@@ -4326,6 +4342,158 @@ width0pt\relax} \fi
}
% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
% If we want to allow any <char> as delimiter,
% we need the curly braces so that makeinfo sees the @verb command, eg:
% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
%
% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
%
% [Knuth] p. 344; only we need to do '@' too
\def\dospecials{%
\do\ \do\\\do\@\do\{\do\}\do\$\do\&%
\do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~}
%
% [Knuth] p. 380
\def\uncatcodespecials{%
\def\do##1{\catcode`##1=12}\dospecials}
%
% [Knuth] pp. 380,381,391
% Disable Spanish ligatures ?` and !` of \tt font
\begingroup
\catcode`\`=\active\gdef`{\relax\lq}
\endgroup
%
% Setup for the @verb command.
%
% Eight spaces for a tab
\begingroup
\catcode`\^^I=\active
\gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
\endgroup
%
\def\setupverb{%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\leavevmode\endgraf}%
\catcode`\`=\active
\tabeightspaces
% Respect line breaks,
% print special symbols as themselves, and
% make each space count
% must do in this order:
\obeylines \uncatcodespecials \sepspaces
}
% Setup for the @verbatim environment
%
% Real tab expansion
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
%
\def\starttabbox{\setbox0=\hbox\bgroup}
\begingroup
\catcode`\^^I=\active
\gdef\tabexpand{%
\catcode`\^^I=\active
\def^^I{\leavevmode\egroup
\dimen0=\wd0 % the width so far, or since the previous tab
\divide\dimen0 by\tabw
\multiply\dimen0 by\tabw % compute previous multiple of \tabw
\advance\dimen0 by\tabw % advance to next multiple of \tabw
\wd0=\dimen0 \box0 \starttabbox
}%
}
\endgroup
\def\setupverbatim{%
% Easiest (and conventionally used) font for verbatim
\tt
\def\par{\leavevmode\egroup\box0\endgraf}%
\catcode`\`=\active
\tabexpand
% Respect line breaks,
% print special symbols as themselves, and
% make each space count
% must do in this order:
\obeylines \uncatcodespecials \sepspaces
\everypar{\starttabbox}%
}
% Do the @verb magic: verbatim text is quoted by unique
% delimiter characters. Before first delimiter expect a
% right brace, after last delimiter expect closing brace:
%
% \def\doverb'{'<char>#1<char>'}'{#1}
%
% [Knuth] p. 382; only eat outer {}
\begingroup
\catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12
\gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
\endgroup
%
\def\verb{\begingroup\setupverb\doverb}
%
%
% Do the @verbatim magic: define the macro \doverbatim so that
% the (first) argument ends when '@end verbatim' is reached, ie:
%
% \def\doverbatim#1@end verbatim{#1}
%
% For Texinfo it's a lot easier than for LaTeX,
% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
% we need not redefine '\', '{' and '}'
%
% Inspired by LaTeX's verbatim command set [latex.ltx]
%% Include LaTeX hack for completeness -- never know
%% \begingroup
%% \catcode`|=0 \catcode`[=1
%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active
%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[
%% #1|endgroup|def|Everbatim[]|end[verbatim]]
%% |endgroup
\begingroup
\catcode`\ =\active
\gdef\doverbatim#1@end verbatim{#1\end{verbatim}}
\endgroup
%
\def\verbatim{%
\def\Everbatim{\nonfillfinish\endgroup}%
\begingroup
\nonfillstart
\advance\leftskip by -\defbodyindent
\begingroup\setupverbatim\doverbatim
}
% @verbatiminclude FILE - insert text of file in verbatim environment.
%
% Allow normal characters that we make active in the argument (a file name).
\def\verbatiminclude{%
\begingroup
\catcode`\\=12
\catcode`~=12
\catcode`^=12
\catcode`_=12
\catcode`|=12
\catcode`<=12
\catcode`>=12
\catcode`+=12
\parsearg\doverbatiminclude
}
\def\setupverbatiminclude{%
\begingroup
\nonfillstart
\advance\leftskip by -\defbodyindent
\begingroup\setupverbatim
}
%
\def\doverbatiminclude#1{%
% Restore active chars for included file.
\endgroup
\begingroup
\def\thisfile{#1}%
\expandafter\expandafter\setupverbatiminclude\input\thisfile
\endgroup\nonfillfinish\endgroup
}
\message{defuns,}
% @defun etc.

View File

@@ -2260,6 +2260,24 @@ If @var{output-file} is one of the input files, @code{sort} copies
it to a temporary file before sorting and writing the output to
@var{output-file}.
@item -S @var{size}
@opindex -S
@cindex size for main memory sorting
Use a main-memory sort buffer of the given @var{size}. By default,
@var{size} is in units of 1,024 bytes. Appending @samp{%} causes
@var{size} to be interpreted as a percentage of physical memory.
Appending @samp{k} multiplies @var{size} by 1,024 (the default),
@samp{M} by 1,048,576, @samp{G} by 1,073,741,824, and so on for
@samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. Appending
@samp{b} causes @var{size} to be interpreted as a byte count, with no
multiplication.
This option can improve the performance of @command{sort} by causing it
to start with a larger or smaller sort buffer than the default.
However, this option affects only the initial buffer size. The buffer
grows beyond @var{size} if @command{sort} encounters input lines larger
than @var{size}.
@item -t @var{separator}
@opindex -t
@cindex field separator character

View File

@@ -1,3 +1,66 @@
2000-10-31 Bruno Haible <haible@clisp.cons.org>
* localcharset.c (locale_charset): Add support for Win32.
2000-12-18 Paul Eggert <eggert@twinsun.com>
* physmem.h, physmem.c: New files.
* Makefile.am (libfetish_a_SOURCES): Add physmem.c.
(noinst_HEADERS): Add physmem.h.
* xstrtol.c (__xstrtol): Add undocumented suffixes 'g' and
't' for compatibility with Solaris 8 sort.
2000-12-18 Bruno Haible <haible@clisp.cons.org>
* config.charset: Add support for BeOS.
2000-12-16 Jim Meyering <meyering@lucent.com>
* getusershell.c [!SHELLS_FILE && __DJGPP__]: Define
SHELLS_FILE to a file name that's useful on djgpp systems.
Include stdlib.h.
(ADDITIONAL_DEFAULT_SHELLS): Define.
(default_shells): Prepend ADDITIONAL_DEFAULT_SHELLS.
Based mostly on a patch from Prashant TR.
2000-12-16 Jim Meyering <meyering@lucent.com>
This bug had a serious impact on chown: `chown N:M FILE' (for integer
N and M) would have treated it like `chown N:N FILE'.
* userspec.c (parse_user_spec): Fix typo: s/u/g/.
2000-10-31 Bruno Haible <haible@clisp.cons.org>
* config.charset: Add ISO-8859-3, BIG5HKSCS, GB18030, JOHAB, VISCII,
CP874, CP949, CP950, CP1250, CP1253, CP1254, CP1255, CP1256, CP1257
to the list of canonical encodings. Rename EUC-CN to GB2312.
2000-12-08 Andreas Schwab <schwab@suse.de>
* mbswidth.c (mbsnwidth): Don't loop endlessly when called with an
invalid mulitbyte sequence and with the MBSW_ACCEPT_INVALID flag set.
2000-12-07 Jim Meyering <meyering@lucent.com>
* stripslash.c (ISSLASH): Define.
(strip_trailing_slashes): Use ISSLASH rather than comparing against `/'.
From Prashant TR.
* dirname.c (FILESYSTEM_PREFIX_LEN): Define.
(dir_name_r): Declare this function as static.
[BACKSLASH_IS_PATH_SEPARATOR]: Fix a bug that'd
manifest itself on a name containing a mix of slashes and
backslashes.
Make this function work with names starting with a DOS-style
drive letter and colon prefix.
(dir_name): Append `.' if necessary.
Based mostly on patches from Prashant TR and Eli Zaretskii.
* dirname.h (dir_name_r): Remove prototype.
2000-12-05 Jim Meyering <meyering@lucent.com>
* dirname.c (dir_name_r): Add `const' in a few local declarations.

View File

@@ -13,7 +13,7 @@ libfetish_a_SOURCES = \
full-write.c getopt.c getopt1.c getstr.c getugroups.c hard-locale.c hash.c \
human.c idcache.c isdir.c linebuffer.c localcharset.c long-options.c \
makepath.c mbswidth.c md5.c memcasecmp.c memcoll.c modechange.c \
path-concat.c \
path-concat.c physmem.c \
quote.c quotearg.c readtokens.c safe-read.c same.c save-cwd.c \
savedir.c sha.c stripslash.c unicodeio.c userspec.c version-etc.c xgetcwd.c \
xgethostname.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c \
@@ -29,7 +29,8 @@ noinst_HEADERS = \
getstr.h getpagesize.h group-member.h hard-locale.h hash.h human.h lchown.h \
linebuffer.h long-options.h mbswidth.h md5.h memcasecmp.h memcoll.h \
makepath.h mbswidth.h modechange.h mountlist.h nanosleep.h obstack.h \
path-concat.h pathmax.h posixtm.h quote.h quotearg.h readtokens.h \
path-concat.h pathmax.h physmem.h posixtm.h \
quote.h quotearg.h readtokens.h \
readutmp.h regex.h safe-read.h same.h save-cwd.h savedir.h sha.h \
strverscmp.h unicodeio.h version-etc.h xalloc.h xstrtod.h xstrtol.h

View File

@@ -129,7 +129,7 @@ libfetish_a_SOURCES = \
full-write.c getopt.c getopt1.c getstr.c getugroups.c hard-locale.c hash.c \
human.c idcache.c isdir.c linebuffer.c localcharset.c long-options.c \
makepath.c mbswidth.c md5.c memcasecmp.c memcoll.c modechange.c \
path-concat.c \
path-concat.c physmem.c \
quote.c quotearg.c readtokens.c safe-read.c same.c save-cwd.c \
savedir.c sha.c stripslash.c unicodeio.c userspec.c version-etc.c xgetcwd.c \
xgethostname.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c \
@@ -146,7 +146,8 @@ noinst_HEADERS = \
getstr.h getpagesize.h group-member.h hard-locale.h hash.h human.h lchown.h \
linebuffer.h long-options.h mbswidth.h md5.h memcasecmp.h memcoll.h \
makepath.h mbswidth.h modechange.h mountlist.h nanosleep.h obstack.h \
path-concat.h pathmax.h posixtm.h quote.h quotearg.h readtokens.h \
path-concat.h pathmax.h physmem.h posixtm.h \
quote.h quotearg.h readtokens.h \
readutmp.h regex.h safe-read.h same.h save-cwd.h savedir.h sha.h \
strverscmp.h unicodeio.h version-etc.h xalloc.h xstrtod.h xstrtol.h
@@ -180,11 +181,12 @@ diacrit$U.o dirname$U.o exclude$U.o filemode$U.o full-write$U.o \
getopt$U.o getopt1$U.o getstr$U.o getugroups$U.o hard-locale$U.o \
hash$U.o human$U.o idcache$U.o isdir$U.o linebuffer$U.o \
localcharset$U.o long-options$U.o makepath$U.o mbswidth$U.o md5$U.o \
memcasecmp$U.o memcoll$U.o modechange$U.o path-concat$U.o quote$U.o \
quotearg$U.o readtokens$U.o safe-read$U.o same$U.o save-cwd$U.o \
savedir$U.o sha$U.o stripslash$U.o unicodeio$U.o userspec$U.o \
version-etc$U.o xgetcwd$U.o xgethostname$U.o xmalloc$U.o xstrdup$U.o \
xstrtod$U.o xstrtol$U.o xstrtoul$U.o xstrtoumax$U.o yesno$U.o
memcasecmp$U.o memcoll$U.o modechange$U.o path-concat$U.o physmem$U.o \
quote$U.o quotearg$U.o readtokens$U.o safe-read$U.o same$U.o \
save-cwd$U.o savedir$U.o sha$U.o stripslash$U.o unicodeio$U.o \
userspec$U.o version-etc$U.o xgetcwd$U.o xgethostname$U.o xmalloc$U.o \
xstrdup$U.o xstrtod$U.o xstrtol$U.o xstrtoul$U.o xstrtoumax$U.o \
yesno$U.o
libfetish_a_OBJECTS = $(am_libfetish_a_OBJECTS)
AR = ar
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -217,14 +219,15 @@ $(DEPDIR)/memchr.Po $(DEPDIR)/memcmp.Po $(DEPDIR)/memcoll$U.Po \
$(DEPDIR)/memcpy.Po $(DEPDIR)/memmove.Po $(DEPDIR)/memrchr.Po \
$(DEPDIR)/memset.Po $(DEPDIR)/mktime.Po $(DEPDIR)/modechange$U.Po \
$(DEPDIR)/mountlist.Po $(DEPDIR)/nanosleep.Po $(DEPDIR)/obstack.Po \
$(DEPDIR)/path-concat$U.Po $(DEPDIR)/posixtm$U.Po $(DEPDIR)/putenv.Po \
$(DEPDIR)/quote$U.Po $(DEPDIR)/quotearg$U.Po $(DEPDIR)/readtokens$U.Po \
$(DEPDIR)/readutmp.Po $(DEPDIR)/realloc.Po $(DEPDIR)/regex.Po \
$(DEPDIR)/rmdir.Po $(DEPDIR)/rpmatch.Po $(DEPDIR)/safe-read$U.Po \
$(DEPDIR)/same$U.Po $(DEPDIR)/save-cwd$U.Po $(DEPDIR)/savedir$U.Po \
$(DEPDIR)/sha$U.Po $(DEPDIR)/stat.Po $(DEPDIR)/stime.Po \
$(DEPDIR)/stpcpy.Po $(DEPDIR)/strcasecmp.Po $(DEPDIR)/strcspn.Po \
$(DEPDIR)/strdup.Po $(DEPDIR)/strftime.Po $(DEPDIR)/stripslash$U.Po \
$(DEPDIR)/path-concat$U.Po $(DEPDIR)/physmem$U.Po \
$(DEPDIR)/posixtm$U.Po $(DEPDIR)/putenv.Po $(DEPDIR)/quote$U.Po \
$(DEPDIR)/quotearg$U.Po $(DEPDIR)/readtokens$U.Po $(DEPDIR)/readutmp.Po \
$(DEPDIR)/realloc.Po $(DEPDIR)/regex.Po $(DEPDIR)/rmdir.Po \
$(DEPDIR)/rpmatch.Po $(DEPDIR)/safe-read$U.Po $(DEPDIR)/same$U.Po \
$(DEPDIR)/save-cwd$U.Po $(DEPDIR)/savedir$U.Po $(DEPDIR)/sha$U.Po \
$(DEPDIR)/stat.Po $(DEPDIR)/stime.Po $(DEPDIR)/stpcpy.Po \
$(DEPDIR)/strcasecmp.Po $(DEPDIR)/strcspn.Po $(DEPDIR)/strdup.Po \
$(DEPDIR)/strftime.Po $(DEPDIR)/stripslash$U.Po \
$(DEPDIR)/strncasecmp.Po $(DEPDIR)/strndup.Po $(DEPDIR)/strnlen.Po \
$(DEPDIR)/strpbrk.Po $(DEPDIR)/strstr.Po $(DEPDIR)/strtod.Po \
$(DEPDIR)/strtol.Po $(DEPDIR)/strtoul.Po $(DEPDIR)/strtoull.Po \
@@ -425,6 +428,8 @@ obstack_.c: obstack.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/obstack.c; then echo $(srcdir)/obstack.c; else echo obstack.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > obstack_.c
path-concat_.c: path-concat.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/path-concat.c; then echo $(srcdir)/path-concat.c; else echo path-concat.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > path-concat_.c
physmem_.c: physmem.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/physmem.c; then echo $(srcdir)/physmem.c; else echo physmem.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > physmem_.c
posixtm_.c: posixtm.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/posixtm.c; then echo $(srcdir)/posixtm.c; else echo posixtm.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > posixtm_.c
putenv_.c: putenv.c $(ANSI2KNR)
@@ -530,10 +535,10 @@ lchown_.o linebuffer_.o localcharset_.o long-options_.o lstat_.o \
makepath_.o malloc_.o mbswidth_.o md5_.o memcasecmp_.o memchr_.o \
memcmp_.o memcoll_.o memcpy_.o memmove_.o memrchr_.o memset_.o \
mktime_.o modechange_.o mountlist_.o nanosleep_.o obstack_.o \
path-concat_.o posixtm_.o putenv_.o quote_.o quotearg_.o readtokens_.o \
readutmp_.o realloc_.o regex_.o rmdir_.o rpmatch_.o safe-read_.o \
same_.o save-cwd_.o savedir_.o sha_.o stat_.o stime_.o stpcpy_.o \
strcasecmp_.o strcspn_.o strdup_.o strftime_.o stripslash_.o \
path-concat_.o physmem_.o posixtm_.o putenv_.o quote_.o quotearg_.o \
readtokens_.o readutmp_.o realloc_.o regex_.o rmdir_.o rpmatch_.o \
safe-read_.o same_.o save-cwd_.o savedir_.o sha_.o stat_.o stime_.o \
stpcpy_.o strcasecmp_.o strcspn_.o strdup_.o strftime_.o stripslash_.o \
strncasecmp_.o strndup_.o strnlen_.o strpbrk_.o strstr_.o strtod_.o \
strtol_.o strtoul_.o strtoull_.o strtoumax_.o strverscmp_.o \
unicodeio_.o userspec_.o utime_.o version-etc_.o xgetcwd_.o \
@@ -641,6 +646,7 @@ maintainer-clean-tags:
@AMDEP@include $(DEPDIR)/nanosleep.Po
@AMDEP@include $(DEPDIR)/obstack.Po
@AMDEP@include $(DEPDIR)/path-concat$U.Po
@AMDEP@include $(DEPDIR)/physmem$U.Po
@AMDEP@include $(DEPDIR)/posixtm$U.Po
@AMDEP@include $(DEPDIR)/putenv.Po
@AMDEP@include $(DEPDIR)/quote$U.Po

View File

@@ -34,6 +34,7 @@
# ASCII, ANSI_X3.4-1968 glibc solaris freebsd
# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes
# ISO-8859-2 glibc aix hpux irix solaris freebsd yes
# ISO-8859-3 glibc yes
# ISO-8859-4 solaris yes
# ISO-8859-5 glibc aix hpux irix solaris yes
# ISO-8859-6 glibc aix hpux solaris yes
@@ -41,28 +42,41 @@
# ISO-8859-8 glibc aix hpux solaris yes
# ISO-8859-9 glibc aix hpux irix osf solaris yes
# ISO-8859-13 glibc
# ISO-8859-15 aix solaris freebsd
# ISO-8859-15 glibc aix solaris freebsd
# KOI8-R glibc solaris freebsd yes
# KOI8-U glibc yes
# CP850 aix osf
# CP856 aix
# CP866 freebsd
# CP874 win32
# CP922 aix
# CP932 aix
# CP932 aix win32
# CP943 aix
# CP949 win32
# CP950 win32
# CP1046 aix
# CP1124 aix
# CP1129 aix
# CP1251 glibc
# CP1252 aix
# EUC-CN aix hpux irix solaris
# EUC-JP aix hpux irix solaris yes
# EUC-KR aix hpux irix solaris yes
# EUC-TW aix hpux irix solaris
# BIG5 aix hpux solaris yes
# GBK aix
# CP1250 win32
# CP1251 glibc win32
# CP1252 aix win32
# CP1253 win32
# CP1254 win32
# CP1255 win32
# CP1256 win32
# CP1257 win32
# GB2312 glibc aix hpux irix solaris yes
# EUC-JP glibc aix hpux irix solaris yes
# EUC-KR glibc aix hpux irix solaris yes
# EUC-TW glibc aix hpux irix solaris
# BIG5 glibc aix hpux solaris yes
# BIG5HKSCS glibc
# GBK aix win32
# GB18030 glibc
# SJIS hpux solaris
# TIS-620 aix hpux solaris
# JOHAB glibc win32
# TIS-620 glibc aix hpux solaris
# VISCII glibc yes
# HP-ROMAN8 hpux
# HP-ARABIC8 hpux
# HP-GREEK8 hpux
@@ -117,7 +131,7 @@ case "$os" in
echo "IBM-1124 CP1124"
echo "IBM-1129 CP1129"
echo "IBM-1252 CP1252"
echo "IBM-eucCN EUC-CN"
echo "IBM-eucCN GB2312"
echo "IBM-eucJP EUC-JP"
echo "IBM-eucKR EUC-KR"
echo "IBM-eucTW EUC-TW"
@@ -146,7 +160,7 @@ case "$os" in
echo "eucJP EUC-JP"
echo "eucKR EUC-KR"
echo "eucTW EUC-TW"
echo "hp15CN EUC-CN"
echo "hp15CN GB2312"
#echo "ccdc ?" # what is this?
echo "SJIS SJIS"
echo "utf8 UTF-8"
@@ -157,7 +171,7 @@ case "$os" in
echo "ISO8859-5 ISO-8859-5"
echo "ISO8859-7 ISO-8859-7"
echo "ISO8859-9 ISO-8859-9"
echo "eucCN EUC-CN"
echo "eucCN GB2312"
echo "eucJP EUC-JP"
echo "eucKR EUC-KR"
echo "eucTW EUC-TW"
@@ -181,7 +195,7 @@ case "$os" in
echo "ISO8859-15 ISO-8859-15"
echo "koi8-r KOI8-R"
echo "BIG5 BIG5"
echo "gb2312 EUC-CN"
echo "gb2312 GB2312"
echo "cns11643 EUC-TW"
echo "5601 EUC-KR"
echo "eucJP EUC-JP"
@@ -213,4 +227,8 @@ case "$os" in
echo "$l.CP866 CP866"
done
;;
beos*)
# BeOS has a single locale, and it has UTF-8 encoding.
echo "C UTF-8"
;;
esac

View File

@@ -43,17 +43,23 @@ void *memrchr ();
#include "dirname.h"
#ifndef FILESYSTEM_PREFIX_LEN
# define FILESYSTEM_PREFIX_LEN(Filename) 0
#endif
#ifndef ISSLASH
# define ISSLASH(C) ((C) == '/')
#endif
#define BACKSLASH_IS_PATH_SEPARATOR ISSLASH ('\\')
/* Return the length of `dirname (PATH)' and set *RESULT
to point to PATH or to `"."', as appropriate.
Works properly even if there are trailing slashes
(by effectively ignoring them). */
size_t
/* Return the length of `dirname (PATH)' and set *RESULT to point
to PATH or to `"."', as appropriate. Works properly even if
there are trailing slashes (by effectively ignoring them).
WARNING: This function doesn't work for cwd-relative names like
`a:foo' that are specified with a drive-letter prefix. That case
is handled in the caller. */
static size_t
dir_name_r (char const *path, char const **result)
{
char const *slash;
@@ -78,10 +84,11 @@ dir_name_r (char const *path, char const **result)
if (path < slash)
{
slash = memrchr (path, '/', slash - path);
size_t len = slash - path;
slash = memrchr (path, '/', len);
if (BACKSLASH_IS_PATH_SEPARATOR)
{
char const *b = memrchr (path, '\\', slash - path);
char const *b = memrchr (path, '\\', len);
if (b && slash < b)
slash = b;
}
@@ -91,27 +98,23 @@ dir_name_r (char const *path, char const **result)
if (slash == 0)
{
/* File is in the current directory. */
path = ".";
length = 1;
length = FILESYSTEM_PREFIX_LEN (path);
if (length == 0)
{
path = ".";
length = 1;
}
}
else
{
/* Remove any trailing slashes from the result. */
if (BACKSLASH_IS_PATH_SEPARATOR)
{
char const *lim = ((path[0] >= 'A' && path[0] <= 'z'
&& path[1] == ':')
? path + 2 : path);
/* Remove any trailing slashes from the result. If we have a
canonicalized "d:/path", leave alone the root case "d:/". */
char const *lim = path + FILESYSTEM_PREFIX_LEN (path);
/* If canonicalized "d:/path", leave alone the root case "d:/". */
while (slash > lim && ISSLASH (*slash))
--slash;
}
else
{
while (slash > path && ISSLASH (*slash))
--slash;
}
while (lim < slash && ISSLASH (*slash))
--slash;
length = slash - path + 1;
}
@@ -130,10 +133,14 @@ dir_name (char const *path)
{
char const *result;
size_t length = dir_name_r (path, &result);
char *newpath = (char *) malloc (length + 1);
int append_dot = (length && length == FILESYSTEM_PREFIX_LEN (newpath));
char *newpath = (char *) malloc (length + append_dot + 1);
if (newpath == 0)
return 0;
strncpy (newpath, result, length);
/* If PATH is "d:foo", return "d:.", the CWD on drive d: */
if (append_dot)
newpath[length++] = '.';
newpath[length] = 0;
return newpath;
}

View File

@@ -28,7 +28,4 @@
char *
dir_name PARAMS ((const char *path));
size_t
dir_name_r PARAMS ((const char *path, const char **result));
#endif /* not DIRNAME_H_ */

View File

@@ -22,11 +22,19 @@
#endif
#ifndef SHELLS_FILE
# ifndef __DJGPP__
/* File containing a list of nonrestricted shells, one per line. */
# define SHELLS_FILE "/etc/shells"
# define SHELLS_FILE "/etc/shells"
# else
/* This is a horrible kludge. Isn't there a better way? */
# define SHELLS_FILE "/dev/env/DJDIR/etc/shells"
# endif
#endif
#include <stdio.h>
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <ctype.h>
#include "xalloc.h"
@@ -40,9 +48,17 @@
static int readname ();
#if ! defined ADDITIONAL_DEFAULT_SHELLS && defined __MSDOS__
# define ADDITIONAL_DEFAULT_SHELLS \
"c:/dos/command.com", "c:/windows/command.com", "c:/command.com",
#else
# define ADDITIONAL_DEFAULT_SHELLS /* empty */
#endif
/* List of shells to use if the shells file is missing. */
static char const* const default_shells[] =
{
ADDITIONAL_DEFAULT_SHELLS
"/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL
};

View File

@@ -37,12 +37,22 @@
# include <stdlib.h>
#endif
#if HAVE_LANGINFO_CODESET
# include <langinfo.h>
#else
# if HAVE_SETLOCALE
# include <locale.h>
#if defined _WIN32 || defined __WIN32__
# undef WIN32 /* avoid warning on mingw32 */
# define WIN32
#endif
#ifndef WIN32
# if HAVE_LANGINFO_CODESET
# include <langinfo.h>
# else
# if HAVE_SETLOCALE
# include <locale.h>
# endif
# endif
#else /* WIN32 */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#ifndef DIRECTORY_SEPARATOR
@@ -73,6 +83,7 @@ get_charset_aliases ()
cp = charset_aliases;
if (cp == NULL)
{
#ifndef WIN32
FILE *fp;
const char *dir = LIBDIR;
const char *base = "charset.alias";
@@ -157,9 +168,20 @@ get_charset_aliases ()
}
}
charset_aliases = cp;
if (file_name != NULL)
free (file_name);
#else /* WIN32 */
/* To avoid the troubles of installing a separate file in the same
directory as the DLL and of retrieving the DLL's directory at
runtime, simply inline the aliases here. */
cp = "CP936" "\0" "GBK" "\0"
"CP1361" "\0" "JOHAB" "\0";
#endif
charset_aliases = cp;
}
return cp;
@@ -180,19 +202,21 @@ locale_charset ()
const char *codeset;
const char *aliases;
#if HAVE_LANGINFO_CODESET
#ifndef WIN32
# if HAVE_LANGINFO_CODESET
/* Most systems support nl_langinfo (CODESET) nowadays. */
codeset = nl_langinfo (CODESET);
#else
# else
/* On old systems which lack it, use setlocale and getenv. */
const char *locale = NULL;
# if HAVE_SETLOCALE
# if HAVE_SETLOCALE
locale = setlocale (LC_CTYPE, NULL);
# endif
# endif
if (locale == NULL || locale[0] == '\0')
{
locale = getenv ("LC_ALL");
@@ -209,6 +233,16 @@ locale_charset ()
through the charset.alias file. */
codeset = locale;
# endif
#else /* WIN32 */
static char buf[2 + 10 + 1];
/* Win32 has a function returning the locale's codepage as a number. */
sprintf (buf, "CP%u", GetACP ());
codeset = buf;
#endif
if (codeset != NULL && codeset[0] != '\0')

View File

@@ -153,7 +153,11 @@ mbsnwidth (const char *string, size_t nbytes, int flags)
/* An invalid multibyte sequence was encountered. */
{
if (flags & MBSW_ACCEPT_INVALID)
break;
{
p++;
width++;
break;
}
else
return -1;
}
@@ -162,7 +166,11 @@ mbsnwidth (const char *string, size_t nbytes, int flags)
/* An incomplete multibyte character at the end. */
{
if (flags & MBSW_ACCEPT_INVALID)
break;
{
p = plimit;
width++;
break;
}
else
return -1;
}

58
lib/physmem.c Normal file
View File

@@ -0,0 +1,58 @@
/* Calculate the size of physical memory.
Copyright 2000 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 2, 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, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Paul Eggert. */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include "physmem.h"
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
/* Return the total amount of physical memory. */
double
physmem_total (void)
{
#if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
double pages = sysconf (_SC_PHYS_PAGES);
double pagesize = sysconf (_SC_PAGESIZE);
if (0 <= pages && 0 <= pagesize)
return pages * pagesize;
#endif
/* Guess 64 MB. It's probably an older host, so guess small. */
return 64 * 1024 * 1024;
}
/* Return the amount of physical memory available. */
double
physmem_available (void)
{
#if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
double pages = sysconf (_SC_AVPHYS_PAGES);
double pagesize = sysconf (_SC_PAGESIZE);
if (0 <= pages && 0 <= pagesize)
return pages * pagesize;
#endif
/* Guess 25% of physical memory. */
return physmem_total () / 4;
}

19
lib/physmem.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef PHYSMEM_H_
# define PHYSMEM_H_ 1
# if HAVE_CONFIG_H
# include <config.h>
# endif
# ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args
# else
# define PARAMS(Args) ()
# endif
# endif
double physmem_total PARAMS ((void));
double physmem_available PARAMS ((void));
#endif /* PHYSMEM_H_ */

View File

@@ -19,12 +19,16 @@
# include <config.h>
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#ifndef ISSLASH
# define ISSLASH(C) ((C) == '/')
#endif
/* Remove trailing slashes from PATH.
This is useful when using filename completion from a shell that
adds a "/" after directory names (such as tcsh and bash), because
@@ -37,6 +41,6 @@ strip_trailing_slashes (char *path)
int last;
last = strlen (path) - 1;
while (last > 0 && path[last] == '/')
while (0 < last && ISSLASH (path[last]))
path[last--] = '\0';
}

View File

@@ -163,8 +163,8 @@ is_number (const char *str)
use the given user's login group.
If SPEC_ARG contains a `:', then use that as the separator, ignoring
any `.'s. If there is no `:', but there is a `.', then first look
up SPEC_ARG as a login name. If that look-up fails, then try again
interpreting the `.' as a separator.
up the entire SPEC_ARG as a login name. If that look-up fails, then
try again interpreting the `.' as a separator.
USERNAME and GROUPNAME will be in newly malloc'd memory.
Either one might be NULL instead, indicating that it was not
@@ -304,7 +304,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
else
{
unsigned long int tmp_long;
if (xstrtoul (u, NULL, 0, &tmp_long, NULL) != LONGINT_OK
if (xstrtoul (g, NULL, 0, &tmp_long, NULL) != LONGINT_OK
|| tmp_long > MAXGID)
return _(E_invalid_group);
*gid = tmp_long;

View File

@@ -199,6 +199,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'G': /* Giga */
case 'g': /* 'g' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 3);
break;
@@ -207,7 +208,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'M': /* Mega */
case 'm': /* 'm' is undocumented; for backward compatibility only */
case 'm': /* 'm' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 2);
break;
@@ -216,6 +217,7 @@ __xstrtol (const char *s, char **ptr, int strtol_base,
break;
case 'T': /* Tera */
case 't': /* 't' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 4);
break;

View File

@@ -1,8 +1,21 @@
2000-12-17 Jim Meyering <meyering@lucent.com>
* dos.m4 (jm_AC_DOS): New file and macro.
* jm-macros.m4 (jm_MACROS): Require jm_AC_DOS.
2000-12-06 Paul Eggert <eggert@twinsun.com>
* off_t-format.m4: Remove this file.
* jm-macros.m4 (jm_MACROS): Remove jm_SYS_OFF_T_PRINTF_FORMAT.
2000-12-06 Jim Meyering <meyering@lucent.com>
* xstrtoumax.m4 (jm_AC_PREREQ_XSTRTOUMAX): If we need the replacement
strtoull, we may well need the replacement strtoul, too.
Check for declarations of strtoul and strtoull.
Check for strtol. Mainly as a cue to cause automake to include
strtol.c -- that file is included by each of strtoul.c and strtoull.c.
Check for limits.h -- strtol.c needs it.
2000-12-02 Jim Meyering <meyering@lucent.com>

View File

@@ -11,6 +11,7 @@ chown.m4 \
codeset.m4 \
d-ino.m4 \
d-type.m4 \
dos.m4 \
error.m4 \
fnmatch.m4 \
fpending.m4 \
@@ -44,7 +45,6 @@ mbstate_t.m4 \
mbswidth.m4 \
memcmp.m4 \
nanosleep.m4 \
off_t-format.m4 \
perl.m4 \
prereq.m4 \
progtest.m4 \

View File

@@ -126,6 +126,7 @@ chown.m4 \
codeset.m4 \
d-ino.m4 \
d-type.m4 \
dos.m4 \
error.m4 \
fnmatch.m4 \
fpending.m4 \
@@ -159,7 +160,6 @@ mbstate_t.m4 \
mbswidth.m4 \
memcmp.m4 \
nanosleep.m4 \
off_t-format.m4 \
perl.m4 \
prereq.m4 \
progtest.m4 \

27
m4/dos.m4 Normal file
View File

@@ -0,0 +1,27 @@
# serial 1
# Define some macros required for proper operation of code in lib/*.c
# on MSDOS/Windows systems.
# From Jim Meyering.
AC_DEFUN(jm_AC_DOS,
[
# FIXME: this is incomplete. Add a compile-test that does something
# like this:
#if defined _WIN32 || defined __WIN32__ || defined __MSDOS__
ac_fspl_def="((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)"
ac_fspl_def=0
AC_DEFINE_UNQUOTED([FILESYSTEM_PREFIX_LEN(Filename)], $ac_fspl_def,
[On systems for which file names may have a so-called `drive letter'
prefix, define this to compute the length of that prefix, including
the colon. Otherwise, define it to zero.])
ac_isslash_def="((C) == '/' || (C) == '\\')"
ac_isslash_def="((C) == '/')"
AC_DEFINE_UNQUOTED([ISSLASH(C)], $ac_isslash_def,
[Define to return nonzero for any character that may serve as
a file name component separator. On POSIX systems, it is the
slash character. Some other systems also accept backslash.])
])

View File

@@ -1,4 +1,4 @@
#serial 28 -*- autoconf -*-
#serial 29 -*- autoconf -*-
dnl Misc type-related macros for fileutils, sh-utils, textutils.
@@ -70,7 +70,6 @@ AC_DEFUN(jm_MACROS,
AC_REQUIRE([jm_PREREQ])
AC_REQUIRE([jm_SYS_OFF_T_PRINTF_FORMAT])
AC_REQUIRE([jm_FUNC_LCHOWN])
AC_REQUIRE([fetish_FUNC_RMDIR_NOTEMPTY])
AC_REQUIRE([jm_FUNC_CHOWN])
@@ -224,6 +223,7 @@ AC_DEFUN(jm_MACROS,
AC_LIBOBJ(fsusage)
AC_LIBOBJ(mountlist)
fi
AC_REQUIRE([jm_AC_DOS])
])

View File

@@ -1,55 +0,0 @@
#serial 1 -*- autoconf -*-
dnl FIXME
AC_DEFUN(jm_SYS_OFF_T_PRINTF_FORMAT,
[dnl
AC_REQUIRE([AC_TYPE_OFF_T])
AC_CHECK_HEADERS(string.h stdlinb.h)
AC_CACHE_CHECK([for printf format that works with type off_t],
jm_cv_sys_off_t_printf_format,
[
jm_cv_sys_off_t_printf_format=undef
for jm_fmt in '' L ll q; do
jm_OFF_T_FORMAT="$jm_fmt"
export jm_OFF_T_FORMAT
AC_TRY_RUN([
# include <sys/types.h>
# include <stdio.h>
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
# if HAVE_STRING_H
# include <string.h>
# endif
int
main()
{
static off_t x[] = {1, 255, 65535, 99999999};
char buf[50], fmt[50];
/* this should be one of these values: "", "L", "ll", "q" */
char *f = getenv ("jm_OFF_T_FORMAT");
sprintf (fmt, "%%%sd %%%sx %%%sx %%%sd", f, f, f, f);
sprintf (buf, fmt, x[0], x[1], x[2], x[3]);
exit (strcmp (buf, "1 ff ffff 99999999"));
}
], jm_cv_sys_off_t_printf_format=$jm_fmt; break
, dnl didn't work
dnl Cross compiling -- you lose. Specify it via the cache.
)
done
# Die if none of the above worked.
# FIXME: If this failure become a problem that we can't work around,
# an alternative would be to arrange not to build od.
if test "$jm_cv_sys_off_t_printf_format" = undef; then
AC_MSG_ERROR(dnl
[couldn't find a printf format that works with the type, off_t])
fi
])
AC_DEFINE_UNQUOTED(OFF_T_PRINTF_FORMAT_STRING,
"$jm_cv_sys_off_t_printf_format",
[printf format string for type off_t, without the `%'])
])

View File

@@ -1,7 +1,127 @@
2000-12-03 Jim Meyering <meyering@lucent.com>
2000-12-22 Jim Meyering <meyering@lucent.com>
* Version 4.0.34.
* src/shred.c (isaac_seed_machdep) [_ARCH_PPC]: Disable the code
that would use the PPC mfspr `asm' code. Suggestion from Michael Stone.
2000-12-19 Jim Meyering <meyering@lucent.com>
* doc/fileutils.texi: Use `ref_file' in place of `file' to make
descriptions of the various --reference=... options clearer.
2000-12-17 Jim Meyering <meyering@lucent.com>
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
2000-12-16 Jim Meyering <meyering@lucent.com>
* src/chown-core.c (uint_to_string): New function.
(uid_to_name): Use it.
(gid_to_name): Use it.
Rename locals, user/group, to uid/gid.
* src/chown-core.h (enum Change_status): Start with 1.
* src/chown.c (main): Rename locals, user/group, to uid/gid.
* src/chgrp.c (main): Rename local, group, to gid.
* tests/group-names: New file.
* tests/Makefile.am (EXTRA_DIST): Add group-names.
* tests/chgrp/basic: Use group-names.
* tests/chgrp/deref: Likewise.
* tests/chgrp/recurse: Likewise.
* tests/chgrp/basic: Don't assume that creating a file gives it
group $g1.
* tests/chgrp/Makefile.am (TESTS): Add recurse.
2000-12-15 Jim Meyering <meyering@lucent.com>
* src/chown-core.h [enum Dereference_symlink] (dereference): Rename
from change_symlinks.
* src/chown-core.c: Declare lstat.
Rename change_symlinks member to `dereference' and use the DEREF_*
enum values.
(describe_change): Merge the chgrp and chown switch statements.
Use xmalloc to form the `user:group' string.
(change_file_owner): Record (and later, use) is_symlink and is_directory
from the lstat stats, in order to control whether we operate on symlinks
and whether (with -R) we traverse symlinks to directories.
When dereferencing, use open/fchown (rather than chown) on symlinks.
* src/chown.c (main): Reflect renaming: s/dereference/change_symlinks/.
* src/chgrp.c (main): Likewise.
* src/chown-core.c (describe_change): Use `:' (not `.') to separate the
username and group in messages evoked by the --verbose and --changes
options.
2000-12-09 Jim Meyering <meyering@lucent.com>
* src/Makefile.am (noinst_HEADERS): Add chown-core.h.
(chown_SOURCES): Define.
(chgrp_SOURCES): Define.
* src/chgrp.c: Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
Remove decl of xstat.
(describe_change): Remove function.
(change_file_group): Likewise.
(change_dir_group): Likewise.
(parse_group): Don't set global, groupname, here...
(main): ... instead, initialize `chopt.group_name' here.
Initialize chopt and update uses of the now-members.
Set group_name also when it's obtained via a --reference=FILE option.
Call change_file_owner (with -1 for uids), not change_file_group.
* src/chown.c: Don't include pwd.h or grp.h -- no longer needed.
Include "chown-core.h".
[enum Change_status, enum Verbosity]: Remove declarations.
Remove decls of globals that are now part of struct Chown_option.
(describe_change): Remove function.
(change_file_owner): Likewise.
(change_dir_owner): Likewise.
(main): Initialize chopt and update uses of the now-members.
Set user_name and group_name also when they're obtained via a
--reference=FILE option.
Pass `chopt' to change_file_owner.
* src/chown-core.c: Include <pwd.h>, <grp.h>, and "xalloc.h".
[!_POSIX_VERSION]: Declare getgrnam and getgrgid.
(gid_to_name): New function.
(uid_to_name): Likewise.
(chopt_free): Likewise.
Factor out code that's common to chgrp.c and chown.c.
* src/chown-core.h: New file.
* src/chown-core.c (chopt_init): New function.
(describe_change): Extracted/combined from chgrp.c and chown.c.
(change_dir_owner): Likewise.
(change_file_owner): Likewise.
* po/POTFILES.in: Add src/chown-core.c.
* configure.in (AC_OUTPUT): Add tests/chgrp/Makefile.
* tests/Makefile.am (SUBDIRS): Add chgrp.
* tests/chgrp: New directory.
* tests/chgrp/basic: New test.
* tests/chgrp/deref: Likewise.
* tests/chgrp/Makefile.am: New file.
* src/chown.c (change_file_owner): Restore special file permission
bits, since calling chown resets them on some systems.
Reported by Matt Perry.
2000-12-08 Andreas Schwab <schwab@suse.de>
* tests/mv/mv-special-1: Don't make the success of the test depend
on the order in which directory entries are processed.
2000-12-03 Jim Meyering <meyering@lucent.com>
* src/ls.c (gobble_file) [USE_ACL]: Set have_acl member unconditionally
to avoid uninitialized memory reference via FILE_HAS_ACL.

View File

@@ -1,5 +1,10 @@
Changes in release 4.01:
[4.0.34]
* fix a bug (introduced in 4.0z) that made `chown 123:456 file' act like
`chown 123:123 file'. Other uses with a numeric group ID would cause
chown to fail when it shouldn't have.
* the chown and chgrp programs preserve set-uid and set-gid bits, even on
systems for which the chown function call resets those bits.
* `ls -L dangling-symlink' now fails (per POSIX) rather than printing the
link name
* dd no longer honors the just-added `B' suffix on skip= and seek= arguments.

View File

@@ -1,6 +1,22 @@
2000-12-02 Jim Meyering <meyering@lucent.com>
2000-12-17 Jim Meyering <meyering@lucent.com>
* Version 2.0.12.
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
* djgpp: New directory.
* djgpp/*: New files.
* Makefile.am (SUBDIRS): Add djgpp.
* configure.in (AC_OUTPUT): Add djgpp/Makefile.
From Prashant TR.
2000-12-08 Jim Meyering <meyering@lucent.com>
* src/dirname.c: Include xalloc.h.
(main): Use dir_name rather than the underlying dir_name_r.
The former now handles cwd-relative names with drive-letter prefixes.
2000-12-02 Jim Meyering <meyering@lucent.com>
* src/seq.c (valid_format): Move pre-increment to a separate statement
to avoid a warning.

View File

@@ -1,3 +1,61 @@
2000-12-19 Jim Meyering <meyering@lucent.com>
* Version 2.0.11.
2000-12-18 Paul Eggert <eggert@twinsun.com>
* NEWS, doc/textutils.texi: New "sort" option -S SIZE.
* src/sys2.h (UINTMAX_MAX): New macro, taken from C99.
* src/sort.c: Include physmem.h.
(SORTALLOC, mergealloc, LINEALLOC): Remove.
(sortalloc): Default to zero at program startup.
(SORTALLOC_MIN, SORTALLOC_DEFAULT_MIN): New macros.
(usage, main): Add support for new -S SIZE option.
(specify_sort_size, default_sort_size): New functions.
(initlines): Do not let alloc exceed limit.
(findlines): Likewise.
(checkfp, mergefps, sort): Use sortalloc to size everything
else, instead of relying on precomputed sizes.
2000-12-17 Jim Meyering <meyering@lucent.com>
* doc/texinfo.tex: Update from master repository.
* config.sub: Likewise.
* config.guess: Likewise.
2000-12-11 Jim Meyering <meyering@lucent.com>
* Version 2.0.10.
2000-12-07 Jim Meyering <meyering@lucent.com>
* src/od.c (address_base): Declare to be static.
2000-12-06 Paul Eggert <eggert@twinsun.com>
* src/od.c (address_base, address_pad_len): New var.
(output_address_fmt_string, address_fmt_buffer, address_pad): Remove.
(flag_pseudo_start): Now int, not long int.
(pseudo_offset): Now off_t, not long int.
(n_specs, n_specs_allocated): Now size_t, not unsigned int.
(format_address, format_address_none, format_address_std,
format_address_label): Now accepts an extra char argument (an extra
char to print if nonzero), and prints instead of returning a string.
All callers changed.
(bytes_per_block): Now size_t, not int.
(format_address_none): Do not even print the extra char argument.
This simplifies the callers.
(format_address_std, format_address_label): Print off_t ourself
instead of trying to use autoconfigured format. This is faster and
more portable.
(format_address_paren): New function.
(dump): Remove unnecessary cast.
(expand_address_fmt): Remove.
(main): Use size_t, off_t, etc. instead of builtin types where this is
advisable. Adjust to above changes. Remove unnecessary cast.
2000-12-03 Jim Meyering <meyering@lucent.com>
* src/tail.c (tail_file): Initialize ignore, dev, and ino members,

View File

@@ -1,4 +1,9 @@
Changes in release 2.1
[2.0.11]
* sort accepts new -S SIZE option, to specify main-memory usage.
[2.0.10]
* od is faster and more portable than it was in 2.0.9
* tail avoids an uninitialized memory reference
[2.0.9]
* od now prints valid addresses for offsets of 2^32 and larger, and allows
the byte offset (-j) and byte count (-N) arguments to be 2^32 and larger.

View File

@@ -30,6 +30,7 @@
#include "quote.h"
#include "savedir.h"
#include "xstrtol.h"
#include "chown-core.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "chgrp"
@@ -52,54 +53,9 @@ struct group *getgrnam ();
# define endgrent() ((void) 0)
#endif
enum Change_status
{
CH_NOT_APPLIED,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
int lstat ();
static int change_dir_group PARAMS ((const char *dir, gid_t group,
const struct stat *statp));
/* The name the program was run with. */
char *program_name;
/* If nonzero, and the systems has support for it, change the ownership
of symbolic links rather than any files they point to. */
static int change_symlinks = 1;
/* When change_symlinks is set, this should be set to `lstat', otherwise,
it should be `stat'. */
static int (*xstat) ();
/* If nonzero, change the ownership of directories recursively. */
static int recurse;
/* If nonzero, force silence (no error messages). */
static int force_silent;
/* Level of verbosity. */
static enum Verbosity verbosity = V_off;
/* The name of the group to which ownership of the files is being given. */
static const char *groupname;
/* The argument to the --reference option. Use the group ID of this file.
This file must exist. */
static char *reference_file;
@@ -127,38 +83,6 @@ static struct option const long_options[] =
{0, 0, 0, 0}
};
/* Tell the user how/if the group of FILE has been changed.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed)
{
const char *fmt;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = _("group of %s changed to %s\n");
break;
case CH_FAILED:
fmt = _("failed to change group of %s to %s\n");
break;
case CH_NO_CHANGE_REQUESTED:
fmt = _("group of %s retained as %s\n");
break;
default:
abort ();
}
printf (fmt, quote (file), groupname);
}
/* Set *G according to NAME. */
static void
@@ -166,7 +90,6 @@ parse_group (const char *name, gid_t *g)
{
struct group *grp;
groupname = name;
if (*name == '\0')
error (1, 0, _("can not change to null group"));
@@ -193,139 +116,6 @@ parse_group (const char *name, gid_t *g)
endgrent (); /* Save a file descriptor. */
}
/* Change the ownership of FILE to GID GROUP.
If it is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
static int
change_file_group (int cmdline_arg, const char *file, gid_t group)
{
struct stat file_stats;
int errors = 0;
if ((*xstat) (file, &file_stats))
{
if (force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
if (group != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
if (S_ISLNK (file_stats.st_mode) && change_symlinks)
{
fail = lchown (file, (uid_t) -1, group);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else
{
fail = chown (file, (uid_t) -1, group);
}
/* Save errno, since in verbose mode, describe_change might change it. */
saved_errno = errno;
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed ? CH_NOT_APPLIED
: (fail ? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status);
}
if (fail)
{
errors = 1;
if (force_silent == 0)
{
/* Give a more specific message. Some systems set errno
to EPERM for both `inaccessible file' and `user not a member
of the specified group' errors. */
if (saved_errno == EPERM && !group_member (group))
{
error (0, saved_errno, _("you are not a member of group %s"),
quote (groupname));
}
else if (saved_errno == EINVAL && group > MAXUID)
{
error (0, 0, _("%s: invalid group number"),
quote (groupname));
}
else
{
error (0, saved_errno, _("changing group of %s"),
quote (file));
}
}
}
}
else if (verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED);
}
if (recurse && S_ISDIR (file_stats.st_mode))
errors |= change_dir_group (file, group, &file_stats);
return errors;
}
/* Recursively change the ownership of the files in directory DIR
to GID GROUP.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_group (const char *dir, gid_t group, const struct stat *statp)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_group (0, path, group);
}
free (path);
free (name_space);
return errors;
}
void
usage (int status)
{
@@ -364,9 +154,10 @@ Change the group membership of each FILE to GROUP.\n\
int
main (int argc, char **argv)
{
gid_t group;
gid_t gid;
int errors = 0;
int optc;
struct Chown_option chopt;
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -375,7 +166,7 @@ main (int argc, char **argv)
atexit (close_stdout);
recurse = force_silent = 0;
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
{
@@ -387,22 +178,22 @@ main (int argc, char **argv)
reference_file = optarg;
break;
case DEREFERENCE_OPTION:
change_symlinks = 0;
chopt.dereference = DEREF_ALWAYS;
break;
case 'R':
recurse = 1;
chopt.recurse = 1;
break;
case 'c':
verbosity = V_changes_only;
chopt.verbosity = V_changes_only;
break;
case 'f':
force_silent = 1;
chopt.force_silent = 1;
break;
case 'h':
change_symlinks = 1;
chopt.dereference = DEREF_NEVER;
break;
case 'v':
verbosity = V_high;
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -417,24 +208,26 @@ main (int argc, char **argv)
usage (1);
}
if (change_symlinks)
xstat = lstat;
else
xstat = stat;
if (reference_file)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
error (1, errno, _("getting attributes of %s"), quote (reference_file));
group = ref_stats.st_gid;
chopt.group_name = gid_to_name (ref_stats.st_gid);
gid = ref_stats.st_gid;
}
else
parse_group (argv[optind++], &group);
{
chopt.group_name = argv[optind++];
parse_group (chopt.group_name, &gid);
}
for (; optind < argc; ++optind)
errors |= change_file_group (1, argv[optind], group);
errors |= change_file_owner (1, argv[optind], (uid_t) -1, gid,
(uid_t) -1, (gid_t) -1, &chopt);
chopt_free (&chopt);
exit (errors);
}

366
src/chown-core.c Normal file
View File

@@ -0,0 +1,366 @@
/* chown-core.c -- core functions for changing ownership.
Copyright (C) 2000 Free Software Foundation.
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 2, 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, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Extracted from chown.c/chgrp.c and librarified by Jim Meyering. */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include "system.h"
#include "error.h"
#include "lchown.h"
#include "quote.h"
#include "savedir.h"
#include "chown-core.h"
#include "xalloc.h"
/* The number of decimal digits required to represent the largest value of
type `unsigned int'. This is enough for an 8-byte unsigned int type. */
#define UINT_MAX_DECIMAL_DIGITS 20
#ifndef _POSIX_VERSION
struct group *getgrnam ();
struct group *getgrgid ();
#endif
int lstat ();
void
chopt_init (struct Chown_option *chopt)
{
chopt->verbosity = V_off;
chopt->dereference = DEREF_NEVER;
chopt->recurse = 0;
chopt->force_silent = 0;
chopt->user_name = 0;
chopt->group_name = 0;
}
void
chopt_free (struct Chown_option *chopt)
{
/* Deliberately do not free chopt->user_name or ->group_name.
They're not always allocated. */
}
/* Convert N to a string, and return a pointer to that string in memory
allocated from the heap. */
static char *
uint_to_string (unsigned int n)
{
char buf[UINT_MAX_DECIMAL_DIGITS + 1];
char *p = buf + sizeof buf;
*--p = '\0';
do
*--p = '0' + (n % 10);
while ((n /= 10) != 0);
return xstrdup (p);
}
/* Convert the numeric group-id, GID, to a string stored in xmalloc'd memory,
and return it. If there's no corresponding group name, use the decimal
representation of the ID. */
char *
gid_to_name (gid_t gid)
{
struct group *grp = getgrgid (gid);
return grp ? xstrdup (grp->gr_name) : uint_to_string (gid);
}
/* Convert the numeric user-id, UID, to a string stored in xmalloc'd memory,
and return it. If there's no corresponding user name, use the decimal
representation of the ID. */
char *
uid_to_name (uid_t uid)
{
struct passwd *pwd = getpwuid (uid);
return pwd ? xstrdup (pwd->pw_name) : uint_to_string (uid);
}
/* Tell the user how/if the user and group of FILE have been changed.
If USER is NULL, give the group-oriented messages.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed,
char const *user, char const *group)
{
const char *fmt;
char *spec;
int spec_allocated = 0;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
if (user)
{
if (group)
{
spec = xmalloc (strlen (user) + 1 + strlen (group) + 1);
stpcpy (stpcpy (stpcpy (spec, user), ":"), group);
spec_allocated = 1;
}
else
{
spec = (char *) user;
}
}
else
{
spec = (char *) group;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = (user
? _("changed ownership of %s to %s\n")
: _("changed group of %s to %s\n"));
break;
case CH_FAILED:
fmt = (user
? _("failed to change ownership of %s to %s\n")
: _("failed to change group of %s to %s\n"));
break;
case CH_NO_CHANGE_REQUESTED:
fmt = (user
? _("ownership of %s retained as %s\n")
: _("group of %s retained as %s\n"));
break;
default:
abort ();
}
printf (fmt, quote (file), spec);
if (spec_allocated)
free (spec);
}
/* Recursively change the ownership of the files in directory DIR to user-id,
UID, and group-id, GID, according to the options specified by CHOPT.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_owner (const char *dir, uid_t uid, gid_t gid,
uid_t old_uid, gid_t old_gid,
const struct stat *statp,
struct Chown_option const *chopt)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (chopt->force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_owner (0, path, uid, gid, old_uid, old_gid,
chopt);
}
free (path);
free (name_space);
return errors;
}
/* Change the ownership of FILE to user-id, UID, and group-id, GID,
provided it presently has owner OLD_UID and group OLD_GID.
Honor the options specified by CHOPT.
If FILE is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
int
change_file_owner (int cmdline_arg, const char *file, uid_t uid, gid_t gid,
uid_t old_uid, gid_t old_gid,
struct Chown_option const *chopt)
{
struct stat file_stats;
uid_t new_uid;
gid_t new_gid;
int errors = 0;
int is_symlink;
int is_directory;
if (lstat (file, &file_stats))
{
if (chopt->force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
/* If it's a symlink and we're dereferencing, then use stat
to get the attributes of the referent. */
if (S_ISLNK (file_stats.st_mode))
{
if (chopt->dereference == DEREF_ALWAYS
&& stat (file, &file_stats))
{
if (chopt->force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
is_symlink = 1;
/* With -R, don't traverse through symlinks-to-directories.
But of course, this will all change with POSIX's new
-H, -L, -P options. */
is_directory = 0;
}
else
{
is_symlink = 0;
is_directory = S_ISDIR (file_stats.st_mode);
}
if ((old_uid == (uid_t) -1 || file_stats.st_uid == old_uid)
&& (old_gid == (gid_t) -1 || file_stats.st_gid == old_gid))
{
new_uid = (uid == (uid_t) -1 ? file_stats.st_uid : uid);
new_gid = (gid == (gid_t) -1 ? file_stats.st_gid : gid);
if (new_uid != file_stats.st_uid || new_gid != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
int called_lchown = 0;
if (is_symlink)
{
if (chopt->dereference == DEREF_NEVER)
{
called_lchown = 1;
fail = lchown (file, new_uid, new_gid);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else if (chopt->dereference == DEREF_ALWAYS)
{
/* Applying chown to a symlink and expecting it to affect
the referent is not portable. So instead, open the
file and use fchown on the resulting descriptor. */
int fd = open (file, O_RDONLY | O_NONBLOCK | O_NOCTTY);
fail = (fd == -1 ? 1 : fchown (fd, new_uid, new_gid));
}
else
{
/* FIXME */
abort ();
}
}
else
{
fail = chown (file, new_uid, new_gid);
}
saved_errno = errno;
if (chopt->verbosity == V_high
|| (chopt->verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed
? CH_NOT_APPLIED
: (fail
? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status,
chopt->user_name, chopt->group_name);
}
if (fail)
{
if (chopt->force_silent == 0)
error (0, saved_errno, (uid != (uid_t) -1
? _("changing ownership of %s")
: _("changing group of %s")),
quote (file));
errors = 1;
}
else
{
/* The change succeeded. On some systems, the chown function
resets the `special' permission bits. When run by a
`privileged' user, this program must ensure that at least
the set-uid and set-group ones are still set. */
if (file_stats.st_mode & ~(S_IFMT | S_IRWXUGO)
/* If we called lchown above (which means this is a symlink),
then skip it. */
&& ! called_lchown)
{
if (chmod (file, file_stats.st_mode))
{
error (0, saved_errno,
_("unable to restore permissions of %s"),
quote (file));
fail = 1;
}
}
}
}
else if (chopt->verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED,
chopt->user_name, chopt->group_name);
}
}
if (chopt->recurse && is_directory)
errors |= change_dir_owner (file, uid, gid,
old_uid, old_gid, &file_stats, chopt);
return errors;
}

89
src/chown-core.h Normal file
View File

@@ -0,0 +1,89 @@
/* chown-core.h -- types and prototypes shared by chown and chgrp.
Copyright (C) 2000 Free Software Foundation.
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 2, 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, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef CHOWN_CORE_H
# define CHOWN_CORE_H
enum Change_status
{
CH_NOT_APPLIED = 1,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
enum Dereference_symlink
{
DEREF_UNDEFINED = 1,
DEREF_NEVER, /* -P */
DEREF_COMMAND_LINE_ARGUMENTS, /* -H */
DEREF_ALWAYS /* -L */
};
struct Chown_option
{
/* Level of verbosity. */
enum Verbosity verbosity;
/* If nonzero, change the ownership of directories recursively. */
int recurse;
/* This is useful only on systems with support for changing the
ownership of symbolic links. */
enum Dereference_symlink dereference;
/* If nonzero, force silence (no error messages). */
int force_silent;
/* The name of the user to which ownership of the files is being given. */
char *user_name;
/* The name of the group to which ownership of the files is being given. */
char *group_name;
};
void
chopt_init (struct Chown_option *);
void
chopt_free (struct Chown_option *);
char *
gid_to_name (gid_t);
char *
uid_to_name (uid_t);
int
change_file_owner PARAMS ((int, const char *,
uid_t, gid_t,
uid_t, gid_t,
struct Chown_option const *));
#endif /* CHOWN_CORE_H */

View File

@@ -31,8 +31,6 @@
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <getopt.h>
#include "system.h"
@@ -40,6 +38,7 @@
#include "lchown.h"
#include "quote.h"
#include "savedir.h"
#include "chown-core.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "chown"
@@ -59,52 +58,9 @@ struct group *getgrgid ();
char *parse_user_spec ();
void strip_trailing_slashes ();
enum Change_status
{
CH_NOT_APPLIED,
CH_SUCCEEDED,
CH_FAILED,
CH_NO_CHANGE_REQUESTED
};
enum Verbosity
{
/* Print a message for each file that is processed. */
V_high,
/* Print a message for each file whose attributes we change. */
V_changes_only,
/* Do not be verbose. This is the default. */
V_off
};
static int change_dir_owner PARAMS ((const char *dir, uid_t user, gid_t group,
uid_t old_user, gid_t old_group,
const struct stat *statp));
/* The name the program was run with. */
char *program_name;
/* If nonzero, and the systems has support for it, change the ownership
of symbolic links rather than any files they point to. */
static int change_symlinks = 1;
/* If nonzero, change the ownership of directories recursively. */
static int recurse;
/* If nonzero, force silence (no error messages). */
static int force_silent;
/* Level of verbosity. */
static enum Verbosity verbosity = V_off;
/* The name of the user to which ownership of the files is being given. */
static char *username;
/* The name of the group to which ownership of the files is being given. */
static const char *groupname;
/* The argument to the --reference option. Use the owner and group IDs
of this file. This file must exist. */
static char *reference_file;
@@ -134,169 +90,6 @@ static struct option const long_options[] =
{0, 0, 0, 0}
};
/* Tell the user how/if the user and group of FILE have been changed.
CHANGED describes what (if anything) has happened. */
static void
describe_change (const char *file, enum Change_status changed)
{
const char *fmt;
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
return;
}
switch (changed)
{
case CH_SUCCEEDED:
fmt = _("owner of %s changed to ");
break;
case CH_FAILED:
fmt = _("failed to change owner of %s to ");
break;
case CH_NO_CHANGE_REQUESTED:
fmt = _("owner of %s retained as ");
break;
default:
abort ();
}
printf (fmt, file);
if (groupname)
printf ("%s.%s\n", username, groupname);
else
printf ("%s\n", username);
}
/* Change the ownership of FILE to UID USER and GID GROUP
provided it presently has UID OLDUSER and GID OLDGROUP.
If it is a directory and -R is given, recurse.
Return 0 if successful, 1 if errors occurred. */
static int
change_file_owner (int cmdline_arg, const char *file, uid_t user, gid_t group,
uid_t old_user, gid_t old_group)
{
struct stat file_stats;
uid_t newuser;
gid_t newgroup;
int errors = 0;
if (lstat (file, &file_stats))
{
if (force_silent == 0)
error (0, errno, _("getting attributes of %s"), quote (file));
return 1;
}
if ((old_user == (uid_t) -1 || file_stats.st_uid == old_user) &&
(old_group == (gid_t) -1 || file_stats.st_gid == old_group))
{
newuser = user == (uid_t) -1 ? file_stats.st_uid : user;
newgroup = group == (gid_t) -1 ? file_stats.st_gid : group;
if (newuser != file_stats.st_uid || newgroup != file_stats.st_gid)
{
int fail;
int symlink_changed = 1;
int saved_errno;
if (S_ISLNK (file_stats.st_mode) && change_symlinks)
{
fail = lchown (file, newuser, newgroup);
/* Ignore the failure if it's due to lack of support (ENOSYS)
and this is not a command line argument. */
if (!cmdline_arg && fail && errno == ENOSYS)
{
fail = 0;
symlink_changed = 0;
}
}
else
{
fail = chown (file, newuser, newgroup);
}
saved_errno = errno;
if (verbosity == V_high || (verbosity == V_changes_only && !fail))
{
enum Change_status ch_status = (! symlink_changed
? CH_NOT_APPLIED
: (fail
? CH_FAILED : CH_SUCCEEDED));
describe_change (file, ch_status);
}
if (fail)
{
if (force_silent == 0)
error (0, saved_errno, _("changing ownership of %s"),
quote (file));
errors = 1;
}
}
else if (verbosity == V_high)
{
describe_change (file, CH_NO_CHANGE_REQUESTED);
}
}
if (recurse && S_ISDIR (file_stats.st_mode))
errors |= change_dir_owner (file, user, group,
old_user, old_group, &file_stats);
return errors;
}
/* Recursively change the ownership of the files in directory DIR
to UID USER and GID GROUP.
STATP points to the results of lstat on DIR.
Return 0 if successful, 1 if errors occurred. */
static int
change_dir_owner (const char *dir, uid_t user, gid_t group,
uid_t old_user, gid_t old_group,
const struct stat *statp)
{
char *name_space, *namep;
char *path; /* Full path of each entry to process. */
unsigned dirlength; /* Length of `dir' and '\0'. */
unsigned filelength; /* Length of each pathname to process. */
unsigned pathlength; /* Bytes allocated for `path'. */
int errors = 0;
name_space = savedir (dir, statp->st_size);
if (name_space == NULL)
{
if (force_silent == 0)
error (0, errno, "%s", quote (dir));
return 1;
}
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
pathlength = dirlength + 1;
/* Give `path' a dummy value; it will be reallocated before first use. */
path = xmalloc (pathlength);
strcpy (path, dir);
path[dirlength - 1] = '/';
for (namep = name_space; *namep; namep += filelength - dirlength)
{
filelength = dirlength + strlen (namep) + 1;
if (filelength > pathlength)
{
pathlength = filelength * 2;
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_owner (0, path, user, group, old_user, old_group);
}
free (path);
free (name_space);
return errors;
}
void
usage (int status)
{
@@ -345,10 +138,11 @@ as symbolic.\n\
int
main (int argc, char **argv)
{
uid_t user = (uid_t) -1; /* New uid; -1 if not to be changed. */
gid_t group = (uid_t) -1; /* New gid; -1 if not to be changed. */
uid_t old_user = (uid_t) -1; /* Old uid; -1 if unrestricted. */
gid_t old_group = (uid_t) -1; /* Old gid; -1 if unrestricted. */
uid_t uid = (uid_t) -1; /* New uid; -1 if not to be changed. */
gid_t gid = (uid_t) -1; /* New gid; -1 if not to be changed. */
uid_t old_uid = (uid_t) -1; /* Old uid; -1 if unrestricted. */
gid_t old_gid = (uid_t) -1; /* Old gid; -1 if unrestricted. */
struct Chown_option chopt;
int errors = 0;
int optc;
@@ -360,7 +154,7 @@ main (int argc, char **argv)
atexit (close_stdout);
recurse = force_silent = 0;
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "Rcfhv", long_options, NULL)) != -1)
{
@@ -372,32 +166,32 @@ main (int argc, char **argv)
reference_file = optarg;
break;
case DEREFERENCE_OPTION:
change_symlinks = 0;
chopt.dereference = DEREF_ALWAYS;
break;
case FROM_OPTION:
{
char *u_dummy, *g_dummy;
const char *e = parse_user_spec (argv[optind],
&old_user, &old_group,
&old_uid, &old_gid,
&u_dummy, &g_dummy);
if (e)
error (1, 0, "%s: %s", quote (argv[optind]), e);
break;
}
case 'R':
recurse = 1;
chopt.recurse = 1;
break;
case 'c':
verbosity = V_changes_only;
chopt.verbosity = V_changes_only;
break;
case 'f':
force_silent = 1;
chopt.force_silent = 1;
break;
case 'h':
change_symlinks = 1;
chopt.dereference = DEREF_NEVER;
break;
case 'v':
verbosity = V_high;
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -419,17 +213,21 @@ main (int argc, char **argv)
if (stat (reference_file, &ref_stats))
error (1, errno, _("getting attributes of %s"), quote (reference_file));
user = ref_stats.st_uid;
group = ref_stats.st_gid;
uid = ref_stats.st_uid;
gid = ref_stats.st_gid;
chopt.user_name = uid_to_name (ref_stats.st_uid);
chopt.group_name = gid_to_name (ref_stats.st_gid);
}
else
{
const char *e = parse_user_spec (argv[optind], &user, &group,
&username, &groupname);
const char *e = parse_user_spec (argv[optind], &uid, &gid,
&chopt.user_name, &chopt.group_name);
if (e)
error (1, 0, "%s: %s", argv[optind], e);
if (username == NULL)
username = "";
/* FIXME: set it to the empty string? */
if (chopt.user_name == NULL)
chopt.user_name = "";
optind++;
}
@@ -437,9 +235,11 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
{
strip_trailing_slashes (argv[optind]);
errors |= change_file_owner (1, argv[optind], user, group,
old_user, old_group);
errors |= change_file_owner (1, argv[optind], uid, gid,
old_uid, old_gid, &chopt);
}
chopt_free (&chopt);
exit (errors);
}

View File

@@ -26,6 +26,7 @@
#include "error.h"
#include "dirname.h"
#include "closeout.h"
#include "xalloc.h"
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "dirname"
@@ -92,9 +93,11 @@ main (int argc, char **argv)
usage (1);
}
len = dir_name_r (argv[1], &result);
fwrite (result, 1, len, stdout);
putchar ('\n');
result = dir_name (argv[1]);
if (result == NULL)
xalloc_die ();
puts (result);
free (result);
exit (0);
}

182
src/od.c
View File

@@ -150,17 +150,15 @@ static const char *const charname[33] =
"sp"
};
/* A printf control string for printing a file offset. */
static const char *output_address_fmt_string;
/* Address base (8, 10 or 16). */
static int address_base;
/* The number of octal digits required to represent the largest off_t value. */
#define MAX_ADDRESS_LENGTH \
((sizeof (off_t) * CHAR_BIT + CHAR_BIT - 1) / 3)
/* Space for a normal address, a space, a pseudo address, parentheses
around the pseudo address, and a trailing zero byte. */
static char address_fmt_buffer[2 * MAX_ADDRESS_LENGTH + 4];
static char address_pad[MAX_ADDRESS_LENGTH + 1];
/* Width of a normal address. */
static int address_pad_len;
static size_t string_min;
static int flag_dump_strings;
@@ -171,15 +169,15 @@ static int flag_dump_strings;
static int traditional;
/* Non-zero if an old-style `pseudo-address' was specified. */
static long int flag_pseudo_start;
static int flag_pseudo_start;
/* The difference between the old-style pseudo starting address and
the number of bytes to skip. */
static long int pseudo_offset;
static off_t pseudo_offset;
/* Function to format an address and optionally an additional parenthesized
pseudo-address; it returns the formatted string. */
static const char *(*format_address) PARAMS ((off_t));
/* Function that accepts an address and an optional following char,
and prints the address and char to stdout. */
static void (*format_address) PARAMS ((off_t, char));
/* The number of input bytes to skip before formatting and writing. */
static off_t n_bytes_to_skip = 0;
@@ -201,16 +199,16 @@ static int abbreviate_duplicate_blocks = 1;
static struct tspec *spec;
/* The number of format specs. */
static unsigned int n_specs;
static size_t n_specs;
/* The allocated length of SPEC. */
static unsigned int n_specs_allocated;
static size_t n_specs_allocated;
/* The number of input bytes formatted per output line. It must be
a multiple of the least common multiple of the sizes associated with
the specified output types. It should be as large as possible, but
no larger than 16 -- unless specified with the -w option. */
static unsigned int bytes_per_block;
static size_t bytes_per_block;
/* Human-readable representation of *file_list (for error messages).
It differs from *file_list only when *file_list is "-". */
@@ -1042,32 +1040,64 @@ skip (off_t n_skip)
return err;
}
static const char *
format_address_none (off_t address ATTRIBUTE_UNUSED)
static void
format_address_none (off_t address ATTRIBUTE_UNUSED, char c ATTRIBUTE_UNUSED)
{
return "";
}
static const char *
format_address_std (off_t address)
static void
format_address_std (off_t address, char c)
{
const char *address_string;
char buf[MAX_ADDRESS_LENGTH + 2];
char *p = buf + sizeof buf;
char const *pbound;
sprintf (address_fmt_buffer, output_address_fmt_string, address);
address_string = address_fmt_buffer;
return address_string;
*--p = '\0';
*--p = c;
pbound = p - address_pad_len;
/* Use a special case of the code for each base. This is measurably
faster than generic code. */
switch (address_base)
{
case 8:
do
*--p = '0' + (address & 7);
while ((address >>= 3) != 0);
break;
case 10:
do
*--p = '0' + (address % 10);
while ((address /= 10) != 0);
break;
case 16:
do
*--p = "0123456789abcdef"[address & 15];
while ((address >>= 4) != 0);
break;
}
while (pbound < p)
*--p = '0';
fputs (p, stdout);
}
static const char *
format_address_label (off_t address)
static void
format_address_paren (off_t address, char c)
{
const char *address_string;
assert (output_address_fmt_string != NULL);
putchar ('(');
format_address_std (address, ')');
putchar (c);
}
sprintf (address_fmt_buffer, output_address_fmt_string,
address, address + pseudo_offset);
address_string = address_fmt_buffer;
return address_string;
static void
format_address_label (off_t address, char c)
{
format_address_std (address, ' ');
format_address_paren (address + pseudo_offset, c);
}
/* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
@@ -1107,16 +1137,15 @@ write_block (off_t current_offset, off_t n_bytes,
}
else
{
unsigned int i;
size_t i;
prev_pair_equal = 0;
for (i = 0; i < n_specs; i++)
{
const char *addr_or_pad = (i == 0
? format_address (current_offset)
: address_pad);
fputs (addr_or_pad, stdout);
if (i == 0)
format_address (current_offset, '\0');
else
printf ("%*s", address_pad_len, "");
(*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
if (spec[i].hexl_mode_trailer)
{
@@ -1307,7 +1336,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
static int
get_lcm (void)
{
unsigned int i;
size_t i;
int l_c_m = 1;
for (i = 0; i < n_specs; i++)
@@ -1436,7 +1465,7 @@ dump (void)
/* Make bytes_to_write the smallest multiple of l_c_m that
is at least as large as n_bytes_read. */
bytes_to_write = l_c_m * (int) ((n_bytes_read + l_c_m - 1) / l_c_m);
bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
memset (block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
write_block (current_offset, bytes_to_write,
@@ -1444,8 +1473,7 @@ dump (void)
current_offset += n_bytes_read;
}
if (output_address_fmt_string != NULL)
printf ("%s\n", format_address (current_offset));
format_address (current_offset, '\n');
if (limit_bytes_to_format && current_offset > end_offset)
err |= check_and_close ();
@@ -1523,10 +1551,8 @@ dump_strings (void)
/* If we get here, the string is all printable and null-terminated,
so print it. It is all in `buf' and `i' is its length. */
buf[i] = 0;
if (output_address_fmt_string != NULL)
{
printf ("%s ", format_address (address - i - 1));
}
format_address (address - i - 1, ' ');
for (i = 0; (c = buf[i]); i++)
{
switch (c)
@@ -1575,42 +1601,21 @@ dump_strings (void)
return err;
}
/* There must be exactly one %s format specifier in FORMAT_TEMPLATE.
Return the just-malloc'd result of using sprintf to insert
OFF_T_PRINTF_FORMAT_STRING into FORMAT_TEMPLATE.
Technically, the caller should free this memory, but IMHO it's not
worth it in this case. */
static char *
expand_address_fmt (char const *format_template)
{
size_t len = strlen (format_template);
char *fmt = xmalloc (len + 1);
/* Ensure that the literal we're inserting is no longer than the two-byte
string `%s' it's replacing. There's also the %%, so technically we don't
even need the `+ 1' above. */
assert (OFF_T_PRINTF_FORMAT_STRING[0] == 0
|| OFF_T_PRINTF_FORMAT_STRING[1] == 0
|| OFF_T_PRINTF_FORMAT_STRING[2] == 0);
sprintf (fmt, format_template, OFF_T_PRINTF_FORMAT_STRING);
return fmt;
}
int
main (int argc, char **argv)
{
int c;
int n_files;
unsigned int i;
unsigned int l_c_m;
unsigned int address_pad_len;
unsigned long int desired_width IF_LINT (= 0);
size_t i;
int l_c_m;
size_t desired_width IF_LINT (= 0);
int width_specified = 0;
int n_failed_decodes = 0;
int err;
/* The old-style `pseudo starting address' to be printed in parentheses
after any true address. */
long int pseudo_start IF_LINT (= 0);
off_t pseudo_start IF_LINT (= 0);
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -1646,8 +1651,8 @@ main (int argc, char **argv)
n_specs_allocated = 5;
spec = (struct tspec *) xmalloc (n_specs_allocated * sizeof (struct tspec));
output_address_fmt_string = expand_address_fmt ("%%07%so");
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
flag_dump_strings = 0;
@@ -1666,22 +1671,21 @@ main (int argc, char **argv)
switch (optarg[0])
{
case 'd':
output_address_fmt_string = expand_address_fmt ("%%07%sd");
format_address = format_address_std;
address_base = 10;
address_pad_len = 7;
break;
case 'o':
output_address_fmt_string = expand_address_fmt ("%%07%so");
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
break;
case 'x':
output_address_fmt_string = expand_address_fmt ("%%06%sx");
format_address = format_address_std;
address_base = 16;
address_pad_len = 6;
break;
case 'n':
output_address_fmt_string = NULL;
format_address = format_address_none;
address_pad_len = 0;
break;
@@ -1785,7 +1789,7 @@ it must be one character from [doxn]"),
s_err = xstrtoumax (optarg, NULL, 10, &w_tmp, "");
if (s_err != LONGINT_OK)
STRTOL_FATAL_ERROR (optarg, _("width specification"), s_err);
if (ULONG_MAX < w_tmp)
if (SIZE_MAX < w_tmp)
error (EXIT_FAILURE, 0, _("%s is too large"), optarg);
desired_width = w_tmp;
}
@@ -1885,29 +1889,17 @@ it must be one character from [doxn]"),
if (flag_pseudo_start)
{
static char buf[10];
if (output_address_fmt_string == NULL)
if (format_address == format_address_none)
{
output_address_fmt_string = expand_address_fmt ("(%%07%so)");
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
format_address = format_address_paren;
}
else
{
sprintf (buf, "%s (%s)",
output_address_fmt_string,
output_address_fmt_string);
output_address_fmt_string = buf;
format_address = format_address_label;
}
format_address = format_address_label;
}
}
assert (address_pad_len <= MAX_ADDRESS_LENGTH);
for (i = 0; i < address_pad_len; i++)
address_pad[i] = ' ';
address_pad[address_pad_len] = '\0';
if (n_specs == 0)
{
if (decode_one_format ("o2", "o2", NULL, &(spec[0])))
@@ -1948,14 +1940,14 @@ it must be one character from [doxn]"),
else
{
error (0, 0, _("warning: invalid width %lu; using %d instead"),
desired_width, l_c_m);
(unsigned long) desired_width, l_c_m);
bytes_per_block = l_c_m;
}
}
else
{
if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
bytes_per_block = l_c_m * (int) (DEFAULT_BYTES_PER_BLOCK / l_c_m);
bytes_per_block = l_c_m * (DEFAULT_BYTES_PER_BLOCK / l_c_m);
else
bytes_per_block = l_c_m;
}

View File

@@ -779,7 +779,7 @@ isaac_seed_finish (struct isaac_state *s)
#define ISAAC_SEED(s,x) isaac_seed_data (s, &(x), sizeof (x))
#if __GNUC__ >= 2 && (__i386__ || __alpha__ || _ARCH_PPC)
#if __GNUC__ >= 2 && (__i386__ || __alpha__)
/*
* Many processors have very-high-resolution timer registers,
* The timer registers can be made inaccessible, so we have to deal with the
@@ -815,6 +815,8 @@ isaac_seed_machdep (struct isaac_state *s)
__asm__ __volatile__ ("rpcc %0" : "=r" (t));
# endif
# if _ARCH_PPC
/* Code not used because this instruction is available only on first-
generation PPCs and evokes a SIGBUS on some Linux 2.4 kernels. */
word32 t;
__asm__ __volatile__ ("mfspr %0,22" : "=r" (t));
# endif
@@ -833,12 +835,12 @@ isaac_seed_machdep (struct isaac_state *s)
}
}
#else /* !(__i386__ || __alpha__ || _ARCH_PPC) */
#else /* !(__i386__ || __alpha__) */
/* Do-nothing stub */
# define isaac_seed_machdep(s) (void) 0
#endif /* !(__i386__ || __alpha__ || _ARCH_PPC) */
#endif /* !(__i386__ || __alpha__) */
/*

View File

@@ -34,6 +34,7 @@
#include "hard-locale.h"
#include "human.h"
#include "memcoll.h"
#include "physmem.h"
#include "xalloc.h"
#include "xstrtol.h"
@@ -57,6 +58,7 @@ double strtod ();
#endif
/* Undefine, to avoid warning about redefinition on some systems. */
/* FIXME: Remove these: use MIN/MAX from sys2.h. */
#undef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#undef max
@@ -215,21 +217,19 @@ static MONTHTAB_CONST struct month monthtab[] =
/* During the merge phase, the number of files to merge at once. */
#define NMERGE 16
/* Initial buffer size for in-core sorting. The buffer will grow only
if a line longer than this is seen. */
#define SORTALLOC (8 * 1024 * 1024)
static size_t const sortalloc = SORTALLOC;
/* Minimum text buffer size. */
#define SORTALLOC_MIN (4 * NMERGE * sizeof (struct line))
/* Initial buffer size for in core merge buffers. Bear in mind that
up to NMERGE * mergealloc bytes may be allocated for merge buffers. */
static size_t const mergealloc = SORTALLOC / NMERGE / 2;
/* Minimum text buffer size if the user does not specify a size. */
#define SORTALLOC_DEFAULT_MIN max (SORTALLOC_MIN, 1024 * 1024)
/* Initial text buffer size for main-memory sorting. The buffer will
grow only if a line longer than this is seen. */
static size_t sortalloc;
/* Guess of average line length. */
static size_t const linelength = 30;
/* Maximum number of elements for the array(s) of struct line's, in bytes. */
#define LINEALLOC (SORTALLOC / 2)
/* Array of directory names in which any temporary files are to be created. */
static char const **temp_dirs;
@@ -298,6 +298,7 @@ Write sorted concatenation of all FILE(s) to standard output.\n\
-o FILE write result on FILE instead of standard output\n\
-r reverse the result of comparisons\n\
-s stabilize sort by disabling last resort comparison\n\
-S SIZE use SIZE for main memory sorting\n\
-t SEP use SEParator instead of non- to whitespace transition\n\
-T DIRECTORY use DIRECTORY for temporary files, not $TMPDIR or %s\n\
multiple -T options specify multiple directories\n\
@@ -314,7 +315,12 @@ POS is F[.C][OPTS], where F is the field number and C the character position\n\
in the field, both counted from one with -k, from zero with the obsolescent\n\
form. OPTS is made up of one or more of Mbdfinr; this effectively disables\n\
global -Mbdfinr settings for that key. If no key is given, use the entire\n\
line as the key. With no FILE, or when FILE is -, read standard input.\n\
line as the key.\n\
\n\
SIZE may be followed by the following multiplicative suffixes:\n\
%% 1%% of memory, b 1, k 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
\n\
*** WARNING ***\n\
The locale specified by the environment affects sort order.\n\
@@ -558,6 +564,79 @@ inittables (void)
#endif /* NLS */
}
/* Specify the amount of main memory to use when sorting. */
static void
specify_sort_size (char const *s)
{
uintmax_t n;
char *suffix;
enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkmMPtTYZ");
/* The default unit is kB. */
if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
{
if (n <= UINTMAX_MAX / 1024)
n *= 1024;
else
e = LONGINT_OVERFLOW;
}
/* A 'b' suffix means bytes; a '%' suffix means percent of memory. */
if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1])
switch (suffix[0])
{
case 'b':
e = LONGINT_OK;
break;
case '%':
{
double mem = physmem_total () * n / 100;
/* Use "<", not "<=", to avoid problems with rounding. */
if (mem < UINTMAX_MAX)
{
n = mem;
e = LONGINT_OK;
}
else
e = LONGINT_OVERFLOW;
}
break;
}
if (e == LONGINT_OK)
{
/* Normally a buffer is allocated with sortalloc bytes, and a
line table with at most sortalloc / 2 bytes. So adjust the
size so that size * 1.5 is about n. */
sortalloc = (n / 3) * 2;
if (sortalloc == (n / 3) * 2)
{
if (sortalloc < SORTALLOC_MIN)
sortalloc = SORTALLOC_MIN;
return;
}
e = LONGINT_OVERFLOW;
}
STRTOL_FATAL_ERROR (s, _("sort size"), e);
}
/* Set the sort size to the default. */
static void
default_sort_size (void)
{
/* Set sortalloc to 50% of available memory, unless it overflows. */
double mem = physmem_available ();
sortalloc = min (mem, SIZE_MAX);
sortalloc >>= 1;
if (sortalloc < SORTALLOC_DEFAULT_MIN)
sortalloc = SORTALLOC_DEFAULT_MIN;
}
/* Initialize BUF, allocating ALLOC bytes initially. */
static void
@@ -631,6 +710,8 @@ fillbuf (struct buffer *buf, FILE *fp)
static void
initlines (struct lines *lines, size_t alloc, size_t limit)
{
if (limit < alloc)
alloc = limit;
lines->alloc = alloc;
if (SIZE_MAX / sizeof (struct line) < alloc)
xalloc_die ();
@@ -806,7 +887,7 @@ findlines (struct buffer *buf, struct lines *lines)
if (lines->used == lines->alloc)
{
lines->alloc *= 2;
lines->alloc = min (2 * lines->alloc, lines->limit);
if (SIZE_MAX / sizeof (struct line) < lines->alloc)
xalloc_die ();
lines->lines = (struct line *)
@@ -1360,10 +1441,11 @@ checkfp (FILE *fp, const char *file_name)
struct line *disorder_line IF_LINT (= NULL);
uintmax_t disorder_line_number = 0;
struct keyfield *key = keylist;
size_t mergealloc = sortalloc / (2 * NMERGE);
initbuf (&buf, mergealloc);
initlines (&lines, mergealloc / linelength + 1,
LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
sortalloc / (4 * NMERGE * sizeof (struct line)));
alloc = linelength;
temp.text = xmalloc (alloc);
@@ -1460,6 +1542,7 @@ mergefps (FILE **fps, register int nfps, FILE *ofp, const char *output_file)
struct line saved; /* Saved line storage for unique check. */
struct line const *savedline IF_LINT (= NULL);
/* &saved if there is a saved line. */
size_t mergealloc = sortalloc / (2 * NMERGE);
size_t savealloc IF_LINT (= 0); /* Size allocated for the saved line. */
size_t cur[NMERGE]; /* Current line in each line table. */
int ord[NMERGE]; /* Table representing a permutation of fps,
@@ -1494,7 +1577,7 @@ mergefps (FILE **fps, register int nfps, FILE *ofp, const char *output_file)
else
{
initlines (&lines[i], mergealloc / linelength + 1,
LINEALLOC / ((NMERGE + NMERGE) * sizeof (struct line)));
sortalloc / (4 * NMERGE * sizeof (struct line)));
findlines (&buffer[i], &lines[i]);
cur[i] = 0;
}
@@ -1721,7 +1804,7 @@ sort (char **files, int nfiles, FILE *ofp, const char *output_file)
initbuf (&buf, sortalloc);
initlines (&lines, sortalloc / linelength + 1,
LINEALLOC / sizeof (struct line));
sortalloc / (2 * sizeof (struct line)));
while (nfiles--)
{
@@ -2181,6 +2264,15 @@ but lacks following character offset"));
case 's':
stable = 1;
break;
case 'S':
if (s[1])
specify_sort_size (++s);
else if (i < argc - 1)
specify_sort_size (argv[++i]);
else
error (SORT_FAILURE, 0,
_("option `-S' requires an argument"));
goto outer;
case 't':
if (s[1])
tab = *++s;
@@ -2239,7 +2331,7 @@ but lacks following character offset"));
for (key = keylist; key; key = key->next)
if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse
&& !key->skipeblanks && !key->month && !key->numeric
&& !key->general_numeric)
&& !key->general_numeric)
{
key->ignore = gkey.ignore;
key->translate = gkey.translate;
@@ -2269,6 +2361,9 @@ but lacks following character offset"));
files = &minus;
}
if (sortalloc == 0)
default_sort_size ();
if (checkonly)
{
if (nfiles > 1)

View File

@@ -171,6 +171,10 @@ char *alloca ();
# include <stdint.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h> /* for the definition of UINTMAX_MAX */
#endif
#include <ctype.h>
/* Jim Meyering writes:
@@ -527,6 +531,10 @@ enum
# define SIZE_MAX TYPE_MAXIMUM (size_t)
#endif
#ifndef UINTMAX_MAX
# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
#endif
#ifndef OFF_T_MIN
# define OFF_T_MIN TYPE_MINIMUM (off_t)
#endif

7
tests/chgrp/Makefile.am Normal file
View File

@@ -0,0 +1,7 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-.
AUTOMAKE_OPTIONS = 1.4 gnits
TESTS = basic deref recurse
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH

283
tests/chgrp/Makefile.in Normal file
View File

@@ -0,0 +1,283 @@
# Makefile.in generated automatically by automake 1.4a from Makefile.am
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_FLAG =
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
@SET_MAKE@
host_alias = @host_alias@
host_triplet = @host@
AMDEP = @AMDEP@
AMTAR = @AMTAR@
AWK = @AWK@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
CXX = @CXX@
CXXCPP = @CXXCPP@
DATADIRNAME = @DATADIRNAME@
DEPDIR = @DEPDIR@
DF_PROG = @DF_PROG@
FESETROUND_LIBM = @FESETROUND_LIBM@
GENCAT = @GENCAT@
GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
GLIBC21 = @GLIBC21@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GNU_PACKAGE = @GNU_PACKAGE@
GT_NO = @GT_NO@
GT_YES = @GT_YES@
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
INSTOBJEXT = @INSTOBJEXT@
INTLDEPS = @INTLDEPS@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
KMEM_GROUP = @KMEM_GROUP@
LIBICONV = @LIBICONV@
LIBOBJS = @LIBOBJS@
LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
LIB_CRYPT = @LIB_CRYPT@
LIB_NANOSLEEP = @LIB_NANOSLEEP@
MAKEINFO = @MAKEINFO@
MAN = @MAN@
MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
NEED_SETGID = @NEED_SETGID@
OPTIONAL_BIN_PROGS = @OPTIONAL_BIN_PROGS@
OPTIONAL_BIN_ZCRIPTS = @OPTIONAL_BIN_ZCRIPTS@
PACKAGE = @PACKAGE@
PERL = @PERL@
POFILES = @POFILES@
POSUB = @POSUB@
POW_LIBM = @POW_LIBM@
RANLIB = @RANLIB@
SEQ_LIBM = @SEQ_LIBM@
SQRT_LIBM = @SQRT_LIBM@
U = @U@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
YACC = @YACC@
install_sh = @install_sh@
l = @l@
AUTOMAKE_OPTIONS = 1.4 gnits
TESTS = basic deref recurse
EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT = \
PATH=`pwd`/../../src:$$PATH
subdir = tests/chgrp
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnits tests/chgrp/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
tags: TAGS
TAGS:
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; \
srcdir=$(srcdir); export srcdir; \
list='$(TESTS)'; \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
;; \
*) \
echo "PASS: $$tst"; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*" $$tst "*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
*) \
failed=`expr $$failed + 1`; \
echo "FAIL: $$tst"; \
;; \
esac; \
fi; \
done; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="All $$all tests passed"; \
else \
banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all tests failed"; \
else \
banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
fi; \
fi; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"; \
test "$$failed" -eq 0; \
fi
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pR $$d/$$file $(distdir) \
|| exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
-rm -f Makefile.in
mostlyclean-am: mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: tags check-TESTS distdir info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all install-strip installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

89
tests/chgrp/basic Executable file
View File

@@ -0,0 +1,89 @@
#!/bin/sh
# make sure chgrp is reasonable
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../envvar-check
. $srcdir/../lang-default
. $srcdir/../group-names
pwd=`pwd`
tmp=basic.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
fail=0
set _ $groups; shift
g1=$1
g2=$2
mkdir d
touch f f2 d/f3
chgrp $g1 f || fail=1
chgrp $g2 f || fail=1
chgrp $g2 f2 || fail=1
(
chgrp -c $g1 f
chgrp -c $g2 f
chgrp -c $g2 f
chgrp --verbose $g1 f
chgrp --verbose $g1 f
chgrp --verbose --reference=f2 f
chgrp -R --verbose $g2 d
chgrp -R --verbose $g1 d
chgrp -R -c $g2 d
chgrp -R -c $g1 d
chgrp -c $g2 d
rm -f f
touch f
ln -s f symlink
chgrp $g1 f
chgrp $g2 symlink 2> /dev/null
# This should not change the group of f.
chgrp -c $g2 symlink 2> /dev/null
chgrp -c $g2 f
# This *should* change the group of f.
# Though note that the diagnostic is misleading in that
# it says the `group of `symlink'' has been changed.
chgrp --dereference -c $g1 symlink
) 2>&1 | sed "s/ $g1$/ G1/;s/ $g2$/ G2/" > actual
cat <<\EOF > expected
changed group of `f' to G1
changed group of `f' to G2
changed group of `f' to G1
group of `f' retained as G1
changed group of `f' to G2
changed group of `d' to G2
changed group of `d/f3' to G2
changed group of `d' to G1
changed group of `d/f3' to G1
changed group of `d' to G2
changed group of `d/f3' to G2
changed group of `d' to G1
changed group of `d/f3' to G1
changed group of `d' to G2
changed group of `f' to G2
changed group of `symlink' to G1
EOF
cmp expected actual \
|| { diff -u expected actual 1>&2; fail=1; }
(exit $fail); exit

67
tests/chgrp/deref Executable file
View File

@@ -0,0 +1,67 @@
#!/bin/sh
# see if chgrp can change the group of a symlink
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../group-names
pwd=`pwd`
tmp=slink.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
set _ $groups; shift
g1=$1
g2=$2
touch f
ln -s f symlink
chgrp $g2 symlink 2> /dev/null
set _ `ls -l symlink`
g=$5
test "$g" = $g2 || {
cat <<EOF 1>&2
$0: skipping this test; your system doesn't support changing
the owner or group of a symbolic link.
EOF
(exit 77); exit
}
fail=0
chgrp $g1 f
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
chgrp $g2 symlink || fail=1
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
# This should not change the group of f.
chgrp $g2 symlink || fail=1
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
chgrp $g2 f
set _ `ls -l f`; g=$5; test "$g" = $g2 || fail=1
# This *should* change the group of f.
# Though note that the diagnostic you'd get with -c is misleading in that
# it says the `group of `symlink'' has been changed.
chgrp --dereference $g1 symlink
set _ `ls -l f`; g=$5; test "$g" = $g1 || fail=1
set _ `ls -l symlink`; g=$5; test "$g" = $g2 || fail=1
(exit $fail); exit

47
tests/chgrp/recurse Executable file
View File

@@ -0,0 +1,47 @@
#!/bin/sh
# make sure chgrp handles --recursive w/symlinks
if test "$VERBOSE" = yes; then
set -x
chgrp --version
fi
. $srcdir/../group-names
pwd=`pwd`
tmp=slink.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
framework_failure=0
mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi
set _ $groups; shift
g1=$1
g2=$2
fail=0
# chgrp -R should not traverse a symlink to a directory.
mkdir d e
touch e/f
ln -s ../e d/s
chgrp -R $g1 e/f || fail=1
# Neither of the following should change the group of e/f
chgrp -R $g2 d
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
chgrp --deref -R $g2 d
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
# Even when the symlink-to-directory is a command line argument, it should
# not be traversed. So this shouldn't change the group of e/f either.
chgrp --deref -R $g2 d/s || fail=1
set _ `ls -l e/f`; g=$5; test "$g" = $g1 || fail=1
(exit $fail); exit

19
tests/group-names Normal file
View File

@@ -0,0 +1,19 @@
# -*- sh -*-
# Set `groups' to a space-separated list of at least two groups of which
# the user is a member.
groups=${FETISH_GROUPS-`id -nG 2>/dev/null`}
case "$groups" in
*' '*) ;;
*) cat <<EOF 1>&2
$0: this test requires that you be a member of more than one group,
but running \`id -nG' either failed or found just one. If you really
are a member of at least two group, then rerun this test with FETISH_GROUPS
set in your environment to the space-separated list of names. E.g.,
env FETISH_GROUPS='users cdrom' make check
EOF
(exit 77); exit
;;
esac

View File

@@ -50,9 +50,9 @@ test -d $dir && fail=1
ls $other_partition_tmpdir/$null > /dev/null || fail=1
test -d $other_partition_tmpdir/$dir/a/b/c || fail=1
sed "s,$other_partition_tmpdir,XXX," out > out2
sed "s,$other_partition_tmpdir,XXX," out | sort > out2
cat > exp <<EOF
cat <<EOF | sort > exp
\`$null' -> \`XXX/$null'
removing \`$null'
\`$dir' -> \`XXX/$dir'

View File

@@ -6,6 +6,9 @@ if test "$VERBOSE" = yes; then
FIXME --version
fi
# FIXME: . $srcdir/../envvar-check
# FIXME: . $srcdir/../lang-default
pwd=`pwd`
tmp=FIXME.$$
trap 'status=$?; cd $pwd; rm -rf $tmp && exit $status' 0
@@ -16,7 +19,7 @@ mkdir $tmp || framework_failure=1
cd $tmp || framework_failure=1
if test $framework_failure = 1; then
echo 'failure in testing framework'
echo 'failure in testing framework' 1>&2
(exit 1); exit
fi

View File

@@ -126,7 +126,7 @@ TESTS_ENVIRONMENT = \
PROG=tail
TESTS = assert
TESTS = assert assert-2
subdir = tests/tail-2
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h