Compare commits

...

1045 Commits

Author SHA1 Message Date
Jim Meyering
c4176dd559 . 1995-11-03 20:03:44 +00:00
Jim Meyering
47d5042d1e . 1995-11-03 20:03:18 +00:00
Jim Meyering
6df632b672 New version from glibc. 1995-11-03 20:02:00 +00:00
Jim Meyering
6875b205d6 (remove_file, remove_dir): Use euidaccess instead of euidaccess_stat.Likewise. 1995-11-03 20:01:13 +00:00
Jim Meyering
47306242ec (do_move): Use euidaccess instead of euidaccess_stat.Likewise. 1995-11-03 20:00:24 +00:00
Jim Meyering
83780d95f0 (copy): Use euidaccess instead of euidaccess_stat. 1995-11-03 19:59:44 +00:00
Jim Meyering
5b804afa6a New version from glibc. 1995-11-03 19:56:08 +00:00
Jim Meyering
83b9d5e9ef Add `const' attribute to some parameters. 1995-11-02 17:11:51 +00:00
Jim Meyering
a2b0b9846d . 1995-11-02 17:11:17 +00:00
Jim Meyering
a0ad16498b . 1995-11-02 17:11:04 +00:00
Jim Meyering
aa084c8407 Protoize. 1995-11-02 17:08:24 +00:00
Jim Meyering
ac821ab1ef Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-11-02 17:06:52 +00:00
Jim Meyering
6e146d4216 (isdigits, convint): Remove these.
(main): Use xstrtol instead.
1995-10-31 12:52:29 +00:00
Jim Meyering
e4a96fff58 . 1995-10-31 12:52:14 +00:00
Jim Meyering
aa6cde5ca1 Add `const' attribute to some parameters. 1995-10-31 12:39:18 +00:00
Jim Meyering
05a5e42609 protoize. 1995-10-31 12:36:43 +00:00
Jim Meyering
11a013bf87 Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-31 12:34:48 +00:00
Jim Meyering
de4de17bc5 (usage, next_line_num, main): Protoize. 1995-10-31 02:22:23 +00:00
Jim Meyering
b0302bb3a6 Add `const' attribute to some parameters. 1995-10-31 02:21:37 +00:00
Jim Meyering
334f8dcbb7 Add `const' attribute to some parameters. 1995-10-31 02:21:13 +00:00
Jim Meyering
47eaf4a1e8 Protoize. 1995-10-30 21:01:35 +00:00
Jim Meyering
1e30b2f8c4 Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-30 21:00:36 +00:00
Jim Meyering
84df8be864 (eaccess_stat): Make static. 1995-10-30 18:00:05 +00:00
Jim Meyering
f05befc26c (copy): Update one of the calls to eaccess_stat to use 3 arguments. Ugh! 1995-10-30 17:53:48 +00:00
Jim Meyering
96e22ecc78 . 1995-10-29 20:44:54 +00:00
Jim Meyering
9eb195d6a5 . 1995-10-29 20:44:14 +00:00
Jim Meyering
40f0f4d2e8 (xwrite): Give output buffer parameter const attribute.
(output): Likewise for both parameters.
(tac): Likewise for file name parameter.
(tac_file): Likewise.
1995-10-29 20:38:01 +00:00
Jim Meyering
4fa07774d6 protoize. 1995-10-29 20:35:11 +00:00
Jim Meyering
7567c84e76 Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-29 20:33:04 +00:00
Jim Meyering
a87c771012 (bsd_sum_file): Give file name parameter const attribute.
(sysv_sum_file): Likewise.
1995-10-29 20:24:53 +00:00
Jim Meyering
a2535fc95f Protoize. 1995-10-29 20:20:08 +00:00
Jim Meyering
d2aaf842b4 (main): Move function body to end of file.
Remove forward dcls.
1995-10-29 20:19:26 +00:00
Jim Meyering
13e93efe91 (nl_file): Give parameter const attribute.
Protoize.
1995-10-29 20:15:54 +00:00
Jim Meyering
af1033c63c Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-29 20:12:32 +00:00
Jim Meyering
768f92072f (main): Move function body to end of file.
Remove forward dcls and protoize.
1995-10-29 20:05:29 +00:00
Jim Meyering
8b92864e1d Rename --file to --reference.
Leave --file as an alias, for now.  It will be removed later.
(usage): Update, but don't mention --file.
1995-10-29 19:29:19 +00:00
Jim Meyering
d97d668b69 . 1995-10-29 19:28:59 +00:00
Jim Meyering
5d1c0a2af5 . 1995-10-29 19:21:08 +00:00
Jim Meyering
b1c9ce6621 [TEST_STANDALONE]: Define. 1995-10-29 19:20:36 +00:00
Jim Meyering
aec547d764 . 1995-10-29 19:20:12 +00:00
Jim Meyering
185c59d3bd (mostlyclean): Remove *.info. 1995-10-29 14:26:48 +00:00
Jim Meyering
f1c5cfd5f2 (distclean): Remove .deps. 1995-10-29 14:23:11 +00:00
Jim Meyering
c848009e29 . 1995-10-29 14:22:15 +00:00
Jim Meyering
a0d766c204 . 1995-10-29 14:20:13 +00:00
Jim Meyering
c1f248d670 (INCLUDE, COMPILE): New variables.
(.c.o): Rewrite to be more like src/Makefile.in.
Add line that (--with-autodeps) will include mkdep-Makefile.
1995-10-29 12:14:37 +00:00
Jim Meyering
9b1d63b4a3 . 1995-10-28 21:07:18 +00:00
Jim Meyering
c7262bbe86 *** empty log message *** 1995-10-28 21:04:08 +00:00
Jim Meyering
008028896b . 1995-10-28 21:02:57 +00:00
Jim Meyering
c5716550a6 (md5_check): Use the same message format when the single file has a
read error or checksum mismatch as when there are more.
Write diagnostic to stderr, not stdout.
1995-10-28 21:01:01 +00:00
Jim Meyering
b43f5fb25b . 1995-10-28 05:55:34 +00:00
Jim Meyering
013277d331 New option --reference=FILE (-r FILE) analogous to the
like-named touch option.
(main): Recognize it and give diagnostic for misuse.
(usage): Describe briefly.
From Franc,ois Pinard.

(batch_convert): Close input stream also when it's not stdin.
(main): Reorganize to do option-consistency checks before all else.
1995-10-28 05:52:24 +00:00
Jim Meyering
09eedba01f . 1995-10-28 05:51:44 +00:00
Jim Meyering
ca59b76b50 (batch_convert): Close input stream also when it's not stdin. 1995-10-27 15:12:31 +00:00
Jim Meyering
b9485b8d52 (main): Use xfopen, not xtmpopen to open final output file. 1995-10-26 13:20:25 +00:00
Jim Meyering
66b9285a6f (xtmpfopen): New function -- for opening temp files.
Use it instead of xfopen.
1995-10-26 13:19:10 +00:00
Jim Meyering
470e773e76 . 1995-10-26 05:14:53 +00:00
Jim Meyering
039942bfc1 (xfopen): Rewrite using open/fdopen in order to set
proper permissions on temporary files.  Reported by Erik Corry
(erik@kroete2.freinet.de).
1995-10-26 05:14:41 +00:00
Jim Meyering
a94e341d85 . 1995-10-24 04:24:06 +00:00
Jim Meyering
db98ca11cf . 1995-10-24 04:17:33 +00:00
Jim Meyering
22a5274de9 . 1995-10-21 12:52:05 +00:00
Jim Meyering
2ee6cf8ea0 . 1995-10-21 12:50:56 +00:00
Jim Meyering
baf81e4974 . 1995-10-20 04:29:00 +00:00
Jim Meyering
bda4a5e5b7 (BEGIN_STATE): Use INT_MAX - 1 so as not to interfere with large repeat counts.
(struct E_string): New struct.

(find_closing_delim): Take E_string arg rather than char* and length.
(find_bracketed_repeat): Likewise.
(star_digits_closebracket): New function.

(append_char_class): No longer give diagnostic.
(append_equiv_class): No longer give diagnostic.
(build_spec_list): Give them here instead, allowing things like [:*][:upper:]
that got errors before.
Take E_string arg rather than char*.
Convert switch stmts into if-then so as to use ES_MATCH.
1995-10-20 04:26:56 +00:00
Jim Meyering
0598102472 . 1995-10-19 22:40:10 +00:00
Jim Meyering
4aba8a55f2 . 1995-10-19 22:39:16 +00:00
Jim Meyering
6f6a35a9a1 Indent cpp directives. 1995-10-19 22:38:39 +00:00
Jim Meyering
d691ea7ebc (build_spec_list): Propagate interface change.
(parse_str): Likewise.
1995-10-19 15:42:45 +00:00
Jim Meyering
ca63ca90ab (struct E_string): Define.
(unquote): Convert string to E_string instead of overwriting input.
Backslash-escaped non-special characters are marked as quoted in E_string.
(build_spec_list): Convert outer switch stmt to an if-stmt.
(parse_str): Update sole caller of unquote.
1995-10-19 15:33:33 +00:00
Jim Meyering
43dd57eba9 New version from FSF. 1995-10-19 14:21:35 +00:00
Jim Meyering
6dd358e12d Break lines longer than 79-80 chars. 1995-10-19 13:29:34 +00:00
Jim Meyering
c73aa6b629 . 1995-10-19 04:10:45 +00:00
Jim Meyering
63b348b3a9 Use HAVE_SYS_WAIT_H, not _POSIX_VERSION in conditional
inclusion of sys/wait.h.
[endgrent]: Test !HAVE_ENDGRENT rather than _POSIX_SOURCE.
[endpwent]: Test !HAVE_ENDPWENT rather than _POSIX_SOURCE.
1995-10-18 22:05:29 +00:00
Jim Meyering
6181f175e3 Use HAVE_SYS_IOCTL_H, rather than !_POSIX_SOURCE || _AIX. 1995-10-18 22:05:06 +00:00
Jim Meyering
5a52e61271 (duplicate_entry): Always return 0 if !D_INO_IN_DIRENT, rather than
if _POSIX_SOURCE
1995-10-18 17:02:07 +00:00
Jim Meyering
e74c290ac7 . 1995-10-18 16:33:52 +00:00
Jim Meyering
5ea57c875d . 1995-10-18 16:28:14 +00:00
Jim Meyering
492b177ca5 (main): Fail if the same file system type was both selected and excluded. 1995-10-18 16:11:58 +00:00
Jim Meyering
daa976fff6 [endgrent]: Test !HAVE_ENDGRENT rather than _POSIX_SOURCE. 1995-10-18 16:08:13 +00:00
Jim Meyering
871d176f15 [endpwent]: Test !HAVE_ENDPWENT rather than _POSIX_SOURCE.
[endgrent]: Remove unused definition.
1995-10-18 16:07:44 +00:00
Jim Meyering
fc2e23b1ad [HAVE_ENDGRENT]: Define away endgrent.
[HAVE_ENDPWENT]: Define away endpwent.
1995-10-18 15:59:12 +00:00
Jim Meyering
1cde2ceb5c Use _POSIX_VERSION, not _POSIX_SOURCE. 1995-10-18 15:57:50 +00:00
Jim Meyering
539457f1ae Merge latest change from FSF. 1995-10-18 14:31:14 +00:00
Jim Meyering
b6ff24fb7f Get latest from FSF. 1995-10-18 14:29:16 +00:00
Jim Meyering
da20dc044a . 1995-10-18 03:48:29 +00:00
Jim Meyering
a42c7fe2d1 Prootize. 1995-10-18 03:45:44 +00:00
Jim Meyering
b792f7aa0e Add `const' attribute to dcls of lots of formals. 1995-10-17 14:01:00 +00:00
Jim Meyering
9242af95a3 Protoize. 1995-10-17 13:49:32 +00:00
Jim Meyering
9583179c1b Protoize. 1995-10-17 13:47:48 +00:00
Jim Meyering
d9dee002e6 Reorder functions to obviate forward dcls. Remove forward dcls. 1995-10-17 13:43:00 +00:00
Jim Meyering
434b809272 Reorder functions to obviate forward dcls. Remove forward dcls. 1995-10-17 13:39:44 +00:00
Jim Meyering
4feb3b1e06 Protoize. Reorder functions to obviate forward dcls. Remove forward dcls. 1995-10-17 13:35:26 +00:00
Jim Meyering
14390d1fed Protoize. Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-17 13:13:19 +00:00
Jim Meyering
8831ffbec4 Protoize.
Reorder functions to obviate forward dcls.
Remove forward dcls.
1995-10-16 21:30:25 +00:00
Jim Meyering
45d4def5e4 Move struct dcls to precede dcls of file-scope variables.
(monthtab, keyhead): Separate variable dcls from type dcls.
1995-10-16 14:45:09 +00:00
Jim Meyering
b9c1393e5f (usage): Move function definition to precede uses and
remove remove forward dcl.
Protoize and add `const' attribute to dcls of lots of formals.
1995-10-16 14:38:11 +00:00
Jim Meyering
c5bf4b6c9c . 1995-10-14 01:39:01 +00:00
Jim Meyering
3ac64eda17 (prjoin): Handle case in which file spec is 0.
(add_field): Update assertions.
(decode_field_spec): For S == "0", set file spec to zero and don't modify
*FIELD_INDEX.  Otherwise, *FIELD_INDEX gets the zero-based index.
1995-10-13 17:22:58 +00:00
Jim Meyering
148f37c34e Add tests to exercize -o 0. 1995-10-13 17:16:48 +00:00
Jim Meyering
9845d179b3 (prjoin): Rewrite loop that iterates over field specs. 1995-10-13 13:16:34 +00:00
Jim Meyering
11b87d29cc (add_field_list): Allow SPACE and TAB as well as `,' as list item separators. 1995-10-12 21:42:52 +00:00
Jim Meyering
bc7210e563 Remove bogus FIXME. 1995-10-12 04:08:35 +00:00
Jim Meyering
e1ab53f969 . 1995-10-09 13:59:55 +00:00
Jim Meyering
790196a645 . 1995-10-09 13:59:25 +00:00
Jim Meyering
b5c8c81d4d Indent cpp directives to reflect nesting. 1995-10-09 03:48:08 +00:00
Jim Meyering
91a709b210 Modified from glibc copy. 1995-10-09 03:46:41 +00:00
Jim Meyering
5e25ee19e4 (SOURCES): Add strpbrk.c..
Remove bcopy.c.
1995-10-09 03:42:21 +00:00
Jim Meyering
70390f60ec . 1995-10-09 03:42:11 +00:00
Jim Meyering
c22889019c . 1995-10-08 04:02:09 +00:00
Jim Meyering
06ea91f2f3 (main): Close input files. 1995-10-08 04:02:00 +00:00
Jim Meyering
3c7699600f Add alloca junk. 1995-10-08 03:38:09 +00:00
Jim Meyering
c8c90bb532 . 1995-10-08 03:30:22 +00:00
Jim Meyering
6f63d53e1b (add_field): No longer return a value.
(decode_field_spec): New function.
(add_field_list): Rewrite to be more strict about what is accepted.
Before, `,1.2' was accepted as valid.
(main): Use xstrtol instead atoi.
Combine nearly identical -a and -v cases.
1995-10-08 03:28:21 +00:00
Jim Meyering
cd1dbbcfc1 . 1995-10-06 19:23:31 +00:00
Jim Meyering
4bbadbb14a . 1995-10-06 02:55:44 +00:00
Jim Meyering
cc61df7131 Include limits.h.
[!INT_MAX]: Define it.
1995-10-06 02:55:14 +00:00
Jim Meyering
965c0bf39d [!HAVE_UTIME_H]: Don't declare struct utimbuf here.
[!HAVE_STRUCT_UTIMBUF]: Declare struct utimbuf here instead.
1995-10-06 02:53:42 +00:00
Jim Meyering
6fc3c211ec . 1995-10-06 02:51:04 +00:00
Jim Meyering
c25dcdd843 (read_filesystem_list): Cast -1 to dev_t before assignment. 1995-10-05 14:14:45 +00:00
Jim Meyering
e387fd1471 (show_point): Cast -2 to dev_t before assignment. 1995-10-05 14:12:29 +00:00
Jim Meyering
1c7bc6028a protoize 1995-10-04 21:21:23 +00:00
Jim Meyering
74f061de82 Remove forward dcl of usage. 1995-10-04 21:20:40 +00:00
Jim Meyering
47b91b8948 (usage): Move to precede all other functions. 1995-10-04 21:19:28 +00:00
Jim Meyering
2d73c959cc (main): Report `too few/many non-option arguments' then print --help
output rather than just the latter.
Properly interpret obsolescent usage like `join -o 2.1 2.1 2.2'.
(usage): Describe POSIX -1, -2 options and deprecate -j* ones
1995-10-04 21:17:43 +00:00
Jim Meyering
9a17340b10 . 1995-10-04 03:46:43 +00:00
Jim Meyering
a9de4d485a Test SA_INTERRUPT, not _POSIX_VERSION,
to determine whether `sigaction' functions are available.
Reported by Paul Nevai <nevai@ops.mps.ohio-state.edu>.
Fix suggested by Karl Berry.
1995-10-04 03:46:35 +00:00
Jim Meyering
111cb717e8 (set_fields): Use memset (not open coded loop) to initialize array. 1995-10-03 20:28:44 +00:00
Jim Meyering
6a45f61547 Convert a lot of int' types to unsigned int' to avoid warnings from
`gcc -Wall' about comparing signed and unsigned types.
1995-10-03 20:21:32 +00:00
Jim Meyering
026d10d369 (main): Declare counter, N_STRINGS, to be an integral type, not `char'. 1995-10-03 20:18:39 +00:00
Jim Meyering
d832bf77eb Correct typos, mostly from Jens Schweikhardt. 1995-10-03 19:05:47 +00:00
Jim Meyering
de97a7099c .c 1995-10-01 22:50:25 +00:00
Jim Meyering
1d15980fb6 Remove trailing whitespace. 1995-10-01 22:49:07 +00:00
Jim Meyering
b3303ba072 Declare stat, xstat. 1995-10-01 22:40:11 +00:00
Jim Meyering
eddb25aa26 Declare stat, xstat. 1995-10-01 20:17:25 +00:00
Jim Meyering
40c6966137 (SOURCES): Add strtoul. 1995-10-01 19:02:29 +00:00
Jim Meyering
4de6eab547 (get_fs_usage) [STATFS_TRUNCATES_BLOCK_COUNTS]: Copy untruncated block
counts from f_spare array into proper members of struct statfs.
From Eirik Fuller (eirik@netapp.com);
1995-10-01 18:23:29 +00:00
Jim Meyering
caa2df2274 . 1995-09-29 04:50:31 +00:00
Jim Meyering
4c8c0b69ba . 1995-09-29 04:49:08 +00:00
Jim Meyering
527d04d44b (dired_dump_obstack): Don't generate any output if the obstack is empty.
(main): Always initialize and dump subdired_obstack, not just if -R.
`ls -lDR dir dir2' was using uninitialized subdired_obstack.
Reported by Samuli K{rkk{inen <hskarkka@snakemail.hut.fi>.
1995-09-29 04:09:22 +00:00
Jim Meyering
9a12d05216 (decode_one_format): Remove spurious semicolon. 1995-09-27 15:58:18 +00:00
Jim Meyering
77c46a6b42 . 1995-09-27 04:06:28 +00:00
Jim Meyering
744393f0f4 (show_point): Ignore mtab entries with either
nonexistent mount points or with inconsistent device number.
From Eirik Fuller <eirik@synopsys.com>.
1995-09-26 04:18:55 +00:00
Jim Meyering
6f200d7982 . 1995-09-25 04:14:36 +00:00
Jim Meyering
12e85d31e2 Protoize. 1995-09-24 13:36:13 +00:00
Jim Meyering
17821cc15e [REL_ALLOC]: #ifdef-out dcls of unused variables. 1995-09-23 20:55:02 +00:00
Jim Meyering
0bcd6e68a9 . 1995-09-23 20:46:22 +00:00
Jim Meyering
528390fa58 (print_kth): Change order of args in compare, and reverse sense of comparison
(Hence, no semantic change).
1995-09-23 20:42:52 +00:00
Jim Meyering
a719a87508 Merge in changes for ConvexOS 11.0. 1995-09-23 20:28:39 +00:00
Jim Meyering
a1fa4eff25 New version from FSF. 1995-09-23 20:28:10 +00:00
Jim Meyering
f344b7fab6 (md5_check): Distinguish between open/read failure and checksum mismatch. 1995-09-23 20:22:05 +00:00
Jim Meyering
eca98f76ac . 1995-09-23 20:21:22 +00:00
Jim Meyering
f30618bac7 . 1995-09-23 20:09:52 +00:00
Jim Meyering
dc4a18b537 . 1995-09-23 19:56:32 +00:00
Jim Meyering
9801e9cde1 Update to reflect changes in md5sum.c.
Add FIXME with Karl's comm suggestion.
1995-09-21 18:17:14 +00:00
Jim Meyering
1b16c152bd (main): Reverse order of check' and compute sums' blocks in if-else
chain to make it a little more readable.
1995-09-20 12:47:37 +00:00
Jim Meyering
3ed71a2fdd . 1995-09-19 14:30:59 +00:00
Jim Meyering
0e15d57a89 Rewrite confusing comment. 1995-09-19 12:59:49 +00:00
Jim Meyering
c253d247ca (checkfp): Rearrange loop to avoid duplicate test.
Move a couple dcls from function scope into inner block.
1995-09-19 12:50:34 +00:00
Jim Meyering
656fac3d80 . 1995-09-19 12:48:46 +00:00
Jim Meyering
dde2c138e9 Protoize. 1995-09-18 12:44:47 +00:00
Jim Meyering
7823351d6b (main, usage): Remove -h, -s, -v short options.
Rename --verbose to --warn, --quiet to --status.
(main): Handle --help and --version using parse_long_options.
(md5_check): Check ferror.
1995-09-18 12:36:12 +00:00
Jim Meyering
b23b6bbcf7 (tempname): Replace `16' with a more readable expansion.
Make sure that SEQ never exceeds 99999.
1995-09-14 13:31:52 +00:00
Jim Meyering
800e219a2d (sort): Rename local: ntemp -> n_temp_files, to avoid confusion
with another local, ntmp.
1995-09-14 13:09:27 +00:00
Jim Meyering
ecf0d31b72 Fix typo in comment. 1995-09-13 13:15:35 +00:00
Jim Meyering
c3f476d467 . 1995-08-11 06:26:39 +00:00
Jim Meyering
7f3e86b27b . 1995-08-11 06:26:12 +00:00
Jim Meyering
b0453a43c0 (main) [handling --string option]: Don't output nonstandard `b' binary flag. 1995-08-10 21:11:24 +00:00
Jim Meyering
b30b152bb7 . 1995-08-09 05:33:24 +00:00
Jim Meyering
a030007908 (my_strtol): Remove function.
(main): Use xstrtol instead.
1995-08-09 05:33:19 +00:00
Jim Meyering
10c5aeabc5 Include config.h.
Define bcopy to memcpy if possible.
1995-08-09 05:15:31 +00:00
Jim Meyering
9c5f82a7f1 Indent cpp directives. 1995-08-09 05:14:06 +00:00
Jim Meyering
7bbe6cbe82 . 1995-08-09 04:21:48 +00:00
Jim Meyering
b014a71007 (main): Fail if either --verbose or --quiet is specified
when not verifying checksums.
1995-08-09 04:21:14 +00:00
Jim Meyering
36c29006f8 . 1995-08-09 04:17:53 +00:00
Jim Meyering
59e80c1a0a . 1995-08-09 04:17:27 +00:00
Jim Meyering
e4dc3d6d36 . 1995-08-09 04:14:52 +00:00
Jim Meyering
a6fdb5b75d Include system.h. 1995-08-09 03:57:17 +00:00
Jim Meyering
26574d5284 (md5_check): Fail if no valid line is found.
Don't use the word `fail' unless there were failures --
say `all N tests passed.'
1995-08-09 02:50:09 +00:00
Jim Meyering
c02722d395 work on updating md5sum 1995-08-08 05:37:39 +00:00
Jim Meyering
b3d74743a8 . 1995-08-08 04:59:01 +00:00
Jim Meyering
f03f8dcc44 (mergefps) [lint]: Initialize SAVEALLOC to avoid spurious
compiler warning.  From Ulrich Drepper.
1995-08-08 04:58:46 +00:00
Jim Meyering
a5656326f0 (read_line) [lint]: Initialize CHARS to avoid spurious
compiler warning.  From Ulrich Drepper.
1995-08-08 04:58:23 +00:00
Jim Meyering
f0556f3517 Annotate localizable strings with _(...). From Franc,ois. 1995-08-08 04:37:34 +00:00
Jim Meyering
6b853ebe01 . 1995-08-08 04:31:02 +00:00
Jim Meyering
d0e2b9c466 Declare xmalloc, xrealloc rather than including xalloc.h. 1995-08-07 22:21:03 +00:00
Jim Meyering
a94a8dd402 . 1995-08-07 16:09:10 +00:00
Jim Meyering
7c342fe2a1 Add FIXME comments. 1995-08-07 16:07:28 +00:00
Jim Meyering
9c3f1711e2 (is_number): Rename from isnumber. 1995-08-07 16:06:43 +00:00
Jim Meyering
0347634ad3 . 1995-08-07 14:57:56 +00:00
Jim Meyering
92c50e7f52 Annotate localizable strings with _(...). From Franc,ois. 1995-08-07 14:57:29 +00:00
Jim Meyering
22ebf9c6ac Sort examples. 1995-08-06 20:02:27 +00:00
Jim Meyering
5fa76547cf . 1995-08-06 04:54:08 +00:00
Jim Meyering
e29f6ae24d . 1995-08-06 04:52:09 +00:00
Jim Meyering
00dadad79c (validate): Remove const attribute from formal #1.
It may be modified.
1995-08-05 05:09:21 +00:00
Jim Meyering
767768457c (__P): No longer define this. It's not used. 1995-08-05 04:58:31 +00:00
Jim Meyering
a468aa55b6 . 1995-08-05 04:22:16 +00:00
Jim Meyering
cbc82e5cc3 Protoize. 1995-08-05 03:36:29 +00:00
Jim Meyering
b0aa8e6985 Protoize. 1995-08-05 03:19:56 +00:00
Jim Meyering
c3f2e69471 (isnumber): Rename to is_number.
(parse_user_spec): Rename uses, too.
1995-08-05 03:13:16 +00:00
Jim Meyering
86c9719f0a . 1995-08-05 03:11:30 +00:00
Jim Meyering
be22aff966 (save_cwd, restore_cwd, free_cwd): Remove functions.
New versions have been broken out into save-cwd.c.
(du_files): Adapt to handle status code returned by new versions
of save_cwd and restore_cwd.
(count_entry): Likewise.
1995-08-05 03:10:27 +00:00
Jim Meyering
0159470d3d (decode_switches): Set SORT_TYPE. Before, ls -c was sorting
by name, rather than change time.  Reported by Ken Estes
(m-ke0082@sparky.cs.nyu.edu).
1995-08-05 03:09:41 +00:00
Jim Meyering
2adeb32b35 (SOURCES, OBJECTS, DISTFILES): Update for new files, save-cwd.[ch]. 1995-08-05 03:08:09 +00:00
Jim Meyering
351cf87351 (isnumber): Rename to is_number to avoid conflict with
FreeBSD 2.0.5 macro definition.  Reported by David O'Brien
(obrien@sea.legent.com).
1995-08-05 03:06:41 +00:00
Jim Meyering
3139de9726 . 1995-08-04 15:23:25 +00:00
Jim Meyering
b4a47508d4 (SOURCES, OBJECTS, DISTFILES): Update for new files. 1995-08-04 15:15:24 +00:00
Jim Meyering
f7860d6172 . 1995-08-04 15:09:12 +00:00
Jim Meyering
f6b3413fcc (_getopt_internal) [lint]: Initialize INDFOUND to
avoid warning from gcc.
1995-08-04 14:30:19 +00:00
Jim Meyering
e799d19df8 . 1995-08-03 16:44:17 +00:00
Jim Meyering
b1ab76f3e4 . 1995-08-02 04:26:31 +00:00
Jim Meyering
ccb00b7ef9 . 1995-07-30 23:58:28 +00:00
Jim Meyering
ac37278a41 . 1995-07-30 23:58:06 +00:00
Jim Meyering
fc88df7458 (md5_check): Use getline instead of fgets. 1995-07-30 23:57:03 +00:00
Jim Meyering
11ec25d3ce New version -- now derived from the line in libc. 1995-07-30 18:42:09 +00:00
Jim Meyering
4aa1e2f2e8 Get new copy from FSF. 1995-07-30 05:30:04 +00:00
Jim Meyering
ea4cda6907 [memcpy]: Define to bcopy if needed.
(md5_buffer): Explicitely cast SWAP expressions to unsigned
to avoid warning.
1995-07-30 05:12:30 +00:00
Jim Meyering
ba477b681a Add parens to clarify ?: expression. 1995-07-30 05:03:26 +00:00
Jim Meyering
f2fc6e4cad (check): Print `disorder on...' message on standard error, not stdout.
This is a minor concession to POSIX which says `no output shall be produced'.
(main): Fix -k so it works. -k 2,3 was being treated like -k 2.
Reported by Marcus Daniels <marcus@sysc.pdx.edu>.
1995-07-30 05:02:37 +00:00
Jim Meyering
6473e3638f . 1995-07-27 20:22:29 +00:00
Jim Meyering
7e93c0f64b Initial revision 1995-07-27 14:43:01 +00:00
Jim Meyering
1126d3b93e remove trailing blanks 1995-07-27 14:15:09 +00:00
Jim Meyering
c02e97e2c5 . 1995-07-27 04:04:18 +00:00
Jim Meyering
f7ccdd300d . 1995-07-27 03:57:20 +00:00
Jim Meyering
8904d4a45c Remove spurious space. 1995-07-27 03:57:10 +00:00
Jim Meyering
8c17f50aea (tail_bytes) [from_start]: For regular files, seek
relative to the initial input file pointer position, not
necessarily from the beginning of the file.
[!from_start]: Don't back up past the initial position of the
input file pointer.
(tail_lines): Call file_lines only if FD refers to a regular file
with its file pointer positioned at beginning of file.  Otherwise,
call pipe_lines.  This is a kludge.  Once there's a decent test
suite, fix this properly.
Before, (echo 1; echo 2) > k; sh -c 'read x; tail' < k
would output both lines of the input file even though the first had
already been read.  Reported by John Roll (john@panic.harvard.edu).
1995-07-27 03:56:35 +00:00
Jim Meyering
28e28e6d74 (have_read_stdin): New global variable.
(md5_file, md5_check): Set it.
(main): Use it.

[OPENOPTS]: Depend explicitly on BINARY.
(md5_file): Take a new parameter, MD5_RESULT, and no longer
generate output.
(md5_check): Invoke md5_file instead of calling fopen directly.
When giving a diagnostic for a line with invalid format, also report
the line number.
(main): Generate output after a successful md5_file call.
[in many places]: Upon detection of an error, rather than exiting
immediately, issue a diagnostic, note that an error occurred and
exit later.
1995-07-27 03:45:11 +00:00
Jim Meyering
7732d5d7cf (main): When too few arguments are given, don't just
issue the usage message; also report why.
1995-07-25 04:50:04 +00:00
Jim Meyering
5f33b78417 [_LIBC || STDC_HEADERS] (TOLOWER): Define to tolower. 1995-07-25 02:48:00 +00:00
Jim Meyering
6abd6fdd72 (md5_check): New function -- extracted from main. 1995-07-22 05:16:40 +00:00
Jim Meyering
0e7bce124f reformat comment 1995-07-21 06:27:39 +00:00
Jim Meyering
35eda3509e . 1995-07-21 06:23:11 +00:00
Jim Meyering
58b1195eb4 (md5_file): New function -- extracted from main.
(main): Call the new function instead of doing all that in an if stmt.
Always use "%s" format rather than raw filename as format argument
in printf-style functions like error.  Otherwise, filenames containing
e.g. `%s' lose.
Remove all traces of `old format'.  There is only one format now.
The compatible one.
1995-07-21 06:18:58 +00:00
Jim Meyering
bb79abc8a3 (md5_stream): Update prototype.
[__P]: Define macro.
1995-07-21 04:48:03 +00:00
Jim Meyering
574cc98b23 (md5_stream): Check for read failure and return
indication of success rather than second argument.
1995-07-21 04:46:50 +00:00
Jim Meyering
855741c7cb Use EXIT_FAILURE and EXIT_SUCCESS.
(main): Report an error if md5_stream fails.  Otherwise, running
`md5sum dir-on-mounted-filesystem' always reported the checksum
for an empty file.  Now it gets the `is a directory' error.
Greg McGary reported that the released version got stuck in an
infinite loop with such arguments.
1995-07-21 04:45:40 +00:00
Jim Meyering
d58bdcd4fa (split_3): Accept only old format.
Properly handle file names with leading and trailing white space.
1995-07-20 21:09:57 +00:00
Jim Meyering
1ae54a6140 more comment tweaks 1995-07-20 19:22:28 +00:00
Jim Meyering
db566dba37 Correct typo in Copyright.
Reformat paragraph so line with new FSF address fits in 80 columns.
1995-07-20 19:13:23 +00:00
Jim Meyering
3d699e8ee0 (usage): Move it to precede all other functions.
Fiddle comments.
1995-07-20 19:10:08 +00:00
Jim Meyering
e20e0ba392 New version from Drepper. 1995-07-20 19:08:08 +00:00
Jim Meyering
dfe3d8837e . 1995-07-20 17:52:49 +00:00
Jim Meyering
e59ec88ea2 . 1995-07-16 23:43:17 +00:00
Jim Meyering
66c43ec708 . 1995-07-16 23:41:17 +00:00
Jim Meyering
e692090b89 . 1995-07-16 23:39:51 +00:00
Jim Meyering
1e74962c8a Add #else block after #ifdef VMS.
(main): Rename local variable.
Add FIXME: allow newlines in filenames.
Detect and report failed fclose calls on stdout and checkfile_stream.
1995-07-16 05:47:55 +00:00
Jim Meyering
14aaf3eab3 (build_spec_list): Declare CLOSING_DELIM_IDX and CLOSING_BRACKET_IDX to
be of type size_t, not int.
(main): Declare NR and CHARS_READ to be of type long, not int.
1995-07-16 05:39:09 +00:00
Jim Meyering
adfa243b0d (unqote): Comment out unreachable break stmts.
(append_range): Declare FIRST and LAST parameters to be unsigned int,
not size_t.
(find_closing_delim): Clean up interface, separating boolean success
indicator and index.
(find_bracketed_repeat): Likewise.
(build_spec_list): Adapt to use new interfaces.
1995-07-12 03:13:40 +00:00
Jim Meyering
37ba8d9867 (main): Comment out unreachable break stmt. 1995-07-12 03:06:49 +00:00
Jim Meyering
c20ee98ac8 (dump): Convert to use smaller -- but seemingly equivalent -- patch. 1995-07-12 03:06:03 +00:00
Jim Meyering
21aa588967 Reorder functions so main is last, so no forward dcls are needed. 1995-07-12 03:01:33 +00:00
Jim Meyering
ba34723398 (tail): Explicitly cast to long the N_UNITS argumennt in
call to tail_lines.  Otherwise, NetBSD lost because N_UNITS (of type
off_t, a 64-bit type on NetBSD) wasn't converted to the target type,
long.  Reported by Dan Hagerty (hag@gnu.ai.it.edu).
1995-07-12 02:59:44 +00:00
Jim Meyering
51c3164ba3 (main): Add UCHAR casts. 1995-07-09 17:06:41 +00:00
Jim Meyering
307526e92d . 1995-07-09 16:42:40 +00:00
Jim Meyering
6dfad5e900 (main): When using obsolescent +pos -pos syntax, allow
omission of field spec only when character offset is specified.
Otherwise, -. +. would be accepted.
1995-07-09 16:42:31 +00:00
Jim Meyering
ccfb7f032d (main): Allow field spec, M, to be omitted in +M.N or -M.N
position specification.  Omitting M is equivalent to specifying `0'
for M.  From Rick Sladkey (jrs@world.std.com).
1995-07-09 02:25:11 +00:00
Jim Meyering
bb5590f7b6 . 1995-07-07 04:46:18 +00:00
Jim Meyering
67718aff76 (dump): Correct loop-termination criterion.
Before, running `printf 1234| ./od --width=4 --read-bytes=4'
printed output for 8 bytes -- the last four were garbage.
This happened only when the dump limit, N, was specified (with
--read-bytes=N) and N was a multiple of bytes_per_block
(usually 16, but 4 in this example).  From Andreas Schwab.
1995-07-07 04:46:03 +00:00
Jim Meyering
b9d3dc4101 Remove trailing white space. 1995-07-06 16:07:07 +00:00
Jim Meyering
20b6a5b40a (od): Remove space beteen -w and optional argument. 1995-07-06 16:06:32 +00:00
Jim Meyering
72d4155c90 . 1995-07-03 03:12:54 +00:00
Jim Meyering
e7c2d62889 . 1995-07-03 03:11:05 +00:00
Jim Meyering
c8e05ecd8d (split_3): Rewrite to parse Plumb/Lankester format as well.
(main): Write (de facto) standard Plumb/Lankester format.
New option: --quiet.
Check option no longer takes an argument.
When checking, exit status reflects success.
1995-07-03 03:10:59 +00:00
Jim Meyering
9c8e5123bd Remove unused dcl of isnumber. 1995-06-25 01:46:32 +00:00
Jim Meyering
9a5882ba80 (parse_group): Use xstrtoul instead of isnumber; the latter would
silently overflow, accepting a group id larger than INT_MAX.
(isnumber): Remove now-unused static function.
(change_file_group) [MAXUID]: Give a more descriptive message
when numeric group id is larger than MAXUID.
1995-06-25 01:44:35 +00:00
Jim Meyering
7981e85eb3 merge with 1.12a 1995-06-24 22:02:25 +00:00
Jim Meyering
1d7e1a535b . 1995-06-24 21:34:02 +00:00
Jim Meyering
4610e33cb2 Don't conditionalize use of "inline". Autoconf takes care of defining
it away for compilers that don't grok it.
1995-06-24 21:33:52 +00:00
Jim Meyering
9cda676546 . 1995-06-24 21:22:11 +00:00
Jim Meyering
f5ff11c61d . 1995-06-24 21:17:13 +00:00
Jim Meyering
86671a4ed0 Undefine min and/or max before defining to avoid redefinition warning
on systems.
1995-06-24 21:10:12 +00:00
Jim Meyering
5cd7a18539 (read_input): Rename paramater MAX to MAX_N_BYTES. To avoid potential
conflict with max macro from some system's header files and bad pre-ANSI
compilers.
1995-06-24 21:07:55 +00:00
Jim Meyering
4b366ceed5 [uint32]: When testing for 32-bit arithmetic type,
also check `unsigned long', as a concession to systems with
int's smaller than 32 bits.
1995-06-24 20:53:17 +00:00
Jim Meyering
eb5665733a (usage): Fix typo. 1995-06-24 20:38:52 +00:00
Jim Meyering
ec8d1fce62 (main): Include program name in --version output. 1995-06-22 18:43:14 +00:00
Jim Meyering
4afe3f334a [join]: Redefine. Otherwise, systems (Unicos for one) with
headers that have a different prototype for `join' get an error.
1995-06-22 04:03:33 +00:00
Jim Meyering
b27934a727 . 1995-06-22 04:00:26 +00:00
Jim Meyering
e7d420aabb [word]: Redefine. Otherwise, systems (Unicos for one) with
headers that define `word' to be a type get syntax errors because
of the variable by the same name.
1995-06-22 03:59:55 +00:00
Jim Meyering
3f76720636 (interrupt_handler): Declare to have a single integer
parameter.  Otherwise, some compilers failed with a type mismatch
error in sa_handler assignment.
1995-06-22 03:59:27 +00:00
Jim Meyering
3fba1e486e (main): Remove spurious colon in getopt spec string.
From Ken Pizzini <kenp@spry.com>.
1995-06-22 03:58:21 +00:00
Jim Meyering
59f93bf56c (md5_file): Initialize two elements of LEN portably,
rather than with ANSI aggregate initialization.  Reported by
Edzer Pebesma <Edzer.Pebesma@rivm.nl>.
1995-06-20 12:00:55 +00:00
Jim Meyering
6ebaf82426 merge with 1.12 1995-06-18 19:33:31 +00:00
Jim Meyering
d96ba2d153 . 1995-06-18 14:24:56 +00:00
Jim Meyering
2adaaa8521 . 1995-06-18 14:21:58 +00:00
Jim Meyering
755cdcee27 (process_buffer): Copy values from struct into
individual local variables before performing computation on them,
then copy results back into returned struct.  Solely for better
optimization by compilers that can't keep struct members in
registers.  From Ulrich Drepper.
1995-06-18 14:21:50 +00:00
Jim Meyering
643a49ea6c . 1995-06-16 04:25:05 +00:00
Jim Meyering
583e66e5b0 . 1995-06-16 04:21:08 +00:00
Jim Meyering
769f82b90b . 1995-06-16 04:15:25 +00:00
Jim Meyering
19ffe3f16e (split_3): Unprotoize.
(hex_digits): Unprotoize.
(main): Interpret `no file args' as request to read from stdin.
(usage): Reflect that change.
1995-06-16 04:13:36 +00:00
Jim Meyering
66196f8fd7 Half-assed patch from Karl -- probably need to change file name' to filename'. 1995-06-16 03:59:41 +00:00
Jim Meyering
820cd5c090 . 1995-06-16 03:26:56 +00:00
Jim Meyering
cdfc0cf26f Remove unnecessary uses of `defined' in #if* tests.
Don't use #elif.  Some older compilers don't grok it.
(split_3): New function to parse out sum, flag, and filename
when reading check file.
(hex_digits): Remove length parameter since string parameter is
now nul-terminated.
(main): Don't allocate separate arrays for filename and sum
when checking.  Get pointers into line buffer with split_3 instead
of using sscanf.
1995-06-16 03:14:19 +00:00
Jim Meyering
aab046d29b Don't include values.h.
[__P]: Undefine it.

[UNIX || unix]: Also test __UNIX__, __unix__,
and _POSIX_VERSION.  Reported by Arne H. Juul.
1995-06-15 18:44:48 +00:00
Jim Meyering
ad1b9f0851 . 1995-06-15 18:44:27 +00:00
Jim Meyering
f9f17d4b0f merge with 1.11.5b 1995-06-15 16:46:34 +00:00
Jim Meyering
33969b2c90 patch from drepper 1995-06-15 15:02:01 +00:00
Jim Meyering
88b9522242 Alloca fix for ConvexOS-11.0. 1995-06-15 14:55:26 +00:00
Jim Meyering
2907e4e4f1 Use void* alloca, not char*. The latter lost on convexOS. 1995-06-15 03:57:49 +00:00
Jim Meyering
84876e7e9e md5sum docs from Ulrich. 1995-06-15 03:43:52 +00:00
Jim Meyering
8f6e9e8827 (main): Rename char binary' to type_flag to avoid confusion with int binary'. 1995-06-15 03:18:13 +00:00
Jim Meyering
9387b92371 Don't use #elif. Some old C compilers don't recognize it.
(hex_digits): New function.
(result): Give ctx parameter the `const' attribute.
(usage): Rewrite to make it clearer that there are three modes.
(main): Process all options before generating any output.
In particular, collect all --string options rather than operating
on them as they are encountered.

Allow --check=-.  Before it tried to open the file named `-'.

Detect bogus input when --check'ing: non-hex, non-[tb] flag.

Map to lower case all hex digits read from check file.
1995-06-15 03:15:37 +00:00
Jim Meyering
a04bfe9cbf . 1995-06-14 03:44:16 +00:00
Jim Meyering
f7c77084b4 . 1995-06-14 02:24:18 +00:00
Jim Meyering
60437a80ca [NDEBUG]: Define it to disable assertions.
(is_char_class_member): Set a variable in each branch of switch stmt
and return that value after the switch (rather than returning directly
from every branch).
(unquote): More int->size_t changes.
(build_spec_list): More int->size_t changes.
Be very careful about comparison now that variables are unsigned:
Use i + 2 < len rather than i < len - 2.  The latter failed for len < 2.
1995-06-14 02:23:48 +00:00
Jim Meyering
891c9b5cc7 . 1995-06-13 04:46:19 +00:00
Jim Meyering
1aa5954b42 (xfclose): Don't try to flush stdin, only stdout.
Otherwise, at least Ultrix-4.3's fflush would return EOF.
Reported by Jim Blandy (jimb@cyclic.com).
1995-06-13 04:46:12 +00:00
Jim Meyering
46a1fec4a5 . 1995-06-13 04:33:45 +00:00
Jim Meyering
ca73f85acf [struct Spec_list] (indefinite_repeat_element): New member.
Use size_t rather than int or unsigned long where reasonable.
(get_spec_status): Make interface cleaner.
(get_s1_spec_status): New function.
(get_s2_spec_status): New function.
(validate): Use new functions.
1995-06-13 04:08:59 +00:00
Jim Meyering
da78e2df64 Indent some things.
(long_options): Add NULL entry.  From Uli.
Touch up some comments.
(process_buffer): Bracket definition of OP with do...while(0) so stmts can be
semicolon terminated.
1995-06-13 04:02:22 +00:00
Jim Meyering
bcee3d43ca (non_neg_strtol): Don't compare signed and unsigned. 1995-06-12 18:28:24 +00:00
Jim Meyering
afe762e4e6 [!__GNUC__]: Define INLINE to /* empty */. 1995-06-12 14:42:41 +00:00
Jim Meyering
5b45da2a71 . 1995-06-12 05:27:12 +00:00
Jim Meyering
bb789f462c . 1995-06-12 05:25:04 +00:00
Jim Meyering
a14d08e891 Remove now-obsolete comment and leading space. 1995-06-12 05:09:57 +00:00
Jim Meyering
81ca3a8b6c Remove now-obsolete comment and leading space. 1995-06-12 05:08:16 +00:00
Jim Meyering
fd9df74e75 . 1995-06-11 19:56:29 +00:00
Jim Meyering
c502988b26 Use invalid', not illegal' in error message. 1995-06-11 19:54:49 +00:00
Jim Meyering
1d1094a69e Remove trailing white space. 1995-06-11 19:37:03 +00:00
Jim Meyering
8ddb66cff4 [SWAP]: Parenthesize uses of macro argument.
Don't use autoconf macros that require running test programs.
1995-06-11 06:16:17 +00:00
Jim Meyering
3763a4f24e From Ulrich Drepper. 1995-06-11 06:04:15 +00:00
Jim Meyering
c3754d6f21 (look_up_char_class, append_char_class, append_equiv_class): Use const
attribute when appropriate.
1995-06-11 05:40:05 +00:00
Jim Meyering
a2e52e58b1 (Convert): Use 2037 as threshold, not 1999.
Otherwise years after 1999 are treated as invalid.
From Andreas Schwab.
1995-06-07 18:10:17 +00:00
Jim Meyering
85bf8c2e1c merge with 1.11.5 1995-06-01 14:12:51 +00:00
Jim Meyering
f97e625d3d merge with 1.11.4b 1995-05-29 05:33:13 +00:00
Jim Meyering
9584732376 (add_field_list): Compute max once for each call to add_field. 1995-05-28 20:12:24 +00:00
Jim Meyering
0a73924f60 . 1995-05-28 20:11:38 +00:00
Jim Meyering
d1a5552fbe . 1995-05-28 19:51:25 +00:00
Jim Meyering
e1c9600ae7 . 1995-05-28 19:48:40 +00:00
Jim Meyering
88daaaf385 (main): Call make_blank after *all* argument processing.
Get rid of blank1, blank2.  Just use uni_blank instead.
1995-05-28 19:46:04 +00:00
Jim Meyering
5c08b11b30 Overhaul so -a1 and -a2 (as used in cnews) work. 1995-05-28 18:01:54 +00:00
Jim Meyering
22e09d7c8e Add tests. 1995-05-28 17:58:16 +00:00
Jim Meyering
0dfe7fe96e Correct a test. 1995-05-28 15:33:00 +00:00
Jim Meyering
4657b1e9ec (main): Remove dcl of and statements that set now-unused variable. 1995-05-28 02:04:55 +00:00
Jim Meyering
4fb3e0f061 merge with 1.11.4a 1995-05-28 01:55:00 +00:00
Jim Meyering
a528bd5d9f [!STDC_HEADERS && HAVE_MEMORY_H]: Include memory.h.
Without this, SunOS doesn't get type for memchr.
Reported by Kaveh Ghazi.
1995-05-27 11:41:00 +00:00
Jim Meyering
4662661e71 . 1995-05-27 11:39:15 +00:00
Jim Meyering
4d00132265 Remove trailing white space. 1995-05-26 15:08:55 +00:00
Jim Meyering
0be7c19204 Remove trailing white space. 1995-05-26 14:15:37 +00:00
Jim Meyering
ae3864618a . 1995-05-25 05:10:03 +00:00
Jim Meyering
1bca766a5d [struct control]: Change type of `repeat' member to unsigned
long to avoid conversion warning.
1995-05-25 05:09:50 +00:00
Jim Meyering
a660862d4c (tail_lines): Change one more long' to off_t'.
Otherwise, tail didn't work on NetBSD.  From by Arne H. Juul.
1995-05-25 05:09:00 +00:00
Jim Meyering
871da9a196 merge with 1.11.3 1995-05-25 05:02:37 +00:00
Jim Meyering
e4326d5926 . 1995-05-22 04:43:42 +00:00
Jim Meyering
ec651d2263 (__strtol): Remove prototype altogether.
Move inclusion of xstrtol.h back so that it follows system headers.
1995-05-22 04:43:36 +00:00
Jim Meyering
0895e4a7c4 . 1995-05-22 04:32:53 +00:00
Jim Meyering
ee79446888 (usage): Add one or two lines of descriptive text. 1995-05-22 04:30:18 +00:00
Jim Meyering
d0da35f3d2 . 1995-05-21 18:46:56 +00:00
Jim Meyering
b8a56f0503 . 1995-05-21 18:46:33 +00:00
Jim Meyering
f001fccf74 . 1995-05-21 18:46:11 +00:00
Jim Meyering
9451f098d6 . 1995-05-21 12:32:03 +00:00
Jim Meyering
a42221d051 (install-exec, install-exec): New targets. From Karl Berry.
(maintainer-clean): Renamed from realclean per GNU Standards.
1995-05-21 12:27:45 +00:00
Jim Meyering
f76df4e179 . 1995-05-21 12:23:15 +00:00
Jim Meyering
937f55f61f merge with 1.11.2 1995-05-21 11:57:14 +00:00
Jim Meyering
7f9311c20e merge with 1.11.1b 1995-05-21 11:44:22 +00:00
Jim Meyering
37a6bc3abf merge with 1.11.1a 1995-05-20 13:28:24 +00:00
Jim Meyering
e364481ca4 . 1995-05-20 12:36:49 +00:00
Jim Meyering
4b54af76ea . 1995-05-20 12:09:05 +00:00
Jim Meyering
e8db76575a (look_up_char_class): Take a string length argument.
Use strncmp, not strcmp and verify that string lengths are the same.
(append_char_class): Update caller.
From Andreas Schwab.
1995-05-20 12:08:35 +00:00
Jim Meyering
9918713e5b (next_file_name): Move dcls of file-scope variables into this function.
Don't rely on arithmetic being two's complement.
1995-05-20 11:52:36 +00:00
Jim Meyering
4c9e84124c [CLOSED, ENDLIST]: Don't cast constants to FILE pointers.
Instead, declare two FILE structs and use their addresses.
1995-05-20 11:47:31 +00:00
Jim Meyering
0753cff4a1 (usage): Tweak wording. 1995-05-20 11:41:13 +00:00
Jim Meyering
3bfa2eb8bb Remove backquote. 1995-05-19 16:49:33 +00:00
Jim Meyering
c253f9ba51 (record_line_starts): Remove set-but-not-used, file-scope variable. 1995-05-19 15:59:40 +00:00
Jim Meyering
1fffbc7472 No longer include safe-l?stat.h. 1995-05-19 15:23:18 +00:00
Jim Meyering
a693d752bc Oops. Test $tr, not `tr' from PATH. 1995-05-18 18:20:57 +00:00
Jim Meyering
a547f02ddf Test [:lower:] to [:upper:] and vice versa. 1995-05-18 18:20:12 +00:00
Jim Meyering
c9c8ba714c Save error output in t*.err. 1995-05-16 17:19:46 +00:00
Jim Meyering
be7c86dfd2 . 1995-05-16 17:19:32 +00:00
Jim Meyering
68681fe067 Remove spurious space for missing arg2. 1995-05-16 17:14:11 +00:00
Jim Meyering
6a3f88500f Always print message at end, not just upon failure. 1995-05-16 17:13:39 +00:00
Jim Meyering
b03da97486 . 1995-05-15 16:43:39 +00:00
Jim Meyering
0dc531502b . 1995-05-15 06:00:33 +00:00
Jim Meyering
635b1b5b6e (usage): Add one- and two-line descriptions to --help output.
From Karl.
1995-05-15 04:53:56 +00:00
Jim Meyering
2c74d574d3 . 1995-05-13 18:35:36 +00:00
Jim Meyering
7cdc7a0bd9 (usage): Include one- or two-line synopsis in --help output.
From Karl Berry.
1995-05-13 18:34:54 +00:00
Jim Meyering
e8be969ec8 . 1995-05-13 14:05:46 +00:00
Jim Meyering
56c8261d7e (maintainer-clean): Rename from realclean.
(.PHONY): New dependencies.
[.c.o]: Remove -I. since safe-l?stat.h is no longer used.
1995-05-13 13:55:56 +00:00
Jim Meyering
fe6756d42e . 1995-05-13 13:39:07 +00:00
Jim Meyering
c093a8e789 (make_path): Use stat, not SAFE_STAT.
Use strchr, not index.  Adjust defines accordingly.
1995-05-13 13:30:10 +00:00
Jim Meyering
7ce06ceca7 (parse_user_spec): Use strchr, not index.
[!HAVE_STRING_H]: Define strchr in terms of index, not the other way around.
1995-05-13 13:25:42 +00:00
Jim Meyering
8a7a1fda12 (rmdir): Use stat, not safe_stat. 1995-05-13 13:20:19 +00:00
Jim Meyering
eec5824b1a (rename): Use stat, not safe_stat.
(rename): Compare src and dest inode numbers rather than src
inode and dest *dev* when determining whether src and dest refer
to the same file.  From marc@math.cornell.edu (Marc Parmet).
1995-05-13 13:19:07 +00:00
Jim Meyering
b3fc4e375f (mkdir): Use stat, not safe_stat. 1995-05-13 13:13:04 +00:00
Jim Meyering
5a69bc6e5f Undef __P before defining.
Guard definition with simpler `#if __STDC__'.
1995-05-13 13:10:38 +00:00
Jim Meyering
e8bfedbcd4 (isdir): Usage stat, not safe_stat. 1995-05-13 13:07:54 +00:00
Jim Meyering
627abb8251 (statfs): Use stat, not safe_stat. 1995-05-13 13:06:46 +00:00
Jim Meyering
4198f93479 (eaccess_stat): Make statp and path arguments const.
(euidaccess): Make statp argument const.  Use stat, not safe_stat.
1995-05-13 13:05:35 +00:00
Jim Meyering
26abb25bd0 Remove unnecessary definitions for r?index.
Update definitions for ISDIGIT.
1995-05-13 13:02:08 +00:00
Jim Meyering
d931bb8005 Remove safe-l?stat.[ch]in and related rules. 1995-05-13 12:57:46 +00:00
Jim Meyering
e5be6fdf8a (argmatch): Include sys/types.h and declare length argument with type size_t. 1995-05-13 12:55:49 +00:00
Jim Meyering
143415e6b8 (basename): Make arg const. 1995-05-13 12:52:57 +00:00
Jim Meyering
99ce9e9832 Use stat (lstat), not safe_stat (safe_lstat). 1995-05-13 12:48:33 +00:00
Jim Meyering
466ecc5db8 maintainer-clean, PHONY, ... 1995-05-13 12:22:27 +00:00
Jim Meyering
274e5f86b5 Use l?stat, not safe_l?stat. 1995-05-13 02:31:46 +00:00
Jim Meyering
31faa61270 (usage): Remove duplicate descriptions of --help and --version.
From Karl Berry.
1995-05-13 02:26:18 +00:00
Jim Meyering
7108d098ae (movefile): Remove a single trailing slash from destdir before concatenating
with `/' and filename for `ok to overwrite...' message.
1995-05-13 02:21:40 +00:00
Jim Meyering
63c91c859f Test tr in $PATH, not ./tr. 1995-05-12 02:11:06 +00:00
Jim Meyering
01eb16e339 merge with 1.11.1 1995-05-11 14:06:53 +00:00
Jim Meyering
821c7fe59e merge with 1.11.g 1995-05-10 14:22:19 +00:00
Jim Meyering
344458e890 . 1995-05-07 18:37:14 +00:00
Jim Meyering
b0aa499bb2 . 1995-05-05 14:58:59 +00:00
Jim Meyering
6ebd309cb8 (save_stdin): Don't hard-code /tmp.
[DEFAULT_TMPDIR]: Use this instead.
1995-05-05 05:09:58 +00:00
Jim Meyering
151f4af0da . 1995-05-05 05:03:56 +00:00
Jim Meyering
a5da850f3f (main): Use stat, not safe_stat. The latter was unnecessary. 1995-05-05 05:03:50 +00:00
Jim Meyering
21657d3c67 . 1995-05-05 04:37:58 +00:00
Jim Meyering
04c2f73f6f Patch from Mike to fix handling of +x.yn. 1995-05-05 04:37:21 +00:00
Jim Meyering
f45ff2cfaf Don't hard-code /tmp.
[DEFAULT_TMPDIR]: Use this instead.
1995-05-05 04:16:12 +00:00
Jim Meyering
6cd5abb0c4 . 1995-05-02 04:04:39 +00:00
Jim Meyering
70b90a6f9d (quote_filename): Never return NULL when quoting filenames
as C-strings.  --quote-name was quoting only strings containing
at least one C-quotable character.  Reported by David J. MacKenzie.
1995-05-02 04:04:32 +00:00
Jim Meyering
6d94a2954d (usage): Fix per kb's suggestions. 1995-04-30 12:57:50 +00:00
Jim Meyering
843193374f Use __-protected versions of format' and printf' only with gcc-2.7 and later. 1995-04-27 17:04:23 +00:00
Jim Meyering
732fb15b45 merge with 1.11.f 1995-04-27 06:06:46 +00:00
Jim Meyering
00c3a48bd7 (REGEX_FREE): Add back the `while (0)' hack
Put back ifdefs to protect unnecessary decl.
1995-04-27 05:23:35 +00:00
Jim Meyering
1fa0e4dfd6 Latest from RMS. 1995-04-27 04:54:07 +00:00
Jim Meyering
7008c3aa9d . 1995-04-27 04:51:57 +00:00
Jim Meyering
14755ac891 (EMACS_INT): Define it to int. (BIG KLUDGE) 1995-04-26 17:19:13 +00:00
Jim Meyering
9c5392e4af (REGEX_FREE): Define to `while (0) /* empty */' rather than nothing.
Otherwise, some uses got warnings about empty if-clause.

Declare failure_stack_ptr only #ifdef REL_ALLOC.
1995-04-26 17:18:27 +00:00
Jim Meyering
fd3bfce0cc New version from FSF. 1995-04-26 17:02:38 +00:00
Jim Meyering
a3edacb315 (tempname): AND-off high bits of pid so that its decimal
string representation is no longer than five digits.
From Hans Verkuil (hans@wyst.hobby.nl)
1995-04-26 16:12:01 +00:00
Jim Meyering
062c5a1fd0 . 1995-04-25 05:40:06 +00:00
Jim Meyering
1b51c7e73b Protect format and printf with __*__. 1995-04-24 16:25:29 +00:00
Jim Meyering
af8e117d0d Fix mostly per Franc,ois' suggestions. 1995-04-22 05:54:18 +00:00
Jim Meyering
a87015327e Update and add copyright. 1995-04-21 17:29:15 +00:00
Jim Meyering
775493dedd . 1995-04-21 06:24:54 +00:00
Jim Meyering
27f19ab42b . 1995-04-21 04:22:00 +00:00
Jim Meyering
586c892910 (add_tabstop): Give correct size when reallocating tab_list buffer.
From Geoff Odhner (geoff@franklin.com).
1995-04-21 04:12:33 +00:00
Jim Meyering
f9834f6bee . 1995-04-19 03:58:38 +00:00
Jim Meyering
5e1b1dabb2 . 1995-04-15 13:15:02 +00:00
Jim Meyering
93b95d2b78 (next_file_name): Don't reuse X as an index.
Declare new variable I instead.
1995-04-14 04:29:41 +00:00
Jim Meyering
73daf89227 (write_block): Declare index I as unsigned int, not int.
(get_lcm): Likewise.
(dump_strings): Likewise.
(main): Likewise.
(dump): Cast BYTES_PER_BLOCK to off_t in MIN expression.
(dump_strings): Declare bufsize to be of type size_t, not int.
1995-04-14 04:27:46 +00:00
Jim Meyering
9f888b86b8 Remove block of redundant comments describing options.
(usage): Remove reference to -l option.  It's not valid.
1995-04-14 04:23:22 +00:00
Jim Meyering
364c21f831 . 1995-04-04 21:19:44 +00:00
Jim Meyering
d71f5443c9 . 1995-04-03 13:53:18 +00:00
Jim Meyering
1beb8c40f3 . 1995-04-03 13:52:54 +00:00
Jim Meyering
09dec6f72f (fold_file): Declare offset_out size_t. 1995-03-25 21:09:34 +00:00
Jim Meyering
42357adff5 (set_fields): Declare index unsigned. 1995-03-25 21:08:36 +00:00
Jim Meyering
ebaf614a13 Declare as unsigned int' all variables that were just unsigned'.
(make_filename): Change type of arg to unsigned int.
(split_file): Change type of indices to unsigned int.
1995-03-24 23:40:41 +00:00
Jim Meyering
80fab638f1 merge with 1.11.e 1995-03-21 03:50:10 +00:00
Jim Meyering
5ddea12690 . 1995-03-21 03:45:22 +00:00
Jim Meyering
107da866a6 (usage): Add ellipsis after `[OPTION]'.
Use FILE, not deprecated PATH.  From Karl Berry.
1995-03-21 03:45:15 +00:00
Jim Meyering
88650610c1 . 1995-03-21 01:58:18 +00:00
Jim Meyering
c70ee3bf4a merge with 1.11.d 1995-03-21 01:43:35 +00:00
Jim Meyering
429a8df30a . 1995-03-20 15:10:37 +00:00
Jim Meyering
f371bb0b80 sync from FSF 1995-03-20 15:09:56 +00:00
Jim Meyering
4b72e436e6 . 1995-03-20 14:26:41 +00:00
Jim Meyering
6ac40b721e version.texi: Put only version number in VERSION definition. 1995-03-17 04:07:19 +00:00
Jim Meyering
16c1678f6d . 1995-03-17 04:05:46 +00:00
Jim Meyering
b94687cecb Detect when -N argument is too large to fit in an off_t. 1995-03-16 21:54:02 +00:00
Jim Meyering
4976b0c0c2 . 1995-03-12 18:31:55 +00:00
Jim Meyering
cb715fe584 . 1995-03-12 18:21:38 +00:00
Jim Meyering
858157b65b . 1995-03-12 18:12:18 +00:00
Jim Meyering
f8b678f7c8 Better but-reporting instructions.
wc tweak: lines->newlines.
1995-03-12 18:07:15 +00:00
Jim Meyering
e71dcd4c81 Undef __P before defining it. 1995-03-12 18:06:08 +00:00
Jim Meyering
ae50e4b6fc . 1995-03-12 18:00:33 +00:00
Jim Meyering
91f5d65874 Make source const. 1995-03-12 15:26:36 +00:00
Jim Meyering
e677aefec1 Update from glibc. 1995-03-12 15:26:09 +00:00
Jim Meyering
1423198343 add 1995 to Copyright dates 1995-03-10 04:15:06 +00:00
Jim Meyering
0d6850348c add 1995 to Copyright dates 1995-03-09 22:33:05 +00:00
Jim Meyering
eba8aab7f2 add 1995 to Copyright dates 1995-03-09 22:20:59 +00:00
Jim Meyering
c2c77cdc0f . 1995-03-06 14:20:34 +00:00
Jim Meyering
d307cc738a from Karl Berry 1995-03-06 14:11:41 +00:00
Jim Meyering
6e811f30ac (SET_REGS_MATCHED): Enclose if-stmt in `do {...} while(0)'
instead of using trailing `else' -- otherwise, gcc -Wall complains
of `empty body in an else-statement'.
1995-02-28 13:54:33 +00:00
Jim Meyering
40f6e92067 (wc): oops. Add missing dcl of stats. 1995-02-28 12:50:35 +00:00
Jim Meyering
b53cae8492 Always include system headers, but define-away any putenv prototype. 1995-02-28 12:08:03 +00:00
Jim Meyering
861ff7f26c Remove sys-dependent cruft and define-away getopt in system headers
instead.
1995-02-28 12:06:57 +00:00
Jim Meyering
9ac5e4ef97 (color_indicator[0]): Add missing `['. 1995-02-27 16:37:54 +00:00
Jim Meyering
2b4f9ff609 . 1995-02-27 14:54:45 +00:00
Jim Meyering
7cdef7f19f . 1995-02-27 14:51:30 +00:00
Jim Meyering
e9c2895a55 (userid_compare): K&R'ify function definition. 1995-02-27 14:47:40 +00:00
Jim Meyering
30d09ddbed (correct_password): Use memset instead of bzero. 1995-02-27 14:09:10 +00:00
Jim Meyering
617dbb12c2 (main, set_window_size): Use memset instead of bzero. 1995-02-27 14:07:58 +00:00
Jim Meyering
5d49fcbeaa Remove \n's from error format strings.
(main): Let `seq 1 1' work.
Invoke usage always with 1 when failing.
1995-02-27 14:05:43 +00:00
Jim Meyering
788bd6716f (docolon): Use memset instead of bzero. 1995-02-27 06:01:27 +00:00
Jim Meyering
829c226954 (batch_convert): Remove any trailing newline from offending
line before including it in the `invalid date' error from `date -f'.
Reported by Franc,ois Pinard.
1995-02-27 06:00:14 +00:00
Jim Meyering
06b585059b (wc): Put back test for S_ISREG. On some systems lseek returns zero for
non-regular files (esp ttys on SunOS) even when it fails.
1995-02-27 00:07:35 +00:00
Jim Meyering
0988b76df5 . 1995-02-26 19:05:34 +00:00
Jim Meyering
8467987e4b . 1995-02-26 05:09:04 +00:00
Jim Meyering
5f40ddc1a1 . 1995-02-24 04:31:04 +00:00
Jim Meyering
6812f61900 (restore_cwd): Test whether fchdir return value is non-zero, not negative.
Be consistent!
1995-02-23 21:14:12 +00:00
Jim Meyering
aeebbd038c (save_cwd) [!HAVE_FCHDIR]: Avoid a core dump via abort() which occurred
because cwd->desc was uninitialed.
(restore_cwd) [!HAVE_FCHDIR]: Remove unnecessary redefinition of fchdir.
Both from Bruno Haible.
1995-02-23 21:12:11 +00:00
Jim Meyering
875eafd489 (count_entry): Fix bug in polarity of safe-stat status test. 1995-02-21 05:19:03 +00:00
Jim Meyering
03daea30a6 (save_cwd, restore_cwd): New functions.
(main): Use them instead of in-line versions.
(count_entry): Use them here instead of relying on chdir ("..") --
but only when necessary.  Before, with --dereference (-L),
traversing a symlink caused failure because chdir ("..") didn't
work as expected.  Reported by Bruno Haible.
1995-02-21 05:01:08 +00:00
Jim Meyering
44416660ae update from FSF 1995-02-16 20:25:54 +00:00
Jim Meyering
695dd11003 (wc): Fix off-by-one error when counting lines. 1995-02-16 00:10:49 +00:00
Jim Meyering
e1453c467f . 1995-02-11 14:15:09 +00:00
Jim Meyering
a40b092725 (SOURCES): Add memcmp.c, memcpy.c, and memset.c. 1995-02-11 14:11:36 +00:00
Jim Meyering
b4994dc3fe . 1995-02-11 14:02:02 +00:00
Jim Meyering
4ef39a33cb (copy): Use memset, not bzero.
(copy_simple): Use memcpy, not bcopy.
1995-02-11 13:58:11 +00:00
Jim Meyering
b743f8afc3 Remove index/rindex and bcmp/bcopy/bzero references.
Separate errno declaration from STDC_HEADERS.
1995-02-11 13:53:39 +00:00
Jim Meyering
f299c4e0f6 . 1995-02-11 13:36:02 +00:00
Jim Meyering
79c16924de Fix example in comment. 1995-02-11 13:21:46 +00:00
Jim Meyering
a3d2e589ed (wc): Eliminate fstat call -- using lseek is sufficient.
Detect/handle case in which CURR position > EOF.
1995-02-10 05:53:54 +00:00
Jim Meyering
15d9f70d1a (wc): Handle separately the cases in which words need
not be counted.  Suggested by Karl Heuer.
(wc): Use memchr.c instead.
1995-02-10 05:34:27 +00:00
Jim Meyering
d131ddcf1f (wc): Add a separate loop for counting only lines or lines and bytes.
From Karl Heuer.
1995-02-09 17:15:17 +00:00
Jim Meyering
05d1bec3e5 (wc): Don't overcount the number of bytes when reading from
a regular file on stdin with file pointer not at BOF.  From Karl Heuer.
1995-02-09 17:05:43 +00:00
Jim Meyering
b968f43e95 . 1995-01-29 05:34:15 +00:00
Jim Meyering
5695b2f051 (parse_old_offset): Use strchr, not index. 1995-01-29 05:33:05 +00:00
Jim Meyering
faed18c267 (extract_regexp): Use strrchr, not rindex. 1995-01-29 05:32:10 +00:00
Jim Meyering
8c3911c2b4 . 1995-01-28 14:07:41 +00:00
Jim Meyering
a6f7c6d0c7 . 1995-01-28 13:23:10 +00:00
Jim Meyering
6be15c9af0 (substr): Don't allocate a byte for trailing NUL in result
since the result needn't be NUL-terminated.  Don't NUL terminate it.
1995-01-28 13:22:53 +00:00
Jim Meyering
7fc638a948 (pipe_lines, pipe_bytes): Use memcpy instead of bcopy. 1995-01-28 13:22:25 +00:00
Jim Meyering
3cd9e1dd23 (append_equiv_class): Use memcpy instead of bcopy.
(card_of_complement, set_initialize): Use memset, not bzero.
1995-01-28 13:15:35 +00:00
Jim Meyering
af7e99c091 (tac): Use memmove instead of bcopy.
(output): Use memcpy instead of bcopy.
1995-01-28 13:09:42 +00:00
Jim Meyering
9646d48630 (main): Use memset, not bzero.
(line_bytes_split): Use memmove instead of bcopy.
1995-01-28 13:06:29 +00:00
Jim Meyering
849868e342 (checkfp, mergefps): Use memcpy instead of bcopy.
(fillbuf): Use memmove instead of bcopy.
1995-01-28 13:04:27 +00:00
Jim Meyering
197bc3fd5a (decode_format_string): Use memmove instead of bcopy.
[EQUAL_BLOCKS]: Use memcmp, not bcmp.
(dump): Use memset, not bzero.
1995-01-28 13:02:44 +00:00
Jim Meyering
392dd54529 (fold_file): Use memmove instead of bcopy. 1995-01-28 13:00:10 +00:00
Jim Meyering
3794d3b8ad . 1995-01-28 04:58:03 +00:00
Jim Meyering
42a6a38712 (isopen, isclose, isperiod): Use strchr, not index.
(flush_paragraph): Use memmove instead of bcopy.
1995-01-28 04:57:45 +00:00
Jim Meyering
45f162ad7a (load_buffer): Use memcpy rather than bcopy. 1995-01-28 04:47:03 +00:00
Jim Meyering
9a915d886e (cat): Use memmove rather than bcopy. 1995-01-28 04:45:19 +00:00
Jim Meyering
1976546062 . 1995-01-27 19:32:16 +00:00
Jim Meyering
fedcb63136 (get_fs_usage, statfs): Use safe_read, and safe_stat rather than
bare read and stat.
1995-01-27 17:20:54 +00:00
Jim Meyering
7ccb88fbc5 Declare errno if it's not defined.
Rename SAFE_STAT to safe_stat.
1995-01-27 17:16:56 +00:00
Jim Meyering
0fd3803567 Declare errno if it's not defined. 1995-01-27 17:16:19 +00:00
Jim Meyering
b284f343cb (DEFS): Remove -Dlint.
(DISTFILES): Add error.h.
1995-01-27 17:09:18 +00:00
Jim Meyering
5dabd0cdec Rename SAFE_STAT to safe_stat. 1995-01-27 17:07:36 +00:00
Jim Meyering
fbf807583e Rename SAFE_STAT to safe_stat. 1995-01-27 17:05:42 +00:00
Jim Meyering
e6e3d524da Rename SAFE_STAT to safe_stat. 1995-01-27 17:05:11 +00:00
Jim Meyering
69f39255bc Rename SAFE_STAT and SAFE_LSTAT to lower case names. 1995-01-27 17:03:21 +00:00
Jim Meyering
b4cde80810 . 1995-01-27 15:35:17 +00:00
Jim Meyering
85bb215ab8 (basename): Use strrchr, not rindex.
[!STDC_HEADERS && !HAVE_STRING_H]: Define strrchr to rindex.
1995-01-27 15:23:48 +00:00
Jim Meyering
b38a5a7a17 . 1995-01-27 15:01:25 +00:00
Jim Meyering
4ecaaf1fa7 . 1995-01-27 15:00:54 +00:00
Jim Meyering
428920f8fc . 1995-01-27 14:41:51 +00:00
Jim Meyering
4e2a9fa5f2 . 1995-01-27 05:39:25 +00:00
Jim Meyering
1a41e74d32 . 1995-01-27 05:37:03 +00:00
Jim Meyering
66444bdafb Remove/rewrite some comments. 1995-01-27 05:36:14 +00:00
Jim Meyering
b554fee401 . 1995-01-27 05:22:23 +00:00
Jim Meyering
293530a4c8 . 1995-01-25 04:32:58 +00:00
Jim Meyering
8b285f6be9 * fmt.c (copy_rest): Replace ||' with &&'. Before, a paragraph
not followed by a newline would be followed by data copied from
uninitialized storage.  Repeat by `printf abc|fmt|od -ac'.
Reported by Franc,ois Pinard.
1995-01-25 04:32:15 +00:00
Jim Meyering
851162a0da Rename macros with FP_ prefix. Use FLOAT_ instead.
AIX-2.2.1 declares a typedef, FP_DOUBLE, that conflicted.
Be careful to use off_t instead of explicit `unsigned long'.
Otherwise, systems like 4.4BSD lose on calls to fseek that
expect off_t (which is long long on that system).
(parse_old_offset): Use xstrtoul
(main): Likewise.
1995-01-25 04:19:46 +00:00
Jim Meyering
41fc246374 Don't use legal' when you mean valid'. 1995-01-17 13:57:22 +00:00
Jim Meyering
cfaf788606 Fix typo: seperator -> separator. 1995-01-12 05:03:08 +00:00
Jim Meyering
98b530a36d Remove FIXMEs.
(get_width_format): Use stub function if not all of the needed math
functions are available.  From Ulrich.
(main): Give reason for failure.
1995-01-08 20:20:19 +00:00
Jim Meyering
9485d96553 See log in textutils/lib/. 1995-01-08 19:33:34 +00:00
Jim Meyering
f30ca710d9 . 1995-01-08 19:30:12 +00:00
Jim Meyering
4ad4a00de4 Add some FIXME comments. 1994-12-31 18:38:23 +00:00
Jim Meyering
81f671740e Include "system.h".
Don't explicitly include headers that it includes.
Use error, not `fprintf (stderr'.
1994-12-31 18:32:47 +00:00
Jim Meyering
d6b36e21cb Minor indentation change.
(usage): Change wording a little.
1994-12-31 18:17:34 +00:00
Jim Meyering
47d3dc6fc3 From Ulrich Drepper. 1994-12-31 18:04:40 +00:00
Jim Meyering
d4ba41692f . 1994-12-31 17:56:47 +00:00
Jim Meyering
a872332ad9 . 1994-12-31 17:55:01 +00:00
Jim Meyering
e8bb8dff6a . 1994-12-31 17:54:33 +00:00
Jim Meyering
e0c2f72ee5 . 1994-12-31 17:53:04 +00:00
Jim Meyering
60d3ac3f15 . 1994-12-31 17:51:57 +00:00
Jim Meyering
e50ceb339f still checking 1994-12-31 17:46:31 +00:00
Jim Meyering
6a8f231a9c checking whether cvs lock works 1994-12-31 17:43:19 +00:00
Jim Meyering
029da0400b (print_factors): Increase size of FACTOR array to 128. 1994-12-31 17:39:22 +00:00
Jim Meyering
3de797b535 Indent.
Add deactivated assertions.
1994-12-31 17:33:56 +00:00
Jim Meyering
14842c9a59 Use readtoken. 1994-12-31 15:28:51 +00:00
Jim Meyering
652d4c6cd6 . 1994-12-27 13:39:54 +00:00
Jim Meyering
59097c0922 Include "error.h" rather than simply declaring `void error ();'. 1994-12-27 13:36:22 +00:00
Jim Meyering
dcb4b37240 * dd.c (skip): Use safe_read instead of read.
(copy): Use full_write instead of write.
	From Bruno Haible.
1994-12-27 13:12:52 +00:00
Jim Meyering
410e779e8d * sync.c (main): Make error message accurate. 1994-12-27 13:08:05 +00:00
Jim Meyering
d7cd6fb738 Write file name instead of filename. 1994-12-27 05:28:58 +00:00
Jim Meyering
ca39edc494 . 1994-12-27 02:50:40 +00:00
Jim Meyering
2ea2c7bf78 [member]: Use strchr instead of index. 1994-12-27 02:47:50 +00:00
Jim Meyering
b772193f4b . 1994-12-27 02:46:10 +00:00
Jim Meyering
c84154eb28 * test.c (term): Running `./test \( a -o b' got a seg fault.
From Klaus.Reichl@aut.alcatel.at.
1994-12-27 00:33:03 +00:00
Jim Meyering
72bb9e6307 Rearrange to accept a user-specified set of suffix chars (must be
a subset of master list), each with a hard-coded value.
1994-12-22 05:10:32 +00:00
Jim Meyering
7c141b258d (main): Update xstrtol calls to be consistent with new decl. 1994-12-22 05:08:40 +00:00
Jim Meyering
2999aefb84 . 1994-12-20 05:26:56 +00:00
Jim Meyering
a9f1783e20 * src/*.c: Include "error.h" instead of simply declaring
`void error ();'.
1994-12-20 05:26:44 +00:00
Jim Meyering
6bb619d33c Begin overhaul. 1994-12-20 05:24:13 +00:00
Jim Meyering
0477175963 . 1994-12-20 05:10:42 +00:00
Jim Meyering
eaa5cc3f91 . 1994-12-20 05:05:55 +00:00
Jim Meyering
735c6a9adc (test_stat, binary_operator): Use safe_stat instead of SAFE_STAT.
(unary_operator): Use safe_lstat instead of SAFE_LSTAT.
1994-12-20 04:51:10 +00:00
Jim Meyering
6d59e126b5 (print_entry): Use safe_stat instead of SAFE_STAT. 1994-12-20 04:50:25 +00:00
Jim Meyering
bb705c7c3e (dir_ok): Use safe_stat instead of SAFE_STAT. 1994-12-20 04:49:55 +00:00
Jim Meyering
398dbbb832 (numerous functions): Give char* filename arguments the const attribute. 1994-12-20 04:27:35 +00:00
Jim Meyering
90a33c19fe . 1994-12-20 04:23:49 +00:00
Jim Meyering
3205d087e2 . 1994-12-20 04:17:23 +00:00
Jim Meyering
a09358fc2c . 1994-12-20 04:15:30 +00:00
Jim Meyering
c5811b6a26 (main): Use safe_stat, not SAFE_STAT. 1994-12-20 04:03:28 +00:00
Jim Meyering
73d8d0a43f Include "error.h" instead of simply declaring `void error ();'.
(main): Don't advance optarg past leading sign -- otherwise, we'd
be making tail accept invalid options like `-+1'.
(tail_file): Fix call to error with %s in format, but no corresponding argument.
1994-12-16 05:45:57 +00:00
Jim Meyering
7323b7d9f2 Include "error.h" instead of simply declaring `void error ();'. 1994-12-16 05:42:47 +00:00
Jim Meyering
8d6c6946dd Include "error.h" instead of simply declaring `void error ();'. 1994-12-16 05:41:05 +00:00
Jim Meyering
029fcaa913 (main): Use %lu, not %d for unsigned long.
(my_strtoul, uint_fatal_error): Remove functions.  Use xstrtoul
and STRTOL_FATAL_ERROR instead.
1994-12-16 05:32:30 +00:00
Jim Meyering
bebb9b3286 (main): Move to end.
(factor, do_stdin): Declare static.
1994-12-13 05:42:44 +00:00
Jim Meyering
3ae9a27c25 (docolon): Zero out re_buffer and re_regs before using them.
From H.J. Lu <hjl@nynexst.com>.
1994-12-13 04:42:23 +00:00
Jim Meyering
0050411112 . 1994-12-12 17:49:55 +00:00
Jim Meyering
5bfdd91cdf . 1994-12-12 00:00:28 +00:00
Jim Meyering
88442ad885 sort.c (main): Fix interpretation of field offsets when specified
via -k option.  They were being interpreted as zero-indexed.
POSIX says they are 1-based indices.
(keycompare): Don't ignore characters at the end of words
when otherwise they compare equal.  Both from Rik Faith
<faith@cs.unc.edu>.
1994-12-12 00:00:22 +00:00
Jim Meyering
f46511eb69 * (<most functions>): Change the type of n_units/n_lines/n_bytes
to off_t because n_bytes is used as the option to fseek and off_t may
be long long (e.g. on BSD4.4).  The only place where a 32-bit limit is
imposed is in the string-to-integer converstion of xstrtol.
(main): Use xstrtol instead of manual string to integer conversion.
1994-12-11 23:53:54 +00:00
Jim Meyering
cfa6527373 . 1994-12-11 23:44:07 +00:00
Jim Meyering
0e168c7d03 (get_format_width, get_format_prec): Use ISDIGIT instead of
comparisons against '0' and '9'.
1994-12-11 23:43:21 +00:00
Jim Meyering
9c5d0aa7a6 [ULONGMAX]: Define it.
[LONGMAX]: Define in terms of ULONGMAX instead of as a 32-bit constant.
1994-12-11 23:31:12 +00:00
Jim Meyering
5b66c03ac0 . 1994-12-11 23:13:08 +00:00
Jim Meyering
5dd4159e77 (safe_read): Get this function from gcc's cccp.c. 1994-12-10 22:00:12 +00:00
Jim Meyering
b3d3591aed . 1994-12-10 06:04:53 +00:00
Jim Meyering
fb5c9e690f . 1994-12-10 05:48:14 +00:00
Jim Meyering
e737fe145f . 1994-12-10 05:46:18 +00:00
Jim Meyering
abdf594b85 No longer include <ctype.h>.
[isascii, ISDIGIT]: Remove definitions.
1994-12-10 05:45:52 +00:00
Jim Meyering
33c44e1d1b No longer include <ctype.h>.
Remove IS* macros.
1994-12-10 05:45:02 +00:00
Jim Meyering
ec27c85596 No longer include <ctype.h>. 1994-12-10 05:43:18 +00:00
Jim Meyering
36a504f605 (copy, make_path_private): Use strr?chr instead of r?index. 1994-12-10 05:41:52 +00:00
Jim Meyering
c95989d148 (parse_conversion, scan_args): Use strr?chr instead of r?index. 1994-12-10 05:41:16 +00:00
Jim Meyering
06f4d47a29 (remove_parents): Use strr?chr instead of r?index. 1994-12-10 05:39:59 +00:00
Jim Meyering
7f58bbba88 * [!HAVE_STRING_H]: Define strchr to index and strrchr to
rindex instead of the other way around.
* Include <ctype.h> and define IS* macros.
1994-12-10 05:25:15 +00:00
Jim Meyering
651ccf648d No longer include <ctype.h>. 1994-12-10 05:21:29 +00:00
Jim Meyering
2a242b8989 New chapter by Arnold Robbins via Karl. 1994-12-07 14:17:04 +00:00
Jim Meyering
f445de3b86 . 1994-12-04 21:15:54 +00:00
Jim Meyering
12042b2fa2 Use strr?chr instead of r?index. 1994-12-04 21:15:46 +00:00
Jim Meyering
06084cb7e8 Get putenv.c from /copies (derived from glibc).
Hack it to work with SGI's __environ junk.
1994-12-04 21:08:50 +00:00
Jim Meyering
96dd28efa2 . 1994-12-04 20:56:35 +00:00
Jim Meyering
3b0ea78aef . 1994-12-04 20:55:30 +00:00
Jim Meyering
be4a8a192a . 1994-12-04 20:53:43 +00:00
Jim Meyering
fec974e60e (DISTFILES): Add getdate.texi. 1994-12-04 20:52:46 +00:00
Jim Meyering
5150ebf157 Mods from Karl to include getdate.texi. 1994-12-04 20:50:57 +00:00
Jim Meyering
9a102f76c8 . 1994-12-04 20:48:11 +00:00
Jim Meyering
1d6dc36be9 (du_files): Handle very low-probability fchdir failure (when errno != 0
&& errno != EINVAL).
1994-12-03 20:38:20 +00:00
Jim Meyering
9f715b2bdb (du_files): Variable name changes. 1994-12-03 20:29:28 +00:00
Jim Meyering
103e83b65e (du_files): Work around SunOS restriction that fchdir doesn't work when
accounting is enabled -- modelled after djm's find.c mods.
1994-12-03 20:26:33 +00:00
Jim Meyering
f55a29ab93 (checkfp): Initialize keybeg and keylim fields.
Before, this command
  perl -e 'print join ("\n", (1..513)), "\n";'|sort -cs -n
failed on SunOS 4 systems.  From Robert H. de Vries <robert@and.nl>.
1994-12-02 16:54:56 +00:00
Jim Meyering
97f9755aeb (xfclose): Report failed fflush. Otherwise, failed write to stdout
could be missed because of subsequent clearerr.
(main): Include filename in a couple error messages.
Add missing %s in an error format string.
1994-12-02 16:49:47 +00:00
Jim Meyering
f2fc6e9054 name changes: number->n_lines|n_bytes 1994-11-30 20:54:21 +00:00
Jim Meyering
04b546bdb9 Make some globals static' and/or const'.
(LEN_STR_PAIR): New macro.
(decode_switches): Only ignore invalid TABSET value instead of dying.
(parse_ls_color): Use error, not fprintf.
(print_type_indicator): Remove dcls of two unused variables.
1994-11-28 06:00:56 +00:00
Jim Meyering
f214bd45dc indent 1994-11-28 04:38:27 +00:00
Jim Meyering
f021d0ca05 (indent): Use TABs only when doing so replaces at least two spaces. 1994-11-28 04:32:07 +00:00
Jim Meyering
c65e1fe89f `colorize' patch from Drepper. 1994-11-28 04:25:31 +00:00
Jim Meyering
7f2c21525b . 1994-11-21 14:23:15 +00:00
Jim Meyering
5fce52076e (list_entries): Delete. Split in two actually...
(list_entries_users, list_entries_who, userid_compare): New functions.
(list_entries_users): Sort the user names.  Reported by
Michael I Bushnell.
Topologically sort the functions and remove fwd declarations.
1994-11-18 05:15:04 +00:00
Jim Meyering
42c03d3135 . 1994-11-17 17:37:22 +00:00
Jim Meyering
fdfd720ec4 (output): Use STDOUT_FILENO instead of `1' in xwrite call. 1994-11-17 12:49:38 +00:00
Jim Meyering
53c46c67ac (dump_remainder): Flush standard output just before
sleeping so that `tail -f' will output partial lines sooner.
This applies only when following the end of a single file.
From Leonard N. Zubkoff <lnz@dandelion.com>.

(file_lines, pipe_lines, pipe_bytes, start_bytes, start_lines, dump_remainder):
Use STDOUT_FILENO instead of `1' in XWRITE calls.
1994-11-17 12:49:10 +00:00
Jim Meyering
13e79f4f72 Include <getopt.h> instead of "getopt.h". 1994-11-16 13:19:25 +00:00
Jim Meyering
67af2936fa (tempname): Merge two very similar sprintf stmts into one. 1994-11-16 13:16:53 +00:00
Jim Meyering
5d9de33889 Use BUFSIZ instead of BUFSIZE. 1994-11-16 13:13:07 +00:00
Jim Meyering
5356de1df7 Rewriting to help it pass a reasonable suite of tests. 1994-11-16 13:10:34 +00:00
Jim Meyering
c85cac33ab Declare DELIM to be `int' rather than unsigned char. 1994-11-16 13:09:13 +00:00
Jim Meyering
b4a1e5cb83 . 1994-11-16 13:06:45 +00:00
Jim Meyering
c35f55124b . 1994-11-16 13:05:38 +00:00
Jim Meyering
005bf81461 . 1994-11-14 22:31:47 +00:00
Jim Meyering
6b558ed117 (my_strtol): New function.
(main): Use it instead of atoi to convert argument strings to
major and minor device numbers.  Now, mknod diagnoses invalid
device numbers and accepts octal and hexadecimal as well as
decimal string arguments.  Ralf Lammers
<rlammers@physik.uni-osnabrueck.de> suggested that mknod accept
hex device numbers for compatibility with HPUX's mknod program.
1994-11-11 16:14:19 +00:00
Jim Meyering
b81d2117e2 (SOURCES): Add strtol.c. 1994-11-11 16:10:16 +00:00
Jim Meyering
34406025e5 . 1994-11-09 20:16:23 +00:00
Jim Meyering
75d902ef01 . 1994-11-08 22:40:52 +00:00
Jim Meyering
da098ddd8a . 1994-11-07 12:55:05 +00:00
Jim Meyering
cb4c5aaf0a Initial revision 1994-11-07 12:47:50 +00:00
Jim Meyering
8761507929 . 1994-11-07 05:38:19 +00:00
Jim Meyering
ba2a317029 . 1994-11-07 05:37:05 +00:00
Jim Meyering
c47ec4af2a Add test names. 1994-11-07 04:36:41 +00:00
Jim Meyering
1f875effab Add -w and clean up. 1994-11-07 04:36:07 +00:00
Jim Meyering
4c722a96ba merge with 1.12 1994-11-06 17:51:23 +00:00
Jim Meyering
c67fdb5c94 merge with 1.11 1994-11-06 17:47:32 +00:00
Jim Meyering
398d617cc9 merge with 1.10 1994-11-06 17:42:51 +00:00
Jim Meyering
0683ef74d1 Initial revision 1994-11-06 17:40:20 +00:00
Jim Meyering
4f89d5bcfa merge with 1.12 1994-11-05 14:17:55 +00:00
Jim Meyering
9bfdace83a merge with 3.10 1994-11-05 13:37:38 +00:00
Jim Meyering
fad3ef71a4 merge with 3.9u1 1994-11-04 16:50:04 +00:00
Jim Meyering
c21a3a4ec6 merge with 1.9.1k1 1994-11-04 16:43:33 +00:00
Jim Meyering
05bcdf4d41 . 1994-11-04 14:48:40 +00:00
Jim Meyering
cda4ac2e91 . 1994-11-04 14:15:12 +00:00
Jim Meyering
8de255ea61 Change _P to __P. 1994-11-04 14:04:43 +00:00
Jim Meyering
4b579f1836 . 1994-11-04 14:04:03 +00:00
Jim Meyering
8edc08d48e Include makepath.h.
Add an argument: PRESERVE_EXISTING.
Declare char* arguments const.
1994-11-04 06:05:34 +00:00
Jim Meyering
3b99cd3ae3 . 1994-11-04 06:04:42 +00:00
Jim Meyering
0ccaadc62c Include <limits.h> before system.h because limits.h on
some systems undefines PATH_MAX, whereas system.h includes pathmax.h
which sets PATH_MAX.  From Kaveh Ghazi.
1994-11-04 06:04:02 +00:00
Jim Meyering
aebff608dc (make_path_private): Rename function from make_path to avoid confusion.
(do_copy): Update caller.
1994-11-04 06:03:25 +00:00
Jim Meyering
0e1e2d8069 (DISTFILES): Add makepath.h.
(makepath.o): Depend on it.
1994-11-04 06:02:21 +00:00
Jim Meyering
7cced49416 Update calls to make_path. 1994-11-04 06:00:41 +00:00
Jim Meyering
70fe5e3261 . 1994-11-03 22:32:35 +00:00
Jim Meyering
b808409fe7 (rwx): Use S_IRUSR, S_IWUSR, S_IXUSR instead of obsolete
S_IREAD, S_IWRITE, S_IEXEC.
Make sure the former three are defined.
1994-11-03 22:03:54 +00:00
Jim Meyering
17a29b6eea Define S_IXUSR, S_IXGRP, and S_IXOTH in terms of _IEXEC if they're not
already defined.  Reported by Daniel Hagerty <hag@gnu.ai.mit.edu>.
1994-11-03 22:03:16 +00:00
Jim Meyering
8d447abdbf merge with 3.9t3 1994-11-03 04:34:05 +00:00
Jim Meyering
1423156a9c merge with 1.9.1j2 1994-11-03 04:33:52 +00:00
Jim Meyering
40f3df0acd merge with 1.9.1j2 1994-11-03 04:33:22 +00:00
Jim Meyering
4e253268e1 merge with 1.10x1 1994-11-03 00:58:25 +00:00
Jim Meyering
21229f21b4 . 1994-11-02 23:55:02 +00:00
Jim Meyering
995c18ba28 . 1994-11-02 05:24:13 +00:00
Jim Meyering
c6411b91f5 (cat): Conditionalize test for errno == ENOSYS. It's not
defined on some Next and Alliant systems.  From Kaveh Ghazi.
1994-11-02 05:21:37 +00:00
Jim Meyering
346a1b2351 (cut_bytes): Print at least a newline for every line of input.
(cut_fields): Print a newline even for lines whose only selected
field is empty.  But print nothing when using -s without -f1.
And print nothing for empty input.  Reported by
Richard_Sharman@software.mitel.com.
1994-11-02 05:04:17 +00:00
Jim Meyering
32340b45e7 (XWRITE): Guard against calling xwrite with n_bytes == 0. 1994-11-01 22:38:11 +00:00
Jim Meyering
7a5462a0b7 (XWRITE): Allow n_bytes to be zero in assertion. Otherwise `tail /dev/null'
gets failed assertion.
1994-11-01 22:21:23 +00:00
Jim Meyering
ca83b5d174 merge with 3.9t2 1994-11-01 14:57:56 +00:00
Jim Meyering
7a1813fe39 merge with 3.9t2 1994-11-01 14:57:28 +00:00
Jim Meyering
e877a26079 Initial revision 1994-11-01 14:50:16 +00:00
Jim Meyering
a175b4affb . 1994-10-31 14:03:58 +00:00
Jim Meyering
159929688d . 1994-10-31 12:55:27 +00:00
Jim Meyering
5b4430b4d2 merge with 1.9.1j 1994-10-31 04:38:31 +00:00
Jim Meyering
67e2c217d6 . 1994-10-31 04:15:31 +00:00
Jim Meyering
c2f3b72b93 merge with 1.9.1i1 1994-10-30 13:56:10 +00:00
Jim Meyering
2654c2012b merge with 1.9.1i 1994-10-30 05:28:15 +00:00
Jim Meyering
21b82f43b9 . 1994-10-29 05:06:43 +00:00
Jim Meyering
1fd77b2ddf . 1994-10-29 04:49:55 +00:00
Jim Meyering
2ef20008e8 . 1994-10-28 18:32:31 +00:00
Jim Meyering
c0119ac534 . 1994-10-28 17:03:06 +00:00
Jim Meyering
1cd8c36e4d merge with 3.9t 1994-10-27 23:36:15 +00:00
Jim Meyering
2e9d555f8c . 1994-10-27 13:45:55 +00:00
Jim Meyering
f6b8bdc529 merge with 3.9s 1994-10-27 13:43:59 +00:00
Jim Meyering
0c9fb4050b merge with 1.10x 1994-10-27 13:39:39 +00:00
Jim Meyering
2ba9e70e52 merge with 3.9q 1994-10-27 05:02:28 +00:00
Jim Meyering
51244615e9 merge with 3.9q 1994-10-27 05:02:05 +00:00
Jim Meyering
c0c7ee9ab1 merge with 1.10w 1994-10-27 04:47:39 +00:00
Jim Meyering
4c8adc4821 . 1994-10-27 04:18:00 +00:00
Jim Meyering
9f7d860db2 merge with 1.10u 1994-10-24 20:07:32 +00:00
Jim Meyering
4cc84a6164 . 1994-10-21 13:37:48 +00:00
Jim Meyering
b902a4439e merge with 1.10t 1994-10-21 05:25:03 +00:00
Jim Meyering
aa3d6d01e8 . 1994-10-20 16:22:32 +00:00
Jim Meyering
154bd660bb merge with 3.9p 1994-10-20 16:16:39 +00:00
Jim Meyering
adeff820d3 Initial revision 1994-10-20 16:10:00 +00:00
Jim Meyering
3bdb536a55 . 1994-10-20 15:29:38 +00:00
Jim Meyering
5868a8d57c . 1994-10-20 14:57:33 +00:00
Jim Meyering
550968ec92 . 1994-10-20 14:48:51 +00:00
Jim Meyering
9f167c85b0 . 1994-10-20 04:42:43 +00:00
Jim Meyering
544baf5482 merge with 1.9.1h 1994-10-19 03:39:33 +00:00
Jim Meyering
6a76abbf9c . 1994-10-19 02:45:36 +00:00
Jim Meyering
131aa77dd9 . 1994-10-18 23:23:44 +00:00
Jim Meyering
3e9cafcf42 merge with 1.10s 1994-10-18 23:23:04 +00:00
Jim Meyering
ee2f172106 . 1994-10-18 22:55:26 +00:00
Jim Meyering
f9fea3cd18 . 1994-10-17 14:19:50 +00:00
Jim Meyering
ed41665d78 . 1994-10-17 14:03:27 +00:00
Jim Meyering
d8843f4b6e . 1994-10-17 14:01:44 +00:00
Jim Meyering
f45f10b17d . 1994-10-17 13:24:35 +00:00
Jim Meyering
ff18f4c072 . 1994-10-15 02:40:27 +00:00
Jim Meyering
4157d2bf7f . 1994-10-13 04:03:24 +00:00
Jim Meyering
977995573d merge with 3.9n 1994-10-13 02:57:52 +00:00
Jim Meyering
3593b80a51 merge with 1.10r 1994-10-13 02:16:01 +00:00
Jim Meyering
d3a7a3d262 . 1994-10-11 01:56:53 +00:00
Jim Meyering
d3d49453a4 . 1994-10-10 01:17:52 +00:00
Jim Meyering
ec7c19de56 . 1994-10-09 05:24:31 +00:00
Jim Meyering
a41f5ad96e . 1994-10-09 05:06:10 +00:00
Jim Meyering
eb57e662fc . 1994-10-09 05:03:54 +00:00
Jim Meyering
c0723b4189 merge with 3.9k 1994-10-08 17:26:58 +00:00
Jim Meyering
e8670c071b merge with 3.9j 1994-10-08 16:56:34 +00:00
Jim Meyering
09b0c4ab6e . 1994-10-08 16:39:30 +00:00
Jim Meyering
deef174caa . 1994-10-08 16:38:01 +00:00
Jim Meyering
35adb7c5be . 1994-10-08 14:52:10 +00:00
Jim Meyering
f827615b89 merge with 3.9i 1994-10-08 04:54:06 +00:00
Jim Meyering
09d7d195be merge with 3.9i 1994-10-08 02:42:43 +00:00
Jim Meyering
4b8534f940 . 1994-10-08 02:05:20 +00:00
Jim Meyering
7354f66153 . 1994-10-08 02:04:47 +00:00
Jim Meyering
9c9b761562 . 1994-10-08 00:58:41 +00:00
Jim Meyering
d72ab4ffe7 . 1994-10-08 00:56:50 +00:00
Jim Meyering
d734172c73 merge with 1.10q 1994-10-08 00:40:55 +00:00
Jim Meyering
5a31cea3d4 . 1994-10-08 00:34:54 +00:00
Jim Meyering
0eb406c7e6 . 1994-10-07 23:46:47 +00:00
Jim Meyering
94d327a68a . 1994-10-07 01:19:51 +00:00
Jim Meyering
33a89ddba5 . 1994-10-05 00:43:46 +00:00
Jim Meyering
83577ddb4d . 1994-10-03 03:01:32 +00:00
Jim Meyering
c9b696a6bd merge with 1.9.1g 1994-10-02 23:01:05 +00:00
Jim Meyering
b2e7f0596a Initial revision 1994-10-02 22:50:11 +00:00
Jim Meyering
3994e55f58 . 1994-10-02 22:11:44 +00:00
Jim Meyering
7079da8b5a . 1994-10-02 22:10:57 +00:00
Jim Meyering
d9a92fd81c . 1994-10-02 21:12:44 +00:00
Jim Meyering
f1ce35a10c merge with 3.9h 1994-10-02 05:43:03 +00:00
Jim Meyering
c543c4b10c merge with 3.9h 1994-10-02 05:42:43 +00:00
Jim Meyering
ff6263f4f9 Initial revision 1994-10-02 05:35:52 +00:00
Jim Meyering
f17c045d21 . 1994-10-02 02:09:38 +00:00
Jim Meyering
b055972c6b . 1994-10-01 18:06:39 +00:00
Jim Meyering
bc60940ea9 merge with 1.10p 1994-10-01 13:06:03 +00:00
Jim Meyering
11020daf89 merge with 1.10n5 1994-10-01 04:48:44 +00:00
Jim Meyering
e9bbe5be67 merge with 1.10n4 1994-10-01 04:37:18 +00:00
Jim Meyering
fe1ad4509c . 1994-10-01 04:15:13 +00:00
Jim Meyering
ea89a760d8 . 1994-10-01 04:14:50 +00:00
Jim Meyering
ec90359f34 . 1994-10-01 02:52:05 +00:00
Jim Meyering
c8131583ac Update from Karl. 1994-10-01 02:22:07 +00:00
Jim Meyering
10c7a38d84 . 1994-09-30 00:50:23 +00:00
Jim Meyering
7413391dae test 1994-09-30 00:50:13 +00:00
Jim Meyering
eed9880cdd . 1994-09-30 00:05:41 +00:00
Jim Meyering
dccf44af32 . 1994-09-29 23:47:37 +00:00
Jim Meyering
3c28751b48 merge with 1.10n3 1994-09-29 17:57:49 +00:00
Jim Meyering
31d95cf0ca . 1994-09-29 16:19:18 +00:00
Jim Meyering
8a693e3070 . 1994-09-29 16:18:55 +00:00
Jim Meyering
5cfcf6dc93 remove ansidecl junk 1994-09-28 01:19:14 +00:00
Jim Meyering
0a0800fe25 merge with 1.10n2 1994-09-27 22:02:00 +00:00
Jim Meyering
e13a0b7f49 merge with 1.10n1 1994-09-27 20:52:02 +00:00
Jim Meyering
d67dbfcf80 . 1994-09-27 04:43:08 +00:00
Jim Meyering
552cc77dcf . 1994-09-26 23:58:40 +00:00
Jim Meyering
08b0b0fe95 . 1994-09-25 16:30:49 +00:00
Jim Meyering
7d3aa65903 . 1994-09-25 13:19:17 +00:00
Jim Meyering
649d081fee merge with 1.10n 1994-09-25 03:12:38 +00:00
Jim Meyering
4bac19f0bf . 1994-09-25 02:25:20 +00:00
Jim Meyering
c09c590616 . 1994-09-25 01:56:42 +00:00
Jim Meyering
451fa3013e . 1994-09-25 01:25:18 +00:00
Jim Meyering
1ba691350b merge with 1.10m 1994-09-24 19:12:46 +00:00
Jim Meyering
4e2b49d717 . 1994-09-24 16:33:21 +00:00
Jim Meyering
c312500094 . 1994-09-24 16:31:57 +00:00
Jim Meyering
b659452519 . 1994-09-24 16:31:27 +00:00
Jim Meyering
67c493ed67 (main): Cast string literal to (char*). 1994-09-24 16:28:52 +00:00
Jim Meyering
bfb7a14ab7 Use RELEASE_DATE instead of hard-coded date. 1994-09-24 16:23:59 +00:00
Jim Meyering
cbee99cebe (read_utmp): New variable: size to avoid type warnings. 1994-09-24 16:18:11 +00:00
Jim Meyering
3d74506f21 (main, tee): More const dcls and casting. 1994-09-24 16:17:54 +00:00
Jim Meyering
d26f6b1796 (wrapf): Declare first argument const char *. 1994-09-24 16:17:35 +00:00
Jim Meyering
553cabb1d1 (main): Cast string literal to (char*). 1994-09-24 16:16:17 +00:00
Jim Meyering
fed388a533 Don't include <ctype.h> or define IS* macros since system.h now does that. 1994-09-24 15:20:51 +00:00
Jim Meyering
fd16a39c69 (main): Revamp option processing to detect options like `--7' manually
and pass the rest off to getopt_long.
(isinteger): Use ISDIGIT.
1994-09-24 15:20:21 +00:00
Jim Meyering
43545372ed Enumerate (Yuck!) the --1 .. --20 long options 1994-09-24 12:50:59 +00:00
Jim Meyering
00aa944946 (main): Make sure s is not NULL before dereferencing it. 1994-09-24 00:41:27 +00:00
Jim Meyering
f0ea13bbe9 merge with 1.10l 1994-09-19 01:39:58 +00:00
Jim Meyering
2ab8e21d5d merge with 1.10k 1994-09-18 00:42:41 +00:00
Jim Meyering
fe106be46b . 1994-09-18 00:28:34 +00:00
Jim Meyering
73b9e4b762 merge with 1.10j 1994-09-17 02:46:48 +00:00
Jim Meyering
920c0db5c0 . 1994-09-17 02:19:11 +00:00
Jim Meyering
e1b35181ba . 1994-09-17 01:58:43 +00:00
Jim Meyering
b4baf84d32 . 1994-09-17 00:17:25 +00:00
Jim Meyering
1401f3e3f9 . 1994-09-15 23:09:36 +00:00
Jim Meyering
ec13d92b20 . 1994-09-12 17:35:58 +00:00
Jim Meyering
00dceaff2e merge with 1.10i 1994-09-08 04:48:40 +00:00
Jim Meyering
556b9f622f . 1994-09-06 13:13:41 +00:00
Jim Meyering
b58bc13bee . 1994-09-05 02:19:59 +00:00
Jim Meyering
4e0d869f9a . 1994-09-04 04:18:24 +00:00
Jim Meyering
83e202ca50 . 1994-09-04 04:05:45 +00:00
Jim Meyering
d7e6b36faa . 1994-09-04 03:56:21 +00:00
Jim Meyering
b8b4c48285 . 1994-09-03 18:04:35 +00:00
Jim Meyering
6c0ec66614 . 1994-09-03 17:54:55 +00:00
Jim Meyering
af52175661 . 1994-09-03 04:27:02 +00:00
Jim Meyering
de8c62d0f0 merge with 1.10h 1994-09-01 23:20:29 +00:00
Jim Meyering
52b4bf84e7 . 1994-08-27 21:34:13 +00:00
Jim Meyering
fe4becacb4 . 1994-08-27 21:26:52 +00:00
Jim Meyering
e1a2cd7e46 . 1994-08-27 21:23:07 +00:00
Jim Meyering
94172d0764 . 1994-08-27 21:04:53 +00:00
Jim Meyering
6d3aa2169e . 1994-08-27 20:55:59 +00:00
Jim Meyering
4fb9a0a740 . 1994-08-27 20:32:40 +00:00
Jim Meyering
326b01a327 . 1994-08-25 13:28:58 +00:00
Jim Meyering
da13561d3d merge with 3.9f 1994-08-19 22:42:59 +00:00
Jim Meyering
8a5d6318e7 merge with 1.10g 1994-08-19 22:42:22 +00:00
Jim Meyering
109d16cbce . 1994-08-19 17:05:18 +00:00
Jim Meyering
cb6cf9485c . 1994-08-19 17:01:45 +00:00
Jim Meyering
257b028a06 . 1994-08-19 13:50:42 +00:00
Jim Meyering
86ba2b2bdf . 1994-08-19 13:36:37 +00:00
Jim Meyering
e50688802c . 1994-08-19 13:13:48 +00:00
Jim Meyering
1763c83a50 . 1994-08-19 12:45:55 +00:00
Jim Meyering
e1640b71fa . 1994-08-03 15:28:30 +00:00
Jim Meyering
b946e9ee2e . 1994-08-03 15:21:03 +00:00
Jim Meyering
a8778c2665 merge with 3.9e 1994-07-30 18:59:12 +00:00
Jim Meyering
32bd426778 . 1994-07-30 16:34:17 +00:00
Jim Meyering
a272d8b0c6 . 1994-07-30 16:17:45 +00:00
Jim Meyering
15ddd652be . 1994-07-30 16:12:44 +00:00
Jim Meyering
2c4f4e60d8 . 1994-07-30 16:10:22 +00:00
Jim Meyering
2399435ba4 . 1994-07-30 14:17:26 +00:00
Jim Meyering
2ac5b86618 . 1994-07-30 14:15:54 +00:00
Jim Meyering
aa60b32c1c . 1994-07-30 13:18:39 +00:00
Jim Meyering
be7d4a230e Use SAFE_STAT instead of stat to avoid unnecessary failure
on systems for which stat can return EINTR.
1994-07-30 13:13:52 +00:00
Jim Meyering
a1d3a7aee6 . 1994-07-30 13:12:40 +00:00
Jim Meyering
f1f85daaed . 1994-07-30 12:10:53 +00:00
Jim Meyering
88494fb8f3 . 1994-07-30 12:05:32 +00:00
Jim Meyering
2e3cc9b7b9 merge with 1.10f 1994-07-26 04:06:18 +00:00
Jim Meyering
7b5a41383b . 1994-07-26 03:44:37 +00:00
Jim Meyering
6cab708162 (group_member): Remove function and all its baggage. 1994-07-23 04:43:56 +00:00
Jim Meyering
340d9cec31 . 1994-07-23 04:42:46 +00:00
Jim Meyering
eebb80a187 (unary_operator): (-u, -g): Return false if S_ISUID,S_ISGID etc aren't defined. 1994-07-23 03:58:31 +00:00
Jim Meyering
fc0bbac463 * who.c (print_entry): Use SAFE_STAT. 1994-07-22 17:19:23 +00:00
Jim Meyering
754e4abb56 * test.c (test_stat, binary_operator, unary_operator): Use SAFE_STAT and
SAFE_LSTAT.
1994-07-22 17:18:46 +00:00
Jim Meyering
7314448bef * pathchk.c (dir_ok): Use SAFE_STAT. 1994-07-22 17:17:25 +00:00
Jim Meyering
dd46047168 (substr): Allocate len+1 bytes (not just len) to leave room for trailing NUL. 1994-07-13 15:45:24 +00:00
Jim Meyering
35b631eb04 . 1994-07-13 15:35:56 +00:00
Jim Meyering
545ac40616 . 1994-07-13 14:17:38 +00:00
Jim Meyering
d2205a42a1 merge with 1.10e 1994-07-13 14:11:38 +00:00
Jim Meyering
e577b09b46 . 1994-07-12 13:21:49 +00:00
Jim Meyering
53cd09b3bc merge with 1.10d 1994-07-05 02:22:12 +00:00
Jim Meyering
792d894bd9 . 1994-07-03 17:46:37 +00:00
Jim Meyering
363b712c93 . 1994-07-03 13:18:31 +00:00
Jim Meyering
763968d428 . 1994-07-03 12:48:38 +00:00
Jim Meyering
f980ff966d (main): Initialize cwd_only in first two statements, rather than as part
of the declaration.  The latter evoked an error from /bin/cc of HPUX 9.01.
1994-07-02 04:25:04 +00:00
Jim Meyering
926b8285be merge with 3.9d 1994-07-01 19:51:39 +00:00
Jim Meyering
59c6679733 Initial revision 1994-07-01 19:46:42 +00:00
Jim Meyering
414e5b1d06 . 1994-07-01 18:42:52 +00:00
Jim Meyering
c1920a67e2 . 1994-07-01 18:06:49 +00:00
Jim Meyering
5c92a5735d . 1994-07-01 17:59:34 +00:00
Jim Meyering
4eb8e70031 . 1994-07-01 16:53:29 +00:00
Jim Meyering
a32610143c (main): Change #ifdef TESTING to TEST. 1994-07-01 15:23:47 +00:00
Jim Meyering
844a6c1a11 Include alloca directives.
Replace 3 lines with V_STRDUP equivalent.
1994-07-01 14:04:23 +00:00
Jim Meyering
9e01db73f9 Rewrite. 1994-07-01 13:58:06 +00:00
Jim Meyering
8dedd7864d . 1994-07-01 13:47:06 +00:00
Jim Meyering
11023e1493 . 1994-07-01 13:46:42 +00:00
Jim Meyering
1cf80189ac . 1994-06-30 14:41:20 +00:00
Jim Meyering
1525e2cb30 . 1994-06-30 14:33:41 +00:00
Jim Meyering
6b1785ed05 merge with 1.10c + local build mods 1994-06-22 14:40:59 +00:00
Jim Meyering
d62acd19e9 . 1994-06-22 14:11:23 +00:00
Jim Meyering
7a3fb2d7ad . 1994-06-20 14:14:34 +00:00
Jim Meyering
3a3b00cc54 . 1994-06-20 13:24:14 +00:00
Jim Meyering
0d3ba947f3 merge with 1.10b + local build mods 1994-06-19 04:52:50 +00:00
Jim Meyering
2bdde50d3f . 1994-06-19 04:27:52 +00:00
Jim Meyering
a3ad002027 (count_entry): Print "/" instead of "". 1994-06-18 21:04:00 +00:00
Jim Meyering
33fec67464 . 1994-06-02 18:11:26 +00:00
Jim Meyering
cb9d9f0f71 merge with 1.10a + local build mods 1994-05-30 13:37:52 +00:00
Jim Meyering
e3360a98c2 merge with 1.10a + local build mods 1994-05-30 00:06:15 +00:00
Jim Meyering
f277d830bb . 1994-05-29 19:50:31 +00:00
Jim Meyering
cf1d805fec (test_syntax_error, beyond): add __attribute__ ((noreturn)) 1994-05-20 15:56:47 +00:00
Jim Meyering
b98b0e107f merge with 1.10 + local build mods 1994-05-20 13:50:43 +00:00
Jim Meyering
a0f30b3f2c merge with 1.9.4l + local build mods 1994-05-14 16:09:51 +00:00
Jim Meyering
8b21a5c229 merge with 1.9.4k 1994-05-13 15:49:16 +00:00
Jim Meyering
2d981879d6 . 1994-05-13 14:24:15 +00:00
Jim Meyering
6874eb8797 . 1994-05-13 14:21:20 +00:00
Jim Meyering
323e95c8b3 . 1994-05-13 13:57:20 +00:00
Jim Meyering
af6e86c537 . 1994-05-13 13:44:07 +00:00
Jim Meyering
1f53ad0803 . 1994-05-08 16:42:40 +00:00
Jim Meyering
31c8ce9ef8 . 1994-05-08 16:16:03 +00:00
Jim Meyering
a99f319d12 merge with 1.9.1f 1994-05-06 18:39:32 +00:00
Jim Meyering
758d3a260d . 1994-05-06 15:37:56 +00:00
Jim Meyering
556cdce5c8 . 1994-05-06 15:28:01 +00:00
Jim Meyering
3118577120 . 1994-05-02 04:26:07 +00:00
Jim Meyering
bd3061bed9 merge with 1.9.4j 1994-05-01 16:23:17 +00:00
Jim Meyering
92434b0b67 . 1994-05-01 13:28:12 +00:00
Jim Meyering
2812688dfc . 1994-04-29 22:26:57 +00:00
Jim Meyering
23441bf2ab merge with 1.9.4i 1994-04-28 18:43:36 +00:00
Jim Meyering
d90d17e378 Initial revision 1994-04-28 18:39:34 +00:00
Jim Meyering
f770080426 . 1994-04-28 16:53:41 +00:00
Jim Meyering
07474b189d . 1994-04-27 17:33:22 +00:00
Jim Meyering
4fe59aa3b9 merge with 1.9.4h 1994-04-25 19:08:47 +00:00
Jim Meyering
085c609f77 merge with 1.9.4g 1994-04-25 18:34:37 +00:00
Jim Meyering
36f920112b . 1994-04-25 17:01:36 +00:00
Jim Meyering
256a906698 merge with 1.9.4f 1994-04-25 16:34:49 +00:00
Jim Meyering
7c68f857d0 Revert 1.14-1.16 changes that removed difftm and modified get_date. 1994-04-24 12:48:45 +00:00
Jim Meyering
e628e7bb9e . 1994-04-20 00:23:45 +00:00
Jim Meyering
33955663ad merge with 1.9.4e 1994-04-19 13:40:42 +00:00
Jim Meyering
e614cf3cbb . 1994-04-19 02:30:46 +00:00
Jim Meyering
f1e3280296 . 1994-04-19 00:45:54 +00:00
Jim Meyering
85274fb910 (main): Give a reason for failure when given no
non-option arguments, rather than just the pointer to --help.
1994-04-16 01:36:40 +00:00
Jim Meyering
b26bc02086 . 1994-04-16 01:22:56 +00:00
Jim Meyering
85842e28eb . 1994-04-13 17:12:17 +00:00
Jim Meyering
baaac7ac25 . 1994-04-13 15:26:17 +00:00
Jim Meyering
7960ad7d8b . 1994-04-11 22:22:23 +00:00
Jim Meyering
abbc6f5242 . 1994-04-11 22:03:06 +00:00
Jim Meyering
9bc0437bab merge with 1.9.4d 1994-04-04 22:19:22 +00:00
Jim Meyering
196ad04add . 1994-03-30 13:51:09 +00:00
Jim Meyering
de330273f1 (prline): Remove unused function. 1994-03-28 14:22:52 +00:00
Jim Meyering
2c2e515911 indent 1994-03-28 14:21:26 +00:00
Jim Meyering
23ae451acb merge with 1.9.1e 1994-03-26 00:19:13 +00:00
Jim Meyering
88049ac444 . 1994-03-25 23:42:14 +00:00
Jim Meyering
8bf5a6ed18 . 1994-03-25 23:38:00 +00:00
Jim Meyering
8bcd22c510 . 1994-03-25 23:17:21 +00:00
Jim Meyering
eaf35aca32 merge with 1.9.4c 1994-03-25 17:22:11 +00:00
Jim Meyering
91bfcc7c16 merge with 1.9.4b 1994-03-23 16:56:16 +00:00
Jim Meyering
945f1c9781 (adjust_blocks): Code it as a function again. 1994-03-16 14:47:59 +00:00
Jim Meyering
239d98e18d . 1994-03-16 14:32:26 +00:00
Jim Meyering
3e13a5f6dc . 1994-03-14 18:47:31 +00:00
Jim Meyering
bd25077b16 . 1994-03-14 18:41:13 +00:00
Jim Meyering
f2b1a05bff . 1994-03-14 16:24:52 +00:00
Jim Meyering
cbd7649260 . 1994-03-14 14:54:14 +00:00
Jim Meyering
77e63b2236 merge with 1.9.4a 1994-03-08 16:01:14 +00:00
Jim Meyering
dde7c39a92 . 1994-03-08 15:31:04 +00:00
Jim Meyering
d7fbc5eaba . 1994-03-08 15:30:19 +00:00
Jim Meyering
31b899e2e1 merge with 1.9.4 1994-02-20 17:01:44 +00:00
Jim Meyering
01b914a12e merge with 1.9.3 1994-02-19 19:49:02 +00:00
Jim Meyering
695581bf65 * stty.c (main): Use getopt only to recognize long options.
Hand code the loop to detect -a, -g, -ag and -ga.  Using getopt
to detect the short options loses (because we have to ignore
unrecognized options and we are allowing GNU getopt to permute)
because e.g. `-tabs' is interpreted as a group of options, one of
which is `-a'.  Before, running `stty -tabs echo' gave this error:
 stty: when specifying an output style, modes may not be set
Reported by Arne H. Juul.
1994-02-16 23:36:41 +00:00
Jim Meyering
4923c48619 . 1994-02-16 23:36:20 +00:00
Jim Meyering
c6f59f7abe . 1994-02-14 21:19:12 +00:00
Jim Meyering
e4aba2047a . 1994-02-13 20:27:08 +00:00
Jim Meyering
fd69d39c66 . 1994-02-13 20:03:47 +00:00
Jim Meyering
026dac4594 (main): Change optind' to k'. 1994-02-13 20:02:41 +00:00
Jim Meyering
86af3d8f1b (main): Use parse_long_options.
Rework option handling so stty no longer ignores arguments.
1994-02-13 19:59:52 +00:00
Jim Meyering
1731098e4d (set_window_size): Patch from Rick Sladkey. 1994-02-13 19:58:25 +00:00
Jim Meyering
380435c33b merge with 1.9.2j 1994-02-13 16:39:44 +00:00
Jim Meyering
9935449e9d merge with 1.9.2i 1994-02-12 17:23:44 +00:00
Jim Meyering
4caa3d07cf merge with 1.9.2g 1994-02-10 19:14:24 +00:00
Jim Meyering
589f6b1c17 CIBAUD hack for SunOS 4.1.x 1994-02-10 18:30:08 +00:00
Jim Meyering
a751e87562 . 1994-02-10 14:59:01 +00:00
Jim Meyering
75a474834b . 1994-02-01 14:11:50 +00:00
Jim Meyering
525ecdfbe1 . 1994-02-01 14:01:26 +00:00
Jim Meyering
7b3845a4a5 . 1994-01-29 19:06:23 +00:00
Jim Meyering
200b442ee4 . 1994-01-29 18:31:36 +00:00
Jim Meyering
ad82404564 . 1994-01-26 19:19:14 +00:00
Jim Meyering
d5dc4b055f . 1994-01-26 18:58:08 +00:00
Jim Meyering
c6756ec787 . 1994-01-26 18:51:44 +00:00
Jim Meyering
f1adf86d09 merge with 3.9c 1994-01-26 18:46:41 +00:00
Jim Meyering
63e9766256 . 1994-01-26 18:22:44 +00:00
Jim Meyering
35b0248480 . 1994-01-26 18:20:04 +00:00
Jim Meyering
5629153f1e . 1994-01-26 18:19:10 +00:00
Jim Meyering
2b16e3652c . 1994-01-26 17:48:15 +00:00
Jim Meyering
ac736f7cdc . 1994-01-26 16:08:35 +00:00
Jim Meyering
370edcd71f merge with 1.9.2e 1994-01-24 20:46:23 +00:00
Jim Meyering
a63a148116 Revert last change -- timing showed 10% speedup w/o stream I/O. 1994-01-11 05:52:05 +00:00
Jim Meyering
cd7ed8b383 Use fwrite insted of write. 1994-01-11 05:50:45 +00:00
Jim Meyering
1fc09c536b merge with 1.9.1c 1994-01-09 19:20:32 +00:00
Jim Meyering
07cd9a8d15 safe_read and full_write + join patch 1994-01-09 03:47:21 +00:00
Jim Meyering
4f90578a4f * who.c (print_entry): Prepend `/dev/' only if ut_line is not
already an absolute filename.  Just to be safe.
1994-01-07 00:06:38 +00:00
Jim Meyering
5bed1ce3db merge with 1.9.2d 1994-01-03 06:22:54 +00:00
Jim Meyering
82a7098474 merge with 1.9.2c 1994-01-03 05:22:20 +00:00
Jim Meyering
2c921595f2 . 1993-12-29 06:16:08 +00:00
Jim Meyering
8067b6fb73 . 1993-12-29 06:13:37 +00:00
Jim Meyering
9a30fc037e . 1993-12-29 05:07:52 +00:00
Jim Meyering
39f2fdda08 merge with 1.9.2b 1993-12-29 04:40:30 +00:00
Jim Meyering
3ffdef958d . 1993-12-28 23:46:12 +00:00
Jim Meyering
0f5e2eba7c . 1993-12-28 23:22:03 +00:00
Jim Meyering
704a7eba4a who.c 1993-12-28 21:18:17 +00:00
Jim Meyering
2db44d14e4 merge with 1.9.1b 1993-12-23 19:11:21 +00:00
Jim Meyering
5fbc4e2384 merge with 1.9.2a 1993-12-23 00:38:35 +00:00
Jim Meyering
d7daf7444e . 1993-12-23 00:08:23 +00:00
Jim Meyering
797585985f . 1993-12-22 22:41:00 +00:00
Jim Meyering
9883bf7280 . 1993-12-22 22:15:29 +00:00
Jim Meyering
7061c33d7b (set_fields): Convert ranges like 3-5,6- into 3-.
Before, this was off-by-two and converted 3-5,4-, but not 3-5,5-
1993-12-19 06:20:51 +00:00
Jim Meyering
0311e952db merge with 1.9.1a 1993-12-17 23:51:12 +00:00
Jim Meyering
f4c0b38042 merge with 3.9b 1993-12-17 23:12:34 +00:00
Jim Meyering
22110bde07 merge with 1.9.2 1993-12-02 18:31:46 +00:00
Jim Meyering
a8e2420def merge with 1.9.1c 1993-11-30 16:07:29 +00:00
Jim Meyering
4ebaf0fd9c merge with 1.9.1b 1993-11-30 15:51:34 +00:00
Jim Meyering
80d70870f5 * (main): If an adjustment is specified, but no command is
given, give a diagnostic in addition to the usage message.
(isinteger): Accept a leading `+'.
1993-11-27 21:59:45 +00:00
Jim Meyering
3ea7d72957 Redefine TIOCGWINSZ to TCGETS for Solaris. 1993-11-27 00:05:27 +00:00
Jim Meyering
22ba8f3323 merge with 1.9.1a 1993-11-20 17:00:37 +00:00
Jim Meyering
700f99c873 utmpx changes 1993-11-20 06:00:00 +00:00
Jim Meyering
76b0654112 merge with 1.9.1 1993-11-16 14:38:08 +00:00
Jim Meyering
bef401e8dc fix typo in comment 1993-11-15 16:05:00 +00:00
Jim Meyering
8c26c6bbba merge with 1.9.1 1993-11-15 15:58:21 +00:00
Jim Meyering
c75156c7c8 merge with 1.9.1 1993-11-15 15:57:55 +00:00
Jim Meyering
4bce07bc25 merge with 1.9a 1993-11-15 14:32:17 +00:00
Jim Meyering
39fd5971dd merge with 1.9 1993-11-10 06:05:02 +00:00
Jim Meyering
a1b9bc9a42 merge with 1.9 1993-11-09 13:21:32 +00:00
Jim Meyering
2d0c47b8aa merge with 1.9 1993-11-07 06:09:50 +00:00
Jim Meyering
56deeee42b merge with 1.8.1b 1993-11-02 22:10:58 +00:00
Jim Meyering
693e5c427a merge with 1.8.1k 1993-11-02 20:26:05 +00:00
Jim Meyering
c7ebcc8326 merge with 1.8.1a 1993-10-30 15:57:46 +00:00
Jim Meyering
01e9d7611a merge with 1.8.1 1993-10-28 04:34:57 +00:00
Jim Meyering
5f5fe4ae6d merge with 3.9a 1993-10-27 16:30:36 +00:00
Jim Meyering
ce4dbc8513 merge with 3.9a 1993-10-26 23:39:04 +00:00
Jim Meyering
f5da03589e merge with 1.8i 1993-10-26 01:19:12 +00:00
Jim Meyering
d7c526e66d merge with 1.8.1i 1993-10-26 00:11:14 +00:00
Jim Meyering
cfe240bbd8 merge with 1.8.1h 1993-10-24 21:30:08 +00:00
Jim Meyering
3bc2827212 merge with 1.8h 1993-10-24 20:00:39 +00:00
Jim Meyering
6d920eca0c merge with 1.8g 1993-10-24 19:04:12 +00:00
Jim Meyering
cd908e158d merge with 1.8f 1993-10-23 16:06:33 +00:00
Jim Meyering
b869639f46 merge with 1.8d+ 1993-10-23 15:37:19 +00:00
Jim Meyering
d1df8c198d merge with 1.8d 1993-10-21 22:08:53 +00:00
Jim Meyering
df1e389479 merge with 1.8c 1993-10-21 17:19:34 +00:00
Jim Meyering
193e68abd4 merge with 3.9 1993-10-21 14:48:03 +00:00
Jim Meyering
0f8257073a * memchr.c (memchr): Do the 32-bit assignment only if !LONG_64_BITS.
In the 64-bit assignment, be careful to cast the shift operand to
long.
Abort if sizeof (unsigned long) > 8.
1993-10-21 00:10:34 +00:00
Jim Meyering
e9220f5117 * [MAX]: Macro renamed from max and moved to top of file.
* (bytes_to_octal_digits): New static array.
* (get_format_flags): Combine '+' and ' ' cases of switch stmt.
Return count if for loop terminates.  Otherwise --suffix=%- would lose.
* (get_format_width): Use `bytes_to_octal_digits' instead of just 11.
* (get_format_prec): Make sure is_negative is defined before used.
* (get_format_conv_type): Give a different error message if there
is no conversion specifier.
Test ISPRINT (ch) instead of `ch < '~' && ch > ' ''.
* (max_out): Use `%%' rather than `%' in format string.
1993-10-20 02:17:05 +00:00
Jim Meyering
c24cb37374 Remove register keyword (replace with `int' in two cases). 1993-10-20 02:09:45 +00:00
Jim Meyering
4a18680233 patch from rfg 1993-10-20 02:08:24 +00:00
Jim Meyering
723d3d528d merge with 3.8.4k 1993-10-19 00:00:06 +00:00
Jim Meyering
712ac6d5a0 add newline back, but only for --help output 1993-10-18 03:22:20 +00:00
Jim Meyering
47ff7adaa2 Change fprintf (stdout' to printf ('. 1993-10-18 03:11:02 +00:00
Jim Meyering
ce559ec2e5 remove extra newline in usage message 1993-10-18 03:03:07 +00:00
Jim Meyering
53c1f3e4c6 [member]: Don't cast index() to an int. That is wrong on systems with 64-bit
pointers.
1993-10-18 02:50:21 +00:00
Jim Meyering
64b0b993f6 merge with 3.8.4h 1993-10-18 02:17:58 +00:00
Jim Meyering
214c19a8b3 merge with 3.8.4g 1993-10-17 22:43:10 +00:00
Jim Meyering
1958250cc6 [!NINDIR]: Define BSIZE only if it's not already defined. 1993-10-17 22:31:39 +00:00
Jim Meyering
fa7a1e19e2 merge with 1.8.1g 1993-10-17 03:57:04 +00:00
Jim Meyering
6e1a4cca68 merge with 1.8b 1993-10-17 02:57:45 +00:00
Jim Meyering
c2b140693b merge with 3.8.4f 1993-10-16 22:55:37 +00:00
Jim Meyering
6a06c02f21 (main): When argc == 1, don't try to xmalloc (0). 1993-10-16 14:47:43 +00:00
Jim Meyering
20905f2c93 merge with 3.8.4e 1993-10-13 22:30:38 +00:00
Jim Meyering
7691d2fba0 merge with 3.8.4c 1993-10-12 20:24:09 +00:00
Jim Meyering
ff6b97e13e merge with 1.8.1e 1993-10-12 20:13:45 +00:00
Jim Meyering
44c053f008 merge with 1.8.1d 1993-10-12 14:49:11 +00:00
Jim Meyering
9cfcec5b05 merge with 3.8.4b 1993-10-12 04:30:50 +00:00
Jim Meyering
d463bda066 merge with 1.8.1c 1993-10-12 02:42:06 +00:00
Jim Meyering
87fa23e641 merge with 1.8.1b 1993-10-12 01:52:24 +00:00
Jim Meyering
f12b53b2ce merge with 3.8.4 1993-10-09 20:49:07 +00:00
Jim Meyering
87372cd3ae merge with 3.8.3e 1993-10-09 20:44:16 +00:00
Jim Meyering
4ab2d8f53a merge with 3.8.3e 1993-10-09 20:43:31 +00:00
Jim Meyering
ae89477b9b merge with 3.8.3e 1993-10-09 20:43:10 +00:00
Jim Meyering
95f7eb6267 merge with 3.8.3d 1993-10-08 00:51:10 +00:00
Jim Meyering
d9d6720b77 merge with 3.8.3c 1993-10-07 00:41:21 +00:00
176 changed files with 37648 additions and 8691 deletions

17
doc/.cvsignore Normal file
View File

@@ -0,0 +1,17 @@
Makefile
fileutils.info
version.texi
fileutils.log
fileutils.dvi
fileutils.aux
fileutils.toc
fileutils.cp
fileutils.fn
fileutils.vr
fileutils.tp
fileutils.ky
fileutils.pg
fileutils.cm
fileutils.fl
fileutils.op
fileutils.cps

104
doc/Makefile.in Normal file
View File

@@ -0,0 +1,104 @@
# Makefile for GNU file utilities documentation.
# Copyright (C) 1994, 1995 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.
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = @srcdir@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
prefix = @prefix@
infodir = $(prefix)/info
.SUFFIXES:
DISTFILES = Makefile.in texinfo.tex fileutils.texi fileutils.info \
version.texi perm.texi getdate.texi
all: fileutils.info
info: fileutils.info
version.texi: ../src/version.c
sed -e '/version_string/!d' \
-e 's/[^0-9.]*\([0-9.a-z]*\).*/@set VERSION \1/' \
-e q $(srcdir)/../src/version.c \
> $@-t
echo '@set RELEASEDATE '`date '+%B %Y'` >> $@-t
mv $@-t $@
fileutils.info: fileutils.texi version.texi
$(MAKEINFO) -I$(srcdir) --no-split fileutils.texi --output=$@
dvi: fileutils.dvi
fileutils.dvi: fileutils.texi version.texi texinfo.tex
$(TEXI2DVI) $(srcdir)/fileutils.texi
installdirs:
$(srcdir)/../mkinstalldirs $(infodir)
install: install-exec install-data
install-exec:
install-data: all installdirs
cd $(srcdir) && for file in fileutils.info; do \
$(INSTALL_DATA) $$file $(infodir)/$$file; \
done
uninstall:
rm -f $(infodir)/fileutils.info
check:
texclean:
rm -f *.aux *.cp *.dvi *.fn *.ky *.log *.pg *.toc *.tp *.vr \
*.fl *.cm *.op *.cps
mostlyclean: texclean
rm -f *.info
clean: mostlyclean
distclean: clean
rm -f Makefile
maintainer-clean: distclean
@echo "This command is intended for use by maintainers;"
@echo "it deletes files that may require special tools to rebuild."
rm -f fileutils.info version.texi
distdir = ../`cat ../distname`/$(subdir)
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file $(distdir) \
|| { echo copying $$file instead; cp -p $$file $(distdir);}; \
done
subdir = doc
Makefile: ../config.status Makefile.in
cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
.PHONY: all check clean dist distclean dvi info install install-data \
install-exec installdirs maintainer-clean mostlyclean texclean uninstall
# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

483
doc/getdate.texi Normal file
View File

@@ -0,0 +1,483 @@
@ifinfo
@set Francois Franc,ois
@end ifinfo
@tex
@set Francois Fran\noexpand\ptexc cois
@end tex
@node Date input formats
@chapter Date input formats
@cindex date input formats
@findex getdate
This section describes the textual date representations that GNU
programs accept. These are the strings you, as a user, can supply as
arguments to the various programs. The C interface (via the
@code{getdate} function) is not described here.
@cindex beginning of time, for Unix
@cindex epoch, for Unix
Although the date syntax here can represent any possible time since zero
A.D., computer integers are not big enough for such a (comparatively)
long time. The earliest date semantically allowed on Unix systems is
midnight, 1 January 1970 UCT.
@menu
* General date syntax:: Common rules.
* Calendar date item:: 19 Dec 1994.
* Time of day item:: 9:20pm.
* Timezone item:: EST, DST, BST, UCT, AHST, ...
* Day of week item:: Monday and others.
* Relative item in date strings:: next tuesday, 2 years ago.
* Pure numbers in date strings:: 19931219, 1440.
* Authors of getdate:: Bellovin, Salz, Berets, et al.
@end menu
@node General date syntax
@section General date syntax
@cindex general date syntax
@cindex items in date strings
A @dfn{date} is a string, possibly empty, containing many items
separated by whitespace. The whitespace may be omitted when no
ambiguity arises. The empty string means the beginning of today (i.e.,
midnight). Order of the items is immaterial. A date string may contain
many flavors of items:
@itemize @bullet
@item calendar date items
@item time of the day items
@item time zone items
@item day of the week items
@item relative items
@item pure numbers.
@end itemize
@noindent We describe each of these item types in turn, below.
@cindex numbers, written-out
@cindex ordinal numbers
@findex first @r{in date strings}
@findex next @r{in date strings}
@findex last @r{in date strings}
A few numbers may be written out in words in most contexts. This is
most useful for specifying day of the week items or relative items (see
below). Here is the list: @samp{first} for 1, @samp{next} for 2,
@samp{third} for 3, @samp{fourth} for 4, @samp{fifth} for 5,
@samp{sixth} for 6, @samp{seventh} for 7, @samp{eighth} for 8,
@samp{ninth} for 9, @samp{tenth} for 10, @samp{eleventh} for 11 and
@samp{twelfth} for 12. Also, @samp{last} means exactly @math{-1}.
@cindex months, written-out
When a month is written this way, it is still considered to be written
numerically, instead of being ``spelled in full''; this changes the
allowed strings.
@cindex case, ignored in dates
@cindex comments, in dates
Alphabetic case is completely ignored in dates. Comments may be introduced
between round parentheses, as long as included parentheses are properly
nested. Hyphens not followed by a digit are currently ignored. Leading
zeros on numbers are ignored.
@node Calendar date item
@section Calendar date item
@cindex calendar date item
A @dfn{calendar date item} specifies a day of the year. It is
specified differently, depending on whether the month is specified
numerically or literally. All these strings specify the same calendar date:
@example
1970-9-17 # ISO 8601.
70-9-17 # This century assumed by default.
70-09-17 # Leading zeros are ignored.
9/17/72 # Common U.S. writing.
24 September 1972
24 Sept 72 # September has a special abbreviation.
24 Sep 72 # Three-letter abbreviations always allowed.
Sep 24, 1972
24-sep-72
24sep72
@end example
The year can also be omitted. In this case, the last specified year is
used, or the current year if none. For example:
@example
9/17
sep 17
@end example
Here are the rules.
@cindex ISO 8601 date format
@cindex date format, ISO 8601
For numeric months, the ISO 8601 format
@samp{@var{year}-@var{month}-@var{day}} is allowed, where @var{year} is
any positive number, @var{month} is a number between 1 and 12, and
@var{day} is a number between 1 and 31. If @var{year} is less than 100,
then 1900 is added to it to force a date in this century. The construct
@samp{@var{month}/@var{day}/@var{year}}, popular in the United States,
is accepted. Also @samp{@var{month}/@var{day}}, omitting the year.
@cindex month names in date strings
@cindex abbreviations for months
Literal months may be spelled out in full: @samp{January},
@samp{February}, @samp{March}, @samp{April}, @samp{May}, @samp{June},
@samp{July}, @samp{August}, @samp{September}, @samp{October},
@samp{November} or @samp{December}. Literal months may be abbreviated
to their first three letters, possibly followed by an abbreviating dot.
It is also permitted to write @samp{Sept} instead of @samp{September}.
When months are written literally, the calendar date may be given as any
of the following:
@example
@var{day} @var{month} @var{year}
@var{day} @var{month}
@var{month} @var{day} @var{year}
@var{day}-@var{month}-@var{year}
@end example
Or, omitting the year:
@example
@var{month} @var{day}
@end example
@node Time of day item
@section Time of day item
@cindex time of day item
A @dfn{time of day item} in date strings specifies the time on a given
day. Here are some examples, all of which represent the same time:
@example
20:02:0
20:02
8:02pm
20:02-0500 # In EST (Eastern U.S. Standard Time).
@end example
More generally, the time of the day may be given as
@samp{@var{hour}:@var{minute}:@var{second}}, where @var{hour} is
a number between 0 and 23, @var{minute} is a number between 0 and
59, and @var{second} is a number between 0 and 59. Alternatively,
@samp{:@var{second}} can be omitted, in which case it is taken to
be zero.
@findex am @r{in date strings}
@findex pm @r{in date strings}
@findex midnight @r{in date strings}
@findex noon @r{in date strings}
If the time is followed by @samp{am} or @samp{pm} (or @samp{a.m.}
or @samp{p.m.}), @var{hour} is restricted to run from 1 to 12, and
@samp{:@var{minute}} may be omitted (taken to be zero). @samp{am}
indicates the first half of the day, @samp{pm} indicates the second
half of the day. In this notation, 12 is the predecessor of 1:
midnight is @samp{12am} while noon is @samp{12pm}.
@cindex timezone correction
@cindex minutes, timezone correction by
The time may alternatively be followed by a timezone correction,
expressed as @samp{@var{s}@var{hh}@var{mm}}, where @var{s} is @samp{+}
or @samp{-}, @var{hh} is a number of zone hours and @var{mm} is a number
of zone minutes. When a timezone correction is given this way, it
forces interpretation of the time in UTC, overriding any previous
specification for the timezone or the local timezone. The @var{minute}
part of the time of the day may not be elided when a timezone correction
is used. This is the only way to specify a timezone correction by
fractional parts of an hour.
Either @samp{am}/@samp{pm} or a timezone correction may be specified,
but not both.
@node Timezone item
@section Timezone item
@cindex timezone item
A @dfn{timezone item} specifies an international timezone, indicated by
a small set of letters. Any included period is ignored. Military
timezone designations use a single letter. Currently, only integral
zone hours may be represented in a timezone item. See the previous
section for a finer control over the timezone correction.
Here are many non-daylight-savings-time timezones, indexed by the zone
hour value.
@table @asis
@item +000
@cindex Greenwich Mean Time
@cindex Universal Coordinated Time
@cindex Western European Time
@samp{GMT} for Greenwich Mean, @samp{UT} or @samp{UTC} for Universal
(Coordinated), @samp{WET} for Western European and @samp{Z} for
militaries.
@item +100
@cindex West African Time
@samp{WAT} for West Africa and
@samp{A} for militaries.
@item +200
@cindex Azores Time
@samp{AT} for Azores and @samp{B} for militaries.
@item +300
@samp{C} for militaries.
@item +400
@cindex Atlantic Standard Time
@samp{AST} for Atlantic Standard and @samp{D} for militaries.
@item +500
@cindex Eastern Standard Time
@samp{E} for militaries and @samp{EST} for Eastern Standard.
@item +600
@cindex Central Standard Time
@samp{CST} for Central Standard and @samp{F} for militaries.
@item +700
@cindex Mountain Standard Time
@samp{G} for militaries and @samp{MST} for Mountain Standard.
@item +800
@cindex Pacific Standard Time
@samp{H} for militaries and @samp{PST} for Pacific Standard.
@item +900
@cindex Yukon Standard Time
@samp{I} for militaries and @samp{YST} for Yukon Standard.
@item +1000
@cindex Alaska-Hawaii Time
@cindex Central Alaska Time
@cindex Hawaii Standard Time
@samp{AHST} for Alaska-Hawaii Standard, @samp{CAT} for Central Alaska,
@samp{HST} for Hawaii Standard and @samp{K} for militaries.
@item +1100
@cindex Nome Standard Time
@samp{L} for militaries and @samp{NT} for Nome.
@item +1200
@cindex International Date Line West
@samp{IDLW} for International Date Line West and @samp{M} for
militaries.
@item -100
@cindex Central European Time
@cindex Middle European Time
@cindex Middle European Winter Time
@cindex French Winter Time
@cindex Swedish Winter Time
@samp{CET} for Central European, @samp{FWT} for French Winter,
@samp{MET} for Middle European, @samp{MEWT} for Middle European
Winter, @samp{N} for militaries and @samp{SWT} for Swedish Winter.
@item -200
@cindex Eastern European Time
@cindex USSR Zone
@samp{EET} for Eastern European, USSR Zone 1 and @samp{O} for militaries.
@item -300
@cindex Baghdad Time
@samp{BT} for Baghdad, USSR Zone 2 and @samp{P} for militaries.
@item -400
@samp{Q} for militaries and @samp{ZP4} for USSR Zone 3.
@item -500
@samp{R} for militaries and @samp{ZP5} for USSR Zone 4.
@item -600
@samp{S} for militaries and @samp{ZP6} for USSR Zone 5.
@item -700
@cindex West Australian Standard Time
@samp{T} for militaries and @samp{WAST} for West Australian Standard.
@item -800
@cindex China Coast Time
@samp{CCT} for China Coast, USSR Zone 7 and @samp{U} for militaries.
@item -900
@cindex Japan Standard Time
@samp{JST} for Japan Standard, USSR Zone 8 and @samp{V} for militaries.
@item -1000
@cindex East Australian Standard Time
@cindex Guam Standard Time
@samp{EAST} for East Australian Standard, @samp{GST} for Guam
Standard, USSR Zone 9 and @samp{W} for militaries.
@item -1100
@samp{X} for militaries.
@item -1200
@cindex International Date Line East
@cindex New Zealand Standard Time
@samp{IDLE} for International Date Line East, @samp{NZST} for
New Zealand Standard, @samp{NZT} for New Zealand and @samp{Y} for
militaries.
@end table
@cindex daylight savings time
Here are many DST timezones, indexed by the zone hour value. Also, by
following a non-DST timezone by the string @samp{DST} in a separate word
(that is, separated by some whitespace), the corresponding DST timezone
may be specified.
@table @asis
@item 0
@samp{BST} for British Summer.
@item +400
@samp{ADT} for Atlantic Daylight.
@item +500
@samp{EDT} for Eastern Daylight.
@item +600
@samp{CDT} for Central Daylight.
@item +700
@samp{MDT} for Mountain Daylight.
@item +800
@samp{PDT} for Pacific Daylight.
@item +900
@samp{YDT} for Yukon Daylight.
@item +1000
@samp{HDT} for Hawaii Daylight.
@item -100
@samp{MEST} for Middle European Summer, @samp{MESZ} for Middle European
Summer, @samp{SST} for Swedish Summer and @samp{FST} for French Summer.
@item -700
@samp{WADT} for West Australian Daylight.
@item -1000
@samp{EADT} for Eastern Australian Daylight.
@item -1200
@samp{NZDT} for New Zealand Daylight.
@end table
@node Day of week item
@section Day of week item
@cindex day of week item
The explicit mention of a day of the week will forward the date
(only if necessary) to reach that day of the week in the future.
Days of the week may be spelled out in full: @samp{Sunday},
@samp{Monday}, @samp{Tuesday}, @samp{Wednesday}, @samp{Thursday},
@samp{Friday} or @samp{Saturday}. Days may be abbreviated to their
first three letters, optionally followed by a period. The special
abbreviations @samp{Tues} for @samp{Tuesday}, @samp{Wednes} for
@samp{Wednesday} and @samp{Thur} or @samp{Thurs} for @samp{Thursday} are
also allowed.
@findex next @var{day}
@findex last @var{day}
A number may precede a day of the week item to move forward
supplementary weeks. It is best used in expression like @samp{third
monday}. In this context, @samp{last @var{day}} or @samp{next
@var{day}} is also acceptable; they move one week before or after
the day that @var{day} by itself would represent.
A comma following a day of the week item is ignored.
@node Relative item in date strings
@section Relative item in date strings
@cindex relative items in date strings
@cindex displacement of dates
@dfn{Relative items} adjust a date (or the current date if none) forward
or backward. The effects of relative items accumulate. Here are some
examples:
@example
1 year
1 year ago
3 years
2 days
@end example
@findex year @r{in date strings}
@findex month @r{in date strings}
@findex fortnight @r{in date strings}
@findex week @r{in date strings}
@findex day @r{in date strings}
@findex hour @r{in date strings}
@findex minute @r{in date strings}
The unit of time displacement may be selected by the string @samp{year}
or @samp{month} for moving by whole years or months. These are fuzzy
units, as years and months are not all of equal duration. More precise
units are @samp{fortnight} which is worth 14 days, @samp{week} worth 7
days, @samp{day} worth 24 hours, @samp{hour} worth 60 minutes,
@samp{minute} or @samp{min} worth 60 seconds, and @samp{second} or
@samp{sec} worth one second. An @samp{s} suffix on these units is
accepted and ignored.
@findex ago @r{in date strings}
The unit of time may be preceded by a multiplier, given as an optionally
signed number. Unsigned numbers are taken as positively signed. No
number at all implies 1 for a multiplier. Following a relative item by
the string @samp{ago} is equivalent to preceding the unit by a
multiplicator with value @math{-1}.
@findex day @r{in date strings}
@findex tomorrow @r{in date strings}
@findex yesterday @r{in date strings}
The string @samp{tomorrow} is worth one day in the future (equivalent
to @samp{day}), the string @samp{yesterday} is worth
one day in the past (equivalent to @samp{day ago}).
@findex now @r{in date strings}
@findex today @r{in date strings}
@findex this @r{in date strings}
The strings @samp{now} or @samp{today} are relative items corresponding
to zero-valued time displacement, these strings come from the fact
a zero-valued time displacement represents the current time when not
otherwise change by previous items. They may be used to stress other
items, like in @samp{12:00 today}. The string @samp{this} also has
the meaning of a zero-valued time displacement, but is preferred in
date strings like @samp{this thursday}.
When a relative item makes the resulting date to cross the boundary
between DST and non-DST (or vice-versa), the hour is adjusted according
to the local time.
@node Pure numbers in date strings
@section Pure numbers in date strings
@cindex pure numbers in date strings
The precise intepretation of a pure decimal number is dependent of
the context in the date string.
If the decimal number is of the form @var{yyyy}@var{mm}@var{dd} and no
other calendar date item (@pxref{Calendar date item}) appears before it
in the date string, then @var{yyyy} is read as the year, @var{mm} as the
month number and @var{dd} as the day of the month, for the specified
calendar date.
If the decimal number is of the form @var{hh}@var{mm} and no other time
of day item appears before it in the date string, then @var{hh} is read
as the hour of the day and @var{mm} as the minute of the hour, for the
specified time of the day. @var{mm} can also be omitted.
If both a calendar date and a time of day appear to the left of a number
in the date string, but no relative item, then the number overrides the
year.
@node Authors of getdate
@section Authors of @code{getdate}
@cindex authors of @code{getdate}
@cindex Bellovin, Steven M.
@cindex Salz, Rich
@cindex Berets, Jim
@cindex MacKenzie, David
@cindex Meyering, Jim
@code{getdate} was originally implemented by Steven M. Bellovin
(@samp{smb@@research.att.com}) while at the University of North Carolina
at Chapel Hill. The code was later tweaked by a couple of people on
Usenet, then completely overhauled by Rich $alz (@samp{rsalz@@bbn.com})
and Jim Berets (@samp{jberets@@bbn.com}) in August, 1990. Various
revisions for the GNU system were made by David MacKenzie, Jim Meyering,
and others.
@cindex Pinard, F.
@cindex Berry, K.
This chapter was originally produced by @value{Francois} Pinard
(@samp{pinard@@iro.umontreal.ca}) from the @file{getdate.y} source code,
and then edited by K.@: Berry (@samp{kb@@cs.umb.edu}).

481
doc/perm.texi Normal file
View File

@@ -0,0 +1,481 @@
Each file has a set of @dfn{permissions} that control the kinds of
access that users have to that file. The permissions for a file are
also called its @dfn{access mode}. They can be represented either in
symbolic form or as an octal number.
@menu
* Mode Structure:: Structure of file permissions.
* Symbolic Modes:: Mnemonic permissions representation.
* Numeric Modes:: Permissions as octal numbers.
@end menu
@node Mode Structure
@section Structure of File Permissions
There are three kinds of permissions that a user can have for a file:
@enumerate
@item
@cindex read permission
permission to read the file. For directories, this means permission to
list the contents of the directory.
@item
@cindex write permission
permission to write to (change) the file. For directories, this means
permission to create and remove files in the directory.
@item
@cindex execute permission
permission to execute the file (run it as a program). For directories,
this means permission to access files in the directory.
@end enumerate
There are three categories of users who may have different permissions
to perform any of the above operations on a file:
@enumerate
@item
the file's owner;
@item
other users who are in the file's group;
@item
everyone else.
@end enumerate
@cindex owner, default
@cindex group owner, default
Files are given an owner and group when they are created. Usually the
owner is the current user and the group is the group of the directory
the file is in, but this varies with the operating system, the
filesystem the file is created on, and the way the file is created. You
can change the owner and group of a file by using the @code{chown} and
@code{chgrp} commands.
In addition to the three sets of three permissions listed above, a
file's permissions have three special components, which affect only
executable files (programs) and, on some systems, directories:
@enumerate
@item
@cindex setuid
set the process's effective user ID to that of the file upon execution
(called the @dfn{setuid bit}). No effect on directories.
@item
@cindex setgid
set the process's effective group ID to that of the file upon execution
(called the @dfn{setgid bit}). For directories on some systems, put
files created in the directory into the same group as the directory, no
matter what group the user who creates them is in.
@item
@cindex sticky
@cindex swap space, saving text image in
@cindex text image, saving in swap space
@cindex append-only directories
save the program's text image on the swap device so it will load more
quickly when run (called the @dfn{sticky bit}). For directories on some
systems, prevent users from removing files that they do not own in the
directory; this is called making the directory @dfn{append-only}.
@end enumerate
@node Symbolic Modes
@section Symbolic Modes
@cindex symbolic modes
@dfn{Symbolic modes} represent changes to files' permissions as
operations on single-character symbols. They allow you to modify either
all or selected parts of files' permissions, optionally based on
their previous values, and perhaps on the current @code{umask} as well
(@pxref{Umask and Protection}).
The format of symbolic modes is:
@example
@r{[}ugoa@dots{}@r{][[}+-=@r{][}rwxXstugo@dots{}@r{]}@dots{}@r{][},@dots{}@r{]}
@end example
The following sections describe the operators and other details of
symbolic modes.
@menu
* Setting Permissions:: Basic operations on permissions.
* Copying Permissions:: Copying existing permissions.
* Changing Special Permissions:: Special permissions.
* Conditional Executability:: Conditionally affecting executability.
* Multiple Changes:: Making multiple changes.
* Umask and Protection:: The effect of the umask.
@end menu
@node Setting Permissions
@subsection Setting Permissions
The basic symbolic operations on a file's permissions are adding,
removing, and setting the permission that certain users have to read,
write, and execute the file. These operations have the following
format:
@example
@var{users} @var{operation} @var{permissions}
@end example
@noindent
The spaces between the three parts above are shown for readability only;
symbolic modes can not contain spaces.
The @var{users} part tells which users' access to the file is changed.
It consists of one or more of the following letters (or it can be empty;
@pxref{Umask and Protection}, for a description of what happens then). When
more than one of these letters is given, the order that they are in does
not matter.
@table @code
@item u
@cindex owner of file, permissions for
the user who owns the file;
@item g
@cindex group, permissions for
other users who are in the file's group;
@item o
@cindex other permissions
all other users;
@item a
all users; the same as @samp{ugo}.
@end table
The @var{operation} part tells how to change the affected users' access
to the file, and is one of the following symbols:
@table @code
@item +
@cindex adding permissions
to add the @var{permissions} to whatever permissions the @var{users}
already have for the file;
@item -
@cindex removing permissions
@cindex subtracting permissions
to remove the @var{permissions} from whatever permissions the
@var{users} already have for the file;
@item =
@cindex setting permissions
to make the @var{permissions} the only permissions that the @var{users}
have for the file.
@end table
The @var{permissions} part tells what kind of access to the file should
be changed; it is zero or more of the following letters. As with the
@var{users} part, the order does not matter when more than one letter is
given. Omitting the @var{permissions} part is useful only with the
@samp{=} operation, where it gives the specified @var{users} no access
at all to the file.
@table @code
@item r
@cindex read permission, symbolic
the permission the @var{users} have to read the file;
@item w
@cindex write permission, symbolic
the permission the @var{users} have to write to the file;
@item x
@cindex execute permission, symbolic
the permission the @var{users} have to execute the file.
@end table
For example, to give everyone permission to read and write a file,
but not to execute it, use:
@example
a=rw
@end example
To remove write permission for from all users other than the file's
owner, use:
@example
go-w
@end example
@noindent
The above command does not affect the access that the owner of
the file has to it, nor does it affect whether other users can
read or execute the file.
To give everyone except a file's owner no permission to do anything with
that file, use the mode below. Other users could still remove the file,
if they have write permission on the directory it is in.
@example
go=
@end example
@noindent
Another way to specify the same thing is:
@example
og-rxw
@end example
@node Copying Permissions
@subsection Copying Existing Permissions
@cindex copying existing permissions
@cindex permissions, copying existing
You can base part of a file's permissions on part of its existing
permissions. To do this, instead of using @samp{r}, @samp{w}, or
@samp{x} after the operator, you use the letter @samp{u}, @samp{g}, or
@samp{o}. For example, the mode
@example
o+g
@end example
@noindent
@c FIXME describe the ls -l notation for showing permissions.
adds the permissions for users who are in a file's group to the
permissions that other users have for the file. Thus, if the file
started out as mode 664 (@samp{rw-rw-r--}), the above mode would change
it to mode 666 (@samp{rw-rw-rw-}). If the file had started out as mode
741 (@samp{rwxr----x}), the above mode would change it to mode 745
(@samp{rwxr--r-x}). The @samp{-} and @samp{=} operations work
analogously.
@node Changing Special Permissions
@subsection Changing Special Permissions
@cindex changing special permissions
In addition to changing a file's read, write, and execute permissions,
you can change its special permissions. @xref{Mode Structure}, for a
summary of these permissions.
To change a file's permission to set the user ID on execution, use
@samp{u} in the @var{users} part of the symbolic mode and
@samp{s} in the @var{permissions} part.
To change a file's permission to set the group ID on execution, use
@samp{g} in the @var{users} part of the symbolic mode and
@samp{s} in the @var{permissions} part.
To change a file's permission to stay permanently on the swap device,
use @samp{o} in the @var{users} part of the symbolic mode and
@samp{t} in the @var{permissions} part.
For example, to add set user ID permission to a program,
you can use the mode:
@example
u+s
@end example
To remove both set user ID and set group ID permission from
it, you can use the mode:
@example
ug-s
@end example
To cause a program to be saved on the swap device, you can use
the mode:
@example
o+t
@end example
Remember that the special permissions only affect files that are
executable, plus, on some systems, directories (on which they have
different meanings; @pxref{Mode Structure}). Using @samp{a}
in the @var{users} part of a symbolic mode does not cause the special
permissions to be affected; thus,
@example
a+s
@end example
@noindent
has @emph{no effect}. You must use @samp{u}, @samp{g}, and @samp{o}
explicitly to affect the special permissions. Also, the
combinations @samp{u+t}, @samp{g+t}, and @samp{o+s} have no effect.
The @samp{=} operator is not very useful with special permissions; for
example, the mode:
@example
o=t
@end example
@noindent
does cause the file to be saved on the swap device, but it also
removes all read, write, and execute permissions that users not in the
file's group might have had for it.
@node Conditional Executability
@subsection Conditional Executability
@cindex conditional executability
There is one more special type of symbolic permission: if you use
@samp{X} instead of @samp{x}, execute permission is affected only if the
file already had execute permission or is a directory. It affects
directories' execute permission even if they did not initially have any
execute permissions set.
For example, this mode:
@example
a+X
@end example
@noindent
gives all users permission to execute files (or search directories) if
anyone could before.
@node Multiple Changes
@subsection Making Multiple Changes
@cindex multiple changes to permissions
The format of symbolic modes is actually more complex than described
above (@pxref{Setting Permissions}). It provides two ways to make
multiple changes to files' permissions.
The first way is to specify multiple @var{operation} and
@var{permissions} parts after a @var{users} part in the symbolic mode.
For example, the mode:
@example
og+rX-w
@end example
@noindent
gives users other than the owner of the file read permission and, if
it is a directory or if someone already had execute permission
to it, gives them execute permission; and it also denies them write
permission to it file. It does not affect the permission that the
owner of the file has for it. The above mode is equivalent to
the two modes:
@example
og+rX
og-w
@end example
The second way to make multiple changes is to specify more than one
simple symbolic mode, separated by commas. For example, the mode:
@example
a+r,go-w
@end example
@noindent
gives everyone permission to read the file and removes write
permission on it for all users except its owner. Another example:
@example
u=rwx,g=rx,o=
@end example
@noindent
sets all of the non-special permissions for the file explicitly. (It
gives users who are not in the file's group no permission at all for
it.)
The two methods can be combined. The mode:
@example
a+r,g+x-w
@end example
@noindent
gives all users permission to read the file, and gives users who are in
the file's group permission to execute it, as well, but not permission
to write to it. The above mode could be written in several different
ways; another is:
@example
u+r,g+rx,o+r,g-w
@end example
@node Umask and Protection
@subsection The Umask and Protection
@cindex umask and modes
@cindex modes and umask
If the @var{users} part of a symbolic mode is omitted, it defaults to
@samp{a} (affect all users), except that any permissions that are
@emph{set} in the system variable @code{umask} are @emph{not affected}.
The value of @code{umask} can be set using the
@code{umask} command. Its default value varies from system to system.
@cindex giving away permissions
Omitting the @var{users} part of a symbolic mode is generally not useful
with operations other than @samp{+}. It is useful with @samp{+} because
it allows you to use @code{umask} as an easily customizable protection
against giving away more permission to files than you intended to.
As an example, if @code{umask} has the value 2, which removes write
permission for users who are not in the file's group, then the mode:
@example
+w
@end example
@noindent
adds permission to write to the file to its owner and to other users who
are in the file's group, but @emph{not} to other users. In contrast,
the mode:
@example
a+w
@end example
@noindent
ignores @code{umask}, and @emph{does} give write permission for
the file to all users.
@node Numeric Modes
@section Numeric Modes
@cindex numeric modes
@cindex file permissions, numeric
@cindex octal numbers for file modes
File permissions are stored internally as 16 bit integers. As an
alternative to giving a symbolic mode, you can give an octal (base 8)
number that corresponds to the internal representation of the new mode.
This number is always interpreted in octal; you do not have to add a
leading 0, as you do in C. Mode 0055 is the same as mode 55.
A numeric mode is usually shorter than the corresponding symbolic
mode, but it is limited in that it can not take into account a file's
previous permissions; it can only set them absolutely.
The permissions granted to the user, to other users in the file's group,
and to other users not in the file's group are each stored as three
bits, which are represented as one octal digit. The three special
permissions are also each stored as one bit, and they are as a group
represented as another octal digit. Here is how the bits are arranged
in the 16 bit integer, starting with the lowest valued bit:
@example
Value in Corresponding
Mode Permission
Other users not in the file's group:
1 Execute
2 Write
4 Read
Other users in the file's group:
10 Execute
20 Write
40 Read
The file's owner:
100 Execute
200 Write
400 Read
Special permissions:
1000 Save text image on swap device
2000 Set group ID on execution
4000 Set user ID on execution
@end example
For example, numeric mode 4755 corresponds to symbolic mode
@samp{u=rwxs,go=rx}, and numeric mode 664 corresponds to symbolic mode
@samp{ug=rw,o=r}. Numeric mode 0 corresponds to symbolic mode
@samp{ugo=}.

2894
doc/sh-utils.texi Normal file

File diff suppressed because it is too large Load Diff

4421
doc/texinfo.tex Normal file

File diff suppressed because it is too large Load Diff

3237
doc/textutils.texi Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,8 @@
Makefile
getdate.c
posixtm.c
safe-stat.h
safe-stat.c
safe-lstat.c
safe-lstat.h
getdate.tab.c

View File

@@ -1,5 +1,5 @@
# Makefile for library files used by GNU fileutils.
# Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
# Makefile for library files used by GNU file utilities.
# Copyright (C) 1990, 1991, 1992, 1993, 1994 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
@@ -25,33 +25,51 @@ AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
YACC = @YACC@
exec_prefix = @exec_prefix@
libdir = $(exec_prefix)/lib
SOURCES = getdate.y posixtm.y \
argmatch.c backupfile.c basename.c dirname.c eaccess.c \
error.c filemode.c fsusage.c getopt.c getopt1.c \
getversion.c idcache.c isdir.c makepath.c \
modechange.c mountlist.c savedir.c \
argmatch.c backupfile.c basename.c dirname.c euidaccess.c \
error.c filemode.c fsusage.c full-write.c getopt.c getopt1.c \
getversion.c group-member.c idcache.c isdir.c makepath.c \
modechange.c mountlist.c obstack.c safe-read.c savedir.c \
stripslash.c xgetcwd.c xmalloc.c xstrdup.c userspec.c yesno.c \
fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
strdup.c strstr.c alloca.c
fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c rmdir.c \
save-cwd.c stpcpy.c \
strdup.c strstr.c strtol.c strtoul.c alloca.c long-options.c \
memcmp.c memcpy.c memset.c xstrtol.c xstrtoul.c
OBJECTS = getdate.o posixtm.o \
argmatch.o backupfile.o basename.o dirname.o eaccess.o \
error.o filemode.o getopt.o getopt1.o \
getversion.o idcache.o isdir.o makepath.o \
modechange.o savedir.o \
argmatch.o backupfile.o basename.o dirname.o \
error.o filemode.o full-write.o getopt.o getopt1.o \
getversion.o group-member.o idcache.o isdir.o long-options.o makepath.o \
modechange.o obstack.o safe-read.o save-cwd.o savedir.o \
stripslash.o xgetcwd.o xmalloc.o xstrdup.o userspec.o yesno.o \
@LIBOBJS@ @ALLOCA@
xstrtol.o xstrtoul.o @LIBOBJS@ @ALLOCA@
DISTFILES = Makefile.in backupfile.h getopt.h modechange.h \
fnmatch.h fsusage.h mountlist.h pathmax.h system.h $(SOURCES)
DISTFILES = Makefile.in backupfile.h getopt.h long-options.h modechange.h \
fnmatch.h fsusage.h group-member.h makepath.h mountlist.h obstack.h pathmax.h \
save-cwd.h getdate.c posixtm.c error.h xstrtol.h xstrtoul.h $(SOURCES)
all: libfu.a
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I.. -I$(srcdir) $(CFLAGS) $<
.SUFFIXES:
.SUFFIXES: .c .o
install: all
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
INCLUDES = -I.. -I$(srcdir)
.c.o:
$(COMPILE) $<
subdir = lib
Makefile: ../config.status Makefile.in
cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
installdirs:
install install-exec install-data: all
uninstall:
@@ -66,15 +84,17 @@ clean:
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c getdate.c *posixtm.c
rm -f Makefile *.tab.c tposixtm.c
rm -rf .deps
realclean: distclean
rm -f TAGS
maintainer-clean: distclean
rm -f TAGS getdate.c posixtm.c
dist:
distdir = ../`cat ../distname`/$(subdir)
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
ln $$file $(distdir) \
|| { echo copying $$file instead; cp -p $$file $(distdir);}; \
done
libfu.a: $(OBJECTS)
@@ -85,7 +105,7 @@ libfu.a: $(OBJECTS)
# Since this directory contains two parsers, we have to be careful to avoid
# running two $(YACC)s during parallel makes. See below.
getdate.c: getdate.y
@echo expect 9 shift/reduce conflicts
@echo expect 10 shift/reduce conflicts
$(YACC) $(srcdir)/getdate.y
mv y.tab.c getdate.c
@@ -100,6 +120,12 @@ posixtm.c: posixtm.y getdate.c
mv tposixtm.c posixtm.c
rm -f posixtm.tab.c
rename.o: rename.c
$(CC) -c $(CPPFLAGS) -DMVDIR="\"$(libdir)/mvdir\"" $(DEFS) \
-I.. -I$(srcdir) $(CFLAGS) $(srcdir)/rename.c
$(OBJECTS): ../config.h
backupfile.o getversion.o: backupfile.h
fnmatch.o: fnmatch.h
fsusage.o: fsusage.h
@@ -107,7 +133,18 @@ getopt1.o: getopt.h
modechange.o: modechange.h
mountlist.o: mountlist.h
xgetcwd.o: pathmax.h
makepath.o: makepath.h
obstack.o: obstack.h
group-member.o: group-member.h
.PHONY: all check clean dist distclean install install-data install-exec \
installdirs maintainer-clean mostlyclean uninstall
# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# The following include directive is uncommented automatically
# when this package is configured with the --with-autodep option.
# You need GNU make and a C compiler that can generate dependencies.
@AUTODEP_COMMENT@include @top_srcdir@/mkdep-Makefile

View File

@@ -17,6 +17,12 @@
/* Written by David MacKenzie <djm@ai.mit.edu> */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#ifdef STDC_HEADERS
#include <string.h>
@@ -35,12 +41,12 @@ argmatch (arg, optlist)
char **optlist;
{
int i; /* Temporary index in OPTLIST. */
int arglen; /* Length of ARG. */
size_t arglen; /* Length of ARG. */
int matchind = -1; /* Index of first nonexact match. */
int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
arglen = strlen (arg);
/* Test all elements for either exact match or abbreviated matches. */
for (i = 0; optlist[i]; i++)
{

View File

@@ -19,68 +19,56 @@
Some algorithms adapted from GNU Emacs. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
# include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include "backupfile.h"
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#ifndef index
#define index strchr
#endif
#ifndef rindex
#define rindex strrchr
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
#include <strings.h>
# include <strings.h>
#endif
#if defined(DIRENT) || defined(_POSIX_VERSION)
#include <dirent.h>
#define NLENGTH(direct) (strlen((direct)->d_name))
#else /* not (DIRENT or _POSIX_VERSION) */
#define dirent direct
#define NLENGTH(direct) ((direct)->d_namlen)
#ifdef SYSNDIR
#include <sys/ndir.h>
#endif /* SYSNDIR */
#ifdef SYSDIR
#include <sys/dir.h>
#endif /* SYSDIR */
#ifdef NDIR
#include <ndir.h>
#endif /* NDIR */
#endif /* DIRENT or _POSIX_VERSION */
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NLENGTH(direct) (strlen((direct)->d_name))
#else /* not HAVE_DIRENT_H */
# define dirent direct
# define NLENGTH(direct) ((direct)->d_namlen)
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#ifdef VOID_CLOSEDIR
#ifdef CLOSEDIR_VOID
/* Fake a return value. */
#define CLOSEDIR(d) (closedir (d), 0)
# define CLOSEDIR(d) (closedir (d), 0)
#else
#define CLOSEDIR(d) closedir (d)
# define CLOSEDIR(d) closedir (d)
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
# include <stdlib.h>
#else
char *malloc ();
#endif
#if !defined (isascii) || defined (STDC_HEADERS)
#undef isascii
#define isascii(c) 1
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
# define ISASCII(c) 1
#else
# define ISASCII(c) isascii(c)
#endif
#define ISDIGIT(c) (isascii ((unsigned char ) c) \
#define ISDIGIT(c) (ISASCII ((unsigned char) (c)) \
&& isdigit ((unsigned char) (c)))
#if defined (HAVE_UNISTD_H)
@@ -90,9 +78,9 @@ char *malloc ();
#if defined (_POSIX_VERSION)
/* POSIX does not require that the d_ino field be present, and some
systems do not provide it. */
#define REAL_DIR_ENTRY(dp) 1
# define REAL_DIR_ENTRY(dp) 1
#else
#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
# define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
#endif
/* Which type of backup file names are generated. */
@@ -156,11 +144,11 @@ max_backup_version (file, dir)
int highest_version;
int this_version;
int file_name_length;
dirp = opendir (dir);
if (!dirp)
return 0;
highest_version = 0;
file_name_length = strlen (file);
@@ -168,7 +156,7 @@ max_backup_version (file, dir)
{
if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
continue;
this_version = version_number (file, dp->d_name, file_name_length);
if (this_version > highest_version)
highest_version = this_version;
@@ -207,7 +195,7 @@ version_number (base, backup, base_length)
{
int version;
char *p;
version = 0;
if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
{

View File

@@ -15,21 +15,27 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined(USG) || defined(STDC_HEADERS)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#define rindex strrchr
#else
#include <strings.h>
#ifndef strrchr
#define strrchr rindex
#endif
#endif
/* Return NAME with any leading path stripped off. */
char *
basename (name)
char *name;
const char *name;
{
char *base;
base = rindex (name, '/');
return base ? base + 1 : name;
base = strrchr (name, '/');
return base ? base + 1 : (char *) name;
}

View File

@@ -16,14 +16,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#ifdef STDC_HEADERS
@@ -33,11 +26,11 @@ char *malloc ();
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#ifndef rindex
#define rindex strrchr
#endif
#else
#include <strings.h>
#ifndef strrchr
#define strrchr rindex
#endif
#endif
/* Return the leading directories part of PATH,
@@ -53,7 +46,7 @@ dirname (path)
char *slash;
int length; /* Length of result, not including NUL. */
slash = rindex (path, '/');
slash = strrchr (path, '/');
if (slash == 0)
{
/* File is in the current directory. */
@@ -68,7 +61,7 @@ dirname (path)
length = slash - path + 1;
}
newpath = malloc (length + 1);
newpath = (char *) malloc (length + 1);
if (newpath == 0)
return 0;
strncpy (newpath, path, length);

View File

@@ -1,5 +1,5 @@
/* error.c -- error handler for noninteractive utilities
Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94, 95 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
@@ -15,40 +15,51 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by David MacKenzie. */
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#ifdef HAVE_VPRINTF
#if HAVE_VPRINTF || HAVE_DOPRNT
# if __STDC__
# include <stdarg.h>
# define VA_START(args, lastarg) va_start(args, lastarg)
# else
# include <varargs.h>
# define VA_START(args, lastarg) va_start(args)
# endif
#else
# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
#endif
#if __STDC__
#include <stdarg.h>
#define VA_START(args, lastarg) va_start(args, lastarg)
#else /* !__STDC__ */
#include <varargs.h>
#define VA_START(args, lastarg) va_start(args)
#endif /* !__STDC__ */
#else /* !HAVE_VPRINTF */
#ifdef HAVE_DOPRNT
#define va_alist args
#define va_dcl int args;
#else /* !HAVE_DOPRNT */
#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
#endif /* !HAVE_DOPRNT */
#endif /* !HAVE_VPRINTF */
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#else /* !STDC_HEADERS */
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
void exit ();
#endif /* !STDC_HEADERS */
#endif
#ifndef HAVE_STRERROR
/* This variable is incremented each time `error' is called. */
unsigned int error_message_count;
/* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space. Otherwise, error will call this
function without parameters instead. */
void (*error_print_progname) () = NULL;
/* The calling program should define program_name and set it to the
name of the executing program. */
extern char *program_name;
#if HAVE_STRERROR
# ifndef strerror /* On some systems, strerror is a macro */
char *strerror ();
# endif
#else
static char *
private_strerror (errnum)
int errnum;
@@ -61,41 +72,51 @@ private_strerror (errnum)
return "Unknown system error";
}
#define strerror private_strerror
#endif /* !HAVE_STRERROR */
#endif
/* Print the program name and error message MESSAGE, which is a printf-style
format string with optional args.
If ERRNUM is nonzero, print its corresponding system error message.
Exit with status STATUS if it is nonzero. */
/* VARARGS */
void
#if defined (HAVE_VPRINTF) && __STDC__
error (int status, int errnum, char *message, ...)
#else /* !HAVE_VPRINTF or !__STDC__ */
#if defined(VA_START) && __STDC__
error (int status, int errnum, const char *message, ...)
#else
error (status, errnum, message, va_alist)
int status;
int errnum;
char *message;
va_dcl
#endif /* !HAVE_VPRINTF or !__STDC__ */
#endif
{
extern char *program_name;
#ifdef HAVE_VPRINTF
#ifdef VA_START
va_list args;
#endif /* HAVE_VPRINTF */
#endif
fprintf (stderr, "%s: ", program_name);
#ifdef HAVE_VPRINTF
if (error_print_progname)
(*error_print_progname) ();
else
{
fflush (stdout);
fprintf (stderr, "%s: ", program_name);
}
#ifdef VA_START
VA_START (args, message);
# if HAVE_VPRINTF
vfprintf (stderr, message, args);
# else
_doprnt (message, args, stderr);
# endif
va_end (args);
#else /* !HAVE_VPRINTF */
#ifdef HAVE_DOPRNT
_doprnt (message, &args, stderr);
#else /* !HAVE_DOPRNT */
#else
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
#endif /* !HAVE_DOPRNT */
#endif /* !HAVE_VPRINTF */
#endif
++error_message_count;
if (errnum)
fprintf (stderr, ": %s", strerror (errnum));
putc ('\n', stderr);

44
lib/error.h Normal file
View File

@@ -0,0 +1,44 @@
/* error.h -- declaration for error-reporting function
Copyright (C) 1995 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _error_h_
#define _error_h_
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
# define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format
# define __printf__ printf
# endif
#endif
#if __STDC__
void error (int, int, const char *, ...) \
__attribute__ ((__format__ (__printf__, 3, 4)));
#else
void error ();
#endif
/* This variable is incremented each time `error' is called. */
extern unsigned int error_message_count;
#endif /* _error_h_ */

171
lib/euidaccess.c Normal file
View File

@@ -0,0 +1,171 @@
/* euidaccess -- check if effective user id can access file
Copyright (C) 1990, 1991, 1995 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* Written by David MacKenzie and Torbjorn Granlund.
Adapted for GNU C library by Roland McGrath. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef S_IEXEC
#ifndef S_IXUSR
#define S_IXUSR S_IEXEC
#endif
#ifndef S_IXGRP
#define S_IXGRP (S_IEXEC >> 3)
#endif
#ifndef S_IXOTH
#define S_IXOTH (S_IEXEC >> 6)
#endif
#endif /* S_IEXEC */
#if defined (HAVE_UNISTD_H) || defined (_LIBC)
#include <unistd.h>
#endif
#ifdef _POSIX_VERSION
#include <limits.h>
#if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
#undef NGROUPS_MAX
#define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
#endif /* NGROUPS_MAX */
#else /* not _POSIX_VERSION */
uid_t getuid ();
gid_t getgid ();
uid_t geteuid ();
gid_t getegid ();
#include <sys/param.h>
#if !defined(NGROUPS_MAX) && defined(NGROUPS)
#define NGROUPS_MAX NGROUPS
#endif /* not NGROUPS_MAX and NGROUPS */
#endif /* not POSIX_VERSION */
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#if defined(EACCES) && !defined(EACCESS)
#define EACCESS EACCES
#endif
#ifndef F_OK
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
#endif
#ifdef _LIBC
#define group_member __group_member
#else
/* The user's real user id. */
static uid_t uid;
/* The user's real group id. */
static gid_t gid;
/* The user's effective user id. */
static uid_t euid;
/* The user's effective group id. */
static gid_t egid;
/* Nonzero if UID, GID, EUID, and EGID have valid values. */
static int have_ids = 0;
#ifdef HAVE_GETGROUPS
int group_member ();
#else
#define group_member(gid) 0
#endif
#endif
/* Return 0 if the user has permission of type MODE on file PATH;
otherwise, return -1 and set `errno' to EACCESS.
Like access, except that it uses the effective user and group
id's instead of the real ones, and it does not check for read-only
filesystem, text busy, etc. */
int
euidaccess (path, mode)
const char *path;
int mode;
{
struct stat stats;
int granted;
#ifdef _LIBC
uid_t uid = getuid (), euid = geteuid ();
gid_t gid = getgid (), egid = getegid ();
#else
if (have_ids == 0)
{
have_ids = 1;
uid = getuid ();
gid = getgid ();
euid = geteuid ();
egid = getegid ();
}
#endif
if (uid == euid && gid == egid)
/* If we are not set-uid or set-gid, access does the same. */
return access (path, mode);
if (stat (path, &stats))
return -1;
mode &= (X_OK | W_OK | R_OK); /* Clear any bogus bits. */
#if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
?error Oops, portability assumptions incorrect.
#endif
if (mode == F_OK)
return 0; /* The file exists. */
/* The super-user can read and write any file, and execute any file
that anyone can execute. */
if (euid == 0 && ((mode & X_OK) == 0
|| (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
return 0;
if (euid == stats.st_uid)
granted = (unsigned) (stats.st_mode & (mode << 6)) >> 6;
else if (egid == stats.st_gid || group_member (stats.st_gid))
granted = (unsigned) (stats.st_mode & (mode << 3)) >> 3;
else
granted = (stats.st_mode & mode);
if (granted == mode)
return 0;
errno = EACCESS;
return -1;
}

View File

@@ -17,14 +17,20 @@
/* Written by Brian L. Matthews, blm@6sceng.UUCP. */
#if !defined (HAVE_ST_BLOCKS) && !defined(_POSIX_SOURCE)
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !defined (HAVE_ST_BLOCKS) && !defined(_POSIX_VERSION)
#include <sys/types.h>
#include <sys/param.h>
#ifndef NINDIR
/* Some SysV's, like Irix, seem to lack these. Hope they're correct. */
/* Size of a indirect block, in bytes. */
#ifndef BSIZE
#define BSIZE 1024
#endif
/* Number of inode pointers per indirect block. */
#define NINDIR (BSIZE/sizeof(daddr_t))

View File

@@ -1,5 +1,5 @@
/* filemode.c -- make a string describing file modes
Copyright (C) 1985, 1990 Free Software Foundation, Inc.
Copyright (C) 1985, 1990, 1993 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
@@ -15,36 +15,70 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifndef S_IREAD
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
#define S_IEXEC S_IXUSR
#if !S_IRUSR
# if S_IREAD
# define S_IRUSR S_IREAD
# else
# define S_IRUSR 00400
# endif
#endif
#ifndef S_ISREG /* Doesn't have POSIX.1 stat stuff. */
#define mode_t unsigned short
#if !S_IWUSR
# if S_IWRITE
# define S_IWUSR S_IWRITE
# else
# define S_IWUSR 00200
# endif
#endif
#if !S_IXUSR
# if S_IEXEC
# define S_IXUSR S_IEXEC
# else
# define S_IXUSR 00100
# endif
#endif
#ifdef STAT_MACROS_BROKEN
#undef S_ISBLK
#undef S_ISCHR
#undef S_ISDIR
#undef S_ISFIFO
#undef S_ISLNK
#undef S_ISMPB
#undef S_ISMPC
#undef S_ISNWK
#undef S_ISREG
#undef S_ISSOCK
#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISBLK) && defined(S_IFBLK)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined(S_ISCHR) && defined(S_IFCHR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG) && defined(S_IFREG)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISFIFO) && defined(S_IFIFO)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISLNK) && defined(S_IFLNK)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
@@ -111,7 +145,7 @@ mode_string (mode, str)
unsigned short mode;
char *str;
{
str[0] = ftypelet (mode);
str[0] = ftypelet ((long) mode);
rwx ((mode & 0700) << 0, &str[1]);
rwx ((mode & 0070) << 3, &str[4]);
rwx ((mode & 0007) << 6, &str[7]);
@@ -132,7 +166,7 @@ mode_string (mode, str)
static char
ftypelet (bits)
mode_t bits;
long bits;
{
#ifdef S_ISBLK
if (S_ISBLK (bits))
@@ -175,9 +209,9 @@ rwx (bits, chars)
unsigned short bits;
char *chars;
{
chars[0] = (bits & S_IREAD) ? 'r' : '-';
chars[1] = (bits & S_IWRITE) ? 'w' : '-';
chars[2] = (bits & S_IEXEC) ? 'x' : '-';
chars[0] = (bits & S_IRUSR) ? 'r' : '-';
chars[1] = (bits & S_IWUSR) ? 'w' : '-';
chars[2] = (bits & S_IXUSR) ? 'x' : '-';
}
/* Set the 's' and 't' flags in file attributes string CHARS,

View File

@@ -1,19 +1,21 @@
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
This library is distributed in the hope that it will be useful,
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
Library General Public License for more details.
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 Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -35,7 +37,7 @@ Cambridge, MA 02139, USA. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
#ifndef errno
extern int errno;
#endif

View File

@@ -16,66 +16,64 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include "fsusage.h"
int statfs ();
#if defined (STATFS_OSF1) /* DEC Alpha running OSF/1 */
# include <sys/mount.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if defined(STAT_STATFS2_BSIZE) && !defined(_IBMR2) /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */
#include <sys/mount.h>
#ifdef HAVE_SYS_FILSYS_H
#include <sys/filsys.h> /* SVR2. */
#endif
#ifdef STAT_STATFS2_FS_DATA /* Ultrix. */
#include <sys/param.h>
#include <sys/mount.h>
#endif
#ifdef STAT_READ /* SVR2. */
#include <sys/param.h>
#include <sys/filsys.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if defined(STAT_STATFS4) || (defined(_AIX) && defined(_IBMR2)) /* SVR3, Dynix, Irix, AIX RS6000. */
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if defined(_AIX) && defined(_I386) /* AIX PS/2. */
#include <sys/stat.h>
#ifdef HAVE_DUSTAT_H /* AIX PS/2. */
#include <sys/dustat.h>
#endif
#ifdef STAT_STATVFS /* SVR4. */
#ifdef HAVE_SYS_STATVFS_H /* SVR4. */
#include <sys/statvfs.h>
int statvfs ();
#endif
int safe_read ();
/* Return the number of TOSIZE-byte blocks used by
BLOCKS FROMSIZE-byte blocks, rounding away from zero. */
BLOCKS FROMSIZE-byte blocks, rounding away from zero.
TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */
static long
adjust_blocks (blocks, fromsize, tosize)
long blocks;
int fromsize, tosize;
{
if (tosize <= 0)
abort ();
if (fromsize <= 0)
return -1;
if (fromsize == tosize) /* E.g., from 512 to 512. */
return blocks;
else if (fromsize > tosize) /* E.g., from 2048 to 512. */
@@ -95,28 +93,28 @@ get_fs_usage (path, disk, fsp)
char *path, *disk;
struct fs_usage *fsp;
{
#if defined (STATFS_OSF1)
#if defined (STAT_STATFS3_OSF1)
struct statfs fsd;
if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
return (-1);
#define convert_blocks(b) adjust_blocks ((b),fsd.f_fsize, 512)
#endif /* STATFS_OSF1 */
return -1;
#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512)
#endif /* STAT_STATFS3_OSF1 */
#ifdef STAT_STATFS2_FS_DATA /* Ultrix. */
struct fs_data fsd;
if (statfs (path, &fsd) != 1)
return -1;
#define convert_blocks(b) adjust_blocks ((b), 1024, 512)
fsp->fsu_blocks = convert_blocks (fsd.fd_req.btot);
fsp->fsu_bfree = convert_blocks (fsd.fd_req.bfree);
fsp->fsu_bavail = convert_blocks (fsd.fd_req.bfreen);
#define CONVERT_BLOCKS(b) adjust_blocks ((b), 1024, 512)
fsp->fsu_blocks = CONVERT_BLOCKS (fsd.fd_req.btot);
fsp->fsu_bfree = CONVERT_BLOCKS (fsd.fd_req.bfree);
fsp->fsu_bavail = CONVERT_BLOCKS (fsd.fd_req.bfreen);
fsp->fsu_files = fsd.fd_req.gtot;
fsp->fsu_ffree = fsd.fd_req.gfree;
#endif
#ifdef STAT_READ /* SVR2. */
#ifdef STAT_READ_FILSYS /* SVR2. */
#ifndef SUPERBOFF
#define SUPERBOFF (SUPERB * 512)
#endif
@@ -127,16 +125,16 @@ get_fs_usage (path, disk, fsp)
if (fd < 0)
return -1;
lseek (fd, (long) SUPERBOFF, 0);
if (read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
if (safe_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
{
close (fd);
return -1;
}
close (fd);
#define convert_blocks(b) adjust_blocks ((b), (fsd.s_type == Fs2b ? 1024 : 512), 512)
fsp->fsu_blocks = convert_blocks (fsd.s_fsize);
fsp->fsu_bfree = convert_blocks (fsd.s_tfree);
fsp->fsu_bavail = convert_blocks (fsd.s_tfree);
#define CONVERT_BLOCKS(b) adjust_blocks ((b), (fsd.s_type == Fs2b ? 1024 : 512), 512)
fsp->fsu_blocks = CONVERT_BLOCKS (fsd.s_fsize);
fsp->fsu_bfree = CONVERT_BLOCKS (fsd.s_tfree);
fsp->fsu_bavail = CONVERT_BLOCKS (fsd.s_tfree);
fsp->fsu_files = (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1);
fsp->fsu_ffree = fsd.s_tinode;
#endif
@@ -146,7 +144,22 @@ get_fs_usage (path, disk, fsp)
if (statfs (path, &fsd) < 0)
return -1;
#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512)
#ifdef STATFS_TRUNCATES_BLOCK_COUNTS
/* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
struct statfs are truncated to 2GB. These conditions detect that
truncation, presumably without botching the 4.1.1 case, in which
the values are not truncated. The correct counts are stored in
undocumented spare fields. */
if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0)
{
fsd.f_blocks = fsd.f_spare[0];
fsd.f_bfree = fsd.f_spare[1];
fsd.f_bavail = fsd.f_spare[2];
}
#endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512)
#endif
#ifdef STAT_STATFS2_FSIZE /* 4.4BSD. */
@@ -154,10 +167,10 @@ get_fs_usage (path, disk, fsp)
if (statfs (path, &fsd) < 0)
return -1;
#define convert_blocks(b) adjust_blocks ((b), fsd.f_fsize, 512)
#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512)
#endif
#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix. */
#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX. */
struct statfs fsd;
if (statfs (path, &fsd, sizeof fsd, 0) < 0)
@@ -165,12 +178,16 @@ get_fs_usage (path, disk, fsp)
/* Empirically, the block counts on most SVR3 and SVR3-derived
systems seem to always be in terms of 512-byte blocks,
no matter what value f_bsize has. */
#define convert_blocks(b) (b)
#ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */
#ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
#define f_bavail f_bfree
#endif
#endif
# if _AIX
# define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512)
# else
# define CONVERT_BLOCKS(b) (b)
# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */
# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
# define f_bavail f_bfree
# endif
# endif
# endif
#endif
#ifdef STAT_STATVFS /* SVR4. */
@@ -179,14 +196,14 @@ get_fs_usage (path, disk, fsp)
if (statvfs (path, &fsd) < 0)
return -1;
/* f_frsize isn't guaranteed to be supported. */
#define convert_blocks(b) \
#define CONVERT_BLOCKS(b) \
adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
#endif
#if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ) /* !Ultrix && !SVR2. */
fsp->fsu_blocks = convert_blocks (fsd.f_blocks);
fsp->fsu_bfree = convert_blocks (fsd.f_bfree);
fsp->fsu_bavail = convert_blocks (fsd.f_bavail);
#if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS) /* !Ultrix && !SVR2. */
fsp->fsu_blocks = CONVERT_BLOCKS (fsd.f_blocks);
fsp->fsu_bfree = CONVERT_BLOCKS (fsd.f_bfree);
fsp->fsu_bavail = CONVERT_BLOCKS (fsd.f_bavail);
fsp->fsu_files = fsd.f_files;
fsp->fsu_ffree = fsd.f_ffree;
#endif

View File

@@ -1,10 +1,15 @@
/* ftruncate emulations that work on some System V's.
This file is in the public domain. */
This file is in the public domain. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#ifdef F_CHSIZE
int
ftruncate (fd, length)
int fd;
@@ -12,14 +17,17 @@ ftruncate (fd, length)
{
return fcntl (fd, F_CHSIZE, length);
}
#else
#else /* not F_CHSIZE */
#ifdef F_FREESP
/* The following function was written by
kucharsk@Solbourne.com (William Kucharski) */
/* By William Kucharski <kucharsk@netcom.com>. */
#include <sys/stat.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
int
ftruncate (fd, length)
@@ -44,23 +52,28 @@ ftruncate (fd, length)
}
else
{
/* Truncate length. */
fl.l_whence = 0;
fl.l_len = 0;
fl.l_start = length;
fl.l_type = F_WRLCK; /* Write lock on file space. */
fl.l_type = F_WRLCK; /* write lock on file space */
/* This relies on the *undocumented* F_FREESP argument to fcntl,
which truncates the file so that it ends at the position
indicated by fl.l_start. Will minor miracles never cease? */
/* This relies on the UNDOCUMENTED F_FREESP argument to
fcntl, which truncates the file so that it ends at the
position indicated by fl.l_start.
Will minor miracles never cease? */
if (fcntl (fd, F_FREESP, &fl) < 0)
return -1;
}
return 0;
}
#else
#else /* not F_CHSIZE nor F_FREESP */
#ifdef HAVE_CHSIZE
int
ftruncate (fd, length)
int fd;
@@ -68,5 +81,23 @@ ftruncate (fd, length)
{
return chsize (fd, length);
}
#else /* not F_CHSIZE nor F_FREESP nor HAVE_CHSIZE */
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#endif
int
ftruncate (fd, length)
int fd;
off_t length;
{
errno = EIO;
return -1;
}
#endif /* not HAVE_CHSIZE */
#endif /* not F_FREESP */
#endif /* not F_CHSIZE */

64
lib/full-write.c Normal file
View File

@@ -0,0 +1,64 @@
/* full-write.c -- an interface to write that retries after interrupts
Copyright (C) 1993, 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA.
Copied largely from GNU C's cccp.c.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifndef errno
extern int errno;
#endif
/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
Return LEN upon success, write's (negative) error code otherwise. */
int
full_write (desc, ptr, len)
int desc;
char *ptr;
size_t len;
{
int total_written;
total_written = 0;
while (len > 0)
{
int written = write (desc, ptr, len);
if (written < 0)
{
#ifdef EINTR
if (errno == EINTR)
continue;
#endif
return written;
}
total_written += written;
ptr += written;
len -= written;
}
return total_written;
}

File diff suppressed because it is too large Load Diff

126
lib/getline.c Normal file
View File

@@ -0,0 +1,126 @@
/* getline.c -- Replacement for GNU C library function getline
Copyright (C) 1993 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 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#define NDEBUG
#include <assert.h>
#if STDC_HEADERS
#include <stdlib.h>
#else
char *malloc (), *realloc ();
#endif
/* Always add at least this many bytes when extending the buffer. */
#define MIN_CHUNK 64
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
+ OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
malloc (or NULL), pointing to *N characters of space. It is realloc'd
as necessary. Return the number of characters read (not including the
null terminator), or -1 on error or EOF. */
int
getstr (lineptr, n, stream, terminator, offset)
char **lineptr;
size_t *n;
FILE *stream;
char terminator;
int offset;
{
int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
char *read_pos; /* Where we're reading into *LINEPTR. */
int ret;
if (!lineptr || !n || !stream)
return -1;
if (!*lineptr)
{
*n = MIN_CHUNK;
*lineptr = malloc (*n);
if (!*lineptr)
return -1;
}
nchars_avail = *n - offset;
read_pos = *lineptr + offset;
for (;;)
{
register int c = getc (stream);
/* We always want at least one char left in the buffer, since we
always (unless we get an error while reading the first char)
NUL-terminate the line buffer. */
assert(*n - nchars_avail == read_pos - *lineptr);
if (nchars_avail < 2)
{
if (*n > MIN_CHUNK)
*n *= 2;
else
*n += MIN_CHUNK;
nchars_avail = *n + *lineptr - read_pos;
*lineptr = realloc (*lineptr, *n);
if (!*lineptr)
return -1;
read_pos = *n - nchars_avail + *lineptr;
assert(*n - nchars_avail == read_pos - *lineptr);
}
if (c == EOF || ferror (stream))
{
/* Return partial line, if any. */
if (read_pos == *lineptr)
return -1;
else
break;
}
*read_pos++ = c;
nchars_avail--;
if (c == terminator)
/* Return the line. */
break;
}
/* Done - NUL terminate and return the number of chars read. */
*read_pos = '\0';
ret = read_pos - (*lineptr + offset);
return ret;
}
int
getline (lineptr, n, stream)
char **lineptr;
size_t *n;
FILE *stream;
{
return getstr (lineptr, n, stream, '\n', 0);
}

17
lib/getline.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _getline_h_
#define _getline_h_ 1
#include <stdio.h>
#ifndef __P
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
#define __P(args) args
#else
#define __P(args) ()
#endif /* GCC. */
#endif /* Not __P. */
int
getline __P ((char **_lineptr, size_t *_n, FILE *_stream));
#endif /* _getline_h_ */

View File

@@ -3,7 +3,7 @@
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -20,18 +20,17 @@
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
#ifndef __STDC__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
@@ -39,11 +38,6 @@
#endif
#endif
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
@@ -65,10 +59,16 @@
#include <stdlib.h>
#endif /* GNU C library. */
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
long-named option. Because this is not POSIX.2 compliant, it is
being phased out. */
/* #define GETOPT_COMPAT */
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
# include <libintl.h>
# define _(msgid) gettext (msgid)
#else
# define _(msgid) (msgid)
#endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
@@ -92,7 +92,7 @@
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = 0;
char *optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
@@ -162,6 +162,9 @@ static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
@@ -192,19 +195,18 @@ my_index (str, chr)
}
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it.
(Supposedly there are some machines where it might get a warning,
but changing this conditional to __STDC__ is too risky.) */
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
#ifdef IN_GCC
#include "gstddef.h"
#else
#include <stddef.h>
#endif
extern size_t strlen (const char *);
#endif
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
#if !defined (__STDC__) || !__STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* GNU C library. */
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
@@ -279,6 +281,42 @@ exchange (argv)
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Initialize the internal data when the first call is made. */
static const char *
_getopt_initialize (optstring)
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = optind = 1;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
@@ -345,41 +383,18 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int *longind;
int long_only;
{
int option_index;
optarg = 0;
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
optarg = NULL;
if (optind == 0)
{
first_nonopt = last_nonopt = optind = 1;
nextchar = NULL;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (getenv ("POSIXLY_CORRECT") != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
optstring = _getopt_initialize (optstring);
optind = 1; /* Don't scan ARGV[0], the program name. */
}
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
@@ -390,21 +405,16 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else if (last_nonopt != optind)
first_nonopt = optind;
/* Now skip any additional non-options
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
&& (longopts == NULL
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif /* GETOPT_COMPAT */
)
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
optind++;
last_nonopt = optind;
}
/* Special ARGV-element `--' means premature end of options.
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
@@ -437,12 +447,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
&& (longopts == NULL
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif /* GETOPT_COMPAT */
)
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
{
if (ordering == REQUIRE_ORDER)
return EOF;
@@ -451,36 +456,53 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
/* We have found another option-ARGV-element.
Start decoding its characters. */
Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if (longopts != NULL
&& ((argv[optind][0] == '-'
&& (argv[optind][1] == '-' || long_only))
#ifdef GETOPT_COMPAT
|| argv[optind][0] == '+'
#endif /* GETOPT_COMPAT */
))
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2]
|| !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
char *s = nextchar;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
const struct option *pfound = NULL;
int indfound;
int option_index;
while (*s && *s != '=')
s++;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all options for either exact match or abbreviated matches. */
for (p = longopts, option_index = 0; p->name;
p++, option_index++)
if (!strncmp (p->name, nextchar, s - nextchar))
#ifdef lint
indfound = 0; /* Avoid spurious compiler warning. */
#endif
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if (s - nextchar == strlen (p->name))
if (nameend - nextchar == strlen (p->name))
{
/* Exact match found. */
pfound = p;
@@ -495,14 +517,14 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
indfound = option_index;
}
else
/* Second nonexact match found. */
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, "%s: option `%s' is ambiguous\n",
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
@@ -513,27 +535,26 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
option_index = indfound;
optind++;
if (*s)
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = s + 1;
optarg = nameend + 1;
else
{
if (opterr)
{
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
"%s: option `--%s' doesn't allow an argument\n",
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
"%s: option `%c%s' doesn't allow an argument\n",
argv[0], argv[optind - 1][0], pfound->name);
}
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
@@ -545,8 +566,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else
{
if (opterr)
fprintf (stderr, "%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
@@ -561,25 +583,23 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
return pfound->val;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
#ifdef GETOPT_COMPAT
|| argv[optind][0] == '+'
#endif /* GETOPT_COMPAT */
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, "%s: unrecognized option `--%s'\n",
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
@@ -588,7 +608,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
}
/* Look at and handle the next option-character. */
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
@@ -602,16 +622,13 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
if (opterr)
{
#if 0
if (c < 040 || c >= 0177)
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
if (posixly_correct)
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
#else
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
#endif
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
optopt = c;
return '?';
@@ -627,7 +644,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optind++;
}
else
optarg = 0;
optarg = NULL;
nextchar = NULL;
}
else
@@ -644,14 +661,10 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
if (opterr)
{
#if 0
fprintf (stderr, "%s: option `-%c' requires an argument\n",
argv[0], c);
#else
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: option requires an argument -- %c\n",
argv[0], c);
#endif
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')

View File

@@ -1,5 +1,5 @@
/* Declarations for getopt.
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1989, 90, 91, 92, 93, 94 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
@@ -76,7 +76,7 @@ extern int optopt;
struct option
{
#if __STDC__
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
@@ -94,15 +94,15 @@ struct option
#define required_argument 1
#define optional_argument 2
#if __STDC__
#if defined(__GNU_LIBRARY__)
#if defined (__STDC__) && __STDC__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* not __GNU_LIBRARY__ */
#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
@@ -120,7 +120,7 @@ extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* not __STDC__ */
#endif /* __STDC__ */
#ifdef __cplusplus
}

View File

@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -17,19 +17,12 @@
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include "getopt.h"
#ifndef __STDC__
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const

View File

@@ -17,6 +17,10 @@
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef SHELLS_FILE
/* File containing a list of nonrestricted shells, one per line. */
#define SHELLS_FILE "/etc/shells"
@@ -32,6 +36,8 @@ char *malloc ();
char *realloc ();
#endif
char *xstrdup ();
static int readname ();
/* List of shells to use if the shells file is missing. */
@@ -54,6 +60,8 @@ static char *line = NULL;
static int line_size = 0;
/* Return an entry from the shells file, ignoring comment lines.
If the file doesn't exist, use the list in DEFAULT_SHELLS (above).
In any case, the returned string is in memory allocated through malloc.
Return NULL if there are no more entries. */
char *
@@ -63,7 +71,7 @@ getusershell ()
{
if (default_shells[default_index])
/* Not at the end of the list yet. */
return default_shells[default_index++];
return xstrdup (default_shells[default_index++]);
return NULL;
}
@@ -74,7 +82,7 @@ getusershell ()
{
/* No shells file. Use the default list. */
default_index = 1;
return default_shells[0];
return xstrdup (default_shells[0]);
}
}

151
lib/group-member.c Normal file
View File

@@ -0,0 +1,151 @@
/* group-member.c -- determine whether group id is in calling user's group list
Copyright (C) 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "group-member.h"
char *xmalloc ();
char *xrealloc ();
struct group_info
{
int n_groups;
GETGROUPS_T *group;
};
#ifdef HAVE_GETGROUPS
static void
free_group_info (g)
struct group_info *g;
{
free (g->group);
free (g);
}
static struct group_info *
get_group_info ()
{
int n_groups;
int n_group_slots;
struct group_info *gi;
GETGROUPS_T *group;
/* getgroups () returns the number of elements that it was able to
place into the array. We simply continue to call getgroups ()
until the number of elements placed into the array is smaller than
the physical size of the array. */
group = NULL;
n_groups = 0;
n_group_slots = 0;
while (n_groups == n_group_slots)
{
n_group_slots += 64;
group = (GETGROUPS_T *) xrealloc (group,
n_group_slots * sizeof (GETGROUPS_T));
n_groups = getgroups (n_group_slots, group);
}
/* In case of error, the user loses. */
if (n_groups < 0)
{
free (group);
return NULL;
}
gi = (struct group_info *) xmalloc (sizeof (*gi));
gi->n_groups = n_groups;
gi->group = group;
return gi;
}
#endif /* not HAVE_GETGROUPS */
/* Return non-zero if GID is one that we have in our groups list.
If there is no getgroups function, return non-zero if GID matches
either of the current or effective group IDs. */
int
group_member (gid)
gid_t gid;
{
#ifndef HAVE_GETGROUPS
return ((gid == getgid ()) || (gid == getegid ()));
#else
int i;
int found;
struct group_info *gi;
gi = get_group_info ();
if (gi == NULL)
return 0;
/* Search through the list looking for GID. */
found = 0;
for (i = 0; i < gi->n_groups; i++)
{
if (gid == gi->group[i])
{
found = 1;
break;
}
}
free_group_info (gi);
return found;
#endif /* HAVE_GETGROUPS */
}
#ifdef TEST
char *program_name;
int
main (int argc, char** argv)
{
int i;
program_name = argv[0];
for (i=1; i<argc; i++)
{
gid_t gid;
gid = atoi (argv[i]);
printf ("%d: %s\n", gid, group_member (gid) ? "yes" : "no");
}
exit (0);
}
#endif /* TEST */

7
lib/group-member.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _group_member_h_
#define _group_member_h_ 1
int
group_member ();
#endif /* _group_member_h_ */

View File

@@ -15,11 +15,19 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
/* If PATH is an existing directory or symbolic link to a directory,

View File

@@ -13,7 +13,7 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* A `struct linebuffer' holds a line of text. */
@@ -24,19 +24,20 @@ struct linebuffer
char *buffer;
};
#ifdef __STDC__
#undef __P
#if defined (__STDC__) && __STDC__
#define __P(x) x
#else
#define __P(x) ()
#endif
/* Initialize linebuffer LINEBUFFER for use. */
void initbuffer (struct linebuffer *linebuffer);
void initbuffer __P ((struct linebuffer *linebuffer));
/* Read an arbitrarily long line of text from STREAM into LINEBUFFER.
Remove any newline. Does not null terminate.
Return LINEBUFFER, except at end of file return 0. */
struct linebuffer *readline (struct linebuffer *linebuffer, FILE *stream);
struct linebuffer *readline __P ((struct linebuffer *linebuffer, FILE *stream));
/* Free linebuffer LINEBUFFER and its data, all allocated with malloc. */
void freebuffer (struct linebuffer *);
#else
void initbuffer ();
struct linebuffer *readline ();
void freebuffer ();
#endif
void freebuffer __P ((struct linebuffer *));

79
lib/long-options.c Normal file
View File

@@ -0,0 +1,79 @@
/* Utility to accept --help and --version options as unobtrusively as possible.
Copyright (C) 1993, 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Jim Meyering (meyering@comco.com) */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <getopt.h>
#include "long-options.h"
static struct option const long_options[] =
{
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
/* Process long options --help and --version, but only if argc == 2.
Be careful not to gobble up `--'. */
void
parse_long_options (argc, argv, command_name, version_string, usage)
int argc;
char **argv;
const char *command_name;
const char *version_string;
void (*usage)();
{
int c;
int saved_opterr;
int saved_optind;
saved_opterr = opterr;
saved_optind = optind;
/* Don't print an error message for unrecognized options. */
opterr = 0;
if (argc == 2
&& (c = getopt_long (argc, argv, "+", long_options, (int *) 0)) != EOF)
{
switch (c)
{
case 'h':
(*usage) (0);
case 'v':
printf ("%s - %s\n", command_name, version_string);
exit (0);
default:
/* Don't process any other long-named options. */
break;
}
}
/* Restore previous value. */
opterr = saved_opterr;
/* Restore optind in case it has advanced past a leading `--'. */
optind = saved_optind;
}

10
lib/long-options.h Normal file
View File

@@ -0,0 +1,10 @@
#undef __P
#if defined (__STDC__) && __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
void
parse_long_options __P ((int _argc, char **_argv, const char *_command_name,
const char *_version_string, void (*_usage) (int)));

View File

@@ -19,14 +19,7 @@
Jim Meyering <meyering@cs.utexas.edu>. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#ifdef __GNUC__
@@ -43,17 +36,6 @@ char *alloca ();
#endif
#endif
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -61,11 +43,9 @@ char *alloca ();
#include <unistd.h>
#endif
#ifdef STAT_MACROS_BROKEN
#ifdef S_ISDIR
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif
#endif /* STAT_MACROS_BROKEN. */
#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
@@ -79,17 +59,17 @@ char *alloca ();
#include <errno.h>
#endif
#ifndef STDC_HEADERS
#ifndef errno
extern int errno;
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#ifndef index
#define index strchr
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
#include <strings.h>
# include <strings.h>
# ifndef strchr
# define strchr index
# endif
#endif
#ifdef __MSDOS__
@@ -97,38 +77,57 @@ typedef int uid_t;
typedef int gid_t;
#endif
#include "makepath.h"
void error ();
/* Ensure that the directory ARGPATH exists.
Remove any trailing slashes from ARGPATH before calling this function.
Make any leading directories that don't already exist, with
Create any leading directories that don't already exist, with
permissions PARENT_MODE.
If the last element of ARGPATH does not exist, create it as
a new directory with permissions MODE.
If OWNER and GROUP are non-negative, make them the UID and GID of
created directories.
If OWNER and GROUP are non-negative, use them to set the UID and GID of
any created directories.
If VERBOSE_FMT_STRING is nonzero, use it as a printf format
string for printing a message after successfully making a directory,
with the name of the directory that was just made as an argument.
If PRESERVE_EXISTING is non-zero and ARGPATH is an existing directory,
then do not attempt to set its permissions and ownership.
Return 0 if ARGPATH exists as a directory with the proper
ownership and permissions when done, otherwise 1. */
#if __STDC__
int
make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
char *argpath;
make_path (const char *argpath,
int mode,
int parent_mode,
uid_t owner,
gid_t group,
int preserve_existing,
const char *verbose_fmt_string)
#else
int
make_path (argpath, mode, parent_mode, owner, group, preserve_existing,
verbose_fmt_string)
const char *argpath;
int mode;
int parent_mode;
uid_t owner;
gid_t group;
char *verbose_fmt_string;
int preserve_existing;
const char *verbose_fmt_string;
#endif
{
char *dirpath; /* A copy we can scribble NULs on. */
struct stat stats;
int retval = 0;
int oldmask = umask (0);
/* FIXME: move this alloca and strcpy into the if-block.
Set dirpath to argpath in the else-block. */
dirpath = (char *) alloca (strlen (argpath) + 1);
strcpy (dirpath, argpath);
@@ -163,14 +162,14 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
slash = dirpath;
while (*slash == '/')
slash++;
while ((slash = index (slash, '/')))
while ((slash = strchr (slash, '/')))
{
*slash = '\0';
if (stat (dirpath, &stats))
{
if (mkdir (dirpath, tmp_mode))
{
error (0, errno, "cannot make directory `%s'", dirpath);
error (0, errno, "cannot create directory `%s'", dirpath);
umask (oldmask);
return 1;
}
@@ -215,11 +214,14 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
}
/* We're done making leading directories.
Make the final component of the path. */
Create the final component of the path. */
if (mkdir (dirpath, mode))
/* The path could end in "/." or contain "/..", so test
if we really have to create the directory. */
if (stat (dirpath, &stats) && mkdir (dirpath, mode))
{
error (0, errno, "cannot make directory `%s'", dirpath);
error (0, errno, "cannot create directory `%s'", dirpath);
umask (oldmask);
return 1;
}
@@ -269,26 +271,29 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
return 1;
}
/* chown must precede chmod because on some systems,
chown clears the set[ug]id bits for non-superusers,
resulting in incorrect permissions.
On System V, users can give away files with chown and then not
be able to chmod them. So don't give files away. */
if (!preserve_existing)
{
/* chown must precede chmod because on some systems,
chown clears the set[ug]id bits for non-superusers,
resulting in incorrect permissions.
On System V, users can give away files with chown and then not
be able to chmod them. So don't give files away. */
if (owner != (uid_t) -1 && group != (gid_t) -1
&& chown (dirpath, owner, group)
if (owner != (uid_t) -1 && group != (gid_t) -1
&& chown (dirpath, owner, group)
#ifdef AFS
&& errno != EPERM
&& errno != EPERM
#endif
)
{
error (0, errno, "%s", dirpath);
retval = 1;
}
if (chmod (dirpath, mode))
{
error (0, errno, "%s", dirpath);
retval = 1;
)
{
error (0, errno, "%s", dirpath);
retval = 1;
}
if (chmod (dirpath, mode))
{
error (0, errno, "%s", dirpath);
retval = 1;
}
}
}

15
lib/makepath.h Normal file
View File

@@ -0,0 +1,15 @@
#if __STDC__
#undef __P
#define __P(args) args
#else
#define __P(args) ()
#endif
int
make_path __P ((const char *_argpath,
int _mode,
int _parent_mode,
uid_t _owner,
gid_t _group,
int _preserve_existing,
const char *_verbose_fmt_string));

366
lib/md5.c Normal file
View File

@@ -0,0 +1,366 @@
/* md5.c - Functions to compute MD5 message digest of files or memory blocks
according to the definition of MD5 in RFC 1321 from April 1992.
Copyright (C) 1995 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#include "md5.h"
#ifdef WORDS_BIGENDIAN
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
# define SWAP(n) (n)
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (RFC 1321, 3.1: Step 1) */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
/* Initialize structure containing state of computation.
(RFC 1321, 3.3: Step 3) */
void
md5_init_ctx (ctx)
struct md5_ctx *ctx;
{
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
}
/* Put result from CTX in first 16 bytes following RESBUF. The result must
be in little endian byte order. */
void *
md5_read_ctx (ctx, resbuf)
const struct md5_ctx *ctx;
void *resbuf;
{
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
return resbuf;
}
/* Compute MD5 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
int
md5_stream (stream, resblock)
FILE *stream;
void *resblock;
{
/* Important: BLOCKSIZE must be a multiple of 64. */
#define BLOCKSIZE 4096
struct md5_ctx ctx;
md5_uint32 len[2];
char buffer[BLOCKSIZE + 72];
size_t pad, sum;
/* Initialize the computation context. */
md5_init_ctx (&ctx);
len[0] = 0;
len[1] = 0;
/* Iterate over full file contents. */
while (1)
{
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
computation function processes the whole buffer so that with the
next round of the loop another block can be read. */
size_t n;
sum = 0;
/* Read block. Take care for partial reads. */
do
{
n = fread (buffer, 1, BLOCKSIZE - sum, stream);
sum += n;
}
while (sum < BLOCKSIZE && n != 0);
if (n == 0 && ferror (stream))
return 1;
/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
Here we only compute the number of bytes. Do a double word
increment. */
len[0] += sum;
if (len[0] < sum)
++len[1];
/* If end of file is reached, end the loop. */
if (n == 0)
break;
/* Process buffer with BLOCKSIZE bytes. Note that
BLOCKSIZE % 64 == 0
*/
md5_process_block (buffer, BLOCKSIZE, &ctx);
}
/* We can copy 64 byte because the buffer is always big enough. FILLBUF
contains the needed bits. */
memcpy (&buffer[sum], fillbuf, 64);
/* Compute amount of padding bytes needed. Alignment is done to
(N + PAD) % 64 == 56
There is always at least one byte padded. I.e. even the alignment
is correctly aligned 64 padding bytes are added. */
pad = sum & 63;
pad = pad >= 56 ? 64 + 56 - pad : 56 - pad;
/* Put the 64-bit file length in *bits* at the end of the buffer. */
*(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3);
*(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3)
| (len[0] >> 29));
/* Process last bytes. */
md5_process_block (buffer, sum + pad + 8, &ctx);
/* Construct result in desired memory. */
md5_read_ctx (&ctx, resblock);
return 0;
}
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *
md5_buffer (buffer, len, resblock)
const char *buffer;
size_t len;
void *resblock;
{
struct md5_ctx ctx;
char restbuf[64 + 72];
size_t blocks = len & ~63;
size_t pad, rest;
/* Initialize the computation context. */
md5_init_ctx (&ctx);
/* Process whole buffer but last len % 64 bytes. */
md5_process_block (buffer, blocks, &ctx);
/* REST bytes are not processed yet. */
rest = len - blocks;
/* Copy to own buffer. */
memcpy (restbuf, &buffer[blocks], rest);
/* Append needed fill bytes at end of buffer. We can copy 64 byte
because the buffer is always big enough. */
memcpy (&restbuf[rest], fillbuf, 64);
/* PAD bytes are used for padding to correct alignment. Note that
always at least one byte is padded. */
pad = rest >= 56 ? 64 + 56 - rest : 56 - rest;
/* Put length of buffer in *bits* in last eight bytes. */
*(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP (len << 3);
*(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP (len >> 29);
/* Process last bytes. */
md5_process_block (restbuf, rest + pad + 8, &ctx);
/* Put result in desired memory area. */
return md5_read_ctx (&ctx, resblock);
}
/* These are the four functions used in the four steps of the MD5 algorithm
and defined in the RFC 1321. The first function is a little bit optimized
(as found in Colin Plumbs public domain implementation). */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d) (d ^ (b & (c ^ d)))
#define FG(b, c, d) FF (d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 64 == 0. */
void
md5_process_block (buffer, len, ctx)
const void *buffer;
size_t len;
struct md5_ctx *ctx;
{
md5_uint32 correct_words[16];
const md5_uint32 *words = buffer;
size_t nwords = len / sizeof (md5_uint32);
const md5_uint32 *endp = words + nwords;
md5_uint32 A = ctx->A;
md5_uint32 B = ctx->B;
md5_uint32 C = ctx->C;
md5_uint32 D = ctx->D;
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */
while (words < endp)
{
md5_uint32 *cwp = correct_words;
md5_uint32 A_save = A;
md5_uint32 B_save = B;
md5_uint32 C_save = C;
md5_uint32 D_save = D;
/* First round: using the given function, the context and a constant
the next context is computed. Because the algorithms processing
unit is a 32-bit word and it is determined to work on words in
little endian byte order we perhaps have to change the byte order
before the computation. To reduce the work for the next steps
we store the swapped words in the array CORRECT_WORDS. */
#define OP(a, b, c, d, s, T) \
do \
{ \
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
++words; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
/* Before we start, one word to the strange constants.
They are defined in RFC 1321 as
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
*/
/* Round 1. */
OP (A, B, C, D, 7, 0xd76aa478);
OP (D, A, B, C, 12, 0xe8c7b756);
OP (C, D, A, B, 17, 0x242070db);
OP (B, C, D, A, 22, 0xc1bdceee);
OP (A, B, C, D, 7, 0xf57c0faf);
OP (D, A, B, C, 12, 0x4787c62a);
OP (C, D, A, B, 17, 0xa8304613);
OP (B, C, D, A, 22, 0xfd469501);
OP (A, B, C, D, 7, 0x698098d8);
OP (D, A, B, C, 12, 0x8b44f7af);
OP (C, D, A, B, 17, 0xffff5bb1);
OP (B, C, D, A, 22, 0x895cd7be);
OP (A, B, C, D, 7, 0x6b901122);
OP (D, A, B, C, 12, 0xfd987193);
OP (C, D, A, B, 17, 0xa679438e);
OP (B, C, D, A, 22, 0x49b40821);
/* For the second to fourth round we have the possibly swapped words
in CORRECT_WORDS. Redefine the macro to take an additional first
argument specifying the function to use. */
#undef OP
#define OP(f, a, b, c, d, k, s, T) \
do \
{ \
a += f (b, c, d) + correct_words[k] + T; \
CYCLIC (a, s); \
a += b; \
} \
while (0)
/* Round 2. */
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
OP (FG, D, A, B, C, 10, 9, 0x02441453);
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
/* Round 3. */
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
/* Round 4. */
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
/* Add the starting values of the context. */
A += A_save;
B += B_save;
C += C_save;
D += D_save;
}
/* Put checksum in context given as argument. */
ctx->A = A;
ctx->B = B;
ctx->C = C;
ctx->D = D;
}

115
lib/md5.h Normal file
View File

@@ -0,0 +1,115 @@
/* md5.h - Declaration of functions and data types used for MD5 sum
computing library functions.
Copyright (C) 1995 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. */
#ifndef _MD5_H
#define _MD5_H
#include <stdio.h>
#if defined HAVE_LIMITS_H || _LIBC
# include <limits.h>
#endif
/* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
doing that would require that the configure script compile and *run*
the resulting executable. Locally running cross-compiled executables
is usually not possible. */
#if defined __STDC__ && __STDC__
# define UINT_MAX_32_BITS 4294967295U
#else
# define UINT_MAX_32_BITS 0xFFFFFFFF
#endif
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
This should be valid for all systems GNU cares about because
that doesn't include 16-bit systems, and only modern systems
(that certainly have <limits.h>) have 64+-bit integral types. */
#ifndef UINT_MAX
# define UINT_MAX UINT_MAX_32_BITS
#endif
#if UINT_MAX == UINT_MAX_32_BITS
typedef unsigned int md5_uint32;
#else
# if USHRT_MAX == UINT_MAX_32_BITS
typedef unsigned short md5_uint32;
# else
# if ULONG_MAX == UINT_MAX_32_BITS
typedef unsigned long md5_uint32;
# else
/* The following line is intended to evoke an error.
Using #error is not portable enough. */
"Cannot determine unsigned 32-bit data type."
# endif
# endif
#endif
#undef __P
#if defined (__STDC__) && __STDC__
#define __P(x) x
#else
#define __P(x) ()
#endif
/* Structure to save state of computation between the single steps. */
struct md5_ctx
{
md5_uint32 A;
md5_uint32 B;
md5_uint32 C;
md5_uint32 D;
};
/*
* The following three functions are build up the low level used in
* the functions `md5_stream' and `md5_buffer'.
*/
/* Initialize structure containing state of computation.
(RFC 1321, 3.3: Step 3) */
void md5_init_ctx __P ((struct md5_ctx *ctx));
/* Starting with the result of former calls of this function (or the
initialzation function update the context for the next LEN bytes
starting at BUFFER.
It is necessary that LEN is a multiple of 64!!! */
void md5_process_block __P ((const void *buffer, size_t len,
struct md5_ctx *ctx));
/* Put result from CTX in first 16 bytes following RESBUF. The result is
always in little endian byte order, so that a byte-wise output yields
to the wanted ASCII representation of the message digest. */
void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
/* Compute MD5 message digest for bytes read from STREAM. The
resulting message digest number will be written into the 16 bytes
beginning at RESBLOCK. */
int md5_stream __P ((FILE *stream, void *resblock));
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
result is always in little endian byte order, so that a byte-wise
output yields to the wanted ASCII representation of the message
digest. */
void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
#endif

View File

@@ -1,70 +1,113 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
Based on strlen implemention by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
commentary by Jim Blandy (jimb@ai.mit.edu);
adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
and implemented by Roland McGrath (roland@ai.mit.edu).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
The GNU C Library is distributed in the hope that it will be useful,
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
Library General Public License for more details.
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 Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#undef __ptr_t
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
# define __ptr_t void *
#else /* Not C++ or ANSI C. */
# define __ptr_t char *
#endif /* C++ or ANSI C. */
#if defined (_LIBC)
# include <string.h>
#endif
#if defined (HAVE_LIMITS_H) || defined (_LIBC)
# include <limits.h>
#endif
#define LONG_MAX_32_BITS 2147483647
#ifndef LONG_MAX
#define LONG_MAX LONG_MAX_32_BITS
#endif
#include <sys/types.h>
/* Search no more than N bytes of S for C. */
char *
memchr(s, c, n)
unsigned char * s ;
int c ;
unsigned n;
__ptr_t
memchr (s, c, n)
const __ptr_t s;
int c;
size_t n;
{
unsigned char *char_ptr;
unsigned long int *longword_ptr;
const unsigned char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, charmask;
c = (unsigned char) c;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a 4-byte border. */
for (char_ptr = s; n > 0 && ((unsigned long int) char_ptr & 3) != 0;
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s;
n > 0 && ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
--n, ++char_ptr)
if (*char_ptr == c)
return (char *) char_ptr;
return (__ptr_t) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to 8-byte longwords. */
longword_ptr = (unsigned long int *) char_ptr;
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
the "holes." Note that there is a hole just to the left of
each byte, with an extra at the end:
bits: 01111110 11111110 11111110 11111111
bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
if (sizeof (longword) != 4 && sizeof (longword) != 8)
abort ();
#if LONG_MAX <= LONG_MAX_32_BITS
magic_bits = 0x7efefeff;
#else
magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
#endif
/* Set up a longword, each of whose bytes is C. */
charmask = c | (c << 8);
charmask |= charmask << 16;
#if LONG_MAX > LONG_MAX_32_BITS
charmask |= charmask << 32;
#endif
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
if *any of the four* bytes in the longword in question are zero. */
while (n >= 4)
while (n >= sizeof (longword))
{
/* We tentatively exit the loop if adding MAGIC_BITS to
LONGWORD fails to change any of the hole bits of LONGWORD.
@@ -104,10 +147,10 @@ memchr(s, c, n)
/* Add MAGIC_BITS to LONGWORD. */
if ((((longword + magic_bits)
/* Set those bits that were unchanged by the addition. */
^ ~longword)
/* Look at only the hole bits. If any of the hole bits
are unchanged, most likely one of the bytes was a
zero. */
@@ -116,27 +159,37 @@ memchr(s, c, n)
/* Which of the bytes was C? If none of them were, it was
a misfire; continue the search. */
unsigned char *cp = ( unsigned char *) (longword_ptr - 1);
const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
if (cp[0] == c)
return (char *) cp;
return (__ptr_t) cp;
if (cp[1] == c)
return (char *) &cp[1];
return (__ptr_t) &cp[1];
if (cp[2] == c)
return (char *) &cp[2];
return (__ptr_t) &cp[2];
if (cp[3] == c)
return (char *) &cp[3];
return (__ptr_t) &cp[3];
#if LONG_MAX > 2147483647
if (cp[4] == c)
return (__ptr_t) &cp[4];
if (cp[5] == c)
return (__ptr_t) &cp[5];
if (cp[6] == c)
return (__ptr_t) &cp[6];
if (cp[7] == c)
return (__ptr_t) &cp[7];
#endif
}
n -= 4;
n -= sizeof (longword);
}
char_ptr = ( unsigned char *) longword_ptr;
char_ptr = (const unsigned char *) longword_ptr;
while (n-- > 0)
{
if (*char_ptr == c)
return (char *) char_ptr;
return (__ptr_t) char_ptr;
else
++char_ptr;
}

366
lib/memcmp.c Normal file
View File

@@ -0,0 +1,366 @@
/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
Contributed by Torbjorn Granlund (tege@sics.se).
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#undef __ptr_t
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
#define __ptr_t void *
#else /* Not C++ or ANSI C. */
#undef const
#define const
#define __ptr_t char *
#endif /* C++ or ANSI C. */
#if defined (HAVE_STRING_H) || defined (_LIBC)
#include <string.h>
#endif
#ifdef _LIBC
#include <memcopy.h>
#else /* Not in the GNU C library. */
#include <sys/types.h>
/* Type to use for aligned memory operations.
This should normally be the biggest type supported by a single load
and store. Must be an unsigned type. */
#define op_t unsigned long int
#define OPSIZ (sizeof(op_t))
/* Threshold value for when to enter the unrolled loops. */
#define OP_T_THRES 16
/* Type to use for unaligned operations. */
typedef unsigned char byte;
#ifndef WORDS_BIGENDIAN
#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
#else
#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
#endif
#endif /* In the GNU C library. */
#ifdef WORDS_BIGENDIAN
#define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
#else
#define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
#endif
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE! */
/* The strategy of this memcmp is:
1. Compare bytes until one of the block pointers is aligned.
2. Compare using memcmp_common_alignment or
memcmp_not_common_alignment, regarding the alignment of the other
block after the initial byte operations. The maximum number of
full words (of type op_t) are compared in this way.
3. Compare the few remaining bytes. */
#ifndef WORDS_BIGENDIAN
/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
A and B are known to be different.
This is needed only on little-endian machines. */
#ifdef __GNUC__
__inline
#endif
static int
memcmp_bytes (a, b)
op_t a, b;
{
long int srcp1 = (long int) &a;
long int srcp2 = (long int) &b;
op_t a0, b0;
do
{
a0 = ((byte *) srcp1)[0];
b0 = ((byte *) srcp2)[0];
srcp1 += 1;
srcp2 += 1;
}
while (a0 == b0);
return a0 - b0;
}
#endif
/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
objects (not LEN bytes!). Both SRCP1 and SRCP2 should be aligned for
memory operations on `op_t's. */
#ifdef __GNUC__
__inline
#endif
static int
memcmp_common_alignment (srcp1, srcp2, len)
long int srcp1;
long int srcp2;
size_t len;
{
op_t a0, a1;
op_t b0, b1;
switch (len % 4)
{
case 2:
a0 = ((op_t *) srcp1)[0];
b0 = ((op_t *) srcp2)[0];
srcp1 -= 2 * OPSIZ;
srcp2 -= 2 * OPSIZ;
len += 2;
goto do1;
case 3:
a1 = ((op_t *) srcp1)[0];
b1 = ((op_t *) srcp2)[0];
srcp1 -= OPSIZ;
srcp2 -= OPSIZ;
len += 1;
goto do2;
case 0:
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
return 0;
a0 = ((op_t *) srcp1)[0];
b0 = ((op_t *) srcp2)[0];
goto do3;
case 1:
a1 = ((op_t *) srcp1)[0];
b1 = ((op_t *) srcp2)[0];
srcp1 += OPSIZ;
srcp2 += OPSIZ;
len -= 1;
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
goto do0;
/* Fall through. */
}
do
{
a0 = ((op_t *) srcp1)[0];
b0 = ((op_t *) srcp2)[0];
if (a1 != b1)
return CMP_LT_OR_GT (a1, b1);
do3:
a1 = ((op_t *) srcp1)[1];
b1 = ((op_t *) srcp2)[1];
if (a0 != b0)
return CMP_LT_OR_GT (a0, b0);
do2:
a0 = ((op_t *) srcp1)[2];
b0 = ((op_t *) srcp2)[2];
if (a1 != b1)
return CMP_LT_OR_GT (a1, b1);
do1:
a1 = ((op_t *) srcp1)[3];
b1 = ((op_t *) srcp2)[3];
if (a0 != b0)
return CMP_LT_OR_GT (a0, b0);
srcp1 += 4 * OPSIZ;
srcp2 += 4 * OPSIZ;
len -= 4;
}
while (len != 0);
/* This is the right position for do0. Please don't move
it into the loop. */
do0:
if (a1 != b1)
return CMP_LT_OR_GT (a1, b1);
return 0;
}
/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
`op_t' objects (not LEN bytes!). SRCP2 should be aligned for memory
operations on `op_t', but SRCP1 *should be unaligned*. */
#ifdef __GNUC__
__inline
#endif
static int
memcmp_not_common_alignment (srcp1, srcp2, len)
long int srcp1;
long int srcp2;
size_t len;
{
op_t a0, a1, a2, a3;
op_t b0, b1, b2, b3;
op_t x;
int shl, shr;
/* Calculate how to shift a word read at the memory operation
aligned srcp1 to make it aligned for comparison. */
shl = 8 * (srcp1 % OPSIZ);
shr = 8 * OPSIZ - shl;
/* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
it points in the middle of. */
srcp1 &= -OPSIZ;
switch (len % 4)
{
case 2:
a1 = ((op_t *) srcp1)[0];
a2 = ((op_t *) srcp1)[1];
b2 = ((op_t *) srcp2)[0];
srcp1 -= 1 * OPSIZ;
srcp2 -= 2 * OPSIZ;
len += 2;
goto do1;
case 3:
a0 = ((op_t *) srcp1)[0];
a1 = ((op_t *) srcp1)[1];
b1 = ((op_t *) srcp2)[0];
srcp2 -= 1 * OPSIZ;
len += 1;
goto do2;
case 0:
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
return 0;
a3 = ((op_t *) srcp1)[0];
a0 = ((op_t *) srcp1)[1];
b0 = ((op_t *) srcp2)[0];
srcp1 += 1 * OPSIZ;
goto do3;
case 1:
a2 = ((op_t *) srcp1)[0];
a3 = ((op_t *) srcp1)[1];
b3 = ((op_t *) srcp2)[0];
srcp1 += 2 * OPSIZ;
srcp2 += 1 * OPSIZ;
len -= 1;
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
goto do0;
/* Fall through. */
}
do
{
a0 = ((op_t *) srcp1)[0];
b0 = ((op_t *) srcp2)[0];
x = MERGE(a2, shl, a3, shr);
if (x != b3)
return CMP_LT_OR_GT (x, b3);
do3:
a1 = ((op_t *) srcp1)[1];
b1 = ((op_t *) srcp2)[1];
x = MERGE(a3, shl, a0, shr);
if (x != b0)
return CMP_LT_OR_GT (x, b0);
do2:
a2 = ((op_t *) srcp1)[2];
b2 = ((op_t *) srcp2)[2];
x = MERGE(a0, shl, a1, shr);
if (x != b1)
return CMP_LT_OR_GT (x, b1);
do1:
a3 = ((op_t *) srcp1)[3];
b3 = ((op_t *) srcp2)[3];
x = MERGE(a1, shl, a2, shr);
if (x != b2)
return CMP_LT_OR_GT (x, b2);
srcp1 += 4 * OPSIZ;
srcp2 += 4 * OPSIZ;
len -= 4;
}
while (len != 0);
/* This is the right position for do0. Please don't move
it into the loop. */
do0:
x = MERGE(a2, shl, a3, shr);
if (x != b3)
return CMP_LT_OR_GT (x, b3);
return 0;
}
int
memcmp (s1, s2, len)
const __ptr_t s1;
const __ptr_t s2;
size_t len;
{
op_t a0;
op_t b0;
long int srcp1 = (long int) s1;
long int srcp2 = (long int) s2;
op_t res;
if (len >= OP_T_THRES)
{
/* There are at least some bytes to compare. No need to test
for LEN == 0 in this alignment loop. */
while (srcp2 % OPSIZ != 0)
{
a0 = ((byte *) srcp1)[0];
b0 = ((byte *) srcp2)[0];
srcp1 += 1;
srcp2 += 1;
res = a0 - b0;
if (res != 0)
return res;
len -= 1;
}
/* SRCP2 is now aligned for memory operations on `op_t'.
SRCP1 alignment determines if we can do a simple,
aligned compare or need to shuffle bits. */
if (srcp1 % OPSIZ == 0)
res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
else
res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
if (res != 0)
return res;
/* Number of bytes remaining in the interval [0..OPSIZ-1]. */
srcp1 += len & -OPSIZ;
srcp2 += len & -OPSIZ;
len %= OPSIZ;
}
/* There are just a few bytes to compare. Use byte memory operations. */
while (len != 0)
{
a0 = ((byte *) srcp1)[0];
b0 = ((byte *) srcp2)[0];
srcp1 += 1;
srcp2 += 1;
res = a0 - b0;
if (res != 0)
return res;
len -= 1;
}
return 0;
}

16
lib/memcpy.c Normal file
View File

@@ -0,0 +1,16 @@
/* Copy LEN bytes starting at SRCADDR to DESTADDR. Result undefined
if the source overlaps with the destination.
Return DESTADDR. */
char *
memcpy (destaddr, srcaddr, len)
char *destaddr;
const char *srcaddr;
int len;
{
char *dest = destaddr;
while (len-- > 0)
*destaddr++ = *srcaddr++;
return dest;
}

24
lib/memmove.c Normal file
View File

@@ -0,0 +1,24 @@
/* memmove.c -- copy memory.
Copy LENGTH bytes from SOURCE to DEST. Does not null-terminate.
In the public domain.
By David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
void
memmove (dest, source, length)
char *dest;
const char *source;
unsigned length;
{
if (source < dest)
/* Moving from low mem to hi mem; start at end. */
for (source += length, dest += length; length; --length)
*--dest = *--source;
else if (source != dest)
/* Moving from hi mem to low mem; start at beginning. */
for (; length; --length)
*dest++ = *source++;
}

View File

@@ -1,4 +1,4 @@
/* mkrmdir.c -- BSD compatible directory functions for System V
/* mkdir.c -- BSD compatible make directory function for System V
Copyright (C) 1988, 1990 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -15,14 +15,26 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifndef STDC_HEADERS
#ifndef errno
extern int errno;
#endif
/* mkdir and rmdir adapted from GNU tar. */
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
/* mkdir adapted from GNU tar. */
/* Make directory DPATH, with permission mode DMODE.
@@ -57,7 +69,7 @@ mkdir (dpath, dmode)
switch (cpid)
{
case -1: /* Cannot fork. */
return -1; /* errno is set already. */
return -1; /* errno is already set. */
case 0: /* Child process. */
/* Cheap hack to set mode of new directory. Since this child
@@ -70,56 +82,16 @@ mkdir (dpath, dmode)
_exit (1);
default: /* Parent process. */
while (wait (&status) != cpid) /* Wait for kid to finish. */
/* Wait for kid to finish. */
while (wait (&status) != cpid)
/* Do nothing. */ ;
if (status & 0xFFFF)
{
errno = EIO; /* /bin/mkdir failed. */
/* /bin/mkdir failed. */
errno = EIO;
return -1;
}
return chmod (dpath, dmode);
}
}
/* Remove directory DPATH.
Return 0 if successful, -1 if not. */
int
rmdir (dpath)
char *dpath;
{
int cpid, status;
struct stat statbuf;
if (stat (dpath, &statbuf) != 0)
return -1; /* stat set errno. */
if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
{
errno = ENOTDIR;
return -1;
}
cpid = fork ();
switch (cpid)
{
case -1: /* Cannot fork. */
return -1; /* errno is set already. */
case 0: /* Child process. */
execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
_exit (1);
default: /* Parent process. */
while (wait (&status) != cpid) /* Wait for kid to finish. */
/* Do nothing. */ ;
if (status & 0xFFFF)
{
errno = EIO; /* /bin/rmdir failed. */
return -1;
}
return 0;
}
}

View File

@@ -1,4 +1,6 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
Contributed by Paul Eggert (eggert@twinsun.com).
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,209 +18,391 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <errno.h>
#ifndef STDC_HEADERS
extern int errno;
#endif
#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#else
#define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
#define LONG_MIN (-LONG_MAX - 1)
#define INT_MAX (~(1 << (sizeof (int) * 8 - 1)))
#define INT_MIN (-INT_MAX - 1)
/* Define this to have a standalone program to test this implementation of
mktime. */
/* #define DEBUG 1 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef NULL
#define NULL 0
/* Assume that leap seconds are possible, unless told otherwise.
If the host has a `zic' command with a `-L leapsecondfilename' option,
then it supports leap seconds; otherwise it probably doesn't. */
#ifndef LEAP_SECONDS_POSSIBLE
#define LEAP_SECONDS_POSSIBLE 1
#endif
#include <sys/types.h> /* Some systems define `time_t' here. */
#include <time.h>
#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS
#include <limits.h>
#endif
#if DEBUG
#include <stdio.h>
#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS
#include <stdlib.h>
#endif
/* Make it work even if the system's libc has its own mktime routine. */
#define mktime my_mktime
#endif /* DEBUG */
#ifndef __P
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
#define __P(args) args
#else
#define __P(args) ()
#endif /* GCC. */
#endif /* Not __P. */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef INT_MIN
#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
#endif
#ifndef INT_MAX
#define INT_MAX (~0 - INT_MIN)
#endif
#ifndef TIME_T_MIN
#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
#endif
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
except every 100th isn't, and every 1000th is). */
except every 100th isn't, and every 400th is). */
#define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 1000 == 0))
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#endif
/* How many days are in each month. */
static unsigned short int __mon_lengths[2][12] =
/* How many days come before each month (0-12). */
const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
time_t __mktime_internal __P ((struct tm *,
struct tm *(*) (const time_t *, struct tm *),
time_t *));
#if ! HAVE_LOCALTIME_R && ! defined (localtime_r)
#ifdef _LIBC
#define localtime_r __localtime_r
#else
/* Approximate localtime_r as best we can in its absence. */
#define localtime_r my_localtime_r
static struct tm *localtime_r __P ((const time_t *, struct tm *));
static struct tm *
localtime_r (t, tp)
const time_t *t;
struct tm *tp;
{
/* Normal years. */
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
/* Leap years. */
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
#define invalid() return (time_t) -1
/* Return the `time_t' representation of TP and normalizes TP.
Return (time_t) -1 if TP is not representable as a `time_t'.
Note that 31 Dec 1969 23:59:59 is not representable
because it is represented as (time_t) -1. */
time_t
mktime(tp)
register struct tm *tp;
{
static struct tm min, max;
static char init = 0;
register time_t result;
register time_t t;
register int i;
register unsigned short *l;
register struct tm *new;
time_t end;
if (tp == NULL)
{
errno = EINVAL;
invalid();
}
if (!init)
{
init = 1;
end = (time_t) LONG_MIN;
new = gmtime(&end);
if (new != NULL)
min = *new;
else
min.tm_sec = min.tm_min = min.tm_hour =
min.tm_mday = min.tm_mon = min.tm_year = INT_MIN;
end = (time_t) LONG_MAX;
new = gmtime(&end);
if (new != NULL)
max = *new;
else
max.tm_sec = max.tm_min = max.tm_hour =
max.tm_mday = max.tm_mon = max.tm_year = INT_MAX;
}
/* Make all the elements of TP that we pay attention to
be within the ranges of reasonable values for those things. */
#define normalize(elt, min, max, nextelt) \
while (tp->elt < min) \
{ \
--tp->nextelt; \
tp->elt += max + 1; \
} \
while (tp->elt > max) \
{ \
++tp->nextelt; \
tp->elt -= max + 1; \
}
normalize (tm_sec, 0, 59, tm_min);
normalize (tm_min, 0, 59, tm_hour);
normalize (tm_hour, 0, 24, tm_mday);
/* Normalize the month first so we can use
it to figure the range for the day. */
normalize (tm_mon, 0, 11, tm_year);
normalize (tm_mday, 1, __mon_lengths[__isleap (tp->tm_year)][tp->tm_mon],
tm_mon);
/* Normalize the month again, since normalizing
the day may have pushed it out of range. */
normalize (tm_mon, 0, 11, tm_year);
/* Normalize the day again, because normalizing
the month may have changed the range. */
normalize (tm_mday, 1, __mon_lengths[__isleap (tp->tm_year)][tp->tm_mon],
tm_mon);
/* Check for out-of-range values. */
#define lowhigh(field, minmax, cmp) (tp->field cmp minmax.field)
#define low(field) lowhigh(field, min, <)
#define high(field) lowhigh(field, max, >)
#define oor(field) (low(field) || high(field))
#define lowbound(field) (tp->field == min.field)
#define highbound(field) (tp->field == max.field)
if (oor(tm_year))
invalid();
else if (lowbound(tm_year))
{
if (low(tm_mon))
invalid();
else if (lowbound(tm_mon))
{
if (low(tm_mday))
invalid();
else if (lowbound(tm_mday))
{
if (low(tm_hour))
invalid();
else if (lowbound(tm_hour))
{
if (low(tm_min))
invalid();
else if (lowbound(tm_min))
{
if (low(tm_sec))
invalid();
}
}
}
}
}
else if (highbound(tm_year))
{
if (high(tm_mon))
invalid();
else if (highbound(tm_mon))
{
if (high(tm_mday))
invalid();
else if (highbound(tm_mday))
{
if (high(tm_hour))
invalid();
else if (highbound(tm_hour))
{
if (high(tm_min))
invalid();
else if (highbound(tm_min))
{
if (high(tm_sec))
invalid();
}
}
}
}
}
t = 0;
for (i = 1970; i > 1900 + tp->tm_year; --i)
t -= __isleap(i) ? 366 : 365;
for (i = 1970; i < 1900 + tp->tm_year; ++i)
t += __isleap(i) ? 366 : 365;
l = __mon_lengths[__isleap(1900 + tp->tm_year)];
for (i = 0; i < tp->tm_mon; ++i)
t += l[i];
t += tp->tm_mday - 1;
result = ((t * 60 * 60 * 24) +
(tp->tm_hour * 60 * 60) +
(tp->tm_min * 60) +
tp->tm_sec);
end = result;
#if 0 /* This code breaks it, on SunOS anyway. */
if (tp->tm_isdst < 0)
new = localtime(&end);
else
#endif
new = gmtime(&end);
if (new == NULL)
invalid();
new->tm_isdst = tp->tm_isdst;
*tp = *new;
return result;
struct tm *l = localtime (t);
if (! l)
return 0;
*tp = *l;
return tp;
}
#endif /* ! _LIBC */
#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
measured in seconds, ignoring leap seconds.
YEAR uses the same numbering as TM->tm_year.
All values are in range, except possibly YEAR.
If overflow occurs, yield the low order bits of the correct answer. */
static time_t
ydhms_tm_diff (year, yday, hour, min, sec, tp)
int year, yday, hour, min, sec;
const struct tm *tp;
{
time_t ay = year + (time_t) (TM_YEAR_BASE - 1);
time_t by = tp->tm_year + (time_t) (TM_YEAR_BASE - 1);
time_t intervening_leap_days =
(ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
time_t years = ay - by;
time_t days = (365 * years + intervening_leap_days
+ (yday - tp->tm_yday));
return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+ (min - tp->tm_min))
+ (sec - tp->tm_sec));
}
/* Convert *TP to a time_t value. */
time_t
mktime (tp)
struct tm *tp;
{
static time_t localtime_offset;
return __mktime_internal (tp, localtime_r, &localtime_offset);
}
/* Convert *TP to a time_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
If *OFFSET's guess is correct, only one CONVERT call is needed. */
time_t
__mktime_internal (tp, convert, offset)
struct tm *tp;
struct tm *(*convert) __P ((const time_t *, struct tm *));
time_t *offset;
{
time_t t, dt, t0;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
to handle any combinations of time zone rule changes, solar time,
and leap seconds. Posix.1 prohibits leap seconds, but some hosts
have them anyway. */
int remaining_probes = 4;
/* Time requested. Copy it in case CONVERT modifies *TP; this can
occur if TP is localtime's returned value and CONVERT is localtime. */
int sec = tp->tm_sec;
int min = tp->tm_min;
int hour = tp->tm_hour;
int mday = tp->tm_mday;
int mon = tp->tm_mon;
int year_requested = tp->tm_year;
int isdst = tp->tm_isdst;
/* Ensure that mon is in range, and set year accordingly. */
int mon_remainder = mon % 12;
int negative_mon_remainder = mon_remainder < 0;
int mon_years = mon / 12 - negative_mon_remainder;
int year = year_requested + mon_years;
/* The other values need not be in range:
the remaining code handles minor overflows correctly,
assuming int and time_t arithmetic wraps around.
Major overflows are caught at the end. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
[mon_remainder + 12 * negative_mon_remainder])
+ mday - 1);
#if LEAP_SECONDS_POSSIBLE
/* Handle out-of-range seconds specially,
since ydhms_tm_diff assumes every minute has 60 seconds. */
int sec_requested = sec;
if (sec < 0)
sec = 0;
if (59 < sec)
sec = 59;
#endif
/* Invert CONVERT by probing. First assume the same offset as last time.
Then repeatedly use the error to improve the guess. */
tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
for (t = t0 + *offset;
(dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
t += dt)
if (--remaining_probes == 0)
return -1;
/* Check whether tm.tm_isdst has the requested value, if any. */
if (0 <= isdst && 0 <= tm.tm_isdst)
{
int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
if (dst_diff)
{
/* Move two hours in the direction indicated by the disagreement,
probe some more, and switch to a new time if found.
The largest known fallback due to daylight savings is two hours:
once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
time_t ot = t - 2 * 60 * 60 * dst_diff;
while (--remaining_probes != 0)
{
struct tm otm;
if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
(*convert) (&ot, &otm))))
{
t = ot;
tm = otm;
break;
}
if ((ot += dt) == t)
break; /* Avoid a redundant probe. */
}
}
}
*offset = t - t0;
#if LEAP_SECONDS_POSSIBLE
if (sec_requested != tm.tm_sec)
{
/* Adjust time to reflect the tm_sec requested, not the normalized value.
Also, repair any damage from a false match due to a leap second. */
t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
(*convert) (&t, &tm);
}
#endif
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
{
/* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
so check for major overflows. A gross check suffices,
since if t has overflowed, it is off by a multiple of
TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
the difference that is bounded by a small value. */
double dyear = (double) year_requested + mon_years - tm.tm_year;
double dday = 366 * dyear + mday;
double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
return -1;
}
*tp = tm;
return t;
}
#ifdef weak_alias
weak_alias (mktime, timelocal)
#endif
#if DEBUG
static int
not_equal_tm (a, b)
struct tm *a;
struct tm *b;
{
return ((a->tm_sec ^ b->tm_sec)
| (a->tm_min ^ b->tm_min)
| (a->tm_hour ^ b->tm_hour)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_mon ^ b->tm_mon)
| (a->tm_year ^ b->tm_year)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_yday ^ b->tm_yday)
| (a->tm_isdst ^ b->tm_isdst));
}
static void
print_tm (tp)
struct tm *tp;
{
printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
tp->tm_hour, tp->tm_min, tp->tm_sec,
tp->tm_yday, tp->tm_wday, tp->tm_isdst);
}
static int
check_result (tk, tmk, tl, tml)
time_t tk;
struct tm tmk;
time_t tl;
struct tm tml;
{
if (tk != tl || not_equal_tm (&tmk, &tml))
{
printf ("mktime (");
print_tm (&tmk);
printf (")\nyields (");
print_tm (&tml);
printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
return 1;
}
return 0;
}
int
main (argc, argv)
int argc;
char **argv;
{
int status = 0;
struct tm tm, tmk, tml;
time_t tk, tl;
char trailer;
if ((argc == 3 || argc == 4)
&& (sscanf (argv[1], "%d-%d-%d%c",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
== 3)
&& (sscanf (argv[2], "%d:%d:%d%c",
&tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
== 3))
{
tm.tm_year -= TM_YEAR_BASE;
tm.tm_mon--;
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
tml = *localtime (&tl);
printf ("mktime returns %ld == ", (long) tl);
print_tm (&tmk);
printf ("\n");
status = check_result (tl, tmk, tl, tml);
}
else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
{
time_t from = atol (argv[1]);
time_t by = atol (argv[2]);
time_t to = atol (argv[3]);
if (argc == 4)
for (tl = from; tl <= to; tl += by)
{
tml = *localtime (&tl);
tmk = tml;
tk = mktime (&tmk);
status |= check_result (tk, tmk, tl, tml);
}
else
for (tl = from; tl <= to; tl += by)
{
/* Null benchmark. */
tml = *localtime (&tl);
tmk = tml;
tk = tl;
status |= check_result (tk, tmk, tl, tml);
}
}
else
printf ("Usage:\
\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
argv[0], argv[0], argv[0]);
return status;
}
#endif /* DEBUG */
/*
Local Variables:
compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
End:
*/

View File

@@ -24,6 +24,10 @@
changing the mode of many files, this probably results in a
performance gain. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include "modechange.h"
@@ -38,7 +42,11 @@ char *malloc ();
#define NULL 0
#endif
#ifndef S_ISDIR
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
@@ -95,6 +103,9 @@ mode_compile (mode_string, masked_ops)
umask (umask_value); /* Restore the old value. */
head = NULL;
#ifdef lint
change = NULL;
#endif
--mode_string;
/* One loop iteration for each "ugoa...=+-rwxXstugo...[=+-rwxXstugo...]". */

View File

@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include "mountlist.h"
@@ -24,7 +28,7 @@
#else
void free ();
#endif
#if defined(USG) || defined(STDC_HEADERS)
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#else
#include <strings.h>
@@ -36,6 +40,15 @@ char *xrealloc ();
char *xstrdup ();
void error ();
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
# include <sys/mount.h>
# include <sys/fs_types.h>
#endif /* MOUNTED_GETFSSTAT */
#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
#include <mntent.h>
#if !defined(MOUNTED)
@@ -53,7 +66,6 @@ void error ();
#endif
#ifdef MOUNTED_GETMNT /* Ultrix. */
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/fs_types.h>
#endif
@@ -77,6 +89,12 @@ void error ();
#include <sys/vfs.h>
#endif
#ifdef DOLPHIN
/* So special that it's not worth putting this in autoconf. */
#undef MOUNTED_FREAD_FSTYP
#define MOUNTED_GETMNTTBL
#endif
#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
/* Return the value of the hexadecimal number represented by CP.
No prefix (like '0x') or suffix (like 'h') is expected to be
@@ -87,7 +105,7 @@ xatoi (cp)
char *cp;
{
int val;
val = 0;
while (*cp)
{
@@ -105,7 +123,7 @@ xatoi (cp)
}
#endif /* MOUNTED_GETMNTENT1. */
#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
#if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__)
static char *
fstype_to_string (t)
short t;
@@ -116,8 +134,10 @@ fstype_to_string (t)
return "ufs";
case MOUNT_NFS:
return "nfs";
#ifdef MOUNT_PC
case MOUNT_PC:
return "pc";
#endif
#ifdef MOUNT_MFS
case MOUNT_MFS:
return "mfs";
@@ -205,7 +225,7 @@ read_filesystem_list (need_fs_type, all_fs)
me->me_dev = xatoi (devopt + 4);
}
else
me->me_dev = -1; /* Magic; means not known yet. */
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_next = NULL;
/* Add to the linked list. */
@@ -231,8 +251,12 @@ read_filesystem_list (need_fs_type, all_fs)
me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
me->me_devname = xstrdup (fsp->f_mntfromname);
me->me_mountdir = xstrdup (fsp->f_mntonname);
#ifdef __NetBSD__
me->me_type = xstrdup (fsp->f_fstypename);
#else
me->me_type = fstype_to_string (fsp->f_type);
me->me_dev = -1; /* Magic; means not known yet. */
#endif
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_next = NULL;
/* Add to the linked list. */
@@ -268,6 +292,43 @@ read_filesystem_list (need_fs_type, all_fs)
}
#endif /* MOUNTED_GETMNT. */
#if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
{
int numsys, counter, bufsize;
struct statfs *stats;
numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
if (numsys < 0)
return (NULL);
bufsize = (1 + numsys) * sizeof (struct statfs);
stats = (struct statfs *)xmalloc (bufsize);
numsys = getfsstat (stats, bufsize, MNT_WAIT);
if (numsys < 0)
{
free (stats);
return (NULL);
}
for (counter = 0; counter < numsys; counter++)
{
me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
me->me_devname = xstrdup (stats[counter].f_mntfromname);
me->me_mountdir = xstrdup (stats[counter].f_mntonname);
me->me_type = mnt_names[stats[counter].f_type];
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_next = NULL;
/* Add to the linked list. */
mtail->me_next = me;
mtail = me;
}
free (stats);
}
#endif /* MOUNTED_GETFSSTAT */
#if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
{
struct mnttab mnt;
@@ -289,7 +350,7 @@ read_filesystem_list (need_fs_type, all_fs)
strcpy (me->me_devname + 5, mnt.mt_dev);
#endif
me->me_mountdir = xstrdup (mnt.mt_filsys);
me->me_dev = -1; /* Magic; means not known yet. */
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_type = "";
#ifdef GETFSTYP /* SVR3. */
if (need_fs_type)
@@ -314,6 +375,26 @@ read_filesystem_list (need_fs_type, all_fs)
}
#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
{
struct mntent **mnttbl=getmnttbl(),**ent;
for (ent=mnttbl;*ent;ent++)
{
me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
me->me_devname = xstrdup ( (*ent)->mt_resource);
me->me_mountdir = xstrdup( (*ent)->mt_directory);
me->me_type = xstrdup ((*ent)->mt_fstype);
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_next = NULL;
/* Add to the linked list. */
mtail->me_next = me;
mtail = me;
}
endmnttbl();
}
#endif
#ifdef MOUNTED_GETMNTENT2 /* SVR4. */
{
struct mnttab mnt;
@@ -331,7 +412,7 @@ read_filesystem_list (need_fs_type, all_fs)
me->me_devname = xstrdup (mnt.mnt_special);
me->me_mountdir = xstrdup (mnt.mnt_mountp);
me->me_type = xstrdup (mnt.mnt_fstype);
me->me_dev = -1; /* Magic; means not known yet. */
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
me->me_next = NULL;
/* Add to the linked list. */
@@ -378,12 +459,12 @@ read_filesystem_list (need_fs_type, all_fs)
}
else
{
me->me_devname = xstrdup (thisent +
me->me_devname = xstrdup (thisent +
vmp->vmt_data[VMT_OBJECT].vmt_off);
}
me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
me->me_dev = -1; /* vmt_fsid might be the info we want. */
me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
me->me_next = NULL;
/* Add to the linked list. */

485
lib/obstack.c Normal file
View File

@@ -0,0 +1,485 @@
/* obstack.c - subroutines used implicitly by object stack macros
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "obstack.h"
/* This is just to get __GNU_LIBRARY__ defined. */
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
#ifdef __STDC__
#define POINTER void *
#else
#define POINTER char *
#endif
/* Determine default alignment. */
struct fooalign {char x; double d;};
#define DEFAULT_ALIGNMENT \
((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
union fooround {long x; double d;};
#define DEFAULT_ROUNDING (sizeof (union fooround))
/* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work;
in such a case, redefine COPYING_UNIT to `long' (if that works)
or `char' as a last resort. */
#ifndef COPYING_UNIT
#define COPYING_UNIT int
#endif
/* The non-GNU-C macros copy the obstack into this global variable
to avoid multiple evaluation. */
struct obstack *_obstack;
/* Define a macro that either calls functions with the traditional malloc/free
calling interface, or calls functions with the mmalloc/mfree interface
(that adds an extra first argument), based on the state of use_extra_arg.
For free, do not use ?:, since some compilers, like the MIPS compilers,
do not allow (expr) ? void : void. */
#define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
: (*(h)->chunkfun) ((size)))
#define CALL_FREEFUN(h, old_chunk) \
do { \
if ((h) -> use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
else \
(*(h)->freefun) ((old_chunk)); \
} while (0)
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
and FREEFUN the function to free them.
Return nonzero if successful, zero if out of memory.
To recover from an out of memory error,
free up some memory, then call this again. */
int
_obstack_begin (h, size, alignment, chunkfun, freefun)
struct obstack *h;
int size;
int alignment;
POINTER (*chunkfun) ();
void (*freefun) ();
{
register struct _obstack_chunk* chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
h->freefun = freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
if (!chunk)
{
h->alloc_failed = 1;
return 0;
}
h->alloc_failed = 0;
h->next_free = h->object_base = chunk->contents;
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
return 1;
}
int
_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
struct obstack *h;
int size;
int alignment;
POINTER (*chunkfun) ();
void (*freefun) ();
POINTER arg;
{
register struct _obstack_chunk* chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
h->freefun = freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = arg;
h->use_extra_arg = 1;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
if (!chunk)
{
h->alloc_failed = 1;
return 0;
}
h->alloc_failed = 0;
h->next_free = h->object_base = chunk->contents;
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
return 1;
}
/* Allocate a new current chunk for the obstack *H
on the assumption that LENGTH bytes need to be added
to the current object, or a new object of length LENGTH allocated.
Copies any partial object from the end of the old chunk
to the beginning of the new one. */
void
_obstack_newchunk (h, length)
struct obstack *h;
int length;
{
register struct _obstack_chunk* old_chunk = h->chunk;
register struct _obstack_chunk* new_chunk;
register long new_size;
register int obj_size = h->next_free - h->object_base;
register int i;
int already;
/* Compute size for new chunk. */
new_size = (obj_size + length) + (obj_size >> 3) + 100;
if (new_size < h->chunk_size)
new_size = h->chunk_size;
/* Allocate and initialize the new chunk. */
new_chunk = CALL_CHUNKFUN (h, new_size);
if (!new_chunk)
{
h->alloc_failed = 1;
return;
}
h->alloc_failed = 0;
h->chunk = new_chunk;
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
/* Move the existing object to the new chunk.
Word at a time is fast and is safe if the object
is sufficiently aligned. */
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
{
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
i >= 0; i--)
((COPYING_UNIT *)new_chunk->contents)[i]
= ((COPYING_UNIT *)h->object_base)[i];
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
}
else
already = 0;
/* Copy remaining bytes one by one. */
for (i = already; i < obj_size; i++)
new_chunk->contents[i] = h->object_base[i];
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */
if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
{
new_chunk->prev = old_chunk->prev;
CALL_FREEFUN (h, old_chunk);
}
h->object_base = new_chunk->contents;
h->next_free = h->object_base + obj_size;
/* The new chunk certainly contains no empty object yet. */
h->maybe_empty_object = 0;
}
/* Return nonzero if object OBJ has been allocated from obstack H.
This is here for debugging.
If you use it in a program, you are probably losing. */
#ifdef __STDC__
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
obstack.h because it is just for debugging. */
int _obstack_allocated_p (struct obstack *h, POINTER obj);
#endif
int
_obstack_allocated_p (h, obj)
struct obstack *h;
POINTER obj;
{
register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk* plp; /* point to previous chunk if any */
lp = (h)->chunk;
/* We use >= rather than > since the object cannot be exactly at
the beginning of the chunk but might be an empty object exactly
at the end of an adjacent chunk. */
while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
{
plp = lp->prev;
lp = plp;
}
return lp != 0;
}
/* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */
#undef obstack_free
/* This function has two names with identical definitions.
This is the first one, called from non-ANSI code. */
void
_obstack_free (h, obj)
struct obstack *h;
POINTER obj;
{
register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk* plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
{
h->object_base = h->next_free = (char *)(obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
else if (obj != 0)
/* obj is not in any of the chunks! */
abort ();
}
/* This function is used from ANSI code. */
void
obstack_free (h, obj)
struct obstack *h;
POINTER obj;
{
register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk* plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
{
h->object_base = h->next_free = (char *)(obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
else if (obj != 0)
/* obj is not in any of the chunks! */
abort ();
}
#if 0
/* These are now turned off because the applications do not use it
and it uses bcopy via obstack_grow, which causes trouble on sysV. */
/* Now define the functional versions of the obstack macros.
Define them to simply use the corresponding macros to do the job. */
#ifdef __STDC__
/* These function definitions do not work with non-ANSI preprocessors;
they won't pass through the macro names in parentheses. */
/* The function names appear in parentheses in order to prevent
the macro-definitions of the names from being expanded there. */
POINTER (obstack_base) (obstack)
struct obstack *obstack;
{
return obstack_base (obstack);
}
POINTER (obstack_next_free) (obstack)
struct obstack *obstack;
{
return obstack_next_free (obstack);
}
int (obstack_object_size) (obstack)
struct obstack *obstack;
{
return obstack_object_size (obstack);
}
int (obstack_room) (obstack)
struct obstack *obstack;
{
return obstack_room (obstack);
}
void (obstack_grow) (obstack, pointer, length)
struct obstack *obstack;
POINTER pointer;
int length;
{
obstack_grow (obstack, pointer, length);
}
void (obstack_grow0) (obstack, pointer, length)
struct obstack *obstack;
POINTER pointer;
int length;
{
obstack_grow0 (obstack, pointer, length);
}
void (obstack_1grow) (obstack, character)
struct obstack *obstack;
int character;
{
obstack_1grow (obstack, character);
}
void (obstack_blank) (obstack, length)
struct obstack *obstack;
int length;
{
obstack_blank (obstack, length);
}
void (obstack_1grow_fast) (obstack, character)
struct obstack *obstack;
int character;
{
obstack_1grow_fast (obstack, character);
}
void (obstack_blank_fast) (obstack, length)
struct obstack *obstack;
int length;
{
obstack_blank_fast (obstack, length);
}
POINTER (obstack_finish) (obstack)
struct obstack *obstack;
{
return obstack_finish (obstack);
}
POINTER (obstack_alloc) (obstack, length)
struct obstack *obstack;
int length;
{
return obstack_alloc (obstack, length);
}
POINTER (obstack_copy) (obstack, pointer, length)
struct obstack *obstack;
POINTER pointer;
int length;
{
return obstack_copy (obstack, pointer, length);
}
POINTER (obstack_copy0) (obstack, pointer, length)
struct obstack *obstack;
POINTER pointer;
int length;
{
return obstack_copy0 (obstack, pointer, length);
}
#endif /* __STDC__ */
#endif /* 0 */
#endif /* _LIBC or not __GNU_LIBRARY__. */

529
lib/obstack.h Normal file
View File

@@ -0,0 +1,529 @@
/* obstack.h - object stack macros
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Summary:
All the apparent functions defined here are macros. The idea
is that you would use these pre-tested macros to solve a
very specific set of problems, and they would run fast.
Caution: no side-effects in arguments please!! They may be
evaluated MANY times!!
These macros operate a stack of objects. Each object starts life
small, and may grow to maturity. (Consider building a word syllable
by syllable.) An object can move while it is growing. Once it has
been "finished" it never changes address again. So the "top of the
stack" is typically an immature growing object, while the rest of the
stack is of mature, fixed size and fixed address objects.
These routines grab large chunks of memory, using a function you
supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
by calling `obstack_chunk_free'. You must define them and declare
them before using any obstack macros.
Each independent stack is represented by a `struct obstack'.
Each of the obstack macros expects a pointer to such a structure
as the first argument.
One motivation for this package is the problem of growing char strings
in symbol tables. Unless you are "fascist pig with a read-only mind"
--Gosper's immortal quote from HAKMEM item 154, out of context--you
would not like to put any arbitrary upper limit on the length of your
symbols.
In practice this often means you will build many short symbols and a
few long symbols. At the time you are reading a symbol you don't know
how long it is. One traditional method is to read a symbol into a
buffer, realloc()ating the buffer every time you try to read a symbol
that is longer than the buffer. This is beaut, but you still will
want to copy the symbol from the buffer to a more permanent
symbol-table entry say about half the time.
With obstacks, you can work differently. Use one obstack for all symbol
names. As you read a symbol, grow the name in the obstack gradually.
When the name is complete, finalize it. Then, if the symbol exists already,
free the newly read name.
The way we do this is to take a large chunk, allocating memory from
low addresses. When you want to build a symbol in the chunk you just
add chars above the current "high water mark" in the chunk. When you
have finished adding chars, because you got to the end of the symbol,
you know how long the chars are, and you can create a new object.
Mostly the chars will not burst over the highest address of the chunk,
because you would typically expect a chunk to be (say) 100 times as
long as an average object.
In case that isn't clear, when we have enough chars to make up
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
so we just point to it where it lies. No moving of chars is
needed and this is the second win: potentially long strings need
never be explicitly shuffled. Once an object is formed, it does not
change its address during its lifetime.
When the chars burst over a chunk boundary, we allocate a larger
chunk, and then copy the partly formed object from the end of the old
chunk to the beginning of the new larger chunk. We then carry on
accreting characters to the end of the object as we normally would.
A special macro is provided to add a single char at a time to a
growing object. This allows the use of register variables, which
break the ordinary 'growth' macro.
Summary:
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can `unwind' an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
*/
/* Don't do the contents of this file more than once. */
#ifndef __OBSTACK_H__
#define __OBSTACK_H__
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
/* We use subtraction of (char *)0 instead of casting to int
because on word-addressable machines a simple cast to int
may ignore the byte-within-word field of the pointer. */
#ifndef __PTR_TO_INT
#define __PTR_TO_INT(P) ((P) - (char *)0)
#endif
#ifndef __INT_TO_PTR
#define __INT_TO_PTR(P) ((P) + (char *)0)
#endif
/* We need the type of the resulting object. In ANSI C it is ptrdiff_t
but in traditional C it is usually long. If we are in ANSI C and
don't already have ptrdiff_t get it. */
#if defined (__STDC__) && __STDC__ && ! defined (offsetof)
#if defined (__GNUC__) && defined (IN_GCC)
/* On Next machine, the system's stddef.h screws up if included
after we have defined just ptrdiff_t, so include all of stddef.h.
Otherwise, define just ptrdiff_t, which is all we need. */
#ifndef __NeXT__
#define __need_ptrdiff_t
#endif
#endif
#include <stddef.h>
#endif
#if defined (__STDC__) && __STDC__
#define PTR_INT_TYPE ptrdiff_t
#else
#define PTR_INT_TYPE long
#endif
#if HAVE_STRING_H || STDC_HEADERS
# include <string.h>
# ifndef bcopy
# define bcopy(s, d, n) memcpy ((d), (s), (n))
# endif
#else /* HAVE_STRING_H || STDC_HEADERS */
# include <strings.h>
#endif /* not (HAVE_STRING_H || STDC_HEADERS) */
struct _obstack_chunk /* Lives at front of each chunk. */
{
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
};
struct obstack /* control current object in current chunk */
{
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
PTR_INT_TYPE temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
void (*freefun) (); /* User's function to free a chunk. */
char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object:1;/* There is a possibility that the current
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
unsigned alloc_failed:1; /* chunk alloc func returned 0 */
};
/* Declare the external functions we use; they are in obstack.c. */
#if defined (__STDC__) && __STDC__
extern void _obstack_newchunk (struct obstack *, int);
extern void _obstack_free (struct obstack *, void *);
extern int _obstack_begin (struct obstack *, int, int,
void *(*) (), void (*) ());
extern int _obstack_begin_1 (struct obstack *, int, int,
void *(*) (), void (*) (), void *);
#else
extern void _obstack_newchunk ();
extern void _obstack_free ();
extern int _obstack_begin ();
extern int _obstack_begin_1 ();
#endif
#if defined (__STDC__) && __STDC__
/* Do the function-declarations after the structs
but before defining the macros. */
void obstack_init (struct obstack *obstack);
void * obstack_alloc (struct obstack *obstack, int size);
void * obstack_copy (struct obstack *obstack, void *address, int size);
void * obstack_copy0 (struct obstack *obstack, void *address, int size);
void obstack_free (struct obstack *obstack, void *block);
void obstack_blank (struct obstack *obstack, int size);
void obstack_grow (struct obstack *obstack, void *data, int size);
void obstack_grow0 (struct obstack *obstack, void *data, int size);
void obstack_1grow (struct obstack *obstack, int data_char);
void obstack_ptr_grow (struct obstack *obstack, void *data);
void obstack_int_grow (struct obstack *obstack, int data);
void * obstack_finish (struct obstack *obstack);
int obstack_object_size (struct obstack *obstack);
int obstack_room (struct obstack *obstack);
void obstack_1grow_fast (struct obstack *obstack, int data_char);
void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
void obstack_int_grow_fast (struct obstack *obstack, int data);
void obstack_blank_fast (struct obstack *obstack, int size);
void * obstack_base (struct obstack *obstack);
void * obstack_next_free (struct obstack *obstack);
int obstack_alignment_mask (struct obstack *obstack);
int obstack_chunk_size (struct obstack *obstack);
#endif /* __STDC__ */
/* Non-ANSI C cannot really support alternative functions for these macros,
so we do not declare them. */
/* Pointer to beginning of object being allocated or to be allocated next.
Note that this might not be the final address of the object
because a new chunk might be needed to hold the final size. */
#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base)
/* Size for allocating ordinary chunks. */
#define obstack_chunk_size(h) ((h)->chunk_size)
/* Pointer to next byte not yet allocated in current chunk. */
#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free)
/* Mask specifying low bits that should be clear in address of an object. */
#define obstack_alignment_mask(h) ((h)->alignment_mask)
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
(void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
(void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \
(void *(*) ()) (chunkfun), (void (*) ()) (freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \
(void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
#define obstack_chunkfun(h, newchunkfun) \
((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
#define obstack_freefun(h, newfreefun) \
((h) -> freefun = (void (*)()) (newfreefun))
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
#if defined (__GNUC__) && defined (__STDC__)
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
does not implement __extension__. But that compiler doesn't define
__GNUC_MINOR__. */
#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
#define __extension__
#endif
/* For GNU C, if not -traditional,
we can define these macros to compute all args only once
without using a global variable.
Also, we can avoid using the `temp' slot, to make faster code. */
#define obstack_object_size(OBSTACK) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
__o->alloc_failed ? 0 : \
(unsigned) (__o->next_free - __o->object_base); })
#define obstack_room(OBSTACK) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); })
#define obstack_grow(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len > __o->chunk_limit) \
_obstack_newchunk (__o, __len); \
if (!__o->alloc_failed) \
{ \
bcopy ((char *) (where), __o->next_free, __len); \
__o->next_free += __len; \
} \
(void) 0; })
#define obstack_grow0(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->next_free + __len + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, __len + 1); \
if (!__o->alloc_failed) \
{ \
bcopy ((char *) (where), __o->next_free, __len); \
__o->next_free += __len; \
*(__o->next_free)++ = 0; \
} \
(void) 0; })
#define obstack_1grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \
if (!__o->alloc_failed) \
*(__o->next_free)++ = (datum); \
(void) 0; })
/* These assume that the obstack alignment is good enough for pointers or ints,
and that the data added so far to the current object
shares that much alignment. */
#define obstack_ptr_grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \
if (!__o->alloc_failed) \
*((void **)__o->next_free)++ = ((void *)datum); \
(void) 0; })
#define obstack_int_grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \
if (!__o->alloc_failed) \
*((int *)__o->next_free)++ = ((int)datum); \
(void) 0; })
#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
#define obstack_blank(OBSTACK,length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
if (!__o->alloc_failed) \
__o->next_free += __len; \
(void) 0; })
#define obstack_alloc(OBSTACK,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_blank (__h, (length)); \
obstack_finish (__h); })
#define obstack_copy(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow (__h, (where), (length)); \
obstack_finish (__h); })
#define obstack_copy0(OBSTACK,where,length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); })
/* The local variable is named __o1 to avoid a name conflict
when obstack_blank is called. */
#define obstack_finish(OBSTACK) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *value; \
if (__o1->alloc_failed) \
value = 0; \
else \
{ \
value = (void *) __o1->object_base; \
if (__o1->next_free == value) \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
& ~ (__o1->alignment_mask)); \
if (__o1->next_free - (char *)__o1->chunk \
> __o1->chunk_limit - (char *)__o1->chunk) \
__o1->next_free = __o1->chunk_limit; \
__o1->object_base = __o1->next_free; \
} \
value; })
#define obstack_free(OBSTACK, OBJ) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
void *__obj = (OBJ); \
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
__o->next_free = __o->object_base = __obj; \
else (obstack_free) (__o, __obj); })
#else /* not __GNUC__ or not __STDC__ */
#define obstack_object_size(h) \
(unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base)
#define obstack_room(h) \
(unsigned) ((h)->chunk_limit - (h)->next_free)
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
so that we can avoid having void expressions
in the arms of the conditional expression.
Casting the third operand to void was tried before,
but some compilers won't accept it. */
#define obstack_grow(h,where,length) \
( (h)->temp = (length), \
(((h)->next_free + (h)->temp > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
((h)->alloc_failed ? 0 : \
(bcopy ((char *) (where), (h)->next_free, (h)->temp), \
(h)->next_free += (h)->temp)))
#define obstack_grow0(h,where,length) \
( (h)->temp = (length), \
(((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
((h)->alloc_failed ? 0 : \
(bcopy ((char *) (where), (h)->next_free, (h)->temp), \
(h)->next_free += (h)->temp, \
*((h)->next_free)++ = 0)))
#define obstack_1grow(h,datum) \
( (((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
((h)->alloc_failed ? 0 : \
(*((h)->next_free)++ = (datum))))
#define obstack_ptr_grow(h,datum) \
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
((h)->alloc_failed ? 0 : \
(*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))))
#define obstack_int_grow(h,datum) \
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
((h)->alloc_failed ? 0 : \
(*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))))
#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
#define obstack_blank(h,length) \
( (h)->temp = (length), \
(((h)->chunk_limit - (h)->next_free < (h)->temp) \
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
((h)->alloc_failed ? 0 : \
((h)->next_free += (h)->temp)))
#define obstack_alloc(h,length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
#define obstack_copy(h,where,length) \
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
#define obstack_copy0(h,where,length) \
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
#define obstack_finish(h) \
( (h)->alloc_failed ? 0 : \
(((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
(h)->temp = __PTR_TO_INT ((h)->object_base), \
(h)->next_free \
= __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
& ~ ((h)->alignment_mask)), \
(((h)->next_free - (char *)(h)->chunk \
> (h)->chunk_limit - (char *)(h)->chunk) \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
__INT_TO_PTR ((h)->temp)))
#if defined (__STDC__) && __STDC__
#define obstack_free(h,obj) \
( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
(((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
? (int) ((h)->next_free = (h)->object_base \
= (h)->temp + (char *) (h)->chunk) \
: (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
#else
#define obstack_free(h,obj) \
( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
(((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
? (int) ((h)->next_free = (h)->object_base \
= (h)->temp + (char *) (h)->chunk) \
: (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
#endif
#endif /* not __GNUC__ or not __STDC__ */
#endif /* not __OBSTACK_H__ */

53
lib/pathmax.h Normal file
View File

@@ -0,0 +1,53 @@
/* Define PATH_MAX somehow. Requires sys/types.h.
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _PATHMAX_H
#define _PATHMAX_H
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
PATH_MAX but might cause redefinition warnings when sys/param.h is
later included (as on MORE/BSD 4.3). */
#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
#include <limits.h>
#endif
#ifndef _POSIX_PATH_MAX
#define _POSIX_PATH_MAX 255
#endif
#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
#define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
#endif
/* Don't include sys/param.h if it already has been. */
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
#include <sys/param.h>
#endif
#if !defined(PATH_MAX) && defined(MAXPATHLEN)
#define PATH_MAX MAXPATHLEN
#endif
#ifndef PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX
#endif
#endif /* _PATHMAX_H */

978
lib/posixtm.c Normal file
View File

@@ -0,0 +1,978 @@
/* A Bison parser, made from ./posixtm.y with Bison version GNU Bison version 1.22
*/
#define YYBISON 1 /* Identify Bison output. */
#define DIGIT 258
#line 19 "./posixtm.y"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* The following block of alloca-related preprocessor directives is here
solely to allow compilation by non GNU-C compilers of the C parser
produced from this file by old versions of bison. Newer versions of
bison include a block similar to this one in bison.simple. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#else
#ifdef _AIX
#pragma alloca
#else
void *alloca ();
#endif
#endif
#endif
#include <stdio.h>
#include <sys/types.h>
#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
#else
#include <time.h>
#endif
/* Some old versions of bison generate parsers that use bcopy.
That loses on systems that don't provide the function, so we have
to redefine it here. */
#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
#define bcopy(from, to, len) memcpy ((to), (from), (len))
#endif
#define YYDEBUG 1
/* Lexical analyzer's current scan position in the input string. */
static char *curpos;
/* The return value. */
static struct tm t;
time_t mktime ();
#define zzparse posixtime_zzparse
static int zzlex ();
static int zzerror ();
#ifndef YYLTYPE
typedef
struct zzltype
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
}
zzltype;
#define YYLTYPE zzltype
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#include <stdio.h>
#ifndef __cplusplus
#ifndef __STDC__
#define const
#endif
#endif
#define YYFINAL 15
#define YYFLAG -32768
#define YYNTBASE 5
#define YYTRANSLATE(x) ((unsigned)(x) <= 258 ? zztranslate[x] : 9)
static const char zztranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 4, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 2, 3
};
#if YYDEBUG != 0
static const short zzprhs[] = { 0,
0, 7, 9, 12, 13, 14, 17
};
static const short zzrhs[] = { 8,
8, 8, 8, 6, 7, 0, 8, 0, 8, 8,
0, 0, 0, 4, 8, 0, 3, 3, 0
};
#endif
#if YYDEBUG != 0
static const short zzrline[] = { 0,
78, 107, 114, 121, 132, 135, 144
};
static const char * const zztname[] = { "$","error","$illegal.","DIGIT","'.'",
"date","year","seconds","digitpair",""
};
#endif
static const short zzr1[] = { 0,
5, 6, 6, 6, 7, 7, 8
};
static const short zzr2[] = { 0,
6, 1, 2, 0, 0, 2, 2
};
static const short zzdefact[] = { 0,
0, 0, 7, 0, 0, 4, 5, 2, 0, 1,
3, 6, 0, 0, 0
};
static const short zzdefgoto[] = { 13,
7, 10, 2
};
static const short zzpact[] = { 2,
5, 2,-32768, 2, 2, 2, -3, 2, 2,-32768,
-32768,-32768, 9, 10,-32768
};
static const short zzpgoto[] = {-32768,
-32768,-32768, -2
};
#define YYLAST 10
static const short zztable[] = { 4,
9, 5, 6, 8, 1, 11, 12, 3, 14, 15
};
static const short zzcheck[] = { 2,
4, 4, 5, 6, 3, 8, 9, 3, 0, 0
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/local/lib/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef alloca
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
#include <alloca.h>
#else /* not sparc */
#if defined (MSDOS) && !defined (__TURBOC__)
#include <malloc.h>
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
#include <malloc.h>
#pragma alloca
#else /* not MSDOS, __TURBOC__, or _AIX */
#ifdef __hpux
#ifdef __cplusplus
extern "C" {
void *alloca (unsigned int);
};
#else /* not __cplusplus */
void *alloca ();
#endif /* not __cplusplus */
#endif /* __hpux */
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
#endif /* not sparc. */
#endif /* not GNU C. */
#endif /* alloca not defined. */
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
as one case of the switch. */
#define zzerrok (zzerrstatus = 0)
#define zzclearin (zzchar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR goto zzerrlab1
/* Like YYERROR except do call zzerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto zzerrlab
#define YYRECOVERING() (!!zzerrstatus)
#define YYBACKUP(token, value) \
do \
if (zzchar == YYEMPTY && zzlen == 1) \
{ zzchar = (token), zzlval = (value); \
zzchar1 = YYTRANSLATE (zzchar); \
YYPOPSTACK; \
goto zzbackup; \
} \
else \
{ zzerror ("syntax error: cannot back up"); YYERROR; } \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYPURE
#define YYLEX zzlex()
#endif
#ifdef YYPURE
#ifdef YYLSP_NEEDED
#define YYLEX zzlex(&zzlval, &zzlloc)
#else
#define YYLEX zzlex(&zzlval)
#endif
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYPURE
int zzchar; /* the lookahead symbol */
YYSTYPE zzlval; /* the semantic value of the */
/* lookahead symbol */
#ifdef YYLSP_NEEDED
YYLTYPE zzlloc; /* location data for the lookahead */
/* symbol */
#endif
int zznerrs; /* number of parse errors so far */
#endif /* not YYPURE */
#if YYDEBUG != 0
int zzdebug; /* nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#ifndef YYINITDEPTH
#define YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can grow to
(effective only if the built-in stack extension method is used). */
#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
/* Prevent warning if -Wstrict-prototypes. */
#ifdef __GNUC__
int zzparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
#define __zz_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
#ifndef __cplusplus
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__zz_bcopy (from, to, count)
char *from;
char *to;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#else /* __cplusplus */
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__zz_bcopy (char *from, char *to, int count)
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#endif
#endif
#line 184 "/usr/local/lib/bison.simple"
int
zzparse()
{
register int zzstate;
register int zzn;
register short *zzssp;
register YYSTYPE *zzvsp;
int zzerrstatus; /* number of tokens to shift before error messages enabled */
int zzchar1 = 0; /* lookahead token as an internal (translated) token number */
short zzssa[YYINITDEPTH]; /* the state stack */
YYSTYPE zzvsa[YYINITDEPTH]; /* the semantic value stack */
short *zzss = zzssa; /* refer to the stacks thru separate pointers */
YYSTYPE *zzvs = zzvsa; /* to allow zzoverflow to reallocate them elsewhere */
#ifdef YYLSP_NEEDED
YYLTYPE zzlsa[YYINITDEPTH]; /* the location stack */
YYLTYPE *zzls = zzlsa;
YYLTYPE *zzlsp;
#define YYPOPSTACK (zzvsp--, zzssp--, zzlsp--)
#else
#define YYPOPSTACK (zzvsp--, zzssp--)
#endif
int zzstacksize = YYINITDEPTH;
#ifdef YYPURE
int zzchar;
YYSTYPE zzlval;
int zznerrs;
#ifdef YYLSP_NEEDED
YYLTYPE zzlloc;
#endif
#endif
YYSTYPE zzval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int zzlen;
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Starting parse\n");
#endif
zzstate = 0;
zzerrstatus = 0;
zznerrs = 0;
zzchar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
zzssp = zzss - 1;
zzvsp = zzvs;
#ifdef YYLSP_NEEDED
zzlsp = zzls;
#endif
/* Push a new state, which is found in zzstate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
zznewstate:
*++zzssp = zzstate;
if (zzssp >= zzss + zzstacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *zzvs1 = zzvs;
short *zzss1 = zzss;
#ifdef YYLSP_NEEDED
YYLTYPE *zzls1 = zzls;
#endif
/* Get the current used size of the three stacks, in elements. */
int size = zzssp - zzss + 1;
#ifdef zzoverflow
/* Each stack pointer address is followed by the size of
the data in use in that stack, in bytes. */
#ifdef YYLSP_NEEDED
/* This used to be a conditional around just the two extra args,
but that might be undefined if zzoverflow is a macro. */
zzoverflow("parser stack overflow",
&zzss1, size * sizeof (*zzssp),
&zzvs1, size * sizeof (*zzvsp),
&zzls1, size * sizeof (*zzlsp),
&zzstacksize);
#else
zzoverflow("parser stack overflow",
&zzss1, size * sizeof (*zzssp),
&zzvs1, size * sizeof (*zzvsp),
&zzstacksize);
#endif
zzss = zzss1; zzvs = zzvs1;
#ifdef YYLSP_NEEDED
zzls = zzls1;
#endif
#else /* no zzoverflow */
/* Extend the stack our own way. */
if (zzstacksize >= YYMAXDEPTH)
{
zzerror("parser stack overflow");
return 2;
}
zzstacksize *= 2;
if (zzstacksize > YYMAXDEPTH)
zzstacksize = YYMAXDEPTH;
zzss = (short *) alloca (zzstacksize * sizeof (*zzssp));
__zz_bcopy ((char *)zzss1, (char *)zzss, size * sizeof (*zzssp));
zzvs = (YYSTYPE *) alloca (zzstacksize * sizeof (*zzvsp));
__zz_bcopy ((char *)zzvs1, (char *)zzvs, size * sizeof (*zzvsp));
#ifdef YYLSP_NEEDED
zzls = (YYLTYPE *) alloca (zzstacksize * sizeof (*zzlsp));
__zz_bcopy ((char *)zzls1, (char *)zzls, size * sizeof (*zzlsp));
#endif
#endif /* no zzoverflow */
zzssp = zzss + size - 1;
zzvsp = zzvs + size - 1;
#ifdef YYLSP_NEEDED
zzlsp = zzls + size - 1;
#endif
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Stack size increased to %d\n", zzstacksize);
#endif
if (zzssp >= zzss + zzstacksize - 1)
YYABORT;
}
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Entering state %d\n", zzstate);
#endif
goto zzbackup;
zzbackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* zzresume: */
/* First try to decide what to do without reference to lookahead token. */
zzn = zzpact[zzstate];
if (zzn == YYFLAG)
goto zzdefault;
/* Not known => get a lookahead token if don't already have one. */
/* zzchar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (zzchar == YYEMPTY)
{
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Reading a token: ");
#endif
zzchar = YYLEX;
}
/* Convert token to internal form (in zzchar1) for indexing tables with */
if (zzchar <= 0) /* This means end of input. */
{
zzchar1 = 0;
zzchar = YYEOF; /* Don't call YYLEX any more */
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Now at end of input.\n");
#endif
}
else
{
zzchar1 = YYTRANSLATE(zzchar);
#if YYDEBUG != 0
if (zzdebug)
{
fprintf (stderr, "Next token is %d (%s", zzchar, zztname[zzchar1]);
/* Give the individual parser a way to print the precise meaning
of a token, for further debugging info. */
#ifdef YYPRINT
YYPRINT (stderr, zzchar, zzlval);
#endif
fprintf (stderr, ")\n");
}
#endif
}
zzn += zzchar1;
if (zzn < 0 || zzn > YYLAST || zzcheck[zzn] != zzchar1)
goto zzdefault;
zzn = zztable[zzn];
/* zzn is what to do for this token type in this state.
Negative => reduce, -zzn is rule number.
Positive => shift, zzn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (zzn < 0)
{
if (zzn == YYFLAG)
goto zzerrlab;
zzn = -zzn;
goto zzreduce;
}
else if (zzn == 0)
goto zzerrlab;
if (zzn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Shifting token %d (%s), ", zzchar, zztname[zzchar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (zzchar != YYEOF)
zzchar = YYEMPTY;
*++zzvsp = zzlval;
#ifdef YYLSP_NEEDED
*++zzlsp = zzlloc;
#endif
/* count tokens shifted since error; after three, turn off error status. */
if (zzerrstatus) zzerrstatus--;
zzstate = zzn;
goto zznewstate;
/* Do the default action for the current state. */
zzdefault:
zzn = zzdefact[zzstate];
if (zzn == 0)
goto zzerrlab;
/* Do a reduction. zzn is the number of a rule to reduce with. */
zzreduce:
zzlen = zzr2[zzn];
if (zzlen > 0)
zzval = zzvsp[1-zzlen]; /* implement default value of the action */
#if YYDEBUG != 0
if (zzdebug)
{
int i;
fprintf (stderr, "Reducing via rule %d (line %d), ",
zzn, zzrline[zzn]);
/* Print the symbols being reduced, and their result. */
for (i = zzprhs[zzn]; zzrhs[i] > 0; i++)
fprintf (stderr, "%s ", zztname[zzrhs[i]]);
fprintf (stderr, " -> %s\n", zztname[zzr1[zzn]]);
}
#endif
switch (zzn) {
case 1:
#line 84 "./posixtm.y"
{
if (zzvsp[-5] >= 1 && zzvsp[-5] <= 12)
t.tm_mon = zzvsp[-5] - 1;
else {
YYABORT;
}
if (zzvsp[-4] >= 1 && zzvsp[-4] <= 31)
t.tm_mday = zzvsp[-4];
else {
YYABORT;
}
if (zzvsp[-3] >= 0 && zzvsp[-3] <= 23)
t.tm_hour = zzvsp[-3];
else {
YYABORT;
}
if (zzvsp[-2] >= 0 && zzvsp[-2] <= 59)
t.tm_min = zzvsp[-2];
else {
YYABORT;
}
;
break;}
case 2:
#line 107 "./posixtm.y"
{
t.tm_year = zzvsp[0];
/* Deduce the century based on the year.
See POSIX.2 section 4.63.3. */
if (zzvsp[0] <= 68)
t.tm_year += 100;
;
break;}
case 3:
#line 114 "./posixtm.y"
{
t.tm_year = zzvsp[-1] * 100 + zzvsp[0];
if (t.tm_year < 1900) {
YYABORT;
} else
t.tm_year -= 1900;
;
break;}
case 4:
#line 121 "./posixtm.y"
{
time_t now;
struct tm *tmp;
/* Use current year. */
time (&now);
tmp = localtime (&now);
t.tm_year = tmp->tm_year;
;
break;}
case 5:
#line 132 "./posixtm.y"
{
t.tm_sec = 0;
;
break;}
case 6:
#line 135 "./posixtm.y"
{
if (zzvsp[0] >= 0 && zzvsp[0] <= 61)
t.tm_sec = zzvsp[0];
else {
YYABORT;
}
;
break;}
case 7:
#line 144 "./posixtm.y"
{
zzval = zzvsp[-1] * 10 + zzvsp[0];
;
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 465 "/usr/local/lib/bison.simple"
zzvsp -= zzlen;
zzssp -= zzlen;
#ifdef YYLSP_NEEDED
zzlsp -= zzlen;
#endif
#if YYDEBUG != 0
if (zzdebug)
{
short *ssp1 = zzss - 1;
fprintf (stderr, "state stack now");
while (ssp1 != zzssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++zzvsp = zzval;
#ifdef YYLSP_NEEDED
zzlsp++;
if (zzlen == 0)
{
zzlsp->first_line = zzlloc.first_line;
zzlsp->first_column = zzlloc.first_column;
zzlsp->last_line = (zzlsp-1)->last_line;
zzlsp->last_column = (zzlsp-1)->last_column;
zzlsp->text = 0;
}
else
{
zzlsp->last_line = (zzlsp+zzlen-1)->last_line;
zzlsp->last_column = (zzlsp+zzlen-1)->last_column;
}
#endif
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
zzn = zzr1[zzn];
zzstate = zzpgoto[zzn - YYNTBASE] + *zzssp;
if (zzstate >= 0 && zzstate <= YYLAST && zzcheck[zzstate] == *zzssp)
zzstate = zztable[zzstate];
else
zzstate = zzdefgoto[zzn - YYNTBASE];
goto zznewstate;
zzerrlab: /* here on detecting error */
if (! zzerrstatus)
/* If not already recovering from an error, report this error. */
{
++zznerrs;
#ifdef YYERROR_VERBOSE
zzn = zzpact[zzstate];
if (zzn > YYFLAG && zzn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
/* Start X at -zzn if nec to avoid negative indexes in zzcheck. */
for (x = (zzn < 0 ? -zzn : 0);
x < (sizeof(zztname) / sizeof(char *)); x++)
if (zzcheck[x + zzn] == x)
size += strlen(zztname[x]) + 15, count++;
msg = (char *) malloc(size + 15);
if (msg != 0)
{
strcpy(msg, "parse error");
if (count < 5)
{
count = 0;
for (x = (zzn < 0 ? -zzn : 0);
x < (sizeof(zztname) / sizeof(char *)); x++)
if (zzcheck[x + zzn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, zztname[x]);
strcat(msg, "'");
count++;
}
}
zzerror(msg);
free(msg);
}
else
zzerror ("parse error; also virtual memory exceeded");
}
else
#endif /* YYERROR_VERBOSE */
zzerror("parse error");
}
goto zzerrlab1;
zzerrlab1: /* here on error raised explicitly by an action */
if (zzerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (zzchar == YYEOF)
YYABORT;
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Discarding token %d (%s).\n", zzchar, zztname[zzchar1]);
#endif
zzchar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
zzerrstatus = 3; /* Each real token shifted decrements this */
goto zzerrhandle;
zzerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
zzn = zzdefact[zzstate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (zzn) goto zzdefault;
#endif
zzerrpop: /* pop the current state because it cannot handle the error token */
if (zzssp == zzss) YYABORT;
zzvsp--;
zzstate = *--zzssp;
#ifdef YYLSP_NEEDED
zzlsp--;
#endif
#if YYDEBUG != 0
if (zzdebug)
{
short *ssp1 = zzss - 1;
fprintf (stderr, "Error: state stack now");
while (ssp1 != zzssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
zzerrhandle:
zzn = zzpact[zzstate];
if (zzn == YYFLAG)
goto zzerrdefault;
zzn += YYTERROR;
if (zzn < 0 || zzn > YYLAST || zzcheck[zzn] != YYTERROR)
goto zzerrdefault;
zzn = zztable[zzn];
if (zzn < 0)
{
if (zzn == YYFLAG)
goto zzerrpop;
zzn = -zzn;
goto zzreduce;
}
else if (zzn == 0)
goto zzerrpop;
if (zzn == YYFINAL)
YYACCEPT;
#if YYDEBUG != 0
if (zzdebug)
fprintf(stderr, "Shifting error token, ");
#endif
*++zzvsp = zzlval;
#ifdef YYLSP_NEEDED
*++zzlsp = zzlloc;
#endif
zzstate = zzn;
goto zznewstate;
}
#line 148 "./posixtm.y"
static int
zzlex ()
{
char ch = *curpos++;
if (ch >= '0' && ch <= '9')
{
zzlval = ch - '0';
return DIGIT;
}
else if (ch == '.' || ch == 0)
return ch;
else
return '?'; /* Cause an error. */
}
static int
zzerror ()
{
return 0;
}
/* Parse a POSIX-style date and return it, or (time_t)-1 for an error. */
time_t
posixtime (s)
char *s;
{
curpos = s;
/* Let mktime decide whether it is daylight savings time. */
t.tm_isdst = -1;
if (zzparse ())
return (time_t)-1;
else
return mktime (&t);
}
/* Parse a POSIX-style date and return it, or NULL for an error. */
struct tm *
posixtm (s)
char *s;
{
if (posixtime (s) == -1)
return NULL;
return &t;
}

View File

@@ -1,64 +1,65 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
/* Copyright (C) 1991, 1994 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
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
Library General Public License for more details.
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 Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <errno.h>
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* Define-away any (possibly conflicting) prototype of putenv.
Many systems omit the `const' attribute on the argument. */
#define putenv _sys_putenv
#if defined (__GNU_LIBRARY__) || defined (HAVE_STDLIB_H)
#include <stdlib.h>
#endif /* GNU C library. */
#ifndef STDC_HEADERS
extern int errno;
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#if defined (__GNU_LIBRARY__) || defined (HAVE_STRING_H)
#include <string.h>
#ifndef index
#define index strchr
#endif
#ifndef bcopy
#define bcopy(s, d, n) memcpy((d), (s), (n))
#endif
#else
#include <strings.h>
#endif
#ifdef HAVE_UNISTD_H
#if defined (__GNU_LIBRARY__) || defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#ifndef NULL
#define NULL 0
#undef putenv
#if !defined (__GNU_LIBRARY__) && !defined (HAVE_STRCHR)
#define strchr index
#endif
#if !defined (__GNU_LIBRARY__) && !defined (HAVE_MEMCPY)
#define memcpy(d,s,n) bcopy ((s), (d), (n))
#endif
#if HAVE_GNU_LD
#define environ __environ
#else
extern char **environ;
#endif
/* Put STRING, which is of the form "NAME=VALUE", in the environment. */
int
putenv (string)
const char *string;
{
char *name_end = index (string, '=');
const char *const name_end = strchr (string, '=');
register size_t size;
register char **ep;
@@ -93,11 +94,12 @@ putenv (string)
char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
if (new_environ == NULL)
return -1;
(void) bcopy ((char *) environ, (char *) new_environ, size * sizeof (char *));
(void) memcpy ((void *) new_environ, (void *) environ,
size * sizeof (char *));
new_environ[size] = (char *) string;
new_environ[size + 1] = NULL;
if (last_environ != NULL)
free ((char *) last_environ);
free ((void *) last_environ);
last_environ = new_environ;
environ = new_environ;
}

214
lib/readtokens.c Normal file
View File

@@ -0,0 +1,214 @@
/* readtokens.c -- Functions for reading tokens from an input stream.
Copyright (C) 1990-1991 Jim Meyering.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Written by Jim Meyering. */
/* This almost supercedes xreadline stuff -- using delim="\n"
gives the same functionality, except that these functions
would never return empty lines.
To Do:
- To allow '\0' as a delimiter, I will have to change
interfaces to permit specification of delimiter-string
length.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
#if defined (STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
#include "readtokens.h"
void *xmalloc ();
void *xrealloc ();
#define STREQ(a,b) ((a) == (b) || ((a) && (b) && *(a) == *(b) \
&& strcmp(a, b) == 0))
/* Initialize a tokenbuffer. */
void
init_tokenbuffer (token_buffer *tokenbuffer)
{
tokenbuffer->size = INITIAL_TOKEN_LENGTH;
tokenbuffer->buffer = ((char *) xmalloc (INITIAL_TOKEN_LENGTH));
}
/* Read a token from `stream' into `tokenbuffer'.
Upon return, the token is in tokenbuffer->buffer and
has a trailing '\0' instead of the original delimiter.
The function value is the length of the token not including
the final '\0'. When EOF is reached (i.e. on the call
after the last token is read), -1 is returned and tokenbuffer
isn't modified.
This function will work properly on lines containing NUL bytes
and on files that aren't newline-terminated. */
long
readtoken (FILE *stream, const char *delim, int n_delim,
token_buffer *tokenbuffer)
{
char *p;
int c, i, n;
static const char *saved_delim = NULL;
static char isdelim[256];
int same_delimiters;
if (delim == NULL && saved_delim == NULL)
abort ();
same_delimiters = 0;
if (delim != saved_delim && saved_delim != NULL)
{
same_delimiters = 1;
for (i = 0; i < n_delim; i++)
{
if (delim[i] != saved_delim[i])
{
same_delimiters = 0;
break;
}
}
}
if (!same_delimiters)
{
const char *t;
saved_delim = delim;
for (i = 0; i < sizeof (isdelim); i++)
isdelim[i] = 0;
for (t = delim; *t; t++)
isdelim[(unsigned int) *t] = 1;
}
p = tokenbuffer->buffer;
n = tokenbuffer->size;
i = 0;
/* FIXME: don't fool with this caching BS. Use strchr instead. */
/* skip over any leading delimiters */
for (c = getc (stream); c >= 0 && isdelim[c]; c = getc (stream))
{
/* empty */
}
for (;;)
{
if (i >= n)
{
n = 3 * (n / 2 + 1);
p = xrealloc (p, (unsigned int) n);
}
if (c < 0)
{
if (i == 0)
return (-1);
p[i] = 0;
break;
}
if (isdelim[c])
{
p[i] = 0;
break;
}
p[i++] = c;
c = getc (stream);
}
tokenbuffer->buffer = p;
tokenbuffer->size = n;
return (i);
}
/* Return a NULL-terminated array of pointers to tokens
read from `stream.' The number of tokens is returned
as the value of the function.
All storage is obtained through calls to malloc();
%%% Question: is it worth it to do a single
%%% realloc() of `tokens' just before returning? */
int
readtokens (FILE *stream, int projected_n_tokens,
const char *delim, int n_delim,
char ***tokens_out, long **token_lengths)
{
token_buffer tb, *token = &tb;
int token_length;
char **tokens;
long *lengths;
int sz;
int n_tokens;
n_tokens = 0;
if (projected_n_tokens > 0)
projected_n_tokens++; /* add one for trailing NULL pointer */
else
projected_n_tokens = 64;
sz = projected_n_tokens;
tokens = (char **) xmalloc (sz * sizeof (char *));
lengths = (long *) xmalloc (sz * sizeof (long));
init_tokenbuffer (token);
for (;;)
{
char *tmp;
token_length = readtoken (stream, delim, n_delim, token);
if (n_tokens >= sz)
{
sz *= 2;
tokens = (char **) xrealloc (tokens, sz * sizeof (char *));
lengths = (long *) xrealloc (lengths, sz * sizeof (long));
}
if (token_length < 0)
{
/* don't increment n_tokens for NULL entry */
tokens[n_tokens] = NULL;
lengths[n_tokens] = -1;
break;
}
tmp = (char *) xmalloc ((token_length + 1) * sizeof (char));
lengths[n_tokens] = token_length;
tokens[n_tokens] = strncpy (tmp, token->buffer,
(unsigned) (token_length + 1));
n_tokens++;
}
free (token->buffer);
*tokens_out = tokens;
if (token_lengths != NULL)
*token_lengths = lengths;
return n_tokens;
}

29
lib/readtokens.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef H_READTOKENS_H
#define H_READTOKENS_H
#ifndef INITIAL_TOKEN_LENGTH
#define INITIAL_TOKEN_LENGTH 20
#endif
#ifndef TOKENBUFFER_DEFINED
#define TOKENBUFFER_DEFINED
struct tokenbuffer
{
long size;
char *buffer;
};
typedef struct tokenbuffer token_buffer;
#endif /* not TOKENBUFFER_DEFINED */
void init_tokenbuffer (token_buffer *tokenbuffer);
long
readtoken (FILE *stream, const char *delim, int n_delim,
token_buffer *tokenbuffer);
int
readtokens (FILE *stream, int projected_n_tokens,
const char *delim, int n_delim,
char ***tokens_out, long **token_lengths);
#endif /* not H_READTOKENS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.11.
expression library, version 0.12.
Copyright (C) 1985, 89, 90, 91, 92 Free Software Foundation, Inc.
Copyright (C) 1985, 89, 90, 91, 92, 93, 95 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
@@ -20,7 +20,15 @@
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__
/* POSIX says that <sys/types.h> must be included before <regex.h>. */
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#if !defined (_POSIX_C_SOURCE) && !defined (_POSIX_SOURCE) && defined (VMS)
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
#include <stddef.h>
#endif
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax
@@ -122,6 +130,10 @@ typedef unsigned reg_syntax_t;
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
@@ -137,7 +149,7 @@ extern reg_syntax_t re_syntax_options;
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VAR | RE_NO_EMPTY_RANGES \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_UNMATCHED_RIGHT_PAREN_ORD)
#define RE_SYNTAX_POSIX_AWK \
@@ -157,6 +169,9 @@ extern reg_syntax_t re_syntax_options;
#define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
@@ -264,6 +279,10 @@ typedef enum
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
#define RE_TRANSLATE_TYPE char *
#endif
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
@@ -290,7 +309,7 @@ struct re_pattern_buffer
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
char *translate;
RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
@@ -311,12 +330,12 @@ struct re_pattern_buffer
#define REGS_FIXED 2
unsigned regs_allocated : 2;
/* Set to zero when regex_compile compiles a pattern; set to one
by re_compile_fastmap when it updates the fastmap, if any. */
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned fastmap_accurate : 1;
/* If set, regexec reports only success or failure and does not
return anything in pmatch. */
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned no_sub : 1;
/* If set, a beginning-of-line anchor doesn't match at the
@@ -333,11 +352,6 @@ struct re_pattern_buffer
};
typedef struct re_pattern_buffer regex_t;
/* search.c (search_buffer) in Emacs needs this one opcode value. It is
defined both in `regex.c' and here. */
#define RE_EXACTN_VALUE 1
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
@@ -376,19 +390,17 @@ typedef struct
prototype (if we are ANSI), and once without (if we aren't) -- we
use the following macro to declare argument types. This
unfortunately clutters up the declarations a bit, but I think it's
worth it.
We also have to undo `const' if we are not ANSI and if it hasn't
previously being taken care of. */
worth it. */
#if __STDC__
#define _RE_ARGS(args) args
#else
#else /* not __STDC__ */
#define _RE_ARGS(args) ()
#ifndef const
#define const
#endif
#endif
#endif /* not __STDC__ */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
@@ -456,9 +468,11 @@ extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
#ifdef _REGEX_RE_COMP
/* 4.2 bsd compatibility. */
extern char *re_comp _RE_ARGS ((const char *));
extern int re_exec _RE_ARGS ((const char *));
#endif
/* POSIX compatibility. */
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));

View File

@@ -15,15 +15,23 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifndef STDC_HEADERS
#ifndef errno
extern int errno;
#endif
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif /* STAT_MACROS_BROKEN. */
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
/* Rename file FROM to file TO.
@@ -34,14 +42,30 @@ rename (from, to)
char *from;
char *to;
{
struct stat from_stats;
struct stat from_stats, to_stats;
int pid, status;
if (stat (from, &from_stats))
return -1;
if (unlink (to) && errno != ENOENT)
return -1;
/* Be careful not to unlink `from' if it happens to be equal to `to' or
(on filesystems that silently truncate filenames after 14 characters)
if `from' and `to' share the significant characters. */
if (stat (to, &to_stats))
{
if (errno != ENOENT)
return -1;
}
else
{
if ((from_stats.st_dev == to_stats.st_dev)
&& (from_stats.st_ino == to_stats.st_ino))
/* `from' and `to' designate the same file on that filesystem. */
return 0;
if (unlink (to) && errno != ENOENT)
return -1;
}
if (S_ISDIR (from_stats.st_mode))
{

86
lib/rmdir.c Normal file
View File

@@ -0,0 +1,86 @@
/* rmdir.c -- BSD compatible remove directory function for System V
Copyright (C) 1988, 1990 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
/* rmdir adapted from GNU tar. */
/* Remove directory DPATH.
Return 0 if successful, -1 if not. */
int
rmdir (dpath)
char *dpath;
{
int cpid, status;
struct stat statbuf;
if (stat (dpath, &statbuf) != 0)
return -1; /* errno already set */
if (!S_ISDIR (statbuf.st_mode))
{
errno = ENOTDIR;
return -1;
}
cpid = fork ();
switch (cpid)
{
case -1: /* cannot fork */
return -1; /* errno already set */
case 0: /* child process */
execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
_exit (1);
default: /* parent process */
/* Wait for kid to finish. */
while (wait (&status) != cpid)
/* Do nothing. */ ;
if (status & 0xFFFF)
{
/* /bin/rmdir failed. */
errno = EIO;
return -1;
}
return 0;
}
}

60
lib/safe-read.c Normal file
View File

@@ -0,0 +1,60 @@
/* safe-read.c -- an interface to read that retries after interrupts
Copyright (C) 1993, 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifndef errno
extern int errno;
#endif
/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
Return the actual number of bytes read, zero for EOF, or negative
for an error. */
int
safe_read (desc, ptr, len)
int desc;
char *ptr;
int len;
{
int n_chars;
if (len <= 0)
return len;
#ifdef EINTR
do
{
n_chars = read (desc, ptr, len);
}
while (n_chars < 0 && errno == EINTR);
#else
n_chars = read (desc, ptr, len);
#endif
return n_chars;
}

136
lib/save-cwd.c Normal file
View File

@@ -0,0 +1,136 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else
# include <sys/file.h>
#endif
#include <errno.h>
# ifndef errno
extern int errno;
#endif
#include "save-cwd.h"
#include "error.h"
char *xgetcwd __P((void));
/* Record the location of the current working directory in CWD so that
the program may change to other directories and later use restore_cwd
to return to the recorded location. This function may allocate
space using malloc (via xgetcwd) or leave a file descriptor open;
use free_cwd to perform the necessary free or close. Upon failure,
no memory is allocated, any locally opened file descriptors are
closed; return non-zero -- in that case, free_cwd need not be
called, but doing so is ok. Otherwise, return zero. */
int
save_cwd (cwd)
struct saved_cwd *cwd;
{
static int have_working_fchdir = 1;
cwd->desc = -1;
cwd->name = NULL;
if (have_working_fchdir)
{
#ifdef HAVE_FCHDIR
cwd->desc = open (".", O_RDONLY);
if (cwd->desc < 0)
{
error (0, errno, "cannot open current directory");
return 1;
}
# if __sun__ || sun
/* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
so we have to fall back to chdir. */
if (fchdir (cwd->desc))
{
if (errno == EINVAL)
{
close (cwd->desc);
cwd->desc = -1;
have_working_fchdir = 0;
}
else
{
error (0, errno, "current directory");
close (cwd->desc);
cwd->desc = -1;
return 1;
}
}
# endif /* __sun__ || sun */
#else
#define fchdir(x) (abort (), 0)
have_working_fchdir = 0;
#endif
}
if (!have_working_fchdir)
{
cwd->name = xgetcwd ();
if (cwd->name == NULL)
{
error (0, errno, "cannot get current directory");
return 1;
}
}
return 0;
}
/* Change to recorded location, CWD, in directory hierarchy.
If "saved working directory", NULL))
*/
int
restore_cwd (cwd, dest, from)
const struct saved_cwd *cwd;
const char *dest;
const char *from;
{
int fail = 0;
if (cwd->desc >= 0)
{
if (fchdir (cwd->desc))
{
error (0, errno, "cannot return to %s%s%s",
(dest ? dest : "saved working directory"),
(from ? " from " : ""),
(from ? from : ""));
fail = 1;
}
}
else if (chdir (cwd->name) < 0)
{
error (0, errno, "%s", cwd->name);
fail = 1;
}
return fail;
}
void
free_cwd (cwd)
struct saved_cwd *cwd;
{
if (cwd->desc >= 0)
close (cwd->desc);
if (cwd->name)
free (cwd->name);
}

23
lib/save-cwd.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef SAVE_CWD_H
#define SAVE_CWD_H 1
struct saved_cwd
{
int desc;
char *name;
};
#ifndef __P
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
#define __P(args) args
#else
#define __P(args) ()
#endif /* GCC. */
#endif /* Not __P. */
int save_cwd __P((struct saved_cwd *cwd));
int restore_cwd __P((const struct saved_cwd *cwd, const char *dest,
const char *from));
void free_cwd __P((struct saved_cwd *cwd));
#endif /* SAVE_CWD_H */

View File

@@ -15,30 +15,36 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by David MacKenzie <djm@ai.mit.edu>. */
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#ifdef DIRENT
#include <dirent.h>
#ifdef direct
#undef direct
#endif
#define direct dirent
#define NLENGTH(direct) (strlen((direct)->d_name))
#else
#define NLENGTH(direct) ((direct)->d_namlen)
#ifdef USG
#ifdef SYSNDIR
#include <sys/ndir.h>
#else
#include <ndir.h>
#endif
#else
#include <sys/dir.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef VOID_CLOSEDIR
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#ifdef CLOSEDIR_VOID
/* Fake a return value. */
#define CLOSEDIR(d) (closedir (d), 0)
#else
@@ -51,10 +57,10 @@
#else
char *malloc ();
char *realloc ();
#endif
#ifndef NULL
#define NULL 0
#endif
#endif
char *stpcpy ();
@@ -71,7 +77,7 @@ savedir (dir, name_size)
unsigned name_size;
{
DIR *dirp;
struct direct *dp;
struct dirent *dp;
char *name_space;
char *namep;
@@ -94,7 +100,7 @@ savedir (dir, name_size)
|| (dp->d_name[1] != '\0'
&& (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
{
unsigned size_needed = (namep - name_space) + NLENGTH (dp) + 2;
unsigned size_needed = (namep - name_space) + NAMLEN (dp) + 2;
if (size_needed > name_size)
{

View File

@@ -15,16 +15,18 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Copy SOURCE into DEST, stopping after copying the first '\0', and
return a pointer to the '\0' at the end of DEST;
in other words, return DEST + strlen (SOURCE). */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
char *
stpcpy (dest, source)
stpcpy (dest, src)
char *dest;
char *source;
const char *src;
{
while ((*dest++ = *source++) != '\0')
while ((*dest++ = *src++) != '\0')
/* Do nothing. */ ;
return dest - 1;
}

View File

@@ -1,22 +1,31 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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.
The GNU C Library 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
Library General Public License for more details.
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 Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
char *index ();
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#ifndef strchr
#define strchr index
#endif
#endif
/* Return the length of the maximum inital segment of S
which contains no characters from REJECT. */
@@ -28,7 +37,7 @@ strcspn (s, reject)
register int count = 0;
while (*s != '\0')
if (index (reject, *s++) == 0)
if (strchr (reject, *s++) == 0)
++count;
else
return count;

View File

@@ -46,6 +46,7 @@
%p locale's AM or PM
%r time, 12-hour (hh:mm:ss [AP]M)
%R time, 24-hour (hh:mm)
%s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension)
%S second (00..61)
%T time, 24-hour (hh:mm:ss)
%X locale's time representation (%H:%M:%S)
@@ -73,6 +74,11 @@
David MacKenzie <djm@gnu.ai.mit.edu> */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME))
#include <sys/time.h>
@@ -80,6 +86,10 @@
#include <time.h>
#endif
#ifndef STDC_HEADERS
time_t mktime ();
#endif
#if defined(HAVE_TZNAME)
extern char *tzname[2];
#endif
@@ -164,7 +174,7 @@ add_num3 (string, num, max, pad)
static int
add_str (to, from, max)
char *to;
char *from;
const char *from;
int max;
{
int i;
@@ -174,6 +184,25 @@ add_str (to, from, max)
return i;
}
static int
add_num_time_t (string, max, num)
char *string;
int max;
time_t num;
{
/* This buffer is large enough to hold the character representation
(including the trailing NUL) of any unsigned decimal quantity
whose binary representation fits in 128 bits. */
char buf[40];
int length;
if (sizeof (num) > 16)
abort ();
sprintf (buf, "%lu", (unsigned long) num);
length = add_str (string, buf, max);
return length;
}
/* Return the week in the year of the time in TM, with the weeks
starting on Sundays. */
@@ -319,6 +348,16 @@ strftime (string, max, format, tm)
length +=
strftime (&string[length], max - length, "%H:%M", tm);
break;
case 's':
{
struct tm writable_tm;
writable_tm = *tm;
length += add_num_time_t (&string[length], max - length,
mktime (&writable_tm));
}
break;
case 'S':
length +=
add_num2 (&string[length], tm->tm_sec, max - length, pad);

39
lib/strpbrk.c Normal file
View File

@@ -0,0 +1,39 @@
/* Copyright (C) 1991, 1994 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
/* Find the first ocurrence in S of any character in ACCEPT. */
char *
strpbrk (s, accept)
register const char *s;
register const char *accept;
{
while (*s != '\0')
{
const char *a = accept;
while (*a != '\0')
if (*a++ == *s)
return (char *) s;
++s;
}
return 0;
}

View File

@@ -1,41 +1,46 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
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.
The GNU C Library 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
Library General Public License for more details.
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 Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#include <ctype.h>
#include <math.h>
#if STDC_HEADERS
#ifdef HAVE_FLOAT_H
#include <float.h>
#else
#define DBL_MAX 1.7976931348623159e+308
#define DBL_MIN 2.2250738585072010e-308
#endif
#if STDC_HEADERS
#include <stdlib.h>
#include <string.h>
#else
#define NULL 0
#define DBL_MAX 1.7976931348623159e+308
#define DBL_MIN 2.2250738585072010e-308
extern int errno;
#endif
#ifndef HUGE_VAL
#define HUGE_VAL HUGE
#endif
#if !__STDC__
#define const
#endif
/* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the

View File

@@ -1,75 +1,152 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
The GNU C Library 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
Library General Public License for more details.
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.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef _LIBC
# define USE_NUMBER_GROUPING
# define STDC_HEADERS
# define HAVE_LIMITS_H
#endif
#include <ctype.h>
#include <errno.h>
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef ULONG_MAX
#define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
#define LONG_MIN (-LONG_MAX-1)
#define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
#endif
#if STDC_HEADERS
#include <stddef.h>
#include <stdlib.h>
#else
#define NULL 0
#ifndef errno
extern int errno;
#endif
#if !__STDC__
#define const
#if HAVE_LIMITS_H
# include <limits.h>
#endif
#ifndef UNSIGNED
#define UNSIGNED 0
#ifdef STDC_HEADERS
# include <stddef.h>
# include <stdlib.h>
#else
# ifndef NULL
# define NULL 0
# endif
#endif
#ifdef USE_NUMBER_GROUPING
# include "../locale/localeinfo.h"
#endif
/* Nonzero if we are defining `strtoul' or `strtouq', operating on
unsigned integers. */
#ifndef UNSIGNED
# define UNSIGNED 0
# define INT LONG int
#else
# define strtol strtoul
# define INT unsigned LONG int
#endif
/* If QUAD is defined, we are defining `strtoq' or `strtouq',
operating on `long long int's. */
#ifdef QUAD
# if UNSIGNED
# define strtoul strtouq
# else
# define strtol strtoq
# endif
# define LONG long long
# undef LONG_MIN
# define LONG_MIN LONG_LONG_MIN
# undef LONG_MAX
# define LONG_MAX LONG_LONG_MAX
# undef ULONG_MAX
# define ULONG_MAX ULONG_LONG_MAX
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
/* Work around gcc bug with using this constant. */
static const unsigned long long int maxquad = ULONG_LONG_MAX;
# undef ULONG_MAX
# define ULONG_MAX maxquad
# endif
#else
# define LONG long
#endif
#ifdef __STDC__
# define INTERNAL(x) INTERNAL1(x)
# define INTERNAL1(x) __##x##_internal
#else
# define INTERNAL(x) __/**/x/**/_internal
#endif
#ifdef USE_NUMBER_GROUPING
/* This file defines a function to check for correct grouping. */
# include "grouping.h"
#endif
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
If BASE is 0 the base is determined by the presence of a leading
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
If BASE is < 2 or > 36, it is reset to 10.
If ENDPTR is not NULL, a pointer to the character after the last
one converted is stored in *ENDPTR. */
#if UNSIGNED
unsigned long int
#define strtol strtoul
#else
long int
#endif
strtol (nptr, endptr, base)
INT
INTERNAL (strtol) (nptr, endptr, base, group)
const char *nptr;
char **endptr;
int base;
int group;
{
int negative;
register unsigned long int cutoff;
register unsigned LONG int cutoff;
register unsigned int cutlim;
register unsigned long int i;
register unsigned LONG int i;
register const char *s;
register unsigned char c;
const char *save;
const char *save, *end;
int overflow;
#ifdef USE_NUMBER_GROUPING
/* The thousands character of the current locale. */
wchar_t thousands;
/* The numeric grouping specification of the current locale,
in the format described in <locale.h>. */
const char *grouping;
if (group)
{
grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
if (*grouping <= 0 || *grouping == CHAR_MAX)
grouping = NULL;
else
{
/* Figure out the thousands separator character. */
if (mbtowc (&thousands, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
if (thousands == L'\0')
grouping = NULL;
}
}
else
grouping = NULL;
#endif
if (base < 0 || base == 1 || base > 36)
base = 10;
@@ -100,31 +177,49 @@ strtol (nptr, endptr, base)
/* If BASE is zero, figure it out ourselves. */
if (base == 0)
{
if (*s == '0')
{
if (toupper (s[1]) == 'X')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
}
if (*s == '0')
{
if (toupper (s[1]) == 'X')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
/* Save the pointer so we can check later if anything happened. */
save = s;
cutoff = ULONG_MAX / (unsigned long int) base;
cutlim = ULONG_MAX % (unsigned long int) base;
#ifdef USE_NUMBER_GROUPING
if (group)
{
/* Find the end of the digit string and check its grouping. */
end = s;
for (c = *end; c != '\0'; c = *++end)
if (c != thousands && !isdigit (c) &&
(!isalpha (c) || toupper (c) - 'A' + 10 >= base))
break;
if (*s == thousands)
end = s;
else
end = correctly_grouped_prefix (s, end, thousands, grouping);
}
else
#endif
end = NULL;
cutoff = ULONG_MAX / (unsigned LONG int) base;
cutlim = ULONG_MAX % (unsigned LONG int) base;
overflow = 0;
i = 0;
for (c = *s; c != '\0'; c = *++s)
{
if (s == end)
break;
if (isdigit (c))
c -= '0';
else if (isalpha (c))
@@ -138,7 +233,7 @@ strtol (nptr, endptr, base)
overflow = 1;
else
{
i *= (unsigned long int) base;
i *= (unsigned LONG int) base;
i += c;
}
}
@@ -152,18 +247,18 @@ strtol (nptr, endptr, base)
if (endptr != NULL)
*endptr = (char *) s;
#if !UNSIGNED
#if !UNSIGNED
/* Check for a value that is within the range of
`unsigned long int', but outside the range of `long int'. */
`unsigned LONG int', but outside the range of `LONG int'. */
if (i > (negative ?
- (unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
-(unsigned LONG int) LONG_MIN : (unsigned LONG int) LONG_MAX))
overflow = 1;
#endif
if (overflow)
{
errno = ERANGE;
#if UNSIGNED
#if UNSIGNED
return ULONG_MAX;
#else
return negative ? LONG_MIN : LONG_MAX;
@@ -171,11 +266,26 @@ strtol (nptr, endptr, base)
}
/* Return the result of the appropriate sign. */
return (negative ? - i : i);
return (negative ? -i : i);
noconv:;
noconv:
/* There was no number to convert. */
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
/* External user entry point. */
#ifdef weak_symbol
weak_symbol (strtol)
#endif
INT
strtol (nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
return INTERNAL (strtol) (nptr, endptr, base, 0);
}

View File

@@ -18,14 +18,21 @@
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I will use ./config.h rather than /config.h
(which it would do because it found this file in ). */
#include <config.h>
#else
#include "config.h"
#endif
#ifdef __GNUC__
# define alloca __builtin_alloca
#else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
char *alloca ();
# endif
# endif
#endif
#include <stdio.h>
@@ -33,23 +40,21 @@
#include <pwd.h>
#include <grp.h>
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#ifndef index
#define index strchr
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
#include <strings.h>
# include <strings.h>
# ifndef strchr
# define strchr index
# endif
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
char *malloc ();
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
# include <unistd.h>
#endif
#ifndef _POSIX_VERSION
@@ -58,15 +63,42 @@ struct group *getgrnam ();
struct group *getgrgid ();
#endif
#ifdef _POSIX_SOURCE
#define endpwent()
#define endgrent()
#ifndef HAVE_ENDGRENT
# define endgrent() ((void) 0)
#endif
#ifndef HAVE_ENDPWENT
# define endpwent() ((void) 0)
#endif
/* Perform the equivalent of the statement `dest = strdup (src);',
but obtaining storage via alloca instead of from the heap. */
#define V_STRDUP(dest, src) \
do \
{ \
int _len = strlen ((src)); \
(dest) = (char *) alloca (_len + 1); \
strcpy (dest, src); \
} \
while (0)
#define isdigit(c) ((c) >= '0' && (c) <= '9')
char *strdup ();
static int isnumber ();
/* Return nonzero if STR represents an unsigned decimal integer,
otherwise return 0. */
static int
is_number (str)
const char *str;
{
for (; *str; str++)
if (!isdigit (*str))
return 0;
return 1;
}
/* Extract from NAME, which has the form "[user][:.][group]",
a USERNAME, UID U, GROUPNAME, and GID G.
@@ -77,115 +109,172 @@ static int isnumber ();
USERNAME and GROUPNAME will be in newly malloc'd memory.
Either one might be NULL instead, indicating that it was not
given and the corresponding numeric ID was left unchanged.
Might write NULs into NAME.
Return NULL if successful, a static error message string if not. */
char *
parse_user_spec (name, uid, gid, username, groupname)
char *name;
const char *
parse_user_spec (spec_arg, uid, gid, username_arg, groupname_arg)
const char *spec_arg;
uid_t *uid;
gid_t *gid;
char **username, **groupname;
char **username_arg, **groupname_arg;
{
static char *tired = "virtual memory exhausted";
static const char *tired = "virtual memory exhausted";
const char *error_msg;
char *spec; /* A copy we can write on. */
struct passwd *pwd;
struct group *grp;
char *cp;
int use_login_group = 0;
char *g, *u, *separator;
char *groupname;
*username = *groupname = NULL;
error_msg = NULL;
*username_arg = *groupname_arg = NULL;
groupname = NULL;
/* Check whether a group is given. */
cp = index (name, ':');
if (cp == NULL)
cp = index (name, '.');
if (cp != NULL)
V_STRDUP (spec, spec_arg);
/* Find the separator if there is one. */
separator = strchr (spec, ':');
if (separator == NULL)
separator = strchr (spec, '.');
/* Replace separator with a NUL. */
if (separator != NULL)
*separator = '\0';
/* Set U and G to non-zero length strings corresponding to user and
group specifiers or to NULL. */
u = (*spec == '\0' ? NULL : spec);
g = (separator == NULL || *(separator + 1) == '\0'
? NULL
: separator + 1);
if (u == NULL && g == NULL)
return "can not omit both user and group";
if (u != NULL)
{
*cp++ = '\0';
if (*cp == '\0')
pwd = getpwnam (u);
if (pwd == NULL)
{
if (cp == name + 1)
/* Neither user nor group given, just "." or ":". */
return "can not omit both user and group";
if (!is_number (u))
error_msg = "invalid user";
else
/* "user.". */
use_login_group = 1;
{
int use_login_group;
use_login_group = (separator != NULL && g == NULL);
if (use_login_group)
error_msg = "cannot get the login group of a numeric UID";
else
*uid = atoi (u);
}
}
else
{
/* Explicit group. */
*groupname = strdup (cp);
if (*groupname == NULL)
return tired;
grp = getgrnam (cp);
if (grp == NULL)
*uid = pwd->pw_uid;
if (g == NULL && separator != NULL)
{
if (!isnumber (cp))
return "invalid group";
*gid = atoi (cp);
/* A separator was given, but a group was not specified,
so get the login group. */
*gid = pwd->pw_gid;
grp = getgrgid (pwd->pw_gid);
if (grp == NULL)
{
/* This is enough room to hold the unsigned decimal
representation of any 32-bit quantity and the trailing
zero byte. */
char uint_buf[21];
sprintf (uint_buf, "%u", (unsigned) (pwd->pw_gid));
V_STRDUP (groupname, uint_buf);
}
else
{
V_STRDUP (groupname, grp->gr_name);
}
endgrent ();
}
else
*gid = grp->gr_gid;
endgrent (); /* Save a file descriptor. */
}
endpwent ();
}
/* Parse the user name, now that any group has been removed. */
if (name[0] == '\0')
/* No user name was given, just a group. */
return NULL;
*username = strdup (name);
if (*username == NULL)
return tired;
pwd = getpwnam (name);
if (pwd == NULL)
if (g != NULL && error_msg == NULL)
{
if (!isnumber (name))
return "invalid user";
if (use_login_group)
return "cannot get the login group of a numeric UID";
*uid = atoi (name);
}
else
{
*uid = pwd->pw_uid;
if (use_login_group)
/* Explicit group. */
grp = getgrnam (g);
if (grp == NULL)
{
*gid = pwd->pw_gid;
grp = getgrgid (pwd->pw_gid);
if (grp == NULL)
{
*groupname = malloc (15);
if (*groupname == NULL)
return tired;
sprintf (*groupname, "%u", pwd->pw_gid);
}
if (!is_number (g))
error_msg = "invalid group";
else
*gid = atoi (g);
}
else
*gid = grp->gr_gid;
endgrent (); /* Save a file descriptor. */
if (error_msg == NULL)
V_STRDUP (groupname, g);
}
if (error_msg == NULL)
{
if (u != NULL)
{
*username_arg = strdup (u);
if (*username_arg == NULL)
error_msg = tired;
}
if (groupname != NULL && error_msg == NULL)
{
*groupname_arg = strdup (groupname);
if (*groupname_arg == NULL)
{
*groupname = strdup (grp->gr_name);
if (*groupname == NULL)
return tired;
if (*username_arg != NULL)
{
free (*username_arg);
*username_arg = NULL;
}
error_msg = tired;
}
endgrent ();
}
}
endpwent ();
return NULL;
return error_msg;
}
/* Return nonzero if STR represents an unsigned decimal integer,
otherwise return 0. */
#ifdef TEST
static int
isnumber (str)
char *str;
#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s))
int
main (int argc, char **argv)
{
for (; *str; str++)
if (!isdigit (*str))
return 0;
return 1;
int i;
for (i = 1; i < argc; i++)
{
const char *e;
char *username, *groupname;
uid_t uid;
gid_t gid;
char *tmp;
tmp = strdup (argv[i]);
e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
free (tmp);
printf ("%s: %u %u %s %s %s\n",
argv[i],
(unsigned int) uid,
(unsigned int) gid,
NULL_CHECK (username),
NULL_CHECK (groupname),
NULL_CHECK (e));
}
exit (0);
}
#endif

85
lib/xgetcwd.c Normal file
View File

@@ -0,0 +1,85 @@
/* xgetcwd.c -- return current directory with unlimited length
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by David MacKenzie, djm@gnu.ai.mit.edu. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#include <sys/types.h>
#include "pathmax.h"
#if !defined(_POSIX_VERSION) && !defined(HAVE_GETCWD)
char *getwd ();
#define getcwd(buf, max) getwd (buf)
#else
char *getcwd ();
#endif
/* Amount to increase buffer size by in each try. */
#define PATH_INCR 32
char *xmalloc ();
char *xrealloc ();
void free ();
/* Return the current directory, newly allocated, arbitrarily long.
Return NULL and set errno on error. */
char *
xgetcwd ()
{
char *cwd;
char *ret;
unsigned path_max;
errno = 0;
path_max = (unsigned) PATH_MAX;
path_max += 2; /* The getcwd docs say to do this. */
cwd = xmalloc (path_max);
errno = 0;
while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE)
{
path_max += PATH_INCR;
cwd = xrealloc (cwd, path_max);
errno = 0;
}
if (ret == NULL)
{
int save_errno = errno;
free (cwd);
errno = save_errno;
return NULL;
}
return cwd;
}

54
lib/xgethostname.c Normal file
View File

@@ -0,0 +1,54 @@
/* xgethostname.c -- return current hostname with unlimited length
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Jim Meyering, meyering@comco.com */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
int gethostname ();
char *xmalloc ();
char *xrealloc ();
#ifndef INITIAL_HOSTNAME_LENGTH
#define INITIAL_HOSTNAME_LENGTH 33
#endif
char *
xgethostname ()
{
char *hostname;
size_t size;
int err;
size = INITIAL_HOSTNAME_LENGTH;
hostname = xmalloc (size);
while (1)
{
hostname[size - 1] = '\0';
err = gethostname (hostname, size);
if (err == 0 && hostname[size - 1] == '\0')
break;
size *= 2;
hostname = xrealloc (hostname, size);
}
return hostname;
}

View File

@@ -1,5 +1,5 @@
/* xmalloc.c -- malloc with out of memory checking
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 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
@@ -15,51 +15,89 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef STDC_HEADERS
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if __STDC__
#define VOID void
#else
#define VOID char
#endif
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
#else
char *malloc ();
char *realloc ();
VOID *malloc ();
VOID *realloc ();
void free ();
#endif
/* This is for other GNU distributions with internationalized messages.
The GNU C Library itself does not yet support such messages. */
#if HAVE_LIBINTL_H
# include <libintl.h>
#else
# define gettext(msgid) (msgid)
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
/* Exit value when the requested amount of memory is not available.
The caller may set it to some other value. */
int xmalloc_exit_failure = EXIT_FAILURE;
#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
void error (int, int, const char *, ...);
#else
void error ();
#endif
static VOID *
fixup_null_alloc (n)
size_t n;
{
VOID *p;
p = 0;
if (n == 0)
p = malloc ((size_t) 1);
if (p == 0)
error (xmalloc_exit_failure, 0, gettext ("Memory exhausted"));
return p;
}
/* Allocate N bytes of memory dynamically, with error checking. */
char *
VOID *
xmalloc (n)
unsigned n;
size_t n;
{
char *p;
VOID *p;
p = malloc (n);
if (p == 0)
/* Must exit with 2 for `cmp'. */
error (2, 0, "virtual memory exhausted");
p = fixup_null_alloc (n);
return p;
}
/* Change the size of an allocated block of memory P to N bytes,
with error checking.
If P is NULL, run xmalloc.
If N is 0, run free and return NULL. */
If P is NULL, run xmalloc. */
char *
VOID *
xrealloc (p, n)
char *p;
unsigned n;
VOID *p;
size_t n;
{
if (p == 0)
return xmalloc (n);
if (n == 0)
{
free (p);
return 0;
}
p = realloc (p, n);
if (p == 0)
/* Must exit with 2 for `cmp'. */
error (2, 0, "virtual memory exhausted");
p = fixup_null_alloc (n);
return p;
}

156
lib/xstrtol.c Normal file
View File

@@ -0,0 +1,156 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
# ifndef strchr
# define strchr index
# endif
#endif
#define NDEBUG
#include <assert.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#if HAVE_LIMITS_H
# include <limits.h>
#endif
#ifndef ULONG_MAX
# define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
#endif
#ifndef LONG_MAX
# define LONG_MAX ((long int) (ULONG_MAX >> 1))
#endif
#include "xstrtol.h"
#define BKM_SCALE(x, scale_factor, error_return) \
do \
{ \
if ((x) > (double) __ZLONG_MAX / (scale_factor)) \
return (error_return); \
(x) *= (scale_factor); \
} \
while (0)
__unsigned long int __strtol ();
/* FIXME: comment. */
strtol_error
__xstrtol (s, ptr, base, val, valid_suffixes)
const char *s;
char **ptr;
int base;
__unsigned long int *val;
const char *valid_suffixes;
{
char *t_ptr;
char **p;
__unsigned long int tmp;
assert (0 <= base && base <= 36);
p = (ptr ? ptr : &t_ptr);
errno = 0;
tmp = __strtol (s, p, base);
if (errno != 0)
return LONGINT_OVERFLOW;
if (*p == s)
return LONGINT_INVALID;
if (!valid_suffixes)
{
if (**p == '\0')
{
*val = tmp;
return LONGINT_OK;
}
else
return LONGINT_INVALID_SUFFIX_CHAR;
}
if (**p != '\0' && strchr (valid_suffixes, **p))
{
switch (**p)
{
case 'b':
BKM_SCALE (tmp, 512, LONGINT_OVERFLOW);
++(*p);
break;
case 'c':
++(*p);
break;
case 'B':
case 'k':
BKM_SCALE (tmp, 1024, LONGINT_OVERFLOW);
++(*p);
break;
case 'm':
BKM_SCALE (tmp, 1024 * 1024, LONGINT_OVERFLOW);
++(*p);
break;
case 'w':
BKM_SCALE (tmp, 2, LONGINT_OVERFLOW);
++(*p);
break;
default:
return LONGINT_INVALID_SUFFIX_CHAR;
break;
}
}
*val = tmp;
return LONGINT_OK;
}
#ifdef TESTING_XSTRTO
#include <stdio.h>
#include "error.h"
char *program_name;
int
main (int argc, char** argv)
{
strtol_error s_err;
int i;
program_name = argv[0];
for (i=1; i<argc; i++)
{
char *p;
__unsigned long int val;
s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
if (s_err == LONGINT_OK)
{
printf ("%s->%lu (%s)\n", argv[i], val, p);
}
else
{
STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
}
}
exit (0);
}
#endif /* TESTING_XSTRTO */

66
lib/xstrtol.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef _xstrtol_h_
#define _xstrtol_h_ 1
#if STRING_TO_UNSIGNED
# define __xstrtol xstrtoul
# define __strtol strtoul
# define __unsigned unsigned
# define __ZLONG_MAX ULONG_MAX
#else
# define __xstrtol xstrtol
# define __strtol strtol
# define __unsigned /* empty */
# define __ZLONG_MAX LONG_MAX
#endif
#undef __P
#if defined (__STDC__) && __STDC__
#define __P(x) x
#else
#define __P(x) ()
#endif
enum strtol_error
{
LONGINT_OK, LONGINT_INVALID, LONGINT_INVALID_SUFFIX_CHAR, LONGINT_OVERFLOW
};
typedef enum strtol_error strtol_error;
strtol_error
__xstrtol __P ((const char *s, char **ptr, int base,
__unsigned long int *val, const char *valid_suffixes));
#define _STRTOL_ERROR(exit_code, str, argument_type_string, err) \
do \
{ \
switch ((err)) \
{ \
case LONGINT_OK: \
abort (); \
\
case LONGINT_INVALID: \
error ((exit_code), 0, "invalid %s `%s'", \
(argument_type_string), (str)); \
break; \
\
case LONGINT_INVALID_SUFFIX_CHAR: \
error ((exit_code), 0, "invalid character following %s `%s'", \
(argument_type_string), (str)); \
break; \
\
case LONGINT_OVERFLOW: \
/* FIXME: make this message dependent on STRING_TO_UNSIGNED */\
error ((exit_code), 0, "%s `%s' larger than maximum long int",\
(argument_type_string), (str)); \
break; \
} \
} \
while (0)
#define STRTOL_FATAL_ERROR(str, argument_type_string, err) \
_STRTOL_ERROR (2, str, argument_type_string, err)
#define STRTOL_FAIL_WARN(str, argument_type_string, err) \
_STRTOL_ERROR (0, str, argument_type_string, err)
#endif /* _xstrtol_h_ */

2
lib/xstrtoul.c Normal file
View File

@@ -0,0 +1,2 @@
#define STRING_TO_UNSIGNED 1
#include "xstrtol.c"

7
lib/xstrtoul.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _xstrtoul_h_
#define _xstrtoul_h_ 1
#define STRING_TO_UNSIGNED 1
#include "xstrtol.h"
#endif /* _xstrtoul_h_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,62 @@
User-visible changes in release 3.13:
* rename touch long option name --file to --reference.
`touch --file' will continue to work a little longer.
* df fails if the same file system type is both selected and excluded.
* df works around SunOS statfs brokenness wrt filesystems larger than 2GB
* df better handles inconsistent mtab entries
* `ls -lDR dir dir2' works
* `ls -c' does what it's supposed to
* all programs include program name in --version output
* `ls --quote-name' works
* mv properly determines whether src and dest are the same file
Before, it could (though with very low probability) fail to do the move,
reporting that distinct source and destination are the same file.
* du --dereference (-L) works with directory symlinks
* du works on SunOS 4 systems even when accounting is enabled
* many programs that convert strings to integers now use strtol or strtoul
and detect overflow
User-visible changes in release 3.12:
* None.
User-visible changes in release 3.11:
* None.
User-visible changes in release 3.10:
* mkdir -p now ignores arguments that are existing directories. Before,
(contrary to POSIX spec) it would attempt to change ownership and/or
protections of existing directories listed on the command line. And
it would fail when such a directory was owned by another user.
* Fix bug in cp that made the commands `mkdir dir; touch foo; cp -P foo dir'
incorrectly change the permissions on directory, dir.
* df accepts a new option, --no-sync, that inhibits the default invocation
of the sync system call. FIXME.
* ls accepts a new option, --dired, that makes emacs' dired mode more efficient
* skeletal texinfo documentation (mainly just the `invoking' nodes)
* ln accepts a new option: --no-dereference (-n). With this option,
if the destination command line argument is a symlink to a directory,
use that as the destination instead of the file in the directory.
* `ln -i no-such-file existing-file' gives a diagnostic and fails.
Before, if you responded `yes' to the prompt it would both remove
`existing-file' and fail to make a link.
* du no longer requires read access to all of the directory components
of the current working directory on systems with fchdir.
* touch -d 'date' is no longer off by one hour.
* New program: sync.
* Fix bug in cp that made the commands `ln -s . s; cp -rd s r' incorrectly
create `r' as a symlink instead of as a regular file.
* du's -S and -c options now work when used together.
Before, the grand total was always reported to be zero.
Major changes in release 3.9:
* --help gives a one-line description of each option and shows the
correspondence between short and long-named options.
* work around systems with BROKEN_STAT_MACROS
* work around problem where $(srcdir)/config.h was used instead of
../config.h -- this happened only when building in a subdirectory
and when config.h remained in $(srcdir) from a previous ./configure.
* GNU chmod treats symlinks the same way other vendor's versions do.
Now symlinks listed on the command line are processed (they were
ignored before); the permissions of the dereferenced files are
changed. Symlinks encountered in recursive traversals are still
ignored. This makes GNU chmod act more like e.g. Sun's.
* configure uses config.h, so DEFS won't exceed preprocessor limits of
some compilers on the number of symbols defined via -D.
* ls and cp can handle mount points on more systems
@@ -11,7 +69,7 @@ Major changes in release 3.9:
They used to succeed, ignoring the implicitly contradictory trailing slash.
Major changes in release 3.8:
* install isn't as likely to produce spurious errors
* install isn't as likely to produce spurious errors
* avoid redundant compilations for `dir' and `vdir';
* configure properly defines STAT_STATFS2_BSIZE on a Pyramid MIServer
running OSx 5.1
@@ -37,7 +95,7 @@ Major changes in release 3.5:
Major changes in release 3.4:
* cp -p and mv preserve setuid and setgid bits
* chown works on systems where sizeof(uid_t) != sizeof(int)
* chown works on systems where sizeof(uid_t) != sizeof(int)
or sizeof(uid) != sizeof(gid)
* catch errors from spurious slashes at ends of arguments

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,76 @@
User visible changes in release 1.13
* New utilities: factor, seq.
User visible changes in release 1.12
* None.
User visible changes in release 1.11
* date accepts new option: (-f) --file=DATEFILE
* skeletal texinfo documentation (mainly just the `invoking' nodes)
* `stty werase ^W' works. Before, werase wasn't enabled for AIX-3.2.5.
* su with no arguments works properly
* nice accepts options like `--5' (this is interpreted like `-n -5')
* nice now interprets `-1 -1' like `-1' not like `-11'
* `stty speed' and `stty size' no longer output a spurious newline
User visible changes in release 1.10
* change package name from shellutils to sh-utils
* add hostname, pwd, and users commands
* --version outputs the name of the utility as well as the package name
and version number.
* Configure properly determines options for stty on SCO ODT 3.0 systems.
* `date -d' works better. Before, `date -d '4apr94'' produced
`Sun Apr 3 23:00:00 CDT 1994'.
User visible changes in release 1.9.4
* Repair stty option handling.
User visible changes in release 1.9.3
* `stty -a -g' gets a diagnostic
* `stty {-a|-g} any-other-argument' gets a diagnostic
* stty no longer ignores some of its arguments
* basename and dirname no longer treat `--' specially
* `basename -- file.c .c' generates a usage error. Before, it output `file'.
* `basename file-dist -dist' outputs `file'. Before it output `file-dist'.
* stty defaults `swtch' to undefined for Solaris so `susp' (^Z) will work.
Before, with the default settings ^Z did nothing.
* stty no longer gives an error message when it finds a spurious difference
(due to buggy tcgetattr/tcsetattr) between requested and current tty
modes under SunOS 4.1.x.
* stty no longer fails if the ioctl to determine the display width fails
when displaying settings.
* stty works around SunOS 4.x kernel bug that made `stty rows 0 cols 0' fail.
* who and tee no longer fail gratuitously when continued after an
interrupted read or write system call.
* date accepts new format: %s time in seconds since 1970-01-01 00:00:00 UCT
* date -d can parse dates like `11-JUL-1991'
* expr '' == 0 works (before, it printed 1)
* stty no longer fails on telnet sessions to Solaris systems
* `cd /etc; who utmp' now works. Before, any filename argument had to be
absolute or relative to /dev.
User visible changes in release 1.9.2:
* who output is better formatted on Solaris and other SysVr4 systems
* fix a minor problem in formatting the output from `stty -a'
* yes with arguments outputs newlines again
* partial stty failures are reported
Major changes in release 1.9.1:
* stty can be built on Suns again
* minor fix for who -q
Major changes in release 1.9:
* su fails gracefully when getpass is unable to open /dev/tty.
* printenv and tty detect and report write errors
* fix bug in stty
* stty accepts the new options status and flush on systems that provide them
* `expr 1 / 0' gives an error message rather than trying to divide by zero
* expr's `substr' doesn't overrun malloc'd buffer
* expr recognizes the string `0' as zero
* better support for Linux, Dec Alpha, and SGI Irix
* all programs (even true and false) accept --version and --help options
* uname's --version option is no longer equivalent to its -v option
* configure uses config.h, so DEFS won't exceed preprocessor limits of
some compilers on the number of symbols defined via -D.
* work around problem where $(srcdir)/config.h was used instead of
../config.h -- this happened only when building in a subdirectory
and when config.h remained in $(srcdir) from a previous ./configure.
* make may be run from the subdirectories
Major changes in release 1.8:
* add echo command

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,82 @@
User-visible changes in release 1.14
* join accepts POSIX `-o 0' field specifier.
* tr 'a[b*512]' '[a*]' < /dev/null terminates
* tr '[:*3][:digit:]' 'a-m' and tr 'a[=*2][=c=]' 'xyyz' no longer fail
* special characters in tr's string1 and string2 may be escaped with backslash
User-visible changes in release 1.13
* md5sum: with --check, distinguish between open/read failure and bad checksum
* md5sum: remove -h, -s, -v short options
* md5sum: rename --verbose to --warn, --quiet to --status
* md5sum --check fails if it finds no properly formatted checksum lines
* sort -c prints `disorder on...' message on standard error, not stdout
* sort -k works as described in the texinfo documentation
* tail works on NetBSD
* md5sum reads and writes (de facto) standard Plumb/Lankester format
* sort accepts -.1 +.2 options for compatibility
* od works properly when dump limit is specified and is a multiple of
bytes_per_block (set by --width, 16 by default).
User-visible changes in release 1.12
* sort no longer reports spurious errors on Ultrix systems
* new program: md5sum
* all --help messages have been improved
* join's -a1 and -a2 options work
* tr '[:upper:]' '[:lower:]' no longer reads uninitialized memory
* sort properly handles command line arguments like `+7.2n'
* fmt properly formats paragraphs not terminated by a newline
* tail -f flushes stdout before sleeping so that it will output partial
lines sooner
* sort properly orders fields where one field is a proper prefix of the other
* sort properly interprets field offsets specified via the -k option
* dd, od, and tail work on systems for which off_t is long long (e.g. BSD4.4)
* wc is faster when not counting words
* wc now works even when file pointer isn't at beginning of file
* expand no longer seg faults with very long tab lists
User-visible changes in release 1.11
* fmt is built
User-visible changes in release 1.10
* skeletal texinfo documentation (mainly just the `invoking' nodes)
* new program: fmt
* tail -f on multiple files reports file truncation
* tail -q has been fixed so it never prints headers
* wc -c is much faster when operating on non-regular files
* unexpand gives a diagnostic (rather than a segfault) when given a name of
a nonexistent file.
* cat, csplit, head, split, sum, tac, tail, tr, and wc no longer fail
gratuitously when continued after a suspended read or write system call.
* cut interprets -d '' to mean `use the NUL byte as the delimiter' rather
than reporting that no delimiter was specified and failing.
* `echo a:b:c: | cut -d: -f3,4' prints `c:'. Before it printed just `c'.
* cut has been rewritten, is markedly faster for large inputs, and passes a
fairly large test suite.
* sort properly handles the argument to the -T option.
Major changes in release 1.9.1:
* cut no longer ignores the last line of input when that line lacks a
trailing newline character
Major changes in release 1.9:
* `echo a:b:c: | cut -d: -f3-' prints `c:' and
`echo a:b | cut -d: -f1' prints `a'.
* the command `printf '\t\n' |fold -w n' now terminates.
Before, it wouldn't stop for n less than 8.
* sort accepts and ignores -y[string] options for compatibilty with Solaris.
* cat -v /dev/null works on more systems
* od's --compatible (-C) flag renamed to --traditional (no short option)
* --help and --version exit successfully
* --help gives a one-line description of each option and shows the
correspondence between short and long-named options.
* fix bug in cut. Now `echo 'a:b:c:' | cut -d: -f3-' works.
Before it printed `c' instead of `c:'
* csplit allows repeat counts to be specified via `{*}'.
* csplit accepts a new option, --suffix=format that supercedes the
--digits option. The --digits option will continue to work.
* csplit accepts a new option, --elide-empty-files.
* configure uses config.h, so DEFS won't exceed preprocessor limits of
some compilers on the number of symbols defined via -D.
* work around problem where $(srcdir)/config.h was used instead of
../config.h -- this happened only when building in a subdirectory
and when config.h remained in $(srcdir) from a previous ./configure.
Major changes in release 1.8:
* added non-ANSIfied version of memchr.c from GNU libc.

19
src/ansi2knr.1 Normal file
View File

@@ -0,0 +1,19 @@
.TH ANSI2KNR 1 "31 December 1990"
.SH NAME
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS
.I ansi2knr
input_file output_file
.SH DESCRIPTION
If no output_file is supplied, output goes to stdout.
.br
There are no error messages.
.sp
.I ansi2knr
recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line.
.sp
The following constructs will confuse it:
.br
- Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call).
.br
- Macros that tinker with the syntax of the function header.

439
src/ansi2knr.c Normal file
View File

@@ -0,0 +1,439 @@
/* Copyright (C) 1989, 1991, 1993, 1994 Aladdin Enterprises. All rights reserved. */
/* ansi2knr.c */
/* Convert ANSI function declarations to K&R syntax */
/*
ansi2knr is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the GNU General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
ansi2knr, but only under the conditions described in the GNU
General Public License. A copy of this license is supposed to have been
given to you along with ansi2knr so you can know your rights and
responsibilities. It should be in a file named COPYLEFT. Among other
things, the copyright notice and this notice must be preserved on all
copies.
*/
/*
* Usage:
ansi2knr [--varargs] input_file [output_file]
* If no output_file is supplied, output goes to stdout.
* There are no error messages.
*
* ansi2knr recognizes function definitions by seeing a non-keyword
* identifier at the left margin, followed by a left parenthesis,
* with a right parenthesis as the last character on the line.
* It will recognize a multi-line header provided that the last character
* of the last line of the header is a right parenthesis,
* and no intervening line ends with a left brace or a semicolon.
* These algorithms ignore whitespace and comments, except that
* the function name must be the first thing on the line.
* The following constructs will confuse it:
* - Any other construct that starts at the left margin and
* follows the above syntax (such as a macro or function call).
* - Macros that tinker with the syntax of the function header.
*
* If the --varargs switch is supplied, ansi2knr will attempt to
* convert a ... argument to va_alist and va_dcl. If this switch is not
* supplied, ansi2knr will simply drop any such arguments.
*/
/*
* The original and principal author of ansi2knr is L. Peter Deutsch
* <ghost@aladdin.com>. Other authors are noted in the change history
* that follows (in reverse chronological order):
lpd 94-10-10 removed CONFIG_BROKETS conditional
lpd 94-07-16 added some conditionals to help GNU `configure',
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
properly erase prototype args in function parameters,
contributed by Jim Avera <jima@netcom.com>;
correct error in writeblanks (it shouldn't erase EOLs)
lpd 89-xx-xx original version
*/
/* Most of the conditionals here are to make ansi2knr work with */
/* the GNU configure machinery. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_CONFIG_H
/*
For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
This will define HAVE_CONFIG_H and so, activate the following lines.
*/
# if STDC_HEADERS || HAVE_STRING_H
# include <string.h>
# else
# include <strings.h>
# endif
#else /* not HAVE_CONFIG_H */
/*
Without AC_CONFIG_HEADER, merely use <string.h> as in the original
Ghostscript distribution. This loses on older BSD systems.
*/
# include <string.h>
#endif /* not HAVE_CONFIG_H */
#ifdef STDC_HEADERS
# include <stdlib.h>
#else
/*
malloc and free should be declared in stdlib.h,
but if you've got a K&R compiler, they probably aren't.
*/
char *malloc();
void free();
#endif
/* Scanning macros */
#define isidchar(ch) (isalnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
/* Forward references */
char *skipspace();
void writeblanks();
int test1();
int convert1();
/* The main program */
int
main(argc, argv)
int argc;
char *argv[];
{ FILE *in, *out;
#define bufsize 5000 /* arbitrary size */
char *buf;
char *line;
int convert_varargs = 0;
if ( argc > 1 && argv[1][0] == '-' )
{ if ( !strcmp(argv[1], "--varargs") )
{ convert_varargs = 1;
argc--;
argv++;
}
else
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
exit(1);
}
}
switch ( argc )
{
default:
printf("Usage: ansi2knr [--varargs] input_file [output_file]\n");
exit(0);
case 2:
out = stdout;
break;
case 3:
out = fopen(argv[2], "w");
if ( out == NULL )
{ fprintf(stderr, "Cannot open output file %s\n", argv[2]);
exit(1);
}
}
in = fopen(argv[1], "r");
if ( in == NULL )
{ fprintf(stderr, "Cannot open input file %s\n", argv[1]);
exit(1);
}
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
buf = malloc(bufsize);
line = buf;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{ switch ( test1(buf) )
{
case 2: /* a function header */
convert1(buf, out, 1, convert_varargs);
break;
case 1: /* a function */
convert1(buf, out, 0, convert_varargs);
break;
case -1: /* maybe the start of a function */
line = buf + strlen(buf);
if ( line != buf + (bufsize - 1) ) /* overflow check */
continue;
/* falls through */
default: /* not a function */
fputs(buf, out);
break;
}
line = buf;
}
if ( line != buf ) fputs(buf, out);
free(buf);
fclose(out);
fclose(in);
return 0;
}
/* Skip over space and comments, in either direction. */
char *
skipspace(p, dir)
register char *p;
register int dir; /* 1 for forward, -1 for backward */
{ for ( ; ; )
{ while ( isspace(*p) ) p += dir;
if ( !(*p == '/' && p[dir] == '*') ) break;
p += dir; p += dir;
while ( !(*p == '*' && p[dir] == '/') )
{ if ( *p == 0 ) return p; /* multi-line comment?? */
p += dir;
}
p += dir; p += dir;
}
return p;
}
/*
* Write blanks over part of a string.
* Don't overwrite end-of-line characters.
*/
void
writeblanks(start, end)
char *start;
char *end;
{ char *p;
for ( p = start; p < end; p++ )
if ( *p != '\r' && *p != '\n' ) *p = ' ';
}
/*
* Test whether the string in buf is a function definition.
* The string may contain and/or end with a newline.
* Return as follows:
* 0 - definitely not a function definition;
* 1 - definitely a function definition;
* 2 - definitely a function prototype (NOT USED);
* -1 - may be the beginning of a function definition,
* append another line and look again.
* The reason we don't attempt to convert function prototypes is that
* Ghostscript's declaration-generating macros look too much like
* prototypes, and confuse the algorithms.
*/
int
test1(buf)
char *buf;
{ register char *p = buf;
char *bend;
char *endfn;
int contin;
if ( !isidfirstchar(*p) )
return 0; /* no name at left margin */
bend = skipspace(buf + strlen(buf) - 1, -1);
switch ( *bend )
{
case ';': contin = 0 /*2*/; break;
case ')': contin = 1; break;
case '{': return 0; /* not a function */
default: contin = -1;
}
while ( isidchar(*p) ) p++;
endfn = p;
p = skipspace(p, 1);
if ( *p++ != '(' )
return 0; /* not a function */
p = skipspace(p, 1);
if ( *p == ')' )
return 0; /* no parameters */
/* Check that the apparent function name isn't a keyword. */
/* We only need to check for keywords that could be followed */
/* by a left parenthesis (which, unfortunately, is most of them). */
{ static char *words[] =
{ "asm", "auto", "case", "char", "const", "double",
"extern", "float", "for", "if", "int", "long",
"register", "return", "short", "signed", "sizeof",
"static", "switch", "typedef", "unsigned",
"void", "volatile", "while", 0
};
char **key = words;
char *kp;
int len = endfn - buf;
while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
return 0; /* name is a keyword */
key++;
}
}
return contin;
}
/* Convert a recognized function definition or header to K&R syntax. */
int
convert1(buf, out, header, convert_varargs)
char *buf;
FILE *out;
int header; /* Boolean */
int convert_varargs; /* Boolean */
{ char *endfn;
register char *p;
char **breaks;
unsigned num_breaks = 2; /* for testing */
char **btop;
char **bp;
char **ap;
char *vararg = 0;
/* Pre-ANSI implementations don't agree on whether strchr */
/* is called strchr or index, so we open-code it here. */
for ( endfn = buf; *(endfn++) != '('; ) ;
top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
if ( breaks == 0 )
{ /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out);
return -1;
}
btop = breaks + num_breaks * 2 - 2;
bp = breaks;
/* Parse the argument list */
do
{ int level = 0;
char *lp = NULL;
char *rp;
char *end = NULL;
if ( bp >= btop )
{ /* Filled up break table. */
/* Allocate a bigger one and start over. */
free((char *)breaks);
num_breaks <<= 1;
goto top;
}
*bp++ = p;
/* Find the end of the argument */
for ( ; end == NULL; p++ )
{ switch(*p)
{
case ',':
if ( !level ) end = p;
break;
case '(':
if ( !level ) lp = p;
level++;
break;
case ')':
if ( --level < 0 ) end = p;
else rp = p;
break;
case '/':
p = skipspace(p, 1) - 1;
break;
default:
;
}
}
/* Erase any embedded prototype parameters. */
if ( lp )
writeblanks(lp + 1, rp);
p--; /* back up over terminator */
/* Find the name being declared. */
/* This is complicated because of procedure and */
/* array modifiers. */
for ( ; ; )
{ p = skipspace(p - 1, -1);
switch ( *p )
{
case ']': /* skip array dimension(s) */
case ')': /* skip procedure args OR name */
{ int level = 1;
while ( level )
switch ( *--p )
{
case ']': case ')': level++; break;
case '[': case '(': level--; break;
case '/': p = skipspace(p, -1) + 1; break;
default: ;
}
}
if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
{ /* We found the name being declared */
while ( !isidfirstchar(*p) )
p = skipspace(p, 1) + 1;
goto found;
}
break;
default: goto found;
}
}
found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
{ if ( convert_varargs )
{ *bp++ = "va_alist";
vararg = p-2;
}
else
{ p++;
if ( bp == breaks + 1 ) /* sole argument */
writeblanks(breaks[0], p);
else
writeblanks(bp[-1] - 1, p);
bp--;
}
}
else
{ while ( isidchar(*p) ) p--;
*bp++ = p+1;
}
p = end;
}
while ( *p++ == ',' );
*bp = p;
/* Make a special check for 'void' arglist */
if ( bp == breaks+2 )
{ p = skipspace(breaks[0], 1);
if ( !strncmp(p, "void", 4) )
{ p = skipspace(p+4, 1);
if ( p == breaks[2] - 1 )
{ bp = breaks; /* yup, pretend arglist is empty */
writeblanks(breaks[0], p + 1);
}
}
}
/* Put out the function name and left parenthesis. */
p = buf;
while ( p != endfn ) putc(*p, out), p++;
/* Put out the declaration. */
if ( header )
{ fputs(");", out);
for ( p = breaks[0]; *p; p++ )
if ( *p == '\r' || *p == '\n' )
putc(*p, out);
}
else
{ for ( ap = breaks+1; ap < bp; ap += 2 )
{ p = *ap;
while ( isidchar(*p) )
putc(*p, out), p++;
if ( ap < bp - 1 )
fputs(", ", out);
}
fputs(") ", out);
/* Put out the argument declarations */
for ( ap = breaks+2; ap <= bp; ap += 2 )
(*ap)[-1] = ';';
if ( vararg != 0 )
{ *vararg = 0;
fputs(breaks[0], out); /* any prior args */
fputs("va_dcl", out); /* the final arg */
fputs(bp[0], out);
}
else
fputs(breaks[0], out);
}
free((char *)breaks);
return 0;
}

View File

@@ -1,5 +1,5 @@
/* basename -- strip directory and suffix from filenames
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 90, 91, 92, 93, 94, 1995 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
@@ -25,12 +25,14 @@
basename functions.lisp p
=> functions.lis */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "version.h"
#include "system.h"
#include "version.h"
#include "long-options.h"
#include "error.h"
char *basename ();
void strip_trailing_slashes ();
@@ -40,25 +42,29 @@ static void remove_suffix ();
/* The name this program was run with. */
char *program_name;
/* If non-zero, display usage information and exit. */
static int show_help;
/* If non-zero, print the version on standard error. */
static int show_version;
static struct option const long_options[] =
{
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{0, 0, 0, 0}
};
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "Usage: %s [{--help,--version}] name [suffix]\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("\
Usage: %s NAME [SUFFIX]\n\
or: %s OPTION\n\
",
program_name, program_name);
printf ("\
Print NAME with any leading directory components removed.\n\
If specified, also remove a trailing SUFFIX.\n\
\n\
--help display this help and exit\n\
--version output version information and exit\n\
");
}
exit (status);
}
void
@@ -67,40 +73,23 @@ main (argc, argv)
char **argv;
{
char *name;
int c;
program_name = argv[0];
while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
{
switch (c)
{
case 0:
break;
parse_long_options (argc, argv, "basename", version_string, usage);
default:
usage ();
}
if (argc == 1 || argc > 3)
{
error (0, 0, "too %s arguments", argc == 1 ? "few" : "many");
usage (1);
}
if (show_version)
{
printf ("%s\n", version_string);
exit (0);
}
strip_trailing_slashes (argv[1]);
if (show_help)
usage ();
if (argc - optind == 0 || argc - optind > 2)
usage ();
strip_trailing_slashes (argv[optind]);
name = basename (argv[optind]);
name = basename (argv[1]);
if (argc == 3)
remove_suffix (name, argv[optind + 1]);
remove_suffix (name, argv[2]);
puts (name);

699
src/cat.c
View File

@@ -1,5 +1,5 @@
/* cat -- concatenate files and print on the standard output.
Copyright (C) 1988, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1990, 1991, 1995 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
@@ -12,16 +12,18 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Differences from the Unix cat:
* Always unbuffered, -u is ignored.
* 100 times faster with -v -u.
* 20 times faster with -v.
* Usually much faster than other versions of cat, the difference
is especially apparent when using the -v option.
By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman. */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
@@ -30,16 +32,16 @@
#endif
#include "system.h"
#include "version.h"
#include "error.h"
/* Undefine, to avoid warning about redefinition on some systems. */
#undef max
#define max(h,i) ((h) > (i) ? (h) : (i))
char *stpcpy ();
char *xmalloc ();
void error ();
static void cat ();
static void next_line_num ();
static void simple_cat ();
int full_write ();
int safe_read ();
/* Name under which this program was invoked. */
char *program_name;
@@ -58,7 +60,7 @@ static char line_buf[13] =
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '\t', '\0'};
/* Position in `line_buf' where printing starts. This will not change
unless the number of lines are more than 999999. */
unless the number of lines is larger than 999999. */
static char *line_num_print = line_buf + 5;
/* Position of the first digit in `line_buf'. */
@@ -74,306 +76,68 @@ static int newlines2 = 0;
static int exit_stat = 0;
static void
usage ()
usage (int status)
{
fprintf (stderr, "\
Usage: %s [-benstuvAET] [--number] [--number-nonblank] [--squeeze-blank]\n\
[--show-nonprinting] [--show-ends] [--show-tabs] [--show-all]\n\
[--help] [--version] [file...]\n",
program_name);
exit (2);
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s [OPTION] [FILE]...\n\
"),
program_name);
printf (_("\
Concatenate FILE(s), or standard input, to standard output.\n\
\n\
-b, --number-nonblank number nonblank output lines\n\
-e equivalent to -vE\n\
-n, --number number all output lines\n\
-s, --squeeze-blank never more than one single blank line\n\
-t equivalent to -vT\n\
-u (ignored)\n\
-v, --show-nonprinting use ^ and M- notation, save for LFD and TAB\n\
-A, --show-all equivalent to -vET\n\
-E, --show-ends display $ at end of each line\n\
-T, --show-tabs display TAB characters as ^I\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"));
}
exit (status);
}
void
main (argc, argv)
int argc;
char *argv[];
/* Compute the next line number. */
static void
next_line_num (void)
{
/* Optimal size of i/o operations of output. */
int outsize;
/* Optimal size of i/o operations of input. */
int insize;
/* Pointer to the input buffer. */
unsigned char *inbuf;
/* Pointer to the output buffer. */
unsigned char *outbuf;
int c;
/* Index in argv to processed argument. */
int argind;
/* Device number of the output (file or whatever). */
int out_dev;
/* I-node number of the output. */
int out_ino;
/* Nonzero if the output file should not be the same as any input file. */
int check_redirection = 1;
/* Nonzero if we have ever read standard input. */
int have_read_stdin = 0;
struct stat stat_buf;
/* Variables that are set according to the specified options. */
int numbers = 0;
int numbers_at_empty_lines = 1;
int squeeze_empty_lines = 0;
int mark_line_ends = 0;
int quote = 0;
int output_tabs = 1;
/* If non-zero, call cat, otherwise call simple_cat to do the actual work. */
int options = 0;
/* If non-zero, display usage information and exit. */
static int show_help;
/* If non-zero, print the version on standard output then exit. */
static int show_version;
static struct option const long_options[] =
{
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
{"show-nonprinting", no_argument, NULL, 'v'},
{"show-ends", no_argument, NULL, 'E'},
{"show-tabs", no_argument, NULL, 'T'},
{"show-all", no_argument, NULL, 'A'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{NULL, 0, NULL, 0}
};
program_name = argv[0];
/* Parse command line options. */
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, (int *) 0))
!= EOF)
{
switch (c)
{
case 0:
break;
case 'b':
++options;
numbers = 1;
numbers_at_empty_lines = 0;
break;
case 'e':
++options;
mark_line_ends = 1;
quote = 1;
break;
case 'n':
++options;
numbers = 1;
break;
case 's':
++options;
squeeze_empty_lines = 1;
break;
case 't':
++options;
output_tabs = 0;
quote = 1;
break;
case 'u':
/* We provide the -u feature unconditionally. */
break;
case 'v':
++options;
quote = 1;
break;
case 'A':
++options;
quote = 1;
mark_line_ends = 1;
output_tabs = 0;
break;
case 'E':
++options;
mark_line_ends = 1;
break;
case 'T':
++options;
output_tabs = 0;
break;
default:
usage ();
}
}
if (show_version)
{
printf ("%s\n", version_string);
exit (0);
}
if (show_help)
usage ();
output_desc = 1;
/* Get device, i-node number, and optimal blocksize of output. */
if (fstat (output_desc, &stat_buf) < 0)
error (1, errno, "standard output");
outsize = ST_BLKSIZE (stat_buf);
/* Input file can be output file for non-regular files.
fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
on others, so the checking should not be done for those types,
and to allow things like cat < /dev/tty > /dev/tty, checking
is not done for device files either. */
if (S_ISREG (stat_buf.st_mode))
{
out_dev = stat_buf.st_dev;
out_ino = stat_buf.st_ino;
}
else
check_redirection = 0;
/* Check if any of the input files are the same as the output file. */
/* Main loop. */
infile = "-";
argind = optind;
char *endp = line_num_end;
do
{
if (argind < argc)
infile = argv[argind];
if (infile[0] == '-' && infile[1] == 0)
{
have_read_stdin = 1;
input_desc = 0;
}
else
{
input_desc = open (infile, O_RDONLY);
if (input_desc < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
continue;
}
}
if (fstat (input_desc, &stat_buf) < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
goto contin;
}
insize = ST_BLKSIZE (stat_buf);
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
stdout, and skip this input file if they coincide. Input
files cannot be redirected to themselves. */
if (check_redirection
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino)
{
error (0, 0, "%s: input file is output file", infile);
exit_stat = 1;
goto contin;
}
/* Select which version of `cat' to use. If any options (more than -u,
--version, or --help) were specified, use `cat', otherwise use
`simple_cat'. */
if (options == 0)
{
insize = max (insize, outsize);
inbuf = (unsigned char *) xmalloc (insize);
simple_cat (inbuf, insize);
}
else
{
inbuf = (unsigned char *) xmalloc (insize + 1);
/* Why are (OUTSIZE - 1 + INSIZE * 4 + 13) bytes allocated for
the output buffer?
A test whether output needs to be written is done when the input
buffer empties or when a newline appears in the input. After
output is written, at most (OUTSIZE - 1) bytes will remain in the
buffer. Now INSIZE bytes of input is read. Each input character
may grow by a factor of 4 (by the prepending of M-^). If all
characters do, and no newlines appear in this block of input, we
will have at most (OUTSIZE - 1 + INSIZE) bytes in the buffer. If
the last character in the preceding block of input was a
newline, a line number may be written (according to the given
options) as the first thing in the output buffer. (Done after the
new input is read, but before processing of the input begins.) A
line number requires seldom more than 13 positions. */
outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4 + 13);
cat (inbuf, insize, outbuf, outsize, quote,
output_tabs, numbers, numbers_at_empty_lines, mark_line_ends,
squeeze_empty_lines);
free (outbuf);
}
free (inbuf);
contin:
if (strcmp (infile, "-") && close (input_desc) < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
}
if ((*endp)++ < '9')
return;
*endp-- = '0';
}
while (++argind < argc);
if (have_read_stdin && close (0) < 0)
error (1, errno, "-");
if (close (1) < 0)
error (1, errno, "write error");
exit (exit_stat);
while (endp >= line_num_start);
*--line_num_start = '1';
if (line_num_start < line_num_print)
line_num_print--;
}
/* Plain cat. Copies the file behind `input_desc' to the file behind
`output_desc'. */
static void
simple_cat (buf, bufsize)
simple_cat (
/* Pointer to the buffer, used by reads and writes. */
unsigned char *buf;
unsigned char *buf,
/* Number of characters preferably read or written by each read and write
call. */
int bufsize;
int bufsize)
{
/* Actual number of characters read, and therefore written. */
int n_read;
@@ -384,7 +148,7 @@ simple_cat (buf, bufsize)
{
/* Read a block of input. */
n_read = read (input_desc, buf, bufsize);
n_read = safe_read (input_desc, buf, bufsize);
if (n_read < 0)
{
error (0, errno, "%s", infile);
@@ -399,11 +163,11 @@ simple_cat (buf, bufsize)
/* Write this block out. */
if (write (output_desc, buf, n_read) != n_read)
error (1, errno, "write error");
if (full_write (output_desc, buf, n_read) < 0)
error (1, errno, _("write error"));
}
}
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
Called if any option more than -u was specified.
@@ -411,29 +175,26 @@ simple_cat (buf, bufsize)
an explicit test for buffer end unnecessary. */
static void
cat (inbuf, insize, outbuf, outsize, quote,
output_tabs, numbers, numbers_at_empty_lines,
mark_line_ends, squeeze_empty_lines)
cat (
/* Pointer to the beginning of the input buffer. */
unsigned char *inbuf;
unsigned char *inbuf,
/* Number of characters read in each read call. */
int insize;
int insize,
/* Pointer to the beginning of the output buffer. */
unsigned char *outbuf;
unsigned char *outbuf,
/* Number of characters written by each write call. */
int outsize;
int outsize,
/* Variables that have values according to the specified options. */
int quote;
int output_tabs;
int numbers;
int numbers_at_empty_lines;
int mark_line_ends;
int squeeze_empty_lines;
int quote,
int output_tabs,
int numbers,
int numbers_at_empty_lines,
int mark_line_ends,
int squeeze_empty_lines)
{
/* Last character read from the input buffer. */
unsigned char ch;
@@ -483,8 +244,8 @@ cat (inbuf, insize, outbuf, outsize, quote,
unsigned char *wp = outbuf;
do
{
if (write (output_desc, wp, outsize) != outsize)
error (1, errno, "write error");
if (full_write (output_desc, wp, outsize) < 0)
error (1, errno, _("write error"));
wp += outsize;
}
while (bpout - wp >= outsize);
@@ -492,7 +253,7 @@ cat (inbuf, insize, outbuf, outsize, quote,
/* Move the remaining bytes to the beginning of the
buffer. */
bcopy (wp, outbuf, bpout - wp);
memmove (outbuf, wp, bpout - wp);
bpout = outbuf + (bpout - wp);
}
@@ -514,13 +275,18 @@ cat (inbuf, insize, outbuf, outsize, quote,
HP-UX returns ENOTTY on pipes.
SunOS returns EINVAL and
More/BSD returns ENODEV on special files
like /dev/null. */
like /dev/null.
Irix-5 returns ENOSYS on pipes. */
if (errno == EOPNOTSUPP || errno == ENOTTY
|| errno == EINVAL || errno == ENODEV)
|| errno == EINVAL || errno == ENODEV
#ifdef ENOSYS
|| errno == ENOSYS
#endif
)
use_fionread = 0;
else
{
error (0, errno, "cannot do ioctl on `%s'", infile);
error (0, errno, _("cannot do ioctl on `%s'"), infile);
exit_stat = 1;
newlines2 = newlines;
return;
@@ -531,14 +297,14 @@ cat (inbuf, insize, outbuf, outsize, quote,
{
int n_write = bpout - outbuf;
if (write (output_desc, outbuf, n_write) != n_write)
error (1, errno, "write error");
if (full_write (output_desc, outbuf, n_write) < 0)
error (1, errno, _("write error"));
bpout = outbuf;
}
/* Read more input into INBUF. */
n_read = read (input_desc, inbuf, insize);
n_read = safe_read (input_desc, inbuf, insize);
if (n_read < 0)
{
error (0, errno, "%s", infile);
@@ -673,20 +439,283 @@ cat (inbuf, insize, outbuf, outsize, quote,
}
}
/* Compute the next line number. */
static void
next_line_num ()
void
main (int argc, char **argv)
{
char *endp = line_num_end;
/* Optimal size of i/o operations of output. */
int outsize;
/* Optimal size of i/o operations of input. */
int insize;
/* Pointer to the input buffer. */
unsigned char *inbuf;
/* Pointer to the output buffer. */
unsigned char *outbuf;
int c;
/* Index in argv to processed argument. */
int argind;
/* Device number of the output (file or whatever). */
int out_dev;
/* I-node number of the output. */
int out_ino;
/* Nonzero if the output file should not be the same as any input file. */
int check_redirection = 1;
/* Nonzero if we have ever read standard input. */
int have_read_stdin = 0;
struct stat stat_buf;
/* Variables that are set according to the specified options. */
int numbers = 0;
int numbers_at_empty_lines = 1;
int squeeze_empty_lines = 0;
int mark_line_ends = 0;
int quote = 0;
int output_tabs = 1;
/* If non-zero, call cat, otherwise call simple_cat to do the actual work. */
int options = 0;
/* If non-zero, display usage information and exit. */
static int show_help;
/* If non-zero, print the version on standard output then exit. */
static int show_version;
static struct option const long_options[] =
{
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
{"show-nonprinting", no_argument, NULL, 'v'},
{"show-ends", no_argument, NULL, 'E'},
{"show-tabs", no_argument, NULL, 'T'},
{"show-all", no_argument, NULL, 'A'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{NULL, 0, NULL, 0}
};
program_name = argv[0];
/* Parse command line options. */
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, (int *) 0))
!= EOF)
{
switch (c)
{
case 0:
break;
case 'b':
++options;
numbers = 1;
numbers_at_empty_lines = 0;
break;
case 'e':
++options;
mark_line_ends = 1;
quote = 1;
break;
case 'n':
++options;
numbers = 1;
break;
case 's':
++options;
squeeze_empty_lines = 1;
break;
case 't':
++options;
output_tabs = 0;
quote = 1;
break;
case 'u':
/* We provide the -u feature unconditionally. */
break;
case 'v':
++options;
quote = 1;
break;
case 'A':
++options;
quote = 1;
mark_line_ends = 1;
output_tabs = 0;
break;
case 'E':
++options;
mark_line_ends = 1;
break;
case 'T':
++options;
output_tabs = 0;
break;
default:
usage (2);
}
}
if (show_version)
{
printf ("cat - %s\n", version_string);
exit (0);
}
if (show_help)
usage (0);
output_desc = 1;
/* Get device, i-node number, and optimal blocksize of output. */
if (fstat (output_desc, &stat_buf) < 0)
error (1, errno, _("standard output"));
outsize = ST_BLKSIZE (stat_buf);
/* Input file can be output file for non-regular files.
fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
on others, so the checking should not be done for those types,
and to allow things like cat < /dev/tty > /dev/tty, checking
is not done for device files either. */
if (S_ISREG (stat_buf.st_mode))
{
out_dev = stat_buf.st_dev;
out_ino = stat_buf.st_ino;
}
else
{
check_redirection = 0;
#ifdef lint /* Suppress `used before initialized' warning. */
out_dev = 0;
out_ino = 0;
#endif
}
/* Check if any of the input files are the same as the output file. */
/* Main loop. */
infile = "-";
argind = optind;
do
{
if ((*endp)++ < '9')
return;
*endp-- = '0';
if (argind < argc)
infile = argv[argind];
if (infile[0] == '-' && infile[1] == 0)
{
have_read_stdin = 1;
input_desc = 0;
}
else
{
input_desc = open (infile, O_RDONLY);
if (input_desc < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
continue;
}
}
if (fstat (input_desc, &stat_buf) < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
goto contin;
}
insize = ST_BLKSIZE (stat_buf);
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
stdout, and skip this input file if they coincide. Input
files cannot be redirected to themselves. */
if (check_redirection
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino)
{
error (0, 0, _("%s: input file is output file"), infile);
exit_stat = 1;
goto contin;
}
/* Select which version of `cat' to use. If any options (more than -u,
--version, or --help) were specified, use `cat', otherwise use
`simple_cat'. */
if (options == 0)
{
insize = max (insize, outsize);
inbuf = (unsigned char *) xmalloc (insize);
simple_cat (inbuf, insize);
}
else
{
inbuf = (unsigned char *) xmalloc (insize + 1);
/* Why are (OUTSIZE - 1 + INSIZE * 4 + 13) bytes allocated for
the output buffer?
A test whether output needs to be written is done when the input
buffer empties or when a newline appears in the input. After
output is written, at most (OUTSIZE - 1) bytes will remain in the
buffer. Now INSIZE bytes of input is read. Each input character
may grow by a factor of 4 (by the prepending of M-^). If all
characters do, and no newlines appear in this block of input, we
will have at most (OUTSIZE - 1 + INSIZE) bytes in the buffer. If
the last character in the preceding block of input was a
newline, a line number may be written (according to the given
options) as the first thing in the output buffer. (Done after the
new input is read, but before processing of the input begins.) A
line number requires seldom more than 13 positions. */
outbuf = (unsigned char *) xmalloc (outsize - 1 + insize * 4 + 13);
cat (inbuf, insize, outbuf, outsize, quote,
output_tabs, numbers, numbers_at_empty_lines, mark_line_ends,
squeeze_empty_lines);
free (outbuf);
}
free (inbuf);
contin:
if (strcmp (infile, "-") && close (input_desc) < 0)
{
error (0, errno, "%s", infile);
exit_stat = 1;
}
}
while (endp >= line_num_start);
*--line_num_start = '1';
if (line_num_start < line_num_print)
line_num_print--;
while (++argind < argc);
if (have_read_stdin && close (0) < 0)
error (1, errno, "-");
if (close (1) < 0)
error (1, errno, _("write error"));
exit (exit_stat);
}

View File

@@ -1,5 +1,5 @@
/* chgrp -- change group ownership of files
Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 89, 90, 91, 1995 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
@@ -17,50 +17,44 @@
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <grp.h>
#include <getopt.h>
#include "system.h"
#include "version.h"
#if !defined (isascii) || defined (STDC_HEADERS)
#undef isascii
#define isascii(c) 1
#if HAVE_LIMITS_H
# include <limits.h>
#endif
#define ISDIGIT(c) (isascii (c) && isdigit (c))
#ifndef UINT_MAX
# define UINT_MAX ((unsigned int) ~(unsigned int) 0)
#endif
#ifndef INT_MAX
# define INT_MAX ((int) (UINT_MAX >> 1))
#endif
#include "system.h"
#include "version.h"
#include "xstrtoul.h"
#include "error.h"
#ifndef _POSIX_VERSION
struct group *getgrnam ();
#endif
#ifdef _POSIX_SOURCE
#define endgrent()
#ifndef HAVE_ENDGRENT
# define endgrent() ((void) 0)
#endif
int lstat ();
char *group_member ();
char *savedir ();
char *xmalloc ();
char *xrealloc ();
void error ();
static int change_file_group ();
static int change_dir_group ();
static int isnumber ();
static void describe_change ();
static void parse_group ();
static void usage ();
@@ -134,21 +128,24 @@ main (argc, argv)
verbose = 1;
break;
default:
usage ();
usage (1);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("chgrp - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (optind >= argc - 1)
usage ();
if (argc - optind <= 1)
{
error (0, 0, "too few arguments");
usage (1);
}
parse_group (argv[optind++], &group);
@@ -174,9 +171,15 @@ parse_group (name, g)
grp = getgrnam (name);
if (grp == NULL)
{
if (!isnumber (name))
error (1, 0, "invalid group `%s'", name);
*g = atoi (name);
strtol_error s_err;
unsigned long int tmp_long;
s_err = xstrtoul (name, NULL, 0, &tmp_long, NULL);
*g = tmp_long;
if (s_err == LONGINT_OVERFLOW || tmp_long > INT_MAX)
{
STRTOL_FATAL_ERROR (name, "group number", s_err);
}
}
else
*g = grp->gr_gid;
@@ -208,9 +211,28 @@ change_file_group (file, group)
describe_change (file, 1);
if (chown (file, file_stats.st_uid, group))
{
if (force_silent == 0)
error (0, errno, "%s", file);
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 (errno == EPERM && !group_member (group))
{
error (0, errno, "you are not a member of group `%s'",
groupname);
}
#ifdef MAXUID
else if (errno == EINVAL && group > MAXUID)
{
error (0, 0, "%s: invalid group number", groupname);
}
#endif
else
{
error (0, errno, "%s", file);
}
}
}
}
else if (verbose && changes_only == 0)
@@ -290,25 +312,25 @@ describe_change (file, changed)
printf ("group of %s retained as %s\n", file, groupname);
}
/* Return nonzero if STR represents an unsigned decimal integer,
otherwise return 0. */
static int
isnumber (str)
char *str;
{
for (; *str; str++)
if (!ISDIGIT (*str))
return 0;
return 1;
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [-Rcfv] [--recursive] [--changes] [--silent] [--quiet]\n\
[--verbose] [--help] [--version] group file...\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("Usage: %s [OPTION]... GROUP FILE...\n", program_name);
printf ("\
Change the group membership of each FILE to GROUP.\n\
\n\
-c, --changes like verbose but report only when a change is made\n\
-f, --silent, --quiet suppress most error messages\n\
-v, --verbose output a diagnostic for every file processed\n\
-R, --recursive change files and directories recursively\n\
--help display this help and exit\n\
--version output version information and exit\n");
}
exit (status);
}

View File

@@ -1,5 +1,5 @@
/* chmod -- change permission modes of files
Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1989, 1990, 1991, 1995 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
@@ -23,31 +23,21 @@
David MacKenzie <djm@gnu.ai.mit.edu> */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include "modechange.h"
#include "system.h"
#include "version.h"
#include "error.h"
int lstat ();
void mode_string ();
char *savedir ();
void strip_trailing_slashes ();
char *xmalloc ();
char *xrealloc ();
void error ();
void mode_string ();
static int change_file_mode ();
static int change_dir_mode ();
@@ -149,24 +139,27 @@ main (argc, argv)
verbose = 1;
break;
default:
usage ();
usage (1);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("chmod - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (modeind == 0)
modeind = optind++;
if (optind >= argc)
usage ();
{
error (0, 0, "too few arguments");
usage (1);
}
changes = mode_compile (argv[modeind],
MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
@@ -176,18 +169,24 @@ main (argc, argv)
error (1, 0, "virtual memory exhausted");
for (; optind < argc; ++optind)
errors |= change_file_mode (argv[optind], changes);
{
strip_trailing_slashes (argv[optind]);
errors |= change_file_mode (argv[optind], changes, 1);
}
exit (errors);
}
/* Change the mode of FILE according to the list of operations CHANGES.
Return 0 if successful, 1 if errors occurred. */
If DEREF_SYMLINK is non-zero and FILE is a symbolic link, change the
mode of the referenced file. If DEREF_SYMLINK is zero, ignore symbolic
links. Return 0 if successful, 1 if errors occurred. */
static int
change_file_mode (file, changes)
change_file_mode (file, changes, deref_symlink)
char *file;
struct mode_change *changes;
int deref_symlink;
{
struct stat file_stats;
unsigned short newmode;
@@ -201,7 +200,17 @@ change_file_mode (file, changes)
}
#ifdef S_ISLNK
if (S_ISLNK (file_stats.st_mode))
return 0;
{
if (! deref_symlink)
return 0;
else
if (stat (file, &file_stats))
{
if (force_silent == 0)
error (0, errno, "%s", file);
return 1;
}
}
#endif
newmode = mode_adjust (file_stats.st_mode, changes);
@@ -273,7 +282,7 @@ change_dir_mode (dir, changes, statp)
path = xrealloc (path, pathlength);
}
strcpy (path + dirlength, namep);
errors |= change_file_mode (path, changes);
errors |= change_file_mode (path, changes, 0);
}
free (path);
free (name_space);
@@ -302,12 +311,30 @@ describe_change (file, mode, changed)
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [-Rcfv] [--recursive] [--changes] [--silent] [--quiet]\n\
[--verbose] [--help] [--version] mode file...\n\
mode is [ugoa...][[+-=][rwxXstugo...]...][,...] or octal number\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("\
Usage: %s [OPTION]... MODE[,MODE]... FILE...\n\
or: %s [OPTION]... OCTAL_MODE FILE...\n\
",
program_name, program_name);
printf ("\
\n\
-c, --changes like verbose but report only when a change is made\n\
-f, --silent, --quiet suppress most error messages\n\
-v, --verbose output a diagnostic for every file processed\n\
-R, --recursive change files and directories recursively\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
Each MODE is one or more of the letters ugoa, one of the symbols +-= and\n\
one or more of the letters rwxXstugo.\n");
}
exit (status);
}

View File

@@ -1,5 +1,5 @@
/* chown -- change user and group ownership of files
Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1989, 1990, 1991, 1995 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
@@ -15,7 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
/*
| user
| unchanged explicit
-------------|-------------------------+-------------------------|
@@ -28,25 +28,16 @@
Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <getopt.h>
#include "system.h"
#include "version.h"
#include "error.h"
#ifndef _POSIX_VERSION
struct passwd *getpwnam ();
@@ -54,18 +45,15 @@ struct group *getgrnam ();
struct group *getgrgid ();
#endif
#ifdef _POSIX_SOURCE
#define endgrent()
#define endpwent()
#ifndef HAVE_ENDPWENT
# define endpwent() ((void) 0)
#endif
int lstat ();
char *savedir ();
char *parse_user_spec ();
void strip_trailing_slashes ();
char *xmalloc ();
char *xrealloc ();
void error ();
int isnumber ();
static int change_file_owner ();
static int change_dir_owner ();
@@ -146,21 +134,24 @@ main (argc, argv)
verbose = 1;
break;
default:
usage ();
usage (1);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("chown - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (optind >= argc - 1)
usage ();
{
error (0, 0, "too few arguments");
usage (1);
}
e = parse_user_spec (argv[optind], &user, &group, &username, &groupname);
if (e)
@@ -169,7 +160,10 @@ main (argc, argv)
username = "";
for (++optind; optind < argc; ++optind)
errors |= change_file_owner (argv[optind], user, group);
{
strip_trailing_slashes (argv[optind]);
errors |= change_file_owner (argv[optind], user, group);
}
exit (errors);
}
@@ -292,11 +286,31 @@ describe_change (file, changed)
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [-Rcfv] [--recursive] [--changes] [--silent] [--quiet]\n\
[--verbose] [--help] [--version] [user][:.][group] file...\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("\
Usage: %s [OPTION]... OWNER[.[GROUP]] FILE...\n\
or: %s [OPTION]... .[GROUP] FILE...\n\
",
program_name, program_name);
printf ("\
Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\
\n\
-c, --changes be verbose whenever change occurs\n\
-f, --silent, --quiet suppress most error messages\n\
-v, --verbose explain what is being done\n\
-R, --recursive change files and directories recursively\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
Owner is unchanged if missing. Group is unchanged if missing, but changed\n\
to login group if implied by a period. A colon may replace the period.\n");
}
exit (status);
}

View File

@@ -1,5 +1,5 @@
/* cksum -- calculate and print POSIX.2 checksums and sizes of files
Copyright (C) 1992 Free Software Foundation, Inc.
Copyright (C) 1992, 1995 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
@@ -13,7 +13,7 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Q. Frank Xia, qx@math.columbia.edu.
Cosmetic changes and reorganization by David MacKenzie, djm@gnu.ai.mit.edu.
@@ -40,6 +40,8 @@
except foreign language interface (4.9.5.3 of P1003.2/D11.2) support.
Any inconsistency with the standard except 4.9.5.3 is a bug. */
#include <config.h>
#ifdef CRCTAB
#include <stdio.h>
@@ -107,12 +109,11 @@ main ()
#include <sys/types.h>
#include "system.h"
#include "version.h"
#include "error.h"
/* Number of bytes to read at once. */
#define BUFLEN (1 << 16)
void error ();
/* The name this program was run with. */
char *program_name;
@@ -194,9 +195,7 @@ static int have_read_stdin;
Return 0 if successful, -1 if an error occurs. */
static int
cksum (file, print_name)
char *file;
int print_name;
cksum (char *file, int print_name)
{
unsigned char buf[BUFLEN];
unsigned long crc = 0;
@@ -260,17 +259,29 @@ cksum (file, print_name)
}
static void
usage ()
usage (int status)
{
fprintf (stderr, "\
Usage: %s [--help] [--version] [file...]\n", program_name);
exit (1);
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
printf (_("\
Print CRC checksum and byte counts of each FILE.\n\
\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
}
exit (status);
}
void
main (argc, argv)
int argc;
char **argv;
main (int argc, char **argv)
{
int i, c;
int errors = 0;
@@ -286,18 +297,18 @@ main (argc, argv)
break;
default:
usage ();
usage (1);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("cksum - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (optind >= argc)
{

View File

@@ -1,5 +1,5 @@
/* comm -- compare two sorted files line by line.
Copyright (C) 1986, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1986, 1990, 1991, 1995 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
@@ -13,17 +13,22 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Richard Stallman and David MacKenzie. */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "linebuffer.h"
#include "version.h"
#include "error.h"
/* Undefine, to avoid warning about redefinition on some systems. */
#undef min
#define min(x, y) ((x) < (y) ? (x) : (y))
/* The name this program was run with. */
@@ -51,61 +56,72 @@ static struct option const long_options[] =
{0, 0, 0, 0}
};
void error ();
static int compare_files ();
static void writeline ();
static void usage ();
void
main (argc, argv)
int argc;
char *argv[];
static void
usage (int status)
{
int c;
program_name = argv[0];
only_file_1 = 1;
only_file_2 = 1;
both = 1;
while ((c = getopt_long (argc, argv, "123", long_options, (int *) 0)) != EOF)
switch (c)
{
case 0:
break;
case '1':
only_file_1 = 0;
break;
case '2':
only_file_2 = 0;
break;
case '3':
both = 0;
break;
default:
usage ();
}
if (show_version)
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf ("%s\n", version_string);
exit (0);
printf (_("\
Usage: %s [OPTION]... LEFT_FILE RIGHT_FILE\n\
"),
program_name);
printf (_("\
Compare sorted files LEFT_FILE and RIGHT_FILE line by line.\n\
\n\
-1 suppress lines unique to left file\n\
-2 suppress lines unique to right file\n\
-3 suppress lines unique to both files\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
}
exit (status);
}
/* Output the line in linebuffer LINE to stream STREAM
provided the switches say it should be output.
CLASS is 1 for a line found only in file 1,
2 for a line only in file 2, 3 for a line in both. */
static void
writeline (struct linebuffer *line, FILE *stream, int class)
{
switch (class)
{
case 1:
if (!only_file_1)
return;
break;
case 2:
if (!only_file_2)
return;
/* Skip the tab stop for case 1, if we are printing case 1. */
if (only_file_1)
putc ('\t', stream);
break;
case 3:
if (!both)
return;
/* Skip the tab stop for case 1, if we are printing case 1. */
if (only_file_1)
putc ('\t', stream);
/* Skip the tab stop for case 2, if we are printing case 2. */
if (only_file_2)
putc ('\t', stream);
break;
}
if (show_help)
usage ();
if (optind + 2 != argc)
usage ();
exit (compare_files (argv + optind));
fwrite (line->buffer, sizeof (char), line->length, stream);
putc ('\n', stream);
}
/* Compare INFILES[0] and INFILES[1].
If either is "-", use the standard input for that file.
Assume that each input file is sorted;
@@ -113,8 +129,7 @@ main (argc, argv)
Return 0 if successful, 1 if any errors occur. */
static int
compare_files (infiles)
char **infiles;
compare_files (char **infiles)
{
/* For each file, we have one linebuffer in lb1. */
struct linebuffer lb1[2];
@@ -191,58 +206,56 @@ compare_files (infiles)
}
if (ferror (stdout) || fclose (stdout) == EOF)
{
error (0, errno, "write error");
error (0, errno, _("write error"));
ret = 1;
}
return ret;
}
/* Output the line in linebuffer LINE to stream STREAM
provided the switches say it should be output.
CLASS is 1 for a line found only in file 1,
2 for a line only in file 2, 3 for a line in both. */
static void
writeline (line, stream, class)
struct linebuffer *line;
FILE *stream;
int class;
void
main (int argc, char **argv)
{
switch (class)
int c;
program_name = argv[0];
only_file_1 = 1;
only_file_2 = 1;
both = 1;
while ((c = getopt_long (argc, argv, "123", long_options, (int *) 0)) != EOF)
switch (c)
{
case 0:
break;
case '1':
only_file_1 = 0;
break;
case '2':
only_file_2 = 0;
break;
case '3':
both = 0;
break;
default:
usage (1);
}
if (show_version)
{
case 1:
if (!only_file_1)
return;
break;
case 2:
if (!only_file_2)
return;
/* Skip the tab stop for case 1, if we are printing case 1. */
if (only_file_1)
putc ('\t', stream);
break;
case 3:
if (!both)
return;
/* Skip the tab stop for case 1, if we are printing case 1. */
if (only_file_1)
putc ('\t', stream);
/* Skip the tab stop for case 2, if we are printing case 2. */
if (only_file_2)
putc ('\t', stream);
break;
printf ("comm - %s\n", version_string);
exit (0);
}
fwrite (line->buffer, sizeof (char), line->length, stream);
putc ('\n', stream);
}
static void
usage ()
{
fprintf (stderr, "Usage: %s [-123] [--help] [--version] file1 file2\n",
program_name);
exit (1);
if (show_help)
usage (0);
if (optind + 2 != argc)
usage (1);
exit (compare_files (argv + optind));
}

View File

@@ -1,5 +1,5 @@
/* cp-hash.c -- file copying (hash search routines)
Copyright (C) 1989, 1990, 1991 Free Software Foundation.
Copyright (C) 1989, 1990, 1991, 1995 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
@@ -17,6 +17,7 @@
Written by Torbjorn Granlund, Sweden (tege@sics.se). */
#include <config.h>
#include <stdio.h>
#include "cp.h"

View File

@@ -1,5 +1,5 @@
/* cp.c -- file copying (main routines)
Copyright (C) 1989, 1990, 1991 Free Software Foundation.
Copyright (C) 1989, 1990, 1991, 1995 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
@@ -21,17 +21,7 @@
#pragma alloca
#endif
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <getopt.h>
#include "cp.h"
@@ -42,7 +32,7 @@
uid_t geteuid ();
#endif
/* Used by do_copy, make_path, and re_protect
/* Used by do_copy, make_path_private, and re_protect
to keep a list of leading directories whose protections
need to be fixed after copying. */
struct dir_attr
@@ -52,15 +42,19 @@ struct dir_attr
struct dir_attr *next;
};
int stat ();
int lstat ();
char *dirname ();
char *xstrdup ();
enum backup_type get_version ();
int eaccess_stat ();
int euidaccess ();
int full_write ();
static int do_copy ();
static int copy ();
static int copy_dir ();
static int make_path ();
static int make_path_private ();
static int copy_reg ();
static int re_protect ();
@@ -77,8 +71,8 @@ char *program_name;
whether dereferencing of symlinks is done. */
static int (*xstat) ();
/* If nonzero, copy all files except directories and, if not dereferencing
them, symbolic links, as if they were regular files. */
/* If nonzero, copy all files except (directories and, if not dereferencing
them, symbolic links,) as if they were regular files. */
static int flag_copy_as_regular = 1;
/* If nonzero, dereference symbolic links (copy the files they point to). */
@@ -268,21 +262,21 @@ main (argc, argv)
break;
default:
usage ((char *) 0);
usage (2, (char *) 0);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("cp - %s\n", version_string);
exit (0);
}
if (show_help)
usage (NULL);
usage (0, NULL);
if (flag_hard_link && flag_symbolic_link)
usage ("cannot make both hard and symbolic links");
usage (2, "cannot make both hard and symbolic links");
if (make_backups)
backup_type = get_version (version);
@@ -321,9 +315,9 @@ do_copy (argc, argv)
int ret = 0;
if (optind >= argc)
usage ("missing file arguments");
usage (2, "missing file arguments");
if (optind >= argc - 1)
usage ("missing file argument");
usage (2, "missing file argument");
dest = argv[argc - 1];
@@ -375,7 +369,7 @@ do_copy (argc, argv)
/* For --parents, we have to make sure that the directory
dirname (dst_path) exists. We may have to create a few
leading directories. */
parent_exists = !make_path (dst_path,
parent_exists = !make_path_private (dst_path,
strlen (dest) + 1, 0700,
flag_verbose ? "%s -> %s\n" :
(char *) NULL,
@@ -398,14 +392,14 @@ do_copy (argc, argv)
if (!parent_exists)
{
/* make_path failed, so we shouldn't even attempt the copy. */
/* make_path_private failed, so we shouldn't even attempt the copy. */
ret = 1;
}
else
{
ret |= copy (arg, dst_path, new_dst, 0, (struct dir_list *) 0);
forget_all ();
if (flag_path)
{
ret |= re_protect (dst_path, strlen (dest) + 1,
@@ -427,7 +421,7 @@ do_copy (argc, argv)
struct stat source_stats;
if (flag_path)
usage ("when preserving paths, last argument must be a directory");
usage (2, "when preserving paths, last argument must be a directory");
source = argv[optind];
@@ -459,7 +453,8 @@ do_copy (argc, argv)
return copy (source, new_dest, new_dst, 0, (struct dir_list *) 0);
}
else
usage ("when copying multiple files, last argument must be a directory");
usage (2,
"when copying multiple files, last argument must be a directory");
}
/* Copy the file SRC_PATH to the file DST_PATH. The files may be of
@@ -561,10 +556,11 @@ copy (src_path, dst_path, new_dst, device, ancestors)
{
if (flag_interactive)
{
if (eaccess_stat (&dst_sb, W_OK) != 0)
if (euidaccess (dst_path, W_OK) != 0)
fprintf (stderr,
"%s: overwrite `%s', overriding mode %04o? ",
program_name, dst_path, dst_sb.st_mode & 07777);
program_name, dst_path,
(unsigned int) (dst_sb.st_mode & 07777));
else
fprintf (stderr, "%s: overwrite `%s'? ",
program_name, dst_path);
@@ -598,7 +594,7 @@ copy (src_path, dst_path, new_dst, device, ancestors)
if (S_ISDIR (dst_sb.st_mode))
{
/* Temporarily change mode to allow overwriting. */
if (eaccess_stat (&dst_sb, W_OK | X_OK) != 0)
if (euidaccess (dst_path, W_OK | X_OK) != 0)
{
if (chmod (dst_path, 0700))
{
@@ -695,8 +691,8 @@ copy (src_path, dst_path, new_dst, device, ancestors)
else if (flag_symbolic_link)
{
if (*src_path == '/'
|| (!strncmp (dst_path, "./", 2) && index (dst_path + 2, '/') == 0)
|| index (dst_path, '/') == 0)
|| (!strncmp (dst_path, "./", 2) && strchr (dst_path + 2, '/') == 0)
|| strchr (dst_path, '/') == 0)
{
if (symlink (src_path, dst_path))
{
@@ -764,7 +760,7 @@ copy (src_path, dst_path, new_dst, device, ancestors)
int link_size;
link_val = (char *) alloca (PATH_MAX + 2);
link_size = readlink (src_path, link_val, sizeof (link_val) - 1);
link_size = readlink (src_path, link_val, PATH_MAX + 1);
if (link_size < 0)
{
error (0, errno, "cannot read symbolic link `%s'", src_path);
@@ -805,7 +801,9 @@ copy (src_path, dst_path, new_dst, device, ancestors)
/* If non-root uses -p, it's ok if we can't preserve ownership.
But root probably wants to know, e.g. if NFS disallows it. */
if (chown (dst_path, src_sb.st_uid, src_sb.st_gid)
if (chown (dst_path,
(myeuid == 0 ? src_sb.st_uid : myeuid),
src_sb.st_gid)
&& (errno != EPERM || myeuid == 0))
{
error (0, errno, "%s", dst_path);
@@ -862,8 +860,8 @@ un_backup:
permissions when done, otherwise 1. */
static int
make_path (const_dirpath, src_offset, mode, verbose_fmt_string,
attr_list, new_dst)
make_path_private (const_dirpath, src_offset, mode, verbose_fmt_string,
attr_list, new_dst)
char *const_dirpath;
int src_offset;
int mode;
@@ -882,7 +880,7 @@ make_path (const_dirpath, src_offset, mode, verbose_fmt_string,
src = dirpath + src_offset;
tmp_dst_dirname = dirname (dirpath);
tmp_dst_dirname = dirname (dirpath);
dst_dirname = (char *) alloca (strlen (tmp_dst_dirname) + 1);
strcpy (dst_dirname, tmp_dst_dirname);
free (tmp_dst_dirname);
@@ -898,7 +896,7 @@ make_path (const_dirpath, src_offset, mode, verbose_fmt_string,
slash = src;
while (*slash == '/')
slash++;
while ((slash = index (slash, '/')))
while ((slash = strchr (slash, '/')))
{
/* Add this directory to the list of directories whose modes need
fixing later. */
@@ -914,7 +912,8 @@ make_path (const_dirpath, src_offset, mode, verbose_fmt_string,
/* This element of the path does not exist. We must set
*new_dst and new->is_new_dir inside this loop because,
for example, in the command `cp --parents ../a/../b/c e_dir',
make_path creates only e_dir/../a if ./b already exists. */
make_path_private creates only e_dir/../a if ./b already
exists. */
*new_dst = 1;
new->is_new_dir = 1;
if (mkdir (dirpath, mode))
@@ -954,11 +953,6 @@ make_path (const_dirpath, src_offset, mode, verbose_fmt_string,
error (0, 0, "`%s' exists but is not a directory", dst_dirname);
return 1;
}
else if (chmod (dst_dirname, mode))
{
error (0, errno, "%s", dst_dirname);
return 1;
}
else
{
*new_dst = 0;
@@ -998,7 +992,7 @@ re_protect (const_dst_path, src_offset, attr_list)
dst_path = (char *) alloca (strlen (const_dst_path) + 1);
strcpy (dst_path, const_dst_path);
src_path = dst_path + src_offset;
src_path = dst_path + src_offset;
for (p = attr_list; p; p = p->next)
{
@@ -1127,7 +1121,6 @@ copy_reg (src_path, dst_path)
int dest_desc;
int source_desc;
int n_read;
int n_written;
struct stat sb;
char *cp;
int *ip;
@@ -1180,8 +1173,7 @@ copy_reg (src_path, dst_path)
/* If the file has fewer blocks than would normally
be needed for a file of its size, then
at least one of the blocks in the file is a hole. */
if (S_ISREG (sb.st_mode) &&
sb.st_size - (sb.st_blocks * DEV_BSIZE) >= DEV_BSIZE)
if (S_ISREG (sb.st_mode) && sb.st_size > sb.st_blocks * DEV_BSIZE)
make_holes = 1;
}
#endif
@@ -1195,6 +1187,10 @@ copy_reg (src_path, dst_path)
n_read = read (source_desc, buf, buf_size);
if (n_read < 0)
{
#ifdef EINTR
if (errno == EINTR)
continue;
#endif
error (0, errno, "%s", src_path);
return_val = -1;
goto ret;
@@ -1241,8 +1237,7 @@ copy_reg (src_path, dst_path)
}
if (ip == 0)
{
n_written = write (dest_desc, buf, n_read);
if (n_written < n_read)
if (full_write (dest_desc, buf, n_read) < 0)
{
error (0, errno, "%s", dst_path);
return_val = -1;
@@ -1260,12 +1255,12 @@ copy_reg (src_path, dst_path)
{
#ifdef HAVE_FTRUNCATE
/* Write a null character and truncate it again. */
if (write (dest_desc, "", 1) != 1
if (full_write (dest_desc, "", 1) < 0
|| ftruncate (dest_desc, n_read_total) < 0)
#else
/* Seek backwards one character and write a null. */
if (lseek (dest_desc, (off_t) -1, SEEK_CUR) < 0L
|| write (dest_desc, "", 1) != 1)
|| full_write (dest_desc, "", 1) < 0)
#endif
{
error (0, errno, "%s", dst_path);

View File

@@ -1,5 +1,5 @@
/* csplit - split a file into sections determined by context lines
Copyright (C) 1991 Free Software Foundation, Inc.
Copyright (C) 1991, 1995 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
@@ -13,18 +13,24 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by Stuart Kemp, cpsrk@groper.jcu.edu.au.
Modified by David MacKenzie, djm@gnu.ai.mit.edu. */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <signal.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif /* HAVE_LIMITS_H */
#include "regex.h"
#include "system.h"
#include "version.h"
#include "error.h"
#ifdef STDC_HEADERS
#include <stdlib.h>
@@ -33,8 +39,11 @@ char *malloc ();
char *realloc ();
#endif
void error ();
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
int safe_read ();
static char *xrealloc ();
static char *xmalloc ();
@@ -64,7 +73,8 @@ struct control
struct re_pattern_buffer re_compiled; /* Compiled regular expression. */
int offset; /* Offset from regexp to split at. */
int lines_required; /* Number of lines required. */
int repeat; /* Repeat count. */
unsigned int repeat; /* Repeat count. */
int repeat_forever; /* Non-zero if `*' used as a repeat count. */
int argnum; /* ARGV index. */
boolean ignore; /* If true, produce no output (for regexp). */
};
@@ -122,6 +132,13 @@ struct buffer_record
/* The name this program was run with. */
char *program_name;
/* Convert the number of 8-bit bytes of a binary representation to
the number of characters required to represent the same quantity
as an unsigned octal. For example, a 32-bit (4-byte) quantity may
require a field width as wide as 11 characters. */
static const unsigned int bytes_to_octal_digits[] =
{0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
/* Input file descriptor. */
static int input_desc = 0;
@@ -143,9 +160,6 @@ static unsigned last_line_number = 0;
/* Number of the line currently being examined. */
static unsigned current_line = 0;
/* Number of the last line in the input file. */
static unsigned last_line_in_file = 0;
/* If TRUE, we have read EOF. */
static boolean have_read_eof = FALSE;
@@ -155,18 +169,24 @@ static char *filename_space = NULL;
/* Prefix part of output file names. */
static char *prefix = NULL;
/* Suffix part of output file names. */
static char *suffix = NULL;
/* Number of digits to use in output file names. */
static int digits = 2;
/* Number of files created so far. */
static unsigned files_created = 0;
static unsigned int files_created = 0;
/* Number of bytes written to current file. */
static unsigned bytes_written;
static unsigned int bytes_written;
/* Output file pointer. */
static FILE *output_stream = NULL;
/* Output file name. */
static char *output_filename = NULL;
/* Perhaps it would be cleaner to pass arg values instead of indexes. */
static char **global_argv;
@@ -176,12 +196,15 @@ static boolean suppress_count;
/* If TRUE, remove output files on error. */
static boolean remove_files;
/* If TRUE, remove all output files which have a zero length. */
static boolean elide_empty_files;
/* The compiled pattern arguments, which determine how to split
the input file. */
static struct control *controls;
/* Number of elements in `controls'. */
static unsigned control_used;
static unsigned int control_used;
/* If non-zero, display usage information and exit. */
static int show_help;
@@ -192,10 +215,12 @@ static int show_version;
static struct option const longopts[] =
{
{"digits", required_argument, NULL, 'n'},
{"quiet", no_argument, NULL, 's'},
{"quiet", no_argument, NULL, 'q'},
{"silent", no_argument, NULL, 's'},
{"keep-files", no_argument, NULL, 'k'},
{"elide-empty-files", no_argument, NULL, 'z'},
{"prefix", required_argument, NULL, 'f'},
{"suffix-format", required_argument, NULL, 'b'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{NULL, 0, NULL, 0}
@@ -205,14 +230,14 @@ static struct option const longopts[] =
static char *
xmalloc (n)
unsigned n;
unsigned int n;
{
char *p;
p = malloc (n);
if (p == NULL)
{
error (0, 0, "virtual memory exhausted");
error (0, 0, _("virtual memory exhausted"));
cleanup ();
}
return p;
@@ -226,7 +251,7 @@ xmalloc (n)
static char *
xrealloc (p, n)
char *p;
unsigned n;
unsigned int n;
{
if (p == NULL)
return xmalloc (n);
@@ -238,7 +263,7 @@ xrealloc (p, n)
p = realloc (p, n);
if (p == NULL)
{
error (0, 0, "virtual memory exhausted");
error (0, 0, _("virtual memory exhausted"));
cleanup ();
}
return p;
@@ -255,33 +280,33 @@ xrealloc (p, n)
static void
save_to_hold_area (start, num)
char *start;
unsigned num;
unsigned int num;
{
hold_area = start;
hold_count = num;
}
/* Read up to MAX chars from the input stream into DEST.
/* Read up to MAX_N_BYTES chars from the input stream into DEST.
Return the number of chars read. */
static int
read_input (dest, max)
read_input (dest, max_n_bytes)
char *dest;
unsigned max;
unsigned int max_n_bytes;
{
int bytes_read;
if (max == 0)
if (max_n_bytes == 0)
return 0;
bytes_read = read (input_desc, dest, max);
bytes_read = safe_read (input_desc, dest, max_n_bytes);
if (bytes_read == 0)
have_read_eof = TRUE;
if (bytes_read < 0)
{
error (0, errno, "read error");
error (0, errno, _("read error"));
cleanup ();
}
@@ -365,15 +390,15 @@ keep_new_line (b, line_start, line_len)
a pointer is kept to this area, which will be used when
the next buffer is filled. */
static unsigned
static unsigned int
record_line_starts (b)
struct buffer_record *b;
{
char *line_start; /* Start of current line. */
char *line_end; /* End of each line found. */
unsigned bytes_left; /* Length of incomplete last line. */
unsigned lines; /* Number of lines found. */
unsigned line_length; /* Length of each line found. */
unsigned int bytes_left; /* Length of incomplete last line. */
unsigned int lines; /* Number of lines found. */
unsigned int line_length; /* Length of each line found. */
if (b->bytes_used == 0)
return 0;
@@ -401,7 +426,6 @@ record_line_starts (b)
{
keep_new_line (b, line_start, bytes_left);
lines++;
last_line_in_file = last_line_number + lines;
}
else
save_to_hold_area (line_start, bytes_left);
@@ -419,7 +443,7 @@ record_line_starts (b)
static struct buffer_record *
create_new_buffer (size)
unsigned size;
unsigned int size;
{
struct buffer_record *new_buffer;
@@ -439,11 +463,11 @@ create_new_buffer (size)
static struct buffer_record *
get_new_buffer (min_size)
unsigned min_size;
unsigned int min_size;
{
struct buffer_record *p, *q;
struct buffer_record *new_buffer; /* Buffer to return. */
unsigned alloc_size; /* Actual size that will be requested. */
unsigned int alloc_size; /* Actual size that will be requested. */
alloc_size = START_SIZE;
while (min_size > alloc_size)
@@ -535,9 +559,9 @@ static boolean
load_buffer ()
{
struct buffer_record *b;
unsigned bytes_wanted = START_SIZE; /* Minimum buffer size. */
unsigned bytes_avail; /* Size of new buffer created. */
unsigned lines_found; /* Number of lines in this new buffer. */
unsigned int bytes_wanted = START_SIZE; /* Minimum buffer size. */
unsigned int bytes_avail; /* Size of new buffer created. */
unsigned int lines_found; /* Number of lines in this new buffer. */
char *p; /* Place to load into buffer. */
if (have_read_eof)
@@ -558,17 +582,17 @@ load_buffer ()
if (hold_count)
{
if (p != hold_area)
bcopy (hold_area, p, hold_count);
memcpy (p, hold_area, hold_count);
p += hold_count;
b->bytes_used += hold_count;
bytes_avail -= hold_count;
hold_count = 0;
}
b->bytes_used += (unsigned) read_input (p, bytes_avail);
b->bytes_used += (unsigned int) read_input (p, bytes_avail);
lines_found = record_line_starts (b);
bytes_wanted = b->bytes_alloc + INCR_SIZE;
bytes_wanted = b->bytes_alloc * 2;
if (!lines_found)
free_buffer (b);
}
@@ -582,16 +606,16 @@ load_buffer ()
/* Return the line number of the first line that has not yet been retrieved. */
static unsigned
static unsigned int
get_first_line_in_buffer ()
{
if (head == NULL && !load_buffer ())
error (1, errno, "input disappeared");
error (1, errno, _("input disappeared"));
return head->first_available;
}
/* Return a pointer to the logical first line in the buffer and make the
/* Return a pointer to the logical first line in the buffer and make the
next line the logical first line.
Return NULL if there is no more input. */
@@ -635,7 +659,7 @@ remove_line ()
static struct cstring *
find_line (linenum)
unsigned linenum;
unsigned int linenum;
{
struct buffer_record *b;
@@ -651,7 +675,7 @@ find_line (linenum)
{
/* The line is in this buffer. */
struct line *l;
unsigned offset; /* How far into the buffer the line is. */
unsigned int offset; /* How far into the buffer the line is. */
l = b->line_start;
offset = linenum - b->start_line;
@@ -700,20 +724,20 @@ set_input_file (name)
static void
write_to_file (last_line, ignore, argnum)
unsigned last_line;
unsigned int last_line;
boolean ignore;
int argnum;
{
struct cstring *line;
unsigned first_line; /* First available input line. */
unsigned lines; /* Number of lines to output. */
unsigned i;
unsigned int first_line; /* First available input line. */
unsigned int lines; /* Number of lines to output. */
unsigned int i;
first_line = get_first_line_in_buffer ();
if (first_line > last_line)
{
error (0, 0, "%s: line number out of range", global_argv[argnum]);
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
cleanup ();
}
@@ -724,7 +748,7 @@ write_to_file (last_line, ignore, argnum)
line = remove_line ();
if (line == NULL)
{
error (0, 0, "%s: line number out of range", global_argv[argnum]);
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
cleanup ();
}
if (!ignore)
@@ -751,10 +775,10 @@ handle_line_error (p, repetition)
struct control *p;
int repetition;
{
fprintf (stderr, "%s: `%d': line number out of range",
fprintf (stderr, _("%s: `%d': line number out of range"),
program_name, p->lines_required);
if (repetition)
fprintf (stderr, " on repetition %d\n", repetition);
fprintf (stderr, _(" on repetition %d\n"), repetition);
else
fprintf (stderr, "\n");
@@ -771,8 +795,8 @@ process_line_count (p, repetition)
struct control *p;
int repetition;
{
unsigned linenum;
unsigned last_line_to_save = p->lines_required * (repetition + 1);
unsigned int linenum;
unsigned int last_line_to_save = p->lines_required * (repetition + 1);
struct cstring *line;
create_output_file ();
@@ -782,7 +806,7 @@ process_line_count (p, repetition)
/* Check for requesting a line that has already been written out.
If this ever happens, it's due to a bug in csplit. */
if (linenum >= last_line_to_save)
handle_line_error (p, repetition);
abort ();
while (linenum++ < last_line_to_save)
{
@@ -806,11 +830,11 @@ regexp_error (p, repetition, ignore)
int repetition;
boolean ignore;
{
fprintf (stderr, "%s: `%s': match not found",
fprintf (stderr, _("%s: `%s': match not found"),
program_name, global_argv[p->argnum]);
if (repetition)
fprintf (stderr, " on repetition %d\n", repetition);
fprintf (stderr, _(" on repetition %d\n"), repetition);
else
fprintf (stderr, "\n");
@@ -832,8 +856,8 @@ process_regexp (p, repetition)
int repetition;
{
struct cstring *line; /* From input file. */
register unsigned line_len; /* To make "$" in regexps work. */
unsigned break_line; /* First line number of next file. */
unsigned int line_len; /* To make "$" in regexps work. */
unsigned int break_line; /* First line number of next file. */
boolean ignore = p->ignore; /* If TRUE, skip this section. */
int ret;
@@ -849,7 +873,19 @@ process_regexp (p, repetition)
{
line = find_line (++current_line);
if (line == NULL)
regexp_error (p, repetition, ignore);
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (0);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
@@ -857,7 +893,7 @@ process_regexp (p, repetition)
0, line_len, (struct re_registers *) 0);
if (ret == -2)
{
error (0, 0, "error in regular expression search");
error (0, 0, _("error in regular expression search"));
cleanup ();
}
if (ret == -1)
@@ -877,7 +913,19 @@ process_regexp (p, repetition)
{
line = find_line (++current_line);
if (line == NULL)
regexp_error (p, repetition, ignore);
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (0);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
@@ -885,7 +933,7 @@ process_regexp (p, repetition)
0, line_len, (struct re_registers *) 0);
if (ret == -2)
{
error (0, 0, "error in regular expression search");
error (0, 0, _("error in regular expression search"));
cleanup ();
}
if (ret >= 0)
@@ -909,18 +957,20 @@ process_regexp (p, repetition)
static void
split_file ()
{
register int i, j;
unsigned int i, j;
for (i = 0; i < control_used; i++)
{
if (controls[i].regexpr)
{
for (j = 0; j <= controls[i].repeat; j++)
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_regexp (&controls[i], j);
}
else
{
for (j = 0; j <= controls[i].repeat; j++)
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_line_count (&controls[i], j);
}
}
@@ -934,9 +984,13 @@ split_file ()
static char *
make_filename (num)
int num;
unsigned int num;
{
sprintf (filename_space, "%s%0*d", prefix, digits, num);
strcpy (filename_space, prefix);
if (suffix)
sprintf (filename_space+strlen(prefix), suffix, num);
else
sprintf (filename_space+strlen(prefix), "%0*d", digits, num);
return filename_space;
}
@@ -945,13 +999,11 @@ make_filename (num)
static void
create_output_file ()
{
char *name;
name = make_filename (files_created);
output_stream = fopen (name, "w");
output_filename = make_filename (files_created);
output_stream = fopen (output_filename, "w");
if (output_stream == NULL)
{
error (0, errno, "%s", name);
error (0, errno, "%s", output_filename);
cleanup ();
}
files_created++;
@@ -963,7 +1015,7 @@ create_output_file ()
static void
delete_all_files ()
{
int i;
unsigned int i;
char *name;
for (i = 0; i < files_created; i++)
@@ -984,11 +1036,18 @@ close_output_file ()
{
if (fclose (output_stream) == EOF)
{
error (0, errno, "write error");
error (0, errno, _("write error for `%s'"), output_filename);
cleanup ();
}
if (!suppress_count)
fprintf (stdout, "%d\n", bytes_written);
if (bytes_written == 0 && elide_empty_files)
{
if (unlink (output_filename))
error (0, errno, "%s", output_filename);
files_created--;
}
else
if (!suppress_count)
fprintf (stdout, "%d\n", bytes_written);
output_stream = NULL;
}
}
@@ -1025,7 +1084,7 @@ static struct control *
new_control_record ()
{
static unsigned control_allocated = 0; /* Total space allocated. */
register struct control *p;
struct control *p;
if (control_allocated == 0)
{
@@ -1042,6 +1101,7 @@ new_control_record ()
p = &controls[control_used++];
p->regexpr = NULL;
p->repeat = 0;
p->repeat_forever = 0;
p->lines_required = 0;
p->offset = 0;
return p;
@@ -1050,14 +1110,15 @@ new_control_record ()
/* Convert string NUM to an integer and put the value in *RESULT.
Return a TRUE if the string consists entirely of digits,
FALSE if not. */
/* FIXME: use xstrtoul in place of this function. */
static boolean
string_to_number (result, num)
int *result;
char *num;
{
register char ch;
register int val = 0;
char ch;
int val = 0;
if (*num == '\0')
return FALSE;
@@ -1085,10 +1146,10 @@ check_for_offset (p, str, num)
char *num;
{
if (*num != '-' && *num != '+')
error (1, 0, "%s: `+' or `-' expected after delimeter", str);
error (1, 0, _("%s: `+' or `-' expected after delimeter"), str);
if (!string_to_number (&p->offset, num + 1))
error (1, 0, "%s: integer expected after `%c'", str, *num);
error (1, 0, _("%s: integer expected after `%c'"), str, *num);
if (*num == '-')
p->offset = -p->offset;
@@ -1109,12 +1170,15 @@ parse_repeat_count (argnum, p, str)
end = str + strlen (str) - 1;
if (*end != '}')
error (1, 0, "%s: `}' is required in repeat count", str);
error (1, 0, _("%s: `}' is required in repeat count"), str);
*end = '\0';
if (!string_to_number (&p->repeat, str + 1))
error (1, 0, "%s}: integer required between `{' and `}'",
global_argv[argnum]);
if (str+1 == end-1 && *(str+1) == '*')
p->repeat_forever = 1;
else
if (!string_to_number (&p->repeat, str + 1))
error (1, 0, _("%s}: integer required between `{' and `}'"),
global_argv[argnum]);
*end = '}';
}
@@ -1137,9 +1201,9 @@ extract_regexp (argnum, ignore, str)
struct control *p;
const char *err;
closing_delim = rindex (str + 1, delim);
closing_delim = strrchr (str + 1, delim);
if (closing_delim == NULL)
error (1, 0, "%s: closing delimeter `%c' missing", str, delim);
error (1, 0, _("%s: closing delimeter `%c' missing"), str, delim);
len = closing_delim - str - 1;
p = new_control_record ();
@@ -1155,7 +1219,7 @@ extract_regexp (argnum, ignore, str)
err = re_compile_pattern (p->regexpr, len, &p->re_compiled);
if (err)
{
error (0, 0, "%s: invalid regular expression: %s", str, err);
error (0, 0, _("%s: invalid regular expression: %s"), str, err);
cleanup ();
}
@@ -1188,7 +1252,7 @@ parse_patterns (argc, start, argv)
p = new_control_record ();
p->argnum = i;
if (!string_to_number (&p->lines_required, argv[i]))
error (1, 0, "%s: invalid pattern", argv[i]);
error (1, 0, _("%s: invalid pattern"), argv[i]);
}
if (i + 1 < argc && *argv[i + 1] == '{')
@@ -1200,10 +1264,168 @@ parse_patterns (argc, start, argv)
}
}
static void
interrupt_handler ()
static unsigned
get_format_flags (format_ptr)
char **format_ptr;
{
error (0, 0, "interrupted");
unsigned count = 0;
for (; **format_ptr; (*format_ptr)++)
{
switch (**format_ptr)
{
case '-':
break;
case '+':
case ' ':
count++;
break;
case '#':
count += 2; /* Allow for 0x prefix preceeding an `x' conversion. */
break;
default:
return count;
}
}
return count;
}
static unsigned
get_format_width (format_ptr)
char **format_ptr;
{
unsigned count = 0;
char *start;
int ch_save;
start = *format_ptr;
for (; **format_ptr; (*format_ptr)++)
if (!ISDIGIT (**format_ptr))
break;
ch_save = **format_ptr;
**format_ptr = '\0';
/* In the case where no minimum field width is explicitly specified,
allow for enough octal digits to represent the value of LONG_MAX. */
count = ((*format_ptr == start)
? bytes_to_octal_digits[sizeof (long)]
: atoi (start));
**format_ptr = ch_save;
return count;
}
static unsigned
get_format_prec (format_ptr)
char **format_ptr;
{
unsigned count = 0;
char *start;
int ch_save;
int is_negative;
if (**format_ptr != '.')
return 0;
(*format_ptr)++;
if (**format_ptr == '-' || **format_ptr == '+')
{
is_negative = (**format_ptr == '-');
(*format_ptr)++;
}
else
{
is_negative = 0;
}
start = *format_ptr;
for (; **format_ptr; (*format_ptr)++)
if (!ISDIGIT (**format_ptr))
break;
/* ANSI 4.9.6.1 says that if the precision is negative, it's as good as
not there. */
if (is_negative)
start = *format_ptr;
ch_save = **format_ptr;
**format_ptr = '\0';
count = (*format_ptr == start) ? 11 : atoi (start);
**format_ptr = ch_save;
return count;
}
static void
get_format_conv_type (format_ptr)
char **format_ptr;
{
int ch = *((*format_ptr)++);
switch (ch)
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
break;
case 0:
error (1, 0, _("missing conversion specifier in suffix"));
break;
default:
if (ISPRINT (ch))
error (1, 0, _("invalid conversion specifier in suffix: %c"), ch);
else
error (1, 0, _("invalid conversion specifier in suffix: \\%.3o"), ch);
}
}
static unsigned
max_out (format)
char *format;
{
unsigned out_count = 0;
unsigned percents = 0;
for (; *format; )
{
int ch = *format++;
if (ch != '%')
out_count++;
else
{
percents++;
out_count += get_format_flags (&format);
{
int width = get_format_width (&format);
int prec = get_format_prec (&format);
out_count += MAX (width, prec);
}
get_format_conv_type (&format);
}
}
if (percents == 0)
error (1, 0, _("missing %% conversion specification in suffix"));
else if (percents > 1)
error (1, 0, _("too many %% conversion specifications in suffix"));
return out_count;
}
static void
interrupt_handler (signum)
int signum;
{
error (0, 0, _("interrupted"));
cleanup ();
}
@@ -1213,9 +1435,9 @@ main (argc, argv)
char **argv;
{
int optc;
#ifdef _POSIX_VERSION
#ifdef SA_INTERRUPT
struct sigaction oldact, newact;
#endif /* _POSIX_VERSION */
#endif /* SA_INTERRUPT */
program_name = argv[0];
global_argv = argv;
@@ -1225,7 +1447,7 @@ main (argc, argv)
remove_files = TRUE;
prefix = DEFAULT_PREFIX;
#ifdef _POSIX_VERSION
#ifdef SA_INTERRUPT
newact.sa_handler = interrupt_handler;
sigemptyset (&newact.sa_mask);
newact.sa_flags = 0;
@@ -1245,7 +1467,7 @@ main (argc, argv)
sigaction (SIGTERM, NULL, &oldact);
if (oldact.sa_handler != SIG_IGN)
sigaction (SIGTERM, &newact, NULL);
#else /* !_POSIX_VERSION */
#else
if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
signal (SIGHUP, interrupt_handler);
if (signal (SIGINT, SIG_IGN) != SIG_IGN)
@@ -1256,7 +1478,7 @@ main (argc, argv)
signal (SIGTERM, interrupt_handler);
#endif
while ((optc = getopt_long (argc, argv, "f:kn:s", longopts, (int *) 0))
while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, (int *) 0))
!= EOF)
switch (optc)
{
@@ -1267,36 +1489,51 @@ main (argc, argv)
prefix = optarg;
break;
case 'b':
suffix = optarg;
break;
case 'k':
remove_files = FALSE;
break;
case 'n':
if (!string_to_number (&digits, optarg))
error (1, 0, "%s: invalid number", optarg);
error (1, 0, _("%s: invalid number"), optarg);
break;
case 's':
case 'q':
suppress_count = TRUE;
break;
case 'z':
elide_empty_files = TRUE;
break;
default:
usage ();
usage (1);
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("csplit - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (optind >= argc - 1)
usage ();
if (argc - optind < 2)
{
error (0, 0, _("too few arguments"));
usage (1);
}
filename_space = (char *) xmalloc (strlen (prefix) + digits + 2);
if (suffix)
filename_space = (char *) xmalloc (strlen (prefix) + max_out (suffix) + 2);
else
filename_space = (char *) xmalloc (strlen (prefix) + digits + 2);
set_input_file (argv[optind++]);
@@ -1306,7 +1543,7 @@ main (argc, argv)
if (close (input_desc) < 0)
{
error (0, errno, "read error");
error (0, errno, _("read error"));
cleanup ();
}
@@ -1314,12 +1551,41 @@ main (argc, argv)
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [-sk] [-f prefix] [-n digits] [--prefix=prefix]\n\
[--digits=digits] [--quiet] [--silent] [--keep-files]\n\
[--help] [--version] file pattern...\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... FILE PATTERN...\n\
"),
program_name);
printf (_("\
Output pieces of FILE separated by PATTERN(s) to files `xx01', `xx02', ...,\n\
and output byte counts of each piece to standard output.\n\
\n\
-b, --suffix-format=FORMAT use sprintf FORMAT instead of %%d\n\
-f, --prefix=PREFIX use PREFIX instead of `xx'\n\
-k, --keep-files do not remove output files on errors\n\
-n, --digits=DIGITS use specified number of digits instead of 2\n\
-s, --quiet, --silent do not print counts of output file sizes\n\
-z, --elide-empty-files remove empty output files\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
Read standard input if FILE is -. Each PATTERN may be:\n\
\n\
INTEGER copy up to but not including specified line number\n\
/REGEXP/[OFFSET] copy up to but not including a matching line\n\
%%REGEXP%%[OFFSET] skip to, but not including a matching line\n\
{INTEGER} repeat the previous pattern specified number of times\n\
{*} repeat the previous pattern as many times as possible\n\
\n\
A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
"));
}
exit (status);
}

870
src/cut.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* date - print or set the system date and time
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
Copyright (C) 89, 90, 91, 92, 93, 94, 1995 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
@@ -13,38 +13,19 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Options:
-d DATESTR Display the date DATESTR.
-s DATESTR Set the date to DATESTR.
-u Display or set the date in universal instead of local time.
+FORMAT Specify custom date output format, described below.
MMDDhhmm[[CC]YY][.ss] Set the date in the format described below.
If one non-option argument is given, it is used as the date to which
to set the system clock, and must have the format:
MM month (01..12)
DD day in month (01..31)
hh hour (00..23)
mm minute (00..59)
CC first 2 digits of year (optional, defaults to current) (00..99)
YY last 2 digits of year (optional, defaults to current) (00..99)
ss second (00..61)
If a non-option argument that starts with a `+' is specified, it
is used to control the format in which the date is printed; it
can contain any of the `%' substitutions allowed by the strftime
function. A newline is always added at the end of the output.
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
David MacKenzie <djm@gnu.ai.mit.edu> */
#include <config.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include "version.h"
#include "system.h"
#include "getline.h"
#include "error.h"
#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
@@ -53,67 +34,133 @@
#endif
#ifndef STDC_HEADERS
time_t mktime ();
size_t strftime ();
time_t time ();
#endif
int putenv ();
int stime ();
char *xrealloc ();
time_t get_date ();
time_t posixtime ();
void error ();
static void show_date ();
static void usage ();
/* putenv string to use Universal Coordinated Time.
POSIX.2 says it should be "TZ=UCT0" or "TZ=GMT0". */
#ifndef TZ_UCT
#if defined(hpux) || defined(__hpux__) || defined(ultrix) || defined(__ultrix__) || defined(USG)
#define TZ_UCT "TZ=GMT0"
#else
#define TZ_UCT "TZ="
#endif
#endif
/* The name this program was run with, for error messages. */
char *program_name;
/* If non-zero, display usage information and exit. */
static int show_help;
/* If non-zero, print the version on standard error. */
/* If non-zero, print the version on standard output and exit. */
static int show_version;
/* If non-zero, print or set Coordinated Universal Time. */
static int universal_time = 0;
static struct option const long_options[] =
{
{"date", required_argument, NULL, 'd'},
{"file", required_argument, NULL, 'f'},
{"help", no_argument, &show_help, 1},
{"reference", required_argument, NULL, 'r'},
{"set", required_argument, NULL, 's'},
{"uct", no_argument, NULL, 'u'},
{"utc", no_argument, NULL, 'u'},
{"universal", no_argument, NULL, 'u'},
{"version", no_argument, &show_version, 1},
{NULL, 0, NULL, 0}
};
/* Parse each line in INPUT_FILENAME as with --date and display the
each resulting time and date. If the file cannot be opened, tell why
then exit. Issue a diagnostic for any lines that cannot be parsed.
If any line cannot be parsed, return non-zero; otherwise return zero. */
static int
batch_convert (input_filename, format)
const char *input_filename;
const char *format;
{
int status;
FILE *in_stream;
char *line;
int line_length;
int buflen;
time_t when;
if (strcmp (input_filename, "-") == 0)
{
input_filename = _("standard input");
in_stream = stdin;
}
else
{
in_stream = fopen (input_filename, "r");
if (in_stream == NULL)
{
error (0, errno, "%s", input_filename);
}
}
line = NULL;
buflen = 0;
status = 0;
while (1)
{
line_length = getline (&line, &buflen, in_stream);
if (line_length < 0)
{
/* FIXME: detect/handle error here. */
break;
}
when = get_date (line, NULL);
if (when == -1)
{
if (line[line_length - 1] == '\n')
line[line_length - 1] = '\0';
error (0, 0, _("invalid date `%s'"), line);
status = 1;
}
else
{
show_date (format, when);
}
}
if (fclose (in_stream) == EOF)
error (2, errno, input_filename);
if (line != NULL)
free (line);
return status;
}
void
main (argc, argv)
int argc;
char **argv;
{
int optc;
char *datestr = NULL;
const char *datestr = NULL;
const char *set_datestr = NULL;
time_t when;
int set_date = 0;
int universal_time = 0;
char *format;
char *batch_file = NULL;
char *reference = NULL;
struct stat refstats;
int n_args;
int status;
int option_specified_date;
program_name = argv[0];
while ((optc = getopt_long (argc, argv, "d:s:u", long_options, (int *) 0))
!= EOF)
while (optc = getopt_long (argc, argv, "d:f:r:s:u", long_options, (int *) 0),
optc != EOF)
switch (optc)
{
case 0:
@@ -121,55 +168,130 @@ main (argc, argv)
case 'd':
datestr = optarg;
break;
case 'f':
batch_file = optarg;
break;
case 'r':
reference = optarg;
break;
case 's':
datestr = optarg;
set_datestr = optarg;
set_date = 1;
break;
case 'u':
universal_time = 1;
break;
default:
usage ();
usage (1);
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("date - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (argc - optind > 1)
usage ();
n_args = argc - optind;
if (universal_time && putenv (TZ_UCT) != 0)
error (1, 0, "virtual memory exhausted");
option_specified_date = ((datestr ? 1 : 0)
+ (batch_file ? 1 : 0)
+ (reference ? 1 : 0));
time (&when);
if (datestr)
when = get_date (datestr, NULL);
if (argc - optind == 1 && argv[optind][0] != '+')
if (option_specified_date > 1)
{
when = posixtime (argv[optind]);
set_date = 1;
error (0, 0,
_("the options to specify dates for printing are mutually exclusive"));
usage (1);
}
if (when == -1)
error (1, 0, "invalid date");
if (set_date && option_specified_date)
{
error (0, 0,
_("the options to print and set the time may not be used together"));
usage (1);
}
if (set_date && stime (&when) == -1)
error (0, errno, "cannot set date");
if (n_args > 1)
{
error (0, 0, _("too many non-option arguments"));
usage (1);
}
if (argc - optind == 1 && argv[optind][0] == '+')
show_date (argv[optind] + 1, when);
if ((set_date || option_specified_date)
&& n_args == 1 && argv[optind][0] != '+')
{
error (0, 0, _("\
when using an option to specify date(s), any\n\
non-option argument must be a format string beginning with `+'"));
usage (1);
}
if (set_date)
datestr = set_datestr;
if (batch_file != NULL)
{
status = batch_convert (batch_file,
(n_args == 1 ? argv[optind] + 1 : NULL));
}
else
show_date ((char *) NULL, when);
{
status = 0;
exit (0);
if (!option_specified_date && !set_date)
{
if (n_args == 1 && argv[optind][0] != '+')
{
/* Prepare to set system clock to the specified date/time
given in the POSIX-format. */
set_date = 1;
datestr = argv[optind];
when = posixtime (datestr);
format = NULL;
}
else
{
/* Prepare to print the current date/time. */
datestr = _("undefined");
time (&when);
format = (n_args == 1 ? argv[optind] + 1 : NULL);
}
}
else
{
/* (option_specified_date || set_date) */
if (reference != NULL)
{
if (stat (reference, &refstats))
error (1, errno, "%s", reference);
when = refstats.st_mtime;
}
else
when = get_date (datestr, NULL);
format = (n_args == 1 ? argv[optind] + 1 : NULL);
}
if (when == -1)
error (1, 0, _("invalid date `%s'"), datestr);
if (set_date)
{
/* Set the system clock to the specified date, then regardless of
the success of that operation, format and print that date. */
if (stime (&when) == -1)
error (0, errno, _("cannot set date"));
}
show_date (format, when);
}
if (fclose (stdout) == EOF)
error (2, errno, _("write error"));
exit (status);
}
/* Display the date and/or time in WHEN according to the format specified
@@ -178,20 +300,24 @@ main (argc, argv)
static void
show_date (format, when)
char *format;
const char *format;
time_t when;
{
struct tm *tm;
char *out = NULL;
size_t out_length = 0;
tm = localtime (&when);
tm = (universal_time ? gmtime : localtime) (&when);
if (format == NULL)
/* Print the date in the default format. Vanilla ANSI C strftime
doesn't support %e, but POSIX requires it. If you don't use
a GNU strftime, make sure yours supports %e. */
format = "%a %b %e %H:%M:%S %Z %Y";
{
/* Print the date in the default format. Vanilla ANSI C strftime
doesn't support %e, but POSIX requires it. If you don't use
a GNU strftime, make sure yours supports %e. */
format = (universal_time
? "%a %b %e %H:%M:%S UTC %Y"
: "%a %b %e %H:%M:%S %Z %Y");
}
else if (*format == '\0')
{
printf ("\n");
@@ -210,12 +336,73 @@ show_date (format, when)
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [{--help,--version}] [-u] [-d datestr] [-s datestr]\n\
[--date datestr] [--set datestr] [--uct] [--universal]\n\
[+FORMAT] [MMDDhhmm[[CC]YY][.ss]]\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [+FORMAT]\n\
or: %s [OPTION] [MMDDhhmm[[CC]YY][.ss]]\n\
"),
program_name, program_name);
printf (_("\
Display the current time in the given FORMAT, or set the system date.\n\
\n\
-d, --date=STRING display time described by STRING, not `now'\n\
-f, --file=DATEFILE like --date once for each line of DATEFILE\n\
-r, --reference=FILE display the last modification time of FILE\n\
-s, --set=STRING set time described by STRING\n\
-u, --utc, --universal print or set Coordinated Universal Time\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
printf (_("\
\n\
FORMAT controls the output. The only valid option for the second form\n\
specifies Coordinated Universal Time. Interpreted sequences are:\n\
\n\
%%%% a literal %%\n\
%%a locale's abbreviated weekday name (Sun..Sat)\n\
%%A locale's full weekday name, variable length (Sunday..Saturday)\n\
%%b locale's abbreviated month name (Jan..Dec)\n\
%%B locale's full month name, variable length (January..December)\n\
%%c locale's date and time (Sat Nov 04 12:02:33 EST 1989)\n\
%%d day of month (01..31)\n\
%%D date (mm/dd/yy)\n\
%%h same as %%b\n\
%%H hour (00..23)\n\
%%I hour (01..12)\n\
%%j day of year (001..366)\n\
%%k hour ( 0..23)\n\
%%l hour ( 1..12)\n\
%%m month (01..12)\n\
%%M minute (00..59)\n\
%%n a newline\n\
%%p locale's AM or PM\n\
%%r time, 12-hour (hh:mm:ss [AP]M)\n\
%%s seconds since 00:00:00, Jan 1, 1970 (a GNU extension)\n\
%%S second (00..61)\n\
%%t a horizontal tab\n\
%%T time, 24-hour (hh:mm:ss)\n\
%%U week number of year with Sunday as first day of week (00..53)\n\
%%w day of week (0..6); 0 represents Sunday\n\
%%W week number of year with Monday as first day of week (00..53)\n\
%%x locale's date representation (mm/dd/yy)\n\
%%X locale's time representation (%%H:%%M:%%S)\n\
%%y last two digits of year (00..99)\n\
%%Y year (1970...)\n\
%%Z time zone (e.g., EDT), or nothing if no time zone is determinable\n\
\n\
By default, date pads numeric fields with zeroes. GNU date recognizes\n\
the following modifiers between `%%' and a numeric directive.\n\
\n\
`-' (hyphen) do not pad the field\n\
`_' (underscore) pad the field with spaces\n\
"));
}
exit (status);
}

154
src/dd.c
View File

@@ -1,5 +1,5 @@
/* dd -- convert a file while copying it.
Copyright (C) 1985, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1985, 1990, 1991, 1995 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
@@ -44,8 +44,8 @@
cbs, replacing newline with trailing spaces.
unblock Replace trailing spaces in cbs-sized block
with newline.
lcase Change uppercase characters to lowercase.
ucase Change lowercase characters to uppercase.
lcase Change upper case characters to lower case.
ucase Change lower case characters to upper case.
swab Swap every pair of input bytes.
Unlike the Unix dd, this works when an odd
number of bytes are read.
@@ -53,34 +53,18 @@
sync Pad every input block to size of ibs with
trailing NULs. */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#if !defined (isascii) || defined (STDC_HEADERS)
#undef isascii
#define isascii(c) 1
#endif
#define ISLOWER(c) (isascii (c) && islower (c))
#define ISUPPER(c) (isascii (c) && isupper (c))
#define ISDIGIT(c) (isascii (c) && isdigit (c))
#define SWAB_ALIGN_OFFSET 2
#include <sys/types.h>
#include <signal.h>
#include <getopt.h>
#include "system.h"
#include "version.h"
#include "error.h"
#define equal(p, q) (strcmp ((p),(q)) == 0)
#define max(a, b) ((a) > (b) ? (a) : (b))
@@ -108,7 +92,8 @@
#define C_TWOBUFS 04000
char *xmalloc ();
void error ();
int safe_read ();
int full_write ();
static RETSIGTYPE interrupt_handler ();
static int bit_count ();
@@ -353,12 +338,12 @@ main (argc, argv)
if (show_version)
{
printf ("%s\n", version_string);
printf ("dd - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
apply_translations ();
@@ -393,7 +378,7 @@ main (argc, argv)
}
else
output_file = "standard output";
#ifdef _POSIX_VERSION
sigaction (SIGINT, NULL, &sigact);
if (sigact.sa_handler != SIG_IGN)
@@ -403,9 +388,19 @@ main (argc, argv)
sigact.sa_flags = 0;
sigaction (SIGINT, &sigact, NULL);
}
sigaction (SIGPIPE, NULL, &sigact);
if (sigact.sa_handler != SIG_IGN)
{
sigact.sa_handler = interrupt_handler;
sigemptyset (&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction (SIGPIPE, &sigact, NULL);
}
#else /* !_POSIX_VERSION */
if (signal (SIGINT, SIG_IGN) != SIG_IGN)
signal (SIGINT, interrupt_handler);
if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
signal (SIGPIPE, interrupt_handler);
#endif /* !_POSIX_VERSION */
copy ();
}
@@ -427,12 +422,16 @@ skip (fdesc, file, records, blocksize, buf)
/* Use fstat instead of checking for errno == ESPIPE because
lseek doesn't work on some special files but doesn't return an
error, either. */
/* FIXME: can this really happen? What system? */
if (fstat (fdesc, &stats))
{
error (0, errno, "%s", file);
quit (1);
}
/* FIXME: why use lseek only on regular files?
Better: try lseek and if an error indicates it was an inappropriate
operation, fall back on using read. */
if (S_ISREG (stats.st_mode))
{
if (lseek (fdesc, records * blocksize, SEEK_SET) < 0)
@@ -445,13 +444,19 @@ skip (fdesc, file, records, blocksize, buf)
{
while (records-- > 0)
{
if (read (fdesc, buf, blocksize) < 0)
int nread;
nread = safe_read (fdesc, buf, blocksize);
if (nread < 0)
{
error (0, errno, "%s", file);
quit (1);
}
/* FIXME If fewer bytes were read than requested, meaning that
EOF was reached, POSIX wants the output file padded with NULs. */
/* POSIX doesn't say what to do when dd detects it has been
asked to skip past EOF, so I assume it's non-fatal.
FIXME: maybe give a warning. */
if (nread == 0)
break;
}
}
}
@@ -535,8 +540,14 @@ copy ()
int nread; /* Bytes read in the current block. */
int exit_status = 0;
/* Leave an extra byte at the beginning and end of `ibuf' for conv=swab. */
ibuf = (unsigned char *) xmalloc (input_blocksize + 2) + 1;
/* Leave at least one extra byte at the beginning and end of `ibuf'
for conv=swab, but keep the buffer address even. But some peculiar
device drivers work only with word-aligned buffers, so leave an
extra two bytes. */
ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
ibuf += SWAB_ALIGN_OFFSET;
if (conversions_mask & C_TWOBUFS)
obuf = (unsigned char *) xmalloc (output_blocksize);
else
@@ -560,9 +571,9 @@ copy ()
whatever data we are able to read is followed by zeros.
This minimizes data loss. */
if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
bzero (ibuf, input_blocksize);
memset (ibuf, 0, input_blocksize);
nread = read (input_fd, ibuf, input_blocksize);
nread = safe_read (input_fd, ibuf, input_blocksize);
if (nread == 0)
break; /* EOF. */
@@ -597,7 +608,7 @@ copy ()
{
if (!(conversions_mask & C_NOERROR))
/* If C_NOERROR, we zeroed the block before reading. */
bzero (ibuf + nread, input_blocksize - nread);
memset (ibuf + nread, 0, input_blocksize - nread);
nread = input_blocksize;
}
}
@@ -606,7 +617,7 @@ copy ()
if (ibuf == obuf) /* If not C_TWOBUFS. */
{
int nwritten = write (output_fd, obuf, nread);
int nwritten = full_write (output_fd, obuf, nread);
if (nwritten != nread)
{
error (0, errno, "%s", output_file);
@@ -670,7 +681,7 @@ copy ()
/* Write out the last block. */
if (oc > 0)
{
int nwritten = write (output_fd, obuf, oc);
int nwritten = full_write (output_fd, obuf, oc);
if (nwritten > 0)
w_partial++;
if (nwritten != oc)
@@ -680,7 +691,7 @@ copy ()
}
}
free (ibuf - 1);
free (ibuf - SWAB_ALIGN_OFFSET);
if (obuf != ibuf)
free (obuf);
@@ -703,8 +714,8 @@ copy_simple (buf, nread)
if (nfree > nread)
nfree = nread;
bcopy (start, obuf + oc, nfree);
memcpy (obuf + oc, start, nfree);
nread -= nfree; /* Update the number of bytes left to copy. */
start += nfree;
oc += nfree;
@@ -792,7 +803,7 @@ copy_with_unblock (buf, nread)
static void
write_output ()
{
int nwritten = write (output_fd, obuf, output_blocksize);
int nwritten = full_write (output_fd, obuf, output_blocksize);
if (nwritten != output_blocksize)
{
error (0, errno, "%s", output_file);
@@ -821,7 +832,7 @@ scanargs (argc, argv)
break;
default:
usage ();
usage (1);
}
}
@@ -830,11 +841,11 @@ scanargs (argc, argv)
char *name, *val;
name = argv[i];
val = index (name, '=');
val = strchr (name, '=');
if (val == NULL)
{
error (0, 0, "unrecognized option `%s'", name);
usage ();
usage (1);
}
*val++ = '\0';
@@ -873,7 +884,7 @@ scanargs (argc, argv)
else
{
error (0, 0, "unrecognized option `%s=%s'", name, val);
usage ();
usage (1);
}
}
}
@@ -895,6 +906,8 @@ scanargs (argc, argv)
optionally multiplied by various values.
Return -1 if STR does not represent a number in this format. */
/* FIXME: use xstrtou?l */
static int
parse_integer (str)
char *str;
@@ -947,7 +960,7 @@ parse_conversion (str)
do
{
new = index (str, ',');
new = strchr (str, ',');
if (new != NULL)
*new++ = '\0';
for (i = 0; conversions[i].convname != NULL; i++)
@@ -959,7 +972,7 @@ parse_conversion (str)
if (conversions[i].convname == NULL)
{
error (0, 0, "%s: invalid conversion", str);
usage ();
usage (1);
}
str = new;
} while (new != NULL);
@@ -1069,15 +1082,44 @@ interrupt_handler ()
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [if=file] [of=file] [ibs=bytes] [obs=bytes] [bs=bytes] [cbs=bytes]\n\
[skip=blocks] [seek=blocks] [count=blocks]\n\
[conv={ascii,ebcdic,ibm,block,unblock,lcase,ucase,swab,noerror,notrunc,\n\
sync}] [--help] [--version]\n\
Numbers can be followed by a multiplier:\n\
b=512, c=1, k=1024, w=2, xm=number m\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("Usage: %s [OPTION]...\n", program_name);
printf ("\
Copy a file, converting and formatting according to the options.\n\
\n\
bs=BYTES force ibs=BYTES and obs=BYTES\n\
cbs=BYTES convert BYTES bytes at a time\n\
conv=KEYWORDS convert the file as per the comma separated keyword list\n\
count=BLOCKS copy only BLOCKS input blocks\n\
ibs=BYTES read BYTES bytes at a time\n\
if=FILE read from FILE instead of stdin\n\
obs=BYTES write BYTES bytes at a time\n\
of=FILE write to FILE instead of stdout, don't truncate file\n\
seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
\n\
ascii from EBCDIC to ASCII\n\
ebcdic from ASCII to EBCDIC\n\
ibm from ASCII to alternated EBCDIC\n\
block pad newline-terminated records with spaces to cbs-size \n\
unblock replace trailing spaces in cbs-size records with newline\n\
lcase change upper case to lower case\n\
ucase change lower case to upper case\n\
swab swap every pair of input bytes\n\
noerror continue after read errors\n\
sync pad every input block with NULs to ibs-size\n");
}
exit (status);
}

150
src/df.c
View File

@@ -1,5 +1,5 @@
/* df - summarize free disk space
Copyright (C) 1991 Free Software Foundation, Inc.
Copyright (C) 1991, 1995 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
@@ -15,15 +15,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Usage: df [-aikP] [-t fstype] [-x fstype] [--all] [--inodes]
/* Usage: df [-aikPT] [-t fstype] [-x fstype] [--all] [--inodes] [--print-type]
[--type fstype] [--exclude-type fstype] [--kilobytes] [--portability]
[path...]
[file...]
Options:
-a, --all List all filesystems, even zero-size ones.
-i, --inodes List inode usage information instead of block usage.
-k, --kilobytes Print sizes in 1K blocks instead of 512-byte blocks.
-P, --portability Use the POSIX output format (one line per filesystem).
-T, --print-type Print filesystem type.
-t, --type fstype Limit the listing to filesystems of type `fstype'.
-x, --exclude-type=fstype
Limit the listing to filesystems not of type `fstype'.
@@ -32,29 +33,19 @@
Written by David MacKenzie <djm@gnu.ai.mit.edu> */
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "mountlist.h"
#include "fsusage.h"
#include "system.h"
#include "version.h"
#include "error.h"
char *strstr ();
char *xmalloc ();
char *xstrdup ();
void error ();
static int selected_fstype ();
static int excluded_fstype ();
@@ -88,6 +79,14 @@ static int kilobyte_blocks;
/* If nonzero, use the POSIX output format. */
static int posix_format;
/* If nonzero, invoke the `sync' system call before getting any usage data.
Using this option can make df very slow, especially with many or very
busy disks. Default to non-zero because the sync call does make a
difference on some systems -- SunOs4.1.3, for one. I have been assured
that it is *not* necessary on Linux, so there should be a way to
configure this. FIXME. */
static int require_sync = 1;
/* Nonzero if errors have occurred. */
static int exit_status;
@@ -126,12 +125,18 @@ static int show_help;
/* If non-zero, print the version on standard output and exit. */
static int show_version;
/* If non-zero, print filesystem type as well. */
static int print_type;
static struct option const long_options[] =
{
{"all", no_argument, &show_all_fs, 1},
{"inodes", no_argument, &inode_format, 1},
{"kilobytes", no_argument, &kilobyte_blocks, 1},
{"portability", no_argument, &posix_format, 1},
{"print-type", no_argument, &print_type, 1},
{"sync", no_argument, 0, 129},
{"no-sync", no_argument, 0, 130},
{"type", required_argument, 0, 't'},
{"exclude-type", required_argument, 0, 'x'},
{"help", no_argument, &show_help, 1},
@@ -154,10 +159,11 @@ main (argc, argv)
show_all_fs = 0;
show_listed_fs = 0;
kilobyte_blocks = getenv ("POSIXLY_CORRECT") == 0;
print_type = 0;
posix_format = 0;
exit_status = 0;
while ((i = getopt_long (argc, argv, "aikPt:vx:", long_options, (int *) 0))
while ((i = getopt_long (argc, argv, "aikPTt:vx:", long_options, (int *) 0))
!= EOF)
{
switch (i)
@@ -173,9 +179,18 @@ main (argc, argv)
case 'k':
kilobyte_blocks = 1;
break;
case 'T':
print_type = 1;
break;
case 'P':
posix_format = 1;
break;
case 129:
require_sync = 1;
break;
case 130:
require_sync = 0;
break;
case 't':
add_fs_type (optarg);
break;
@@ -185,20 +200,50 @@ main (argc, argv)
add_excluded_fs_type (optarg);
break;
default:
usage ();
usage (1);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("df - %s\n", version_string);
exit (0);
}
if (show_help)
usage ();
usage (0);
if (optind != argc)
/* Fail if the same file system type was both selected and excluded. */
{
int match = 0;
struct fs_type_list *i;
for (i = fs_select_list; i; i = i->fs_next)
{
struct fs_type_list *j;
for (j = fs_exclude_list; j; j = j->fs_next)
{
if (strcmp (i->fs_name, j->fs_name) == 0)
{
error (0, 0,
"file system type `%s' both selected and excluded",
i->fs_name);
match = 1;
break;
}
}
}
if (match)
exit (1);
}
if (optind == argc)
{
#ifdef lint
/* Suppress `used before initialized' warning. */
stats = NULL;
#endif
}
else
{
/* stat all the given entries to make sure they get automounted,
if necessary, before reading the filesystem table. */
@@ -221,7 +266,8 @@ main (argc, argv)
error (1, errno, "cannot read table of mounted filesystems");
print_header ();
sync ();
if (require_sync)
sync ();
if (optind == argc)
show_all_entries ();
@@ -241,10 +287,17 @@ main (argc, argv)
static void
print_header ()
{
if (inode_format)
printf ("Filesystem Inodes IUsed IFree %%IUsed");
printf ("Filesystem ");
if (print_type)
printf (" Type");
else
printf ("Filesystem %s Used Available Capacity",
printf (" ");
if (inode_format)
printf (" Inodes IUsed IFree %%IUsed");
else
printf (" %s Used Available Capacity",
kilobyte_blocks ? "1024-blocks" : " 512-blocks");
printf (" Mounted on\n");
}
@@ -316,12 +369,17 @@ show_point (point, statp)
{
error (0, errno, "%s", me->me_mountdir);
exit_status = 1;
me->me_dev = -2; /* So we won't try and fail repeatedly. */
/* So we won't try and fail repeatedly. */
me->me_dev = (dev_t) -2;
}
}
if (statp->st_dev == me->me_dev)
{
/* Skip bogus mtab entries. */
if (stat (me->me_mountdir, &disk_stats) != 0 ||
disk_stats.st_dev != me->me_dev)
continue;
show_dev (me->me_devname, me->me_mountdir, me->me_type);
return;
}
@@ -395,9 +453,12 @@ show_dev (disk, mount_point, fstype)
(inodes_used * 100.0 / fsu.fsu_files + 0.5);
}
printf ("%-20s", disk);
if (strlen (disk) > 20 && !posix_format)
printf ("\n ");
printf ((print_type ? "%-13s" : "%-20s"), disk);
if (strlen (disk) > (print_type ? 13 : 20) && !posix_format)
printf ((print_type ? "\n%13s" : "\n%20s"), "");
if (print_type)
printf (" %-5s ", fstype);
if (inode_format)
printf (" %7ld %7ld %7ld %5ld%%",
@@ -475,12 +536,31 @@ excluded_fstype (fstype)
}
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "\
Usage: %s [-aikPv] [-t fstype] [-x fstype] [--all] [--inodes]\n\
\t[--type=fstype] [--exclude-type=fstype] [--kilobytes] [--portability]\n\
\t[--help] [--version] [path...]\n",
program_name);
exit (1);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
printf ("\
Show information about the filesystem on which each FILE resides,\n\
or all filesystems by default.\n\
\n\
-a, --all include filesystems having 0 blocks\n\
-i, --inodes list inode information instead of block usage\n\
-k, --kilobytes use 1024 blocks, not 512 despite POSIXLY_CORRECT\n\
--sync invoke sync before getting usage info (default)\n\
--no-sync do not invoke sync before getting usage info\n\
-t, --type=TYPE limit listing to filesystems of type TYPE\n\
-x, --exclude-type=TYPE limit listing to filesystems not of type TYPE\n\
-v (ignored)\n\
-P, --portability use the POSIX output format\n\
-T, --print-type print filesystem type\n\
--help display this help and exit\n\
--version output version information and exit\n");
}
exit (status);
}

View File

@@ -1,5 +1,5 @@
/* dirname -- strip filename suffix from pathname
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 90, 91, 92, 93, 94, 1995 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
@@ -17,36 +17,43 @@
/* Written by David MacKenzie and Jim Meyering. */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "version.h"
#include "system.h"
#include "version.h"
#include "long-options.h"
#include "error.h"
void strip_trailing_slashes ();
/* The name this program was run with. */
char *program_name;
/* If non-zero, display usage information and exit. */
static int show_help;
/* If non-zero, print the version on standard error. */
static int show_version;
static struct option const long_options[] =
{
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{0, 0, 0, 0}
};
static void
usage ()
usage (status)
int status;
{
fprintf (stderr, "Usage: %s [{--help,--version}] path\n", program_name);
exit (1);
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("\
Usage: %s NAME\n\
or: %s OPTION\n\
"),
program_name, program_name);
printf (_("\
Print NAME with its trailing /component removed; if NAME contains no /'s,\n\
output `.' (meaning the current directory).\n\
\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
}
exit (status);
}
void
@@ -56,40 +63,23 @@ main (argc, argv)
{
register char *path;
register char *slash;
int c;
program_name = argv[0];
while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
{
switch (c)
{
case 0:
break;
parse_long_options (argc, argv, "dirname", version_string, usage);
default:
usage ();
}
if (argc != 2)
{
error (0, 0, _("too %s arguments"), argc < 2 ? _("few") : _("many"));
usage (1);
}
if (show_version)
{
printf ("%s\n", version_string);
exit (0);
}
if (show_help)
usage ();
if (argc - optind != 1)
usage ();
path = argv[optind];
path = argv[1];
strip_trailing_slashes (path);
slash = rindex (path, '/');
slash = strrchr (path, '/');
if (slash == NULL)
path = ".";
path = (char *) ".";
else
{
/* Remove any trailing slashes and final element. */

167
src/du.c
View File

@@ -1,5 +1,5 @@
/* du -- summarize disk usage
Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1990, 1991, 1995 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
@@ -40,25 +40,15 @@
#pragma alloca
#endif
#ifdef HAVE_CONFIG_H
#if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "version.h"
int lstat ();
int stat ();
#include "save-cwd.h"
#include "error.h"
/* Initial number of entries in each hash table entry's table of inodes. */
#define INITIAL_HASH_MODULE 100
@@ -100,11 +90,12 @@ typedef struct
char *text; /* Pointer to the text. */
} *string, stringstruct;
int stat ();
int lstat ();
char *savedir ();
char *xgetcwd ();
char *xmalloc ();
char *xrealloc ();
void error ();
static int hash_insert ();
static int hash_insert2 ();
@@ -173,6 +164,9 @@ static int show_help;
/* If non-zero, print the version on standard output and exit. */
static int show_version;
/* Grand total size of all args. */
static long tot_size = 0L;
static struct option const long_options[] =
{
{"all", no_argument, &opt_all, 1},
@@ -191,19 +185,37 @@ static struct option const long_options[] =
};
static void
usage (reason)
usage (status, reason)
int status;
char *reason;
{
if (reason != NULL)
fprintf (stderr, "%s: %s\n", program_name, reason);
fprintf (status == 0 ? stdout : stderr, "%s: %s\n",
program_name, reason);
fprintf (stderr, "\
Usage: %s [-abcklsxDLS] [--all] [--total] [--count-links] [--summarize]\n\
[--bytes] [--kilobytes] [--one-file-system] [--separate-dirs]\n\
[--dereference] [--dereference-args] [--help] [--version] [path...]\n",
program_name);
exit (2);
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n",
program_name);
else
{
printf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
printf ("\
Summarize disk usage of each FILE, recursively for directories.\n\
\n\
-a, --all write counts for all files, not just directories\n\
-b, --bytes print size in bytes\n\
-c, --total produce a grand total\n\
-k, --kilobytes use 1024 blocks, not 512 despite POSIXLY_CORRECT\n\
-l, --count-links count sizes many times if hard linked\n\
-s, --summarize display only a total for each argument\n\
-x, --one-file-system skip directories on different filesystems\n\
-D, --dereference-args dereference PATHs when symbolic link\n\
-L, --dereference dereference all symbolic links\n\
-S, --separate-dirs do not include size of subdirectories\n\
--help display this help and exit\n\
--version output version information and exit\n");
}
exit (status);
}
void
@@ -212,6 +224,10 @@ main (argc, argv)
char *argv[];
{
int c;
char *cwd_only[2];
cwd_only[0] = ".";
cwd_only[1] = NULL;
program_name = argv[0];
xstat = lstat;
@@ -266,41 +282,28 @@ main (argc, argv)
break;
default:
usage ((char *) 0);
usage (2, (char *) 0);
}
}
if (show_version)
{
printf ("%s\n", version_string);
printf ("du - %s\n", version_string);
exit (0);
}
if (show_help)
usage (NULL);
usage (0, NULL);
if (opt_all && opt_summarize_only)
usage ("cannot both summarize and show all entries");
usage (2, "cannot both summarize and show all entries");
/* Initialize the hash structure for inode numbers. */
hash_init (INITIAL_HASH_MODULE, INITIAL_ENTRY_TAB_SIZE);
str_init (&path, INITIAL_PATH_SIZE);
if (optind == argc)
{
str_copyc (path, ".");
/* Initialize the hash structure for inode numbers. */
hash_reset ();
/* Get the size of the current directory only. */
count_entry (".", 1, 0);
}
else
{
du_files (argv + optind);
}
du_files (optind == argc ? cwd_only : argv + optind);
exit (exit_status);
}
@@ -312,15 +315,13 @@ static void
du_files (files)
char **files;
{
char *wd;
struct saved_cwd cwd;
ino_t initial_ino; /* Initial directory's inode. */
dev_t initial_dev; /* Initial directory's device. */
long tot_size = 0L; /* Grand total size of all args. */
int i; /* Index in FILES. */
wd = xgetcwd ();
if (wd == NULL)
error (1, errno, "cannot get current directory");
if (save_cwd (&cwd))
exit (1);
/* Remember the inode and device number of the current directory. */
if (stat (".", &stat_buf))
@@ -352,14 +353,16 @@ du_files (files)
if (!opt_combined_arguments)
hash_reset ();
tot_size += count_entry (arg, 1, 0);
count_entry (arg, 1, 0);
/* chdir if `count_entry' has changed the working directory. */
if (stat (".", &stat_buf))
error (1, errno, ".");
if ((stat_buf.st_ino != initial_ino || stat_buf.st_dev != initial_dev)
&& chdir (wd) < 0)
error (1, errno, "cannot change to directory %s", wd);
if (stat_buf.st_ino != initial_ino || stat_buf.st_dev != initial_dev)
{
if (restore_cwd (&cwd, "starting directory", NULL))
exit (1);
}
}
if (opt_combined_arguments)
@@ -369,7 +372,7 @@ du_files (files)
fflush (stdout);
}
free (wd);
free_cwd (&cwd);
}
/* Print (if appropriate) and return the size
@@ -385,9 +388,9 @@ count_entry (ent, top, last_dev)
{
long size;
if ((top && opt_dereference_arguments ?
stat (ent, &stat_buf) :
(*xstat) (ent, &stat_buf)) < 0)
if (((top && opt_dereference_arguments)
? stat (ent, &stat_buf)
: (*xstat) (ent, &stat_buf)) < 0)
{
error (0, errno, "%s", path->text);
exit_status = 1;
@@ -404,18 +407,36 @@ count_entry (ent, top, last_dev)
else
size = ST_NBLOCKS (stat_buf);
tot_size += size;
if (S_ISDIR (stat_buf.st_mode))
{
unsigned pathlen;
dev_t dir_dev;
char *name_space;
char *namep;
struct saved_cwd cwd;
int through_symlink;
struct stat e_buf;
dir_dev = stat_buf.st_dev;
if (opt_one_file_system && !top && last_dev != dir_dev)
return 0; /* Don't enter a new file system. */
#ifndef S_ISDIR
# define S_ISDIR(s) 0
#endif
/* If we're dereferencing symlinks and we're about to chdir through
a symlink, remember the current directory so we can return to it
later. In other cases, chdir ("..") works fine. */
through_symlink = (xstat == stat
&& lstat (ent, &e_buf) == 0
&& S_ISLNK (e_buf.st_mode));
if (through_symlink)
if (save_cwd (&cwd))
exit (1);
if (chdir (ent) < 0)
{
error (0, errno, "cannot change to directory %s", path->text);
@@ -430,9 +451,15 @@ count_entry (ent, top, last_dev)
if (errno)
{
error (0, errno, "%s", path->text);
if (chdir ("..") < 0) /* Try to return to previous dir. */
error (1, errno, "cannot change to `..' from directory %s",
path->text);
if (through_symlink)
{
if (restore_cwd (&cwd, "..", path->text))
exit (1);
free_cwd (&cwd);
}
else if (chdir ("..") < 0)
error (1, errno, "cannot change to `..' from directory %s",
path->text);
exit_status = 1;
return 0;
}
@@ -456,7 +483,12 @@ count_entry (ent, top, last_dev)
namep += strlen (namep) + 1;
}
free (name_space);
if (chdir ("..") < 0)
if (through_symlink)
{
restore_cwd (&cwd, "..", path->text);
free_cwd (&cwd);
}
else if (chdir ("..") < 0)
error (1, errno, "cannot change to `..' from directory %s", path->text);
str_trunc (path, pathlen - 1); /* Remove the "/" we added. */
@@ -464,17 +496,22 @@ count_entry (ent, top, last_dev)
{
printf ("%ld\t%s\n", output_size == size_bytes ? size
: convert_blocks (size, output_size == size_kilobytes),
path->text);
path->length > 0 ? path->text : "/");
fflush (stdout);
}
return opt_separate_dirs ? 0 : size;
}
else if (opt_all || top)
{
printf ("%ld\t%s\n", output_size == size_bytes ? size
: convert_blocks (size, output_size == size_kilobytes),
path->text);
fflush (stdout);
/* FIXME: make this an option. */
int print_only_dir_size = 0;
if (!print_only_dir_size)
{
printf ("%ld\t%s\n", output_size == size_bytes ? size
: convert_blocks (size, output_size == size_kilobytes),
path->text);
fflush (stdout);
}
}
return size;

Some files were not shown because too many files have changed in this diff Show More