mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
Compare commits
1542 Commits
ISDIGIT-bu
...
FILEUTILS-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a4a5dd66c | ||
|
|
fe456215a6 | ||
|
|
65957278ab | ||
|
|
6f2e1d1ce2 | ||
|
|
51078dff7f | ||
|
|
03824c9e29 | ||
|
|
10c96c43ac | ||
|
|
8e8fd5439a | ||
|
|
d3bcbd9968 | ||
|
|
6526b37460 | ||
|
|
9379b5aed5 | ||
|
|
f2794b3c5d | ||
|
|
f090816a3f | ||
|
|
d385bbc985 | ||
|
|
715765a548 | ||
|
|
de0fdbb080 | ||
|
|
e6800f5073 | ||
|
|
e1ff4d762b | ||
|
|
ffccedee33 | ||
|
|
8ddd60a387 | ||
|
|
eaf359df0c | ||
|
|
ff6400a018 | ||
|
|
a74458a36e | ||
|
|
e6c847ea05 | ||
|
|
c7d28e2bd8 | ||
|
|
898f3e5757 | ||
|
|
c239e82816 | ||
|
|
aaa9cb7c22 | ||
|
|
73d802bead | ||
|
|
29b0ceae9f | ||
|
|
b21af8a7dd | ||
|
|
7a888be2e5 | ||
|
|
815b5ca1d5 | ||
|
|
76118226b6 | ||
|
|
091c054eed | ||
|
|
3d2a9041f9 | ||
|
|
aeb85812a1 | ||
|
|
3a3b589b06 | ||
|
|
20c8b4db54 | ||
|
|
c44dd6ddad | ||
|
|
446976666c | ||
|
|
c997ad6f05 | ||
|
|
27a6efc25b | ||
|
|
557514f55c | ||
|
|
5ba09e9ace | ||
|
|
60ae95f973 | ||
|
|
9a181424ac | ||
|
|
4e3478c9d6 | ||
|
|
3803547285 | ||
|
|
cbdd4ce994 | ||
|
|
3749705b11 | ||
|
|
c940655b0f | ||
|
|
db18c4898e | ||
|
|
5d78a2a235 | ||
|
|
268ddc7d50 | ||
|
|
dee715bb6f | ||
|
|
edac0ff420 | ||
|
|
3f10c64fca | ||
|
|
d706ee318c | ||
|
|
a4d2c17357 | ||
|
|
6f37efd8b2 | ||
|
|
746c5e5528 | ||
|
|
6ff9e537fe | ||
|
|
b12057e3bd | ||
|
|
34e1cf8304 | ||
|
|
178d3b59d5 | ||
|
|
ce4e2493ee | ||
|
|
85f9983c19 | ||
|
|
9cb56e2980 | ||
|
|
c5134a9b13 | ||
|
|
475d6600c1 | ||
|
|
3dbdcab168 | ||
|
|
756fe67e60 | ||
|
|
23d07a32b2 | ||
|
|
9f82a64eb6 | ||
|
|
79b86f69e6 | ||
|
|
4d81490eb3 | ||
|
|
28a24ea3be | ||
|
|
6a4e9d5422 | ||
|
|
777d5f0ba8 | ||
|
|
9e7cf8346d | ||
|
|
1f37d82ce4 | ||
|
|
baf2a7b0fe | ||
|
|
73d5e9c5dd | ||
|
|
daf7870cb0 | ||
|
|
796e41bedf | ||
|
|
816194943b | ||
|
|
2eabfeeea8 | ||
|
|
5715c04ceb | ||
|
|
dd05029135 | ||
|
|
78362fb43a | ||
|
|
1723365c85 | ||
|
|
7e9524d7b9 | ||
|
|
c4b593538b | ||
|
|
0b2ebf9875 | ||
|
|
aa35ed104c | ||
|
|
737a7a7116 | ||
|
|
4634a5c628 | ||
|
|
c33725a845 | ||
|
|
e70623f196 | ||
|
|
862593b1f7 | ||
|
|
215318944a | ||
|
|
58e02de834 | ||
|
|
e02a4a825a | ||
|
|
73c74c0303 | ||
|
|
2d882a7200 | ||
|
|
d2a3720ad0 | ||
|
|
e6777f1523 | ||
|
|
41d5fb8189 | ||
|
|
3480c29030 | ||
|
|
a5c268a9f9 | ||
|
|
4f3121b654 | ||
|
|
73b2951ffe | ||
|
|
46505987ea | ||
|
|
bf58f8aea9 | ||
|
|
6c52fbcdfd | ||
|
|
e76eb59d84 | ||
|
|
5b093c28e1 | ||
|
|
9d3b949aa6 | ||
|
|
a468d7579f | ||
|
|
4eb32cb4f2 | ||
|
|
8f08533808 | ||
|
|
3b69e6514c | ||
|
|
9018ec3d41 | ||
|
|
5d16193294 | ||
|
|
61b305d30d | ||
|
|
efc9004234 | ||
|
|
ba733f2d38 | ||
|
|
34a122edc8 | ||
|
|
a5afd877aa | ||
|
|
1289479fce | ||
|
|
7bfb13dea7 | ||
|
|
744d31d57a | ||
|
|
a58305d61e | ||
|
|
3bd2561144 | ||
|
|
156a61c86d | ||
|
|
5850877aea | ||
|
|
847dcc878b | ||
|
|
84791e75cc | ||
|
|
e30230223c | ||
|
|
884e63790c | ||
|
|
a0b8bf89d3 | ||
|
|
c3e64b1b2d | ||
|
|
2131b2e9d5 | ||
|
|
6981af01ee | ||
|
|
863c253425 | ||
|
|
08d800d44e | ||
|
|
e23e3f656a | ||
|
|
4ad4b8aaec | ||
|
|
0f32a82524 | ||
|
|
2a0d3143dd | ||
|
|
6e867c19c9 | ||
|
|
c78152220a | ||
|
|
be2519d4dd | ||
|
|
9800c1597f | ||
|
|
2bf12371d8 | ||
|
|
7243acff2a | ||
|
|
bfa30819b9 | ||
|
|
ac5e053d8f | ||
|
|
13751495a1 | ||
|
|
1d2f218bff | ||
|
|
00b953713e | ||
|
|
ed4a024430 | ||
|
|
53398947a1 | ||
|
|
5e14cce7ae | ||
|
|
27276e481d | ||
|
|
7949927db6 | ||
|
|
634853cee6 | ||
|
|
0f100b0d3f | ||
|
|
83adf65c37 | ||
|
|
67b467223a | ||
|
|
2e6b75c735 | ||
|
|
0ec5eacc92 | ||
|
|
b024130dc2 | ||
|
|
aff66fa170 | ||
|
|
92e8245d90 | ||
|
|
c300ac7a4d | ||
|
|
67b836ed72 | ||
|
|
388569f846 | ||
|
|
981d081027 | ||
|
|
6a7bd50a0b | ||
|
|
f280d719f3 | ||
|
|
1d39399861 | ||
|
|
008d74220b | ||
|
|
0f0189167b | ||
|
|
bf6bcd3c16 | ||
|
|
b439039b9b | ||
|
|
2cada8c970 | ||
|
|
360b2870d8 | ||
|
|
b669dbd1ad | ||
|
|
b81692a8a9 | ||
|
|
dfa0cede72 | ||
|
|
add1d7c11f | ||
|
|
221ef68cc3 | ||
|
|
a7190a7381 | ||
|
|
f721ed2bf4 | ||
|
|
6dde9c58fe | ||
|
|
f1a5372cbc | ||
|
|
c22b040b21 | ||
|
|
0c5abc43a0 | ||
|
|
d5f4d5f22e | ||
|
|
2a5c6dea54 | ||
|
|
05d30f2715 | ||
|
|
c8d085374c | ||
|
|
9ceb93e7ff | ||
|
|
b808e70940 | ||
|
|
654ad9e596 | ||
|
|
8cff7ef2b9 | ||
|
|
137cf55755 | ||
|
|
ddc22e05ab | ||
|
|
42fcbf3950 | ||
|
|
11f5ed65ba | ||
|
|
99cf57df5f | ||
|
|
b71a140977 | ||
|
|
e49897affc | ||
|
|
2ef6cb6073 | ||
|
|
4db03fe797 | ||
|
|
8506a6bc2a | ||
|
|
8303c90f14 | ||
|
|
a530d04879 | ||
|
|
4a99368c87 | ||
|
|
46faa9979f | ||
|
|
c038102c6a | ||
|
|
23cfe44342 | ||
|
|
b3d7a51157 | ||
|
|
23f91764bc | ||
|
|
2ab1921d24 | ||
|
|
1c2d713cab | ||
|
|
395224e372 | ||
|
|
43cdd09d2d | ||
|
|
de6c7a9b78 | ||
|
|
7d7530446c | ||
|
|
208fa17ad0 | ||
|
|
5a1b7d267a | ||
|
|
1bcceb8ba4 | ||
|
|
e0bcf6c00d | ||
|
|
0a5f63aee2 | ||
|
|
2008517b36 | ||
|
|
517bef6ccd | ||
|
|
e2db29a312 | ||
|
|
a3fa97f5e3 | ||
|
|
7fc45bccbd | ||
|
|
7d3a280b7a | ||
|
|
be60b8e319 | ||
|
|
4090d52520 | ||
|
|
1f88c647cd | ||
|
|
08b596b409 | ||
|
|
e625640bd0 | ||
|
|
a6a2dbc63c | ||
|
|
5c3c1931dd | ||
|
|
d75c1aaea1 | ||
|
|
f1a905664b | ||
|
|
5cf455d736 | ||
|
|
8ef322d66f | ||
|
|
1d5b09348e | ||
|
|
5782ca8976 | ||
|
|
623ce837c7 | ||
|
|
73f21f7813 | ||
|
|
a8377ab773 | ||
|
|
5106e930d1 | ||
|
|
74b4707ea6 | ||
|
|
99b8fcfb0d | ||
|
|
5df13c9b0a | ||
|
|
5eeef11a3b | ||
|
|
cfbca54a71 | ||
|
|
f0f6a9c44e | ||
|
|
cc1a9180a7 | ||
|
|
155639bf0f | ||
|
|
c0f51577fd | ||
|
|
efac765819 | ||
|
|
1c7a2ac60f | ||
|
|
f4b094e098 | ||
|
|
e984b74461 | ||
|
|
c1e61448b3 | ||
|
|
2f077ef41f | ||
|
|
cfc48b6ee9 | ||
|
|
073c4cb543 | ||
|
|
8bacb0720c | ||
|
|
da8c36f53f | ||
|
|
83cf5efca9 | ||
|
|
4d9669b8d9 | ||
|
|
18573f3eb2 | ||
|
|
57ec0f45c9 | ||
|
|
a7830ac93b | ||
|
|
488bd9911e | ||
|
|
7956c15081 | ||
|
|
0402200daf | ||
|
|
dc0708fa82 | ||
|
|
7b9ad5a22f | ||
|
|
c4e9f56745 | ||
|
|
b69a467146 | ||
|
|
75cce0c815 | ||
|
|
546754d2e9 | ||
|
|
e8f8b7a82d | ||
|
|
c54a604289 | ||
|
|
f52e14c576 | ||
|
|
a0aef26c06 | ||
|
|
4d4a6210f7 | ||
|
|
a5ad9a2579 | ||
|
|
79d6ddd36a | ||
|
|
18da62e303 | ||
|
|
77469b714b | ||
|
|
1fbac54162 | ||
|
|
cf14c509f3 | ||
|
|
02bde8d334 | ||
|
|
e99f534046 | ||
|
|
aeac9910cb | ||
|
|
f84513b43e | ||
|
|
34fc818d7e | ||
|
|
f1e1eb58be | ||
|
|
3d6c17e94f | ||
|
|
ef3e297950 | ||
|
|
5cf3719e7b | ||
|
|
b36e366ef4 | ||
|
|
c2b86aabe0 | ||
|
|
849a1c46cf | ||
|
|
7c863aef95 | ||
|
|
cc7705fe6f | ||
|
|
e97b60d16a | ||
|
|
1b1382a3a9 | ||
|
|
ff0e048521 | ||
|
|
0af7afd19f | ||
|
|
24aec7f87f | ||
|
|
acb7c4ee48 | ||
|
|
5796c221a1 | ||
|
|
dde28b7ffe | ||
|
|
dfa21e5966 | ||
|
|
8014db4d68 | ||
|
|
c6394074a8 | ||
|
|
83ce0dcba6 | ||
|
|
9a69ea769a | ||
|
|
3044600151 | ||
|
|
da6d91f64b | ||
|
|
c6ca8a1528 | ||
|
|
8108bc26d6 | ||
|
|
908b4d6cb9 | ||
|
|
0683df4bf8 | ||
|
|
05907fc584 | ||
|
|
ca56751421 | ||
|
|
dd084ce340 | ||
|
|
92278a462b | ||
|
|
ca56be1e3e | ||
|
|
09f8e7fb03 | ||
|
|
c2e9e7a31b | ||
|
|
49f397e6e7 | ||
|
|
6161f25abc | ||
|
|
0898b54377 | ||
|
|
6f1c4b7a75 | ||
|
|
b7b00aad08 | ||
|
|
ec2a94a410 | ||
|
|
4796ddfe36 | ||
|
|
31856b16c3 | ||
|
|
6732422b97 | ||
|
|
2b3ce6fab9 | ||
|
|
b951477c80 | ||
|
|
0bf332a016 | ||
|
|
3e12088cf0 | ||
|
|
c0d94c89ec | ||
|
|
dd3a088973 | ||
|
|
5c15113c49 | ||
|
|
553eb65acd | ||
|
|
0c43179cf9 | ||
|
|
b031f89b29 | ||
|
|
b7df779b8b | ||
|
|
96ed803f48 | ||
|
|
fd798dd6fe | ||
|
|
dd8b68966f | ||
|
|
72ce8c67c5 | ||
|
|
22132a47aa | ||
|
|
0705aa7388 | ||
|
|
762769cf3b | ||
|
|
82eae6c9b5 | ||
|
|
86f04e3bb3 | ||
|
|
ce5f4177bc | ||
|
|
48f3bca87e | ||
|
|
adf0ec7008 | ||
|
|
5b4dde5a7b | ||
|
|
2224409994 | ||
|
|
30d11429a9 | ||
|
|
c4176dd559 | ||
|
|
47d5042d1e | ||
|
|
6df632b672 | ||
|
|
6875b205d6 | ||
|
|
47306242ec | ||
|
|
83780d95f0 | ||
|
|
5b804afa6a | ||
|
|
83b9d5e9ef | ||
|
|
a2b0b9846d | ||
|
|
a0ad16498b | ||
|
|
aa084c8407 | ||
|
|
ac821ab1ef | ||
|
|
6e146d4216 | ||
|
|
e4a96fff58 | ||
|
|
aa6cde5ca1 | ||
|
|
05a5e42609 | ||
|
|
11a013bf87 | ||
|
|
de4de17bc5 | ||
|
|
b0302bb3a6 | ||
|
|
334f8dcbb7 | ||
|
|
47eaf4a1e8 | ||
|
|
1e30b2f8c4 | ||
|
|
84df8be864 | ||
|
|
f05befc26c | ||
|
|
96e22ecc78 | ||
|
|
9eb195d6a5 | ||
|
|
40f0f4d2e8 | ||
|
|
4fa07774d6 | ||
|
|
7567c84e76 | ||
|
|
a87c771012 | ||
|
|
a2535fc95f | ||
|
|
d2aaf842b4 | ||
|
|
13e93efe91 | ||
|
|
af1033c63c | ||
|
|
768f92072f | ||
|
|
8b92864e1d | ||
|
|
d97d668b69 | ||
|
|
5d1c0a2af5 | ||
|
|
b1c9ce6621 | ||
|
|
aec547d764 | ||
|
|
185c59d3bd | ||
|
|
f1c5cfd5f2 | ||
|
|
c848009e29 | ||
|
|
a0d766c204 | ||
|
|
c1f248d670 | ||
|
|
9b1d63b4a3 | ||
|
|
c7262bbe86 | ||
|
|
008028896b | ||
|
|
c5716550a6 | ||
|
|
b43f5fb25b | ||
|
|
013277d331 | ||
|
|
09eedba01f | ||
|
|
ca59b76b50 | ||
|
|
b9485b8d52 | ||
|
|
66b9285a6f | ||
|
|
470e773e76 | ||
|
|
039942bfc1 | ||
|
|
a94e341d85 | ||
|
|
db98ca11cf | ||
|
|
22a5274de9 | ||
|
|
2ee6cf8ea0 | ||
|
|
baf81e4974 | ||
|
|
bda4a5e5b7 | ||
|
|
0598102472 | ||
|
|
4aba8a55f2 | ||
|
|
6f6a35a9a1 | ||
|
|
d691ea7ebc | ||
|
|
ca63ca90ab | ||
|
|
43dd57eba9 | ||
|
|
6dd358e12d | ||
|
|
c73aa6b629 | ||
|
|
63b348b3a9 | ||
|
|
6181f175e3 | ||
|
|
5a52e61271 | ||
|
|
e74c290ac7 | ||
|
|
5ea57c875d | ||
|
|
492b177ca5 | ||
|
|
daa976fff6 | ||
|
|
871d176f15 | ||
|
|
fc2e23b1ad | ||
|
|
1cde2ceb5c | ||
|
|
539457f1ae | ||
|
|
b6ff24fb7f | ||
|
|
da20dc044a | ||
|
|
a42c7fe2d1 | ||
|
|
b792f7aa0e | ||
|
|
9242af95a3 | ||
|
|
9583179c1b | ||
|
|
d9dee002e6 | ||
|
|
434b809272 | ||
|
|
4feb3b1e06 | ||
|
|
14390d1fed | ||
|
|
8831ffbec4 | ||
|
|
45d4def5e4 | ||
|
|
b9c1393e5f | ||
|
|
c5bf4b6c9c | ||
|
|
3ac64eda17 | ||
|
|
148f37c34e | ||
|
|
9845d179b3 | ||
|
|
11b87d29cc | ||
|
|
bc7210e563 | ||
|
|
e1ab53f969 | ||
|
|
790196a645 | ||
|
|
b5c8c81d4d | ||
|
|
91a709b210 | ||
|
|
5e25ee19e4 | ||
|
|
70390f60ec | ||
|
|
c22889019c | ||
|
|
06ea91f2f3 | ||
|
|
3c7699600f | ||
|
|
c8c90bb532 | ||
|
|
6f63d53e1b | ||
|
|
cd1dbbcfc1 | ||
|
|
4bbadbb14a | ||
|
|
cc61df7131 | ||
|
|
965c0bf39d | ||
|
|
6fc3c211ec | ||
|
|
c25dcdd843 | ||
|
|
e387fd1471 | ||
|
|
1c7bc6028a | ||
|
|
74f061de82 | ||
|
|
47b91b8948 | ||
|
|
2d73c959cc | ||
|
|
9a17340b10 | ||
|
|
a9de4d485a | ||
|
|
111cb717e8 | ||
|
|
6a45f61547 | ||
|
|
026d10d369 | ||
|
|
d832bf77eb | ||
|
|
de97a7099c | ||
|
|
1d15980fb6 | ||
|
|
b3303ba072 | ||
|
|
eddb25aa26 | ||
|
|
40c6966137 | ||
|
|
4de6eab547 | ||
|
|
caa2df2274 | ||
|
|
4c8c0b69ba | ||
|
|
527d04d44b | ||
|
|
9a12d05216 | ||
|
|
77c46a6b42 | ||
|
|
744393f0f4 | ||
|
|
6f200d7982 | ||
|
|
12e85d31e2 | ||
|
|
17821cc15e | ||
|
|
0bcd6e68a9 | ||
|
|
528390fa58 | ||
|
|
a719a87508 | ||
|
|
a1fa4eff25 | ||
|
|
f344b7fab6 | ||
|
|
eca98f76ac | ||
|
|
f30618bac7 | ||
|
|
dc4a18b537 | ||
|
|
9801e9cde1 | ||
|
|
1b16c152bd | ||
|
|
3ed71a2fdd | ||
|
|
0e15d57a89 | ||
|
|
c253d247ca | ||
|
|
656fac3d80 | ||
|
|
dde2c138e9 | ||
|
|
7823351d6b | ||
|
|
b23b6bbcf7 | ||
|
|
800e219a2d | ||
|
|
ecf0d31b72 | ||
|
|
c3f476d467 | ||
|
|
7f3e86b27b | ||
|
|
b0453a43c0 | ||
|
|
b30b152bb7 | ||
|
|
a030007908 | ||
|
|
10c5aeabc5 | ||
|
|
9c5f82a7f1 | ||
|
|
7bbe6cbe82 | ||
|
|
b014a71007 | ||
|
|
36c29006f8 | ||
|
|
59e80c1a0a | ||
|
|
e4dc3d6d36 | ||
|
|
a6fdb5b75d | ||
|
|
26574d5284 | ||
|
|
c02722d395 | ||
|
|
b3d74743a8 | ||
|
|
f03f8dcc44 | ||
|
|
a5656326f0 | ||
|
|
f0556f3517 | ||
|
|
6b853ebe01 | ||
|
|
d0e2b9c466 | ||
|
|
a94a8dd402 | ||
|
|
7c342fe2a1 | ||
|
|
9c3f1711e2 | ||
|
|
0347634ad3 | ||
|
|
92c50e7f52 | ||
|
|
22ebf9c6ac | ||
|
|
5fa76547cf | ||
|
|
e29f6ae24d | ||
|
|
00dadad79c | ||
|
|
767768457c | ||
|
|
a468aa55b6 | ||
|
|
cbc82e5cc3 | ||
|
|
b0aa8e6985 | ||
|
|
c3f2e69471 | ||
|
|
86c9719f0a | ||
|
|
be22aff966 | ||
|
|
0159470d3d | ||
|
|
2adeb32b35 | ||
|
|
351cf87351 | ||
|
|
3139de9726 | ||
|
|
b4a47508d4 | ||
|
|
f7860d6172 | ||
|
|
f6b3413fcc | ||
|
|
e799d19df8 | ||
|
|
b1ab76f3e4 | ||
|
|
ccb00b7ef9 | ||
|
|
ac37278a41 | ||
|
|
fc88df7458 | ||
|
|
11ec25d3ce | ||
|
|
4aa1e2f2e8 | ||
|
|
ea4cda6907 | ||
|
|
ba477b681a | ||
|
|
f2fc6e4cad | ||
|
|
6473e3638f | ||
|
|
7e93c0f64b | ||
|
|
1126d3b93e | ||
|
|
c02e97e2c5 | ||
|
|
f7ccdd300d | ||
|
|
8904d4a45c | ||
|
|
8c17f50aea | ||
|
|
28e28e6d74 | ||
|
|
7732d5d7cf | ||
|
|
5f33b78417 | ||
|
|
6abd6fdd72 | ||
|
|
0e7bce124f | ||
|
|
35eda3509e | ||
|
|
58b1195eb4 | ||
|
|
bb79abc8a3 | ||
|
|
574cc98b23 | ||
|
|
855741c7cb | ||
|
|
d58bdcd4fa | ||
|
|
1ae54a6140 | ||
|
|
db566dba37 | ||
|
|
3d699e8ee0 | ||
|
|
e20e0ba392 | ||
|
|
dfe3d8837e | ||
|
|
e59ec88ea2 | ||
|
|
66c43ec708 | ||
|
|
e692090b89 | ||
|
|
1e74962c8a | ||
|
|
14aaf3eab3 | ||
|
|
adfa243b0d | ||
|
|
37ba8d9867 | ||
|
|
c20ee98ac8 | ||
|
|
21aa588967 | ||
|
|
ba34723398 | ||
|
|
51c3164ba3 | ||
|
|
307526e92d | ||
|
|
6dfad5e900 | ||
|
|
ccfb7f032d | ||
|
|
bb5590f7b6 | ||
|
|
67718aff76 | ||
|
|
b9d3dc4101 | ||
|
|
20b6a5b40a | ||
|
|
72d4155c90 | ||
|
|
e7c2d62889 | ||
|
|
c8e05ecd8d | ||
|
|
9c8e5123bd | ||
|
|
9a5882ba80 | ||
|
|
7981e85eb3 | ||
|
|
1d7e1a535b | ||
|
|
4610e33cb2 | ||
|
|
9cda676546 | ||
|
|
f5ff11c61d | ||
|
|
86671a4ed0 | ||
|
|
5cd7a18539 | ||
|
|
4b366ceed5 | ||
|
|
eb5665733a | ||
|
|
ec8d1fce62 | ||
|
|
4afe3f334a | ||
|
|
b27934a727 | ||
|
|
e7d420aabb | ||
|
|
3f76720636 | ||
|
|
3fba1e486e | ||
|
|
59f93bf56c | ||
|
|
6ebaf82426 | ||
|
|
d96ba2d153 | ||
|
|
2adaaa8521 | ||
|
|
755cdcee27 | ||
|
|
643a49ea6c | ||
|
|
583e66e5b0 | ||
|
|
769f82b90b | ||
|
|
19ffe3f16e | ||
|
|
66196f8fd7 | ||
|
|
820cd5c090 | ||
|
|
cdfc0cf26f | ||
|
|
aab046d29b | ||
|
|
ad1b9f0851 | ||
|
|
f9f17d4b0f | ||
|
|
33969b2c90 | ||
|
|
88b9522242 | ||
|
|
2907e4e4f1 | ||
|
|
84876e7e9e | ||
|
|
8f6e9e8827 | ||
|
|
9387b92371 | ||
|
|
a04bfe9cbf | ||
|
|
f7c77084b4 | ||
|
|
60437a80ca | ||
|
|
891c9b5cc7 | ||
|
|
1aa5954b42 | ||
|
|
46a1fec4a5 | ||
|
|
ca73f85acf | ||
|
|
da78e2df64 | ||
|
|
bcee3d43ca | ||
|
|
afe762e4e6 | ||
|
|
5b45da2a71 | ||
|
|
bb789f462c | ||
|
|
a14d08e891 | ||
|
|
81ca3a8b6c | ||
|
|
fd9df74e75 | ||
|
|
c502988b26 | ||
|
|
1d1094a69e | ||
|
|
8ddb66cff4 | ||
|
|
3763a4f24e | ||
|
|
c3754d6f21 | ||
|
|
a2e52e58b1 | ||
|
|
85bf8c2e1c | ||
|
|
f97e625d3d | ||
|
|
9584732376 | ||
|
|
0a73924f60 | ||
|
|
d1a5552fbe | ||
|
|
e1c9600ae7 | ||
|
|
88daaaf385 | ||
|
|
5c08b11b30 | ||
|
|
22e09d7c8e | ||
|
|
0dfe7fe96e | ||
|
|
4657b1e9ec | ||
|
|
4fb3e0f061 | ||
|
|
a528bd5d9f | ||
|
|
4662661e71 | ||
|
|
4d00132265 | ||
|
|
0be7c19204 | ||
|
|
ae3864618a | ||
|
|
1bca766a5d | ||
|
|
a660862d4c | ||
|
|
871da9a196 | ||
|
|
e4326d5926 | ||
|
|
ec651d2263 | ||
|
|
0895e4a7c4 | ||
|
|
ee79446888 | ||
|
|
d0da35f3d2 | ||
|
|
b8a56f0503 | ||
|
|
f001fccf74 | ||
|
|
9451f098d6 | ||
|
|
a42221d051 | ||
|
|
f76df4e179 | ||
|
|
937f55f61f | ||
|
|
7f9311c20e | ||
|
|
37a6bc3abf | ||
|
|
e364481ca4 | ||
|
|
4b54af76ea | ||
|
|
e8db76575a | ||
|
|
9918713e5b | ||
|
|
4c9e84124c | ||
|
|
0753cff4a1 | ||
|
|
3bfa2eb8bb | ||
|
|
c253f9ba51 | ||
|
|
1fffbc7472 | ||
|
|
a693d752bc | ||
|
|
a547f02ddf | ||
|
|
c9c8ba714c | ||
|
|
be7c86dfd2 | ||
|
|
68681fe067 | ||
|
|
6a3f88500f | ||
|
|
b03da97486 | ||
|
|
0dc531502b | ||
|
|
635b1b5b6e | ||
|
|
2c74d574d3 | ||
|
|
7cdc7a0bd9 | ||
|
|
e8be969ec8 | ||
|
|
56c8261d7e | ||
|
|
fe6756d42e | ||
|
|
c093a8e789 | ||
|
|
7ce06ceca7 | ||
|
|
8a7a1fda12 | ||
|
|
eec5824b1a | ||
|
|
b3fc4e375f | ||
|
|
5a69bc6e5f | ||
|
|
e8bfedbcd4 | ||
|
|
627abb8251 | ||
|
|
4198f93479 | ||
|
|
26abb25bd0 | ||
|
|
d931bb8005 | ||
|
|
e5be6fdf8a | ||
|
|
143415e6b8 | ||
|
|
99ce9e9832 | ||
|
|
466ecc5db8 | ||
|
|
274e5f86b5 | ||
|
|
31faa61270 | ||
|
|
7108d098ae | ||
|
|
63c91c859f | ||
|
|
01eb16e339 | ||
|
|
821c7fe59e | ||
|
|
344458e890 | ||
|
|
b0aa499bb2 | ||
|
|
6ebd309cb8 | ||
|
|
151f4af0da | ||
|
|
a5da850f3f | ||
|
|
21657d3c67 | ||
|
|
04c2f73f6f | ||
|
|
f45ff2cfaf | ||
|
|
6cd5abb0c4 | ||
|
|
70b90a6f9d | ||
|
|
6d94a2954d | ||
|
|
843193374f | ||
|
|
732fb15b45 | ||
|
|
00c3a48bd7 | ||
|
|
1fa0e4dfd6 | ||
|
|
7008c3aa9d | ||
|
|
14755ac891 | ||
|
|
9c5392e4af | ||
|
|
fd3bfce0cc | ||
|
|
a3edacb315 | ||
|
|
062c5a1fd0 | ||
|
|
1b51c7e73b | ||
|
|
af8e117d0d | ||
|
|
a87015327e | ||
|
|
775493dedd | ||
|
|
27f19ab42b | ||
|
|
586c892910 | ||
|
|
f9834f6bee | ||
|
|
5e1b1dabb2 | ||
|
|
93b95d2b78 | ||
|
|
73daf89227 | ||
|
|
9f888b86b8 | ||
|
|
364c21f831 | ||
|
|
d71f5443c9 | ||
|
|
1beb8c40f3 | ||
|
|
09dec6f72f | ||
|
|
42357adff5 | ||
|
|
ebaf614a13 | ||
|
|
80fab638f1 | ||
|
|
5ddea12690 | ||
|
|
107da866a6 | ||
|
|
88650610c1 | ||
|
|
c70ee3bf4a | ||
|
|
429a8df30a | ||
|
|
f371bb0b80 | ||
|
|
4b72e436e6 | ||
|
|
6ac40b721e | ||
|
|
16c1678f6d | ||
|
|
b94687cecb | ||
|
|
4976b0c0c2 | ||
|
|
cb715fe584 | ||
|
|
858157b65b | ||
|
|
f8b678f7c8 | ||
|
|
e71dcd4c81 | ||
|
|
ae50e4b6fc | ||
|
|
91f5d65874 | ||
|
|
e677aefec1 | ||
|
|
1423198343 | ||
|
|
0d6850348c | ||
|
|
eba8aab7f2 | ||
|
|
c2c77cdc0f | ||
|
|
d307cc738a | ||
|
|
6e811f30ac | ||
|
|
40f6e92067 | ||
|
|
b53cae8492 | ||
|
|
861ff7f26c | ||
|
|
9ac5e4ef97 | ||
|
|
2b4f9ff609 | ||
|
|
7cdef7f19f | ||
|
|
e9c2895a55 | ||
|
|
30d09ddbed | ||
|
|
617dbb12c2 | ||
|
|
5d49fcbeaa | ||
|
|
788bd6716f | ||
|
|
829c226954 | ||
|
|
06b585059b | ||
|
|
0988b76df5 | ||
|
|
8467987e4b | ||
|
|
5f40ddc1a1 | ||
|
|
6812f61900 | ||
|
|
aeebbd038c | ||
|
|
875eafd489 | ||
|
|
03daea30a6 | ||
|
|
44416660ae | ||
|
|
695dd11003 | ||
|
|
e1453c467f | ||
|
|
a40b092725 | ||
|
|
b4994dc3fe | ||
|
|
4ef39a33cb | ||
|
|
b743f8afc3 | ||
|
|
f299c4e0f6 | ||
|
|
79c16924de | ||
|
|
a3d2e589ed | ||
|
|
15d9f70d1a | ||
|
|
d131ddcf1f | ||
|
|
05d1bec3e5 | ||
|
|
b968f43e95 | ||
|
|
5695b2f051 | ||
|
|
faed18c267 | ||
|
|
8c3911c2b4 | ||
|
|
a6f7c6d0c7 | ||
|
|
6be15c9af0 | ||
|
|
7fc638a948 | ||
|
|
3cd9e1dd23 | ||
|
|
af7e99c091 | ||
|
|
9646d48630 | ||
|
|
849868e342 | ||
|
|
197bc3fd5a | ||
|
|
392dd54529 | ||
|
|
3794d3b8ad | ||
|
|
42a6a38712 | ||
|
|
45f162ad7a | ||
|
|
9a915d886e | ||
|
|
1976546062 | ||
|
|
fedcb63136 | ||
|
|
7ccb88fbc5 | ||
|
|
0fd3803567 | ||
|
|
b284f343cb | ||
|
|
5dabd0cdec | ||
|
|
fbf807583e | ||
|
|
e6e3d524da | ||
|
|
69f39255bc | ||
|
|
b4cde80810 | ||
|
|
85bb215ab8 | ||
|
|
b38a5a7a17 | ||
|
|
4ecaaf1fa7 | ||
|
|
428920f8fc | ||
|
|
4e2a9fa5f2 | ||
|
|
1a41e74d32 | ||
|
|
66444bdafb | ||
|
|
b554fee401 | ||
|
|
293530a4c8 | ||
|
|
8b285f6be9 | ||
|
|
851162a0da | ||
|
|
41fc246374 | ||
|
|
cfaf788606 | ||
|
|
98b530a36d | ||
|
|
9485d96553 | ||
|
|
f30ca710d9 | ||
|
|
4ad4a00de4 | ||
|
|
81f671740e | ||
|
|
d6b36e21cb | ||
|
|
47d3dc6fc3 | ||
|
|
d4ba41692f | ||
|
|
a872332ad9 | ||
|
|
e8bb8dff6a | ||
|
|
e0c2f72ee5 | ||
|
|
60d3ac3f15 | ||
|
|
e50ceb339f | ||
|
|
6a8f231a9c | ||
|
|
029da0400b | ||
|
|
3de797b535 | ||
|
|
14842c9a59 | ||
|
|
652d4c6cd6 | ||
|
|
59097c0922 | ||
|
|
dcb4b37240 | ||
|
|
410e779e8d | ||
|
|
d7cd6fb738 | ||
|
|
ca39edc494 | ||
|
|
2ea2c7bf78 | ||
|
|
b772193f4b | ||
|
|
c84154eb28 | ||
|
|
72bb9e6307 | ||
|
|
7c141b258d | ||
|
|
2999aefb84 | ||
|
|
a9f1783e20 | ||
|
|
6bb619d33c | ||
|
|
0477175963 | ||
|
|
eaa5cc3f91 | ||
|
|
735c6a9adc | ||
|
|
6d59e126b5 | ||
|
|
bb705c7c3e | ||
|
|
398dbbb832 | ||
|
|
90a33c19fe | ||
|
|
3205d087e2 | ||
|
|
a09358fc2c | ||
|
|
c5811b6a26 | ||
|
|
73d8d0a43f | ||
|
|
7323b7d9f2 | ||
|
|
8d6c6946dd | ||
|
|
029fcaa913 | ||
|
|
bebb9b3286 | ||
|
|
3ae9a27c25 | ||
|
|
0050411112 | ||
|
|
5bfdd91cdf | ||
|
|
88442ad885 | ||
|
|
f46511eb69 | ||
|
|
cfa6527373 | ||
|
|
0e168c7d03 | ||
|
|
9c5d0aa7a6 | ||
|
|
5b66c03ac0 | ||
|
|
5dd4159e77 | ||
|
|
b3d3591aed | ||
|
|
fb5c9e690f | ||
|
|
e737fe145f | ||
|
|
abdf594b85 | ||
|
|
33c44e1d1b | ||
|
|
ec27c85596 | ||
|
|
36a504f605 | ||
|
|
c95989d148 | ||
|
|
06f4d47a29 | ||
|
|
7f58bbba88 | ||
|
|
651ccf648d | ||
|
|
2a242b8989 | ||
|
|
f445de3b86 | ||
|
|
12042b2fa2 | ||
|
|
06084cb7e8 | ||
|
|
96dd28efa2 | ||
|
|
3b0ea78aef | ||
|
|
be4a8a192a | ||
|
|
fec974e60e | ||
|
|
5150ebf157 | ||
|
|
9a102f76c8 | ||
|
|
1d6dc36be9 | ||
|
|
9f715b2bdb | ||
|
|
103e83b65e | ||
|
|
f55a29ab93 | ||
|
|
97f9755aeb | ||
|
|
f2fc6e9054 | ||
|
|
04b546bdb9 | ||
|
|
f214bd45dc | ||
|
|
f021d0ca05 | ||
|
|
c65e1fe89f | ||
|
|
7f2c21525b | ||
|
|
5fce52076e | ||
|
|
42c03d3135 | ||
|
|
fdfd720ec4 | ||
|
|
53c46c67ac | ||
|
|
13e79f4f72 | ||
|
|
67af2936fa | ||
|
|
5d9de33889 | ||
|
|
5356de1df7 | ||
|
|
c85cac33ab | ||
|
|
b4a1e5cb83 | ||
|
|
c35f55124b | ||
|
|
005bf81461 | ||
|
|
6b558ed117 | ||
|
|
b81d2117e2 | ||
|
|
34406025e5 | ||
|
|
75d902ef01 | ||
|
|
da098ddd8a | ||
|
|
cb4c5aaf0a | ||
|
|
8761507929 | ||
|
|
ba2a317029 | ||
|
|
c47ec4af2a | ||
|
|
1f875effab | ||
|
|
4c722a96ba | ||
|
|
c67fdb5c94 | ||
|
|
398d617cc9 | ||
|
|
0683ef74d1 | ||
|
|
4f89d5bcfa | ||
|
|
9bfdace83a | ||
|
|
fad3ef71a4 | ||
|
|
c21a3a4ec6 | ||
|
|
05bcdf4d41 | ||
|
|
cda4ac2e91 | ||
|
|
8de255ea61 | ||
|
|
4b579f1836 | ||
|
|
8edc08d48e | ||
|
|
3b99cd3ae3 | ||
|
|
0ccaadc62c | ||
|
|
aebff608dc | ||
|
|
0e1e2d8069 | ||
|
|
7cced49416 | ||
|
|
70fe5e3261 | ||
|
|
b808409fe7 | ||
|
|
17a29b6eea | ||
|
|
8d447abdbf | ||
|
|
1423156a9c | ||
|
|
40f3df0acd | ||
|
|
4e253268e1 | ||
|
|
21229f21b4 | ||
|
|
995c18ba28 | ||
|
|
c6411b91f5 | ||
|
|
346a1b2351 | ||
|
|
32340b45e7 | ||
|
|
7a5462a0b7 | ||
|
|
ca83b5d174 | ||
|
|
7a1813fe39 | ||
|
|
e877a26079 | ||
|
|
a175b4affb | ||
|
|
159929688d | ||
|
|
5b4430b4d2 | ||
|
|
67e2c217d6 | ||
|
|
c2f3b72b93 | ||
|
|
2654c2012b | ||
|
|
21b82f43b9 | ||
|
|
1fd77b2ddf | ||
|
|
2ef20008e8 | ||
|
|
c0119ac534 | ||
|
|
1cd8c36e4d | ||
|
|
2e9d555f8c | ||
|
|
f6b8bdc529 | ||
|
|
0c9fb4050b | ||
|
|
2ba9e70e52 | ||
|
|
51244615e9 | ||
|
|
c0c7ee9ab1 | ||
|
|
4c8adc4821 | ||
|
|
9f7d860db2 | ||
|
|
4cc84a6164 | ||
|
|
b902a4439e | ||
|
|
aa3d6d01e8 | ||
|
|
154bd660bb | ||
|
|
adeff820d3 | ||
|
|
3bdb536a55 | ||
|
|
5868a8d57c | ||
|
|
550968ec92 | ||
|
|
9f167c85b0 | ||
|
|
544baf5482 | ||
|
|
6a76abbf9c | ||
|
|
131aa77dd9 | ||
|
|
3e9cafcf42 | ||
|
|
ee2f172106 | ||
|
|
f9fea3cd18 | ||
|
|
ed41665d78 | ||
|
|
d8843f4b6e | ||
|
|
f45f10b17d | ||
|
|
ff18f4c072 | ||
|
|
4157d2bf7f | ||
|
|
977995573d | ||
|
|
3593b80a51 | ||
|
|
d3a7a3d262 | ||
|
|
d3d49453a4 | ||
|
|
ec7c19de56 | ||
|
|
a41f5ad96e | ||
|
|
eb57e662fc | ||
|
|
c0723b4189 | ||
|
|
e8670c071b | ||
|
|
09b0c4ab6e | ||
|
|
deef174caa | ||
|
|
35adb7c5be | ||
|
|
f827615b89 | ||
|
|
09d7d195be | ||
|
|
4b8534f940 | ||
|
|
7354f66153 | ||
|
|
9c9b761562 | ||
|
|
d72ab4ffe7 | ||
|
|
d734172c73 | ||
|
|
5a31cea3d4 | ||
|
|
0eb406c7e6 | ||
|
|
94d327a68a | ||
|
|
33a89ddba5 | ||
|
|
83577ddb4d | ||
|
|
c9b696a6bd | ||
|
|
b2e7f0596a | ||
|
|
3994e55f58 | ||
|
|
7079da8b5a | ||
|
|
d9a92fd81c | ||
|
|
f1ce35a10c | ||
|
|
c543c4b10c | ||
|
|
ff6263f4f9 | ||
|
|
f17c045d21 | ||
|
|
b055972c6b | ||
|
|
bc60940ea9 | ||
|
|
11020daf89 | ||
|
|
e9bbe5be67 | ||
|
|
fe1ad4509c | ||
|
|
ea89a760d8 | ||
|
|
ec90359f34 | ||
|
|
c8131583ac | ||
|
|
10c7a38d84 | ||
|
|
7413391dae | ||
|
|
eed9880cdd | ||
|
|
dccf44af32 | ||
|
|
3c28751b48 | ||
|
|
31d95cf0ca | ||
|
|
8a693e3070 | ||
|
|
5cfcf6dc93 | ||
|
|
0a0800fe25 | ||
|
|
e13a0b7f49 | ||
|
|
d67dbfcf80 | ||
|
|
552cc77dcf | ||
|
|
08b0b0fe95 | ||
|
|
7d3aa65903 | ||
|
|
649d081fee | ||
|
|
4bac19f0bf | ||
|
|
c09c590616 | ||
|
|
451fa3013e | ||
|
|
1ba691350b | ||
|
|
4e2b49d717 | ||
|
|
c312500094 | ||
|
|
b659452519 | ||
|
|
67c493ed67 | ||
|
|
bfb7a14ab7 | ||
|
|
cbee99cebe | ||
|
|
3d74506f21 | ||
|
|
d26f6b1796 | ||
|
|
553cabb1d1 | ||
|
|
fed388a533 | ||
|
|
fd16a39c69 | ||
|
|
43545372ed | ||
|
|
00aa944946 | ||
|
|
f0ea13bbe9 | ||
|
|
2ab8e21d5d | ||
|
|
fe106be46b | ||
|
|
73b9e4b762 | ||
|
|
920c0db5c0 | ||
|
|
e1b35181ba | ||
|
|
b4baf84d32 | ||
|
|
1401f3e3f9 | ||
|
|
ec13d92b20 | ||
|
|
00dceaff2e | ||
|
|
556b9f622f | ||
|
|
b58bc13bee | ||
|
|
4e0d869f9a | ||
|
|
83e202ca50 | ||
|
|
d7e6b36faa | ||
|
|
b8b4c48285 | ||
|
|
6c0ec66614 | ||
|
|
af52175661 | ||
|
|
de8c62d0f0 | ||
|
|
52b4bf84e7 | ||
|
|
fe4becacb4 | ||
|
|
e1a2cd7e46 | ||
|
|
94172d0764 | ||
|
|
6d3aa2169e | ||
|
|
4fb9a0a740 | ||
|
|
326b01a327 | ||
|
|
da13561d3d | ||
|
|
8a5d6318e7 | ||
|
|
109d16cbce | ||
|
|
cb6cf9485c | ||
|
|
257b028a06 | ||
|
|
86ba2b2bdf | ||
|
|
e50688802c | ||
|
|
1763c83a50 | ||
|
|
e1640b71fa | ||
|
|
b946e9ee2e | ||
|
|
a8778c2665 | ||
|
|
32bd426778 | ||
|
|
a272d8b0c6 | ||
|
|
15ddd652be | ||
|
|
2c4f4e60d8 | ||
|
|
2399435ba4 | ||
|
|
2ac5b86618 | ||
|
|
aa60b32c1c | ||
|
|
be7d4a230e | ||
|
|
a1d3a7aee6 | ||
|
|
f1f85daaed | ||
|
|
88494fb8f3 | ||
|
|
2e3cc9b7b9 | ||
|
|
7b5a41383b | ||
|
|
6cab708162 | ||
|
|
340d9cec31 | ||
|
|
eebb80a187 | ||
|
|
fc0bbac463 | ||
|
|
754e4abb56 | ||
|
|
7314448bef | ||
|
|
dd46047168 | ||
|
|
35b631eb04 | ||
|
|
545ac40616 | ||
|
|
d2205a42a1 | ||
|
|
e577b09b46 | ||
|
|
53cd09b3bc | ||
|
|
792d894bd9 | ||
|
|
363b712c93 | ||
|
|
763968d428 | ||
|
|
f980ff966d | ||
|
|
926b8285be | ||
|
|
59c6679733 | ||
|
|
414e5b1d06 | ||
|
|
c1920a67e2 | ||
|
|
5c92a5735d | ||
|
|
4eb8e70031 | ||
|
|
a32610143c | ||
|
|
844a6c1a11 | ||
|
|
9e01db73f9 | ||
|
|
8dedd7864d | ||
|
|
11023e1493 | ||
|
|
1cf80189ac | ||
|
|
1525e2cb30 | ||
|
|
6b1785ed05 | ||
|
|
d62acd19e9 | ||
|
|
7a3fb2d7ad | ||
|
|
3a3b00cc54 | ||
|
|
0d3ba947f3 | ||
|
|
2bdde50d3f | ||
|
|
a3ad002027 | ||
|
|
33fec67464 | ||
|
|
cb9d9f0f71 | ||
|
|
e3360a98c2 | ||
|
|
f277d830bb | ||
|
|
cf1d805fec | ||
|
|
b98b0e107f | ||
|
|
a0f30b3f2c | ||
|
|
8b21a5c229 | ||
|
|
2d981879d6 | ||
|
|
6874eb8797 | ||
|
|
323e95c8b3 | ||
|
|
af6e86c537 | ||
|
|
1f53ad0803 | ||
|
|
31c8ce9ef8 | ||
|
|
a99f319d12 | ||
|
|
758d3a260d | ||
|
|
556cdce5c8 | ||
|
|
3118577120 | ||
|
|
bd3061bed9 | ||
|
|
92434b0b67 | ||
|
|
2812688dfc | ||
|
|
23441bf2ab | ||
|
|
d90d17e378 | ||
|
|
f770080426 | ||
|
|
07474b189d | ||
|
|
4fe59aa3b9 | ||
|
|
085c609f77 | ||
|
|
36f920112b | ||
|
|
256a906698 | ||
|
|
7c68f857d0 | ||
|
|
e628e7bb9e | ||
|
|
33955663ad | ||
|
|
e614cf3cbb | ||
|
|
f1e3280296 | ||
|
|
85274fb910 | ||
|
|
b26bc02086 | ||
|
|
85842e28eb | ||
|
|
baaac7ac25 | ||
|
|
7960ad7d8b | ||
|
|
abbc6f5242 | ||
|
|
9bc0437bab | ||
|
|
196ad04add | ||
|
|
de330273f1 | ||
|
|
2c2e515911 | ||
|
|
23ae451acb | ||
|
|
88049ac444 | ||
|
|
8bf5a6ed18 | ||
|
|
8bcd22c510 | ||
|
|
eaf35aca32 | ||
|
|
91bfcc7c16 | ||
|
|
945f1c9781 | ||
|
|
239d98e18d | ||
|
|
3e13a5f6dc | ||
|
|
bd25077b16 | ||
|
|
f2b1a05bff | ||
|
|
cbd7649260 | ||
|
|
77e63b2236 | ||
|
|
dde7c39a92 | ||
|
|
d7fbc5eaba | ||
|
|
31b899e2e1 | ||
|
|
01b914a12e | ||
|
|
695581bf65 | ||
|
|
4923c48619 | ||
|
|
c6f59f7abe | ||
|
|
e4aba2047a | ||
|
|
fd69d39c66 | ||
|
|
026dac4594 | ||
|
|
86af3d8f1b | ||
|
|
1731098e4d | ||
|
|
380435c33b | ||
|
|
9935449e9d | ||
|
|
4caa3d07cf | ||
|
|
589f6b1c17 | ||
|
|
a751e87562 | ||
|
|
75a474834b | ||
|
|
525ecdfbe1 | ||
|
|
7b3845a4a5 | ||
|
|
200b442ee4 | ||
|
|
ad82404564 | ||
|
|
d5dc4b055f | ||
|
|
c6756ec787 | ||
|
|
f1adf86d09 | ||
|
|
63e9766256 | ||
|
|
35b0248480 | ||
|
|
5629153f1e | ||
|
|
2b16e3652c | ||
|
|
ac736f7cdc | ||
|
|
370edcd71f | ||
|
|
a63a148116 | ||
|
|
cd7ed8b383 | ||
|
|
1fc09c536b | ||
|
|
07cd9a8d15 | ||
|
|
4f90578a4f | ||
|
|
5bed1ce3db | ||
|
|
82a7098474 | ||
|
|
2c921595f2 | ||
|
|
8067b6fb73 | ||
|
|
9a30fc037e | ||
|
|
39f2fdda08 | ||
|
|
3ffdef958d | ||
|
|
0f5e2eba7c | ||
|
|
704a7eba4a | ||
|
|
2db44d14e4 | ||
|
|
5fbc4e2384 | ||
|
|
d7daf7444e | ||
|
|
797585985f | ||
|
|
9883bf7280 | ||
|
|
7061c33d7b | ||
|
|
0311e952db | ||
|
|
f4c0b38042 | ||
|
|
22110bde07 | ||
|
|
a8e2420def | ||
|
|
4ebaf0fd9c | ||
|
|
80d70870f5 | ||
|
|
3ea7d72957 | ||
|
|
22ba8f3323 | ||
|
|
700f99c873 | ||
|
|
76b0654112 | ||
|
|
bef401e8dc | ||
|
|
8c26c6bbba | ||
|
|
c75156c7c8 | ||
|
|
4bce07bc25 | ||
|
|
39fd5971dd | ||
|
|
a1b9bc9a42 | ||
|
|
2d0c47b8aa | ||
|
|
56deeee42b | ||
|
|
693e5c427a | ||
|
|
c7ebcc8326 | ||
|
|
01e9d7611a | ||
|
|
5f5fe4ae6d | ||
|
|
ce4dbc8513 | ||
|
|
f5da03589e | ||
|
|
d7c526e66d | ||
|
|
cfe240bbd8 | ||
|
|
3bc2827212 | ||
|
|
6d920eca0c | ||
|
|
cd908e158d | ||
|
|
b869639f46 | ||
|
|
d1df8c198d | ||
|
|
df1e389479 | ||
|
|
193e68abd4 | ||
|
|
0f8257073a | ||
|
|
e9220f5117 | ||
|
|
c24cb37374 | ||
|
|
4a18680233 | ||
|
|
723d3d528d | ||
|
|
712ac6d5a0 | ||
|
|
47ff7adaa2 | ||
|
|
ce559ec2e5 | ||
|
|
53c1f3e4c6 | ||
|
|
64b0b993f6 | ||
|
|
214c19a8b3 | ||
|
|
1958250cc6 | ||
|
|
fa7a1e19e2 | ||
|
|
6e1a4cca68 | ||
|
|
c2b140693b | ||
|
|
6a06c02f21 | ||
|
|
20905f2c93 | ||
|
|
7691d2fba0 | ||
|
|
ff6b97e13e | ||
|
|
44c053f008 | ||
|
|
9cfcec5b05 | ||
|
|
d463bda066 | ||
|
|
87fa23e641 | ||
|
|
f12b53b2ce | ||
|
|
87372cd3ae | ||
|
|
4ab2d8f53a | ||
|
|
ae89477b9b | ||
|
|
95f7eb6267 | ||
|
|
d9d6720b77 | ||
|
|
f2080b7714 | ||
|
|
19cd821ddb | ||
|
|
061697058c | ||
|
|
712109716a | ||
|
|
3b5543d431 | ||
|
|
5bf316d15e | ||
|
|
3134fad324 | ||
|
|
ae0074289c | ||
|
|
219bbb0758 | ||
|
|
27049d3bfc | ||
|
|
429043125e | ||
|
|
410da16d02 | ||
|
|
08701d38a4 | ||
|
|
75dd041027 | ||
|
|
adcd9b9c14 | ||
|
|
2a33928da6 | ||
|
|
eb3d538fdd | ||
|
|
e500c52f49 | ||
|
|
6587c39b3a | ||
|
|
d1c5cbfcdd | ||
|
|
5ca6750d57 | ||
|
|
9a96f7c461 | ||
|
|
f7999d7584 | ||
|
|
236ab993af | ||
|
|
93dcd18946 | ||
|
|
a4bfda47ac | ||
|
|
d7fcb354de | ||
|
|
cd3f5c47d5 | ||
|
|
2ff4fc1672 | ||
|
|
19272693f5 | ||
|
|
8993498904 | ||
|
|
cff8d231ff | ||
|
|
adcff142d8 | ||
|
|
29c0442cad | ||
|
|
0c6e5c710b | ||
|
|
67c4edfeb2 | ||
|
|
5e292210c9 | ||
|
|
ffcc3ee57c | ||
|
|
9b8fe62dc8 | ||
|
|
e5a97dc971 | ||
|
|
b93c15a217 | ||
|
|
5c0034bed5 | ||
|
|
7f7cd1d678 | ||
|
|
fb81d346de | ||
|
|
d059fe157a | ||
|
|
cb06e8f515 | ||
|
|
4cc0ccbeba | ||
|
|
43a62704e9 | ||
|
|
5b21dc1ece | ||
|
|
7ff4e5a700 | ||
|
|
0df7488562 | ||
|
|
7db02117a9 | ||
|
|
dc903be45e | ||
|
|
223b1d7604 | ||
|
|
9cf66fe2b1 | ||
|
|
febc4c49c1 | ||
|
|
0ab48a40d7 | ||
|
|
0f1b91f942 | ||
|
|
cf4b6ee8fe | ||
|
|
a92a94f719 | ||
|
|
dc932e0a18 | ||
|
|
2469b27db0 | ||
|
|
5a09fe4494 | ||
|
|
7597dbd0da | ||
|
|
6b9e1727c8 | ||
|
|
32821bb3f4 | ||
|
|
4d78dd47ab | ||
|
|
ee871dbed8 | ||
|
|
0a6061f1f9 | ||
|
|
326ea43a59 | ||
|
|
5c9a84b610 | ||
|
|
def996ca60 | ||
|
|
0f4b670f25 | ||
|
|
d24f7571cc | ||
|
|
0f8d90bd48 | ||
|
|
b681a22c29 | ||
|
|
e2780ba79b | ||
|
|
a3dc0b45fc | ||
|
|
6cc9334011 | ||
|
|
a7c3b38bb6 | ||
|
|
f1f04bac77 | ||
|
|
c3798f9e61 | ||
|
|
6a08b3a1e5 | ||
|
|
56b1029ccf | ||
|
|
86a2a3f5f6 | ||
|
|
80f8bd8e8c | ||
|
|
eb652720df | ||
|
|
7b90e466f9 | ||
|
|
16e01be2da | ||
|
|
4e66f13a79 | ||
|
|
d446f94a60 | ||
|
|
7735ccac5e | ||
|
|
a34d7ff0ac | ||
|
|
c1c67d3295 | ||
|
|
fbc2f821ff | ||
|
|
d4f175199f | ||
|
|
c7fdeca168 | ||
|
|
c9b0bde5e6 | ||
|
|
1a34a11854 | ||
|
|
0fb79b9ee4 | ||
|
|
89ed6c2fec | ||
|
|
82bdb546d9 | ||
|
|
38456f092f | ||
|
|
4f0f13ad00 | ||
|
|
45849c5602 | ||
|
|
b1770970a8 | ||
|
|
a299f3cc81 | ||
|
|
90a2952982 | ||
|
|
3855a21213 | ||
|
|
8a010c44a5 | ||
|
|
978afa51c0 | ||
|
|
d71cb4d9c7 | ||
|
|
d766e142ea | ||
|
|
63354f0c3f | ||
|
|
efd83f0b57 | ||
|
|
bc18a8e7f7 | ||
|
|
f7c04842b9 | ||
|
|
8ae407c539 |
250
INSTALL
250
INSTALL
@@ -1,111 +1,181 @@
|
||||
This is a generic INSTALL file for utilities distributions.
|
||||
If this package does not come with, e.g., installable documentation or
|
||||
data files, please ignore the references to them below.
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
To compile this package:
|
||||
These are generic installation instructions.
|
||||
|
||||
1. Configure the package for your system. In the directory that this
|
||||
file is in, type `./configure'. If you're using `csh' on an old
|
||||
version of System V, you might need to type `sh configure' instead to
|
||||
prevent `csh' from trying to execute `configure' itself.
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation, and
|
||||
creates the Makefile(s) (one in each subdirectory of the source
|
||||
directory). In some packages it creates a C header file containing
|
||||
system-dependent definitions. It also creates a file `config.status'
|
||||
that you can run in the future to recreate the current configuration.
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
Running `configure' takes a minute or two. While it is running, it
|
||||
prints some messages that tell what it is doing. If you don't want to
|
||||
see the messages, run `configure' with its standard output redirected
|
||||
to `/dev/null'; for example, `./configure >/dev/null'.
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
To compile the package in a different directory from the one
|
||||
containing the source code, you must use a version of make that
|
||||
supports the VPATH variable, such as GNU make. `cd' to the directory
|
||||
where you want the object files and executables to go and run
|
||||
`configure'. `configure' automatically checks for the source code in
|
||||
the directory that `configure' is in and in `..'. If for some reason
|
||||
`configure' is not in the source code directory that you are
|
||||
configuring, then it will report that it can't find the source code.
|
||||
In that case, run `configure' with the option `--srcdir=DIR', where
|
||||
DIR is the directory that contains the source code.
|
||||
The simplest way to compile this package is:
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify
|
||||
an installation prefix other than /usr/local by giving `configure' the
|
||||
option `--prefix=PATH'. Alternately, you can do so by giving a value
|
||||
for the `prefix' variable when you run `make', e.g.,
|
||||
make prefix=/usr/gnu
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If
|
||||
you give `configure' the option `--exec_prefix=PATH' or set the
|
||||
`make' variable `exec_prefix' to PATH, the package will use PATH as
|
||||
the prefix for installing programs and libraries. Data files and
|
||||
documentation will still use the regular prefix. Normally, all files
|
||||
are installed using the regular prefix.
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
You can tell `configure' to figure out the configuration for your
|
||||
system, and record it in `config.status', without actually configuring
|
||||
the package (creating `Makefile's and perhaps a configuration header
|
||||
file). To do this, give `configure' the `--no-create' option. Later,
|
||||
you can run `./config.status' to actually configure the package. This
|
||||
option is useful mainly in `Makefile' rules for updating `config.status'
|
||||
and `Makefile'. You can also give `config.status' the `--recheck'
|
||||
option, which makes it re-run `configure' with the same arguments you
|
||||
used before. This is useful if you change `configure'.
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
`configure' ignores any other arguments that you give it.
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
If your system requires unusual options for compilation or linking
|
||||
that `configure' doesn't know about, you can give `configure' initial
|
||||
values for some variables by setting them in the environment. In
|
||||
Bourne-compatible shells, you can do that on the command line like
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
The `make' variables that you might want to override with environment
|
||||
variables when running `configure' are:
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
(For these variables, any value given in the environment overrides the
|
||||
value that `configure' would choose:)
|
||||
CC C compiler program.
|
||||
Default is `cc', or `gcc' if `gcc' is in your PATH.
|
||||
INSTALL Program to use to install files.
|
||||
Default is `install' if you have it, `cp' otherwise.
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
(For these variables, any value given in the environment is added to
|
||||
the value that `configure' chooses:)
|
||||
DEFS Configuration options, in the form `-Dfoo -Dbar ...'
|
||||
LIBS Libraries to link with, in the form `-lfoo -lbar ...'
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you need to do unusual things to compile the package, we encourage
|
||||
you to figure out how `configure' could check whether to do them, and
|
||||
mail diffs or instructions to the address given in the README so we
|
||||
can include them in the next release.
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
2. Type `make' to compile the package. If you want, you can override
|
||||
the `make' variables CFLAGS and LDFLAGS like this:
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
make CFLAGS=-O2 LDFLAGS=-s
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
3. If the package comes with self-tests and you want to run them,
|
||||
type `make check'. If you're not sure whether there are any, try it;
|
||||
if `make' responds with something like
|
||||
make: *** No way to make target `check'. Stop.
|
||||
then the package does not come with self-tests.
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
4. Type `make install' to install programs, data files, and
|
||||
documentation.
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source directory by typing `make clean'. To also remove the
|
||||
Makefile(s), the header file containing system-dependent definitions
|
||||
(if the package uses one), and `config.status' (all the files that
|
||||
`configure' created), type `make distclean'.
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made.
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
||||
The file `configure.in' is used as a template to create `configure' by
|
||||
a program called `autoconf'. You will only need it if you want to
|
||||
regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
20
doc/.cvsignore
Normal file
20
doc/.cvsignore
Normal file
@@ -0,0 +1,20 @@
|
||||
Makefile
|
||||
fileutils.info
|
||||
version.texi
|
||||
fileutils.info*
|
||||
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
|
||||
stamp-vti
|
||||
version.texi
|
||||
2
doc/Makefile.am
Normal file
2
doc/Makefile.am
Normal file
@@ -0,0 +1,2 @@
|
||||
info_TEXINFOS = fileutils.texi
|
||||
DIST_OTHER = perm.texi getdate.texi
|
||||
203
doc/Makefile.in
Normal file
203
doc/Makefile.in
Normal file
@@ -0,0 +1,203 @@
|
||||
# Makefile.in generated automatically by automake 0.30 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy, distribute and modify it.
|
||||
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
info_TEXINFOS = fileutils.texi
|
||||
DIST_OTHER = perm.texi getdate.texi
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
||||
MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
INFOS = fileutils.info*
|
||||
INFO_DEPS = fileutils.info
|
||||
DVIS = fileutils.dvi
|
||||
TEXINFOS = fileutils.texi
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in mdate-sh stamp-vti texinfo.tex \
|
||||
version.texi
|
||||
|
||||
|
||||
PACKAGE = @PACKAGE@
|
||||
VERSION = @VERSION@
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
||||
$(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER) $(DATA)
|
||||
DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
||||
$(TEXINFOS) $(INFO_DEPS) $(MANS) $(DIST_OTHER) $(DATA)
|
||||
default: all
|
||||
|
||||
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
|
||||
cd $(top_srcdir) && automake $(subdir)/Makefile
|
||||
|
||||
Makefile: $(top_builddir)/config.status Makefile.in
|
||||
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
|
||||
|
||||
version.texi: stamp-vti
|
||||
|
||||
stamp-vti: fileutils.texi $(top_srcdir)/configure.in
|
||||
echo "@set UPDATED `cd $(srcdir) && $(SHELL) mdate-sh fileutils.texi`" \
|
||||
> vti.tmp
|
||||
echo "@set EDITION $(VERSION)" >> vti.tmp
|
||||
echo "@set VERSION $(VERSION)" >> vti.tmp
|
||||
if cmp -s vti.tmp $(srcdir)/version.texi; then \
|
||||
rm vti.tmp; \
|
||||
else \
|
||||
mv vti.tmp $(srcdir)/version.texi; \
|
||||
fi
|
||||
echo timestamp > $(srcdir)/stamp-vti
|
||||
|
||||
mostlyclean-vti:
|
||||
rm -f vti.tmp
|
||||
|
||||
clean-vti:
|
||||
|
||||
distclean-vti:
|
||||
|
||||
maintainer-clean-vti:
|
||||
rm -f stamp-vti version.texi
|
||||
|
||||
fileutils.info: fileutils.texi version.texi
|
||||
|
||||
|
||||
.texi.info:
|
||||
$(MAKEINFO) -I$(srcdir) $<
|
||||
|
||||
.texi.dvi:
|
||||
TEXINPUTS=$(srcdir):$$TEXINPUTS $(TEXI2DVI) $<
|
||||
|
||||
install-info: $(INFO_DEPS)
|
||||
$(top_srcdir)/mkinstalldirs $(infodir)
|
||||
for file in $(INFO_DEPS); do \
|
||||
for ifile in `cd $(srcdir) && echo $$file*`; do \
|
||||
$(INSTALL_DATA) $(srcdir)/$$ifile $(infodir)/$$ifile; \
|
||||
done; \
|
||||
done
|
||||
|
||||
uninstall-info:
|
||||
cd $(srcdir) && for file in *.info*; do \
|
||||
rm -f $(infodir)/$$file; \
|
||||
done
|
||||
|
||||
mostlyclean-info:
|
||||
rm -f fileutils.aux fileutils.cp fileutils.cps fileutils.dvi \
|
||||
fileutils.fn fileutils.fns fileutils.ky fileutils.log \
|
||||
fileutils.pg fileutils.toc fileutils.tp fileutils.vr \
|
||||
fileutils.op
|
||||
|
||||
clean-info:
|
||||
|
||||
distclean-info:
|
||||
|
||||
maintainer-clean-info:
|
||||
rm -f $(INFOS)
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
|
||||
subdir = doc
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
dist: $(DEP_DISTFILES)
|
||||
@for file in `cd $(srcdir) && echo $(DISTFILES)`; do \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $(srcdir)/$$file $(distdir)/$$file; \
|
||||
done
|
||||
info: $(INFO_DEPS)
|
||||
|
||||
dvi: $(DVIS)
|
||||
|
||||
check: all
|
||||
|
||||
installcheck:
|
||||
|
||||
install-exec:
|
||||
|
||||
install-data: install-info
|
||||
|
||||
install: install-exec install-data
|
||||
@:
|
||||
|
||||
uninstall: uninstall-info
|
||||
|
||||
all: $(INFO_DEPS) Makefile
|
||||
|
||||
installdirs:
|
||||
$(top_srcdir)/mkinstalldirs $(infodir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
rm -f Makefile $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log $(CONFIG_HEADER) stamp-h
|
||||
|
||||
maintainer-clean-generic:
|
||||
test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-vti mostlyclean-info mostlyclean-generic
|
||||
|
||||
clean: clean-vti clean-info clean-generic mostlyclean
|
||||
|
||||
distclean: distclean-vti distclean-info distclean-generic clean
|
||||
rm -f config.status
|
||||
|
||||
maintainer-clean: maintainer-clean-vti maintainer-clean-info \
|
||||
maintainer-clean-generic distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
.PHONY: default mostlyclean-vti distclean-vti clean-vti \
|
||||
maintainer-clean-vti install-info uninstall-info mostlyclean-info \
|
||||
distclean-info clean-info maintainer-clean-info tags dist info dvi \
|
||||
check installcheck install-exec install-data install uninstall all \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean \
|
||||
maintainer-clean
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .texi .info .dvi
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
483
doc/getdate.texi
Normal file
483
doc/getdate.texi
Normal 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}).
|
||||
92
doc/mdate-sh
Executable file
92
doc/mdate-sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/bin/sh
|
||||
# mdate-sh - get modification time of a file and pretty-print it
|
||||
# Copyright (C) 1995 Software Foundation, Inc.
|
||||
# Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Prevent date giving response in another language.
|
||||
LANG=C
|
||||
export LANG
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
LC_TIME=C
|
||||
export LC_TIME
|
||||
|
||||
# Get the extended ls output of the file.
|
||||
if ls -L /dev/null 1>/dev/null 2>&1; then
|
||||
set - `ls -L -l $1`
|
||||
else
|
||||
set - `ls -l $1`
|
||||
fi
|
||||
# The month is at least the fourth argument.
|
||||
# (3 shifts here, the next inside the loop)
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
|
||||
# Find the month. Next argument is day, followed by the year or time.
|
||||
month=
|
||||
until test $month
|
||||
do
|
||||
shift
|
||||
case $1 in
|
||||
Jan) month=January; nummonth=1;;
|
||||
Feb) month=February; nummonth=2;;
|
||||
Mar) month=March; nummonth=3;;
|
||||
Apr) month=April; nummonth=4;;
|
||||
May) month=May; nummonth=5;;
|
||||
Jun) month=June; nummonth=6;;
|
||||
Jul) month=July; nummonth=7;;
|
||||
Aug) month=August; nummonth=8;;
|
||||
Sep) month=September; nummonth=9;;
|
||||
Oct) month=October; nummonth=10;;
|
||||
Nov) month=November; nummonth=11;;
|
||||
Dec) month=December; nummonth=12;;
|
||||
esac
|
||||
done
|
||||
|
||||
day=$2
|
||||
|
||||
# Here we have to deal with the problem that the ls output gives either
|
||||
# the time of day or the year.
|
||||
case $3 in
|
||||
*:*) set `date`; year=$6
|
||||
case $2 in
|
||||
Jan) nummonthtod=1;;
|
||||
Feb) nummonthtod=2;;
|
||||
Mar) nummonthtod=3;;
|
||||
Apr) nummonthtod=4;;
|
||||
May) nummonthtod=5;;
|
||||
Jun) nummonthtod=6;;
|
||||
Jul) nummonthtod=7;;
|
||||
Aug) nummonthtod=8;;
|
||||
Sep) nummonthtod=9;;
|
||||
Oct) nummonthtod=10;;
|
||||
Nov) nummonthtod=11;;
|
||||
Dec) nummonthtod=12;;
|
||||
esac
|
||||
# For the first six month of the year the time notation can also
|
||||
# be used for file modified in the last year.
|
||||
if (expr $nummonth \> $nummonthtod) > /dev/null;
|
||||
then
|
||||
year=`expr $year - 1`
|
||||
fi
|
||||
;;
|
||||
*) year=$3;;
|
||||
esac
|
||||
|
||||
# The result.
|
||||
echo $day $month $year
|
||||
481
doc/perm.texi
Normal file
481
doc/perm.texi
Normal 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
2894
doc/sh-utils.texi
Normal file
File diff suppressed because it is too large
Load Diff
4431
doc/texinfo.tex
Normal file
4431
doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
3302
doc/textutils.texi
Normal file
3302
doc/textutils.texi
Normal file
File diff suppressed because it is too large
Load Diff
9
lib/.cvsignore
Normal file
9
lib/.cvsignore
Normal file
@@ -0,0 +1,9 @@
|
||||
Makefile
|
||||
getdate.c
|
||||
posixtm.c
|
||||
safe-stat.h
|
||||
safe-stat.c
|
||||
safe-lstat.c
|
||||
safe-lstat.h
|
||||
getdate.tab.c
|
||||
.deps
|
||||
40
lib/Makefile.am
Normal file
40
lib/Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
noinst_LIBRARIES = fu
|
||||
|
||||
DIST_OTHER = alloca.c euidaccess.c fnmatch.c fsusage.c ftruncate.c \
|
||||
getdate.y memcmp.c memcpy.c memset.c mkdir.c mktime.c mountlist.c \
|
||||
posixtm.y rename.c rmdir.c stpcpy.c strdup.c strstr.c strtol.c strtoul.c
|
||||
|
||||
INCLUDES = -I.. -I$(srcdir)
|
||||
|
||||
fu_SOURCES = getdate.c posixtm.c argmatch.c backupfile.c basename.c \
|
||||
dirname.c error.c fileblocks.c filemode.c \
|
||||
full-write.c getopt.c getopt1.c getversion.c group-member.c idcache.c \
|
||||
isdir.c long-options.c makepath.c modechange.c obstack.c \
|
||||
safe-read.c save-cwd.c savedir.c stripslash.c userspec.c xgetcwd.c \
|
||||
xmalloc.c xstrdup.c xstrtol.c xstrtoul.c yesno.c
|
||||
|
||||
fu_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
|
||||
noinst_HEADERS = argmatch.h backupfile.h error.h fnmatch.h fsusage.h \
|
||||
getopt.h group-member.h long-options.h makepath.h modechange.h mountlist.h \
|
||||
obstack.h pathmax.h save-cwd.h xstrtol.h xstrtoul.h
|
||||
|
||||
BUILT_SOURCES = getdate.c posixtm.c
|
||||
|
||||
# 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 10 shift/reduce conflicts
|
||||
$(YACC) $(srcdir)/getdate.y
|
||||
mv y.tab.c getdate.c
|
||||
|
||||
# Make the rename atomic, in case sed is interrupted and later rerun.
|
||||
# The artificial dependency on getdate.c keeps the two parsers from being
|
||||
# built in parallel. Enforcing this little bit of sequentiality lets
|
||||
# everyone (even those without bison) still run mostly parallel builds.
|
||||
posixtm.c: posixtm.y getdate.c
|
||||
$(YACC) $(srcdir)/posixtm.y
|
||||
mv y.tab.c posixtm.tab.c
|
||||
sed -e 's/yy/zz/g' posixtm.tab.c > tposixtm.c
|
||||
mv tposixtm.c posixtm.c
|
||||
rm -f posixtm.tab.c
|
||||
325
lib/Makefile.in
325
lib/Makefile.in
@@ -1,98 +1,289 @@
|
||||
# Makefile for library files used by GNU fileutils.
|
||||
# Do not use this makefile directly, but only from `../Makefile'.
|
||||
# Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
# Makefile.in generated automatically by automake 0.30 from Makefile.am
|
||||
|
||||
# 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.
|
||||
# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy, distribute and modify it.
|
||||
|
||||
# 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.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
SOURCES = 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 \
|
||||
stripslash.c xgetcwd.c xmalloc.c xstrdup.c userspec.c yesno.c \
|
||||
getdate.y posixtm.y \
|
||||
fileblocks.c fnmatch.c ftruncate.c mkdir.c mktime.c rename.c stpcpy.c \
|
||||
strdup.c strstr.c alloca.c
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
OBJECTS = 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 \
|
||||
stripslash.o xgetcwd.o xmalloc.o xstrdup.o userspec.o yesno.o \
|
||||
getdate.o posixtm.o @LIBOBJS@ @ALLOCA@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
DISTFILES = Makefile.in backupfile.h getopt.h modechange.h \
|
||||
fnmatch.h fsusage.h mountlist.h pathmax.h system.h $(SOURCES)
|
||||
top_builddir = ..
|
||||
|
||||
all: libfu.a
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
noinst_LIBRARIES = fu
|
||||
|
||||
DIST_OTHER = alloca.c euidaccess.c fnmatch.c fsusage.c ftruncate.c \
|
||||
getdate.y memcmp.c memcpy.c memset.c mkdir.c mktime.c mountlist.c \
|
||||
posixtm.y rename.c rmdir.c stpcpy.c strdup.c strstr.c strtol.c strtoul.c
|
||||
|
||||
INCLUDES = -I.. -I$(srcdir)
|
||||
|
||||
fu_SOURCES = getdate.c posixtm.c argmatch.c backupfile.c basename.c \
|
||||
dirname.c error.c fileblocks.c filemode.c \
|
||||
full-write.c getopt.c getopt1.c getversion.c group-member.c idcache.c \
|
||||
isdir.c long-options.c makepath.c modechange.c obstack.c \
|
||||
safe-read.c save-cwd.c savedir.c stripslash.c userspec.c xgetcwd.c \
|
||||
xmalloc.c xstrdup.c xstrtol.c xstrtoul.c yesno.c
|
||||
|
||||
fu_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
|
||||
noinst_HEADERS = argmatch.h backupfile.h error.h fnmatch.h fsusage.h \
|
||||
getopt.h group-member.h long-options.h makepath.h modechange.h mountlist.h \
|
||||
obstack.h pathmax.h save-cwd.h xstrtol.h xstrtoul.h
|
||||
|
||||
BUILT_SOURCES = getdate.c posixtm.c
|
||||
CONFIG_HEADER = ../config.h
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
|
||||
noinst_LIBFILES = libfu.a
|
||||
|
||||
CC = @CC@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir) -I..
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(CC) $(LDFLAGS) -o $@
|
||||
fu_OBJECTS = getdate.o posixtm.o argmatch.o backupfile.o basename.o \
|
||||
dirname.o error.o fileblocks.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 userspec.o xgetcwd.o xmalloc.o \
|
||||
xstrdup.o xstrtol.o xstrtoul.o yesno.o
|
||||
LIBFILES = libfu.a
|
||||
|
||||
AR = ar
|
||||
RANLIB = @RANLIB@
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in alloca.c fileblocks.c fnmatch.c \
|
||||
fsusage.c ftruncate.c mountlist.c
|
||||
|
||||
|
||||
PACKAGE = @PACKAGE@
|
||||
VERSION = @VERSION@
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
||||
$(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER) $(DATA)
|
||||
DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
|
||||
$(TEXINFOS) $(INFO_DEPS) $(MANS) $(DIST_OTHER) $(DATA)
|
||||
DEP_FILES = .deps/alloca.P .deps/argmatch.P .deps/backupfile.P \
|
||||
.deps/basename.P .deps/dirname.P .deps/error.P .deps/fileblocks.P \
|
||||
.deps/filemode.P .deps/fnmatch.P .deps/fsusage.P .deps/ftruncate.P \
|
||||
.deps/full-write.P .deps/getdate.P .deps/getopt.P .deps/getopt1.P \
|
||||
.deps/getversion.P .deps/group-member.P .deps/idcache.P \
|
||||
.deps/isdir.P .deps/long-options.P .deps/makepath.P \
|
||||
.deps/modechange.P .deps/mountlist.P .deps/obstack.P \
|
||||
.deps/posixtm.P .deps/safe-read.P .deps/save-cwd.P .deps/savedir.P \
|
||||
.deps/stripslash.P .deps/userspec.P .deps/xgetcwd.P .deps/xmalloc.P \
|
||||
.deps/xstrdup.P .deps/xstrtol.P .deps/xstrtoul.P .deps/yesno.P
|
||||
SOURCES = $(fu_SOURCES)
|
||||
OBJECTS = $(fu_OBJECTS)
|
||||
|
||||
default: all
|
||||
|
||||
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
|
||||
cd $(top_srcdir) && automake $(subdir)/Makefile
|
||||
|
||||
Makefile: $(top_builddir)/config.status Makefile.in
|
||||
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
|
||||
|
||||
mostlyclean-noinstLIBRARIES:
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
rm -f $(noinst_LIBFILES)
|
||||
|
||||
distclean-noinstLIBRARIES:
|
||||
|
||||
maintainer-clean-noinstLIBRARIES:
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) $<
|
||||
$(COMPILE) $<
|
||||
|
||||
install: all
|
||||
mostlyclean-compile:
|
||||
rm -f *.o core
|
||||
|
||||
uninstall:
|
||||
clean-compile:
|
||||
|
||||
TAGS: $(SOURCES)
|
||||
etags $(SOURCES)
|
||||
distclean-compile:
|
||||
rm -f *.tab.c
|
||||
|
||||
clean:
|
||||
rm -f *.a *.o
|
||||
maintainer-clean-compile:
|
||||
$(fu_OBJECTS): ../config.h
|
||||
|
||||
mostlyclean: clean
|
||||
libfu.a: $(fu_OBJECTS) $(fu_LIBADD)
|
||||
rm -f libfu.a
|
||||
$(AR) cru libfu.a $(fu_OBJECTS) $(fu_LIBADD)
|
||||
$(RANLIB) libfu.a
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c getdate.c *posixtm.c
|
||||
ID: $(HEADERS) $(SOURCES)
|
||||
here=`pwd` && cd $(srcdir) && mkid -f $$here/ID $(SOURCES) $(HEADERS)
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS
|
||||
tags: TAGS
|
||||
|
||||
dist:
|
||||
ln $(DISTFILES) ../`cat ../.fname`/lib
|
||||
TAGS:
|
||||
here=`pwd` && cd $(srcdir) && etags $(ETAGS_ARGS) $(SOURCES) $(HEADERS) -o $$here/TAGS
|
||||
|
||||
libfu.a: $(OBJECTS)
|
||||
rm -f $@
|
||||
$(AR) cr $@ $(OBJECTS)
|
||||
-$(RANLIB) $@
|
||||
mostlyclean-tags:
|
||||
|
||||
# Since this directory contains two parsers, using bison without -y
|
||||
# is the only way to reliably do a parallel make.
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
subdir = lib
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
dist: $(DEP_DISTFILES)
|
||||
@for file in `cd $(srcdir) && echo $(DISTFILES)`; do \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $(srcdir)/$$file $(distdir)/$$file; \
|
||||
done
|
||||
|
||||
# This fragment is probably only useful for maintainers. It relies on
|
||||
# GNU make and gcc. It is only included in the generated Makefile.in
|
||||
# if `automake' is not passed the `--include-deps' flag.
|
||||
|
||||
MKDEP = gcc -MM $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
-include .deps/.P
|
||||
.deps/.P: $(BUILT_SOURCES)
|
||||
test -d .deps || mkdir .deps
|
||||
echo > $@
|
||||
|
||||
-include $(DEP_FILES)
|
||||
$(DEP_FILES): .deps/.P
|
||||
|
||||
.deps/%.P: %.c
|
||||
@echo "mkdeps $< > $@"
|
||||
@re=`echo 's,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g' | sed 's,\.,\\\\.,g'`; \
|
||||
$(MKDEP) $< | sed "$$re" > $@-tmp
|
||||
@if test -n "$o"; then \
|
||||
sed 's/\.o:/$$o:/' $@-tmp > $@; \
|
||||
rm $@-tmp; \
|
||||
else \
|
||||
mv $@-tmp $@; \
|
||||
fi
|
||||
|
||||
# End of maintainer-only section
|
||||
info:
|
||||
|
||||
dvi:
|
||||
|
||||
check: all
|
||||
|
||||
installcheck:
|
||||
|
||||
install-exec:
|
||||
|
||||
install-data:
|
||||
|
||||
install: install-exec install-data
|
||||
@:
|
||||
|
||||
uninstall:
|
||||
|
||||
all: $(LIBFILES) $(HEADERS) Makefile
|
||||
|
||||
installdirs:
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
rm -f Makefile $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log $(CONFIG_HEADER) stamp-h
|
||||
|
||||
maintainer-clean-generic:
|
||||
test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||
mostlyclean-tags mostlyclean-generic
|
||||
|
||||
clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
|
||||
mostlyclean
|
||||
|
||||
distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \
|
||||
distclean-generic clean
|
||||
rm -f config.status
|
||||
|
||||
maintainer-clean: maintainer-clean-noinstLIBRARIES \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
.PHONY: default mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
|
||||
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
|
||||
mostlyclean-compile distclean-compile clean-compile \
|
||||
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
|
||||
clean-tags maintainer-clean-tags dist info dvi check installcheck \
|
||||
install-exec install-data install uninstall all installdirs \
|
||||
mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean \
|
||||
maintainer-clean
|
||||
|
||||
|
||||
# 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
|
||||
-bison -o getdate.c $(srcdir)/getdate.y || yacc $(srcdir)/getdate.y
|
||||
test ! -f y.tab.c || mv y.tab.c getdate.c
|
||||
@echo expect 10 shift/reduce conflicts
|
||||
$(YACC) $(srcdir)/getdate.y
|
||||
mv y.tab.c getdate.c
|
||||
|
||||
# Make the rename atomic, in case sed is interrupted and later rerun.
|
||||
posixtm.c: posixtm.y
|
||||
-bison -o posixtm.tab.c $(srcdir)/posixtm.y || yacc $(srcdir)/posixtm.y
|
||||
test ! -f y.tab.c || mv y.tab.c posixtm.tab.c
|
||||
# The artificial dependency on getdate.c keeps the two parsers from being
|
||||
# built in parallel. Enforcing this little bit of sequentiality lets
|
||||
# everyone (even those without bison) still run mostly parallel builds.
|
||||
posixtm.c: posixtm.y getdate.c
|
||||
$(YACC) $(srcdir)/posixtm.y
|
||||
mv y.tab.c posixtm.tab.c
|
||||
sed -e 's/yy/zz/g' posixtm.tab.c > tposixtm.c
|
||||
mv tposixtm.c posixtm.c
|
||||
rm -f posixtm.tab.c
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
backupfile.o getversion.o: backupfile.h
|
||||
fnmatch.o: fnmatch.h
|
||||
fsusage.o: fsusage.h
|
||||
getopt1.o: getopt.h
|
||||
modechange.o: modechange.h
|
||||
mountlist.o: mountlist.h
|
||||
xgetcwd.o: pathmax.h
|
||||
|
||||
# Prevent GNU make v3 from overflowing arg limit on SysV.
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
@@ -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>
|
||||
@@ -31,16 +37,16 @@ extern char *program_name;
|
||||
|
||||
int
|
||||
argmatch (arg, optlist)
|
||||
char *arg;
|
||||
char **optlist;
|
||||
const char *arg;
|
||||
const char *const *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++)
|
||||
{
|
||||
@@ -70,8 +76,8 @@ argmatch (arg, optlist)
|
||||
|
||||
void
|
||||
invalid_arg (kind, value, problem)
|
||||
char *kind;
|
||||
char *value;
|
||||
const char *kind;
|
||||
const char *value;
|
||||
int problem;
|
||||
{
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
|
||||
18
lib/argmatch.h
Normal file
18
lib/argmatch.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef ARGMATCH_H
|
||||
#define ARGMATCH_H 1
|
||||
|
||||
#ifndef __P
|
||||
# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
|
||||
# define __P(args) args
|
||||
# else
|
||||
# define __P(args) ()
|
||||
# endif /* GCC. */
|
||||
#endif /* Not __P. */
|
||||
|
||||
int
|
||||
argmatch __P ((const char *arg, const char *const *optlist));
|
||||
|
||||
void
|
||||
invalid_arg __P ((const char *kind, const char *value, int problem));
|
||||
|
||||
#endif /* ARGMATCH_H */
|
||||
@@ -15,60 +15,62 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* David MacKenzie <djm@ai.mit.edu>.
|
||||
/* David MacKenzie <djm@gnu.ai.mit.edu>.
|
||||
Some algorithms adapted from GNU Emacs. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include "backupfile.h"
|
||||
#if defined(USG) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef DIRENT
|
||||
#include <dirent.h>
|
||||
#ifdef direct
|
||||
#undef direct
|
||||
#endif
|
||||
#define direct dirent
|
||||
#define NLENGTH(direct) (strlen((direct)->d_name))
|
||||
#else /* !DIRENT */
|
||||
#define NLENGTH(direct) ((direct)->d_namlen)
|
||||
#ifdef USG
|
||||
#ifdef SYSNDIR
|
||||
#include <sys/ndir.h>
|
||||
#else /* !SYSNDIR */
|
||||
#include <ndir.h>
|
||||
#endif /* !SYSNDIR */
|
||||
#else /* !USG */
|
||||
#include <sys/dir.h>
|
||||
#endif /* !USG */
|
||||
#endif /* !DIRENT */
|
||||
#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
|
||||
|
||||
#ifndef isascii
|
||||
#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
|
||||
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
|
||||
# define ISASCII(c) 1
|
||||
#else
|
||||
#define ISDIGIT(c) (isascii (c) && isdigit (c))
|
||||
# define ISASCII(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#define ISDIGIT(c) (ISASCII ((unsigned char) (c)) \
|
||||
&& isdigit ((unsigned char) (c)))
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -76,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. */
|
||||
@@ -138,15 +140,15 @@ max_backup_version (file, dir)
|
||||
char *file, *dir;
|
||||
{
|
||||
DIR *dirp;
|
||||
struct direct *dp;
|
||||
struct dirent *dp;
|
||||
int highest_version;
|
||||
int this_version;
|
||||
int file_name_length;
|
||||
|
||||
size_t file_name_length;
|
||||
|
||||
dirp = opendir (dir);
|
||||
if (!dirp)
|
||||
return 0;
|
||||
|
||||
|
||||
highest_version = 0;
|
||||
file_name_length = strlen (file);
|
||||
|
||||
@@ -154,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;
|
||||
@@ -193,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]))
|
||||
{
|
||||
@@ -213,7 +215,7 @@ concat (str1, str2)
|
||||
char *str1, *str2;
|
||||
{
|
||||
char *newstr;
|
||||
char str1_length = strlen (str1);
|
||||
int str1_length = strlen (str1);
|
||||
|
||||
newstr = malloc (str1_length + strlen (str2) + 1);
|
||||
if (newstr == 0)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
80
lib/canon-host.c
Normal file
80
lib/canon-host.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Host name canonicalization
|
||||
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
|
||||
Written by Miles Bader <miles@gnu.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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
/* Returns the canonical hostname associated with HOST (allocated in a static
|
||||
buffer), or 0 if it can't be determined. */
|
||||
char *
|
||||
canon_host (host)
|
||||
char *host;
|
||||
{
|
||||
#ifdef HAVE_GETHOSTBYNAME
|
||||
struct hostent *he = gethostbyname (host);
|
||||
|
||||
if (he)
|
||||
{
|
||||
#ifdef HAVE_GETHOSTBYADDR
|
||||
char *addr = 0;
|
||||
|
||||
/* Try and get an ascii version of the numeric host address. */
|
||||
switch (he->h_addrtype)
|
||||
{
|
||||
#ifdef HAVE_INET_NTOA
|
||||
case AF_INET:
|
||||
addr = inet_ntoa (*(struct in_addr *) he->h_addr);
|
||||
break;
|
||||
#endif /* HAVE_INET_NTOA */
|
||||
}
|
||||
|
||||
if (addr && strcmp (he->h_name, addr) == 0)
|
||||
/* gethostbyname() cheated! Lookup the host name via the address
|
||||
this time to get the actual host name. */
|
||||
he = gethostbyaddr (he->h_addr, he->h_length, he->h_addrtype);
|
||||
#endif /* HAVE_GETHOSTBYADDR */
|
||||
|
||||
if (he)
|
||||
return (char *) (he->h_name);
|
||||
}
|
||||
#endif /* HAVE_GETHOSTBYNAME */
|
||||
return 0;
|
||||
}
|
||||
@@ -15,16 +15,22 @@
|
||||
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
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
#endif
|
||||
#if defined(USG) || defined(STDC_HEADERS)
|
||||
#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 the leading directories part of PATH,
|
||||
@@ -40,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. */
|
||||
@@ -55,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);
|
||||
|
||||
115
lib/error.c
115
lib/error.c
@@ -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,55 @@
|
||||
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 || _LIBC
|
||||
# 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 || _LIBC
|
||||
# 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;
|
||||
|
||||
#ifdef _LIBC
|
||||
#define program_name program_invocation_name
|
||||
#endif
|
||||
|
||||
/* The calling program should define program_name and set it to the
|
||||
name of the executing program. */
|
||||
extern char *program_name;
|
||||
|
||||
#if HAVE_STRERROR || _LIBC
|
||||
# ifndef strerror /* On some systems, strerror is a macro */
|
||||
char *strerror ();
|
||||
# endif
|
||||
#else
|
||||
static char *
|
||||
private_strerror (errnum)
|
||||
int errnum;
|
||||
@@ -61,41 +76,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 || _LIBC
|
||||
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
44
lib/error.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* error.h -- declaration for error-reporting function
|
||||
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 _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
171
lib/euidaccess.c
Normal 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;
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
|
||||
103
lib/fnmatch.c
103
lib/fnmatch.c
@@ -1,29 +1,44 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
/* 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. */
|
||||
|
||||
#include <errno.h>
|
||||
#include "fnmatch.h"
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.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__)
|
||||
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
@@ -37,40 +52,42 @@ fnmatch (pattern, string, flags)
|
||||
register const char *p = pattern, *n = string;
|
||||
register char c;
|
||||
|
||||
if ((flags & ~__FNM_FLAGS) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
/* Note that this evalutes C many times. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PATHNAME) && *n == '/')
|
||||
else if ((flags & FNM_FILE_NAME) && *n == '/')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
c = *p++;
|
||||
if (*n != c)
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (*n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||
if (((flags & FNM_PATHNAME) && *n == '/') ||
|
||||
if (((flags & FNM_FILE_NAME) && *n == '/') ||
|
||||
(c == '?' && *n == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
@@ -79,8 +96,9 @@ fnmatch (pattern, string, flags)
|
||||
|
||||
{
|
||||
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; *n != '\0'; ++n)
|
||||
if ((c == '[' || *n == c1) &&
|
||||
if ((c == '[' || FOLD (*n) == c1) &&
|
||||
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
@@ -95,7 +113,7 @@ fnmatch (pattern, string, flags)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
@@ -110,13 +128,16 @@ fnmatch (pattern, string, flags)
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
cstart = cend = *p++;
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_PATHNAME) && c == '/')
|
||||
if ((flags & FNM_FILE_NAME) && c == '/')
|
||||
/* [/] can never match. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
@@ -127,10 +148,12 @@ fnmatch (pattern, string, flags)
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (*n >= cstart && *n <= cend)
|
||||
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
|
||||
goto matched;
|
||||
|
||||
if (c == ']')
|
||||
@@ -150,7 +173,7 @@ fnmatch (pattern, string, flags)
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
/* 1003.2d11 is unclear if this is right. %%% */
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
if (not)
|
||||
@@ -159,15 +182,21 @@ fnmatch (pattern, string, flags)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != *n)
|
||||
if (c != FOLD (*n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0' || ((flags & FNM_TARPATH) && *n == '/'))
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
140
lib/fsusage.c
140
lib/fsusage.c
@@ -15,55 +15,72 @@
|
||||
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 "fsusage.h"
|
||||
|
||||
int statfs ();
|
||||
|
||||
#if defined(STAT_STATFS2_BSIZE) && !defined(_IBMR2) /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
/* Return the number of TOSIZE-byte blocks used by
|
||||
BLOCKS FROMSIZE-byte blocks, rounding up. */
|
||||
int safe_read ();
|
||||
|
||||
#define adjust_blocks(blocks, fromsize, tosize) \
|
||||
(((fromsize) == (tosize)) \
|
||||
? (blocks) /* E.g., from 512 to 512. */ \
|
||||
: (((fromsize) > (tosize)) \
|
||||
/* E.g., from 2048 to 512. */ \
|
||||
? (blocks) * ((fromsize) / (tosize)) \
|
||||
/* E.g., from 256 to 512. */ \
|
||||
: ((blocks) + 1) / ((tosize) / (fromsize))))
|
||||
/* Return the number of TOSIZE-byte blocks used by
|
||||
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. */
|
||||
return blocks * (fromsize / tosize);
|
||||
else /* E.g., from 256 to 512. */
|
||||
return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize);
|
||||
}
|
||||
|
||||
/* Fill in the fields of FSP with information about space usage for
|
||||
the filesystem on which PATH resides.
|
||||
@@ -76,20 +93,28 @@ get_fs_usage (path, disk, fsp)
|
||||
char *path, *disk;
|
||||
struct fs_usage *fsp;
|
||||
{
|
||||
#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 /* 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
|
||||
@@ -100,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
|
||||
@@ -119,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. */
|
||||
@@ -127,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)
|
||||
@@ -138,10 +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. */
|
||||
#define f_bavail f_bfree
|
||||
#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. */
|
||||
@@ -150,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
|
||||
|
||||
@@ -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
64
lib/full-write.c
Normal 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;
|
||||
}
|
||||
951
lib/getdate.y
951
lib/getdate.y
File diff suppressed because it is too large
Load Diff
126
lib/getline.c
Normal file
126
lib/getline.c
Normal 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
17
lib/getline.h
Normal 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_ */
|
||||
375
lib/getopt.c
375
lib/getopt.c
@@ -3,58 +3,72 @@
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
|
||||
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
|
||||
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. */
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#else
|
||||
char *alloca ();
|
||||
/* 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
|
||||
|
||||
#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
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
#endif /* alloca.h */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#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__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#undef alloca
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#else /* Not GNU C library. */
|
||||
#define __alloca alloca
|
||||
#endif /* GNU C library. */
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
@@ -78,7 +92,7 @@ char *alloca ();
|
||||
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
|
||||
@@ -92,6 +106,7 @@ char *optarg = 0;
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
@@ -108,6 +123,12 @@ static char *nextchar;
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
@@ -141,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
|
||||
@@ -149,7 +173,6 @@ static enum
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
@@ -158,29 +181,32 @@ static enum
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (string, chr)
|
||||
char *string;
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*string)
|
||||
while (*str)
|
||||
{
|
||||
if (*string == chr)
|
||||
return string;
|
||||
string++;
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_bcopy (from, to, size)
|
||||
char *from, *to;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
#endif /* GNU C library. */
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
/* 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 /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
@@ -204,23 +230,93 @@ static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) __alloca (nonopts_size);
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
/* Interchange the two blocks of data in ARGV. */
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
my_bcopy ((char *) temp,
|
||||
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
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.
|
||||
@@ -287,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,
|
||||
@@ -332,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. */
|
||||
@@ -379,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;
|
||||
@@ -393,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;
|
||||
@@ -437,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++;
|
||||
@@ -455,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 '?';
|
||||
}
|
||||
@@ -487,10 +566,11 @@ _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 '?';
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
@@ -503,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 *) "";
|
||||
@@ -530,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++;
|
||||
@@ -544,12 +622,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
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);
|
||||
fprintf (stderr, _("%s: invalid option -- %c\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
@@ -563,7 +644,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
@@ -579,9 +660,17 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr,
|
||||
_("%s: option requires an argument -- %c\n"),
|
||||
argv[0], c);
|
||||
c = '?';
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
@@ -605,6 +694,8 @@ getopt (argc, argv, optstring)
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
|
||||
20
lib/getopt.h
20
lib/getopt.h
@@ -1,16 +1,16 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992 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
|
||||
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. */
|
||||
@@ -49,6 +49,10 @@ extern int optind;
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
@@ -72,7 +76,7 @@ extern int opterr;
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
@@ -90,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,
|
||||
@@ -116,7 +120,7 @@ extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,31 +1,55 @@
|
||||
/* Getopt for GNU.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
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
|
||||
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 "getopt.h"
|
||||
|
||||
#ifndef __STDC__
|
||||
#define const
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__) || defined (LIBC)
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
@@ -47,7 +71,7 @@ getopt_long (argc, argv, options, long_options, opt_index)
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
@@ -57,6 +81,9 @@ getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
|
||||
@@ -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
151
lib/group-member.c
Normal 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
7
lib/group-member.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef _group_member_h_
|
||||
#define _group_member_h_ 1
|
||||
|
||||
int
|
||||
group_member ();
|
||||
|
||||
#endif /* _group_member_h_ */
|
||||
10
lib/isdir.c
10
lib/isdir.c
@@ -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,
|
||||
|
||||
@@ -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
79
lib/long-options.c
Normal 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
10
lib/long-options.h
Normal 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)));
|
||||
115
lib/makepath.c
115
lib/makepath.c
@@ -18,6 +18,10 @@
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
|
||||
Jim Meyering <meyering@cs.utexas.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else
|
||||
@@ -38,22 +42,34 @@ char *alloca ();
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#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
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if defined(USG) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#define index strchr
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
# include <strings.h>
|
||||
# ifndef strchr
|
||||
# define strchr index
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
@@ -61,39 +77,58 @@ 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);
|
||||
|
||||
dirpath = alloca (strlen (argpath) + 1);
|
||||
/* 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);
|
||||
|
||||
if (stat (dirpath, &stats))
|
||||
@@ -127,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;
|
||||
}
|
||||
@@ -145,7 +180,7 @@ make_path (argpath, mode, parent_mode, owner, group, verbose_fmt_string)
|
||||
|
||||
if (owner != (uid_t) -1 && group != (gid_t) -1
|
||||
&& chown (dirpath, owner, group)
|
||||
#ifdef AFS
|
||||
#if defined(AFS) && defined (EPERM)
|
||||
&& errno != EPERM
|
||||
#endif
|
||||
)
|
||||
@@ -179,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;
|
||||
}
|
||||
@@ -233,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
15
lib/makepath.h
Normal 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
366
lib/md5.c
Normal 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
115
lib/md5.h
Normal 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
|
||||
123
lib/memchr.c
123
lib/memchr.c
@@ -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
366
lib/memcmp.c
Normal 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
16
lib/memcpy.c
Normal 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
24
lib/memmove.c
Normal 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++;
|
||||
}
|
||||
68
lib/mkdir.c
68
lib/mkdir.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
576
lib/mktime.c
576
lib/mktime.c
@@ -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:
|
||||
*/
|
||||
|
||||
@@ -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...]". */
|
||||
|
||||
101
lib/mountlist.c
101
lib/mountlist.c
@@ -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
485
lib/obstack.c
Normal 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
529
lib/obstack.h
Normal 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
53
lib/pathmax.h
Normal 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
978
lib/posixtm.c
Normal 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;
|
||||
}
|
||||
79
lib/putenv.c
79
lib/putenv.c
@@ -1,57 +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>
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
extern int errno;
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(USG)
|
||||
#include <string.h>
|
||||
#define index strchr
|
||||
#define bcopy(s, d, n) memcpy((d), (s), (n))
|
||||
#else /* not (STDC_HEADERS or USG) */
|
||||
#include <strings.h>
|
||||
#endif /* STDC_HEADERS or USG */
|
||||
/* Define-away any (possibly conflicting) prototype of putenv.
|
||||
Many systems omit the `const' attribute on the argument. */
|
||||
#define putenv _sys_putenv
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#if defined (__GNU_LIBRARY__) || defined (HAVE_STDLIB_H)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#if defined (__GNU_LIBRARY__) || defined (HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#endif
|
||||
#if defined (__GNU_LIBRARY__) || defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#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;
|
||||
|
||||
@@ -86,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;
|
||||
}
|
||||
|
||||
223
lib/readtokens.c
Normal file
223
lib/readtokens.c
Normal file
@@ -0,0 +1,223 @@
|
||||
/* 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 (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 (stream, delim, n_delim, tokenbuffer)
|
||||
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 (stream, projected_n_tokens, delim, n_delim,
|
||||
tokens_out, token_lengths)
|
||||
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;
|
||||
}
|
||||
36
lib/readtokens.h
Normal file
36
lib/readtokens.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#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 */
|
||||
|
||||
#undef __P
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
|
||||
void init_tokenbuffer __P ((token_buffer *tokenbuffer));
|
||||
|
||||
long
|
||||
readtoken __P ((FILE *stream, const char *delim, int n_delim,
|
||||
token_buffer *tokenbuffer));
|
||||
int
|
||||
readtokens __P ((FILE *stream, int projected_n_tokens,
|
||||
const char *delim, int n_delim,
|
||||
char ***tokens_out, long **token_lengths));
|
||||
|
||||
#endif /* not H_READTOKENS_H */
|
||||
2233
lib/regex.c
2233
lib/regex.c
File diff suppressed because it is too large
Load Diff
60
lib/regex.h
60
lib/regex.h
@@ -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));
|
||||
|
||||
34
lib/rename.c
34
lib/rename.c
@@ -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
86
lib/rmdir.c
Normal 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
60
lib/safe-read.c
Normal 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;
|
||||
}
|
||||
155
lib/save-cwd.c
Normal file
155
lib/save-cwd.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/* save-cwd.c -- Save and restore current working directory.
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by Jim Meyering <meyering@na-net.ornl.gov>. */
|
||||
|
||||
#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
23
lib/save-cwd.h
Normal 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 */
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
14
lib/stpcpy.c
14
lib/stpcpy.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
114
lib/strftime.c
114
lib/strftime.c
@@ -46,9 +46,11 @@
|
||||
%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)
|
||||
%z RFC-822 style numeric timezone (-0500) (a nonstandard extension)
|
||||
%Z time zone (EDT), or nothing if no time zone is determinable
|
||||
|
||||
Date fields:
|
||||
@@ -73,6 +75,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,12 +87,12 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
#ifndef STDC_HEADERS
|
||||
time_t mktime ();
|
||||
#endif
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#if defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
#endif
|
||||
|
||||
/* Types of padding for numbers in date and time. */
|
||||
@@ -108,7 +115,13 @@ static char const * const months[] =
|
||||
/* Add character C to STRING and increment LENGTH,
|
||||
unless LENGTH would exceed MAX. */
|
||||
|
||||
#define add_char(c) (length + 1 <= max) && (string[length++] = (c))
|
||||
#define add_char(c) \
|
||||
do \
|
||||
{ \
|
||||
if (length + 1 <= max) \
|
||||
string[length++] = (c); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Add a 2 digit number to STRING, padding if specified.
|
||||
Return the number of characters added, up to MAX. */
|
||||
@@ -162,7 +175,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;
|
||||
@@ -172,6 +185,54 @@ 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;
|
||||
}
|
||||
|
||||
/* Convert MINUTES_EAST into a string suitable for use as the RFC-822
|
||||
timezone indicator. Write no more than MAX bytes into STRING.
|
||||
Return the number of bytes written into STRING. */
|
||||
|
||||
static int
|
||||
add_num_tz (string, max, minutes_east)
|
||||
char *string;
|
||||
int max;
|
||||
int minutes_east;
|
||||
{
|
||||
int length;
|
||||
|
||||
if (max < 1)
|
||||
return 0;
|
||||
|
||||
if (minutes_east < 0)
|
||||
{
|
||||
*string = '-';
|
||||
minutes_east = -minutes_east;
|
||||
}
|
||||
else
|
||||
*string = '+';
|
||||
|
||||
length = 1 + add_num2 (&string[1], (minutes_east / 60) % 24, max - 1, zero);
|
||||
length += add_num2 (&string[length], minutes_east % 60, max - length, zero);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Return the week in the year of the time in TM, with the weeks
|
||||
starting on Sundays. */
|
||||
|
||||
@@ -317,6 +378,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);
|
||||
@@ -329,6 +400,37 @@ strftime (string, max, format, tm)
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%H:%M:%S", tm);
|
||||
break;
|
||||
case 'z':
|
||||
{
|
||||
time_t t;
|
||||
struct tm tml, tmg;
|
||||
int diff;
|
||||
|
||||
tml = *tm;
|
||||
t = mktime (&tml);
|
||||
tml = *localtime (&t); /* Canonicalize the local time */
|
||||
tmg = *gmtime (&t);
|
||||
|
||||
/* Compute the difference */
|
||||
|
||||
diff = tml.tm_min - tmg.tm_min;
|
||||
diff += 60 * (tml.tm_hour - tmg.tm_hour);
|
||||
|
||||
if (tml.tm_mon != tmg.tm_mon)
|
||||
{
|
||||
/* We assume no timezone differs from UTC by more than
|
||||
+- 23 hours. This should be safe. */
|
||||
if (tmg.tm_mday == 1)
|
||||
tml.tm_mday = 0;
|
||||
else /* tml.tm_mday == 1 */
|
||||
tmg.tm_mday = 0;
|
||||
}
|
||||
|
||||
diff += 1440 * (tml.tm_mday - tmg.tm_mday);
|
||||
|
||||
length += add_num_tz (&string[length], max - length, diff);
|
||||
}
|
||||
break;
|
||||
case 'Z':
|
||||
#ifdef HAVE_TM_ZONE
|
||||
length += add_str (&string[length], tm->tm_zone, max - length);
|
||||
|
||||
39
lib/strpbrk.c
Normal file
39
lib/strpbrk.c
Normal 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;
|
||||
}
|
||||
47
lib/strtod.c
47
lib/strtod.c
@@ -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
|
||||
|
||||
241
lib/strtol.c
241
lib/strtol.c
@@ -1,75 +1,153 @@
|
||||
/* 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.
|
||||
|
||||
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. */
|
||||
|
||||
#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
|
||||
#ifdef 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 +178,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 +234,7 @@ strtol (nptr, endptr, base)
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
i *= (unsigned long int) base;
|
||||
i *= (unsigned LONG int) base;
|
||||
i += c;
|
||||
}
|
||||
}
|
||||
@@ -152,18 +248,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 +267,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. */
|
||||
|
||||
INT
|
||||
strtol (nptr, endptr, base)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
int base;
|
||||
{
|
||||
return INTERNAL (strtol) (nptr, endptr, base, 0);
|
||||
}
|
||||
|
||||
#ifdef weak_symbol
|
||||
weak_symbol (strtol)
|
||||
#endif
|
||||
|
||||
284
lib/userspec.c
284
lib/userspec.c
@@ -17,26 +17,44 @@
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#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>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if defined(USG) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#define index strchr
|
||||
#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
|
||||
@@ -45,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.
|
||||
@@ -64,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
85
lib/xgetcwd.c
Normal 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
54
lib/xgethostname.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
48
lib/xstrtod.c
Normal file
48
lib/xstrtod.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
double strtod ();
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "xstrtod.h"
|
||||
|
||||
int
|
||||
xstrtod (str, ptr, result)
|
||||
const char *str;
|
||||
const char **ptr;
|
||||
double *result;
|
||||
{
|
||||
double val;
|
||||
char *terminator;
|
||||
int fail;
|
||||
|
||||
fail = 0;
|
||||
errno = 0;
|
||||
val = strtod (str, &terminator);
|
||||
|
||||
/* Having a non-zero terminator is an error only when PTR is NULL. */
|
||||
if (terminator == str || (ptr == NULL && *terminator != '\0'))
|
||||
fail = 1;
|
||||
else
|
||||
{
|
||||
/* Allow underflow (in which case strtod returns zero),
|
||||
but flag overflow as an error. */
|
||||
if (val != 0.0 && errno == ERANGE)
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
if (ptr != NULL)
|
||||
*ptr = terminator;
|
||||
|
||||
*result = val;
|
||||
return fail;
|
||||
}
|
||||
|
||||
15
lib/xstrtod.h
Normal file
15
lib/xstrtod.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef XSTRTOD_H
|
||||
#define XSTRTOD_H 1
|
||||
|
||||
#ifndef __P
|
||||
# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
|
||||
# define __P(args) args
|
||||
# else
|
||||
# define __P(args) ()
|
||||
# endif /* GCC. */
|
||||
#endif /* Not __P. */
|
||||
|
||||
int
|
||||
xstrtod __P ((const char *str, const char **ptr, double *result));
|
||||
|
||||
#endif /* XSTRTOD_H */
|
||||
156
lib/xstrtol.c
Normal file
156
lib/xstrtol.c
Normal 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
66
lib/xstrtol.h
Normal 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
2
lib/xstrtoul.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#define STRING_TO_UNSIGNED 1
|
||||
#include "xstrtol.c"
|
||||
7
lib/xstrtoul.h
Normal file
7
lib/xstrtoul.h
Normal 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
@@ -1,6 +1,109 @@
|
||||
User-visible changes in release 3.13:
|
||||
* cp --backup a~ a fails instead of silently destroying the source file
|
||||
* df and du have new options --human-readable (-h) and --megabytes (-m).
|
||||
* install now honors --backup (-b), --suffix=SUFFIX (-S SUFFIX), and
|
||||
--version-control=WORD (-V WORD) options just as cp, ln, and mv do.
|
||||
* ln --verbose output is less prone to misinterpretation
|
||||
* ls -o works like -lG; for compatibility with other versions of ls
|
||||
* cp has a new option to control creation of sparse files
|
||||
* rm -rf '' behaves properly on SunOS 4 systems
|
||||
* touch: rename 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
|
||||
* cp, mkdir, and rmdir long option --path renamed to --parents; --path
|
||||
will still work for a while
|
||||
* cp, ln, and mv convert `cp A B/' to cp A B/A when A is not a directory.
|
||||
This change affects only the two-argument form of the commands. It makes
|
||||
such commands fail when the target has a trailing slash but is not a
|
||||
directory or symlink to a directory and the source is not a directory.
|
||||
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
|
||||
* avoid redundant compilations for `dir' and `vdir';
|
||||
* configure properly defines STAT_STATFS2_BSIZE on a Pyramid MIServer
|
||||
running OSx 5.1
|
||||
|
||||
Major changes in release 3.7:
|
||||
* none
|
||||
Major changes in release 3.6:
|
||||
* `ln -s dir_pathname .' works when the pathname has a trailing slash
|
||||
* with the --version option programs print the version and exit immediately
|
||||
* GNU ls -f works like Unix ls -f
|
||||
* mktime replacement works
|
||||
|
||||
Major changes in release 3.5:
|
||||
* adds support for DEC Alpha under OSF/1
|
||||
* configuring with gcc uses CFLAGS='-g -O' by default
|
||||
* all programs accept --help and --version options
|
||||
* long-named options must be introduced with `--'; `+' is no longer
|
||||
accepted since it is incompatible with the POSIX.2 standard
|
||||
* chmod accepts long-named options
|
||||
* dd conv=unblock doesn't hang
|
||||
* new df option --exclude=fstype
|
||||
* new ls option --full-time
|
||||
|
||||
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
@@ -1,3 +1,84 @@
|
||||
User visible changes in release 1.13
|
||||
* `date -d "01/01/1998 3 years" +%Y' now works properly. It prints 2001.
|
||||
* expr's match operator has been corrected to use basic regular expressions
|
||||
* New programs: factor, seq.
|
||||
* date accepts new option --rfc-822 (-R) and new %z format.
|
||||
* date: fix bugs in the handling of date -u +'%s %Z'.
|
||||
* date accepts new option --reference=FILE (-r FILE) analogous to the
|
||||
like-named touch option.
|
||||
* date can now format dates up to and including ones in the year 2037
|
||||
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
|
||||
* fix some incorrect warnings in pathchk
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,122 @@
|
||||
User-visible changes in release 1.15
|
||||
* join without -t now ignores leading blanks
|
||||
* sort accepts new option: -z for NUL terminated records
|
||||
* join accepts new option: --ignore-case, -i
|
||||
User-visible changes in release 1.14
|
||||
* sort -i and sort -d properly order strings containing ignored characters
|
||||
* nl: rename misleading --first-page=N option to --starting-line-number=N.
|
||||
* sort diagnoses invalid arguments to -k, then fails
|
||||
* sort -n properly orders invalid integers with respect to valid integers
|
||||
* sorting works with character offsets larger than corresponding field width
|
||||
* sort's -b option and `b' modifier work
|
||||
* sort -k2,2 works.
|
||||
* csplit detects integer overflow when converting command line arguments
|
||||
* sort accepts new option/flag, -g, for sorting numbers in scientific notation
|
||||
* 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.
|
||||
|
||||
Major changes in release 1.7:
|
||||
* none
|
||||
Major changes in release 1.6:
|
||||
* with the --version option programs print the version and exit immediately
|
||||
* pr -2a really terminates
|
||||
* pr -n produces multi-column output
|
||||
|
||||
Major changes in release 1.5:
|
||||
* sort is 8-bit clean
|
||||
* sort's -n and -M options no longer imply -b
|
||||
* several bugs in sort have been fixed
|
||||
* all programs accept --help and --version options
|
||||
* od --compatible accepts pre-POSIX arguments
|
||||
* pr -2a terminates
|
||||
|
||||
Major changes in release 1.4:
|
||||
* add od and cksum programs
|
||||
* move cmp to GNU diff distribution
|
||||
* tail -f works for multiple files
|
||||
* pr prints the file name in error messages
|
||||
* fix some off by 1 errors in pr and fold
|
||||
* optimize wc -c on regular files
|
||||
* sort handles `-' argument correctly
|
||||
* sort supports -T option
|
||||
* tr ranges like a-a work
|
||||
* tr x '' fails gracefully
|
||||
* default sum output format is BSD compatible
|
||||
|
||||
19
src/ansi2knr.1
Normal file
19
src/ansi2knr.1
Normal 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
439
src/ansi2knr.c
Normal 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;
|
||||
}
|
||||
@@ -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,26 +25,60 @@
|
||||
basename functions.lisp p
|
||||
=> functions.lis */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "system.h"
|
||||
|
||||
char *basename ();
|
||||
#include "system.h"
|
||||
#include "version.h"
|
||||
#include "long-options.h"
|
||||
#include "error.h"
|
||||
|
||||
char *basename __P ((char *));
|
||||
void strip_trailing_slashes ();
|
||||
|
||||
static void remove_suffix ();
|
||||
static void remove_suffix __P ((register char *name, register char *suffix));
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
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
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *name;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
parse_long_options (argc, argv, "basename", version_string, usage);
|
||||
|
||||
if (argc == 1 || argc > 3)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s name [suffix]\n", argv[0]);
|
||||
exit (1);
|
||||
error (0, 0, "too %s arguments", argc == 1 ? "few" : "many");
|
||||
usage (1);
|
||||
}
|
||||
|
||||
strip_trailing_slashes (argv[1]);
|
||||
@@ -63,8 +97,7 @@ main (argc, argv)
|
||||
consists entirely of SUFFIX. */
|
||||
|
||||
static void
|
||||
remove_suffix (name, suffix)
|
||||
register char *name, *suffix;
|
||||
remove_suffix (register char *name, register char *suffix)
|
||||
{
|
||||
register char *np, *sp;
|
||||
|
||||
|
||||
684
src/cat.c
684
src/cat.c
@@ -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>
|
||||
@@ -29,16 +31,17 @@
|
||||
#include <sys/ioctl.h>
|
||||
#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;
|
||||
@@ -57,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'. */
|
||||
@@ -73,280 +76,68 @@ static int newlines2 = 0;
|
||||
static int exit_stat = 0;
|
||||
|
||||
static void
|
||||
usage (reason)
|
||||
char *reason;
|
||||
usage (int status)
|
||||
{
|
||||
if (reason != NULL)
|
||||
fprintf (stderr, "%s: %s\n", program_name, reason);
|
||||
|
||||
fprintf (stderr, "\
|
||||
Usage: %s [-benstuvAET] [--number] [--number-nonblank] [--squeeze-blank]\n\
|
||||
[--show-nonprinting] [--show-ends] [--show-tabs] [--show-all]\n\
|
||||
[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;
|
||||
int options = 0;
|
||||
|
||||
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'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
/* Parse command line options. */
|
||||
|
||||
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
options++;
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
numbers = 1;
|
||||
numbers_at_empty_lines = 0;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
mark_line_ends = 1;
|
||||
quote = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
numbers = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
squeeze_empty_lines = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
output_tabs = 0;
|
||||
quote = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
/* We provide the -u feature unconditionally. */
|
||||
options--;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
quote = 1;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
quote = 1;
|
||||
mark_line_ends = 1;
|
||||
output_tabs = 0;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
mark_line_ends = 1;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
output_tabs = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage ((char *) 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;
|
||||
|
||||
/* 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)
|
||||
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 preceeding 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;
|
||||
@@ -357,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);
|
||||
@@ -372,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.
|
||||
|
||||
@@ -384,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;
|
||||
@@ -424,7 +212,7 @@ cat (inbuf, insize, outbuf, outsize, quote,
|
||||
/* Number of characters read by the last read call. */
|
||||
int n_read;
|
||||
|
||||
/* Determines how many consequtive newlines there have been in the
|
||||
/* Determines how many consecutive newlines there have been in the
|
||||
input. 0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
|
||||
etc. Initially 0 to indicate that we are at the beginning of a
|
||||
new line. The "state" of the procedure is determined by
|
||||
@@ -456,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);
|
||||
@@ -465,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);
|
||||
}
|
||||
|
||||
@@ -484,12 +272,21 @@ cat (inbuf, insize, outbuf, outsize, quote,
|
||||
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
|
||||
{
|
||||
/* Ultrix returns EOPNOTSUPP on NFS;
|
||||
HP-UX returns ENOTTY on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY)
|
||||
HP-UX returns ENOTTY on pipes.
|
||||
SunOS returns EINVAL and
|
||||
More/BSD returns ENODEV on special files
|
||||
like /dev/null.
|
||||
Irix-5 returns ENOSYS on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY
|
||||
|| errno == EINVAL || errno == ENODEV
|
||||
#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;
|
||||
@@ -500,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);
|
||||
@@ -642,20 +439,287 @@ 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 nonzero, call cat, otherwise call simple_cat to do the actual work. */
|
||||
int options = 0;
|
||||
|
||||
/* If nonzero, display usage information and exit. */
|
||||
static int show_help;
|
||||
|
||||
/* If nonzero, 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];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
/* 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
|
||||
&& (input_desc != fileno (stdin) || output_desc != fileno (stdout)))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
248
src/chgrp.c
248
src/chgrp.c
@@ -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,40 +17,43 @@
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <getopt.h>
|
||||
#include "system.h"
|
||||
|
||||
#ifndef 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 ();
|
||||
static int change_dir_group __P ((char *dir, int group, struct stat *statp));
|
||||
|
||||
/* The name the program was run with. */
|
||||
char *program_name;
|
||||
@@ -70,6 +73,12 @@ static int changes_only;
|
||||
/* The name of the group to which ownership of the files is being given. */
|
||||
static char *groupname;
|
||||
|
||||
/* If nonzero, display usage information and exit. */
|
||||
static int show_help;
|
||||
|
||||
/* If nonzero, print the version on standard output and exit. */
|
||||
static int show_version;
|
||||
|
||||
static struct option const long_options[] =
|
||||
{
|
||||
{"recursive", no_argument, 0, 'R'},
|
||||
@@ -77,74 +86,46 @@ static struct option const long_options[] =
|
||||
{"silent", no_argument, 0, 'f'},
|
||||
{"quiet", no_argument, 0, 'f'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"help", no_argument, &show_help, 1},
|
||||
{"version", no_argument, &show_version, 1},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
/* Tell the user the group name to which ownership of FILE
|
||||
has been given; if CHANGED is zero, FILE was that group already. */
|
||||
|
||||
static void
|
||||
describe_change (char *file, int changed)
|
||||
{
|
||||
int group;
|
||||
int errors = 0;
|
||||
int optc;
|
||||
|
||||
program_name = argv[0];
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "Rcfv", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc - 1)
|
||||
usage ();
|
||||
|
||||
parse_group (argv[optind++], &group);
|
||||
|
||||
for (; optind < argc; ++optind)
|
||||
errors |= change_file_group (argv[optind], group);
|
||||
|
||||
exit (errors);
|
||||
if (changed)
|
||||
printf (_("group of %s changed to %s\n"), file, groupname);
|
||||
else
|
||||
printf (_("group of %s retained as %s\n"), file, groupname);
|
||||
}
|
||||
|
||||
/* Set *G according to NAME. */
|
||||
|
||||
static void
|
||||
parse_group (name, g)
|
||||
char *name;
|
||||
int *g;
|
||||
parse_group (char *name, int *g)
|
||||
{
|
||||
struct group *grp;
|
||||
|
||||
groupname = name;
|
||||
if (*name == '\0')
|
||||
error (1, 0, "can not change to null group");
|
||||
error (1, 0, _("can not change to null group"));
|
||||
|
||||
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;
|
||||
@@ -156,9 +137,7 @@ parse_group (name, g)
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
|
||||
static int
|
||||
change_file_group (file, group)
|
||||
char *file;
|
||||
int group;
|
||||
change_file_group (char *file, int group)
|
||||
{
|
||||
struct stat file_stats;
|
||||
int errors = 0;
|
||||
@@ -176,9 +155,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)
|
||||
@@ -195,10 +193,7 @@ change_file_group (file, group)
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
|
||||
static int
|
||||
change_dir_group (dir, group, statp)
|
||||
char *dir;
|
||||
int group;
|
||||
struct stat *statp;
|
||||
change_dir_group (char *dir, int group, struct stat *statp)
|
||||
{
|
||||
char *name_space, *namep;
|
||||
char *path; /* Full path of each entry to process. */
|
||||
@@ -218,7 +213,7 @@ change_dir_group (dir, group, statp)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
error (1, 0, "virtual memory exhausted");
|
||||
error (1, 0, _("virtual memory exhausted"));
|
||||
}
|
||||
|
||||
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
|
||||
@@ -244,39 +239,82 @@ change_dir_group (dir, group, statp)
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Tell the user the group name to which ownership of FILE
|
||||
has been given; if CHANGED is zero, FILE was that group already. */
|
||||
|
||||
static void
|
||||
describe_change (file, changed)
|
||||
char *file;
|
||||
int changed;
|
||||
usage (int status)
|
||||
{
|
||||
if (changed)
|
||||
printf ("group of %s changed to %s\n", file, groupname);
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
printf ("group of %s retained as %s\n", file, groupname);
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* Return nonzero if STR represents an unsigned decimal integer,
|
||||
otherwise return 0. */
|
||||
|
||||
static int
|
||||
isnumber (str)
|
||||
char *str;
|
||||
void
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
for (; *str; str++)
|
||||
if (!ISDIGIT (*str))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
int group;
|
||||
int errors = 0;
|
||||
int optc;
|
||||
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr, "\
|
||||
Usage: %s [-Rcfv] [--recursive] [--changes] [--silent] [--quiet]\n\
|
||||
[--verbose] group file...\n",
|
||||
program_name);
|
||||
exit (1);
|
||||
program_name = argv[0];
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "Rcfv", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
{
|
||||
printf ("chgrp - %s\n", version_string);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (show_help)
|
||||
usage (0);
|
||||
|
||||
if (argc - optind <= 1)
|
||||
{
|
||||
error (0, 0, _("too few arguments"));
|
||||
usage (1);
|
||||
}
|
||||
|
||||
parse_group (argv[optind++], &group);
|
||||
|
||||
for (; optind < argc; ++optind)
|
||||
errors |= change_file_group (argv[optind], group);
|
||||
|
||||
exit (errors);
|
||||
}
|
||||
|
||||
295
src/chmod.c
295
src/chmod.c
@@ -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,24 +23,24 @@
|
||||
|
||||
David MacKenzie <djm@gnu.ai.mit.edu> */
|
||||
|
||||
#include <config.h>
|
||||
#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 ();
|
||||
static void describe_change ();
|
||||
static void usage ();
|
||||
static int change_dir_mode __P ((char *dir, struct mode_change *changes,
|
||||
struct stat *statp));
|
||||
|
||||
/* The name the program was run with. */
|
||||
char *program_name;
|
||||
@@ -57,94 +57,49 @@ static int verbose;
|
||||
/* If nonzero, describe only modes that change. */
|
||||
static int changes_only;
|
||||
|
||||
/* Parse the ASCII mode given on the command line into a linked list
|
||||
of `struct mode_change' and apply that to each file argument. */
|
||||
/* If nonzero, display usage information and exit. */
|
||||
static int show_help;
|
||||
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
/* If nonzero, print the version on standard output and exit. */
|
||||
static int show_version;
|
||||
|
||||
static struct option const long_options[] =
|
||||
{
|
||||
struct mode_change *changes;
|
||||
int errors = 0;
|
||||
int modeind = 0; /* Index of the mode argument in `argv'. */
|
||||
int thisind;
|
||||
int c;
|
||||
{"recursive", no_argument, 0, 'R'},
|
||||
{"changes", no_argument, 0, 'c'},
|
||||
{"silent", no_argument, 0, 'f'},
|
||||
{"quiet", no_argument, 0, 'f'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"help", no_argument, &show_help, 1},
|
||||
{"version", no_argument, &show_version, 1},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
program_name = argv[0];
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
/* Tell the user the mode MODE that file FILE has been set to;
|
||||
if CHANGED is zero, FILE had that mode already. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
thisind = optind ? optind : 1;
|
||||
static void
|
||||
describe_change (char *file, short unsigned int mode, int changed)
|
||||
{
|
||||
char perms[11]; /* "-rwxrwxrwx" ls-style modes. */
|
||||
|
||||
c = getopt (argc, argv, "RcfvrwxXstugoa,+-=");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'g':
|
||||
case 'o':
|
||||
case 'a':
|
||||
case ',':
|
||||
case '+':
|
||||
case '-':
|
||||
case '=':
|
||||
if (modeind != 0 && modeind != thisind)
|
||||
error (1, 0, "invalid mode");
|
||||
modeind = thisind;
|
||||
break;
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (modeind == 0)
|
||||
modeind = optind++;
|
||||
if (optind >= argc)
|
||||
usage ();
|
||||
|
||||
changes = mode_compile (argv[modeind],
|
||||
MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
|
||||
if (changes == MODE_INVALID)
|
||||
error (1, 0, "invalid mode");
|
||||
else if (changes == MODE_MEMORY_EXHAUSTED)
|
||||
error (1, 0, "virtual memory exhausted");
|
||||
|
||||
for (; optind < argc; ++optind)
|
||||
errors |= change_file_mode (argv[optind], changes);
|
||||
|
||||
exit (errors);
|
||||
mode_string (mode, perms);
|
||||
perms[10] = '\0'; /* `mode_string' does not null terminate. */
|
||||
if (changed)
|
||||
printf (_("mode of %s changed to %04o (%s)\n"),
|
||||
file, mode & 07777, &perms[1]);
|
||||
else
|
||||
printf (_("mode of %s retained as %04o (%s)\n"),
|
||||
file, mode & 07777, &perms[1]);
|
||||
}
|
||||
|
||||
/* Change the mode of FILE according to the list of operations CHANGES.
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
If DEREF_SYMLINK is nonzero 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)
|
||||
char *file;
|
||||
struct mode_change *changes;
|
||||
change_file_mode (char *file, struct mode_change *changes, int deref_symlink)
|
||||
{
|
||||
struct stat file_stats;
|
||||
unsigned short newmode;
|
||||
@@ -158,7 +113,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);
|
||||
@@ -188,10 +153,7 @@ change_file_mode (file, changes)
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
|
||||
static int
|
||||
change_dir_mode (dir, changes, statp)
|
||||
char *dir;
|
||||
struct mode_change *changes;
|
||||
struct stat *statp;
|
||||
change_dir_mode (char *dir, struct mode_change *changes, struct stat *statp)
|
||||
{
|
||||
char *name_space, *namep;
|
||||
char *path; /* Full path of each entry to process. */
|
||||
@@ -211,7 +173,7 @@ change_dir_mode (dir, changes, statp)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
error (1, 0, "virtual memory exhausted");
|
||||
error (1, 0, _("virtual memory exhausted"));
|
||||
}
|
||||
|
||||
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
|
||||
@@ -230,40 +192,139 @@ 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);
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Tell the user the mode MODE that file FILE has been set to;
|
||||
if CHANGED is zero, FILE had that mode already. */
|
||||
|
||||
static void
|
||||
describe_change (file, mode, changed)
|
||||
char *file;
|
||||
unsigned short mode;
|
||||
int changed;
|
||||
usage (int status)
|
||||
{
|
||||
char perms[11]; /* "-rwxrwxrwx" ls-style modes. */
|
||||
|
||||
mode_string (mode, perms);
|
||||
perms[10] = '\0'; /* `mode_string' does not null terminate. */
|
||||
if (changed)
|
||||
printf ("mode of %s changed to %04o (%s)\n",
|
||||
file, mode & 07777, &perms[1]);
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
printf ("mode of %s retained as %04o (%s)\n",
|
||||
file, mode & 07777, &perms[1]);
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
usage ()
|
||||
/* Parse the ASCII mode given on the command line into a linked list
|
||||
of `struct mode_change' and apply that to each file argument. */
|
||||
|
||||
void
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
fprintf (stderr, "\
|
||||
Usage: %s [-Rcfv] mode file...\n\
|
||||
mode is [ugoa...][[+-=][rwxXstugo...]...][,...] or octal number\n",
|
||||
program_name);
|
||||
exit (1);
|
||||
struct mode_change *changes;
|
||||
int errors = 0;
|
||||
int modeind = 0; /* Index of the mode argument in `argv'. */
|
||||
int thisind;
|
||||
int c;
|
||||
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
thisind = optind ? optind : 1;
|
||||
|
||||
c = getopt_long (argc, argv, "RcfvrwxXstugoa,+-=", long_options,
|
||||
(int *) 0);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'r':
|
||||
case 'w':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 's':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'g':
|
||||
case 'o':
|
||||
case 'a':
|
||||
case ',':
|
||||
case '+':
|
||||
case '-':
|
||||
case '=':
|
||||
if (modeind != 0 && modeind != thisind)
|
||||
error (1, 0, _("invalid mode"));
|
||||
modeind = thisind;
|
||||
break;
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
{
|
||||
printf ("chmod - %s\n", version_string);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (show_help)
|
||||
usage (0);
|
||||
|
||||
if (modeind == 0)
|
||||
modeind = optind++;
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
error (0, 0, _("too few arguments"));
|
||||
usage (1);
|
||||
}
|
||||
|
||||
changes = mode_compile (argv[modeind],
|
||||
MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
|
||||
if (changes == MODE_INVALID)
|
||||
error (1, 0, _("invalid mode"));
|
||||
else if (changes == MODE_MEMORY_EXHAUSTED)
|
||||
error (1, 0, _("virtual memory exhausted"));
|
||||
|
||||
for (; optind < argc; ++optind)
|
||||
{
|
||||
strip_trailing_slashes (argv[optind]);
|
||||
errors |= change_file_mode (argv[optind], changes, 1);
|
||||
}
|
||||
|
||||
exit (errors);
|
||||
}
|
||||
|
||||
219
src/chown.c
219
src/chown.c
@@ -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,13 +28,16 @@
|
||||
|
||||
Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
#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 ();
|
||||
@@ -42,23 +45,18 @@ 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 ();
|
||||
static void describe_change ();
|
||||
static void usage ();
|
||||
static int change_dir_owner __P ((char *dir, uid_t user, gid_t group,
|
||||
struct stat *statp));
|
||||
|
||||
/* The name the program was run with. */
|
||||
char *program_name;
|
||||
@@ -81,6 +79,12 @@ static char *username;
|
||||
/* The name of the group to which ownership of the files is being given. */
|
||||
static char *groupname;
|
||||
|
||||
/* If nonzero, display usage information and exit. */
|
||||
static int show_help;
|
||||
|
||||
/* If nonzero, print the version on standard output and exit. */
|
||||
static int show_version;
|
||||
|
||||
static struct option const long_options[] =
|
||||
{
|
||||
{"recursive", no_argument, 0, 'R'},
|
||||
@@ -88,59 +92,25 @@ static struct option const long_options[] =
|
||||
{"silent", no_argument, 0, 'f'},
|
||||
{"quiet", no_argument, 0, 'f'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"help", no_argument, &show_help, 1},
|
||||
{"version", no_argument, &show_version, 1},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
/* Tell the user the user and group names to which ownership of FILE
|
||||
has been given; if CHANGED is zero, FILE had those owners already. */
|
||||
|
||||
static void
|
||||
describe_change (char *file, int changed)
|
||||
{
|
||||
uid_t user = -1; /* New uid; -1 if not to be changed. */
|
||||
gid_t group = -1; /* New gid; -1 if not to be changed. */
|
||||
int errors = 0;
|
||||
int optc;
|
||||
char *e;
|
||||
|
||||
program_name = argv[0];
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "Rcfv", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc - 1)
|
||||
usage ();
|
||||
|
||||
e = parse_user_spec (argv[optind], &user, &group, &username, &groupname);
|
||||
if (e)
|
||||
error (1, 0, "%s: %s", argv[optind], e);
|
||||
if (username == NULL)
|
||||
username = "";
|
||||
|
||||
for (++optind; optind < argc; ++optind)
|
||||
errors |= change_file_owner (argv[optind], user, group);
|
||||
|
||||
exit (errors);
|
||||
if (changed)
|
||||
printf (_("owner of %s changed to "), file);
|
||||
else
|
||||
printf (_("owner of %s retained as "), file);
|
||||
if (groupname)
|
||||
printf ("%s.%s\n", username, groupname);
|
||||
else
|
||||
printf ("%s\n", username);
|
||||
}
|
||||
|
||||
/* Change the ownership of FILE to UID USER and GID GROUP.
|
||||
@@ -148,10 +118,7 @@ main (argc, argv)
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
|
||||
static int
|
||||
change_file_owner (file, user, group)
|
||||
char *file;
|
||||
uid_t user;
|
||||
gid_t group;
|
||||
change_file_owner (char *file, uid_t user, gid_t group)
|
||||
{
|
||||
struct stat file_stats;
|
||||
uid_t newuser;
|
||||
@@ -192,11 +159,7 @@ change_file_owner (file, user, group)
|
||||
Return 0 if successful, 1 if errors occurred. */
|
||||
|
||||
static int
|
||||
change_dir_owner (dir, user, group, statp)
|
||||
char *dir;
|
||||
uid_t user;
|
||||
gid_t group;
|
||||
struct stat *statp;
|
||||
change_dir_owner (char *dir, uid_t user, gid_t group, struct stat *statp)
|
||||
{
|
||||
char *name_space, *namep;
|
||||
char *path; /* Full path of each entry to process. */
|
||||
@@ -216,7 +179,7 @@ change_dir_owner (dir, user, group, statp)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
error (1, 0, "virtual memory exhausted");
|
||||
error (1, 0, _("virtual memory exhausted"));
|
||||
}
|
||||
|
||||
dirlength = strlen (dir) + 1; /* + 1 is for the trailing '/'. */
|
||||
@@ -242,30 +205,102 @@ change_dir_owner (dir, user, group, statp)
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Tell the user the user and group names to which ownership of FILE
|
||||
has been given; if CHANGED is zero, FILE had those owners already. */
|
||||
|
||||
static void
|
||||
describe_change (file, changed)
|
||||
char *file;
|
||||
int changed;
|
||||
usage (int status)
|
||||
{
|
||||
if (changed)
|
||||
printf ("owner of %s changed to ", file);
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
printf ("owner of %s retained as ", file);
|
||||
if (groupname)
|
||||
printf ("%s.%s\n", username, groupname);
|
||||
else
|
||||
printf ("%s\n", username);
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
usage ()
|
||||
void
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
fprintf (stderr, "\
|
||||
Usage: %s [-Rcfv] [--recursive] [--changes] [--silent] [--quiet]\n\
|
||||
[--verbose] [user][:.][group] file...\n",
|
||||
program_name);
|
||||
exit (1);
|
||||
uid_t user = (uid_t) -1; /* New uid; -1 if not to be changed. */
|
||||
gid_t group = (uid_t) -1; /* New gid; -1 if not to be changed. */
|
||||
int errors = 0;
|
||||
int optc;
|
||||
char *e;
|
||||
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
recurse = force_silent = verbose = changes_only = 0;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "Rcfv", long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'R':
|
||||
recurse = 1;
|
||||
break;
|
||||
case 'c':
|
||||
verbose = 1;
|
||||
changes_only = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force_silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
{
|
||||
printf ("chown - %s\n", version_string);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (show_help)
|
||||
usage (0);
|
||||
|
||||
if (optind >= argc - 1)
|
||||
{
|
||||
error (0, 0, _("too few arguments"));
|
||||
usage (1);
|
||||
}
|
||||
|
||||
e = parse_user_spec (argv[optind], &user, &group, &username, &groupname);
|
||||
if (e)
|
||||
error (1, 0, "%s: %s", argv[optind], e);
|
||||
if (username == NULL)
|
||||
username = "";
|
||||
|
||||
for (++optind; optind < argc; ++optind)
|
||||
{
|
||||
strip_trailing_slashes (argv[optind]);
|
||||
errors |= change_file_owner (argv[optind], user, group);
|
||||
}
|
||||
|
||||
exit (errors);
|
||||
}
|
||||
|
||||
94
src/cksum.c
94
src/cksum.c
@@ -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>
|
||||
@@ -103,13 +105,30 @@ main ()
|
||||
#else /* !CRCTAB */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#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;
|
||||
|
||||
/* If nonzero, display usage information and exit. */
|
||||
static int show_help;
|
||||
|
||||
/* If nonzero, print the version on standard output then exit. */
|
||||
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 unsigned long const crctab[256] =
|
||||
{
|
||||
@@ -167,9 +186,6 @@ static unsigned long const crctab[256] =
|
||||
0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
|
||||
};
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
/* Nonzero if any of the files read were the standard input. */
|
||||
static int have_read_stdin;
|
||||
|
||||
@@ -179,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;
|
||||
@@ -244,27 +258,71 @@ cksum (file, print_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
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 (int argc, char **argv)
|
||||
{
|
||||
int i, c;
|
||||
int errors = 0;
|
||||
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
have_read_stdin = 0;
|
||||
|
||||
if (argc == 1)
|
||||
while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
usage (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_version)
|
||||
{
|
||||
printf ("cksum - %s\n", version_string);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (show_help)
|
||||
usage (0);
|
||||
|
||||
if (optind >= argc)
|
||||
{
|
||||
if (cksum ("-", 0) < 0)
|
||||
errors = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int optind;
|
||||
|
||||
for (optind = 1; optind < argc; ++optind)
|
||||
if (cksum (argv[optind], 1) < 0)
|
||||
for (i = optind; i < argc; i++)
|
||||
if (cksum (argv[i], 1) < 0)
|
||||
errors = 1;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user