mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Compare commits
1616
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a964be6d2c | ||
|
|
dc30028e8a | ||
|
|
706276d54f | ||
|
|
ea5b20a895 | ||
|
|
bd6b22825f | ||
|
|
3d381dd6ba | ||
|
|
e8cbb7c5eb | ||
|
|
10162cff31 | ||
|
|
9b9e86aec0 | ||
|
|
0ac2d4e8b8 | ||
|
|
4e962c3513 | ||
|
|
7b1fc5e6e7 | ||
|
|
70e347a07f | ||
|
|
b665309b38 | ||
|
|
9427edfa27 | ||
|
|
a55c0eec2c | ||
|
|
1f60ba6137 | ||
|
|
7265e1844c | ||
|
|
73c988a2d5 | ||
|
|
87a8d2ef5c | ||
|
|
38e13cac21 | ||
|
|
cba8fade7e | ||
|
|
1f0e1ae558 | ||
|
|
a49a5c1300 | ||
|
|
42dcebdd3f | ||
|
|
e78a248db5 | ||
|
|
50d2a89e37 | ||
|
|
0f37b82f56 | ||
|
|
00fc993ecd | ||
|
|
e79d2757b0 | ||
|
|
2fe7772c28 | ||
|
|
b423c8e2e7 | ||
|
|
eda83fe3c2 | ||
|
|
343520487f | ||
|
|
082e61ea3f | ||
|
|
26a898ce71 | ||
|
|
fea67202f5 | ||
|
|
62cac52999 | ||
|
|
8af8d42f6b | ||
|
|
3660b809ee | ||
|
|
b79386490e | ||
|
|
2e3ee62c97 | ||
|
|
e976c1e0b9 | ||
|
|
ad18737c76 | ||
|
|
67ab5879ab | ||
|
|
744689d5d4 | ||
|
|
ecbd7a36ef | ||
|
|
ccf9238b52 | ||
|
|
4e7c905bf2 | ||
|
|
b129da97af | ||
|
|
c61e54decc | ||
|
|
27dd9ae9fc | ||
|
|
f2dfe41b43 | ||
|
|
9d236e38d1 | ||
|
|
28aaf63a39 | ||
|
|
dcd5b9ba5d | ||
|
|
724d700502 | ||
|
|
2197aaf139 | ||
|
|
cfb4c85341 | ||
|
|
62ad85efac | ||
|
|
b503a9bdf0 | ||
|
|
52bcec6f19 | ||
|
|
a75c6d7408 | ||
|
|
f4cb140d3c | ||
|
|
6ac124d56c | ||
|
|
a7a1fe81d6 | ||
|
|
e3009dc890 | ||
|
|
90eac804bf | ||
|
|
bd73645d91 | ||
|
|
0fd5828e8f | ||
|
|
719a5e9b6c | ||
|
|
c08ca7e5d3 | ||
|
|
725b1893d9 | ||
|
|
2dcc5d730d | ||
|
|
6877bab512 | ||
|
|
87c301151a | ||
|
|
374f9d1322 | ||
|
|
3cf2ea87c7 | ||
|
|
24c358ae24 | ||
|
|
b11054f214 | ||
|
|
0a92f3e597 | ||
|
|
a4d0a3e648 | ||
|
|
450b22b1bc | ||
|
|
212a5eed32 | ||
|
|
6dd6726e00 | ||
|
|
2836fb8111 | ||
|
|
cc79c2dd05 | ||
|
|
46e32530ef | ||
|
|
5aa9d015a2 | ||
|
|
23a2f21e97 | ||
|
|
e0dac163b0 | ||
|
|
ed4bb30bc9 | ||
|
|
ee5c35be73 | ||
|
|
e5bb07c7ed | ||
|
|
963553fa63 | ||
|
|
6894ac6cdc | ||
|
|
124a159bc9 | ||
|
|
95efa94b4c | ||
|
|
47a14c6a96 | ||
|
|
58eac067c7 | ||
|
|
450d529990 | ||
|
|
80b37ecb95 | ||
|
|
71c5b433e9 | ||
|
|
a9efb803af | ||
|
|
cda29f45ee | ||
|
|
7ef2721789 | ||
|
|
1f4c495902 | ||
|
|
83cab6e19f | ||
|
|
42aab7dff3 | ||
|
|
78f8d0eee3 | ||
|
|
196b5480cc | ||
|
|
2a1a2c1ac6 | ||
|
|
5109314672 | ||
|
|
3fda56775a | ||
|
|
f077738952 | ||
|
|
78fce0ecdc | ||
|
|
5d74d3d4a6 | ||
|
|
e70653fea8 | ||
|
|
b2c4b4594b | ||
|
|
a1fce657bc | ||
|
|
d0f1ad17b6 | ||
|
|
d1e9a109d8 | ||
|
|
46b5087c4c | ||
|
|
f938b54a68 | ||
|
|
021ba4d2ed | ||
|
|
e59c84c0ec | ||
|
|
3344f6a053 | ||
|
|
7d913f9481 | ||
|
|
974525a8de | ||
|
|
0a9175709b | ||
|
|
b2d1c5b99f | ||
|
|
346313d25e | ||
|
|
f9975905f0 | ||
|
|
42ecf1982d | ||
|
|
c3e15b16b9 | ||
|
|
2a92ef7fdf | ||
|
|
da29a0b856 | ||
|
|
6b605b9c1a | ||
|
|
20d40aef90 | ||
|
|
744b9254bb | ||
|
|
b4a03676c0 | ||
|
|
63a9889802 | ||
|
|
c557084ecd | ||
|
|
6dc70c1a90 | ||
|
|
fa5a092898 | ||
|
|
cf317c3226 | ||
|
|
66a2fbdcf3 | ||
|
|
b7e06c2871 | ||
|
|
c817403b25 | ||
|
|
ab7efc62a5 | ||
|
|
d7680ac351 | ||
|
|
83160a94c3 | ||
|
|
31cc3a5c56 | ||
|
|
3e413989d1 | ||
|
|
6d4d16989b | ||
|
|
8f96f8d9dc | ||
|
|
b1e3a2ca55 | ||
|
|
9fafa5b55b | ||
|
|
804dc4707a | ||
|
|
583be38487 | ||
|
|
6c9cdc988c | ||
|
|
6ef5cfa19d | ||
|
|
fcb0e2d463 | ||
|
|
97d64b052b | ||
|
|
bd175b9445 | ||
|
|
25ccfd73dd | ||
|
|
481d3372c2 | ||
|
|
dcd49ea29b | ||
|
|
729f4472b2 | ||
|
|
61110af19a | ||
|
|
e96b211bc2 | ||
|
|
17cb33ade5 | ||
|
|
b0857cf5d9 | ||
|
|
076f5c13d1 | ||
|
|
8f0379148f | ||
|
|
e8ee1b1413 | ||
|
|
40a4c6d434 | ||
|
|
2a4696d896 | ||
|
|
0c56bab446 | ||
|
|
abf9d14c72 | ||
|
|
46d3c97e66 | ||
|
|
443a8c25d1 | ||
|
|
3264931df9 | ||
|
|
7aed3c61f5 | ||
|
|
26c4d5a017 | ||
|
|
cb38e6c7ff | ||
|
|
95d2558bd4 | ||
|
|
e65b696ab5 | ||
|
|
ee6a4f5f57 | ||
|
|
033d8e7a3e | ||
|
|
4251d087b3 | ||
|
|
32ad25520c | ||
|
|
e0f65104be | ||
|
|
959003b42f | ||
|
|
8307b732b3 | ||
|
|
e9ddc9edcf | ||
|
|
52a85ef4ff | ||
|
|
2eba555b9c | ||
|
|
836db5992c | ||
|
|
04d396a55f | ||
|
|
9b54ae5632 | ||
|
|
bb90379156 | ||
|
|
94d1478564 | ||
|
|
c3b5cba32f | ||
|
|
dacc8db399 | ||
|
|
28e4736c5a | ||
|
|
9a6e97f0c0 | ||
|
|
94511e52c7 | ||
|
|
f88ea02a10 | ||
|
|
26947b4288 | ||
|
|
378656c2ba | ||
|
|
34937f7b56 | ||
|
|
dceb3eda96 | ||
|
|
6b579a7276 | ||
|
|
4c1a559200 | ||
|
|
8e53f39053 | ||
|
|
7e45650fd3 | ||
|
|
c413b7a76b | ||
|
|
5ddeab1625 | ||
|
|
dc81f49071 | ||
|
|
4d209f48cf | ||
|
|
02821588bd | ||
|
|
923caadcbd | ||
|
|
92c55c4389 | ||
|
|
f3793b88fa | ||
|
|
1f978f3571 | ||
|
|
1c5912a06e | ||
|
|
437b7bee1b | ||
|
|
8f0d65b2f6 | ||
|
|
a460d39629 | ||
|
|
63d5d13fdf | ||
|
|
5e06a95bc3 | ||
|
|
df331198b2 | ||
|
|
ff0b720ced | ||
|
|
afcc676b55 | ||
|
|
996bc59c64 | ||
|
|
256d6c4af5 | ||
|
|
72d930e81e | ||
|
|
c3a9ff919e | ||
|
|
d3805793d1 | ||
|
|
7187fcea9f | ||
|
|
63190dd5af | ||
|
|
7e8fdbf995 | ||
|
|
8c6a7ca6cb | ||
|
|
1552f65c1b | ||
|
|
2265fa2e37 | ||
|
|
5b54f318b3 | ||
|
|
d98be20460 | ||
|
|
e9fd3cc02f | ||
|
|
0db96370f6 | ||
|
|
40af4470dc | ||
|
|
39a5a01e1e | ||
|
|
e1811eedfb | ||
|
|
7ee95268b1 | ||
|
|
b8208390d6 | ||
|
|
b9c57fd923 | ||
|
|
ce9f1403ec | ||
|
|
cdcfcede28 | ||
|
|
5228fba672 | ||
|
|
a7ea07cd8d | ||
|
|
791a870513 | ||
|
|
4d92c58cb4 | ||
|
|
5bc9481d42 | ||
|
|
e6d0854e13 | ||
|
|
8b0561f190 | ||
|
|
de4bebdf7b | ||
|
|
1dbc97bf4c | ||
|
|
7ff4ba0de1 | ||
|
|
7ee0b4f7b1 | ||
|
|
12013ebd2c | ||
|
|
551d294924 | ||
|
|
6a5a88d1df | ||
|
|
887eb398a8 | ||
|
|
cbbcd6a92c | ||
|
|
5fea23d46f | ||
|
|
36ce76e69a | ||
|
|
43d82bbbee | ||
|
|
f50998bd4b | ||
|
|
bf28989c2b | ||
|
|
848f374e3d | ||
|
|
56b00f61b3 | ||
|
|
10c37b91f1 | ||
|
|
b8e902937a | ||
|
|
93fc58e7da | ||
|
|
b309c41436 | ||
|
|
f4e6c5f84d | ||
|
|
0efcbc1350 | ||
|
|
b5bdeb1afc | ||
|
|
fdde763ed7 | ||
|
|
00c1f35eea | ||
|
|
9854a0793c | ||
|
|
629b2937a1 | ||
|
|
54c1c1aacb | ||
|
|
3df48b4b47 | ||
|
|
2881e1ac5e | ||
|
|
9f36a9c67a | ||
|
|
fe8e91db96 | ||
|
|
721cd8e17c | ||
|
|
73a7d22d3d | ||
|
|
4055dc96a3 | ||
|
|
5a9685c245 | ||
|
|
184100f266 | ||
|
|
763c7aad18 | ||
|
|
b78a4af76e | ||
|
|
52ae3f5bab | ||
|
|
b45b3911b5 | ||
|
|
edd76eaa18 | ||
|
|
fbcdf636e1 | ||
|
|
2645dd1013 | ||
|
|
e7114ef0e1 | ||
|
|
3af5512b7b | ||
|
|
b2bb34bdca | ||
|
|
da254dfc21 | ||
|
|
06b15c6416 | ||
|
|
e9e9c198fc | ||
|
|
ce64f535c2 | ||
|
|
737545b140 | ||
|
|
a7e26c5339 | ||
|
|
231b7f9b4a | ||
|
|
ab7e81a486 | ||
|
|
0dcc861b81 | ||
|
|
a29ac6b0c9 | ||
|
|
8dc04b7e26 | ||
|
|
bf5e7d2875 | ||
|
|
0a67393d4a | ||
|
|
1e6433e1a3 | ||
|
|
977425bc56 | ||
|
|
78e61d468b | ||
|
|
4cbbf884d4 | ||
|
|
d87e7e14ed | ||
|
|
a0bdf11637 | ||
|
|
557a640a9b | ||
|
|
f9692fa078 | ||
|
|
db8c2ff864 | ||
|
|
d9ad8d5843 | ||
|
|
d048a217c0 | ||
|
|
df556fbf3e | ||
|
|
f8cce538b1 | ||
|
|
ae6ab690f8 | ||
|
|
bf6d711fd0 | ||
|
|
a0c7f455ba | ||
|
|
7071d16e96 | ||
|
|
94cb5b63f2 | ||
|
|
5a5cb9d267 | ||
|
|
27888b02c7 | ||
|
|
2c569c0da5 | ||
|
|
771a487e8b | ||
|
|
3b862d9e44 | ||
|
|
6f66be2e19 | ||
|
|
701aa2303e | ||
|
|
d2325b6c39 | ||
|
|
4667c82218 | ||
|
|
a38a9833ad | ||
|
|
ad2443fdda | ||
|
|
5cbf51af5f | ||
|
|
bec723d71a | ||
|
|
1252806759 | ||
|
|
a914f21190 | ||
|
|
b2f59c1dc1 | ||
|
|
c8059ba46d | ||
|
|
b545bdc0df | ||
|
|
1247f4a751 | ||
|
|
123159a007 | ||
|
|
2c8609be2e | ||
|
|
4901b526d8 | ||
|
|
4d1ed1560f | ||
|
|
ed85262720 | ||
|
|
0b8e60d5b2 | ||
|
|
5d0e6f26ab | ||
|
|
06bc5adf33 | ||
|
|
03f45b885c | ||
|
|
e6684dbb9d | ||
|
|
209a6f5a68 | ||
|
|
f8c4dd457f | ||
|
|
d05cd64b43 | ||
|
|
1083e477fe | ||
|
|
b5a7a55d08 | ||
|
|
5f543405de | ||
|
|
ec805cae0d | ||
|
|
2e649496c1 | ||
|
|
e56355504e | ||
|
|
ad57d45b78 | ||
|
|
af494413a4 | ||
|
|
7a535a693b | ||
|
|
966528b5f2 | ||
|
|
ef4bca0bf6 | ||
|
|
50a88cdd3b | ||
|
|
7b2a5ca673 | ||
|
|
08aac9ca4c | ||
|
|
81eed8b85b | ||
|
|
6cfec0d1e0 | ||
|
|
5c7450e87c | ||
|
|
bf901a4dbf | ||
|
|
f446e0805c | ||
|
|
cdd3a9648d | ||
|
|
bb289120b3 | ||
|
|
a87ccd369e | ||
|
|
da4a74e382 | ||
|
|
7d7515836f | ||
|
|
d39385e84d | ||
|
|
4cfe61fd87 | ||
|
|
27ddb0d5db | ||
|
|
c2649bd905 | ||
|
|
7a1c2a40e1 | ||
|
|
568fd2f6bb | ||
|
|
69e33ecb3a | ||
|
|
c72e366670 | ||
|
|
384f95dcd9 | ||
|
|
ce611ff881 | ||
|
|
06e934645d | ||
|
|
6bf0cb5d3a | ||
|
|
47bfd35ff0 | ||
|
|
aa69c7f0ec | ||
|
|
44d9d36741 | ||
|
|
375068e4de | ||
|
|
dd7ad53bc1 | ||
|
|
867b68e401 | ||
|
|
c61cd1a832 | ||
|
|
f571de6489 | ||
|
|
81772b59e0 | ||
|
|
9cca497a9d | ||
|
|
9b3422d6e4 | ||
|
|
eef5b4dfd5 | ||
|
|
d2aa485211 | ||
|
|
7a69a52439 | ||
|
|
ecba3b861a | ||
|
|
f97505514d | ||
|
|
ee99765c76 | ||
|
|
75e8ac38b1 | ||
|
|
118e0424c9 | ||
|
|
229eea0db6 | ||
|
|
91c6aab4d6 | ||
|
|
873c7968ec | ||
|
|
a904106e1c | ||
|
|
bdef1367a0 | ||
|
|
b9c7e39ae8 | ||
|
|
10c1242d8e | ||
|
|
e03ee5debd | ||
|
|
ec338b964a | ||
|
|
10618f4020 | ||
|
|
70629e46f0 | ||
|
|
b5d4a42dbe | ||
|
|
756c2616b8 | ||
|
|
b3db32c3d9 | ||
|
|
cd1a41b26b | ||
|
|
e7e3cef62b | ||
|
|
c24432e6f0 | ||
|
|
191eb32cbd | ||
|
|
c41a56466e | ||
|
|
3383f19d6b | ||
|
|
b24278a2e0 | ||
|
|
c65eded03b | ||
|
|
0719608a61 | ||
|
|
85ffb74447 | ||
|
|
595099b414 | ||
|
|
3aee87a881 | ||
|
|
7f748e6367 | ||
|
|
13c7715f7b | ||
|
|
8e2d8ce245 | ||
|
|
a846081312 | ||
|
|
aed6a96c48 | ||
|
|
2390f50b84 | ||
|
|
7d9490d9df | ||
|
|
ee8762a725 | ||
|
|
3d1ecd9f80 | ||
|
|
eef6e7d85e | ||
|
|
ee2ffd26e7 | ||
|
|
abff5f4e0f | ||
|
|
cdcf87294b | ||
|
|
9eb5672306 | ||
|
|
3ceb8741c8 | ||
|
|
31102137ca | ||
|
|
9ac958a865 | ||
|
|
ee8f5914ca | ||
|
|
ac31856e15 | ||
|
|
6564e96498 | ||
|
|
ceaf6abdb0 | ||
|
|
91becd249d | ||
|
|
2bd8ab81c5 | ||
|
|
9ae9824ae4 | ||
|
|
8d11ea018d | ||
|
|
c226261be4 | ||
|
|
a4f7e87717 | ||
|
|
92b807be17 | ||
|
|
442caf2729 | ||
|
|
c2447dfc70 | ||
|
|
f070f0d04e | ||
|
|
3be82adc64 | ||
|
|
860b4863a3 | ||
|
|
6515385ad3 | ||
|
|
9a86dd8ae7 | ||
|
|
b534d38ce2 | ||
|
|
733a48bba4 | ||
|
|
c0395a7dd2 | ||
|
|
6f4719ea02 | ||
|
|
83cb554141 | ||
|
|
953b7fa37f | ||
|
|
25360fe99c | ||
|
|
49da41564e | ||
|
|
92d99305d8 | ||
|
|
9142187c1c | ||
|
|
9c5a03ddee | ||
|
|
cc010aab96 | ||
|
|
15a12e9668 | ||
|
|
250d7106a2 | ||
|
|
60b5983773 | ||
|
|
3060b94fb5 | ||
|
|
d46de200d2 | ||
|
|
d5487070e0 | ||
|
|
bb38f026db | ||
|
|
50a48337bf | ||
|
|
fb3200d755 | ||
|
|
7b6a16ad37 | ||
|
|
f15b5b5940 | ||
|
|
394b56b7ca | ||
|
|
970f920a95 | ||
|
|
7b091a11f9 | ||
|
|
b4db493aec | ||
|
|
463c9adbf3 | ||
|
|
8632cdc383 | ||
|
|
663d601001 | ||
|
|
22fbec8206 | ||
|
|
14b2d19b1f | ||
|
|
a962db4085 | ||
|
|
2f309218d7 | ||
|
|
0cce866da6 | ||
|
|
28f40b79b7 | ||
|
|
ff6cbfa2f8 | ||
|
|
d25c830c8d | ||
|
|
4d5cde0e88 | ||
|
|
063e768fb6 | ||
|
|
bc2256ef17 | ||
|
|
71ceba7ff7 | ||
|
|
7b245619bb | ||
|
|
15f533b0f8 | ||
|
|
db1420d771 | ||
|
|
7994d3a6ce | ||
|
|
a564d9da25 | ||
|
|
b1ad650c95 | ||
|
|
29dfb4ec5e | ||
|
|
339f3b3bcf | ||
|
|
ac26ebc13c | ||
|
|
cf6f2c12ad | ||
|
|
b85dec9af3 | ||
|
|
0a6959fc0a | ||
|
|
4a59381a42 | ||
|
|
06cebea477 | ||
|
|
9f11634768 | ||
|
|
3657b038c7 | ||
|
|
1e7a3de465 | ||
|
|
9a30f89851 | ||
|
|
1da65dd7d0 | ||
|
|
792b0bd86d | ||
|
|
eee21bf447 | ||
|
|
b0702e3080 | ||
|
|
ef57b88fee | ||
|
|
4ef68ba7e7 | ||
|
|
b181aa2d1e | ||
|
|
36efbb4cdb | ||
|
|
4ff4df7b97 | ||
|
|
aac314c81e | ||
|
|
a4c59fe5eb | ||
|
|
fdb75ab25f | ||
|
|
02801e4d1b | ||
|
|
8108d5fc7e | ||
|
|
074c4338dc | ||
|
|
25e915c536 | ||
|
|
d634475991 | ||
|
|
09e1521e11 | ||
|
|
e3a30b0334 | ||
|
|
8b3ee53457 | ||
|
|
919d496eda | ||
|
|
e67f9f4aec | ||
|
|
8caba68982 | ||
|
|
04d2ac4233 | ||
|
|
f85a059834 | ||
|
|
2282bcf521 | ||
|
|
0ba4ef57c4 | ||
|
|
09d589d3c1 | ||
|
|
42656335a4 | ||
|
|
9e2c5c95c4 | ||
|
|
9078482b99 | ||
|
|
77c58b102c | ||
|
|
a198063ccc | ||
|
|
ff80c22866 | ||
|
|
7a601ea795 | ||
|
|
3a7ffea87f | ||
|
|
8c1b1a19ee | ||
|
|
487aacda9a | ||
|
|
2d3baae6dc | ||
|
|
32b12ab483 | ||
|
|
d9430d368c | ||
|
|
1528962d13 | ||
|
|
f2bcc56299 | ||
|
|
8707649c92 | ||
|
|
33a5c4260c | ||
|
|
86f6312a89 | ||
|
|
9440208b90 | ||
|
|
3460c6748c | ||
|
|
9a9d0b5d91 | ||
|
|
754e504d42 | ||
|
|
3af102fd40 | ||
|
|
047a79cc56 | ||
|
|
32f4d1f4c7 | ||
|
|
4a378e74d5 | ||
|
|
3b06c47a49 | ||
|
|
8a6ea4f96c | ||
|
|
4e3eee501a | ||
|
|
5848d02f29 | ||
|
|
3110f35b90 | ||
|
|
74b36d1cb2 | ||
|
|
dd4dddae84 | ||
|
|
8fae36cc6f | ||
|
|
a485fc643e | ||
|
|
2ce4c75797 | ||
|
|
e94060c94a | ||
|
|
81313c07b9 | ||
|
|
56d5d8700e | ||
|
|
09a76f4665 | ||
|
|
5199e0142e | ||
|
|
04c70f1a88 | ||
|
|
f164d253e5 | ||
|
|
67d7d6790b | ||
|
|
0155dbab71 | ||
|
|
0ec93aa429 | ||
|
|
5e4a04f5d5 | ||
|
|
30f9694c25 | ||
|
|
94ec6bec0c | ||
|
|
280796eef0 | ||
|
|
a94bacff8a | ||
|
|
139548a97e | ||
|
|
9484654df2 | ||
|
|
2a1d44f622 | ||
|
|
9d67f7c498 | ||
|
|
588d3b4e0d | ||
|
|
d8bf7d747f | ||
|
|
e153613ab0 | ||
|
|
1f0ba10b41 | ||
|
|
7121f47886 | ||
|
|
624ea18ac5 | ||
|
|
ebb1d7255f | ||
|
|
6d9ba1e6c5 | ||
|
|
a9190b69e5 | ||
|
|
6ae863c83e | ||
|
|
a5a95cfa05 | ||
|
|
b2c3854934 | ||
|
|
dcaf1f3604 | ||
|
|
54a61a2fd1 | ||
|
|
0066d5c87b | ||
|
|
749a51e804 | ||
|
|
995a1ebb0b | ||
|
|
c9cb94fb4b | ||
|
|
e0446b4df3 | ||
|
|
35c176ff83 | ||
|
|
46ff7cb0dc | ||
|
|
d17a1b532b | ||
|
|
48f5cb73c9 | ||
|
|
5348088fa8 | ||
|
|
d3e59a8f25 | ||
|
|
546d70e0ed | ||
|
|
c908e3b3cd | ||
|
|
cbafbfd70f | ||
|
|
3ddd8420dd | ||
|
|
96a3115d75 | ||
|
|
461b1a3bbe | ||
|
|
cbc6ce3995 | ||
|
|
6f02358d0c | ||
|
|
8dca31a768 | ||
|
|
ac365fd452 | ||
|
|
9bb4a95866 | ||
|
|
f325efaaa8 | ||
|
|
358c7ac1dc | ||
|
|
ba69801acb | ||
|
|
a3dc9d0d49 | ||
|
|
945478703f | ||
|
|
6fdceb7fc4 | ||
|
|
0976e378df | ||
|
|
ac01b81856 | ||
|
|
7c6e002bd5 | ||
|
|
a588b737ee | ||
|
|
12b9ffbb9b | ||
|
|
fa9e49dab8 | ||
|
|
d5c4e10f4b | ||
|
|
2e334a213f | ||
|
|
c72a3e5247 | ||
|
|
eda4480be0 | ||
|
|
593907b4d0 | ||
|
|
6b56f179d8 | ||
|
|
89efc37b28 | ||
|
|
b1a961edb8 | ||
|
|
2f62774cdd | ||
|
|
9a3a008e72 | ||
|
|
f3b39d17ad | ||
|
|
a28b7387be | ||
|
|
e3dbcf5374 | ||
|
|
0ceb54f0a7 | ||
|
|
decbe87c56 | ||
|
|
a4930c1643 | ||
|
|
915f59dafc | ||
|
|
d0c4b1ba87 | ||
|
|
6038fd0dfe | ||
|
|
0097e29672 | ||
|
|
00339489d8 | ||
|
|
e5ef2d3fd0 | ||
|
|
afb85591d2 | ||
|
|
59165f63b2 | ||
|
|
b86b8fe1d7 | ||
|
|
2db507dbfb | ||
|
|
3c95b47caa | ||
|
|
eb05dca747 | ||
|
|
03ffd6e9ca | ||
|
|
8cf71d59dc | ||
|
|
77e6a8817a | ||
|
|
076bb8ea6b | ||
|
|
0a2a364239 | ||
|
|
3063a96181 | ||
|
|
ed21836875 | ||
|
|
e1995c01d4 | ||
|
|
9bf18d2f2b | ||
|
|
0a357eda0f | ||
|
|
c8ddb2dcb5 | ||
|
|
c46bdd4cc0 | ||
|
|
d1b2943563 | ||
|
|
5f1fd1a636 | ||
|
|
58ea5cbcfc | ||
|
|
f642f5eb06 | ||
|
|
a27520aae1 | ||
|
|
07a1f58444 | ||
|
|
e3a4328970 | ||
|
|
555216ed29 | ||
|
|
4f9b2f139e | ||
|
|
164dca0cb9 | ||
|
|
ae436a5b0e | ||
|
|
642bf4ae05 | ||
|
|
876d82a959 | ||
|
|
c48cb91608 | ||
|
|
5ad4631147 | ||
|
|
f599a69858 | ||
|
|
cc9a153647 | ||
|
|
e89906b676 | ||
|
|
9ea44cf9cc | ||
|
|
4b3fc74024 | ||
|
|
724de9a4fb | ||
|
|
b58448d849 | ||
|
|
0c763d0af9 | ||
|
|
b5629377de | ||
|
|
0d3e1704ed | ||
|
|
6bc75c32bc | ||
|
|
c155b0ad3c | ||
|
|
9a25c6d335 | ||
|
|
19615d268a | ||
|
|
aad54e571c | ||
|
|
2729f4526f | ||
|
|
8642ad5e72 | ||
|
|
b4de1302e9 | ||
|
|
26793cef6e | ||
|
|
777f6346bd | ||
|
|
064cea0b96 | ||
|
|
e308a562bb | ||
|
|
a68aad8392 | ||
|
|
97f98462a8 | ||
|
|
e659f15a71 | ||
|
|
d19818594b | ||
|
|
9494821b38 | ||
|
|
674a247434 | ||
|
|
6f2204ec84 | ||
|
|
2df915fe2d | ||
|
|
05cc4fc42b | ||
|
|
e97d59550e | ||
|
|
f4a4e55900 | ||
|
|
f7cf24b266 | ||
|
|
80d6348ece | ||
|
|
2e4ffa3f74 | ||
|
|
37e53f0291 | ||
|
|
e5167cf6f3 | ||
|
|
44ca7bef1c | ||
|
|
b1cea3d85f | ||
|
|
d05e2d56c6 | ||
|
|
e386e73546 | ||
|
|
91368684b7 | ||
|
|
7a8af3795c | ||
|
|
890e32b21d | ||
|
|
2932cf65b6 | ||
|
|
dbbc395010 | ||
|
|
59c5eb6d7d | ||
|
|
9eb6c7a4f9 | ||
|
|
b93e3bd7c9 | ||
|
|
6e0b5a1d0f | ||
|
|
0de8efd2e9 | ||
|
|
fe08d50e3e | ||
|
|
af8892ca63 | ||
|
|
106faf402a | ||
|
|
61577ad971 | ||
|
|
b7aaa05bb9 | ||
|
|
4e10331a2d | ||
|
|
d28d23f0c3 | ||
|
|
0aea79b735 | ||
|
|
292b25347a | ||
|
|
fd38af6891 | ||
|
|
8d3534426f | ||
|
|
eb32c14127 | ||
|
|
3f3e152142 | ||
|
|
5577a0cd97 | ||
|
|
bd90d99ff9 | ||
|
|
59b7a874b7 | ||
|
|
c555f68b93 | ||
|
|
f96edbbdf7 | ||
|
|
029c17c4bf | ||
|
|
72a905bb5a | ||
|
|
f2327ea33a | ||
|
|
6e25b83a10 | ||
|
|
7ecfce6d8c | ||
|
|
698fb3cecd | ||
|
|
d8cb367423 | ||
|
|
77e2301643 | ||
|
|
84ed0cec48 | ||
|
|
85fa479083 | ||
|
|
8a0439de62 | ||
|
|
453a5b8c71 | ||
|
|
759c9424ba | ||
|
|
6e2de6f842 | ||
|
|
d4840d255c | ||
|
|
fe3e11179c | ||
|
|
3af2ea02b0 | ||
|
|
4a4d5adc9f | ||
|
|
d945674ac7 | ||
|
|
7c3c9173da | ||
|
|
8df7dce672 | ||
|
|
54c89f7728 | ||
|
|
843966b97e | ||
|
|
dbc1b0b4eb | ||
|
|
34388d7059 | ||
|
|
b60f35f5e8 | ||
|
|
8895937130 | ||
|
|
31b362f410 | ||
|
|
cdbae149df | ||
|
|
835e27304f | ||
|
|
c049bc436c | ||
|
|
875638bb16 | ||
|
|
2cb84d580d | ||
|
|
b6b88e4892 | ||
|
|
ae2b1b1bf4 | ||
|
|
412c792a12 | ||
|
|
ec99425c57 | ||
|
|
bd9f6bc2ae | ||
|
|
fc7abe829c | ||
|
|
71da5b4fdc | ||
|
|
d6ded6941e | ||
|
|
c2760e4f6a | ||
|
|
c56f9ceb38 | ||
|
|
504bd512cb | ||
|
|
5eb5e892bd | ||
|
|
30432979cc | ||
|
|
ad8c9711b0 | ||
|
|
063528928b | ||
|
|
598b9ebaa7 | ||
|
|
2d0b10de3c | ||
|
|
d8ca4776ae | ||
|
|
c4bb5b297c | ||
|
|
10df6c93a6 | ||
|
|
c2a0ce080e | ||
|
|
f93d068772 | ||
|
|
b686364452 | ||
|
|
1190f5ed6d | ||
|
|
cbbf378f6a | ||
|
|
7864852d8b | ||
|
|
ee6c4a6172 | ||
|
|
5720e2761b | ||
|
|
e716019251 | ||
|
|
ee14f23695 | ||
|
|
cd67ecf46a | ||
|
|
59a43a56fe | ||
|
|
bcbdc6452f | ||
|
|
5fb2f505a6 | ||
|
|
e4d60cc53a | ||
|
|
9e8b821520 | ||
|
|
1b0a34e4bd | ||
|
|
7b381be68f | ||
|
|
32d8173ae7 | ||
|
|
546b52af6c | ||
|
|
ccf0ec128c | ||
|
|
e7c45a4cab | ||
|
|
b7734b7cec | ||
|
|
a29b2971b9 | ||
|
|
591edda266 | ||
|
|
3ca5f13a43 | ||
|
|
912bdd1b05 | ||
|
|
1f7f22843a | ||
|
|
da103a5a53 | ||
|
|
bd25b92a9b | ||
|
|
69d58e6b24 | ||
|
|
617376495a | ||
|
|
9a5766cadc | ||
|
|
009e260ce3 | ||
|
|
ab1198ee60 | ||
|
|
a332545726 | ||
|
|
7956004626 | ||
|
|
be17c8808b | ||
|
|
fd61824c56 | ||
|
|
5e7a9d54b5 | ||
|
|
8504f73ad2 | ||
|
|
ea358e2604 | ||
|
|
fa9be106cc | ||
|
|
7f2ac632a2 | ||
|
|
e26b801dbf | ||
|
|
50d2915314 | ||
|
|
51e0667460 | ||
|
|
d756773b47 | ||
|
|
623d55aca0 | ||
|
|
4d88951380 | ||
|
|
8ee9d5ed5b | ||
|
|
854a42b2c9 | ||
|
|
c7431897f8 | ||
|
|
1e1f9d2651 | ||
|
|
fb958785e1 | ||
|
|
7aaf6e8b27 | ||
|
|
b08ea31439 | ||
|
|
6a332fec63 | ||
|
|
27021c2b48 | ||
|
|
397d0d5ad5 | ||
|
|
f7a569df34 | ||
|
|
6dc4f852cc | ||
|
|
cb61625dfc | ||
|
|
0b90c122f6 | ||
|
|
187ed9f7fb | ||
|
|
0057ff3e7a | ||
|
|
6e78189bb0 | ||
|
|
49d964b040 | ||
|
|
47f52fcf47 | ||
|
|
a14c2def4f | ||
|
|
4a2f67e9e7 | ||
|
|
5fd9412aa9 | ||
|
|
8939328872 | ||
|
|
f075597652 | ||
|
|
4a76f35d50 | ||
|
|
402753e637 | ||
|
|
18c00c7317 | ||
|
|
e9e2fe89b2 | ||
|
|
10d00bb005 | ||
|
|
f7adedd55b | ||
|
|
ba5376dbfd | ||
|
|
9c42318277 | ||
|
|
7b2be49518 | ||
|
|
0c9a355456 | ||
|
|
61e1bd658f | ||
|
|
cc90b38301 | ||
|
|
c7d29e58fa | ||
|
|
1e8f7bc85e | ||
|
|
abdb48432b | ||
|
|
e53d5aa0b6 | ||
|
|
b7526ea4ba | ||
|
|
32807f2fe8 | ||
|
|
43cde79801 | ||
|
|
b66e4a0869 | ||
|
|
785a6e7b79 | ||
|
|
0c58d4e8c5 | ||
|
|
ad79a245db | ||
|
|
1623195bae | ||
|
|
d549c74d98 | ||
|
|
0f0bd6baa2 | ||
|
|
b28a601642 | ||
|
|
100df8a86a | ||
|
|
d0646ae734 | ||
|
|
8ef680403f | ||
|
|
3509e75baa | ||
|
|
4c3d2121b1 | ||
|
|
f021a6ac4d | ||
|
|
e13f070e00 | ||
|
|
564545771a | ||
|
|
f3706c3fc0 | ||
|
|
7fbcba63e8 | ||
|
|
d72a616340 | ||
|
|
51f7a10b57 | ||
|
|
d2b6b104a8 | ||
|
|
a7ae432439 | ||
|
|
85bdbd0051 | ||
|
|
855f42f529 | ||
|
|
2bd1b92196 | ||
|
|
1149f976ef | ||
|
|
4baef56164 | ||
|
|
f7646dedad | ||
|
|
e0245b7de1 | ||
|
|
da0f4fe0ff | ||
|
|
16759191a0 | ||
|
|
0c0a5a3b18 | ||
|
|
20f6e02b59 | ||
|
|
48bfc63c45 | ||
|
|
7783998e1f | ||
|
|
236555d112 | ||
|
|
45a7c05453 | ||
|
|
2483622648 | ||
|
|
b0642a9da5 | ||
|
|
17e87df543 | ||
|
|
33e89f27e9 | ||
|
|
a532895a91 | ||
|
|
b468d8d5b4 | ||
|
|
3aa0904c7b | ||
|
|
55c1466131 | ||
|
|
c31e42c405 | ||
|
|
942c28c2a0 | ||
|
|
69fe290f2f | ||
|
|
07df56528c | ||
|
|
01b42d297e | ||
|
|
8c01173586 | ||
|
|
94ad550a5b | ||
|
|
b8de45ec52 | ||
|
|
811fd9b8db | ||
|
|
f19e5fde61 | ||
|
|
1cb21bb950 | ||
|
|
f7cc82e8ed | ||
|
|
f8a2fadabc | ||
|
|
06aaddc4df | ||
|
|
0e04122322 | ||
|
|
f876d2fa87 | ||
|
|
95e1659f9f | ||
|
|
342775c738 | ||
|
|
a13f5c9826 | ||
|
|
c11c4fe22e | ||
|
|
ba25c69485 | ||
|
|
ca308852b5 | ||
|
|
2528a53103 | ||
|
|
0ff367fc6a | ||
|
|
b942e3cd58 | ||
|
|
6fa7068c78 | ||
|
|
a90f6d6691 | ||
|
|
03299bf1a3 | ||
|
|
2aab88f043 | ||
|
|
64e9d65bf4 | ||
|
|
d56e6910f1 | ||
|
|
a0205d9c58 | ||
|
|
ca3b0034c0 | ||
|
|
eaa3023f5a | ||
|
|
a4ccf50ddc | ||
|
|
462f214932 | ||
|
|
9075203591 | ||
|
|
2fc540877c | ||
|
|
9c9f50ee8a | ||
|
|
221eaac980 | ||
|
|
a83aac64b9 | ||
|
|
87404aea88 | ||
|
|
933e895f05 | ||
|
|
6f647648ab | ||
|
|
ba8d6ee8ff | ||
|
|
a7e50b58cd | ||
|
|
d7b2ac81af | ||
|
|
403d524e65 | ||
|
|
1398ac3bc4 | ||
|
|
1efb48b740 | ||
|
|
f806c1b8ed | ||
|
|
6ab8eeb2e8 | ||
|
|
7304b47e24 | ||
|
|
411c5f8623 | ||
|
|
20c7d4e51e | ||
|
|
b4b8f590b2 | ||
|
|
59a9e52176 | ||
|
|
b2b5d1ddc8 | ||
|
|
9564f73354 | ||
|
|
36c73e6f47 | ||
|
|
22ee0c02b1 | ||
|
|
eafb3a7fbe | ||
|
|
b102d331ae | ||
|
|
22c021810f | ||
|
|
c899f7a75a | ||
|
|
4d624caf8b | ||
|
|
fdfe4c76bb | ||
|
|
16f80df95c | ||
|
|
e95e9158d3 | ||
|
|
3c971919cd | ||
|
|
98dcccd66b | ||
|
|
de23d8e771 | ||
|
|
b749837d0f | ||
|
|
198e2844e9 | ||
|
|
0203725632 | ||
|
|
14df5884cb | ||
|
|
e1bdbc8581 | ||
|
|
a3595a68e1 | ||
|
|
3ebc719d74 | ||
|
|
19513c6725 | ||
|
|
fae2f1c3ce | ||
|
|
361acf3ea1 | ||
|
|
92fc5ceb19 | ||
|
|
53ef40deb9 | ||
|
|
b5cdf7af71 | ||
|
|
917b4d7bc3 | ||
|
|
ac1ab41bf0 | ||
|
|
df1244c823 | ||
|
|
03ee8c31fd | ||
|
|
97d3caf4d5 | ||
|
|
36d3587c0a | ||
|
|
ef6bb44479 | ||
|
|
38edf5fefc | ||
|
|
aa9d2024c8 | ||
|
|
952f87f595 | ||
|
|
fb1147df5c | ||
|
|
b6b7e948ab | ||
|
|
ce66d39032 | ||
|
|
89b6ebf5ce | ||
|
|
cad3353083 | ||
|
|
3db83ddcfb | ||
|
|
7fc161b5a2 | ||
|
|
d565578c64 | ||
|
|
8584b01041 | ||
|
|
99cea52065 | ||
|
|
f78a7fb563 | ||
|
|
d7f7a9df9d | ||
|
|
5b049b964d | ||
|
|
1416fc99b4 | ||
|
|
f891be9e4c | ||
|
|
60aa8cbc73 | ||
|
|
865e2fe152 | ||
|
|
e08632a245 | ||
|
|
f6653e807e | ||
|
|
979a383ec4 | ||
|
|
4ce91c332a | ||
|
|
f595b06231 | ||
|
|
110eb90512 | ||
|
|
80a70ba6d2 | ||
|
|
f077241f1a | ||
|
|
ebf0cc0e63 | ||
|
|
924e430c97 | ||
|
|
774a47dd97 | ||
|
|
d4b2a629ae | ||
|
|
0dd39cc3d0 | ||
|
|
7d10c049cb | ||
|
|
d59571a208 | ||
|
|
bfaaf37635 | ||
|
|
c6658deac3 | ||
|
|
d5feec0a94 | ||
|
|
db7a666366 | ||
|
|
742ea4d09b | ||
|
|
8ac7aefaec | ||
|
|
b5db2ba985 | ||
|
|
83431df74f | ||
|
|
dfd960278c | ||
|
|
e20b2507cf | ||
|
|
af7c1500f5 | ||
|
|
ee8dc4da91 | ||
|
|
8ca35daa1c | ||
|
|
309ed14654 | ||
|
|
85f115f1b9 | ||
|
|
6bc491a10b | ||
|
|
b02a64df75 | ||
|
|
64c1e066ba | ||
|
|
d63526fcc4 | ||
|
|
ae9f5eb96d | ||
|
|
89ddae5c57 | ||
|
|
de1aebbda5 | ||
|
|
bd0781e29b | ||
|
|
e2cba5ead7 | ||
|
|
e7b7b582f5 | ||
|
|
7e8e62d194 | ||
|
|
6f7b444f23 | ||
|
|
4a27f2a7d9 | ||
|
|
f84f311876 | ||
|
|
3e94418b8b | ||
|
|
0bf6ef3f3b | ||
|
|
5f8dad1f6c | ||
|
|
4b0f72d621 | ||
|
|
113af5c9f9 | ||
|
|
6508258a83 | ||
|
|
19a37a3d92 | ||
|
|
7cce85fc6d | ||
|
|
9428771d76 | ||
|
|
68539e05a9 | ||
|
|
aebf3fb531 | ||
|
|
2cd9d2e646 | ||
|
|
5db372b5d2 | ||
|
|
8649d988df | ||
|
|
2c4311b4a1 | ||
|
|
406ccf67c8 | ||
|
|
71e940f34f | ||
|
|
686b448e5a | ||
|
|
f0a9e505fa | ||
|
|
ad8efd3578 | ||
|
|
3b0e4a44bf | ||
|
|
0ec8c2a2e6 | ||
|
|
468a30f435 | ||
|
|
438ca8148b | ||
|
|
4458bab7e4 | ||
|
|
2a496f7d4d | ||
|
|
18bb3fbf07 | ||
|
|
fc34c50fd3 | ||
|
|
694d45d2f2 | ||
|
|
d8cbe8365f | ||
|
|
0d635ca4e8 | ||
|
|
84d10c2fdb | ||
|
|
97854f9e49 | ||
|
|
811074f9c9 | ||
|
|
7ab0aa0d63 | ||
|
|
523f885fce | ||
|
|
8f77f2580b | ||
|
|
4601daf795 | ||
|
|
71c26ce520 | ||
|
|
6443309308 | ||
|
|
3faec93675 | ||
|
|
935a4d612d | ||
|
|
300ef15de7 | ||
|
|
c488e05530 | ||
|
|
f1a8df5a98 | ||
|
|
22ffe61c4c | ||
|
|
6e0474e02c | ||
|
|
e1bcb45816 | ||
|
|
c074848b3d | ||
|
|
ed759edf27 | ||
|
|
c2bb147134 | ||
|
|
f42902bf42 | ||
|
|
8b5b171155 | ||
|
|
5f1c06922a | ||
|
|
9c8127832b | ||
|
|
9508383f56 | ||
|
|
2c19fdb00f | ||
|
|
31f17a3c1b | ||
|
|
46aae5e795 | ||
|
|
8f52f28a44 | ||
|
|
7efe193a09 | ||
|
|
89e6fbe778 | ||
|
|
39bf7e2118 | ||
|
|
df404cb995 | ||
|
|
13d41e9b33 | ||
|
|
fe72b4478e | ||
|
|
1530999a02 | ||
|
|
a2e9248b7b | ||
|
|
fff7401aa7 | ||
|
|
54665628cd | ||
|
|
6053092fc5 | ||
|
|
f704b120a1 | ||
|
|
ba915c8fff | ||
|
|
361de0cb49 | ||
|
|
da666b7277 | ||
|
|
aa9cd25462 | ||
|
|
383c30fcec | ||
|
|
ec9ca91281 | ||
|
|
8f3d06fb9d | ||
|
|
4903d68024 | ||
|
|
f8e3a307ea | ||
|
|
a089e96b58 | ||
|
|
27e61fdc3b | ||
|
|
c83030c354 | ||
|
|
2c13cd0c2c | ||
|
|
91605d38e1 | ||
|
|
ef17d7f8db | ||
|
|
8534aa3425 | ||
|
|
1a7232b6a7 | ||
|
|
6a0d63a761 | ||
|
|
0eb85fe209 | ||
|
|
7357841153 | ||
|
|
4fd162720e | ||
|
|
69e117554a | ||
|
|
e979ec36a4 | ||
|
|
940bf41701 | ||
|
|
6b1e17c021 | ||
|
|
b9c82157e5 | ||
|
|
b1d5dc4671 | ||
|
|
b99fb1a4a9 | ||
|
|
5750f844ff | ||
|
|
936b5f048e | ||
|
|
a1f69e620b | ||
|
|
7dec749f7c | ||
|
|
9784694ee8 | ||
|
|
01fce57322 | ||
|
|
c773e361ff | ||
|
|
f2a01ac966 | ||
|
|
694619707d | ||
|
|
6f20d624af | ||
|
|
abc2635848 | ||
|
|
95f2a89368 | ||
|
|
8707bb021a | ||
|
|
a7f6a73356 | ||
|
|
9441c78584 | ||
|
|
ede16bc486 | ||
|
|
6a970be1d8 | ||
|
|
1da792d5fd | ||
|
|
d5efaa17bc | ||
|
|
de82524415 | ||
|
|
8aaf137797 | ||
|
|
1b920f0606 | ||
|
|
157746d2d8 | ||
|
|
9f3197053a | ||
|
|
7606f1ff10 | ||
|
|
298ea9fe40 | ||
|
|
805593368c | ||
|
|
ae6c5a5c27 | ||
|
|
8750a3a8c1 | ||
|
|
56a184dcc8 | ||
|
|
8d10fd8b64 | ||
|
|
3171f6e34a | ||
|
|
a572115ece | ||
|
|
30f0abd359 | ||
|
|
273209f0cf | ||
|
|
8688c4b0de | ||
|
|
077388061b | ||
|
|
2cd2be9144 | ||
|
|
74419b1a54 | ||
|
|
3c6235a772 | ||
|
|
f87c43cdd1 | ||
|
|
0d05075b61 | ||
|
|
ec5c390c0a | ||
|
|
a76955039c | ||
|
|
587281bef7 | ||
|
|
aa553cbcda | ||
|
|
a560edcb0a | ||
|
|
d044cfd160 | ||
|
|
08a5ca91ce | ||
|
|
9dd10e5048 | ||
|
|
933d5c4a55 | ||
|
|
c620e49315 | ||
|
|
47fe690a6d | ||
|
|
7b9fa15fac | ||
|
|
5b41c79b48 | ||
|
|
3f795425aa | ||
|
|
5c91affcf3 | ||
|
|
f845ee2be0 | ||
|
|
9e951d5d29 | ||
|
|
eac2e0d3f0 | ||
|
|
df2186b330 | ||
|
|
0136cf15de | ||
|
|
465a2e5f4e | ||
|
|
081c7828fb | ||
|
|
9cc36f3ab2 | ||
|
|
ebbee1c436 | ||
|
|
10d17efe54 | ||
|
|
e991f82640 | ||
|
|
d5f85f0cf5 | ||
|
|
9a2c24dc92 | ||
|
|
0a4df4ff3e | ||
|
|
b6cf2d07e2 | ||
|
|
8c3c7e827f | ||
|
|
5129825f4f | ||
|
|
0e0843b9e5 | ||
|
|
1086d38605 | ||
|
|
5376f98cc2 | ||
|
|
56c4c60670 | ||
|
|
4ed2551a19 | ||
|
|
b251faf8e2 | ||
|
|
bf935ee7a5 | ||
|
|
0213b1b8a5 | ||
|
|
ad71a1730f | ||
|
|
0c5afc6039 | ||
|
|
52887e27dc | ||
|
|
4790499440 | ||
|
|
783fc18bd1 | ||
|
|
982b1a7dfd | ||
|
|
155b6543b4 | ||
|
|
51c443df58 | ||
|
|
44794dec4e | ||
|
|
a7cac79d4d | ||
|
|
a93dac9079 | ||
|
|
71339c22ac | ||
|
|
8d635de429 | ||
|
|
fb25e01363 | ||
|
|
b2080b34bf | ||
|
|
1a3663ae50 | ||
|
|
977181ec71 | ||
|
|
7526157367 | ||
|
|
992e658e7a | ||
|
|
5c28bce0d7 | ||
|
|
796c7dc313 | ||
|
|
3b88f15d03 | ||
|
|
400d244dc5 | ||
|
|
24611ae3ad | ||
|
|
3fd09d63b5 | ||
|
|
3e7455d7b1 | ||
|
|
9b69498bf3 | ||
|
|
7f04e80273 | ||
|
|
4a43ea40ac | ||
|
|
efa5476524 | ||
|
|
0d417f3793 | ||
|
|
a647efc716 | ||
|
|
9e3cdb66bb | ||
|
|
9217428c25 | ||
|
|
50b50e273d | ||
|
|
f0c9266e03 | ||
|
|
42db005878 | ||
|
|
7b33103575 | ||
|
|
a8486f7094 | ||
|
|
e7a6bca5da | ||
|
|
6531e0bf84 | ||
|
|
ee06e9bd92 | ||
|
|
d11a33163f | ||
|
|
5cd63cb32b | ||
|
|
b0e6606d68 | ||
|
|
28d3671674 | ||
|
|
28810cda29 | ||
|
|
e056a37322 | ||
|
|
1247b53994 | ||
|
|
798540aa11 | ||
|
|
e6231132e9 | ||
|
|
1ecd82ae8f | ||
|
|
01a21e2e11 | ||
|
|
bd99a86ff2 | ||
|
|
b89d73558e | ||
|
|
ecae928abc | ||
|
|
e4fce3019b | ||
|
|
e438a2d7a0 | ||
|
|
80a38f5d3e | ||
|
|
54a4e05e1a | ||
|
|
7920f61238 | ||
|
|
57fa93a128 | ||
|
|
c0eca48cdf | ||
|
|
099af5d7b7 | ||
|
|
db5478aa9a | ||
|
|
8353fe6eb2 | ||
|
|
f849628814 | ||
|
|
2e1d0f2abf | ||
|
|
02afb236f8 | ||
|
|
409c824fe7 | ||
|
|
1f6d634846 | ||
|
|
4b284350b5 | ||
|
|
c401563753 | ||
|
|
d1709153d6 | ||
|
|
e68be15e08 | ||
|
|
8e78e91f6c | ||
|
|
ce54545818 | ||
|
|
aa0d4aee37 | ||
|
|
2a877ab383 | ||
|
|
80b6b0e639 | ||
|
|
657ef5b05a | ||
|
|
45a7f4e9eb | ||
|
|
4f36945b70 | ||
|
|
cbd5b25a26 | ||
|
|
ecdc46edca | ||
|
|
26b6cfc406 | ||
|
|
0d6778e96f | ||
|
|
58d5d7c030 | ||
|
|
735adc7764 | ||
|
|
c094c84082 | ||
|
|
4600caf505 | ||
|
|
4f4dc46f11 | ||
|
|
1602dc778b | ||
|
|
72ea016eb2 | ||
|
|
786548060c | ||
|
|
7c1ac0f2e4 | ||
|
|
25b3732189 | ||
|
|
e04c32e724 | ||
|
|
74035caef8 | ||
|
|
79f416473f | ||
|
|
5d52243319 | ||
|
|
b6f20b870f | ||
|
|
4c96c22ad3 | ||
|
|
e9ee036b8e | ||
|
|
fed8b895c1 | ||
|
|
07544e75bc | ||
|
|
c443d2144c | ||
|
|
e43b81f846 | ||
|
|
e7dffd3105 | ||
|
|
e9a81f4378 | ||
|
|
1ef1874d8f | ||
|
|
82976da065 | ||
|
|
bc30cc731e | ||
|
|
93c58c517b | ||
|
|
0708736496 | ||
|
|
6410c81d68 | ||
|
|
e2b1107c58 | ||
|
|
93fae68b82 | ||
|
|
afce374225 | ||
|
|
c0f9b1dc1a | ||
|
|
3ebd4784d7 | ||
|
|
c9fdde545a | ||
|
|
0612667471 | ||
|
|
e15d9354d1 | ||
|
|
f0dfca3a7c | ||
|
|
6d8114ac20 | ||
|
|
3a11988a9b | ||
|
|
afee369a88 | ||
|
|
840fb64165 | ||
|
|
c4c6c339b7 | ||
|
|
56a43a65e8 | ||
|
|
5bdf93e090 | ||
|
|
8bf8ce58ac | ||
|
|
56955b4502 | ||
|
|
f79a7f6916 | ||
|
|
830e40d62c | ||
|
|
4c2800ded2 | ||
|
|
f843751d69 | ||
|
|
f6e07ddb89 | ||
|
|
c840113576 | ||
|
|
183eeae102 | ||
|
|
2abb019147 | ||
|
|
86d9039fb7 | ||
|
|
52da92f406 | ||
|
|
5cf73ea62e | ||
|
|
59367397fc | ||
|
|
300bf3fa50 | ||
|
|
be11ac7223 | ||
|
|
2470a988fd | ||
|
|
f1819d1cc6 | ||
|
|
d22aa59955 | ||
|
|
8c8f63e6d7 | ||
|
|
a2072fc5cc | ||
|
|
67be10ef73 | ||
|
|
ce7d1eb491 | ||
|
|
a8f574395c | ||
|
|
9fc98f3380 | ||
|
|
950f73b33d | ||
|
|
8bfdee54b9 | ||
|
|
6c5826fb40 | ||
|
|
615904db16 | ||
|
|
f9dec630bb | ||
|
|
b486cfcc69 | ||
|
|
e9224e67a0 | ||
|
|
b4d329f87b | ||
|
|
95cf6f3e27 | ||
|
|
04f49fec44 | ||
|
|
9704564693 | ||
|
|
68dfb4c2e3 | ||
|
|
6bb94d58e1 | ||
|
|
54c4f2d131 | ||
|
|
3c4cf1d028 | ||
|
|
aa1607ad5a | ||
|
|
1768cb447b | ||
|
|
f369721a98 | ||
|
|
2d5f671f95 | ||
|
|
971a0063d6 | ||
|
|
0f46afe406 | ||
|
|
fa309c5d17 | ||
|
|
e5de00b39f | ||
|
|
a41787837f | ||
|
|
16f9a9769a | ||
|
|
ac4831e4b9 | ||
|
|
c29f820217 | ||
|
|
fc21f54156 | ||
|
|
eff80b32fb | ||
|
|
03c6fe5078 | ||
|
|
736d87d799 | ||
|
|
6dd217fb64 | ||
|
|
ce9e2834a9 | ||
|
|
f3031dc1dd | ||
|
|
e4a9126488 | ||
|
|
9d0c327b80 | ||
|
|
99987baa90 | ||
|
|
2e6ad5be75 | ||
|
|
e1932339b5 | ||
|
|
4f6fa01059 | ||
|
|
96609c47d4 | ||
|
|
bc2d30eea4 | ||
|
|
f7816bb405 | ||
|
|
c1cd36ab9c | ||
|
|
124f186245 | ||
|
|
c2e1ffd0a0 | ||
|
|
668324cf66 | ||
|
|
669276e349 | ||
|
|
a842bcdbae | ||
|
|
60fffa9c54 | ||
|
|
c6015fe000 | ||
|
|
68e0539770 | ||
|
|
058b24af1b | ||
|
|
57606b34c8 | ||
|
|
c4c452a332 | ||
|
|
fbbd81efbd | ||
|
|
a1ebc84878 | ||
|
|
6bcb381c5c | ||
|
|
a06bbaf476 | ||
|
|
47412d7cb6 | ||
|
|
0753948cf0 | ||
|
|
ba8dcfc8f7 | ||
|
|
b7b695a389 | ||
|
|
f66055e511 | ||
|
|
4c1d243906 | ||
|
|
9849d03ef9 | ||
|
|
48c884b741 | ||
|
|
81f0479643 | ||
|
|
7a351c2158 | ||
|
|
9bd1ae9fb0 | ||
|
|
64f71965f8 | ||
|
|
38896db6e0 | ||
|
|
aa1089befb | ||
|
|
c1c4a981d5 | ||
|
|
c7983acd36 | ||
|
|
17ad08f628 | ||
|
|
ee012037df | ||
|
|
080027799d | ||
|
|
fd8f951e5a | ||
|
|
409febc1e4 | ||
|
|
f80c667d6e | ||
|
|
92b1a58036 | ||
|
|
c2c85a945d | ||
|
|
4e06750dce | ||
|
|
0794517534 | ||
|
|
60700b4ae6 | ||
|
|
a74d39ef0c | ||
|
|
76ff782b6f | ||
|
|
14dd88494c | ||
|
|
839fcf5634 | ||
|
|
d5bd67f7a9 | ||
|
|
545d727e69 | ||
|
|
b07f02d67c | ||
|
|
1992c65515 | ||
|
|
4cfe404eca | ||
|
|
41e117588f | ||
|
|
6d450870fc | ||
|
|
b635c6b302 | ||
|
|
8bdb41562a | ||
|
|
3ffb365ac0 | ||
|
|
67ea6a3b98 | ||
|
|
c4c4a69a45 | ||
|
|
eff15831c0 | ||
|
|
4641e28c8f | ||
|
|
6261970fb0 | ||
|
|
0a7d464a50 | ||
|
|
d281aade56 | ||
|
|
3bc3e3e7a0 | ||
|
|
882a774068 | ||
|
|
629f6b0bf2 | ||
|
|
e1a24d8124 | ||
|
|
98fe3299b5 | ||
|
|
3536cebfe7 | ||
|
|
8059c08edf | ||
|
|
636e8b707b | ||
|
|
8d89ba84f2 | ||
|
|
360c01d3ff | ||
|
|
1518f96ea4 | ||
|
|
a52267f5d2 | ||
|
|
11d9599263 | ||
|
|
48d99c98a4 | ||
|
|
0b079fd92f | ||
|
|
842f308487 |
No files matched your search
+9
-6
@@ -338,7 +338,7 @@ reinstall:
|
||||
# be set to cross-build, we have to make sure MACHINE is set
|
||||
# properly.
|
||||
|
||||
KERNEL?= GENERIC GENERIC98
|
||||
KERNEL?= GENERIC
|
||||
|
||||
# The only exotic MACHINE_ARCH/MACHINE combination valid at this
|
||||
# time is i386/pc98. In all other cases set MACHINE equal to
|
||||
@@ -378,14 +378,16 @@ buildkernel:
|
||||
@echo "--------------------------------------------------------------"
|
||||
.for _kernel in ${BUILDKERNELS}
|
||||
@echo "===> ${_kernel}"
|
||||
mkdir -p ${KRNLOBJDIR}
|
||||
cd ${KRNLCONFDIR}; \
|
||||
PATH=${TMPPATH} \
|
||||
config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} ${_kernel}
|
||||
cd ${KRNLOBJDIR}/${_kernel}; \
|
||||
MAKESRCPATH=${KRNLSRCDIR}/dev/aic7xxx \
|
||||
${MAKE} -f ${KRNLSRCDIR}/dev/aic7xxx/Makefile; \
|
||||
${WMAKEENV} MACHINE=${MACHINE} ${MAKE} depend; \
|
||||
${WMAKEENV} MACHINE=${MACHINE} ${MAKE} all
|
||||
${WMAKEENV} MACHINE=${MACHINE} KERNEL=${_kernel} \
|
||||
${MAKE} depend; \
|
||||
${WMAKEENV} MACHINE=${MACHINE} KERNEL=${_kernel} ${MAKE} all
|
||||
.endfor
|
||||
|
||||
#
|
||||
@@ -395,7 +397,8 @@ buildkernel:
|
||||
#
|
||||
installkernel:
|
||||
cd ${KRNLOBJDIR}/${INSTALLKERNEL}; \
|
||||
${IMAKEENV} MACHINE=${MACHINE} ${MAKE} install
|
||||
${IMAKEENV} MACHINE=${MACHINE} KERNEL=${INSTALLKERNEL} \
|
||||
${MAKE} install
|
||||
|
||||
#
|
||||
# update
|
||||
@@ -425,7 +428,7 @@ update:
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> Updating ${.CURDIR} from cvs repository" ${CVSROOT}
|
||||
@echo "--------------------------------------------------------------"
|
||||
cd ${.CURDIR}; cvs -q update -P -d
|
||||
cd ${.CURDIR}; cvs -q update -rRELENG_4 -P -d
|
||||
.endif
|
||||
|
||||
#
|
||||
@@ -485,7 +488,7 @@ _strfile= games/fortune/strfile
|
||||
|
||||
bootstrap-tools:
|
||||
.for _tool in ${_strfile} usr.bin/yacc usr.bin/colldef usr.sbin/config \
|
||||
gnu/usr.bin/texinfo
|
||||
gnu/usr.bin/gperf gnu/usr.bin/texinfo
|
||||
cd ${.CURDIR}/${_tool}; \
|
||||
${MAKE} obj; \
|
||||
${MAKE} depend; \
|
||||
|
||||
@@ -1,9 +1,128 @@
|
||||
Updating Information for FreeBSD current users
|
||||
Updating Information for FreeBSD STABLE users
|
||||
|
||||
This file is maintained by [email protected]. Please send new entries
|
||||
directly to him. See end of file for further details. For commonly
|
||||
done items, please see the end of the file. Search for 'COMMON
|
||||
ITEMS:'
|
||||
directly to him. See end of file for further details. A reverse
|
||||
chronology since 4.0 was released is included, followed by the common
|
||||
items quick how-tos, followed by entries for versions of -current
|
||||
prior to 4.0 Release.
|
||||
|
||||
20000724:
|
||||
FreeBSD 4.1 Released on or about this date.
|
||||
|
||||
20000711:
|
||||
If you use CVSUP or CTM to get CVS trees, AND you used to get
|
||||
the old crypto files from internat.freebsd.org AND you check
|
||||
out files from the CVS tree with the cvs command, please read
|
||||
http://people.freebsd.org/~imp/internat.txt
|
||||
for details on potential problems that you might have and how
|
||||
to get around them.
|
||||
|
||||
If you are merely a mirror, or don't answer yes to each of the
|
||||
clauses above, you needn't worry.
|
||||
|
||||
20000706:
|
||||
Binutils were updated. In order to build a kernel after this
|
||||
date, you must follow the updating procedure for building
|
||||
kernels exactly as presented here. You may be able to get away
|
||||
with doing it the old way, but if it breaks, make sure that you've
|
||||
tried the "To build a kernel" section with a fresh /usr/obj
|
||||
first.
|
||||
|
||||
20000622:
|
||||
The license on the softupdates is now a standard 2 clause
|
||||
BSD license. You may need to remove your symbolic links
|
||||
that used to be required when updating.
|
||||
|
||||
20000501:
|
||||
At approximately this date, an incompatible kernel change
|
||||
was made which means that if you update kernels accross
|
||||
this boundary, you also have to update modules, and vice
|
||||
versa.
|
||||
|
||||
20000315:
|
||||
FreeBSD 4.0 RELEASE. Historical entries follow the common
|
||||
items.
|
||||
|
||||
****************************** 4.0 RELEASE ******************************
|
||||
|
||||
COMMON ITEMS:
|
||||
|
||||
To build a kernel
|
||||
-----------------
|
||||
cd /usr/src
|
||||
# If you have not already done so, please buildworld here
|
||||
# You will also need to update your config file to 4.0. Usually
|
||||
# people tend to start with GENERIC from 4.0 and hack from there.
|
||||
make buildkernel KERNEL=<YOUR_KERNEL_HERE>
|
||||
make installkernel KERNEL=<YOUR_KERNEL_HERE>
|
||||
# Verify that the new kernel works, it will be installed as
|
||||
# /YOUR_KERNEL_HERE
|
||||
chflags noschg /kernel
|
||||
chflags noschg /YOUR_KERNEL_HERE
|
||||
mv /kernel /kernel.old
|
||||
mv /YOUR_KERNEL_HERE /kernel
|
||||
chflags schg /kernel
|
||||
|
||||
To rebuild disk /dev entries
|
||||
----------------------------
|
||||
MAKEDEV should be copied from src/etc/MAKEDEV to /dev before
|
||||
starting the following:
|
||||
|
||||
For N in the list of disks
|
||||
MAKEDEV N # eg ad0
|
||||
for M in the list of slices
|
||||
MAKEDEV NsMa # eg ad0s1a
|
||||
|
||||
|
||||
To rebuild everything
|
||||
---------------------
|
||||
make world
|
||||
|
||||
Except when it doesn't work :-)
|
||||
|
||||
To update from 3.x to 4.0 stable
|
||||
--------------------------------
|
||||
<see notes below> [3]
|
||||
cd /usr/src
|
||||
<see notes below> [2]
|
||||
make buildworld
|
||||
<follow directions to build/install a kernel>
|
||||
cd /usr/src/sys/modules
|
||||
make install
|
||||
cd /usr/src/sbin/mknod
|
||||
make install
|
||||
<follow rebuild disk /dev entries above> [1]
|
||||
reboot
|
||||
<in single user>
|
||||
cd /usr/src
|
||||
cd gnu/usr.bin/texinfo/install-info
|
||||
make install
|
||||
cd ../../../..
|
||||
make installworld [5]
|
||||
mergemaster [4]
|
||||
reboot
|
||||
<multi-user>
|
||||
|
||||
[1] You may need to switch from wd to ad ala 19991210
|
||||
[2] If you have any of the following in your /etc/make.conf,
|
||||
please comment them out before following these instructions
|
||||
and then do a make buildworld + make installworld after you
|
||||
are back to <multi-user> above:
|
||||
MAKE_KERBEROS4
|
||||
[3] Update to 4.0-stable sources. Make sure that you get all
|
||||
the parts. If you are using cvsup files that are older than a
|
||||
couple of months, be sure they have all the components listed
|
||||
in /usr/share/examples/cvsup. Crypto and secure are now
|
||||
required.
|
||||
[4] This step is optional, but is generally a good idea. If
|
||||
you wish to use many of the new features in 4.0, you must do
|
||||
this anyway.
|
||||
[5] If you get warnings from ld-elf.so that it cannot load
|
||||
libc.so, run 'ldconfig -R /usr/obj/usr/src/lib/libc' and repeat
|
||||
the installworld target.
|
||||
|
||||
What follows are older entries for those people upgrading from earlier
|
||||
versions of -stable.
|
||||
|
||||
20000308:
|
||||
The binary interface of perl to its modules changed. You
|
||||
@@ -617,56 +736,6 @@ http://www.freebsd.org/cgi/getmsg.cgi?fetch=827400+0+current/freebsd-current
|
||||
to silence warnings from authentication programs (login, etc).
|
||||
See src/etc/pam.conf for a sample.
|
||||
|
||||
COMMON ITEMS:
|
||||
|
||||
To build a kernel
|
||||
-----------------
|
||||
Update config, genassym and go:
|
||||
cd src/usr.bin/genassym
|
||||
make depend all install clean
|
||||
cd ../../usr.sbin/config
|
||||
make depend all install clean
|
||||
cd ../../sys/i386/conf
|
||||
config YOUR_KERNEL_HERE
|
||||
cd ../../compile/YOUR_KERNEL_HERE
|
||||
make depend && make
|
||||
make install
|
||||
|
||||
To rebuild disk /dev entries
|
||||
----------------------------
|
||||
|
||||
MAKEDEV should be copied from src/etc/MAKEDEV to /dev before
|
||||
starting the following:
|
||||
|
||||
For N in the list of disks
|
||||
MAKEDEV N # eg ad0
|
||||
for M in the list of slices
|
||||
MAKEDEV NsMa # eg ad0s1a
|
||||
|
||||
|
||||
To rebuild everything
|
||||
---------------------
|
||||
make world
|
||||
|
||||
Except when it doesn't work.
|
||||
|
||||
To update from 3.x to 4.0 stable
|
||||
--------------------------------
|
||||
cd /usr/src
|
||||
make buildworld
|
||||
cd sbin/mknod
|
||||
make install
|
||||
<follow directions to build/install a kernel>
|
||||
<follow rebuild disk /dev entries above> [*]
|
||||
reboot
|
||||
<in single user>
|
||||
cd /usr/src
|
||||
make -DNOINFO installworld
|
||||
make installworld
|
||||
|
||||
[*] You may need to switch from wd to ad ala 19991210
|
||||
|
||||
|
||||
FORMAT:
|
||||
|
||||
This file contains a list, in reverse chronologocal order, of major
|
||||
|
||||
+4
-1
@@ -5,7 +5,6 @@ SUBDIR= cat \
|
||||
chio \
|
||||
chmod \
|
||||
cp \
|
||||
csh \
|
||||
date \
|
||||
dd \
|
||||
df \
|
||||
@@ -31,6 +30,10 @@ SUBDIR= cat \
|
||||
sync \
|
||||
test
|
||||
|
||||
.if !defined(NO_TCSH)
|
||||
SUBDIR+=csh
|
||||
.endif
|
||||
|
||||
.if !defined(NO_SENDMAIL)
|
||||
SUBDIR+=rmail
|
||||
.endif
|
||||
|
||||
+81
-14
@@ -37,14 +37,13 @@
|
||||
.\"
|
||||
.Dd May 2, 1995
|
||||
.Dt CAT 1
|
||||
.Os BSD 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cat
|
||||
.Nd concatenate and print files
|
||||
.Sh SYNOPSIS
|
||||
.Nm cat
|
||||
.Op Fl benstuv
|
||||
.Op Fl
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@@ -52,8 +51,14 @@ The
|
||||
utility reads files sequentially, writing them to the standard output.
|
||||
The
|
||||
.Ar file
|
||||
operands are processed in command line order.
|
||||
A single dash represents the standard input.
|
||||
operands are processed in command-line order.
|
||||
If
|
||||
.Ar file
|
||||
is a single dash
|
||||
.Pq Sq \&-
|
||||
or absent,
|
||||
.Nm
|
||||
reads from the standard input.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
@@ -94,30 +99,92 @@ characters (with the high bit set) are printed as
|
||||
.Sh DIAGNOSTICS
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh BUGS
|
||||
Because of the shell language mechanism used to perform output
|
||||
redirection, the command
|
||||
.Dq Li cat file1 file2 > file1
|
||||
will cause the original data in file1 to be destroyed!
|
||||
utility exits 0 on success or >0 if an error occurred.
|
||||
.Sh EXAMPLES
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
.Ic cat file1
|
||||
.Ed
|
||||
.Pp
|
||||
will print the contents of
|
||||
.Ar file1
|
||||
to the standard output.
|
||||
.Pp
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
.Ic cat file1 file2 > file3
|
||||
.Ed
|
||||
.Pp
|
||||
will sequentially print the contents of
|
||||
.Ar file1
|
||||
and
|
||||
.Ar file2
|
||||
to the file
|
||||
.Ar file3 ,
|
||||
truncating
|
||||
.Ar file3
|
||||
if it already exists.
|
||||
See the manual page for your shell (i.e.,
|
||||
.Xr sh 1 )
|
||||
for more information on redirection.
|
||||
.Pp
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
.Ic cat file1 - file2 - file3
|
||||
.Ed
|
||||
.Pp
|
||||
will print the contents of
|
||||
.Ar file1 ,
|
||||
print data it receives from the standard input until it receives an
|
||||
.Dv EOF
|
||||
.Pq Sq ^D
|
||||
character, print the contents of
|
||||
.Ar file2 ,
|
||||
read and output contents of the standard input again, then finally output
|
||||
the contents of
|
||||
.Ar file3 .
|
||||
Note that if the standard input referred to a file, the second dash
|
||||
on the command-line would have no effect, since the entire contents of the file
|
||||
would have already been read and printed by
|
||||
.Nm
|
||||
when it encountered the first
|
||||
.Ql \&-
|
||||
operand.
|
||||
.Sh SEE ALSO
|
||||
.Xr head 1 ,
|
||||
.Xr more 1 ,
|
||||
.Xr pr 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr tail 1 ,
|
||||
.Xr vis 1
|
||||
.Xr vis 1 ,
|
||||
.Xr setbuf 3
|
||||
.Rs
|
||||
.%A Rob Pike
|
||||
.%T "UNIX Style, or cat -v Considered Harmful"
|
||||
.%J "USENIX Summer Conference Proceedings"
|
||||
.%D 1983
|
||||
.Re
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is compliant with the
|
||||
.St -p1003.2-92
|
||||
specification.
|
||||
.Pp
|
||||
The flags
|
||||
.Op Fl benstv
|
||||
are extensions to the specification.
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in Version 1 AT&T UNIX.
|
||||
utility appeared in
|
||||
.At v1 .
|
||||
.An Dennis Ritchie
|
||||
designed and wrote the first man page.
|
||||
designed and wrote the first man page.
|
||||
It appears to have been
|
||||
.Xr cat 1 .
|
||||
|
||||
.Sh BUGS
|
||||
Because of the shell language mechanism used to perform output
|
||||
redirection, the command
|
||||
.Dq Li cat file1 file2 > file1
|
||||
will cause the original data in file1 to be destroyed!
|
||||
+2
-2
@@ -96,7 +96,7 @@ main(argc, argv)
|
||||
tflag = vflag = 1; /* -t implies -v */
|
||||
break;
|
||||
case 'u':
|
||||
setbuf(stdout, (char *)NULL);
|
||||
setbuf(stdout, NULL);
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
@@ -249,7 +249,7 @@ raw_cat(rfd)
|
||||
err(1, "%s", filename);
|
||||
bsize = MAX(sbuf.st_blksize, 1024);
|
||||
if ((buf = malloc(bsize)) == NULL)
|
||||
err(1, NULL);
|
||||
err(1, "buffer");
|
||||
}
|
||||
while ((nr = read(rfd, buf, bsize)) > 0)
|
||||
for (off = 0; nr; nr -= nw, off += nw)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $FreeBSD$
|
||||
|
||||
NOSHARED?=yes
|
||||
|
||||
PROG= chflags
|
||||
CFLAGS+=-Wall
|
||||
.PATH: ${.CURDIR}/../../lib/libc/gen
|
||||
SRCS= chflags.c setflags.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,138 +0,0 @@
|
||||
.\" Copyright (c) 1989, 1990, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)chflags.1 8.4 (Berkeley) 5/2/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 2, 1995
|
||||
.Dt CHFLAGS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm chflags
|
||||
.Nd change file flags
|
||||
.Sh SYNOPSIS
|
||||
.Nm chflags
|
||||
.Oo
|
||||
.Fl R
|
||||
.Op Fl H | Fl L | Fl P
|
||||
.Oc
|
||||
.Ar flags
|
||||
.Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility modifies the file flags of the listed files
|
||||
as specified by the
|
||||
.Ar flags
|
||||
operand.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl H
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, symbolic links on the command line are followed.
|
||||
(Symbolic links encountered in the tree traversal are not followed.)
|
||||
.It Fl L
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, all symbolic links are followed.
|
||||
.It Fl P
|
||||
If the
|
||||
.Fl R
|
||||
option is specified, no symbolic links are followed.
|
||||
.It Fl R
|
||||
Change the file flags for the file hierarchies rooted
|
||||
in the files instead of just the files themselves.
|
||||
.El
|
||||
.Pp
|
||||
Flags are a comma separated list of keywords.
|
||||
The following keywords are currently defined:
|
||||
.Bd -literal -offset indent compact
|
||||
arch set the archived flag (super-user only)
|
||||
opaque set the opaque flag (owner or super-user only)
|
||||
nodump set the nodump flag (owner or super-user only)
|
||||
sappnd set the system append-only flag (super-user only)
|
||||
schg set the system immutable flag (super-user only)
|
||||
sunlnk set the system undeletable flag (super-user only)
|
||||
uappnd set the user append-only flag (owner or super-user only)
|
||||
uchg set the user immutable flag (owner or super-user only)
|
||||
uunlnk set the user undeletable flag (owner or super-user only)
|
||||
archived, sappend, schange, simmutable, uappend, uchange, uimmutable,
|
||||
sunlink, uunlink
|
||||
aliases for the above
|
||||
.Ed
|
||||
.Pp
|
||||
Putting the letters
|
||||
.Dq no
|
||||
before an option causes the flag to be turned off.
|
||||
For example:
|
||||
.Bd -literal -offset indent compact
|
||||
nouchg the immutable bit should be cleared
|
||||
.Ed
|
||||
.Pp
|
||||
Symbolic links do not have flags, so unless the
|
||||
.Fl H
|
||||
or
|
||||
.Fl L
|
||||
option is set,
|
||||
.Nm
|
||||
on a symbolic link always succeeds and has no effect.
|
||||
The
|
||||
.Fl H ,
|
||||
.Fl L
|
||||
and
|
||||
.Fl P
|
||||
options are ignored unless the
|
||||
.Fl R
|
||||
option is specified.
|
||||
In addition, these options override each other and the
|
||||
command's actions are determined by the last one specified.
|
||||
.Pp
|
||||
You can use "ls -lo" to see the flags of existing files.
|
||||
.Sh DIAGNOSTICS
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr ls 1 ,
|
||||
.Xr chflags 2 ,
|
||||
.Xr stat 2 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr symlink 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Bx 4.4 .
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)chflags.c 8.5 (Berkeley) 4/1/94";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern u_long setflags __P((char **, u_long *, u_long *));
|
||||
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
FTS *ftsp;
|
||||
FTSENT *p;
|
||||
u_long clear, set;
|
||||
long val;
|
||||
int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval;
|
||||
char *flags, *ep;
|
||||
|
||||
Hflag = Lflag = Pflag = Rflag = 0;
|
||||
while ((ch = getopt(argc, argv, "HLPR")) != -1)
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
Hflag = 1;
|
||||
Lflag = Pflag = 0;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = 1;
|
||||
Hflag = Pflag = 0;
|
||||
break;
|
||||
case 'P':
|
||||
Pflag = 1;
|
||||
Hflag = Lflag = 0;
|
||||
break;
|
||||
case 'R':
|
||||
Rflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
fts_options = FTS_PHYSICAL;
|
||||
if (Rflag) {
|
||||
if (Hflag)
|
||||
fts_options |= FTS_COMFOLLOW;
|
||||
if (Lflag) {
|
||||
fts_options &= ~FTS_PHYSICAL;
|
||||
fts_options |= FTS_LOGICAL;
|
||||
}
|
||||
}
|
||||
|
||||
flags = *argv;
|
||||
if (*flags >= '0' && *flags <= '7') {
|
||||
errno = 0;
|
||||
val = strtol(flags, &ep, 8);
|
||||
if (val < 0)
|
||||
errno = ERANGE;
|
||||
if (errno)
|
||||
err(1, "invalid flags: %s", flags);
|
||||
if (*ep)
|
||||
errx(1, "invalid flags: %s", flags);
|
||||
set = val;
|
||||
oct = 1;
|
||||
} else {
|
||||
if (setflags(&flags, &set, &clear))
|
||||
errx(1, "invalid flag: %s", flags);
|
||||
clear = ~clear;
|
||||
oct = 0;
|
||||
}
|
||||
|
||||
if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_D:
|
||||
if (Rflag) /* Change it at FTS_DP. */
|
||||
continue;
|
||||
fts_set(ftsp, p, FTS_SKIP);
|
||||
break;
|
||||
case FTS_DNR: /* Warn, chflag, continue. */
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
break;
|
||||
case FTS_ERR: /* Warn, continue. */
|
||||
case FTS_NS:
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
continue;
|
||||
case FTS_SL: /* Ignore. */
|
||||
case FTS_SLNONE:
|
||||
/*
|
||||
* The only symlinks that end up here are ones that
|
||||
* don't point to anything and ones that we found
|
||||
* doing a physical walk.
|
||||
*/
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (oct) {
|
||||
if (!chflags(p->fts_accpath, set))
|
||||
continue;
|
||||
} else {
|
||||
p->fts_statp->st_flags |= set;
|
||||
p->fts_statp->st_flags &= clear;
|
||||
if (!chflags(p->fts_accpath, p->fts_statp->st_flags))
|
||||
continue;
|
||||
}
|
||||
warn("%s", p->fts_path);
|
||||
rval = 1;
|
||||
}
|
||||
if (errno)
|
||||
err(1, "fts_read");
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: chflags [-R [-H | -L | -P]] flags file ...\n");
|
||||
exit(1);
|
||||
}
|
||||
+1
-1
@@ -193,7 +193,7 @@ done: argv += optind;
|
||||
}
|
||||
if (chmod(p->fts_accpath, oct ? omode :
|
||||
getmode(set, p->fts_statp->st_mode)) && !fflag) {
|
||||
warn(p->fts_path);
|
||||
warn("%s", p->fts_path);
|
||||
rval = 1;
|
||||
} else {
|
||||
if (vflag)
|
||||
|
||||
+48
-14
@@ -6,36 +6,70 @@
|
||||
#
|
||||
# To profile, put -DPROF in DEFS and -pg in CFLAGS, and recompile.
|
||||
|
||||
TCSHDIR= ${.CURDIR}/../../contrib/tcsh
|
||||
.PATH: ${TCSHDIR}
|
||||
|
||||
PROG= csh
|
||||
DFLAGS=-DBUILTIN -DFILEC -DNLS -DSHORT_STRINGS
|
||||
CFLAGS+=-I${.CURDIR} -I. ${DFLAGS}
|
||||
SRCS= alloc.c char.c const.c csh.c dir.c dol.c err.c exec.c exp.c file.c \
|
||||
func.c glob.c hist.c init.c lex.c misc.c parse.c printf.c proc.c \
|
||||
sem.c set.c str.c time.c const.h errnum.h
|
||||
.PATH: ${.CURDIR}/../../usr.bin/printf
|
||||
SUBDIR= nls
|
||||
DFLAGS= -D_PATH_TCSHELL='"${DESTDIR}/bin/${PROG}"'
|
||||
CFLAGS+= -I${TCSHDIR} -I${.CURDIR} -I. ${DFLAGS}
|
||||
SRCS= sh.c sh.dir.c sh.dol.c sh.err.c sh.exec.c sh.char.c \
|
||||
sh.exp.c sh.file.c sh.func.c sh.glob.c sh.hist.c sh.init.c \
|
||||
sh.lex.c sh.misc.c sh.parse.c sh.print.c sh.proc.c sh.sem.c \
|
||||
sh.set.c sh.time.c sh.h sh.char.h sh.dir.h sh.proc.h
|
||||
SRCS+= sh.decls.h glob.c glob.h mi.termios.c mi.wait.h mi.varargs.h
|
||||
SRCS+= tw.decls.h tw.h tw.help.c tw.init.c tw.parse.c tw.spell.c \
|
||||
tw.comp.c tw.color.c
|
||||
SRCS+= ed.chared.c ed.decls.h ed.defns.c ed.h ed.init.c ed.inputl.c \
|
||||
ed.refresh.c ed.screen.c ed.xmap.c ed.term.c ed.term.h
|
||||
SRCS+= tc.alloc.c tc.bind.c tc.const.c tc.decls.h tc.disc.c \
|
||||
tc.func.c tc.os.c tc.os.h tc.printf.c tc.prompt.c \
|
||||
tc.sched.c tc.sig.c tc.sig.h tc.str.c sh.types.h tc.vers.c tc.wait.h \
|
||||
tc.who.c tc.h
|
||||
SRCS+= tc.defs.c
|
||||
GENHDRS= ed.defns.h sh.err.h tc.const.h
|
||||
SRCS+= ${GENHDRS}
|
||||
|
||||
MAN1= csh.1
|
||||
MLINKS= csh.1 tcsh.1
|
||||
# MLINKS for Shell built in commands for which there are no userland
|
||||
# utilities of the same name are handled with the associated manpage,
|
||||
# builtin.1 in share/man/man1/.
|
||||
|
||||
CLEANFILES+=const.h errnum.h
|
||||
DPADD= ${LIBTERMCAP} ${LIBCRYPT}
|
||||
LDADD= -ltermcap -lcrypt
|
||||
|
||||
const.h: errnum.h
|
||||
LINKS= ${BINDIR}/csh ${BINDIR}/tcsh
|
||||
|
||||
errnum.h: err.c
|
||||
CLEANFILES= ${GENHDRS} csh.1
|
||||
|
||||
csh.1: tcsh.man
|
||||
ln -sf ${.ALLSRC} ${.TARGET}
|
||||
|
||||
ed.defns.h: ed.defns.c
|
||||
@rm -f ${.TARGET}
|
||||
@echo '/* Do not edit this file, make creates it. */' > ${.TARGET}
|
||||
@echo '#ifndef _h_sh_error' >> ${.TARGET}
|
||||
@echo '#define _h_sh_error' >> ${.TARGET}
|
||||
@echo '#ifndef _h_ed_defns' >> ${.TARGET}
|
||||
@echo '#define _h_ed_defns' >> ${.TARGET}
|
||||
grep '[FV]_' ${TCSHDIR}/ed.defns.c | grep '^#define' >> ${.TARGET}
|
||||
@echo '#endif /* _h_ed_defns */' >> ${.TARGET}
|
||||
|
||||
sh.err.h: sh.err.c
|
||||
@rm -f ${.TARGET}
|
||||
@echo '/* Do not edit this file, make creates it. */' > ${.TARGET}
|
||||
@echo '#ifndef _h_sh_err' >> ${.TARGET}
|
||||
@echo '#define _h_sh_err' >> ${.TARGET}
|
||||
egrep 'ERR_' ${.ALLSRC} | egrep '^#define' >> ${.TARGET}
|
||||
@echo '#endif /* _h_sh_error */' >> ${.TARGET}
|
||||
@echo '#endif /* _h_sh_err */' >> ${.TARGET}
|
||||
|
||||
const.h: const.c
|
||||
tc.const.h: tc.const.c sh.char.h config.h config_f.h sh.types.h sh.err.h
|
||||
@rm -f ${.TARGET}
|
||||
@echo '/* Do not edit this file, make creates it. */' > ${.TARGET}
|
||||
${CC} -E ${CFLAGS} ${.ALLSRC} | egrep 'Char STR' | \
|
||||
@echo '#ifndef _h_tc_const' >> ${.TARGET}
|
||||
@echo '#define _h_tc_const' >> ${.TARGET}
|
||||
${CC} -E ${CFLAGS} ${.ALLSRC} -D_h_tc_const | egrep 'Char STR' | \
|
||||
sed -e 's/Char \([a-zA-Z0-9_]*\)\(.*\)/extern Char \1[];/' | \
|
||||
sort >> ${.TARGET}
|
||||
@echo '#endif /* _h_tc_const */' >> ${.TARGET}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)alloc.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
char *memtop = NULL; /* PWP: top of current memory */
|
||||
char *membot = NULL; /* PWP: bottom of allocatable memory */
|
||||
|
||||
ptr_t
|
||||
Malloc(n)
|
||||
size_t n;
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if (membot == NULL)
|
||||
memtop = membot = sbrk(0);
|
||||
if ((ptr = malloc(n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
ptr_t
|
||||
Realloc(p, n)
|
||||
ptr_t p;
|
||||
size_t n;
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if (membot == NULL)
|
||||
memtop = membot = sbrk(0);
|
||||
if ((ptr = realloc(p, n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
ptr_t
|
||||
Calloc(s, n)
|
||||
size_t s, n;
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if (membot == NULL)
|
||||
memtop = membot = sbrk(0);
|
||||
if ((ptr = calloc(s, n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
Free(p)
|
||||
ptr_t p;
|
||||
{
|
||||
if (p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* mstats - print out statistics about malloc
|
||||
*
|
||||
* Prints two lines of numbers, one showing the length of the free list
|
||||
* for each size category, the second showing the number of mallocs -
|
||||
* frees for each size category.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
showall(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
memtop = (char *) sbrk(0);
|
||||
(void) fprintf(cshout, "Allocated memory from 0x%lx to 0x%lx (%ld).\n",
|
||||
(unsigned long) membot, (unsigned long) memtop,
|
||||
(unsigned long) (memtop - membot));
|
||||
}
|
||||
-316
@@ -1,316 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)char.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "char.h"
|
||||
|
||||
unsigned short _cmap[256] = {
|
||||
/* nul soh stx etx */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* eot enq ack bel */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* bs ht nl vt */
|
||||
_CTR, _CTR|_SP|_META, _CTR|_NL|_META, _CTR,
|
||||
|
||||
/* np cr so si */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* dle dc1 dc2 dc3 */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* dc4 nak syn etb */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* can em sub esc */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* fs gs rs us */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* sp ! " # */
|
||||
_SP|_META, 0, _QF, _META,
|
||||
|
||||
/* $ % & ' */
|
||||
_DOL, 0, _META|_CMD, _QF,
|
||||
|
||||
/* ( ) * + */
|
||||
_META|_CMD, _META, _GLOB, 0,
|
||||
|
||||
/* , - . / */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* 0 1 2 3 */
|
||||
_DIG|_XD, _DIG|_XD, _DIG|_XD, _DIG|_XD,
|
||||
|
||||
/* 4 5 6 7 */
|
||||
_DIG|_XD, _DIG|_XD, _DIG|_XD, _DIG|_XD,
|
||||
|
||||
/* 8 9 : ; */
|
||||
_DIG|_XD, _DIG|_XD, 0, _META|_CMD,
|
||||
|
||||
/* < = > ? */
|
||||
_META, 0, _META, _GLOB,
|
||||
|
||||
/* @ A B C */
|
||||
0, _LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP|_XD,
|
||||
|
||||
/* D E F G */
|
||||
_LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP,
|
||||
|
||||
/* H I J K */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* L M N O */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* P Q R S */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* T U V W */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* X Y Z [ */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _GLOB,
|
||||
|
||||
/* \ ] ^ _ */
|
||||
_ESC, 0, 0, 0,
|
||||
|
||||
/* ` a b c */
|
||||
_QB|_GLOB|_META, _LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW|_XD,
|
||||
|
||||
/* d e f g */
|
||||
_LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW,
|
||||
|
||||
/* h i j k */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* l m n o */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* p q r s */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* t u v w */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* x y z { */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _GLOB,
|
||||
|
||||
/* | } ~ del */
|
||||
_META|_CMD, 0, 0, _CTR,
|
||||
|
||||
#if defined(SHORT_STRINGS) && !defined(KANJI)
|
||||
/****************************************************************/
|
||||
/* 128 - 255 The below is supposedly ISO 8859/1 */
|
||||
/****************************************************************/
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* (undef) (undef) (undef) (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* nobreakspace exclamdown cent sterling */
|
||||
_SP, 0, 0, 0,
|
||||
|
||||
/* currency yen brokenbar section */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* diaeresis copyright ordfeminine guillemotleft */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* notsign hyphen registered macron */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* degree plusminus twosuperior threesuperior */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* acute mu paragraph periodcentered */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* cedilla onesuperior masculine guillemotright */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* onequarter onehalf threequarters questiondown */
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* Agrave Aacute Acircumflex Atilde */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* Adiaeresis Aring AE Ccedilla */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* Egrave Eacute Ecircumflex Ediaeresis */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* Igrave Iacute Icircumflex Idiaeresis */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* ETH Ntilde Ograve Oacute */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* Ocircumflex Otilde Odiaeresis multiply */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, 0,
|
||||
|
||||
/* Ooblique Ugrave Uacute Ucircumflex */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* Udiaeresis Yacute THORN ssharp */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_LOW,
|
||||
|
||||
/* agrave aacute acircumflex atilde */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* adiaeresis aring ae ccedilla */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* egrave eacute ecircumflex ediaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* igrave iacute icircumflex idiaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* eth ntilde ograve oacute */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* ocircumflex otilde odiaeresis division */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, 0,
|
||||
|
||||
/* oslash ugrave uacute ucircumflex */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* udiaeresis yacute thorn ydiaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
#endif /* SHORT_STRINGS && !KANJI */
|
||||
};
|
||||
|
||||
#ifndef NLS
|
||||
/* _cmap_lower, _cmap_upper for ISO 8859/1 */
|
||||
|
||||
unsigned char _cmap_lower[256] = {
|
||||
0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
|
||||
0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
|
||||
0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
|
||||
0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
|
||||
0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
|
||||
0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
|
||||
0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
|
||||
0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
|
||||
0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
|
||||
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
||||
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
||||
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
||||
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
||||
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
||||
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
||||
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0327,
|
||||
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0337,
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
||||
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
|
||||
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
|
||||
};
|
||||
|
||||
unsigned char _cmap_upper[256] = {
|
||||
0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
|
||||
0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
|
||||
0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
|
||||
0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
|
||||
0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
|
||||
0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
|
||||
0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
|
||||
0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
||||
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
||||
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
||||
0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
|
||||
0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
||||
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
||||
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
||||
0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
|
||||
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
||||
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
||||
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
||||
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
||||
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
||||
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
||||
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
||||
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
||||
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
|
||||
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
||||
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
||||
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0367,
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0377,
|
||||
};
|
||||
#endif /* NLS */
|
||||
@@ -1,97 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)char.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
extern unsigned short _cmap[];
|
||||
|
||||
#ifndef NLS
|
||||
extern unsigned char _cmap_lower[], _cmap_upper[];
|
||||
|
||||
#endif
|
||||
|
||||
#define _QF 0x0001 /* '" (Forward quotes) */
|
||||
#define _QB 0x0002 /* ` (Backquote) */
|
||||
#define _SP 0x0004 /* space and tab */
|
||||
#define _NL 0x0008 /* \n */
|
||||
#define _META 0x0010 /* lex meta characters, sp #'`";&<>()|\t\n */
|
||||
#define _GLOB 0x0020 /* glob characters, *?{[` */
|
||||
#define _ESC 0x0040 /* \ */
|
||||
#define _DOL 0x0080 /* $ */
|
||||
#define _DIG 0x0100 /* 0-9 */
|
||||
#define _LET 0x0200 /* a-z, A-Z, _ */
|
||||
#define _UP 0x0400 /* A-Z */
|
||||
#define _LOW 0x0800 /* a-z */
|
||||
#define _XD 0x1000 /* 0-9, a-f, A-F */
|
||||
#define _CMD 0x2000 /* lex end of command chars, ;&(|` */
|
||||
#define _CTR 0x4000 /* control */
|
||||
|
||||
#define cmap(c, bits) \
|
||||
(((c) & QUOTE) ? 0 : (_cmap[(unsigned char)(c)] & (bits)))
|
||||
|
||||
#define isglob(c) cmap(c, _GLOB)
|
||||
#define isspc(c) cmap(c, _SP)
|
||||
#define ismeta(c) cmap(c, _META)
|
||||
#define iscmdmeta(c) cmap(c, _CMD)
|
||||
#define letter(c) (((c) & QUOTE) ? 0 : \
|
||||
(isalpha((unsigned char) (c)) || (c) == '_'))
|
||||
#define alnum(c) (((c) & QUOTE) ? 0 : \
|
||||
(isalnum((unsigned char) (c)) || (c) == '_'))
|
||||
#ifdef NLS
|
||||
#define Isspace(c) (((c) & QUOTE) ? 0 : isspace((unsigned char) (c)))
|
||||
#define Isdigit(c) (((c) & QUOTE) ? 0 : isdigit((unsigned char) (c)))
|
||||
#define Isalpha(c) (((c) & QUOTE) ? 0 : isalpha((unsigned char) (c)))
|
||||
#define Islower(c) (((c) & QUOTE) ? 0 : islower((unsigned char) (c)))
|
||||
#define Isupper(c) (((c) & QUOTE) ? 0 : isupper((unsigned char) (c)))
|
||||
#define Tolower(c) (((c) & QUOTE) ? 0 : tolower((unsigned char) (c)))
|
||||
#define Toupper(c) (((c) & QUOTE) ? 0 : toupper((unsigned char) (c)))
|
||||
#define Isxdigit(c) (((c) & QUOTE) ? 0 : isxdigit((unsigned char) (c)))
|
||||
#define Isalnum(c) (((c) & QUOTE) ? 0 : isalnum((unsigned char) (c)))
|
||||
#define Iscntrl(c) (((c) & QUOTE) ? 0 : iscntrl((unsigned char) (c)))
|
||||
#define Isprint(c) (((c) & QUOTE) ? 0 : isprint((unsigned char) (c)))
|
||||
#else
|
||||
#define Isspace(c) cmap(c, _SP|_NL)
|
||||
#define Isdigit(c) cmap(c, _DIG)
|
||||
#define Isalpha(c) (cmap(c,_LET) && !(((c) & META) && AsciiOnly))
|
||||
#define Islower(c) (cmap(c,_LOW) && !(((c) & META) && AsciiOnly))
|
||||
#define Isupper(c) (cmap(c, _UP) && !(((c) & META) && AsciiOnly))
|
||||
#define Tolower(c) (_cmap_lower[(unsigned char)(c)])
|
||||
#define Toupper(c) (_cmap_upper[(unsigned char)(c)])
|
||||
#define Isxdigit(c) cmap(c, _XD)
|
||||
#define Isalnum(c) (cmap(c, _DIG|_LET) && !(((c) & META) && AsciiOnly))
|
||||
#define Iscntrl(c) (cmap(c,_CTR) && !(((c) & META) && AsciiOnly))
|
||||
#define Isprint(c) (!cmap(c,_CTR) && !(((c) & META) && AsciiOnly))
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/*
|
||||
* config.h -- configure various defines for tcsh
|
||||
*
|
||||
* All source files should #include this FIRST.
|
||||
*
|
||||
* Edit this to match your system type.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef _h_config
|
||||
#define _h_config
|
||||
/****************** System dependant compilation flags ****************/
|
||||
/*
|
||||
* POSIX This system supports IEEE Std 1003.1-1988 (POSIX).
|
||||
*/
|
||||
#define POSIX
|
||||
|
||||
/*
|
||||
* POSIXJOBS This system supports the optional IEEE Std 1003.1-1988 (POSIX)
|
||||
* job control facilities.
|
||||
*/
|
||||
#define POSIXJOBS
|
||||
|
||||
/*
|
||||
* POSIXSIGS Use the POSIX signal facilities to emulate BSD signals.
|
||||
*/
|
||||
/* #undef POSIXSIGS */
|
||||
|
||||
/*
|
||||
* VFORK This machine has a vfork().
|
||||
* It used to be that for job control to work, this define
|
||||
* was mandatory. This is not the case any more.
|
||||
* If you think you still need it, but you don't have vfork,
|
||||
* define this anyway and then do #define vfork fork.
|
||||
* I do this anyway on a Sun because of yellow pages brain damage,
|
||||
* [should not be needed under 4.1]
|
||||
* and on the iris4d cause SGI's fork is sufficiently "virtual"
|
||||
* that vfork isn't necessary. (Besides, SGI's vfork is weird).
|
||||
* Note that some machines eg. rs6000 have a vfork, but not
|
||||
* with the berkeley semantics, so we cannot use it there either.
|
||||
*/
|
||||
#define VFORK
|
||||
|
||||
/*
|
||||
* BSDJOBS You have BSD-style job control (both process groups and
|
||||
* a tty that deals correctly
|
||||
*/
|
||||
#define BSDJOBS
|
||||
|
||||
/*
|
||||
* BSDSIGS You have 4.2-style signals, rather than USG style.
|
||||
* Note: POSIX systems should not define this unless they
|
||||
* have sigvec() and friends (ie: 4.3BSD-RENO, HP-UX).
|
||||
*/
|
||||
#define BSDSIGS
|
||||
|
||||
/*
|
||||
* BSDTIMES You have BSD-style process time stuff (like rusage)
|
||||
* This may or may not be true. For example, Apple Unix
|
||||
* (OREO) has BSDJOBS and BSDSIGS but not BSDTIMES.
|
||||
*/
|
||||
#define BSDTIMES
|
||||
|
||||
/*
|
||||
* BSDLIMIT You have BSD-style resource limit stuff (getrlimit/setrlimit)
|
||||
*/
|
||||
#define BSDLIMIT
|
||||
|
||||
/*
|
||||
* BSDNICE Your system uses setpriority() instead of nice, to
|
||||
* change a processes scheduling priority
|
||||
*/
|
||||
#define BSDNICE
|
||||
|
||||
/*
|
||||
* TERMIO You have struct termio instead of struct sgttyb.
|
||||
* This is usually the case for SYSV systems, where
|
||||
* BSD uses sgttyb. POSIX systems should define this
|
||||
* anyway, even though they use struct termios.
|
||||
*/
|
||||
#define TERMIO
|
||||
|
||||
/*
|
||||
* SYSVREL Your machine is SYSV based (HPUX, A/UX)
|
||||
* NOTE: don't do this if you are on a Pyramid -- tcsh is
|
||||
* built in a BSD universe.
|
||||
* Set SYSVREL to 1, 2, 3, or 4, depending the version of System V
|
||||
* you are running. Or set it to 0 if you are not SYSV based
|
||||
*/
|
||||
#define SYSVREL 0
|
||||
|
||||
/*
|
||||
* YPBUGS Work around Sun YP bugs that cause expansion of ~username
|
||||
* to send command output to /dev/null
|
||||
*/
|
||||
/* #undef YPBUGS */
|
||||
|
||||
/*
|
||||
* SIGVOID Define this if your signal handlers return void. On older
|
||||
* systems, signal returns int, but on newer ones, it returns void.
|
||||
*/
|
||||
#define SIGVOID
|
||||
|
||||
/*
|
||||
* HAVEDUP2 Define this if your system supports dup2().
|
||||
*/
|
||||
#define HAVEDUP2
|
||||
|
||||
/*
|
||||
* UTHOST Does the utmp file have a host field?
|
||||
*/
|
||||
#define UTHOST
|
||||
|
||||
/*
|
||||
* DIRENT Your system has <dirent.h> instead of <sys/dir.h>
|
||||
*/
|
||||
#define DIRENT
|
||||
/****************** local defines *********************/
|
||||
/****************** configurable hacks ****************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* have been moved to config_f.h */
|
||||
#include "config_f.h"
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define NLS_BUGS
|
||||
/* we want to use the system malloc when we install as /bin/csh */
|
||||
#define SYSMALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__bsdi__)
|
||||
/*
|
||||
* _PATH_TCSHELL if you've change the installation location (vix)
|
||||
*/
|
||||
# ifdef _BSDI_VERSION >= 199701
|
||||
# define _PATH_TCSHELL "/bin/tcsh"
|
||||
/* # undef SYSMALLOC */
|
||||
# define SYSMALLOC
|
||||
# else
|
||||
# define _PATH_TCSHELL "/usr/contrib/bin/tcsh"
|
||||
# endif
|
||||
|
||||
# undef NLS
|
||||
# undef NLS_CATALOGS
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# define SYSMALLOC
|
||||
|
||||
#else
|
||||
# define NLS_CATALOGS
|
||||
#endif
|
||||
|
||||
#define KANJI
|
||||
#define DSPMBYTE
|
||||
|
||||
#endif /* _h_config */
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)const.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* tc.const.c: String constants for csh.
|
||||
*/
|
||||
|
||||
#include "csh.h"
|
||||
|
||||
Char STR0[] = { '0', '\0' };
|
||||
Char STR1[] = { '1', '\0' };
|
||||
Char STRHOME[] = { 'H', 'O', 'M', 'E', '\0' };
|
||||
Char STRLANG[] = { 'L', 'A', 'N', 'G', '\0' };
|
||||
Char STRLC_ALL[] = { 'L', 'C', '_', 'A', 'L', 'L', '\0' };
|
||||
Char STRLC_CTYPE[] = { 'L', 'C', '_', 'C', 'T', 'Y', 'P', 'E', '\0' };
|
||||
Char STRLC_COLLATE[] = { 'L', 'C', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', '\0' };
|
||||
Char STRLOGNAME[] = { 'L', 'O', 'G', 'N', 'A', 'M', 'E', '\0' };
|
||||
Char STRLbrace[] = { '{', '\0' };
|
||||
Char STRLparen[] = { '(', '\0' };
|
||||
Char STRLparensp[] = { '(', ' ', '\0' };
|
||||
Char STRNULL[] = { '\0' };
|
||||
Char STRPATH[] = { 'P', 'A', 'T', 'H', '\0' };
|
||||
Char STRPWD[] = { 'P', 'W', 'D', '\0' };
|
||||
Char STRQNULL[] = { '\0' | QUOTE, '\0' };
|
||||
Char STRRbrace[] = { '}', '\0' };
|
||||
Char STRspRparen[] = { ' ', ')', '\0' };
|
||||
Char STRTERM[] = { 'T', 'E', 'R', 'M', '\0' };
|
||||
Char STRUSER[] = { 'U', 'S', 'E', 'R', '\0' };
|
||||
Char STRalias[] = { 'a', 'l', 'i', 'a', 's', '\0' };
|
||||
Char STRand[] = { '&', '\0' };
|
||||
Char STRand2[] = { '&', '&', '\0' };
|
||||
Char STRaout[] = { 'a', '.', 'o', 'u', 't', '\0' };
|
||||
Char STRargv[] = { 'a', 'r', 'g', 'v', '\0' };
|
||||
Char STRbang[] = { '!', '\0' };
|
||||
Char STRcaret[] = { '^', '\0' };
|
||||
Char STRcdpath[] = { 'c', 'd', 'p', 'a', 't', 'h', '\0' };
|
||||
Char STRcent2[] = { '%', '%', '\0' };
|
||||
Char STRcenthash[] = { '%', '#', '\0' };
|
||||
Char STRcentplus[] = { '%', '+', '\0' };
|
||||
Char STRcentminus[] = { '%', '-', '\0' };
|
||||
Char STRchase_symlinks[] = { 'c', 'h', 'a', 's', 'e', '_', 's', 'y', 'm', 'l',
|
||||
'i', 'n', 'k', 's', '\0' };
|
||||
Char STRchild[] = { 'c', 'h', 'i', 'l', 'd', '\0' };
|
||||
Char STRcolon[] = { ':', '\0' };
|
||||
Char STRcwd[] = { 'c', 'w', 'd', '\0' };
|
||||
Char STRdefault[] = { 'd', 'e', 'f', 'a', 'u', 'l', 't', '\0' };
|
||||
Char STRdot[] = { '.', '\0' };
|
||||
Char STRdotdotsl[] = { '.', '.', '/', '\0' };
|
||||
Char STRdotsl[] = { '.', '/', '\0' };
|
||||
Char STRecho[] = { 'e', 'c', 'h', 'o', '\0' };
|
||||
Char STRequal[] = { '=', '\0' };
|
||||
Char STRfakecom[] = { '{', ' ', '.', '.', '.', ' ', '}', '\0' };
|
||||
Char STRfakecom1[] = { '`', ' ', '.', '.', '.', ' ', '`', '\0' };
|
||||
Char STRfignore[] = { 'f', 'i', 'g', 'n', 'o', 'r', 'e', '\0' };
|
||||
#ifdef FILEC
|
||||
Char STRfilec[] = { 'f', 'i', 'l', 'e', 'c', '\0' };
|
||||
#endif /* FILEC */
|
||||
Char STRhistchars[] = { 'h', 'i', 's', 't', 'c', 'h', 'a', 'r', 's', '\0' };
|
||||
Char STRtildothist[] = { '~', '/', '.', 'h', 'i', 's', 't', 'o', 'r',
|
||||
'y', '\0' };
|
||||
Char STRhistfile[] = { 'h', 'i', 's', 't', 'f', 'i', 'l', 'e', '\0' };
|
||||
Char STRhistory[] = { 'h', 'i', 's', 't', 'o', 'r', 'y', '\0' };
|
||||
Char STRhome[] = { 'h', 'o', 'm', 'e', '\0' };
|
||||
Char STRignore_symlinks[] = { 'i', 'g', 'n', 'o', 'r', 'e', '_', 's', 'y', 'm',
|
||||
'l', 'i', 'n', 'k', 's', '\0' };
|
||||
Char STRignoreeof[] = { 'i', 'g', 'n', 'o', 'r', 'e', 'e', 'o', 'f', '\0' };
|
||||
Char STRjobs[] = { 'j', 'o', 'b', 's', '\0' };
|
||||
Char STRlistjobs[] = { 'l', 'i', 's', 't', 'j', 'o', 'b', 's', '\0' };
|
||||
Char STRlogout[] = { 'l', 'o', 'g', 'o', 'u', 't', '\0' };
|
||||
Char STRlong[] = { 'l', 'o', 'n', 'g', '\0' };
|
||||
Char STRmail[] = { 'm', 'a', 'i', 'l', '\0' };
|
||||
Char STRmh[] = { '-', 'h', '\0' };
|
||||
Char STRminus[] = { '-', '\0' };
|
||||
Char STRml[] = { '-', 'l', '\0' };
|
||||
Char STRmn[] = { '-', 'n', '\0' };
|
||||
Char STRmquestion[] = { '?' | QUOTE, ' ', '\0' };
|
||||
Char STRnice[] = { 'n', 'i', 'c', 'e', '\0' };
|
||||
Char STRnoambiguous[] = { 'n', 'o', 'a', 'm', 'b', 'i', 'g', 'u', 'o', 'u',
|
||||
's', '\0' };
|
||||
Char STRnobeep[] = { 'n', 'o', 'b', 'e', 'e', 'p', '\0' };
|
||||
Char STRnoclobber[] = { 'n', 'o', 'c', 'l', 'o', 'b', 'b', 'e', 'r', '\0' };
|
||||
Char STRnoglob[] = { 'n', 'o', 'g', 'l', 'o', 'b', '\0' };
|
||||
Char STRnohup[] = { 'n', 'o', 'h', 'u', 'p', '\0' };
|
||||
Char STRnonomatch[] = { 'n', 'o', 'n', 'o', 'm', 'a', 't', 'c', 'h', '\0' };
|
||||
Char STRnormal[] = { 'n', 'o', 'r', 'm', 'a', 'l', '\0' };
|
||||
Char STRnotify[] = { 'n', 'o', 't', 'i', 'f', 'y', '\0' };
|
||||
Char STRor[] = { '|', '\0' };
|
||||
Char STRor2[] = { '|', '|', '\0' };
|
||||
Char STRpath[] = { 'p', 'a', 't', 'h', '\0' };
|
||||
Char STRprintexitvalue[] = { 'p', 'r', 'i', 'n', 't', 'e', 'x', 'i', 't', 'v',
|
||||
'a', 'l', 'u', 'e', '\0' };
|
||||
Char STRprompt[] = { 'p', 'r', 'o', 'm', 'p', 't', '\0' };
|
||||
Char STRprompt2[] = { 'p', 'r', 'o', 'm', 'p', 't', '2', '\0' };
|
||||
Char STRpushdsilent[] = { 'p', 'u', 's', 'h', 'd', 's', 'i', 'l', 'e', 'n',
|
||||
't', '\0' };
|
||||
Char STRret[] = { '\n', '\0' };
|
||||
Char STRsavehist[] = { 's', 'a', 'v', 'e', 'h', 'i', 's', 't', '\0' };
|
||||
Char STRsemisp[] = { ';', ' ', '\0' };
|
||||
Char STRshell[] = { 's', 'h', 'e', 'l', 'l', '\0' };
|
||||
Char STRslash[] = { '/', '\0' };
|
||||
Char STRsldotcshrc[] = { '/', '.', 'c', 's', 'h', 'r', 'c', '\0' };
|
||||
Char STRsldotlogin[] = { '/', '.', 'l', 'o', 'g', 'i', 'n', '\0' };
|
||||
Char STRsldthist[] = { '/', '.', 'h', 'i', 's', 't', 'o', 'r', 'y', '\0' };
|
||||
Char STRsldtlogout[] = { '/', '.', 'l', 'o', 'g', 'o', 'u', 't', '\0' };
|
||||
Char STRsource[] = { 's', 'o', 'u', 'r', 'c', 'e', '\0' };
|
||||
Char STRsp3dots[] = { ' ', '.', '.', '.', '\0' };
|
||||
Char STRspLarrow2sp[] = { ' ', '<', '<', ' ', '\0' };
|
||||
Char STRspLarrowsp[] = { ' ', '<', ' ', '\0' };
|
||||
Char STRspRarrow[] = { ' ', '>', '\0' };
|
||||
Char STRspRarrow2[] = { ' ', '>', '>', '\0' };
|
||||
Char STRRparen[] = { ')', '\0' };
|
||||
Char STRspace[] = { ' ', '\0' };
|
||||
Char STRspand2sp[] = { ' ', '&', '&', ' ', '\0' };
|
||||
Char STRspor2sp[] = { ' ', '|', '|', ' ', '\0' };
|
||||
Char STRsporsp[] = { ' ', '|', ' ', '\0' };
|
||||
Char STRstar[] = { '*', '\0' };
|
||||
Char STRstatus[] = { 's', 't', 'a', 't', 'u', 's', '\0' };
|
||||
Char STRsymcent[] = { '%', ' ', '\0' };
|
||||
Char STRsymhash[] = { '#', ' ', '\0' };
|
||||
Char STRterm[] = { 't', 'e', 'r', 'm', '\0' };
|
||||
Char STRthen[] = { 't', 'h', 'e', 'n', '\0' };
|
||||
Char STRtilde[] = { '~', '\0' };
|
||||
Char STRtime[] = { 't', 'i', 'm', 'e', '\0' };
|
||||
Char STRtmpsh[] = { '/', 't', 'm', 'p', '/', 's', 'h', '\0' };
|
||||
Char STRunalias[] = { 'u', 'n', 'a', 'l', 'i', 'a', 's', '\0' };
|
||||
Char STRuser[] = { 'u', 's', 'e', 'r', '\0' };
|
||||
Char STRverbose[] = { 'v', 'e', 'r', 'b', 'o', 's', 'e', '\0' };
|
||||
Char STRwordchars[] = { 'w', 'o', 'r', 'd', 'c', 'h', 'a', 'r', 's', '\0' };
|
||||
-2220
File diff suppressed because it is too large.
Load diff
-1362
File diff suppressed because it is too large.
Load diff
-551
@@ -1,551 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)csh.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fundamental definitions which may vary from system to system.
|
||||
*
|
||||
* BUFSIZ The i/o buffering size; also limits word size
|
||||
* MAILINTVL How often to mailcheck; more often is more expensive
|
||||
*/
|
||||
#ifndef BUFSIZ
|
||||
#define BUFSIZ 1024 /* default buffer size */
|
||||
#endif /* BUFSIZ */
|
||||
|
||||
#define FORKSLEEP 10 /* delay loop on non-interactive fork failure */
|
||||
#define MAILINTVL 600 /* 10 minutes */
|
||||
|
||||
/*
|
||||
* The shell moves std in/out/diag and the old std input away from units
|
||||
* 0, 1, and 2 so that it is easy to set up these standards for invoked
|
||||
* commands.
|
||||
*/
|
||||
#define FSHTTY 15 /* /dev/tty when manip pgrps */
|
||||
#define FSHIN 16 /* Preferred desc for shell input */
|
||||
#define FSHOUT 17 /* ... shell output */
|
||||
#define FSHERR 18 /* ... shell diagnostics */
|
||||
#define FOLDSTD 19 /* ... old std input */
|
||||
|
||||
#ifdef PROF
|
||||
#define xexit(n) done(n)
|
||||
#endif
|
||||
|
||||
#ifdef SHORT_STRINGS
|
||||
typedef short Char;
|
||||
|
||||
#define SAVE(a) (Strsave(str2short(a)))
|
||||
#else
|
||||
typedef char Char;
|
||||
|
||||
#define SAVE(a) (strsave(a))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure a variable is not stored in a register by taking its address
|
||||
* This is used where variables might be clobbered by longjmp.
|
||||
*/
|
||||
#define UNREGISTER(a) (void) &a
|
||||
|
||||
typedef void *ioctl_t; /* Third arg of ioctl */
|
||||
|
||||
typedef void *ptr_t;
|
||||
|
||||
#include "const.h"
|
||||
#include "char.h"
|
||||
#include "errnum.h"
|
||||
|
||||
#define xmalloc(i) Malloc(i)
|
||||
#define xrealloc(p, i) Realloc(p, i)
|
||||
#define xcalloc(n, s) Calloc(n, s)
|
||||
#define xfree(p) Free(p)
|
||||
|
||||
#include <stdio.h>
|
||||
FILE *cshin, *cshout, *csherr;
|
||||
|
||||
#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
|
||||
|
||||
typedef int bool;
|
||||
|
||||
#define eq(a, b) (Strcmp(a, b) == 0)
|
||||
|
||||
/* globone() flags */
|
||||
#define G_ERROR 0 /* default action: error if multiple words */
|
||||
#define G_IGNORE 1 /* ignore the rest of the words */
|
||||
#define G_APPEND 2 /* make a sentence by cat'ing the words */
|
||||
|
||||
/*
|
||||
* Global flags
|
||||
*/
|
||||
bool chkstop; /* Warned of stopped jobs... allow exit */
|
||||
bool didfds; /* Have setup i/o fd's for child */
|
||||
bool doneinp; /* EOF indicator after reset from readc */
|
||||
bool exiterr; /* Exit if error or non-zero exit status */
|
||||
bool child; /* Child shell ... errors cause exit */
|
||||
bool haderr; /* Reset was because of an error */
|
||||
bool intty; /* Input is a tty */
|
||||
bool intact; /* We are interactive... therefore prompt */
|
||||
bool justpr; /* Just print because of :p hist mod */
|
||||
bool loginsh; /* We are a loginsh -> .login/.logout */
|
||||
bool neednote; /* Need to pnotify() */
|
||||
bool noexec; /* Don't execute, just syntax check */
|
||||
bool pjobs; /* want to print jobs if interrupted */
|
||||
bool setintr; /* Set interrupts on/off -> Wait intr... */
|
||||
bool timflg; /* Time the next waited for command */
|
||||
bool havhash; /* path hashing is available */
|
||||
|
||||
#ifdef FILEC
|
||||
bool filec; /* doing filename expansion */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global i/o info
|
||||
*/
|
||||
Char *arginp; /* Argument input for sh -c and internal `xx` */
|
||||
int onelflg; /* 2 -> need line for -t, 1 -> exit on read */
|
||||
Char *ffile; /* Name of shell file for $0 */
|
||||
|
||||
char *seterr; /* Error message from scanner/parser */
|
||||
Char *shtemp; /* Temp name for << shell files in /tmp */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
struct timeval time0; /* Time at which the shell started */
|
||||
struct rusage ru0;
|
||||
|
||||
/*
|
||||
* Miscellany
|
||||
*/
|
||||
Char *doldol; /* Character pid for $$ */
|
||||
int backpid; /* Pid of the last background process */
|
||||
int uid, euid; /* Invokers uid */
|
||||
int gid, egid; /* Invokers gid */
|
||||
time_t chktim; /* Time mail last checked */
|
||||
int shpgrp; /* Pgrp of shell */
|
||||
int tpgrp; /* Terminal process group */
|
||||
|
||||
/* If tpgrp is -1, leave tty alone! */
|
||||
int opgrp; /* Initial pgrp and tty pgrp */
|
||||
|
||||
|
||||
/*
|
||||
* To be able to redirect i/o for builtins easily, the shell moves the i/o
|
||||
* descriptors it uses away from 0,1,2.
|
||||
* Ideally these should be in units which are closed across exec's
|
||||
* (this saves work) but for version 6, this is not usually possible.
|
||||
* The desired initial values for these descriptors are F{SHIN,...}.
|
||||
*/
|
||||
int SHIN; /* Current shell input (script) */
|
||||
int SHOUT; /* Shell output */
|
||||
int SHERR; /* Diagnostic output... shell errs go here */
|
||||
int OLDSTD; /* Old standard input (def for cmds) */
|
||||
|
||||
/*
|
||||
* Error control
|
||||
*
|
||||
* Errors in scanning and parsing set up an error message to be printed
|
||||
* at the end and complete. Other errors always cause a reset.
|
||||
* Because of source commands and .cshrc we need nested error catches.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
jmp_buf reslab;
|
||||
|
||||
#define setexit() (setjmp(reslab))
|
||||
#define reset() longjmp(reslab, 1)
|
||||
/* Should use structure assignment here */
|
||||
#define getexit(a) memmove((char *)(a), (char *)reslab, sizeof reslab)
|
||||
#define resexit(a) memmove((char *)reslab, (char *)(a), sizeof reslab)
|
||||
|
||||
Char *gointr; /* Label for an onintr transfer */
|
||||
|
||||
#include <signal.h>
|
||||
sig_t parintr; /* Parents interrupt catch */
|
||||
sig_t parterm; /* Parents terminate catch */
|
||||
|
||||
/*
|
||||
* Lexical definitions.
|
||||
*
|
||||
* All lexical space is allocated dynamically.
|
||||
* The eighth/sixteenth bit of characters is used to prevent recognition,
|
||||
* and eventually stripped.
|
||||
*/
|
||||
#define META 0200
|
||||
#define ASCII 0177
|
||||
#ifdef SHORT_STRINGS
|
||||
#define CHAR 0377
|
||||
#define QUOTE 0100000 /* 16nth char bit used for 'ing */
|
||||
#define TRIM 0077777 /* Mask to strip quote bit */
|
||||
#else
|
||||
#define CHAR 0177
|
||||
#define QUOTE 0200 /* Eighth char bit used for 'ing */
|
||||
#define TRIM 0177 /* Mask to strip quote bit */
|
||||
#endif
|
||||
|
||||
int AsciiOnly; /* If set only 7 bits is expected in characters */
|
||||
|
||||
/*
|
||||
* Each level of input has a buffered input structure.
|
||||
* There are one or more blocks of buffered input for each level,
|
||||
* exactly one if the input is seekable and tell is available.
|
||||
* In other cases, the shell buffers enough blocks to keep all loops
|
||||
* in the buffer.
|
||||
*/
|
||||
struct Bin {
|
||||
off_t Bfseekp; /* Seek pointer */
|
||||
off_t Bfbobp; /* Seekp of beginning of buffers */
|
||||
off_t Bfeobp; /* Seekp of end of buffers */
|
||||
int Bfblocks; /* Number of buffer blocks */
|
||||
Char **Bfbuf; /* The array of buffer blocks */
|
||||
} B;
|
||||
|
||||
/*
|
||||
* This structure allows us to seek inside aliases
|
||||
*/
|
||||
struct Ain {
|
||||
int type;
|
||||
#define I_SEEK -1 /* Invalid seek */
|
||||
#define A_SEEK 0 /* Alias seek */
|
||||
#define F_SEEK 1 /* File seek */
|
||||
#define E_SEEK 2 /* Eval seek */
|
||||
union {
|
||||
off_t _f_seek;
|
||||
Char* _c_seek;
|
||||
} fc;
|
||||
#define f_seek fc._f_seek
|
||||
#define c_seek fc._c_seek
|
||||
Char **a_seek;
|
||||
} ;
|
||||
extern int aret; /* What was the last character returned */
|
||||
#define SEEKEQ(a, b) ((a)->type == (b)->type && \
|
||||
(a)->f_seek == (b)->f_seek && \
|
||||
(a)->a_seek == (b)->a_seek)
|
||||
|
||||
#define fseekp B.Bfseekp
|
||||
#define fbobp B.Bfbobp
|
||||
#define feobp B.Bfeobp
|
||||
#define fblocks B.Bfblocks
|
||||
#define fbuf B.Bfbuf
|
||||
|
||||
/*
|
||||
* The shell finds commands in loops by reseeking the input
|
||||
* For whiles, in particular, it reseeks to the beginning of the
|
||||
* line the while was on; hence the while placement restrictions.
|
||||
*/
|
||||
struct Ain lineloc;
|
||||
|
||||
bool cantell; /* Is current source tellable ? */
|
||||
|
||||
/*
|
||||
* Input lines are parsed into doubly linked circular
|
||||
* lists of words of the following form.
|
||||
*/
|
||||
struct wordent {
|
||||
Char *word;
|
||||
struct wordent *prev;
|
||||
struct wordent *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* During word building, both in the initial lexical phase and
|
||||
* when expanding $ variable substitutions, expansion by `!' and `$'
|
||||
* must be inhibited when reading ahead in routines which are themselves
|
||||
* processing `!' and `$' expansion or after characters such as `\' or in
|
||||
* quotations. The following flags are passed to the getC routines
|
||||
* telling them which of these substitutions are appropriate for the
|
||||
* next character to be returned.
|
||||
*/
|
||||
#define DODOL 1
|
||||
#define DOEXCL 2
|
||||
#define DOALL DODOL|DOEXCL
|
||||
|
||||
/*
|
||||
* Labuf implements a general buffer for lookahead during lexical operations.
|
||||
* Text which is to be placed in the input stream can be stuck here.
|
||||
* We stick parsed ahead $ constructs during initial input,
|
||||
* process id's from `$$', and modified variable values (from qualifiers
|
||||
* during expansion in sh.dol.c) here.
|
||||
*/
|
||||
Char *lap;
|
||||
|
||||
/*
|
||||
* Parser structure
|
||||
*
|
||||
* Each command is parsed to a tree of command structures and
|
||||
* flags are set bottom up during this process, to be propagated down
|
||||
* as needed during the semantics/execution pass (sh.sem.c).
|
||||
*/
|
||||
struct command {
|
||||
short t_dtyp; /* Type of node */
|
||||
#define NODE_COMMAND 1 /* t_dcom <t_dlef >t_drit */
|
||||
#define NODE_PAREN 2 /* ( t_dspr ) <t_dlef >t_drit */
|
||||
#define NODE_PIPE 3 /* t_dlef | t_drit */
|
||||
#define NODE_LIST 4 /* t_dlef ; t_drit */
|
||||
#define NODE_OR 5 /* t_dlef || t_drit */
|
||||
#define NODE_AND 6 /* t_dlef && t_drit */
|
||||
short t_dflg; /* Flags, e.g. F_AMPERSAND|... */
|
||||
#define F_SAVE (F_NICE|F_TIME|F_NOHUP) /* save these when re-doing */
|
||||
|
||||
#define F_AMPERSAND (1<<0) /* executes in background */
|
||||
#define F_APPEND (1<<1) /* output is redirected >> */
|
||||
#define F_PIPEIN (1<<2) /* input is a pipe */
|
||||
#define F_PIPEOUT (1<<3) /* output is a pipe */
|
||||
#define F_NOFORK (1<<4) /* don't fork, last ()ized cmd */
|
||||
#define F_NOINTERRUPT (1<<5) /* should be immune from intr's */
|
||||
/* spare */
|
||||
#define F_STDERR (1<<7) /* redirect unit 2 with unit 1 */
|
||||
#define F_OVERWRITE (1<<8) /* output was ! */
|
||||
#define F_READ (1<<9) /* input redirection is << */
|
||||
#define F_REPEAT (1<<10) /* reexec aft if, repeat,... */
|
||||
#define F_NICE (1<<11) /* t_nice is meaningful */
|
||||
#define F_NOHUP (1<<12) /* nohup this command */
|
||||
#define F_TIME (1<<13) /* time this command */
|
||||
union {
|
||||
Char *T_dlef; /* Input redirect word */
|
||||
struct command *T_dcar; /* Left part of list/pipe */
|
||||
} L;
|
||||
union {
|
||||
Char *T_drit; /* Output redirect word */
|
||||
struct command *T_dcdr; /* Right part of list/pipe */
|
||||
} R;
|
||||
#define t_dlef L.T_dlef
|
||||
#define t_dcar L.T_dcar
|
||||
#define t_drit R.T_drit
|
||||
#define t_dcdr R.T_dcdr
|
||||
Char **t_dcom; /* Command/argument vector */
|
||||
struct command *t_dspr; /* Pointer to ()'d subtree */
|
||||
int t_nice;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* These are declared here because they want to be
|
||||
* initialized in sh.init.c (to allow them to be made readonly)
|
||||
*/
|
||||
|
||||
extern struct biltins {
|
||||
char *bname;
|
||||
void (*bfunct) __P((Char **, struct command *));
|
||||
short minargs, maxargs;
|
||||
} bfunc[];
|
||||
extern int nbfunc;
|
||||
|
||||
extern struct srch {
|
||||
char *s_name;
|
||||
short s_value;
|
||||
} srchn[];
|
||||
extern int nsrchn;
|
||||
|
||||
/*
|
||||
* The keywords for the parser
|
||||
*/
|
||||
#define T_BREAK 0
|
||||
#define T_BRKSW 1
|
||||
#define T_CASE 2
|
||||
#define T_DEFAULT 3
|
||||
#define T_ELSE 4
|
||||
#define T_END 5
|
||||
#define T_ENDIF 6
|
||||
#define T_ENDSW 7
|
||||
#define T_EXIT 8
|
||||
#define T_FOREACH 9
|
||||
#define T_GOTO 10
|
||||
#define T_IF 11
|
||||
#define T_LABEL 12
|
||||
#define T_LET 13
|
||||
#define T_SET 14
|
||||
#define T_SWITCH 15
|
||||
#define T_TEST 16
|
||||
#define T_THEN 17
|
||||
#define T_WHILE 18
|
||||
|
||||
/*
|
||||
* Structure defining the existing while/foreach loops at this
|
||||
* source level. Loops are implemented by seeking back in the
|
||||
* input. For foreach (fe), the word list is attached here.
|
||||
*/
|
||||
struct whyle {
|
||||
struct Ain w_start; /* Point to restart loop */
|
||||
struct Ain w_end; /* End of loop (0 if unknown) */
|
||||
Char **w_fe, **w_fe0; /* Current/initial wordlist for fe */
|
||||
Char *w_fename; /* Name for fe */
|
||||
struct whyle *w_next; /* Next (more outer) loop */
|
||||
} *whyles;
|
||||
|
||||
/*
|
||||
* Variable structure
|
||||
*
|
||||
* Aliases and variables are stored in AVL balanced binary trees.
|
||||
*/
|
||||
struct varent {
|
||||
Char **vec; /* Array of words which is the value */
|
||||
Char *v_name; /* Name of variable/alias */
|
||||
struct varent *v_link[3]; /* The links, see below */
|
||||
int v_bal; /* Balance factor */
|
||||
} shvhed, aliases;
|
||||
|
||||
#define v_left v_link[0]
|
||||
#define v_right v_link[1]
|
||||
#define v_parent v_link[2]
|
||||
|
||||
#define adrof(v) adrof1(v, &shvhed)
|
||||
#define value(v) value1(v, &shvhed)
|
||||
|
||||
/*
|
||||
* The following are for interfacing redo substitution in
|
||||
* aliases to the lexical routines.
|
||||
*/
|
||||
struct wordent *alhistp; /* Argument list (first) */
|
||||
struct wordent *alhistt; /* Node after last in arg list */
|
||||
Char **alvec, *alvecp; /* The (remnants of) alias vector */
|
||||
|
||||
/*
|
||||
* Filename/command name expansion variables
|
||||
*/
|
||||
int gflag; /* After tglob -> is globbing needed? */
|
||||
|
||||
#define MAXVARLEN 30 /* Maximum number of char in a variable name */
|
||||
|
||||
/*
|
||||
* Variables for filename expansion
|
||||
*/
|
||||
extern Char **gargv; /* Pointer to the (stack) arglist */
|
||||
extern long gargc; /* Number args in gargv */
|
||||
|
||||
/*
|
||||
* Variables for command expansion.
|
||||
*/
|
||||
extern Char **pargv; /* Pointer to the argv list space */
|
||||
extern long pargc; /* Count of arguments in pargv */
|
||||
Char *pargs; /* Pointer to start current word */
|
||||
long pnleft; /* Number of chars left in pargs */
|
||||
Char *pargcp; /* Current index into pargs */
|
||||
|
||||
/*
|
||||
* History list
|
||||
*
|
||||
* Each history list entry contains an embedded wordlist
|
||||
* from the scanner, a number for the event, and a reference count
|
||||
* to aid in discarding old entries.
|
||||
*
|
||||
* Essentially "invisible" entries are put on the history list
|
||||
* when history substitution includes modifiers, and thrown away
|
||||
* at the next discarding since their event numbers are very negative.
|
||||
*/
|
||||
struct Hist {
|
||||
struct wordent Hlex;
|
||||
int Hnum;
|
||||
int Href;
|
||||
struct Hist *Hnext;
|
||||
} Histlist;
|
||||
|
||||
struct wordent paraml; /* Current lexical word list */
|
||||
int eventno; /* Next events number */
|
||||
int lastev; /* Last event reference (default) */
|
||||
|
||||
Char HIST; /* history invocation character */
|
||||
Char HISTSUB; /* auto-substitute character */
|
||||
|
||||
/*
|
||||
* strings.h:
|
||||
*/
|
||||
#ifndef SHORT_STRINGS
|
||||
#define Strchr(a, b) strchr(a, b)
|
||||
#define Strrchr(a, b) strrchr(a, b)
|
||||
#define Strcat(a, b) strcat(a, b)
|
||||
#define Strncat(a, b, c) strncat(a, b, c)
|
||||
#define Strcpy(a, b) strcpy(a, b)
|
||||
#define Strncpy(a, b, c) strncpy(a, b, c)
|
||||
#define Strlen(a) strlen(a)
|
||||
#define Strcmp(a, b) strcmp(a, b)
|
||||
#define Strncmp(a, b, c) strncmp(a, b, c)
|
||||
|
||||
#define Strspl(a, b) strspl(a, b)
|
||||
#define Strsave(a) strsave(a)
|
||||
#define Strend(a) strend(a)
|
||||
#define Strstr(a, b) strstr(a, b)
|
||||
|
||||
#define str2short(a) (a)
|
||||
#define blk2short(a) saveblk(a)
|
||||
#define short2blk(a) saveblk(a)
|
||||
#define short2str(a) strip(a)
|
||||
#else
|
||||
#define Strchr(a, b) s_strchr(a, b)
|
||||
#define Strrchr(a, b) s_strrchr(a, b)
|
||||
#define Strcat(a, b) s_strcat(a, b)
|
||||
#define Strncat(a, b, c) s_strncat(a, b, c)
|
||||
#define Strcpy(a, b) s_strcpy(a, b)
|
||||
#define Strncpy(a, b, c) s_strncpy(a, b, c)
|
||||
#define Strlen(a) s_strlen(a)
|
||||
#define Strcmp(a, b) s_strcmp(a, b)
|
||||
#define Strncmp(a, b, c) s_strncmp(a, b, c)
|
||||
|
||||
#define Strspl(a, b) s_strspl(a, b)
|
||||
#define Strsave(a) s_strsave(a)
|
||||
#define Strend(a) s_strend(a)
|
||||
#define Strstr(a, b) s_strstr(a, b)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* setname is a macro to save space (see sh.err.c)
|
||||
*/
|
||||
char *bname;
|
||||
|
||||
#define setname(a) (bname = (a))
|
||||
|
||||
Char *Vsav;
|
||||
Char *Vdp;
|
||||
Char *Vexpath;
|
||||
char **Vt;
|
||||
|
||||
Char **evalvec;
|
||||
Char *evalp;
|
||||
|
||||
/* word_chars is set by default to WORD_CHARS but can be overridden by
|
||||
the wordchars variable--if unset, reverts to WORD_CHARS */
|
||||
|
||||
Char *word_chars;
|
||||
|
||||
#define WORD_CHARS "*?_-.[]~=" /* default chars besides alnums in words */
|
||||
|
||||
Char *STR_SHELLPATH;
|
||||
|
||||
#include <paths.h>
|
||||
#ifdef _PATH_BSHELL
|
||||
Char *STR_BSHELL;
|
||||
#endif
|
||||
Char *STR_WORD_CHARS;
|
||||
Char **STR_environ;
|
||||
-933
@@ -1,933 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "dir.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* Directory management. */
|
||||
|
||||
static struct directory
|
||||
*dfind __P((Char *));
|
||||
static Char *dfollow __P((Char *));
|
||||
static void printdirs __P((void));
|
||||
static Char *dgoto __P((Char *));
|
||||
static void dnewcwd __P((struct directory *));
|
||||
static void dset __P((Char *));
|
||||
|
||||
struct directory dhead; /* "head" of loop */
|
||||
int printd; /* force name to be printed */
|
||||
|
||||
static int dirflag = 0;
|
||||
|
||||
/*
|
||||
* dinit - initialize current working directory
|
||||
*/
|
||||
void
|
||||
dinit(hp)
|
||||
Char *hp;
|
||||
{
|
||||
char *tcp;
|
||||
Char *cp;
|
||||
struct directory *dp;
|
||||
char path[MAXPATHLEN];
|
||||
static char *emsg = "csh: Trying to start from \"%s\"\n";
|
||||
|
||||
/* Don't believe the login shell home, because it may be a symlink */
|
||||
tcp = getcwd(path, MAXPATHLEN); /* see ngetwd.c for System V version */
|
||||
if (tcp == NULL || *tcp == '\0') {
|
||||
(void) fprintf(csherr, "csh: %s: %s\n", path, strerror(errno));
|
||||
if (hp && *hp) {
|
||||
tcp = short2str(hp);
|
||||
if (chdir(tcp) == -1)
|
||||
cp = NULL;
|
||||
else
|
||||
cp = hp;
|
||||
(void) fprintf(csherr, emsg, vis_str(hp));
|
||||
}
|
||||
else
|
||||
cp = NULL;
|
||||
if (cp == NULL) {
|
||||
(void) fprintf(csherr, emsg, "/");
|
||||
if (chdir("/") == -1)
|
||||
/* I am not even try to print an error message! */
|
||||
xexit(1);
|
||||
cp = SAVE("/");
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct stat swd, shp;
|
||||
|
||||
/*
|
||||
* See if $HOME is the working directory we got and use that
|
||||
*/
|
||||
if (hp && *hp &&
|
||||
stat(tcp, &swd) != -1 && stat(short2str(hp), &shp) != -1 &&
|
||||
swd.st_dev == shp.st_dev && swd.st_ino == shp.st_ino)
|
||||
cp = hp;
|
||||
else {
|
||||
char *cwd;
|
||||
|
||||
/*
|
||||
* use PWD if we have it (for subshells)
|
||||
*/
|
||||
if ((cwd = getenv("PWD")) != NULL) {
|
||||
if (stat(cwd, &shp) != -1 && swd.st_dev == shp.st_dev &&
|
||||
swd.st_ino == shp.st_ino)
|
||||
tcp = cwd;
|
||||
}
|
||||
cp = dcanon(SAVE(tcp), STRNULL);
|
||||
}
|
||||
}
|
||||
|
||||
dp = (struct directory *) xcalloc(sizeof(struct directory), 1);
|
||||
dp->di_name = Strsave(cp);
|
||||
dp->di_count = 0;
|
||||
dhead.di_next = dhead.di_prev = dp;
|
||||
dp->di_next = dp->di_prev = &dhead;
|
||||
printd = 0;
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
static void
|
||||
dset(dp)
|
||||
Char *dp;
|
||||
{
|
||||
/*
|
||||
* Don't call set() directly cause if the directory contains ` or
|
||||
* other junk characters glob will fail.
|
||||
*/
|
||||
Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **)));
|
||||
|
||||
vec[0] = Strsave(dp);
|
||||
vec[1] = 0;
|
||||
setq(STRcwd, vec, &shvhed);
|
||||
Setenv(STRPWD, dp);
|
||||
}
|
||||
|
||||
#define DIR_LONG 1
|
||||
#define DIR_VERT 2
|
||||
#define DIR_LINE 4
|
||||
|
||||
static void
|
||||
skipargs(v, str)
|
||||
Char ***v;
|
||||
char *str;
|
||||
{
|
||||
Char **n = *v, *s;
|
||||
|
||||
dirflag = 0;
|
||||
for (n++; *n != NULL && (*n)[0] == '-'; n++)
|
||||
for (s = &((*n)[1]); *s; s++)
|
||||
switch (*s) {
|
||||
case 'l':
|
||||
dirflag |= DIR_LONG;
|
||||
break;
|
||||
case 'v':
|
||||
dirflag |= DIR_VERT;
|
||||
break;
|
||||
case 'n':
|
||||
dirflag |= DIR_LINE;
|
||||
break;
|
||||
default:
|
||||
stderror(ERR_DIRUS, vis_str(**v), str);
|
||||
break;
|
||||
}
|
||||
*v = n;
|
||||
}
|
||||
|
||||
/*
|
||||
* dodirs - list all directories in directory loop
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dodirs(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
skipargs(&v, "");
|
||||
|
||||
if (*v != NULL)
|
||||
stderror(ERR_DIRUS, "dirs", "");
|
||||
printdirs();
|
||||
}
|
||||
|
||||
static void
|
||||
printdirs()
|
||||
{
|
||||
struct directory *dp;
|
||||
Char *s, *hp = value(STRhome);
|
||||
int idx, len, cur;
|
||||
|
||||
if (*hp == '\0')
|
||||
hp = NULL;
|
||||
dp = dcwd;
|
||||
idx = 0;
|
||||
cur = 0;
|
||||
do {
|
||||
if (dp == &dhead)
|
||||
continue;
|
||||
if (dirflag & DIR_VERT) {
|
||||
(void) fprintf(cshout, "%d\t", idx++);
|
||||
cur = 0;
|
||||
}
|
||||
if (!(dirflag & DIR_LONG) && hp != NULL && !eq(hp, STRslash) &&
|
||||
(len = Strlen(hp), Strncmp(hp, dp->di_name, len) == 0) &&
|
||||
(dp->di_name[len] == '\0' || dp->di_name[len] == '/'))
|
||||
len = Strlen(s = (dp->di_name + len)) + 2;
|
||||
else
|
||||
len = Strlen(s = dp->di_name) + 1;
|
||||
|
||||
cur += len;
|
||||
if ((dirflag & DIR_LINE) && cur >= 80 - 1 && len < 80) {
|
||||
(void) fprintf(cshout, "\n");
|
||||
cur = len;
|
||||
}
|
||||
(void) fprintf(cshout, s != dp->di_name ? "~%s%c" : "%s%c",
|
||||
vis_str(s), (dirflag & DIR_VERT) ? '\n' : ' ');
|
||||
} while ((dp = dp->di_prev) != dcwd);
|
||||
if (!(dirflag & DIR_VERT))
|
||||
(void) fprintf(cshout, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dtildepr(home, dir)
|
||||
Char *home, *dir;
|
||||
{
|
||||
|
||||
if (!eq(home, STRslash) && prefix(home, dir))
|
||||
(void) fprintf(cshout, "~%s", vis_str(dir + Strlen(home)));
|
||||
else
|
||||
(void) fprintf(cshout, "%s", vis_str(dir));
|
||||
}
|
||||
|
||||
void
|
||||
dtilde()
|
||||
{
|
||||
struct directory *d = dcwd;
|
||||
|
||||
do {
|
||||
if (d == &dhead)
|
||||
continue;
|
||||
d->di_name = dcanon(d->di_name, STRNULL);
|
||||
} while ((d = d->di_prev) != dcwd);
|
||||
|
||||
dset(dcwd->di_name);
|
||||
}
|
||||
|
||||
|
||||
/* dnormalize():
|
||||
* If the name starts with . or .. then we might need to normalize
|
||||
* it depending on the symbolic link flags
|
||||
*/
|
||||
Char *
|
||||
dnormalize(cp)
|
||||
Char *cp;
|
||||
{
|
||||
|
||||
#define UC (unsigned char)
|
||||
#define ISDOT(c) (UC(c)[0] == '.' && ((UC(c)[1] == '\0') || (UC(c)[1] == '/')))
|
||||
#define ISDOTDOT(c) (UC(c)[0] == '.' && ISDOT(&((c)[1])))
|
||||
|
||||
if ((unsigned char) cp[0] == '/')
|
||||
return (Strsave(cp));
|
||||
|
||||
if (adrof(STRignore_symlinks)) {
|
||||
int dotdot = 0;
|
||||
Char *dp, *cwd;
|
||||
|
||||
cwd = (Char *) xmalloc((size_t) ((Strlen(dcwd->di_name) + 3) *
|
||||
sizeof(Char)));
|
||||
(void) Strcpy(cwd, dcwd->di_name);
|
||||
|
||||
/*
|
||||
* Ignore . and count ..'s
|
||||
*/
|
||||
while (*cp) {
|
||||
if (ISDOT(cp)) {
|
||||
if (*++cp)
|
||||
cp++;
|
||||
}
|
||||
else if (ISDOTDOT(cp)) {
|
||||
dotdot++;
|
||||
cp += 2;
|
||||
if (*cp)
|
||||
cp++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (dotdot > 0)
|
||||
if ((dp = Strrchr(cwd, '/'))) {
|
||||
*dp = '\0';
|
||||
dotdot--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if (*cp) {
|
||||
cwd[dotdot = Strlen(cwd)] = '/';
|
||||
cwd[dotdot + 1] = '\0';
|
||||
dp = Strspl(cwd, cp);
|
||||
xfree((ptr_t) cwd);
|
||||
return dp;
|
||||
}
|
||||
else {
|
||||
if (!*cwd) {
|
||||
cwd[0] = '/';
|
||||
cwd[1] = '\0';
|
||||
}
|
||||
return cwd;
|
||||
}
|
||||
}
|
||||
return Strsave(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dochngd - implement chdir command.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dochngd(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
Char *cp;
|
||||
struct directory *dp;
|
||||
|
||||
skipargs(&v, " [<dir>]");
|
||||
printd = 0;
|
||||
if (*v == NULL) {
|
||||
if ((cp = value(STRhome)) == NULL || *cp == 0)
|
||||
stderror(ERR_NAME | ERR_NOHOMEDIR);
|
||||
if (chdir(short2str(cp)) < 0)
|
||||
stderror(ERR_NAME | ERR_CANTCHANGE);
|
||||
cp = Strsave(cp);
|
||||
}
|
||||
else if (v[1] != NULL) {
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
else if ((dp = dfind(*v)) != 0) {
|
||||
char *tmp;
|
||||
|
||||
printd = 1;
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
dcwd->di_prev->di_next = dcwd->di_next;
|
||||
dcwd->di_next->di_prev = dcwd->di_prev;
|
||||
dfree(dcwd);
|
||||
dnewcwd(dp);
|
||||
return;
|
||||
}
|
||||
else
|
||||
cp = dfollow(*v);
|
||||
dp = (struct directory *) xcalloc(sizeof(struct directory), 1);
|
||||
dp->di_name = cp;
|
||||
dp->di_count = 0;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dp->di_prev = dcwd->di_prev;
|
||||
dp->di_prev->di_next = dp;
|
||||
dp->di_next->di_prev = dp;
|
||||
dfree(dcwd);
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
static Char *
|
||||
dgoto(cp)
|
||||
Char *cp;
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
if (*cp != '/') {
|
||||
Char *p, *q;
|
||||
int cwdlen;
|
||||
|
||||
for (p = dcwd->di_name; *p++;)
|
||||
continue;
|
||||
if ((cwdlen = p - dcwd->di_name - 1) == 1) /* root */
|
||||
cwdlen = 0;
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
dp = (Char *) xmalloc((size_t)((cwdlen + (p - cp) + 1) * sizeof(Char)));
|
||||
for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
if (cwdlen)
|
||||
p[-1] = '/';
|
||||
else
|
||||
p--; /* don't add a / after root */
|
||||
for (q = cp; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
dp += cwdlen;
|
||||
}
|
||||
else
|
||||
dp = cp;
|
||||
|
||||
cp = dcanon(cp, dp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* dfollow - change to arg directory; fall back on cdpath if not valid
|
||||
*/
|
||||
static Char *
|
||||
dfollow(cp)
|
||||
Char *cp;
|
||||
{
|
||||
Char *dp;
|
||||
struct varent *c;
|
||||
char ebuf[MAXPATHLEN];
|
||||
int serrno;
|
||||
|
||||
cp = globone(cp, G_ERROR);
|
||||
/*
|
||||
* if we are ignoring symlinks, try to fix relatives now.
|
||||
*/
|
||||
dp = dnormalize(cp);
|
||||
if (chdir(short2str(dp)) >= 0) {
|
||||
xfree((ptr_t) cp);
|
||||
return dgoto(dp);
|
||||
}
|
||||
else {
|
||||
xfree((ptr_t) dp);
|
||||
if (chdir(short2str(cp)) >= 0)
|
||||
return dgoto(cp);
|
||||
serrno = errno;
|
||||
}
|
||||
|
||||
if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)
|
||||
&& (c = adrof(STRcdpath))) {
|
||||
Char **cdp;
|
||||
Char *p;
|
||||
Char buf[MAXPATHLEN];
|
||||
|
||||
for (cdp = c->vec; *cdp; cdp++) {
|
||||
for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';)
|
||||
continue;
|
||||
dp[-1] = '/';
|
||||
for (p = cp; (*dp++ = *p++) != '\0';)
|
||||
continue;
|
||||
if (chdir(short2str(buf)) >= 0) {
|
||||
printd = 1;
|
||||
xfree((ptr_t) cp);
|
||||
cp = Strsave(buf);
|
||||
return dgoto(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp = value(cp);
|
||||
if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {
|
||||
xfree((ptr_t) cp);
|
||||
cp = Strsave(dp);
|
||||
printd = 1;
|
||||
return dgoto(cp);
|
||||
}
|
||||
(void) strcpy(ebuf, short2str(cp));
|
||||
xfree((ptr_t) cp);
|
||||
stderror(ERR_SYSTEM, ebuf, strerror(serrno));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dopushd - push new directory onto directory stack.
|
||||
* with no arguments exchange top and second.
|
||||
* with numeric argument (+n) bring it to top.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dopushd(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
struct directory *dp;
|
||||
|
||||
skipargs(&v, " [<dir>|+<n>]");
|
||||
printd = 1;
|
||||
if (*v == NULL) {
|
||||
char *tmp;
|
||||
|
||||
if ((dp = dcwd->di_prev) == &dhead)
|
||||
dp = dhead.di_prev;
|
||||
if (dp == dcwd)
|
||||
stderror(ERR_NAME | ERR_NODIR);
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
dp->di_prev->di_next = dp->di_next;
|
||||
dp->di_next->di_prev = dp->di_prev;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dp->di_prev = dcwd;
|
||||
dcwd->di_next->di_prev = dp;
|
||||
dcwd->di_next = dp;
|
||||
}
|
||||
else if (v[1] != NULL) {
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
else if ((dp = dfind(*v)) != NULL) {
|
||||
char *tmp;
|
||||
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
else {
|
||||
Char *ccp;
|
||||
|
||||
ccp = dfollow(*v);
|
||||
dp = (struct directory *) xcalloc(sizeof(struct directory), 1);
|
||||
dp->di_name = ccp;
|
||||
dp->di_count = 0;
|
||||
dp->di_prev = dcwd;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dcwd->di_next = dp;
|
||||
dp->di_next->di_prev = dp;
|
||||
}
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dfind - find a directory if specified by numeric (+n) argument
|
||||
*/
|
||||
static struct directory *
|
||||
dfind(cp)
|
||||
Char *cp;
|
||||
{
|
||||
struct directory *dp;
|
||||
int i;
|
||||
Char *ep;
|
||||
|
||||
if (*cp++ != '+')
|
||||
return (0);
|
||||
for (ep = cp; Isdigit(*ep); ep++)
|
||||
continue;
|
||||
if (*ep)
|
||||
return (0);
|
||||
i = getn(cp);
|
||||
if (i <= 0)
|
||||
return (0);
|
||||
for (dp = dcwd; i != 0; i--) {
|
||||
if ((dp = dp->di_prev) == &dhead)
|
||||
dp = dp->di_prev;
|
||||
if (dp == dcwd)
|
||||
stderror(ERR_NAME | ERR_DEEP);
|
||||
}
|
||||
return (dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dopopd - pop a directory out of the directory stack
|
||||
* with a numeric argument just discard it.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dopopd(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
struct directory *dp, *p = NULL;
|
||||
|
||||
skipargs(&v, " [+<n>]");
|
||||
printd = 1;
|
||||
if (*v == NULL)
|
||||
dp = dcwd;
|
||||
else if (v[1] != NULL) {
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
else if ((dp = dfind(*v)) == 0)
|
||||
stderror(ERR_NAME | ERR_BADDIR);
|
||||
if (dp->di_prev == &dhead && dp->di_next == &dhead)
|
||||
stderror(ERR_NAME | ERR_EMPTY);
|
||||
if (dp == dcwd) {
|
||||
char *tmp;
|
||||
|
||||
if ((p = dp->di_prev) == &dhead)
|
||||
p = dhead.di_prev;
|
||||
if (chdir(tmp = short2str(p->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
dp->di_prev->di_next = dp->di_next;
|
||||
dp->di_next->di_prev = dp->di_prev;
|
||||
if (dp == dcwd)
|
||||
dnewcwd(p);
|
||||
else {
|
||||
printdirs();
|
||||
}
|
||||
dfree(dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dfree - free the directory (or keep it if it still has ref count)
|
||||
*/
|
||||
void
|
||||
dfree(dp)
|
||||
struct directory *dp;
|
||||
{
|
||||
|
||||
if (dp->di_count != 0) {
|
||||
dp->di_next = dp->di_prev = 0;
|
||||
}
|
||||
else {
|
||||
xfree((char *) dp->di_name);
|
||||
xfree((ptr_t) dp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dcanon - canonicalize the pathname, removing excess ./ and ../ etc.
|
||||
* we are of course assuming that the file system is standardly
|
||||
* constructed (always have ..'s, directories have links)
|
||||
*/
|
||||
Char *
|
||||
dcanon(cp, p)
|
||||
Char *cp, *p;
|
||||
{
|
||||
Char *sp;
|
||||
Char *p1, *p2; /* general purpose */
|
||||
bool slash;
|
||||
|
||||
Char link[MAXPATHLEN];
|
||||
char tlink[MAXPATHLEN];
|
||||
int cc;
|
||||
Char *newcp;
|
||||
|
||||
/*
|
||||
* christos: if the path given does not start with a slash prepend cwd. If
|
||||
* cwd does not start with a path or the result would be too long abort().
|
||||
*/
|
||||
if (*cp != '/') {
|
||||
Char tmpdir[MAXPATHLEN];
|
||||
|
||||
p1 = value(STRcwd);
|
||||
if (p1 == NULL || *p1 != '/')
|
||||
abort();
|
||||
if (Strlen(p1) + Strlen(cp) + 1 >= MAXPATHLEN)
|
||||
abort();
|
||||
(void) Strcpy(tmpdir, p1);
|
||||
(void) Strcat(tmpdir, STRslash);
|
||||
(void) Strcat(tmpdir, cp);
|
||||
xfree((ptr_t) cp);
|
||||
cp = p = Strsave(tmpdir);
|
||||
}
|
||||
|
||||
while (*p) { /* for each component */
|
||||
sp = p; /* save slash address */
|
||||
while (*++p == '/') /* flush extra slashes */
|
||||
continue;
|
||||
if (p != ++sp)
|
||||
for (p1 = sp, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = sp; /* save start of component */
|
||||
slash = 0;
|
||||
while (*++p) /* find next slash or end of path */
|
||||
if (*p == '/') {
|
||||
slash = 1;
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*sp == '\0') /* if component is null */
|
||||
if (--sp == cp) /* if path is one char (i.e. /) */
|
||||
break;
|
||||
else
|
||||
*sp = '\0';
|
||||
else if (sp[0] == '.' && sp[1] == 0) {
|
||||
if (slash) {
|
||||
for (p1 = sp, p2 = p + 1; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = --sp;
|
||||
}
|
||||
else if (--sp != cp)
|
||||
*sp = '\0';
|
||||
}
|
||||
else if (sp[0] == '.' && sp[1] == '.' && sp[2] == 0) {
|
||||
/*
|
||||
* We have something like "yyy/xxx/..", where "yyy" can be null or
|
||||
* a path starting at /, and "xxx" is a single component. Before
|
||||
* compressing "xxx/..", we want to expand "yyy/xxx", if it is a
|
||||
* symbolic link.
|
||||
*/
|
||||
*--sp = 0; /* form the pathname for readlink */
|
||||
if (sp != cp && !adrof(STRignore_symlinks) &&
|
||||
(cc = readlink(short2str(cp), tlink, sizeof(tlink) - 1)) >= 0) {
|
||||
(void) Strcpy(link, str2short(tlink));
|
||||
link[cc] = '\0';
|
||||
|
||||
if (slash)
|
||||
*p = '/';
|
||||
/*
|
||||
* Point p to the '/' in "/..", and restore the '/'.
|
||||
*/
|
||||
*(p = sp) = '/';
|
||||
/*
|
||||
* find length of p
|
||||
*/
|
||||
for (p1 = p; *p1++;)
|
||||
continue;
|
||||
if (*link != '/') {
|
||||
/*
|
||||
* Relative path, expand it between the "yyy/" and the
|
||||
* "/..". First, back sp up to the character past "yyy/".
|
||||
*/
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
sp++;
|
||||
*sp = 0;
|
||||
/*
|
||||
* New length is "yyy/" + link + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = (Char *) xmalloc((size_t)
|
||||
(((sp - cp) + cc + (p1 - p)) *
|
||||
sizeof(Char)));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = cp; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = link; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at expanded "/xxx".
|
||||
*/
|
||||
p = sp - cp - 1 + newcp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* New length is link + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = (Char *) xmalloc((size_t)
|
||||
((cc + (p1 - p)) * sizeof(Char)));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = link; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at beginning
|
||||
*/
|
||||
p = newcp;
|
||||
}
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
continue; /* canonicalize the link */
|
||||
}
|
||||
*sp = '/';
|
||||
if (sp != cp)
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
if (slash) {
|
||||
for (p1 = sp + 1, p2 = p + 1; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = sp;
|
||||
}
|
||||
else if (cp == sp)
|
||||
*++sp = '\0';
|
||||
else
|
||||
*sp = '\0';
|
||||
}
|
||||
else { /* normal dir name (not . or .. or nothing) */
|
||||
|
||||
if (sp != cp && adrof(STRchase_symlinks) &&
|
||||
!adrof(STRignore_symlinks) &&
|
||||
(cc = readlink(short2str(cp), tlink, sizeof(tlink) - 1)) >= 0) {
|
||||
(void) Strcpy(link, str2short(tlink));
|
||||
link[cc] = '\0';
|
||||
|
||||
/*
|
||||
* restore the '/'.
|
||||
*/
|
||||
if (slash)
|
||||
*p = '/';
|
||||
|
||||
/*
|
||||
* point sp to p (rather than backing up).
|
||||
*/
|
||||
sp = p;
|
||||
|
||||
/*
|
||||
* find length of p
|
||||
*/
|
||||
for (p1 = p; *p1++;)
|
||||
continue;
|
||||
if (*link != '/') {
|
||||
/*
|
||||
* Relative path, expand it between the "yyy/" and the
|
||||
* remainder. First, back sp up to the character past
|
||||
* "yyy/".
|
||||
*/
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
sp++;
|
||||
*sp = 0;
|
||||
/*
|
||||
* New length is "yyy/" + link + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = (Char *) xmalloc((size_t)
|
||||
(((sp - cp) + cc + (p1 - p))
|
||||
* sizeof(Char)));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = cp; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = link; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at expanded "/xxx".
|
||||
*/
|
||||
p = sp - cp - 1 + newcp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* New length is link + the rest
|
||||
*/
|
||||
p1 = newcp = (Char *) xmalloc((size_t)
|
||||
((cc + (p1 - p)) * sizeof(Char)));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = link; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at beginning
|
||||
*/
|
||||
p = newcp;
|
||||
}
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
continue; /* canonicalize the link */
|
||||
}
|
||||
if (slash)
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fix home...
|
||||
*/
|
||||
p1 = value(STRhome);
|
||||
cc = Strlen(p1);
|
||||
/*
|
||||
* See if we're not in a subdir of STRhome
|
||||
*/
|
||||
if (p1 && *p1 == '/' &&
|
||||
(Strncmp(p1, cp, cc) != 0 || (cp[cc] != '/' && cp[cc] != '\0'))) {
|
||||
static ino_t home_ino = -1;
|
||||
static dev_t home_dev = -1;
|
||||
static Char *home_ptr = NULL;
|
||||
struct stat statbuf;
|
||||
|
||||
/*
|
||||
* Get dev and ino of STRhome
|
||||
*/
|
||||
if (home_ptr != p1 &&
|
||||
stat(short2str(p1), &statbuf) != -1) {
|
||||
home_dev = statbuf.st_dev;
|
||||
home_ino = statbuf.st_ino;
|
||||
home_ptr = p1;
|
||||
}
|
||||
/*
|
||||
* Start comparing dev & ino backwards
|
||||
*/
|
||||
p2 = Strcpy(link, cp);
|
||||
for (sp = NULL; *p2 && stat(short2str(p2), &statbuf) != -1;) {
|
||||
if (statbuf.st_dev == home_dev &&
|
||||
statbuf.st_ino == home_ino) {
|
||||
sp = (Char *) - 1;
|
||||
break;
|
||||
}
|
||||
if ((sp = Strrchr(p2, '/')) != NULL)
|
||||
*sp = '\0';
|
||||
}
|
||||
/*
|
||||
* See if we found it
|
||||
*/
|
||||
if (*p2 && sp == (Char *) -1) {
|
||||
/*
|
||||
* Use STRhome to make '~' work
|
||||
*/
|
||||
newcp = Strspl(p1, cp + Strlen(p2));
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
}
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dnewcwd - make a new directory in the loop the current one
|
||||
*/
|
||||
static void
|
||||
dnewcwd(dp)
|
||||
struct directory *dp;
|
||||
{
|
||||
dcwd = dp;
|
||||
dset(dcwd->di_name);
|
||||
if (printd && !(adrof(STRpushdsilent)))
|
||||
printdirs();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dir.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure for entries in directory stack.
|
||||
*/
|
||||
struct directory {
|
||||
struct directory *di_next; /* next in loop */
|
||||
struct directory *di_prev; /* prev in loop */
|
||||
unsigned short *di_count; /* refcount of processes */
|
||||
Char *di_name; /* actual name */
|
||||
};
|
||||
struct directory *dcwd; /* the one we are in now */
|
||||
-991
@@ -1,991 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dol.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* These routines perform variable substitution and quoting via ' and ".
|
||||
* To this point these constructs have been preserved in the divided
|
||||
* input words. Here we expand variables and turn quoting via ' and " into
|
||||
* QUOTE bits on characters (which prevent further interpretation).
|
||||
* If the `:q' modifier was applied during history expansion, then
|
||||
* some QUOTEing may have occurred already, so we dont "trim()" here.
|
||||
*/
|
||||
|
||||
static int Dpeekc, Dpeekrd; /* Peeks for DgetC and Dreadc */
|
||||
static Char *Dcp, **Dvp; /* Input vector for Dreadc */
|
||||
|
||||
#define DEOF -1
|
||||
|
||||
#define unDgetC(c) Dpeekc = c
|
||||
|
||||
#define QUOTES (_QF|_QB|_ESC) /* \ ' " ` */
|
||||
|
||||
/*
|
||||
* The following variables give the information about the current
|
||||
* $ expansion, recording the current word position, the remaining
|
||||
* words within this expansion, the count of remaining words, and the
|
||||
* information about any : modifier which is being applied.
|
||||
*/
|
||||
#define MAXWLEN (BUFSIZ - 4)
|
||||
#define MAXMOD MAXWLEN /* This cannot overflow */
|
||||
static Char *dolp; /* Remaining chars from this word */
|
||||
static Char **dolnxt; /* Further words */
|
||||
static int dolcnt; /* Count of further words */
|
||||
static Char dolmod[MAXMOD]; /* : modifier character */
|
||||
static int dolnmod; /* Number of modifiers */
|
||||
static int dolmcnt; /* :gx -> 10000, else 1 */
|
||||
static int dolwcnt; /* :wx -> 10000, else 1 */
|
||||
|
||||
static void Dfix2 __P((Char **));
|
||||
static Char *Dpack __P((Char *, Char *));
|
||||
static int Dword __P((void));
|
||||
static void dolerror __P((Char *));
|
||||
static int DgetC __P((int));
|
||||
static void Dgetdol __P((void));
|
||||
static void fixDolMod __P((void));
|
||||
static void setDolp __P((Char *));
|
||||
static void unDredc __P((int));
|
||||
static int Dredc __P((void));
|
||||
static void Dtestq __P((int));
|
||||
|
||||
|
||||
/*
|
||||
* Fix up the $ expansions and quotations in the
|
||||
* argument list to command t.
|
||||
*/
|
||||
void
|
||||
Dfix(t)
|
||||
struct command *t;
|
||||
{
|
||||
Char **pp;
|
||||
Char *p;
|
||||
|
||||
if (noexec)
|
||||
return;
|
||||
/* Note that t_dcom isn't trimmed thus !...:q's aren't lost */
|
||||
for (pp = t->t_dcom; (p = *pp++) != NULL;)
|
||||
for (; *p; p++) {
|
||||
if (cmap(*p, _DOL | QUOTES)) { /* $, \, ', ", ` */
|
||||
Dfix2(t->t_dcom); /* found one */
|
||||
blkfree(t->t_dcom);
|
||||
t->t_dcom = gargv;
|
||||
gargv = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $ substitute one word, for i/o redirection
|
||||
*/
|
||||
Char *
|
||||
Dfix1(cp)
|
||||
Char *cp;
|
||||
{
|
||||
Char *Dv[2];
|
||||
|
||||
if (noexec)
|
||||
return (0);
|
||||
Dv[0] = cp;
|
||||
Dv[1] = NULL;
|
||||
Dfix2(Dv);
|
||||
if (gargc != 1) {
|
||||
setname(vis_str(cp));
|
||||
stderror(ERR_NAME | ERR_AMBIG);
|
||||
}
|
||||
cp = Strsave(gargv[0]);
|
||||
blkfree(gargv), gargv = 0;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Subroutine to do actual fixing after state initialization.
|
||||
*/
|
||||
static void
|
||||
Dfix2(v)
|
||||
Char **v;
|
||||
{
|
||||
ginit(); /* Initialize glob's area pointers */
|
||||
Dvp = v;
|
||||
Dcp = STRNULL; /* Setup input vector for Dreadc */
|
||||
unDgetC(0);
|
||||
unDredc(0); /* Clear out any old peeks (at error) */
|
||||
dolp = 0;
|
||||
dolcnt = 0; /* Clear out residual $ expands (...) */
|
||||
while (Dword())
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack up more characters in this word
|
||||
*/
|
||||
static Char *
|
||||
Dpack(wbuf, wp)
|
||||
Char *wbuf, *wp;
|
||||
{
|
||||
int c;
|
||||
int i = MAXWLEN - (wp - wbuf);
|
||||
|
||||
for (;;) {
|
||||
c = DgetC(DODOL);
|
||||
if (c == '\\') {
|
||||
c = DgetC(0);
|
||||
if (c == DEOF) {
|
||||
unDredc(c);
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (c == '\n')
|
||||
c = ' ';
|
||||
else
|
||||
c |= QUOTE;
|
||||
}
|
||||
if (c == DEOF) {
|
||||
unDredc(c);
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (cmap(c, _SP | _NL | _QF | _QB)) { /* sp \t\n'"` */
|
||||
unDgetC(c);
|
||||
if (cmap(c, QUOTES))
|
||||
return (wp);
|
||||
*wp++ = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (--i <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
*wp++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a word. This routine is analogous to the routine
|
||||
* word() in sh.lex.c for the main lexical input. One difference
|
||||
* here is that we don't get a newline to terminate our expansion.
|
||||
* Rather, DgetC will return a DEOF when we hit the end-of-input.
|
||||
*/
|
||||
static int
|
||||
Dword()
|
||||
{
|
||||
int c, c1;
|
||||
Char wbuf[BUFSIZ];
|
||||
Char *wp = wbuf;
|
||||
int i = MAXWLEN;
|
||||
bool dolflg;
|
||||
bool sofar = 0, done = 0;
|
||||
|
||||
while (!done) {
|
||||
done = 1;
|
||||
c = DgetC(DODOL);
|
||||
switch (c) {
|
||||
|
||||
case DEOF:
|
||||
if (sofar == 0)
|
||||
return (0);
|
||||
/* finish this word and catch the code above the next time */
|
||||
unDredc(c);
|
||||
/* fall into ... */
|
||||
|
||||
case '\n':
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (1);
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
done = 0;
|
||||
break;
|
||||
|
||||
case '`':
|
||||
/* We preserve ` quotations which are done yet later */
|
||||
*wp++ = c, --i;
|
||||
case '\'':
|
||||
case '"':
|
||||
/*
|
||||
* Note that DgetC never returns a QUOTES character from an
|
||||
* expansion, so only true input quotes will get us here or out.
|
||||
*/
|
||||
c1 = c;
|
||||
dolflg = c1 == '"' ? DODOL : 0;
|
||||
for (;;) {
|
||||
c = DgetC(dolflg);
|
||||
if (c == c1)
|
||||
break;
|
||||
if (c == '\n' || c == DEOF)
|
||||
stderror(ERR_UNMATCHED, c1);
|
||||
if ((c & (QUOTE | TRIM)) == ('\n' | QUOTE))
|
||||
--wp, ++i;
|
||||
if (--i <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
switch (c1) {
|
||||
|
||||
case '"':
|
||||
/*
|
||||
* Leave any `s alone for later. Other chars are all
|
||||
* quoted, thus `...` can tell it was within "...".
|
||||
*/
|
||||
*wp++ = c == '`' ? '`' : c | QUOTE;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
/* Prevent all further interpretation */
|
||||
*wp++ = c | QUOTE;
|
||||
break;
|
||||
|
||||
case '`':
|
||||
/* Leave all text alone for later */
|
||||
*wp++ = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c1 == '`')
|
||||
*wp++ = '`' /* i--; eliminated */;
|
||||
sofar = 1;
|
||||
if ((wp = Dpack(wbuf, wp)) == NULL)
|
||||
return (1);
|
||||
else {
|
||||
i = MAXWLEN - (wp - wbuf);
|
||||
done = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
c = DgetC(0); /* No $ subst! */
|
||||
if (c == '\n' || c == DEOF) {
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
c |= QUOTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (done) {
|
||||
unDgetC(c);
|
||||
sofar = 1;
|
||||
if ((wp = Dpack(wbuf, wp)) == NULL)
|
||||
return (1);
|
||||
else {
|
||||
i = MAXWLEN - (wp - wbuf);
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Really NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a character, performing $ substitution unless flag is 0.
|
||||
* Any QUOTES character which is returned from a $ expansion is
|
||||
* QUOTEd so that it will not be recognized above.
|
||||
*/
|
||||
static int
|
||||
DgetC(flag)
|
||||
int flag;
|
||||
{
|
||||
int c;
|
||||
|
||||
top:
|
||||
if ((c = Dpeekc) != '\0') {
|
||||
Dpeekc = 0;
|
||||
return (c);
|
||||
}
|
||||
if (lap) {
|
||||
c = *lap++ & (QUOTE | TRIM);
|
||||
if (c == 0) {
|
||||
lap = 0;
|
||||
goto top;
|
||||
}
|
||||
quotspec:
|
||||
if (cmap(c, QUOTES))
|
||||
return (c | QUOTE);
|
||||
return (c);
|
||||
}
|
||||
if (dolp) {
|
||||
if ((c = *dolp++ & (QUOTE | TRIM)) != '\0')
|
||||
goto quotspec;
|
||||
if (dolcnt > 0) {
|
||||
setDolp(*dolnxt++);
|
||||
--dolcnt;
|
||||
return (' ');
|
||||
}
|
||||
dolp = 0;
|
||||
}
|
||||
if (dolcnt > 0) {
|
||||
setDolp(*dolnxt++);
|
||||
--dolcnt;
|
||||
goto top;
|
||||
}
|
||||
c = Dredc();
|
||||
if (c == '$' && flag) {
|
||||
Dgetdol();
|
||||
goto top;
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
static Char *nulvec[] = {0};
|
||||
static struct varent nulargv = {nulvec, STRargv, { NULL, NULL, NULL }, 0};
|
||||
|
||||
static void
|
||||
dolerror(s)
|
||||
Char *s;
|
||||
{
|
||||
setname(vis_str(s));
|
||||
stderror(ERR_NAME | ERR_RANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the multitudinous $ expansion forms.
|
||||
* Ugh.
|
||||
*/
|
||||
static void
|
||||
Dgetdol()
|
||||
{
|
||||
Char *np;
|
||||
struct varent *vp = NULL;
|
||||
Char name[4 * MAXVARLEN + 1];
|
||||
int c, sc;
|
||||
int subscr = 0, lwb = 1, upb = 0;
|
||||
bool dimen = 0, bitset = 0;
|
||||
char tnp;
|
||||
Char wbuf[BUFSIZ];
|
||||
static Char *dolbang = NULL;
|
||||
|
||||
dolnmod = dolmcnt = dolwcnt = 0;
|
||||
c = sc = DgetC(0);
|
||||
if (c == '{')
|
||||
c = DgetC(0); /* sc is { to take } later */
|
||||
if ((c & TRIM) == '#')
|
||||
dimen++, c = DgetC(0); /* $# takes dimension */
|
||||
else if (c == '?')
|
||||
bitset++, c = DgetC(0); /* $? tests existence */
|
||||
switch (c) {
|
||||
|
||||
case '!':
|
||||
if (dimen || bitset)
|
||||
stderror(ERR_SYNTAX);
|
||||
if (backpid != 0) {
|
||||
if (dolbang)
|
||||
xfree((ptr_t) dolbang);
|
||||
setDolp(dolbang = putn(backpid));
|
||||
}
|
||||
goto eatbrac;
|
||||
|
||||
case '$':
|
||||
if (dimen || bitset)
|
||||
stderror(ERR_SYNTAX);
|
||||
setDolp(doldol);
|
||||
goto eatbrac;
|
||||
|
||||
case '<' | QUOTE:
|
||||
if (bitset)
|
||||
stderror(ERR_NOTALLOWED, "$?<");
|
||||
if (dimen)
|
||||
stderror(ERR_NOTALLOWED, "$?#");
|
||||
for (np = wbuf; read(OLDSTD, &tnp, 1) == 1; np++) {
|
||||
*np = (unsigned char) tnp;
|
||||
if (np >= &wbuf[BUFSIZ - 1])
|
||||
stderror(ERR_LTOOLONG);
|
||||
if (tnp == '\n')
|
||||
break;
|
||||
}
|
||||
*np = 0;
|
||||
/*
|
||||
* KLUDGE: dolmod is set here because it will cause setDolp to call
|
||||
* domod and thus to copy wbuf. Otherwise setDolp would use it
|
||||
* directly. If we saved it ourselves, no one would know when to free
|
||||
* it. The actual function of the 'q' causes filename expansion not to
|
||||
* be done on the interpolated value.
|
||||
*/
|
||||
dolmod[dolnmod++] = 'q';
|
||||
dolmcnt = 10000;
|
||||
setDolp(wbuf);
|
||||
goto eatbrac;
|
||||
|
||||
case DEOF:
|
||||
case '\n':
|
||||
stderror(ERR_SYNTAX);
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
|
||||
case '*':
|
||||
(void) Strcpy(name, STRargv);
|
||||
vp = adrof(STRargv);
|
||||
subscr = -1; /* Prevent eating [...] */
|
||||
break;
|
||||
|
||||
default:
|
||||
np = name;
|
||||
if (Isdigit(c)) {
|
||||
if (dimen)
|
||||
stderror(ERR_NOTALLOWED, "$#<num>");
|
||||
subscr = 0;
|
||||
do {
|
||||
subscr = subscr * 10 + c - '0';
|
||||
c = DgetC(0);
|
||||
} while (Isdigit(c));
|
||||
unDredc(c);
|
||||
if (subscr < 0) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
if (subscr == 0) {
|
||||
if (bitset) {
|
||||
dolp = ffile ? STR1 : STR0;
|
||||
goto eatbrac;
|
||||
}
|
||||
if (ffile == 0)
|
||||
stderror(ERR_DOLZERO);
|
||||
fixDolMod();
|
||||
setDolp(ffile);
|
||||
goto eatbrac;
|
||||
}
|
||||
if (bitset)
|
||||
stderror(ERR_DOLQUEST);
|
||||
vp = adrof(STRargv);
|
||||
if (vp == 0) {
|
||||
vp = &nulargv;
|
||||
goto eatmod;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!alnum(c))
|
||||
stderror(ERR_VARALNUM);
|
||||
for (;;) {
|
||||
*np++ = c;
|
||||
c = DgetC(0);
|
||||
if (!alnum(c))
|
||||
break;
|
||||
if (np >= &name[MAXVARLEN])
|
||||
stderror(ERR_VARTOOLONG);
|
||||
}
|
||||
*np++ = 0;
|
||||
unDredc(c);
|
||||
vp = adrof(name);
|
||||
}
|
||||
if (bitset) {
|
||||
dolp = (vp || getenv(short2str(name))) ? STR1 : STR0;
|
||||
goto eatbrac;
|
||||
}
|
||||
if (vp == 0) {
|
||||
np = str2short(getenv(short2str(name)));
|
||||
if (np) {
|
||||
fixDolMod();
|
||||
setDolp(np);
|
||||
goto eatbrac;
|
||||
}
|
||||
udvar(name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
c = DgetC(0);
|
||||
upb = blklen(vp->vec);
|
||||
if (dimen == 0 && subscr == 0 && c == '[') {
|
||||
np = name;
|
||||
for (;;) {
|
||||
c = DgetC(DODOL); /* Allow $ expand within [ ] */
|
||||
if (c == ']')
|
||||
break;
|
||||
if (c == '\n' || c == DEOF)
|
||||
stderror(ERR_INCBR);
|
||||
if (np >= &name[sizeof(name) / sizeof(Char) - 2])
|
||||
stderror(ERR_VARTOOLONG);
|
||||
*np++ = c;
|
||||
}
|
||||
*np = 0, np = name;
|
||||
if (dolp || dolcnt) /* $ exp must end before ] */
|
||||
stderror(ERR_EXPORD);
|
||||
if (!*np)
|
||||
stderror(ERR_SYNTAX);
|
||||
if (Isdigit(*np)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; Isdigit(*np); i = i * 10 + *np++ - '0')
|
||||
continue;
|
||||
if ((i < 0 || i > upb) && !any("-*", *np)) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
lwb = i;
|
||||
if (!*np)
|
||||
upb = lwb, np = STRstar;
|
||||
}
|
||||
if (*np == '*')
|
||||
np++;
|
||||
else if (*np != '-')
|
||||
stderror(ERR_MISSING, '-');
|
||||
else {
|
||||
int i = upb;
|
||||
|
||||
np++;
|
||||
if (Isdigit(*np)) {
|
||||
i = 0;
|
||||
while (Isdigit(*np))
|
||||
i = i * 10 + *np++ - '0';
|
||||
if (i < 0 || i > upb) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i < lwb)
|
||||
upb = lwb - 1;
|
||||
else
|
||||
upb = i;
|
||||
}
|
||||
if (lwb == 0) {
|
||||
if (upb != 0) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
upb = -1;
|
||||
}
|
||||
if (*np)
|
||||
stderror(ERR_SYNTAX);
|
||||
}
|
||||
else {
|
||||
if (subscr > 0) {
|
||||
if (subscr > upb)
|
||||
lwb = 1, upb = 0;
|
||||
else
|
||||
lwb = upb = subscr;
|
||||
}
|
||||
unDredc(c);
|
||||
}
|
||||
if (dimen) {
|
||||
Char *cp = putn(upb - lwb + 1);
|
||||
|
||||
addla(cp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
else {
|
||||
eatmod:
|
||||
fixDolMod();
|
||||
dolnxt = &vp->vec[lwb - 1];
|
||||
dolcnt = upb - lwb + 1;
|
||||
}
|
||||
eatbrac:
|
||||
if (sc == '{') {
|
||||
c = Dredc();
|
||||
if (c != '}')
|
||||
stderror(ERR_MISSING, '}');
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fixDolMod()
|
||||
{
|
||||
int c;
|
||||
|
||||
c = DgetC(0);
|
||||
if (c == ':') {
|
||||
do {
|
||||
c = DgetC(0), dolmcnt = 1, dolwcnt = 1;
|
||||
if (c == 'g' || c == 'a') {
|
||||
if (c == 'g')
|
||||
dolmcnt = 10000;
|
||||
else
|
||||
dolwcnt = 10000;
|
||||
c = DgetC(0);
|
||||
}
|
||||
if ((c == 'g' && dolmcnt != 10000) ||
|
||||
(c == 'a' && dolwcnt != 10000)) {
|
||||
if (c == 'g')
|
||||
dolmcnt = 10000;
|
||||
else
|
||||
dolwcnt = 10000;
|
||||
c = DgetC(0);
|
||||
}
|
||||
|
||||
if (c == 's') { /* [eichin:19910926.0755EST] */
|
||||
int delimcnt = 2;
|
||||
int delim = DgetC(0);
|
||||
dolmod[dolnmod++] = c;
|
||||
dolmod[dolnmod++] = delim;
|
||||
|
||||
if (!delim || letter(delim)
|
||||
|| Isdigit(delim) || any(" \t\n", delim)) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
while ((c = DgetC(0)) != (-1)) {
|
||||
dolmod[dolnmod++] = c;
|
||||
if(c == delim) delimcnt--;
|
||||
if(!delimcnt) break;
|
||||
}
|
||||
if(delimcnt) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!any("htrqxes", c))
|
||||
stderror(ERR_BADMOD, c);
|
||||
dolmod[dolnmod++] = c;
|
||||
if (c == 'q')
|
||||
dolmcnt = 10000;
|
||||
}
|
||||
while ((c = DgetC(0)) == ':');
|
||||
unDredc(c);
|
||||
}
|
||||
else
|
||||
unDredc(c);
|
||||
}
|
||||
|
||||
static void
|
||||
setDolp(cp)
|
||||
Char *cp;
|
||||
{
|
||||
Char *dp;
|
||||
int i;
|
||||
|
||||
if (dolnmod == 0 || dolmcnt == 0) {
|
||||
dolp = cp;
|
||||
return;
|
||||
}
|
||||
dp = cp = Strsave(cp);
|
||||
for (i = 0; i < dolnmod; i++) {
|
||||
/* handle s// [eichin:19910926.0510EST] */
|
||||
if(dolmod[i] == 's') {
|
||||
int delim;
|
||||
Char *lhsub, *rhsub, *np;
|
||||
size_t lhlen = 0, rhlen = 0;
|
||||
int didmod = 0;
|
||||
|
||||
delim = dolmod[++i];
|
||||
if (!delim || letter(delim)
|
||||
|| Isdigit(delim) || any(" \t\n", delim)) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
lhsub = &dolmod[++i];
|
||||
while(dolmod[i] != delim && dolmod[++i]) {
|
||||
lhlen++;
|
||||
}
|
||||
dolmod[i] = 0;
|
||||
rhsub = &dolmod[++i];
|
||||
while(dolmod[i] != delim && dolmod[++i]) {
|
||||
rhlen++;
|
||||
}
|
||||
dolmod[i] = 0;
|
||||
|
||||
do {
|
||||
dp = Strstr(cp, lhsub);
|
||||
if (dp) {
|
||||
np = (Char *) xmalloc((size_t)
|
||||
((Strlen(cp) + 1 - lhlen + rhlen) *
|
||||
sizeof(Char)));
|
||||
(void) Strncpy(np, cp, dp - cp);
|
||||
(void) Strcpy(np + (dp - cp), rhsub);
|
||||
(void) Strcpy(np + (dp - cp) + rhlen, dp + lhlen);
|
||||
|
||||
xfree((ptr_t) cp);
|
||||
dp = cp = np;
|
||||
didmod = 1;
|
||||
} else {
|
||||
/* should this do a seterror? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (dolwcnt == 10000);
|
||||
/*
|
||||
* restore dolmod for additional words
|
||||
*/
|
||||
dolmod[i] = rhsub[-1] = delim;
|
||||
if (didmod)
|
||||
dolmcnt--;
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
int didmod = 0;
|
||||
|
||||
do {
|
||||
if ((dp = domod(cp, dolmod[i]))) {
|
||||
didmod = 1;
|
||||
if (Strcmp(cp, dp) == 0) {
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (dolwcnt == 10000);
|
||||
dp = cp;
|
||||
if (didmod)
|
||||
dolmcnt--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dp) {
|
||||
addla(dp);
|
||||
xfree((ptr_t) dp);
|
||||
}
|
||||
else
|
||||
addla(cp);
|
||||
|
||||
dolp = STRNULL;
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
}
|
||||
|
||||
static void
|
||||
unDredc(c)
|
||||
int c;
|
||||
{
|
||||
|
||||
Dpeekrd = c;
|
||||
}
|
||||
|
||||
static int
|
||||
Dredc()
|
||||
{
|
||||
int c;
|
||||
|
||||
if ((c = Dpeekrd) != '\0') {
|
||||
Dpeekrd = 0;
|
||||
return (c);
|
||||
}
|
||||
if (Dcp && (c = *Dcp++))
|
||||
return (c & (QUOTE | TRIM));
|
||||
if (*Dvp == 0) {
|
||||
Dcp = 0;
|
||||
return (DEOF);
|
||||
}
|
||||
Dcp = *Dvp++;
|
||||
return (' ');
|
||||
}
|
||||
|
||||
static void
|
||||
Dtestq(c)
|
||||
int c;
|
||||
{
|
||||
|
||||
if (cmap(c, QUOTES))
|
||||
gflag = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Form a shell temporary file (in unit 0) from the words
|
||||
* of the shell input up to EOF or a line the same as "term".
|
||||
* Unit 0 should have been closed before this call.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
heredoc(term)
|
||||
Char *term;
|
||||
{
|
||||
int c;
|
||||
Char *Dv[2];
|
||||
Char obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ];
|
||||
int ocnt, lcnt, mcnt;
|
||||
Char *lbp, *obp, *mbp;
|
||||
Char **vp;
|
||||
bool quoted;
|
||||
char *tmp;
|
||||
|
||||
if (creat(tmp = short2str(shtemp), 0600) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
(void) close(0);
|
||||
if (open(tmp, O_RDWR) < 0) {
|
||||
int oerrno = errno;
|
||||
|
||||
(void) unlink(tmp);
|
||||
errno = oerrno;
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
(void) unlink(tmp); /* 0 0 inode! */
|
||||
Dv[0] = term;
|
||||
Dv[1] = NULL;
|
||||
gflag = 0;
|
||||
trim(Dv);
|
||||
rscan(Dv, Dtestq);
|
||||
quoted = gflag;
|
||||
ocnt = BUFSIZ;
|
||||
obp = obuf;
|
||||
for (;;) {
|
||||
/*
|
||||
* Read up a line
|
||||
*/
|
||||
lbp = lbuf;
|
||||
lcnt = BUFSIZ - 4;
|
||||
for (;;) {
|
||||
c = readc(1); /* 1 -> Want EOF returns */
|
||||
if (c < 0 || c == '\n')
|
||||
break;
|
||||
if ((c &= TRIM) != '\0') {
|
||||
*lbp++ = c;
|
||||
if (--lcnt < 0) {
|
||||
setname("<<");
|
||||
stderror(ERR_NAME | ERR_OVERFLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
*lbp = 0;
|
||||
|
||||
/*
|
||||
* Check for EOF or compare to terminator -- before expansion
|
||||
*/
|
||||
if (c < 0 || eq(lbuf, term)) {
|
||||
(void) write(0, short2str(obuf), (size_t) (BUFSIZ - ocnt));
|
||||
(void) lseek(0, 0l, L_SET);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If term was quoted or -n just pass it on
|
||||
*/
|
||||
if (quoted || noexec) {
|
||||
*lbp++ = '\n';
|
||||
*lbp = 0;
|
||||
for (lbp = lbuf; (c = *lbp++) != '\0';) {
|
||||
*obp++ = c;
|
||||
if (--ocnt == 0) {
|
||||
(void) write(0, short2str(obuf), BUFSIZ);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZ;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Term wasn't quoted so variable and then command expand the input
|
||||
* line
|
||||
*/
|
||||
Dcp = lbuf;
|
||||
Dvp = Dv + 1;
|
||||
mbp = mbuf;
|
||||
mcnt = BUFSIZ - 4;
|
||||
for (;;) {
|
||||
c = DgetC(DODOL);
|
||||
if (c == DEOF)
|
||||
break;
|
||||
if ((c &= TRIM) == 0)
|
||||
continue;
|
||||
/* \ quotes \ $ ` here */
|
||||
if (c == '\\') {
|
||||
c = DgetC(0);
|
||||
if (!any("$\\`", c))
|
||||
unDgetC(c | QUOTE), c = '\\';
|
||||
else
|
||||
c |= QUOTE;
|
||||
}
|
||||
*mbp++ = c;
|
||||
if (--mcnt == 0) {
|
||||
setname("<<");
|
||||
stderror(ERR_NAME | ERR_OVERFLOW);
|
||||
}
|
||||
}
|
||||
*mbp++ = 0;
|
||||
|
||||
/*
|
||||
* If any ` in line do command substitution
|
||||
*/
|
||||
mbp = mbuf;
|
||||
if (any(short2str(mbp), '`')) {
|
||||
/*
|
||||
* 1 arg to dobackp causes substitution to be literal. Words are
|
||||
* broken only at newlines so that all blanks and tabs are
|
||||
* preserved. Blank lines (null words) are not discarded.
|
||||
*/
|
||||
vp = dobackp(mbuf, 1);
|
||||
}
|
||||
else
|
||||
/* Setup trivial vector similar to return of dobackp */
|
||||
Dv[0] = mbp, Dv[1] = NULL, vp = Dv;
|
||||
|
||||
/*
|
||||
* Resurrect the words from the command substitution each separated by
|
||||
* a newline. Note that the last newline of a command substitution
|
||||
* will have been discarded, but we put a newline after the last word
|
||||
* because this represents the newline after the last input line!
|
||||
*/
|
||||
for (; *vp; vp++) {
|
||||
for (mbp = *vp; *mbp; mbp++) {
|
||||
*obp++ = *mbp & TRIM;
|
||||
if (--ocnt == 0) {
|
||||
(void) write(0, short2str(obuf), BUFSIZ);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZ;
|
||||
}
|
||||
}
|
||||
*obp++ = '\n';
|
||||
if (--ocnt == 0) {
|
||||
(void) write(0, short2str(obuf), BUFSIZ);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZ;
|
||||
}
|
||||
}
|
||||
if (pargv)
|
||||
blkfree(pargv), pargv = 0;
|
||||
}
|
||||
}
|
||||
-411
@@ -1,411 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
char *seterr = NULL; /* Holds last error if there was one */
|
||||
|
||||
#define ERR_FLAGS 0xf0000000
|
||||
#define ERR_NAME 0x10000000
|
||||
#define ERR_SILENT 0x20000000
|
||||
#define ERR_OLD 0x40000000
|
||||
|
||||
static char *errorlist[] =
|
||||
{
|
||||
#define ERR_SYNTAX 0
|
||||
"Syntax Error",
|
||||
#define ERR_NOTALLOWED 1
|
||||
"%s is not allowed",
|
||||
#define ERR_WTOOLONG 2
|
||||
"Word too long",
|
||||
#define ERR_LTOOLONG 3
|
||||
"$< line too long",
|
||||
#define ERR_DOLZERO 4
|
||||
"No file for $0",
|
||||
#define ERR_DOLQUEST 5
|
||||
"$? not allowed here",
|
||||
#define ERR_INCBR 6
|
||||
"Incomplete [] modifier",
|
||||
#define ERR_EXPORD 7
|
||||
"$ expansion must end before ]",
|
||||
#define ERR_BADMOD 8
|
||||
"Bad : modifier in $ (%c)",
|
||||
#define ERR_SUBSCRIPT 9
|
||||
"Subscript error",
|
||||
#define ERR_BADNUM 10
|
||||
"Badly formed number",
|
||||
#define ERR_NOMORE 11
|
||||
"No more words",
|
||||
#define ERR_FILENAME 12
|
||||
"Missing file name",
|
||||
#define ERR_GLOB 13
|
||||
"Internal glob error",
|
||||
#define ERR_COMMAND 14
|
||||
"Command not found",
|
||||
#define ERR_TOOFEW 15
|
||||
"Too few arguments",
|
||||
#define ERR_TOOMANY 16
|
||||
"Too many arguments",
|
||||
#define ERR_DANGER 17
|
||||
"Too dangerous to alias that",
|
||||
#define ERR_EMPTYIF 18
|
||||
"Empty if",
|
||||
#define ERR_IMPRTHEN 19
|
||||
"Improper then",
|
||||
#define ERR_NOPAREN 20
|
||||
"Words not parenthesized",
|
||||
#define ERR_NOTFOUND 21
|
||||
"%s not found",
|
||||
#define ERR_MASK 22
|
||||
"Improper mask",
|
||||
#define ERR_LIMIT 23
|
||||
"No such limit",
|
||||
#define ERR_TOOLARGE 24
|
||||
"Argument too large",
|
||||
#define ERR_SCALEF 25
|
||||
"Improper or unknown scale factor",
|
||||
#define ERR_UNDVAR 26
|
||||
"Undefined variable",
|
||||
#define ERR_DEEP 27
|
||||
"Directory stack not that deep",
|
||||
#define ERR_BADSIG 28
|
||||
"Bad signal number",
|
||||
#define ERR_UNKSIG 29
|
||||
"Unknown signal; kill -l lists signals",
|
||||
#define ERR_VARBEGIN 30
|
||||
"Variable name must begin with a letter",
|
||||
#define ERR_VARTOOLONG 31
|
||||
"Variable name too long",
|
||||
#define ERR_VARALNUM 32
|
||||
"Variable name must contain alphanumeric characters",
|
||||
#define ERR_JOBCONTROL 33
|
||||
"No job control in this shell",
|
||||
#define ERR_EXPRESSION 34
|
||||
"Expression Syntax",
|
||||
#define ERR_NOHOMEDIR 35
|
||||
"No home directory",
|
||||
#define ERR_CANTCHANGE 36
|
||||
"Can't change to home directory",
|
||||
#define ERR_NULLCOM 37
|
||||
"Invalid null command",
|
||||
#define ERR_ASSIGN 38
|
||||
"Assignment missing expression",
|
||||
#define ERR_UNKNOWNOP 39
|
||||
"Unknown operator",
|
||||
#define ERR_AMBIG 40
|
||||
"Ambiguous",
|
||||
#define ERR_EXISTS 41
|
||||
"%s: File exists",
|
||||
#define ERR_INTR 42
|
||||
"Interrupted",
|
||||
#define ERR_RANGE 43
|
||||
"Subscript out of range",
|
||||
#define ERR_OVERFLOW 44
|
||||
"Line overflow",
|
||||
#define ERR_VARMOD 45
|
||||
"Unknown variable modifier",
|
||||
#define ERR_NOSUCHJOB 46
|
||||
"No such job",
|
||||
#define ERR_TERMINAL 47
|
||||
"Can't from terminal",
|
||||
#define ERR_NOTWHILE 48
|
||||
"Not in while/foreach",
|
||||
#define ERR_NOPROC 49
|
||||
"No more processes",
|
||||
#define ERR_NOMATCH 50
|
||||
"No match",
|
||||
#define ERR_MISSING 51
|
||||
"Missing %c",
|
||||
#define ERR_UNMATCHED 52
|
||||
"Unmatched %c",
|
||||
#define ERR_NOMEM 53
|
||||
"Out of memory",
|
||||
#define ERR_PIPE 54
|
||||
"Can't make pipe",
|
||||
#define ERR_SYSTEM 55
|
||||
"%s: %s",
|
||||
#define ERR_STRING 56
|
||||
"%s",
|
||||
#define ERR_JOBS 57
|
||||
"Usage: jobs [ -l ]",
|
||||
#define ERR_JOBARGS 58
|
||||
"Arguments should be jobs or process id's",
|
||||
#define ERR_JOBCUR 59
|
||||
"No current job",
|
||||
#define ERR_JOBPREV 60
|
||||
"No previous job",
|
||||
#define ERR_JOBPAT 61
|
||||
"No job matches pattern",
|
||||
#define ERR_NESTING 62
|
||||
"Fork nesting > %d; maybe `...` loop",
|
||||
#define ERR_JOBCTRLSUB 63
|
||||
"No job control in subshells",
|
||||
#define ERR_BADPLPS 64
|
||||
"Badly placed ()'s",
|
||||
#define ERR_STOPPED 65
|
||||
"%sThere are suspended jobs",
|
||||
#define ERR_NODIR 66
|
||||
"No other directory",
|
||||
#define ERR_EMPTY 67
|
||||
"Directory stack empty",
|
||||
#define ERR_BADDIR 68
|
||||
"Bad directory",
|
||||
#define ERR_DIRUS 69
|
||||
"Usage: %s [-lvn]%s",
|
||||
#define ERR_HFLAG 70
|
||||
"No operand for -h flag",
|
||||
#define ERR_NOTLOGIN 71
|
||||
"Not a login shell",
|
||||
#define ERR_DIV0 72
|
||||
"Division by 0",
|
||||
#define ERR_MOD0 73
|
||||
"Mod by 0",
|
||||
#define ERR_BADSCALE 74
|
||||
"Bad scaling; did you mean \"%s\"?",
|
||||
#define ERR_SUSPLOG 75
|
||||
"Can't suspend a login shell (yet)",
|
||||
#define ERR_UNKUSER 76
|
||||
"Unknown user: %s",
|
||||
#define ERR_NOHOME 77
|
||||
"No $home variable set",
|
||||
#define ERR_HISTUS 78
|
||||
"Usage: history [-rh] [# number of events]",
|
||||
#define ERR_SPDOLLT 79
|
||||
"$, ! or < not allowed with $# or $?",
|
||||
#define ERR_NEWLINE 80
|
||||
"Newline in variable name",
|
||||
#define ERR_SPSTAR 81
|
||||
"* not allowed with $# or $?",
|
||||
#define ERR_DIGIT 82
|
||||
"$?<digit> or $#<digit> not allowed",
|
||||
#define ERR_VARILL 83
|
||||
"Illegal variable name",
|
||||
#define ERR_NLINDEX 84
|
||||
"Newline in variable index",
|
||||
#define ERR_EXPOVFL 85
|
||||
"Expansion buffer overflow",
|
||||
#define ERR_VARSYN 86
|
||||
"Variable syntax",
|
||||
#define ERR_BADBANG 87
|
||||
"Bad ! form",
|
||||
#define ERR_NOSUBST 88
|
||||
"No previous substitute",
|
||||
#define ERR_BADSUBST 89
|
||||
"Bad substitute",
|
||||
#define ERR_LHS 90
|
||||
"No previous left hand side",
|
||||
#define ERR_RHSLONG 91
|
||||
"Right hand side too long",
|
||||
#define ERR_BADBANGMOD 92
|
||||
"Bad ! modifier: %c",
|
||||
#define ERR_MODFAIL 93
|
||||
"Modifier failed",
|
||||
#define ERR_SUBOVFL 94
|
||||
"Substitution buffer overflow",
|
||||
#define ERR_BADBANGARG 95
|
||||
"Bad ! arg selector",
|
||||
#define ERR_NOSEARCH 96
|
||||
"No prev search",
|
||||
#define ERR_NOEVENT 97
|
||||
"%s: Event not found",
|
||||
#define ERR_TOOMANYRP 98
|
||||
"Too many )'s",
|
||||
#define ERR_TOOMANYLP 99
|
||||
"Too many ('s",
|
||||
#define ERR_BADPLP 100
|
||||
"Badly placed (",
|
||||
#define ERR_MISRED 101
|
||||
"Missing name for redirect",
|
||||
#define ERR_OUTRED 102
|
||||
"Ambiguous output redirect",
|
||||
#define ERR_REDPAR 103
|
||||
"Can't << within ()'s",
|
||||
#define ERR_INRED 104
|
||||
"Ambiguous input redirect",
|
||||
#define ERR_ALIASLOOP 105
|
||||
"Alias loop",
|
||||
#define ERR_HISTLOOP 106
|
||||
"!# History loop",
|
||||
#define ERR_ARCH 107
|
||||
"%s: %s. Wrong Architecture",
|
||||
#define ERR_FILEINQ 108
|
||||
"Malformed file inquiry",
|
||||
#define ERR_SELOVFL 109
|
||||
"Selector overflow",
|
||||
#define ERR_INVALID 110
|
||||
"Invalid Error"
|
||||
};
|
||||
|
||||
/*
|
||||
* The parser and scanner set up errors for later by calling seterr,
|
||||
* which sets the variable err as a side effect; later to be tested,
|
||||
* e.g. in process.
|
||||
*/
|
||||
void
|
||||
#if __STDC__
|
||||
seterror(int id, ...)
|
||||
#else
|
||||
seterror(id, va_alist)
|
||||
int id;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
if (seterr == 0) {
|
||||
char berr[BUFSIZ];
|
||||
va_list va;
|
||||
|
||||
#if __STDC__
|
||||
va_start(va, id);
|
||||
#else
|
||||
va_start(va);
|
||||
#endif
|
||||
if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0]))
|
||||
id = ERR_INVALID;
|
||||
vsnprintf(berr, sizeof(berr), errorlist[id], va);
|
||||
va_end(va);
|
||||
|
||||
seterr = strsave(berr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the error with the given id.
|
||||
*
|
||||
* Special ids:
|
||||
* ERR_SILENT: Print nothing.
|
||||
* ERR_OLD: Print the previously set error if one was there.
|
||||
* otherwise return.
|
||||
* ERR_NAME: If this bit is set, print the name of the function
|
||||
* in bname
|
||||
*
|
||||
* This routine always resets or exits. The flag haderr
|
||||
* is set so the routine who catches the unwind can propagate
|
||||
* it if they want.
|
||||
*
|
||||
* Note that any open files at the point of error will eventually
|
||||
* be closed in the routine process in sh.c which is the only
|
||||
* place error unwinds are ever caught.
|
||||
*/
|
||||
void
|
||||
#if __STDC__
|
||||
stderror(int id, ...)
|
||||
#else
|
||||
stderror(id, va_alist)
|
||||
int id;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list va;
|
||||
Char **v;
|
||||
int flags = id & ERR_FLAGS;
|
||||
|
||||
id &= ~ERR_FLAGS;
|
||||
|
||||
if ((flags & ERR_OLD) && seterr == NULL)
|
||||
return;
|
||||
|
||||
if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0]))
|
||||
id = ERR_INVALID;
|
||||
|
||||
(void) fflush(cshout);
|
||||
(void) fflush(csherr);
|
||||
haderr = 1; /* Now to diagnostic output */
|
||||
timflg = 0; /* This isn't otherwise reset */
|
||||
|
||||
|
||||
if (!(flags & ERR_SILENT)) {
|
||||
if (flags & ERR_NAME)
|
||||
(void) fprintf(csherr, "%s: ", bname);
|
||||
if ((flags & ERR_OLD))
|
||||
/* Old error. */
|
||||
(void) fprintf(csherr, "%s.\n", seterr);
|
||||
else {
|
||||
#if __STDC__
|
||||
va_start(va, id);
|
||||
#else
|
||||
va_start(va);
|
||||
#endif
|
||||
(void) vfprintf(csherr, errorlist[id], va);
|
||||
va_end(va);
|
||||
(void) fprintf(csherr, ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (seterr) {
|
||||
xfree((ptr_t) seterr);
|
||||
seterr = NULL;
|
||||
}
|
||||
|
||||
if ((v = pargv) != NULL)
|
||||
pargv = 0, blkfree(v);
|
||||
if ((v = gargv) != NULL)
|
||||
gargv = 0, blkfree(v);
|
||||
|
||||
(void) fflush(cshout);
|
||||
(void) fflush(csherr);
|
||||
didfds = 0; /* Forget about 0,1,2 */
|
||||
/*
|
||||
* Go away if -e or we are a child shell
|
||||
*/
|
||||
if (exiterr || child)
|
||||
xexit(1);
|
||||
|
||||
/*
|
||||
* Reset the state of the input. This buffered seek to end of file will
|
||||
* also clear the while/foreach stack.
|
||||
*/
|
||||
btoeof();
|
||||
|
||||
set(STRstatus, Strsave(STR1));
|
||||
if (tpgrp > 0)
|
||||
(void) tcsetpgrp(FSHTTY, tpgrp);
|
||||
reset(); /* Unwind */
|
||||
}
|
||||
-746
@@ -1,746 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* System level search and execute of a command. We look in each directory
|
||||
* for the specified command name. If the name contains a '/' then we
|
||||
* execute only the full path name. If there is no search path then we
|
||||
* execute only full path names.
|
||||
*/
|
||||
extern char **environ;
|
||||
|
||||
/*
|
||||
* As we search for the command we note the first non-trivial error
|
||||
* message for presentation to the user. This allows us often
|
||||
* to show that a file has the wrong mode/no access when the file
|
||||
* is not in the last component of the search path, so we must
|
||||
* go on after first detecting the error.
|
||||
*/
|
||||
static char *exerr; /* Execution error message */
|
||||
static Char *expath; /* Path for exerr */
|
||||
|
||||
/*
|
||||
* Xhash is an array of HSHSIZ bits (HSHSIZ / 8 chars), which are used
|
||||
* to hash execs. If it is allocated (havhash true), then to tell
|
||||
* whether ``name'' is (possibly) present in the i'th component
|
||||
* of the variable path, you look at the bit in xhash indexed by
|
||||
* hash(hashname("name"), i). This is setup automatically
|
||||
* after .login is executed, and recomputed whenever ``path'' is
|
||||
* changed.
|
||||
* The two part hash function is designed to let texec() call the
|
||||
* more expensive hashname() only once and the simple hash() several
|
||||
* times (once for each path component checked).
|
||||
* Byte size is assumed to be 8.
|
||||
*/
|
||||
#define HSHSIZ 8192 /* 1k bytes */
|
||||
#define HSHMASK (HSHSIZ - 1)
|
||||
#define HSHMUL 243
|
||||
static char xhash[HSHSIZ / 8];
|
||||
|
||||
#define hash(a, b) (((a) * HSHMUL + (b)) & HSHMASK)
|
||||
#define bit(h, b) ((h)[(b) >> 3] & 1 << ((b) & 7)) /* bit test */
|
||||
#define bis(h, b) ((h)[(b) >> 3] |= 1 << ((b) & 7)) /* bit set */
|
||||
static int hits, misses;
|
||||
|
||||
/* Dummy search path for just absolute search when no path */
|
||||
static Char *justabs[] = {STRNULL, 0};
|
||||
|
||||
static void pexerr __P((void));
|
||||
static void texec __P((Char *, Char **));
|
||||
static int hashname __P((Char *));
|
||||
static void tellmewhat __P((struct wordent *));
|
||||
static int executable __P((Char *, Char *, bool));
|
||||
static int iscommand __P((Char *));
|
||||
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
doexec(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
Char *dp, **pv, **av, *sav;
|
||||
struct varent *pathv;
|
||||
bool slash;
|
||||
int hashval = 0, hashval1, i;
|
||||
Char *blk[2];
|
||||
|
||||
/*
|
||||
* Glob the command name. We will search $path even if this does something,
|
||||
* as in sh but not in csh. One special case: if there is no PATH, then we
|
||||
* execute only commands which start with '/'.
|
||||
*/
|
||||
blk[0] = t->t_dcom[0];
|
||||
blk[1] = 0;
|
||||
gflag = 0, tglob(blk);
|
||||
if (gflag) {
|
||||
pv = globall(blk);
|
||||
if (pv == 0) {
|
||||
setname(vis_str(blk[0]));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
gargv = 0;
|
||||
}
|
||||
else
|
||||
pv = saveblk(blk);
|
||||
|
||||
trim(pv);
|
||||
|
||||
exerr = 0;
|
||||
expath = Strsave(pv[0]);
|
||||
Vexpath = expath;
|
||||
|
||||
pathv = adrof(STRpath);
|
||||
if (pathv == 0 && expath[0] != '/') {
|
||||
blkfree(pv);
|
||||
pexerr();
|
||||
}
|
||||
slash = any(short2str(expath), '/');
|
||||
|
||||
/*
|
||||
* Glob the argument list, if necessary. Otherwise trim off the quote bits.
|
||||
*/
|
||||
gflag = 0;
|
||||
av = &t->t_dcom[1];
|
||||
tglob(av);
|
||||
if (gflag) {
|
||||
av = globall(av);
|
||||
if (av == 0) {
|
||||
blkfree(pv);
|
||||
setname(vis_str(expath));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
gargv = 0;
|
||||
}
|
||||
else
|
||||
av = saveblk(av);
|
||||
|
||||
blkfree(t->t_dcom);
|
||||
t->t_dcom = blkspl(pv, av);
|
||||
xfree((ptr_t) pv);
|
||||
xfree((ptr_t) av);
|
||||
av = t->t_dcom;
|
||||
trim(av);
|
||||
|
||||
if (*av == NULL || **av == '\0')
|
||||
pexerr();
|
||||
|
||||
xechoit(av); /* Echo command if -x */
|
||||
/*
|
||||
* Since all internal file descriptors are set to close on exec, we don't
|
||||
* need to close them explicitly here. Just reorient ourselves for error
|
||||
* messages.
|
||||
*/
|
||||
SHIN = 0;
|
||||
SHOUT = 1;
|
||||
SHERR = 2;
|
||||
OLDSTD = 0;
|
||||
/*
|
||||
* We must do this AFTER any possible forking (like `foo` in glob) so that
|
||||
* this shell can still do subprocesses.
|
||||
*/
|
||||
(void) sigsetmask(0);
|
||||
/*
|
||||
* If no path, no words in path, or a / in the filename then restrict the
|
||||
* command search.
|
||||
*/
|
||||
if (pathv == 0 || pathv->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = pathv->vec;
|
||||
sav = Strspl(STRslash, *av);/* / command name for postpending */
|
||||
Vsav = sav;
|
||||
if (havhash)
|
||||
hashval = hashname(*av);
|
||||
i = 0;
|
||||
hits++;
|
||||
do {
|
||||
/*
|
||||
* Try to save time by looking at the hash table for where this command
|
||||
* could be. If we are doing delayed hashing, then we put the names in
|
||||
* one at a time, as the user enters them. This is kinda like Korn
|
||||
* Shell's "tracked aliases".
|
||||
*/
|
||||
if (!slash && pv[0][0] == '/' && havhash) {
|
||||
hashval1 = hash(hashval, i);
|
||||
if (!bit(xhash, hashval1))
|
||||
goto cont;
|
||||
}
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) /* don't make ./xxx */
|
||||
texec(*av, av);
|
||||
else {
|
||||
dp = Strspl(*pv, sav);
|
||||
Vdp = dp;
|
||||
texec(dp, av);
|
||||
Vdp = 0;
|
||||
xfree((ptr_t) dp);
|
||||
}
|
||||
misses++;
|
||||
cont:
|
||||
pv++;
|
||||
i++;
|
||||
} while (*pv);
|
||||
hits--;
|
||||
Vsav = 0;
|
||||
xfree((ptr_t) sav);
|
||||
pexerr();
|
||||
}
|
||||
|
||||
static void
|
||||
pexerr()
|
||||
{
|
||||
/* Couldn't find the damn thing */
|
||||
if (expath) {
|
||||
setname(vis_str(expath));
|
||||
Vexpath = 0;
|
||||
xfree((ptr_t) expath);
|
||||
expath = 0;
|
||||
}
|
||||
else
|
||||
setname("");
|
||||
if (exerr)
|
||||
stderror(ERR_NAME | ERR_STRING, exerr);
|
||||
stderror(ERR_NAME | ERR_COMMAND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute command f, arg list t.
|
||||
* Record error message if not found.
|
||||
* Also do shell scripts here.
|
||||
*/
|
||||
static void
|
||||
texec(sf, st)
|
||||
Char *sf;
|
||||
Char **st;
|
||||
{
|
||||
char **t;
|
||||
char *f;
|
||||
struct varent *v;
|
||||
Char **vp;
|
||||
Char *lastsh[2];
|
||||
int fd;
|
||||
unsigned char c;
|
||||
Char *st0, **ost;
|
||||
|
||||
/* The order for the conversions is significant */
|
||||
t = short2blk(st);
|
||||
f = short2str(sf);
|
||||
Vt = t;
|
||||
errno = 0; /* don't use a previous error */
|
||||
(void) execve(f, t, environ);
|
||||
Vt = 0;
|
||||
blkfree((Char **) t);
|
||||
switch (errno) {
|
||||
|
||||
case ENOEXEC:
|
||||
/*
|
||||
* From: [email protected] (Casper H.S. Dik) If we could not execute
|
||||
* it, don't feed it to the shell if it looks like a binary!
|
||||
*/
|
||||
if ((fd = open(f, O_RDONLY)) != -1) {
|
||||
if (read(fd, (char *) &c, 1) == 1) {
|
||||
if (!Isprint(c) && (c != '\n' && c != '\t')) {
|
||||
(void) close(fd);
|
||||
/*
|
||||
* We *know* what ENOEXEC means.
|
||||
*/
|
||||
stderror(ERR_ARCH, f, strerror(errno));
|
||||
}
|
||||
}
|
||||
#ifdef _PATH_BSHELL
|
||||
else
|
||||
c = '#';
|
||||
#endif
|
||||
(void) close(fd);
|
||||
}
|
||||
/*
|
||||
* If there is an alias for shell, then put the words of the alias in
|
||||
* front of the argument list replacing the command name. Note no
|
||||
* interpretation of the words at this point.
|
||||
*/
|
||||
v = adrof1(STRshell, &aliases);
|
||||
if (v == 0) {
|
||||
vp = lastsh;
|
||||
vp[0] = adrof(STRshell) ? value(STRshell) : STR_SHELLPATH;
|
||||
vp[1] = NULL;
|
||||
#ifdef _PATH_BSHELL
|
||||
if (fd != -1 && c != '#')
|
||||
vp[0] = STR_BSHELL;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
vp = v->vec;
|
||||
st0 = st[0];
|
||||
st[0] = sf;
|
||||
ost = st;
|
||||
st = blkspl(vp, st); /* Splice up the new arglst */
|
||||
ost[0] = st0;
|
||||
sf = *st;
|
||||
/* The order for the conversions is significant */
|
||||
t = short2blk(st);
|
||||
f = short2str(sf);
|
||||
xfree((ptr_t) st);
|
||||
Vt = t;
|
||||
(void) execve(f, t, environ);
|
||||
Vt = 0;
|
||||
blkfree((Char **) t);
|
||||
/* The sky is falling, the sky is falling! */
|
||||
|
||||
case ENOMEM:
|
||||
stderror(ERR_SYSTEM, f, strerror(errno));
|
||||
|
||||
case ENOENT:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (exerr == 0) {
|
||||
exerr = strerror(errno);
|
||||
if (expath)
|
||||
xfree((ptr_t) expath);
|
||||
expath = Strsave(sf);
|
||||
Vexpath = expath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
execash(t, kp)
|
||||
Char **t;
|
||||
struct command *kp;
|
||||
{
|
||||
int saveIN, saveOUT, saveDIAG, saveSTD;
|
||||
int oSHIN;
|
||||
int oSHOUT;
|
||||
int oSHERR;
|
||||
int oOLDSTD;
|
||||
jmp_buf osetexit;
|
||||
int my_reenter;
|
||||
int odidfds;
|
||||
sig_t osigint, osigquit, osigterm;
|
||||
|
||||
if (chkstop == 0 && setintr)
|
||||
panystop(0);
|
||||
/*
|
||||
* Hmm, we don't really want to do that now because we might
|
||||
* fail, but what is the choice
|
||||
*/
|
||||
rechist();
|
||||
|
||||
osigint = signal(SIGINT, parintr);
|
||||
osigquit = signal(SIGQUIT, parintr);
|
||||
osigterm = signal(SIGTERM, parterm);
|
||||
|
||||
odidfds = didfds;
|
||||
oSHIN = SHIN;
|
||||
oSHOUT = SHOUT;
|
||||
oSHERR = SHERR;
|
||||
oOLDSTD = OLDSTD;
|
||||
|
||||
saveIN = dcopy(SHIN, -1);
|
||||
saveOUT = dcopy(SHOUT, -1);
|
||||
saveDIAG = dcopy(SHERR, -1);
|
||||
saveSTD = dcopy(OLDSTD, -1);
|
||||
|
||||
lshift(kp->t_dcom, 1);
|
||||
|
||||
getexit(osetexit);
|
||||
|
||||
if ((my_reenter = setexit()) == 0) {
|
||||
SHIN = dcopy(0, -1);
|
||||
SHOUT = dcopy(1, -1);
|
||||
SHERR = dcopy(2, -1);
|
||||
didfds = 0;
|
||||
doexec(t, kp);
|
||||
}
|
||||
|
||||
(void) signal(SIGINT, osigint);
|
||||
(void) signal(SIGQUIT, osigquit);
|
||||
(void) signal(SIGTERM, osigterm);
|
||||
|
||||
doneinp = 0;
|
||||
didfds = odidfds;
|
||||
(void) close(SHIN);
|
||||
(void) close(SHOUT);
|
||||
(void) close(SHERR);
|
||||
(void) close(OLDSTD);
|
||||
SHIN = dmove(saveIN, oSHIN);
|
||||
SHOUT = dmove(saveOUT, oSHOUT);
|
||||
SHERR = dmove(saveDIAG, oSHERR);
|
||||
OLDSTD = dmove(saveSTD, oOLDSTD);
|
||||
|
||||
resexit(osetexit);
|
||||
if (my_reenter)
|
||||
stderror(ERR_SILENT);
|
||||
}
|
||||
|
||||
void
|
||||
xechoit(t)
|
||||
Char **t;
|
||||
{
|
||||
if (adrof(STRecho)) {
|
||||
(void) fflush(csherr);
|
||||
blkpr(csherr, t);
|
||||
(void) fputc('\n', csherr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dohash(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
int cnt;
|
||||
int i = 0;
|
||||
struct varent *pathv = adrof(STRpath);
|
||||
Char **pv;
|
||||
int hashval;
|
||||
|
||||
havhash = 1;
|
||||
for (cnt = 0; cnt < sizeof xhash; cnt++)
|
||||
xhash[cnt] = 0;
|
||||
if (pathv == 0)
|
||||
return;
|
||||
for (pv = pathv->vec; *pv; pv++, i++) {
|
||||
if (pv[0][0] != '/')
|
||||
continue;
|
||||
dirp = opendir(short2str(*pv));
|
||||
if (dirp == NULL)
|
||||
continue;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (dp->d_ino == 0)
|
||||
continue;
|
||||
if (dp->d_name[0] == '.' &&
|
||||
(dp->d_name[1] == '\0' ||
|
||||
(dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
|
||||
continue;
|
||||
hashval = hash(hashname(str2short(dp->d_name)), i);
|
||||
bis(xhash, hashval);
|
||||
/* tw_add_comm_name (dp->d_name); */
|
||||
}
|
||||
(void) closedir(dirp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dounhash(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
havhash = 0;
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
hashstat(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
if (hits + misses)
|
||||
(void) fprintf(cshout, "%d hits, %d misses, %d%%\n",
|
||||
hits, misses, 100 * hits / (hits + misses));
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash a command name.
|
||||
*/
|
||||
static int
|
||||
hashname(cp)
|
||||
Char *cp;
|
||||
{
|
||||
long h = 0;
|
||||
|
||||
while (*cp)
|
||||
h = hash(h, *cp++);
|
||||
return ((int) h);
|
||||
}
|
||||
|
||||
static int
|
||||
iscommand(name)
|
||||
Char *name;
|
||||
{
|
||||
Char **pv;
|
||||
Char *sav;
|
||||
struct varent *v;
|
||||
bool slash = any(short2str(name), '/');
|
||||
int hashval = 0, hashval1, i;
|
||||
|
||||
v = adrof(STRpath);
|
||||
if (v == 0 || v->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = v->vec;
|
||||
sav = Strspl(STRslash, name); /* / command name for postpending */
|
||||
if (havhash)
|
||||
hashval = hashname(name);
|
||||
i = 0;
|
||||
do {
|
||||
if (!slash && pv[0][0] == '/' && havhash) {
|
||||
hashval1 = hash(hashval, i);
|
||||
if (!bit(xhash, hashval1))
|
||||
goto cont;
|
||||
}
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) { /* don't make ./xxx */
|
||||
if (executable(NULL, name, 0)) {
|
||||
xfree((ptr_t) sav);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (executable(*pv, sav, 0)) {
|
||||
xfree((ptr_t) sav);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
cont:
|
||||
pv++;
|
||||
i++;
|
||||
} while (*pv);
|
||||
xfree((ptr_t) sav);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Also by:
|
||||
* Andreas Luik <[email protected]>
|
||||
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
|
||||
* Azenberstr. 35
|
||||
* D-7000 Stuttgart 1
|
||||
* West-Germany
|
||||
* is the executable() routine below and changes to iscommand().
|
||||
* Thanks again!!
|
||||
*/
|
||||
|
||||
/*
|
||||
* executable() examines the pathname obtained by concatenating dir and name
|
||||
* (dir may be NULL), and returns 1 either if it is executable by us, or
|
||||
* if dir_ok is set and the pathname refers to a directory.
|
||||
* This is a bit kludgy, but in the name of optimization...
|
||||
*/
|
||||
static int
|
||||
executable(dir, name, dir_ok)
|
||||
Char *dir, *name;
|
||||
bool dir_ok;
|
||||
{
|
||||
struct stat stbuf;
|
||||
Char path[MAXPATHLEN + 1], *dp, *sp;
|
||||
char *strname;
|
||||
|
||||
if (dir && *dir) {
|
||||
for (dp = path, sp = dir; *sp; *dp++ = *sp++)
|
||||
if (dp == &path[MAXPATHLEN + 1]) {
|
||||
*--dp = '\0';
|
||||
break;
|
||||
}
|
||||
for (sp = name; *sp; *dp++ = *sp++)
|
||||
if (dp == &path[MAXPATHLEN + 1]) {
|
||||
*--dp = '\0';
|
||||
break;
|
||||
}
|
||||
*dp = '\0';
|
||||
strname = short2str(path);
|
||||
}
|
||||
else
|
||||
strname = short2str(name);
|
||||
return (stat(strname, &stbuf) != -1 &&
|
||||
((S_ISREG(stbuf.st_mode) &&
|
||||
/* save time by not calling access() in the hopeless case */
|
||||
(stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) &&
|
||||
access(strname, X_OK) == 0) ||
|
||||
(dir_ok && S_ISDIR(stbuf.st_mode))));
|
||||
}
|
||||
|
||||
/* The dowhich() is by:
|
||||
* Andreas Luik <[email protected]>
|
||||
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
|
||||
* Azenberstr. 35
|
||||
* D-7000 Stuttgart 1
|
||||
* West-Germany
|
||||
* Thanks!!
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
dowhich(v, c)
|
||||
Char **v;
|
||||
struct command *c;
|
||||
{
|
||||
struct wordent lex[3];
|
||||
struct varent *vp;
|
||||
|
||||
lex[0].next = &lex[1];
|
||||
lex[1].next = &lex[2];
|
||||
lex[2].next = &lex[0];
|
||||
|
||||
lex[0].prev = &lex[2];
|
||||
lex[1].prev = &lex[0];
|
||||
lex[2].prev = &lex[1];
|
||||
|
||||
lex[0].word = STRNULL;
|
||||
lex[2].word = STRret;
|
||||
|
||||
while (*++v) {
|
||||
if ((vp = adrof1(*v, &aliases)) != NULL) {
|
||||
(void) fprintf(cshout, "%s: \t aliased to ", vis_str(*v));
|
||||
blkpr(cshout, vp->vec);
|
||||
(void) fputc('\n', cshout);
|
||||
}
|
||||
else {
|
||||
lex[1].word = *v;
|
||||
tellmewhat(lex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tellmewhat(lex)
|
||||
struct wordent *lex;
|
||||
{
|
||||
int i;
|
||||
struct biltins *bptr;
|
||||
struct wordent *sp = lex->next;
|
||||
bool aliased = 0;
|
||||
Char *s0, *s1, *s2, *cmd;
|
||||
Char qc;
|
||||
|
||||
if (adrof1(sp->word, &aliases)) {
|
||||
alias(lex);
|
||||
sp = lex->next;
|
||||
aliased = 1;
|
||||
}
|
||||
|
||||
s0 = sp->word; /* to get the memory freeing right... */
|
||||
|
||||
/* handle quoted alias hack */
|
||||
if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE)
|
||||
(sp->word)++;
|
||||
|
||||
/* do quoting, if it hasn't been done */
|
||||
s1 = s2 = sp->word;
|
||||
while (*s2)
|
||||
switch (*s2) {
|
||||
case '\'':
|
||||
case '"':
|
||||
qc = *s2++;
|
||||
while (*s2 && *s2 != qc)
|
||||
*s1++ = *s2++ | QUOTE;
|
||||
if (*s2)
|
||||
s2++;
|
||||
break;
|
||||
case '\\':
|
||||
if (*++s2)
|
||||
*s1++ = *s2++ | QUOTE;
|
||||
break;
|
||||
default:
|
||||
*s1++ = *s2++;
|
||||
}
|
||||
*s1 = '\0';
|
||||
|
||||
for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
|
||||
if (eq(sp->word, str2short(bptr->bname))) {
|
||||
if (aliased)
|
||||
prlex(cshout, lex);
|
||||
(void) fprintf(cshout, "%s: shell built-in command.\n",
|
||||
vis_str(sp->word));
|
||||
sp->word = s0; /* we save and then restore this */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sp->word = cmd = globone(sp->word, G_IGNORE);
|
||||
|
||||
if ((i = iscommand(strip(sp->word))) != 0) {
|
||||
Char **pv;
|
||||
struct varent *v;
|
||||
bool slash = any(short2str(sp->word), '/');
|
||||
|
||||
v = adrof(STRpath);
|
||||
if (v == 0 || v->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = v->vec;
|
||||
|
||||
while (--i)
|
||||
pv++;
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) {
|
||||
if (!slash) {
|
||||
sp->word = Strspl(STRdotsl, sp->word);
|
||||
prlex(cshout, lex);
|
||||
xfree((ptr_t) sp->word);
|
||||
} else
|
||||
prlex(cshout, lex);
|
||||
sp->word = s0; /* we save and then restore this */
|
||||
xfree((ptr_t) cmd);
|
||||
return;
|
||||
}
|
||||
s1 = Strspl(*pv, STRslash);
|
||||
sp->word = Strspl(s1, sp->word);
|
||||
xfree((ptr_t) s1);
|
||||
prlex(cshout, lex);
|
||||
xfree((ptr_t) sp->word);
|
||||
}
|
||||
else {
|
||||
if (aliased)
|
||||
prlex(cshout, lex);
|
||||
(void) fprintf(csherr, "%s: Command not found.\n", vis_str(sp->word));
|
||||
}
|
||||
xfree((ptr_t) cmd);
|
||||
sp->word = s0; /* we save and then restore this */
|
||||
}
|
||||
-712
@@ -1,712 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define IGNORE 1 /* in ignore, it means to ignore value, just parse */
|
||||
#define NOGLOB 2 /* in ignore, it means not to globone */
|
||||
|
||||
#define ADDOP 1
|
||||
#define MULOP 2
|
||||
#define EQOP 4
|
||||
#define RELOP 8
|
||||
#define RESTOP 16
|
||||
#define ANYOP 31
|
||||
|
||||
#define EQEQ 1
|
||||
#define GTR 2
|
||||
#define LSS 4
|
||||
#define NOTEQ 6
|
||||
#define EQMATCH 7
|
||||
#define NOTEQMATCH 8
|
||||
|
||||
static int exp1 __P((Char ***, bool));
|
||||
static int exp2 __P((Char ***, bool));
|
||||
static int exp2a __P((Char ***, bool));
|
||||
static int exp2b __P((Char ***, bool));
|
||||
static int exp2c __P((Char ***, bool));
|
||||
static Char * exp3 __P((Char ***, bool));
|
||||
static Char * exp3a __P((Char ***, bool));
|
||||
static Char * exp4 __P((Char ***, bool));
|
||||
static Char * exp5 __P((Char ***, bool));
|
||||
static Char * exp6 __P((Char ***, bool));
|
||||
static void evalav __P((Char **));
|
||||
static int isa __P((Char *, int));
|
||||
static int egetn __P((Char *));
|
||||
|
||||
#ifdef EDEBUG
|
||||
static void etracc __P((char *, Char *, Char ***));
|
||||
static void etraci __P((char *, int, Char ***));
|
||||
#endif
|
||||
|
||||
int
|
||||
expr(vp)
|
||||
Char ***vp;
|
||||
{
|
||||
return (exp0(vp, 0));
|
||||
}
|
||||
|
||||
int
|
||||
exp0(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int p1 = exp1(vp, ignore);
|
||||
|
||||
#ifdef EDEBUG
|
||||
etraci("exp0 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRor2)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp0(vp, (ignore & IGNORE) || p1);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp0 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 || p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp1(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int p1 = exp2(vp, ignore);
|
||||
|
||||
#ifdef EDEBUG
|
||||
etraci("exp1 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRand2)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp1(vp, (ignore & IGNORE) || !p1);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp1 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 && p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int p1 = exp2a(vp, ignore);
|
||||
|
||||
#ifdef EDEBUG
|
||||
etraci("exp3 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRor)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp2(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp3 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 | p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2a(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int p1 = exp2b(vp, ignore);
|
||||
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2a p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRcaret)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp2a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2a p2", p2, vp);
|
||||
#endif
|
||||
return (p1 ^ p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2b(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int p1 = exp2c(vp, ignore);
|
||||
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2b p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRand)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp2b(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2b p2", p2, vp);
|
||||
#endif
|
||||
return (p1 & p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2c(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
Char *p1 = exp3(vp, ignore);
|
||||
Char *p2;
|
||||
int i;
|
||||
|
||||
#ifdef EDEBUG
|
||||
etracc("exp2c p1", p1, vp);
|
||||
#endif
|
||||
if ((i = isa(**vp, EQOP)) != 0) {
|
||||
(*vp)++;
|
||||
if (i == EQMATCH || i == NOTEQMATCH)
|
||||
ignore |= NOGLOB;
|
||||
p2 = exp3(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp2c p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (i) {
|
||||
|
||||
case EQEQ:
|
||||
i = eq(p1, p2);
|
||||
break;
|
||||
|
||||
case NOTEQ:
|
||||
i = !eq(p1, p2);
|
||||
break;
|
||||
|
||||
case EQMATCH:
|
||||
i = Gmatch(p1, p2);
|
||||
break;
|
||||
|
||||
case NOTEQMATCH:
|
||||
i = !Gmatch(p1, p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (i);
|
||||
}
|
||||
i = egetn(p1);
|
||||
xfree((ptr_t) p1);
|
||||
return (i);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp3(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i;
|
||||
|
||||
p1 = exp3a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3 p1", p1, vp);
|
||||
#endif
|
||||
if ((i = isa(**vp, RELOP)) != 0) {
|
||||
(*vp)++;
|
||||
if (**vp && eq(**vp, STRequal))
|
||||
i |= 1, (*vp)++;
|
||||
p2 = exp3(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (i) {
|
||||
|
||||
case GTR:
|
||||
i = egetn(p1) > egetn(p2);
|
||||
break;
|
||||
|
||||
case GTR | 1:
|
||||
i = egetn(p1) >= egetn(p2);
|
||||
break;
|
||||
|
||||
case LSS:
|
||||
i = egetn(p1) < egetn(p2);
|
||||
break;
|
||||
|
||||
case LSS | 1:
|
||||
i = egetn(p1) <= egetn(p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp3a(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
Char *p1, *p2, *op;
|
||||
int i;
|
||||
|
||||
p1 = exp4(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3a p1", p1, vp);
|
||||
#endif
|
||||
op = **vp;
|
||||
if (op && any("<>", op[0]) && op[0] == op[1]) {
|
||||
(*vp)++;
|
||||
p2 = exp3a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3a p2", p2, vp);
|
||||
#endif
|
||||
if (op[0] == '<')
|
||||
i = egetn(p1) << egetn(p2);
|
||||
else
|
||||
i = egetn(p1) >> egetn(p2);
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp4(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i = 0;
|
||||
|
||||
p1 = exp5(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp4 p1", p1, vp);
|
||||
#endif
|
||||
if (isa(**vp, ADDOP)) {
|
||||
Char *op = *(*vp)++;
|
||||
|
||||
p2 = exp4(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp4 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (op[0]) {
|
||||
|
||||
case '+':
|
||||
i = egetn(p1) + egetn(p2);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
i = egetn(p1) - egetn(p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp5(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i = 0;
|
||||
|
||||
p1 = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp5 p1", p1, vp);
|
||||
#endif
|
||||
if (isa(**vp, MULOP)) {
|
||||
Char *op = *(*vp)++;
|
||||
|
||||
p2 = exp5(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp5 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (op[0]) {
|
||||
|
||||
case '*':
|
||||
i = egetn(p1) * egetn(p2);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
i = egetn(p2);
|
||||
if (i == 0)
|
||||
stderror(ERR_DIV0);
|
||||
i = egetn(p1) / i;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
i = egetn(p2);
|
||||
if (i == 0)
|
||||
stderror(ERR_MOD0);
|
||||
i = egetn(p1) % i;
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp6(vp, ignore)
|
||||
Char ***vp;
|
||||
bool ignore;
|
||||
{
|
||||
int ccode, i = 0;
|
||||
Char *cp, *dp, *ep;
|
||||
|
||||
if (**vp == 0)
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
if (eq(**vp, STRbang)) {
|
||||
(*vp)++;
|
||||
cp = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 ! cp", cp, vp);
|
||||
#endif
|
||||
i = egetn(cp);
|
||||
xfree((ptr_t) cp);
|
||||
return (putn(!i));
|
||||
}
|
||||
if (eq(**vp, STRtilde)) {
|
||||
(*vp)++;
|
||||
cp = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 ~ cp", cp, vp);
|
||||
#endif
|
||||
i = egetn(cp);
|
||||
xfree((ptr_t) cp);
|
||||
return (putn(~i));
|
||||
}
|
||||
if (eq(**vp, STRLparen)) {
|
||||
(*vp)++;
|
||||
ccode = exp0(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 () ccode", ccode, vp);
|
||||
#endif
|
||||
if (*vp == 0 || **vp == 0 || ***vp != ')')
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
(*vp)++;
|
||||
return (putn(ccode));
|
||||
}
|
||||
if (eq(**vp, STRLbrace)) {
|
||||
Char **v;
|
||||
struct command faket;
|
||||
Char *fakecom[2];
|
||||
|
||||
faket.t_dtyp = NODE_COMMAND;
|
||||
faket.t_dflg = 0;
|
||||
faket.t_dcar = faket.t_dcdr = faket.t_dspr = NULL;
|
||||
faket.t_dcom = fakecom;
|
||||
fakecom[0] = STRfakecom;
|
||||
fakecom[1] = NULL;
|
||||
(*vp)++;
|
||||
v = *vp;
|
||||
for (;;) {
|
||||
if (!**vp)
|
||||
stderror(ERR_NAME | ERR_MISSING, '}');
|
||||
if (eq(*(*vp)++, STRRbrace))
|
||||
break;
|
||||
}
|
||||
if (ignore & IGNORE)
|
||||
return (Strsave(STRNULL));
|
||||
psavejob();
|
||||
if (pfork(&faket, -1) == 0) {
|
||||
*--(*vp) = 0;
|
||||
evalav(v);
|
||||
exitstat();
|
||||
}
|
||||
pwait();
|
||||
prestjob();
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 {} status", egetn(value(STRstatus)), vp);
|
||||
#endif
|
||||
return (putn(egetn(value(STRstatus)) == 0));
|
||||
}
|
||||
if (isa(**vp, ANYOP))
|
||||
return (Strsave(STRNULL));
|
||||
cp = *(*vp)++;
|
||||
if (*cp == '-' && any("erwxfdzopls", cp[1])) {
|
||||
struct stat stb;
|
||||
|
||||
if (cp[2] != '\0')
|
||||
stderror(ERR_NAME | ERR_FILEINQ);
|
||||
/*
|
||||
* Detect missing file names by checking for operator in the file name
|
||||
* position. However, if an operator name appears there, we must make
|
||||
* sure that there's no file by that name (e.g., "/") before announcing
|
||||
* an error. Even this check isn't quite right, since it doesn't take
|
||||
* globbing into account.
|
||||
*/
|
||||
if (isa(**vp, ANYOP) && stat(short2str(**vp), &stb))
|
||||
stderror(ERR_NAME | ERR_FILENAME);
|
||||
|
||||
dp = *(*vp)++;
|
||||
if (ignore & IGNORE)
|
||||
return (Strsave(STRNULL));
|
||||
ep = globone(dp, G_ERROR);
|
||||
switch (cp[1]) {
|
||||
|
||||
case 'r':
|
||||
i = !access(short2str(ep), R_OK);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
i = !access(short2str(ep), W_OK);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
i = !access(short2str(ep), X_OK);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (
|
||||
#ifdef S_IFLNK
|
||||
cp[1] == 'l' ? lstat(short2str(ep), &stb) :
|
||||
#endif
|
||||
stat(short2str(ep), &stb)) {
|
||||
xfree((ptr_t) ep);
|
||||
return (Strsave(STR0));
|
||||
}
|
||||
switch (cp[1]) {
|
||||
|
||||
case 'f':
|
||||
i = S_ISREG(stb.st_mode);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
i = S_ISDIR(stb.st_mode);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
#ifdef S_ISFIFO
|
||||
i = S_ISFIFO(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
#ifdef S_ISLNK
|
||||
i = S_ISLNK(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 's':
|
||||
#ifdef S_ISSOCK
|
||||
i = S_ISSOCK(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
i = stb.st_size == 0;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
i = 1;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
i = stb.st_uid == uid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 -? i", i, vp);
|
||||
#endif
|
||||
xfree((ptr_t) ep);
|
||||
return (putn(i));
|
||||
}
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 default", cp, vp);
|
||||
#endif
|
||||
return (ignore & NOGLOB ? Strsave(cp) : globone(cp, G_ERROR));
|
||||
}
|
||||
|
||||
static void
|
||||
evalav(v)
|
||||
Char **v;
|
||||
{
|
||||
struct wordent paraml1;
|
||||
struct wordent *hp = ¶ml1;
|
||||
struct command *t;
|
||||
struct wordent *wdp = hp;
|
||||
|
||||
set(STRstatus, Strsave(STR0));
|
||||
hp->prev = hp->next = hp;
|
||||
hp->word = STRNULL;
|
||||
while (*v) {
|
||||
struct wordent *new =
|
||||
(struct wordent *) xcalloc(1, sizeof *wdp);
|
||||
|
||||
new->prev = wdp;
|
||||
new->next = hp;
|
||||
wdp->next = new;
|
||||
wdp = new;
|
||||
wdp->word = Strsave(*v++);
|
||||
}
|
||||
hp->prev = wdp;
|
||||
alias(¶ml1);
|
||||
t = syntax(paraml1.next, ¶ml1, 0);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
execute(t, -1, NULL, NULL);
|
||||
freelex(¶ml1), freesyn(t);
|
||||
}
|
||||
|
||||
static int
|
||||
isa(cp, what)
|
||||
Char *cp;
|
||||
int what;
|
||||
{
|
||||
if (cp == 0)
|
||||
return ((what & RESTOP) != 0);
|
||||
if (cp[1] == 0) {
|
||||
if (what & ADDOP && (*cp == '+' || *cp == '-'))
|
||||
return (1);
|
||||
if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
|
||||
return (1);
|
||||
if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
|
||||
*cp == '~' || *cp == '^' || *cp == '"'))
|
||||
return (1);
|
||||
}
|
||||
else if (cp[2] == 0) {
|
||||
if (what & RESTOP) {
|
||||
if (cp[0] == '|' && cp[1] == '&')
|
||||
return (1);
|
||||
if (cp[0] == '<' && cp[1] == '<')
|
||||
return (1);
|
||||
if (cp[0] == '>' && cp[1] == '>')
|
||||
return (1);
|
||||
}
|
||||
if (what & EQOP) {
|
||||
if (cp[0] == '=') {
|
||||
if (cp[1] == '=')
|
||||
return (EQEQ);
|
||||
if (cp[1] == '~')
|
||||
return (EQMATCH);
|
||||
}
|
||||
else if (cp[0] == '!') {
|
||||
if (cp[1] == '=')
|
||||
return (NOTEQ);
|
||||
if (cp[1] == '~')
|
||||
return (NOTEQMATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (what & RELOP) {
|
||||
if (*cp == '<')
|
||||
return (LSS);
|
||||
if (*cp == '>')
|
||||
return (GTR);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
egetn(cp)
|
||||
Char *cp;
|
||||
{
|
||||
if (*cp && *cp != '-' && !Isdigit(*cp))
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
return (getn(cp));
|
||||
}
|
||||
|
||||
/* Phew! */
|
||||
|
||||
#ifdef EDEBUG
|
||||
static void
|
||||
etraci(str, i, vp)
|
||||
char *str;
|
||||
int i;
|
||||
Char ***vp;
|
||||
{
|
||||
(void) fprintf(csherr, "%s=%d\t", str, i);
|
||||
blkpr(csherr, *vp);
|
||||
(void) fprintf(csherr, "\n");
|
||||
}
|
||||
static void
|
||||
etracc(str, cp, vp)
|
||||
char *str;
|
||||
Char *cp;
|
||||
Char ***vp;
|
||||
{
|
||||
(void) fprintf(csherr, "%s=%s\t", str, vis_str(cp));
|
||||
blkpr(csherr, *vp);
|
||||
(void) fprintf(csherr, "\n");
|
||||
}
|
||||
#endif
|
||||
@@ -1,339 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* csh.c
|
||||
*/
|
||||
int gethdir __P((Char *));
|
||||
void dosource __P((Char **, struct command *));
|
||||
void exitstat __P((void));
|
||||
void goodbye __P((void));
|
||||
void importpath __P((Char *));
|
||||
void initdesc __P((void));
|
||||
void pintr __P((int));
|
||||
void pintr1 __P((bool));
|
||||
void printprompt __P((void));
|
||||
void process __P((bool));
|
||||
void rechist __P((void));
|
||||
void untty __P((void));
|
||||
int vis_fputc __P((int, FILE *));
|
||||
|
||||
#ifdef PROF
|
||||
void done __P((int));
|
||||
#else
|
||||
void xexit __P((int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dir.c
|
||||
*/
|
||||
void dinit __P((Char *));
|
||||
void dodirs __P((Char **, struct command *));
|
||||
Char *dcanon __P((Char *, Char *));
|
||||
void dtildepr __P((Char *, Char *));
|
||||
void dtilde __P((void));
|
||||
void dochngd __P((Char **, struct command *));
|
||||
Char *dnormalize __P((Char *));
|
||||
void dopushd __P((Char **, struct command *));
|
||||
void dopopd __P((Char **, struct command *));
|
||||
struct directory;
|
||||
void dfree __P((struct directory *));
|
||||
|
||||
/*
|
||||
* dol.c
|
||||
*/
|
||||
void Dfix __P((struct command *));
|
||||
Char *Dfix1 __P((Char *));
|
||||
void heredoc __P((Char *));
|
||||
|
||||
/*
|
||||
* err.c
|
||||
*/
|
||||
void seterror __P((int, ...));
|
||||
void stderror __P((int, ...));
|
||||
|
||||
/*
|
||||
* exec.c
|
||||
*/
|
||||
void doexec __P((Char **, struct command *));
|
||||
void dohash __P((Char **, struct command *));
|
||||
void dounhash __P((Char **, struct command *));
|
||||
void dowhich __P((Char **, struct command *));
|
||||
void execash __P((Char **, struct command *));
|
||||
void hashstat __P((Char **, struct command *));
|
||||
void xechoit __P((Char **));
|
||||
|
||||
/*
|
||||
* exp.c
|
||||
*/
|
||||
int expr __P((Char ***));
|
||||
int exp0 __P((Char ***, bool));
|
||||
|
||||
/*
|
||||
* file.c
|
||||
*/
|
||||
#ifdef FILEC
|
||||
int tenex __P((Char *, int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* func.c
|
||||
*/
|
||||
void Setenv __P((Char *, Char *));
|
||||
void doalias __P((Char **, struct command *));
|
||||
void dobreak __P((Char **, struct command *));
|
||||
void docontin __P((Char **, struct command *));
|
||||
void doecho __P((Char **, struct command *));
|
||||
void doelse __P((Char **, struct command *));
|
||||
void doend __P((Char **, struct command *));
|
||||
void doeval __P((Char **, struct command *));
|
||||
void doexit __P((Char **, struct command *));
|
||||
void doforeach __P((Char **, struct command *));
|
||||
void doglob __P((Char **, struct command *));
|
||||
void dogoto __P((Char **, struct command *));
|
||||
void doif __P((Char **, struct command *));
|
||||
void dolimit __P((Char **, struct command *));
|
||||
void dologin __P((Char **, struct command *));
|
||||
void dologout __P((Char **, struct command *));
|
||||
void donohup __P((Char **, struct command *));
|
||||
void doonintr __P((Char **, struct command *));
|
||||
void doprintf __P((Char **, struct command *));
|
||||
void dorepeat __P((Char **, struct command *));
|
||||
void dosetenv __P((Char **, struct command *));
|
||||
void dosuspend __P((Char **, struct command *));
|
||||
void doswbrk __P((Char **, struct command *));
|
||||
void doswitch __P((Char **, struct command *));
|
||||
void doumask __P((Char **, struct command *));
|
||||
void dounlimit __P((Char **, struct command *));
|
||||
void dounsetenv __P((Char **, struct command *));
|
||||
void dowhile __P((Char **, struct command *));
|
||||
void dozip __P((Char **, struct command *));
|
||||
void func __P((struct command *, struct biltins *));
|
||||
struct biltins *
|
||||
isbfunc __P((struct command *));
|
||||
void prvars __P((void));
|
||||
void gotolab __P((Char *));
|
||||
int srchx __P((Char *));
|
||||
void unalias __P((Char **, struct command *));
|
||||
void wfree __P((void));
|
||||
|
||||
/*
|
||||
* glob.c
|
||||
*/
|
||||
Char **dobackp __P((Char *, bool));
|
||||
void Gcat __P((Char *, Char *));
|
||||
Char *globone __P((Char *, int));
|
||||
int Gmatch __P((Char *, Char *));
|
||||
void ginit __P((void));
|
||||
Char **globall __P((Char **));
|
||||
void rscan __P((Char **, void (*)(int)));
|
||||
void tglob __P((Char **));
|
||||
void trim __P((Char **));
|
||||
#ifdef FILEC
|
||||
int sortscmp __P((const ptr_t, const ptr_t));
|
||||
#endif /* FILEC */
|
||||
|
||||
/*
|
||||
* hist.c
|
||||
*/
|
||||
void dohist __P((Char **, struct command *));
|
||||
struct Hist *
|
||||
enthist __P((int, struct wordent *, bool));
|
||||
void savehist __P((struct wordent *));
|
||||
|
||||
/*
|
||||
* lex.c
|
||||
*/
|
||||
void addla __P((Char *));
|
||||
void bseek __P((struct Ain *));
|
||||
void btell __P((struct Ain *));
|
||||
void btoeof __P((void));
|
||||
void copylex __P((struct wordent *, struct wordent *));
|
||||
Char *domod __P((Char *, int));
|
||||
void freelex __P((struct wordent *));
|
||||
int lex __P((struct wordent *));
|
||||
void prlex __P((FILE *, struct wordent *));
|
||||
int readc __P((bool));
|
||||
void settell __P((void));
|
||||
void unreadc __P((int));
|
||||
|
||||
/*
|
||||
* misc.c
|
||||
*/
|
||||
int any __P((char *, int));
|
||||
Char **blkcat __P((Char **, Char **));
|
||||
Char **blkcpy __P((Char **, Char **));
|
||||
Char **blkend __P((Char **));
|
||||
void blkfree __P((Char **));
|
||||
int blklen __P((Char **));
|
||||
void blkpr __P((FILE *, Char **));
|
||||
Char **blkspl __P((Char **, Char **));
|
||||
void closem __P((void));
|
||||
Char **copyblk __P((Char **));
|
||||
int dcopy __P((int, int));
|
||||
int dmove __P((int, int));
|
||||
void donefds __P((void));
|
||||
Char lastchr __P((Char *));
|
||||
void lshift __P((Char **, int));
|
||||
int number __P((Char *));
|
||||
int prefix __P((Char *, Char *));
|
||||
Char **saveblk __P((Char **));
|
||||
void setzero __P((char *, int));
|
||||
Char *strip __P((Char *));
|
||||
char *strsave __P((char *));
|
||||
char *strspl __P((char *, char *));
|
||||
void udvar __P((Char *));
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
# ifdef NOTUSED
|
||||
char *strstr __P((const char *, const char *));
|
||||
# endif /* NOTUSED */
|
||||
char *strend __P((char *));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parse.c
|
||||
*/
|
||||
void alias __P((struct wordent *));
|
||||
void freesyn __P((struct command *));
|
||||
struct command *
|
||||
syntax __P((struct wordent *, struct wordent *, int));
|
||||
|
||||
|
||||
/*
|
||||
* proc.c
|
||||
*/
|
||||
void dobg __P((Char **, struct command *));
|
||||
void dobg1 __P((Char **, struct command *));
|
||||
void dofg __P((Char **, struct command *));
|
||||
void dofg1 __P((Char **, struct command *));
|
||||
void dojobs __P((Char **, struct command *));
|
||||
void dokill __P((Char **, struct command *));
|
||||
void donotify __P((Char **, struct command *));
|
||||
void dostop __P((Char **, struct command *));
|
||||
void dowait __P((Char **, struct command *));
|
||||
void palloc __P((int, struct command *));
|
||||
void panystop __P((bool));
|
||||
void pchild __P((int));
|
||||
void pendjob __P((void));
|
||||
struct process *
|
||||
pfind __P((Char *));
|
||||
int pfork __P((struct command *, int));
|
||||
void pgetty __P((int, int));
|
||||
void pjwait __P((struct process *));
|
||||
void pnote __P((void));
|
||||
void prestjob __P((void));
|
||||
void psavejob __P((void));
|
||||
void pstart __P((struct process *, int));
|
||||
void pwait __P((void));
|
||||
|
||||
/*
|
||||
* sem.c
|
||||
*/
|
||||
void execute __P((struct command *, int, int *, int *));
|
||||
void mypipe __P((int *));
|
||||
|
||||
/*
|
||||
* set.c
|
||||
*/
|
||||
struct varent
|
||||
*adrof1 __P((Char *, struct varent *));
|
||||
void doset __P((Char **, struct command *));
|
||||
void dolet __P((Char **, struct command *));
|
||||
Char *putn __P((int));
|
||||
int getn __P((Char *));
|
||||
Char *value1 __P((Char *, struct varent *));
|
||||
void set __P((Char *, Char *));
|
||||
void set1 __P((Char *, Char **, struct varent *));
|
||||
void setq __P((Char *, Char **, struct varent *));
|
||||
void unset __P((Char **, struct command *));
|
||||
void unset1 __P((Char *[], struct varent *));
|
||||
void unsetv __P((Char *));
|
||||
void setNS __P((Char *));
|
||||
void shift __P((Char **, struct command *));
|
||||
void plist __P((struct varent *));
|
||||
|
||||
/*
|
||||
* time.c
|
||||
*/
|
||||
void donice __P((Char **, struct command *));
|
||||
void dotime __P((Char **, struct command *));
|
||||
void prusage __P((struct rusage *, struct rusage *,
|
||||
struct timeval *, struct timeval *));
|
||||
void ruadd __P((struct rusage *, struct rusage *));
|
||||
void settimes __P((void));
|
||||
void tvadd __P((struct timeval *, struct timeval *));
|
||||
void tvsub __P((struct timeval *, struct timeval *, struct timeval *));
|
||||
void pcsecs __P((long));
|
||||
void psecs __P((long));
|
||||
|
||||
/*
|
||||
* alloc.c
|
||||
*/
|
||||
void Free __P((ptr_t));
|
||||
ptr_t Malloc __P((size_t));
|
||||
ptr_t Realloc __P((ptr_t, size_t));
|
||||
ptr_t Calloc __P((size_t, size_t));
|
||||
void showall __P((Char **, struct command *));
|
||||
|
||||
/*
|
||||
* str.c:
|
||||
*/
|
||||
#ifdef SHORT_STRINGS
|
||||
Char *s_strchr __P((Char *, int));
|
||||
Char *s_strrchr __P((Char *, int));
|
||||
Char *s_strcat __P((Char *, Char *));
|
||||
#ifdef NOTUSED
|
||||
Char *s_strncat __P((Char *, Char *, size_t));
|
||||
#endif
|
||||
Char *s_strcpy __P((Char *, Char *));
|
||||
Char *s_strncpy __P((Char *, Char *, size_t));
|
||||
Char *s_strspl __P((Char *, Char *));
|
||||
size_t s_strlen __P((Char *));
|
||||
int s_strcmp __P((Char *, Char *));
|
||||
int s_strncmp __P((Char *, Char *, size_t));
|
||||
Char *s_strsave __P((Char *));
|
||||
Char *s_strend __P((Char *));
|
||||
Char *s_strstr __P((Char *, Char *));
|
||||
Char *str2short __P((char *));
|
||||
Char **blk2short __P((char **));
|
||||
char *short2str __P((Char *));
|
||||
char **short2blk __P((Char **));
|
||||
#endif
|
||||
char *short2qstr __P((Char *));
|
||||
char *vis_str __P((Char *));
|
||||
-685
@@ -1,685 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)file.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef FILEC
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* Tenex style file name recognition, .. and more.
|
||||
* History:
|
||||
* Author: Ken Greer, Sept. 1975, CMU.
|
||||
* Finally got around to adding to the Cshell., Ken Greer, Dec. 1981.
|
||||
*/
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define ESC '\033'
|
||||
|
||||
typedef enum {
|
||||
LIST, RECOGNIZE
|
||||
} COMMAND;
|
||||
|
||||
static void setup_tty __P((int));
|
||||
static void back_to_col_1 __P((void));
|
||||
static void pushback __P((Char *));
|
||||
static void catn __P((Char *, Char *, int));
|
||||
static void copyn __P((Char *, Char *, int));
|
||||
static Char filetype __P((Char *, Char *));
|
||||
static void print_by_column __P((Char *, Char *[], int));
|
||||
static Char *tilde __P((Char *, Char *));
|
||||
static void retype __P((void));
|
||||
static void beep __P((void));
|
||||
static void print_recognized_stuff __P((Char *));
|
||||
static void extract_dir_and_name __P((Char *, Char *, Char *));
|
||||
static Char *getentry __P((DIR *, int));
|
||||
static void free_items __P((Char **));
|
||||
static int tsearch __P((Char *, COMMAND, int));
|
||||
static int recognize __P((Char *, Char *, int, int));
|
||||
static int is_prefix __P((Char *, Char *));
|
||||
static int is_suffix __P((Char *, Char *));
|
||||
static int ignored __P((Char *));
|
||||
|
||||
/*
|
||||
* Put this here so the binary can be patched with adb to enable file
|
||||
* completion by default. Filec controls completion, nobeep controls
|
||||
* ringing the terminal bell on incomplete expansions.
|
||||
*/
|
||||
bool filec = 0;
|
||||
|
||||
static void
|
||||
setup_tty(on)
|
||||
int on;
|
||||
{
|
||||
struct termios tchars;
|
||||
|
||||
(void) tcgetattr(SHIN, &tchars);
|
||||
|
||||
if (on) {
|
||||
tchars.c_cc[VEOL] = ESC;
|
||||
if (tchars.c_lflag & ICANON)
|
||||
on = TCSADRAIN;
|
||||
else {
|
||||
on = TCSAFLUSH;
|
||||
tchars.c_lflag |= ICANON;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tchars.c_cc[VEOL] = _POSIX_VDISABLE;
|
||||
on = TCSADRAIN;
|
||||
}
|
||||
|
||||
(void) tcsetattr(SHIN, on, &tchars);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move back to beginning of current line
|
||||
*/
|
||||
static void
|
||||
back_to_col_1()
|
||||
{
|
||||
struct termios tty, tty_normal;
|
||||
int omask;
|
||||
|
||||
omask = sigblock(sigmask(SIGINT));
|
||||
(void) tcgetattr(SHOUT, &tty);
|
||||
tty_normal = tty;
|
||||
tty.c_iflag &= ~INLCR;
|
||||
tty.c_oflag &= ~ONLCR;
|
||||
(void) tcsetattr(SHOUT, TCSANOW, &tty);
|
||||
(void) write(SHOUT, "\r", 1);
|
||||
(void) tcsetattr(SHOUT, TCSANOW, &tty_normal);
|
||||
(void) sigsetmask(omask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push string contents back into tty queue
|
||||
*/
|
||||
static void
|
||||
pushback(string)
|
||||
Char *string;
|
||||
{
|
||||
Char *p;
|
||||
struct termios tty, tty_normal;
|
||||
int omask;
|
||||
char c;
|
||||
|
||||
omask = sigblock(sigmask(SIGINT));
|
||||
(void) tcgetattr(SHOUT, &tty);
|
||||
tty_normal = tty;
|
||||
tty.c_lflag &= ~(ECHOKE | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL);
|
||||
(void) tcsetattr(SHOUT, TCSANOW, &tty);
|
||||
|
||||
for (p = string; (c = *p) != '\0'; p++)
|
||||
(void) ioctl(SHOUT, TIOCSTI, (ioctl_t) & c);
|
||||
(void) tcsetattr(SHOUT, TCSANOW, &tty_normal);
|
||||
(void) sigsetmask(omask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenate src onto tail of des.
|
||||
* Des is a string whose maximum length is count.
|
||||
* Always null terminate.
|
||||
*/
|
||||
static void
|
||||
catn(des, src, count)
|
||||
Char *des, *src;
|
||||
int count;
|
||||
{
|
||||
while (--count >= 0 && *des)
|
||||
des++;
|
||||
while (--count >= 0)
|
||||
if ((*des++ = *src++) == 0)
|
||||
return;
|
||||
*des = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Like strncpy but always leave room for trailing \0
|
||||
* and always null terminate.
|
||||
*/
|
||||
static void
|
||||
copyn(des, src, count)
|
||||
Char *des, *src;
|
||||
int count;
|
||||
{
|
||||
while (--count >= 0)
|
||||
if ((*des++ = *src++) == 0)
|
||||
return;
|
||||
*des = '\0';
|
||||
}
|
||||
|
||||
static Char
|
||||
filetype(dir, file)
|
||||
Char *dir, *file;
|
||||
{
|
||||
Char path[MAXPATHLEN];
|
||||
struct stat statb;
|
||||
|
||||
catn(Strcpy(path, dir), file, sizeof(path) / sizeof(Char));
|
||||
if (lstat(short2str(path), &statb) == 0) {
|
||||
switch (statb.st_mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
return ('/');
|
||||
|
||||
case S_IFLNK:
|
||||
if (stat(short2str(path), &statb) == 0 && /* follow it out */
|
||||
S_ISDIR(statb.st_mode))
|
||||
return ('>');
|
||||
else
|
||||
return ('@');
|
||||
|
||||
case S_IFSOCK:
|
||||
return ('=');
|
||||
|
||||
default:
|
||||
if (statb.st_mode & 0111)
|
||||
return ('*');
|
||||
}
|
||||
}
|
||||
return (' ');
|
||||
}
|
||||
|
||||
static struct winsize win;
|
||||
|
||||
/*
|
||||
* Print sorted down columns
|
||||
*/
|
||||
static void
|
||||
print_by_column(dir, items, count)
|
||||
Char *dir, *items[];
|
||||
int count;
|
||||
{
|
||||
int i, rows, r, c, maxwidth = 0, columns;
|
||||
|
||||
if (ioctl(SHOUT, TIOCGWINSZ, (ioctl_t) & win) < 0 || win.ws_col == 0)
|
||||
win.ws_col = 80;
|
||||
for (i = 0; i < count; i++)
|
||||
maxwidth = maxwidth > (r = Strlen(items[i])) ? maxwidth : r;
|
||||
maxwidth += 2; /* for the file tag and space */
|
||||
columns = win.ws_col / maxwidth;
|
||||
if (columns == 0)
|
||||
columns = 1;
|
||||
rows = (count + (columns - 1)) / columns;
|
||||
for (r = 0; r < rows; r++) {
|
||||
for (c = 0; c < columns; c++) {
|
||||
i = c * rows + r;
|
||||
if (i < count) {
|
||||
int w;
|
||||
|
||||
(void) fprintf(cshout, "%s", vis_str(items[i]));
|
||||
(void) fputc(dir ? filetype(dir, items[i]) : ' ', cshout);
|
||||
if (c < columns - 1) { /* last column? */
|
||||
w = Strlen(items[i]) + 1;
|
||||
for (; w < maxwidth; w++)
|
||||
(void) fputc(' ', cshout);
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) fputc('\r', cshout);
|
||||
(void) fputc('\n', cshout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand file name with possible tilde usage
|
||||
* ~person/mumble
|
||||
* expands to
|
||||
* home_directory_of_person/mumble
|
||||
*/
|
||||
static Char *
|
||||
tilde(new, old)
|
||||
Char *new, *old;
|
||||
{
|
||||
Char *o, *p;
|
||||
struct passwd *pw;
|
||||
static Char person[40];
|
||||
|
||||
if (old[0] != '~')
|
||||
return (Strcpy(new, old));
|
||||
|
||||
for (p = person, o = &old[1]; *o && *o != '/'; *p++ = *o++)
|
||||
continue;
|
||||
*p = '\0';
|
||||
if (person[0] == '\0')
|
||||
(void) Strcpy(new, value(STRhome));
|
||||
else {
|
||||
pw = getpwnam(short2str(person));
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
(void) Strcpy(new, str2short(pw->pw_dir));
|
||||
}
|
||||
(void) Strcat(new, o);
|
||||
return (new);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cause pending line to be printed
|
||||
*/
|
||||
static void
|
||||
retype()
|
||||
{
|
||||
struct termios tty;
|
||||
|
||||
(void) tcgetattr(SHOUT, &tty);
|
||||
tty.c_lflag |= PENDIN;
|
||||
(void) tcsetattr(SHOUT, TCSANOW, &tty);
|
||||
}
|
||||
|
||||
static void
|
||||
beep()
|
||||
{
|
||||
if (adrof(STRnobeep) == 0)
|
||||
(void) write(SHOUT, "\007", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase that silly ^[ and
|
||||
* print the recognized part of the string
|
||||
*/
|
||||
static void
|
||||
print_recognized_stuff(recognized_part)
|
||||
Char *recognized_part;
|
||||
{
|
||||
/* An optimized erasing of that silly ^[ */
|
||||
(void) fputc('\b', cshout);
|
||||
(void) fputc('\b', cshout);
|
||||
switch (Strlen(recognized_part)) {
|
||||
|
||||
case 0: /* erase two Characters: ^[ */
|
||||
(void) fputc(' ', cshout);
|
||||
(void) fputc(' ', cshout);
|
||||
(void) fputc('\b', cshout);
|
||||
(void) fputc('\b', cshout);
|
||||
break;
|
||||
|
||||
case 1: /* overstrike the ^, erase the [ */
|
||||
(void) fprintf(cshout, "%s", vis_str(recognized_part));
|
||||
(void) fputc(' ', cshout);
|
||||
(void) fputc('\b', cshout);
|
||||
break;
|
||||
|
||||
default: /* overstrike both Characters ^[ */
|
||||
(void) fprintf(cshout, "%s", vis_str(recognized_part));
|
||||
break;
|
||||
}
|
||||
(void) fflush(cshout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse full path in file into 2 parts: directory and file names
|
||||
* Should leave final slash (/) at end of dir.
|
||||
*/
|
||||
static void
|
||||
extract_dir_and_name(path, dir, name)
|
||||
Char *path, *dir, *name;
|
||||
{
|
||||
Char *p;
|
||||
|
||||
p = Strrchr(path, '/');
|
||||
if (p == NULL) {
|
||||
copyn(name, path, MAXNAMLEN);
|
||||
dir[0] = '\0';
|
||||
}
|
||||
else {
|
||||
copyn(name, ++p, MAXNAMLEN);
|
||||
copyn(dir, path, p - path);
|
||||
}
|
||||
}
|
||||
|
||||
static Char *
|
||||
getentry(dir_fd, looking_for_lognames)
|
||||
DIR *dir_fd;
|
||||
int looking_for_lognames;
|
||||
{
|
||||
struct passwd *pw;
|
||||
struct dirent *dirp;
|
||||
|
||||
if (looking_for_lognames) {
|
||||
if ((pw = getpwent()) == NULL)
|
||||
return (NULL);
|
||||
return (str2short(pw->pw_name));
|
||||
}
|
||||
if ((dirp = readdir(dir_fd)) != NULL)
|
||||
return (str2short(dirp->d_name));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
free_items(items)
|
||||
Char **items;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; items[i]; i++)
|
||||
xfree((ptr_t) items[i]);
|
||||
xfree((ptr_t) items);
|
||||
}
|
||||
|
||||
#define FREE_ITEMS(items) { \
|
||||
int omask;\
|
||||
\
|
||||
omask = sigblock(sigmask(SIGINT));\
|
||||
free_items(items);\
|
||||
items = NULL;\
|
||||
(void) sigsetmask(omask);\
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a RECOGNIZE or LIST command on string "word".
|
||||
*/
|
||||
static int
|
||||
tsearch(word, command, max_word_length)
|
||||
Char *word;
|
||||
COMMAND command;
|
||||
int max_word_length;
|
||||
{
|
||||
static Char **items = NULL;
|
||||
DIR *dir_fd;
|
||||
int numitems = 0, ignoring = TRUE, nignored = 0;
|
||||
int name_length, looking_for_lognames;
|
||||
Char tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1];
|
||||
Char name[MAXNAMLEN + 1], extended_name[MAXNAMLEN + 1];
|
||||
Char *entry;
|
||||
|
||||
#define MAXITEMS 1024
|
||||
|
||||
if (items != NULL)
|
||||
FREE_ITEMS(items);
|
||||
|
||||
looking_for_lognames = (*word == '~') && (Strchr(word, '/') == NULL);
|
||||
if (looking_for_lognames) {
|
||||
setpwent();
|
||||
copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */
|
||||
dir_fd = NULL;
|
||||
}
|
||||
else {
|
||||
extract_dir_and_name(word, dir, name);
|
||||
if (tilde(tilded_dir, dir) == 0)
|
||||
return (0);
|
||||
dir_fd = opendir(*tilded_dir ? short2str(tilded_dir) : ".");
|
||||
if (dir_fd == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
again: /* search for matches */
|
||||
name_length = Strlen(name);
|
||||
for (numitems = 0; (entry = getentry(dir_fd, looking_for_lognames)) != NULL;) {
|
||||
if (!is_prefix(name, entry))
|
||||
continue;
|
||||
/* Don't match . files on null prefix match */
|
||||
if (name_length == 0 && entry[0] == '.' &&
|
||||
!looking_for_lognames)
|
||||
continue;
|
||||
if (command == LIST) {
|
||||
if (numitems >= MAXITEMS) {
|
||||
(void) fprintf(csherr, "\nYikes!! Too many %s!!\n",
|
||||
looking_for_lognames ?
|
||||
"names in password file" : "files");
|
||||
break;
|
||||
}
|
||||
if (items == NULL)
|
||||
items = (Char **) xcalloc(sizeof(items[0]), MAXITEMS);
|
||||
items[numitems] = (Char *) xmalloc((size_t) (Strlen(entry) + 1) *
|
||||
sizeof(Char));
|
||||
copyn(items[numitems], entry, MAXNAMLEN);
|
||||
numitems++;
|
||||
}
|
||||
else { /* RECOGNIZE command */
|
||||
if (ignoring && ignored(entry))
|
||||
nignored++;
|
||||
else if (recognize(extended_name,
|
||||
entry, name_length, ++numitems))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ignoring && numitems == 0 && nignored > 0) {
|
||||
ignoring = FALSE;
|
||||
nignored = 0;
|
||||
if (looking_for_lognames)
|
||||
setpwent();
|
||||
else
|
||||
rewinddir(dir_fd);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (looking_for_lognames)
|
||||
(void) endpwent();
|
||||
else
|
||||
(void) closedir(dir_fd);
|
||||
if (numitems == 0)
|
||||
return (0);
|
||||
if (command == RECOGNIZE) {
|
||||
if (looking_for_lognames)
|
||||
copyn(word, STRtilde, 1);
|
||||
else
|
||||
/* put back dir part */
|
||||
copyn(word, dir, max_word_length);
|
||||
/* add extended name */
|
||||
catn(word, extended_name, max_word_length);
|
||||
return (numitems);
|
||||
}
|
||||
else { /* LIST */
|
||||
qsort((ptr_t) items, numitems, sizeof(items[0]),
|
||||
(int (*) __P((const void *, const void *))) sortscmp);
|
||||
print_by_column(looking_for_lognames ? NULL : tilded_dir,
|
||||
items, numitems);
|
||||
if (items != NULL)
|
||||
FREE_ITEMS(items);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Object: extend what user typed up to an ambiguity.
|
||||
* Algorithm:
|
||||
* On first match, copy full entry (assume it'll be the only match)
|
||||
* On subsequent matches, shorten extended_name to the first
|
||||
* Character mismatch between extended_name and entry.
|
||||
* If we shorten it back to the prefix length, stop searching.
|
||||
*/
|
||||
static int
|
||||
recognize(extended_name, entry, name_length, numitems)
|
||||
Char *extended_name, *entry;
|
||||
int name_length, numitems;
|
||||
{
|
||||
if (numitems == 1) /* 1st match */
|
||||
copyn(extended_name, entry, MAXNAMLEN);
|
||||
else { /* 2nd & subsequent matches */
|
||||
Char *x, *ent;
|
||||
int len = 0;
|
||||
|
||||
x = extended_name;
|
||||
for (ent = entry; *x && *x == *ent++; x++, len++)
|
||||
continue;
|
||||
*x = '\0'; /* Shorten at 1st Char diff */
|
||||
if (len == name_length) /* Ambiguous to prefix? */
|
||||
return (-1); /* So stop now and save time */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if check matches initial Chars in template.
|
||||
* This differs from PWB imatch in that if check is null
|
||||
* it matches anything.
|
||||
*/
|
||||
static int
|
||||
is_prefix(check, template)
|
||||
Char *check, *template;
|
||||
{
|
||||
do
|
||||
if (*check == 0)
|
||||
return (TRUE);
|
||||
while (*check++ == *template++);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the Chars in template appear at the
|
||||
* end of check, I.e., are it's suffix.
|
||||
*/
|
||||
static int
|
||||
is_suffix(check, template)
|
||||
Char *check, *template;
|
||||
{
|
||||
Char *c, *t;
|
||||
|
||||
for (c = check; *c++;)
|
||||
continue;
|
||||
for (t = template; *t++;)
|
||||
continue;
|
||||
for (;;) {
|
||||
if (t == template)
|
||||
return 1;
|
||||
if (c == check || *--t != *--c)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tenex(inputline, inputline_size)
|
||||
Char *inputline;
|
||||
int inputline_size;
|
||||
{
|
||||
int numitems, num_read;
|
||||
char tinputline[BUFSIZ];
|
||||
|
||||
|
||||
setup_tty(ON);
|
||||
|
||||
while ((num_read = read(SHIN, tinputline, BUFSIZ)) > 0) {
|
||||
int i;
|
||||
static Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<',
|
||||
'>', '(', ')', '|', '^', '%', '\0'};
|
||||
Char *str_end, *word_start, last_Char, should_retype;
|
||||
int space_left;
|
||||
COMMAND command;
|
||||
|
||||
for (i = 0; i < num_read; i++)
|
||||
inputline[i] = (unsigned char) tinputline[i];
|
||||
last_Char = inputline[num_read - 1] & ASCII;
|
||||
|
||||
if (last_Char == '\n' || num_read == inputline_size)
|
||||
break;
|
||||
command = (last_Char == ESC) ? RECOGNIZE : LIST;
|
||||
if (command == LIST)
|
||||
(void) fputc('\n', cshout);
|
||||
str_end = &inputline[num_read];
|
||||
if (last_Char == ESC)
|
||||
--str_end; /* wipeout trailing cmd Char */
|
||||
*str_end = '\0';
|
||||
/*
|
||||
* Find LAST occurence of a delimiter in the inputline. The word start
|
||||
* is one Character past it.
|
||||
*/
|
||||
for (word_start = str_end; word_start > inputline; --word_start)
|
||||
if (Strchr(delims, word_start[-1]))
|
||||
break;
|
||||
space_left = inputline_size - (word_start - inputline) - 1;
|
||||
numitems = tsearch(word_start, command, space_left);
|
||||
|
||||
if (command == RECOGNIZE) {
|
||||
/* print from str_end on */
|
||||
print_recognized_stuff(str_end);
|
||||
if (numitems != 1) /* Beep = No match/ambiguous */
|
||||
beep();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tabs in the input line cause trouble after a pushback. tty driver
|
||||
* won't backspace over them because column positions are now
|
||||
* incorrect. This is solved by retyping over current line.
|
||||
*/
|
||||
should_retype = FALSE;
|
||||
if (Strchr(inputline, '\t')) { /* tab Char in input line? */
|
||||
back_to_col_1();
|
||||
should_retype = TRUE;
|
||||
}
|
||||
if (command == LIST) /* Always retype after a LIST */
|
||||
should_retype = TRUE;
|
||||
if (should_retype)
|
||||
printprompt();
|
||||
pushback(inputline);
|
||||
if (should_retype)
|
||||
retype();
|
||||
}
|
||||
setup_tty(OFF);
|
||||
return (num_read);
|
||||
}
|
||||
|
||||
static int
|
||||
ignored(entry)
|
||||
Char *entry;
|
||||
{
|
||||
struct varent *vp;
|
||||
Char **cp;
|
||||
|
||||
if ((vp = adrof(STRfignore)) == NULL || (cp = vp->vec) == NULL)
|
||||
return (FALSE);
|
||||
for (; *cp != NULL; cp++)
|
||||
if (is_suffix(entry, *cp))
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
#endif /* FILEC */
|
||||
-1520
File diff suppressed because it is too large.
Load diff
-961
@@ -1,961 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)glob.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <glob.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int noglob;
|
||||
static int pargsiz, gargsiz;
|
||||
|
||||
/*
|
||||
* Values for gflag
|
||||
*/
|
||||
#define G_NONE 0 /* No globbing needed */
|
||||
#define G_GLOB 1 /* string contains *?[] characters */
|
||||
#define G_CSH 2 /* string contains ~`{ characters */
|
||||
|
||||
#define GLOBSPACE 100 /* Alloc increment */
|
||||
|
||||
#define LBRC '{'
|
||||
#define RBRC '}'
|
||||
#define LBRK '['
|
||||
#define RBRK ']'
|
||||
#define EOS '\0'
|
||||
|
||||
Char **gargv = NULL;
|
||||
long gargc = 0;
|
||||
Char **pargv = NULL;
|
||||
long pargc = 0;
|
||||
|
||||
/*
|
||||
* globbing is now done in two stages. In the first pass we expand
|
||||
* csh globbing idioms ~`{ and then we proceed doing the normal
|
||||
* globbing if needed ?*[
|
||||
*
|
||||
* Csh type globbing is handled in globexpand() and the rest is
|
||||
* handled in glob() which is part of the 4.4BSD libc.
|
||||
*
|
||||
*/
|
||||
static Char *globtilde __P((Char **, Char *));
|
||||
static Char **libglob __P((Char **));
|
||||
static Char **globexpand __P((Char **));
|
||||
static int globbrace __P((Char *, Char *, Char ***));
|
||||
static void expbrace __P((Char ***, Char ***, int));
|
||||
static int pmatch __P((Char *, Char *));
|
||||
static void pword __P((void));
|
||||
static void psave __P((int));
|
||||
static void backeval __P((Char *, bool));
|
||||
static int collate_range_cmp __P((int, int));
|
||||
|
||||
static int collate_range_cmp (c1, c2)
|
||||
int c1, c2;
|
||||
{
|
||||
static char s1[2], s2[2];
|
||||
int ret;
|
||||
|
||||
c1 &= UCHAR_MAX;
|
||||
c2 &= UCHAR_MAX;
|
||||
if (c1 == c2)
|
||||
return (0);
|
||||
s1[0] = c1;
|
||||
s2[0] = c2;
|
||||
if ((ret = strcoll(s1, s2)) != 0)
|
||||
return (ret);
|
||||
return (c1 - c2);
|
||||
}
|
||||
|
||||
static Char *
|
||||
globtilde(nv, s)
|
||||
Char **nv, *s;
|
||||
{
|
||||
Char gbuf[MAXPATHLEN], *gstart, *b, *u, *e;
|
||||
|
||||
gstart = gbuf;
|
||||
*gstart++ = *s++;
|
||||
u = s;
|
||||
for (b = gstart, e = &gbuf[MAXPATHLEN - 1];
|
||||
*s && *s != '/' && *s != ':' && b < e;
|
||||
*b++ = *s++)
|
||||
continue;
|
||||
*b = EOS;
|
||||
if (gethdir(gstart)) {
|
||||
blkfree(nv);
|
||||
if (*gstart)
|
||||
stderror(ERR_UNKUSER, vis_str(gstart));
|
||||
else
|
||||
stderror(ERR_NOHOME);
|
||||
}
|
||||
b = &gstart[Strlen(gstart)];
|
||||
while (*s)
|
||||
*b++ = *s++;
|
||||
*b = EOS;
|
||||
--u;
|
||||
xfree((ptr_t) u);
|
||||
return (Strsave(gstart));
|
||||
}
|
||||
|
||||
static int
|
||||
globbrace(s, p, bl)
|
||||
Char *s, *p, ***bl;
|
||||
{
|
||||
int i, len;
|
||||
Char *pm, *pe, *lm, *pl;
|
||||
Char **nv, **vl;
|
||||
Char gbuf[MAXPATHLEN];
|
||||
int size = GLOBSPACE;
|
||||
|
||||
nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size);
|
||||
*vl = NULL;
|
||||
|
||||
len = 0;
|
||||
/* copy part up to the brace */
|
||||
for (lm = gbuf, p = s; *p != LBRC; *lm++ = *p++)
|
||||
continue;
|
||||
|
||||
/* check for balanced braces */
|
||||
for (i = 0, pe = ++p; *pe; pe++)
|
||||
if (*pe == LBRK) {
|
||||
/* Ignore everything between [] */
|
||||
for (++pe; *pe != RBRK && *pe != EOS; pe++)
|
||||
continue;
|
||||
if (*pe == EOS) {
|
||||
blkfree(nv);
|
||||
return (-RBRK);
|
||||
}
|
||||
}
|
||||
else if (*pe == LBRC)
|
||||
i++;
|
||||
else if (*pe == RBRC) {
|
||||
if (i == 0)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
|
||||
if (i != 0 || *pe == '\0') {
|
||||
blkfree(nv);
|
||||
return (-RBRC);
|
||||
}
|
||||
|
||||
for (i = 0, pl = pm = p; pm <= pe; pm++)
|
||||
switch (*pm) {
|
||||
case LBRK:
|
||||
for (++pm; *pm != RBRK && *pm != EOS; pm++)
|
||||
continue;
|
||||
if (*pm == EOS) {
|
||||
*vl = NULL;
|
||||
blkfree(nv);
|
||||
return (-RBRK);
|
||||
}
|
||||
break;
|
||||
case LBRC:
|
||||
i++;
|
||||
break;
|
||||
case RBRC:
|
||||
if (i) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ',':
|
||||
if (i && *pm == ',')
|
||||
break;
|
||||
else {
|
||||
Char savec = *pm;
|
||||
|
||||
*pm = EOS;
|
||||
(void) Strcpy(lm, pl);
|
||||
(void) Strcat(gbuf, pe + 1);
|
||||
*pm = savec;
|
||||
*vl++ = Strsave(gbuf);
|
||||
len++;
|
||||
pl = pm + 1;
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **) xrealloc((ptr_t) nv, (size_t)
|
||||
size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*vl = NULL;
|
||||
*bl = nv;
|
||||
return (len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
expbrace(nvp, elp, size)
|
||||
Char ***nvp, ***elp;
|
||||
int size;
|
||||
{
|
||||
Char **vl, **el, **nv, *s;
|
||||
|
||||
vl = nv = *nvp;
|
||||
if (elp != NULL)
|
||||
el = *elp;
|
||||
else
|
||||
for (el = vl; *el; el++)
|
||||
continue;
|
||||
|
||||
for (s = *vl; s; s = *++vl) {
|
||||
Char *b;
|
||||
Char **vp, **bp;
|
||||
|
||||
/* leave {} untouched for find */
|
||||
if (s[0] == '{' && (s[1] == '\0' || (s[1] == '}' && s[2] == '\0')))
|
||||
continue;
|
||||
if ((b = Strchr(s, '{')) != NULL) {
|
||||
Char **bl;
|
||||
int len;
|
||||
|
||||
if ((len = globbrace(s, b, &bl)) < 0) {
|
||||
xfree((ptr_t) nv);
|
||||
stderror(ERR_MISSING, -len);
|
||||
}
|
||||
xfree((ptr_t) s);
|
||||
if (len == 1) {
|
||||
*vl-- = *bl;
|
||||
xfree((ptr_t) bl);
|
||||
continue;
|
||||
}
|
||||
len = blklen(bl);
|
||||
if (&el[len] >= &nv[size]) {
|
||||
int l, e;
|
||||
|
||||
l = &el[len] - &nv[size];
|
||||
size += GLOBSPACE > l ? GLOBSPACE : l;
|
||||
l = vl - nv;
|
||||
e = el - nv;
|
||||
nv = (Char **) xrealloc((ptr_t) nv, (size_t)
|
||||
size * sizeof(Char *));
|
||||
vl = nv + l;
|
||||
el = nv + e;
|
||||
}
|
||||
vp = vl--;
|
||||
*vp = *bl;
|
||||
len--;
|
||||
for (bp = el; bp != vp; bp--)
|
||||
bp[len] = *bp;
|
||||
el += len;
|
||||
vp++;
|
||||
for (bp = bl + 1; *bp; *vp++ = *bp++)
|
||||
continue;
|
||||
xfree((ptr_t) bl);
|
||||
}
|
||||
|
||||
}
|
||||
if (elp != NULL)
|
||||
*elp = el;
|
||||
*nvp = nv;
|
||||
}
|
||||
|
||||
static Char **
|
||||
globexpand(v)
|
||||
Char **v;
|
||||
{
|
||||
Char *s;
|
||||
Char **nv, **vl, **el;
|
||||
int size = GLOBSPACE;
|
||||
|
||||
|
||||
nv = vl = (Char **) xmalloc((size_t) sizeof(Char *) * size);
|
||||
*vl = NULL;
|
||||
|
||||
/*
|
||||
* Step 1: expand backquotes.
|
||||
*/
|
||||
while ((s = *v++) != NULL) {
|
||||
if (Strchr(s, '`')) {
|
||||
int i;
|
||||
|
||||
(void) dobackp(s, 0);
|
||||
for (i = 0; i < pargc; i++) {
|
||||
*vl++ = pargv[i];
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **) xrealloc((ptr_t) nv,
|
||||
(size_t) size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
xfree((ptr_t) pargv);
|
||||
pargv = NULL;
|
||||
}
|
||||
else {
|
||||
*vl++ = Strsave(s);
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **) xrealloc((ptr_t) nv, (size_t)
|
||||
size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
}
|
||||
*vl = NULL;
|
||||
|
||||
if (noglob)
|
||||
return (nv);
|
||||
|
||||
/*
|
||||
* Step 2: expand braces
|
||||
*/
|
||||
el = vl;
|
||||
expbrace(&nv, &el, size);
|
||||
|
||||
/*
|
||||
* Step 3: expand ~
|
||||
*/
|
||||
vl = nv;
|
||||
for (s = *vl; s; s = *++vl)
|
||||
if (*s == '~')
|
||||
*vl = globtilde(nv, s);
|
||||
vl = nv;
|
||||
return (vl);
|
||||
}
|
||||
|
||||
static Char *
|
||||
handleone(str, vl, action)
|
||||
Char *str, **vl;
|
||||
int action;
|
||||
{
|
||||
|
||||
Char *cp, **vlp = vl;
|
||||
|
||||
switch (action) {
|
||||
case G_ERROR:
|
||||
setname(vis_str(str));
|
||||
blkfree(vl);
|
||||
stderror(ERR_NAME | ERR_AMBIG);
|
||||
break;
|
||||
case G_APPEND:
|
||||
trim(vlp);
|
||||
str = Strsave(*vlp++);
|
||||
do {
|
||||
cp = Strspl(str, STRspace);
|
||||
xfree((ptr_t) str);
|
||||
str = Strspl(cp, *vlp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
while (*++vlp);
|
||||
blkfree(vl);
|
||||
break;
|
||||
case G_IGNORE:
|
||||
str = Strsave(strip(*vlp));
|
||||
blkfree(vl);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
static Char **
|
||||
libglob(vl)
|
||||
Char **vl;
|
||||
{
|
||||
int gflgs = GLOB_QUOTE | GLOB_NOMAGIC;
|
||||
glob_t globv;
|
||||
char *ptr;
|
||||
int nonomatch = adrof(STRnonomatch) != 0, magic = 0, match = 0;
|
||||
|
||||
if (!vl || !vl[0])
|
||||
return (vl);
|
||||
|
||||
globv.gl_offs = 0;
|
||||
globv.gl_pathv = 0;
|
||||
globv.gl_pathc = 0;
|
||||
|
||||
if (nonomatch)
|
||||
gflgs |= GLOB_NOCHECK;
|
||||
|
||||
do {
|
||||
ptr = short2qstr(*vl);
|
||||
switch (glob(ptr, gflgs, 0, &globv)) {
|
||||
case GLOB_ABEND:
|
||||
setname(vis_str(*vl));
|
||||
stderror(ERR_NAME | ERR_GLOB);
|
||||
/* NOTREACHED */
|
||||
case GLOB_NOSPACE:
|
||||
stderror(ERR_NOMEM);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (globv.gl_flags & GLOB_MAGCHAR) {
|
||||
match |= (globv.gl_matchc != 0);
|
||||
magic = 1;
|
||||
}
|
||||
gflgs |= GLOB_APPEND;
|
||||
}
|
||||
while (*++vl);
|
||||
vl = (globv.gl_pathc == 0 || (magic && !match && !nonomatch)) ?
|
||||
NULL : blk2short(globv.gl_pathv);
|
||||
globfree(&globv);
|
||||
return (vl);
|
||||
}
|
||||
|
||||
Char *
|
||||
globone(str, action)
|
||||
Char *str;
|
||||
int action;
|
||||
{
|
||||
Char *v[2], **vl, **vo;
|
||||
int gflg;
|
||||
|
||||
noglob = adrof(STRnoglob) != 0;
|
||||
gflag = 0;
|
||||
v[0] = str;
|
||||
v[1] = 0;
|
||||
tglob(v);
|
||||
gflg = gflag;
|
||||
if (gflg == G_NONE)
|
||||
return (strip(Strsave(str)));
|
||||
|
||||
if (gflg & G_CSH) {
|
||||
/*
|
||||
* Expand back-quote, tilde and brace
|
||||
*/
|
||||
vo = globexpand(v);
|
||||
if (noglob || (gflg & G_GLOB) == 0) {
|
||||
if (vo[0] == NULL) {
|
||||
xfree((ptr_t) vo);
|
||||
return (Strsave(STRNULL));
|
||||
}
|
||||
if (vo[1] != NULL)
|
||||
return (handleone(str, vo, action));
|
||||
else {
|
||||
str = strip(vo[0]);
|
||||
xfree((ptr_t) vo);
|
||||
return (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (noglob || (gflg & G_GLOB) == 0)
|
||||
return (strip(Strsave(str)));
|
||||
else
|
||||
vo = v;
|
||||
|
||||
vl = libglob(vo);
|
||||
if ((gflg & G_CSH) && vl != vo)
|
||||
blkfree(vo);
|
||||
if (vl == NULL) {
|
||||
setname(vis_str(str));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
if (vl[0] == NULL) {
|
||||
xfree((ptr_t) vl);
|
||||
return (Strsave(STRNULL));
|
||||
}
|
||||
if (vl[1] != NULL)
|
||||
return (handleone(str, vl, action));
|
||||
else {
|
||||
str = strip(*vl);
|
||||
xfree((ptr_t) vl);
|
||||
return (str);
|
||||
}
|
||||
}
|
||||
|
||||
Char **
|
||||
globall(v)
|
||||
Char **v;
|
||||
{
|
||||
Char **vl, **vo;
|
||||
int gflg = gflag;
|
||||
|
||||
if (!v || !v[0]) {
|
||||
gargv = saveblk(v);
|
||||
gargc = blklen(gargv);
|
||||
return (gargv);
|
||||
}
|
||||
|
||||
noglob = adrof(STRnoglob) != 0;
|
||||
|
||||
if (gflg & G_CSH)
|
||||
/*
|
||||
* Expand back-quote, tilde and brace
|
||||
*/
|
||||
vl = vo = globexpand(v);
|
||||
else
|
||||
vl = vo = saveblk(v);
|
||||
|
||||
if (!noglob && (gflg & G_GLOB)) {
|
||||
vl = libglob(vo);
|
||||
if ((gflg & G_CSH) && vl != vo)
|
||||
blkfree(vo);
|
||||
}
|
||||
else
|
||||
trim(vl);
|
||||
|
||||
gargc = vl ? blklen(vl) : 0;
|
||||
return (gargv = vl);
|
||||
}
|
||||
|
||||
void
|
||||
ginit()
|
||||
{
|
||||
gargsiz = GLOBSPACE;
|
||||
gargv = (Char **) xmalloc((size_t) sizeof(Char *) * gargsiz);
|
||||
gargv[0] = 0;
|
||||
gargc = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rscan(t, f)
|
||||
Char **t;
|
||||
void (*f) __P((int));
|
||||
{
|
||||
Char *p;
|
||||
|
||||
while ((p = *t++) != NULL)
|
||||
while (*p)
|
||||
(*f) (*p++);
|
||||
}
|
||||
|
||||
void
|
||||
trim(t)
|
||||
Char **t;
|
||||
{
|
||||
Char *p;
|
||||
|
||||
while ((p = *t++) != NULL)
|
||||
while (*p)
|
||||
*p++ &= TRIM;
|
||||
}
|
||||
|
||||
void
|
||||
tglob(t)
|
||||
Char **t;
|
||||
{
|
||||
Char *p, c;
|
||||
|
||||
while ((p = *t++) != NULL) {
|
||||
if (*p == '~' || *p == '=')
|
||||
gflag |= G_CSH;
|
||||
else if (*p == '{' &&
|
||||
(p[1] == '\0' || (p[1] == '}' && p[2] == '\0')))
|
||||
continue;
|
||||
while ((c = *p++) != '\0') {
|
||||
/*
|
||||
* eat everything inside the matching backquotes
|
||||
*/
|
||||
if (c == '`') {
|
||||
gflag |= G_CSH;
|
||||
while (*p && *p != '`')
|
||||
if (*p++ == '\\') {
|
||||
if (*p) /* Quoted chars */
|
||||
p++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (*p) /* The matching ` */
|
||||
p++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else if (c == '{')
|
||||
gflag |= G_CSH;
|
||||
else if (isglob(c))
|
||||
gflag |= G_GLOB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Command substitute cp. If literal, then this is a substitution from a
|
||||
* << redirection, and so we should not crunch blanks and tabs, separating
|
||||
* words only at newlines.
|
||||
*/
|
||||
Char **
|
||||
dobackp(cp, literal)
|
||||
Char *cp;
|
||||
bool literal;
|
||||
{
|
||||
Char *lp, *rp;
|
||||
Char *ep, word[MAXPATHLEN];
|
||||
|
||||
if (pargv) {
|
||||
#ifdef notdef
|
||||
abort();
|
||||
#endif
|
||||
blkfree(pargv);
|
||||
}
|
||||
pargsiz = GLOBSPACE;
|
||||
pargv = (Char **) xmalloc((size_t) sizeof(Char *) * pargsiz);
|
||||
pargv[0] = NULL;
|
||||
pargcp = pargs = word;
|
||||
pargc = 0;
|
||||
pnleft = MAXPATHLEN - 4;
|
||||
for (;;) {
|
||||
for (lp = cp; *lp != '`'; lp++) {
|
||||
if (*lp == 0) {
|
||||
if (pargcp != pargs)
|
||||
pword();
|
||||
return (pargv);
|
||||
}
|
||||
psave(*lp);
|
||||
}
|
||||
lp++;
|
||||
for (rp = lp; *rp && *rp != '`'; rp++)
|
||||
if (*rp == '\\') {
|
||||
rp++;
|
||||
if (!*rp)
|
||||
goto oops;
|
||||
}
|
||||
if (!*rp)
|
||||
oops: stderror(ERR_UNMATCHED, '`');
|
||||
ep = Strsave(lp);
|
||||
ep[rp - lp] = 0;
|
||||
backeval(ep, literal);
|
||||
cp = rp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
backeval(cp, literal)
|
||||
Char *cp;
|
||||
bool literal;
|
||||
{
|
||||
int icnt, c;
|
||||
Char *ip;
|
||||
struct command faket;
|
||||
bool hadnl;
|
||||
int pvec[2], quoted;
|
||||
Char *fakecom[2], ibuf[BUFSIZ];
|
||||
char tibuf[BUFSIZ];
|
||||
|
||||
hadnl = 0;
|
||||
icnt = 0;
|
||||
quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
|
||||
faket.t_dtyp = NODE_COMMAND;
|
||||
faket.t_dflg = 0;
|
||||
faket.t_dlef = 0;
|
||||
faket.t_drit = 0;
|
||||
faket.t_dspr = 0;
|
||||
faket.t_dcom = fakecom;
|
||||
fakecom[0] = STRfakecom1;
|
||||
fakecom[1] = 0;
|
||||
|
||||
/*
|
||||
* We do the psave job to temporarily change the current job so that the
|
||||
* following fork is considered a separate job. This is so that when
|
||||
* backquotes are used in a builtin function that calls glob the "current
|
||||
* job" is not corrupted. We only need one level of pushed jobs as long as
|
||||
* we are sure to fork here.
|
||||
*/
|
||||
psavejob();
|
||||
|
||||
/*
|
||||
* It would be nicer if we could integrate this redirection more with the
|
||||
* routines in sh.sem.c by doing a fake execute on a builtin function that
|
||||
* was piped out.
|
||||
*/
|
||||
mypipe(pvec);
|
||||
if (pfork(&faket, -1) == 0) {
|
||||
struct wordent paraml;
|
||||
struct command *t;
|
||||
|
||||
(void) close(pvec[0]);
|
||||
(void) dmove(pvec[1], 1);
|
||||
(void) dmove(SHERR, 2);
|
||||
initdesc();
|
||||
/*
|
||||
* Bugfix for nested backquotes by Michael Greim <[email protected]>,
|
||||
* posted to comp.bugs.4bsd 12 Sep. 1989.
|
||||
*/
|
||||
if (pargv) /* mg, 21.dec.88 */
|
||||
blkfree(pargv), pargv = 0, pargsiz = 0;
|
||||
/* mg, 21.dec.88 */
|
||||
arginp = cp;
|
||||
while (*cp)
|
||||
*cp++ &= TRIM;
|
||||
|
||||
/*
|
||||
* In the child ``forget'' everything about current aliases or
|
||||
* eval vectors.
|
||||
*/
|
||||
alvec = NULL;
|
||||
evalvec = NULL;
|
||||
alvecp = NULL;
|
||||
evalp = NULL;
|
||||
(void) lex(¶ml);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
alias(¶ml);
|
||||
t = syntax(paraml.next, ¶ml, 0);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
if (t)
|
||||
t->t_dflg |= F_NOFORK;
|
||||
(void) signal(SIGTSTP, SIG_IGN);
|
||||
(void) signal(SIGTTIN, SIG_IGN);
|
||||
(void) signal(SIGTTOU, SIG_IGN);
|
||||
execute(t, -1, NULL, NULL);
|
||||
exitstat();
|
||||
}
|
||||
xfree((ptr_t) cp);
|
||||
(void) close(pvec[1]);
|
||||
c = 0;
|
||||
ip = NULL;
|
||||
do {
|
||||
int cnt = 0;
|
||||
|
||||
for (;;) {
|
||||
if (icnt == 0) {
|
||||
int i;
|
||||
|
||||
ip = ibuf;
|
||||
do
|
||||
icnt = read(pvec[0], tibuf, BUFSIZ);
|
||||
while (icnt == -1 && errno == EINTR);
|
||||
if (icnt <= 0) {
|
||||
c = -1;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < icnt; i++)
|
||||
ip[i] = (unsigned char) tibuf[i];
|
||||
}
|
||||
if (hadnl)
|
||||
break;
|
||||
--icnt;
|
||||
c = (*ip++ & TRIM);
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c == '\n') {
|
||||
/*
|
||||
* Continue around the loop one more time, so that we can eat
|
||||
* the last newline without terminating this word.
|
||||
*/
|
||||
hadnl = 1;
|
||||
continue;
|
||||
}
|
||||
if (!quoted && (c == ' ' || c == '\t'))
|
||||
break;
|
||||
cnt++;
|
||||
psave(c | quoted);
|
||||
}
|
||||
/*
|
||||
* Unless at end-of-file, we will form a new word here if there were
|
||||
* characters in the word, or in any case when we take text literally.
|
||||
* If we didn't make empty words here when literal was set then we
|
||||
* would lose blank lines.
|
||||
*/
|
||||
if (c != -1 && (cnt || literal))
|
||||
pword();
|
||||
hadnl = 0;
|
||||
} while (c >= 0);
|
||||
(void) close(pvec[0]);
|
||||
pwait();
|
||||
prestjob();
|
||||
}
|
||||
|
||||
static void
|
||||
psave(c)
|
||||
int c;
|
||||
{
|
||||
if (--pnleft <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
*pargcp++ = c;
|
||||
}
|
||||
|
||||
static void
|
||||
pword()
|
||||
{
|
||||
psave(0);
|
||||
if (pargc == pargsiz - 1) {
|
||||
pargsiz += GLOBSPACE;
|
||||
pargv = (Char **) xrealloc((ptr_t) pargv,
|
||||
(size_t) pargsiz * sizeof(Char *));
|
||||
}
|
||||
pargv[pargc++] = Strsave(pargs);
|
||||
pargv[pargc] = NULL;
|
||||
pargcp = pargs;
|
||||
pnleft = MAXPATHLEN - 4;
|
||||
}
|
||||
|
||||
int
|
||||
Gmatch(string, pattern)
|
||||
Char *string, *pattern;
|
||||
{
|
||||
Char **blk, **p;
|
||||
int gpol = 1, gres = 0;
|
||||
|
||||
if (*pattern == '^') {
|
||||
gpol = 0;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
blk = (Char **) xmalloc(GLOBSPACE * sizeof(Char *));
|
||||
blk[0] = Strsave(pattern);
|
||||
blk[1] = NULL;
|
||||
|
||||
expbrace(&blk, NULL, GLOBSPACE);
|
||||
|
||||
for (p = blk; *p; p++)
|
||||
gres |= pmatch(string, *p);
|
||||
|
||||
blkfree(blk);
|
||||
return(gres == gpol);
|
||||
}
|
||||
|
||||
static int
|
||||
pmatch(string, pattern)
|
||||
Char *string, *pattern;
|
||||
{
|
||||
Char stringc, patternc;
|
||||
int match, negate_range;
|
||||
Char rangec;
|
||||
|
||||
for (;; ++string) {
|
||||
stringc = *string & TRIM;
|
||||
patternc = *pattern++;
|
||||
switch (patternc) {
|
||||
case 0:
|
||||
return (stringc == 0);
|
||||
case '?':
|
||||
if (stringc == 0)
|
||||
return (0);
|
||||
break;
|
||||
case '*':
|
||||
if (!*pattern)
|
||||
return (1);
|
||||
while (*string)
|
||||
if (Gmatch(string++, pattern))
|
||||
return (1);
|
||||
return (0);
|
||||
case '[':
|
||||
match = 0;
|
||||
if ((negate_range = (*pattern == '^')) != 0)
|
||||
pattern++;
|
||||
while ((rangec = *pattern++) != '\0') {
|
||||
if (rangec == ']')
|
||||
break;
|
||||
if (match)
|
||||
continue;
|
||||
if (rangec == '-' && *(pattern-2) != '[' && *pattern != ']') {
|
||||
match = ( collate_range_cmp(stringc, *pattern & TRIM) <= 0
|
||||
&& collate_range_cmp(*(pattern-2) & TRIM, stringc) <= 0
|
||||
);
|
||||
pattern++;
|
||||
}
|
||||
else
|
||||
match = (stringc == (rangec & TRIM));
|
||||
}
|
||||
if (rangec == 0)
|
||||
stderror(ERR_NAME | ERR_MISSING, ']');
|
||||
if (match == negate_range)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
if ((patternc & TRIM) != stringc)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Gcat(s1, s2)
|
||||
Char *s1, *s2;
|
||||
{
|
||||
Char *p, *q;
|
||||
int n;
|
||||
|
||||
for (p = s1; *p++;)
|
||||
continue;
|
||||
for (q = s2; *q++;)
|
||||
continue;
|
||||
n = (p - s1) + (q - s2) - 1;
|
||||
if (++gargc >= gargsiz) {
|
||||
gargsiz += GLOBSPACE;
|
||||
gargv = (Char **) xrealloc((ptr_t) gargv,
|
||||
(size_t) gargsiz * sizeof(Char *));
|
||||
}
|
||||
gargv[gargc] = 0;
|
||||
p = gargv[gargc - 1] = (Char *) xmalloc((size_t) n * sizeof(Char));
|
||||
for (q = s1; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
for (p--, q = s2; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef FILEC
|
||||
int
|
||||
sortscmp(a, b)
|
||||
const ptr_t a, b;
|
||||
{
|
||||
#if defined(NLS) && !defined(NOSTRCOLL)
|
||||
char buf[2048];
|
||||
#endif
|
||||
|
||||
if (!a) /* check for NULL */
|
||||
return (b ? 1 : 0);
|
||||
if (!b)
|
||||
return (-1);
|
||||
|
||||
if (!*(Char **)a) /* check for NULL */
|
||||
return (*(Char **)b ? 1 : 0);
|
||||
if (!*(Char **)b)
|
||||
return (-1);
|
||||
|
||||
#if defined(NLS) && !defined(NOSTRCOLL)
|
||||
(void) strcpy(buf, short2str(*(Char **)a));
|
||||
return ((int) strcoll(buf, short2str(*(Char **)b)));
|
||||
#else
|
||||
return ((int) Strcmp(*(Char **)a, *(Char **)b));
|
||||
#endif
|
||||
}
|
||||
#endif /* FILEC */
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void hfree __P((struct Hist *));
|
||||
static void dohist1 __P((struct Hist *, int *, int, int));
|
||||
static void phist __P((struct Hist *, int));
|
||||
|
||||
void
|
||||
savehist(sp)
|
||||
struct wordent *sp;
|
||||
{
|
||||
struct Hist *hp, *np;
|
||||
int histlen = 0;
|
||||
Char *cp;
|
||||
|
||||
/* throw away null lines */
|
||||
if (sp->next->word[0] == '\n')
|
||||
return;
|
||||
cp = value(STRhistory);
|
||||
if (*cp) {
|
||||
Char *p = cp;
|
||||
|
||||
while (*p) {
|
||||
if (!Isdigit(*p)) {
|
||||
histlen = 0;
|
||||
break;
|
||||
}
|
||||
histlen = histlen * 10 + *p++ - '0';
|
||||
}
|
||||
}
|
||||
for (hp = &Histlist; (np = hp->Hnext) != NULL;)
|
||||
if (eventno - np->Href >= histlen || histlen == 0)
|
||||
hp->Hnext = np->Hnext, hfree(np);
|
||||
else
|
||||
hp = np;
|
||||
(void) enthist(++eventno, sp, 1);
|
||||
}
|
||||
|
||||
struct Hist *
|
||||
enthist(event, lp, docopy)
|
||||
int event;
|
||||
struct wordent *lp;
|
||||
bool docopy;
|
||||
{
|
||||
struct Hist *np;
|
||||
|
||||
np = (struct Hist *) xmalloc((size_t) sizeof(*np));
|
||||
np->Hnum = np->Href = event;
|
||||
if (docopy) {
|
||||
copylex(&np->Hlex, lp);
|
||||
}
|
||||
else {
|
||||
np->Hlex.next = lp->next;
|
||||
lp->next->prev = &np->Hlex;
|
||||
np->Hlex.prev = lp->prev;
|
||||
lp->prev->next = &np->Hlex;
|
||||
}
|
||||
np->Hnext = Histlist.Hnext;
|
||||
Histlist.Hnext = np;
|
||||
return (np);
|
||||
}
|
||||
|
||||
static void
|
||||
hfree(hp)
|
||||
struct Hist *hp;
|
||||
{
|
||||
|
||||
freelex(&hp->Hlex);
|
||||
xfree((ptr_t) hp);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dohist(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
int n, rflg = 0, hflg = 0;
|
||||
|
||||
if (getn(value(STRhistory)) == 0)
|
||||
return;
|
||||
if (setintr)
|
||||
(void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
|
||||
while (*++v && **v == '-') {
|
||||
Char *vp = *v;
|
||||
|
||||
while (*++vp)
|
||||
switch (*vp) {
|
||||
case 'h':
|
||||
hflg++;
|
||||
break;
|
||||
case 'r':
|
||||
rflg++;
|
||||
break;
|
||||
case '-': /* ignore multiple '-'s */
|
||||
break;
|
||||
default:
|
||||
stderror(ERR_HISTUS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*v)
|
||||
n = getn(*v);
|
||||
else {
|
||||
n = getn(value(STRhistory));
|
||||
}
|
||||
dohist1(Histlist.Hnext, &n, rflg, hflg);
|
||||
}
|
||||
|
||||
static void
|
||||
dohist1(hp, np, rflg, hflg)
|
||||
struct Hist *hp;
|
||||
int *np, rflg, hflg;
|
||||
{
|
||||
bool print = (*np) > 0;
|
||||
|
||||
for (; hp != 0; hp = hp->Hnext) {
|
||||
(*np)--;
|
||||
hp->Href++;
|
||||
if (rflg == 0) {
|
||||
dohist1(hp->Hnext, np, rflg, hflg);
|
||||
if (print)
|
||||
phist(hp, hflg);
|
||||
return;
|
||||
}
|
||||
if (*np >= 0)
|
||||
phist(hp, hflg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
phist(hp, hflg)
|
||||
struct Hist *hp;
|
||||
int hflg;
|
||||
{
|
||||
if (hflg == 0)
|
||||
(void) fprintf(cshout, "%6d\t", hp->Hnum);
|
||||
prlex(cshout, &hp->Hlex);
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define INF 1000
|
||||
|
||||
struct biltins bfunc[] =
|
||||
{
|
||||
{ "@", dolet, 0, INF },
|
||||
{ "alias", doalias, 0, INF },
|
||||
{ "alloc", showall, 0, 1 },
|
||||
{ "bg", dobg, 0, INF },
|
||||
{ "break", dobreak, 0, 0 },
|
||||
{ "breaksw", doswbrk, 0, 0 },
|
||||
{ "case", dozip, 0, 1 },
|
||||
{ "cd", dochngd, 0, INF },
|
||||
{ "chdir", dochngd, 0, INF },
|
||||
{ "continue", docontin, 0, 0 },
|
||||
{ "default", dozip, 0, 0 },
|
||||
{ "dirs", dodirs, 0, INF },
|
||||
{ "echo", doecho, 0, INF },
|
||||
{ "else", doelse, 0, INF },
|
||||
{ "end", doend, 0, 0 },
|
||||
{ "endif", dozip, 0, 0 },
|
||||
{ "endsw", dozip, 0, 0 },
|
||||
{ "eval", doeval, 0, INF },
|
||||
{ "exec", execash, 1, INF },
|
||||
{ "exit", doexit, 0, INF },
|
||||
{ "fg", dofg, 0, INF },
|
||||
{ "foreach", doforeach, 3, INF },
|
||||
{ "glob", doglob, 0, INF },
|
||||
{ "goto", dogoto, 1, 1 },
|
||||
{ "hashstat", hashstat, 0, 0 },
|
||||
{ "history", dohist, 0, 2 },
|
||||
{ "if", doif, 1, INF },
|
||||
{ "jobs", dojobs, 0, 1 },
|
||||
{ "kill", dokill, 1, INF },
|
||||
{ "limit", dolimit, 0, 3 },
|
||||
{ "linedit", doecho, 0, INF },
|
||||
{ "login", dologin, 0, 1 },
|
||||
{ "logout", dologout, 0, 0 },
|
||||
{ "nice", donice, 0, INF },
|
||||
{ "nohup", donohup, 0, INF },
|
||||
{ "notify", donotify, 0, INF },
|
||||
{ "onintr", doonintr, 0, 2 },
|
||||
{ "popd", dopopd, 0, INF },
|
||||
{ "printf", doprintf, 1, INF },
|
||||
{ "pushd", dopushd, 0, INF },
|
||||
{ "rehash", dohash, 0, 0 },
|
||||
{ "repeat", dorepeat, 2, INF },
|
||||
{ "set", doset, 0, INF },
|
||||
{ "setenv", dosetenv, 0, 2 },
|
||||
{ "shift", shift, 0, 1 },
|
||||
{ "source", dosource, 1, 2 },
|
||||
{ "stop", dostop, 1, INF },
|
||||
{ "suspend", dosuspend, 0, 0 },
|
||||
{ "switch", doswitch, 1, INF },
|
||||
{ "time", dotime, 0, INF },
|
||||
{ "umask", doumask, 0, 1 },
|
||||
{ "unalias", unalias, 1, INF },
|
||||
{ "unhash", dounhash, 0, 0 },
|
||||
{ "unlimit", dounlimit, 0, INF },
|
||||
{ "unset", unset, 1, INF },
|
||||
{ "unsetenv", dounsetenv, 1, INF },
|
||||
{ "wait", dowait, 0, 0 },
|
||||
{ "which", dowhich, 1, INF },
|
||||
{ "while", dowhile, 1, INF }
|
||||
};
|
||||
int nbfunc = sizeof bfunc / sizeof *bfunc;
|
||||
|
||||
struct srch srchn[] =
|
||||
{
|
||||
{ "@", T_LET },
|
||||
{ "break", T_BREAK },
|
||||
{ "breaksw", T_BRKSW },
|
||||
{ "case", T_CASE },
|
||||
{ "default", T_DEFAULT },
|
||||
{ "else", T_ELSE },
|
||||
{ "end", T_END },
|
||||
{ "endif", T_ENDIF },
|
||||
{ "endsw", T_ENDSW },
|
||||
{ "exit", T_EXIT },
|
||||
{ "foreach", T_FOREACH },
|
||||
{ "goto", T_GOTO },
|
||||
{ "if", T_IF },
|
||||
{ "label", T_LABEL },
|
||||
{ "set", T_SET },
|
||||
{ "switch", T_SWITCH },
|
||||
{ "while", T_WHILE }
|
||||
};
|
||||
int nsrchn = sizeof srchn / sizeof *srchn;
|
||||
|
||||
-1643
File diff suppressed because it is too large.
Load diff
-424
@@ -1,424 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int renum __P((int, int));
|
||||
|
||||
int
|
||||
any(s, c)
|
||||
char *s;
|
||||
int c;
|
||||
{
|
||||
if (!s)
|
||||
return (0); /* Check for nil pointer */
|
||||
while (*s)
|
||||
if (*s++ == c)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
setzero(cp, i)
|
||||
char *cp;
|
||||
int i;
|
||||
{
|
||||
if (i != 0)
|
||||
do
|
||||
*cp++ = 0;
|
||||
while (--i);
|
||||
}
|
||||
|
||||
char *
|
||||
strsave(s)
|
||||
char *s;
|
||||
{
|
||||
char *n;
|
||||
char *p;
|
||||
|
||||
if (s == NULL)
|
||||
s = "";
|
||||
for (p = s; *p++;)
|
||||
continue;
|
||||
n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
|
||||
while ((*p++ = *s++) != '\0')
|
||||
continue;
|
||||
return (n);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkend(up)
|
||||
Char **up;
|
||||
{
|
||||
|
||||
while (*up)
|
||||
up++;
|
||||
return (up);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
blkpr(fp, av)
|
||||
FILE *fp;
|
||||
Char **av;
|
||||
{
|
||||
|
||||
for (; *av; av++) {
|
||||
(void) fprintf(fp, "%s", vis_str(*av));
|
||||
if (av[1])
|
||||
(void) fprintf(fp, " ");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
blklen(av)
|
||||
Char **av;
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (*av++)
|
||||
i++;
|
||||
return (i);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkcpy(oav, bv)
|
||||
Char **oav;
|
||||
Char **bv;
|
||||
{
|
||||
Char **av = oav;
|
||||
|
||||
while ((*av++ = *bv++) != NULL)
|
||||
continue;
|
||||
return (oav);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkcat(up, vp)
|
||||
Char **up, **vp;
|
||||
{
|
||||
|
||||
(void) blkcpy(blkend(up), vp);
|
||||
return (up);
|
||||
}
|
||||
|
||||
void
|
||||
blkfree(av0)
|
||||
Char **av0;
|
||||
{
|
||||
Char **av = av0;
|
||||
|
||||
if (!av0)
|
||||
return;
|
||||
for (; *av; av++)
|
||||
xfree((ptr_t) * av);
|
||||
xfree((ptr_t) av0);
|
||||
}
|
||||
|
||||
Char **
|
||||
saveblk(v)
|
||||
Char **v;
|
||||
{
|
||||
Char **newv =
|
||||
(Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
|
||||
Char **onewv = newv;
|
||||
|
||||
while (*v)
|
||||
*newv++ = Strsave(*v++);
|
||||
return (onewv);
|
||||
}
|
||||
|
||||
#ifdef NOTUSED
|
||||
char *
|
||||
strstr(s, t)
|
||||
char *s, *t;
|
||||
{
|
||||
do {
|
||||
char *ss = s;
|
||||
char *tt = t;
|
||||
|
||||
do
|
||||
if (*tt == '\0')
|
||||
return (s);
|
||||
while (*ss++ == *tt++);
|
||||
} while (*s++ != '\0');
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif /* NOTUSED */
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
char *
|
||||
strspl(cp, dp)
|
||||
char *cp, *dp;
|
||||
{
|
||||
char *ep;
|
||||
char *p, *q;
|
||||
|
||||
if (!cp)
|
||||
cp = "";
|
||||
if (!dp)
|
||||
dp = "";
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
for (q = dp; *q++;)
|
||||
continue;
|
||||
ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
|
||||
for (p = ep, q = cp; *p++ = *q++;)
|
||||
continue;
|
||||
for (p--, q = dp; *p++ = *q++;)
|
||||
continue;
|
||||
return (ep);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Char **
|
||||
blkspl(up, vp)
|
||||
Char **up, **vp;
|
||||
{
|
||||
Char **wp =
|
||||
(Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
|
||||
sizeof(Char **));
|
||||
|
||||
(void) blkcpy(wp, up);
|
||||
return (blkcat(wp, vp));
|
||||
}
|
||||
|
||||
Char
|
||||
lastchr(cp)
|
||||
Char *cp;
|
||||
{
|
||||
|
||||
if (!cp)
|
||||
return (0);
|
||||
if (!*cp)
|
||||
return (0);
|
||||
while (cp[1])
|
||||
cp++;
|
||||
return (*cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called after an error to close up
|
||||
* any units which may have been left open accidentally.
|
||||
*/
|
||||
void
|
||||
closem()
|
||||
{
|
||||
int f, flimit;
|
||||
|
||||
for (f = 0, flimit = getdtablesize(); f < flimit; f++)
|
||||
if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
|
||||
f != FSHTTY)
|
||||
(void) close(f);
|
||||
}
|
||||
|
||||
void
|
||||
donefds()
|
||||
{
|
||||
(void) close(0);
|
||||
(void) close(1);
|
||||
(void) close(2);
|
||||
|
||||
didfds = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move descriptor i to j.
|
||||
* If j is -1 then we just want to get i to a safe place,
|
||||
* i.e. to a unit > 2. This also happens in dcopy.
|
||||
*/
|
||||
int
|
||||
dmove(i, j)
|
||||
int i, j;
|
||||
{
|
||||
|
||||
if (i == j || i < 0)
|
||||
return (i);
|
||||
if (j >= 0) {
|
||||
(void) dup2(i, j);
|
||||
if (j != i)
|
||||
(void) close(i);
|
||||
return (j);
|
||||
}
|
||||
j = dcopy(i, j);
|
||||
if (j != i)
|
||||
(void) close(i);
|
||||
return (j);
|
||||
}
|
||||
|
||||
int
|
||||
dcopy(i, j)
|
||||
int i, j;
|
||||
{
|
||||
|
||||
if (i == j || i < 0 || (j < 0 && i > 2))
|
||||
return (i);
|
||||
if (j >= 0) {
|
||||
(void) dup2(i, j);
|
||||
return (j);
|
||||
}
|
||||
(void) close(j);
|
||||
return (renum(i, j));
|
||||
}
|
||||
|
||||
static int
|
||||
renum(i, j)
|
||||
int i, j;
|
||||
{
|
||||
int k = dup(i);
|
||||
|
||||
if (k < 0)
|
||||
return (-1);
|
||||
if (j == -1 && k > 2)
|
||||
return (k);
|
||||
if (k != j) {
|
||||
j = renum(k, j);
|
||||
(void) close(k);
|
||||
return (j);
|
||||
}
|
||||
return (k);
|
||||
}
|
||||
|
||||
/*
|
||||
* Left shift a command argument list, discarding
|
||||
* the first c arguments. Used in "shift" commands
|
||||
* as well as by commands like "repeat".
|
||||
*/
|
||||
void
|
||||
lshift(v, c)
|
||||
Char **v;
|
||||
int c;
|
||||
{
|
||||
Char **u;
|
||||
|
||||
for (u = v; *u && --c >= 0; u++)
|
||||
xfree((ptr_t) *u);
|
||||
(void) blkcpy(v, u);
|
||||
}
|
||||
|
||||
int
|
||||
number(cp)
|
||||
Char *cp;
|
||||
{
|
||||
if (!cp)
|
||||
return(0);
|
||||
if (*cp == '-') {
|
||||
cp++;
|
||||
if (!Isdigit(*cp))
|
||||
return (0);
|
||||
cp++;
|
||||
}
|
||||
while (*cp && Isdigit(*cp))
|
||||
cp++;
|
||||
return (*cp == 0);
|
||||
}
|
||||
|
||||
Char **
|
||||
copyblk(v)
|
||||
Char **v;
|
||||
{
|
||||
Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
|
||||
|
||||
return (blkcpy(nv, v));
|
||||
}
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
char *
|
||||
strend(cp)
|
||||
char *cp;
|
||||
{
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while (*cp)
|
||||
cp++;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
Char *
|
||||
strip(cp)
|
||||
Char *cp;
|
||||
{
|
||||
Char *dp = cp;
|
||||
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while ((*dp++ &= TRIM) != '\0')
|
||||
continue;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
void
|
||||
udvar(name)
|
||||
Char *name;
|
||||
{
|
||||
|
||||
setname(vis_str(name));
|
||||
stderror(ERR_NAME | ERR_UNDVAR);
|
||||
}
|
||||
|
||||
int
|
||||
prefix(sub, str)
|
||||
Char *sub, *str;
|
||||
{
|
||||
|
||||
for (;;) {
|
||||
if (*sub == 0)
|
||||
return (1);
|
||||
if (*str == 0)
|
||||
return (0);
|
||||
if (*sub++ != *str++)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= finnish french ja german italian spanish
|
||||
|
||||
# We are not ready for greek yet
|
||||
#SUBDIR+= greek
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
@@ -0,0 +1,17 @@
|
||||
# $FreeBSD$
|
||||
|
||||
GENCAT= gencat -new
|
||||
BASESRC= ${.CURDIR}/../../../../contrib/tcsh/nls
|
||||
|
||||
.SUFFIXES: .msg .cat
|
||||
|
||||
.msg.cat:
|
||||
${GENCAT} ${.TARGET} ${.IMPSRC}
|
||||
|
||||
CLEANFILES+= tcsh.cat tcsh.msg
|
||||
|
||||
all: tcsh.cat
|
||||
|
||||
tcsh.cat: tcsh.msg
|
||||
|
||||
distribute:
|
||||
@@ -0,0 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= finnish
|
||||
DL= fi_FI.ISO_8859-1
|
||||
LL= fi_FI.DIS_8859-15
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
.for i in ${LL}
|
||||
ln -fs ../${DL}/tcsh.cat ${DESTDIR}${NLSDIR}/$i/tcsh.cat
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,22 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= french
|
||||
DL= fr_FR.ISO_8859-1
|
||||
LL= fr_BE.ISO_8859-1 fr_CA.ISO_8859-1 fr_CH.ISO_8859-1 \
|
||||
fr_BE.DIS_8859-15 fr_CA.DIS_8859-15 fr_CH.DIS_8859-15 \
|
||||
fr_FR.DIS_8859-15
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
.for i in ${LL}
|
||||
ln -fs ../${DL}/tcsh.cat ${DESTDIR}${NLSDIR}/$i/tcsh.cat
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,21 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= german
|
||||
DL= de_DE.ISO_8859-1
|
||||
LL= de_AT.ISO_8859-1 de_CH.ISO_8859-1 de_AT.DIS_8859-15 \
|
||||
de_CH.DIS_8859-15 de_DE.DIS_8859-15
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
.for i in ${LL}
|
||||
ln -fs ../${DL}/tcsh.cat ${DESTDIR}${NLSDIR}/$i/tcsh.cat
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= greek
|
||||
DL= el_GR.ISO_8859-7
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= italian
|
||||
DL= it_IT.ISO_8859-1
|
||||
LL= it_CH.ISO_8859-1 it_IT.DIS_8859-15 it_CH.DIS_8859-15
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
.for i in ${LL}
|
||||
ln -fs ../${DL}/tcsh.cat ${DESTDIR}${NLSDIR}/$i/tcsh.cat
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= ja
|
||||
DL= ja_JP.EUC
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,20 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NL= spanish
|
||||
DL= es_ES.ISO_8859-1
|
||||
LL= es_ES.DIS_8859-15
|
||||
|
||||
.PATH: ${BASESRC}/${NL}
|
||||
|
||||
tcsh.msg: set[0-9]*
|
||||
cat ${BASESRC}/${NL}/set[0-9] \
|
||||
${BASESRC}/${NL}/set[0-9][0-9] > ${.TARGET}
|
||||
|
||||
install:
|
||||
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
|
||||
tcsh.cat ${DESTDIR}${NLSDIR}/${DL}/tcsh.cat
|
||||
.for i in ${LL}
|
||||
ln -fs ../${DL}/tcsh.cat ${DESTDIR}${NLSDIR}/$i/tcsh.cat
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
-702
@@ -1,702 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void asyntax __P((struct wordent *, struct wordent *));
|
||||
static void asyn0 __P((struct wordent *, struct wordent *));
|
||||
static void asyn3 __P((struct wordent *, struct wordent *));
|
||||
static struct wordent
|
||||
*freenod __P((struct wordent *, struct wordent *));
|
||||
static struct command
|
||||
*syn0 __P((struct wordent *, struct wordent *, int));
|
||||
static struct command
|
||||
*syn1 __P((struct wordent *, struct wordent *, int));
|
||||
static struct command
|
||||
*syn1a __P((struct wordent *, struct wordent *, int));
|
||||
static struct command
|
||||
*syn1b __P((struct wordent *, struct wordent *, int));
|
||||
static struct command
|
||||
*syn2 __P((struct wordent *, struct wordent *, int));
|
||||
static struct command
|
||||
*syn3 __P((struct wordent *, struct wordent *, int));
|
||||
|
||||
#define ALEFT 21 /* max of 20 alias expansions */
|
||||
#define HLEFT 11 /* max of 10 history expansions */
|
||||
/*
|
||||
* Perform aliasing on the word list lex
|
||||
* Do a (very rudimentary) parse to separate into commands.
|
||||
* If word 0 of a command has an alias, do it.
|
||||
* Repeat a maximum of 20 times.
|
||||
*/
|
||||
static int aleft;
|
||||
extern int hleft;
|
||||
void
|
||||
alias(lex)
|
||||
struct wordent *lex;
|
||||
{
|
||||
jmp_buf osetexit;
|
||||
|
||||
aleft = ALEFT;
|
||||
hleft = HLEFT;
|
||||
getexit(osetexit);
|
||||
(void) setexit();
|
||||
if (haderr) {
|
||||
resexit(osetexit);
|
||||
reset();
|
||||
}
|
||||
if (--aleft == 0)
|
||||
stderror(ERR_ALIASLOOP);
|
||||
asyntax(lex->next, lex);
|
||||
resexit(osetexit);
|
||||
}
|
||||
|
||||
static void
|
||||
asyntax(p1, p2)
|
||||
struct wordent *p1, *p2;
|
||||
{
|
||||
while (p1 != p2)
|
||||
if (any(";&\n", p1->word[0]))
|
||||
p1 = p1->next;
|
||||
else {
|
||||
asyn0(p1, p2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
asyn0(p1, p2)
|
||||
struct wordent *p1;
|
||||
struct wordent *p2;
|
||||
{
|
||||
struct wordent *p;
|
||||
int l = 0;
|
||||
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
if (l < 0)
|
||||
stderror(ERR_TOOMANYRP);
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
if (p->next != p2 && eq(p->next->word, STRand))
|
||||
p = p->next;
|
||||
continue;
|
||||
|
||||
case '&':
|
||||
case '|':
|
||||
case ';':
|
||||
case '\n':
|
||||
if (l != 0)
|
||||
continue;
|
||||
asyn3(p1, p);
|
||||
asyntax(p->next, p2);
|
||||
return;
|
||||
}
|
||||
if (l == 0)
|
||||
asyn3(p1, p2);
|
||||
}
|
||||
|
||||
static void
|
||||
asyn3(p1, p2)
|
||||
struct wordent *p1;
|
||||
struct wordent *p2;
|
||||
{
|
||||
struct varent *ap;
|
||||
struct wordent alout;
|
||||
bool redid;
|
||||
|
||||
if (p1 == p2)
|
||||
return;
|
||||
if (p1->word[0] == '(') {
|
||||
for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
|
||||
if (p2 == p1)
|
||||
return;
|
||||
if (p2 == p1->next)
|
||||
return;
|
||||
asyn0(p1->next, p2);
|
||||
return;
|
||||
}
|
||||
ap = adrof1(p1->word, &aliases);
|
||||
if (ap == 0)
|
||||
return;
|
||||
alhistp = p1->prev;
|
||||
alhistt = p2;
|
||||
alvec = ap->vec;
|
||||
redid = lex(&alout);
|
||||
alhistp = alhistt = 0;
|
||||
alvec = 0;
|
||||
if (seterr) {
|
||||
freelex(&alout);
|
||||
stderror(ERR_OLD);
|
||||
}
|
||||
if (p1->word[0] && eq(p1->word, alout.next->word)) {
|
||||
Char *cp = alout.next->word;
|
||||
|
||||
alout.next->word = Strspl(STRQNULL, cp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
p1 = freenod(p1, redid ? p2 : p1->next);
|
||||
if (alout.next != &alout) {
|
||||
p1->next->prev = alout.prev->prev;
|
||||
alout.prev->prev->next = p1->next;
|
||||
alout.next->prev = p1;
|
||||
p1->next = alout.next;
|
||||
xfree((ptr_t) alout.prev->word);
|
||||
xfree((ptr_t) (alout.prev));
|
||||
}
|
||||
reset(); /* throw! */
|
||||
}
|
||||
|
||||
static struct wordent *
|
||||
freenod(p1, p2)
|
||||
struct wordent *p1, *p2;
|
||||
{
|
||||
struct wordent *retp = p1->prev;
|
||||
|
||||
while (p1 != p2) {
|
||||
xfree((ptr_t) p1->word);
|
||||
p1 = p1->next;
|
||||
xfree((ptr_t) (p1->prev));
|
||||
}
|
||||
retp->next = p2;
|
||||
p2->prev = retp;
|
||||
return (retp);
|
||||
}
|
||||
|
||||
#define PHERE 1
|
||||
#define PIN 2
|
||||
#define POUT 4
|
||||
#define PERR 8
|
||||
|
||||
/*
|
||||
* syntax
|
||||
* empty
|
||||
* syn0
|
||||
*/
|
||||
struct command *
|
||||
syntax(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
|
||||
while (p1 != p2)
|
||||
if (any(";&\n", p1->word[0]))
|
||||
p1 = p1->next;
|
||||
else
|
||||
return (syn0(p1, p2, flags));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* syn0
|
||||
* syn1
|
||||
* syn1 & syntax
|
||||
*/
|
||||
static struct command *
|
||||
syn0(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t, *t1;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
if (l < 0)
|
||||
seterror(ERR_TOOMANYRP);
|
||||
continue;
|
||||
|
||||
case '|':
|
||||
if (p->word[1] == '|')
|
||||
continue;
|
||||
/* fall into ... */
|
||||
|
||||
case '>':
|
||||
if (p->next != p2 && eq(p->next->word, STRand))
|
||||
p = p->next;
|
||||
continue;
|
||||
|
||||
case '&':
|
||||
if (l != 0)
|
||||
break;
|
||||
if (p->word[1] == '&')
|
||||
continue;
|
||||
t1 = syn1(p1, p, flags);
|
||||
if (t1->t_dtyp == NODE_LIST ||
|
||||
t1->t_dtyp == NODE_AND ||
|
||||
t1->t_dtyp == NODE_OR) {
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_PAREN;
|
||||
t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
|
||||
t->t_dspr = t1;
|
||||
t1 = t;
|
||||
}
|
||||
else
|
||||
t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_LIST;
|
||||
t->t_dflg = 0;
|
||||
t->t_dcar = t1;
|
||||
t->t_dcdr = syntax(p, p2, flags);
|
||||
return (t);
|
||||
}
|
||||
if (l == 0)
|
||||
return (syn1(p1, p2, flags));
|
||||
seterror(ERR_TOOMANYLP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1
|
||||
* syn1a
|
||||
* syn1a ; syntax
|
||||
*/
|
||||
static struct command *
|
||||
syn1(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
|
||||
case ';':
|
||||
case '\n':
|
||||
if (l != 0)
|
||||
break;
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_LIST;
|
||||
t->t_dcar = syn1a(p1, p, flags);
|
||||
t->t_dcdr = syntax(p->next, p2, flags);
|
||||
if (t->t_dcdr == 0)
|
||||
t->t_dcdr = t->t_dcar, t->t_dcar = 0;
|
||||
return (t);
|
||||
}
|
||||
return (syn1a(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1a
|
||||
* syn1b
|
||||
* syn1b || syn1a
|
||||
*/
|
||||
static struct command *
|
||||
syn1a(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l = 0;
|
||||
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
|
||||
case '|':
|
||||
if (p->word[1] != '|')
|
||||
continue;
|
||||
if (l == 0) {
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_OR;
|
||||
t->t_dcar = syn1b(p1, p, flags);
|
||||
t->t_dcdr = syn1a(p->next, p2, flags);
|
||||
t->t_dflg = 0;
|
||||
return (t);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return (syn1b(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1b
|
||||
* syn2
|
||||
* syn2 && syn1b
|
||||
*/
|
||||
static struct command *
|
||||
syn1b(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l = 0;
|
||||
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
|
||||
case '&':
|
||||
if (p->word[1] == '&' && l == 0) {
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_AND;
|
||||
t->t_dcar = syn2(p1, p, flags);
|
||||
t->t_dcdr = syn1b(p->next, p2, flags);
|
||||
t->t_dflg = 0;
|
||||
return (t);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return (syn2(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn2
|
||||
* syn3
|
||||
* syn3 | syn2
|
||||
* syn3 |& syn2
|
||||
*/
|
||||
static struct command *
|
||||
syn2(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p, *pn;
|
||||
struct command *t;
|
||||
int l = 0;
|
||||
int f;
|
||||
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
|
||||
case '|':
|
||||
if (l != 0)
|
||||
continue;
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
f = flags | POUT;
|
||||
pn = p->next;
|
||||
if (pn != p2 && pn->word[0] == '&') {
|
||||
f |= PERR;
|
||||
t->t_dflg |= F_STDERR;
|
||||
}
|
||||
t->t_dtyp = NODE_PIPE;
|
||||
t->t_dcar = syn3(p1, p, f);
|
||||
if (pn != p2 && pn->word[0] == '&')
|
||||
p = pn;
|
||||
t->t_dcdr = syn2(p->next, p2, flags | PIN);
|
||||
return (t);
|
||||
}
|
||||
return (syn3(p1, p2, flags));
|
||||
}
|
||||
|
||||
static char RELPAR[] = {'<', '>', '(', ')', '\0'};
|
||||
|
||||
/*
|
||||
* syn3
|
||||
* ( syn0 ) [ < in ] [ > out ]
|
||||
* word word* [ < in ] [ > out ]
|
||||
* KEYWORD ( word* ) word* [ < in ] [ > out ]
|
||||
*
|
||||
* KEYWORD = (@ exit foreach if set switch test while)
|
||||
*/
|
||||
static struct command *
|
||||
syn3(p1, p2, flags)
|
||||
struct wordent *p1, *p2;
|
||||
int flags;
|
||||
{
|
||||
struct wordent *p;
|
||||
struct wordent *lp, *rp;
|
||||
struct command *t;
|
||||
int l;
|
||||
Char **av;
|
||||
int n, c;
|
||||
bool specp = 0;
|
||||
|
||||
if (p1 != p2) {
|
||||
p = p1;
|
||||
again:
|
||||
switch (srchx(p->word)) {
|
||||
|
||||
case T_ELSE:
|
||||
p = p->next;
|
||||
if (p != p2)
|
||||
goto again;
|
||||
break;
|
||||
|
||||
case T_EXIT:
|
||||
case T_FOREACH:
|
||||
case T_IF:
|
||||
case T_LET:
|
||||
case T_SET:
|
||||
case T_SWITCH:
|
||||
case T_WHILE:
|
||||
specp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
|
||||
case '(':
|
||||
if (specp)
|
||||
n++;
|
||||
l++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
if (specp)
|
||||
n++;
|
||||
l--;
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
case '<':
|
||||
if (l != 0) {
|
||||
if (specp)
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
if (p->next == p2)
|
||||
continue;
|
||||
if (any(RELPAR, p->next->word[0]))
|
||||
continue;
|
||||
n--;
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (!specp && l != 0)
|
||||
continue;
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **));
|
||||
t->t_dcom = av;
|
||||
n = 0;
|
||||
if (p2->word[0] == ')')
|
||||
t->t_dflg = F_NOFORK;
|
||||
lp = 0;
|
||||
rp = 0;
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next) {
|
||||
c = p->word[0];
|
||||
switch (c) {
|
||||
|
||||
case '(':
|
||||
if (l == 0) {
|
||||
if (lp != 0 && !specp)
|
||||
seterror(ERR_BADPLP);
|
||||
lp = p->next;
|
||||
}
|
||||
l++;
|
||||
goto savep;
|
||||
|
||||
case ')':
|
||||
l--;
|
||||
if (l == 0)
|
||||
rp = p;
|
||||
goto savep;
|
||||
|
||||
case '>':
|
||||
if (l != 0)
|
||||
goto savep;
|
||||
if (p->word[1] == '>')
|
||||
t->t_dflg |= F_APPEND;
|
||||
if (p->next != p2 && eq(p->next->word, STRand)) {
|
||||
t->t_dflg |= F_STDERR, p = p->next;
|
||||
if (flags & (POUT | PERR)) {
|
||||
seterror(ERR_OUTRED);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (p->next != p2 && eq(p->next->word, STRbang))
|
||||
t->t_dflg |= F_OVERWRITE, p = p->next;
|
||||
if (p->next == p2) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
if (any(RELPAR, p->word[0])) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
if ((flags & POUT) && ((flags & PERR) == 0 || t->t_drit))
|
||||
seterror(ERR_OUTRED);
|
||||
else
|
||||
t->t_drit = Strsave(p->word);
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
if (l != 0)
|
||||
goto savep;
|
||||
if (p->word[1] == '<')
|
||||
t->t_dflg |= F_READ;
|
||||
if (p->next == p2) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
if (any(RELPAR, p->word[0])) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
if ((flags & PHERE) && (t->t_dflg & F_READ))
|
||||
seterror(ERR_REDPAR);
|
||||
else if ((flags & PIN) || t->t_dlef)
|
||||
seterror(ERR_INRED);
|
||||
else
|
||||
t->t_dlef = Strsave(p->word);
|
||||
continue;
|
||||
|
||||
savep:
|
||||
if (!specp)
|
||||
continue;
|
||||
default:
|
||||
if (l != 0 && !specp)
|
||||
continue;
|
||||
if (seterr == 0)
|
||||
av[n] = Strsave(p->word);
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (lp != 0 && !specp) {
|
||||
if (n != 0)
|
||||
seterror(ERR_BADPLPS);
|
||||
t->t_dtyp = NODE_PAREN;
|
||||
t->t_dspr = syn0(lp, rp, PHERE);
|
||||
}
|
||||
else {
|
||||
if (n == 0)
|
||||
seterror(ERR_NULLCOM);
|
||||
t->t_dtyp = NODE_COMMAND;
|
||||
}
|
||||
return (t);
|
||||
}
|
||||
|
||||
void
|
||||
freesyn(t)
|
||||
struct command *t;
|
||||
{
|
||||
Char **v;
|
||||
|
||||
if (t == 0)
|
||||
return;
|
||||
switch (t->t_dtyp) {
|
||||
|
||||
case NODE_COMMAND:
|
||||
for (v = t->t_dcom; *v; v++)
|
||||
xfree((ptr_t) * v);
|
||||
xfree((ptr_t) (t->t_dcom));
|
||||
xfree((ptr_t) t->t_dlef);
|
||||
xfree((ptr_t) t->t_drit);
|
||||
break;
|
||||
case NODE_PAREN:
|
||||
freesyn(t->t_dspr);
|
||||
xfree((ptr_t) t->t_dlef);
|
||||
xfree((ptr_t) t->t_drit);
|
||||
break;
|
||||
|
||||
case NODE_AND:
|
||||
case NODE_OR:
|
||||
case NODE_PIPE:
|
||||
case NODE_LIST:
|
||||
freesyn(t->t_dcar), freesyn(t->t_dcdr);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) t);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define _PATH_BIN "/bin"
|
||||
#define _PATH_DOTCSHRC "/etc/csh.cshrc"
|
||||
#define _PATH_DOTLOGIN "/etc/csh.login"
|
||||
#define _PATH_DOTLOGOUT "/etc/csh.logout"
|
||||
#define _PATH_LOGIN "/usr/bin/login"
|
||||
#define _PATH_USRBIN "/usr/bin"
|
||||
-1362
File diff suppressed because it is too large.
Load diff
-102
@@ -1,102 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)proc.h 8.1 (Berkeley) 5/31/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure for each process the shell knows about:
|
||||
* allocated and filled by pcreate.
|
||||
* flushed by pflush; freeing always happens at top level
|
||||
* so the interrupt level has less to worry about.
|
||||
* processes are related to "friends" when in a pipeline;
|
||||
* p_friends links makes a circular list of such jobs
|
||||
*/
|
||||
struct process {
|
||||
struct process *p_next; /* next in global "proclist" */
|
||||
struct process *p_friends; /* next in job list (or self) */
|
||||
struct directory *p_cwd; /* cwd of the job (only in head) */
|
||||
short unsigned p_flags; /* various job status flags */
|
||||
char p_reason; /* reason for entering this state */
|
||||
int p_index; /* shorthand job index */
|
||||
int p_pid;
|
||||
int p_jobid; /* pid of job leader */
|
||||
/* if a job is stopped/background p_jobid gives its pgrp */
|
||||
struct timeval p_btime; /* begin time */
|
||||
struct timeval p_etime; /* end time */
|
||||
struct rusage p_rusage;
|
||||
Char *p_command; /* first PMAXLEN chars of command */
|
||||
};
|
||||
|
||||
/* flag values for p_flags */
|
||||
#define PRUNNING (1<<0) /* running */
|
||||
#define PSTOPPED (1<<1) /* stopped */
|
||||
#define PNEXITED (1<<2) /* normally exited */
|
||||
#define PAEXITED (1<<3) /* abnormally exited */
|
||||
#define PSIGNALED (1<<4) /* terminated by a signal != SIGINT */
|
||||
|
||||
#define PALLSTATES (PRUNNING|PSTOPPED|PNEXITED|PAEXITED|PSIGNALED|PINTERRUPTED)
|
||||
#define PNOTIFY (1<<5) /* notify async when done */
|
||||
#define PTIME (1<<6) /* job times should be printed */
|
||||
#define PAWAITED (1<<7) /* top level is waiting for it */
|
||||
#define PFOREGND (1<<8) /* started in shells pgrp */
|
||||
#define PDUMPED (1<<9) /* process dumped core */
|
||||
#define PERR (1<<10) /* diagnostic output also piped out */
|
||||
#define PPOU (1<<11) /* piped output */
|
||||
#define PREPORTED (1<<12) /* status has been reported */
|
||||
#define PINTERRUPTED (1<<13) /* job stopped via interrupt signal */
|
||||
#define PPTIME (1<<14) /* time individual process */
|
||||
#define PNEEDNOTE (1<<15) /* notify as soon as practical */
|
||||
|
||||
#define PMAXLEN 80
|
||||
|
||||
/* defines for arguments to pprint */
|
||||
#define NUMBER 01
|
||||
#define NAME 02
|
||||
#define REASON 04
|
||||
#define AMPERSAND 010
|
||||
#define FANCY 020
|
||||
#define SHELLDIR 040 /* print shell's dir if not the same */
|
||||
#define JOBDIR 0100 /* print job's dir if not the same */
|
||||
#define AREASON 0200
|
||||
|
||||
struct process proclist; /* list head of all processes */
|
||||
bool pnoprocesses; /* pchild found nothing to wait for */
|
||||
|
||||
struct process *pholdjob; /* one level stack of current jobs */
|
||||
|
||||
struct process *pcurrjob; /* current job */
|
||||
struct process *pcurrent; /* current job in table */
|
||||
struct process *pprevious; /* previous job in table */
|
||||
|
||||
int pmaxindex; /* current maximum job index */
|
||||
-650
@@ -1,650 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)sem.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "proc.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void vffree __P((int));
|
||||
static Char *splicepipe __P((struct command *t, Char *));
|
||||
static void doio __P((struct command *t, int *, int *));
|
||||
static void chkclob __P((char *));
|
||||
|
||||
void
|
||||
execute(t, wanttty, pipein, pipeout)
|
||||
struct command *t;
|
||||
int wanttty, *pipein, *pipeout;
|
||||
{
|
||||
bool forked = 0;
|
||||
struct biltins *bifunc;
|
||||
int pid = 0;
|
||||
int pv[2];
|
||||
|
||||
static int csigmask;
|
||||
|
||||
static int ocsigmask;
|
||||
static int onosigchld = 0;
|
||||
static int nosigchld = 0;
|
||||
|
||||
UNREGISTER(forked);
|
||||
UNREGISTER(bifunc);
|
||||
UNREGISTER(wanttty);
|
||||
|
||||
if (t == 0)
|
||||
return;
|
||||
|
||||
if (t->t_dflg & F_AMPERSAND)
|
||||
wanttty = 0;
|
||||
switch (t->t_dtyp) {
|
||||
|
||||
case NODE_COMMAND:
|
||||
if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE)
|
||||
(void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1);
|
||||
if ((t->t_dflg & F_REPEAT) == 0)
|
||||
Dfix(t); /* $ " ' \ */
|
||||
if (t->t_dcom[0] == 0)
|
||||
return;
|
||||
/* fall into... */
|
||||
|
||||
case NODE_PAREN:
|
||||
if (t->t_dflg & F_PIPEOUT)
|
||||
mypipe(pipeout);
|
||||
/*
|
||||
* Must do << early so parent will know where input pointer should be.
|
||||
* If noexec then this is all we do.
|
||||
*/
|
||||
if (t->t_dflg & F_READ) {
|
||||
(void) close(0);
|
||||
heredoc(t->t_dlef);
|
||||
if (noexec)
|
||||
(void) close(0);
|
||||
}
|
||||
|
||||
set(STRstatus, Strsave(STR0));
|
||||
|
||||
/*
|
||||
* This mess is the necessary kludge to handle the prefix builtins:
|
||||
* nice, nohup, time. These commands can also be used by themselves,
|
||||
* and this is not handled here. This will also work when loops are
|
||||
* parsed.
|
||||
*/
|
||||
while (t->t_dtyp == NODE_COMMAND)
|
||||
if (eq(t->t_dcom[0], STRnice))
|
||||
if (t->t_dcom[1])
|
||||
if (strchr("+-", t->t_dcom[1][0]))
|
||||
if (t->t_dcom[2]) {
|
||||
setname("nice");
|
||||
t->t_nice =
|
||||
getn(t->t_dcom[1]);
|
||||
lshift(t->t_dcom, 2);
|
||||
t->t_dflg |= F_NICE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
else {
|
||||
t->t_nice = 4;
|
||||
lshift(t->t_dcom, 1);
|
||||
t->t_dflg |= F_NICE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
else if (eq(t->t_dcom[0], STRnohup))
|
||||
if (t->t_dcom[1]) {
|
||||
t->t_dflg |= F_NOHUP;
|
||||
lshift(t->t_dcom, 1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
else if (eq(t->t_dcom[0], STRtime))
|
||||
if (t->t_dcom[1]) {
|
||||
t->t_dflg |= F_TIME;
|
||||
lshift(t->t_dcom, 1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
else
|
||||
break;
|
||||
|
||||
/* is it a command */
|
||||
if (t->t_dtyp == NODE_COMMAND) {
|
||||
/*
|
||||
* Check if we have a builtin function and remember which one.
|
||||
*/
|
||||
bifunc = isbfunc(t);
|
||||
if (noexec) {
|
||||
/*
|
||||
* Continue for builtins that are part of the scripting language
|
||||
*/
|
||||
if (bifunc->bfunct != dobreak && bifunc->bfunct != docontin &&
|
||||
bifunc->bfunct != doelse && bifunc->bfunct != doend &&
|
||||
bifunc->bfunct != doforeach && bifunc->bfunct != dogoto &&
|
||||
bifunc->bfunct != doif && bifunc->bfunct != dorepeat &&
|
||||
bifunc->bfunct != doswbrk && bifunc->bfunct != doswitch &&
|
||||
bifunc->bfunct != dowhile && bifunc->bfunct != dozip)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* not a command */
|
||||
bifunc = NULL;
|
||||
if (noexec)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We fork only if we are timed, or are not the end of a parenthesized
|
||||
* list and not a simple builtin function. Simple meaning one that is
|
||||
* not pipedout, niced, nohupped, or &'d. It would be nice(?) to not
|
||||
* fork in some of these cases.
|
||||
*/
|
||||
/*
|
||||
* Prevent forking cd, pushd, popd, chdir cause this will cause the
|
||||
* shell not to change dir!
|
||||
*/
|
||||
if (bifunc && (bifunc->bfunct == dochngd ||
|
||||
bifunc->bfunct == dopushd ||
|
||||
bifunc->bfunct == dopopd))
|
||||
t->t_dflg &= ~(F_NICE);
|
||||
if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&
|
||||
(!bifunc || t->t_dflg &
|
||||
(F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) ||
|
||||
/*
|
||||
* We have to fork for eval too.
|
||||
*/
|
||||
(bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 &&
|
||||
bifunc->bfunct == doeval)) {
|
||||
if (t->t_dtyp == NODE_PAREN ||
|
||||
t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
|
||||
forked++;
|
||||
/*
|
||||
* We need to block SIGCHLD here, so that if the process does
|
||||
* not die before we can set the process group
|
||||
*/
|
||||
if (wanttty >= 0 && !nosigchld) {
|
||||
csigmask = sigblock(sigmask(SIGCHLD));
|
||||
nosigchld = 1;
|
||||
}
|
||||
|
||||
pid = pfork(t, wanttty);
|
||||
if (pid == 0 && nosigchld) {
|
||||
(void) sigsetmask(csigmask);
|
||||
nosigchld = 0;
|
||||
}
|
||||
else if (pid != 0 && (t->t_dflg & F_AMPERSAND))
|
||||
backpid = pid;
|
||||
|
||||
}
|
||||
else {
|
||||
int ochild, osetintr, ohaderr, odidfds;
|
||||
int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp;
|
||||
int omask;
|
||||
|
||||
/*
|
||||
* Prepare for the vfork by saving everything that the child
|
||||
* corrupts before it exec's. Note that in some signal
|
||||
* implementations which keep the signal info in user space
|
||||
* (e.g. Sun's) it will also be necessary to save and restore
|
||||
* the current sigvec's for the signals the child touches
|
||||
* before it exec's.
|
||||
*/
|
||||
if (wanttty >= 0 && !nosigchld && !noexec) {
|
||||
csigmask = sigblock(sigmask(SIGCHLD));
|
||||
nosigchld = 1;
|
||||
}
|
||||
omask = sigblock(sigmask(SIGCHLD) | sigmask(SIGINT));
|
||||
ochild = child;
|
||||
osetintr = setintr;
|
||||
ohaderr = haderr;
|
||||
odidfds = didfds;
|
||||
oSHIN = SHIN;
|
||||
oSHOUT = SHOUT;
|
||||
oSHERR = SHERR;
|
||||
oOLDSTD = OLDSTD;
|
||||
otpgrp = tpgrp;
|
||||
ocsigmask = csigmask;
|
||||
onosigchld = nosigchld;
|
||||
Vsav = Vdp = 0;
|
||||
Vexpath = 0;
|
||||
Vt = 0;
|
||||
pid = vfork();
|
||||
|
||||
if (pid < 0) {
|
||||
(void) sigsetmask(omask);
|
||||
stderror(ERR_NOPROC);
|
||||
}
|
||||
forked++;
|
||||
if (pid) { /* parent */
|
||||
child = ochild;
|
||||
setintr = osetintr;
|
||||
haderr = ohaderr;
|
||||
didfds = odidfds;
|
||||
SHIN = oSHIN;
|
||||
SHOUT = oSHOUT;
|
||||
SHERR = oSHERR;
|
||||
OLDSTD = oOLDSTD;
|
||||
tpgrp = otpgrp;
|
||||
csigmask = ocsigmask;
|
||||
nosigchld = onosigchld;
|
||||
|
||||
xfree((ptr_t) Vsav);
|
||||
Vsav = 0;
|
||||
xfree((ptr_t) Vdp);
|
||||
Vdp = 0;
|
||||
xfree((ptr_t) Vexpath);
|
||||
Vexpath = 0;
|
||||
blkfree((Char **) Vt);
|
||||
Vt = 0;
|
||||
/* this is from pfork() */
|
||||
palloc(pid, t);
|
||||
(void) sigsetmask(omask);
|
||||
}
|
||||
else { /* child */
|
||||
/* this is from pfork() */
|
||||
int pgrp;
|
||||
bool ignint = 0;
|
||||
|
||||
if (nosigchld) {
|
||||
(void) sigsetmask(csigmask);
|
||||
nosigchld = 0;
|
||||
}
|
||||
|
||||
if (setintr)
|
||||
ignint =
|
||||
(tpgrp == -1 &&
|
||||
(t->t_dflg & F_NOINTERRUPT))
|
||||
|| (gointr && eq(gointr, STRminus));
|
||||
pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
|
||||
child++;
|
||||
if (setintr) {
|
||||
setintr = 0;
|
||||
if (ignint) {
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGQUIT, SIG_IGN);
|
||||
}
|
||||
else {
|
||||
(void) signal(SIGINT, vffree);
|
||||
(void) signal(SIGQUIT, SIG_DFL);
|
||||
}
|
||||
|
||||
if (wanttty >= 0) {
|
||||
(void) signal(SIGTSTP, SIG_DFL);
|
||||
(void) signal(SIGTTIN, SIG_DFL);
|
||||
(void) signal(SIGTTOU, SIG_DFL);
|
||||
}
|
||||
|
||||
(void) signal(SIGTERM, parterm);
|
||||
}
|
||||
else if (tpgrp == -1 &&
|
||||
(t->t_dflg & F_NOINTERRUPT)) {
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGQUIT, SIG_IGN);
|
||||
}
|
||||
|
||||
pgetty(wanttty, pgrp);
|
||||
if (t->t_dflg & F_NOHUP)
|
||||
(void) signal(SIGHUP, SIG_IGN);
|
||||
if (t->t_dflg & F_NICE)
|
||||
(void) setpriority(PRIO_PROCESS, 0, t->t_nice);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (pid != 0) {
|
||||
/*
|
||||
* It would be better if we could wait for the whole job when we
|
||||
* knew the last process had been started. Pwait, in fact, does
|
||||
* wait for the whole job anyway, but this test doesn't really
|
||||
* express our intentions.
|
||||
*/
|
||||
if (didfds == 0 && t->t_dflg & F_PIPEIN) {
|
||||
(void) close(pipein[0]);
|
||||
(void) close(pipein[1]);
|
||||
}
|
||||
if ((t->t_dflg & F_PIPEOUT) == 0) {
|
||||
if (nosigchld) {
|
||||
(void) sigsetmask(csigmask);
|
||||
nosigchld = 0;
|
||||
}
|
||||
if ((t->t_dflg & F_AMPERSAND) == 0)
|
||||
pwait();
|
||||
}
|
||||
break;
|
||||
}
|
||||
doio(t, pipein, pipeout);
|
||||
if (t->t_dflg & F_PIPEOUT) {
|
||||
(void) close(pipeout[0]);
|
||||
(void) close(pipeout[1]);
|
||||
}
|
||||
/*
|
||||
* Perform a builtin function. If we are not forked, arrange for
|
||||
* possible stopping
|
||||
*/
|
||||
if (bifunc) {
|
||||
func(t, bifunc);
|
||||
if (forked)
|
||||
exitstat();
|
||||
break;
|
||||
}
|
||||
if (t->t_dtyp != NODE_PAREN) {
|
||||
doexec(NULL, t);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/*
|
||||
* For () commands must put new 0,1,2 in FSH* and recurse
|
||||
*/
|
||||
OLDSTD = dcopy(0, FOLDSTD);
|
||||
SHOUT = dcopy(1, FSHOUT);
|
||||
SHERR = dcopy(2, FSHERR);
|
||||
(void) close(SHIN);
|
||||
SHIN = -1;
|
||||
didfds = 0;
|
||||
wanttty = -1;
|
||||
t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dspr, wanttty, NULL, NULL);
|
||||
exitstat();
|
||||
|
||||
case NODE_PIPE:
|
||||
t->t_dcar->t_dflg |= F_PIPEOUT |
|
||||
(t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT));
|
||||
execute(t->t_dcar, wanttty, pipein, pv);
|
||||
t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg &
|
||||
(F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT));
|
||||
if (wanttty > 0)
|
||||
wanttty = 0; /* got tty already */
|
||||
execute(t->t_dcdr, wanttty, pv, pipeout);
|
||||
break;
|
||||
|
||||
case NODE_LIST:
|
||||
if (t->t_dcar) {
|
||||
t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dcar, wanttty, NULL, NULL);
|
||||
/*
|
||||
* In strange case of A&B make a new job after A
|
||||
*/
|
||||
if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr &&
|
||||
(t->t_dcdr->t_dflg & F_AMPERSAND) == 0)
|
||||
pendjob();
|
||||
}
|
||||
if (t->t_dcdr) {
|
||||
t->t_dcdr->t_dflg |= t->t_dflg &
|
||||
(F_NOFORK | F_NOINTERRUPT);
|
||||
execute(t->t_dcdr, wanttty, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_OR:
|
||||
case NODE_AND:
|
||||
if (t->t_dcar) {
|
||||
t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dcar, wanttty, NULL, NULL);
|
||||
if ((getn(value(STRstatus)) == 0) !=
|
||||
(t->t_dtyp == NODE_AND))
|
||||
return;
|
||||
}
|
||||
if (t->t_dcdr) {
|
||||
t->t_dcdr->t_dflg |= t->t_dflg &
|
||||
(F_NOFORK | F_NOINTERRUPT);
|
||||
execute(t->t_dcdr, wanttty, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Fall through for all breaks from switch
|
||||
*
|
||||
* If there will be no more executions of this command, flush all file
|
||||
* descriptors. Places that turn on the F_REPEAT bit are responsible for
|
||||
* doing donefds after the last re-execution
|
||||
*/
|
||||
if (didfds && !(t->t_dflg & F_REPEAT))
|
||||
donefds();
|
||||
}
|
||||
|
||||
static void
|
||||
vffree(i)
|
||||
int i;
|
||||
{
|
||||
Char **v;
|
||||
|
||||
if ((v = gargv) != NULL) {
|
||||
gargv = 0;
|
||||
xfree((ptr_t) v);
|
||||
}
|
||||
if ((v = pargv) != NULL) {
|
||||
pargv = 0;
|
||||
xfree((ptr_t) v);
|
||||
}
|
||||
_exit(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand and glob the words after an i/o redirection.
|
||||
* If more than one word is generated, then update the command vector.
|
||||
*
|
||||
* This is done differently in all the shells:
|
||||
* 1. in the Bourne shell and ksh globbing is not performed
|
||||
* 2. Bash/csh say ambiguous
|
||||
* 3. zsh does i/o to/from all the files
|
||||
* 4. itcsh concatenates the words.
|
||||
*
|
||||
* I don't know what is best to do. I think that Ambiguous is better
|
||||
* than restructuring the command vector, because the user can get
|
||||
* unexpected results. In any case, the command vector restructuring
|
||||
* code is present and the user can choose it by setting noambiguous
|
||||
*/
|
||||
static Char *
|
||||
splicepipe(t, cp)
|
||||
struct command *t;
|
||||
Char *cp; /* word after < or > */
|
||||
{
|
||||
Char *blk[2];
|
||||
|
||||
if (adrof(STRnoambiguous)) {
|
||||
Char **pv;
|
||||
|
||||
blk[0] = Dfix1(cp); /* expand $ */
|
||||
blk[1] = NULL;
|
||||
|
||||
gflag = 0, tglob(blk);
|
||||
if (gflag) {
|
||||
pv = globall(blk);
|
||||
if (pv == NULL) {
|
||||
setname(vis_str(blk[0]));
|
||||
xfree((ptr_t) blk[0]);
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
gargv = NULL;
|
||||
if (pv[1] != NULL) { /* we need to fix the command vector */
|
||||
Char **av = blkspl(t->t_dcom, &pv[1]);
|
||||
xfree((ptr_t) t->t_dcom);
|
||||
t->t_dcom = av;
|
||||
}
|
||||
xfree((ptr_t) blk[0]);
|
||||
blk[0] = pv[0];
|
||||
xfree((ptr_t) pv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
blk[0] = globone(blk[1] = Dfix1(cp), G_ERROR);
|
||||
xfree((ptr_t) blk[1]);
|
||||
}
|
||||
return(blk[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform io redirection.
|
||||
* We may or maynot be forked here.
|
||||
*/
|
||||
static void
|
||||
doio(t, pipein, pipeout)
|
||||
struct command *t;
|
||||
int *pipein, *pipeout;
|
||||
{
|
||||
int fd;
|
||||
Char *cp;
|
||||
int flags = t->t_dflg;
|
||||
|
||||
if (didfds || (flags & F_REPEAT))
|
||||
return;
|
||||
if ((flags & F_READ) == 0) {/* F_READ already done */
|
||||
if (t->t_dlef) {
|
||||
char tmp[MAXPATHLEN+1];
|
||||
|
||||
/*
|
||||
* so < /dev/std{in,out,err} work
|
||||
*/
|
||||
(void) dcopy(SHIN, 0);
|
||||
(void) dcopy(SHOUT, 1);
|
||||
(void) dcopy(SHERR, 2);
|
||||
cp = splicepipe(t, t->t_dlef);
|
||||
(void) strncpy(tmp, short2str(cp), MAXPATHLEN);
|
||||
tmp[MAXPATHLEN] = '\0';
|
||||
xfree((ptr_t) cp);
|
||||
if ((fd = open(tmp, O_RDONLY)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
(void) dmove(fd, 0);
|
||||
}
|
||||
else if (flags & F_PIPEIN) {
|
||||
(void) close(0);
|
||||
(void) dup(pipein[0]);
|
||||
(void) close(pipein[0]);
|
||||
(void) close(pipein[1]);
|
||||
}
|
||||
else if ((flags & F_NOINTERRUPT) && tpgrp == -1) {
|
||||
(void) close(0);
|
||||
(void) open(_PATH_DEVNULL, O_RDONLY);
|
||||
}
|
||||
else {
|
||||
(void) close(0);
|
||||
(void) dup(OLDSTD);
|
||||
(void) ioctl(0, FIONCLEX, NULL);
|
||||
}
|
||||
}
|
||||
if (t->t_drit) {
|
||||
char tmp[MAXPATHLEN+1];
|
||||
|
||||
cp = splicepipe(t, t->t_drit);
|
||||
(void) strncpy(tmp, short2str(cp), MAXPATHLEN);
|
||||
tmp[MAXPATHLEN] = '\0';
|
||||
xfree((ptr_t) cp);
|
||||
/*
|
||||
* so > /dev/std{out,err} work
|
||||
*/
|
||||
(void) dcopy(SHOUT, 1);
|
||||
(void) dcopy(SHERR, 2);
|
||||
if ((flags & F_APPEND) &&
|
||||
#ifdef O_APPEND
|
||||
(fd = open(tmp, O_WRONLY | O_APPEND)) >= 0);
|
||||
#else
|
||||
(fd = open(tmp, O_WRONLY)) >= 0)
|
||||
(void) lseek(1, (off_t) 0, L_XTND);
|
||||
#endif
|
||||
else {
|
||||
if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) {
|
||||
if (flags & F_APPEND)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
chkclob(tmp);
|
||||
}
|
||||
if ((fd = creat(tmp, 0666)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
(void) dmove(fd, 1);
|
||||
}
|
||||
else if (flags & F_PIPEOUT) {
|
||||
(void) close(1);
|
||||
(void) dup(pipeout[1]);
|
||||
}
|
||||
else {
|
||||
(void) close(1);
|
||||
(void) dup(SHOUT);
|
||||
(void) ioctl(1, FIONCLEX, NULL);
|
||||
}
|
||||
|
||||
(void) close(2);
|
||||
if (flags & F_STDERR) {
|
||||
(void) dup(1);
|
||||
}
|
||||
else {
|
||||
(void) dup(SHERR);
|
||||
(void) ioctl(2, FIONCLEX, NULL);
|
||||
}
|
||||
didfds = 1;
|
||||
}
|
||||
|
||||
void
|
||||
mypipe(pv)
|
||||
int *pv;
|
||||
{
|
||||
|
||||
if (pipe(pv) < 0)
|
||||
goto oops;
|
||||
pv[0] = dmove(pv[0], -1);
|
||||
pv[1] = dmove(pv[1], -1);
|
||||
if (pv[0] >= 0 && pv[1] >= 0)
|
||||
return;
|
||||
oops:
|
||||
stderror(ERR_PIPE);
|
||||
}
|
||||
|
||||
static void
|
||||
chkclob(cp)
|
||||
char *cp;
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if (stat(cp, &stb) < 0)
|
||||
return;
|
||||
if (S_ISCHR(stb.st_mode))
|
||||
return;
|
||||
stderror(ERR_EXISTS, cp);
|
||||
}
|
||||
-847
@@ -1,847 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)set.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static Char *getinx __P((Char *, int *));
|
||||
static void asx __P((Char *, int, Char *));
|
||||
static struct varent
|
||||
*getvx __P((Char *, int));
|
||||
static Char *xset __P((Char *, Char ***));
|
||||
static Char *operate __P((int, Char *, Char *));
|
||||
static void putn1 __P((int));
|
||||
static struct varent
|
||||
*madrof __P((Char *, struct varent *));
|
||||
static void unsetv1 __P((struct varent *));
|
||||
static void exportpath __P((Char **));
|
||||
static void balance __P((struct varent *, int, int));
|
||||
|
||||
|
||||
/*
|
||||
* C Shell
|
||||
*/
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
doset(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
Char *p;
|
||||
Char *vp, op;
|
||||
Char **vecp;
|
||||
bool hadsub;
|
||||
int subscr;
|
||||
|
||||
v++;
|
||||
p = *v++;
|
||||
if (p == 0) {
|
||||
prvars();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
hadsub = 0;
|
||||
vp = p;
|
||||
if (letter(*p))
|
||||
for (; alnum(*p); p++)
|
||||
continue;
|
||||
if (vp == p || !letter(*vp))
|
||||
stderror(ERR_NAME | ERR_VARBEGIN);
|
||||
if ((p - vp) > MAXVARLEN) {
|
||||
stderror(ERR_NAME | ERR_VARTOOLONG);
|
||||
return;
|
||||
}
|
||||
if (*p == '[') {
|
||||
hadsub++;
|
||||
p = getinx(p, &subscr);
|
||||
}
|
||||
if ((op = *p) != '\0') {
|
||||
*p++ = 0;
|
||||
if (*p == 0 && *v && **v == '(')
|
||||
p = *v++;
|
||||
}
|
||||
else if (*v && eq(*v, STRequal)) {
|
||||
op = '=', v++;
|
||||
if (*v)
|
||||
p = *v++;
|
||||
}
|
||||
if (op && op != '=')
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
if (eq(p, STRLparen)) {
|
||||
Char **e = v;
|
||||
|
||||
if (hadsub)
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
for (;;) {
|
||||
if (!*e)
|
||||
stderror(ERR_NAME | ERR_MISSING, ')');
|
||||
if (**e == ')')
|
||||
break;
|
||||
e++;
|
||||
}
|
||||
p = *e;
|
||||
*e = 0;
|
||||
vecp = saveblk(v);
|
||||
set1(vp, vecp, &shvhed);
|
||||
*e = p;
|
||||
v = e + 1;
|
||||
}
|
||||
else if (hadsub)
|
||||
asx(vp, subscr, Strsave(p));
|
||||
else
|
||||
set(vp, Strsave(p));
|
||||
if (eq(vp, STRpath)) {
|
||||
exportpath(adrof(STRpath)->vec);
|
||||
dohash(NULL, NULL);
|
||||
}
|
||||
else if (eq(vp, STRhistchars)) {
|
||||
Char *pn = value(STRhistchars);
|
||||
|
||||
HIST = *pn++;
|
||||
HISTSUB = *pn;
|
||||
}
|
||||
else if (eq(vp, STRuser)) {
|
||||
Setenv(STRUSER, value(vp));
|
||||
Setenv(STRLOGNAME, value(vp));
|
||||
}
|
||||
else if (eq(vp, STRwordchars)) {
|
||||
word_chars = value(vp);
|
||||
}
|
||||
else if (eq(vp, STRterm))
|
||||
Setenv(STRTERM, value(vp));
|
||||
else if (eq(vp, STRhome)) {
|
||||
Char *cp;
|
||||
|
||||
cp = Strsave(value(vp)); /* get the old value back */
|
||||
|
||||
/*
|
||||
* convert to canonical pathname (possibly resolving symlinks)
|
||||
*/
|
||||
cp = dcanon(cp, cp);
|
||||
|
||||
set(vp, Strsave(cp)); /* have to save the new val */
|
||||
|
||||
/* and now mirror home with HOME */
|
||||
Setenv(STRHOME, cp);
|
||||
/* fix directory stack for new tilde home */
|
||||
dtilde();
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
#ifdef FILEC
|
||||
else if (eq(vp, STRfilec))
|
||||
filec = 1;
|
||||
#endif
|
||||
} while ((p = *v++) != NULL);
|
||||
}
|
||||
|
||||
static Char *
|
||||
getinx(cp, ip)
|
||||
Char *cp;
|
||||
int *ip;
|
||||
{
|
||||
|
||||
*ip = 0;
|
||||
*cp++ = 0;
|
||||
while (*cp && Isdigit(*cp))
|
||||
*ip = *ip * 10 + *cp++ - '0';
|
||||
if (*cp++ != ']')
|
||||
stderror(ERR_NAME | ERR_SUBSCRIPT);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
static void
|
||||
asx(vp, subscr, p)
|
||||
Char *vp;
|
||||
int subscr;
|
||||
Char *p;
|
||||
{
|
||||
struct varent *v = getvx(vp, subscr);
|
||||
|
||||
xfree((ptr_t) v->vec[subscr - 1]);
|
||||
v->vec[subscr - 1] = globone(p, G_APPEND);
|
||||
}
|
||||
|
||||
static struct varent *
|
||||
getvx(vp, subscr)
|
||||
Char *vp;
|
||||
int subscr;
|
||||
{
|
||||
struct varent *v = adrof(vp);
|
||||
|
||||
if (v == 0)
|
||||
udvar(vp);
|
||||
if (subscr < 1 || subscr > blklen(v->vec))
|
||||
stderror(ERR_NAME | ERR_RANGE);
|
||||
return (v);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dolet(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
Char *p;
|
||||
Char *vp, c, op;
|
||||
bool hadsub;
|
||||
int subscr;
|
||||
|
||||
v++;
|
||||
p = *v++;
|
||||
if (p == 0) {
|
||||
prvars();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
hadsub = 0;
|
||||
vp = p;
|
||||
if (letter(*p))
|
||||
for (; alnum(*p); p++)
|
||||
continue;
|
||||
if (vp == p || !letter(*vp))
|
||||
stderror(ERR_NAME | ERR_VARBEGIN);
|
||||
if ((p - vp) > MAXVARLEN)
|
||||
stderror(ERR_NAME | ERR_VARTOOLONG);
|
||||
if (*p == '[') {
|
||||
hadsub++;
|
||||
p = getinx(p, &subscr);
|
||||
}
|
||||
if (*p == 0 && *v)
|
||||
p = *v++;
|
||||
if ((op = *p) != '\0')
|
||||
*p++ = 0;
|
||||
else
|
||||
stderror(ERR_NAME | ERR_ASSIGN);
|
||||
|
||||
if (*p == '\0' && *v == NULL)
|
||||
stderror(ERR_NAME | ERR_ASSIGN);
|
||||
|
||||
vp = Strsave(vp);
|
||||
if (op == '=') {
|
||||
c = '=';
|
||||
p = xset(p, &v);
|
||||
}
|
||||
else {
|
||||
c = *p++;
|
||||
if (any("+-", c)) {
|
||||
if (c != op || *p)
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
p = Strsave(STR1);
|
||||
}
|
||||
else {
|
||||
if (any("<>", op)) {
|
||||
if (c != op)
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
c = *p++;
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
}
|
||||
if (c != '=')
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
p = xset(p, &v);
|
||||
}
|
||||
}
|
||||
if (op == '=')
|
||||
if (hadsub)
|
||||
asx(vp, subscr, p);
|
||||
else
|
||||
set(vp, p);
|
||||
else if (hadsub) {
|
||||
struct varent *gv = getvx(vp, subscr);
|
||||
|
||||
asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
|
||||
}
|
||||
else
|
||||
set(vp, operate(op, value(vp), p));
|
||||
if (eq(vp, STRpath)) {
|
||||
exportpath(adrof(STRpath)->vec);
|
||||
dohash(NULL, NULL);
|
||||
}
|
||||
xfree((ptr_t) vp);
|
||||
if (c != '=')
|
||||
xfree((ptr_t) p);
|
||||
} while ((p = *v++) != NULL);
|
||||
}
|
||||
|
||||
static Char *
|
||||
xset(cp, vp)
|
||||
Char *cp, ***vp;
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
if (*cp) {
|
||||
dp = Strsave(cp);
|
||||
--(*vp);
|
||||
xfree((ptr_t) ** vp);
|
||||
**vp = dp;
|
||||
}
|
||||
return (putn(expr(vp)));
|
||||
}
|
||||
|
||||
static Char *
|
||||
operate(op, vp, p)
|
||||
int op;
|
||||
Char *vp, *p;
|
||||
{
|
||||
Char opr[2];
|
||||
Char *vec[5];
|
||||
Char **v = vec;
|
||||
Char **vecp = v;
|
||||
int i;
|
||||
|
||||
if (op != '=') {
|
||||
if (*vp)
|
||||
*v++ = vp;
|
||||
opr[0] = op;
|
||||
opr[1] = 0;
|
||||
*v++ = opr;
|
||||
if (op == '<' || op == '>')
|
||||
*v++ = opr;
|
||||
}
|
||||
*v++ = p;
|
||||
*v++ = 0;
|
||||
i = expr(&vecp);
|
||||
if (*vecp)
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
return (putn(i));
|
||||
}
|
||||
|
||||
static Char *putp;
|
||||
|
||||
Char *
|
||||
putn(n)
|
||||
int n;
|
||||
{
|
||||
int num;
|
||||
static Char number[15];
|
||||
|
||||
putp = number;
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
*putp++ = '-';
|
||||
}
|
||||
num = 2; /* confuse lint */
|
||||
if (sizeof(int) == num && ((unsigned int) n) == 0x8000) {
|
||||
*putp++ = '3';
|
||||
n = 2768;
|
||||
#ifdef pdp11
|
||||
}
|
||||
#else
|
||||
}
|
||||
else {
|
||||
num = 4; /* confuse lint */
|
||||
if (sizeof(int) == num && ((unsigned int) n) == 0x80000000) {
|
||||
*putp++ = '2';
|
||||
n = 147483648;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
putn1(n);
|
||||
*putp = 0;
|
||||
return (Strsave(number));
|
||||
}
|
||||
|
||||
static void
|
||||
putn1(n)
|
||||
int n;
|
||||
{
|
||||
if (n > 9)
|
||||
putn1(n / 10);
|
||||
*putp++ = n % 10 + '0';
|
||||
}
|
||||
|
||||
int
|
||||
getn(cp)
|
||||
Char *cp;
|
||||
{
|
||||
int n;
|
||||
int sign;
|
||||
|
||||
sign = 0;
|
||||
if (cp[0] == '+' && cp[1])
|
||||
cp++;
|
||||
if (*cp == '-') {
|
||||
sign++;
|
||||
cp++;
|
||||
if (!Isdigit(*cp))
|
||||
stderror(ERR_NAME | ERR_BADNUM);
|
||||
}
|
||||
n = 0;
|
||||
while (Isdigit(*cp))
|
||||
n = n * 10 + *cp++ - '0';
|
||||
if (*cp)
|
||||
stderror(ERR_NAME | ERR_BADNUM);
|
||||
return (sign ? -n : n);
|
||||
}
|
||||
|
||||
Char *
|
||||
value1(var, head)
|
||||
Char *var;
|
||||
struct varent *head;
|
||||
{
|
||||
struct varent *vp;
|
||||
|
||||
vp = adrof1(var, head);
|
||||
return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]);
|
||||
}
|
||||
|
||||
static struct varent *
|
||||
madrof(pat, vp)
|
||||
Char *pat;
|
||||
struct varent *vp;
|
||||
{
|
||||
struct varent *vp1;
|
||||
|
||||
for (; vp; vp = vp->v_right) {
|
||||
if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
|
||||
return vp1;
|
||||
if (Gmatch(vp->v_name, pat))
|
||||
return vp;
|
||||
}
|
||||
return vp;
|
||||
}
|
||||
|
||||
struct varent *
|
||||
adrof1(name, v)
|
||||
Char *name;
|
||||
struct varent *v;
|
||||
{
|
||||
int cmp;
|
||||
|
||||
v = v->v_left;
|
||||
while (v && ((cmp = *name - *v->v_name) ||
|
||||
(cmp = Strcmp(name, v->v_name))))
|
||||
if (cmp < 0)
|
||||
v = v->v_left;
|
||||
else
|
||||
v = v->v_right;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible for putting value in a safe place
|
||||
*/
|
||||
void
|
||||
set(var, val)
|
||||
Char *var, *val;
|
||||
{
|
||||
Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **)));
|
||||
|
||||
vec[0] = val;
|
||||
vec[1] = 0;
|
||||
set1(var, vec, &shvhed);
|
||||
}
|
||||
|
||||
void
|
||||
set1(var, vec, head)
|
||||
Char *var, **vec;
|
||||
struct varent *head;
|
||||
{
|
||||
Char **oldv = vec;
|
||||
|
||||
gflag = 0;
|
||||
tglob(oldv);
|
||||
if (gflag) {
|
||||
vec = globall(oldv);
|
||||
if (vec == 0) {
|
||||
blkfree(oldv);
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
return;
|
||||
}
|
||||
blkfree(oldv);
|
||||
gargv = 0;
|
||||
}
|
||||
setq(var, vec, head);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setq(name, vec, p)
|
||||
Char *name, **vec;
|
||||
struct varent *p;
|
||||
{
|
||||
struct varent *c;
|
||||
int f;
|
||||
|
||||
f = 0; /* tree hangs off the header's left link */
|
||||
while ((c = p->v_link[f]) != NULL) {
|
||||
if ((f = *name - *c->v_name) == 0 &&
|
||||
(f = Strcmp(name, c->v_name)) == 0) {
|
||||
blkfree(c->vec);
|
||||
goto found;
|
||||
}
|
||||
p = c;
|
||||
f = f > 0;
|
||||
}
|
||||
p->v_link[f] = c = (struct varent *) xmalloc((size_t) sizeof(struct varent));
|
||||
c->v_name = Strsave(name);
|
||||
c->v_bal = 0;
|
||||
c->v_left = c->v_right = 0;
|
||||
c->v_parent = p;
|
||||
balance(p, f, 0);
|
||||
found:
|
||||
trim(c->vec = vec);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
unset(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
unset1(v, &shvhed);
|
||||
#ifdef FILEC
|
||||
if (adrof(STRfilec) == 0)
|
||||
filec = 0;
|
||||
#endif
|
||||
if (adrof(STRhistchars) == 0) {
|
||||
HIST = '!';
|
||||
HISTSUB = '^';
|
||||
}
|
||||
if (adrof(STRwordchars) == 0)
|
||||
word_chars = STR_WORD_CHARS;
|
||||
}
|
||||
|
||||
void
|
||||
unset1(v, head)
|
||||
Char *v[];
|
||||
struct varent *head;
|
||||
{
|
||||
struct varent *vp;
|
||||
int cnt;
|
||||
|
||||
while (*++v) {
|
||||
cnt = 0;
|
||||
while ((vp = madrof(*v, head->v_left)) != NULL)
|
||||
unsetv1(vp), cnt++;
|
||||
if (cnt == 0)
|
||||
setname(vis_str(*v));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unsetv(var)
|
||||
Char *var;
|
||||
{
|
||||
struct varent *vp;
|
||||
|
||||
if ((vp = adrof1(var, &shvhed)) == 0)
|
||||
udvar(var);
|
||||
unsetv1(vp);
|
||||
}
|
||||
|
||||
static void
|
||||
unsetv1(p)
|
||||
struct varent *p;
|
||||
{
|
||||
struct varent *c, *pp;
|
||||
int f;
|
||||
|
||||
/*
|
||||
* Free associated memory first to avoid complications.
|
||||
*/
|
||||
blkfree(p->vec);
|
||||
xfree((ptr_t) p->v_name);
|
||||
/*
|
||||
* If p is missing one child, then we can move the other into where p is.
|
||||
* Otherwise, we find the predecessor of p, which is guaranteed to have no
|
||||
* right child, copy it into p, and move it's left child into it.
|
||||
*/
|
||||
if (p->v_right == 0)
|
||||
c = p->v_left;
|
||||
else if (p->v_left == 0)
|
||||
c = p->v_right;
|
||||
else {
|
||||
for (c = p->v_left; c->v_right; c = c->v_right)
|
||||
continue;
|
||||
p->v_name = c->v_name;
|
||||
p->vec = c->vec;
|
||||
p = c;
|
||||
c = p->v_left;
|
||||
}
|
||||
/*
|
||||
* Move c into where p is.
|
||||
*/
|
||||
pp = p->v_parent;
|
||||
f = pp->v_right == p;
|
||||
if ((pp->v_link[f] = c) != NULL)
|
||||
c->v_parent = pp;
|
||||
/*
|
||||
* Free the deleted node, and rebalance.
|
||||
*/
|
||||
xfree((ptr_t) p);
|
||||
balance(pp, f, 1);
|
||||
}
|
||||
|
||||
void
|
||||
setNS(cp)
|
||||
Char *cp;
|
||||
{
|
||||
set(cp, Strsave(STRNULL));
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
shift(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
struct varent *argv;
|
||||
Char *name;
|
||||
|
||||
v++;
|
||||
name = *v;
|
||||
if (name == 0)
|
||||
name = STRargv;
|
||||
else
|
||||
(void) strip(name);
|
||||
argv = adrof(name);
|
||||
if (argv == 0)
|
||||
udvar(name);
|
||||
if (argv->vec[0] == 0)
|
||||
stderror(ERR_NAME | ERR_NOMORE);
|
||||
lshift(argv->vec, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
exportpath(val)
|
||||
Char **val;
|
||||
{
|
||||
Char exppath[BUFSIZ];
|
||||
|
||||
exppath[0] = 0;
|
||||
if (val)
|
||||
while (*val) {
|
||||
if (Strlen(*val) + Strlen(exppath) + 2 > BUFSIZ) {
|
||||
(void) fprintf(csherr,
|
||||
"Warning: ridiculously long PATH truncated\n");
|
||||
break;
|
||||
}
|
||||
if (**val != '/' && (euid == 0 || uid == 0) &&
|
||||
(intact || (intty && isatty(SHOUT))))
|
||||
(void) fprintf(csherr,
|
||||
"Warning: exported path contains relative components.\n");
|
||||
(void) Strcat(exppath, *val++);
|
||||
if (*val == 0 || eq(*val, STRRparen))
|
||||
break;
|
||||
(void) Strcat(exppath, STRcolon);
|
||||
}
|
||||
Setenv(STRPATH, exppath);
|
||||
}
|
||||
|
||||
#ifndef lint
|
||||
/*
|
||||
* Lint thinks these have null effect
|
||||
*/
|
||||
/* macros to do single rotations on node p */
|
||||
#define rright(p) (\
|
||||
t = (p)->v_left,\
|
||||
(t)->v_parent = (p)->v_parent,\
|
||||
((p)->v_left = t->v_right) ? (t->v_right->v_parent = (p)) : 0,\
|
||||
(t->v_right = (p))->v_parent = t,\
|
||||
(p) = t)
|
||||
#define rleft(p) (\
|
||||
t = (p)->v_right,\
|
||||
(t)->v_parent = (p)->v_parent,\
|
||||
((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
|
||||
(t->v_left = (p))->v_parent = t,\
|
||||
(p) = t)
|
||||
#else
|
||||
struct varent *
|
||||
rleft(p)
|
||||
struct varent *p;
|
||||
{
|
||||
return (p);
|
||||
}
|
||||
struct varent *
|
||||
rright(p)
|
||||
struct varent *p;
|
||||
{
|
||||
return (p);
|
||||
}
|
||||
|
||||
#endif /* ! lint */
|
||||
|
||||
|
||||
/*
|
||||
* Rebalance a tree, starting at p and up.
|
||||
* F == 0 means we've come from p's left child.
|
||||
* D == 1 means we've just done a delete, otherwise an insert.
|
||||
*/
|
||||
static void
|
||||
balance(p, f, d)
|
||||
struct varent *p;
|
||||
int f, d;
|
||||
{
|
||||
struct varent *pp;
|
||||
|
||||
#ifndef lint
|
||||
struct varent *t; /* used by the rotate macros */
|
||||
|
||||
#endif
|
||||
int ff;
|
||||
|
||||
/*
|
||||
* Ok, from here on, p is the node we're operating on; pp is it's parent; f
|
||||
* is the branch of p from which we have come; ff is the branch of pp which
|
||||
* is p.
|
||||
*/
|
||||
for (; (pp = p->v_parent) != NULL; p = pp, f = ff) {
|
||||
ff = pp->v_right == p;
|
||||
if (f ^ d) { /* right heavy */
|
||||
switch (p->v_bal) {
|
||||
case -1: /* was left heavy */
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* was balanced */
|
||||
p->v_bal = 1;
|
||||
break;
|
||||
case 1: /* was already right heavy */
|
||||
switch (p->v_right->v_bal) {
|
||||
case 1: /* single rotate */
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal = 0;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* single rotate */
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal = 1;
|
||||
p->v_bal = -1;
|
||||
break;
|
||||
case -1: /* double rotate */
|
||||
(void) rright(p->v_right);
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal =
|
||||
p->v_bal < 1 ? 0 : -1;
|
||||
p->v_right->v_bal =
|
||||
p->v_bal > -1 ? 0 : 1;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* left heavy */
|
||||
switch (p->v_bal) {
|
||||
case 1: /* was right heavy */
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* was balanced */
|
||||
p->v_bal = -1;
|
||||
break;
|
||||
case -1: /* was already left heavy */
|
||||
switch (p->v_left->v_bal) {
|
||||
case -1: /* single rotate */
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_right->v_bal = 0;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* single rotate */
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_right->v_bal = -1;
|
||||
p->v_bal = 1;
|
||||
break;
|
||||
case 1: /* double rotate */
|
||||
(void) rleft(p->v_left);
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_left->v_bal =
|
||||
p->v_bal < 1 ? 0 : -1;
|
||||
p->v_right->v_bal =
|
||||
p->v_bal > -1 ? 0 : 1;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If from insert, then we terminate when p is balanced. If from
|
||||
* delete, then we terminate when p is unbalanced.
|
||||
*/
|
||||
if ((p->v_bal == 0) ^ d)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
plist(p)
|
||||
struct varent *p;
|
||||
{
|
||||
struct varent *c;
|
||||
int len;
|
||||
|
||||
if (setintr)
|
||||
(void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
|
||||
|
||||
for (;;) {
|
||||
while (p->v_left)
|
||||
p = p->v_left;
|
||||
x:
|
||||
if (p->v_parent == 0) /* is it the header? */
|
||||
return;
|
||||
len = blklen(p->vec);
|
||||
(void) fprintf(cshout, "%s\t", short2str(p->v_name));
|
||||
if (len != 1)
|
||||
(void) fputc('(', cshout);
|
||||
blkpr(cshout, p->vec);
|
||||
if (len != 1)
|
||||
(void) fputc(')', cshout);
|
||||
(void) fputc('\n', cshout);
|
||||
if (p->v_right) {
|
||||
p = p->v_right;
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
c = p;
|
||||
p = p->v_parent;
|
||||
} while (p->v_right == c);
|
||||
goto x;
|
||||
}
|
||||
}
|
||||
-472
@@ -1,472 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)str.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#define MALLOC_INCR 128
|
||||
|
||||
/*
|
||||
* tc.str.c: Short string package
|
||||
* This has been a lesson of how to write buggy code!
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
#include <vis.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifdef SHORT_STRINGS
|
||||
|
||||
Char **
|
||||
blk2short(src)
|
||||
char **src;
|
||||
{
|
||||
size_t n;
|
||||
Char **sdst, **dst;
|
||||
|
||||
/*
|
||||
* Count
|
||||
*/
|
||||
for (n = 0; src[n] != NULL; n++)
|
||||
continue;
|
||||
sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *)));
|
||||
|
||||
for (; *src != NULL; src++)
|
||||
*dst++ = SAVE(*src);
|
||||
*dst = NULL;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
char **
|
||||
short2blk(src)
|
||||
Char **src;
|
||||
{
|
||||
size_t n;
|
||||
char **sdst, **dst;
|
||||
|
||||
/*
|
||||
* Count
|
||||
*/
|
||||
for (n = 0; src[n] != NULL; n++)
|
||||
continue;
|
||||
sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *)));
|
||||
|
||||
for (; *src != NULL; src++)
|
||||
*dst++ = strsave(short2str(*src));
|
||||
*dst = NULL;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
str2short(src)
|
||||
char *src;
|
||||
{
|
||||
static Char *sdst;
|
||||
static size_t dstsize = 0;
|
||||
Char *dst, *edst;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == (NULL)) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = (Char *) xmalloc((size_t) dstsize * sizeof(Char));
|
||||
}
|
||||
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
*dst++ = (Char) ((unsigned char) *src++);
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = (Char *) xrealloc((ptr_t) sdst,
|
||||
(size_t) dstsize * sizeof(Char));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
char *
|
||||
short2str(src)
|
||||
Char *src;
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
char *dst, *edst;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == NULL) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = (char *) xmalloc((size_t) dstsize * sizeof(char));
|
||||
}
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
*dst++ = (char) *src++;
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = (char *) xrealloc((ptr_t) sdst,
|
||||
(size_t) dstsize * sizeof(char));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strcpy(dst, src)
|
||||
Char *dst, *src;
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
sdst = dst;
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
continue;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strncpy(dst, src, n)
|
||||
Char *dst, *src;
|
||||
size_t n;
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
if (n == 0)
|
||||
return(dst);
|
||||
|
||||
sdst = dst;
|
||||
do
|
||||
if ((*dst++ = *src++) == '\0') {
|
||||
while (--n != 0)
|
||||
*dst++ = '\0';
|
||||
return(sdst);
|
||||
}
|
||||
while (--n != 0);
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strcat(dst, src)
|
||||
Char *dst, *src;
|
||||
{
|
||||
short *sdst;
|
||||
|
||||
sdst = dst;
|
||||
while (*dst++)
|
||||
continue;
|
||||
--dst;
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
continue;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
#ifdef NOTUSED
|
||||
Char *
|
||||
s_strncat(dst, src, n)
|
||||
Char *dst, *src;
|
||||
size_t n;
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
if (n == 0)
|
||||
return (dst);
|
||||
|
||||
sdst = dst;
|
||||
|
||||
while (*dst++)
|
||||
continue;
|
||||
--dst;
|
||||
|
||||
do
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
return(sdst);
|
||||
while (--n != 0)
|
||||
continue;
|
||||
|
||||
*dst = '\0';
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Char *
|
||||
s_strchr(str, ch)
|
||||
Char *str;
|
||||
int ch;
|
||||
{
|
||||
do
|
||||
if (*str == ch)
|
||||
return (str);
|
||||
while (*str++);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strrchr(str, ch)
|
||||
Char *str;
|
||||
int ch;
|
||||
{
|
||||
Char *rstr;
|
||||
|
||||
rstr = NULL;
|
||||
do
|
||||
if (*str == ch)
|
||||
rstr = str;
|
||||
while (*str++);
|
||||
return (rstr);
|
||||
}
|
||||
|
||||
size_t
|
||||
s_strlen(str)
|
||||
Char *str;
|
||||
{
|
||||
size_t n;
|
||||
|
||||
for (n = 0; *str++; n++)
|
||||
continue;
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
s_strcmp(str1, str2)
|
||||
Char *str1, *str2;
|
||||
{
|
||||
for (; *str1 && *str1 == *str2; str1++, str2++)
|
||||
continue;
|
||||
/*
|
||||
* The following case analysis is necessary so that characters which look
|
||||
* negative collate low against normal characters but high against the
|
||||
* end-of-string NUL.
|
||||
*/
|
||||
if (*str1 == '\0' && *str2 == '\0')
|
||||
return (0);
|
||||
else if (*str1 == '\0')
|
||||
return (-1);
|
||||
else if (*str2 == '\0')
|
||||
return (1);
|
||||
else
|
||||
return (*str1 - *str2);
|
||||
}
|
||||
|
||||
int
|
||||
s_strncmp(str1, str2, n)
|
||||
Char *str1, *str2;
|
||||
size_t n;
|
||||
{
|
||||
if (n == 0)
|
||||
return (0);
|
||||
do {
|
||||
if (*str1 != *str2) {
|
||||
/*
|
||||
* The following case analysis is necessary so that characters
|
||||
* which look negative collate low against normal characters
|
||||
* but high against the end-of-string NUL.
|
||||
*/
|
||||
if (*str1 == '\0')
|
||||
return (-1);
|
||||
else if (*str2 == '\0')
|
||||
return (1);
|
||||
else
|
||||
return (*str1 - *str2);
|
||||
break;
|
||||
}
|
||||
if (*str1 == '\0')
|
||||
return(0);
|
||||
str1++, str2++;
|
||||
} while (--n != 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strsave(s)
|
||||
Char *s;
|
||||
{
|
||||
Char *n;
|
||||
Char *p;
|
||||
|
||||
if (s == 0)
|
||||
s = STRNULL;
|
||||
for (p = s; *p++;)
|
||||
continue;
|
||||
n = p = (Char *) xmalloc((size_t) ((p - s) * sizeof(Char)));
|
||||
while ((*p++ = *s++) != '\0')
|
||||
continue;
|
||||
return (n);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strspl(cp, dp)
|
||||
Char *cp, *dp;
|
||||
{
|
||||
Char *ep;
|
||||
Char *p, *q;
|
||||
|
||||
if (!cp)
|
||||
cp = STRNULL;
|
||||
if (!dp)
|
||||
dp = STRNULL;
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
for (q = dp; *q++;)
|
||||
continue;
|
||||
ep = (Char *) xmalloc((size_t)
|
||||
(((p - cp) + (q - dp) - 1) * sizeof(Char)));
|
||||
for (p = ep, q = cp; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
for (p--, q = dp; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
return (ep);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strend(cp)
|
||||
Char *cp;
|
||||
{
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while (*cp)
|
||||
cp++;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strstr(s, t)
|
||||
Char *s, *t;
|
||||
{
|
||||
do {
|
||||
Char *ss = s;
|
||||
Char *tt = t;
|
||||
|
||||
do
|
||||
if (*tt == '\0')
|
||||
return (s);
|
||||
while (*ss++ == *tt++);
|
||||
} while (*s++ != '\0');
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
char *
|
||||
short2qstr(src)
|
||||
Char *src;
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
char *dst, *edst;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == NULL) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = (char *) xmalloc((size_t) dstsize * sizeof(char));
|
||||
}
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
if (*src & QUOTE) {
|
||||
*dst++ = '\\';
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = (char *) xrealloc((ptr_t) sdst,
|
||||
(size_t) dstsize * sizeof(char));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst++ = (char) *src++;
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = (char *) xrealloc((ptr_t) sdst,
|
||||
(size_t) dstsize * sizeof(char));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Should we worry about QUOTE'd chars?
|
||||
*/
|
||||
char *
|
||||
vis_str(cp)
|
||||
Char *cp;
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
size_t n;
|
||||
Char *dp;
|
||||
|
||||
if (cp == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (dp = cp; *dp++;)
|
||||
continue;
|
||||
n = ((dp - cp) << 2) + 1; /* 4 times + NULL */
|
||||
if (dstsize < n) {
|
||||
sdst = (char *) (dstsize ?
|
||||
xrealloc(sdst, (size_t) n * sizeof(char)) :
|
||||
xmalloc((size_t) n * sizeof(char)));
|
||||
dstsize = n;
|
||||
}
|
||||
/*
|
||||
* XXX: When we are in AsciiOnly we want all characters >= 0200 to
|
||||
* be encoded, but currently there is no way in vis to do that.
|
||||
*/
|
||||
(void) strvis(sdst, short2str(cp), VIS_NOSLASH);
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
+2709
File diff suppressed because it is too large.
Load diff
-321
@@ -1,321 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#if __STDC__
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* C Shell - routines handling process timing and niceing
|
||||
*/
|
||||
static void pdeltat __P((struct timeval *, struct timeval *));
|
||||
|
||||
void
|
||||
settimes()
|
||||
{
|
||||
struct rusage ruch;
|
||||
|
||||
(void) gettimeofday(&time0, NULL);
|
||||
(void) getrusage(RUSAGE_SELF, &ru0);
|
||||
(void) getrusage(RUSAGE_CHILDREN, &ruch);
|
||||
ruadd(&ru0, &ruch);
|
||||
}
|
||||
|
||||
/*
|
||||
* dotime is only called if it is truly a builtin function and not a
|
||||
* prefix to another command
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dotime(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
struct timeval timedol;
|
||||
struct rusage ru1, ruch;
|
||||
|
||||
(void) getrusage(RUSAGE_SELF, &ru1);
|
||||
(void) getrusage(RUSAGE_CHILDREN, &ruch);
|
||||
ruadd(&ru1, &ruch);
|
||||
(void) gettimeofday(&timedol, NULL);
|
||||
prusage(&ru0, &ru1, &timedol, &time0);
|
||||
}
|
||||
|
||||
/*
|
||||
* donice is only called when it on the line by itself or with a +- value
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
donice(v, t)
|
||||
Char **v;
|
||||
struct command *t;
|
||||
{
|
||||
Char *cp;
|
||||
int nval = 0;
|
||||
|
||||
v++, cp = *v++;
|
||||
if (cp == 0)
|
||||
nval = 4;
|
||||
else if (*v == 0 && any("+-", cp[0]))
|
||||
nval = getn(cp);
|
||||
(void) setpriority(PRIO_PROCESS, 0, nval);
|
||||
}
|
||||
|
||||
void
|
||||
ruadd(ru, ru2)
|
||||
struct rusage *ru, *ru2;
|
||||
{
|
||||
tvadd(&ru->ru_utime, &ru2->ru_utime);
|
||||
tvadd(&ru->ru_stime, &ru2->ru_stime);
|
||||
if (ru2->ru_maxrss > ru->ru_maxrss)
|
||||
ru->ru_maxrss = ru2->ru_maxrss;
|
||||
|
||||
ru->ru_ixrss += ru2->ru_ixrss;
|
||||
ru->ru_idrss += ru2->ru_idrss;
|
||||
ru->ru_isrss += ru2->ru_isrss;
|
||||
ru->ru_minflt += ru2->ru_minflt;
|
||||
ru->ru_majflt += ru2->ru_majflt;
|
||||
ru->ru_nswap += ru2->ru_nswap;
|
||||
ru->ru_inblock += ru2->ru_inblock;
|
||||
ru->ru_oublock += ru2->ru_oublock;
|
||||
ru->ru_msgsnd += ru2->ru_msgsnd;
|
||||
ru->ru_msgrcv += ru2->ru_msgrcv;
|
||||
ru->ru_nsignals += ru2->ru_nsignals;
|
||||
ru->ru_nvcsw += ru2->ru_nvcsw;
|
||||
ru->ru_nivcsw += ru2->ru_nivcsw;
|
||||
}
|
||||
|
||||
void
|
||||
prusage(r0, r1, e, b)
|
||||
struct rusage *r0, *r1;
|
||||
struct timeval *e, *b;
|
||||
{
|
||||
time_t t =
|
||||
(r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
|
||||
(r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
|
||||
(r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
|
||||
(r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
|
||||
char *cp;
|
||||
long i;
|
||||
struct varent *vp = adrof(STRtime);
|
||||
|
||||
int ms =
|
||||
(e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000;
|
||||
|
||||
cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
|
||||
|
||||
if (vp && vp->vec[0] && vp->vec[1])
|
||||
cp = short2str(vp->vec[1]);
|
||||
|
||||
for (; *cp; cp++)
|
||||
if (*cp != '%')
|
||||
(void) fputc(*cp, cshout);
|
||||
else if (cp[1])
|
||||
switch (*++cp) {
|
||||
|
||||
case 'U': /* user CPU time used */
|
||||
pdeltat(&r1->ru_utime, &r0->ru_utime);
|
||||
break;
|
||||
|
||||
case 'S': /* system CPU time used */
|
||||
pdeltat(&r1->ru_stime, &r0->ru_stime);
|
||||
break;
|
||||
|
||||
case 'E': /* elapsed (wall-clock) time */
|
||||
pcsecs((long) ms);
|
||||
break;
|
||||
|
||||
case 'P': /* percent time spent running */
|
||||
/* check if it did not run at all */
|
||||
i = (ms == 0) ? 0 : (t * 1000 / ms);
|
||||
/* nn.n% */
|
||||
(void) fprintf(cshout, "%ld.%01ld%%", i / 10, i % 10);
|
||||
break;
|
||||
|
||||
case 'W': /* number of swaps */
|
||||
i = r1->ru_nswap - r0->ru_nswap;
|
||||
(void) fprintf(cshout, "%ld", i);
|
||||
break;
|
||||
|
||||
case 'X': /* (average) shared text size */
|
||||
(void) fprintf(cshout, "%ld", t == 0 ? 0L :
|
||||
(r1->ru_ixrss - r0->ru_ixrss) / t);
|
||||
break;
|
||||
|
||||
case 'D': /* (average) unshared data size */
|
||||
(void) fprintf(cshout, "%ld", t == 0 ? 0L :
|
||||
(r1->ru_idrss + r1->ru_isrss -
|
||||
(r0->ru_idrss + r0->ru_isrss)) / t);
|
||||
break;
|
||||
|
||||
case 'K': /* (average) total data memory used */
|
||||
(void) fprintf(cshout, "%ld", t == 0 ? 0L :
|
||||
((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
|
||||
(r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t);
|
||||
break;
|
||||
|
||||
case 'M': /* max. Resident Set Size */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_maxrss / 2L);
|
||||
break;
|
||||
|
||||
case 'F': /* page faults */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_majflt - r0->ru_majflt);
|
||||
break;
|
||||
|
||||
case 'R': /* page reclaims */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_minflt - r0->ru_minflt);
|
||||
break;
|
||||
|
||||
case 'I': /* FS blocks in */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_inblock - r0->ru_inblock);
|
||||
break;
|
||||
|
||||
case 'O': /* FS blocks out */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_oublock - r0->ru_oublock);
|
||||
break;
|
||||
|
||||
case 'r': /* socket messages received */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_msgrcv - r0->ru_msgrcv);
|
||||
break;
|
||||
|
||||
case 's': /* socket messages sent */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_msgsnd - r0->ru_msgsnd);
|
||||
break;
|
||||
|
||||
case 'k': /* number of signals received */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_nsignals-r0->ru_nsignals);
|
||||
break;
|
||||
|
||||
case 'w': /* num. voluntary context switches (waits) */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_nvcsw - r0->ru_nvcsw);
|
||||
break;
|
||||
|
||||
case 'c': /* num. involuntary context switches */
|
||||
(void) fprintf(cshout, "%ld", r1->ru_nivcsw - r0->ru_nivcsw);
|
||||
break;
|
||||
}
|
||||
(void) fputc('\n', cshout);
|
||||
}
|
||||
|
||||
static void
|
||||
pdeltat(t1, t0)
|
||||
struct timeval *t1, *t0;
|
||||
{
|
||||
struct timeval td;
|
||||
|
||||
tvsub(&td, t1, t0);
|
||||
(void) fprintf(cshout, "%ld.%01ld", td.tv_sec, td.tv_usec / 100000L);
|
||||
}
|
||||
|
||||
void
|
||||
tvadd(tsum, t0)
|
||||
struct timeval *tsum, *t0;
|
||||
{
|
||||
|
||||
tsum->tv_sec += t0->tv_sec;
|
||||
tsum->tv_usec += t0->tv_usec;
|
||||
if (tsum->tv_usec >= 1000000)
|
||||
tsum->tv_sec++, tsum->tv_usec -= 1000000;
|
||||
}
|
||||
|
||||
void
|
||||
tvsub(tdiff, t1, t0)
|
||||
struct timeval *tdiff, *t1, *t0;
|
||||
{
|
||||
|
||||
tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||
tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||
if (tdiff->tv_usec < 0)
|
||||
tdiff->tv_sec--, tdiff->tv_usec += 1000000;
|
||||
}
|
||||
|
||||
#define P2DIG(i) (void) fprintf(cshout, "%d%d", (i) / 10, (i) % 10)
|
||||
|
||||
void
|
||||
psecs(l)
|
||||
long l;
|
||||
{
|
||||
int i;
|
||||
|
||||
i = l / 3600;
|
||||
if (i) {
|
||||
(void) fprintf(cshout, "%d:", i);
|
||||
i = l % 3600;
|
||||
P2DIG(i / 60);
|
||||
goto minsec;
|
||||
}
|
||||
i = l;
|
||||
(void) fprintf(cshout, "%d", i / 60);
|
||||
minsec:
|
||||
i %= 60;
|
||||
(void) fputc(':', cshout);
|
||||
P2DIG(i);
|
||||
}
|
||||
|
||||
void
|
||||
pcsecs(l) /* PWP: print mm:ss.dd, l is in sec*100 */
|
||||
long l;
|
||||
{
|
||||
int i;
|
||||
|
||||
i = l / 360000;
|
||||
if (i) {
|
||||
(void) fprintf(cshout, "%d:", i);
|
||||
i = (l % 360000) / 100;
|
||||
P2DIG(i / 60);
|
||||
goto minsec;
|
||||
}
|
||||
i = l / 100;
|
||||
(void) fprintf(cshout, "%d", i / 60);
|
||||
minsec:
|
||||
i %= 60;
|
||||
(void) fputc(':', cshout);
|
||||
P2DIG(i);
|
||||
(void) fputc('.', cshout);
|
||||
P2DIG((int) (l % 100));
|
||||
}
|
||||
+87
-57
@@ -61,23 +61,26 @@
|
||||
.Oc
|
||||
.Op Cm + Ns Ar format
|
||||
.Sh DESCRIPTION
|
||||
.Nm Date
|
||||
displays the current date and time when invoked without arguments.
|
||||
Providing arguments will format the date and time in a user-defined
|
||||
way or set the date.
|
||||
When invoked without arguments, the
|
||||
.Nm
|
||||
utility displays the current date and time.
|
||||
Otherwise, depending on the options specified,
|
||||
.Nm
|
||||
will set the date and time or print it in a user-defined way.
|
||||
.Pp
|
||||
Only the superuser may set the date.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d
|
||||
Set the kernel's value for daylight savings time.
|
||||
.It Fl d Ar dst
|
||||
Set the kernel's value for daylight saving time.
|
||||
If
|
||||
.Ar dst
|
||||
is non-zero, future calls
|
||||
to
|
||||
.Xr gettimeofday 2
|
||||
will return a non-zero
|
||||
.Ql tz_dsttime .
|
||||
will return a non-zero for
|
||||
.Fa tz_dsttime .
|
||||
.It Fl f
|
||||
Use
|
||||
.Ar fmt
|
||||
@@ -89,61 +92,64 @@ the default
|
||||
.Oc "\&yy" Oc "\&mm" Oc "\&dd" Oc "\&HH" Ns
|
||||
.Oc
|
||||
.No "\&MM" Ns Op "\&.ss" Xc
|
||||
format. Parsing is done using
|
||||
format.
|
||||
Parsing is done using
|
||||
.Xr strptime 3 .
|
||||
.It Fl j
|
||||
Do not try to set the date. This allows you to use the
|
||||
Do not try to set the date.
|
||||
This allows you to use the
|
||||
.Fl f
|
||||
flag in addition to the
|
||||
.Cm +
|
||||
option to convert one date format to another.
|
||||
.It Fl n
|
||||
The utility
|
||||
By default, if the
|
||||
.Xr timed 8
|
||||
is used to synchronize the clocks on groups of machines.
|
||||
By default, if
|
||||
.Xr timed
|
||||
is running,
|
||||
daemon is running,
|
||||
.Nm
|
||||
will set the time on all of the machines in the local group.
|
||||
sets the time on all of the machines in the local group.
|
||||
The
|
||||
.Fl n
|
||||
option stops
|
||||
.Nm
|
||||
from setting the time for other than the current machine.
|
||||
.It Fl r
|
||||
Print out the date and time that is
|
||||
option suppresses this behavior and causes the time to be set only on the
|
||||
current machine.
|
||||
.It Fl r Ar seconds
|
||||
Print the date and time represented by
|
||||
.Ar seconds ,
|
||||
where
|
||||
.Ar seconds
|
||||
from the Epoch
|
||||
is the number of seconds since the Epoch
|
||||
.Po
|
||||
00:00:00 UTC, January 1, 1970;
|
||||
see
|
||||
.Xr time 3
|
||||
.Pc .
|
||||
.It Fl t
|
||||
Set the kernel's value for minutes west of
|
||||
.It Fl t Ar minutes_west
|
||||
Set the system's value for minutes west of
|
||||
.Tn GMT .
|
||||
.Ar Minutes_west
|
||||
.Ar minutes_west
|
||||
specifies the number of minutes returned in
|
||||
.Ql tz_minuteswest
|
||||
.Fa tz_minuteswest
|
||||
by future calls to
|
||||
.Xr gettimeofday 2 .
|
||||
.It Fl u
|
||||
Display or set the date in
|
||||
.Tn UCT
|
||||
.Pq universal
|
||||
time.
|
||||
.Tn UTC
|
||||
(Coordinated Universal) time.
|
||||
.It Fl v
|
||||
Adjust the second, minute, hour, month day, week day, month or year according to
|
||||
Adjust the second, minute, hour, month day, week day,
|
||||
month or year according to
|
||||
.Ar val .
|
||||
If
|
||||
.Ar val
|
||||
is preceded with a plus or minus sign, the date is adjusted forwards
|
||||
or backwards according to the remaining string, otherwise the relevant
|
||||
part of the date is set. The date can be adjusted as many times as
|
||||
required using these flags. Flags are processed in the order given.
|
||||
is preceded with a plus or minus sign,
|
||||
the date is adjusted forwards or backwards according to the remaining string,
|
||||
otherwise the relevant part of the date is set.
|
||||
The date can be adjusted as many times as required using these flags.
|
||||
Flags are processed in the order given.
|
||||
.Pp
|
||||
Seconds are in the range 0-59, minutes are in the range 0-59, hours are
|
||||
When setting values
|
||||
.Pq rather than adjusting them ,
|
||||
seconds are in the range 0-59, minutes are in the range 0-59, hours are
|
||||
in the range 1-12, month days are in the range 1-31, week days are in the
|
||||
range 0-6
|
||||
.Pq Sun-Sat ,
|
||||
@@ -165,26 +171,52 @@ or
|
||||
must be used to specify which part of the date is to be adjusted.
|
||||
.Pp
|
||||
The week day or month may be specified using a name rather than a
|
||||
number. If a name is used with the plus
|
||||
number.
|
||||
If a name is used with the plus
|
||||
.Pq or minus
|
||||
sign, the date will be put forwards
|
||||
.Pq or backwards
|
||||
to the next
|
||||
.Pq previous
|
||||
date that matches the given week day or month. This will not adjust the date
|
||||
date that matches the given week day or month.
|
||||
This will not adjust the date,
|
||||
if the given week day or month is the same as the current one.
|
||||
.Pp
|
||||
When a date is adjusted to a specific value or in units greater than hours,
|
||||
daylight savings time considerations are ignored.
|
||||
Adjustments in units of hours or less honor daylight saving time.
|
||||
So, assuming the current date is March 26, 0:30 and that the DST adjustment
|
||||
means that the clock goes forward at 01:00 to 02:00, using
|
||||
.Fl v No +1H
|
||||
will adjust the date to March 26, 2:30.
|
||||
Likewise, if the date is October 29, 0:30 and the DST adjustment means that
|
||||
the clock goes back at 02:00 to 01:00, using
|
||||
.Fl v No +3H
|
||||
will be necessary to reach October 29, 2:30.
|
||||
.Pp
|
||||
When the date is adjusted to a specific value that doesn't actually exist
|
||||
.Pq for example March 26, 1:30 BST 2000 in the Europe/London timezone ,
|
||||
the date will be silently adjusted forwards in units of one hour until it
|
||||
reaches a valid time.
|
||||
When the date is adjusted to a specific value that occurs twice
|
||||
.Pq for example October 29, 1:30 2000 ,
|
||||
the resulting timezone will be set so that the date matches the earlier of
|
||||
the two times.
|
||||
.Pp
|
||||
Refer to the examples below for further details.
|
||||
.El
|
||||
.Pp
|
||||
An operand with a leading plus
|
||||
.Pq Dq \&+
|
||||
sign signals a user-defined format string which specifies the format in
|
||||
which to display the date and time. The format string may contain any of
|
||||
the conversion specifications described in the
|
||||
.Pq Sq +
|
||||
sign signals a user-defined format string
|
||||
which specifies the format in which to display the date and time.
|
||||
The format string may contain any of the conversion specifications
|
||||
described in the
|
||||
.Xr strftime 3
|
||||
manual page, as well as any arbitrary text.
|
||||
A <newline> character is always output after the characters specified by
|
||||
A newline
|
||||
.Pq Ql \en
|
||||
character is always output after the characters specified by
|
||||
the format string.
|
||||
The format string for the default display is
|
||||
.Dq +%+ .
|
||||
@@ -202,23 +234,22 @@ prepended to the abbreviated year.
|
||||
Year in abbreviated form
|
||||
.Pq e.g. 89 for 1989, 06 for 2006 .
|
||||
.It Ar mm
|
||||
Numeric month.
|
||||
A number from 1 to 12.
|
||||
Numeric month, a number from 1 to 12.
|
||||
.It Ar dd
|
||||
Day, a number from 1 to 31.
|
||||
.It Ar HH
|
||||
Hour, a number from 0 to 23.
|
||||
.It Ar MM
|
||||
Minutes, a number from 0 to 59.
|
||||
.It Ar .ss
|
||||
.It Ar ss
|
||||
Seconds, a number from 0 to 61
|
||||
.Pq 59 plus a maximum of two leap seconds .
|
||||
.El
|
||||
.Pp
|
||||
Everything but the minutes is optional.
|
||||
.Pp
|
||||
Time changes for Daylight Saving and Standard time and leap seconds
|
||||
and years are handled automatically.
|
||||
Time changes for Daylight Saving Time, standard time, leap seconds,
|
||||
and leap years are handled automatically.
|
||||
.Sh EXAMPLES
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
@@ -231,14 +262,14 @@ DATE: 1987-11-21
|
||||
TIME: 13:36:16
|
||||
.Ed
|
||||
.Pp
|
||||
The command:
|
||||
In the Europe/London timezone, the command:
|
||||
.Bd -literal -offset indent
|
||||
date -v1m -v+1y
|
||||
.Ed
|
||||
.Pp
|
||||
will display:
|
||||
.Bd -literal -offset indent
|
||||
Sun Jan 4 03:15:24 GMT 1998
|
||||
Sun Jan 4 04:15:24 GMT 1998
|
||||
.Ed
|
||||
.Pp
|
||||
where it is currently Mon Aug 4 04:15:24 BST 1997.
|
||||
@@ -282,9 +313,8 @@ sets the time to
|
||||
.Li "2:32 PM" ,
|
||||
without modifying the date.
|
||||
.Sh ENVIRONMENT
|
||||
The execution of
|
||||
.Nm
|
||||
is affected by the following environment variables:
|
||||
The following environment variables affect the execution of
|
||||
.Nm Ns :
|
||||
.Bl -tag -width Ds
|
||||
.It Ev TZ
|
||||
The timezone to use when displaying dates.
|
||||
@@ -300,9 +330,9 @@ for more information.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/messages -compact
|
||||
.It Pa /var/log/wtmp
|
||||
a record of date resets and time changes
|
||||
record of date resets and time changes
|
||||
.It Pa /var/log/messages
|
||||
a record of the user setting the time
|
||||
record of the user setting the time
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gettimeofday 2 ,
|
||||
@@ -322,7 +352,7 @@ utility exits 0 on success, 1 if unable to set the date, and 2
|
||||
if able to set the local date, but unable to set it globally.
|
||||
.Pp
|
||||
Occasionally, when
|
||||
.Xr timed
|
||||
.Xr timed 8
|
||||
synchronizes the time on many hosts, the setting of a new time value may
|
||||
require more than a few seconds.
|
||||
On these occasions,
|
||||
@@ -335,12 +365,12 @@ occurs when the communication
|
||||
between
|
||||
.Nm
|
||||
and
|
||||
.Xr timed
|
||||
.Xr timed 8
|
||||
fails.
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
command is expected to be compatible with
|
||||
utility is expected to be compatible with
|
||||
.St -p1003.2 .
|
||||
.Sh HISTORY
|
||||
A
|
||||
|
||||
+3
-3
@@ -118,15 +118,15 @@ main(argc, argv)
|
||||
rflag = 1;
|
||||
tval = atol(optarg);
|
||||
break;
|
||||
case 't': /* minutes west of GMT */
|
||||
case 't': /* minutes west of UTC */
|
||||
/* error check; don't allow "PST" */
|
||||
tz.tz_minuteswest = strtol(optarg, &endptr, 10);
|
||||
if (endptr == optarg || *endptr != '\0')
|
||||
usage();
|
||||
set_timezone = 1;
|
||||
break;
|
||||
case 'u': /* do everything in GMT */
|
||||
(void)setenv("TZ", "GMT0", 1);
|
||||
case 'u': /* do everything in UTC */
|
||||
(void)setenv("TZ", "UTC0", 1);
|
||||
break;
|
||||
case 'v':
|
||||
v = vary_append(v, optarg);
|
||||
|
||||
+125
-84
@@ -53,6 +53,19 @@ static struct trans trans_wday[] = {
|
||||
};
|
||||
|
||||
static char digits[] = "0123456789";
|
||||
static int adjhour(struct tm *, char, int, int);
|
||||
|
||||
static int
|
||||
domktime(struct tm *t, char type)
|
||||
{
|
||||
time_t ret;
|
||||
|
||||
while ((ret = mktime(t)) == -1 && t->tm_year > 68 && t->tm_year < 138)
|
||||
/* While mktime() fails, adjust by an hour */
|
||||
adjhour(t, type == '-' ? type : '+', 1, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
trans(const struct trans t[], const char *arg)
|
||||
@@ -112,7 +125,7 @@ daysinmonth(const struct tm *t)
|
||||
|
||||
|
||||
static int
|
||||
adjyear(struct tm *t, char type, int val)
|
||||
adjyear(struct tm *t, char type, int val, int mk)
|
||||
{
|
||||
switch (type) {
|
||||
case '+':
|
||||
@@ -129,11 +142,11 @@ adjyear(struct tm *t, char type, int val)
|
||||
t->tm_year -= 1900; /* struct tm holds years since 1900 */
|
||||
break;
|
||||
}
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjmon(struct tm *t, char type, int val, int istext)
|
||||
adjmon(struct tm *t, char type, int val, int istext, int mk)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
@@ -146,12 +159,14 @@ adjmon(struct tm *t, char type, int val, int istext)
|
||||
else
|
||||
val -= t->tm_mon + 1; /* later this year */
|
||||
}
|
||||
if (!adjyear(t, '+', (t->tm_mon + val) / 12))
|
||||
return 0;
|
||||
val %= 12;
|
||||
t->tm_mon += val;
|
||||
if (t->tm_mon > 11)
|
||||
t->tm_mon -= 12;
|
||||
if (val) {
|
||||
if (!adjyear(t, '+', (t->tm_mon + val) / 12, 0))
|
||||
return 0;
|
||||
val %= 12;
|
||||
t->tm_mon += val;
|
||||
if (t->tm_mon > 11)
|
||||
t->tm_mon -= 12;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
@@ -161,15 +176,17 @@ adjmon(struct tm *t, char type, int val, int istext)
|
||||
else
|
||||
val = t->tm_mon - val + 1; /* early this year */
|
||||
}
|
||||
if (!adjyear(t, '-', val / 12))
|
||||
return 0;
|
||||
val %= 12;
|
||||
if (val > t->tm_mon) {
|
||||
if (!adjyear(t, '-', 1))
|
||||
if (val) {
|
||||
if (!adjyear(t, '-', val / 12, 0))
|
||||
return 0;
|
||||
val -= 12;
|
||||
val %= 12;
|
||||
if (val > t->tm_mon) {
|
||||
if (!adjyear(t, '-', 1, 0))
|
||||
return 0;
|
||||
val -= 12;
|
||||
}
|
||||
t->tm_mon -= val;
|
||||
}
|
||||
t->tm_mon -= val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -178,13 +195,14 @@ adjmon(struct tm *t, char type, int val, int istext)
|
||||
t->tm_mon = --val;
|
||||
}
|
||||
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjday(struct tm *t, char type, int val)
|
||||
adjday(struct tm *t, char type, int val, int mk)
|
||||
{
|
||||
int mdays;
|
||||
|
||||
switch (type) {
|
||||
case '+':
|
||||
while (val) {
|
||||
@@ -192,7 +210,7 @@ adjday(struct tm *t, char type, int val)
|
||||
if (val > mdays - t->tm_mday) {
|
||||
val -= mdays - t->tm_mday + 1;
|
||||
t->tm_mday = 1;
|
||||
if (!adjmon(t, '+', 1, 0))
|
||||
if (!adjmon(t, '+', 1, 0, 0))
|
||||
return 0;
|
||||
} else {
|
||||
t->tm_mday += val;
|
||||
@@ -205,7 +223,7 @@ adjday(struct tm *t, char type, int val)
|
||||
if (val >= t->tm_mday) {
|
||||
val -= t->tm_mday;
|
||||
t->tm_mday = 1;
|
||||
if (!adjmon(t, '-', 1, 0))
|
||||
if (!adjmon(t, '-', 1, 0, 0))
|
||||
return 0;
|
||||
t->tm_mday = daysinmonth(t);
|
||||
} else {
|
||||
@@ -221,11 +239,11 @@ adjday(struct tm *t, char type, int val)
|
||||
break;
|
||||
}
|
||||
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjwday(struct tm *t, char type, int val, int istext)
|
||||
adjwday(struct tm *t, char type, int val, int istext, int mk)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
@@ -238,54 +256,62 @@ adjwday(struct tm *t, char type, int val, int istext)
|
||||
else
|
||||
val -= t->tm_wday; /* later this week */
|
||||
else
|
||||
val *= 7; /* "-W +5" == "5 weeks in the future" */
|
||||
return adjday(t, '+', val);
|
||||
val *= 7; /* "-v+5w" == "5 weeks in the future" */
|
||||
return !val || adjday(t, '+', val, mk);
|
||||
case '-':
|
||||
if (istext)
|
||||
if (istext) {
|
||||
if (val > t->tm_wday)
|
||||
val = 7 - val + t->tm_wday; /* later last week */
|
||||
else
|
||||
val = t->tm_wday - val; /* early this week */
|
||||
else
|
||||
val *= 7; /* "-W -5" == "5 weeks ago" */
|
||||
return adjday(t, '-', val);
|
||||
} else
|
||||
val *= 7; /* "-v-5w" == "5 weeks ago" */
|
||||
return !val || adjday(t, '-', val, mk);
|
||||
default:
|
||||
if (val < t->tm_wday)
|
||||
return adjday(t, '-', t->tm_wday - val);
|
||||
return adjday(t, '-', t->tm_wday - val, mk);
|
||||
else if (val > 6)
|
||||
return 0;
|
||||
else if (val > t->tm_wday)
|
||||
return adjday(t, '+', val - t->tm_wday);
|
||||
return adjday(t, '+', val - t->tm_wday, mk);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjhour(struct tm *t, char type, int val)
|
||||
adjhour(struct tm *t, char type, int val, int mk)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case '+':
|
||||
if (!adjday(t, '+', (t->tm_hour + val) / 24))
|
||||
return 0;
|
||||
val %= 24;
|
||||
t->tm_hour += val;
|
||||
if (t->tm_hour > 23)
|
||||
t->tm_hour -= 24;
|
||||
if (val) {
|
||||
int days;
|
||||
|
||||
days = (t->tm_hour + val) / 24;
|
||||
val %= 24;
|
||||
t->tm_hour += val;
|
||||
t->tm_hour %= 24;
|
||||
if (!adjday(t, '+', days, 0))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (!adjday(t, '-', val / 24))
|
||||
return 0;
|
||||
val %= 24;
|
||||
if (val > t->tm_hour) {
|
||||
if (!adjday(t, '-', 1))
|
||||
if (val) {
|
||||
int days;
|
||||
|
||||
days = val / 24;
|
||||
val %= 24;
|
||||
if (val > t->tm_hour) {
|
||||
days++;
|
||||
val -= 24;
|
||||
}
|
||||
t->tm_hour -= val;
|
||||
if (!adjday(t, '-', days, 0))
|
||||
return 0;
|
||||
val -= 24;
|
||||
}
|
||||
t->tm_hour -= val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -294,35 +320,39 @@ adjhour(struct tm *t, char type, int val)
|
||||
t->tm_hour = val;
|
||||
}
|
||||
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjmin(struct tm *t, char type, int val)
|
||||
adjmin(struct tm *t, char type, int val, int mk)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case '+':
|
||||
if (!adjhour(t, '+', (t->tm_min + val) / 60))
|
||||
return 0;
|
||||
val %= 60;
|
||||
t->tm_min += val;
|
||||
if (t->tm_min > 59)
|
||||
t->tm_min -= 60;
|
||||
if (val) {
|
||||
if (!adjhour(t, '+', (t->tm_min + val) / 60, 0))
|
||||
return 0;
|
||||
val %= 60;
|
||||
t->tm_min += val;
|
||||
if (t->tm_min > 59)
|
||||
t->tm_min -= 60;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (!adjhour(t, '-', val / 60))
|
||||
return 0;
|
||||
val %= 60;
|
||||
if (val > t->tm_min) {
|
||||
if (!adjhour(t, '-', 1))
|
||||
if (val) {
|
||||
if (!adjhour(t, '-', val / 60, 0))
|
||||
return 0;
|
||||
val -= 60;
|
||||
val %= 60;
|
||||
if (val > t->tm_min) {
|
||||
if (!adjhour(t, '-', 1, 0))
|
||||
return 0;
|
||||
val -= 60;
|
||||
}
|
||||
t->tm_min -= val;
|
||||
}
|
||||
t->tm_min -= val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -331,35 +361,39 @@ adjmin(struct tm *t, char type, int val)
|
||||
t->tm_min = val;
|
||||
}
|
||||
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
static int
|
||||
adjsec(struct tm *t, char type, int val)
|
||||
adjsec(struct tm *t, char type, int val, int mk)
|
||||
{
|
||||
if (val < 0)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case '+':
|
||||
if (!adjmin(t, '+', (t->tm_sec + val) / 60))
|
||||
return 0;
|
||||
val %= 60;
|
||||
t->tm_sec += val;
|
||||
if (t->tm_sec > 59)
|
||||
t->tm_sec -= 60;
|
||||
if (val) {
|
||||
if (!adjmin(t, '+', (t->tm_sec + val) / 60, 0))
|
||||
return 0;
|
||||
val %= 60;
|
||||
t->tm_sec += val;
|
||||
if (t->tm_sec > 59)
|
||||
t->tm_sec -= 60;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (!adjmin(t, '-', val / 60))
|
||||
return 0;
|
||||
val %= 60;
|
||||
if (val > t->tm_sec) {
|
||||
if (!adjmin(t, '-', 1))
|
||||
if (val) {
|
||||
if (!adjmin(t, '-', val / 60, 0))
|
||||
return 0;
|
||||
val -= 60;
|
||||
val %= 60;
|
||||
if (val > t->tm_sec) {
|
||||
if (!adjmin(t, '-', 1, 0))
|
||||
return 0;
|
||||
val -= 60;
|
||||
}
|
||||
t->tm_sec -= val;
|
||||
}
|
||||
t->tm_sec -= val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -368,7 +402,7 @@ adjsec(struct tm *t, char type, int val)
|
||||
t->tm_sec = val;
|
||||
}
|
||||
|
||||
return mktime(t) != -1;
|
||||
return !mk || domktime(t, type) != -1;
|
||||
}
|
||||
|
||||
const struct vary *
|
||||
@@ -391,15 +425,18 @@ vary_apply(const struct vary *v, struct tm *t)
|
||||
if (len < 2)
|
||||
return v;
|
||||
|
||||
if (type == '\0')
|
||||
t->tm_isdst = -1;
|
||||
|
||||
if (strspn(arg, digits) != len-1) {
|
||||
val = trans(trans_wday, arg);
|
||||
if (val != -1) {
|
||||
if (!adjwday(t, type, val, 1))
|
||||
if (!adjwday(t, type, val, 1, 1))
|
||||
return v;
|
||||
} else {
|
||||
val = trans(trans_mon, arg);
|
||||
if (val != -1) {
|
||||
if (!adjmon(t, type, val, 1))
|
||||
if (!adjmon(t, type, val, 1, 1))
|
||||
return v;
|
||||
} else
|
||||
return v;
|
||||
@@ -410,31 +447,35 @@ vary_apply(const struct vary *v, struct tm *t)
|
||||
|
||||
switch (which) {
|
||||
case 'S':
|
||||
if (!adjsec(t, type, val))
|
||||
if (!adjsec(t, type, val, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'M':
|
||||
if (!adjmin(t, type, val))
|
||||
if (!adjmin(t, type, val, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'H':
|
||||
if (!adjhour(t, type, val))
|
||||
if (!adjhour(t, type, val, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'd':
|
||||
if (!adjday(t, type, val))
|
||||
t->tm_isdst = -1;
|
||||
if (!adjday(t, type, val, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'w':
|
||||
if (!adjwday(t, type, val, 0))
|
||||
t->tm_isdst = -1;
|
||||
if (!adjwday(t, type, val, 0, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'm':
|
||||
if (!adjmon(t, type, val, 0))
|
||||
t->tm_isdst = -1;
|
||||
if (!adjmon(t, type, val, 0, 1))
|
||||
return v;
|
||||
break;
|
||||
case 'y':
|
||||
if (!adjyear(t, type, val))
|
||||
t->tm_isdst = -1;
|
||||
if (!adjyear(t, type, val, 1))
|
||||
return v;
|
||||
break;
|
||||
default:
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
# $FreeBSD$
|
||||
# @(#)Makefile 8.3 (Berkeley) 5/8/95
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= df
|
||||
SRCS= df.c vfslist.c
|
||||
@@ -8,8 +8,9 @@ BINMODE=2555
|
||||
|
||||
MOUNT= ${.CURDIR}/../../sbin/mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
LDADD+= ${LIBM}
|
||||
DPADD+= ${LIBM}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
DPADD= ${LIBM}
|
||||
LDADD= -lm
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
+9
-1
@@ -40,7 +40,10 @@
|
||||
.Nd display free disk space
|
||||
.Sh SYNOPSIS
|
||||
.Nm df
|
||||
.Op Fl b | h | H | k | m | P
|
||||
.Oo
|
||||
.Fl b | h | H | k |
|
||||
.Fl m | P
|
||||
.Oc
|
||||
.Op Fl ain
|
||||
.Op Fl t Ar type
|
||||
.Op Ar file | Ar filesystem ...
|
||||
@@ -68,6 +71,11 @@ Use 512-byte blocks rather than the default. Note that
|
||||
this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl g
|
||||
Use 1073741824-byte (1-Gbyte) blocks rather than the default. Note that
|
||||
this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl H
|
||||
"Human-readable" output. Use unit suffixes: Byte, Kilobyte, Megabyte,
|
||||
Gigabyte, Terabyte and Petabyte in order to reduce the number of
|
||||
|
||||
+5
-1
@@ -122,7 +122,7 @@ main(argc, argv)
|
||||
char *mntpt, *mntpath, **vfslist;
|
||||
|
||||
vfslist = NULL;
|
||||
while ((ch = getopt(argc, argv, "abHhikmnPt:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "abgHhikmnPt:")) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
@@ -133,6 +133,10 @@ main(argc, argv)
|
||||
putenv("BLOCKSIZE=512");
|
||||
hflag = 0;
|
||||
break;
|
||||
case 'g':
|
||||
putenv("BLOCKSIZE=1g");
|
||||
hflag = 0;
|
||||
break;
|
||||
case 'H':
|
||||
hflag = UNITS_SI;
|
||||
valp = vals_si;
|
||||
|
||||
+2
-4
@@ -6,13 +6,11 @@ extensions and possible deviations from POSIX 1003.2.
|
||||
|
||||
OMISSIONS
|
||||
---------
|
||||
1) Locale(3) is not supported yet.
|
||||
|
||||
2) For backwards compatibility, the POSIX rule that says a range of
|
||||
1) For backwards compatibility, the POSIX rule that says a range of
|
||||
addresses cannot be used where only a single address is expected has
|
||||
been relaxed.
|
||||
|
||||
3) To support the BSD `s' command (see extension [1] below),
|
||||
2) To support the BSD `s' command (see extension [1] below),
|
||||
substitution patterns cannot be delimited by numbers or the characters
|
||||
`r', `g' and `p'. In contrast, POSIX specifies any character expect
|
||||
space or newline can used as a delimiter.
|
||||
|
||||
+2
-1
@@ -835,7 +835,8 @@ attempts to write the buffer if the terminal hangs up
|
||||
USD:12-13
|
||||
|
||||
.Rs
|
||||
.%A B. W. Kernighan and P. J. Plauger
|
||||
.%A B. W. Kernighan
|
||||
.%A P. J. Plauger
|
||||
.%B Software Tools in Pascal
|
||||
.%O Addison-Wesley
|
||||
.%D 1981
|
||||
|
||||
+5
-3
@@ -175,7 +175,9 @@ top:
|
||||
if (read_file(*argv, 0) < 0 && !isatty(0))
|
||||
quit(2);
|
||||
else if (**argv != '!')
|
||||
strcpy(old_filename, *argv);
|
||||
if (strlcpy(old_filename, *argv, sizeof(old_filename))
|
||||
>= sizeof(old_filename))
|
||||
quit(2);
|
||||
} else if (argc) {
|
||||
fputs("?\n", stderr);
|
||||
if (**argv == '\0')
|
||||
@@ -1345,8 +1347,8 @@ strip_escapes(s)
|
||||
int i = 0;
|
||||
|
||||
REALLOC(file, filesz, MAXPATHLEN + 1, NULL);
|
||||
/* assert: no trailing escape */
|
||||
while ((file[i++] = (*s == '\\') ? *++s : *s))
|
||||
while (i < filesz - 1 /* Worry about a possible trailing escape */
|
||||
&& (file[i++] = (*s == '\\') ? *++s : *s))
|
||||
s++;
|
||||
return file;
|
||||
}
|
||||
|
||||
+29
-30
@@ -7,12 +7,14 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <regex.h>
|
||||
|
||||
enum valtype {
|
||||
integer, numeric_string, string
|
||||
@@ -22,7 +24,7 @@ struct val {
|
||||
enum valtype type;
|
||||
union {
|
||||
char *s;
|
||||
int i;
|
||||
quad_t i;
|
||||
} u;
|
||||
} ;
|
||||
|
||||
@@ -87,7 +89,7 @@ expr: TOKEN
|
||||
|
||||
struct val *
|
||||
make_integer (i)
|
||||
int i;
|
||||
quad_t i;
|
||||
{
|
||||
struct val *vp;
|
||||
|
||||
@@ -139,11 +141,11 @@ struct val *vp;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
quad_t
|
||||
to_integer (vp)
|
||||
struct val *vp;
|
||||
{
|
||||
int i;
|
||||
quad_t i;
|
||||
|
||||
if (vp->type == integer)
|
||||
return 1;
|
||||
@@ -152,7 +154,7 @@ struct val *vp;
|
||||
return 0;
|
||||
|
||||
/* vp->type == numeric_string, make it numeric */
|
||||
i = atoi(vp->u.s);
|
||||
i = strtoq(vp->u.s, (char**)NULL, 10);
|
||||
free (vp->u.s);
|
||||
vp->u.i = i;
|
||||
vp->type = integer;
|
||||
@@ -173,7 +175,7 @@ struct val *vp;
|
||||
errx (2, "malloc() failed");
|
||||
}
|
||||
|
||||
sprintf (tmp, "%d", vp->u.i);
|
||||
sprintf (tmp, "%qd", vp->u.i);
|
||||
vp->type = string;
|
||||
vp->u.s = tmp;
|
||||
}
|
||||
@@ -239,7 +241,7 @@ char **argv;
|
||||
yyparse ();
|
||||
|
||||
if (result->type == integer)
|
||||
printf ("%d\n", result->u.i);
|
||||
printf ("%qd\n", result->u.i);
|
||||
else
|
||||
printf ("%s\n", result->u.s);
|
||||
|
||||
@@ -274,7 +276,7 @@ struct val *a, *b;
|
||||
if (is_zero_or_null (a) || is_zero_or_null (b)) {
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return (make_integer (0));
|
||||
return (make_integer ((quad_t)0));
|
||||
} else {
|
||||
free_value (b);
|
||||
return (a);
|
||||
@@ -290,11 +292,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) == 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer (a->u.i == b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i == b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -311,11 +313,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) > 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r= make_integer (a->u.i > b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i > b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -332,11 +334,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) < 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer (a->u.i < b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i < b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -353,11 +355,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) >= 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer (a->u.i >= b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i >= b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -374,11 +376,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) <= 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer (a->u.i <= b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i <= b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -395,11 +397,11 @@ struct val *a, *b;
|
||||
if (isstring (a) || isstring (b)) {
|
||||
to_string (a);
|
||||
to_string (b);
|
||||
r = make_integer (strcoll (a->u.s, b->u.s) != 0);
|
||||
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
|
||||
} else {
|
||||
(void)to_integer(a);
|
||||
(void)to_integer(b);
|
||||
r = make_integer (a->u.i != b->u.i);
|
||||
r = make_integer ((quad_t)(a->u.i != b->u.i));
|
||||
}
|
||||
|
||||
free_value (a);
|
||||
@@ -417,7 +419,7 @@ struct val *a, *b;
|
||||
errx (2, "non-numeric argument");
|
||||
}
|
||||
|
||||
r = make_integer (a->u.i + b->u.i);
|
||||
r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
@@ -433,7 +435,7 @@ struct val *a, *b;
|
||||
errx (2, "non-numeric argument");
|
||||
}
|
||||
|
||||
r = make_integer (a->u.i - b->u.i);
|
||||
r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
@@ -449,7 +451,7 @@ struct val *a, *b;
|
||||
errx (2, "non-numeric argument");
|
||||
}
|
||||
|
||||
r = make_integer (a->u.i * b->u.i);
|
||||
r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return (r);
|
||||
@@ -469,7 +471,7 @@ struct val *a, *b;
|
||||
errx (2, "division by zero");
|
||||
}
|
||||
|
||||
r = make_integer (a->u.i / b->u.i);
|
||||
r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
@@ -489,15 +491,12 @@ struct val *a, *b;
|
||||
errx (2, "division by zero");
|
||||
}
|
||||
|
||||
r = make_integer (a->u.i % b->u.i);
|
||||
r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
|
||||
free_value (a);
|
||||
free_value (b);
|
||||
return r;
|
||||
}
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
|
||||
struct val *
|
||||
op_colon (a, b)
|
||||
struct val *a, *b;
|
||||
@@ -526,11 +525,11 @@ struct val *a, *b;
|
||||
v = make_str (a->u.s + rm[1].rm_so);
|
||||
|
||||
} else {
|
||||
v = make_integer (rm[0].rm_eo - rm[0].rm_so);
|
||||
v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
|
||||
}
|
||||
} else {
|
||||
if (rp.re_nsub == 0) {
|
||||
v = make_integer (0);
|
||||
v = make_integer ((quad_t)0);
|
||||
} else {
|
||||
v = make_str ("");
|
||||
}
|
||||
|
||||
+7
-2
@@ -3,7 +3,12 @@
|
||||
|
||||
|
||||
PROG= ls
|
||||
SRCS= cmp.c setflags.c ls.c print.c util.c
|
||||
.PATH: ${.CURDIR}/../../lib/libc/gen
|
||||
SRCS= cmp.c ls.c print.c util.c
|
||||
|
||||
.if !defined(RELEASE_BUILD_FIXIT)
|
||||
CFLAGS+= -DCOLORLS
|
||||
LDADD+= -ltermcap
|
||||
DPADD+= ${LIBTERMCAP}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
+11
-4
@@ -43,11 +43,18 @@ int revnamecmp __P((const FTSENT *, const FTSENT *));
|
||||
int statcmp __P((const FTSENT *, const FTSENT *));
|
||||
int revstatcmp __P((const FTSENT *, const FTSENT *));
|
||||
|
||||
char *flags_to_string __P((u_long, char *));
|
||||
void prcopy __P((char *, char *, int));
|
||||
void printcol __P((DISPLAY *));
|
||||
void printlong __P((DISPLAY *));
|
||||
void printscol __P((DISPLAY *));
|
||||
void usage __P((void));
|
||||
int len_octal __P((char *, int));
|
||||
int prn_octal __P((char *));
|
||||
int len_octal __P((const char *, int));
|
||||
int prn_octal __P((const char *));
|
||||
int prn_printable __P((const char *));
|
||||
#ifdef COLORLS
|
||||
void parsecolors __P((char *cs));
|
||||
void colorquit __P((int));
|
||||
|
||||
extern char *ansi_fgcol;
|
||||
extern char *ansi_bgcol;
|
||||
extern char *ansi_coloff;
|
||||
#endif
|
||||
+112
-3
@@ -43,7 +43,7 @@
|
||||
.Nd list directory contents
|
||||
.Sh SYNOPSIS
|
||||
.Nm ls
|
||||
.Op Fl ABCFHLPRTWabcdfgiklnoqrstu1
|
||||
.Op Fl ABCFGHLPRTWabcdfgiklnoqrstu1
|
||||
.Op Ar file ...
|
||||
.Sh DESCRIPTION
|
||||
For each operand that names a
|
||||
@@ -90,6 +90,30 @@ an equals sign (=) after each socket,
|
||||
a percent sign (%) after each whiteout,
|
||||
and a vertical bar (|) after each that is a
|
||||
.Tn FIFO .
|
||||
.It Fl G
|
||||
Use
|
||||
.Tn ANSI
|
||||
color sequences to distinguish file types.
|
||||
See
|
||||
.Ev LSCOLORS
|
||||
below.
|
||||
In addition to those mentioned above in
|
||||
.Fl F ,
|
||||
some extra attributes (setuid bit set, etc.) are also displayed.
|
||||
The colorization is dependent on a terminal type with the proper
|
||||
.Xr termcap 5
|
||||
capabilities.
|
||||
The default
|
||||
.Dq cons25
|
||||
console has the proper capabilities,
|
||||
however if you want to display the colors in an
|
||||
.Xr xterm 1
|
||||
for example,
|
||||
you need to set your
|
||||
.Ev TERM
|
||||
variable to
|
||||
.Dq xterm-color .
|
||||
Other terminal types may require similar adjustments.
|
||||
.It Fl H
|
||||
Symbolic links on the command line are followed. This option is assumed if
|
||||
none of the
|
||||
@@ -381,11 +405,85 @@ many pathname text columns to display
|
||||
based on the width provided.
|
||||
(See
|
||||
.Fl C . )
|
||||
.It Ev TZ
|
||||
The timezone to use when displaying dates.
|
||||
.It Ev LANG
|
||||
The locale to use when determining the order of day and month in the long
|
||||
.Fl l
|
||||
format output.
|
||||
See
|
||||
.Xr environ 7
|
||||
for more information.
|
||||
.It LSCOLORS
|
||||
The value of this variable describes what color to use for which
|
||||
attribute when the color output
|
||||
.Pq Fl G
|
||||
is specified.
|
||||
This string is a concatenation of pairs of the format
|
||||
.Sy fb ,
|
||||
where
|
||||
.Sy f
|
||||
is the foreground color and
|
||||
.Sy b
|
||||
is the background color.
|
||||
.Pp
|
||||
The color designators are as follows:
|
||||
.Pp
|
||||
.Bl -tag -width 4n -offset indent -compact
|
||||
.It Sy 0
|
||||
black
|
||||
.It Sy 1
|
||||
red
|
||||
.It Sy 2
|
||||
green
|
||||
.It Sy 3
|
||||
brown
|
||||
.It Sy 4
|
||||
blue
|
||||
.It Sy 5
|
||||
magenta
|
||||
.It Sy 6
|
||||
cyan
|
||||
.It Sy 7
|
||||
light grey
|
||||
.It Sy x
|
||||
default foreground or background
|
||||
.El
|
||||
.Pp
|
||||
Note that the above are standard
|
||||
.Tn ANSI
|
||||
colors.
|
||||
The actual display may differ
|
||||
depending on the color capabilities of your terminal.
|
||||
.Pp
|
||||
The order of the attributes are as follows:
|
||||
.Pp
|
||||
.Bl -enum -offset indent -compact
|
||||
.It
|
||||
directory
|
||||
.It
|
||||
symbolic link
|
||||
.It
|
||||
socket
|
||||
.It
|
||||
pipe
|
||||
.It
|
||||
executable
|
||||
.It
|
||||
block special
|
||||
.It
|
||||
character special
|
||||
.It
|
||||
executable with setuid bit set
|
||||
.It
|
||||
executable with setgid bit set
|
||||
.It
|
||||
directory writable to others, with sticky bit
|
||||
.It
|
||||
directory writable to others, without sticky bit
|
||||
.El
|
||||
.Pp
|
||||
The default is "4x5x2x3x1x464301060203", i.e. blue foreground and
|
||||
default background for regular directories, black foreground and red
|
||||
background for setuid executables, etc.
|
||||
.It Ev LS_COLWIDTHS
|
||||
If this variable is set, it is considered to be a
|
||||
colon-delimited list of minimum column widths. Unreasonable
|
||||
@@ -394,6 +492,15 @@ a dynamically sized column). Not all
|
||||
columns have changeable widths. The fields are,
|
||||
in order: inode, block count, number of links, user name,
|
||||
group name, flags, file size, file name.
|
||||
.It Ev TERM
|
||||
The
|
||||
.Fl G
|
||||
option depends on a terminal type with color capabilities.
|
||||
.It Ev TZ
|
||||
The timezone to use when displaying dates.
|
||||
See
|
||||
.Xr environ 7
|
||||
for more information.
|
||||
.El
|
||||
.Sh COMPATIBILITY
|
||||
The group field is now automatically included in the long listing for
|
||||
@@ -403,6 +510,8 @@ specification.
|
||||
.Sh SEE ALSO
|
||||
.Xr chflags 1 ,
|
||||
.Xr chmod 1 ,
|
||||
.Xr xterm 1 ,
|
||||
.Xr termcap 5 ,
|
||||
.Xr symlink 7 ,
|
||||
.Xr sticky 8
|
||||
.Sh HISTORY
|
||||
|
||||
+72
-9
@@ -63,6 +63,10 @@ static const char rcsid[] =
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef COLORLS
|
||||
#include <termcap.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
@@ -74,8 +78,6 @@ static const char rcsid[] =
|
||||
*/
|
||||
#define STRBUF_SIZEOF(t) (1 + CHAR_BIT * sizeof(t) / 3 + 1)
|
||||
|
||||
char *getflags __P((u_long, char *));
|
||||
|
||||
static void display __P((FTSENT *, FTSENT *));
|
||||
static u_quad_t makenines __P((u_long));
|
||||
static int mastercmp __P((const FTSENT **, const FTSENT **));
|
||||
@@ -111,6 +113,13 @@ int f_statustime; /* use time of last mode change */
|
||||
int f_timesort; /* sort by time vice name */
|
||||
int f_type; /* add type character for non-regular files */
|
||||
int f_whiteout; /* show whiteout entries */
|
||||
#ifdef COLORLS
|
||||
int f_color; /* add type in color for non-regular files */
|
||||
|
||||
char *ansi_bgcol; /* ANSI sequence to set background colour */
|
||||
char *ansi_fgcol; /* ANSI sequence to set foreground colour */
|
||||
char *ansi_coloff; /* ANSI sequence to reset colours */
|
||||
#endif
|
||||
|
||||
int rval;
|
||||
|
||||
@@ -124,6 +133,12 @@ main(argc, argv)
|
||||
int ch, fts_options, notused;
|
||||
char *p;
|
||||
|
||||
#ifdef COLORLS
|
||||
char termcapbuf[1024]; /* termcap definition buffer */
|
||||
char tcapbuf[512]; /* capability buffer */
|
||||
char *bp = tcapbuf;
|
||||
#endif
|
||||
|
||||
(void) setlocale(LC_ALL, "");
|
||||
|
||||
/* Terminal defaults to -Cq, non-terminal defaults to -1. */
|
||||
@@ -148,7 +163,7 @@ main(argc, argv)
|
||||
f_listdot = 1;
|
||||
|
||||
fts_options = FTS_PHYSICAL;
|
||||
while ((ch = getopt(argc, argv, "1ABCFHLPRTWabcdfgiklnoqrstu")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "1ABCFGHLPRTWabcdfgiklnoqrstu")) != -1) {
|
||||
switch (ch) {
|
||||
/*
|
||||
* The -1, -C and -l options all override each other so shell
|
||||
@@ -186,6 +201,26 @@ main(argc, argv)
|
||||
case 'H':
|
||||
fts_options |= FTS_COMFOLLOW;
|
||||
break;
|
||||
case 'G':
|
||||
if (isatty(STDOUT_FILENO))
|
||||
#ifdef COLORLS
|
||||
if (tgetent(termcapbuf, getenv("TERM")) == 1) {
|
||||
ansi_fgcol = tgetstr("AF", &bp);
|
||||
ansi_bgcol = tgetstr("AB", &bp);
|
||||
|
||||
/* To switch colours off use 'op' if
|
||||
* available, otherwise use 'oc', or
|
||||
* don't do colours at all. */
|
||||
ansi_coloff = tgetstr("op", &bp);
|
||||
if (!ansi_coloff)
|
||||
ansi_coloff = tgetstr("oc", &bp);
|
||||
if (ansi_fgcol && ansi_bgcol && ansi_coloff)
|
||||
f_color = 1;
|
||||
}
|
||||
#else
|
||||
(void)fprintf(stderr, "Color support not compiled in.\n");
|
||||
#endif
|
||||
break;
|
||||
case 'L':
|
||||
fts_options &= ~FTS_PHYSICAL;
|
||||
fts_options |= FTS_LOGICAL;
|
||||
@@ -259,11 +294,30 @@ main(argc, argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef COLORLS
|
||||
if (f_color) {
|
||||
/*
|
||||
* We can't put tabs and color sequences together:
|
||||
* column number will be incremented incorrectly
|
||||
* for "stty oxtabs" mode.
|
||||
*/
|
||||
f_notabs = 1;
|
||||
(void) signal(SIGINT, colorquit);
|
||||
(void) signal(SIGQUIT, colorquit);
|
||||
parsecolors(getenv("LSCOLORS"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If not -F, -i, -l, -s or -t options, don't require stat
|
||||
* information.
|
||||
* information, unless in color mode in which case we do
|
||||
* need this to determine which colors to display.
|
||||
*/
|
||||
if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type)
|
||||
if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type
|
||||
#ifdef COLORLS
|
||||
&& !f_color
|
||||
#endif
|
||||
)
|
||||
fts_options |= FTS_NOSTAT;
|
||||
|
||||
/*
|
||||
@@ -471,7 +525,11 @@ display(p, list)
|
||||
case 4: maxgroup = 0;
|
||||
case 5: maxflags = 0;
|
||||
case 6: maxsize = 0;
|
||||
case 7: maxlen = 0, f_notabs = 0;
|
||||
case 7: maxlen = 0;
|
||||
#ifdef COLORLS
|
||||
if (!f_color)
|
||||
#endif
|
||||
f_notabs = 0;
|
||||
}
|
||||
maxinode = makenines(maxinode);
|
||||
maxblock = makenines(maxblock);
|
||||
@@ -508,8 +566,6 @@ display(p, list)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f_nonprint)
|
||||
prcopy(cur->fts_name, cur->fts_name, cur->fts_namelen);
|
||||
if (cur->fts_namelen > maxlen)
|
||||
maxlen = cur->fts_namelen;
|
||||
if (f_octal || f_octal_escape) {
|
||||
@@ -545,7 +601,13 @@ display(p, list)
|
||||
if ((glen = strlen(group)) > maxgroup)
|
||||
maxgroup = glen;
|
||||
if (f_flags) {
|
||||
flags = getflags(sp->st_flags, "-");
|
||||
flags = fflagstostr(sp->st_flags);
|
||||
if (flags != NULL && *flags == '\0') {
|
||||
free(flags);
|
||||
flags = strdup("-");
|
||||
}
|
||||
if (flags == NULL)
|
||||
err(1, NULL);
|
||||
if ((flen = strlen(flags)) > maxflags)
|
||||
maxflags = flen;
|
||||
} else
|
||||
@@ -567,6 +629,7 @@ display(p, list)
|
||||
if (f_flags) {
|
||||
np->flags = &np->data[ulen + glen + 2];
|
||||
(void)strcpy(np->flags, flags);
|
||||
free(flags);
|
||||
}
|
||||
cur->fts_pointer = np;
|
||||
}
|
||||
|
||||
@@ -48,11 +48,15 @@ extern int f_inode; /* print inode */
|
||||
extern int f_longform; /* long listing format */
|
||||
extern int f_octal; /* print unprintables in octal */
|
||||
extern int f_octal_escape; /* like f_octal but use C escapes if possible */
|
||||
extern int f_nonprint; /* show unprintables as ? */
|
||||
extern int f_sectime; /* print the real time for all files */
|
||||
extern int f_size; /* list size in short listing */
|
||||
extern int f_statustime; /* use time of last mode change */
|
||||
extern int f_notabs; /* don't use tab-separated multi-col output */
|
||||
extern int f_type; /* add type character for non-regular files */
|
||||
#ifdef COLORLS
|
||||
extern int f_color; /* add type in color for non-regular files */
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
FTSENT *list;
|
||||
|
||||
+217
-24
@@ -56,6 +56,11 @@ static const char rcsid[] =
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef COLORLS
|
||||
#include <ctype.h>
|
||||
#include <termcap.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
@@ -64,9 +69,35 @@ static int printaname __P((FTSENT *, u_long, u_long));
|
||||
static void printlink __P((FTSENT *));
|
||||
static void printtime __P((time_t));
|
||||
static int printtype __P((u_int));
|
||||
#ifdef COLORLS
|
||||
static void endcolor __P((int));
|
||||
static int colortype __P((mode_t));
|
||||
#endif
|
||||
|
||||
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
|
||||
|
||||
#ifdef COLORLS
|
||||
/* Most of these are taken from <sys/stat.h> */
|
||||
typedef enum Colors {
|
||||
C_DIR, /* directory */
|
||||
C_LNK, /* symbolic link */
|
||||
C_SOCK, /* socket */
|
||||
C_FIFO, /* pipe */
|
||||
C_EXEC, /* executable */
|
||||
C_BLK, /* block special */
|
||||
C_CHR, /* character special */
|
||||
C_SUID, /* setuid executable */
|
||||
C_SGID, /* setgid executable */
|
||||
C_WSDIR, /* directory writeble to others, with sticky bit */
|
||||
C_WDIR, /* directory writeble to others, without sticky bit */
|
||||
C_NUMCOLORS /* just a place-holder */
|
||||
} Colors ;
|
||||
|
||||
char *defcolors = "4x5x2x3x1x464301060203";
|
||||
|
||||
static int colors[C_NUMCOLORS][2];
|
||||
#endif
|
||||
|
||||
void
|
||||
printscol(dp)
|
||||
DISPLAY *dp;
|
||||
@@ -81,6 +112,21 @@ printscol(dp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print name in current style
|
||||
*/
|
||||
static int
|
||||
printname(name)
|
||||
const char *name;
|
||||
{
|
||||
if (f_octal || f_octal_escape)
|
||||
return prn_octal(name);
|
||||
else if (f_nonprint)
|
||||
return prn_printable(name);
|
||||
else
|
||||
return printf("%s", name);
|
||||
}
|
||||
|
||||
void
|
||||
printlong(dp)
|
||||
DISPLAY *dp;
|
||||
@@ -89,6 +135,9 @@ printlong(dp)
|
||||
FTSENT *p;
|
||||
NAMES *np;
|
||||
char buf[20];
|
||||
#ifdef COLORLS
|
||||
int color_printed = 0;
|
||||
#endif
|
||||
|
||||
if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
|
||||
(void)printf("total %lu\n", howmany(dp->btotal, blocksize));
|
||||
@@ -128,8 +177,15 @@ printlong(dp)
|
||||
printtime(sp->st_ctime);
|
||||
else
|
||||
printtime(sp->st_mtime);
|
||||
if (f_octal || f_octal_escape) (void)prn_octal(p->fts_name);
|
||||
else (void)printf("%s", p->fts_name);
|
||||
#ifdef COLORLS
|
||||
if (f_color)
|
||||
color_printed = colortype(sp->st_mode);
|
||||
#endif
|
||||
(void)printname(p->fts_name);
|
||||
#ifdef COLORLS
|
||||
if (f_color && color_printed)
|
||||
endcolor(0);
|
||||
#endif
|
||||
if (f_type)
|
||||
(void)printtype(sp->st_mode);
|
||||
if (S_ISLNK(sp->st_mode))
|
||||
@@ -221,6 +277,9 @@ printaname(p, inodefield, sizefield)
|
||||
{
|
||||
struct stat *sp;
|
||||
int chcnt;
|
||||
#ifdef COLORLS
|
||||
int color_printed = 0;
|
||||
#endif
|
||||
|
||||
sp = p->fts_statp;
|
||||
chcnt = 0;
|
||||
@@ -229,8 +288,15 @@ printaname(p, inodefield, sizefield)
|
||||
if (f_size)
|
||||
chcnt += printf("%*qd ",
|
||||
(int)sizefield, howmany(sp->st_blocks, blocksize));
|
||||
chcnt += (f_octal || f_octal_escape) ? prn_octal(p->fts_name)
|
||||
: printf("%s", p->fts_name);
|
||||
#ifdef COLORLS
|
||||
if (f_color)
|
||||
color_printed = colortype(sp->st_mode);
|
||||
#endif
|
||||
chcnt += printname(p->fts_name);
|
||||
#ifdef COLORLS
|
||||
if (f_color && color_printed)
|
||||
endcolor(0);
|
||||
#endif
|
||||
if (f_type)
|
||||
chcnt += printtype(sp->st_mode);
|
||||
return (chcnt);
|
||||
@@ -240,30 +306,28 @@ static void
|
||||
printtime(ftime)
|
||||
time_t ftime;
|
||||
{
|
||||
int i;
|
||||
char longstring[80];
|
||||
static time_t now;
|
||||
const char *format;
|
||||
|
||||
if (now == 0)
|
||||
now = time(NULL);
|
||||
|
||||
strftime(longstring, sizeof(longstring), "%c", localtime(&ftime));
|
||||
for (i = 4; i < 11; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
|
||||
#define SIXMONTHS ((365 / 2) * 86400)
|
||||
/* "%Ef" is a FreeBSD strftime definition for "%e %b" or "%b %e".
|
||||
* Actually format is locale sensitive.
|
||||
*/
|
||||
if (f_sectime)
|
||||
for (i = 11; i < 24; i++)
|
||||
(void)putchar(longstring[i]);
|
||||
/* mmm dd hh:mm:ss yyyy || dd mmm hh:mm:ss yyyy */
|
||||
format = "%Ef %T %Y ";
|
||||
else if (ftime + SIXMONTHS > now && ftime < now + SIXMONTHS)
|
||||
for (i = 11; i < 16; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
else {
|
||||
(void)putchar(' ');
|
||||
for (i = 20; i < 24; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
}
|
||||
(void)putchar(' ');
|
||||
/* mmm dd hh:mm || dd mmm hh:mm */
|
||||
format = "%Ef %R ";
|
||||
else
|
||||
/* mmm dd yyyy || dd mmm yyyy */
|
||||
format = "%Ef %Y ";
|
||||
strftime(longstring, sizeof(longstring), format, localtime(&ftime));
|
||||
fputs(longstring, stdout);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -294,6 +358,138 @@ printtype(mode)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef COLORLS
|
||||
static int
|
||||
putch(c)
|
||||
int c;
|
||||
{
|
||||
(void) putchar(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
writech(c)
|
||||
int c;
|
||||
{
|
||||
char tmp = c;
|
||||
|
||||
(void) write(STDOUT_FILENO, &tmp, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
printcolor(c)
|
||||
Colors c;
|
||||
{
|
||||
char *ansiseq;
|
||||
|
||||
if (colors[c][0] != -1) {
|
||||
ansiseq = tgoto(ansi_fgcol, 0, colors[c][0]);
|
||||
if (ansiseq)
|
||||
tputs(ansiseq, 1, putch);
|
||||
}
|
||||
|
||||
if (colors[c][1] != -1) {
|
||||
ansiseq = tgoto(ansi_bgcol, 0, colors[c][1]);
|
||||
if (ansiseq)
|
||||
tputs(ansiseq, 1, putch);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
endcolor(sig)
|
||||
int sig;
|
||||
{
|
||||
tputs(ansi_coloff, 1, sig ? writech : putch);
|
||||
}
|
||||
|
||||
static int
|
||||
colortype(mode)
|
||||
mode_t mode;
|
||||
{
|
||||
switch(mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
if (mode & S_IWOTH)
|
||||
if (mode & S_ISTXT)
|
||||
printcolor(C_WSDIR);
|
||||
else
|
||||
printcolor(C_WDIR);
|
||||
else
|
||||
printcolor(C_DIR);
|
||||
return(1);
|
||||
case S_IFLNK:
|
||||
printcolor(C_LNK);
|
||||
return(1);
|
||||
case S_IFSOCK:
|
||||
printcolor(C_SOCK);
|
||||
return(1);
|
||||
case S_IFIFO:
|
||||
printcolor(C_FIFO);
|
||||
return(1);
|
||||
case S_IFBLK:
|
||||
printcolor(C_BLK);
|
||||
return(1);
|
||||
case S_IFCHR:
|
||||
printcolor(C_CHR);
|
||||
return(1);
|
||||
}
|
||||
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||
if (mode & S_ISUID)
|
||||
printcolor(C_SUID);
|
||||
else if (mode & S_ISGID)
|
||||
printcolor(C_SGID);
|
||||
else
|
||||
printcolor(C_EXEC);
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
parsecolors(cs)
|
||||
char *cs;
|
||||
{
|
||||
int i, j, len;
|
||||
char c[2];
|
||||
|
||||
if (cs == NULL) cs = ""; /* LSCOLORS not set */
|
||||
len = strlen(cs);
|
||||
for (i = 0 ; i < C_NUMCOLORS ; i++) {
|
||||
if (len <= 2*i) {
|
||||
c[0] = defcolors[2*i];
|
||||
c[1] = defcolors[2*i+1];
|
||||
}
|
||||
else {
|
||||
c[0] = cs[2*i];
|
||||
c[1] = cs[2*i+1];
|
||||
}
|
||||
for (j = 0 ; j < 2 ; j++) {
|
||||
if ((c[j] < '0' || c[j] > '7') &&
|
||||
tolower((unsigned char)c[j]) != 'x') {
|
||||
fprintf(stderr,
|
||||
"error: invalid character '%c' in LSCOLORS env var\n",
|
||||
c[j]);
|
||||
c[j] = defcolors[2*i+j];
|
||||
}
|
||||
if (tolower((unsigned char)c[j]) == 'x')
|
||||
colors[i][j] = -1;
|
||||
else
|
||||
colors[i][j] = c[j]-'0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
colorquit(sig)
|
||||
int sig;
|
||||
{
|
||||
endcolor(sig);
|
||||
|
||||
(void) signal(sig, SIG_DFL);
|
||||
(void) kill(getpid(), sig);
|
||||
}
|
||||
#endif /*COLORLS*/
|
||||
|
||||
static void
|
||||
printlink(p)
|
||||
FTSENT *p;
|
||||
@@ -311,9 +507,6 @@ printlink(p)
|
||||
return;
|
||||
}
|
||||
path[lnklen] = '\0';
|
||||
if (f_octal || f_octal_escape) {
|
||||
(void)printf(" -> ");
|
||||
(void)prn_octal(path);
|
||||
}
|
||||
else (void)printf(" -> %s", path);
|
||||
(void)printf(" -> ");
|
||||
printname(path);
|
||||
}
|
||||
+19
-12
@@ -56,17 +56,19 @@ static const char rcsid[] =
|
||||
#include "ls.h"
|
||||
#include "extern.h"
|
||||
|
||||
void
|
||||
prcopy(src, dest, len)
|
||||
char *src, *dest;
|
||||
int len;
|
||||
int
|
||||
prn_printable(s)
|
||||
const char *s;
|
||||
{
|
||||
unsigned char ch;
|
||||
unsigned char c;
|
||||
int n;
|
||||
|
||||
while (len--) {
|
||||
ch = *src++;
|
||||
*dest++ = isprint(ch) ? ch : '?';
|
||||
}
|
||||
for (n = 0; (c = *s) != '\0'; ++s, ++n)
|
||||
if (isprint(c))
|
||||
putchar(c);
|
||||
else
|
||||
putchar('?');
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -84,7 +86,7 @@ prcopy(src, dest, len)
|
||||
|
||||
int
|
||||
len_octal(s, len)
|
||||
char *s;
|
||||
const char *s;
|
||||
int len;
|
||||
{
|
||||
int r = 0;
|
||||
@@ -96,7 +98,7 @@ len_octal(s, len)
|
||||
|
||||
int
|
||||
prn_octal(s)
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
unsigned char ch;
|
||||
int len = 0;
|
||||
@@ -158,7 +160,12 @@ prn_octal(s)
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: ls [-ACFHLPRTWacdfgiklnoqrstu1]"
|
||||
(void)fprintf(stderr,
|
||||
#ifdef COLORLS
|
||||
"usage: ls [-ACFGHLPRTWacdfgiklnoqrstu1]"
|
||||
#else
|
||||
"usage: ls [-ACFHLPRTWacdfgiklnoqrstu1]"
|
||||
#endif
|
||||
" [file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
+1
-1
@@ -221,7 +221,7 @@ do_move(from, to)
|
||||
* it's a regular file, do the copy internally; otherwise, use
|
||||
* cp and rm.
|
||||
*/
|
||||
if (stat(from, &sb)) {
|
||||
if (lstat(from, &sb)) {
|
||||
warn("%s", from);
|
||||
return (1);
|
||||
}
|
||||
|
||||
+2
-2
@@ -64,8 +64,8 @@ static const char rcsid[] =
|
||||
#define MODELEN 20
|
||||
#define DATELEN 64
|
||||
#define SIXMONTHS ((365 / 2) * 86400)
|
||||
#define CURFRMT "%b %e %H:%M"
|
||||
#define OLDFRMT "%b %e %Y"
|
||||
#define CURFRMT "%Ef %H:%M"
|
||||
#define OLDFRMT "%Ef %Y"
|
||||
#ifndef UT_NAMESIZE
|
||||
#define UT_NAMESIZE 8
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ main(argc, argv)
|
||||
*/
|
||||
printheader();
|
||||
if (nentries == 0)
|
||||
exit(0);
|
||||
exit(1);
|
||||
/*
|
||||
* sort proc list
|
||||
*/
|
||||
|
||||
+1
-2
@@ -2,10 +2,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= rm
|
||||
SRCS= rm.c setflags.c
|
||||
SRCS= rm.c
|
||||
|
||||
LINKS= ${BINDIR}/rm ${BINDIR}/unlink
|
||||
MLINKS= rm.1 unlink.1
|
||||
.PATH: ${.CURDIR}/../../lib/libc/gen
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
+6
-9
@@ -46,7 +46,6 @@ static const char rcsid[] =
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
@@ -61,8 +60,6 @@ static const char rcsid[] =
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *getflags __P((u_long, char *));
|
||||
|
||||
int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok;
|
||||
uid_t uid;
|
||||
|
||||
@@ -424,7 +421,7 @@ check(path, name, sp)
|
||||
struct stat *sp;
|
||||
{
|
||||
int ch, first;
|
||||
char modep[15], flagsp[128];
|
||||
char modep[15], *flagsp;
|
||||
|
||||
/* Check -i first. */
|
||||
if (iflag)
|
||||
@@ -442,15 +439,15 @@ check(path, name, sp)
|
||||
(!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !uid)))
|
||||
return (1);
|
||||
strmode(sp->st_mode, modep);
|
||||
strcpy(flagsp, getflags(sp->st_flags, NULL));
|
||||
if (*flagsp)
|
||||
strcat(flagsp, " ");
|
||||
(void)fprintf(stderr, "override %s%s%s/%s %sfor %s? ",
|
||||
if ((flagsp = fflagstostr(sp->st_flags)) == NULL)
|
||||
err(1, NULL);
|
||||
(void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ",
|
||||
modep + 1, modep[9] == ' ' ? "" : " ",
|
||||
user_from_uid(sp->st_uid, 0),
|
||||
group_from_gid(sp->st_gid, 0),
|
||||
*flagsp ? flagsp : "",
|
||||
*flagsp ? flagsp : "", *flagsp ? " " : "",
|
||||
path);
|
||||
free(flagsp);
|
||||
}
|
||||
(void)fflush(stderr);
|
||||
|
||||
|
||||
@@ -96,6 +96,10 @@ rm_path(path)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = path + strlen(path);
|
||||
while (--p > path && *p == '/')
|
||||
;
|
||||
*++p = '\0';
|
||||
while ((p = strrchr(path, '/')) != NULL) {
|
||||
/* Delete trailing slashes. */
|
||||
while (--p > path && *p == '/')
|
||||
|
||||
@@ -109,6 +109,7 @@ setalias(name, val)
|
||||
ap->val[len+1] = '\0';
|
||||
}
|
||||
#endif
|
||||
ap->flag = 0;
|
||||
ap->next = *app;
|
||||
*app = ap;
|
||||
INTON;
|
||||
|
||||
@@ -45,7 +45,6 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <unistd.h>
|
||||
#include "y.tab.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ main(argc, argv)
|
||||
while ((c = *p++) != '\0') {
|
||||
if (c == '\\' && eflag) {
|
||||
switch (*p++) {
|
||||
case 'a': c = '\a'; break;
|
||||
case 'b': c = '\b'; break;
|
||||
case 'c': return 0; /* exit */
|
||||
case 'e': c = '\e'; break;
|
||||
case 'f': c = '\f'; break;
|
||||
case 'n': c = '\n'; break;
|
||||
case 'r': c = '\r'; break;
|
||||
|
||||
@@ -82,7 +82,6 @@ extern volatile sig_atomic_t exception;
|
||||
|
||||
extern volatile sig_atomic_t suppressint;
|
||||
extern volatile sig_atomic_t intpending;
|
||||
extern char *commandname; /* name of command--printed on error */
|
||||
|
||||
#define INTOFF suppressint++
|
||||
#define INTON { if (--suppressint == 0 && intpending) onint(); }
|
||||
|
||||
@@ -850,6 +850,7 @@ evalcommand(cmd, flags, backcmd)
|
||||
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
|
||||
flushall();
|
||||
cmddone:
|
||||
cmdenviron = NULL;
|
||||
out1 = &output;
|
||||
out2 = &errout;
|
||||
freestdout();
|
||||
|
||||
+1
-1
@@ -667,7 +667,7 @@ again: /* jump here after setting a variable with ${var=text} */
|
||||
set = varisset(var, varflags & VSNUL);
|
||||
val = NULL;
|
||||
} else {
|
||||
val = lookupvar(var);
|
||||
val = bltinlookup(var, 1);
|
||||
if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
|
||||
val = NULL;
|
||||
set = 0;
|
||||
|
||||
+1
-3
@@ -168,8 +168,6 @@ histcmd(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind, optopt, optreset;
|
||||
int ch;
|
||||
char *editor = NULL;
|
||||
const HistEvent *he;
|
||||
@@ -210,7 +208,7 @@ histcmd(argc, argv)
|
||||
(ch = getopt(argc, argv, ":e:lnrs")) != -1)
|
||||
switch ((char)ch) {
|
||||
case 'e':
|
||||
editor = optarg;
|
||||
editor = shoptarg;
|
||||
break;
|
||||
case 'l':
|
||||
lflg = 1;
|
||||
|
||||
@@ -971,7 +971,6 @@ stoppedjobs()
|
||||
|
||||
STATIC char *cmdnextc;
|
||||
STATIC int cmdnleft;
|
||||
STATIC void cmdtxt(), cmdputs();
|
||||
#define MAXCMDTEXT 200
|
||||
|
||||
char *
|
||||
|
||||
+1
-2
@@ -54,7 +54,7 @@ static const char rcsid[] =
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "main.h"
|
||||
@@ -81,7 +81,6 @@ static const char rcsid[] =
|
||||
|
||||
int rootpid;
|
||||
int rootshell;
|
||||
extern int errno;
|
||||
#if PROFILE
|
||||
short profile_buf[16384];
|
||||
extern int etext();
|
||||
|
||||
+3
-6
@@ -67,9 +67,6 @@ static const char rcsid[] =
|
||||
|
||||
#undef eflag
|
||||
|
||||
extern char **argptr; /* argument list for builtin command */
|
||||
|
||||
|
||||
/*
|
||||
* The read builtin. The -r option causes backslashes to be treated like
|
||||
* ordinary characters.
|
||||
@@ -105,7 +102,7 @@ readcmd(argc, argv)
|
||||
while ((i = nextopt("erp:t:")) != '\0') {
|
||||
switch(i) {
|
||||
case 'p':
|
||||
prompt = optarg;
|
||||
prompt = shoptarg;
|
||||
break;
|
||||
case 'e':
|
||||
break;
|
||||
@@ -113,8 +110,8 @@ readcmd(argc, argv)
|
||||
rflag = 1;
|
||||
break;
|
||||
case 't':
|
||||
tv.tv_sec = strtol(optarg, &tvptr, 0);
|
||||
if (tvptr == optarg)
|
||||
tv.tv_sec = strtol(shoptarg, &tvptr, 0);
|
||||
if (tvptr == shoptarg)
|
||||
error("timeout value");
|
||||
switch(*tvptr) {
|
||||
case 0:
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ static const char rcsid[] =
|
||||
char *arg0; /* value of $0 */
|
||||
struct shparam shellparam; /* current positional parameters */
|
||||
char **argptr; /* argument list for builtin commands */
|
||||
char *optarg; /* set by nextopt (like getopt) */
|
||||
char *shoptarg; /* set by nextopt (like getopt) */
|
||||
char *optptr; /* used by nextopt */
|
||||
|
||||
char *minusc; /* argument to -c option */
|
||||
@@ -539,7 +539,7 @@ nextopt(optstring)
|
||||
if (*++q == ':') {
|
||||
if (*p == '\0' && (p = *argptr++) == NULL)
|
||||
error("No arg for -%c option", c);
|
||||
optarg = p;
|
||||
shoptarg = p;
|
||||
p = NULL;
|
||||
}
|
||||
optptr = p;
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ extern char *minusc; /* argument to -c option */
|
||||
extern char *arg0; /* $0 */
|
||||
extern struct shparam shellparam; /* $@ */
|
||||
extern char **argptr; /* argument list for builtin commands */
|
||||
extern char *optarg; /* set by nextopt */
|
||||
extern char *shoptarg; /* set by nextopt */
|
||||
extern char *optptr; /* used by nextopt */
|
||||
|
||||
void procargs __P((int, char **));
|
||||
|
||||
+2
-2
@@ -59,6 +59,7 @@ static const char rcsid[] =
|
||||
#include "mystring.h"
|
||||
#include "alias.h"
|
||||
#include "show.h"
|
||||
#include "eval.h"
|
||||
#ifndef NO_HISTORY
|
||||
#include "myhistedit.h"
|
||||
#endif
|
||||
@@ -136,6 +137,7 @@ parsecmd(interact)
|
||||
{
|
||||
int t;
|
||||
|
||||
tokpushback = 0;
|
||||
doprompt = interact;
|
||||
if (doprompt)
|
||||
setprompt(1);
|
||||
@@ -678,8 +680,6 @@ peektoken() {
|
||||
return (t);
|
||||
}
|
||||
|
||||
STATIC int xxreadtoken();
|
||||
|
||||
STATIC int
|
||||
readtoken() {
|
||||
int t;
|
||||
|
||||
+62
-6
@@ -1269,11 +1269,9 @@ make it the first or last character listed.
|
||||
This section lists the commands which
|
||||
are builtin because they need to perform some operation
|
||||
that can not be performed by a separate process. In addition to
|
||||
these, builtin versions of the
|
||||
these, a builtin version of the
|
||||
.Xr printf 1
|
||||
and
|
||||
.Xr echo 1
|
||||
commands are provided for efficiency.
|
||||
command is provided for efficiency.
|
||||
.Bl -tag -width Ds
|
||||
.It Ic :
|
||||
A null command that returns a 0 (true) exit value.
|
||||
@@ -1349,6 +1347,64 @@ if this is different from the name that the user gave.
|
||||
These may be different either because the
|
||||
.Ev CDPATH
|
||||
mechanism was used or because a symbolic link was crossed.
|
||||
.It Xo
|
||||
.Ic echo
|
||||
.Op Fl en
|
||||
.Ar string
|
||||
.Xc
|
||||
Print
|
||||
.Ar string
|
||||
to the standard output with a newline appended.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl n
|
||||
Suppress the output of the trailing newline.
|
||||
.It Fl e
|
||||
Process C-style backslash escape sequences.
|
||||
.Ic echo
|
||||
understands the following character escapes:
|
||||
.Bl -tag -width Ds
|
||||
.It \ea
|
||||
Alert (ring the terminal bell)
|
||||
.It \eb
|
||||
Backspace
|
||||
.It \ec
|
||||
Suppress the trailing newline (this has the side-effect of truncating the
|
||||
line if it is not the last character)
|
||||
.It \ee
|
||||
The ESC character (ASCII 0x1b)
|
||||
.It \ef
|
||||
Formfeed
|
||||
.It \en
|
||||
Newline
|
||||
.It \er
|
||||
Carriage return
|
||||
.It \et
|
||||
Horizontal tab
|
||||
.It \ev
|
||||
Vertical tab
|
||||
.It \e\e
|
||||
Literal backslash
|
||||
.It \e0nnn
|
||||
(Zero) The character whose octal value is nnn
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
.Ar string
|
||||
is not enclosed in quotes then the backslash itself must be escaped
|
||||
with a backslash to protect it from the shell. For example
|
||||
.Bd -literal -offset indent
|
||||
$ echo -e "a\evb"
|
||||
a
|
||||
b
|
||||
$ echo -e a\e\evb
|
||||
a
|
||||
b
|
||||
$ echo -e "a\e\eb"
|
||||
a\eb
|
||||
$ echo -e a\e\e\e\eb
|
||||
a\eb
|
||||
.Ed
|
||||
.El
|
||||
.It Ic eval Ar string ...
|
||||
Concatenate all the arguments with spaces.
|
||||
Then re-parse and execute the command.
|
||||
@@ -1812,7 +1868,7 @@ The maximal number of simultaneous processes for this user ID.
|
||||
Set the file creation mask (see
|
||||
.Xr umask 2 )
|
||||
to the octal value specified by
|
||||
.Ar mask
|
||||
.Ar mask .
|
||||
If the argument is omitted, the current mask value is printed.
|
||||
.It Xo
|
||||
.Ic unalias
|
||||
@@ -1823,7 +1879,7 @@ If
|
||||
.Ar name
|
||||
is specified, the shell removes that alias.
|
||||
If
|
||||
.Ar a
|
||||
.Fl a
|
||||
is specified, all aliases are removed.
|
||||
.It Ic unset Ar name ...
|
||||
The specified variables and functions are unset and unexported.
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ extern char nullstr[1]; /* null string */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACE(param) trace param
|
||||
#define TRACE(param) sh_trace param
|
||||
#else
|
||||
#define TRACE(param)
|
||||
#endif
|
||||
+6
-2
@@ -48,6 +48,10 @@ static const char rcsid[] =
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#if DEBUG == 2
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "parser.h"
|
||||
@@ -301,9 +305,9 @@ trputc(c)
|
||||
|
||||
void
|
||||
#ifdef __STDC__
|
||||
trace(const char *fmt, ...)
|
||||
sh_trace(const char *fmt, ...)
|
||||
#else
|
||||
trace(va_alist)
|
||||
sh_trace(va_alist)
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
|
||||
void showtree __P((union node *));
|
||||
#ifdef DEBUG
|
||||
void trace __P((const char *, ...));
|
||||
void sh_trace __P((const char *, ...));
|
||||
void trargs __P((char **));
|
||||
void trputc __P((int));
|
||||
void trputs __P((char *));
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ args: argc -= optind;
|
||||
if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
|
||||
err(1, "TIOCGETD");
|
||||
if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
|
||||
warn("TIOCGWINSZ: %s\n", strerror(errno));
|
||||
warn("TIOCGWINSZ");
|
||||
|
||||
checkredirect(); /* conversion aid */
|
||||
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ function call.
|
||||
.Sh SEE ALSO
|
||||
.Xr fsync 2 ,
|
||||
.Xr sync 2 ,
|
||||
.Xr update 4 ,
|
||||
.Xr syncer 4 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr reboot 8
|
||||
.Sh HISTORY
|
||||
|
||||
@@ -108,7 +108,6 @@ t 0 '-r /'
|
||||
t 1 '-w /'
|
||||
t 0 '-x /bin/sh'
|
||||
t 0 '-c /dev/null'
|
||||
t 0 '-b /dev/fd0a -o -b /dev/rfd0a -o true'
|
||||
t 0 '-f /etc/passwd'
|
||||
t 0 '-s /etc/passwd'
|
||||
|
||||
|
||||
+50
-6
@@ -153,6 +153,8 @@ static int binop __P((void));
|
||||
static int filstat __P((char *, enum token));
|
||||
static int isoperand __P((void));
|
||||
static int getn __P((const char *));
|
||||
static quad_t getq __P((const char *));
|
||||
static int intcmp __P((const char *, const char *));
|
||||
static int newerf __P((const char *, const char *));
|
||||
static int olderf __P((const char *, const char *));
|
||||
static int equalf __P((const char *, const char *));
|
||||
@@ -298,17 +300,17 @@ binop()
|
||||
case STRGT:
|
||||
return strcmp(opnd1, opnd2) > 0;
|
||||
case INTEQ:
|
||||
return getn(opnd1) == getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) == 0;
|
||||
case INTNE:
|
||||
return getn(opnd1) != getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) != 0;
|
||||
case INTGE:
|
||||
return getn(opnd1) >= getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) >= 0;
|
||||
case INTGT:
|
||||
return getn(opnd1) > getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) > 0;
|
||||
case INTLE:
|
||||
return getn(opnd1) <= getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) <= 0;
|
||||
case INTLT:
|
||||
return getn(opnd1) < getn(opnd2);
|
||||
return intcmp(opnd1, opnd2) < 0;
|
||||
case FILNT:
|
||||
return newerf (opnd1, opnd2);
|
||||
case FILOT:
|
||||
@@ -443,6 +445,48 @@ getn(s)
|
||||
return (int) r;
|
||||
}
|
||||
|
||||
/* atoi with error detection and 64 bit range */
|
||||
static quad_t
|
||||
getq(s)
|
||||
const char *s;
|
||||
{
|
||||
char *p;
|
||||
quad_t r;
|
||||
|
||||
errno = 0;
|
||||
r = strtoq(s, &p, 10);
|
||||
|
||||
if (errno != 0)
|
||||
errx(2, "%s: out of range", s);
|
||||
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
|
||||
if (*p)
|
||||
errx(2, "%s: bad number", s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
intcmp (s1, s2)
|
||||
const char *s1, *s2;
|
||||
{
|
||||
quad_t q1, q2;
|
||||
|
||||
|
||||
q1 = getq(s1);
|
||||
q2 = getq(s2);
|
||||
|
||||
if (q1 > q2)
|
||||
return 1;
|
||||
|
||||
if (q1 < q2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
newerf (f1, f2)
|
||||
const char *f1, *f2;
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
.Nm amd
|
||||
.Nd automatically mount file systems
|
||||
.Sh SYNOPSIS
|
||||
.Nm amd
|
||||
.Fl H
|
||||
.Nm amd
|
||||
.Op Fl F Ar conf_file
|
||||
.Nm amd
|
||||
@@ -321,7 +323,6 @@ the features.
|
||||
.Xr amd.conf 5 ,
|
||||
.Xr mtab 5 ,
|
||||
.Xr amq 8 ,
|
||||
.Xr automount 8 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr umount 8
|
||||
.Rs
|
||||
@@ -335,8 +336,8 @@ Department of Computing, Imperial College, London, UK.
|
||||
Department of Computer Science, Columbia University,
|
||||
New York, USA.
|
||||
.Pp
|
||||
.An Other authors and contributors to am-utils are listed in the
|
||||
.Nm AUTHORS
|
||||
Other authors and contributors to am-utils are listed in the
|
||||
.Pa AUTHORS
|
||||
file distributed with am-utils.
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
||||
@@ -294,7 +294,6 @@ user's home directory is accessible.
|
||||
.Xr mtab 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr amd 8 ,
|
||||
.Xr automount 8 ,
|
||||
.Xr cron 8 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr sendmail 8 ,
|
||||
|
||||
@@ -678,8 +678,8 @@ Department of Computer Science, Columbia University, New York, USA.
|
||||
.An Jan-Simon Pendry Aq [email protected] ,
|
||||
Department of Computing, Imperial College, London, UK.
|
||||
.Pp
|
||||
.An Other Authors and contributers to am-utils are listed in the
|
||||
.Nm AUTHORS
|
||||
Other authors and contributers to am-utils are listed in the
|
||||
.Pa AUTHORS
|
||||
file distributed with am-utils.
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
||||
@@ -1,3 +1,283 @@
|
||||
--- 8.2.3-T5B (RC3) released ---
|
||||
|
||||
1006. [port] Windows/NT does not have fchown().
|
||||
|
||||
1005. [bug] RD was sometimes left set, inappropriately.
|
||||
|
||||
1004. [bug] cached NXT's were corrupted.
|
||||
|
||||
1003. [bug] correction to #997.
|
||||
|
||||
1002. [bug] file descriptor leak in res_nclose().
|
||||
|
||||
1001. [port] some builds were too fast.
|
||||
|
||||
--- 8.2.3-T4B (RC2) released ---
|
||||
|
||||
1000. [bug] #996 was wrongly implemented; replacement fix.
|
||||
|
||||
--- 8.2.3-T3B released ---
|
||||
|
||||
999. [support] named now makes an effort to create its files with
|
||||
ownership as specified by -u and -g command options.
|
||||
|
||||
998. [support] show version number in NOTIFY log messages.
|
||||
|
||||
997. [support] forwarders are now used in order by measured RTT.
|
||||
|
||||
996. [protocol] if answering ixfr with full zone, used qtype axfr.
|
||||
|
||||
995. [bug] "dig -b" was broken due to missing switch "break;"
|
||||
|
||||
994. [bug] named-xfer did not handle empty question sections.
|
||||
|
||||
993. [bug] TSIG AXFR was completely broken in DiG.
|
||||
|
||||
992. [bug] OPTION_USE_IXFR and OPTION_MAINTAIN_IXFR_BASE had
|
||||
non-single-bit flag values in src/bin/named/ns_defs.h.
|
||||
|
||||
991. [protocol] send A6 glue records in xfr.
|
||||
|
||||
990. [bug] we could loose track of a bottom of zone cut is the
|
||||
write buffer filled up at just the correct moment.
|
||||
|
||||
989. [bug] apply to "fetch-glue no;" to notify processing. need
|
||||
to add A records that would be found this way w/
|
||||
also-notify.
|
||||
|
||||
988. [support] report expired zones when detected in maintainence
|
||||
pass.
|
||||
|
||||
987. [feature] "ndc reconfig -noexpired" skip attempts to load
|
||||
expired zoned when reconfiguring.
|
||||
|
||||
986. [bug] pushlev only needs to be called for axfr/zxfr not ixfr.
|
||||
|
||||
--- 8.2.3-T2B released ---
|
||||
|
||||
985. [support] remove "view" command from nslookup (it used mktemp()).
|
||||
|
||||
984. [bug] always restart processing query from scratch if we
|
||||
have chased a CNAME as we might still have the answer
|
||||
in the cache once the CNAME has been resolved.
|
||||
|
||||
983. [support] "notify from non-master server" is now debug, not info.
|
||||
|
||||
982. [bug] rollback the compression pointers array when a
|
||||
RRset/RR does not fit.
|
||||
|
||||
981. [port] decunix: typedef (u_)int#m_t
|
||||
|
||||
980. [bug] mishandled memget failure w/ TCP connections.
|
||||
|
||||
979. [bug] we were failing to call ns_stopxfrs() before calling
|
||||
purge_zone() in some cases.
|
||||
|
||||
978. [port] sco50: setsockopt(SO_REUSEADDR) fails on unix domain
|
||||
sockets
|
||||
|
||||
977. [bug] we should be returning notimpl for update forwarding
|
||||
rather than refused. a client receiving refused
|
||||
should terminate the update attempt. notimpl should
|
||||
just cause the client to skip to the next server.
|
||||
|
||||
976. [bug] some stats weren't getting incremented, & added a few.
|
||||
|
||||
975. [support] SLAVE_FORWARD is now redundant and has been removed.
|
||||
|
||||
974. [port] ultrix with vendor's y2k patch explicitly desupported.
|
||||
|
||||
973. [bug] some field names added in #935 conflicted with macros.
|
||||
|
||||
972. [support] restore heartbeat notifies.
|
||||
|
||||
971. [bug] out of order updates in log.
|
||||
|
||||
970. [port] solaris: add ipv6 interface scanning support.
|
||||
|
||||
969. [bug] post process a zone load to remove any non-glue at
|
||||
or below bottom of zone.
|
||||
|
||||
968. [bug] TSIGs failed to verify if the key name was compressed.
|
||||
|
||||
967. [bug] zones signed by the BIND 9 signer failed to load.
|
||||
|
||||
--- 8.2.3-T1A released ---
|
||||
|
||||
966. [bug] nslookup and dig misprinted root zone in $ORIGIN.
|
||||
|
||||
965. [feature] dig's command line input buffer was rather small.
|
||||
|
||||
964. [bug] make res_nsearch() behave like res_search() of olde.
|
||||
|
||||
963. [bug] res_debug::do_section() can no longer spin all VM.
|
||||
|
||||
962. [bug] another almost-complete rewrite of IXFR from kjd (462)
|
||||
|
||||
961. [bug] acl "none" now fails to match but doesn't end search.
|
||||
|
||||
960. [bug] more hesiod library fixes from danny.
|
||||
|
||||
959. [doc] christos fixed several man page typos and brainos.
|
||||
|
||||
958. [bug] getnameinfo() should accept experimental/multicast.
|
||||
|
||||
957. [port] ultrix again. "cd" now presumed to be silent again.
|
||||
|
||||
956. [bug] multiline was not being cleared correctly.
|
||||
|
||||
955. [bug] explicit TTL on SOA records were being replaced with
|
||||
soa minimum.
|
||||
|
||||
954. [bug] cannot load a signed root zone.
|
||||
|
||||
953. [bug] memory overrun in set_zone_ixfr_file().
|
||||
|
||||
952. [bug] errs was not being correctly adjusted if the included
|
||||
master file did not exist in db_load().
|
||||
|
||||
951. [bug] contrib/dns_signer/signer: write_trim_name
|
||||
array bounds write error.
|
||||
|
||||
950. [bug] hesiod: ctx->res was not being initalised.
|
||||
|
||||
949. [port] aix32: add prand_conf.h and define WCOREDUMP
|
||||
|
||||
948. [bug] fixed logic error in a number of expressions causing
|
||||
res_ninit() not to be called when it should be.
|
||||
|
||||
947. [bug] sanity check in dst_read_key() wasn't.
|
||||
|
||||
946. [port] freebsd: threaded library support.
|
||||
|
||||
945. [bug] wrong file name logged in ixfr_have_log().
|
||||
|
||||
944. [doc] add forwarders to zone types master/slave/stub in
|
||||
named.conf man page.
|
||||
|
||||
943. [bug] raise CNAME and OTHER / multiple CNAME logging to
|
||||
warning.
|
||||
|
||||
942. [bug] bad referrals logged for forwarders.
|
||||
|
||||
941. [bug] lame server detection wasn't checking for SOA record.
|
||||
|
||||
940. [clarity] unapproved -> denied in log messages.
|
||||
|
||||
939. [bug] reload_master and purgeandload should write the zone
|
||||
if it has been updated.
|
||||
|
||||
938. [bug] update and ixfr logs could get corrupted. fseek()
|
||||
before ftell() on fopen(, "a+") file.
|
||||
|
||||
937. [support] allow parallel makes to work.
|
||||
|
||||
936. [protocol] add preliminary A6 glue recognition in ns_req.
|
||||
|
||||
935. [cleanup] res_nsend() segmented into multiple functions for
|
||||
readability. also fixed two file descriptor leaks.
|
||||
CAN_RECONNECT is gone, keep one socket per nameserver.
|
||||
|
||||
934. [bug] Perror and Aerror where incorrect if DEBUG is not
|
||||
defined.
|
||||
|
||||
933. [port] cygwin port added
|
||||
|
||||
932. [port] sco42 does not have unix domain sockets or gethostid.
|
||||
|
||||
931. [bug] eventlib was not handling unix domain sockets
|
||||
correctly.
|
||||
|
||||
930. [bug] we wern't using all the potential compression pointers
|
||||
in the question section.
|
||||
|
||||
929. [bug] we were accepting updates (adds) with illegal ttls.
|
||||
|
||||
928. [bug] if we manage to get a illegal ttl stored, print it
|
||||
unsigened.
|
||||
|
||||
927. [port] hpux: (11.* 10.30) Makefile.set.gcc
|
||||
|
||||
926. [port] hpux10: gcc needs -D_HPUX_SOURCE and -fPIC
|
||||
|
||||
925. [protocol] when a slave loads it should notify others (RFC 1996).
|
||||
|
||||
924. [port] sunos solaris: #define NEED_SECURE_DIRECTORY to
|
||||
secure the directory containing unix domain socket
|
||||
rather than the socket itself.
|
||||
|
||||
923. [support] shutup "make clean" about missing threaded directories.
|
||||
|
||||
922. [bug] removing an cached zone file then performing a
|
||||
"ndc reload zone" should force a zone transfer.
|
||||
|
||||
921. [bug] nsupdate: listuprec was not being initalised.
|
||||
|
||||
920. [port] aix4: Makefile.set.gcc
|
||||
aix4: __P was being defined by <net/radix.h>
|
||||
|
||||
919 [port] linux: remove one level of symbolic linkage when
|
||||
performing make links on port/linux/include
|
||||
|
||||
918. [bug] update prerequisite could match w/ wildcard.
|
||||
|
||||
917. [port] irix: make the current IRIX release (6.5) work by
|
||||
not patching res_debug.c. see INSTALL if you have
|
||||
problems with 6.3.
|
||||
|
||||
916. [bug] removing / changing a zone type could result in
|
||||
Z_NOTIFY being cleared / tested against the wrong zone.
|
||||
|
||||
915. [bug] evNewWaitList() was not maintaining the prev chain.
|
||||
|
||||
914. [bug] signal EWOULDBLOCK if EV_POLL'ing with no timers.
|
||||
|
||||
913. [bug] input could get lost on the server side of a ctl sock.
|
||||
|
||||
912. [bug] nsupdate now allows explicit 0 TTL's on added RR's.
|
||||
|
||||
911. [bug] gethostbyname() should not return duplicate addresses.
|
||||
|
||||
910. [bug] address-sorting logic was exiting early.
|
||||
|
||||
909. [bug] dig wasn't respecting the +ti and +ret arguments.
|
||||
|
||||
908. [contrib] Tony Stoneley sent us an updated misc/makezones.
|
||||
|
||||
907. [port] winnt fixes from Larry at Nortel.
|
||||
|
||||
906. [bug] res_findzonecut() failed if the NS referred to a CNAME.
|
||||
|
||||
905. [doc] Minor fix to doc/man/Makefile for getnameinfo
|
||||
|
||||
904. [bug] bin/host wasn't looking up MX records if no
|
||||
-t flags were passed to it.
|
||||
|
||||
--- 8.2.2-P6 released ---
|
||||
|
||||
903. [bug] divide by zero bug when querying for SIG records from
|
||||
a secure zone.
|
||||
|
||||
902. [support] don't attempt to set q_fzone if we won't be using it.
|
||||
|
||||
901. [support] delay notify timer setting until all zones have been
|
||||
loaded.
|
||||
|
||||
900. [port] hpux10 fix call to bison; sco call bison consistenly.
|
||||
|
||||
899. [bug] dynamically allocate buffer used to display RR rather
|
||||
than uses a fixed sized one. grow as needed.
|
||||
|
||||
898. [bug] if truncation caused no RR's to appear in the answer we
|
||||
mis-classified the answer on a NODATA.
|
||||
|
||||
897. [support] descriptors used by named should not be inherited by
|
||||
named-xfer.
|
||||
|
||||
896. [contrib] add contrib/adm/adm-nxt, an exploit for the NXT bug
|
||||
in 8.2 and 8.2.1. as before, we do not recommend its
|
||||
use, and we do recommend that you run the latest BIND.
|
||||
|
||||
--- 8.2.2-P5 released ---
|
||||
|
||||
895. [port] minor NT build and documentation improvements.
|
||||
|
||||
+10
-2
@@ -1,23 +1,25 @@
|
||||
Systems it is known to compile and run on:
|
||||
|
||||
BSD/OS 3.1, 4.0.1
|
||||
FreeBSD 3.1, 3.2, 3.3
|
||||
FreeBSD 3.3, 3.4
|
||||
RH Linux 5.2 (don't use "make links" when building, though)
|
||||
Debian GNU/Linux 2.2.9 ("unreleased")
|
||||
Digital UNIX 3.2C, 4.0, 5.0
|
||||
NetBSD/i386 1.3.2, 1.4
|
||||
SunOS 5.6 (Solaris 2.6), SunOS 5.7 (Solaris 7)
|
||||
SCO UnixWare 7.0, 7.0.1, 7.1
|
||||
IRIX 6.5
|
||||
|
||||
Systems it has been known in the past to compile and run on:
|
||||
|
||||
AIX 4.x
|
||||
A/UX 3.1.1
|
||||
Digital ULTRIX 4.5
|
||||
Digital ULTRIX 4.5 (without Compaq's Y2K kit installed)
|
||||
HP MPE
|
||||
HP-UX 9.x, 10.20
|
||||
IRIX 5.3, 6.2, 6.4
|
||||
LynxOS
|
||||
FreeBSD 3.1, 3.2
|
||||
NetBSD 1.2, 1.3
|
||||
OpenBSD 2.1
|
||||
QNX
|
||||
@@ -139,6 +141,12 @@ Operating System Notes
|
||||
The kit should compile even if you have intalled the KAME
|
||||
IPv6 kit.
|
||||
|
||||
IRIX
|
||||
build problems have been reported w/ IRIX 6.3, res_debug.c
|
||||
and #include <stdlib.h>. You may need to comment out
|
||||
the #include <stdlib.h> and declare
|
||||
"void *malloc(size_t size)" to get named to compile on 6.3.
|
||||
|
||||
Linux
|
||||
|
||||
"make links" and "make stdlinks" cause problems on
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
This is the source portion of BIND version 8.2.2, Patchlevel 5. Its
|
||||
companions are "doc" and "contrib" so you are probably not missing anything.
|
||||
This is the source portion of BIND version 8.2.3-T2B. Its companions
|
||||
are "doc" and "contrib" so you are probably not missing anything.
|
||||
|
||||
See the CHANGES file for a detailed listing of all changes. See the INSTALL
|
||||
file for information on building and installing BIND.
|
||||
@@ -208,6 +208,6 @@ To Support the Effort
|
||||
|
||||
The Internet Software Consortium has also commissioned a DHCP server
|
||||
implementation, has taken over official support/release of the INN
|
||||
system, and supports the Kerberos Version 5 effort at MIT. You can
|
||||
learn more about the ISC's goals and accomplishments from the web page
|
||||
at <URL:http://www.isc.org/>.
|
||||
system, and has supported the Kerberos Version 5 effort at MIT. You
|
||||
can learn more about the ISC's goals and accomplishments from the web
|
||||
page at <URL:http://www.isc.org/>.
|
||||
Loaded 100 of 6380 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user