Compare commits
1390 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116fcea5be | ||
|
|
d991abdd34 | ||
|
|
dd9c147444 | ||
|
|
60a4f87b0b | ||
|
|
16a468ccec | ||
|
|
f55f1f3e52 | ||
|
|
47627954a0 | ||
|
|
72cab7a281 | ||
|
|
93a8d9f260 | ||
|
|
665ce9d4e1 | ||
|
|
3b3ea9dc32 | ||
|
|
bab9a671ef | ||
|
|
8ef86ffe84 | ||
|
|
61cb2ba2de | ||
|
|
c540bcb001 | ||
|
|
4c156d8a32 | ||
|
|
5d958f894f | ||
|
|
957f4181c0 | ||
|
|
96940bcd57 | ||
|
|
5b2ae44f78 | ||
|
|
ab0a67f7af | ||
|
|
5a645f22a8 | ||
|
|
ff56906879 | ||
|
|
74caf0e21f | ||
|
|
274212e760 | ||
|
|
0bf3f4c52a | ||
|
|
39fea0a5b9 | ||
|
|
3919b46a4d | ||
|
|
3fb8cb760c | ||
|
|
1ead18e447 | ||
|
|
9ab3cf37ce | ||
|
|
47c1f10835 | ||
|
|
bb364f9cc8 | ||
|
|
342171fa9e | ||
|
|
0491126758 | ||
|
|
a8b1dd7809 | ||
|
|
0f940cc58a | ||
|
|
f4ffbc6072 | ||
|
|
c9f65d5ae6 | ||
|
|
2fe8fb192f | ||
|
|
2487445f5f | ||
|
|
a73c217bf6 | ||
|
|
f94e915e33 | ||
|
|
f6c5d09978 | ||
|
|
80c4685324 | ||
|
|
bba63ef665 | ||
|
|
accaae9b2c | ||
|
|
0949f5b342 | ||
|
|
de89517711 | ||
|
|
35abd4867a | ||
|
|
f87b9a3d2d | ||
|
|
02b46221dd | ||
|
|
0c99f4f4b7 | ||
|
|
e93c1c9f28 | ||
|
|
3ab668c366 | ||
|
|
1ae162d673 | ||
|
|
61a29c4291 | ||
|
|
6f88dc8713 | ||
|
|
d4ddfeb2c0 | ||
|
|
5a46076652 | ||
|
|
3f2ab5b34b | ||
|
|
2ae897db7b | ||
|
|
13d8a6969a | ||
|
|
68bd32bedb | ||
|
|
7a60d6d33f | ||
|
|
636264c1c6 | ||
|
|
3dd49be938 | ||
|
|
8979450631 | ||
|
|
60a2ce010a | ||
|
|
7f2d47d84c | ||
|
|
002fecdd9e | ||
|
|
174e3c15af | ||
|
|
81d26afebe | ||
|
|
6acebc04b6 | ||
|
|
fa6c4a2580 | ||
|
|
9f8e6353e5 | ||
|
|
4c4c045f87 | ||
|
|
602233213e | ||
|
|
f119e63750 | ||
|
|
58a2b0008e | ||
|
|
972a791882 | ||
|
|
abd6043a2f | ||
|
|
4498750810 | ||
|
|
cc1ae59c9b | ||
|
|
65f97ea344 | ||
|
|
14fc51e8aa | ||
|
|
1eea0f5680 | ||
|
|
cdbc4bfb13 | ||
|
|
b33f504e8f | ||
|
|
a65ff8a1aa | ||
|
|
23491b7f46 | ||
|
|
224a0f6e90 | ||
|
|
71634240a0 | ||
|
|
4d3a0887b4 | ||
|
|
d4cdd59eaa | ||
|
|
d5210e9bdd | ||
|
|
a87ec6840f | ||
|
|
1ff24e3f2f | ||
|
|
1fc399a5c1 | ||
|
|
9330d92639 | ||
|
|
becf700bc2 | ||
|
|
9233fdb359 | ||
|
|
0e537f1085 | ||
|
|
0bd011affd | ||
|
|
4bee3cff2e | ||
|
|
5c0927e108 | ||
|
|
c468f4efa5 | ||
|
|
9e1d244cbe | ||
|
|
57b2fe851c | ||
|
|
57794c6690 | ||
|
|
e894c9e1b5 | ||
|
|
700641afb8 | ||
|
|
5691dca9f4 | ||
|
|
ddbdca6cdb | ||
|
|
dd59d50944 | ||
|
|
a6d0ee24c3 | ||
|
|
a282e942bf | ||
|
|
e35528ae79 | ||
|
|
e257c999b8 | ||
|
|
f18dab92bf | ||
|
|
078adc7ed7 | ||
|
|
e6c98c3c55 | ||
|
|
c89aaf7a87 | ||
|
|
2c685f34e0 | ||
|
|
8cb7ba7951 | ||
|
|
2fe79d0b76 | ||
|
|
4668b84158 | ||
|
|
88f990e122 | ||
|
|
974452d4dd | ||
|
|
758d788bbe | ||
|
|
0bb56e0e04 | ||
|
|
41bd5f2fc6 | ||
|
|
8fa95abae4 | ||
|
|
0a55e63413 | ||
|
|
0468fca72b | ||
|
|
192db70960 | ||
|
|
c82a5dd3e3 | ||
|
|
e4d46a2146 | ||
|
|
8d0a1f71bf | ||
|
|
fecaba7ff1 | ||
|
|
36d29dedd5 | ||
|
|
a4d01f8a83 | ||
|
|
af6c39fb9b | ||
|
|
7cd4002083 | ||
|
|
0bb4bb9d51 | ||
|
|
11c15db517 | ||
|
|
d6c5a1280e | ||
|
|
99c3099c32 | ||
|
|
2ea10eeb75 | ||
|
|
3e4fa99098 | ||
|
|
c25e2eb0cf | ||
|
|
c21cdd3154 | ||
|
|
3e46876a73 | ||
|
|
80b03d929d | ||
|
|
472a91708a | ||
|
|
51de979ed9 | ||
|
|
94715d8e54 | ||
|
|
4d4057d8a2 | ||
|
|
6b6d114a21 | ||
|
|
59ff5cbd87 | ||
|
|
9a664b4984 | ||
|
|
9b7d357ca1 | ||
|
|
34a8901eb8 | ||
|
|
3fb6c995e0 | ||
|
|
de5a9a3e8b | ||
|
|
c89bc85009 | ||
|
|
54c0eb9aa6 | ||
|
|
9f9f893123 | ||
|
|
71533c8a83 | ||
|
|
b73089ce3e | ||
|
|
aca5862db1 | ||
|
|
9cd53f1cc0 | ||
|
|
84662ec4b3 | ||
|
|
eccb2d685c | ||
|
|
668fa5cf2a | ||
|
|
194e51aff0 | ||
|
|
c5fae8a617 | ||
|
|
8ab7667da4 | ||
|
|
94da86cbee | ||
|
|
e7db2d3588 | ||
|
|
f65e531ee4 | ||
|
|
4005bba437 | ||
|
|
95d1f25b28 | ||
|
|
35cf8beb33 | ||
|
|
aa712e7e73 | ||
|
|
6f374faca5 | ||
|
|
9701e9dfd2 | ||
|
|
c6459e8ec1 | ||
|
|
26d359a30c | ||
|
|
5cbbfc69e7 | ||
|
|
706873142e | ||
|
|
21168577a5 | ||
|
|
0a61519eea | ||
|
|
5acd97c7e0 | ||
|
|
1adb3b60be | ||
|
|
cb98b586fd | ||
|
|
3b0ee3f234 | ||
|
|
1c3c4d73ef | ||
|
|
67c012b3fc | ||
|
|
ed007ca416 | ||
|
|
9221586f37 | ||
|
|
e379e0936e | ||
|
|
2f622b3a51 | ||
|
|
ba19c83fd6 | ||
|
|
01015cc0e2 | ||
|
|
2a7bc122c1 | ||
|
|
f9d1614e6d | ||
|
|
8a0b9de41a | ||
|
|
db087efac4 | ||
|
|
41e69065b9 | ||
|
|
c9ba1ad75d | ||
|
|
03a8d06668 | ||
|
|
e2758c6759 | ||
|
|
a03f679e88 | ||
|
|
c40c9f7ed0 | ||
|
|
fb50da9dad | ||
|
|
92b61c816d | ||
|
|
b4fb061802 | ||
|
|
ef99a7a3dc | ||
|
|
39b1aee2e1 | ||
|
|
fd4c2b74f3 | ||
|
|
a9f89a7290 | ||
|
|
e8f944d3ca | ||
|
|
0aa01a2dce | ||
|
|
b4d9ac91ba | ||
|
|
1062293981 | ||
|
|
79853dc9bc | ||
|
|
5a70f42ab6 | ||
|
|
9874865a6f | ||
|
|
b4d909d415 | ||
|
|
7643f2b25e | ||
|
|
fa00de707c | ||
|
|
1e1db53986 | ||
|
|
c30f014a89 | ||
|
|
eaa29370f4 | ||
|
|
ebdac755af | ||
|
|
32aabfab40 | ||
|
|
cd107a5ac3 | ||
|
|
81bdb22b0c | ||
|
|
f29ba928cc | ||
|
|
8b69d04fff | ||
|
|
0c9b539a35 | ||
|
|
c24d15b2db | ||
|
|
b1eba81b9d | ||
|
|
3f9ef4ac46 | ||
|
|
f379b3eecb | ||
|
|
ee8602a486 | ||
|
|
79285c3664 | ||
|
|
79bfef9aab | ||
|
|
349a158056 | ||
|
|
2c57ee566b | ||
|
|
34c14b1cab | ||
|
|
c4bce95897 | ||
|
|
41f823ae4c | ||
|
|
0811b47a71 | ||
|
|
5c00743626 | ||
|
|
cedeabb357 | ||
|
|
4311136125 | ||
|
|
490e0de548 | ||
|
|
a209c3ae12 | ||
|
|
85b8fbe72b | ||
|
|
b477504754 | ||
|
|
7207cf2e37 | ||
|
|
b1855cdcf2 | ||
|
|
af01bda509 | ||
|
|
0bb27bb0b1 | ||
|
|
b02c260ecb | ||
|
|
3fbb50397c | ||
|
|
0f3423cd75 | ||
|
|
a80eb6545a | ||
|
|
2602861f23 | ||
|
|
fc34180cca | ||
|
|
ff542f0b27 | ||
|
|
c83a90e2f1 | ||
|
|
47aad344c3 | ||
|
|
5320333614 | ||
|
|
e1d867b686 | ||
|
|
0812293b47 | ||
|
|
8b00ebde78 | ||
|
|
d134121b09 | ||
|
|
8b4492ed1c | ||
|
|
62841e2935 | ||
|
|
1992529666 | ||
|
|
65e54c23e3 | ||
|
|
febb4403ff | ||
|
|
823e42c3e3 | ||
|
|
b1c2329954 | ||
|
|
9e21d55e37 | ||
|
|
ca3fe9fdab | ||
|
|
5cdc54a699 | ||
|
|
391372193c | ||
|
|
586776e98b | ||
|
|
de346b24e8 | ||
|
|
230dd159df | ||
|
|
f2e991439e | ||
|
|
0c3983b25a | ||
|
|
8c9e62b299 | ||
|
|
bc0a39238e | ||
|
|
49532259e5 | ||
|
|
05341dfeb0 | ||
|
|
833183a9e1 | ||
|
|
f71ec49525 | ||
|
|
1dfd43ac27 | ||
|
|
cb54d96eec | ||
|
|
46581e701a | ||
|
|
92fa3189ab | ||
|
|
90cde23c19 | ||
|
|
1c928cf61a | ||
|
|
200b9d7339 | ||
|
|
203937456e | ||
|
|
98233fa144 | ||
|
|
4857d5d554 | ||
|
|
ce1a2793f9 | ||
|
|
d4b72e81b2 | ||
|
|
f78fb05676 | ||
|
|
8a0901c4cb | ||
|
|
35d86581e5 | ||
|
|
7db039347a | ||
|
|
8a266a478e | ||
|
|
fde9a258d0 | ||
|
|
e68cf3bf89 | ||
|
|
4ca68d42a0 | ||
|
|
86b5fa5102 | ||
|
|
a7590083f1 | ||
|
|
7b6c90125c | ||
|
|
ad0c787900 | ||
|
|
121d8aba4d | ||
|
|
9df7ce09aa | ||
|
|
5cddf6dce8 | ||
|
|
4806f7c308 | ||
|
|
7f24c2b3ca | ||
|
|
78183bddff | ||
|
|
27a2afc1e7 | ||
|
|
8a73de51f1 | ||
|
|
30be017762 | ||
|
|
12d9a08f0d | ||
|
|
c78308f469 | ||
|
|
e09714ab53 | ||
|
|
4ee157f5ce | ||
|
|
1f28a4b83e | ||
|
|
68011701bd | ||
|
|
55d926cbaa | ||
|
|
63a49a4b90 | ||
|
|
ae2159c371 | ||
|
|
195190912f | ||
|
|
e81a0fd9c1 | ||
|
|
43e574558f | ||
|
|
88e57eee69 | ||
|
|
27c0e801f2 | ||
|
|
6811647e20 | ||
|
|
cc64313b80 | ||
|
|
f984dbba70 | ||
|
|
e2bdf44720 | ||
|
|
a18a007361 | ||
|
|
a6bd3f4a22 | ||
|
|
ee48228aa0 | ||
|
|
e187d30348 | ||
|
|
e3dafb45b4 | ||
|
|
bc434254ea | ||
|
|
164789226c | ||
|
|
593e3221fc | ||
|
|
1f198f75d7 | ||
|
|
40592de32d | ||
|
|
4c3e216cbd | ||
|
|
2e84a3f594 | ||
|
|
13ded5339f | ||
|
|
426cddbb30 | ||
|
|
65de5d71a9 | ||
|
|
940bbe18b6 | ||
|
|
58c4a9b5f4 | ||
|
|
ca5e8b2c2d | ||
|
|
7b70f548e4 | ||
|
|
35cc7fbeb8 | ||
|
|
55c6f3f507 | ||
|
|
9602f63a72 | ||
|
|
a9a45cddc4 | ||
|
|
10375d2629 | ||
|
|
cd05a95afc | ||
|
|
3a44cd477b | ||
|
|
86b061078b | ||
|
|
4dece73bf0 | ||
|
|
4a8ceeebff | ||
|
|
d477a9ed82 | ||
|
|
862fb8354d | ||
|
|
c484bc1dc8 | ||
|
|
1abfde0e03 | ||
|
|
3977443581 | ||
|
|
b9d027bfe2 | ||
|
|
a99a4b2a05 | ||
|
|
c4ea2a195c | ||
|
|
c0bb1ba1b1 | ||
|
|
d69519f86a | ||
|
|
aaefc6f838 | ||
|
|
989934b37c | ||
|
|
ed651fafef | ||
|
|
f985ecba0d | ||
|
|
ae561b8f12 | ||
|
|
fcc2c77af2 | ||
|
|
1a8cf59d04 | ||
|
|
89f0baab63 | ||
|
|
914d02825f | ||
|
|
f614d0015a | ||
|
|
3ca141ab81 | ||
|
|
7588db2691 | ||
|
|
ece4c9d565 | ||
|
|
9b43de2cb3 | ||
|
|
b67a7fca8c | ||
|
|
d810ebe67b | ||
|
|
6d1095db1e | ||
|
|
530bd5d486 | ||
|
|
3b08b34ceb | ||
|
|
93bb4036ce | ||
|
|
2a9322a117 | ||
|
|
8a8f27951b | ||
|
|
1d45d57e40 | ||
|
|
3a69da5f86 | ||
|
|
2ad6214ef0 | ||
|
|
51ffecc181 | ||
|
|
1ea07af9da | ||
|
|
e376fd97ac | ||
|
|
d2897e946f | ||
|
|
1e56737131 | ||
|
|
06617e7fdf | ||
|
|
01b152d6d9 | ||
|
|
b984fa41df | ||
|
|
04d2db3c44 | ||
|
|
b7b7b3e63f | ||
|
|
dcc683b4ae | ||
|
|
eff1369cab | ||
|
|
7ee78ffb82 | ||
|
|
e3d0bb59ab | ||
|
|
ea1971bd21 | ||
|
|
f9ccc501f8 | ||
|
|
159b8f71b7 | ||
|
|
db5c83c918 | ||
|
|
1341e4aa02 | ||
|
|
3dd7649ae7 | ||
|
|
000a9d36be | ||
|
|
0cd71233e0 | ||
|
|
70712c015e | ||
|
|
f789fee254 | ||
|
|
2a2f25bf29 | ||
|
|
0d9095d116 | ||
|
|
3eb22ca4d1 | ||
|
|
afd132adc9 | ||
|
|
5df8be8e7a | ||
|
|
b1408f61b4 | ||
|
|
c356e9997e | ||
|
|
51e66a47d8 | ||
|
|
49cab1c73c | ||
|
|
832f7f99fd | ||
|
|
d83af38877 | ||
|
|
cb7a3b0299 | ||
|
|
02081e4b62 | ||
|
|
76356eed97 | ||
|
|
85f6d866e6 | ||
|
|
255ae85b1e | ||
|
|
902e0e27e0 | ||
|
|
bd6944ea49 | ||
|
|
044cd57720 | ||
|
|
6cdcbc06d5 | ||
|
|
bb9fb905a1 | ||
|
|
4691eeae9f | ||
|
|
42c2ae9786 | ||
|
|
ebffaa4250 | ||
|
|
6c9aa8a9ca | ||
|
|
66bc7580c7 | ||
|
|
253c293213 | ||
|
|
ef0a265086 | ||
|
|
48331843ea | ||
|
|
8a5484202c | ||
|
|
5da4a0bd56 | ||
|
|
c63a0cfddc | ||
|
|
898d9f97f6 | ||
|
|
b956c8735e | ||
|
|
a97a80178e | ||
|
|
6dea092dec | ||
|
|
123cf7fe37 | ||
|
|
48a4ff2307 | ||
|
|
e582fc2a6f | ||
|
|
d75138be00 | ||
|
|
170457b73f | ||
|
|
084f96981b | ||
|
|
9aa4fb0dc6 | ||
|
|
a4ac03c188 | ||
|
|
cf7f7d0ef1 | ||
|
|
b61266eb51 | ||
|
|
25bd2bd8fa | ||
|
|
f66e550c80 | ||
|
|
545ac12f3d | ||
|
|
9fdd167da4 | ||
|
|
afc8f3defa | ||
|
|
434119ab89 | ||
|
|
a9d15dd3e4 | ||
|
|
97c7d358ea | ||
|
|
4e37b49261 | ||
|
|
f3d5a9dc61 | ||
|
|
a0e986b1f9 | ||
|
|
9c01ceb576 | ||
|
|
cf3b75c687 | ||
|
|
86a226680b | ||
|
|
03ff167d4d | ||
|
|
49a93d54be | ||
|
|
db0be09803 | ||
|
|
35305f8f7c | ||
|
|
66b369c62c | ||
|
|
82932c0d6b | ||
|
|
83b3a3df74 | ||
|
|
881431bf7e | ||
|
|
5971d0532c | ||
|
|
ecb1c96fc5 | ||
|
|
2e8d1eda1b | ||
|
|
ef60bcc0a6 | ||
|
|
cf04da3ebe | ||
|
|
9902a435cd | ||
|
|
d0d7b43342 | ||
|
|
daa14edc0d | ||
|
|
08c8ee9f52 | ||
|
|
e8777fd906 | ||
|
|
55c7e24c74 | ||
|
|
69bf8e4f71 | ||
|
|
ec84a2cfa5 | ||
|
|
93ae43f577 | ||
|
|
e785381d4d | ||
|
|
aba3746220 | ||
|
|
dc1da4a881 | ||
|
|
cc17b27a2b | ||
|
|
e3f68488ee | ||
|
|
6d8d7a88b2 | ||
|
|
3b82f9106d | ||
|
|
6edbcbf9a3 | ||
|
|
35b203fdb1 | ||
|
|
fa0fe45103 | ||
|
|
67c2d2fa54 | ||
|
|
25e9d7317c | ||
|
|
6e0f3b3bda | ||
|
|
25d26d76fd | ||
|
|
b19820774e | ||
|
|
a77c2973b3 | ||
|
|
d34ab6de9f | ||
|
|
b08dff6011 | ||
|
|
1e5f9dfa14 | ||
|
|
419dadf528 | ||
|
|
c2da8cb535 | ||
|
|
900a273d3d | ||
|
|
30fa6d8e03 | ||
|
|
d490669430 | ||
|
|
230b7775fe | ||
|
|
ef257bcc1b | ||
|
|
f011d59d67 | ||
|
|
4a5ca363b5 | ||
|
|
c02833ced6 | ||
|
|
cb13f32a7c | ||
|
|
fb53eb09cf | ||
|
|
0cb22acbda | ||
|
|
f7c1307878 | ||
|
|
423be1545c | ||
|
|
5582aae6d6 | ||
|
|
aff45df1af | ||
|
|
2a839c735e | ||
|
|
314d09adf7 | ||
|
|
674cd6fd48 | ||
|
|
bed9e48c12 | ||
|
|
f5a1e58f59 | ||
|
|
350b60661a | ||
|
|
455b809b17 | ||
|
|
e969b5e11b | ||
|
|
7db58ddc19 | ||
|
|
c50ec2b4e2 | ||
|
|
20a04a068d | ||
|
|
22049c1ec3 | ||
|
|
827daf1fca | ||
|
|
196de8bc40 | ||
|
|
2b09bfde6d | ||
|
|
46cee00ad8 | ||
|
|
afb8067c4f | ||
|
|
020277a38f | ||
|
|
dc8ee363db | ||
|
|
b1a60476c0 | ||
|
|
aba392e630 | ||
|
|
f0740680cd | ||
|
|
c51cd5fe91 | ||
|
|
4e86b0d53f | ||
|
|
c4928b2df9 | ||
|
|
2cde22ee10 | ||
|
|
7457cbe62f | ||
|
|
16e0e9370e | ||
|
|
9db2311b22 | ||
|
|
8200e91073 | ||
|
|
cd9b4b46f4 | ||
|
|
b2c2dc72bc | ||
|
|
0039e02339 | ||
|
|
8171eb0b3d | ||
|
|
dca25a1b39 | ||
|
|
abab24b785 | ||
|
|
77172e23f7 | ||
|
|
3bbd454578 | ||
|
|
8e5cad159f | ||
|
|
53ad9d83b9 | ||
|
|
8a925dcf90 | ||
|
|
28f2a169da | ||
|
|
14e641cb8c | ||
|
|
7a9e3651fd | ||
|
|
294112db54 | ||
|
|
f56c4001d5 | ||
|
|
9caa53e8d9 | ||
|
|
15e58909b6 | ||
|
|
878ba523ac | ||
|
|
6bcf58bab8 | ||
|
|
0dc9e0996a | ||
|
|
6f4e3dd910 | ||
|
|
c8d0edc06a | ||
|
|
03a7d0e8ae | ||
|
|
5f1ab506c8 | ||
|
|
898cce256f | ||
|
|
ba8af817fc | ||
|
|
db8c7af0b8 | ||
|
|
97980446a4 | ||
|
|
aca0749d71 | ||
|
|
f19a4bf1c4 | ||
|
|
693842c855 | ||
|
|
b87af1c325 | ||
|
|
98af1ee195 | ||
|
|
6567e50a6f | ||
|
|
f4814901af | ||
|
|
493ea15714 | ||
|
|
c90cdadcfb | ||
|
|
b6f25271a9 | ||
|
|
81b63473c0 | ||
|
|
685b44e22d | ||
|
|
25a790a631 | ||
|
|
813ba29677 | ||
|
|
09a652926f | ||
|
|
61ad5f9b94 | ||
|
|
dd4b0b7646 | ||
|
|
a1e64f6afd | ||
|
|
e94953a396 | ||
|
|
3c9012886f | ||
|
|
8c8e44d0ae | ||
|
|
77fa5b4116 | ||
|
|
c192577b58 | ||
|
|
beac6b15c9 | ||
|
|
00dcbb9dc6 | ||
|
|
bac0222eec | ||
|
|
2bc8ac55ce | ||
|
|
659dd75c78 | ||
|
|
36f9c1155a | ||
|
|
344c18cf73 | ||
|
|
0908191386 | ||
|
|
083d30afbb | ||
|
|
dc75514afc | ||
|
|
7193ee9890 | ||
|
|
8aa9382e58 | ||
|
|
0b920bb1cd | ||
|
|
7b9d99251f | ||
|
|
0e8d574ebd | ||
|
|
cba6e667da | ||
|
|
b9b9cb8a62 | ||
|
|
c6e6aa8850 | ||
|
|
55ccdba0f6 | ||
|
|
4cf101caae | ||
|
|
5518fe9be1 | ||
|
|
32f3d9842d | ||
|
|
8f860a27d1 | ||
|
|
4f294c247f | ||
|
|
d6e6ee3043 | ||
|
|
287fee89cb | ||
|
|
7840456b77 | ||
|
|
2635038e5c | ||
|
|
3c9575aadc | ||
|
|
ad4dda469f | ||
|
|
58153774b1 | ||
|
|
b6cbf7203b | ||
|
|
43d1edf88c | ||
|
|
f7d5c8ff8d | ||
|
|
05480c229a | ||
|
|
c7b2b11ec2 | ||
|
|
341f8682f2 | ||
|
|
3beb81a5d0 | ||
|
|
9ef5859996 | ||
|
|
a909eaa9b1 | ||
|
|
dce5e09683 | ||
|
|
ab73ac3b6f | ||
|
|
07bfb4f4e4 | ||
|
|
b2d1109737 | ||
|
|
fa59fc6eb4 | ||
|
|
0203ea37bf | ||
|
|
95702f970b | ||
|
|
0a70e23d1d | ||
|
|
b096b323d1 | ||
|
|
914cdb5997 | ||
|
|
06aab2c6ed | ||
|
|
dee29bbd3c | ||
|
|
d5322973fa | ||
|
|
4fc9428808 | ||
|
|
dc1cc91df1 | ||
|
|
e912f6ac38 | ||
|
|
b0aea49465 | ||
|
|
6e86430130 | ||
|
|
0874fa9321 | ||
|
|
e50070e3b3 | ||
|
|
7b2d6c3c98 | ||
|
|
9c7dcbfec3 | ||
|
|
04229f0581 | ||
|
|
9b8f37bb27 | ||
|
|
16895b67ce | ||
|
|
410699874c | ||
|
|
dbcca28c19 | ||
|
|
efca30b081 | ||
|
|
561acfb618 | ||
|
|
5d8d5e0c3a | ||
|
|
d23c3d110e | ||
|
|
361f377493 | ||
|
|
b6f3b7e7f6 | ||
|
|
f0f34dd8d9 | ||
|
|
7aab862a06 | ||
|
|
4fe0dfa9aa | ||
|
|
d824b54d82 | ||
|
|
a53d925844 | ||
|
|
7ff2db1dd6 | ||
|
|
691030d5ce | ||
|
|
11904c0435 | ||
|
|
372b873413 | ||
|
|
9639af49d2 | ||
|
|
7bef45ad3b | ||
|
|
a7285dfabc | ||
|
|
6bf3c91a0a | ||
|
|
cc26fb5ec4 | ||
|
|
cbf7d8f735 | ||
|
|
d1cfc50811 | ||
|
|
5e1e763506 | ||
|
|
46ec37365e | ||
|
|
d87559f9b9 | ||
|
|
9ed280d1ec | ||
|
|
41ae712b50 | ||
|
|
6b5c8751da | ||
|
|
7a4149a3f5 | ||
|
|
4c0cc2719e | ||
|
|
cfc1fe2ead | ||
|
|
504abf4b34 | ||
|
|
3ff6f21b51 | ||
|
|
6208131459 | ||
|
|
c22564335f | ||
|
|
4ee146c00a | ||
|
|
371624e0ec | ||
|
|
f3e1b1c226 | ||
|
|
8ccfb29765 | ||
|
|
8173242e01 | ||
|
|
f0ab18377d | ||
|
|
afeb246328 | ||
|
|
fd2b22474f | ||
|
|
aaaad89244 | ||
|
|
a575be430d | ||
|
|
8f0846e68c | ||
|
|
998af6f111 | ||
|
|
0e6dcf027f | ||
|
|
40fb96b838 | ||
|
|
16493465f9 | ||
|
|
efcfaf4b96 | ||
|
|
51d9144e9f | ||
|
|
09569d399f | ||
|
|
515e8d075f | ||
|
|
3c6274b8be | ||
|
|
ac780f36a0 | ||
|
|
c9bfb13cdb | ||
|
|
9e01a83636 | ||
|
|
7f7822aebd | ||
|
|
5b832396f5 | ||
|
|
40bfed28cd | ||
|
|
98c93e76d7 | ||
|
|
de1bcaa69a | ||
|
|
a1eefc013e | ||
|
|
ebbc730fc3 | ||
|
|
f42b90806a | ||
|
|
e6b1a30a26 | ||
|
|
2419ab589d | ||
|
|
7fddd8358d | ||
|
|
8145b458d6 | ||
|
|
613ff40936 | ||
|
|
b0d7ce8d09 | ||
|
|
ddde360e3e | ||
|
|
cb2e3a98a2 | ||
|
|
431a5a556d | ||
|
|
e743f940d4 | ||
|
|
b653422883 | ||
|
|
26de8dd299 | ||
|
|
9235536f38 | ||
|
|
470a185909 | ||
|
|
a3f2df124c | ||
|
|
e0ac271e5a | ||
|
|
ada0b4ca04 | ||
|
|
591201c1a0 | ||
|
|
c521f2a138 | ||
|
|
b0eaf0bc27 | ||
|
|
7bc944c8a9 | ||
|
|
40ccb7ed54 | ||
|
|
98ddbffe6e | ||
|
|
e2570d9b1b | ||
|
|
36189370a5 | ||
|
|
677d80b781 | ||
|
|
68de328ac1 | ||
|
|
a7072a5e1c | ||
|
|
3736ce3f55 | ||
|
|
1786291e32 | ||
|
|
274fcf8d1f | ||
|
|
8eece1c00c | ||
|
|
6e385a1b01 | ||
|
|
9cf2c02c47 | ||
|
|
de96892970 | ||
|
|
45d3ef7b3c | ||
|
|
ef92583c3a | ||
|
|
d2b56f60da | ||
|
|
87c576584d | ||
|
|
e63b85a50b | ||
|
|
74c5cd7668 | ||
|
|
db12229ce3 | ||
|
|
123a968be3 | ||
|
|
adbc4e4ea7 | ||
|
|
62aba4396e | ||
|
|
d55eab30fa | ||
|
|
82d576c9ca | ||
|
|
b0572bfd1e | ||
|
|
2d1c8849d8 | ||
|
|
df9928711b | ||
|
|
12e167f672 | ||
|
|
3cc13b29f0 | ||
|
|
250fb23dc0 | ||
|
|
300773cdca | ||
|
|
08bf4dec4f | ||
|
|
e9ecba9fc7 | ||
|
|
a665ae3de1 | ||
|
|
3306687363 | ||
|
|
af73996d51 | ||
|
|
831faf58f3 | ||
|
|
c811aa21aa | ||
|
|
13bda81ee0 | ||
|
|
72cc01ff48 | ||
|
|
159ca9c8c7 | ||
|
|
4ee139b0be | ||
|
|
5b8b623765 | ||
|
|
1f89845bb2 | ||
|
|
421f324baa | ||
|
|
e4283176ae | ||
|
|
6513d20744 | ||
|
|
906a81a1c7 | ||
|
|
e2701da5a9 | ||
|
|
e87d29171f | ||
|
|
454589debd | ||
|
|
0ac9b6d4cf | ||
|
|
387e1835d1 | ||
|
|
311f145bc7 | ||
|
|
06b6e5624a | ||
|
|
c554aef0e1 | ||
|
|
93b9873a56 | ||
|
|
1e273f640e | ||
|
|
9e12630d75 | ||
|
|
d37b7ebc0b | ||
|
|
67f039540c | ||
|
|
865e21b884 | ||
|
|
fac5fbfdbf | ||
|
|
ad73a4f50c | ||
|
|
9b6d66c787 | ||
|
|
b7aed08e65 | ||
|
|
85cca7096f | ||
|
|
6aa26565e6 | ||
|
|
a42ab504a0 | ||
|
|
62c666566e | ||
|
|
13a0d5fa5e | ||
|
|
2a2a19e542 | ||
|
|
ce4fd0c0fb | ||
|
|
6c3b981cd6 | ||
|
|
467a01024e | ||
|
|
2065c9982b | ||
|
|
354da24f5b | ||
|
|
d299a6422b | ||
|
|
33b131766f | ||
|
|
40c8a7062c | ||
|
|
d7b10963c2 | ||
|
|
d269f5fb90 | ||
|
|
2c5c5c06ea | ||
|
|
3eb65448a6 | ||
|
|
7763fd67c7 | ||
|
|
a5a8c57fe7 | ||
|
|
eaa37fd21c | ||
|
|
23311d9819 | ||
|
|
b7eb096088 | ||
|
|
7c3cfbde1a | ||
|
|
9375cc8e1f | ||
|
|
42a522f0e8 | ||
|
|
207e88d3c4 | ||
|
|
d29833c5aa | ||
|
|
6b902492ae | ||
|
|
2bda06bbb5 | ||
|
|
2e209097b6 | ||
|
|
e6ebac015d | ||
|
|
5cc29a6c7e | ||
|
|
ad5ecf906b | ||
|
|
18ad0b52d3 | ||
|
|
9e4e26e0c8 | ||
|
|
99d9144556 | ||
|
|
7ae6f8740d | ||
|
|
9560b6dea8 | ||
|
|
43a4725423 | ||
|
|
2440ffae49 | ||
|
|
344e9221ec | ||
|
|
45badf4c05 | ||
|
|
e7252adc1e | ||
|
|
eca25a6cab | ||
|
|
c6cfdbffe4 | ||
|
|
0b00cf70b6 | ||
|
|
bf6f0216d5 | ||
|
|
b3c3a1cb1e | ||
|
|
b1847ae244 | ||
|
|
1f2054c89c | ||
|
|
4448836263 | ||
|
|
36fb30dfef | ||
|
|
a4c30acd9d | ||
|
|
e8ddc0f46e | ||
|
|
13ef7f1f38 | ||
|
|
2297e26660 | ||
|
|
a0bb199f69 | ||
|
|
a37514163b | ||
|
|
a5741a465f | ||
|
|
3e3d627b25 | ||
|
|
a78608ec86 | ||
|
|
c81f201c8c | ||
|
|
5d6c2aae0a | ||
|
|
d8466ce31f | ||
|
|
1c359afad4 | ||
|
|
0f4eda33eb | ||
|
|
cb86231930 | ||
|
|
36fa521a0e | ||
|
|
1d0e0e217d | ||
|
|
50ca7f7f8f | ||
|
|
6fb1789ba4 | ||
|
|
959026c29a | ||
|
|
3211be5d14 | ||
|
|
a2647a4181 | ||
|
|
d743c5c6f3 | ||
|
|
c9d500e9fd | ||
|
|
de231a713e | ||
|
|
60a71efca8 | ||
|
|
292f98dc29 | ||
|
|
2a736d0c2e | ||
|
|
b337d3f8e5 | ||
|
|
205855b8ee | ||
|
|
b9f5e50421 | ||
|
|
02440068fc | ||
|
|
4b9420d7d7 | ||
|
|
3e7c270f6c | ||
|
|
9a21d1a2fd | ||
|
|
c8cfcab5db | ||
|
|
551374c228 | ||
|
|
a3e4dcafe0 | ||
|
|
66b8f17a29 | ||
|
|
b1eb16e5ff | ||
|
|
5a377144b0 | ||
|
|
78fc74633a | ||
|
|
484b2f43d6 | ||
|
|
5998a4b2af | ||
|
|
f8c56494c9 | ||
|
|
a7ed430587 | ||
|
|
3f6f7672c2 | ||
|
|
5824aab560 | ||
|
|
9acaece9cc | ||
|
|
bee1f38e01 | ||
|
|
4e95b347a7 | ||
|
|
46624d640e | ||
|
|
f7ef192c02 | ||
|
|
58654acf08 | ||
|
|
905e94f058 | ||
|
|
c8f70b8154 | ||
|
|
ac9a7f47bd | ||
|
|
d5482f6e75 | ||
|
|
6e614336d6 | ||
|
|
c3c97e66b1 | ||
|
|
5d4ef90b2c | ||
|
|
16f2eb25f4 | ||
|
|
ce41c63f41 | ||
|
|
e1f30da613 | ||
|
|
56770462c2 | ||
|
|
8da0925650 | ||
|
|
a9d31d3169 | ||
|
|
5bf3967f26 | ||
|
|
0fc71a1154 | ||
|
|
912b4e0cb7 | ||
|
|
42a2c1a03a | ||
|
|
e8846c3930 | ||
|
|
83fc90c8c3 | ||
|
|
b43f3b6bfc | ||
|
|
4eb7340395 | ||
|
|
4989de6acc | ||
|
|
256c37f7fa | ||
|
|
42bbd56673 | ||
|
|
e1dc59bd16 | ||
|
|
9ce3961b8e | ||
|
|
4523163411 | ||
|
|
a719ab7780 | ||
|
|
453be3b530 | ||
|
|
0f92964a2f | ||
|
|
25397ef756 | ||
|
|
ebec792700 | ||
|
|
c7859a538c | ||
|
|
3b386ad39f | ||
|
|
dff0434eaf | ||
|
|
253b4b3fe5 | ||
|
|
20eced94e7 | ||
|
|
da597227ac | ||
|
|
170b420d07 | ||
|
|
4510dddae4 | ||
|
|
49fe8e24b2 | ||
|
|
fb96391106 | ||
|
|
c80138ac71 | ||
|
|
a022f412b5 | ||
|
|
05bbf81f93 | ||
|
|
b9cea27497 | ||
|
|
5d47cafa5b | ||
|
|
e9651ae962 | ||
|
|
6dec907191 | ||
|
|
dafc8f1062 | ||
|
|
ee1cabf06c | ||
|
|
541b5c5c38 | ||
|
|
008cc7c1a7 | ||
|
|
eb057107c5 | ||
|
|
cf975bbc22 | ||
|
|
c297701987 | ||
|
|
149153f8ca | ||
|
|
9f0364df60 | ||
|
|
df0ba02a38 | ||
|
|
9212eab21f | ||
|
|
d7c70a41e5 | ||
|
|
1c4065cd10 | ||
|
|
34a58c8d82 | ||
|
|
3a5d923bf1 | ||
|
|
7b9bddad1b | ||
|
|
f389ad2655 | ||
|
|
a06e5c383d | ||
|
|
c4bb6abc2b | ||
|
|
6c2c2f3c34 | ||
|
|
fe343bb002 | ||
|
|
3badab8b70 | ||
|
|
1c2dd749eb | ||
|
|
dbde088d98 | ||
|
|
62d44dc9ef | ||
|
|
81f6039a7f | ||
|
|
e8e2f6f6b9 | ||
|
|
88e7725c13 | ||
|
|
5bf75abb30 | ||
|
|
122a32b928 | ||
|
|
220eafe705 | ||
|
|
f6f20e1269 | ||
|
|
7978f9d2f3 | ||
|
|
63deb069bb | ||
|
|
f6655c171b | ||
|
|
5e5d5ab1f6 | ||
|
|
0824146978 | ||
|
|
03bb1e5750 | ||
|
|
91a83fe265 | ||
|
|
0b364d00bc | ||
|
|
0d984b36ef | ||
|
|
40b4e71db2 | ||
|
|
7f343ed574 | ||
|
|
eb1627049f | ||
|
|
c0074d3aa9 | ||
|
|
13be76efe5 | ||
|
|
8fc07701bc | ||
|
|
fb24016c30 | ||
|
|
f248bffc9e | ||
|
|
1b7d95df29 | ||
|
|
af424b4e43 | ||
|
|
16d0609fad | ||
|
|
068944de36 | ||
|
|
77267ca28b | ||
|
|
5e2c84b119 | ||
|
|
e0701109ca | ||
|
|
103dc9e80a | ||
|
|
6ed6e31e80 | ||
|
|
e37a6ef219 | ||
|
|
53b6f99fb0 | ||
|
|
4234aa2c4a | ||
|
|
069f6ed574 | ||
|
|
373df14150 | ||
|
|
f08922e848 | ||
|
|
ffe7e9166e | ||
|
|
6ce51040a2 | ||
|
|
34dd221af7 | ||
|
|
dc2194efa7 | ||
|
|
ac66d329c7 | ||
|
|
09c18bc918 | ||
|
|
89df7fc91d | ||
|
|
a46b8b84d4 | ||
|
|
b05c989298 | ||
|
|
98725c443e | ||
|
|
7f47f4174d | ||
|
|
6955228f39 | ||
|
|
693bd970e7 | ||
|
|
7e8ed05df4 | ||
|
|
0f7365e6af | ||
|
|
09f03783ea | ||
|
|
84e730cbd8 | ||
|
|
4aca722796 | ||
|
|
28b533cf87 | ||
|
|
2a556de6d2 | ||
|
|
feaa082ea8 | ||
|
|
117bac1e2d | ||
|
|
6c66933f90 | ||
|
|
ee1b608bcf | ||
|
|
d26290a017 | ||
|
|
739f2d7536 | ||
|
|
16d01fba85 | ||
|
|
f531dba2d2 | ||
|
|
5aff633a0b | ||
|
|
ea19830de1 | ||
|
|
ecc8a52f82 | ||
|
|
17a0731f28 | ||
|
|
ca0bed1400 | ||
|
|
3404e8e4e5 | ||
|
|
8a0c10fcb9 | ||
|
|
2639ae9b17 | ||
|
|
8d24932c80 | ||
|
|
4fcd34137c | ||
|
|
20101b3bab | ||
|
|
e41c0b1a2d | ||
|
|
f8a8ea0a79 | ||
|
|
f6e558f5d4 | ||
|
|
9bb7552df5 | ||
|
|
ba759ef03e | ||
|
|
470ab03b86 | ||
|
|
9a14560daf | ||
|
|
8b0dbff312 | ||
|
|
8cedace2f5 | ||
|
|
d4e41fd1f6 | ||
|
|
0574bb5a63 | ||
|
|
835232d504 | ||
|
|
60549b67be | ||
|
|
1ecdac623a | ||
|
|
78a0260993 | ||
|
|
dd19f8cd07 | ||
|
|
bcaf746508 | ||
|
|
652618e458 | ||
|
|
4ff8fdba57 | ||
|
|
78ce6f86f7 | ||
|
|
590ff06418 | ||
|
|
4b30979086 | ||
|
|
12e9303297 | ||
|
|
1cee6fe95e | ||
|
|
ae9fa7fdf6 | ||
|
|
b4345d7598 | ||
|
|
a5dfadeb70 | ||
|
|
8427d774b6 | ||
|
|
895850b8cf | ||
|
|
8c925134f9 | ||
|
|
f3ce085913 | ||
|
|
8182a9d972 | ||
|
|
1f8dbed029 | ||
|
|
e920c1e1df | ||
|
|
5859ad686b | ||
|
|
e698d818c6 | ||
|
|
68db8ed0b9 | ||
|
|
f6f814cb02 | ||
|
|
dc47875fc7 | ||
|
|
0cfdb11450 | ||
|
|
368f77ceea | ||
|
|
397575951e | ||
|
|
3de6a807ce | ||
|
|
42399159da | ||
|
|
fc8f0b9ee2 | ||
|
|
7011e7c680 | ||
|
|
86139e8bf2 | ||
|
|
b4bea1bfcb | ||
|
|
545054c608 | ||
|
|
9fd2d72ce8 | ||
|
|
01fcee7d71 | ||
|
|
4d3c887d6b | ||
|
|
4392e004f8 | ||
|
|
37325bd7c5 | ||
|
|
34a2864e27 | ||
|
|
9a37f63263 | ||
|
|
630f566d3f | ||
|
|
03f64ac97a | ||
|
|
71dbe2d023 | ||
|
|
97eb470bee | ||
|
|
7920d48156 | ||
|
|
b5ae3961bb | ||
|
|
06a0260c3c | ||
|
|
2488cc6442 | ||
|
|
9e4312453d | ||
|
|
4690e8b015 | ||
|
|
23284ee7bd | ||
|
|
b17e3adb60 | ||
|
|
5c591816cb | ||
|
|
5e602d3dab | ||
|
|
0ad4e16985 | ||
|
|
47b58b2ebb | ||
|
|
65be30daed | ||
|
|
429639f938 | ||
|
|
098412be83 | ||
|
|
9313bc9a6f | ||
|
|
180358ffb4 | ||
|
|
06700d05d1 | ||
|
|
869a223d43 | ||
|
|
635a8f772c | ||
|
|
f044bd10ef | ||
|
|
8379b08845 | ||
|
|
67fa273d00 | ||
|
|
b9f53528ee | ||
|
|
6e47e2996f | ||
|
|
a3db59df6f | ||
|
|
dbfb70134c | ||
|
|
831edb6614 | ||
|
|
53866b1ebb | ||
|
|
71435d15cf | ||
|
|
d24348c636 | ||
|
|
6ef440c03b | ||
|
|
f1faf0d327 | ||
|
|
1f20814fe8 | ||
|
|
377f4e7e31 | ||
|
|
f200f53a0b | ||
|
|
5eb6f6e922 | ||
|
|
e2d45ae24c | ||
|
|
d2dbe5b2ae | ||
|
|
2fc2748c5a | ||
|
|
2793cb097b | ||
|
|
b24f63f996 | ||
|
|
a1a12bbc34 | ||
|
|
01b5238d50 | ||
|
|
a187743e75 | ||
|
|
24cb4e60fc | ||
|
|
3f22092d45 | ||
|
|
2f3c9c04cc | ||
|
|
74c06cfc43 | ||
|
|
8003edc357 | ||
|
|
6ebe0cdf82 | ||
|
|
aa6ff4c8be | ||
|
|
8e0253ac3d | ||
|
|
e10916476a | ||
|
|
c0c8d25799 | ||
|
|
9dc7c1f081 | ||
|
|
373aecf3cd | ||
|
|
bfeecdbf62 | ||
|
|
c0dfa2f3f1 | ||
|
|
5c7d64b981 | ||
|
|
6011237232 | ||
|
|
25dc0fc376 | ||
|
|
fe07e7c984 | ||
|
|
3985311b2e | ||
|
|
26ebfa1ce1 | ||
|
|
b3a0a2d86f | ||
|
|
e8d30bba65 | ||
|
|
33c9d427fd | ||
|
|
498d7d8a4c | ||
|
|
491efeead9 | ||
|
|
762665cec1 | ||
|
|
e3354a8556 | ||
|
|
6cd2d1218e | ||
|
|
4b496e29bd | ||
|
|
13b5dd4a82 | ||
|
|
fc01683584 | ||
|
|
45e4cce8c2 | ||
|
|
79d62892ad | ||
|
|
ac310cbe09 | ||
|
|
50539c12f5 | ||
|
|
76708e9bf4 | ||
|
|
921bacd244 | ||
|
|
f2c3cbab00 | ||
|
|
24a5f48921 | ||
|
|
d78ae27865 | ||
|
|
ddc3f62290 | ||
|
|
08f731bae0 | ||
|
|
08e4312998 | ||
|
|
c7050eea55 | ||
|
|
81399e75ad | ||
|
|
6189062d12 | ||
|
|
988b95f150 | ||
|
|
ff26d9a4ff | ||
|
|
2ac57865cb | ||
|
|
86e323da6b | ||
|
|
81056ac999 | ||
|
|
575d055f90 | ||
|
|
d6af53bec0 | ||
|
|
d1c117ec80 | ||
|
|
32c757b12c | ||
|
|
ee1134da9d | ||
|
|
ac6e455f16 | ||
|
|
ad1f2f2d78 | ||
|
|
0c03a6a50f | ||
|
|
c8372f31f8 | ||
|
|
5946b9d41d | ||
|
|
21725c107d | ||
|
|
3eed5d3bdb | ||
|
|
15210b3e06 | ||
|
|
556faf0d3a | ||
|
|
82dee9dbc3 | ||
|
|
3cb1096425 | ||
|
|
4383596e9d | ||
|
|
e68d8eb1ff | ||
|
|
4c0a9db684 | ||
|
|
6dd606eabf | ||
|
|
4269db3991 | ||
|
|
f50f1bf7d6 | ||
|
|
6657c0e58e | ||
|
|
582c0ed74d | ||
|
|
707fbb966d | ||
|
|
1b2189c205 | ||
|
|
a89bcc465b | ||
|
|
e2730c3e2f | ||
|
|
029d91baa9 | ||
|
|
cedc0404e1 | ||
|
|
137495002d | ||
|
|
28663f45d6 | ||
|
|
bb830fc0d3 | ||
|
|
f19304bf22 | ||
|
|
1d14529942 | ||
|
|
5b40436aaf | ||
|
|
d78494cd6e | ||
|
|
330374be9e | ||
|
|
90285c46a2 | ||
|
|
6c0fcd575e | ||
|
|
3cc5e1add4 | ||
|
|
2144b289de | ||
|
|
f60593cc35 | ||
|
|
6bc21b6992 | ||
|
|
11193f5fa4 | ||
|
|
8214e5e284 | ||
|
|
ad5771aa28 | ||
|
|
042b5bf606 | ||
|
|
7b7091e905 | ||
|
|
ae947059e6 | ||
|
|
d59c49aecb | ||
|
|
6312d7238b | ||
|
|
0964b221e7 | ||
|
|
482afb8a6f | ||
|
|
423db7d35a | ||
|
|
eeab8e0680 | ||
|
|
1b2c01db1b | ||
|
|
19b790eb53 | ||
|
|
4d7c317700 | ||
|
|
f838e3c204 | ||
|
|
360de619c0 | ||
|
|
1bf6d23f34 | ||
|
|
f0a158d8c1 | ||
|
|
2758519ed2 | ||
|
|
65764218f7 | ||
|
|
a8cf207549 | ||
|
|
eec65ac664 | ||
|
|
4fe558f44f | ||
|
|
1ce7983ee3 | ||
|
|
c1b4cc24e4 | ||
|
|
61db813ff6 | ||
|
|
ac34bfd42b | ||
|
|
8fea317779 | ||
|
|
6704520919 | ||
|
|
fcd2a802a8 | ||
|
|
13d50be356 | ||
|
|
6faa2a636c | ||
|
|
e216edf294 | ||
|
|
769302d3d6 | ||
|
|
c046958745 | ||
|
|
ba9990cc00 | ||
|
|
60d52d68da | ||
|
|
a0147a8c32 | ||
|
|
7b87ff5b11 | ||
|
|
d7490d374d | ||
|
|
b697b67d53 | ||
|
|
be6490f4b3 | ||
|
|
a6e357da22 | ||
|
|
a0eaaa5c9f | ||
|
|
1207fcc6f0 | ||
|
|
cccfe8e0ce | ||
|
|
826b9590f2 | ||
|
|
4c10a31440 | ||
|
|
7bd7946346 | ||
|
|
78186ee5f5 | ||
|
|
49165ef796 | ||
|
|
31adc0a3c4 | ||
|
|
a09a8d4f3e | ||
|
|
277ff6f2ce | ||
|
|
f448dfe063 | ||
|
|
4b6b1bc47a | ||
|
|
a98b9ca8dc | ||
|
|
cbc9586c13 | ||
|
|
b641afc78a | ||
|
|
e7e6508854 | ||
|
|
354d88f883 | ||
|
|
a53514d4a9 | ||
|
|
8c69c6cd7f | ||
|
|
f28acecb78 | ||
|
|
8afc228c48 | ||
|
|
1bb7c4d78a | ||
|
|
2f892aca91 |
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
cscope.*
|
||||
*.swap
|
||||
.*.sw[po]
|
||||
.sw[po]
|
||||
*~
|
||||
*.orig
|
||||
*.diff
|
||||
*.patch
|
||||
*.rej
|
||||
*.[1-9].gz
|
||||
*.o
|
||||
*.[psS]o
|
||||
*.a
|
||||
*.d
|
||||
.depend
|
||||
nbsdsrc/*
|
||||
tools/revision
|
||||
TAGS
|
||||
tags
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
\#*#
|
||||
CVS
|
||||
!/.gitignore
|
||||
.gitignore
|
||||
.svn
|
||||
minix-port.patch
|
||||
*.worldstone.log
|
||||
.worldstone*
|
||||
usr.bin/mdocml/man/*.7
|
||||
etc/passwd
|
||||
etc/pwd.db
|
||||
etc/spwd.db
|
||||
tools/image
|
||||
tools/kernel
|
||||
share/zoneinfo/builddir
|
||||
lib/libc/compat__*
|
||||
130
Makefile
130
Makefile
@@ -1,5 +1,7 @@
|
||||
# Master Makefile to compile everything in /usr/src except the system.
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MAKE=make
|
||||
|
||||
usage:
|
||||
@@ -13,9 +15,7 @@ usage:
|
||||
@echo " make libraries # Compile and install libraries"
|
||||
@echo " make commands # Compile all, commands, but don't install"
|
||||
@echo " make install # Compile and install commands"
|
||||
@echo " make depend # Generate required .depend files"
|
||||
@echo " make gnu-includes # Install include files for GCC"
|
||||
@echo " make gnu-libraries # Compile and install libraries for GCC"
|
||||
@echo " make clean # Remove all compiler results"
|
||||
@echo ""
|
||||
@echo "Run 'make' in tools/ to create a new MINIX configuration."
|
||||
@@ -29,64 +29,96 @@ usage:
|
||||
# 'make install' target.
|
||||
#
|
||||
# etcfiles has to be done first.
|
||||
.if ${COMPILER_TYPE} == "ack"
|
||||
world: mkfiles includes depend libraries install
|
||||
.elif ${COMPILER_TYPE} == "gnu"
|
||||
world: mkfiles includes depend gnu-libraries install
|
||||
.endif
|
||||
world: mkfiles etcfiles includes libraries dep-all install etcforce
|
||||
|
||||
mkfiles:
|
||||
cp etc/mk/*.mk /etc/mk/
|
||||
make -C share/mk install
|
||||
|
||||
includes:
|
||||
cd include && $(MAKE) includes
|
||||
$(MAKE) -C include includes
|
||||
$(MAKE) -C lib includes NBSD_LIBC=yes
|
||||
|
||||
libraries:
|
||||
cd lib && sh ack_build.sh obj depend all install
|
||||
|
||||
MKHEADERS411=/usr/gnu/libexec/gcc/i386-pc-minix/4.1.1/install-tools/mkheaders
|
||||
MKHEADERS443=/usr/gnu/libexec/gcc/i686-pc-minix/4.4.3/install-tools/mkheaders
|
||||
MKHEADERSS=/usr/pkg/gcc*/libexec/gcc/*/*/install-tools/mkheaders
|
||||
gnu-includes: includes
|
||||
SHELL=/bin/sh; if [ -f $(MKHEADERS411) ] ; then sh -e $(MKHEADERS411) ; fi
|
||||
SHELL=/bin/sh; if [ -f $(MKHEADERS443) ] ; then sh -e $(MKHEADERS443) ; fi
|
||||
SHELL=/bin/sh; for d in $(MKHEADERSS); do if [ -f $$d ] ; then sh -e $$d ; fi; done
|
||||
|
||||
gnu-libraries:
|
||||
cd lib && sh gnu_build.sh obj depend all install
|
||||
libraries: includes
|
||||
$(MAKE) -C lib dependall install
|
||||
|
||||
commands:
|
||||
cd commands && $(MAKE) all
|
||||
commands: includes libraries
|
||||
$(MAKE) -C commands all
|
||||
$(MAKE) -C bin all
|
||||
$(MAKE) -C sbin all
|
||||
$(MAKE) -C usr.bin all
|
||||
$(MAKE) -C libexec all
|
||||
$(MAKE) -C usr.sbin all
|
||||
|
||||
depend::
|
||||
cd boot && $(MAKE) depend
|
||||
cd commands && $(MAKE) depend
|
||||
cd kernel && $(MAKE) depend
|
||||
cd servers && $(MAKE) depend
|
||||
cd drivers && $(MAKE) depend
|
||||
dep-all:
|
||||
$(MAKE) -C sys dependall
|
||||
$(MAKE) -C commands dependall
|
||||
$(MAKE) -C bin dependall
|
||||
$(MAKE) -C sbin dependall
|
||||
$(MAKE) -C usr.bin dependall
|
||||
$(MAKE) -C libexec dependall
|
||||
$(MAKE) -C usr.sbin dependall
|
||||
$(MAKE) -C kernel dependall
|
||||
$(MAKE) -C servers dependall
|
||||
$(MAKE) -C drivers dependall
|
||||
|
||||
etcfiles::
|
||||
cd etc && $(MAKE) install
|
||||
etcfiles:
|
||||
$(MAKE) -C etc install
|
||||
|
||||
all::
|
||||
cd boot && $(MAKE) all
|
||||
cd commands && $(MAKE) all
|
||||
cd tools && $(MAKE) all
|
||||
etcforce:
|
||||
$(MAKE) -C etc installforce
|
||||
|
||||
install::
|
||||
cd boot && $(MAKE) install
|
||||
cd man && $(MAKE) install makedb
|
||||
cd commands && $(MAKE) install
|
||||
cd share && $(MAKE) install
|
||||
cd tools && $(MAKE) install
|
||||
all:
|
||||
$(MAKE) -C sys all
|
||||
$(MAKE) -C commands all
|
||||
$(MAKE) -C bin all
|
||||
$(MAKE) -C sbin all
|
||||
$(MAKE) -C usr.bin all
|
||||
$(MAKE) -C libexec all
|
||||
$(MAKE) -C usr.sbin all
|
||||
$(MAKE) -C tools all
|
||||
|
||||
clean::
|
||||
cd boot && $(MAKE) clean
|
||||
cd commands && $(MAKE) clean
|
||||
cd tools && $(MAKE) clean
|
||||
cd lib && sh ack_build.sh clean
|
||||
cd lib && sh gnu_build.sh clean
|
||||
cd test && $(MAKE) clean
|
||||
install:
|
||||
$(MAKE) -C sys install
|
||||
$(MAKE) -C libexec install
|
||||
$(MAKE) -C man install makedb
|
||||
$(MAKE) -C commands install
|
||||
$(MAKE) -C bin install
|
||||
$(MAKE) -C sbin install
|
||||
$(MAKE) -C usr.bin install
|
||||
$(MAKE) -C usr.sbin install
|
||||
$(MAKE) -C servers install
|
||||
$(MAKE) -C share install
|
||||
$(MAKE) -C tools install
|
||||
|
||||
cleandepend::
|
||||
cd boot && $(MAKE) cleandepend
|
||||
cd commands && $(MAKE) cleandepend
|
||||
cd tools && $(MAKE) cleandepend
|
||||
clean: mkfiles
|
||||
$(MAKE) -C sys clean
|
||||
$(MAKE) -C commands clean
|
||||
$(MAKE) -C bin clean
|
||||
$(MAKE) -C sbin clean
|
||||
$(MAKE) -C usr.bin clean
|
||||
$(MAKE) -C libexec clean
|
||||
$(MAKE) -C usr.sbin clean
|
||||
$(MAKE) -C share clean
|
||||
$(MAKE) -C tools clean
|
||||
$(MAKE) -C lib clean
|
||||
$(MAKE) -C test clean
|
||||
|
||||
cleandepend: mkfiles
|
||||
$(MAKE) -C lib cleandepend
|
||||
$(MAKE) -C sys cleandepend
|
||||
$(MAKE) -C commands cleandepend
|
||||
$(MAKE) -C bin cleandepend
|
||||
$(MAKE) -C sbin cleandepend
|
||||
$(MAKE) -C usr.bin cleandepend
|
||||
$(MAKE) -C libexec cleandepend
|
||||
$(MAKE) -C usr.sbin cleandepend
|
||||
$(MAKE) -C tools cleandepend
|
||||
|
||||
# Warn usage change
|
||||
elf-libraries:
|
||||
echo "That target is just libraries now."
|
||||
false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
#!/usr/pkg/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
@@ -932,9 +932,9 @@ SPDP dtime()
|
||||
return q;
|
||||
}
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
#include <minix/sysinfo.h>
|
||||
#include <time.h>
|
||||
|
||||
struct tms tms;
|
||||
@@ -945,7 +945,7 @@ SPDP dtime(void)
|
||||
int secs, msecs;
|
||||
u32_t system_hz;
|
||||
times(&tms);
|
||||
getsysinfo_up(PM_PROC_NR, SIU_SYSTEMHZ, sizeof(system_hz), &system_hz);
|
||||
system_hz = (u32_t) sysconf(_SC_CLK_TCK);
|
||||
secs = tms.tms_utime / system_hz;
|
||||
q = secs;
|
||||
tms.tms_utime -= secs * system_hz;
|
||||
|
||||
7
bin/Makefile
Normal file
7
bin/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
# Makefile for bin
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= mkdir rm rmdir date
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
4
bin/Makefile.inc
Normal file
4
bin/Makefile.inc
Normal file
@@ -0,0 +1,4 @@
|
||||
CPPFLAGS+= -D_NETBSD_SOURCE
|
||||
|
||||
BINDIR?=/bin
|
||||
|
||||
15
bin/date/Makefile
Normal file
15
bin/date/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
# $NetBSD: Makefile,v 1.15 2011/08/14 10:53:16 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= date
|
||||
SRCS= date.c netdate.c
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
CPPFLAGS+=-I${.CURDIR}
|
||||
|
||||
TZDIR= /usr/share/zoneinfo
|
||||
CPPFLAGS+= -DHAVE_ADJTIME=0 -DTZDIR=\"$(TZDIR)\"
|
||||
|
||||
COPTS.date.c = -Wno-format-nonliteral
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
244
bin/date/date.1
Normal file
244
bin/date/date.1
Normal file
@@ -0,0 +1,244 @@
|
||||
.\" $NetBSD: date.1,v 1.41 2010/02/04 22:56:11 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1990, 1993
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
|
||||
.\"
|
||||
.Dd November 15, 2006
|
||||
.Dt DATE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm date
|
||||
.Nd display or set date and time
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ajnu
|
||||
.Op Fl d Ar date
|
||||
.Op Fl r Ar seconds
|
||||
.Op Cm + Ns Ar format
|
||||
.Sm off
|
||||
.Oo Oo Oo Oo Oo Oo
|
||||
.Ar CC Oc
|
||||
.Ar yy Oc
|
||||
.Ar mm Oc
|
||||
.Ar dd Oc
|
||||
.Ar HH Oc Ar MM Oo
|
||||
.Li \&. Ar SS Oc Oc
|
||||
.Sm on
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
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.
|
||||
Only the superuser may set the date.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Use
|
||||
.Xr adjtime 2
|
||||
to change the local system time slowly,
|
||||
maintaining it as a monotonically increasing function.
|
||||
.Fl a
|
||||
implies
|
||||
.Fl n .
|
||||
.It Fl d Ar date
|
||||
Parse the provided human-described date and time and display the result without
|
||||
actually changing the system clock.
|
||||
(See
|
||||
.Xr parsedate 3
|
||||
for examples.)
|
||||
.It Fl j
|
||||
Parse the provided canonical representation of date and time (described below)
|
||||
and display the result without actually changing the system clock.
|
||||
.It Fl n
|
||||
The utility
|
||||
.Xr timed 8
|
||||
is used to synchronize the clocks on groups of machines.
|
||||
By default, if
|
||||
timed
|
||||
is running,
|
||||
.Nm
|
||||
will set 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 Ar seconds
|
||||
Print out the date and time that is
|
||||
.Ar seconds
|
||||
from the Epoch.
|
||||
.It Fl u
|
||||
Display or set the date in
|
||||
.Tn UTC
|
||||
(universal) time.
|
||||
.El
|
||||
.Pp
|
||||
An operand with a leading plus
|
||||
.Pq Cm +
|
||||
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 \*[Lt]newline\*[Gt] character is always output after the characters
|
||||
specified by the format string.
|
||||
The format string for the default display is:
|
||||
.Bd -literal -offset indent
|
||||
%a %b %e %H:%M:%S %Z %Y
|
||||
.Ed
|
||||
.Pp
|
||||
If an operand does not have a leading plus sign, it is interpreted as
|
||||
a value for setting the system's notion of the current date and time.
|
||||
The canonical representation for setting the date and time is:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact -offset indent
|
||||
.It Ar CC
|
||||
The first two digits of the year (the century).
|
||||
.It Ar yy
|
||||
The second two digits of the year.
|
||||
If
|
||||
.Ar yy
|
||||
is specified, but
|
||||
.Ar CC
|
||||
is not, a value for
|
||||
.Ar yy
|
||||
between 69 and 99 results in a
|
||||
.Ar CC
|
||||
value of 19.
|
||||
Otherwise, a
|
||||
.Ar CC
|
||||
value of 20 is used.
|
||||
.It Ar mm
|
||||
The month of the year, from 01 to 12.
|
||||
.It Ar dd
|
||||
The day of the month, from 01 to 31.
|
||||
.It Ar HH
|
||||
The hour of the day, from 00 to 23.
|
||||
.It Ar MM
|
||||
The minute of the hour, from 00 to 59.
|
||||
.It Ar SS
|
||||
The second of the minute, from 00 to 61.
|
||||
.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.
|
||||
.Sh ENVIRONMENT
|
||||
The following environment variables affect the execution of
|
||||
.Nm :
|
||||
.Bl -tag -width iTZ
|
||||
.It Ev TZ
|
||||
The timezone to use when displaying dates.
|
||||
See
|
||||
.Xr environ 7
|
||||
for more information.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/messages -compact
|
||||
.It Pa /etc/localtime
|
||||
Symlink pointing to system's default timezone information file in
|
||||
.Pa /usr/share/zoneinfo
|
||||
directory.
|
||||
.It Pa /var/log/wtmp
|
||||
A record of date resets and time changes.
|
||||
.It Pa /var/log/messages
|
||||
A record of the user setting the time.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
date '+DATE: %m/%d/%y%nTIME: %H:%M:%S'
|
||||
.Ed
|
||||
.Pp
|
||||
will display:
|
||||
.Bd -literal -offset indent
|
||||
DATE: 11/21/87
|
||||
TIME: 13:36:16
|
||||
.Ed
|
||||
.Pp
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
date 8506131627
|
||||
.Ed
|
||||
.Pp
|
||||
sets the date to
|
||||
.Dq Li "June 13, 1985, 4:27 PM" .
|
||||
.Pp
|
||||
The command:
|
||||
.Bd -literal -offset indent
|
||||
date 1432
|
||||
.Ed
|
||||
.Pp
|
||||
sets the time to
|
||||
.Li "2:32 PM" ,
|
||||
without modifying the date.
|
||||
.Sh DIAGNOSTICS
|
||||
Exit status is 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 8
|
||||
synchronizes the time on many hosts, the setting of a new time value may
|
||||
require more than a few seconds.
|
||||
On these occasions,
|
||||
.Nm
|
||||
prints:
|
||||
.Ql Network time being set .
|
||||
The message
|
||||
.Ql Communication error with timed
|
||||
occurs when the communication
|
||||
between
|
||||
.Nm
|
||||
and
|
||||
timed
|
||||
fails.
|
||||
.Sh SEE ALSO
|
||||
.Xr adjtime 2 ,
|
||||
.Xr gettimeofday 2 ,
|
||||
.Xr settimeofday 2 ,
|
||||
.Xr parsedate 3 ,
|
||||
.Xr strftime 3 ,
|
||||
.Xr utmp 5 ,
|
||||
.Xr timed 8
|
||||
.Rs
|
||||
.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
|
||||
.%A R. Gusella
|
||||
.%A S. Zatti
|
||||
.Re
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is expected to be compatible with
|
||||
.St -p1003.2 .
|
||||
350
bin/date/date.c
Normal file
350
bin/date/date.c
Normal file
@@ -0,0 +1,350 @@
|
||||
/* $NetBSD: date.c,v 1.60 2011/08/27 12:55:09 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, 1987, 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT(
|
||||
"@(#) Copyright (c) 1985, 1987, 1988, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)date.c 8.2 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: date.c,v 1.60 2011/08/27 12:55:09 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
static time_t tval;
|
||||
static int aflag, jflag, rflag, nflag;
|
||||
|
||||
__dead static void badformat(void);
|
||||
__dead static void badtime(void);
|
||||
__dead static void badvalue(const char *);
|
||||
static void setthetime(const char *);
|
||||
__dead static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *buf;
|
||||
size_t bufsiz;
|
||||
const char *format;
|
||||
int ch;
|
||||
long long val;
|
||||
struct tm *tm;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
while ((ch = getopt(argc, argv, "ad:jnr:u")) != -1) {
|
||||
switch (ch) {
|
||||
case 'a': /* adjust time slowly */
|
||||
aflag = 1;
|
||||
nflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
#ifndef __minix
|
||||
rflag = 1;
|
||||
tval = parsedate(optarg, NULL, NULL);
|
||||
if (tval == -1)
|
||||
#endif
|
||||
badarg: errx(EXIT_FAILURE,
|
||||
"Cannot parse `%s'", optarg);
|
||||
break;
|
||||
case 'j': /* don't set time */
|
||||
jflag = 1;
|
||||
break;
|
||||
case 'n': /* don't set network */
|
||||
nflag = 1;
|
||||
break;
|
||||
case 'r': /* user specified seconds */
|
||||
errno = 0;
|
||||
val = strtoll(optarg, &buf, 0);
|
||||
if (optarg[0] == '\0' || *buf != '\0')
|
||||
goto badarg;
|
||||
if (errno == ERANGE && (val == LLONG_MAX ||
|
||||
val == LLONG_MIN))
|
||||
err(EXIT_FAILURE, "Bad number `%s'", optarg);
|
||||
rflag = 1;
|
||||
tval = (time_t)val;
|
||||
break;
|
||||
case 'u': /* do everything in UTC */
|
||||
(void)setenv("TZ", "UTC0", 1);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!rflag && time(&tval) == -1)
|
||||
err(EXIT_FAILURE, "time");
|
||||
|
||||
|
||||
/* allow the operands in any order */
|
||||
if (*argv && **argv == '+') {
|
||||
format = *argv;
|
||||
++argv;
|
||||
} else
|
||||
format = "+%a %b %e %H:%M:%S %Z %Y";
|
||||
|
||||
if (*argv) {
|
||||
setthetime(*argv);
|
||||
++argv;
|
||||
}
|
||||
|
||||
if (*argv && **argv == '+')
|
||||
format = *argv;
|
||||
|
||||
if ((buf = malloc(bufsiz = 1024)) == NULL)
|
||||
goto bad;
|
||||
|
||||
if ((tm = localtime(&tval)) == NULL)
|
||||
err(EXIT_FAILURE, "localtime %lld failed", (long long)tval);
|
||||
|
||||
while (strftime(buf, bufsiz, format, tm) == 0)
|
||||
if ((buf = realloc(buf, bufsiz <<= 1)) == NULL)
|
||||
goto bad;
|
||||
|
||||
(void)printf("%s\n", buf + 1);
|
||||
free(buf);
|
||||
return 0;
|
||||
bad:
|
||||
err(EXIT_FAILURE, "Cannot allocate format buffer");
|
||||
}
|
||||
|
||||
static void
|
||||
badformat(void)
|
||||
{
|
||||
warnx("illegal time format");
|
||||
usage();
|
||||
}
|
||||
|
||||
static void
|
||||
badtime(void)
|
||||
{
|
||||
errx(EXIT_FAILURE, "illegal time");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
badvalue(const char *param)
|
||||
{
|
||||
warnx("invalid %s supplied", param);
|
||||
usage();
|
||||
}
|
||||
|
||||
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
|
||||
|
||||
static void
|
||||
setthetime(const char *p)
|
||||
{
|
||||
struct timeval tv;
|
||||
time_t new_time;
|
||||
struct tm *lt;
|
||||
const char *dot, *t;
|
||||
size_t len;
|
||||
int yearset;
|
||||
|
||||
for (t = p, dot = NULL; *t; ++t) {
|
||||
if (isdigit((unsigned char)*t))
|
||||
continue;
|
||||
if (*t == '.' && dot == NULL) {
|
||||
dot = t;
|
||||
continue;
|
||||
}
|
||||
badformat();
|
||||
}
|
||||
|
||||
if ((lt = localtime(&tval)) == NULL)
|
||||
err(EXIT_FAILURE, "localtime %lld failed", (long long)tval);
|
||||
|
||||
lt->tm_isdst = -1; /* Divine correct DST */
|
||||
|
||||
if (dot != NULL) { /* .ss */
|
||||
len = strlen(dot);
|
||||
if (len != 3)
|
||||
badformat();
|
||||
++dot;
|
||||
lt->tm_sec = ATOI2(dot);
|
||||
if (lt->tm_sec > 61)
|
||||
badvalue("seconds");
|
||||
} else {
|
||||
len = 0;
|
||||
lt->tm_sec = 0;
|
||||
}
|
||||
|
||||
yearset = 0;
|
||||
switch (strlen(p) - len) {
|
||||
case 12: /* cc */
|
||||
lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
|
||||
if (lt->tm_year < 0)
|
||||
badtime();
|
||||
yearset = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 10: /* yy */
|
||||
if (yearset) {
|
||||
lt->tm_year += ATOI2(p);
|
||||
} else {
|
||||
yearset = ATOI2(p);
|
||||
if (yearset < 69)
|
||||
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
|
||||
else
|
||||
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 8: /* mm */
|
||||
lt->tm_mon = ATOI2(p);
|
||||
if (lt->tm_mon > 12 || lt->tm_mon == 0)
|
||||
badvalue("month");
|
||||
--lt->tm_mon; /* time struct is 0 - 11 */
|
||||
/* FALLTHROUGH */
|
||||
case 6: /* dd */
|
||||
lt->tm_mday = ATOI2(p);
|
||||
switch (lt->tm_mon) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 7:
|
||||
case 9:
|
||||
case 11:
|
||||
if (lt->tm_mday > 31 || lt->tm_mday == 0)
|
||||
badvalue("day of month");
|
||||
break;
|
||||
case 3:
|
||||
case 5:
|
||||
case 8:
|
||||
case 10:
|
||||
if (lt->tm_mday > 30 || lt->tm_mday == 0)
|
||||
badvalue("day of month");
|
||||
break;
|
||||
case 1:
|
||||
if (lt->tm_mday > 29 || lt->tm_mday == 0 ||
|
||||
(lt->tm_mday == 29 &&
|
||||
!isleap(lt->tm_year + TM_YEAR_BASE)))
|
||||
badvalue("day of month");
|
||||
break;
|
||||
default:
|
||||
badvalue("month");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 4: /* hh */
|
||||
lt->tm_hour = ATOI2(p);
|
||||
if (lt->tm_hour > 23)
|
||||
badvalue("hour");
|
||||
/* FALLTHROUGH */
|
||||
case 2: /* mm */
|
||||
lt->tm_min = ATOI2(p);
|
||||
if (lt->tm_min > 59)
|
||||
badvalue("minute");
|
||||
break;
|
||||
case 0: /* was just .sss */
|
||||
if (len != 0)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
badformat();
|
||||
}
|
||||
|
||||
/* convert broken-down time to UTC clock time */
|
||||
if ((new_time = mktime(lt)) == -1)
|
||||
badtime();
|
||||
|
||||
/* if jflag is set, don't actually change the time, just return */
|
||||
if (jflag) {
|
||||
tval = new_time;
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the time */
|
||||
if (nflag || netsettime(new_time)) {
|
||||
logwtmp("|", "date", "");
|
||||
#if HAVE_ADJTIME
|
||||
if (aflag) {
|
||||
tv.tv_sec = new_time - tval;
|
||||
tv.tv_usec = 0;
|
||||
if (adjtime(&tv, NULL))
|
||||
err(EXIT_FAILURE, "adjtime");
|
||||
}
|
||||
#else
|
||||
if (aflag) {
|
||||
err(EXIT_FAILURE, "no adjtime");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
tval = new_time;
|
||||
tv.tv_sec = tval;
|
||||
tv.tv_usec = 0;
|
||||
if (settimeofday(&tv, NULL))
|
||||
err(EXIT_FAILURE, "settimeofday");
|
||||
}
|
||||
logwtmp("{", "date", "");
|
||||
}
|
||||
|
||||
if ((p = getlogin()) == NULL)
|
||||
p = "???";
|
||||
syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [-ajnu] [-d date] [-r seconds] [+format]",
|
||||
getprogname());
|
||||
(void)fprintf(stderr, " [[[[[[CC]yy]mm]dd]HH]MM[.SS]]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
39
bin/date/extern.h
Normal file
39
bin/date/extern.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* $NetBSD: extern.h,v 1.8 2006/11/17 22:11:28 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 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. 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
|
||||
*/
|
||||
|
||||
#ifndef _EXTERN_H_
|
||||
#define _EXTERN_H_
|
||||
|
||||
int netsettime(time_t);
|
||||
|
||||
#endif /* !_EXTERN_H_ */
|
||||
200
bin/date/netdate.c
Normal file
200
bin/date/netdate.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* $NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)netdate.c 8.2 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define TSPTYPES
|
||||
#include <protocols/timed.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#define WAITACK 2000 /* milliseconds */
|
||||
#define WAITDATEACK 5000 /* milliseconds */
|
||||
|
||||
static const char *
|
||||
tsp_type_to_string(const struct tsp *msg)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = msg->tsp_type;
|
||||
return i < TSPTYPENUMBER ? tsptype[i] : "unknown";
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the date in the machines controlled by timedaemons by communicating the
|
||||
* new date to the local timedaemon. If the timedaemon is in the master state,
|
||||
* it performs the correction on all slaves. If it is in the slave state, it
|
||||
* notifies the master that a correction is needed.
|
||||
* Returns 0 on success. Returns > 0 on failure.
|
||||
*/
|
||||
int
|
||||
netsettime(time_t tval)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
struct tsp msg;
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
struct servent *sp;
|
||||
struct pollfd ready;
|
||||
int found, s, timed_ack, waittime;
|
||||
|
||||
if ((sp = getservbyname("timed", "udp")) == NULL) {
|
||||
warnx("udp/timed: unknown service");
|
||||
return 2;
|
||||
}
|
||||
|
||||
(void)memset(&dest, 0, sizeof(dest));
|
||||
#ifdef BSD4_4
|
||||
dest.sin_len = sizeof(dest);
|
||||
#endif
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = sp->s_port;
|
||||
dest.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
if (errno != EAFNOSUPPORT)
|
||||
warn("timed");
|
||||
return 2;
|
||||
}
|
||||
|
||||
#ifdef IP_PORTRANGE
|
||||
{
|
||||
static const int on = IP_PORTRANGE_LOW;
|
||||
|
||||
if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &on,
|
||||
sizeof(on)) == -1) {
|
||||
warn("setsockopt");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
msg.tsp_type = TSP_SETDATE;
|
||||
msg.tsp_vers = TSPVERSION;
|
||||
if (gethostname(hostname, sizeof(hostname)) == -1) {
|
||||
warn("gethostname");
|
||||
goto bad;
|
||||
}
|
||||
(void)strlcpy(msg.tsp_name, hostname, sizeof(msg.tsp_name));
|
||||
msg.tsp_seq = htons((in_port_t)0);
|
||||
msg.tsp_time.tv_sec = htonl((in_addr_t)tval); /* XXX: y2038 */
|
||||
msg.tsp_time.tv_usec = htonl((in_addr_t)0);
|
||||
if (connect(s, (const void *)&dest, sizeof(dest)) == -1) {
|
||||
warn("connect");
|
||||
goto bad;
|
||||
}
|
||||
if (send(s, &msg, sizeof(msg), 0) == -1) {
|
||||
if (errno != ECONNREFUSED)
|
||||
warn("send");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
timed_ack = -1;
|
||||
waittime = WAITACK;
|
||||
ready.fd = s;
|
||||
ready.events = POLLIN;
|
||||
loop:
|
||||
found = poll(&ready, 1, waittime);
|
||||
|
||||
{
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
len = sizeof(error);
|
||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
|
||||
warn("getsockopt");
|
||||
goto bad;
|
||||
}
|
||||
if (error) {
|
||||
if (error != ECONNREFUSED) {
|
||||
errno = error;
|
||||
warn("send (delayed error)");
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
if (found > 0 && ready.revents & POLLIN) {
|
||||
ssize_t ret;
|
||||
|
||||
if ((ret = recv(s, &msg, sizeof(msg), 0)) == -1) {
|
||||
if (errno != ECONNREFUSED)
|
||||
warn("recv");
|
||||
goto bad;
|
||||
} else if ((size_t)ret < sizeof(msg)) {
|
||||
warnx("recv: incomplete packet");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
msg.tsp_seq = ntohs(msg.tsp_seq);
|
||||
msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
|
||||
msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
|
||||
switch (msg.tsp_type) {
|
||||
case TSP_ACK:
|
||||
timed_ack = TSP_ACK;
|
||||
waittime = WAITDATEACK;
|
||||
goto loop;
|
||||
case TSP_DATEACK:
|
||||
(void)close(s);
|
||||
return 0;
|
||||
default:
|
||||
warnx("wrong ack received from timed: %s",
|
||||
tsp_type_to_string(&msg));
|
||||
timed_ack = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timed_ack == -1)
|
||||
warnx("can't reach time daemon, time set locally");
|
||||
|
||||
bad:
|
||||
(void)close(s);
|
||||
return 2;
|
||||
}
|
||||
7
bin/mkdir/Makefile
Normal file
7
bin/mkdir/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
# $NetBSD: Makefile,v 1.8 1997/07/20 22:37:21 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= mkdir
|
||||
SYMLINKS= $(BINDIR)/$(PROG) /usr/bin/$(PROG)
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
94
bin/mkdir/mkdir.1
Normal file
94
bin/mkdir/mkdir.1
Normal file
@@ -0,0 +1,94 @@
|
||||
.\" $NetBSD: mkdir.1,v 1.16 2003/08/07 09:05:16 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)mkdir.1 8.2 (Berkeley) 1/25/94
|
||||
.\"
|
||||
.Dd January 25, 1994
|
||||
.Dt MKDIR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mkdir
|
||||
.Nd make directories
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl p
|
||||
.Op Fl m Ar mode
|
||||
.Ar directory_name ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
creates the directories named as operands, in the order specified,
|
||||
using mode
|
||||
.Li rwxrwxrwx (\&0777)
|
||||
as modified by the current
|
||||
.Xr umask 2 .
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Pp
|
||||
.Bl -tag -width indent
|
||||
.It Fl m
|
||||
Set the file permission bits of the final created directory to
|
||||
the specified mode.
|
||||
The mode argument can be in any of the formats specified to the
|
||||
.Xr chmod 1
|
||||
utility.
|
||||
If a symbolic mode is specified, the operation characters
|
||||
.Dq +
|
||||
and
|
||||
.Dq -
|
||||
are interpreted relative to an initial mode of
|
||||
.Dq a=rwx .
|
||||
.It Fl p
|
||||
Create intermediate directories as required.
|
||||
If this option is not specified, the full path prefix of each
|
||||
operand must already exist.
|
||||
Intermediate directories are created with permission bits of
|
||||
.Li rwxrwxrwx (\&0777)
|
||||
as modified by the current umask, plus write and search
|
||||
permission for the owner.
|
||||
Do not consider it an error if the argument directory already exists.
|
||||
.El
|
||||
.Pp
|
||||
The user must have write permission in the parent directory.
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
exits 0 if successful, and \*[Gt]0 if an error occurred.
|
||||
.Sh SEE ALSO
|
||||
.Xr chmod 1 ,
|
||||
.Xr rmdir 1 ,
|
||||
.Xr mkdir 2 ,
|
||||
.Xr umask 2
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is expected to be
|
||||
.St -p1003.2
|
||||
compatible.
|
||||
224
bin/mkdir/mkdir.c
Normal file
224
bin/mkdir/mkdir.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/* $NetBSD: mkdir.c,v 1.37 2008/07/20 00:52:40 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1992, 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1983, 1992, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)mkdir.c 8.2 (Berkeley) 1/25/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: mkdir.c,v 1.37 2008/07/20 00:52:40 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int mkpath(char *, mode_t, mode_t);
|
||||
void usage(void);
|
||||
int main(int, char *[]);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, exitval, pflag;
|
||||
void *set;
|
||||
mode_t mode, dir_mode;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
/*
|
||||
* The default file mode is a=rwx (0777) with selected permissions
|
||||
* removed in accordance with the file mode creation mask. For
|
||||
* intermediate path name components, the mode is the default modified
|
||||
* by u+wx so that the subdirectories can always be created.
|
||||
*/
|
||||
mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~umask(0);
|
||||
dir_mode = mode | S_IWUSR | S_IXUSR;
|
||||
|
||||
pflag = 0;
|
||||
while ((ch = getopt(argc, argv, "m:p")) != -1)
|
||||
switch (ch) {
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if ((set = setmode(optarg)) == NULL) {
|
||||
err(EXIT_FAILURE, "Cannot set file mode `%s'",
|
||||
optarg);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
mode = getmode(set, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
free(set);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (*argv == NULL) {
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
for (exitval = EXIT_SUCCESS; *argv != NULL; ++argv) {
|
||||
#ifdef notdef
|
||||
char *slash;
|
||||
|
||||
/* Kernel takes care of this */
|
||||
/* Remove trailing slashes, per POSIX. */
|
||||
slash = strrchr(*argv, '\0');
|
||||
while (--slash > *argv && *slash == '/')
|
||||
*slash = '\0';
|
||||
#endif
|
||||
|
||||
if (pflag) {
|
||||
if (mkpath(*argv, mode, dir_mode) < 0)
|
||||
exitval = EXIT_FAILURE;
|
||||
} else {
|
||||
if (mkdir(*argv, mode) < 0) {
|
||||
warn("%s", *argv);
|
||||
exitval = EXIT_FAILURE;
|
||||
} else {
|
||||
/*
|
||||
* The mkdir() and umask() calls both honor
|
||||
* only the file permission bits, so if you try
|
||||
* to set a mode including the sticky, setuid,
|
||||
* setgid bits you lose them. So chmod().
|
||||
*/
|
||||
if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 &&
|
||||
chmod(*argv, mode) == -1) {
|
||||
warn("%s", *argv);
|
||||
exitval = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(exitval);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* mkpath -- create directories.
|
||||
* path - path
|
||||
* mode - file mode of terminal directory
|
||||
* dir_mode - file mode of intermediate directories
|
||||
*/
|
||||
int
|
||||
mkpath(char *path, mode_t mode, mode_t dir_mode)
|
||||
{
|
||||
struct stat sb;
|
||||
char *slash;
|
||||
int done, rv;
|
||||
|
||||
done = 0;
|
||||
slash = path;
|
||||
|
||||
for (;;) {
|
||||
slash += strspn(slash, "/");
|
||||
slash += strcspn(slash, "/");
|
||||
|
||||
done = (*slash == '\0');
|
||||
*slash = '\0';
|
||||
|
||||
rv = mkdir(path, done ? mode : dir_mode);
|
||||
if (rv < 0) {
|
||||
/*
|
||||
* Can't create; path exists or no perms.
|
||||
* stat() path to determine what's there now.
|
||||
*/
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
if (stat(path, &sb) < 0) {
|
||||
/* Not there; use mkdir()s error */
|
||||
errno = sverrno;
|
||||
warn("%s", path);
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISDIR(sb.st_mode)) {
|
||||
/* Is there, but isn't a directory */
|
||||
errno = ENOTDIR;
|
||||
warn("%s", path);
|
||||
return -1;
|
||||
}
|
||||
} else if (done) {
|
||||
/*
|
||||
* Created ok, and this is the last element
|
||||
*/
|
||||
/*
|
||||
* The mkdir() and umask() calls both honor only the
|
||||
* file permission bits, so if you try to set a mode
|
||||
* including the sticky, setuid, setgid bits you lose
|
||||
* them. So chmod().
|
||||
*/
|
||||
if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 &&
|
||||
chmod(path, mode) == -1) {
|
||||
warn("%s", path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
*slash = '/';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-p] [-m mode] dirname ...\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
6
bin/rm/Makefile
Normal file
6
bin/rm/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.9 1997/07/20 22:37:50 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= rm
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
207
bin/rm/rm.1
Normal file
207
bin/rm/rm.1
Normal file
@@ -0,0 +1,207 @@
|
||||
.\" $NetBSD: rm.1,v 1.24 2006/09/02 23:28:32 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993, 1994, 2003
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)rm.1 8.5 (Berkeley) 12/5/94
|
||||
.\"
|
||||
.Dd August 25, 2006
|
||||
.Dt RM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rm
|
||||
.Nd remove directory entries
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl f | Fl i
|
||||
.Op Fl dPRrvW
|
||||
.Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility attempts to remove the non-directory type files specified on the
|
||||
command line.
|
||||
If the permissions of the file do not permit writing, and the standard
|
||||
input device is a terminal, the user is prompted (on the standard error
|
||||
output) for confirmation.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width flag
|
||||
.It Fl d
|
||||
Attempt to remove directories as well as other types of files.
|
||||
.It Fl f
|
||||
Attempt to remove the files without prompting for confirmation,
|
||||
regardless of the file's permissions.
|
||||
If the file does not exist, do not display a diagnostic message or modify
|
||||
the exit status to reflect an error.
|
||||
The
|
||||
.Fl f
|
||||
option overrides any previous
|
||||
.Fl i
|
||||
options.
|
||||
.It Fl i
|
||||
Request confirmation before attempting to remove each file, regardless of
|
||||
the file's permissions, or whether or not the standard input device is a
|
||||
terminal.
|
||||
The
|
||||
.Fl i
|
||||
option overrides any previous
|
||||
.Fl f
|
||||
options.
|
||||
.It Fl P
|
||||
Overwrite regular files before deleting them.
|
||||
Files are overwritten three times, first with the byte pattern 0xff,
|
||||
then 0x00, and then with random data, before they are deleted.
|
||||
Some care is taken to ensure that the data are actually written to
|
||||
disk, but this cannot be guaranteed, even on traditional filesystems;
|
||||
on log-structured filesystems or if any block-journaling scheme is
|
||||
in use, this option is completely useless.
|
||||
If the file cannot be
|
||||
overwritten, it will not be removed.
|
||||
.It Fl R
|
||||
Attempt to remove the file hierarchy rooted in each file argument.
|
||||
The
|
||||
.Fl R
|
||||
option implies the
|
||||
.Fl d
|
||||
option.
|
||||
If the
|
||||
.Fl i
|
||||
option is specified, the user is prompted for confirmation before
|
||||
each directory's contents are processed (as well as before the attempt
|
||||
is made to remove the directory).
|
||||
If the user does not respond affirmatively, the file hierarchy rooted in
|
||||
that directory is skipped.
|
||||
.Pp
|
||||
.It Fl r
|
||||
Equivalent to
|
||||
.Fl R .
|
||||
.It Fl v
|
||||
Cause
|
||||
.Nm
|
||||
to be verbose, showing files as they are processed.
|
||||
.It Fl W
|
||||
Attempts to undelete the named files.
|
||||
Currently, this option can only be used to recover
|
||||
files covered by whiteouts.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility removes symbolic links, not the files referenced by the links.
|
||||
.Pp
|
||||
It is an error to attempt to remove the files ``.'' and ``..''.
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 if all of the named files or file hierarchies were removed,
|
||||
or if the
|
||||
.Fl f
|
||||
option was specified and all of the existing files or file hierarchies were
|
||||
removed.
|
||||
If an error occurs,
|
||||
.Nm
|
||||
exits with a value \*[Gt]0.
|
||||
.Sh EXAMPLES
|
||||
.Nm
|
||||
uses
|
||||
.Xr getopt 3
|
||||
standard argument processing.
|
||||
Removing filenames that begin with a dash
|
||||
.Pq e.g., Ar -file
|
||||
in the current directory which might otherwise be taken as option flags to
|
||||
.Nm
|
||||
can be accomplished as follows:
|
||||
.Pp
|
||||
.Ic "rm -- -file"
|
||||
.Pp
|
||||
or
|
||||
.Pp
|
||||
.Ic "rm ./-file"
|
||||
.Sh SEE ALSO
|
||||
.Xr rmdir 1 ,
|
||||
.Xr undelete 2 ,
|
||||
.Xr unlink 2 ,
|
||||
.Xr fts 3 ,
|
||||
.Xr getopt 3 ,
|
||||
.Xr symlink 7
|
||||
.Sh BUGS
|
||||
The
|
||||
.Fl P
|
||||
option assumes that the underlying file system is a fixed-block file
|
||||
system.
|
||||
FFS is a fixed-block file system, LFS is not.
|
||||
In addition, only regular files are overwritten, other types of files
|
||||
are not.
|
||||
Recent research indicates that as many as 35 overwrite passes with
|
||||
carefully chosen data patterns may be necessary to actually prevent
|
||||
recovery of data from a magnetic disk.
|
||||
Thus the
|
||||
.Fl P
|
||||
option is likely both insufficient for its design purpose and far
|
||||
too costly for default operation.
|
||||
However, it will at least prevent the recovery of data from FFS
|
||||
volumes with
|
||||
.Xr fsdb 8 .
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Nm
|
||||
utility differs from historical implementations in that the
|
||||
.Fl f
|
||||
option only masks attempts to remove non-existent files instead of
|
||||
masking a large variety of errors.
|
||||
.Pp
|
||||
Also, historical
|
||||
.Bx
|
||||
implementations prompted on the standard output,
|
||||
not the standard error output.
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is expected to be
|
||||
.St -p1003.2
|
||||
compatible.
|
||||
The
|
||||
.Fl v
|
||||
option is an extension.
|
||||
.Pp
|
||||
The
|
||||
.Fl P
|
||||
option attempts to conform to U.S. DoD 5220-22.M, "National Industrial
|
||||
Security Program Operating Manual" ("NISPOM") as updated by Change
|
||||
2 and the July 23, 2003 "Clearing \*[Am] Sanitization Matrix".
|
||||
However, unlike earlier revisions of NISPOM, the 2003 matrix imposes
|
||||
requirements which make it clear that the standard does not and
|
||||
can not apply to the erasure of individual files, in particular
|
||||
requirements relating to spare sector management for an entire
|
||||
magnetic disk.
|
||||
.Em Because these requirements are not met, the
|
||||
.Fl P
|
||||
.Em option does not conform to the standard .
|
||||
605
bin/rm/rm.c
Normal file
605
bin/rm/rm.c
Normal file
@@ -0,0 +1,605 @@
|
||||
/* $NetBSD: rm.c,v 1.50 2011/08/29 14:48:46 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994, 2003
|
||||
* 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1990, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rm.c 8.8 (Berkeley) 4/27/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: rm.c,v 1.50 2011/08/29 14:48:46 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fts.h>
|
||||
#include <grp.h>
|
||||
#include <locale.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int dflag, eval, fflag, iflag, Pflag, stdin_ok, vflag, Wflag;
|
||||
|
||||
static int check(char *, char *, struct stat *);
|
||||
static void checkdot(char **);
|
||||
static void rm_file(char **);
|
||||
static int rm_overwrite(char *, struct stat *);
|
||||
static void rm_tree(char **);
|
||||
__dead static void usage(void);
|
||||
|
||||
#ifdef __minix
|
||||
# ifndef O_SYNC
|
||||
# define O_SYNC 0
|
||||
# endif
|
||||
# ifndef O_RSYNC
|
||||
# define O_RSYNC 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For the sake of the `-f' flag, check whether an error number indicates the
|
||||
* failure of an operation due to an non-existent file, either per se (ENOENT)
|
||||
* or because its filename argument was illegal (ENAMETOOLONG, ENOTDIR).
|
||||
*/
|
||||
#define NONEXISTENT(x) \
|
||||
((x) == ENOENT || (x) == ENAMETOOLONG || (x) == ENOTDIR)
|
||||
|
||||
/*
|
||||
* rm --
|
||||
* This rm is different from historic rm's, but is expected to match
|
||||
* POSIX 1003.2 behavior. The most visible difference is that -f
|
||||
* has two specific effects now, ignore non-existent files and force
|
||||
* file removal.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, rflag;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
Pflag = rflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dfiPRrvW")) != -1)
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fflag = 1;
|
||||
iflag = 0;
|
||||
break;
|
||||
case 'i':
|
||||
fflag = 0;
|
||||
iflag = 1;
|
||||
break;
|
||||
case 'P':
|
||||
Pflag = 1;
|
||||
break;
|
||||
case 'R':
|
||||
case 'r': /* Compatibility. */
|
||||
rflag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
case 'W':
|
||||
Wflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
if (fflag)
|
||||
return 0;
|
||||
usage();
|
||||
}
|
||||
|
||||
checkdot(argv);
|
||||
|
||||
if (*argv) {
|
||||
stdin_ok = isatty(STDIN_FILENO);
|
||||
|
||||
if (rflag)
|
||||
rm_tree(argv);
|
||||
else
|
||||
rm_file(argv);
|
||||
}
|
||||
|
||||
exit(eval);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
rm_tree(char **argv)
|
||||
{
|
||||
FTS *fts;
|
||||
FTSENT *p;
|
||||
int flags, needstat, rval;
|
||||
|
||||
/*
|
||||
* Remove a file hierarchy. If forcing removal (-f), or interactive
|
||||
* (-i) or can't ask anyway (stdin_ok), don't stat the file.
|
||||
*/
|
||||
needstat = !fflag && !iflag && stdin_ok;
|
||||
|
||||
/*
|
||||
* If the -i option is specified, the user can skip on the pre-order
|
||||
* visit. The fts_number field flags skipped directories.
|
||||
*/
|
||||
#define SKIPPED 1
|
||||
|
||||
flags = FTS_PHYSICAL;
|
||||
if (!needstat)
|
||||
flags |= FTS_NOSTAT;
|
||||
#ifndef __minix
|
||||
if (Wflag)
|
||||
flags |= FTS_WHITEOUT;
|
||||
#endif
|
||||
if ((fts = fts_open(argv, flags, NULL)) == NULL)
|
||||
err(1, "fts_open failed");
|
||||
while ((p = fts_read(fts)) != NULL) {
|
||||
|
||||
switch (p->fts_info) {
|
||||
case FTS_DNR:
|
||||
if (!fflag || p->fts_errno != ENOENT) {
|
||||
warnx("%s: %s", p->fts_path,
|
||||
strerror(p->fts_errno));
|
||||
eval = 1;
|
||||
}
|
||||
continue;
|
||||
case FTS_ERR:
|
||||
errx(EXIT_FAILURE, "%s: %s", p->fts_path,
|
||||
strerror(p->fts_errno));
|
||||
/* NOTREACHED */
|
||||
case FTS_NS:
|
||||
/*
|
||||
* FTS_NS: assume that if can't stat the file, it
|
||||
* can't be unlinked.
|
||||
*/
|
||||
if (fflag && NONEXISTENT(p->fts_errno))
|
||||
continue;
|
||||
if (needstat) {
|
||||
warnx("%s: %s", p->fts_path,
|
||||
strerror(p->fts_errno));
|
||||
eval = 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case FTS_D:
|
||||
/* Pre-order: give user chance to skip. */
|
||||
if (!fflag && !check(p->fts_path, p->fts_accpath,
|
||||
p->fts_statp)) {
|
||||
(void)fts_set(fts, p, FTS_SKIP);
|
||||
p->fts_number = SKIPPED;
|
||||
}
|
||||
continue;
|
||||
case FTS_DP:
|
||||
/* Post-order: see if user skipped. */
|
||||
if (p->fts_number == SKIPPED)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (!fflag &&
|
||||
!check(p->fts_path, p->fts_accpath, p->fts_statp))
|
||||
continue;
|
||||
}
|
||||
|
||||
rval = 0;
|
||||
/*
|
||||
* If we can't read or search the directory, may still be
|
||||
* able to remove it. Don't print out the un{read,search}able
|
||||
* message unless the remove fails.
|
||||
*/
|
||||
switch (p->fts_info) {
|
||||
case FTS_DP:
|
||||
case FTS_DNR:
|
||||
rval = rmdir(p->fts_accpath);
|
||||
if (rval != 0 && fflag && errno == ENOENT)
|
||||
continue;
|
||||
break;
|
||||
|
||||
#ifndef __minix
|
||||
case FTS_W:
|
||||
rval = undelete(p->fts_accpath);
|
||||
if (rval != 0 && fflag && errno == ENOENT)
|
||||
continue;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (Pflag) {
|
||||
if (rm_overwrite(p->fts_accpath, NULL))
|
||||
continue;
|
||||
}
|
||||
rval = unlink(p->fts_accpath);
|
||||
if (rval != 0 && fflag && NONEXISTENT(errno))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (rval != 0) {
|
||||
warn("%s", p->fts_path);
|
||||
eval = 1;
|
||||
} else if (vflag)
|
||||
(void)printf("%s\n", p->fts_path);
|
||||
}
|
||||
if (errno)
|
||||
err(1, "fts_read");
|
||||
fts_close(fts);
|
||||
}
|
||||
|
||||
static void
|
||||
rm_file(char **argv)
|
||||
{
|
||||
struct stat sb;
|
||||
int rval;
|
||||
char *f;
|
||||
|
||||
/*
|
||||
* Remove a file. POSIX 1003.2 states that, by default, attempting
|
||||
* to remove a directory is an error, so must always stat the file.
|
||||
*/
|
||||
while ((f = *argv++) != NULL) {
|
||||
/* Assume if can't stat the file, can't unlink it. */
|
||||
if (lstat(f, &sb)) {
|
||||
if (Wflag) {
|
||||
#ifdef __minix
|
||||
sb.st_mode = S_IWUSR|S_IRUSR;
|
||||
#else
|
||||
sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
|
||||
#endif
|
||||
} else {
|
||||
if (!fflag || !NONEXISTENT(errno)) {
|
||||
warn("%s", f);
|
||||
eval = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else if (Wflag) {
|
||||
warnx("%s: %s", f, strerror(EEXIST));
|
||||
eval = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode) && !dflag) {
|
||||
warnx("%s: is a directory", f);
|
||||
eval = 1;
|
||||
continue;
|
||||
}
|
||||
#ifndef __minix
|
||||
if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
|
||||
#else
|
||||
if (!fflag && !check(f, f, &sb))
|
||||
#endif
|
||||
continue;
|
||||
#ifndef __minix
|
||||
if (S_ISWHT(sb.st_mode))
|
||||
rval = undelete(f);
|
||||
else
|
||||
#endif
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
rval = rmdir(f);
|
||||
else {
|
||||
if (Pflag) {
|
||||
if (rm_overwrite(f, &sb))
|
||||
continue;
|
||||
}
|
||||
rval = unlink(f);
|
||||
}
|
||||
if (rval && (!fflag || !NONEXISTENT(errno))) {
|
||||
warn("%s", f);
|
||||
eval = 1;
|
||||
}
|
||||
if (vflag && rval == 0)
|
||||
(void)printf("%s\n", f);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rm_overwrite --
|
||||
* Overwrite the file 3 times with varying bit patterns.
|
||||
*
|
||||
* This is an expensive way to keep people from recovering files from your
|
||||
* non-snapshotted FFS filesystems using fsdb(8). Really. No more. Only
|
||||
* regular files are deleted, directories (and therefore names) will remain.
|
||||
* Also, this assumes a fixed-block file system (like FFS, or a V7 or a
|
||||
* System V file system). In a logging file system, you'll have to have
|
||||
* kernel support.
|
||||
*
|
||||
* A note on standards: U.S. DoD 5220.22-M "National Industrial Security
|
||||
* Program Operating Manual" ("NISPOM") is often cited as a reference
|
||||
* for clearing and sanitizing magnetic media. In fact, a matrix of
|
||||
* "clearing" and "sanitization" methods for various media was given in
|
||||
* Chapter 8 of the original 1995 version of NISPOM. However, that
|
||||
* matrix was *removed from the document* when Chapter 8 was rewritten
|
||||
* in Change 2 to the document in 2001. Recently, the Defense Security
|
||||
* Service has made a revised clearing and sanitization matrix available
|
||||
* in Microsoft Word format on the DSS web site. The standardization
|
||||
* status of this matrix is unclear. Furthermore, one must be very
|
||||
* careful when referring to this matrix: it is intended for the "clearing"
|
||||
* prior to reuse or "sanitization" prior to disposal of *entire media*,
|
||||
* not individual files and the only non-physically-destructive method of
|
||||
* "sanitization" that is permitted for magnetic disks of any kind is
|
||||
* specifically noted to be prohibited for media that have contained
|
||||
* Top Secret data.
|
||||
*
|
||||
* It is impossible to actually conform to the exact procedure given in
|
||||
* the matrix if one is overwriting a file, not an entire disk, because
|
||||
* the procedure requires examination and comparison of the disk's defect
|
||||
* lists. Any program that claims to securely erase *files* while
|
||||
* conforming to the standard, then, is not correct. We do as much of
|
||||
* what the standard requires as can actually be done when erasing a
|
||||
* file, rather than an entire disk; but that does not make us conformant.
|
||||
*
|
||||
* Furthermore, the presence of track caches, disk and controller write
|
||||
* caches, and so forth make it extremely difficult to ensure that data
|
||||
* have actually been written to the disk, particularly when one tries
|
||||
* to repeatedly overwrite the same sectors in quick succession. We call
|
||||
* fsync(), but controllers with nonvolatile cache, as well as IDE disks
|
||||
* that just plain lie about the stable storage of data, will defeat this.
|
||||
*
|
||||
* Finally, widely respected research suggests that the given procedure
|
||||
* is nowhere near sufficient to prevent the recovery of data using special
|
||||
* forensic equipment and techniques that are well-known. This is
|
||||
* presumably one reason that the matrix requires physical media destruction,
|
||||
* rather than any technique of the sort attempted here, for secret data.
|
||||
*
|
||||
* Caveat Emptor.
|
||||
*
|
||||
* rm_overwrite will return 0 on success.
|
||||
*/
|
||||
|
||||
static int
|
||||
rm_overwrite(char *file, struct stat *sbp)
|
||||
{
|
||||
struct stat sb;
|
||||
int fd, randint;
|
||||
char randchar;
|
||||
|
||||
fd = -1;
|
||||
if (sbp == NULL) {
|
||||
if (lstat(file, &sb))
|
||||
goto err;
|
||||
sbp = &sb;
|
||||
}
|
||||
if (!S_ISREG(sbp->st_mode))
|
||||
return 0;
|
||||
|
||||
/* flags to try to defeat hidden caching by forcing seeks */
|
||||
if ((fd = open(file, O_RDWR|O_SYNC|O_RSYNC, 0)) == -1)
|
||||
goto err;
|
||||
|
||||
#define RAND_BYTES 1
|
||||
#define THIS_BYTE 0
|
||||
|
||||
#define WRITE_PASS(mode, byte) do { \
|
||||
off_t len; \
|
||||
size_t wlen, i; \
|
||||
char buf[8 * 1024]; \
|
||||
\
|
||||
if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET)) \
|
||||
goto err; \
|
||||
\
|
||||
if (mode == THIS_BYTE) \
|
||||
memset(buf, byte, sizeof(buf)); \
|
||||
for (len = sbp->st_size; len > 0; len -= wlen) { \
|
||||
if (mode == RAND_BYTES) { \
|
||||
for (i = 0; i < sizeof(buf); \
|
||||
i+= sizeof(u_int32_t)) \
|
||||
*(int *)(buf + i) = arc4random(); \
|
||||
} \
|
||||
wlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
|
||||
if ((size_t)write(fd, buf, wlen) != wlen) \
|
||||
goto err; \
|
||||
} \
|
||||
sync(); /* another poke at hidden caches */ \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#define READ_PASS(byte) do { \
|
||||
off_t len; \
|
||||
size_t rlen; \
|
||||
char pattern[8 * 1024]; \
|
||||
char buf[8 * 1024]; \
|
||||
\
|
||||
if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET)) \
|
||||
goto err; \
|
||||
\
|
||||
memset(pattern, byte, sizeof(pattern)); \
|
||||
for(len = sbp->st_size; len > 0; len -= rlen) { \
|
||||
rlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
|
||||
if((size_t)read(fd, buf, rlen) != rlen) \
|
||||
goto err; \
|
||||
if(memcmp(buf, pattern, rlen)) \
|
||||
goto err; \
|
||||
} \
|
||||
sync(); /* another poke at hidden caches */ \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
/*
|
||||
* DSS sanitization matrix "clear" for magnetic disks:
|
||||
* option 'c' "Overwrite all addressable locations with a single
|
||||
* character."
|
||||
*/
|
||||
randint = arc4random();
|
||||
randchar = *(char *)&randint;
|
||||
WRITE_PASS(THIS_BYTE, randchar);
|
||||
|
||||
/*
|
||||
* DSS sanitization matrix "sanitize" for magnetic disks:
|
||||
* option 'd', sub 2 "Overwrite all addressable locations with a
|
||||
* character, then its complement. Verify "complement" character
|
||||
* was written successfully to all addressable locations, then
|
||||
* overwrite all addressable locations with random characters; or
|
||||
* verify third overwrite of random characters." The rest of the
|
||||
* text in d-sub-2 specifies requirements for overwriting spared
|
||||
* sectors; we cannot conform to it when erasing only a file, thus
|
||||
* we do not conform to the standard.
|
||||
*/
|
||||
|
||||
/* 1. "a character" */
|
||||
WRITE_PASS(THIS_BYTE, 0xff);
|
||||
|
||||
/* 2. "its complement" */
|
||||
WRITE_PASS(THIS_BYTE, 0x00);
|
||||
|
||||
/* 3. "Verify 'complement' character" */
|
||||
READ_PASS(0x00);
|
||||
|
||||
/* 4. "overwrite all addressable locations with random characters" */
|
||||
|
||||
WRITE_PASS(RAND_BYTES, 0x00);
|
||||
|
||||
/*
|
||||
* As the file might be huge, and we note that this revision of
|
||||
* the matrix says "random characters", not "a random character"
|
||||
* as the original did, we do not verify the random-character
|
||||
* write; the "or" in the standard allows this.
|
||||
*/
|
||||
|
||||
if (close(fd) == -1) {
|
||||
fd = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err: eval = 1;
|
||||
warn("%s", file);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
check(char *path, char *name, struct stat *sp)
|
||||
{
|
||||
int ch, first;
|
||||
char modep[15];
|
||||
|
||||
/* Check -i first. */
|
||||
if (iflag)
|
||||
(void)fprintf(stderr, "remove '%s'? ", path);
|
||||
else {
|
||||
/*
|
||||
* If it's not a symbolic link and it's unwritable and we're
|
||||
* talking to a terminal, ask. Symbolic links are excluded
|
||||
* because their permissions are meaningless. Check stdin_ok
|
||||
* first because we may not have stat'ed the file.
|
||||
*/
|
||||
if (!stdin_ok || S_ISLNK(sp->st_mode) ||
|
||||
!(access(name, W_OK) && (errno != ETXTBSY)))
|
||||
return (1);
|
||||
strmode(sp->st_mode, modep);
|
||||
if (Pflag) {
|
||||
warnx(
|
||||
"%s: -P was specified but file could not"
|
||||
" be overwritten", path);
|
||||
return 0;
|
||||
}
|
||||
(void)fprintf(stderr, "override %s%s%s:%s for '%s'? ",
|
||||
modep + 1, modep[9] == ' ' ? "" : " ",
|
||||
user_from_uid(sp->st_uid, 0),
|
||||
group_from_gid(sp->st_gid, 0), path);
|
||||
}
|
||||
(void)fflush(stderr);
|
||||
|
||||
first = ch = getchar();
|
||||
while (ch != '\n' && ch != EOF)
|
||||
ch = getchar();
|
||||
return (first == 'y' || first == 'Y');
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX.2 requires that if "." or ".." are specified as the basename
|
||||
* portion of an operand, a diagnostic message be written to standard
|
||||
* error and nothing more be done with such operands.
|
||||
*
|
||||
* Since POSIX.2 defines basename as the final portion of a path after
|
||||
* trailing slashes have been removed, we'll remove them here.
|
||||
*/
|
||||
#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
|
||||
static void
|
||||
checkdot(char **argv)
|
||||
{
|
||||
char *p, **save, **t;
|
||||
int complained;
|
||||
|
||||
complained = 0;
|
||||
for (t = argv; *t;) {
|
||||
/* strip trailing slashes */
|
||||
p = strrchr(*t, '\0');
|
||||
while (--p > *t && *p == '/')
|
||||
*p = '\0';
|
||||
|
||||
/* extract basename */
|
||||
if ((p = strrchr(*t, '/')) != NULL)
|
||||
++p;
|
||||
else
|
||||
p = *t;
|
||||
|
||||
if (ISDOT(p)) {
|
||||
if (!complained++)
|
||||
warnx("\".\" and \"..\" may not be removed");
|
||||
eval = 1;
|
||||
for (save = t; (t[0] = t[1]) != NULL; ++t)
|
||||
continue;
|
||||
t = save;
|
||||
} else
|
||||
++t;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-f|-i] [-dPRrvW] file ...\n",
|
||||
getprogname());
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
6
bin/rmdir/Makefile
Normal file
6
bin/rmdir/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.8 1997/07/20 22:37:52 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= rmdir
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
90
bin/rmdir/rmdir.1
Normal file
90
bin/rmdir/rmdir.1
Normal file
@@ -0,0 +1,90 @@
|
||||
.\" $NetBSD: rmdir.1,v 1.15 2003/08/07 09:05:29 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)rmdir.1 8.1 (Berkeley) 5/31/93
|
||||
.\"
|
||||
.Dd May 31, 1993
|
||||
.Dt RMDIR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rmdir
|
||||
.Nd remove directories
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl p
|
||||
.Ar directory ...
|
||||
.Sh DESCRIPTION
|
||||
The rmdir utility removes the directory entry specified by
|
||||
each
|
||||
.Ar directory
|
||||
argument, provided it is empty.
|
||||
.Pp
|
||||
Arguments are processed in the order given.
|
||||
In order to remove both a parent directory and a subdirectory
|
||||
of that parent, the subdirectory
|
||||
must be specified first so the parent directory
|
||||
is empty when
|
||||
.Nm
|
||||
tries to remove it.
|
||||
.Pp
|
||||
The following option is available:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl p
|
||||
Each
|
||||
.Ar directory
|
||||
argument is treated as a pathname of which all
|
||||
components will be removed, if they are empty,
|
||||
starting with the last most component.
|
||||
(See
|
||||
.Xr rm 1
|
||||
for fully non-discriminant recursive removal.)
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits with one of the following values:
|
||||
.Bl -tag -width Ds
|
||||
.It Li \&0
|
||||
Each directory entry specified by a dir operand
|
||||
referred to an empty directory and was removed
|
||||
successfully.
|
||||
.It Li \&\*[Gt]\&0
|
||||
An error occurred.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rm 1
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is expected to be
|
||||
.St -p1003.2
|
||||
compatible.
|
||||
121
bin/rmdir/rmdir.c
Normal file
121
bin/rmdir/rmdir.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/* $NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rmdir.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int rm_path(char *);
|
||||
__dead static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, errors, pflag;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
pflag = 0;
|
||||
while ((ch = getopt(argc, argv, "p")) != -1)
|
||||
switch(ch) {
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
usage();
|
||||
|
||||
for (errors = 0; *argv; argv++) {
|
||||
/* We rely on the kernel to ignore trailing '/' characters. */
|
||||
if (rmdir(*argv) < 0) {
|
||||
warn("%s", *argv);
|
||||
errors = 1;
|
||||
} else if (pflag)
|
||||
errors |= rm_path(*argv);
|
||||
}
|
||||
|
||||
exit(errors);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
rm_path(char *path)
|
||||
{
|
||||
char *p;
|
||||
|
||||
while ((p = strrchr(path, '/')) != NULL) {
|
||||
*p = 0;
|
||||
if (p[1] == 0)
|
||||
/* Ignore trailing '/' on deleted name */
|
||||
continue;
|
||||
|
||||
if (rmdir(path) < 0) {
|
||||
warn("%s", path);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: %s [-p] directory ...\n", getprogname());
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
# Makefile for the boot monitor package.
|
||||
|
||||
# XXX: Can only be built with ACK currently
|
||||
CC:=${CC:C/^gcc/cc/}
|
||||
COMPILER_TYPE:=ack
|
||||
|
||||
PROGS= bootblock cdbootblock bootexec boot masterboot \
|
||||
jumpboot installboot edparams
|
||||
|
||||
SRCS.bootblock= bootblock.s
|
||||
CPPFLAGS.bootblock.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.bootblock= ${I86LDFLAGS}
|
||||
BINDIR.bootblock= /usr/mdec
|
||||
MAN.bootblock=
|
||||
|
||||
SRCS.cdbootblock= cdbootblock.s
|
||||
CPPFLAGS.cdbootblock.s= ${I86CPPFLAGS} -DCDBOOT
|
||||
LDFLAGS.cdbootblock= ${I86LDFLAGS}
|
||||
BINDIR.cdbootblock= /usr/mdec
|
||||
MAN.cdbootblock=
|
||||
|
||||
SRCS.bootexec= boothead.s boot.c bootimage.c rawfs86.c
|
||||
CPPFLAGS.boothead.s= ${I86CPPFLAGS}
|
||||
CPPFLAGS.boot.c= ${I86CPPFLAGS}
|
||||
CPPFLAGS.bootimage.c= ${I86CPPFLAGS}
|
||||
CPPFLAGS.rawfs86.c= ${I86CPPFLAGS}
|
||||
LDFLAGS.bootexec= ${I86LDFLAGS}
|
||||
DPADD.bootexec= ${LIBSYS}
|
||||
LDADD.bootexec= -lsys
|
||||
BINDIR.bootexec= /usr/mdec
|
||||
MAN.bootexec=
|
||||
|
||||
BINDIR.boot= /usr/mdec
|
||||
MAN.boot=
|
||||
|
||||
SRCS.masterboot= masterboot.s
|
||||
CPPFLAGS.masterboot.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.masterboot= ${I86LDFLAGS}
|
||||
BINDIR.masterboot= /usr/mdec
|
||||
MAN.masterboot=
|
||||
|
||||
SRCS.jumpboot= jumpboot.s
|
||||
CPPFLAGS.jumpboot.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.jumpboot= ${I86LDFLAGS}
|
||||
BINDIR.jumpboot= /usr/mdec
|
||||
MAN.jumpboot=
|
||||
|
||||
SRCS.installboot= installboot.c rawfs.c
|
||||
BINDIR.installboot= /usr/bin
|
||||
MAN.installboot=
|
||||
|
||||
SRCS.edparams= edparams.c rawfs.c
|
||||
CPPFLAGS.edparams.c= -DUNIX
|
||||
BINDIR.edparams= /usr/bin
|
||||
MAN.edparams=
|
||||
|
||||
rawfs86.c: rawfs.c
|
||||
ln -f rawfs.c rawfs86.c
|
||||
|
||||
edparams.c: boot.c
|
||||
ln -f boot.c edparams.c
|
||||
|
||||
cdbootblock.s: bootblock.s
|
||||
ln -f bootblock.s cdbootblock.s
|
||||
|
||||
boot: bootexec
|
||||
install -S 22kb bootexec
|
||||
cp bootexec boot
|
||||
|
||||
CPPFLAGS= -I${MINIXSRCDIR}
|
||||
AFLAGS= -I${MINIXSRCDIR}
|
||||
I86CPPFLAGS= -mi86 -Was-ncc
|
||||
I86LDFLAGS= -mi86 -Was-ncc -.o -com
|
||||
|
||||
STRIPFLAG= -s
|
||||
|
||||
CLEANFILES+= rawfs86.c edparams.c cdbootblock.s
|
||||
|
||||
.include <minix.prog.mk>
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# a.out2com - Minix a.out to DOS .COM Author: Kees J. Bot
|
||||
# 17 Jun 1995
|
||||
# Transform a Minix a.out to the COM format of MS-DOS,
|
||||
# the executable must be common I&D with 256 scratch bytes at the start of
|
||||
# the text segment to make space for the Program Segment Prefix. The Minix
|
||||
# a.out header and these 256 bytes are removed to make a COM file.
|
||||
|
||||
case $# in
|
||||
2) aout="$1"
|
||||
com="$2"
|
||||
;;
|
||||
*) echo "Usage: $0 <a.out> <dos.com>" >&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
size "$aout" >/dev/null || exit
|
||||
set `size "$aout" | sed 1d`
|
||||
count=`expr \( $1 + $2 - 256 + 31 \) / 32`
|
||||
|
||||
exec dd if="$aout" of="$com" bs=32 skip=9 count=$count conv=silent
|
||||
|
||||
#
|
||||
# $PchId: a.out2com,v 1.3 1998/08/01 09:13:01 philip Exp $
|
||||
128
boot/addaout.c
128
boot/addaout.c
@@ -1,128 +0,0 @@
|
||||
/* A small utility to append an a.out header to an arbitrary file. This allows
|
||||
* inclusion of arbitrary data in the boot image, so that it is magically
|
||||
* loaded as a RAM disk. The a.out header is structured as follows:
|
||||
*
|
||||
* a_flags: A_IMG to indicate this is not an executable
|
||||
*
|
||||
* Created: April 2005, Jorrit N. Herder
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <a.out.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define INPUT_FILE 1
|
||||
#define OUTPUT_FILE 2
|
||||
|
||||
/* Report problems. */
|
||||
static void report(const char *problem, const char *message)
|
||||
{
|
||||
fprintf(stderr, "%s:\n", problem);
|
||||
fprintf(stderr, " %s\n\n", message);
|
||||
}
|
||||
|
||||
|
||||
static int copy_data(int srcfd, int dstfd)
|
||||
{
|
||||
char buf[8192];
|
||||
ssize_t n;
|
||||
int total=0;
|
||||
|
||||
/** FIXME: handle error from read() */
|
||||
|
||||
/* Copy the little bytes themselves. (Source from cp.c). */
|
||||
while ((n= read(srcfd, buf, sizeof(buf))) > 0) {
|
||||
char *bp = buf;
|
||||
ssize_t r = 0;
|
||||
|
||||
/** FIXME: handle error from write() */
|
||||
while (n > 0 && (r= write(dstfd, bp, n)) > 0) {
|
||||
bp += r;
|
||||
n -= r;
|
||||
total += r;
|
||||
}
|
||||
if (r == 0) {
|
||||
fprintf(stderr, "Warning: EOF writing to output file.\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
return(total);
|
||||
}
|
||||
|
||||
|
||||
/* Main program. */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct exec aout;
|
||||
struct stat stin;
|
||||
int fdin, fdout;
|
||||
char * bp;
|
||||
int n,r;
|
||||
int total_size;
|
||||
|
||||
/* Check if command line arguments are present, or print usage. */
|
||||
if (argc!=3) {
|
||||
printf("Invalid arguments. Usage:\n");
|
||||
printf(" %s <input_file> <output_file>\n",argv[0]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Check if we can open the input and output file. */
|
||||
if (stat(argv[INPUT_FILE], &stin) != 0) {
|
||||
report("Couldn't get status of input file", strerror(errno));
|
||||
return(1);
|
||||
}
|
||||
if ((fdin = open(argv[INPUT_FILE], O_RDONLY)) < 0) {
|
||||
report("Couldn't open input file", strerror(errno));
|
||||
return(1);
|
||||
}
|
||||
if ((fdout = open(argv[OUTPUT_FILE], O_WRONLY|O_CREAT|O_TRUNC,
|
||||
stin.st_mode & 0777)) < 0) {
|
||||
report("Couldn't open output file", strerror(errno));
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Copy input file to output file, but leave space for a.out header. */
|
||||
lseek(fdout, sizeof(aout), SEEK_SET);
|
||||
total_size = copy_data(fdin, fdout);
|
||||
if (total_size < 0) {
|
||||
report("Aborted", "Output file may be truncated.");
|
||||
return(1);
|
||||
} else if (total_size == 0) {
|
||||
report("Aborted without prepending header", "No data in input file.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Build a.out header and write to output file. */
|
||||
memset(&aout, 0, sizeof(struct exec));
|
||||
aout.a_magic[0] = A_MAGIC0;
|
||||
aout.a_magic[1] = A_MAGIC1;
|
||||
aout.a_flags |= A_IMG;
|
||||
aout.a_hdrlen = sizeof(aout);
|
||||
aout.a_text = 0;
|
||||
aout.a_data = total_size;
|
||||
aout.a_bss = 0;
|
||||
aout.a_total = aout.a_hdrlen + aout.a_data;
|
||||
|
||||
bp = (char *) &aout;
|
||||
n = sizeof(aout);
|
||||
lseek(fdout, 0L, SEEK_SET);
|
||||
while (n > 0 && (r= write(fdout, bp, n)) > 0) {
|
||||
bp += r;
|
||||
n -= r;
|
||||
}
|
||||
|
||||
printf("Prepended data file (%d bytes) with a.out header (%u bytes).\n",
|
||||
total_size, sizeof(aout));
|
||||
printf("Done.\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
2041
boot/boot.c
2041
boot/boot.c
File diff suppressed because it is too large
Load Diff
220
boot/boot.h
220
boot/boot.h
@@ -1,220 +0,0 @@
|
||||
/* boot.h - Info between different parts of boot. Author: Kees J. Bot
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
/* Constants describing the metal: */
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define SECTOR_SHIFT 9
|
||||
#define RATIO(b) ((b) / SECTOR_SIZE)
|
||||
|
||||
#define PARAMSEC 1 /* Sector containing boot parameters. */
|
||||
|
||||
#define DSKBASE 0x1E /* Floppy disk parameter vector. */
|
||||
#define DSKPARSIZE 11 /* There are this many bytes of parameters. */
|
||||
|
||||
#define ESC '\33' /* Escape key. */
|
||||
|
||||
#define HEADERPOS 0x00600L /* Place for an array of struct exec's. */
|
||||
|
||||
#define FREEPOS 0x08000L /* Memory from FREEPOS to caddr is free to
|
||||
* play with.
|
||||
*/
|
||||
#if BIOS
|
||||
#define MSEC_PER_TICK 55 /* Clock does 18.2 ticks per second. */
|
||||
#define TICKS_PER_DAY 0x1800B0L /* After 24 hours it wraps. */
|
||||
#endif
|
||||
|
||||
#if UNIX
|
||||
#define MSEC_PER_TICK 1000 /* Clock does 18.2 ticks per second. */
|
||||
#define TICKS_PER_DAY 86400L /* Doesn't wrap, but that doesn't matter. */
|
||||
#endif
|
||||
|
||||
#define BOOTPOS 0x07C00L /* Bootstraps are loaded here. */
|
||||
#define SIGNATURE 0xAA55 /* Proper bootstraps have this signature. */
|
||||
#define SIGNATOFF 510 /* Offset within bootblock. */
|
||||
|
||||
/* BIOS video modes. */
|
||||
#define MONO_MODE 0x07 /* 80x25 monochrome. */
|
||||
#define COLOR_MODE 0x03 /* 80x25 color. */
|
||||
|
||||
|
||||
/* Variables shared with boothead.s: */
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
typedef struct vector { /* 8086 vector */
|
||||
u16_t offset;
|
||||
u16_t segment;
|
||||
} vector;
|
||||
|
||||
EXTERN vector rem_part; /* Boot partition table entry. */
|
||||
|
||||
EXTERN u32_t caddr, daddr; /* Code and data address of the boot program. */
|
||||
EXTERN u32_t runsize; /* Size of this program. */
|
||||
|
||||
EXTERN u16_t device; /* Drive being booted from. */
|
||||
EXTERN u16_t cddevice; /* Drive that is CD if known. */
|
||||
|
||||
#define CDNAME "cd" /* Name of the CD device. */
|
||||
|
||||
typedef struct { /* One chunk of free memory. */
|
||||
u32_t base; /* Start byte. */
|
||||
u32_t size; /* Number of bytes. */
|
||||
} memory;
|
||||
|
||||
EXTERN memory mem[3]; /* List of available memory. */
|
||||
EXTERN int mon_return; /* Monitor stays in memory? */
|
||||
EXTERN int cdbooted; /* Did we boot from CD? (Set by boothead.s.) */
|
||||
|
||||
typedef struct bios_env
|
||||
{
|
||||
u16_t ax;
|
||||
u16_t bx;
|
||||
u16_t cx;
|
||||
u16_t flags;
|
||||
} bios_env_t;
|
||||
|
||||
#define FL_CARRY 0x0001 /* carry flag */
|
||||
|
||||
/* Functions defined by boothead.s: */
|
||||
|
||||
void exit(int code);
|
||||
/* Exit the monitor. */
|
||||
u32_t mon2abs(void *ptr);
|
||||
/* Local monitor address to absolute address. */
|
||||
u32_t vec2abs(vector *vec);
|
||||
/* Vector to absolute address. */
|
||||
void raw_copy(u32_t dstaddr, u32_t srcaddr, u32_t count);
|
||||
/* Copy bytes from anywhere to anywhere. */
|
||||
u16_t get_word(u32_t addr);
|
||||
/* Get a word from anywhere. */
|
||||
void put_word(u32_t addr, u16_t word);
|
||||
/* Put a word anywhere. */
|
||||
void relocate(void);
|
||||
/* Switch to a copy of this program. */
|
||||
int dev_open(void), dev_close(void);
|
||||
/* Open device and determine params / close device. */
|
||||
int dev_boundary(u32_t sector);
|
||||
/* True if sector is on a track boundary. */
|
||||
int readsectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
/* Read 1 or more sectors from "device". */
|
||||
int writesectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
/* Write 1 or more sectors to "device". */
|
||||
|
||||
int biosreadsectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
|
||||
int getch(void);
|
||||
/* Read a keypress. */
|
||||
void scan_keyboard(void);
|
||||
/* Read keypress directly from kb controller. */
|
||||
void ungetch(int c);
|
||||
/* Undo a keypress. */
|
||||
int escape(void);
|
||||
/* True if escape typed. */
|
||||
void putch(int c);
|
||||
/* Send a character to the screen. */
|
||||
#if BIOS
|
||||
void pause(void);
|
||||
/* Wait for an interrupt. */
|
||||
void serial_init(int line);
|
||||
#endif /* Enable copying console I/O to a serial line. */
|
||||
|
||||
void set_mode(unsigned mode);
|
||||
void clear_screen(void);
|
||||
/* Set video mode / clear the screen. */
|
||||
|
||||
u16_t get_bus(void);
|
||||
/* System bus type, XT, AT, or MCA. */
|
||||
u16_t get_video(void);
|
||||
/* Display type, MDA to VGA. */
|
||||
u32_t get_tick(void);
|
||||
/* Current value of the clock tick counter. */
|
||||
|
||||
void bootstrap(int device, struct part_entry *entry);
|
||||
/* Execute a bootstrap routine for a different O.S. */
|
||||
void minix(u32_t koff, u32_t kcs, u32_t kds,
|
||||
char *bootparams, size_t paramsize, u32_t aout);
|
||||
/* Start Minix. */
|
||||
void int15(bios_env_t *);
|
||||
|
||||
|
||||
/* Shared between boot.c and bootimage.c: */
|
||||
|
||||
/* Sticky attributes. */
|
||||
#define E_SPECIAL 0x01 /* These are known to the program. */
|
||||
#define E_DEV 0x02 /* The value is a device name. */
|
||||
#define E_RESERVED 0x04 /* May not be set by user, e.g. 'boot' */
|
||||
#define E_STICKY 0x07 /* Don't go once set. */
|
||||
|
||||
/* Volatile attributes. */
|
||||
#define E_VAR 0x08 /* Variable */
|
||||
#define E_FUNCTION 0x10 /* Function definition. */
|
||||
|
||||
/* Variables, functions, and commands. */
|
||||
typedef struct environment {
|
||||
struct environment *next;
|
||||
char flags;
|
||||
char *name; /* name = value */
|
||||
char *arg; /* name(arg) {value} */
|
||||
char *value;
|
||||
char *defval; /* Safehouse for default values. */
|
||||
} environment;
|
||||
|
||||
EXTERN environment *env; /* Lists the environment. */
|
||||
|
||||
char *b_value(const char *name); /* Get/set the value of a variable. */
|
||||
int b_setvar(int flags, char *name, char *value);
|
||||
void b_unset(const char *name);
|
||||
|
||||
void parse_code(char *code); /* Parse boot monitor commands. */
|
||||
|
||||
extern int fsok; /* True if the boot device contains an FS. */
|
||||
EXTERN u32_t lowsec; /* Offset to the file system on the boot device. */
|
||||
|
||||
/* Called by boot.c: */
|
||||
|
||||
void bootminix(void); /* Load and start a Minix image. */
|
||||
|
||||
|
||||
/* Called by bootimage.c: */
|
||||
|
||||
void readerr(off_t sec, int err);
|
||||
/* Report a read error. */
|
||||
char *ul2a(u32_t n, unsigned b), *ul2a10(u32_t n);
|
||||
/* Transform u32_t to ASCII at base b or base 10. */
|
||||
long a2l(const char *a);
|
||||
/* Cheap atol(). */
|
||||
unsigned a2x(const char *a);
|
||||
/* ASCII to hex. */
|
||||
dev_t name2dev(char *name);
|
||||
/* Translate a device name to a device number. */
|
||||
int numprefix(char *s, char **ps);
|
||||
/* True for a numeric prefix. */
|
||||
int numeric(char *s);
|
||||
/* True for a numeric string. */
|
||||
char *unix_err(int err);
|
||||
/* Give a descriptive text for some UNIX errors. */
|
||||
int run_trailer(void);
|
||||
/* Run the trailer function. */
|
||||
|
||||
#if DOS
|
||||
/* The monitor runs under MS-DOS. */
|
||||
extern char PSP[256]; /* Program Segment Prefix. */
|
||||
EXTERN char *vdisk; /* Name of the virtual disk. */
|
||||
EXTERN char *drun; /* Initial command from DOS command line. */
|
||||
#else
|
||||
/* The monitor uses only the BIOS. */
|
||||
#define DOS 0
|
||||
#endif
|
||||
|
||||
void readblock(off_t, char *, int);
|
||||
void delay(const char *);
|
||||
|
||||
/*
|
||||
* $PchId: boot.h,v 1.12 2002/02/27 19:42:45 philip Exp $
|
||||
*/
|
||||
256
boot/bootblock.s
256
boot/bootblock.s
@@ -1,256 +0,0 @@
|
||||
#
|
||||
! Bootblock 1.5 - Minix boot block. Author: Kees J. Bot
|
||||
! 21 Dec 1991
|
||||
!
|
||||
! When the PC is powered on, it will try to read the first sector of floppy
|
||||
! disk 0 at address 0x7C00. If this fails due to the absence of flexible
|
||||
! magnetic media, it will read the master boot record from the first sector
|
||||
! of the hard disk. This sector not only contains executable code, but also
|
||||
! the partition table of the hard disk. When executed, it will select the
|
||||
! active partition and load the first sector of that at address 0x7C00.
|
||||
! This file contains the code that is eventually read from either the floppy
|
||||
! disk, or the hard disk partition. It is just smart enough to load /boot
|
||||
! from the boot device into memory at address 0x10000 and execute that. The
|
||||
! disk addresses for /boot are patched into this code by installboot as 24-bit
|
||||
! sector numbers and 8-bit sector counts above enddata upwards. /boot is in
|
||||
! turn smart enough to load the different parts of the Minix kernel into
|
||||
! memory and execute them to finally get Minix started.
|
||||
!
|
||||
|
||||
LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
|
||||
BOOTSEG = 0x1000 ! Secondary boot code segment.
|
||||
#ifdef CDBOOT
|
||||
BOOTOFF = 0x0050 ! Offset into /boot above header
|
||||
#else
|
||||
BOOTOFF = 0x0030 ! Offset into /boot above header
|
||||
#endif
|
||||
BUFFER = 0x0600 ! First free memory
|
||||
#ifndef CDBOOT /* just constants, but make no sense for CDs */
|
||||
LOWSEC = 8 ! Offset of logical first sector in partition
|
||||
! table
|
||||
|
||||
! Variables addressed using bp register
|
||||
lowsec = 2 ! Offset of boot partition within drive
|
||||
secpcyl = 6 ! Sectors per cylinder = heads * sectors
|
||||
#endif
|
||||
device = 0 ! The boot device
|
||||
|
||||
.text
|
||||
|
||||
! Start boot procedure.
|
||||
|
||||
boot:
|
||||
xor ax, ax ! ax = 0x0000, the vector segment
|
||||
mov ds, ax
|
||||
cli ! Ignore interrupts while setting stack
|
||||
mov ss, ax ! ss = ds = vector segment
|
||||
mov sp, #LOADOFF ! Usual place for a bootstrap stack
|
||||
sti
|
||||
|
||||
push ax
|
||||
push ax ! Push a zero lowsec(bp)
|
||||
|
||||
push dx ! Boot device in dl will be device(bp)
|
||||
mov bp, sp ! Using var(bp) is one byte cheaper then var.
|
||||
|
||||
push es
|
||||
push si ! es:si = partition table entry if hard disk
|
||||
|
||||
mov di, #LOADOFF+sectors ! char *di = sectors;
|
||||
|
||||
#ifndef CDBOOT
|
||||
testb dl, dl ! Winchester disks if dl >= 0x80
|
||||
jge floppy
|
||||
#endif
|
||||
|
||||
winchester:
|
||||
|
||||
#ifndef CDBOOT
|
||||
! Get the offset of the first sector of the boot partition from the partition
|
||||
! table. The table is found at es:si, the lowsec parameter at offset LOWSEC.
|
||||
|
||||
eseg
|
||||
les ax, LOWSEC(si) ! es:ax = LOWSEC+2(si):LOWSEC(si)
|
||||
mov lowsec+0(bp), ax ! Low 16 bits of partitions first sector
|
||||
mov lowsec+2(bp), es ! High 16 bits of partitions first sector
|
||||
|
||||
! Get the drive parameters, the number of sectors is bluntly written into the
|
||||
! floppy disk sectors/track array.
|
||||
|
||||
movb ah, #0x08 ! Code for drive parameters
|
||||
int 0x13 ! dl still contains drive
|
||||
andb cl, #0x3F ! cl = max sector number (1-origin)
|
||||
movb (di), cl ! Number of sectors per track
|
||||
incb dh ! dh = 1 + max head number (0-origin)
|
||||
#endif
|
||||
jmp loadboot
|
||||
|
||||
#ifndef CDBOOT
|
||||
! Floppy:
|
||||
! Execute three read tests to determine the drive type. Test for each floppy
|
||||
! type by reading the last sector on the first track. If it fails, try a type
|
||||
! that has less sectors. Therefore we start with 1.44M (18 sectors) then 1.2M
|
||||
! (15 sectors) ending with 720K/360K (both 9 sectors).
|
||||
|
||||
next: inc di ! Next number of sectors per track
|
||||
|
||||
floppy: xorb ah, ah ! Reset drive
|
||||
int 0x13
|
||||
|
||||
movb cl, (di) ! cl = number of last sector on track
|
||||
|
||||
cmpb cl, #9 ! No need to do the last 720K/360K test
|
||||
je success
|
||||
|
||||
! Try to read the last sector on track 0
|
||||
|
||||
mov es, lowsec(bp) ! es = vector segment (lowsec = 0)
|
||||
mov bx, #BUFFER ! es:bx buffer = 0x0000:0x0600
|
||||
mov ax, #0x0201 ! Read sector, #sectors = 1
|
||||
xorb ch, ch ! Track 0, last sector
|
||||
xorb dh, dh ! Drive dl, head 0
|
||||
int 0x13
|
||||
jc next ! Error, try the next floppy type
|
||||
|
||||
success:movb dh, #2 ! Load number of heads for multiply
|
||||
#endif
|
||||
|
||||
loadboot:
|
||||
! Load /boot from the boot device
|
||||
|
||||
#ifndef CDBOOT
|
||||
movb al, (di) ! al = (di) = sectors per track
|
||||
mulb dh ! dh = heads, ax = heads * sectors
|
||||
mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors
|
||||
#endif
|
||||
|
||||
mov ax, #BOOTSEG ! Segment to load /boot into
|
||||
mov es, ax
|
||||
xor bx, bx ! Load first sector at es:bx = BOOTSEG:0x0000
|
||||
mov si, #LOADOFF+addresses ! Start of the boot code addresses
|
||||
load:
|
||||
mov ax, 1(si) ! Get next sector number: low 16 bits
|
||||
movb dl, 3(si) ! Bits 16-23 for your up to 8GB partition
|
||||
xorb dh, dh ! dx:ax = sector within partition
|
||||
#ifndef CDBOOT
|
||||
add ax, lowsec+0(bp)
|
||||
adc dx, lowsec+2(bp)! dx:ax = sector within drive
|
||||
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
|
||||
jae bigdisk
|
||||
div secpcyl(bp) ! ax = cylinder, dx = sector within cylinder
|
||||
xchg ax, dx ! ax = sector within cylinder, dx = cylinder
|
||||
movb ch, dl ! ch = low 8 bits of cylinder
|
||||
divb (di) ! al = head, ah = sector (0-origin)
|
||||
xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
|
||||
shr dx, #1
|
||||
shr dx, #1 ! dl[6..7] = high cylinder
|
||||
orb dl, ah ! dl[0..5] = sector (0-origin)
|
||||
movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
|
||||
incb cl ! cl[0..5] = sector (1-origin)
|
||||
movb dh, al ! dh = al = head
|
||||
movb dl, device(bp) ! dl = device to read
|
||||
movb al, (di) ! Sectors per track - Sector number (0-origin)
|
||||
subb al, ah ! = Sectors left on this track
|
||||
cmpb al, (si) ! Compare with # sectors to read
|
||||
jbe read ! Cant read past the end of a cylinder?
|
||||
movb al, (si) ! (si) < sectors left on this track
|
||||
read: push ax ! Save al = sectors to read
|
||||
movb ah, #0x02 ! Code for disk read (all registers in use now!)
|
||||
int 0x13 ! Call the BIOS for a read
|
||||
pop cx ! Restore al in cl
|
||||
jmp rdeval
|
||||
#endif
|
||||
bigdisk:
|
||||
movb cl, (si) ! Number of sectors to read
|
||||
push si ! Save si
|
||||
mov si, #LOADOFF+ext_rw ! si = extended read/write parameter packet
|
||||
movb 2(si), cl ! Fill in # blocks to transfer
|
||||
mov 4(si), bx ! Buffer address
|
||||
mov 8(si), ax ! Starting block number = dx:ax
|
||||
mov 10(si), dx
|
||||
movb dl, device(bp) ! dl = device to read
|
||||
movb ah, #0x42 ! Extended read
|
||||
int 0x13
|
||||
pop si ! Restore si to point to the addresses array
|
||||
!jmp rdeval
|
||||
rdeval:
|
||||
jc error ! Jump on disk read error
|
||||
movb al, cl ! Restore al = sectors read
|
||||
addb bh, al ! bx += 2 * al * 256 (add bytes read)
|
||||
addb bh, al ! es:bx = where next sector must be read
|
||||
#ifdef CDBOOT
|
||||
addb bh, al ! For CDs, a sector is 2048 bytes, so
|
||||
addb bh, al ! do this 6 more times to get byte count.
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
#endif
|
||||
add 1(si), ax ! Update address by sectors read
|
||||
adcb 3(si), ah ! Don't forget bits 16-23 (add ah = 0)
|
||||
subb (si), al ! Decrement sector count by sectors read
|
||||
jnz load ! Not all sectors have been read
|
||||
add si, #4 ! Next (address, count) pair
|
||||
cmpb ah, (si) ! Done when no sectors to read
|
||||
jnz load ! Read next chunk of /boot
|
||||
|
||||
done:
|
||||
|
||||
! Call /boot, assuming a long a.out header (48 bytes). The a.out header is
|
||||
! usually short (32 bytes), but to be sure /boot has two entry points:
|
||||
! One at offset 0 for the long, and one at offset 16 for the short header.
|
||||
! Parameters passed in registers are:
|
||||
!
|
||||
! dl = Boot-device.
|
||||
! es:si = Partition table entry if hard disk.
|
||||
!
|
||||
pop si ! Restore es:si = partition table entry
|
||||
pop es ! dl is still loaded
|
||||
jmpf BOOTOFF, BOOTSEG ! jmp to sec. boot (skipping header).
|
||||
|
||||
! Read error: print message, hang forever
|
||||
error:
|
||||
mov si, #LOADOFF+errno+1
|
||||
prnum: movb al, ah ! Error number in ah
|
||||
andb al, #0x0F ! Low 4 bits
|
||||
cmpb al, #10 ! A-F?
|
||||
jb digit ! 0-9!
|
||||
addb al, #7 ! 'A' - ':'
|
||||
digit: addb (si), al ! Modify '0' in string
|
||||
dec si
|
||||
movb cl, #4 ! Next 4 bits
|
||||
shrb ah, cl
|
||||
jnz prnum ! Again if digit > 0
|
||||
|
||||
mov si, #LOADOFF+rderr ! String to print
|
||||
print: lodsb ! al = *si++ is char to be printed
|
||||
testb al, al ! Null byte marks end
|
||||
hang: jz hang ! Hang forever waiting for CTRL-ALT-DEL
|
||||
movb ah, #0x0E ! Print character in teletype mode
|
||||
mov bx, #0x0001 ! Page 0, foreground color
|
||||
int 0x10 ! Call BIOS VIDEO_IO
|
||||
jmp print
|
||||
|
||||
.data
|
||||
rderr: .ascii "Read error "
|
||||
errno: .ascii "00 \0"
|
||||
errend:
|
||||
|
||||
! Floppy disk sectors per track for the 1.44M, 1.2M and 360K/720K types:
|
||||
sectors:
|
||||
.data1 18, 15, 9
|
||||
|
||||
! Extended read/write commands require a parameter packet.
|
||||
ext_rw:
|
||||
.data1 0x10 ! Length of extended r/w packet
|
||||
.data1 0 ! Reserved
|
||||
.data2 0 ! Blocks to transfer (to be filled in)
|
||||
.data2 0 ! Buffer address offset (tbfi)
|
||||
.data2 BOOTSEG ! Buffer address segment
|
||||
.data4 0 ! Starting block number low 32 bits (tbfi)
|
||||
.data4 0 ! Starting block number high 32 bits
|
||||
|
||||
.align 2
|
||||
addresses:
|
||||
! The space below this is for disk addresses for a 38K /boot program (worst
|
||||
! case, i.e. file is completely fragmented). It should be enough.
|
||||
1548
boot/boothead.s
1548
boot/boothead.s
File diff suppressed because it is too large
Load Diff
857
boot/bootimage.c
857
boot/bootimage.c
@@ -1,857 +0,0 @@
|
||||
/* bootimage.c - Load an image and start it. Author: Kees J. Bot
|
||||
* 19 Jan 1992
|
||||
*/
|
||||
#define BIOS 1 /* Can only be used under the BIOS. */
|
||||
#define nil 0
|
||||
#define _POSIX_SOURCE 1
|
||||
#define _MINIX 1
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <a.out.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <minix/tty.h>
|
||||
#include <sys/video.h>
|
||||
#include <kernel/const.h>
|
||||
#include <kernel/type.h>
|
||||
#include <machine/partition.h>
|
||||
#include "rawfs.h"
|
||||
#include "image.h"
|
||||
#include "boot.h"
|
||||
|
||||
static int block_size = 0;
|
||||
static int verboseboot = VERBOSEBOOT_QUIET;
|
||||
|
||||
#define DEBUG_PRINT(params, level) do { \
|
||||
if (verboseboot >= (level)) printf params; } while (0)
|
||||
#define DEBUGBASIC(params) DEBUG_PRINT(params, VERBOSEBOOT_BASIC)
|
||||
#define DEBUGEXTRA(params) DEBUG_PRINT(params, VERBOSEBOOT_EXTRA)
|
||||
#define DEBUGMAX(params) DEBUG_PRINT(params, VERBOSEBOOT_MAX)
|
||||
|
||||
extern int serial_line;
|
||||
extern u16_t vid_port; /* Video i/o port. */
|
||||
extern u32_t vid_mem_base; /* Video memory base address. */
|
||||
extern u32_t vid_mem_size; /* Video memory size. */
|
||||
|
||||
#define click_shift clck_shft /* 7 char clash with click_size. */
|
||||
|
||||
/* Some kernels have extra features: */
|
||||
#define K_I386 0x0001 /* Make the 386 transition before you call me. */
|
||||
#define K_CLAIM 0x0002 /* I will acquire my own bss pages, thank you. */
|
||||
#define K_CHMEM 0x0004 /* This kernel listens to chmem for its stack size. */
|
||||
#define K_HIGH 0x0008 /* Load mm, fs, etc. in extended memory. */
|
||||
#define K_HDR 0x0010 /* No need to patch sizes, kernel uses the headers. */
|
||||
#define K_RET 0x0020 /* Returns to the monitor on reboot. */
|
||||
#define K_INT86 0x0040 /* Requires generic INT support. */
|
||||
#define K_MEML 0x0080 /* Pass a list of free memory. */
|
||||
#define K_BRET 0x0100 /* New monitor code on shutdown in boot parameters. */
|
||||
#define K_KHIGH 0x0200 /* Load kernel in extended memory. */
|
||||
#define K_ALL 0x03FF /* All feature bits this monitor supports. */
|
||||
|
||||
|
||||
/* Data about the different processes. */
|
||||
|
||||
#define PROCESS_MAX 16 /* Must match the space in kernel/mpx.x */
|
||||
#define KERNEL_IDX 0 /* The first process is the kernel. */
|
||||
#define FS 2 /* The third must be fs. */
|
||||
|
||||
struct process { /* Per-process memory adresses. */
|
||||
u32_t entry; /* Entry point. */
|
||||
u32_t cs; /* Code segment. */
|
||||
u32_t ds; /* Data segment. */
|
||||
u32_t data; /* To access the data segment. */
|
||||
u32_t end; /* End of this process, size = (end - cs). */
|
||||
} process[PROCESS_MAX];
|
||||
int n_procs; /* Number of processes. */
|
||||
|
||||
/* Magic numbers in process' data space. */
|
||||
#define MAGIC_OFF 0 /* Offset of magic # in data seg. */
|
||||
#define CLICK_OFF 2 /* Offset in kernel text to click_shift. */
|
||||
#define FLAGS_OFF 4 /* Offset in kernel text to flags. */
|
||||
#define KERNEL_D_MAGIC 0x526F /* Kernel magic number. */
|
||||
|
||||
/* Offsets of sizes to be patched into kernel and fs. */
|
||||
#define P_SIZ_OFF 0 /* Process' sizes into kernel data. */
|
||||
#define P_INIT_OFF 4 /* Init cs & sizes into fs data. */
|
||||
|
||||
|
||||
#define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
|
||||
|
||||
void pretty_image(const char *image)
|
||||
/* Pretty print the name of the image to load. Translate '/' and '_' to
|
||||
* space, first letter goes uppercase. An 'r' before a digit prints as
|
||||
* 'revision'. E.g. 'minix/1.6.16r10' -> 'Minix 1.6.16 revision 10'.
|
||||
* The idea is that the part before the 'r' is the official Minix release
|
||||
* and after the 'r' you can put version numbers for your own changes.
|
||||
*/
|
||||
{
|
||||
int up= 0, c;
|
||||
|
||||
while ((c= *image++) != 0) {
|
||||
if (c == '/' || c == '_') c= ' ';
|
||||
|
||||
if (c == 'r' && between('0', *image, '9')) {
|
||||
printf(" revision ");
|
||||
continue;
|
||||
}
|
||||
if (!up && between('a', c, 'z')) c= c - 'a' + 'A';
|
||||
|
||||
if (between('A', c, 'Z')) up= 1;
|
||||
|
||||
putch(c);
|
||||
}
|
||||
}
|
||||
|
||||
#define RAW_ALIGN 16
|
||||
#define BUFSIZE_ZEROS 128
|
||||
|
||||
void raw_clear(u32_t addr, u32_t count)
|
||||
/* Clear "count" bytes at absolute address "addr". */
|
||||
{
|
||||
static char zerosdata[BUFSIZE_ZEROS + RAW_ALIGN];
|
||||
char *zeros = zerosdata + RAW_ALIGN - (unsigned) &zerosdata % RAW_ALIGN;
|
||||
u32_t dst;
|
||||
u32_t zct;
|
||||
|
||||
zct= BUFSIZE_ZEROS;
|
||||
if (zct > count) zct= count;
|
||||
raw_copy(addr, mon2abs(zeros), zct);
|
||||
count-= zct;
|
||||
|
||||
while (count > 0) {
|
||||
dst= addr + zct;
|
||||
if (zct > count) zct= count;
|
||||
raw_copy(dst, addr, zct);
|
||||
count-= zct;
|
||||
zct*= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Align a to a multiple of n (a power of 2): */
|
||||
#define align(a, n) (((u32_t)(a) + ((u32_t)(n) - 1)) & ~((u32_t)(n) - 1))
|
||||
unsigned click_shift;
|
||||
unsigned click_size; /* click_size = Smallest kernel memory object. */
|
||||
unsigned k_flags; /* Not all kernels are created equal. */
|
||||
u32_t reboot_code; /* Obsolete reboot code return pointer. */
|
||||
|
||||
int params2params(char *params, size_t psize)
|
||||
/* Repackage the environment settings for the kernel. */
|
||||
{
|
||||
size_t i, n;
|
||||
environment *e;
|
||||
char *name, *value;
|
||||
dev_t dev;
|
||||
|
||||
i= 0;
|
||||
for (e= env; e != nil; e= e->next) {
|
||||
name= e->name;
|
||||
value= e->value;
|
||||
|
||||
if (!(e->flags & E_VAR)) continue;
|
||||
|
||||
if (e->flags & E_DEV) {
|
||||
if ((dev= name2dev(value)) == -1) return 0;
|
||||
value= ul2a10((u16_t) dev);
|
||||
}
|
||||
|
||||
n= i + strlen(name) + 1 + strlen(value) + 1;
|
||||
if (n < psize) {
|
||||
strcpy(params + i, name);
|
||||
strcat(params + i, "=");
|
||||
strcat(params + i, value);
|
||||
}
|
||||
i= n;
|
||||
}
|
||||
|
||||
if (!(k_flags & K_MEML)) {
|
||||
/* Require old memory size variables. */
|
||||
|
||||
value= ul2a10((mem[0].base + mem[0].size) / 1024);
|
||||
n= i + 7 + 1 + strlen(value) + 1;
|
||||
if (n < psize) {
|
||||
strcpy(params + i, "memsize=");
|
||||
strcat(params + i, value);
|
||||
}
|
||||
i= n;
|
||||
value= ul2a10(mem[1].size / 1024);
|
||||
n= i + 7 + 1 + strlen(value) + 1;
|
||||
if (n < psize) {
|
||||
strcpy(params + i, "emssize=");
|
||||
strcat(params + i, value);
|
||||
}
|
||||
i= n;
|
||||
}
|
||||
|
||||
if (i >= psize) {
|
||||
printf("Too many boot parameters\n");
|
||||
return 0;
|
||||
}
|
||||
params[i]= 0; /* End marked with empty string. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void patch_sizes(void)
|
||||
/* Patch sizes of each process into kernel data space, kernel ds into kernel
|
||||
* text space, and sizes of init into data space of fs. All the patched
|
||||
* numbers are based on the kernel click size, not hardware segments.
|
||||
*/
|
||||
{
|
||||
u16_t text_size, data_size;
|
||||
int i;
|
||||
struct process *procp, *initp;
|
||||
u32_t doff;
|
||||
|
||||
if (k_flags & K_HDR) return; /* Uses the headers. */
|
||||
|
||||
/* Patch text and data sizes of the processes into kernel data space.
|
||||
*/
|
||||
doff= process[KERNEL_IDX].data + P_SIZ_OFF;
|
||||
|
||||
for (i= 0; i < n_procs; i++) {
|
||||
procp= &process[i];
|
||||
text_size= (procp->ds - procp->cs) >> click_shift;
|
||||
data_size= (procp->end - procp->ds) >> click_shift;
|
||||
|
||||
/* Two words per process, the text and data size: */
|
||||
put_word(doff, text_size); doff+= 2;
|
||||
put_word(doff, data_size); doff+= 2;
|
||||
|
||||
initp= procp; /* The last process must be init. */
|
||||
}
|
||||
|
||||
if (k_flags & (K_HIGH|K_MEML)) return; /* Doesn't need FS patching. */
|
||||
|
||||
/* Patch cs and sizes of init into fs data. */
|
||||
put_word(process[FS].data + P_INIT_OFF+0, initp->cs >> click_shift);
|
||||
put_word(process[FS].data + P_INIT_OFF+2, text_size);
|
||||
put_word(process[FS].data + P_INIT_OFF+4, data_size);
|
||||
}
|
||||
|
||||
int selected(const char *name)
|
||||
/* True iff name has no label or the proper label. */
|
||||
{
|
||||
char *colon, *label;
|
||||
int cmp;
|
||||
|
||||
if ((colon= strchr(name, ':')) == nil) return 1;
|
||||
if ((label= b_value("label")) == nil) return 1;
|
||||
|
||||
*colon= 0;
|
||||
cmp= strcmp(label, name);
|
||||
*colon= ':';
|
||||
return cmp == 0;
|
||||
}
|
||||
|
||||
static u32_t proc_size(const struct image_header *hdr)
|
||||
/* Return the size of a process in sectors as found in an image. */
|
||||
{
|
||||
u32_t len= hdr->process.a_text;
|
||||
|
||||
if (hdr->process.a_flags & A_PAL) len+= hdr->process.a_hdrlen;
|
||||
if (hdr->process.a_flags & A_SEP) len= align(len, SECTOR_SIZE);
|
||||
len= align(len + hdr->process.a_data, SECTOR_SIZE);
|
||||
|
||||
return len >> SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
off_t image_off, image_size;
|
||||
u32_t (*vir2sec)(u32_t vsec); /* Where is a sector on disk? */
|
||||
|
||||
u32_t file_vir2sec(u32_t vsec)
|
||||
/* Translate a virtual sector number to an absolute disk sector. */
|
||||
{
|
||||
off_t blk;
|
||||
|
||||
if(!block_size) { errno = 0; return -1; }
|
||||
|
||||
if ((blk= r_vir2abs(vsec / RATIO(block_size))) == -1) {
|
||||
errno= EIO;
|
||||
return -1;
|
||||
}
|
||||
return blk == 0 ? 0 : lowsec + blk * RATIO(block_size) + vsec % RATIO(block_size);
|
||||
}
|
||||
|
||||
u32_t flat_vir2sec(u32_t vsec)
|
||||
/* Simply add an absolute sector offset to vsec. */
|
||||
{
|
||||
return lowsec + image_off + vsec;
|
||||
}
|
||||
|
||||
char *get_sector(u32_t vsec)
|
||||
/* Read a sector "vsec" from the image into memory and return its address.
|
||||
* Return nil on error. (This routine tries to read an entire track, so
|
||||
* the next request is usually satisfied from the track buffer.)
|
||||
*/
|
||||
{
|
||||
u32_t sec;
|
||||
int r;
|
||||
#define SECBUFS 16
|
||||
static char bufdata[SECBUFS * SECTOR_SIZE + RAW_ALIGN];
|
||||
static size_t count; /* Number of sectors in the buffer. */
|
||||
static u32_t bufsec; /* First Sector now in the buffer. */
|
||||
char *buf = bufdata + RAW_ALIGN - (unsigned) &bufdata % RAW_ALIGN;
|
||||
|
||||
if (vsec == 0) count= 0; /* First sector; initialize. */
|
||||
|
||||
if ((sec= (*vir2sec)(vsec)) == -1) return nil;
|
||||
|
||||
if (sec == 0) {
|
||||
/* A hole. */
|
||||
count= 0;
|
||||
memset(buf, 0, SECTOR_SIZE);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Can we return a sector from the buffer? */
|
||||
if ((sec - bufsec) < count) {
|
||||
return buf + ((size_t) (sec - bufsec) << SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
/* Not in the buffer. */
|
||||
count= 0;
|
||||
bufsec= sec;
|
||||
|
||||
/* Read a whole track if possible. */
|
||||
while (++count < SECBUFS && !dev_boundary(bufsec + count)) {
|
||||
vsec++;
|
||||
if ((sec= (*vir2sec)(vsec)) == -1) break;
|
||||
|
||||
/* Consecutive? */
|
||||
if (sec != bufsec + count) break;
|
||||
}
|
||||
|
||||
/* Actually read the sectors. */
|
||||
if ((r= readsectors(mon2abs(buf), bufsec, count)) != 0) {
|
||||
readerr(bufsec, r);
|
||||
count= 0;
|
||||
errno= 0;
|
||||
return nil;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int get_clickshift(u32_t ksec, struct image_header *hdr)
|
||||
/* Get the click shift and special flags from kernel text. */
|
||||
{
|
||||
char *textp;
|
||||
|
||||
if ((textp= get_sector(ksec)) == nil) return 0;
|
||||
|
||||
if (hdr->process.a_flags & A_PAL) textp+= hdr->process.a_hdrlen;
|
||||
click_shift= * (u16_t *) (textp + CLICK_OFF);
|
||||
k_flags= * (u16_t *) (textp + FLAGS_OFF);
|
||||
|
||||
if ((k_flags & ~K_ALL) != 0) {
|
||||
printf("%s requires features this monitor doesn't offer\n",
|
||||
hdr->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (click_shift < HCLICK_SHIFT || click_shift > 16) {
|
||||
printf("%s click size is bad\n", hdr->name);
|
||||
errno= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
click_size= 1 << click_shift;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
|
||||
/* Read *size bytes starting at virtual sector *vsec to memory at *addr. */
|
||||
{
|
||||
char *buf;
|
||||
size_t cnt, n;
|
||||
|
||||
cnt= 0;
|
||||
while (*size > 0) {
|
||||
if (cnt == 0) {
|
||||
if ((buf= get_sector((*vsec)++)) == nil) return 0;
|
||||
cnt= SECTOR_SIZE;
|
||||
}
|
||||
if (*addr + click_size > limit)
|
||||
{
|
||||
DEBUGEXTRA(("get_segment: out of memory; "
|
||||
"addr=0x%lx; limit=0x%lx; size=%lx\n",
|
||||
*addr, limit, size));
|
||||
errno= ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
n= click_size;
|
||||
if (n > cnt) n= cnt;
|
||||
DEBUGMAX(("raw_copy(0x%lx, 0x%lx/0x%x, 0x%lx)... ",
|
||||
*addr, mon2abs(buf), buf, n));
|
||||
raw_copy(*addr, mon2abs(buf), n);
|
||||
DEBUGMAX(("done\n"));
|
||||
*addr+= n;
|
||||
*size-= n;
|
||||
buf+= n;
|
||||
cnt-= n;
|
||||
}
|
||||
|
||||
/* Zero extend to a click. */
|
||||
n= align(*addr, click_size) - *addr;
|
||||
DEBUGMAX(("raw_clear(0x%lx, 0x%lx)... ", *addr, n));
|
||||
raw_clear(*addr, n);
|
||||
DEBUGMAX(("done\n"));
|
||||
*addr+= n;
|
||||
*size-= n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void restore_screen(void)
|
||||
{
|
||||
struct boot_tty_info boot_tty_info;
|
||||
u32_t info_location;
|
||||
#define LINES 25
|
||||
#define CHARS 80
|
||||
static u16_t consolescreen[LINES][CHARS];
|
||||
|
||||
/* Try and find out what the main console was displaying
|
||||
* by looking into video memory.
|
||||
*/
|
||||
|
||||
info_location = vid_mem_base+vid_mem_size-sizeof(boot_tty_info);
|
||||
raw_copy(mon2abs(&boot_tty_info), info_location,
|
||||
sizeof(boot_tty_info));
|
||||
|
||||
if(boot_tty_info.magic == TTYMAGIC) {
|
||||
if((boot_tty_info.flags & (BTIF_CONSORIGIN|BTIF_CONSCURSOR)) ==
|
||||
(BTIF_CONSORIGIN|BTIF_CONSCURSOR)) {
|
||||
int line;
|
||||
raw_copy(mon2abs(consolescreen),
|
||||
vid_mem_base + boot_tty_info.consorigin,
|
||||
sizeof(consolescreen));
|
||||
clear_screen();
|
||||
for(line = 0; line < LINES; line++) {
|
||||
int ch;
|
||||
for(ch = 0; ch < CHARS; ch++) {
|
||||
u16_t newch = consolescreen[line][ch] & BYTE;
|
||||
if(newch < ' ') newch = ' ';
|
||||
putch(newch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exec_image(char *image)
|
||||
/* Get a Minix image into core, patch it up and execute. */
|
||||
{
|
||||
int i;
|
||||
struct image_header hdr;
|
||||
char *buf;
|
||||
u32_t vsec, addr, limit, aout, n, totalmem = 0;
|
||||
struct process *procp; /* Process under construction. */
|
||||
long a_text, a_data, a_bss, a_stack;
|
||||
int banner= 0;
|
||||
long processor= a2l(b_value("processor"));
|
||||
u16_t kmagic, mode;
|
||||
char *console;
|
||||
char params[SECTOR_SIZE];
|
||||
extern char *sbrk(int);
|
||||
char *verb;
|
||||
|
||||
/* The stack is pretty deep here, so check if heap and stack collide. */
|
||||
(void) sbrk(0);
|
||||
|
||||
if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil)
|
||||
verboseboot = a2l(verb);
|
||||
|
||||
printf("\nLoading ");
|
||||
pretty_image(image);
|
||||
printf(".\n");
|
||||
|
||||
vsec= 0; /* Load this sector from image next. */
|
||||
addr= mem[0].base; /* Into this memory block. */
|
||||
limit= mem[0].base + mem[0].size;
|
||||
if (limit > caddr) limit= caddr;
|
||||
|
||||
/* Allocate and clear the area where the headers will be placed. */
|
||||
aout = (limit -= PROCESS_MAX * A_MINHDR);
|
||||
|
||||
/* Clear the area where the headers will be placed. */
|
||||
raw_clear(aout, PROCESS_MAX * A_MINHDR);
|
||||
|
||||
/* Read the many different processes: */
|
||||
for (i= 0; vsec < image_size; i++) {
|
||||
u32_t startaddr;
|
||||
startaddr = addr;
|
||||
if (i == PROCESS_MAX) {
|
||||
printf("There are more then %d programs in %s\n",
|
||||
PROCESS_MAX, image);
|
||||
errno= 0;
|
||||
return;
|
||||
}
|
||||
procp= &process[i];
|
||||
|
||||
/* Read header. */
|
||||
DEBUGEXTRA(("Reading header... "));
|
||||
for (;;) {
|
||||
if ((buf= get_sector(vsec++)) == nil) return;
|
||||
|
||||
memcpy(&hdr, buf, sizeof(hdr));
|
||||
|
||||
if (BADMAG(hdr.process)) { errno= ENOEXEC; return; }
|
||||
|
||||
/* Check the optional label on the process. */
|
||||
if (selected(hdr.name)) break;
|
||||
|
||||
/* Bad label, skip this process. */
|
||||
vsec+= proc_size(&hdr);
|
||||
}
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Sanity check: an 8086 can't run a 386 kernel. */
|
||||
if (hdr.process.a_cpu == A_I80386 && processor < 386) {
|
||||
printf("You can't run a 386 kernel on this 80%ld\n",
|
||||
processor);
|
||||
errno= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the click shift from the kernel text segment. */
|
||||
if (i == KERNEL_IDX) {
|
||||
if (!get_clickshift(vsec, &hdr)) return;
|
||||
addr= align(addr, click_size);
|
||||
|
||||
/* big kernels must be loaded into extended memory */
|
||||
if (k_flags & K_KHIGH) {
|
||||
addr= mem[1].base;
|
||||
limit= mem[1].base + mem[1].size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a copy of the header for the kernel, with a_syms
|
||||
* misused as the address where the process is loaded at.
|
||||
*/
|
||||
DEBUGEXTRA(("raw_copy(0x%x, 0x%lx, 0x%x)... ",
|
||||
aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR));
|
||||
hdr.process.a_syms= addr;
|
||||
raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
if (!banner) {
|
||||
DEBUGBASIC((" cs ds text data bss"));
|
||||
if (k_flags & K_CHMEM) DEBUGBASIC((" stack"));
|
||||
DEBUGBASIC(("\n"));
|
||||
banner= 1;
|
||||
}
|
||||
|
||||
/* Segment sizes. */
|
||||
DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n",
|
||||
hdr.process.a_text, hdr.process.a_data,
|
||||
hdr.process.a_bss, hdr.process.a_flags));
|
||||
|
||||
a_text= hdr.process.a_text;
|
||||
a_data= hdr.process.a_data;
|
||||
a_bss= hdr.process.a_bss;
|
||||
if (k_flags & K_CHMEM) {
|
||||
a_stack= hdr.process.a_total - a_data - a_bss;
|
||||
if (!(hdr.process.a_flags & A_SEP)) a_stack-= a_text;
|
||||
} else {
|
||||
a_stack= 0;
|
||||
}
|
||||
|
||||
/* Collect info about the process to be. */
|
||||
procp->cs= addr;
|
||||
|
||||
/* Process may be page aligned so that the text segment contains
|
||||
* the header, or have an unmapped zero page against vaxisms.
|
||||
*/
|
||||
procp->entry= hdr.process.a_entry;
|
||||
if (hdr.process.a_flags & A_PAL) a_text+= hdr.process.a_hdrlen;
|
||||
if (hdr.process.a_flags & A_UZP) procp->cs-= click_size;
|
||||
|
||||
/* Separate I&D: two segments. Common I&D: only one. */
|
||||
if (hdr.process.a_flags & A_SEP) {
|
||||
/* Read the text segment. */
|
||||
DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
|
||||
vsec, a_text, addr, limit));
|
||||
if (!get_segment(&vsec, &a_text, &addr, limit)) return;
|
||||
DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx "
|
||||
"addr=0x%lx\n",
|
||||
vsec, a_text, addr));
|
||||
|
||||
/* The data segment follows. */
|
||||
procp->ds= addr;
|
||||
if (hdr.process.a_flags & A_UZP) procp->ds-= click_size;
|
||||
procp->data= addr;
|
||||
} else {
|
||||
/* Add text to data to form one segment. */
|
||||
procp->data= addr + a_text;
|
||||
procp->ds= procp->cs;
|
||||
a_data+= a_text;
|
||||
}
|
||||
|
||||
/* Read the data segment. */
|
||||
DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
|
||||
vsec, a_data, addr, limit));
|
||||
if (!get_segment(&vsec, &a_data, &addr, limit)) return;
|
||||
DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx "
|
||||
"addr=0x%lx\n",
|
||||
vsec, a_data, addr));
|
||||
|
||||
/* Make space for bss and stack unless... */
|
||||
if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
|
||||
|
||||
DEBUGBASIC(("%07lx %07lx %8ld %8ld %8ld",
|
||||
procp->cs, procp->ds, hdr.process.a_text,
|
||||
hdr.process.a_data, hdr.process.a_bss));
|
||||
if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack));
|
||||
|
||||
/* Note that a_data may be negative now, but we can look at it
|
||||
* as -a_data bss bytes.
|
||||
*/
|
||||
|
||||
/* Compute the number of bss clicks left. */
|
||||
a_bss+= a_data;
|
||||
n= align(a_bss, click_size);
|
||||
a_bss-= n;
|
||||
|
||||
/* Zero out bss. */
|
||||
DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit));
|
||||
if (addr + n > limit) { errno= ENOMEM; return; }
|
||||
raw_clear(addr, n);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
addr+= n;
|
||||
|
||||
/* And the number of stack clicks. */
|
||||
a_stack+= a_bss;
|
||||
n= align(a_stack, click_size);
|
||||
a_stack-= n;
|
||||
|
||||
/* Add space for the stack. */
|
||||
addr+= n;
|
||||
|
||||
/* Process endpoint. */
|
||||
procp->end= addr;
|
||||
|
||||
if (verboseboot >= VERBOSEBOOT_BASIC)
|
||||
printf(" %s\n", hdr.name);
|
||||
else {
|
||||
u32_t mem;
|
||||
mem = addr-startaddr;
|
||||
printf("%s ", hdr.name);
|
||||
totalmem += mem;
|
||||
}
|
||||
|
||||
if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) {
|
||||
/* Load the rest in extended memory. */
|
||||
addr= mem[1].base;
|
||||
limit= mem[1].base + mem[1].size;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseboot < VERBOSEBOOT_BASIC)
|
||||
printf("(%dk)\n", totalmem/1024);
|
||||
|
||||
if ((n_procs= i) == 0) {
|
||||
printf("There are no programs in %s\n", image);
|
||||
errno= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check the kernel magic number. */
|
||||
raw_copy(mon2abs(&kmagic),
|
||||
process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic));
|
||||
if (kmagic != KERNEL_D_MAGIC) {
|
||||
printf("Kernel magic number is incorrect (0x%x@0x%lx)\n",
|
||||
kmagic, process[KERNEL_IDX].data + MAGIC_OFF);
|
||||
errno= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Patch sizes, etc. into kernel data. */
|
||||
DEBUGEXTRA(("patch_sizes()... "));
|
||||
patch_sizes();
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
#if !DOS
|
||||
if (!(k_flags & K_MEML)) {
|
||||
/* Copy the a.out headers to the old place. */
|
||||
raw_copy(HEADERPOS, aout, PROCESS_MAX * A_MINHDR);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Run the trailer function just before starting Minix. */
|
||||
DEBUGEXTRA(("run_trailer()... "));
|
||||
if (!run_trailer()) { errno= 0; return; }
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Translate the boot parameters to what Minix likes best. */
|
||||
DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params)));
|
||||
if (!params2params(params, sizeof(params))) { errno= 0; return; }
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Set the video to the required mode. */
|
||||
if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) {
|
||||
mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE :
|
||||
MONO_MODE;
|
||||
}
|
||||
DEBUGEXTRA(("set_mode(%d)... ", mode));
|
||||
set_mode(mode);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Close the disk. */
|
||||
DEBUGEXTRA(("dev_close()... "));
|
||||
(void) dev_close();
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Minix. */
|
||||
DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n",
|
||||
process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
|
||||
process[KERNEL_IDX].ds, params, sizeof(params), aout));
|
||||
minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
|
||||
process[KERNEL_IDX].ds, params, sizeof(params), aout);
|
||||
|
||||
if (!(k_flags & K_BRET)) {
|
||||
extern u32_t reboot_code;
|
||||
raw_copy(mon2abs(params), reboot_code, sizeof(params));
|
||||
}
|
||||
parse_code(params);
|
||||
|
||||
/* Return from Minix. Things may have changed, so assume nothing. */
|
||||
fsok= -1;
|
||||
errno= 0;
|
||||
|
||||
/* Read leftover character, if any. */
|
||||
scan_keyboard();
|
||||
|
||||
/* Restore screen contents. */
|
||||
restore_screen();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ino_t latest_version(char *version, struct stat *stp)
|
||||
/* Recursively read the current directory, selecting the newest image on
|
||||
* the way up. (One can't use r_stat while reading a directory.)
|
||||
*/
|
||||
{
|
||||
char name[NAME_MAX + 1];
|
||||
ino_t ino, newest;
|
||||
time_t mtime;
|
||||
|
||||
if ((ino= r_readdir(name)) == 0) { stp->st_mtime= 0; return 0; }
|
||||
|
||||
newest= latest_version(version, stp);
|
||||
mtime= stp->st_mtime;
|
||||
r_stat(ino, stp);
|
||||
|
||||
if (S_ISREG(stp->st_mode) && stp->st_mtime > mtime) {
|
||||
newest= ino;
|
||||
strcpy(version, name);
|
||||
} else {
|
||||
stp->st_mtime= mtime;
|
||||
}
|
||||
return newest;
|
||||
}
|
||||
|
||||
char *select_image(char *image)
|
||||
/* Look image up on the filesystem, if it is a file then we're done, but
|
||||
* if its a directory then we want the newest file in that directory. If
|
||||
* it doesn't exist at all, then see if it is 'number:number' and get the
|
||||
* image from that absolute offset off the disk.
|
||||
*/
|
||||
{
|
||||
ino_t image_ino;
|
||||
struct stat st;
|
||||
|
||||
image= strcpy(malloc((strlen(image) + 1 + NAME_MAX + 1)
|
||||
* sizeof(char)), image);
|
||||
|
||||
fsok= r_super(&block_size) != 0;
|
||||
if (!fsok || (image_ino= r_lookup(ROOT_INO, image)) == 0) {
|
||||
char *size;
|
||||
|
||||
if (numprefix(image, &size) && *size++ == ':'
|
||||
&& numeric(size)) {
|
||||
vir2sec= flat_vir2sec;
|
||||
image_off= a2l(image);
|
||||
image_size= a2l(size);
|
||||
strcpy(image, "Minix");
|
||||
return image;
|
||||
}
|
||||
if (!fsok)
|
||||
printf("No image selected\n");
|
||||
else
|
||||
printf("Can't load %s: %s\n", image, unix_err(errno));
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
r_stat(image_ino, &st);
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
char *version= image + strlen(image);
|
||||
char dots[NAME_MAX + 1];
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
printf("%s: %s\n", image, unix_err(ENOTDIR));
|
||||
goto bail_out;
|
||||
}
|
||||
(void) r_readdir(dots);
|
||||
(void) r_readdir(dots); /* "." & ".." */
|
||||
*version++= '/';
|
||||
*version= 0;
|
||||
if ((image_ino= latest_version(version, &st)) == 0) {
|
||||
printf("There are no images in %s\n", image);
|
||||
goto bail_out;
|
||||
}
|
||||
r_stat(image_ino, &st);
|
||||
}
|
||||
vir2sec= file_vir2sec;
|
||||
image_size= (st.st_size + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
|
||||
return image;
|
||||
bail_out:
|
||||
free(image);
|
||||
return nil;
|
||||
}
|
||||
|
||||
void bootminix(void)
|
||||
/* Load Minix and run it. (Given the size of this program it is surprising
|
||||
* that it ever gets to that.)
|
||||
*/
|
||||
{
|
||||
char *image;
|
||||
|
||||
if ((image= select_image(b_value("image"))) == nil) return;
|
||||
|
||||
if(serial_line >= 0) {
|
||||
char linename[2];
|
||||
linename[0] = serial_line + '0';
|
||||
linename[1] = '\0';
|
||||
b_setvar(E_VAR, SERVARNAME, linename);
|
||||
}
|
||||
|
||||
exec_image(image);
|
||||
|
||||
switch (errno) {
|
||||
case ENOEXEC:
|
||||
printf("%s contains a bad program header\n", image);
|
||||
break;
|
||||
case ENOMEM:
|
||||
printf("Not enough memory to load %s\n", image);
|
||||
break;
|
||||
case EIO:
|
||||
printf("Unsuspected EOF on %s\n", image);
|
||||
case 0:
|
||||
/* No error or error already reported. */;
|
||||
}
|
||||
free(image);
|
||||
|
||||
if(serial_line >= 0)
|
||||
b_unset(SERVARNAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: bootimage.c,v 1.10 2002/02/27 19:39:09 philip Exp $
|
||||
*/
|
||||
1380
boot/doshead.s
1380
boot/doshead.s
File diff suppressed because it is too large
Load Diff
13
boot/image.h
13
boot/image.h
@@ -1,13 +0,0 @@
|
||||
/* image.h - Info between installboot and boot. Author: Kees J. Bot
|
||||
*/
|
||||
|
||||
#define IM_NAME_MAX 63
|
||||
|
||||
struct image_header {
|
||||
char name[IM_NAME_MAX + 1]; /* Null terminated. */
|
||||
struct exec process;
|
||||
};
|
||||
|
||||
/*
|
||||
* $PchId: image.h,v 1.4 1995/11/27 22:23:12 philip Exp $
|
||||
*/
|
||||
@@ -1,832 +0,0 @@
|
||||
/* installboot 3.0 - Make a device bootable Author: Kees J. Bot
|
||||
* 21 Dec 1991
|
||||
*
|
||||
* Either make a device bootable or make an image from kernel, mm, fs, etc.
|
||||
*/
|
||||
#define _POSIX_SOURCE 1
|
||||
#define _MINIX 1
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <a.out.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/partition.h>
|
||||
#include <minix/u64.h>
|
||||
#include "rawfs.h"
|
||||
#include "image.h"
|
||||
|
||||
#define BOOTBLOCK 0 /* Of course */
|
||||
#define SECTOR_SIZE 512 /* Disk sector size. */
|
||||
#define RATIO(b) ((b)/SECTOR_SIZE)
|
||||
#define SIGNATURE 0xAA55 /* Boot block signature. */
|
||||
#define BOOT_MAX 64 /* Absolute maximum size of secondary boot */
|
||||
#define SIGPOS 510 /* Where to put signature word. */
|
||||
#define PARTPOS 446 /* Offset to the partition table in a master
|
||||
* boot block.
|
||||
*/
|
||||
|
||||
#define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
|
||||
#define control(c) between('\0', (c), '\37')
|
||||
|
||||
#define BOOT_BLOCK_SIZE 1024
|
||||
|
||||
static void report(const char *label)
|
||||
/* installboot: label: No such file or directory */
|
||||
{
|
||||
fprintf(stderr, "installboot: %s: %s\n", label, strerror(errno));
|
||||
}
|
||||
|
||||
static void fatal(const char *label)
|
||||
{
|
||||
report(label);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *basename(char *name)
|
||||
/* Return the last component of name, stripping trailing slashes from name.
|
||||
* Precondition: name != "/". If name is prefixed by a label, then the
|
||||
* label is copied to the basename too.
|
||||
*/
|
||||
{
|
||||
static char base[IM_NAME_MAX];
|
||||
char *p, *bp= base;
|
||||
|
||||
if ((p= strchr(name, ':')) != NULL) {
|
||||
while (name <= p && bp < base + IM_NAME_MAX - 1)
|
||||
*bp++ = *name++;
|
||||
}
|
||||
for (;;) {
|
||||
if ((p= strrchr(name, '/')) == NULL) { p= name; break; }
|
||||
if (*++p != 0) break;
|
||||
*--p= 0;
|
||||
}
|
||||
while (*p != 0 && bp < base + IM_NAME_MAX - 1) *bp++ = *p++;
|
||||
*bp= 0;
|
||||
return base;
|
||||
}
|
||||
|
||||
static void bread(FILE *f, char *name, void *buf, size_t len)
|
||||
/* Read len bytes. Don't dare return without them. */
|
||||
{
|
||||
if (len > 0 && fread(buf, len, 1, f) != 1) {
|
||||
if (ferror(f)) fatal(name);
|
||||
fprintf(stderr, "installboot: Unexpected EOF on %s\n", name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void bwrite(FILE *f, const char *name, const void *buf, size_t len)
|
||||
{
|
||||
if (len > 0 && fwrite(buf, len, 1, f) != 1) fatal(name);
|
||||
}
|
||||
|
||||
long total_text= 0, total_data= 0, total_bss= 0;
|
||||
int making_image= 0;
|
||||
|
||||
void read_header(int talk, char *proc, FILE *procf, struct image_header *ihdr)
|
||||
/* Read the a.out header of a program and check it. If procf happens to be
|
||||
* NULL then the header is already in *image_hdr and need only be checked.
|
||||
*/
|
||||
{
|
||||
int n, big= 0;
|
||||
static int banner= 0;
|
||||
struct exec *phdr= &ihdr->process;
|
||||
|
||||
if (procf == NULL) {
|
||||
/* Header already present. */
|
||||
n= phdr->a_hdrlen;
|
||||
} else {
|
||||
memset(ihdr, 0, sizeof(*ihdr));
|
||||
|
||||
/* Put the basename of proc in the header. */
|
||||
strncpy(ihdr->name, basename(proc), IM_NAME_MAX);
|
||||
|
||||
/* Read the header. */
|
||||
n= fread(phdr, sizeof(char), A_MINHDR, procf);
|
||||
if (ferror(procf)) fatal(proc);
|
||||
}
|
||||
|
||||
if (n < A_MINHDR || BADMAG(*phdr)) {
|
||||
fprintf(stderr, "installboot: %s is not an executable\n", proc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get the rest of the exec header. */
|
||||
if (procf != NULL) {
|
||||
bread(procf, proc, ((char *) phdr) + A_MINHDR,
|
||||
phdr->a_hdrlen - A_MINHDR);
|
||||
}
|
||||
|
||||
if (talk && !banner) {
|
||||
printf(" text data bss size\n");
|
||||
banner= 1;
|
||||
}
|
||||
|
||||
if (talk) {
|
||||
printf(" %8ld %8ld %8ld %9ld %s\n",
|
||||
phdr->a_text, phdr->a_data, phdr->a_bss,
|
||||
phdr->a_text + phdr->a_data + phdr->a_bss, proc);
|
||||
}
|
||||
total_text+= phdr->a_text;
|
||||
total_data+= phdr->a_data;
|
||||
total_bss+= phdr->a_bss;
|
||||
|
||||
if (phdr->a_cpu == A_I8086) {
|
||||
long data= phdr->a_data + phdr->a_bss;
|
||||
|
||||
if (!(phdr->a_flags & A_SEP)) data+= phdr->a_text;
|
||||
|
||||
if (phdr->a_text >= 65536) big|= 1;
|
||||
if (data >= 65536) big|= 2;
|
||||
}
|
||||
if (big) {
|
||||
fprintf(stderr,
|
||||
"%s will crash, %s%s%s segment%s larger then 64K\n",
|
||||
proc,
|
||||
big & 1 ? "text" : "",
|
||||
big == 3 ? " and " : "",
|
||||
big & 2 ? "data" : "",
|
||||
big == 3 ? "s are" : " is");
|
||||
}
|
||||
}
|
||||
|
||||
void padimage(const char *image, FILE *imagef, int n)
|
||||
/* Add n zeros to image to pad it to a sector boundary. */
|
||||
{
|
||||
while (n > 0) {
|
||||
if (putc(0, imagef) == EOF) fatal(image);
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
#define align(n) (((n) + ((SECTOR_SIZE) - 1)) & ~((SECTOR_SIZE) - 1))
|
||||
|
||||
void copyexec(char *proc, FILE *procf, char *image, FILE *imagef, long n)
|
||||
/* Copy n bytes from proc to image padded to fill a sector. */
|
||||
{
|
||||
int pad, c;
|
||||
|
||||
/* Compute number of padding bytes. */
|
||||
pad= align(n) - n;
|
||||
|
||||
while (n > 0) {
|
||||
if ((c= getc(procf)) == EOF) {
|
||||
if (ferror(procf)) fatal(proc);
|
||||
fprintf(stderr, "installboot: premature EOF on %s\n",
|
||||
proc);
|
||||
exit(1);
|
||||
}
|
||||
if (putc(c, imagef) == EOF) fatal(image);
|
||||
n--;
|
||||
}
|
||||
padimage(image, imagef, pad);
|
||||
}
|
||||
|
||||
void make_image(char *image, char **procv)
|
||||
/* Collect a set of files in an image, each "segment" is nicely padded out
|
||||
* to SECTOR_SIZE, so it may be read from disk into memory without trickery.
|
||||
*/
|
||||
{
|
||||
FILE *imagef, *procf;
|
||||
char *proc, *file;
|
||||
int procn;
|
||||
struct image_header ihdr;
|
||||
struct exec phdr;
|
||||
struct stat st;
|
||||
|
||||
making_image= 1;
|
||||
|
||||
if ((imagef= fopen(image, "w")) == NULL) fatal(image);
|
||||
|
||||
for (procn= 0; (proc= *procv++) != NULL; procn++) {
|
||||
/* Remove the label from the file name. */
|
||||
if ((file= strchr(proc, ':')) != NULL) file++; else file= proc;
|
||||
|
||||
/* Real files please, may need to seek. */
|
||||
if (stat(file, &st) < 0
|
||||
|| (errno= EISDIR, !S_ISREG(st.st_mode))
|
||||
|| (procf= fopen(file, "r")) == NULL
|
||||
) fatal(proc);
|
||||
|
||||
/* Read a.out header. */
|
||||
read_header(1, proc, procf, &ihdr);
|
||||
|
||||
/* Scratch. */
|
||||
phdr= ihdr.process;
|
||||
|
||||
/* The symbol table is always stripped off. */
|
||||
ihdr.process.a_syms= 0;
|
||||
ihdr.process.a_flags &= ~A_NSYM;
|
||||
|
||||
/* Write header padded to fill a sector */
|
||||
bwrite(imagef, image, &ihdr, sizeof(ihdr));
|
||||
|
||||
padimage(image, imagef, SECTOR_SIZE - sizeof(ihdr));
|
||||
|
||||
/* A page aligned executable needs the header in text. */
|
||||
if (phdr.a_flags & A_PAL) {
|
||||
rewind(procf);
|
||||
phdr.a_text+= phdr.a_hdrlen;
|
||||
}
|
||||
|
||||
/* Copy text and data of proc to image. */
|
||||
if (phdr.a_flags & A_SEP) {
|
||||
/* Separate I&D: pad text & data separately. */
|
||||
|
||||
copyexec(proc, procf, image, imagef, phdr.a_text);
|
||||
copyexec(proc, procf, image, imagef, phdr.a_data);
|
||||
} else {
|
||||
/* Common I&D: keep text and data together. */
|
||||
|
||||
copyexec(proc, procf, image, imagef,
|
||||
phdr.a_text + phdr.a_data);
|
||||
}
|
||||
|
||||
/* Done with proc. */
|
||||
(void) fclose(procf);
|
||||
}
|
||||
/* Done with image. */
|
||||
|
||||
if (fclose(imagef) == EOF) fatal(image);
|
||||
|
||||
printf(" ------ ------ ------ -------\n");
|
||||
printf(" %8ld %8ld %8ld %9ld total\n",
|
||||
total_text, total_data, total_bss,
|
||||
total_text + total_data + total_bss);
|
||||
}
|
||||
|
||||
void extractexec(FILE *imagef, char *image, FILE *procf, char *proc,
|
||||
long count, off_t *alen)
|
||||
/* Copy a segment of an executable. It is padded to a sector in image. */
|
||||
{
|
||||
char buf[SECTOR_SIZE];
|
||||
|
||||
while (count > 0) {
|
||||
bread(imagef, image, buf, sizeof(buf));
|
||||
*alen-= sizeof(buf);
|
||||
|
||||
bwrite(procf, proc, buf,
|
||||
count < sizeof(buf) ? (size_t) count : sizeof(buf));
|
||||
count-= sizeof(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void extract_image(char *image)
|
||||
/* Extract the executables from an image. */
|
||||
{
|
||||
FILE *imagef, *procf;
|
||||
off_t len;
|
||||
struct stat st;
|
||||
struct image_header ihdr;
|
||||
struct exec phdr;
|
||||
char buf[SECTOR_SIZE];
|
||||
|
||||
if (stat(image, &st) < 0) fatal(image);
|
||||
|
||||
/* Size of the image. */
|
||||
len= S_ISREG(st.st_mode) ? st.st_size : -1;
|
||||
|
||||
if ((imagef= fopen(image, "r")) == NULL) fatal(image);
|
||||
|
||||
while (len != 0) {
|
||||
/* Extract a program, first sector is an extended header. */
|
||||
bread(imagef, image, buf, sizeof(buf));
|
||||
len-= sizeof(buf);
|
||||
|
||||
memcpy(&ihdr, buf, sizeof(ihdr));
|
||||
phdr= ihdr.process;
|
||||
|
||||
/* Check header. */
|
||||
read_header(1, ihdr.name, NULL, &ihdr);
|
||||
|
||||
if ((procf= fopen(ihdr.name, "w")) == NULL) fatal(ihdr.name);
|
||||
|
||||
if (phdr.a_flags & A_PAL) {
|
||||
/* A page aligned process contains a header in text. */
|
||||
phdr.a_text+= phdr.a_hdrlen;
|
||||
} else {
|
||||
bwrite(procf, ihdr.name, &ihdr.process, phdr.a_hdrlen);
|
||||
}
|
||||
|
||||
/* Extract text and data segments. */
|
||||
if (phdr.a_flags & A_SEP) {
|
||||
extractexec(imagef, image, procf, ihdr.name,
|
||||
phdr.a_text, &len);
|
||||
extractexec(imagef, image, procf, ihdr.name,
|
||||
phdr.a_data, &len);
|
||||
} else {
|
||||
extractexec(imagef, image, procf, ihdr.name,
|
||||
phdr.a_text + phdr.a_data, &len);
|
||||
}
|
||||
|
||||
if (fclose(procf) == EOF) fatal(ihdr.name);
|
||||
}
|
||||
}
|
||||
|
||||
static int rawfd; /* File descriptor to open device. */
|
||||
static const char *rawdev; /* Name of device. */
|
||||
|
||||
void readblock(off_t blk, char *buf, int block_size)
|
||||
/* For rawfs, so that it can read blocks. */
|
||||
{
|
||||
int n;
|
||||
|
||||
if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
|
||||
|| (n= read(rawfd, buf, block_size)) < 0
|
||||
) fatal(rawdev);
|
||||
|
||||
if (n < block_size) {
|
||||
fprintf(stderr, "installboot: Unexpected EOF on %s\n", rawdev);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void writeblock(off_t blk, const char *buf, int block_size)
|
||||
/* Add a function to write blocks for local use. */
|
||||
{
|
||||
if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
|
||||
|| write(rawfd, buf, block_size) < 0
|
||||
) fatal(rawdev);
|
||||
}
|
||||
|
||||
int raw_install(char *file, off_t *start, off_t *len, int block_size)
|
||||
/* Copy bootcode or an image to the boot device at the given absolute disk
|
||||
* block number. This "raw" installation is used to place bootcode and
|
||||
* image on a disk without a filesystem to make a simple boot disk. Useful
|
||||
* in automated scripts for J. Random User.
|
||||
* Note: *len == 0 when an image is read. It is set right afterwards.
|
||||
*/
|
||||
{
|
||||
static char buf[_MAX_BLOCK_SIZE]; /* Nonvolatile block buffer. */
|
||||
FILE *f;
|
||||
off_t sec;
|
||||
unsigned long devsize;
|
||||
static int banner= 0;
|
||||
struct partition entry;
|
||||
|
||||
/* See if the device has a maximum size. */
|
||||
devsize= -1;
|
||||
if (ioctl(rawfd, DIOCGETP, &entry) == 0) devsize= cv64ul(entry.size);
|
||||
|
||||
if ((f= fopen(file, "r")) == NULL) fatal(file);
|
||||
|
||||
/* Copy sectors from file onto the boot device. */
|
||||
sec= *start;
|
||||
do {
|
||||
int off= sec % RATIO(BOOT_BLOCK_SIZE);
|
||||
|
||||
if (fread(buf + off * SECTOR_SIZE, 1, SECTOR_SIZE, f) == 0)
|
||||
break;
|
||||
|
||||
if (sec >= devsize) {
|
||||
fprintf(stderr,
|
||||
"installboot: %s can't be attached to %s\n",
|
||||
file, rawdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (off == RATIO(BOOT_BLOCK_SIZE) - 1) writeblock(sec / RATIO(BOOT_BLOCK_SIZE), buf, BOOT_BLOCK_SIZE);
|
||||
} while (++sec != *start + *len);
|
||||
|
||||
if (ferror(f)) fatal(file);
|
||||
(void) fclose(f);
|
||||
|
||||
/* Write a partial block, this may be the last image. */
|
||||
if (sec % RATIO(BOOT_BLOCK_SIZE) != 0) writeblock(sec / RATIO(BOOT_BLOCK_SIZE), buf, BOOT_BLOCK_SIZE);
|
||||
|
||||
if (!banner) {
|
||||
printf(" sector length\n");
|
||||
banner= 1;
|
||||
}
|
||||
*len= sec - *start;
|
||||
printf("%8ld%8ld %s\n", *start, *len, file);
|
||||
*start= sec;
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum howto { FS, BOOT };
|
||||
|
||||
void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
char *bootcode, char **imagev)
|
||||
/* Install bootblock on the bootsector of device with the disk addresses to
|
||||
* bootcode patched into the data segment of bootblock. "How" tells if there
|
||||
* should or shoudn't be a file system on the disk. The images in the imagev
|
||||
* vector are added to the end of the device.
|
||||
*/
|
||||
{
|
||||
char buf[_MAX_BLOCK_SIZE + 256], *adrp, *parmp;
|
||||
struct fileaddr {
|
||||
off_t address;
|
||||
int count;
|
||||
} bootaddr[BOOT_MAX + 1], *bap= bootaddr;
|
||||
struct exec boothdr;
|
||||
struct image_header dummy;
|
||||
struct stat st;
|
||||
ino_t ino;
|
||||
off_t sector, max_sector;
|
||||
FILE *bootf;
|
||||
off_t addr, fssize, pos, len;
|
||||
char *labels, *label, *image;
|
||||
int nolabel;
|
||||
int block_size = 0;
|
||||
|
||||
/* Open device and set variables for readblock. */
|
||||
if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
|
||||
|
||||
/* Read and check the superblock. */
|
||||
fssize= r_super(&block_size);
|
||||
|
||||
switch (how) {
|
||||
case FS:
|
||||
if (fssize == 0) {
|
||||
fprintf(stderr,
|
||||
"installboot: %s is not a Minix file system\n",
|
||||
device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case BOOT:
|
||||
if (fssize != 0) {
|
||||
int s;
|
||||
printf("%s contains a file system!\n", device);
|
||||
printf("Scribbling in 10 seconds");
|
||||
for (s= 0; s < 10; s++) {
|
||||
fputc('.', stdout);
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
fssize= 1; /* Just a boot block. */
|
||||
}
|
||||
|
||||
if (how == FS) {
|
||||
/* See if the boot code can be found on the file system. */
|
||||
if ((ino= r_lookup(ROOT_INO, bootcode)) == 0) {
|
||||
if (errno != ENOENT) fatal(bootcode);
|
||||
}
|
||||
} else {
|
||||
/* Boot code must be attached at the end. */
|
||||
ino= 0;
|
||||
}
|
||||
|
||||
if (ino == 0) {
|
||||
/* For a raw installation, we need to copy the boot code onto
|
||||
* the device, so we need to look at the file to be copied.
|
||||
*/
|
||||
if (stat(bootcode, &st) < 0) fatal(bootcode);
|
||||
|
||||
if ((bootf= fopen(bootcode, "r")) == NULL) fatal(bootcode);
|
||||
} else {
|
||||
/* Boot code is present in the file system. */
|
||||
r_stat(ino, &st);
|
||||
|
||||
/* Get the header from the first block. */
|
||||
if ((addr= r_vir2abs((off_t) 0)) == 0) {
|
||||
boothdr.a_magic[0]= !A_MAGIC0;
|
||||
} else {
|
||||
readblock(addr, buf, block_size);
|
||||
memcpy(&boothdr, buf, sizeof(struct exec));
|
||||
}
|
||||
bootf= NULL;
|
||||
dummy.process= boothdr;
|
||||
}
|
||||
/* See if it is an executable (read_header does the check). */
|
||||
read_header(0, bootcode, bootf, &dummy);
|
||||
boothdr= dummy.process;
|
||||
|
||||
if (bootf != NULL) fclose(bootf);
|
||||
|
||||
/* Get all the sector addresses of the secondary boot code. */
|
||||
max_sector= (boothdr.a_hdrlen + boothdr.a_text
|
||||
+ boothdr.a_data + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||
|
||||
if (max_sector > BOOT_MAX * RATIO(block_size)) {
|
||||
fprintf(stderr, "installboot: %s is way too big\n", bootcode);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Determine the addresses to the boot code to be patched into the
|
||||
* boot block.
|
||||
*/
|
||||
bap->count= 0; /* Trick to get the address recording going. */
|
||||
|
||||
for (sector= 0; sector < max_sector; sector++) {
|
||||
if (ino == 0) {
|
||||
addr= fssize + (sector / RATIO(block_size));
|
||||
} else
|
||||
if ((addr= r_vir2abs(sector / RATIO(block_size))) == 0) {
|
||||
fprintf(stderr, "installboot: %s has holes!\n",
|
||||
bootcode);
|
||||
exit(1);
|
||||
}
|
||||
addr= (addr * RATIO(block_size)) + (sector % RATIO(block_size));
|
||||
|
||||
/* First address of the addresses array? */
|
||||
if (bap->count == 0) bap->address= addr;
|
||||
|
||||
/* Paste sectors together in a multisector read. */
|
||||
if (bap->address + bap->count == addr)
|
||||
bap->count++;
|
||||
else {
|
||||
/* New address. */
|
||||
bap++;
|
||||
bap->address= addr;
|
||||
bap->count= 1;
|
||||
}
|
||||
}
|
||||
(++bap)->count= 0; /* No more. */
|
||||
|
||||
/* Get the boot block and patch the pieces in. */
|
||||
readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
|
||||
|
||||
if ((bootf= fopen(bootblock, "r")) == NULL) fatal(bootblock);
|
||||
|
||||
read_header(0, bootblock, bootf, &dummy);
|
||||
boothdr= dummy.process;
|
||||
|
||||
if (boothdr.a_text + boothdr.a_data +
|
||||
4 * (bap - bootaddr) + 1 > PARTPOS) {
|
||||
fprintf(stderr,
|
||||
"installboot: %s + addresses to %s don't fit in the boot sector\n",
|
||||
bootblock, bootcode);
|
||||
fprintf(stderr,
|
||||
"You can try copying/reinstalling %s to defragment it\n",
|
||||
bootcode);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* All checks out right. Read bootblock into the boot block! */
|
||||
bread(bootf, bootblock, buf, boothdr.a_text + boothdr.a_data);
|
||||
(void) fclose(bootf);
|
||||
|
||||
/* Patch the addresses in. */
|
||||
adrp= buf + (int) (boothdr.a_text + boothdr.a_data);
|
||||
for (bap= bootaddr; bap->count != 0; bap++) {
|
||||
*adrp++= bap->count;
|
||||
*adrp++= (bap->address >> 0) & 0xFF;
|
||||
*adrp++= (bap->address >> 8) & 0xFF;
|
||||
*adrp++= (bap->address >> 16) & 0xFF;
|
||||
}
|
||||
/* Zero count stops bootblock's reading loop. */
|
||||
*adrp++= 0;
|
||||
|
||||
if (bap > bootaddr+1) {
|
||||
printf("%s and %d addresses to %s patched into %s\n",
|
||||
bootblock, (int)(bap - bootaddr), bootcode, device);
|
||||
}
|
||||
|
||||
/* Boot block signature. */
|
||||
buf[SIGPOS+0]= (SIGNATURE >> 0) & 0xFF;
|
||||
buf[SIGPOS+1]= (SIGNATURE >> 8) & 0xFF;
|
||||
|
||||
/* Sector 2 of the boot block is used for boot parameters, initially
|
||||
* filled with null commands (newlines). Initialize it only if
|
||||
* necessary.
|
||||
*/
|
||||
for (parmp= buf + SECTOR_SIZE; parmp < buf + 2*SECTOR_SIZE; parmp++) {
|
||||
if (*imagev != NULL || (control(*parmp) && *parmp != '\n')) {
|
||||
/* Param sector must be initialized. */
|
||||
memset(buf + SECTOR_SIZE, '\n', SECTOR_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Offset to the end of the file system to add boot code and images. */
|
||||
pos= fssize * RATIO(block_size);
|
||||
|
||||
if (ino == 0) {
|
||||
/* Place the boot code onto the boot device. */
|
||||
len= max_sector;
|
||||
if (!raw_install(bootcode, &pos, &len, block_size)) {
|
||||
if (how == FS) {
|
||||
fprintf(stderr,
|
||||
"\t(Isn't there a copy of %s on %s that can be used?)\n",
|
||||
bootcode, device);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
parmp= buf + SECTOR_SIZE;
|
||||
nolabel= 0;
|
||||
|
||||
if (how == BOOT) {
|
||||
/* A boot only disk needs to have floppies swapped. */
|
||||
strcpy(parmp,
|
||||
"trailer()echo \\nInsert the root diskette then hit RETURN\\n\\w\\c\n");
|
||||
parmp+= strlen(parmp);
|
||||
}
|
||||
|
||||
while ((labels= *imagev++) != NULL) {
|
||||
/* Place each kernel image on the boot device. */
|
||||
|
||||
if ((image= strchr(labels, ':')) != NULL)
|
||||
*image++= 0;
|
||||
else {
|
||||
if (nolabel) {
|
||||
fprintf(stderr,
|
||||
"installboot: Only one image can be the default\n");
|
||||
exit(1);
|
||||
}
|
||||
nolabel= 1;
|
||||
image= labels;
|
||||
labels= NULL;
|
||||
}
|
||||
len= 0;
|
||||
if (!raw_install(image, &pos, &len, block_size)) exit(1);
|
||||
|
||||
if (labels == NULL) {
|
||||
/* Let this image be the default. */
|
||||
sprintf(parmp, "image=%ld:%ld\n", pos-len, len);
|
||||
parmp+= strlen(parmp);
|
||||
}
|
||||
|
||||
while (labels != NULL) {
|
||||
/* Image is prefixed by a comma separated list of
|
||||
* labels. Define functions to select label and image.
|
||||
*/
|
||||
label= labels;
|
||||
if ((labels= strchr(labels, ',')) != NULL) *labels++ = 0;
|
||||
|
||||
sprintf(parmp,
|
||||
"%s(%c){label=%s;image=%ld:%ld;echo %s kernel selected;menu}\n",
|
||||
label,
|
||||
between('A', label[0], 'Z')
|
||||
? label[0]-'A'+'a' : label[0],
|
||||
label, pos-len, len, label);
|
||||
parmp+= strlen(parmp);
|
||||
}
|
||||
|
||||
if (parmp > buf + block_size) {
|
||||
fprintf(stderr,
|
||||
"installboot: Out of parameter space, too many images\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* Install boot block. */
|
||||
writeblock((off_t) BOOTBLOCK, buf, 1024);
|
||||
|
||||
if (pos > fssize * RATIO(block_size)) {
|
||||
/* Tell the total size of the data on the device. */
|
||||
printf("%16ld (%ld kb) total\n", pos,
|
||||
(pos + RATIO(block_size) - 1) / RATIO(block_size));
|
||||
}
|
||||
}
|
||||
|
||||
static void install_master(const char *device, char *masterboot, char **guide)
|
||||
/* Booting a hard disk is a two stage process: The master bootstrap in sector
|
||||
* 0 loads the bootstrap from sector 0 of the active partition which in turn
|
||||
* starts the operating system. This code installs such a master bootstrap
|
||||
* on a hard disk. If guide[0] is non-null then the master bootstrap is
|
||||
* guided into booting a certain device.
|
||||
*/
|
||||
{
|
||||
FILE *masf;
|
||||
unsigned long size;
|
||||
struct stat st;
|
||||
static char buf[_MAX_BLOCK_SIZE];
|
||||
|
||||
/* Open device. */
|
||||
if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
|
||||
|
||||
/* Open the master boot code. */
|
||||
if ((masf= fopen(masterboot, "r")) == NULL) fatal(masterboot);
|
||||
|
||||
/* See if the user is cloning a device. */
|
||||
if (fstat(fileno(masf), &st) >=0 && S_ISBLK(st.st_mode))
|
||||
size= PARTPOS;
|
||||
else {
|
||||
/* Read and check header otherwise. */
|
||||
struct image_header ihdr;
|
||||
|
||||
read_header(1, masterboot, masf, &ihdr);
|
||||
size= ihdr.process.a_text + ihdr.process.a_data;
|
||||
}
|
||||
if (size > PARTPOS) {
|
||||
fprintf(stderr, "installboot: %s is too big\n", masterboot);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Read the master boot block, patch it, write. */
|
||||
readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
|
||||
|
||||
memset(buf, 0, PARTPOS);
|
||||
(void) bread(masf, masterboot, buf, size);
|
||||
|
||||
if (guide[0] != NULL) {
|
||||
/* Fixate partition to boot. */
|
||||
const char *keys= guide[0];
|
||||
const char *logical= guide[1];
|
||||
size_t i;
|
||||
int logfd;
|
||||
u32_t offset;
|
||||
struct partition geometry;
|
||||
|
||||
/* A string of digits to be seen as keystrokes. */
|
||||
i= 0;
|
||||
do {
|
||||
if (!between('0', keys[i], '9')) {
|
||||
fprintf(stderr,
|
||||
"installboot: bad guide keys '%s'\n",
|
||||
keys);
|
||||
exit(1);
|
||||
}
|
||||
} while (keys[++i] != 0);
|
||||
|
||||
if (size + i + 1 > PARTPOS) {
|
||||
fprintf(stderr,
|
||||
"installboot: not enough space after '%s' for '%s'\n",
|
||||
masterboot, keys);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(buf + size, keys, i);
|
||||
size += i;
|
||||
buf[size]= '\r';
|
||||
|
||||
if (logical != NULL) {
|
||||
if ((logfd= open(logical, O_RDONLY)) < 0
|
||||
|| ioctl(logfd, DIOCGETP, &geometry) < 0
|
||||
) {
|
||||
fatal(logical);
|
||||
}
|
||||
offset= div64u(geometry.base, SECTOR_SIZE);
|
||||
if (size + 5 > PARTPOS) {
|
||||
fprintf(stderr,
|
||||
"installboot: not enough space "
|
||||
"after '%s' for '%s' and an offset "
|
||||
"to '%s'\n",
|
||||
masterboot, keys, logical);
|
||||
exit(1);
|
||||
}
|
||||
buf[size]= '#';
|
||||
memcpy(buf+size+1, &offset, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Install signature. */
|
||||
buf[SIGPOS+0]= (SIGNATURE >> 0) & 0xFF;
|
||||
buf[SIGPOS+1]= (SIGNATURE >> 8) & 0xFF;
|
||||
|
||||
writeblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: installboot -i(mage) image kernel mm fs ... init\n"
|
||||
" installboot -(e)x(tract) image\n"
|
||||
" installboot -d(evice) device bootblock boot [image ...]\n"
|
||||
" installboot -b(oot) device bootblock boot image ...\n"
|
||||
" installboot -m(aster) device masterboot [keys [logical]]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int isoption(const char *option, const char *test)
|
||||
/* Check if the option argument is equals "test". Also accept -i as short
|
||||
* for -image, and the special case -x for -extract.
|
||||
*/
|
||||
{
|
||||
if (strcmp(option, test) == 0) return 1;
|
||||
if (option[0] != '-' && strlen(option) != 2) return 0;
|
||||
if (option[1] == test[1]) return 1;
|
||||
if (option[1] == 'x' && test[1] == 'e') return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) usage();
|
||||
|
||||
if (argc >= 4 && isoption(argv[1], "-image")) {
|
||||
make_image(argv[2], argv + 3);
|
||||
} else
|
||||
if (argc == 3 && isoption(argv[1], "-extract")) {
|
||||
extract_image(argv[2]);
|
||||
} else
|
||||
if (argc >= 5 && isoption(argv[1], "-device")) {
|
||||
make_bootable(FS, argv[2], argv[3], argv[4], argv + 5);
|
||||
} else
|
||||
if (argc >= 6 && isoption(argv[1], "-boot")) {
|
||||
make_bootable(BOOT, argv[2], argv[3], argv[4], argv + 5);
|
||||
} else
|
||||
if ((4 <= argc && argc <= 6) && isoption(argv[1], "-master")) {
|
||||
install_master(argv[2], argv[3], argv + 4);
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: installboot.c,v 1.10 2000/08/13 22:07:50 philip Exp $
|
||||
*/
|
||||
261
boot/jumpboot.s
261
boot/jumpboot.s
@@ -1,261 +0,0 @@
|
||||
! jumpboot 1.0 - Jump to another bootstrap Author: Kees J. Bot
|
||||
! 14 Apr 1999
|
||||
!
|
||||
! This code may be placed into any free boot sector, like the first sector
|
||||
! of an extended partition, a file system partition other than the root,
|
||||
! or even the master bootstrap. It will load and run another bootstrap whose
|
||||
! disk, partition, and slice number (not necessarily all three) are patched
|
||||
! into this code by installboot. If the ALT key is held down when this code
|
||||
! is booted then you can type the disk, partition, and slice numbers manually.
|
||||
! The manual interface is default if no numbers are patched in by installboot.
|
||||
!
|
||||
|
||||
o32 = 0x66 ! This assembler doesn't know 386 extensions
|
||||
LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
|
||||
BUFFER = 0x0600 ! First free memory
|
||||
PART_TABLE = 446 ! Location of partition table within master
|
||||
PENTRYSIZE = 16 ! Size of one partition table entry
|
||||
MAGIC = 510 ! Location of the AA55 magic number
|
||||
|
||||
! <ibm/partition.h>:
|
||||
MINIX_PART = 0x81
|
||||
sysind = 4
|
||||
lowsec = 8
|
||||
|
||||
|
||||
.text
|
||||
|
||||
! Find and load another bootstrap and jump to it.
|
||||
jumpboot:
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
cli
|
||||
mov ss, ax ! ds = es = ss = Vector segment
|
||||
mov sp, #LOADOFF
|
||||
sti
|
||||
|
||||
! Move this code to safety, then jump to it.
|
||||
mov si, sp ! si = start of this code
|
||||
mov di, #BUFFER ! di = Buffer area
|
||||
mov cx, #512/2 ! One sector
|
||||
cld
|
||||
rep movs
|
||||
jmpf BUFFER+migrate, 0 ! To safety
|
||||
migrate:
|
||||
|
||||
mov bp, #BUFFER+guide ! Patched guiding characters
|
||||
altkey:
|
||||
movb ah, #0x02 ! Keyboard shift status
|
||||
int 0x16
|
||||
testb al, #0x08 ! Bit 3 = ALT key
|
||||
jz noalt ! ALT key pressed?
|
||||
again:
|
||||
mov bp, #zero ! Ignore patched stuff
|
||||
noalt:
|
||||
|
||||
! Follow guide characters to find the boot partition.
|
||||
call print
|
||||
.ascii "d?\b\0" ! Initial greeting
|
||||
|
||||
! Disk number?
|
||||
disk:
|
||||
movb dl, #0x80 - 0x30 ! Prepare to add an ASCII digit
|
||||
call getch ! Get number to tell which disk
|
||||
addb dl, al ! dl = 0x80 + (al - '0')
|
||||
jns n0nboot ! Result should be >= 0x80
|
||||
mov si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
|
||||
cmpb (bp), #0x23 ! Next guide character is '#'?
|
||||
jne notlogical
|
||||
lea si, 1-lowsec(bp) ! Logical sector offset follows '#'
|
||||
notlogical:
|
||||
call load ! Load chosen sector of chosen disk
|
||||
cmpb (bp), #0x23
|
||||
je boot ! Run bootstrap if a logical is chosen
|
||||
|
||||
call print ! Intro to partition number
|
||||
.ascii "p?\b\0"
|
||||
|
||||
part:
|
||||
call getch ! Get character to tell partition
|
||||
call gettable ! Get partition table
|
||||
call sort ! Sort partition table
|
||||
call choose_load ! Compute chosen entry and load
|
||||
|
||||
cmpb sysind(si), #MINIX_PART ! Minix subpartition table possible?
|
||||
jne waitboot
|
||||
|
||||
call print ! Intro to slice number
|
||||
.ascii "s?\b\0"
|
||||
|
||||
slice:
|
||||
call getch ! Get character to tell slice
|
||||
call gettable ! Get partition table
|
||||
call choose_load ! Compute chosen entry and load
|
||||
|
||||
waitboot:
|
||||
call print ! Intro to nothing
|
||||
.ascii " ?\b\0"
|
||||
call getch ! Supposed to type RETURN now
|
||||
n0nboot:jmp nonboot ! Sorry, can't go further
|
||||
|
||||
! Get a character, either the patched-in, or one from the keyboard.
|
||||
getch:
|
||||
movb al, (bp) ! Get patched-in character
|
||||
testb al, al
|
||||
jz getkey
|
||||
inc bp
|
||||
jmp gotkey
|
||||
getkey: xorb ah, ah ! Wait for keypress
|
||||
int 0x16
|
||||
gotkey: testb dl, dl ! Ignore CR if disk number not yet set
|
||||
jns putch
|
||||
cmpb al, #0x0D ! Carriage return?
|
||||
je boot
|
||||
!jmp putch
|
||||
|
||||
! Print a character
|
||||
putch: movb ah, #0x0E ! Print character in teletype mode
|
||||
mov bx, #0x0001 ! Page 0, foreground color
|
||||
int 0x10
|
||||
ret
|
||||
|
||||
! Print a message.
|
||||
print: mov cx, si ! Save si
|
||||
pop si ! si = String following 'call print'
|
||||
prnext: lodsb ! al = *si++ is char to be printed
|
||||
testb al, al ! Null marks end
|
||||
jz prdone
|
||||
call putch
|
||||
jmp prnext
|
||||
prdone: xchg si, cx ! Restore si
|
||||
jmp (cx) ! Continue after the string
|
||||
|
||||
! Return typed (or in patched data) means to run the bootstrap now in core!
|
||||
boot:
|
||||
call print ! Make line on screen look proper
|
||||
.ascii "\b \r\n\0"
|
||||
jmp LOADOFF-BUFFER ! Jump to LOADOFF
|
||||
|
||||
! Compute address of chosen partition entry from choice al into si, then
|
||||
! continue to load the boot sector of that partition.
|
||||
choose_load:
|
||||
subb al, #0x30 ! al -= '0'
|
||||
cmpb al, #4 ! Only four partitions
|
||||
ja n0nboot
|
||||
movb ah, #PENTRYSIZE
|
||||
mulb ah ! al *= PENTRYSIZE
|
||||
add ax, #BUFFER+PART_TABLE
|
||||
mov si, ax ! si = &part_table[al - '0']
|
||||
movb al, sysind(si) ! System indicator
|
||||
testb al, al ! Unused partition?
|
||||
jz n0nboot
|
||||
!jmp load ! Continue to load boot sector
|
||||
|
||||
! Load boot sector of the current partition.
|
||||
load:
|
||||
push dx ! Save drive code
|
||||
push es ! Next call sets es
|
||||
movb ah, #0x08 ! Code for drive parameters
|
||||
int 0x13
|
||||
pop es
|
||||
andb cl, #0x3F ! cl = max sector number (1-origin)
|
||||
incb dh ! dh = 1 + max head number (0-origin)
|
||||
movb al, cl ! al = cl = sectors per track
|
||||
mulb dh ! dh = heads, ax = heads * sectors
|
||||
mov bx, ax ! bx = sectors per cylinder = heads * sectors
|
||||
mov ax, lowsec+0(si)
|
||||
mov dx, lowsec+2(si) ! dx:ax = sector within drive
|
||||
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
|
||||
jae bigdisk
|
||||
div bx ! ax = cylinder, dx = sector within cylinder
|
||||
xchg ax, dx ! ax = sector within cylinder, dx = cylinder
|
||||
movb ch, dl ! ch = low 8 bits of cylinder
|
||||
divb cl ! al = head, ah = sector (0-origin)
|
||||
xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
|
||||
shr dx, #1
|
||||
shr dx, #1 ! dl[6..7] = high cylinder
|
||||
orb dl, ah ! dl[0..5] = sector (0-origin)
|
||||
movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
|
||||
incb cl ! cl[0..5] = sector (1-origin)
|
||||
pop dx ! Restore drive code in dl
|
||||
movb dh, al ! dh = al = head
|
||||
mov bx, #LOADOFF ! es:bx = where sector is loaded
|
||||
mov ax, #0x0201 ! ah = Code for read / al = one sector
|
||||
int 0x13
|
||||
jmp rdeval ! Evaluate read result
|
||||
bigdisk:
|
||||
mov bx, dx ! bx:ax = dx:ax = sector to read
|
||||
pop dx ! Restore drive code in dl
|
||||
push si ! Save si
|
||||
mov si, #BUFFER+ext_rw ! si = extended read/write parameter packet
|
||||
mov 8(si), ax ! Starting block number = bx:ax
|
||||
mov 10(si), bx
|
||||
movb ah, #0x42 ! Extended read
|
||||
int 0x13
|
||||
pop si ! Restore si to point to partition entry
|
||||
!jmp rdeval
|
||||
rdeval:
|
||||
jnc rdok
|
||||
rderr:
|
||||
call print
|
||||
.ascii "\r\nRead error\r\n\0"
|
||||
jmp again
|
||||
rdok:
|
||||
cmp LOADOFF+MAGIC, #0xAA55
|
||||
je sigok ! Signature ok?
|
||||
nonboot:
|
||||
call print
|
||||
.ascii "\r\nNot bootable\r\n\0"
|
||||
jmp again
|
||||
sigok:
|
||||
ret
|
||||
|
||||
! Get the partition table into my space.
|
||||
gettable:
|
||||
mov si, #LOADOFF+PART_TABLE
|
||||
mov di, #BUFFER+PART_TABLE
|
||||
mov cx, #4*PENTRYSIZE/2
|
||||
rep movs
|
||||
ret
|
||||
|
||||
! Sort the partition table.
|
||||
sort:
|
||||
mov cx, #4 ! Four times is enough to sort
|
||||
bubble: mov si, #BUFFER+PART_TABLE ! First table entry
|
||||
bubble1:lea di, PENTRYSIZE(si) ! Next entry
|
||||
cmpb sysind(si), ch ! Partition type, nonzero when in use
|
||||
jz exchg ! Unused entries sort to the end
|
||||
inuse: mov bx, lowsec+0(di)
|
||||
sub bx, lowsec+0(si) ! Compute di->lowsec - si->lowsec
|
||||
mov bx, lowsec+2(di)
|
||||
sbb bx, lowsec+2(si)
|
||||
jae order ! In order if si->lowsec <= di->lowsec
|
||||
exchg: movb bl, (si)
|
||||
xchgb bl, PENTRYSIZE(si) ! Exchange entries byte by byte
|
||||
movb (si), bl
|
||||
inc si
|
||||
cmp si, di
|
||||
jb exchg
|
||||
order: mov si, di
|
||||
cmp si, #BUFFER+PART_TABLE+3*PENTRYSIZE
|
||||
jb bubble1
|
||||
loop bubble
|
||||
ret
|
||||
|
||||
.data
|
||||
|
||||
! Extended read/write commands require a parameter packet.
|
||||
ext_rw:
|
||||
.data1 0x10 ! Length of extended r/w packet
|
||||
.data1 0 ! Reserved
|
||||
.data2 1 ! Blocks to transfer (just one)
|
||||
.data2 LOADOFF ! Buffer address offset
|
||||
.data2 0 ! Buffer address segment
|
||||
.data4 0 ! Starting block number low 32 bits (tbfi)
|
||||
zero: .data4 0 ! Starting block number high 32 bits
|
||||
|
||||
.align 2
|
||||
guide:
|
||||
! Guide characters and possibly a logical partition number patched here by
|
||||
! installboot, up to 6 bytes maximum.
|
||||
@@ -1,218 +0,0 @@
|
||||
! masterboot 2.0 - Master boot block code Author: Kees J. Bot
|
||||
!
|
||||
! This code may be placed in the first sector (the boot sector) of a floppy,
|
||||
! hard disk or hard disk primary partition. There it will perform the
|
||||
! following actions at boot time:
|
||||
!
|
||||
! - If the booted device is a hard disk and one of the partitions is active
|
||||
! then the active partition is booted.
|
||||
!
|
||||
! - Otherwise the next floppy or hard disk device is booted, trying them one
|
||||
! by one.
|
||||
!
|
||||
! To make things a little clearer, the boot path might be:
|
||||
! /dev/fd0 - Floppy disk containing data, tries fd1 then d0
|
||||
! [/dev/fd1] - Drive empty
|
||||
! /dev/c0d0 - Master boot block, selects active partition 2
|
||||
! /dev/c0d0p2 - Submaster, selects active subpartition 0
|
||||
! /dev/c0d0p2s0 - Minix bootblock, reads Boot Monitor /boot
|
||||
! Minix - Started by /boot from a kernel image in /minix
|
||||
|
||||
LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
|
||||
BUFFER = 0x0600 ! First free memory
|
||||
PART_TABLE = 446 ! Location of partition table within this code
|
||||
PENTRYSIZE = 16 ! Size of one partition table entry
|
||||
MAGIC = 510 ! Location of the AA55 magic number
|
||||
|
||||
! <ibm/partition>.h:
|
||||
bootind = 0
|
||||
sysind = 4
|
||||
lowsec = 8
|
||||
|
||||
|
||||
.text
|
||||
|
||||
! Find active (sub)partition, load its first sector, run it.
|
||||
|
||||
master:
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
cli
|
||||
mov ss, ax ! ds = es = ss = Vector segment
|
||||
mov sp, #LOADOFF
|
||||
sti
|
||||
|
||||
! Copy this code to safety, then jump to it.
|
||||
mov si, sp ! si = start of this code
|
||||
push si ! Also where we'll return to eventually
|
||||
mov di, #BUFFER ! Buffer area
|
||||
mov cx, #512/2 ! One sector
|
||||
cld
|
||||
rep movs
|
||||
jmpf BUFFER+migrate, 0 ! To safety
|
||||
migrate:
|
||||
|
||||
! Find the active partition
|
||||
findactive:
|
||||
testb dl, dl
|
||||
jns nextdisk ! No bootable partitions on floppies
|
||||
mov si, #BUFFER+PART_TABLE
|
||||
find: cmpb sysind(si), #0 ! Partition type, nonzero when in use
|
||||
jz nextpart
|
||||
testb bootind(si), #0x80 ! Active partition flag in bit 7
|
||||
jz nextpart ! It's not active
|
||||
loadpart:
|
||||
call load ! Load partition bootstrap
|
||||
jc error1 ! Not supposed to fail
|
||||
bootstrap:
|
||||
ret ! Jump to the master bootstrap
|
||||
nextpart:
|
||||
add si, #PENTRYSIZE
|
||||
cmp si, #BUFFER+PART_TABLE+4*PENTRYSIZE
|
||||
jb find
|
||||
! No active partition, tell 'em
|
||||
call print
|
||||
.ascii "No active partition\0"
|
||||
jmp reboot
|
||||
|
||||
! There are no active partitions on this drive, try the next drive.
|
||||
nextdisk:
|
||||
incb dl ! Increment dl for the next drive
|
||||
testb dl, dl
|
||||
js nexthd ! Hard disk if negative
|
||||
int 0x11 ! Get equipment configuration
|
||||
shl ax, #1 ! Highest floppy drive # in bits 6-7
|
||||
shl ax, #1 ! Now in bits 0-1 of ah
|
||||
andb ah, #0x03 ! Extract bits
|
||||
cmpb dl, ah ! Must be dl <= ah for drive to exist
|
||||
ja nextdisk ! Otherwise try disk 0 eventually
|
||||
call load0 ! Read the next floppy bootstrap
|
||||
jc nextdisk ! It failed, next disk please
|
||||
ret ! Jump to the next master bootstrap
|
||||
nexthd: call load0 ! Read the hard disk bootstrap
|
||||
error1: jc error ! No disk?
|
||||
ret
|
||||
|
||||
|
||||
! Load sector 0 from the current device. It's either a floppy bootstrap or
|
||||
! a hard disk master bootstrap.
|
||||
load0:
|
||||
mov si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
|
||||
!jmp load
|
||||
|
||||
! Load sector lowsec(si) from the current device. The obvious head, sector,
|
||||
! and cylinder numbers are ignored in favour of the more trustworthy absolute
|
||||
! start of partition.
|
||||
load:
|
||||
mov di, #3 ! Three retries for floppy spinup
|
||||
retry: push dx ! Save drive code
|
||||
push es
|
||||
push di ! Next call destroys es and di
|
||||
movb ah, #0x08 ! Code for drive parameters
|
||||
int 0x13
|
||||
pop di
|
||||
pop es
|
||||
andb cl, #0x3F ! cl = max sector number (1-origin)
|
||||
incb dh ! dh = 1 + max head number (0-origin)
|
||||
movb al, cl ! al = cl = sectors per track
|
||||
mulb dh ! dh = heads, ax = heads * sectors
|
||||
mov bx, ax ! bx = sectors per cylinder = heads * sectors
|
||||
mov ax, lowsec+0(si)
|
||||
mov dx, lowsec+2(si)! dx:ax = sector within drive
|
||||
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
|
||||
jae bigdisk
|
||||
div bx ! ax = cylinder, dx = sector within cylinder
|
||||
xchg ax, dx ! ax = sector within cylinder, dx = cylinder
|
||||
movb ch, dl ! ch = low 8 bits of cylinder
|
||||
divb cl ! al = head, ah = sector (0-origin)
|
||||
xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
|
||||
shr dx, #1
|
||||
shr dx, #1 ! dl[6..7] = high cylinder
|
||||
orb dl, ah ! dl[0..5] = sector (0-origin)
|
||||
movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
|
||||
incb cl ! cl[0..5] = sector (1-origin)
|
||||
pop dx ! Restore drive code in dl
|
||||
movb dh, al ! dh = al = head
|
||||
mov bx, #LOADOFF ! es:bx = where sector is loaded
|
||||
mov ax, #0x0201 ! Code for read, just one sector
|
||||
int 0x13 ! Call the BIOS for a read
|
||||
jmp rdeval ! Evaluate read result
|
||||
bigdisk:
|
||||
mov bx, dx ! bx:ax = dx:ax = sector to read
|
||||
pop dx ! Restore drive code in dl
|
||||
push si ! Save si
|
||||
mov si, #BUFFER+ext_rw ! si = extended read/write parameter packet
|
||||
mov 8(si), ax ! Starting block number = bx:ax
|
||||
mov 10(si), bx
|
||||
movb ah, #0x42 ! Extended read
|
||||
int 0x13
|
||||
pop si ! Restore si to point to partition entry
|
||||
!jmp rdeval
|
||||
rdeval:
|
||||
jnc rdok ! Read succeeded
|
||||
cmpb ah, #0x80 ! Disk timed out? (Floppy drive empty)
|
||||
je rdbad
|
||||
dec di
|
||||
jl rdbad ! Retry count expired
|
||||
xorb ah, ah
|
||||
int 0x13 ! Reset
|
||||
jnc retry ! Try again
|
||||
rdbad: stc ! Set carry flag
|
||||
ret
|
||||
rdok: cmp LOADOFF+MAGIC, #0xAA55
|
||||
jne nosig ! Error if signature wrong
|
||||
ret ! Return with carry still clear
|
||||
nosig: call print
|
||||
.ascii "Not bootable\0"
|
||||
jmp reboot
|
||||
|
||||
! A read error occurred, complain and hang
|
||||
error:
|
||||
mov si, #LOADOFF+errno+1
|
||||
prnum: movb al, ah ! Error number in ah
|
||||
andb al, #0x0F ! Low 4 bits
|
||||
cmpb al, #10 ! A-F?
|
||||
jb digit ! 0-9!
|
||||
addb al, #7 ! 'A' - ':'
|
||||
digit: addb (si), al ! Modify '0' in string
|
||||
dec si
|
||||
movb cl, #4 ! Next 4 bits
|
||||
shrb ah, cl
|
||||
jnz prnum ! Again if digit > 0
|
||||
call print
|
||||
.ascii "Read error "
|
||||
errno: .ascii "00\0"
|
||||
!jmp reboot
|
||||
|
||||
reboot:
|
||||
call print
|
||||
.ascii ". Hit any key to reboot.\0"
|
||||
xorb ah, ah ! Wait for keypress
|
||||
int 0x16
|
||||
call print
|
||||
.ascii "\r\n\0"
|
||||
int 0x19
|
||||
|
||||
! Print a message.
|
||||
print: pop si ! si = String following 'call print'
|
||||
prnext: lodsb ! al = *si++ is char to be printed
|
||||
testb al, al ! Null marks end
|
||||
jz prdone
|
||||
movb ah, #0x0E ! Print character in teletype mode
|
||||
mov bx, #0x0001 ! Page 0, foreground color
|
||||
int 0x10
|
||||
jmp prnext
|
||||
prdone: jmp (si) ! Continue after the string
|
||||
|
||||
.data
|
||||
|
||||
! Extended read/write commands require a parameter packet.
|
||||
ext_rw:
|
||||
.data1 0x10 ! Length of extended r/w packet
|
||||
.data1 0 ! Reserved
|
||||
.data2 1 ! Blocks to transfer (just one)
|
||||
.data2 LOADOFF ! Buffer address offset
|
||||
.data2 0 ! Buffer address segment
|
||||
.data4 0 ! Starting block number low 32 bits (tbfi)
|
||||
zero: .data4 0 ! Starting block number high 32 bits
|
||||
137
boot/mkfhead.s
137
boot/mkfhead.s
@@ -1,137 +0,0 @@
|
||||
! Mkfhead.s - DOS & BIOS support for mkfile.c Author: Kees J. Bot
|
||||
! 9 May 1998
|
||||
!
|
||||
! This file contains the startup and low level support for the MKFILE.COM
|
||||
! utility. See doshead.ack.s for more comments on .COM files.
|
||||
!
|
||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||
.sect .text
|
||||
|
||||
.define _PSP
|
||||
_PSP:
|
||||
.space 256 ! Program Segment Prefix
|
||||
|
||||
mkfile:
|
||||
cld ! C compiler wants UP
|
||||
xor ax, ax ! Zero
|
||||
mov di, _edata ! Start of bss is at end of data
|
||||
mov cx, _end ! End of bss (begin of heap)
|
||||
sub cx, di ! Number of bss bytes
|
||||
shr cx, 1 ! Number of words
|
||||
rep stos ! Clear bss
|
||||
|
||||
xor cx, cx ! cx = argc
|
||||
xor bx, bx
|
||||
push bx ! argv[argc] = NULL
|
||||
movb bl, (_PSP+0x80) ! Argument byte count
|
||||
0: movb _PSP+0x81(bx), ch ! Null terminate
|
||||
dec bx
|
||||
js 9f
|
||||
cmpb _PSP+0x81(bx), 0x20 ! Whitespace?
|
||||
jbe 0b
|
||||
1: dec bx ! One argument character
|
||||
js 2f
|
||||
cmpb _PSP+0x81(bx), 0x20 ! More argument characters?
|
||||
ja 1b
|
||||
2: lea ax, _PSP+0x81+1(bx) ! Address of argument
|
||||
push ax ! argv[n]
|
||||
inc cx ! argc++;
|
||||
test bx, bx
|
||||
jns 0b ! More arguments?
|
||||
9: movb _PSP+0x81(bx), ch ! Make a null string
|
||||
lea ax, _PSP+0x81(bx)
|
||||
push ax ! to use as argv[0]
|
||||
inc cx ! Final value of argc
|
||||
mov ax, sp
|
||||
push ax ! argv
|
||||
push cx ! argc
|
||||
call _main ! main(argc, argv)
|
||||
push ax
|
||||
call _exit ! exit(main(argc, argv))
|
||||
|
||||
! int creat(const char *path, mode_t mode)
|
||||
! Create a file with the old creat() call.
|
||||
.define _creat
|
||||
_creat:
|
||||
mov bx, sp
|
||||
mov dx, 2(bx) ! Filename
|
||||
xor cx, cx ! Ignore mode, always read-write
|
||||
movb ah, 0x3C ! "CREAT"
|
||||
dos: int 0x21 ! ax = creat(path, 0666);
|
||||
jc seterrno
|
||||
ret
|
||||
|
||||
seterrno:
|
||||
mov (_errno), ax ! Set errno to the DOS error code
|
||||
mov ax, -1
|
||||
cwd ! return -1L;
|
||||
ret
|
||||
|
||||
! int open(const char *path, int oflag)
|
||||
! Open a file with the oldfashioned two-argument open() call.
|
||||
.define _open
|
||||
_open:
|
||||
mov bx, sp
|
||||
mov dx, 2(bx) ! Filename
|
||||
movb al, 4(bx) ! O_RDONLY, O_WRONLY, O_RDWR
|
||||
movb ah, 0x3D ! "OPEN"
|
||||
jmp dos
|
||||
|
||||
! int close(int fd)
|
||||
! Close an open file.
|
||||
.define _close
|
||||
_close:
|
||||
mov bx, sp
|
||||
mov bx, 2(bx) ! bx = file handle
|
||||
movb ah, 0x3E ! "CLOSE"
|
||||
jmp dos
|
||||
|
||||
! void exit(int status)
|
||||
! void _exit(int status)
|
||||
! Return to DOS.
|
||||
.define _exit, __exit, ___exit
|
||||
_exit:
|
||||
__exit:
|
||||
___exit:
|
||||
pop ax
|
||||
pop ax ! al = status
|
||||
movb ah, 0x4C ! "EXIT"
|
||||
int 0x21
|
||||
hlt
|
||||
|
||||
! ssize_t read(int fd, void *buf, size_t n)
|
||||
! Read bytes from an open file.
|
||||
.define _read
|
||||
_read:
|
||||
mov bx, sp
|
||||
mov cx, 6(bx)
|
||||
mov dx, 4(bx)
|
||||
mov bx, 2(bx)
|
||||
movb ah, 0x3F ! "READ"
|
||||
jmp dos
|
||||
|
||||
! ssize_t write(int fd, const void *buf, size_t n)
|
||||
! Write bytes to an open file.
|
||||
.define _write
|
||||
_write:
|
||||
mov bx, sp
|
||||
mov cx, 6(bx)
|
||||
mov dx, 4(bx)
|
||||
mov bx, 2(bx)
|
||||
movb ah, 0x40 ! "WRITE"
|
||||
jmp dos
|
||||
|
||||
! off_t lseek(int fd, off_t offset, int whence)
|
||||
! Set file position for read or write.
|
||||
.define _lseek
|
||||
_lseek:
|
||||
mov bx, sp
|
||||
movb al, 8(bx) ! SEEK_SET, SEEK_CUR, SEEK_END
|
||||
mov dx, 4(bx)
|
||||
mov cx, 6(bx) ! cx:dx = offset
|
||||
mov bx, 2(bx)
|
||||
movb ah, 0x42 ! "LSEEK"
|
||||
jmp dos
|
||||
|
||||
!
|
||||
! $PchId: mkfhead.ack.s,v 1.3 1999/01/14 21:17:06 philip Exp $
|
||||
179
boot/mkfile.c
179
boot/mkfile.c
@@ -1,179 +0,0 @@
|
||||
/* mkfile 1.0 - create a file under DOS for use as a Minix "disk".
|
||||
* Author: Kees J. Bot
|
||||
* 9 May 1998
|
||||
*/
|
||||
#define nil 0
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Stuff normally found in <unistd.h>, <errno.h>, etc. */
|
||||
extern int errno;
|
||||
int creat(const char *file, int mode);
|
||||
int open(const char *file, int oflag);
|
||||
off_t lseek(int fd, off_t offset, int whence);
|
||||
ssize_t write(int fd, const char *buf, size_t len);
|
||||
void exit(int status);
|
||||
int printf(const char *fmt, ...);
|
||||
|
||||
#define O_WRONLY 1
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_END 2
|
||||
|
||||
/* Kernel printf requires a putk() function. */
|
||||
void putk(int c)
|
||||
{
|
||||
char ch = c;
|
||||
|
||||
if (c == 0) return;
|
||||
if (c == '\n') putk('\r');
|
||||
(void) write(2, &ch, 1);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage: mkfile <size>[gmk] <file>\n"
|
||||
"(Example sizes, all 50 meg: 52428800, 51200k, 50m)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *strerror(int err)
|
||||
/* Translate some DOS error numbers to text. */
|
||||
{
|
||||
static struct errlist {
|
||||
int err;
|
||||
char *what;
|
||||
} errlist[] = {
|
||||
{ 0, "No error" },
|
||||
{ 1, "Function number invalid" },
|
||||
{ 2, "File not found" },
|
||||
{ 3, "Path not found" },
|
||||
{ 4, "Too many open files" },
|
||||
{ 5, "Access denied" },
|
||||
{ 6, "Invalid handle" },
|
||||
{ 12, "Access code invalid" },
|
||||
{ 39, "Insufficient disk space" },
|
||||
};
|
||||
struct errlist *ep;
|
||||
static char unknown[]= "Error 65535";
|
||||
unsigned e;
|
||||
char *p;
|
||||
|
||||
for (ep= errlist; ep < errlist + sizeof(errlist)/sizeof(errlist[0]);
|
||||
ep++) {
|
||||
if (ep->err == err) return ep->what;
|
||||
}
|
||||
p= unknown + sizeof(unknown) - 1;
|
||||
e= err;
|
||||
do *--p= '0' + (e % 10); while ((e /= 10) > 0);
|
||||
strcpy(unknown + 6, p);
|
||||
return unknown;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static char buf[512];
|
||||
unsigned long size, mul;
|
||||
off_t offset;
|
||||
char *cp;
|
||||
int fd;
|
||||
char *file;
|
||||
|
||||
if (argc != 3) usage();
|
||||
|
||||
cp= argv[1];
|
||||
size= 0;
|
||||
while ((unsigned) (*cp - '0') < 10) {
|
||||
unsigned d= *cp++ - '0';
|
||||
if (size <= (ULONG_MAX-9) / 10) {
|
||||
size= size * 10 + d;
|
||||
} else {
|
||||
size= ULONG_MAX;
|
||||
}
|
||||
}
|
||||
if (cp == argv[1]) usage();
|
||||
while (*cp != 0) {
|
||||
mul = 1;
|
||||
switch (*cp++) {
|
||||
case 'G':
|
||||
case 'g': mul *= 1024;
|
||||
case 'M':
|
||||
case 'm': mul *= 1024;
|
||||
case 'K':
|
||||
case 'k': mul *= 1024;
|
||||
case 'B':
|
||||
case 'b': break;
|
||||
default: usage();
|
||||
}
|
||||
if (size <= ULONG_MAX / mul) {
|
||||
size *= mul;
|
||||
} else {
|
||||
size= ULONG_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 1024L*1024*1024) {
|
||||
printf("mkfile: A file size over 1G is a bit too much\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Open existing file, or create a new file. */
|
||||
file= argv[2];
|
||||
if ((fd= open(file, O_WRONLY)) < 0) {
|
||||
if (errno == 2) {
|
||||
fd= creat(file, 0666);
|
||||
}
|
||||
}
|
||||
if (fd < 0) {
|
||||
printf("mkfile: Can't open %s: %s\n", file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* How big is the file now? */
|
||||
if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
|
||||
printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (offset == 0 && size == 0) exit(0); /* Huh? */
|
||||
|
||||
/* Write the first bit if the file is zero length. This is necessary
|
||||
* to circumvent a DOS bug by extending a new file by lseek. We also
|
||||
* want to make sure there are zeros in the first sector.
|
||||
*/
|
||||
if (offset == 0) {
|
||||
if (write(fd, buf, sizeof(buf)) == -1) {
|
||||
printf("mkfile: Can't write to %s: %s\n",
|
||||
file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Seek to the required size and write 0 bytes to extend/truncate the
|
||||
* file to that size.
|
||||
*/
|
||||
if (lseek(fd, size, SEEK_SET) == -1) {
|
||||
printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (write(fd, buf, 0) == -1) {
|
||||
printf("mkfile: Can't write to %s: %s\n",
|
||||
file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Did the file become the required size? */
|
||||
if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
|
||||
printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (offset != size) {
|
||||
printf("mkfile: Failed to extend %s. Disk full?\n", file);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: mkfile.c,v 1.4 2000/08/13 22:06:40 philip Exp $
|
||||
*/
|
||||
330
boot/rawfs.c
330
boot/rawfs.c
@@ -1,330 +0,0 @@
|
||||
/* rawfs.c - Raw Minix file system support. Author: Kees J. Bot
|
||||
* 23 Dec 1991
|
||||
* Based on readfs by Paul Polderman
|
||||
*/
|
||||
#define _POSIX_SOURCE 1
|
||||
#define _MINIX 1
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h>
|
||||
#include <servers/mfs/const.h>
|
||||
#include <servers/mfs/type.h>
|
||||
#include <servers/mfs/buf.h>
|
||||
#include <servers/mfs/super.h>
|
||||
#include <servers/mfs/inode.h>
|
||||
#include "rawfs.h"
|
||||
|
||||
void readblock(off_t blockno, char *buf, int);
|
||||
|
||||
/* The following code handles two file system types: Version 1 with small
|
||||
* inodes and 16-bit disk addresses and Version 2 with big inodes and 32-bit
|
||||
* disk addresses.
|
||||
#ifdef FLEX
|
||||
* To make matters worse, Minix-vmd knows about the normal Unix Version 7
|
||||
* directories and directories with flexible entries.
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* File system parameters. */
|
||||
static unsigned nr_dzones; /* Fill these in after reading superblock. */
|
||||
static unsigned nr_indirects;
|
||||
static unsigned inodes_per_block;
|
||||
static int block_size;
|
||||
#ifdef FLEX
|
||||
#include <dirent.h>
|
||||
#define direct _v7_direct
|
||||
#else
|
||||
#include <sys/dir.h>
|
||||
#endif
|
||||
|
||||
#if __minix_vmd
|
||||
static struct v12_super_block super; /* Superblock of file system */
|
||||
#define s_log_zone_size s_dummy /* Zones are obsolete. */
|
||||
#else
|
||||
static struct super_block super; /* Superblock of file system */
|
||||
#define SUPER_V1 SUPER_MAGIC /* V1 magic has a weird name. */
|
||||
#endif
|
||||
|
||||
static struct inode curfil; /* Inode of file under examination */
|
||||
static char indir[_MAX_BLOCK_SIZE]; /* Single indirect block. */
|
||||
static char dindir[_MAX_BLOCK_SIZE]; /* Double indirect block. */
|
||||
static char dirbuf[_MAX_BLOCK_SIZE]; /* Scratch/Directory block. */
|
||||
#define scratch dirbuf
|
||||
|
||||
static block_t a_indir, a_dindir; /* Addresses of the indirects. */
|
||||
static off_t dirpos; /* Reading pos in a dir. */
|
||||
|
||||
#define fsbuf(b) (* (union fsdata_u *) (b))
|
||||
|
||||
#define zone_shift (super.s_log_zone_size) /* zone to block ratio */
|
||||
|
||||
off_t r_super(int *bs)
|
||||
/* Initialize variables, return size of file system in blocks,
|
||||
* (zero on error).
|
||||
*/
|
||||
{
|
||||
/* Read superblock. (The superblock is always at 1kB offset,
|
||||
* that's why we lie to readblock and say the block size is 1024
|
||||
* and we want block number 1 (the 'second block', at offset 1kB).)
|
||||
*/
|
||||
readblock(1, scratch, 1024);
|
||||
|
||||
memcpy(&super, scratch, sizeof(super));
|
||||
|
||||
/* Is it really a MINIX file system ? */
|
||||
if (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3) {
|
||||
if(super.s_magic == SUPER_V2)
|
||||
super.s_block_size = 1024;
|
||||
*bs = block_size = super.s_block_size;
|
||||
if(block_size < _MIN_BLOCK_SIZE ||
|
||||
block_size > _MAX_BLOCK_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
nr_dzones= V2_NR_DZONES;
|
||||
nr_indirects= V2_INDIRECTS(block_size);
|
||||
inodes_per_block= V2_INODES_PER_BLOCK(block_size);
|
||||
return (off_t) super.s_zones << zone_shift;
|
||||
} else
|
||||
if (super.s_magic == SUPER_V1) {
|
||||
*bs = block_size = 1024;
|
||||
nr_dzones= V1_NR_DZONES;
|
||||
nr_indirects= V1_INDIRECTS;
|
||||
inodes_per_block= V1_INODES_PER_BLOCK;
|
||||
return (off_t) super.s_nzones << zone_shift;
|
||||
} else {
|
||||
/* Filesystem not recognized as Minix. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void r_stat(Ino_t inum, struct stat *stp)
|
||||
/* Return information about a file like stat(2) and remember it. */
|
||||
{
|
||||
block_t block;
|
||||
block_t ino_block;
|
||||
ino_t ino_offset;
|
||||
union fsdata_u *blockbuf;
|
||||
|
||||
/* Calculate start of i-list */
|
||||
block = START_BLOCK + super.s_imap_blocks + super.s_zmap_blocks;
|
||||
|
||||
/* Calculate block with inode inum */
|
||||
ino_block = ((inum - 1) / inodes_per_block);
|
||||
ino_offset = ((inum - 1) % inodes_per_block);
|
||||
block += ino_block;
|
||||
|
||||
/* Fetch the block */
|
||||
blockbuf = (union fsdata_u *) scratch;
|
||||
readblock(block, (char *) blockbuf, block_size);
|
||||
|
||||
if (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3) {
|
||||
d2_inode *dip;
|
||||
int i;
|
||||
|
||||
dip= &blockbuf->b__v2_ino[(unsigned int) ino_offset];
|
||||
|
||||
curfil.i_mode= dip->d2_mode;
|
||||
curfil.i_nlinks= dip->d2_nlinks;
|
||||
curfil.i_uid= dip->d2_uid;
|
||||
curfil.i_gid= dip->d2_gid;
|
||||
curfil.i_size= dip->d2_size;
|
||||
curfil.i_atime= dip->d2_atime;
|
||||
curfil.i_mtime= dip->d2_mtime;
|
||||
curfil.i_ctime= dip->d2_ctime;
|
||||
for (i= 0; i < V2_NR_TZONES; i++)
|
||||
curfil.i_zone[i]= dip->d2_zone[i];
|
||||
} else {
|
||||
d1_inode *dip;
|
||||
int i;
|
||||
|
||||
dip= &blockbuf->b__v1_ino[(unsigned int) ino_offset];
|
||||
|
||||
curfil.i_mode= dip->d1_mode;
|
||||
curfil.i_nlinks= dip->d1_nlinks;
|
||||
curfil.i_uid= dip->d1_uid;
|
||||
curfil.i_gid= dip->d1_gid;
|
||||
curfil.i_size= dip->d1_size;
|
||||
curfil.i_atime= dip->d1_mtime;
|
||||
curfil.i_mtime= dip->d1_mtime;
|
||||
curfil.i_ctime= dip->d1_mtime;
|
||||
for (i= 0; i < V1_NR_TZONES; i++)
|
||||
curfil.i_zone[i]= dip->d1_zone[i];
|
||||
}
|
||||
curfil.i_dev= -1; /* Can't fill this in alas. */
|
||||
curfil.i_num= inum;
|
||||
|
||||
stp->st_dev= curfil.i_dev;
|
||||
stp->st_ino= curfil.i_num;
|
||||
stp->st_mode= curfil.i_mode;
|
||||
stp->st_nlink= curfil.i_nlinks;
|
||||
stp->st_uid= curfil.i_uid;
|
||||
stp->st_gid= curfil.i_gid;
|
||||
stp->st_rdev= (dev_t) curfil.i_zone[0];
|
||||
stp->st_size= curfil.i_size;
|
||||
stp->st_atime= curfil.i_atime;
|
||||
stp->st_mtime= curfil.i_mtime;
|
||||
stp->st_ctime= curfil.i_ctime;
|
||||
|
||||
a_indir= a_dindir= 0;
|
||||
dirpos= 0;
|
||||
}
|
||||
|
||||
ino_t r_readdir(char *name)
|
||||
/* Read next directory entry at "dirpos" from file "curfil". */
|
||||
{
|
||||
ino_t inum= 0;
|
||||
int blkpos;
|
||||
struct direct *dp;
|
||||
|
||||
if (!S_ISDIR(curfil.i_mode)) { errno= ENOTDIR; return -1; }
|
||||
|
||||
if(!block_size) { errno = 0; return -1; }
|
||||
|
||||
while (inum == 0 && dirpos < curfil.i_size) {
|
||||
if ((blkpos= (int) (dirpos % block_size)) == 0) {
|
||||
/* Need to fetch a new directory block. */
|
||||
|
||||
readblock(r_vir2abs(dirpos / block_size), dirbuf, block_size);
|
||||
}
|
||||
#ifdef FLEX
|
||||
if (super.s_flags & S_FLEX) {
|
||||
struct _fl_direct *dp;
|
||||
|
||||
dp= (struct _fl_direct *) (dirbuf + blkpos);
|
||||
if ((inum= dp->d_ino) != 0) strcpy(name, dp->d_name);
|
||||
|
||||
dirpos+= (1 + dp->d_extent) * FL_DIR_ENTRY_SIZE;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Let dp point to the next entry. */
|
||||
dp= (struct direct *) (dirbuf + blkpos);
|
||||
|
||||
if ((inum= dp->d_ino) != 0) {
|
||||
/* This entry is occupied, return name. */
|
||||
strncpy(name, dp->d_name, sizeof(dp->d_name));
|
||||
name[sizeof(dp->d_name)]= 0;
|
||||
}
|
||||
dirpos+= DIR_ENTRY_SIZE;
|
||||
}
|
||||
return inum;
|
||||
}
|
||||
|
||||
off_t r_vir2abs(off_t virblk)
|
||||
/* Translate a block number in a file to an absolute disk block number.
|
||||
* Returns 0 for a hole and -1 if block is past end of file.
|
||||
*/
|
||||
{
|
||||
block_t b= virblk;
|
||||
zone_t zone, ind_zone;
|
||||
block_t z, zone_index;
|
||||
int i;
|
||||
|
||||
if(!block_size) return -1;
|
||||
|
||||
/* Check if virblk within file. */
|
||||
if (virblk * block_size >= curfil.i_size) return -1;
|
||||
|
||||
/* Calculate zone in which the datablock number is contained */
|
||||
zone = (zone_t) (b >> zone_shift);
|
||||
|
||||
/* Calculate index of the block number in the zone */
|
||||
zone_index = b - ((block_t) zone << zone_shift);
|
||||
|
||||
/* Go get the zone */
|
||||
if (zone < (zone_t) nr_dzones) { /* direct block */
|
||||
zone = curfil.i_zone[(int) zone];
|
||||
z = ((block_t) zone << zone_shift) + zone_index;
|
||||
return z;
|
||||
}
|
||||
|
||||
/* The zone is not a direct one */
|
||||
zone -= (zone_t) nr_dzones;
|
||||
|
||||
/* Is it single indirect ? */
|
||||
if (zone < (zone_t) nr_indirects) { /* single indirect block */
|
||||
ind_zone = curfil.i_zone[nr_dzones];
|
||||
} else { /* double indirect block */
|
||||
/* Fetch the double indirect block */
|
||||
if ((ind_zone = curfil.i_zone[nr_dzones + 1]) == 0) return 0;
|
||||
|
||||
z = (block_t) ind_zone << zone_shift;
|
||||
if (a_dindir != z) {
|
||||
readblock(z, dindir, block_size);
|
||||
a_dindir= z;
|
||||
}
|
||||
/* Extract the indirect zone number from it */
|
||||
zone -= (zone_t) nr_indirects;
|
||||
|
||||
i = zone / (zone_t) nr_indirects;
|
||||
ind_zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
|
||||
? fsbuf(dindir).b__v2_ind[i]
|
||||
: fsbuf(dindir).b__v1_ind[i];
|
||||
zone %= (zone_t) nr_indirects;
|
||||
}
|
||||
if (ind_zone == 0) return 0;
|
||||
|
||||
/* Extract the datablock number from the indirect zone */
|
||||
z = (block_t) ind_zone << zone_shift;
|
||||
if (a_indir != z) {
|
||||
readblock(z, indir, block_size);
|
||||
a_indir= z;
|
||||
}
|
||||
zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
|
||||
? fsbuf(indir).b__v2_ind[(int) zone]
|
||||
: fsbuf(indir).b__v1_ind[(int) zone];
|
||||
|
||||
/* Calculate absolute datablock number */
|
||||
z = ((block_t) zone << zone_shift) + zone_index;
|
||||
return z;
|
||||
}
|
||||
|
||||
ino_t r_lookup(Ino_t cwd, const char *path)
|
||||
/* Translates a pathname to an inode number. This is just a nice utility
|
||||
* function, it only needs r_stat and r_readdir.
|
||||
*/
|
||||
{
|
||||
char name[NAME_MAX+1], r_name[NAME_MAX+1];
|
||||
char *n;
|
||||
struct stat st;
|
||||
ino_t ino;
|
||||
|
||||
ino= path[0] == '/' ? ROOT_INO : cwd;
|
||||
|
||||
for (;;) {
|
||||
if (ino == 0) {
|
||||
errno= ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (*path == '/') path++;
|
||||
|
||||
if (*path == 0) return ino;
|
||||
|
||||
r_stat(ino, &st);
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
errno= ENOTDIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
n= name;
|
||||
while (*path != 0 && *path != '/')
|
||||
if (n < name + NAME_MAX) *n++ = *path++;
|
||||
*n= 0;
|
||||
|
||||
while ((ino= r_readdir(r_name)) != 0
|
||||
&& strcmp(name, r_name) != 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: rawfs.c,v 1.8 1999/11/05 23:14:15 philip Exp $
|
||||
*/
|
||||
48
boot/rawfs.h
48
boot/rawfs.h
@@ -1,48 +0,0 @@
|
||||
/* rawfs.h - Raw Minix file system support. Author: Kees J. Bot
|
||||
*
|
||||
* off_t r_super(int *block_size);
|
||||
* Initialize variables, returns the size of a valid Minix
|
||||
* file system blocks, but zero on error.
|
||||
*
|
||||
* void r_stat(ino_t file, struct stat *stp);
|
||||
* Return information about a file like stat(2) and
|
||||
* remembers file for the next two calls.
|
||||
*
|
||||
* off_t r_vir2abs(off_t virblockno);
|
||||
* Translate virtual block number in file to absolute
|
||||
* disk block number. Returns 0 if the file contains
|
||||
* a hole, or -1 if the block lies past the end of file.
|
||||
*
|
||||
* ino_t r_readdir(char *name);
|
||||
* Return next directory entry or 0 if there are no more.
|
||||
* Returns -1 and sets errno on error.
|
||||
*
|
||||
* ino_t r_lookup(ino_t cwd, const char *path);
|
||||
* A utility function that translates a pathname to an
|
||||
* inode number. It starts from directory "cwd" unless
|
||||
* path starts with a '/', then from ROOT_INO.
|
||||
* Returns 0 and sets errno on error.
|
||||
*
|
||||
* One function needs to be provided by the outside world:
|
||||
*
|
||||
* void readblock(off_t blockno, char *buf, int block_size);
|
||||
* Read a block into the buffer. Outside world handles
|
||||
* errors.
|
||||
*/
|
||||
|
||||
#ifndef INC_RAWFS_H
|
||||
#define INC_RAWFS_H
|
||||
|
||||
#define ROOT_INO ((ino_t) 1) /* Inode nr of root dir. */
|
||||
|
||||
extern off_t r_super(int *);
|
||||
extern void r_stat(Ino_t file, struct stat *stp);
|
||||
extern off_t r_vir2abs(off_t virblockno);
|
||||
extern ino_t r_readdir(char *name);
|
||||
extern ino_t r_lookup(Ino_t cwd, const char *path);
|
||||
|
||||
/*
|
||||
* $PchId: rawfs.h,v 1.4 1996/04/19 08:16:36 philip Exp $
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
BOOT=/boot/boot
|
||||
ROOT=`printroot -r`
|
||||
|
||||
if [ ! -b "$ROOT" ]
|
||||
then echo root device $ROOT not found
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Install boot as $BOOT on current root and patch into $ROOT? (y/N) "
|
||||
read ans
|
||||
|
||||
if [ ! "$ans" = y ]
|
||||
then echo Aborting.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make install || true
|
||||
|
||||
echo Installing boot monitor into $BOOT.
|
||||
cp boot $BOOT
|
||||
|
||||
echo Patching position of $BOOT into $ROOT.
|
||||
installboot -d "$ROOT" /usr/mdec/bootblock $BOOT
|
||||
sync
|
||||
@@ -182,7 +182,7 @@ do
|
||||
des="audio" dev=audio
|
||||
;;
|
||||
14,0)
|
||||
des="audio mixer" dev=mixer
|
||||
des="faulty block device driver" dev=fbd
|
||||
;;
|
||||
15,0)
|
||||
des="kernel log" dev=klog
|
||||
@@ -193,6 +193,9 @@ do
|
||||
17,0)
|
||||
des="hello" dev=hello
|
||||
;;
|
||||
18,0)
|
||||
des="UNIX domain socket" dev=uds
|
||||
;;
|
||||
BAD,BAD)
|
||||
des= dev=
|
||||
;;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SCRIPTS= DESCRIBE.sh
|
||||
MAN=
|
||||
|
||||
.include <minix.prog.mk>
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# M, U - mount or unmount standard devices.
|
||||
|
||||
case $#:$2 in
|
||||
1:|2:-r) ;;
|
||||
*) echo "Usage: $0 <abbreviation> [-r]" >&2; exit 1
|
||||
esac
|
||||
|
||||
. /etc/fstab
|
||||
|
||||
dev=$1 dir=$1
|
||||
|
||||
case $1 in
|
||||
0) dev=/dev/fd0 dir=fd0 ;;
|
||||
1) dev=/dev/fd1 dir=fd1 ;;
|
||||
PS0|at0|fd0|pat0|pc0|ps0) dev=/dev/$dev dir=fd0 ;;
|
||||
PS1|at1|fd1|pat1|pc1|ps1) dev=/dev/$dev dir=fd1 ;;
|
||||
root) dev=$root ;;
|
||||
tmp) dev=$tmp ;;
|
||||
usr) dev=$usr ;;
|
||||
*) dev=/dev/$dev dir=mnt
|
||||
esac
|
||||
|
||||
case $0 in
|
||||
*M) mount $dev /$dir $2 ;;
|
||||
*U) umount $dev
|
||||
esac
|
||||
@@ -1,7 +0,0 @@
|
||||
SCRIPTS= M.sh
|
||||
BINDIR= /bin
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/M ${BINDIR}/U
|
||||
|
||||
.include <minix.prog.mk>
|
||||
@@ -23,7 +23,7 @@ case $#:$1 in
|
||||
ttypa ttypb ttypc ttypd ttype ttypf \
|
||||
ttyq0 ttyq1 ttyq2 ttyq3 ttyq4 ttyq5 ttyq6 ttyq7 ttyq8 ttyq9 \
|
||||
ttyqa ttyqb ttyqc ttyqd ttyqe ttyqf \
|
||||
eth klog random filter hello
|
||||
eth klog random uds filter fbd hello
|
||||
;;
|
||||
0:|1:-\?)
|
||||
cat >&2 <<EOF
|
||||
@@ -45,9 +45,11 @@ Where key is one of the following:
|
||||
audio mixer # Make audio devices
|
||||
klog # Make /dev/klog
|
||||
random # Make /dev/random, /dev/urandom
|
||||
uds # Make /dev/uds
|
||||
kbd # Make /dev/kbd
|
||||
kbdaux # Make /dev/kbdaux
|
||||
filter # Make /dev/filter
|
||||
fbd # Make /dev/fbd
|
||||
hello # Make /dev/hello
|
||||
video # Make /dev/video
|
||||
std # All standard devices
|
||||
@@ -250,6 +252,12 @@ do
|
||||
$e mknod urandom c 16 0; $e chmod 644 urandom
|
||||
$e chgrp operator random urandom
|
||||
;;
|
||||
uds)
|
||||
# unix domain sockets device
|
||||
$e mknod uds c 18 0; $e chmod 644 random
|
||||
$e chgrp operator uds
|
||||
$e chmod 666 uds
|
||||
;;
|
||||
klog)
|
||||
# logging device.
|
||||
$e mknod klog c 15 0
|
||||
@@ -260,6 +268,11 @@ do
|
||||
$e mknod filter b 11 0
|
||||
$e chmod 644 filter
|
||||
;;
|
||||
fbd)
|
||||
# faulty block device driver
|
||||
$e mknod fbd b 14 0
|
||||
$e chmod 600 fbd
|
||||
;;
|
||||
hello)
|
||||
# hello driver
|
||||
$e mknod hello c 17 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SCRIPTS= MAKEDEV.sh
|
||||
MAN=
|
||||
|
||||
.include <minix.prog.mk>
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
# Makefile for commands.
|
||||
|
||||
.include <minix.own.mk>
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
||||
backup badblocks banner basename bigmake binpackage \
|
||||
binpackages binsizes bzip2 bzip2recover cal calendar \
|
||||
cat cawf cd cdiff cdprobe cgrep checkhier chmem \
|
||||
SUBDIR= add_route arp ash at awk \
|
||||
backup badblocks banner basename \
|
||||
btrace cal calendar \
|
||||
cat cawf cd cdprobe checkhier cpp \
|
||||
chmod chown chroot ci cksum cleantmp clear cmp co \
|
||||
comm compress cp crc cron crontab cut datasizes date \
|
||||
dd de decomp16 DESCRIBE dev2name devsize df dhcpd \
|
||||
dhrystone diff dirname dis88 du dumpcore easypack \
|
||||
ed eject elle elvis env expand factor fgrep file \
|
||||
find finger fingerd fix fold format fortune fsck \
|
||||
fsck1 ftp101 ftpd200 getty gomoku grep head host \
|
||||
hostaddr id ifconfig ifdef indent install \
|
||||
comm compress cp crc cron crontab cut \
|
||||
dd decomp16 DESCRIBE dev2name devsize df dhcpd \
|
||||
dhrystone diff dirname diskctl du dumpcore \
|
||||
ed eject elvis env expand factor fbdctl file \
|
||||
find finger fingerd fix fold format fortune fsck.mfs \
|
||||
ftp101 gcore gcov-pull getty grep head hexdump host \
|
||||
hostaddr id ifconfig ifdef install \
|
||||
intr ipcrm ipcs irdpd isoread join kill last leave \
|
||||
lex life loadkeys loadramdisk logger login look lp \
|
||||
lpd ls lspci M m4 mail make MAKEDEV makewhatis man \
|
||||
mdb mesg mined mkdep mkdir mkdist mkfifo mkfs mknod \
|
||||
mkproto modem mount mt netconf newroot nice nm nohup \
|
||||
nonamed od packit packman passwd paste patch pax \
|
||||
less lex loadkeys loadramdisk logger login look lp \
|
||||
lpd ls lspci mail make MAKEDEV \
|
||||
mdb mesg mined mkfifo mkfs.mfs mknod \
|
||||
mkproto modem mount mt netconf newroot nice acknm nohup \
|
||||
nonamed od paste patch pax \
|
||||
ping postinstall poweroff pr prep printf printroot \
|
||||
profile progressbar proto pr_routes ps pwd pwdauth \
|
||||
ramdisk rarpd rawspeed rcp rdate readall readclock \
|
||||
readfs reboot remsync rev rget rlogin rlogind rmdir \
|
||||
rotate rsh rshd sed service setup shar size \
|
||||
sleep slip sort spell split srccrc stat strings strip \
|
||||
stty su sum svclog swapfs swifi sync synctree sysenv \
|
||||
syslogd tail talk talkd tcpd tcpdp tcpstat tee telnet \
|
||||
telnetd term termcap tget time tinyhalt top touch tr \
|
||||
truncate tsort ttt tty udpstat umount uname unexpand \
|
||||
uniq unstack update urlget uud uue version vol wc \
|
||||
whatis whereis which who whoami write writeisofs \
|
||||
xargs yacc yap yes zdump zic zmodem
|
||||
reboot remsync rev rget rlogin rlogind \
|
||||
rotate rsh rshd sed service setup shar acksize \
|
||||
sleep slip sort spell split srccrc \
|
||||
stty su sum svclog swifi sync synctree sysenv \
|
||||
syslogd tail tar tcpd tcpdp tcpstat tee telnet \
|
||||
telnetd term termcap tget time touch tr \
|
||||
truncate tsort tty udpstat umount uname unexpand \
|
||||
unstack update uud uue version vol wc \
|
||||
whereis which who write writeisofs fetch \
|
||||
xargs yacc yes zdump zmodem pkgin_cd \
|
||||
mktemp worldstone updateboot
|
||||
|
||||
.if ${ARCH} == "i386"
|
||||
SUBDIR+= atnormalize dosread fdisk loadfont \
|
||||
mixer autopart part partition playwave postmort \
|
||||
autopart part partition playwave \
|
||||
recwave repartition screendump
|
||||
SUBDIR+= acd asmconv gas2ack
|
||||
.endif
|
||||
|
||||
.include <minix.subdir.mk>
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CPPFLAGS+= -D_MINIX -D_POSIX_SOURCE
|
||||
CPPFLAGS+= -D_MINIX -D_NETBSD_SOURCE -D_MINIX_COMPAT
|
||||
LDADD+= -lminlib -lcompat_minix -lasyn -lterminfo
|
||||
BINDIR?=/usr/bin
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# Makefile for aal
|
||||
|
||||
PROG= aal
|
||||
SRCS= archiver.c print.c rd.c rd_arhdr.c rd_unsig2.c sprint.c \
|
||||
wr_arhdr.c wr_bytes.c wr_int2.c wr_long.c wr_ranlib.c \
|
||||
format.c rd_bytes.c system.c write.c long2str.c
|
||||
CPPFLAGS+= -I${.CURDIR} -DAAL -DSTB -DNDEBUG -DDISTRIBUTION
|
||||
|
||||
LINKS+= ${BINDIR}/aal ${BINDIR}/ar
|
||||
MAN=
|
||||
|
||||
.include <minix.prog.mk>
|
||||
@@ -1,25 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_H_INCLUDED
|
||||
#define __ARCH_H_INCLUDED
|
||||
|
||||
#define ARMAG 0177545
|
||||
#define AALMAG 0177454
|
||||
|
||||
struct ar_hdr {
|
||||
char ar_name[14];
|
||||
long ar_date;
|
||||
char ar_uid;
|
||||
char ar_gid;
|
||||
short ar_mode;
|
||||
long ar_size;
|
||||
};
|
||||
|
||||
#define AR_TOTAL 26
|
||||
#define AR_SIZE 22
|
||||
|
||||
#endif /* __ARCH_H_INCLUDED */
|
||||
@@ -1,796 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* ar - archiver Author: Michiel Huisjes */
|
||||
/* Made into arch/aal by Ceriel Jacobs
|
||||
*/
|
||||
|
||||
static char RcsId[] = "$Header$";
|
||||
|
||||
/*
|
||||
* Usage: [arch|aal] [adprtvx] archive [file] ...
|
||||
* v: verbose
|
||||
* x: extract
|
||||
* a: append
|
||||
* r: replace (append when not in archive)
|
||||
* d: delete
|
||||
* t: print contents of archive
|
||||
* p: print named files
|
||||
* l: temporaries in current directory instead of /usr/tmp
|
||||
* c: don't give "create" message
|
||||
* u: replace only if dated later than member in archive
|
||||
#ifdef DISTRIBUTION
|
||||
* D: make distribution: use distr_time, uid=2, gid=2, mode=0644
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_IREAD
|
||||
#define S_IREAD S_IRUSR
|
||||
#endif
|
||||
#ifndef S_IWRITE
|
||||
#define S_IWRITE S_IWUSR
|
||||
#endif
|
||||
#ifndef S_IEXEC
|
||||
#define S_IEXEC S_IXUSR
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <arch.h>
|
||||
#ifdef AAL
|
||||
#include <ranlib.h>
|
||||
#include <out.h>
|
||||
#define MAGIC_NUMBER AALMAG
|
||||
long offset;
|
||||
struct ranlib *tab;
|
||||
unsigned int tnum = 0;
|
||||
char *tstrtab;
|
||||
unsigned int tssiz = 0;
|
||||
long time();
|
||||
unsigned int tabsz, strtabsz;
|
||||
#else
|
||||
#define MAGIC_NUMBER ARMAG
|
||||
#endif
|
||||
long lseek();
|
||||
|
||||
#define odd(nr) (nr & 01)
|
||||
#define even(nr) (odd(nr) ? nr + 1 : nr)
|
||||
|
||||
typedef char BOOL;
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define READ 0
|
||||
#define APPEND 2
|
||||
#define CREATE 1
|
||||
|
||||
#define MEMBER struct ar_hdr
|
||||
|
||||
#define IO_SIZE (10 * 1024)
|
||||
|
||||
#define equal(str1, str2) (!strncmp((str1), (str2), 14))
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(m) (m & S_IFDIR) /* is a directory */
|
||||
#endif
|
||||
|
||||
BOOL verbose;
|
||||
BOOL app_fl;
|
||||
BOOL ex_fl;
|
||||
BOOL show_fl;
|
||||
BOOL pr_fl;
|
||||
BOOL rep_fl;
|
||||
BOOL del_fl;
|
||||
BOOL nocr_fl;
|
||||
BOOL local_fl;
|
||||
BOOL update_fl;
|
||||
#ifdef DISTRIBUTION
|
||||
BOOL distr_fl;
|
||||
long distr_time;
|
||||
#endif
|
||||
|
||||
int ar_fd;
|
||||
|
||||
char io_buffer[IO_SIZE];
|
||||
|
||||
char *progname;
|
||||
|
||||
char temp_buf[32];
|
||||
char *temp_arch = &temp_buf[0];
|
||||
extern char *mktemp();
|
||||
extern char *ctime();
|
||||
|
||||
usage()
|
||||
{
|
||||
error(TRUE, "usage: %s %s archive [file] ...\n",
|
||||
progname,
|
||||
#ifdef AAL
|
||||
"[acdrtxvlu]"
|
||||
#else
|
||||
"[acdprtxvlu]"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*VARARGS2*/
|
||||
error(quit, str1, str2, str3, str4)
|
||||
BOOL quit;
|
||||
char *str1, *str2, *str3, *str4;
|
||||
{
|
||||
char errbuf[256];
|
||||
|
||||
sprint(errbuf, str1, str2, str3, str4);
|
||||
write(2, errbuf, strlen(errbuf));
|
||||
if (quit) {
|
||||
unlink(temp_arch);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
char *basename(path)
|
||||
char *path;
|
||||
{
|
||||
register char *ptr = path;
|
||||
register char *last = NULL;
|
||||
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == '/')
|
||||
last = ptr;
|
||||
ptr++;
|
||||
}
|
||||
if (last == NULL)
|
||||
return path;
|
||||
if (*(last + 1) == '\0') {
|
||||
*last = '\0';
|
||||
return basename(path);
|
||||
}
|
||||
return last + 1;
|
||||
}
|
||||
|
||||
extern unsigned int rd_unsigned2();
|
||||
|
||||
open_archive(name, mode)
|
||||
register char *name;
|
||||
register int mode;
|
||||
{
|
||||
unsigned short magic = 0;
|
||||
int fd;
|
||||
|
||||
if (mode == CREATE) {
|
||||
if ((fd = creat(name, 0666)) < 0)
|
||||
error(TRUE, "cannot creat %s\n", name);
|
||||
magic = MAGIC_NUMBER;
|
||||
wr_int2(fd, magic);
|
||||
return fd;
|
||||
}
|
||||
|
||||
if ((fd = open(name, mode)) < 0) {
|
||||
if (mode == APPEND) {
|
||||
close(open_archive(name, CREATE));
|
||||
if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name);
|
||||
return open_archive(name, APPEND);
|
||||
}
|
||||
error(TRUE, "cannot open %s\n", name);
|
||||
}
|
||||
lseek(fd, 0L, 0);
|
||||
magic = rd_unsigned2(fd);
|
||||
if (magic != AALMAG && magic != ARMAG)
|
||||
error(TRUE, "%s is not in ar format\n", name);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
void catch(int sig)
|
||||
#else
|
||||
catch()
|
||||
#endif
|
||||
{
|
||||
unlink(temp_arch);
|
||||
_exit (2);
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register char *ptr;
|
||||
int needs_arg = 0;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
if (argc < 3)
|
||||
usage();
|
||||
|
||||
for (ptr = argv[1]; *ptr; ptr++) {
|
||||
switch (*ptr) {
|
||||
case 't' :
|
||||
show_fl = TRUE;
|
||||
break;
|
||||
case 'v' :
|
||||
verbose = TRUE;
|
||||
break;
|
||||
case 'x' :
|
||||
ex_fl = TRUE;
|
||||
break;
|
||||
case 'a' :
|
||||
needs_arg = 1;
|
||||
app_fl = TRUE;
|
||||
break;
|
||||
case 'c' :
|
||||
nocr_fl = TRUE;
|
||||
break;
|
||||
#ifndef AAL
|
||||
case 'p' :
|
||||
needs_arg = 1;
|
||||
pr_fl = TRUE;
|
||||
break;
|
||||
#endif
|
||||
case 'd' :
|
||||
needs_arg = 1;
|
||||
del_fl = TRUE;
|
||||
break;
|
||||
case 'r' :
|
||||
needs_arg = 1;
|
||||
rep_fl = TRUE;
|
||||
break;
|
||||
case 'l' :
|
||||
local_fl = TRUE;
|
||||
break;
|
||||
case 'u' :
|
||||
update_fl = TRUE;
|
||||
break;
|
||||
#ifdef DISTRIBUTION
|
||||
case 'D' :
|
||||
distr_fl = TRUE;
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_arg && argc <= 3)
|
||||
usage();
|
||||
#ifdef DISTRIBUTION
|
||||
if (distr_fl) {
|
||||
struct stat statbuf;
|
||||
|
||||
stat(progname, &statbuf);
|
||||
distr_time = statbuf.st_mtime;
|
||||
}
|
||||
#endif
|
||||
if (local_fl) strcpy(temp_arch, "ar.XXXXXX");
|
||||
else strcpy(temp_arch, "/usr/tmp/ar.XXXXXX");
|
||||
|
||||
if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1)
|
||||
usage();
|
||||
|
||||
if (update_fl && !rep_fl)
|
||||
usage();
|
||||
|
||||
if (rep_fl || del_fl
|
||||
#ifdef AAL
|
||||
|| app_fl
|
||||
#endif
|
||||
) {
|
||||
mktemp(temp_arch);
|
||||
}
|
||||
#ifdef AAL
|
||||
tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib));
|
||||
tstrtab = malloc(4096);
|
||||
if (!tab || !tstrtab) error(TRUE,"Out of core\n");
|
||||
tabsz = 512;
|
||||
strtabsz = 4096;
|
||||
#endif
|
||||
|
||||
signal(SIGINT, catch);
|
||||
get(argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MEMBER *
|
||||
get_member()
|
||||
{
|
||||
static MEMBER member;
|
||||
|
||||
again:
|
||||
if (rd_arhdr(ar_fd, &member) == 0)
|
||||
return NULL;
|
||||
if (member.ar_size < 0) {
|
||||
error(TRUE, "archive has member with negative size\n");
|
||||
}
|
||||
#ifdef AAL
|
||||
if (equal(SYMDEF, member.ar_name)) {
|
||||
lseek(ar_fd, member.ar_size, 1);
|
||||
goto again;
|
||||
}
|
||||
#endif
|
||||
return &member;
|
||||
}
|
||||
|
||||
char *get_mode();
|
||||
|
||||
get(argc, argv)
|
||||
int argc;
|
||||
register char *argv[];
|
||||
{
|
||||
register MEMBER *member;
|
||||
int i = 0;
|
||||
int temp_fd, read_chars;
|
||||
|
||||
ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND);
|
||||
if (rep_fl || del_fl
|
||||
#ifdef AAL
|
||||
|| app_fl
|
||||
#endif
|
||||
)
|
||||
temp_fd = open_archive(temp_arch, CREATE);
|
||||
while ((member = get_member()) != NULL) {
|
||||
if (argc > 3) {
|
||||
for (i = 3; i < argc; i++) {
|
||||
if (equal(basename(argv[i]), member->ar_name))
|
||||
break;
|
||||
}
|
||||
if (i == argc || app_fl) {
|
||||
if (rep_fl || del_fl
|
||||
#ifdef AAL
|
||||
|| app_fl
|
||||
#endif
|
||||
) {
|
||||
#ifdef AAL
|
||||
if (i != argc) {
|
||||
print("%s: already in archive\n", argv[i]);
|
||||
argv[i] = "";
|
||||
}
|
||||
#endif
|
||||
wr_arhdr(temp_fd, member);
|
||||
copy_member(member, ar_fd, temp_fd, 0);
|
||||
}
|
||||
else {
|
||||
#ifndef AAL
|
||||
if (app_fl && i != argc) {
|
||||
print("%s: already in archive\n", argv[i]);
|
||||
argv[i] = "";
|
||||
}
|
||||
#endif
|
||||
lseek(ar_fd, even(member->ar_size),1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ex_fl || pr_fl)
|
||||
extract(member);
|
||||
else {
|
||||
if (rep_fl) {
|
||||
int isold = 0;
|
||||
if(update_fl) {
|
||||
struct stat status;
|
||||
if (stat(argv[i], &status) >= 0) {
|
||||
if(status.st_mtime <= member->ar_date)
|
||||
isold = 1;
|
||||
}
|
||||
}
|
||||
if(!isold)
|
||||
add(argv[i], temp_fd, "r - %s\n");
|
||||
else {
|
||||
wr_arhdr(temp_fd, member);
|
||||
copy_member(member, ar_fd, temp_fd, 0);
|
||||
if(verbose)
|
||||
show("r - %s (old)\n", member->ar_name);
|
||||
}
|
||||
}
|
||||
else if (show_fl) {
|
||||
char buf[sizeof(member->ar_name) + 2];
|
||||
register char *p = buf, *q = member->ar_name;
|
||||
|
||||
while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) {
|
||||
*p++ = *q++;
|
||||
}
|
||||
*p++ = '\n';
|
||||
*p = '\0';
|
||||
if (verbose) {
|
||||
char *mode = get_mode(member->ar_mode);
|
||||
char *date = ctime(&(member->ar_date));
|
||||
|
||||
*(date + 16) = '\0';
|
||||
*(date + 24) = '\0';
|
||||
|
||||
print("%s%3u/%u%7ld %s %s %s",
|
||||
mode,
|
||||
(unsigned) (member->ar_uid & 0377),
|
||||
(unsigned) (member->ar_gid & 0377),
|
||||
member->ar_size,
|
||||
date+4,
|
||||
date+20,
|
||||
buf);
|
||||
}
|
||||
else print(buf);
|
||||
}
|
||||
else if (del_fl)
|
||||
show("d - %s\n", member->ar_name);
|
||||
lseek(ar_fd, even(member->ar_size), 1);
|
||||
}
|
||||
argv[i] = "";
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
for (i = 3; i < argc; i++)
|
||||
if (argv[i][0] != '\0') {
|
||||
#ifndef AAL
|
||||
if (app_fl)
|
||||
add(argv[i], ar_fd, "a - %s\n");
|
||||
else
|
||||
#endif
|
||||
if (rep_fl
|
||||
#ifdef AAL
|
||||
|| app_fl
|
||||
#endif
|
||||
)
|
||||
add(argv[i], temp_fd, "a - %s\n");
|
||||
else {
|
||||
print("%s: not found\n", argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rep_fl || del_fl
|
||||
#ifdef AAL
|
||||
|| app_fl
|
||||
#endif
|
||||
) {
|
||||
signal(SIGINT, SIG_IGN);
|
||||
close(ar_fd);
|
||||
close(temp_fd);
|
||||
ar_fd = open_archive(argv[2], CREATE);
|
||||
temp_fd = open_archive(temp_arch, APPEND);
|
||||
#ifdef AAL
|
||||
write_symdef();
|
||||
#endif
|
||||
while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0)
|
||||
mwrite(ar_fd, io_buffer, read_chars);
|
||||
close(temp_fd);
|
||||
unlink(temp_arch);
|
||||
}
|
||||
close(ar_fd);
|
||||
}
|
||||
|
||||
add(name, fd, mess)
|
||||
char *name;
|
||||
int fd;
|
||||
char *mess;
|
||||
{
|
||||
static MEMBER member;
|
||||
register int read_chars;
|
||||
struct stat status;
|
||||
int src_fd;
|
||||
|
||||
if (stat(name, &status) < 0) {
|
||||
error(FALSE, "cannot find %s\n", name);
|
||||
return;
|
||||
}
|
||||
else if (S_ISDIR(status.st_mode)) {
|
||||
error(FALSE, "%s is a directory (ignored)\n", name);
|
||||
return;
|
||||
}
|
||||
else if ((src_fd = open(name, 0)) < 0) {
|
||||
error(FALSE, "cannot open %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy (member.ar_name, basename (name), sizeof(member.ar_name));
|
||||
member.ar_uid = status.st_uid;
|
||||
member.ar_gid = status.st_gid;
|
||||
member.ar_mode = status.st_mode;
|
||||
member.ar_date = status.st_mtime;
|
||||
member.ar_size = status.st_size;
|
||||
#ifdef DISTRIBUTION
|
||||
if (distr_fl) {
|
||||
member.ar_uid = 2;
|
||||
member.ar_gid = 2;
|
||||
member.ar_mode = 0644;
|
||||
member.ar_date = distr_time;
|
||||
}
|
||||
#endif
|
||||
wr_arhdr(fd, &member);
|
||||
#ifdef AAL
|
||||
do_object(src_fd, member.ar_size);
|
||||
lseek(src_fd, 0L, 0);
|
||||
offset += AR_TOTAL + even(member.ar_size);
|
||||
#endif
|
||||
while (status.st_size > 0) {
|
||||
int x = IO_SIZE;
|
||||
|
||||
read_chars = x;
|
||||
if (status.st_size < x) {
|
||||
x = status.st_size;
|
||||
read_chars = x;
|
||||
status.st_size = 0;
|
||||
x = even(x);
|
||||
}
|
||||
else status.st_size -= x;
|
||||
if (read(src_fd, io_buffer, read_chars) != read_chars) {
|
||||
error(FALSE,"%s seems to shrink\n", name);
|
||||
break;
|
||||
}
|
||||
mwrite(fd, io_buffer, x);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
show(mess, member.ar_name);
|
||||
close(src_fd);
|
||||
}
|
||||
|
||||
extract(member)
|
||||
register MEMBER *member;
|
||||
{
|
||||
int fd = 1;
|
||||
char buf[sizeof(member->ar_name) + 1];
|
||||
|
||||
strncpy(buf, member->ar_name, sizeof(member->ar_name));
|
||||
buf[sizeof(member->ar_name)] = 0;
|
||||
if (pr_fl == FALSE && (fd = creat(buf, 0666)) < 0) {
|
||||
error(FALSE, "cannot create %s\n", buf);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
if (pr_fl == FALSE) show("x - %s\n", buf);
|
||||
else show("\n<%s>\n\n", buf);
|
||||
}
|
||||
|
||||
copy_member(member, ar_fd, fd, 1);
|
||||
|
||||
if (fd >= 0 && fd != 1)
|
||||
close(fd);
|
||||
if (pr_fl == FALSE) chmod(buf, member->ar_mode);
|
||||
}
|
||||
|
||||
copy_member(member, from, to, extracting)
|
||||
register MEMBER *member;
|
||||
int from, to;
|
||||
{
|
||||
register int rest;
|
||||
long mem_size = member->ar_size;
|
||||
BOOL is_odd = odd(mem_size) ? TRUE : FALSE;
|
||||
|
||||
#ifdef AAL
|
||||
if (! extracting) {
|
||||
long pos = lseek(from, 0L, 1);
|
||||
|
||||
do_object(from, mem_size);
|
||||
offset += AR_TOTAL + even(mem_size);
|
||||
lseek(from, pos, 0);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
rest = mem_size > (long) IO_SIZE ? IO_SIZE : (int) mem_size;
|
||||
if (read(from, io_buffer, rest) != rest) {
|
||||
char buf[sizeof(member->ar_name) + 1];
|
||||
|
||||
strncpy(buf, member->ar_name, sizeof(member->ar_name));
|
||||
buf[sizeof(member->ar_name)] = 0;
|
||||
error(TRUE, "read error on %s\n", buf);
|
||||
}
|
||||
if (to >= 0) mwrite(to, io_buffer, rest);
|
||||
mem_size -= (long) rest;
|
||||
} while (mem_size > 0L);
|
||||
|
||||
if (is_odd) {
|
||||
lseek(from, 1L, 1);
|
||||
if (to >= 0 && ! extracting)
|
||||
lseek(to, 1L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
get_mode(mode)
|
||||
register int mode;
|
||||
{
|
||||
static char mode_buf[11];
|
||||
register int tmp = mode;
|
||||
int i;
|
||||
|
||||
mode_buf[9] = ' ';
|
||||
for (i = 0; i < 3; i++) {
|
||||
mode_buf[i * 3] = (tmp & S_IREAD) ? 'r' : '-';
|
||||
mode_buf[i * 3 + 1] = (tmp & S_IWRITE) ? 'w' : '-';
|
||||
mode_buf[i * 3 + 2] = (tmp & S_IEXEC) ? 'x' : '-';
|
||||
tmp <<= 3;
|
||||
}
|
||||
if (mode & S_ISUID)
|
||||
mode_buf[2] = 's';
|
||||
if (mode & S_ISGID)
|
||||
mode_buf[5] = 's';
|
||||
return mode_buf;
|
||||
}
|
||||
|
||||
wr_fatal()
|
||||
{
|
||||
error(TRUE, "write error\n");
|
||||
}
|
||||
|
||||
rd_fatal()
|
||||
{
|
||||
error(TRUE, "read error\n");
|
||||
}
|
||||
|
||||
mwrite(fd, address, bytes)
|
||||
int fd;
|
||||
register char *address;
|
||||
register int bytes;
|
||||
{
|
||||
if (write(fd, address, bytes) != bytes)
|
||||
error(TRUE, "write error\n");
|
||||
}
|
||||
|
||||
show(s, name)
|
||||
char *s, *name;
|
||||
{
|
||||
MEMBER x;
|
||||
char buf[sizeof(x.ar_name)+1];
|
||||
register char *p = buf, *q = name;
|
||||
|
||||
while (q <= &name[sizeof(x.ar_name)-1] && *q) *p++ = *q++;
|
||||
*p++ = '\0';
|
||||
print(s, buf);
|
||||
}
|
||||
|
||||
#ifdef AAL
|
||||
/*
|
||||
* Write out the ranlib table: first 4 bytes telling how many ranlib structs
|
||||
* there are, followed by the ranlib structs,
|
||||
* then 4 bytes giving the size of the string table, followed by the string
|
||||
* table itself.
|
||||
*/
|
||||
write_symdef()
|
||||
{
|
||||
register struct ranlib *ran;
|
||||
register int i;
|
||||
register long delta;
|
||||
MEMBER arbuf;
|
||||
|
||||
if (odd(tssiz))
|
||||
tstrtab[tssiz++] = '\0';
|
||||
for (i = 0; i < sizeof(arbuf.ar_name); i++)
|
||||
arbuf.ar_name[i] = '\0';
|
||||
strcpy(arbuf.ar_name, SYMDEF);
|
||||
arbuf.ar_size = 4 + 2 * 4 * (long)tnum + 4 + (long)tssiz;
|
||||
time(&arbuf.ar_date);
|
||||
arbuf.ar_uid = getuid();
|
||||
arbuf.ar_gid = getgid();
|
||||
arbuf.ar_mode = 0444;
|
||||
#ifdef DISTRIBUTION
|
||||
if (distr_fl) {
|
||||
arbuf.ar_uid = 2;
|
||||
arbuf.ar_gid = 2;
|
||||
arbuf.ar_date = distr_time;
|
||||
}
|
||||
#endif
|
||||
wr_arhdr(ar_fd,&arbuf);
|
||||
wr_long(ar_fd, (long) tnum);
|
||||
/*
|
||||
* Account for the space occupied by the magic number
|
||||
* and the ranlib table.
|
||||
*/
|
||||
delta = 2 + AR_TOTAL + arbuf.ar_size;
|
||||
for (ran = tab; ran < &tab[tnum]; ran++) {
|
||||
ran->ran_pos += delta;
|
||||
}
|
||||
|
||||
wr_ranlib(ar_fd, tab, (long) tnum);
|
||||
wr_long(ar_fd, (long) tssiz);
|
||||
wr_bytes(ar_fd, tstrtab, (long) tssiz);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether the bytes in `buf' form a good object header.
|
||||
* The header is put in `headp'.
|
||||
*/
|
||||
int
|
||||
is_outhead(headp)
|
||||
register struct outhead *headp;
|
||||
{
|
||||
|
||||
return !BADMAGIC(*headp) && headp->oh_nname != 0;
|
||||
}
|
||||
|
||||
do_object(f, size)
|
||||
long size;
|
||||
{
|
||||
struct outhead headbuf;
|
||||
|
||||
if (size < SZ_HEAD) {
|
||||
/* It can't be an object file. */
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Read a header to see if it is an object file.
|
||||
*/
|
||||
if (! rd_fdopen(f)) {
|
||||
rd_fatal();
|
||||
}
|
||||
rd_ohead(&headbuf);
|
||||
if (!is_outhead(&headbuf)) {
|
||||
return;
|
||||
}
|
||||
do_names(&headbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* First skip the names and read in the string table, then seek back to the
|
||||
* name table and read and write the names one by one. Update the ranlib table
|
||||
* accordingly.
|
||||
*/
|
||||
do_names(headp)
|
||||
struct outhead *headp;
|
||||
{
|
||||
register char *strings;
|
||||
register int nnames = headp->oh_nname;
|
||||
#define NNAMES 100
|
||||
struct outname namebuf[NNAMES];
|
||||
long xxx = OFF_CHAR(*headp);
|
||||
|
||||
if ( headp->oh_nchar != (unsigned int)headp->oh_nchar ||
|
||||
(strings = malloc((unsigned int)headp->oh_nchar)) == (char *)0
|
||||
) {
|
||||
error(TRUE, "string table too big\n");
|
||||
}
|
||||
rd_string(strings, headp->oh_nchar);
|
||||
while (nnames) {
|
||||
int i = nnames >= NNAMES ? NNAMES : nnames;
|
||||
register struct outname *p = namebuf;
|
||||
|
||||
nnames -= i;
|
||||
rd_name(namebuf, i);
|
||||
while (i--) {
|
||||
long off = p->on_foff - xxx;
|
||||
if (p->on_foff == (long)0) {
|
||||
p++;
|
||||
continue; /* An unrecognizable name. */
|
||||
}
|
||||
p->on_mptr = strings + off;
|
||||
/*
|
||||
* Only enter names that are exported and are really
|
||||
* defined. Also enter common names. Note, that
|
||||
* this might cause problems when the name is really
|
||||
* defined in a later file, with a value != 0.
|
||||
* However, this problem also exists on the Unix
|
||||
* ranlib archives.
|
||||
*/
|
||||
if ( (p->on_type & S_EXT) &&
|
||||
(p->on_type & S_TYP) != S_UND
|
||||
)
|
||||
enter_name(p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
free(strings);
|
||||
}
|
||||
|
||||
enter_name(namep)
|
||||
struct outname *namep;
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
if (tnum >= tabsz) {
|
||||
tab = (struct ranlib *)
|
||||
realloc((char *) tab, (tabsz += 512) * sizeof(struct ranlib));
|
||||
if (! tab) error(TRUE, "Out of core\n");
|
||||
}
|
||||
tab[tnum].ran_off = tssiz;
|
||||
tab[tnum].ran_pos = offset;
|
||||
|
||||
for (cp = namep->on_mptr;; cp++) {
|
||||
if (tssiz >= strtabsz) {
|
||||
tstrtab = realloc(tstrtab, (strtabsz += 4096));
|
||||
if (! tstrtab) error(TRUE, "string table overflow\n");
|
||||
}
|
||||
tstrtab[tssiz++] = *cp;
|
||||
if (!*cp) break;
|
||||
}
|
||||
tnum++;
|
||||
}
|
||||
#endif /* AAL */
|
||||
@@ -1,9 +0,0 @@
|
||||
#if defined(mc68020) || defined(mc68000) || defined(sparc)
|
||||
#define BYTES_REVERSED 1
|
||||
#define WORDS_REVERSED 1
|
||||
#define CHAR_UNSIGNED 0
|
||||
#else
|
||||
#define BYTES_REVERSED 0
|
||||
#define WORDS_REVERSED 0
|
||||
#define CHAR_UNSIGNED 0
|
||||
#endif
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
extern char *long2str();
|
||||
|
||||
static int
|
||||
integral(c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'b':
|
||||
return -2;
|
||||
case 'd':
|
||||
return 10;
|
||||
case 'o':
|
||||
return -8;
|
||||
case 'u':
|
||||
return -10;
|
||||
case 'x':
|
||||
return -16;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*VARARGS2*/
|
||||
/*FORMAT1 $
|
||||
%s = char *
|
||||
%l = long
|
||||
%c = int
|
||||
%[uxbo] = unsigned int
|
||||
%d = int
|
||||
$ */
|
||||
int
|
||||
_format(buf, fmt, argp)
|
||||
char *buf, *fmt;
|
||||
register va_list argp;
|
||||
{
|
||||
register char *pf = fmt;
|
||||
register char *pb = buf;
|
||||
|
||||
while (*pf) {
|
||||
if (*pf == '%') {
|
||||
register width, base, pad, npad;
|
||||
char *arg;
|
||||
char cbuf[2];
|
||||
char *badformat = "<bad format>";
|
||||
|
||||
/* get padder */
|
||||
if (*++pf == '0') {
|
||||
pad = '0';
|
||||
++pf;
|
||||
}
|
||||
else
|
||||
pad = ' ';
|
||||
|
||||
/* get width */
|
||||
width = 0;
|
||||
while (*pf >= '0' && *pf <= '9')
|
||||
width = 10 * width + *pf++ - '0';
|
||||
|
||||
if (*pf == 's') {
|
||||
arg = va_arg(argp, char *);
|
||||
}
|
||||
else
|
||||
if (*pf == 'c') {
|
||||
cbuf[0] = va_arg(argp, int);
|
||||
cbuf[1] = '\0';
|
||||
arg = &cbuf[0];
|
||||
}
|
||||
else
|
||||
if (*pf == 'l') {
|
||||
/* alignment ??? */
|
||||
if (base = integral(*++pf)) {
|
||||
arg = long2str(va_arg(argp,long), base);
|
||||
}
|
||||
else {
|
||||
pf--;
|
||||
arg = badformat;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (base = integral(*pf)) {
|
||||
arg = long2str((long)va_arg(argp,int), base);
|
||||
}
|
||||
else
|
||||
if (*pf == '%')
|
||||
arg = "%";
|
||||
else
|
||||
arg = badformat;
|
||||
|
||||
npad = width - strlen(arg);
|
||||
|
||||
while (npad-- > 0)
|
||||
*pb++ = pad;
|
||||
|
||||
while (*pb++ = *arg++);
|
||||
pb--;
|
||||
pf++;
|
||||
}
|
||||
else
|
||||
*pb++ = *pf++;
|
||||
}
|
||||
return pb - buf;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* collection of options, selected by including or excluding 'defines' */
|
||||
|
||||
/* Version number of the EM object code */
|
||||
# define VERSION 3 /* 16 bits number */
|
||||
|
||||
/* The default machine used by ack, acc, apc */
|
||||
# define ACKM "minix"
|
||||
|
||||
/* size of local machine, either 0 (for 16 bit address space), or 1 */
|
||||
# undef BIGMACHINE
|
||||
|
||||
/* operating system, SYS_5, V7, BSD4_1 or BSD4_2; Do NOT delete the comment
|
||||
in the next line! */
|
||||
# define V7 1 /* SYSTEM */
|
||||
@@ -1,67 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* Integer to String translator
|
||||
-> base is a value from [-16,-2] V [2,16]
|
||||
-> base < 0: see 'val' as unsigned value
|
||||
-> no checks for buffer overflow and illegal parameters
|
||||
(1985, EHB)
|
||||
*/
|
||||
|
||||
#define MAXWIDTH 32
|
||||
|
||||
char *
|
||||
long2str(val, base)
|
||||
register long val;
|
||||
register base;
|
||||
{
|
||||
static char numbuf[MAXWIDTH];
|
||||
static char vec[] = "0123456789ABCDEF";
|
||||
register char *p = &numbuf[MAXWIDTH];
|
||||
int sign = (base > 0);
|
||||
|
||||
*--p = '\0'; /* null-terminate string */
|
||||
if (val) {
|
||||
if (base > 0) {
|
||||
if (val < 0L) {
|
||||
long v1 = -val;
|
||||
if (v1 == val)
|
||||
goto overflow;
|
||||
val = v1;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
}
|
||||
else
|
||||
if (base < 0) { /* unsigned */
|
||||
base = -base;
|
||||
if (val < 0L) { /* taken from Amoeba src */
|
||||
register mod, i;
|
||||
overflow:
|
||||
mod = 0;
|
||||
for (i = 0; i < 8 * sizeof val; i++) {
|
||||
mod <<= 1;
|
||||
if (val < 0)
|
||||
mod++;
|
||||
val <<= 1;
|
||||
if (mod >= base) {
|
||||
mod -= base;
|
||||
val++;
|
||||
}
|
||||
}
|
||||
*--p = vec[mod];
|
||||
}
|
||||
}
|
||||
do {
|
||||
*--p = vec[(int) (val % base)];
|
||||
val /= base;
|
||||
} while (val != 0L);
|
||||
if (sign)
|
||||
*--p = '-'; /* don't forget it !! */
|
||||
}
|
||||
else
|
||||
*--p = '0'; /* just a simple 0 */
|
||||
return p;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "byte_order.h"
|
||||
#include <local.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if CHAR_UNSIGNED
|
||||
#define Xchar(ch) (ch)
|
||||
#else
|
||||
#define Xchar(ch) ((ch) & 0377)
|
||||
#endif
|
||||
|
||||
#if ! defined(BYTES_REVERSED)
|
||||
#define BYTES_REVERSED 1
|
||||
#endif
|
||||
|
||||
#if ! defined(WORDS_REVERSED)
|
||||
#define WORDS_REVERSED 1
|
||||
#endif
|
||||
|
||||
#if BYTES_REVERSED
|
||||
#define uget2(c) (Xchar((c)[0]) | ((unsigned) Xchar((c)[1]) << 8))
|
||||
#define Xput2(i, c) (((c)[0] = (i)), ((c)[1] = (i) >> 8))
|
||||
#define put2(i, c) { register int j = (i); Xput2(j, c); }
|
||||
#else
|
||||
#define uget2(c) (* ((unsigned short *) (c)))
|
||||
#define Xput2(i, c) (* ((short *) (c)) = (i))
|
||||
#define put2(i, c) Xput2(i, c)
|
||||
#endif
|
||||
|
||||
#define get2(c) ((short) uget2(c))
|
||||
|
||||
#if WORDS_REVERSED || BYTES_REVERSED
|
||||
#define get4(c) (uget2(c) | ((long) uget2((c)+2) << 16))
|
||||
#define put4(l, c) { register long x=(l); \
|
||||
Xput2((int)x,c); \
|
||||
Xput2((int)(x>>16),(c)+2); \
|
||||
}
|
||||
#else
|
||||
#define get4(c) (* ((long *) (c)))
|
||||
#define put4(l, c) (* ((long *) (c)) = (l))
|
||||
#endif
|
||||
|
||||
#define SECTCNT 3 /* number of sections with own output buffer */
|
||||
#if BIGMACHINE
|
||||
#define WBUFSIZ (8*BUFSIZ)
|
||||
#else
|
||||
#define WBUFSIZ BUFSIZ
|
||||
#endif
|
||||
|
||||
struct fil {
|
||||
int cnt;
|
||||
char *pnow;
|
||||
char *pbegin;
|
||||
long currpos;
|
||||
int fd;
|
||||
char pbuf[WBUFSIZ];
|
||||
};
|
||||
|
||||
extern struct fil __parts[];
|
||||
|
||||
#define PARTEMIT 0
|
||||
#define PARTRELO (PARTEMIT+SECTCNT)
|
||||
#define PARTNAME (PARTRELO+1)
|
||||
#define PARTCHAR (PARTNAME+1)
|
||||
#ifdef SYMDBUG
|
||||
#define PARTDBUG (PARTCHAR+1)
|
||||
#else
|
||||
#define PARTDBUG (PARTCHAR+0)
|
||||
#endif
|
||||
#define NPARTS (PARTDBUG + 1)
|
||||
|
||||
#define getsect(s) (PARTEMIT+((s)>=(SECTCNT-1)?(SECTCNT-1):(s)))
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef __OUT_H_INCLUDED
|
||||
#define __OUT_H_INCLUDED
|
||||
/*
|
||||
* output format for ACK assemblers
|
||||
*/
|
||||
#ifndef ushort
|
||||
#define ushort unsigned short
|
||||
#endif /* ushort */
|
||||
|
||||
struct outhead {
|
||||
ushort oh_magic; /* magic number */
|
||||
ushort oh_stamp; /* version stamp */
|
||||
ushort oh_flags; /* several format flags */
|
||||
ushort oh_nsect; /* number of outsect structures */
|
||||
ushort oh_nrelo; /* number of outrelo structures */
|
||||
ushort oh_nname; /* number of outname structures */
|
||||
long oh_nemit; /* sum of all os_flen */
|
||||
long oh_nchar; /* size of string area */
|
||||
};
|
||||
|
||||
#define O_MAGIC 0x0201 /* magic number of output file */
|
||||
#define O_STAMP 0 /* version stamp */
|
||||
#define MAXSECT 64 /* Maximum number of sections */
|
||||
|
||||
#define HF_LINK 0x0004 /* unresolved references left */
|
||||
#define HF_8086 0x0008 /* os_base specially encoded */
|
||||
|
||||
struct outsect {
|
||||
long os_base; /* startaddress in machine */
|
||||
long os_size; /* section size in machine */
|
||||
long os_foff; /* startaddress in file */
|
||||
long os_flen; /* section size in file */
|
||||
long os_lign; /* section alignment */
|
||||
};
|
||||
|
||||
struct outrelo {
|
||||
char or_type; /* type of reference */
|
||||
char or_sect; /* referencing section */
|
||||
ushort or_nami; /* referenced symbol index */
|
||||
long or_addr; /* referencing address */
|
||||
};
|
||||
|
||||
struct outname {
|
||||
union {
|
||||
char *on_ptr; /* symbol name (in core) */
|
||||
long on_off; /* symbol name (in file) */
|
||||
} on_u;
|
||||
#define on_mptr on_u.on_ptr
|
||||
#define on_foff on_u.on_off
|
||||
ushort on_type; /* symbol type */
|
||||
ushort on_desc; /* debug info */
|
||||
long on_valu; /* symbol value */
|
||||
};
|
||||
|
||||
/*
|
||||
* relocation type bits
|
||||
*/
|
||||
#define RELSZ 0x07 /* relocation length */
|
||||
#define RELO1 1 /* 1 byte */
|
||||
#define RELO2 2 /* 2 bytes */
|
||||
#define RELO4 4 /* 4 bytes */
|
||||
#define RELPC 0x08 /* pc relative */
|
||||
#define RELBR 0x10 /* High order byte lowest address. */
|
||||
#define RELWR 0x20 /* High order word lowest address. */
|
||||
|
||||
/*
|
||||
* section type bits and fields
|
||||
*/
|
||||
#define S_TYP 0x007F /* undefined, absolute or relative */
|
||||
#define S_EXT 0x0080 /* external flag */
|
||||
#define S_ETC 0x7F00 /* for symbolic debug, bypassing 'as' */
|
||||
|
||||
/*
|
||||
* S_TYP field values
|
||||
*/
|
||||
#define S_UND 0x0000 /* undefined item */
|
||||
#define S_ABS 0x0001 /* absolute item */
|
||||
#define S_MIN 0x0002 /* first user section */
|
||||
#define S_MAX (S_TYP-1) /* last user section */
|
||||
#define S_CRS S_TYP /* on_valu is symbol index which contains value */
|
||||
|
||||
/*
|
||||
* S_ETC field values
|
||||
*/
|
||||
#define S_SCT 0x0100 /* section names */
|
||||
#define S_LIN 0x0200 /* hll source line item */
|
||||
#define S_FIL 0x0300 /* hll source file item */
|
||||
#define S_MOD 0x0400 /* ass source file item */
|
||||
#define S_COM 0x1000 /* Common name. */
|
||||
#define S_STB 0xe000 /* entries with any of these bits set are
|
||||
reserved for debuggers
|
||||
*/
|
||||
|
||||
/*
|
||||
* structure format strings
|
||||
*/
|
||||
#define SF_HEAD "22222244"
|
||||
#define SF_SECT "44444"
|
||||
#define SF_RELO "1124"
|
||||
#define SF_NAME "4224"
|
||||
|
||||
/*
|
||||
* structure sizes (bytes in file; add digits in SF_*)
|
||||
*/
|
||||
#define SZ_HEAD 20
|
||||
#define SZ_SECT 20
|
||||
#define SZ_RELO 8
|
||||
#define SZ_NAME 12
|
||||
|
||||
/*
|
||||
* file access macros
|
||||
*/
|
||||
#define BADMAGIC(x) ((x).oh_magic!=O_MAGIC)
|
||||
#define OFF_SECT(x) SZ_HEAD
|
||||
#define OFF_EMIT(x) (OFF_SECT(x) + ((long)(x).oh_nsect * SZ_SECT))
|
||||
#define OFF_RELO(x) (OFF_EMIT(x) + (x).oh_nemit)
|
||||
#define OFF_NAME(x) (OFF_RELO(x) + ((long)(x).oh_nrelo * SZ_RELO))
|
||||
#define OFF_CHAR(x) (OFF_NAME(x) + ((long)(x).oh_nname * SZ_NAME))
|
||||
|
||||
#endif /* __OUT_H_INCLUDED */
|
||||
@@ -1,7 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#define SSIZE 1024
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <system.h>
|
||||
#include "param.h"
|
||||
|
||||
/*VARARGS*/
|
||||
/*FORMAT0v $
|
||||
%s = char *
|
||||
%l = long
|
||||
%c = int
|
||||
%[uxbo] = unsigned int
|
||||
%d = int
|
||||
$ */
|
||||
int
|
||||
#if __STDC__
|
||||
print(char *fmt, ...)
|
||||
#else
|
||||
print(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char buf[SSIZE];
|
||||
|
||||
#if __STDC__
|
||||
va_start(args, fmt);
|
||||
#else
|
||||
va_start(args);
|
||||
#endif
|
||||
sys_write(STDOUT, buf, _format(buf, fmt, args));
|
||||
va_end(args);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef __RANLIB_H_INCLUDED
|
||||
#define __RANLIB_H_INCLUDED
|
||||
|
||||
#ifndef SYMDEF
|
||||
# define SYMDEF "__.SYMDEF"
|
||||
#endif /* SYMDEF */
|
||||
|
||||
/*
|
||||
* Structure of the SYMDEF table of contents for an archive.
|
||||
* SYMDEF begins with a long giving the number of ranlib
|
||||
* structures that immediately follow, and then continues with a string
|
||||
* table consisting of a long giving the number of bytes of
|
||||
* strings that follow and then the strings themselves.
|
||||
*/
|
||||
struct ranlib {
|
||||
union {
|
||||
char *ran__ptr; /* symbol name (in core) */
|
||||
long ran__off; /* symbol name (in file) */
|
||||
} ran_u;
|
||||
#define ran_ptr ran_u.ran__ptr
|
||||
#define ran_off ran_u.ran__off
|
||||
long ran_pos; /* library member is at this position */
|
||||
};
|
||||
|
||||
#define SZ_RAN 8
|
||||
#define SF_RAN "44"
|
||||
|
||||
#endif /* __RANLIB_H_INCLUDED */
|
||||
@@ -1,254 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <out.h>
|
||||
#include "object.h"
|
||||
|
||||
extern long lseek();
|
||||
|
||||
/*
|
||||
* Parts of the output file.
|
||||
*/
|
||||
#undef PARTEMIT
|
||||
#undef PARTRELO
|
||||
#undef PARTNAME
|
||||
#undef PARTCHAR
|
||||
#undef PARTDBUG
|
||||
#undef NPARTS
|
||||
|
||||
#define PARTEMIT 0
|
||||
#define PARTRELO 1
|
||||
#define PARTNAME 2
|
||||
#define PARTCHAR 3
|
||||
#ifdef SYMDBUG
|
||||
#define PARTDBUG 4
|
||||
#else
|
||||
#define PARTDBUG 3
|
||||
#endif
|
||||
#define NPARTS (PARTDBUG + 1)
|
||||
|
||||
static long offset[MAXSECT];
|
||||
|
||||
static int outfile;
|
||||
static long outseek[NPARTS];
|
||||
static long currpos;
|
||||
static long rd_base;
|
||||
#define OUTSECT(i) \
|
||||
(outseek[PARTEMIT] = offset[i])
|
||||
#define BEGINSEEK(p, o) \
|
||||
(outseek[(p)] = (o))
|
||||
|
||||
static int sectionnr;
|
||||
|
||||
static
|
||||
OUTREAD(p, b, n)
|
||||
char *b;
|
||||
long n;
|
||||
{
|
||||
register long l = outseek[p];
|
||||
|
||||
if (currpos != l) {
|
||||
lseek(outfile, l, 0);
|
||||
}
|
||||
rd_bytes(outfile, b, n);
|
||||
l += n;
|
||||
currpos = l;
|
||||
outseek[p] = l;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the output file according to the chosen strategy.
|
||||
*/
|
||||
int
|
||||
rd_open(f)
|
||||
char *f;
|
||||
{
|
||||
|
||||
if ((outfile = open(f, 0)) < 0)
|
||||
return 0;
|
||||
return rd_fdopen(outfile);
|
||||
}
|
||||
|
||||
static int offcnt;
|
||||
|
||||
rd_fdopen(fd)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < NPARTS; i++) outseek[i] = 0;
|
||||
offcnt = 0;
|
||||
rd_base = lseek(fd, 0L, 1);
|
||||
if (rd_base < 0) {
|
||||
return 0;
|
||||
}
|
||||
currpos = rd_base;
|
||||
outseek[PARTEMIT] = currpos;
|
||||
outfile = fd;
|
||||
sectionnr = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
rd_close()
|
||||
{
|
||||
|
||||
close(outfile);
|
||||
outfile = -1;
|
||||
}
|
||||
|
||||
rd_fd()
|
||||
{
|
||||
return outfile;
|
||||
}
|
||||
|
||||
rd_ohead(head)
|
||||
register struct outhead *head;
|
||||
{
|
||||
register long off;
|
||||
|
||||
OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outhead) != SZ_HEAD)
|
||||
#endif
|
||||
{
|
||||
register char *c = (char *) head + (SZ_HEAD-4);
|
||||
|
||||
head->oh_nchar = get4(c);
|
||||
c -= 4; head->oh_nemit = get4(c);
|
||||
c -= 2; head->oh_nname = uget2(c);
|
||||
c -= 2; head->oh_nrelo = uget2(c);
|
||||
c -= 2; head->oh_nsect = uget2(c);
|
||||
c -= 2; head->oh_flags = uget2(c);
|
||||
c -= 2; head->oh_stamp = uget2(c);
|
||||
c -= 2; head->oh_magic = uget2(c);
|
||||
}
|
||||
off = OFF_RELO(*head) + rd_base;
|
||||
BEGINSEEK(PARTRELO, off);
|
||||
off += (long) head->oh_nrelo * SZ_RELO;
|
||||
BEGINSEEK(PARTNAME, off);
|
||||
off += (long) head->oh_nname * SZ_NAME;
|
||||
BEGINSEEK(PARTCHAR, off);
|
||||
#ifdef SYMDBUG
|
||||
off += head->oh_nchar;
|
||||
BEGINSEEK(PARTDBUG, off);
|
||||
#endif
|
||||
}
|
||||
|
||||
rd_rew_relos(head)
|
||||
register struct outhead *head;
|
||||
{
|
||||
register long off = OFF_RELO(*head) + rd_base;
|
||||
|
||||
BEGINSEEK(PARTRELO, off);
|
||||
}
|
||||
|
||||
rd_sect(sect, cnt)
|
||||
register struct outsect *sect;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
register char *c = (char *) sect + cnt * SZ_SECT;
|
||||
|
||||
OUTREAD(PARTEMIT, (char *) sect, (long)cnt * SZ_SECT);
|
||||
sect += cnt;
|
||||
offcnt += cnt;
|
||||
while (cnt--) {
|
||||
sect--;
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outsect) != SZ_SECT)
|
||||
#endif
|
||||
{
|
||||
c -= 4; sect->os_lign = get4(c);
|
||||
c -= 4; sect->os_flen = get4(c);
|
||||
c -= 4; sect->os_foff = get4(c);
|
||||
}
|
||||
offset[--offcnt] = sect->os_foff + rd_base;
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outsect) != SZ_SECT)
|
||||
#endif
|
||||
{
|
||||
c -= 4; sect->os_size = get4(c);
|
||||
c -= 4; sect->os_base = get4(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rd_outsect(s)
|
||||
{
|
||||
OUTSECT(s);
|
||||
sectionnr = s;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't have to worry about byte order here.
|
||||
*/
|
||||
rd_emit(emit, cnt)
|
||||
char *emit;
|
||||
long cnt;
|
||||
{
|
||||
OUTREAD(PARTEMIT, emit, cnt);
|
||||
offset[sectionnr] += cnt;
|
||||
}
|
||||
|
||||
rd_relo(relo, cnt)
|
||||
register struct outrelo *relo;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
|
||||
OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outrelo) != SZ_RELO)
|
||||
#endif
|
||||
{
|
||||
register char *c = (char *) relo + (long) cnt * SZ_RELO;
|
||||
|
||||
relo += cnt;
|
||||
while (cnt--) {
|
||||
relo--;
|
||||
c -= 4; relo->or_addr = get4(c);
|
||||
c -= 2; relo->or_nami = uget2(c);
|
||||
relo->or_sect = *--c;
|
||||
relo->or_type = *--c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rd_name(name, cnt)
|
||||
register struct outname *name;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
|
||||
OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outname) != SZ_NAME)
|
||||
#endif
|
||||
{
|
||||
register char *c = (char *) name + (long) cnt * SZ_NAME;
|
||||
|
||||
name += cnt;
|
||||
while (cnt--) {
|
||||
name--;
|
||||
c -= 4; name->on_valu = get4(c);
|
||||
c -= 2; name->on_desc = uget2(c);
|
||||
c -= 2; name->on_type = uget2(c);
|
||||
c -= 4; name->on_foff = get4(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rd_string(addr, len)
|
||||
char *addr;
|
||||
long len;
|
||||
{
|
||||
|
||||
OUTREAD(PARTCHAR, addr, len);
|
||||
}
|
||||
|
||||
#ifdef SYMDBUG
|
||||
rd_dbug(buf, size)
|
||||
char *buf;
|
||||
long size;
|
||||
{
|
||||
OUTREAD(PARTDBUG, buf, size);
|
||||
}
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <arch.h>
|
||||
#include "object.h"
|
||||
|
||||
int
|
||||
rd_arhdr(fd, arhdr)
|
||||
register struct ar_hdr *arhdr;
|
||||
{
|
||||
char buf[AR_TOTAL];
|
||||
register char *c = buf;
|
||||
register char *p = arhdr->ar_name;
|
||||
register int i;
|
||||
|
||||
i = read(fd, c, AR_TOTAL);
|
||||
if (i == 0) return 0;
|
||||
if (i != AR_TOTAL) {
|
||||
rd_fatal();
|
||||
}
|
||||
i = 14;
|
||||
while (i--) {
|
||||
*p++ = *c++;
|
||||
}
|
||||
arhdr->ar_date = ((long) get2(c)) << 16; c += 2;
|
||||
arhdr->ar_date |= ((long) get2(c)) & 0xffff; c += 2;
|
||||
arhdr->ar_uid = *c++;
|
||||
arhdr->ar_gid = *c++;
|
||||
arhdr->ar_mode = get2(c); c += 2;
|
||||
arhdr->ar_size = (long) get2(c) << 16; c += 2;
|
||||
arhdr->ar_size |= (long) get2(c) & 0xffff;
|
||||
return 1;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define MININT (1 << (sizeof(int) * 8 - 1))
|
||||
#define MAXCHUNK (~MININT) /* Highest count we read(2). */
|
||||
/* Unfortunately, MAXCHUNK is too large with some compilers. Put it in
|
||||
an int!
|
||||
*/
|
||||
|
||||
static int maxchunk = MAXCHUNK;
|
||||
|
||||
/*
|
||||
* We don't have to worry about byte order here.
|
||||
* Just read "cnt" bytes from file-descriptor "fd".
|
||||
*/
|
||||
int
|
||||
rd_bytes(fd, string, cnt)
|
||||
register char *string;
|
||||
register long cnt;
|
||||
{
|
||||
|
||||
while (cnt) {
|
||||
register int n = cnt >= maxchunk ? maxchunk : cnt;
|
||||
|
||||
if (read(fd, string, n) != n)
|
||||
rd_fatal();
|
||||
string += n;
|
||||
cnt -= n;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
|
||||
unsigned int
|
||||
rd_unsigned2(fd)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
rd_bytes(fd, buf, 2L);
|
||||
return uget2(buf);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <system.h>
|
||||
#include "param.h"
|
||||
|
||||
/*VARARGS*/
|
||||
/*FORMAT1v $
|
||||
%s = char *
|
||||
%l = long
|
||||
%c = int
|
||||
%[uxbo] = unsigned int
|
||||
%d = int
|
||||
$ */
|
||||
char *
|
||||
#if __STDC__
|
||||
sprint(char *buf, char *fmt, ...)
|
||||
#else
|
||||
sprint(buf, fmt, va_alist)
|
||||
char *buf, *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
#if __STDC__
|
||||
va_start(args, fmt);
|
||||
#else
|
||||
va_start(args);
|
||||
#endif
|
||||
buf[_format(buf, fmt, args)] = '\0';
|
||||
va_end(args);
|
||||
return buf;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* RCS: $Header$ */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
File _sys_ftab[SYS_NOPEN] = {
|
||||
{ 0, OP_READ},
|
||||
{ 1, OP_APPEND},
|
||||
{ 2, OP_APPEND}
|
||||
};
|
||||
|
||||
File *
|
||||
_get_entry()
|
||||
{
|
||||
register File *fp;
|
||||
|
||||
for (fp = &_sys_ftab[0]; fp < &_sys_ftab[SYS_NOPEN]; fp++)
|
||||
if (fp->o_flags == 0)
|
||||
return fp;
|
||||
return (File *)0;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* RCS: $Header$ */
|
||||
#ifndef __SYSTEM_INCLUDED__
|
||||
#define __SYSTEM_INCLUDED__
|
||||
|
||||
struct _sys_fildes {
|
||||
int o_fd; /* UNIX filedescriptor */
|
||||
int o_flags; /* flags for open; 0 if not used */
|
||||
};
|
||||
|
||||
typedef struct _sys_fildes File;
|
||||
|
||||
extern File _sys_ftab[];
|
||||
|
||||
/* flags for sys_open() */
|
||||
#define OP_READ 01
|
||||
#define OP_WRITE 02
|
||||
#define OP_APPEND 04
|
||||
|
||||
/* flags for sys_access() */
|
||||
#define AC_EXIST 00
|
||||
#define AC_READ 04
|
||||
#define AC_WRITE 02
|
||||
#define AC_EXEC 01
|
||||
|
||||
/* flags for sys_stop() */
|
||||
#define S_END 0
|
||||
#define S_EXIT 1
|
||||
#define S_ABORT 2
|
||||
|
||||
/* standard file decsriptors */
|
||||
#define STDIN &_sys_ftab[0]
|
||||
#define STDOUT &_sys_ftab[1]
|
||||
#define STDERR &_sys_ftab[2]
|
||||
|
||||
/* maximum number of open files */
|
||||
#define SYS_NOPEN 20
|
||||
|
||||
/* return value for sys_break */
|
||||
#define ILL_BREAK ((char *)0)
|
||||
|
||||
/* system's idea of block */
|
||||
#define BUFSIZ 1024
|
||||
#endif /* __SYSTEM_INCLUDED__ */
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef _VARARGS_H
|
||||
#define _VARARGS_H
|
||||
|
||||
typedef char *va_list;
|
||||
# define __va_sz(mode) (((sizeof(mode) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
|
||||
# define va_dcl int va_alist;
|
||||
# define va_start(list) (list = (char *) &va_alist)
|
||||
# define va_end(list)
|
||||
# define va_arg(list,mode) (*((mode *)((list += __va_sz(mode)) - __va_sz(mode))))
|
||||
#endif /* _VARARGS_H */
|
||||
@@ -1,28 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <arch.h>
|
||||
#include "object.h"
|
||||
|
||||
wr_arhdr(fd, arhdr)
|
||||
register struct ar_hdr *arhdr;
|
||||
{
|
||||
char buf[AR_TOTAL];
|
||||
register char *c = buf;
|
||||
register char *p = arhdr->ar_name;
|
||||
register int i = 14;
|
||||
|
||||
while (i--) {
|
||||
*c++ = *p++;
|
||||
}
|
||||
put2((int)(arhdr->ar_date>>16),c); c += 2;
|
||||
put2((int)(arhdr->ar_date),c); c += 2;
|
||||
*c++ = arhdr->ar_uid;
|
||||
*c++ = arhdr->ar_gid;
|
||||
put2(arhdr->ar_mode,c); c += 2;
|
||||
put2((int)(arhdr->ar_size>>16),c); c += 2;
|
||||
put2((int)(arhdr->ar_size),c);
|
||||
wr_bytes(fd, buf, (long) AR_TOTAL);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#define MININT (1 << (sizeof(int) * 8 - 1))
|
||||
#define MAXCHUNK (~MININT) /* Highest count we write(2). */
|
||||
/* Notice that MAXCHUNK itself might be too large with some compilers.
|
||||
You have to put it in an int!
|
||||
*/
|
||||
|
||||
static int maxchunk = MAXCHUNK;
|
||||
|
||||
/*
|
||||
* Just write "cnt" bytes to file-descriptor "fd".
|
||||
*/
|
||||
wr_bytes(fd, string, cnt)
|
||||
register char *string;
|
||||
register long cnt;
|
||||
{
|
||||
|
||||
while (cnt) {
|
||||
register int n = cnt >= maxchunk ? maxchunk : cnt;
|
||||
|
||||
if (write(fd, string, n) != n)
|
||||
wr_fatal();
|
||||
string += n;
|
||||
cnt -= n;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
|
||||
wr_int2(fd, i)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
put2(i, buf);
|
||||
wr_bytes(fd, buf, 2L);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
|
||||
wr_long(fd, l)
|
||||
long l;
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
put4(l, buf);
|
||||
wr_bytes(fd, buf, 4L);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <ranlib.h>
|
||||
#include "object.h"
|
||||
|
||||
wr_ranlib(fd, ran, cnt)
|
||||
register struct ranlib *ran;
|
||||
register long cnt;
|
||||
{
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof (struct ranlib) != SZ_RAN)
|
||||
#endif
|
||||
{
|
||||
char buf[100 * SZ_RAN];
|
||||
|
||||
while (cnt) {
|
||||
register int i = (cnt > 100) ? 100 : cnt;
|
||||
register char *c = buf;
|
||||
long j = i * SZ_RAN;
|
||||
|
||||
cnt -= i;
|
||||
while (i--) {
|
||||
put4(ran->ran_off,c); c += 4;
|
||||
put4(ran->ran_pos,c); c += 4;
|
||||
ran++;
|
||||
}
|
||||
wr_bytes(fd, buf, j);
|
||||
}
|
||||
}
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
else wr_bytes(fd, (char *) ran, cnt * SZ_RAN);
|
||||
#endif
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
int
|
||||
sys_write(fp, bufptr, nbytes)
|
||||
File *fp;
|
||||
char *bufptr;
|
||||
int nbytes;
|
||||
{
|
||||
if (! fp) return 0;
|
||||
return write(fp->o_fd, bufptr, nbytes) == nbytes;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
# Makefile for acd
|
||||
|
||||
.include <minix.own.mk>
|
||||
|
||||
PROG= acd
|
||||
CPPFLAGS+= -DARCH=\"`arch`\" -DDESCR=\"/usr/lib/descr\"
|
||||
LINKS+= ${BINDIR}/acd ${BINDIR}/cc
|
||||
FILESDIR= /usr/lib
|
||||
FILES= acd.descr
|
||||
FILESNAME= descr
|
||||
MAN=
|
||||
|
||||
.include <minix.prog.mk>
|
||||
2701
commands/acd/acd.c
2701
commands/acd/acd.c
File diff suppressed because it is too large
Load Diff
@@ -1,438 +0,0 @@
|
||||
# ACD pass description for the ACK compilers.
|
||||
#
|
||||
# Pre-set variables.
|
||||
# PROGRAM - Name the compiler driver is called with.
|
||||
# ARCH - Default target architecture.
|
||||
|
||||
# Library directories search path.
|
||||
L = /lib /usr/lib
|
||||
|
||||
# ACK Compilers support search path.
|
||||
A = $L $L/ack
|
||||
|
||||
# ARCH must be defined.
|
||||
ifndef ARCH
|
||||
error "\$ARCH is not predefined"
|
||||
|
||||
# Get ARCH from the environment if set.
|
||||
import ARCH
|
||||
|
||||
# Compiler passes.
|
||||
ACK_CPP = $A/cpp.ansi $CPP_F $PREDEF $NOLINENO
|
||||
ACK_CEM = $A/em_cemcom.ansi -L $CPP_F $PREDEF \
|
||||
-Vw${W}.${W}i${W}.${W}p${P}.${W}f4.${W}s2.2l4.${W}d8.${W}
|
||||
ACK_M2 = $A/em_m2 -I$MOD_INCL -WR \
|
||||
-Vw${W}.${W}i${W}.${W}p${P}.${W}l4.${W}f4.${W}d8.${W}
|
||||
ACK_PC = $A/em_pc \
|
||||
-Vw${W}.${W}i${W}.${W}l4.${W}p${P}.${W}f8.${W}S${W}.${W}
|
||||
MOD_INCL = $A/m2 +
|
||||
ACK_DECODE = $A/em_decode
|
||||
ACK_ENCODE = $A/em_encode
|
||||
ACK_OPT = $A/em_opt
|
||||
ACK_EGO = $A/em_ego -P $A/ego -M$EGO_DESCR
|
||||
EGO_DESCR = $A/ego/${ARCH}descr +
|
||||
ACK_OPT2 = $A/em_opt2
|
||||
ACK_CG = $A/$ARCH/cg
|
||||
ACK_AS = $A/$ARCH/as \-
|
||||
ACK_LED = $A/em_led -a0:$W -a1:$W -a2:$W -a3:$W
|
||||
ACK_CV = $A/cv
|
||||
ASMCONV = /usr/bin/asmconv
|
||||
AAL = /usr/bin/aal
|
||||
|
||||
# Minix predefined symbols.
|
||||
CPP_F = -D__minix -D__minix3 -D__$ARCH
|
||||
|
||||
# Library path.
|
||||
LIBPATH = $USERLIBPATH $A/$ARCH
|
||||
|
||||
# Default output "model".
|
||||
MODEL = -sep
|
||||
|
||||
# Floating point is done in software.
|
||||
LIBS = -fsoft
|
||||
|
||||
# Default optimization level.
|
||||
OPT_LEVEL = 1
|
||||
|
||||
# Call names.
|
||||
if $PROGRAM = acc
|
||||
PROGRAM = cc
|
||||
if $PROGRAM = apc
|
||||
PROGRAM = pc
|
||||
if $PROGRAM = am2
|
||||
PROGRAM = m2
|
||||
if $PROGRAM = kcc
|
||||
PROGRAM = cc
|
||||
|
||||
# Default transformation target.
|
||||
stop .out
|
||||
|
||||
# Select the runtime environment by option or program name.
|
||||
arg -.c
|
||||
if $PROGRAM = cc
|
||||
ifndef RTSO
|
||||
RTSO = -.c
|
||||
LIBS = $LIBS + -.c
|
||||
|
||||
# Omit the runtime startoff, but keep the libraries.
|
||||
arg -.o
|
||||
RTSO =
|
||||
|
||||
arg -.$any
|
||||
error ".$any: unknown language"
|
||||
|
||||
# Select the target architecture.
|
||||
arg -m$arch
|
||||
ARCH = $arch
|
||||
|
||||
# Preprocessor directives.
|
||||
arg -D$name
|
||||
arg -D $name
|
||||
CPP_F = $CPP_F -D$name
|
||||
arg -U$name
|
||||
arg -U $name
|
||||
CPP_F = $CPP_F -U$name
|
||||
arg -I$dir
|
||||
arg -I $dir
|
||||
CPP_F = $CPP_F -I$dir
|
||||
ACK_M2 = $ACK_M2 -I$dir
|
||||
|
||||
# Debugging.
|
||||
arg -g # Add debugging info.
|
||||
ACK_CEM = $ACK_CEM -g
|
||||
ACK_CG = $ACK_CG -gdb
|
||||
|
||||
arg -n # Suppress line numbers.
|
||||
ACK_M2 = $ACK_M2 -L
|
||||
ACK_PC = $ACK_PC -L
|
||||
arg -a # Enable assertions.
|
||||
arg -A # Enable array bound checks.
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
ACK_PC = $ACK_PC $*
|
||||
|
||||
# Language checking.
|
||||
arg -w # No warnings.
|
||||
ACK_CEM = $ACK_CEM $*
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
ACK_PC = $ACK_PC $*
|
||||
|
||||
arg -ws # No strict warnings.
|
||||
ACK_CEM = $ACK_CEM -s
|
||||
ACK_M2 = $ACK_M2 -wR
|
||||
|
||||
arg -wa # No warnings and no strict warnings.
|
||||
ACK_CEM = $ACK_CEM -a
|
||||
ACK_M2 = $ACK_M2 -wR
|
||||
|
||||
arg -wo # No warnings about old style C.
|
||||
ACK_CPP = $ACK_CPP -o
|
||||
ACK_CEM = $ACK_CEM -o
|
||||
ACK_M2 = $ACK_M2 -wO
|
||||
|
||||
arg -3 # Only accept 3rd generation Modula-2.
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
|
||||
arg -_ # Allow underscores in identifiers.
|
||||
ACK_M2 = $ACK_M2 -U
|
||||
ACK_PC = $ACK_PC -U
|
||||
|
||||
arg -w$any
|
||||
arg -F
|
||||
arg -m
|
||||
# Ignore strange -w flags, and past and present i86 compiler flags.
|
||||
|
||||
# Stop suffix.
|
||||
arg -c
|
||||
stop .o
|
||||
|
||||
arg -c.$stop
|
||||
stop .$stop
|
||||
|
||||
arg -E
|
||||
stop .E
|
||||
|
||||
arg -P
|
||||
CPP_F = $CPP_F -P
|
||||
stop .i
|
||||
|
||||
arg -S
|
||||
stop .s
|
||||
|
||||
# Optimization.
|
||||
arg -O
|
||||
OPT_LEVEL = 1
|
||||
|
||||
arg -OS # Optimize for size.
|
||||
ACK_EGO = $ACK_EGO -S
|
||||
arg -OT # Optimize for time.
|
||||
ACK_EGO = $ACK_EGO -T
|
||||
|
||||
arg -O$n
|
||||
numeric $n
|
||||
OPT_LEVEL = $n
|
||||
|
||||
# Library search path.
|
||||
arg -L$dir
|
||||
arg -L $dir
|
||||
USERLIBPATH = $USERLIBPATH $dir/$ARCH $dir
|
||||
|
||||
# -llib must be searched in $LIBPATH later.
|
||||
arg -l$lib
|
||||
arg -l $lib
|
||||
$> = $LIBPATH/lib$lib.a
|
||||
|
||||
# Software floating point, hardware floating point, or no floating point.
|
||||
arg -f
|
||||
arg -fp
|
||||
arg -fsoft
|
||||
LIBS = $LIBS + -fsoft
|
||||
|
||||
arg -fhard
|
||||
LIBS = $LIBS - -fsoft
|
||||
|
||||
arg -fnone
|
||||
LIBS = $LIBS + -fnone
|
||||
|
||||
# Output model.
|
||||
arg -com
|
||||
MODEL = # Common I&D.
|
||||
|
||||
arg -sep
|
||||
arg -i # Separate I&D.
|
||||
MODEL = -sep
|
||||
|
||||
arg -r # Relocatable object (combined .o)
|
||||
MODEL = -r
|
||||
|
||||
# Strip executable.
|
||||
arg -s
|
||||
ACK_LED = $ACK_LED -s
|
||||
|
||||
# Size of heap+stack.
|
||||
arg -stack $size
|
||||
ACK_CV = $ACK_CV -S $size
|
||||
|
||||
# Change output file.
|
||||
arg -o$out
|
||||
arg -o $out
|
||||
OUT = $out
|
||||
|
||||
# Complain about just -D, -U, -I, ...
|
||||
arg -D; arg -U; arg -I; arg -L; arg -l; arg -o; arg -stack
|
||||
error "argument expected after '$*'"
|
||||
|
||||
arg -R$pass-$flag # The ACK way of passing options to passes.
|
||||
arg -Wack-R$pass-$flag # The ACD way.
|
||||
if $pass = cpp
|
||||
ACK_CPP = $ACK_CPP -$flag
|
||||
if $pass = cem
|
||||
ACK_CEM = $ACK_CEM -$flag
|
||||
if $pass = m2
|
||||
ACK_M2 = $ACK_M2 -$flag
|
||||
if $pass = pc
|
||||
ACK_PC = $ACK_PC -$flag
|
||||
if $pass = opt
|
||||
ACK_OPT = $ACK_OPT -$flag
|
||||
if $pass = ego
|
||||
ACK_EGO = $ACK_EGO -$flag
|
||||
if $pass = opt2
|
||||
ACK_OPT2 = $ACK_OPT2 -$flag
|
||||
if $pass = cg
|
||||
ACK_CG = $ACK_CG -$flag
|
||||
if $pass = as
|
||||
ACK_AS = $ACK_AS -$flag
|
||||
if $pass = led
|
||||
ACK_LED = $ACK_LED -$flag
|
||||
|
||||
arg -Was-$dialect # Default assembly dialect.
|
||||
ASDIALECT = $dialect
|
||||
|
||||
arg -W$any
|
||||
# Ignore any other -W options.
|
||||
|
||||
# Complain about unknown options, don't give them to the loader.
|
||||
arg -$any
|
||||
error "$*: unknown option"
|
||||
|
||||
# Do the scanning phase early, we need to know the architecture.
|
||||
scan
|
||||
|
||||
# The word and pointer sizes of the target.
|
||||
if $ARCH = i86
|
||||
W = 2; P = 2
|
||||
if $ARCH = i386
|
||||
W = 4; P = 4
|
||||
|
||||
ifndef W
|
||||
error "$ARCH: unsupported architecture"
|
||||
|
||||
# Optimize -O2 or higher?
|
||||
if (0 1 - $OPT_LEVEL) = (0 1)
|
||||
ACK_EGO = $ACK_EGO -O$OPT_LEVEL
|
||||
ACK_OPT = $ACK_OPT -m0 # Leave multiplication optimization to opt2.
|
||||
prefer .m .gk
|
||||
|
||||
# Tell cem to reverse bitfields on the i386 to be compatible with gcc.
|
||||
if $ARCH = i386
|
||||
ACK_CEM = $ACK_CEM -Vr
|
||||
|
||||
# Predefined preprocessor flags.
|
||||
PREDEF = -D_EM_WSIZE=$W -D_EM_PSIZE=$P -D_EM_SSIZE=2 -D_EM_LSIZE=4 \
|
||||
-D_EM_FSIZE=4 -D_EM_DSIZE=8 -D__ACK__ -D_ACK
|
||||
|
||||
# Preprocess C source.
|
||||
transform .c .i
|
||||
$ACK_CPP $* > $>
|
||||
|
||||
# Preprocess any type of file and send it to standard output or $OUT.
|
||||
transform "" .E
|
||||
if $* = "-"
|
||||
file = # Standard input.
|
||||
else
|
||||
file = $*
|
||||
ifndef OUT
|
||||
$ACK_CPP $file
|
||||
else
|
||||
$ACK_CPP $file > $OUT
|
||||
|
||||
# Compile C source to EM-code.
|
||||
transform .c .k
|
||||
transform .i .k
|
||||
$ACK_CEM $* $>
|
||||
ifndef RTSO
|
||||
RTSO = -.c
|
||||
LIBS = $LIBS + -.c
|
||||
|
||||
# Compact EM to readable EM.
|
||||
transform .k .e
|
||||
transform .m .e
|
||||
transform .gk .e
|
||||
transform .g .e
|
||||
$ACK_DECODE $* > $>
|
||||
|
||||
# Readable EM to compact EM.
|
||||
transform .e .k
|
||||
ifhash $*
|
||||
NOLINENO = -P # Encode chokes on cpp line directives.
|
||||
apply .c .i
|
||||
unset NOLINENO
|
||||
$ACK_ENCODE $* > $>
|
||||
|
||||
# Peephole optimization.
|
||||
transform .k .m
|
||||
$ACK_OPT $* > $>
|
||||
|
||||
# Global optimization.
|
||||
transform .m .gk
|
||||
$ACK_EGO $* > $>
|
||||
|
||||
# Second peephole optimization after global optimization.
|
||||
transform .gk .g
|
||||
$ACK_OPT2 $* > $>
|
||||
|
||||
# EM-code to target machine assembly.
|
||||
transform .m .ack.s
|
||||
transform .g .ack.s
|
||||
transform .m .s
|
||||
transform .g .s
|
||||
if $ARCH = i386
|
||||
$ACK_CG -F__fp_hook $* > $>
|
||||
else
|
||||
$ACK_CG $* > $>
|
||||
|
||||
# How to treat plain .s?
|
||||
ifndef ASDIALECT
|
||||
transform .s .ack.s
|
||||
$> = $*
|
||||
|
||||
# Assembly to object file.
|
||||
transform .ack.s .o
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
if $> = $<.o
|
||||
ifdef OUT
|
||||
$> = $OUT
|
||||
$ACK_AS -o $> $*
|
||||
|
||||
# Combine object files and libraries to an executable.
|
||||
combine (.o .a) .out
|
||||
if $MODEL = ()
|
||||
model = -b0:0
|
||||
if $MODEL = (-sep)
|
||||
model = -b0:0 -b1:0
|
||||
rtso =
|
||||
if $RTSO = -.c
|
||||
rtso = $A/$ARCH/crtso.o
|
||||
libd = ; libc = ; libfp =
|
||||
if (-.c - $LIBS) = ()
|
||||
libd = $A/$ARCH/libd.a
|
||||
libc = $A/$ARCH/libc.a
|
||||
if (-fsoft - $LIBS) = ()
|
||||
libfp = $A/$ARCH/libfp.a
|
||||
libs = $libd $libc $libfp $A/$ARCH/libe.a
|
||||
ifndef OUT
|
||||
OUT = a.out
|
||||
if (-r - $MODEL) = ()
|
||||
# Combine to an object file.
|
||||
$ACK_LED -r -o $OUT $*
|
||||
else
|
||||
# Combine to an executable.
|
||||
mktemp EXE
|
||||
$ACK_LED $model -o $EXE $rtso $* $libs $A/$ARCH/libend.a
|
||||
$ACK_CV -x -m$ARCH $EXE $OUT
|
||||
|
||||
# Add object files to a library.
|
||||
combine (.o) .a
|
||||
if $> = $<.a
|
||||
ifdef OUT
|
||||
$> = $OUT
|
||||
$AAL cr $> $*
|
||||
|
||||
# Assembly conversions.
|
||||
|
||||
# ACK assembly to ACK Xenix assembly.
|
||||
transform .ack.s .ncc.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ack ncc $* $>
|
||||
|
||||
# ACK assembly to GNU assembly.
|
||||
transform .ack.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ack gnu $* $>
|
||||
|
||||
# ACK Xenix assembly to ACK assembly.
|
||||
transform .ncc.s .ack.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ncc ack $* $>
|
||||
|
||||
# ACK Xenix assembly to GNU assembly.
|
||||
transform .ncc.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ncc gnu $* $>
|
||||
|
||||
# BCC assembly to ACK assembly.
|
||||
transform .bas.s .ack.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas ack $* $>
|
||||
|
||||
# BCC assembly to ACK Xenix assembly.
|
||||
transform .bas.s .ncc.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas ncc $* $>
|
||||
|
||||
# BCC assembly to GNU assembly.
|
||||
transform .bas.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas gnu $* $>
|
||||
|
||||
#ifdef ASDIALECT
|
||||
# Treat plain .s as being in the given dialect.
|
||||
transform .s .$ASDIALECT.s
|
||||
$> = $*
|
||||
4
commands/acknm/Makefile
Normal file
4
commands/acknm/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
PROG= acknm
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
4
commands/acksize/Makefile
Normal file
4
commands/acksize/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
PROG= acksize
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -3,4 +3,4 @@ MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/add_route ${BINDIR}/del_route
|
||||
|
||||
.include <minix.prog.mk>
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -181,26 +181,49 @@ int main(int argc, char *argv[])
|
||||
if (!(high_byte & 0x80)) /* class A or 0 */
|
||||
{
|
||||
if (destination)
|
||||
#ifdef __NBSD_LIBC
|
||||
defaultmask= htonl(0xff000000);
|
||||
#else
|
||||
defaultmask= HTONL(0xff000000);
|
||||
#endif
|
||||
|
||||
}
|
||||
else if (!(high_byte & 0x40)) /* class B */
|
||||
{
|
||||
#ifdef __NBSD_LIBC
|
||||
defaultmask= htonl(0xffff0000);
|
||||
#else
|
||||
defaultmask= HTONL(0xffff0000);
|
||||
#endif
|
||||
|
||||
}
|
||||
else if (!(high_byte & 0x20)) /* class C */
|
||||
{
|
||||
#ifdef __NBSD_LIBC
|
||||
defaultmask= htonl(0xffffff00);
|
||||
#else
|
||||
defaultmask= HTONL(0xffffff00);
|
||||
|
||||
#endif
|
||||
}
|
||||
else /* class D is multicast ... */
|
||||
{
|
||||
fprintf(stderr, "%s: Warning: Martian address '%s'\n",
|
||||
prog_name, inet_ntoa(destination));
|
||||
#ifdef __NBSD_LIBC
|
||||
defaultmask= htonl(0xffffffff);
|
||||
#else
|
||||
defaultmask= HTONL(0xffffffff);
|
||||
#endif
|
||||
}
|
||||
if (destination & ~defaultmask)
|
||||
{
|
||||
/* host route */
|
||||
#ifdef __NBSD_LIBC
|
||||
defaultmask= htonl(0xffffffff);
|
||||
#else
|
||||
defaultmask= HTONL(0xffffffff);
|
||||
#endif
|
||||
}
|
||||
if (!cidr)
|
||||
netmask= defaultmask;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
SCRIPTS= adduser.sh
|
||||
MAN=
|
||||
|
||||
.include <minix.prog.mk>
|
||||
@@ -1,121 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# adduser 1.0 - add a new user to the system Author: Kees J. Bot
|
||||
# 16 Jan 1996
|
||||
|
||||
# Check arguments.
|
||||
case "$#" in
|
||||
3) user="$1"; group="$2"; home="$3"
|
||||
;;
|
||||
*) echo "Usage: adduser user group home-dir" >&2; exit 1
|
||||
esac
|
||||
|
||||
# We need to be root.
|
||||
case "`id`" in
|
||||
'uid=0('*)
|
||||
;;
|
||||
*) echo "adduser: you must be root to add users" >&2; exit 1
|
||||
esac
|
||||
|
||||
# User and group names must be alphanumeric and no longer than 8 characters.
|
||||
len=`expr "$user" : '[a-z][a-z0-9]*$'`
|
||||
if [ "$len" -eq 0 -o "$len" -gt 8 ]
|
||||
then
|
||||
echo >&2 \
|
||||
"adduser: the user name must be alphanumeric and no longer than 8 characters"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
len=`expr "$group" : '[a-z][a-z0-9]*$'`
|
||||
if [ "$len" -eq 0 -o "$len" -gt 8 ]
|
||||
then
|
||||
echo >&2 \
|
||||
"adduser: the group name must be alphanumeric and no longer than 8 characters"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The new user name must not exist, but the group must exist.
|
||||
if grep "^$user:" /etc/passwd >/dev/null
|
||||
then
|
||||
echo "adduser: user $user already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gid=`sed -e "/^$group:/!d" -e 's/^[^:]*:[^:]*:\\([^:]*\\):.*/\\1/' /etc/group`
|
||||
if [ `expr "$gid" : '[0-9]*$'` -eq 0 ]
|
||||
then
|
||||
echo "adduser: group $group does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find the first free user-id of 10 or higher.
|
||||
uid=10
|
||||
while grep "^[^:]*:[^:]*:$uid:.*" /etc/passwd >/dev/null
|
||||
do
|
||||
uid=`expr $uid + 1`
|
||||
done
|
||||
|
||||
# No interruptions.
|
||||
trap '' 1 2 3 15
|
||||
|
||||
# Lock the password file.
|
||||
ln /etc/passwd /etc/ptmp || {
|
||||
echo "adduser: password file busy, try again later"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make the new home directory, it should not exist already.
|
||||
mkdir "$home" || {
|
||||
rm -rf /etc/ptmp
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make the new home directory by copying the honorary home directory of our
|
||||
# fearless leader.
|
||||
echo cpdir /usr/ast "$home"
|
||||
cpdir /usr/ast "$home" || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Change the ownership to the new user.
|
||||
echo chown -R $uid:$gid "$home"
|
||||
chown -R $uid:$group "$home" || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is there a shadow password file? If so add an entry.
|
||||
if [ -f /etc/shadow ]
|
||||
then
|
||||
echo "echo $user::0:0::: >>/etc/shadow"
|
||||
echo "$user::0:0:::" >>/etc/shadow || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
pwd="##$user"
|
||||
else
|
||||
pwd=
|
||||
fi
|
||||
|
||||
# Finish up by adding a password file entry.
|
||||
echo "echo $user:$pwd:$uid:$gid:$user:$home: >>/etc/passwd"
|
||||
echo "$user:$pwd:$uid:$gid:$user:$home:" >>/etc/passwd || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Remove the lock.
|
||||
rm /etc/ptmp || exit
|
||||
|
||||
echo "
|
||||
The new user $user has been added to the system. Note that the password,
|
||||
full name, and shell may be changed with the commands passwd(1), chfn(1),
|
||||
and chsh(1). The password is now empty, so only console logins are possible."
|
||||
if [ $gid = 0 ]
|
||||
then
|
||||
echo "\
|
||||
Also note that a new operator needs an executable search path (\$PATH) that
|
||||
does not contain the current directory (an empty field or "." in \$PATH)."
|
||||
fi
|
||||
exit 0
|
||||
@@ -1,28 +0,0 @@
|
||||
# Makefile for advent
|
||||
|
||||
PROG= advent
|
||||
SRCS= advent.c database.c english.c initial.c itverb.c score.c \
|
||||
travel.c turn.c utility.c verb.c vocab.c
|
||||
|
||||
# Where to put the adventure text files
|
||||
# Need the trailing "/" on TEXTDIR
|
||||
TEXTDIR= /usr/lib/advent/
|
||||
FILESDIR= ${TEXTDIR}
|
||||
DATFILES= advent1.dat advent2.dat advent3.dat advent4.dat
|
||||
FILES= ${DATFILES}
|
||||
MAN=
|
||||
|
||||
database.o: advtext.h
|
||||
|
||||
setup: setup.c advent.h
|
||||
${CC} ${CPPFLAGS} ${LDFLAGS} -o setup setup.c
|
||||
|
||||
advtext.h advent1.dat advent2.dat advent3.dat advent4.dat: \
|
||||
setup advent1.txt advent2.txt advent3.txt advent4.txt
|
||||
./setup
|
||||
|
||||
CPPFLAGS.advent.c= -DTEXTDIR='"${TEXTDIR}"'
|
||||
|
||||
CLEANFILES+= ${DATFILES} advtext.h setup
|
||||
|
||||
.include <minix.prog.mk>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,71 +0,0 @@
|
||||
/* header ADVDEC.H *
|
||||
* WARNING: GLOBAL (EXTERNAL) declarations for adventure */
|
||||
|
||||
#ifndef EXTERN /* #define as '' to define the variables */
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
EXTERN boolean gaveup; /* TRUE if he quits early */
|
||||
EXTERN FILE *fd1, *fd2, *fd3, *fd4;
|
||||
|
||||
/*
|
||||
English variables
|
||||
*/
|
||||
EXTERN char *vtxt[MAXWORDS], *iotxt[MAXITEMS], *otxt[MAXITEMS];
|
||||
EXTERN int verbs[MAXWORDS], objs[MAXITEMS], iobjs[MAXITEMS];
|
||||
EXTERN int vrbx, objx, iobx;
|
||||
EXTERN int verb, object, motion, iobj, prep;
|
||||
EXTERN boolean newtravel, is_wiz;
|
||||
|
||||
/*
|
||||
Play variables
|
||||
*/
|
||||
extern int plac[MAXOBJ]; /* initial location */
|
||||
extern int fixd[MAXOBJ];
|
||||
struct playinfo {
|
||||
int turns;
|
||||
int loc, oldloc, oldloc2, newloc; /* location variables */
|
||||
long loc_attrib[MAXLOC+1]; /* location status */
|
||||
int place[MAXOBJ]; /* object location */
|
||||
int fixed[MAXOBJ]; /* second object loc */
|
||||
int weight[MAXOBJ];
|
||||
int atloc[MAXLOC+1];
|
||||
int link[MAXOBJ * 2];
|
||||
int holder[MAXOBJ];
|
||||
int hlink[MAXOBJ];
|
||||
int visited[MAXLOC+1]; /* >0 if has been here */
|
||||
int prop[MAXOBJ]; /* status of object */
|
||||
long obj_state[MAXOBJ];
|
||||
long points[MAXOBJ];
|
||||
int hinted[HNTMAX+1];
|
||||
int hints[HNTMAX+1][5];
|
||||
int hintlc[HNTMAX+1];
|
||||
int tally, tally2; /* item counts */
|
||||
int limit; /* time limit */
|
||||
int lmwarn; /* lamp warning flag */
|
||||
int wzdark, closing, closed; /* game state flags */
|
||||
int holding; /* count of held items */
|
||||
int detail; /* LOOK count */
|
||||
int knfloc; /* knife location */
|
||||
int clock, clock2, panic; /* timing variables */
|
||||
int dloc[DWARFMAX+1]; /* dwarf locations */
|
||||
int dflag; /* dwarf flag */
|
||||
int dseen[DWARFMAX+1]; /* dwarf seen flag */
|
||||
int odloc[DWARFMAX+1]; /* dwarf old locations */
|
||||
int daltloc; /* alternate appearance */
|
||||
int dkill; /* dwarves killed */
|
||||
int chloc, chloc2; /* chest locations */
|
||||
int bonus; /* to pass to end */
|
||||
int numdie; /* number of deaths */
|
||||
int foobar; /* fee fie foe foo... */
|
||||
int combo; /* combination for safe */
|
||||
boolean terse;
|
||||
int abbnum;
|
||||
int health;
|
||||
int chase;
|
||||
boolean flg239;
|
||||
|
||||
|
||||
int lastglob; /* to get space req. */
|
||||
};
|
||||
extern struct playinfo g;
|
||||
@@ -1,136 +0,0 @@
|
||||
/** Adventure translated from Fortran to "C"
|
||||
and ported to Minix by:
|
||||
Robert R. Hall
|
||||
San Diego, Calif 92115
|
||||
hall@crash.cts.com
|
||||
*/
|
||||
|
||||
/** program ADVENT.C *
|
||||
* "advent.c" allocates GLOBAL storage space by *
|
||||
* #defining EXTERN before #including "advdec.h". */
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "advent.h" /* #define preprocessor equates */
|
||||
#include "advdec.h"
|
||||
|
||||
#ifndef TEXTDIR
|
||||
#define TEXTDIR ""
|
||||
#endif
|
||||
|
||||
char textdir[] = TEXTDIR; /* directory where text files
|
||||
live. */
|
||||
|
||||
_PROTOTYPE(int main, (int, char **));
|
||||
_PROTOTYPE(static void opentxt, (void));
|
||||
_PROTOTYPE(static void file_error, (char *));
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
opentxt();
|
||||
initialize();
|
||||
rspeak(325);
|
||||
if (argc == 2)
|
||||
restore(argv[1]);
|
||||
else {
|
||||
g.hinted[3] = yes(65, 1, 0);
|
||||
g.limit = (g.hinted[3] ? 800 : 550);
|
||||
}
|
||||
gaveup = FALSE;
|
||||
srand((unsigned) time(NULL)); /* seed random */
|
||||
while (!gaveup)
|
||||
turn();
|
||||
fclose(fd1);
|
||||
fclose(fd2);
|
||||
fclose(fd3);
|
||||
fclose(fd4);
|
||||
return (EXIT_SUCCESS); /* exit = ok */
|
||||
} /* main */
|
||||
|
||||
/*
|
||||
Open advent?.txt files
|
||||
*/
|
||||
static void opentxt()
|
||||
{
|
||||
static char filename[sizeof(textdir) + 16];
|
||||
static FILE **fp[] = {0, &fd1, &fd2, &fd3, &fd4};
|
||||
int i;
|
||||
for (i = 1; i <= 4; i++) {
|
||||
sprintf(filename, "%sadvent%d.dat", textdir, i);
|
||||
*fp[i] = fopen(filename, "r");
|
||||
if (!*fp[i])
|
||||
file_error(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
save adventure game
|
||||
*/
|
||||
void saveadv(username)
|
||||
char *username;
|
||||
{
|
||||
int cnt;
|
||||
FILE *savefd;
|
||||
|
||||
savefd = fopen(username, "wb");
|
||||
if (savefd == NULL) {
|
||||
perror(username);
|
||||
return;
|
||||
}
|
||||
cnt = fwrite((void *) &g, 1, sizeof(struct playinfo), savefd);
|
||||
if (cnt != sizeof(struct playinfo)) {
|
||||
fprintf(stderr, "wrote %d of %u bytes\n",
|
||||
cnt, (unsigned) sizeof(struct playinfo));
|
||||
if (ferror(savefd)) {
|
||||
fprintf(stderr, "errno is: 0x%.4x\n", errno);
|
||||
perror(username);
|
||||
}
|
||||
}
|
||||
if (fclose(savefd) == -1) {
|
||||
perror(username);
|
||||
}
|
||||
printf("Saved in %s.\n", username);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
restore saved game handler
|
||||
*/
|
||||
void restore(username)
|
||||
char *username;
|
||||
{
|
||||
int cnt;
|
||||
FILE *restfd;
|
||||
|
||||
restfd = fopen(username, "rb");
|
||||
if (restfd == NULL)
|
||||
file_error(username);
|
||||
cnt = fread((void *) &g, 1, sizeof(struct playinfo), restfd);
|
||||
if (cnt != sizeof(struct playinfo)) {
|
||||
fprintf(stderr, "read %d bytes, expected %u\n",
|
||||
cnt, (unsigned) sizeof(struct playinfo));
|
||||
if (ferror(restfd)) {
|
||||
fprintf(stderr, "errno is: 0x%.4x\n", errno);
|
||||
perror(username);
|
||||
}
|
||||
}
|
||||
if (fclose(restfd) == -1) {
|
||||
perror(username);
|
||||
}
|
||||
printf("Restored from %s.\n", username);
|
||||
return;
|
||||
}
|
||||
|
||||
static void file_error(filename)
|
||||
char *filename;
|
||||
{
|
||||
perror(filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -1,405 +0,0 @@
|
||||
/* header ADVENT.H *
|
||||
* WARNING: HEADER file for all adventure modules */
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#define EXIT_SUCCESS (!(EXIT_FAILURE))
|
||||
#endif
|
||||
|
||||
#define INPUTBUFLEN 80 /* Max input line length */
|
||||
|
||||
typedef int boolean;
|
||||
#define FALSE (0)
|
||||
#define TRUE (!FALSE)
|
||||
|
||||
#define MAXOBJ 123 /* max # of objects in cave */
|
||||
#define MAXLOC 248 /* max # of cave locations */
|
||||
#define WORDSIZE 20 /* max # of chars in commands */
|
||||
#define MAXMSG 408 /* max # of long location descr */
|
||||
#define HNTMAX 18 /* max # of hints */
|
||||
#define HNTMIN 7 /* hints starting count */
|
||||
|
||||
#define MAXWORDS 25
|
||||
#define MAXITEMS 45
|
||||
|
||||
#define CLASS(word) ((word)<0 ? -((-(word)) / 1000) : (word) / 1000)
|
||||
#define VAL(word) ((word)<0 ? -((-(word)) % 1000) : (word) % 1000)
|
||||
#define MAXTRAV (23+1) /* max # of travel directions from loc */
|
||||
/* +1 for terminator travel[x].tdest=-1 */
|
||||
#define DWARFMAX 6 /* max # of nasty dwarves */
|
||||
#define MAXDIE 3 /* max # of deaths before close */
|
||||
#define MAXTRS 79 /* max # of */
|
||||
|
||||
#define Y2 33
|
||||
/*
|
||||
Object definitions
|
||||
*/
|
||||
#define ANVIL 91
|
||||
#define AXE 28
|
||||
#define BATTERIES 39
|
||||
#define BEAR 35
|
||||
#define BEES 87
|
||||
#define BILLBD 116
|
||||
#define BIRD 101
|
||||
#define BOAT 48
|
||||
#define BOOK 110
|
||||
#define BOOK2 BOOK + 1
|
||||
#define BOOTH 93
|
||||
#define BOTTLE 20
|
||||
#define BRUSH 114
|
||||
#define CAGE 4
|
||||
#define CAKES 107
|
||||
#define CARVNG 115
|
||||
#define CASK 71
|
||||
#define CHAIN 64
|
||||
#define CHASM 21
|
||||
#define CHASM2 CHASM + 1
|
||||
#define CHEST 55
|
||||
#define CLAM 14
|
||||
#define CLOAK 47
|
||||
#define COINS 54
|
||||
#define CROWN 66
|
||||
#define DOG 98
|
||||
#define DOOR 41 /* giant door */
|
||||
#define DRAGON 31
|
||||
#define DWARF 17
|
||||
#define EGGS 56
|
||||
#define EMERALD 59
|
||||
#define FISSURE 12
|
||||
#define FLOWER 46
|
||||
#define FLY 69
|
||||
#define FOOD 19
|
||||
#define GNOME 105
|
||||
#define GRAIL 70
|
||||
#define GRATE 3
|
||||
#define HIVE 97
|
||||
#define HONEY 96
|
||||
#define HORN 52
|
||||
#define JEWELS 53
|
||||
#define KEYS 102
|
||||
#define KNIFE 18
|
||||
#define LAMP 2
|
||||
#define LYRE 68
|
||||
#define MAGAZINE 16
|
||||
#define MESSAGE 36
|
||||
#define MIRROR 23
|
||||
#define MUSHRM 106
|
||||
#define NUGGET 50
|
||||
#define OIL 83
|
||||
#define OIL2 OIL + 1
|
||||
#define OYSTER 15
|
||||
#define PLAGUE 125
|
||||
#define PEARL 61
|
||||
#define PHONE 94
|
||||
#define PILLOW 10
|
||||
#define PLANT 24
|
||||
#define PLANT2 PLANT + 1
|
||||
#define POLE 9
|
||||
#define POSTER 113
|
||||
#define PYRAMID 60
|
||||
#define RADIUM 119
|
||||
#define RING 72
|
||||
#define ROCKS 92
|
||||
#define ROD 5
|
||||
#define ROD2 ROD + 1
|
||||
#define RUG 62
|
||||
#define SAFE 112
|
||||
#define SAPPHIRE 69
|
||||
#define SHIELD 118
|
||||
#define SHOES 67
|
||||
#define SKEY 90
|
||||
#define SLUGS 95
|
||||
#define SNAKE 11
|
||||
#define SPHERE 120
|
||||
#define SPICES 63
|
||||
#define SPIDER 121
|
||||
#define STEPS 7
|
||||
#define STICKS 49
|
||||
#define SWORD 65
|
||||
#define TABLET 13
|
||||
#define TDOOR 42 /* tiny door */
|
||||
#define TDOOR2 TDOOR + 1 /* wrought-iron door */
|
||||
#define PDOOR TDOOR2 + 1 /* door to phone booth */
|
||||
#define TRIDENT 57
|
||||
#define TROLL 33
|
||||
#define TROLL2 TROLL + 1
|
||||
#define VASE 58
|
||||
#define VEND 38
|
||||
#define WALL 88
|
||||
#define WALL2 WALL + 1
|
||||
#define WATER 81 /* in bottle */
|
||||
#define WATER2 WATER + 1 /* in cask */
|
||||
#define WINE 85 /* in bottle */
|
||||
#define WINE2 WINE + 1 /* in cask */
|
||||
#define WUMPUS 99
|
||||
|
||||
/*
|
||||
Verb definitions
|
||||
*/
|
||||
#define BACK 8
|
||||
#define CAVE 67
|
||||
#define DEPRESSION 63
|
||||
#define ENTRANCE 64
|
||||
#define EXIT 11
|
||||
#define NULLX 21
|
||||
|
||||
/*
|
||||
Action verb definitions
|
||||
*/
|
||||
#define TAKE 1
|
||||
#define DROP 2
|
||||
#define SAY 3
|
||||
#define OPEN 4
|
||||
#define NOTHING 5
|
||||
#define CLOSE 6
|
||||
#define ON 7
|
||||
#define OFF 8
|
||||
#define WAVE 9
|
||||
#define CALM 10
|
||||
#define WALK 11
|
||||
#define KILL 12
|
||||
#define POUR 13
|
||||
#define EAT 14
|
||||
#define DRINK 15
|
||||
#define RUB 16
|
||||
#define THROW 17
|
||||
#define QUIT 18
|
||||
#define FIND 19
|
||||
#define INVENTORY 20
|
||||
#define FEED 21
|
||||
#define FILL 22
|
||||
#define BLAST 23
|
||||
#define SCORE 24
|
||||
#define FOO 25
|
||||
#define BRIEF 26
|
||||
#define READ 27
|
||||
#define BREAK 28
|
||||
#define WAKE 29
|
||||
#define SUSPEND 30
|
||||
#define RESTORE 31
|
||||
#define YANK 32
|
||||
#define WEAR 33
|
||||
#define HIT 34
|
||||
#define ANSWER 35
|
||||
#define BLOW 36
|
||||
#define LEAVE 37
|
||||
#define YELL 38
|
||||
#define DIAL 39
|
||||
#define PLAY 40
|
||||
#define PICK 41
|
||||
#define PUT 42
|
||||
#define TURN 43
|
||||
#define GET 44
|
||||
#define INSRT 45
|
||||
#define REMOVE 46
|
||||
#define BURN 47
|
||||
#define GRIPE 48
|
||||
#define LOCK 49
|
||||
#define UNLOCK 50
|
||||
#define HEALTH 51
|
||||
#define LOOK 52
|
||||
#define COMBO 53
|
||||
#define SWEEP 54
|
||||
#define TERSE 55
|
||||
#define WIZ 56
|
||||
#define MAP 57
|
||||
#define GATE 58
|
||||
#define PIRLOC 59
|
||||
|
||||
#define GO 11
|
||||
#define SHUT 6
|
||||
#define LOG 33
|
||||
|
||||
#define MOTION 0 /* CLASSD */
|
||||
#define NOUN 1 /* CLASSN */
|
||||
#define ACTION 2 /* CLASSA */
|
||||
#define MISC 3 /* CLASSM */
|
||||
#define PREPOSITION 4 /* CLASSP */
|
||||
#define ADJACTIVE 5 /* CLASSJ */
|
||||
#define CONJUNCTION 6 /* CLASSC */
|
||||
|
||||
/*
|
||||
and a few preposition. prefix PREP to distinguish them from
|
||||
verbs or nouns
|
||||
*/
|
||||
#define PREPAT 9
|
||||
#define PREPDN 8
|
||||
#define PREPIN 1
|
||||
#define PREPFR 5
|
||||
#define PREPOF 6
|
||||
#define PREPOFF 6
|
||||
#define PREPON 2
|
||||
|
||||
/*
|
||||
BIT mapping of "cond" array which indicates location status
|
||||
*/
|
||||
#define LIGHT 1
|
||||
#define WATOIL 2
|
||||
#define LIQUID 4
|
||||
#define NOPIRAT 16
|
||||
|
||||
/* Object condition bit functions */
|
||||
#define OPENBT 2
|
||||
#define LOCKBT 4
|
||||
#define BURNBT 6
|
||||
#define DEADBT 10
|
||||
#define WEARBT 12
|
||||
/*
|
||||
Structure definitions
|
||||
*/
|
||||
struct wac {
|
||||
char *aword;
|
||||
int acode;
|
||||
};
|
||||
|
||||
struct trav {
|
||||
int tdest;
|
||||
int tverb;
|
||||
int tcond;
|
||||
};
|
||||
|
||||
/* Function prototypes.
|
||||
"#if (__STDC__)" should have been be enough,
|
||||
but some compilers are stupid, so allow Makefile to say -DHAS_STDC=whatever.
|
||||
*/
|
||||
#if defined(HAS_STDC) ? (HAS_STDC) : (__STDC__)
|
||||
#undef HAS_STDC
|
||||
#define HAS_STDC 1
|
||||
#define _PROTOTYPE(function, params) function params
|
||||
#define _CONST const
|
||||
#else
|
||||
#define _PROTOTYPE(function, params) function ()
|
||||
#define _CONST
|
||||
#endif
|
||||
|
||||
/* Advent.c */
|
||||
|
||||
_PROTOTYPE(void saveadv, (char *username));
|
||||
_PROTOTYPE(void restore, (char *username));
|
||||
|
||||
/* Initialize.c */
|
||||
|
||||
_PROTOTYPE(void initialize, (void));
|
||||
|
||||
/* Database.c */
|
||||
|
||||
_PROTOTYPE(int yes, (int msg1, int msg2, int msg3));
|
||||
_PROTOTYPE(void rspeak, (int msg));
|
||||
_PROTOTYPE(void pspeak, (int item, int state));
|
||||
_PROTOTYPE(void desclg, (int loc));
|
||||
_PROTOTYPE(void descsh, (int loc));
|
||||
|
||||
/* English.c */
|
||||
|
||||
_PROTOTYPE(int english, (void));
|
||||
_PROTOTYPE(int analyze, (char *word, int *type, int *value));
|
||||
|
||||
/* Itverb.c */
|
||||
|
||||
_PROTOTYPE(void itverb, (void));
|
||||
_PROTOTYPE(void ivblast, (void));
|
||||
_PROTOTYPE(void ivlook, (void));
|
||||
|
||||
/* Turn.c */
|
||||
|
||||
_PROTOTYPE(void turn, (void));
|
||||
_PROTOTYPE(void describe, (void));
|
||||
_PROTOTYPE(void descitem, (void));
|
||||
_PROTOTYPE(void dwarfend, (void));
|
||||
_PROTOTYPE(void normend, (void));
|
||||
_PROTOTYPE(void score, (int));
|
||||
_PROTOTYPE(void death, (void));
|
||||
_PROTOTYPE(char *probj, (void));
|
||||
_PROTOTYPE(void trobj, (void));
|
||||
_PROTOTYPE(void dwarves, (void));
|
||||
_PROTOTYPE(void dopirate, (void));
|
||||
_PROTOTYPE(int stimer, (void));
|
||||
|
||||
/* Verb.c */
|
||||
|
||||
_PROTOTYPE(void trverb, (void));
|
||||
_PROTOTYPE(void vtake, (void));
|
||||
_PROTOTYPE(void vdrop, (void));
|
||||
_PROTOTYPE(void vopen, (void));
|
||||
_PROTOTYPE(void vsay, (void));
|
||||
_PROTOTYPE(void von, (void));
|
||||
_PROTOTYPE(void voff, (void));
|
||||
_PROTOTYPE(void vwave, (void));
|
||||
_PROTOTYPE(void vkill, (void));
|
||||
_PROTOTYPE(void vpour, (void));
|
||||
_PROTOTYPE(void veat, (void));
|
||||
_PROTOTYPE(void vdrink, (void));
|
||||
_PROTOTYPE(void vthrow, (void));
|
||||
_PROTOTYPE(void vfind, (void));
|
||||
_PROTOTYPE(void vfill, (void));
|
||||
_PROTOTYPE(void vfeed, (void));
|
||||
_PROTOTYPE(void vread, (void));
|
||||
_PROTOTYPE(void vbreak, (void));
|
||||
_PROTOTYPE(void vwake, (void));
|
||||
_PROTOTYPE(void actspk, (int verb));
|
||||
_PROTOTYPE(void vyank, (void));
|
||||
_PROTOTYPE(void vwear, (void));
|
||||
_PROTOTYPE(void vlock, (void));
|
||||
_PROTOTYPE(void vunlock, (void));
|
||||
_PROTOTYPE(void vclose, (void));
|
||||
|
||||
/* Utility.c */
|
||||
|
||||
_PROTOTYPE(boolean ajar, (int));
|
||||
_PROTOTYPE(boolean at, (int item));
|
||||
_PROTOTYPE(boolean athand, (int));
|
||||
_PROTOTYPE(void bitoff, (int, int));
|
||||
_PROTOTYPE(void biton, (int, int));
|
||||
_PROTOTYPE(boolean bitset, (long, int));
|
||||
_PROTOTYPE(boolean blind, (void));
|
||||
_PROTOTYPE(int burden, (int));
|
||||
_PROTOTYPE(void carry, (int obj, int where));
|
||||
_PROTOTYPE(int confuz, (void));
|
||||
_PROTOTYPE(boolean dark, (void));
|
||||
_PROTOTYPE(boolean dcheck, (void));
|
||||
_PROTOTYPE(boolean dead, (int));
|
||||
_PROTOTYPE(void drop, (int obj, int where));
|
||||
_PROTOTYPE(void destroy, (int obj));
|
||||
_PROTOTYPE(boolean edible, (int));
|
||||
_PROTOTYPE(boolean enclosed, (int));
|
||||
_PROTOTYPE(void extract, (int));
|
||||
_PROTOTYPE(boolean forced, (int atloc));
|
||||
_PROTOTYPE(boolean here, (int item));
|
||||
_PROTOTYPE(boolean hinged, (int));
|
||||
_PROTOTYPE(boolean holding, (int));
|
||||
_PROTOTYPE(void insert, (int, int));
|
||||
_PROTOTYPE(boolean inside, (int));
|
||||
_PROTOTYPE(void juggle, (int loc));
|
||||
_PROTOTYPE(int liq, (int));
|
||||
_PROTOTYPE(int liqloc, (int loc));
|
||||
_PROTOTYPE(int liq2, (int pbottle));
|
||||
_PROTOTYPE(boolean living, (int));
|
||||
_PROTOTYPE(boolean locked, (int));
|
||||
_PROTOTYPE(boolean locks, (int));
|
||||
_PROTOTYPE(void lookin, (int));
|
||||
_PROTOTYPE(void move, (int obj, int where));
|
||||
_PROTOTYPE(int noway, (void));
|
||||
_PROTOTYPE(boolean opaque, (int));
|
||||
_PROTOTYPE(boolean outside, (int));
|
||||
_PROTOTYPE(boolean pct, (int x));
|
||||
_PROTOTYPE(boolean plural, (int));
|
||||
_PROTOTYPE(boolean portal, (int));
|
||||
_PROTOTYPE(boolean printed, (int));
|
||||
_PROTOTYPE(int put, (int obj, int where, int pval));
|
||||
_PROTOTYPE(int ranz, (int));
|
||||
_PROTOTYPE(boolean small, (int));
|
||||
_PROTOTYPE(boolean toting, (int item));
|
||||
_PROTOTYPE(boolean treasr, (int));
|
||||
_PROTOTYPE(boolean vessel, (int));
|
||||
_PROTOTYPE(boolean wearng, (int));
|
||||
_PROTOTYPE(boolean worn, (int));
|
||||
_PROTOTYPE(void bug, (unsigned int n));
|
||||
_PROTOTYPE(char *ask, (char *prompt, char *buf, int buflen));
|
||||
_PROTOTYPE(void panic, (char *msg, boolean save));
|
||||
|
||||
/* travel.c */
|
||||
_PROTOTYPE(void domove, (void));
|
||||
_PROTOTYPE(void gettrav, (int loc, struct trav *travel));
|
||||
|
||||
/* vocab.c */
|
||||
_PROTOTYPE(int vocab, (char *word, int val));
|
||||
@@ -1,827 +0,0 @@
|
||||
#1
|
||||
You are standing at the end of a road before a small brick building.
|
||||
Around you is a forest. A small stream flows out of the building and
|
||||
down a gully.
|
||||
#2
|
||||
You have walked up a hill, still in the forest. The road slopes back
|
||||
down the other side of the hill. There is a building in the distance.
|
||||
#3
|
||||
You are inside a building, a well house for a large spring. Off
|
||||
to one side is a small pantry.
|
||||
#4
|
||||
You are in a valley in the forest beside a stream tumbling along a
|
||||
rocky bed.
|
||||
#5
|
||||
You are in open forest, with a deep valley to one side. Not far
|
||||
is a large billboard.
|
||||
#6
|
||||
You are in open forest near both a valley and a road.
|
||||
#7
|
||||
At your feet all the water of the stream splashes into a 2-inch slit
|
||||
in the rock. Downstream the stream bed is bare rock.
|
||||
#8
|
||||
You are in a 20-foot depression floored with bare dirt. Set into the
|
||||
dirt is a strong steel grate mounted in concrete. A dry stream bed
|
||||
leads into the depression.
|
||||
#9
|
||||
You are in a small chamber beneath a 3x3 steel grate to the surface.
|
||||
A low crawl over cobbles leads inward to the west.
|
||||
#10
|
||||
You are crawling over cobbles in a low passage. There is a dim light
|
||||
at the east end of the passage.
|
||||
#11
|
||||
You are in a debris room filled with stuff washed in from the surface.
|
||||
A low wide passage with cobbles becomes plugged with mud and debris
|
||||
here, but an awkward canyon leads upward and west. A note on the wall
|
||||
says "Magic Word XYZZY".
|
||||
#12
|
||||
You are in an awkward sloping east/west canyon.
|
||||
#13
|
||||
You are in a splendid chamber thirty feet high. The walls are frozen
|
||||
rivers of orange stone. An awkward canyon and a good passage exit
|
||||
from east and west sides of the chamber.
|
||||
#14
|
||||
At your feet is a small pit breathing traces of white mist. An east
|
||||
passage ends here except for a small crack leading on.
|
||||
#15
|
||||
You are at one end of a vast hall stretching forward out of sight to
|
||||
the west. There are openings to either side. Nearby, a wide stone
|
||||
staircase leads downward. The hall is filled with wisps of white mist
|
||||
swaying to and fro almost as if alive. A cold wind blows up the
|
||||
staircase. There is a passage at the top of a dome behind you.
|
||||
#16
|
||||
The crack is far too small for you to follow.
|
||||
#17
|
||||
You are on the east bank of a fissure slicing clear across the hall.
|
||||
The mist is quite thick here, and the fissure is too wide to jump.
|
||||
#18
|
||||
This is a low room with a crude note on the wall. The note says,
|
||||
"You won't get it up the steps".
|
||||
#19
|
||||
You are in the Hall of the Mountain King, with passages off in all
|
||||
directions.
|
||||
#20
|
||||
You are at the bottom of the pit with a broken neck.
|
||||
#21
|
||||
You didn't make it.
|
||||
#22
|
||||
The dome is unclimbable.
|
||||
#23
|
||||
You are at the west end of the Twopit Room. There is a large hole in
|
||||
the wall above the pit at this end of the room.
|
||||
#24
|
||||
You are at the bottom of the eastern pit in the Twopit Room. There is
|
||||
a small pool of oil in one corner of the pit.
|
||||
#25
|
||||
You are at the bottom of the western pit in the Twopit Room. There is
|
||||
a large hole in the wall about 25 feet above you.
|
||||
#26
|
||||
You clamber up the plant and scurry through the hole at the top.
|
||||
#27
|
||||
You are on the west side of the fissure in the Hall of Mists.
|
||||
#28
|
||||
You are in a low N/S passage at a hole in the floor. The hole goes
|
||||
down to an E/W passage.
|
||||
#29
|
||||
You are in the South Side Chamber.
|
||||
#30
|
||||
You are in the West Side Chamber of the Hall of the Mountain King.
|
||||
A passage continues west and up here.
|
||||
#31
|
||||
<$$<
|
||||
#32
|
||||
You can't get by the snake.
|
||||
#33
|
||||
You are in a large room, with a passage to the south, a passage to the
|
||||
west, and a wall of broken rock to the east. There is a large "Y2" on
|
||||
a rock in the room's center.
|
||||
#34
|
||||
You are in a jumble of rock, with cracks everywhere.
|
||||
#35
|
||||
You're at a low window overlooking a huge pit, which extends up out of
|
||||
sight. A floor is indistinctly visible over 50 feet below. Traces of
|
||||
white mist cover the floor of the pit, becoming thicker to the right.
|
||||
Marks in the dust around the window would seem to indicate that
|
||||
someone has been here recently. Directly across the pit from you and
|
||||
25 feet away there is a similar window looking into a lighted room. A
|
||||
shadowy figure can be seen there peering back at you.
|
||||
#36
|
||||
You are in a dirty broken passage. To the east is a crawl. To the
|
||||
west is a large passage. Above you is a hole to another passage.
|
||||
#37
|
||||
You are on the brink of a small clean climbable pit. A crawl leads
|
||||
west.
|
||||
#38
|
||||
You are in the bottom of a small pit with a little stream, which
|
||||
enters and exits through tiny slits.
|
||||
#39
|
||||
You are in a large room full of dusty rocks. There is a big hole in
|
||||
the floor. There are cracks everywhere, and a passage leading east.
|
||||
#40
|
||||
You have crawled through a very low wide passage parallel to and north
|
||||
of the Hall of Mists.
|
||||
#41
|
||||
You are at the west end of Hall of Mists. A low wide crawl continues
|
||||
west and another goes north. To the south is a little passage 6 feet
|
||||
off the floor.
|
||||
#42
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#43
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#44
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#45
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#46
|
||||
Dead end.
|
||||
#47
|
||||
Dead end.
|
||||
#48
|
||||
Dead end.
|
||||
#49
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#50
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#51
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#52
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#53
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#54
|
||||
Dead end.
|
||||
#55
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#56
|
||||
Dead end.
|
||||
#57
|
||||
You are on the brink of a thirty foot pit with a massive orange column
|
||||
down one wall. You could climb down here but you could not get back
|
||||
up. The maze continues at this level.
|
||||
#58
|
||||
Dead end.
|
||||
#59
|
||||
You have crawled through a very low wide passage parallel to and north
|
||||
of the Hall of Mists.
|
||||
#60
|
||||
You are at the east end of a very long hall apparently without side
|
||||
chambers. In the south wall are several wide cracks and a high
|
||||
hole, but the hole is far above your head. To the east a wide
|
||||
crawl slants up. To the north a round two foot hole slants down.
|
||||
#61
|
||||
You are at the west end of a very long featureless hall. The hall
|
||||
joins up with a narrow north/south passage.
|
||||
#62
|
||||
You are at a crossover of a high N/S passage and a low E/W one.
|
||||
#63
|
||||
Dead end.
|
||||
#64
|
||||
You are at a complex junction. A low hands and knees passage from the
|
||||
north joins a higher crawl from the east to make a walking passage
|
||||
going west. There is also a large room above. The air is damp here.
|
||||
#65
|
||||
You are in Bedquilt, a long east/west passage with holes everywhere.
|
||||
To explore at random select north, south, up, or down.
|
||||
#66
|
||||
You are in a room whose walls resemble swiss cheese. Obvious passages
|
||||
go west, east, NE, and NW. Part of the room is occupied by a large
|
||||
bedrock block.
|
||||
#67
|
||||
You are at the east end of the Twopit Room. The floor here is
|
||||
littered with thin rock slabs, which make it easy to descend the pits.
|
||||
There is a path here bypassing the pits to connect passages from east
|
||||
and west. There are holes all over, but the only big one is on the
|
||||
wall directly over the west pit where you can't get to it.
|
||||
#68
|
||||
You are in a large low circular chamber whose floor is an immense slab
|
||||
fallen from the ceiling (Slab Room). East and west there once were
|
||||
large passages, but they are now filled with boulders. Low small
|
||||
passages go north and south, and the south one quickly bends west
|
||||
around the boulders.
|
||||
#69
|
||||
You are in a secret N/S canyon above a large room.
|
||||
#70
|
||||
You are in a secret N/S canyon above a sizable passage.
|
||||
#71
|
||||
You are in a secret canyon at a junction of three canyons, bearing
|
||||
north, south, and SE. The north one is as tall as the other two
|
||||
combined.
|
||||
#72
|
||||
You are in a large low room. Crawls lead north, NE, and SW.
|
||||
#73
|
||||
Dead end crawl.
|
||||
#74
|
||||
You are in a secret canyon which here runs E/W. It crosses over a
|
||||
very tight canyon 15 feet below. If you go down you may not be able
|
||||
to get back up.
|
||||
#75
|
||||
You are at a wide place in a very tight N/S canyon.
|
||||
#76
|
||||
The canyon here becomes too tight to go further south.
|
||||
#77
|
||||
You are in a tall E/W canyon. A low tight crawl goes 3 feet north and
|
||||
seems to open up.
|
||||
#78
|
||||
The canyon runs into a mass of boulders -- dead end.
|
||||
#79
|
||||
The stream flows out through a pair of 1 foot diameter sewer pipes.
|
||||
It would be advisable to use the exit.
|
||||
#80
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#81
|
||||
Dead end.
|
||||
#82
|
||||
Dead end.
|
||||
#83
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#84
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#85
|
||||
Dead end.
|
||||
#86
|
||||
Dead end.
|
||||
#87
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#88
|
||||
You are in a long, narrow corridor stretching out of sight to the
|
||||
west. At the eastern end is a hole through which you can see a
|
||||
profusion of leaves.
|
||||
#89
|
||||
There is nothing here to climb. Use "up" or "out" to leave the pit.
|
||||
#90
|
||||
You have climbed up the plant and out of the pit.
|
||||
#91
|
||||
You are at the top of a steep incline above a large room. You could
|
||||
climb down here, but you would not be able to climb up. There is a
|
||||
passage leading back to the north.
|
||||
#92
|
||||
You are in the Giant Room. The ceiling here is too high up for your
|
||||
lamp to show it. Cavernous passages lead east, north, and south. On
|
||||
the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
|
||||
#93
|
||||
The passage here is blocked by a recent cave-in.
|
||||
#94
|
||||
You are at one end of an immense north/south passage.
|
||||
#95
|
||||
You are in a magnificent cavern with a rushing stream, which cascades
|
||||
over a sparkling waterfall into a roaring whirlpool which disappears
|
||||
through a hole in the floor. Passages exit to the south and west.
|
||||
#96
|
||||
You are in the Soft Room. The walls are covered with heavy curtains,
|
||||
the floor with a thick pile carpet. Moss covers the ceiling.
|
||||
#97
|
||||
This is the Oriental Room. Ancient oriental cave drawings cover the
|
||||
walls. A gently sloping passage leads upward to the north, another
|
||||
passage leads SE, and a hands and knees crawl leads east.
|
||||
#98
|
||||
You are following a wide path around the outer edge of a large cavern.
|
||||
Far below, through a heavy white mist, strange splashing noises can be
|
||||
heard. The mist rises up through a fissure in the ceiling. The path
|
||||
hugs the cavern's rim to the NE and south, while another branch forks
|
||||
west. A round chute with extremely smooth walls angles sharply up
|
||||
to the southwest.
|
||||
#99
|
||||
You are in an alcove. A small NW path seems to widen after a short
|
||||
distance. An extremely tight tunnel leads east. It looks like a very
|
||||
tight squeeze. An eerie light can be seen at the other end.
|
||||
#100
|
||||
You're in a small chamber lit by an eerie green light. An extremely
|
||||
narrow tunnel exits to the west, and a dark corridor leads NE.
|
||||
#101
|
||||
You're in the Dark-Room. A corridor leading south is the only exit.
|
||||
#102
|
||||
You are in an arched hall. A coral passage once continued up and east
|
||||
from here, but is now blocked by debris. The air smells of sea water.
|
||||
#103
|
||||
You're in a large room carved out of sedimentary rock. The floor and
|
||||
walls are littered with bits of shells imbedded in the stone. A
|
||||
shallow passage proceeds downward, and a somewhat steeper one leads
|
||||
up. A low hands and knees passage enters from the south.
|
||||
#104
|
||||
You are in a long sloping corridor with ragged sharp walls.
|
||||
#105
|
||||
You are in a cul-de-sac about eight feet across.
|
||||
#106
|
||||
You are in an anteroom leading to a large passage to the east. Small
|
||||
passages go west and up. The remnants of recent digging are evident.
|
||||
A sign in midair here says "Cave under construction beyond this point.
|
||||
Proceed at own risk. [Witt Construction Company]".
|
||||
#107
|
||||
You are in a maze of twisty little passages, all different.
|
||||
#108
|
||||
You are at Witt's End. Passages lead off in *ALL* directions.
|
||||
#109
|
||||
You are in a north/south canyon about 25 feet across. The floor is
|
||||
covered by white mist seeping in from the north. The walls extend
|
||||
upward for well over 100 feet. Suspended from some unseen point far
|
||||
above you, an enormous two-sided mirror is hanging parallel to and
|
||||
midway between the canyon walls. (The mirror is obviously provided
|
||||
for the use of the dwarves, who as you know, are extremely vain.) A
|
||||
small window can be seen in either wall, some fifty feet up.
|
||||
#110
|
||||
You're at a low window overlooking a huge pit, which extends up out of
|
||||
sight. A floor is indistinctly visible over 50 feet below. Traces of
|
||||
white mist cover the floor of the pit, becoming thicker to the left.
|
||||
Marks in the dust around the window would seem to indicate that
|
||||
someone has been here recently. Directly across the pit from you and
|
||||
25 feet away there is a similar window looking into a lighted room. A
|
||||
shadowy figure can be seen there peering back at you.
|
||||
#111
|
||||
A large stalactite extends from the roof and almost reaches the floor
|
||||
below. You could climb down it, and jump from it to the floor, but
|
||||
having done so you would be unable to reach it to climb back up.
|
||||
#112
|
||||
You are in a little maze of twisting passages, all different.
|
||||
#113
|
||||
You are at the edge of a large underground reservoir. An opaque cloud
|
||||
of white mist fills the room and rises rapidly upward. The lake is
|
||||
fed by a stream, which tumbles out of a hole in the wall about 10 feet
|
||||
overhead and splashes noisily into the water somewhere within the
|
||||
mist. The indistinct shape of the opposite shore can be dimly seen
|
||||
through the mist. The only passage goes back toward the south.
|
||||
#114
|
||||
Dead end.
|
||||
#115
|
||||
You are at the northeast end of an immense room, even larger than the
|
||||
Giant Room. It appears to be a repository for the "ADVENTURE"
|
||||
program. Massive torches far overhead bathe the room with smoky
|
||||
yellow light. Scattered about you can be seen a pile of bottles (all
|
||||
of them empty), a nursery of young beanstalks murmuring quietly, a bed
|
||||
of oysters, a bundle of black rods with rusty stars on their ends, and
|
||||
a collection of brass lanterns. Off to one side a great many dwarves
|
||||
are sleeping on the floor, snoring loudly. A sign nearby reads: "Do
|
||||
not disturb the dwarves!" An immense mirror is hanging against one
|
||||
wall, and stretches to the other end of the room, where various other
|
||||
sundry objects can be glimpsed dimly in the distance. An unoccupied
|
||||
telephone booth stands against the north wall.
|
||||
#116
|
||||
You are at the southwest end of the repository. To one side is a pit
|
||||
full of fierce green snakes. On the other side is a row of small
|
||||
wicker cages, each of which contains a little sulking bird. In one
|
||||
corner is a bundle of black rods with rusty marks on their ends. A
|
||||
large number of velvet pillows are scattered about on the floor.
|
||||
Beside one of the pillows is a large, dusty, leather-bound volume
|
||||
with the title "History of Adventure" embossed in pure gold.
|
||||
A vast mirror stretches off to the northeast, almost reaching the
|
||||
phone booth. At your feet is a large steel grate, next to which is
|
||||
a sign which reads, "Treasure Vault. Keys in Main Office."
|
||||
#117
|
||||
You are on one side of a large, deep chasm. A heavy white mist rising
|
||||
up from below obscures all view of the far side. A SW path leads away
|
||||
from the chasm into a winding corridor.
|
||||
#118
|
||||
You are in a long winding corridor sloping out of sight in both
|
||||
directions.
|
||||
#119
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#120
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#121
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#122
|
||||
You are on the northeast side of a deep chasm. A NE path leads away
|
||||
from the chasm on this side.
|
||||
#123
|
||||
You're in a long east/west corridor. A faint rumbling noise can be
|
||||
heard in the distance.
|
||||
#124
|
||||
The path forks here. The left fork leads northeast. A dull rumbling
|
||||
seems to get louder in that direction. The right fork leads southeast
|
||||
down a gentle slope. The main corridor enters from the west.
|
||||
#125
|
||||
The walls are quite warm here. From the north can be heard a steady
|
||||
roar, so loud that the entire cave seems to be trembling. Another
|
||||
passage leads south, and a low crawl goes east.
|
||||
#126
|
||||
You are on the edge of a breathtaking view. Far below you is an
|
||||
active volcano, from which great gouts of molten lava come surging
|
||||
out, cascading back down into the depths. The glowing rock fills the
|
||||
farthest reaches of the cavern with a blood-red glare, giving every-
|
||||
thing an eerie, macabre appearance. The air is filled with flickering
|
||||
sparks of ash and a heavy smell of brimstone. The walls are hot to
|
||||
the touch, and the thundering of the volcano drowns out all other
|
||||
sounds. Embedded in the jagged roof far overhead are myriad twisted
|
||||
formations composed of pure white alabaster, which scatter the murky
|
||||
light into sinister apparitions upon the walls. To one side is a deep
|
||||
gorge, filled with a bizarre chaos of tortured rock which seems to
|
||||
have been crafted by the devil himself. An immense river of fire
|
||||
crashes out from the depths of the volcano, burns its way through the
|
||||
gorge, and plummets into a bottomless pit far off to your left. To
|
||||
the right, an immense geyser of blistering steam erupts continuously
|
||||
from a barren island in the center of a sulfurous lake, which bubbles
|
||||
ominously. The far right wall is aflame with an incandescence of its
|
||||
own, which lends an additional infernal splendor to the already
|
||||
hellish scene. A dark, foreboding passage exits to the south.
|
||||
#127
|
||||
You are in a small chamber filled with large boulders. The walls are
|
||||
very warm, causing the air in the room to be almost stifling from the
|
||||
heat. The only exit is a crawl heading west, through which is coming
|
||||
a low rumbling.
|
||||
#128
|
||||
You are walking along a gently sloping north/south passage lined with
|
||||
oddly shaped limestone formations.
|
||||
#129
|
||||
You are standing at the entrance to a large, barren room. A sign
|
||||
posted above the entrance reads: "Caution! Bear in room!"
|
||||
#130
|
||||
You are inside a barren room. The center of the room is completely
|
||||
empty except for some dust. Marks in the dust lead away toward the
|
||||
far end of the room. The only exit is the way you came in.
|
||||
#131
|
||||
You are in a maze of twisting little passages, all different.
|
||||
#132
|
||||
You are in a little maze of twisty passages, all different.
|
||||
#133
|
||||
You are in a twisting maze of little passages, all different.
|
||||
#134
|
||||
You are in a twisting little maze of passages, all different.
|
||||
#135
|
||||
You are in a twisty little maze of passages, all different.
|
||||
#136
|
||||
You are in a twisty maze of little passages, all different.
|
||||
#137
|
||||
You are in a little twisty maze of passages, all different.
|
||||
#138
|
||||
You are in a maze of little twisting passages, all different.
|
||||
#139
|
||||
You are in a maze of little twisty passages, all different.
|
||||
#140
|
||||
Dead end.
|
||||
#141
|
||||
You are on a narrow promontory at the foot of a waterfall, which
|
||||
spurts from an overhead hole in the rock wall and splashes into a
|
||||
large reservoir, sending up clouds of mist and spray.
|
||||
Through the thick white mist looms a polished marble slab, to
|
||||
which is affixed an enormous rusty iron anvil. In golden letters
|
||||
are written the words: "Whoso Pulleth Out This Sword of This
|
||||
Stone and Anvil, is Right wise King-Born of All This Mountain."
|
||||
There is a narrow chimney on the east side of the promontory.
|
||||
#142
|
||||
You are on a narrow shelf above and east of the top of a very steep
|
||||
chimney. A long smooth granite slide curves down out of sight
|
||||
to the east. If you go down the slide, you may not be able to
|
||||
climb back up.
|
||||
#143
|
||||
You are in the private chamber of the Mountain King. Hewn into the
|
||||
solid rock of the east wall of the chamber is an intricately-wrought
|
||||
throne of elvish design. There is an exit to the west.
|
||||
#144
|
||||
You are on the east side of the throne room. On the arm of the throne
|
||||
has been hung a sign which reads "Gone for the day: visiting
|
||||
sick snake. --M.K."
|
||||
#145
|
||||
You are dragged down, down, into the depths of the whirlpool.
|
||||
Just as you can no longer hold your breath, you are shot out over
|
||||
a waterfall into the shallow end of a large reservoir. Gasping
|
||||
and sputtering, you crawl weakly towards the shore....
|
||||
#146
|
||||
You are in dense forest, with a hill to one side. The trees appear
|
||||
to thin out towards the north and east.
|
||||
#147
|
||||
You are at the high point of a wide grassy knoll, partially surrounded
|
||||
by dense forest. The land rises to the south and east, and drops off
|
||||
sharply to the north and west. The air smells of sea water.
|
||||
#148
|
||||
You are at the edge of a trackless salt marsh. Tall reeds obscure
|
||||
the view.
|
||||
#149
|
||||
You're in salt marsh.
|
||||
#150
|
||||
You're in salty marsh.
|
||||
#151
|
||||
You are in salt marsh.
|
||||
#152
|
||||
Dead end.
|
||||
#153
|
||||
You're on a sandy beach at the edge of the open sea. The beach
|
||||
ends a short distance south and the land rises to a point. To
|
||||
the north, the beach ends cliffs and broken rocks.
|
||||
#154
|
||||
You are at a jumble of large broken rocks. A gentle path leads up
|
||||
to the top of the nearby cliffs. A narrow treacherous path
|
||||
disappears among the rocks at the foot of the cliff.
|
||||
#155
|
||||
You are on a high cliff overlooking the sea. Far below the
|
||||
rolling breakers smash into a jumble of large broken rocks.
|
||||
The thunder of the surf is deafening.
|
||||
#156
|
||||
You're at the bottom of the cliff, smashed to smithereens by the
|
||||
pounding surf.
|
||||
#157
|
||||
You are at Thunder Hole, a funnel shaped cavern opening onto the sea.
|
||||
The noise of the surf pounding against the outer rocks of the cave is
|
||||
amplified by the peculiar shape of the cave, causing a thunder-like
|
||||
booming sound to reverberate throughout the cave. Outside, a narrow
|
||||
path leads south towards some large rocks.
|
||||
#158
|
||||
You are at the top of some arched steps. On one side is a blank wall
|
||||
with a tiny door at the base and a shelf overhead. On the other side
|
||||
a westward passage leads to the sea.
|
||||
#159
|
||||
You are in a low cramped chamber at the back of a small cave.
|
||||
There is a shelf in the rock wall at about the height of your
|
||||
shoulder.
|
||||
#160
|
||||
You are on a wide ledge, bounded on one side by a rock wall,
|
||||
and on the other by a sheer cliff. The only way past is through
|
||||
a large wrought-iron door.
|
||||
#161
|
||||
You feel dizzy...Everything around you is spinning, expanding,
|
||||
growing larger.... Dear me! Is the cave bigger or are you smaller?
|
||||
#162
|
||||
You are again overcome by a sickening vertigo, but this time
|
||||
everything around you is shrinking...Shrinking...
|
||||
#163
|
||||
You are again overcome by a sickening vertigo, but this time
|
||||
everything is shrinking... I mean, you are growing. This is
|
||||
terribly confusing!
|
||||
#164
|
||||
You feel dizzy...Everything around you is spinning, expanding,
|
||||
growing larger....
|
||||
#165
|
||||
You're at the bottom of the cliff with a broken neck.
|
||||
#166
|
||||
You are at the western tip of the Blue Grotto. A large lake almost
|
||||
covers the cavern floor, except for where you are standing. Small
|
||||
holes high in the rock wall to the east admit a dim light. The
|
||||
reflection of the light from the water suffuses the cavern with
|
||||
a hazy bluish glow.
|
||||
#167
|
||||
You are on the shore of an underground sea. A high wooden
|
||||
structure of vast proportions extends out into the water to the
|
||||
east. The way west is through a wrought-iron door.
|
||||
#168
|
||||
You are on the eastern shore of the Blue Grotto. An ascending
|
||||
tunnel disappears into the darkness to the SE.
|
||||
#169
|
||||
You are at a high rock on the NE side of a watery chamber at the mouth
|
||||
of a small brook. An unknown gas bubbles up through the water from
|
||||
the chamber floor. A bluish light can be seen to the southwest.
|
||||
#170
|
||||
You are in a windy tunnel between two large rooms.
|
||||
#171
|
||||
You are in the Bat Cave. The walls and ceiling are covered with
|
||||
sleeping bats. The floor is buried by a mass of dry, foul-smelling
|
||||
guano. The stench is overpowering. Exits to the NW and east.
|
||||
#172
|
||||
You are in a very tight N/S crack. The passage seems to widen to
|
||||
the south.
|
||||
#173
|
||||
You are in a very tight N/S crack. The passage south is blocked
|
||||
by a recent cave-in.
|
||||
#174
|
||||
You're in the Cloakroom. This is where the dreaded Wumpus repairs
|
||||
to sleep off heavy meals. (Adventurers are his favorite dinner!)
|
||||
Two very narrow passages exit NW and NE.
|
||||
#175
|
||||
You're in a room containing several small climbable pits. Passages
|
||||
exit to the east and north.
|
||||
#176
|
||||
You are at the bottom of a small featureless pit.
|
||||
#177
|
||||
You are at a high hole in a rock wall.
|
||||
#178
|
||||
The NE passage is blocked by a recent cave-in.
|
||||
#179
|
||||
You are in a sloping muddy defile, next to a tumbling brook.
|
||||
#180
|
||||
You are in a level E/W passage partially blocked by an overhanging
|
||||
tongue of rock. A steep scramble would take you up over the tongue,
|
||||
whence continues an upward crawl.
|
||||
#181
|
||||
The dog won't let you pass.
|
||||
#182
|
||||
You're in the Upper Passage, a long level E/W tunnel.
|
||||
#183
|
||||
You are in a star-shaped chamber. Passages exit north, east, south,
|
||||
and west.
|
||||
#184
|
||||
You are at an elbow in a winding E/W passage.
|
||||
#185
|
||||
Dead end.
|
||||
#186
|
||||
You're at the intersection of two long tunnels. One goes NW,
|
||||
the other NE.
|
||||
#187
|
||||
You're in a long narrow east-west passage which curves out of sight
|
||||
at both ends.
|
||||
#188
|
||||
You're in the Rotunda. Corridors radiate in all directions.
|
||||
There is a telephone booth standing against the north wall.
|
||||
#189
|
||||
You are standing in a telephone booth at the side of a large chamber.
|
||||
Hung on the wall is a banged-up pay telephone of ancient design.
|
||||
#190
|
||||
You're at the Devil's Chair, a large crystallization shaped like a
|
||||
seat, at the edge of a black abyss. You can't see the bottom.
|
||||
An upward path leads away from the abyss.
|
||||
#191
|
||||
You're in a dead-end crack.
|
||||
#192
|
||||
You're on a small gravel beach at the south wall of the Blue Grotto.
|
||||
A gravelly path leads east.
|
||||
#193
|
||||
You are in the Flower Room. The walls are covered with colorful,
|
||||
intricate, flowerlike patterns of crystallized gypsum. A hole leads
|
||||
to the west.
|
||||
#194
|
||||
You are at the end of a short E/W corridor.
|
||||
#195
|
||||
You are looking west from the end of a short E/W corridor. At your
|
||||
feet is a pile of loose rubble. On your left is a hole into another
|
||||
chamber.
|
||||
#196
|
||||
You are in an arched hall. The remnants of a now-plugged coral
|
||||
passage lie to the east. The north wall has partially crumbled,
|
||||
exposing a large connecting hole to another room.
|
||||
#197
|
||||
You're in the Vestibule, a short east-west passage between two rooms.
|
||||
#198
|
||||
You are in the Fairy Grotto. All around you innumerable stalactites,
|
||||
arranged in immense colonnades, form elegant arches. On every side
|
||||
you hear the dripping of water, like the footsteps of a thousand
|
||||
fairies. A small stream runs from the SW corner. A bright glow
|
||||
emanates from the south side of the grotto, and a steep passage
|
||||
descends to the east.
|
||||
#199
|
||||
You have approached the lower end of a steep passage, but it is
|
||||
just too cold here to hang around, and you aren't properly equipped
|
||||
to continue. With teeth chattering, you climb back up....
|
||||
#200
|
||||
You are in the Crystal Palace. An overhead vein of phosphorescent
|
||||
quartz casts a luminous glow which is reflected by countless chips of
|
||||
mica embedded in both walls, which consist of some sort of highly
|
||||
reflective glass, apparently of volcanic origin. A winding path
|
||||
of yellow sandstone leads west and rises steeply to the east.
|
||||
#201
|
||||
You are following a yellow sandstone path. There is a glow
|
||||
to the west.
|
||||
#202
|
||||
You are in a very tall chamber whose walls are comprised of many
|
||||
different rock strata. Layers of red and yellow sandstone
|
||||
intertwine with bright bands of calcareous limestone in a rainbow-
|
||||
like profusion of color. The rainbow effect is so real, you
|
||||
are almost tempted to look for a pot of gold! Poised far over
|
||||
your head, a gigantic slab, wedged tightly between the north and
|
||||
south walls, forms a natural bridge across the roof of the chamber.
|
||||
A trail leads east and west.
|
||||
#203
|
||||
You're in a steeply sloping passage. It is very cold here.
|
||||
#204
|
||||
You are in the Hall of Ice, in the deepest part of the caverns.
|
||||
During winter, frigid outside air settles here, making this room
|
||||
extremely cold all year round. The walls and ceilings are covered
|
||||
with a thick coating of ice. An upward passage exits to the west.
|
||||
#205
|
||||
You are standing on a natural bridge far above the floor of a circular
|
||||
chamber whose walls are a rainbow of multicolored rock. The bridge
|
||||
was formed eons ago by a huge slab which fell from the ceiling and
|
||||
is now jammed between the north and south walls of the chamber.
|
||||
#206
|
||||
You are in a low, wide room below another chamber. A small green
|
||||
pond fills the center of the room. The lake is apparently spring
|
||||
fed. A small stream exits through a narrow passage to the north.
|
||||
A larger passage continues west.
|
||||
#207
|
||||
You are in a tight north/south crawl through a stratum of red
|
||||
colored rock. The air is damp with mist.
|
||||
#208
|
||||
You are in a tall canyon on the south side of a swift, wide river.
|
||||
Written in the mud in crude letters are the words: "You Have Found
|
||||
Lost River." A wide path leads east and west along the bank. A tight
|
||||
crawl way would take you south out of the canyon.
|
||||
#209
|
||||
You are standing on a large flat rock table at the western end of
|
||||
Lost River Canyon. Beneath your feet, the river disappears amidst
|
||||
foam and spray into a large sinkhole. A gentle path leads east
|
||||
along the river's south shore. Another leads sharply upward along
|
||||
the river's north side.
|
||||
#210
|
||||
You are at a niche in the canyon wall, far above a raging river.
|
||||
The air is filled with mist and spray, making it difficult to see
|
||||
ahead. A downward sloping ledge narrows to the east. The path
|
||||
to the west is easier.
|
||||
#211
|
||||
The ledge is growing very narrow and treacherous, and falls off almost
|
||||
vertically. You could go down, but you won't be able to climb back.
|
||||
#212
|
||||
You are standing in a telephone booth at the side of the Repository.
|
||||
#213
|
||||
You're at the east end of a level passage at a hole in the floor.
|
||||
#214
|
||||
You're at the north edge of a dark cove.
|
||||
#215
|
||||
You are in a dry granite basin, worn smooth eons ago by water
|
||||
swirling down from a now-dry spillway.
|
||||
#216
|
||||
You're in a dry spillway east of and above a smooth rock basin.
|
||||
#217
|
||||
You are in the Winery, a cool dark room which extends some
|
||||
distance off to the east.
|
||||
#218
|
||||
You are to the east of the Winery, where the room ends in a thicket
|
||||
of high, sharp, pointed, climbable limestone pinnacles. There is a
|
||||
narrow ledge just above the top of the spires. If you go up, it
|
||||
might be difficult to get back down.
|
||||
#219
|
||||
You are in a high-vaulted cavern whose roof rises over fifty
|
||||
meters to culminate in a series of pointed arches directly over
|
||||
your head. There are also two low arches to either side, forming
|
||||
side portals. The whole effect is that of a gothic cathedral.
|
||||
You can proceed north, south, east, or west.
|
||||
#220
|
||||
You're at the east portal of the Gothic Cathedral. The path leads
|
||||
east and west.
|
||||
#221
|
||||
You're at the west portal of the Gothic Cathedral.
|
||||
#222
|
||||
You are at the foot of the Altar, an immense, broad stalagmite.
|
||||
An opening leads south.
|
||||
#223
|
||||
You're on top of an enormous, broad stalagmite. There is a hole
|
||||
in the ceiling overhead.
|
||||
#224
|
||||
You are in a room the size and shape of a small crypt. A narrow
|
||||
cut exits east. There is a hole in the floor.
|
||||
#225
|
||||
You are in the Gothic Chapel, a small chamber adjoining the Gothic
|
||||
Cathedral. A path leads west.
|
||||
#226
|
||||
You are on the floor of the Rainbow Room. In fact, you are spread
|
||||
*ALL OVER* the floor of the Rainbow Room.
|
||||
#227
|
||||
You are in a dimly lit passage behind Thunder Hole. Etched into
|
||||
the rock wall are the ominous words:
|
||||
* "You are approaching the River Styx. *
|
||||
* Laciate Ogni Speranza Voi Ch'Entrate." *
|
||||
#228
|
||||
You are at the River Styx, a narrow little stream cutting directly
|
||||
across the passageway. The edge of the stream is littered with sticks
|
||||
and other debris washed in by a recent rainfall. On the far side
|
||||
of the river, the passage continues east.
|
||||
#229
|
||||
You're on the east side of the river's sticks.
|
||||
#230
|
||||
You are on a ledge at the northern end of a long N/S crawl. The
|
||||
ledge is above a large number of sharp vertical limestone spires.
|
||||
An attempt to climb down could be dangerous, if you get my *point*!
|
||||
#231
|
||||
You are very neatly skewered on the point of a sharp rock.
|
||||
#232
|
||||
You have poled your boat across the calm water.
|
||||
#233
|
||||
You have poled your boat across the dark water.
|
||||
#234
|
||||
You have poled your boat across the Blue Grotto.
|
||||
#235
|
||||
You're at Dante's Rest, on the north side of a yawning dark chasm.
|
||||
A passage continues west along the chasm's edge.
|
||||
#236
|
||||
You are at the east end of a river bank path in Lost River Canyon.
|
||||
#237
|
||||
The staircase is now unclimbable.
|
||||
#238
|
||||
You're in the caretaker's pantry.
|
||||
#239
|
||||
You are on a small rise overlooking a beautiful bay. In the center
|
||||
of the bay is the castle of the elves.
|
||||
#240
|
||||
You are on the highest pinnacle of the castle in the bay.
|
||||
Steps lead down into the garden.
|
||||
#241
|
||||
You are in the outer courtyard of the garden of the elves.
|
||||
Steps lead up to the tower, and to the west, separating you
|
||||
from the inner courtyard, is a maze of hedges, living things,
|
||||
but almost crystalline in their multicolored splendor.
|
||||
#242
|
||||
From the inside the maze looks like a kaleidoscope, with
|
||||
swatches of color dancing as you move. In this part the colors
|
||||
are produced by shining red berries on the branches.
|
||||
#243
|
||||
You are surrounded by a tall hedge with sharp iridescent leaves
|
||||
and metallic orange flowers.
|
||||
#244
|
||||
You are in the center of the living maze. The plants here are
|
||||
dormant this season, but still carry brilliant yellow leaves.
|
||||
#245
|
||||
Unlike the other areas of the hedge system, this area seems to
|
||||
have no metallic gleam; nevertheless it is still breathtaking.
|
||||
The trees and bushes are all variegated shades of green, the
|
||||
evergreens being a rich dark shade while the seasonal bushes
|
||||
are a lighter yellowish green, making a startling contrast.
|
||||
#246
|
||||
You are near the edge of the maze. You sample the blueberries
|
||||
on the bushes. They are delicious.
|
||||
#247
|
||||
You are at the western end of the living maze. Beside the
|
||||
shrubs forming the walls are tastefully planted beds of
|
||||
violets and brilliant purple pansies.
|
||||
To the west is the inner garden.
|
||||
#248
|
||||
You are in the inner garden of the elves. In the center is
|
||||
a living tree, with shimmering silvery bark, glistening metallic
|
||||
green leaves, and flowers ripe with nectar. As the nectar falls
|
||||
to the ground it forms droplets of silver. Around the tree is
|
||||
a hedge of briars which cannot be crossed. Unfortunately for
|
||||
adventurers such as you, most of the nectar falls inside the hedge.
|
||||
The exit is to the east.
|
||||
@@ -1,514 +0,0 @@
|
||||
#1
|
||||
You're at end of road again.
|
||||
#2
|
||||
You're at hill in road.
|
||||
#3
|
||||
You're inside building.
|
||||
#4
|
||||
You're in valley.
|
||||
#5
|
||||
You're in forest.
|
||||
#6
|
||||
You're in forest.
|
||||
#7
|
||||
You're at slit in streambed.
|
||||
#8
|
||||
You're outside grate.
|
||||
#9
|
||||
You're below the grate.
|
||||
#10
|
||||
You're in cobble crawl.
|
||||
#11
|
||||
You're in Debris Room.
|
||||
#12
|
||||
You are in an awkward sloping east/west canyon.
|
||||
#13
|
||||
You're in Bird Chamber.
|
||||
#14
|
||||
You're at top of small pit.
|
||||
#15
|
||||
You're in Hall of Mists.
|
||||
#16
|
||||
The crack is far too small for you to follow.
|
||||
#17
|
||||
You're on east bank of fissure.
|
||||
#18
|
||||
You're in Nugget of Gold Room.
|
||||
#19
|
||||
You're in Hall of Mt King.
|
||||
#20
|
||||
You are at the bottom of the pit with a broken neck.
|
||||
#21
|
||||
You didn't make it.
|
||||
#22
|
||||
The dome is unclimbable.
|
||||
#23
|
||||
You're at west end of Twopit Room.
|
||||
#24
|
||||
You're in east pit.
|
||||
#25
|
||||
You're in west pit.
|
||||
#26
|
||||
You clamber up the plant and scurry through the hole at the top.
|
||||
#27
|
||||
You are on the west side of the fissure in the Hall of Mists.
|
||||
#28
|
||||
You are in a low N/S passage at a hole in the floor. The hole goes
|
||||
down to an E/W passage.
|
||||
#29
|
||||
You are in the South Side Chamber.
|
||||
#30
|
||||
You are in the West Side Chamber of the Hall of the Mountain King.
|
||||
#31
|
||||
<$$<
|
||||
#32
|
||||
You can't get by the snake.
|
||||
#33
|
||||
You're at "Y2".
|
||||
#34
|
||||
You are in a jumble of rock, with cracks everywhere.
|
||||
#35
|
||||
You're at window on pit.
|
||||
#36
|
||||
You're in dirty passage.
|
||||
#37
|
||||
You are on the brink of a small clean climbable pit.
|
||||
#38
|
||||
You are in the bottom of a small pit with a little stream.
|
||||
#39
|
||||
You're in dusty rock room.
|
||||
#40
|
||||
You have crawled through a very low wide passage parallel.
|
||||
#41
|
||||
You're at west end of Hall of Mists.
|
||||
#42
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#43
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#44
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#45
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#46
|
||||
Dead end.
|
||||
#47
|
||||
Dead end.
|
||||
#48
|
||||
Dead end.
|
||||
#49
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#50
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#51
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#52
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#53
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#54
|
||||
Dead end.
|
||||
#55
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#56
|
||||
Dead end.
|
||||
#57
|
||||
You're at brink of pit.
|
||||
#58
|
||||
Dead end.
|
||||
#59
|
||||
You have crawled through a very low wide passage.
|
||||
#60
|
||||
You're at east end of Long Hall.
|
||||
#61
|
||||
You're at west end of Long Hall.
|
||||
#62
|
||||
You are at a crossover of a high N/S passage and a low E/W one.
|
||||
#63
|
||||
Dead end.
|
||||
#64
|
||||
You're at Complex Junction.
|
||||
#65
|
||||
You are in Bedquilt.
|
||||
#66
|
||||
You're in Swiss Cheese Room.
|
||||
#67
|
||||
You're at east end of Twopit Room.
|
||||
#68
|
||||
You're in Slab Room.
|
||||
#69
|
||||
You are in a secret N/S canyon above a large room.
|
||||
#70
|
||||
You are in a secret N/S canyon above a sizable passage.
|
||||
#71
|
||||
You're at junction of three secret canyons.
|
||||
#72
|
||||
You are in a large low room. Crawls lead north, NE, and SW.
|
||||
#73
|
||||
Dead end crawl.
|
||||
#74
|
||||
You're in secret E/W canyon above tight canyon.
|
||||
#75
|
||||
You are at a wide place in a very tight N/S canyon.
|
||||
#76
|
||||
The canyon here becomes too tight to go further south.
|
||||
#77
|
||||
You are in a tall E/W canyon.
|
||||
#78
|
||||
The canyon runs into a mass of boulders -- dead end.
|
||||
#79
|
||||
The stream flows out through a pair of 1 foot diameter sewer pipes.
|
||||
#80
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#81
|
||||
Dead end.
|
||||
#82
|
||||
Dead end.
|
||||
#83
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#84
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#85
|
||||
Dead end.
|
||||
#86
|
||||
Dead end.
|
||||
#87
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
#88
|
||||
You're in narrow corridor.
|
||||
#89
|
||||
There is nothing here to climb. Use "up" or "out" to leave the pit.
|
||||
#90
|
||||
You have climbed up the plant and out of the pit.
|
||||
#91
|
||||
You're at steep incline above large room.
|
||||
#92
|
||||
You're in Giant Room.
|
||||
#93
|
||||
The passage here is blocked by a recent cave-in.
|
||||
#94
|
||||
You are at one end of an immense north/south passage.
|
||||
#95
|
||||
You're in cavern with waterfall.
|
||||
#96
|
||||
You're in Soft Room.
|
||||
#97
|
||||
You're in Oriental Room.
|
||||
#98
|
||||
You're in Misty Cavern.
|
||||
#99
|
||||
You're in Alcove.
|
||||
#100
|
||||
You're in Plover Room.
|
||||
#101
|
||||
You're in Dark-Room.
|
||||
#102
|
||||
You're in Arched Hall.
|
||||
#103
|
||||
You're in Shell Room.
|
||||
#104
|
||||
You are in a long sloping corridor with ragged sharp walls.
|
||||
#105
|
||||
You are in a cul-de-sac about eight feet across.
|
||||
#106
|
||||
You're in Anteroom.
|
||||
#107
|
||||
You are in a maze of twisty little passages, all different.
|
||||
#108
|
||||
You're at Witt's End.
|
||||
#109
|
||||
You're in Mirror Canyon.
|
||||
#110
|
||||
You're at window on pit.
|
||||
#111
|
||||
You're at top of stalactite.
|
||||
#112
|
||||
You are in a little maze of twisting passages, all different.
|
||||
#113
|
||||
You're at Reservoir.
|
||||
#114
|
||||
Dead end.
|
||||
#115
|
||||
You're at NE end.
|
||||
#116
|
||||
You're at SW end.
|
||||
#117
|
||||
You're on SW side of chasm.
|
||||
#118
|
||||
You're in sloping corridor.
|
||||
#119
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#120
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#121
|
||||
You are in a secret canyon which exits to the north and east.
|
||||
#122
|
||||
You're on NE side of chasm.
|
||||
#123
|
||||
You're in corridor.
|
||||
#124
|
||||
You're at fork in path.
|
||||
#125
|
||||
You're at junction with warm walls.
|
||||
#126
|
||||
You're at breath-taking view.
|
||||
#127
|
||||
You're in Chamber of Boulders.
|
||||
#128
|
||||
You're in Limestone Passage.
|
||||
#129
|
||||
You're in front of Barren Room.
|
||||
#130
|
||||
You're in Barren Room.
|
||||
#131
|
||||
You are in a maze of twisting little passages, all different.
|
||||
#132
|
||||
You are in a little maze of twisty passages, all different.
|
||||
#133
|
||||
You are in a twisting maze of little passages, all different.
|
||||
#134
|
||||
You are in a twisting little maze of passages, all different.
|
||||
#135
|
||||
You are in a twisty little maze of passages, all different.
|
||||
#136
|
||||
You are in a twisty maze of little passages, all different.
|
||||
#137
|
||||
You are in a little twisty maze of passages, all different.
|
||||
#138
|
||||
You are in a maze of little twisting passages, all different.
|
||||
#139
|
||||
You are in a maze of little twisty passages, all different.
|
||||
#140
|
||||
Dead end.
|
||||
#141
|
||||
You're at Sword Point.
|
||||
#142
|
||||
You're at top of slide.
|
||||
#143
|
||||
You're at entrance to Throne Room.
|
||||
#144
|
||||
You're on east side of Throne Room.
|
||||
#145
|
||||
<$$<
|
||||
#146
|
||||
You're in forest.
|
||||
#147
|
||||
You're on grassy knoll.
|
||||
#148
|
||||
You are at the edge of a trackless salt marsh. Tall reeds obscure
|
||||
the view.
|
||||
#149
|
||||
You're in salt marsh.
|
||||
#150
|
||||
You're in salty marsh.
|
||||
#151
|
||||
You are in salt marsh.
|
||||
#152
|
||||
Dead end.
|
||||
#153
|
||||
You're on sandy beach.
|
||||
#154
|
||||
You're at broken rocks.
|
||||
#155
|
||||
You're at Ocean Vista.
|
||||
#156
|
||||
You're at the bottom of the cliff.
|
||||
#157
|
||||
You're at Thunder Hole.
|
||||
#158
|
||||
You're at top of steps in back of Thunder Hole.
|
||||
#159
|
||||
You're in cramped chamber.
|
||||
#160
|
||||
You're at ledge by wrought-iron door.
|
||||
#161
|
||||
You feel dizzy...Everything around you is spinning, expanding,
|
||||
growing larger.... Dear me! Is the cave bigger or are you smaller?
|
||||
#162
|
||||
You are again overcome by a sickening vertigo, but this time
|
||||
everything around you is shrinking...Shrinking...
|
||||
#163
|
||||
You are again overcome by a sickening vertigo, but this time
|
||||
everything is shrinking... I mean, you are growing. This is
|
||||
terribly confusing!
|
||||
#164
|
||||
You feel dizzy...Everything around you is spinning, expanding,
|
||||
growing larger....
|
||||
#165
|
||||
You're at the bottom of the cliff with a broken neck.
|
||||
#166
|
||||
You're at west wall of Blue Grotto.
|
||||
#167
|
||||
You're at underground sea.
|
||||
#168
|
||||
You're on east side of the Blue Grotto.
|
||||
#169
|
||||
You're in Bubble Chamber.
|
||||
#170
|
||||
You are in a windy tunnel between two large rooms.
|
||||
#171
|
||||
You're in Bat Cave.
|
||||
#172
|
||||
You are in a very tight N/S crack.
|
||||
#173
|
||||
You are in a very tight N/S crack.
|
||||
#174
|
||||
You're in the Cloakroom.
|
||||
#175
|
||||
You're in a room containing several small climbable pits.
|
||||
#176
|
||||
You are at the bottom of a small featureless pit.
|
||||
#177
|
||||
You are at a high hole in a rock wall.
|
||||
#178
|
||||
The NE passage is blocked by a recent cave-in.
|
||||
#179
|
||||
You are in a sloping muddy defile, next to a tumbling brook.
|
||||
#180
|
||||
You're at Tongue of Rock.
|
||||
#181
|
||||
The dog won't let you pass.
|
||||
#182
|
||||
You're in the Upper Passage, a long level E/W tunnel.
|
||||
#183
|
||||
You're in Star Chamber.
|
||||
#184
|
||||
You are at an elbow in a winding E/W passage.
|
||||
#185
|
||||
Dead end.
|
||||
#186
|
||||
You're at the intersection of two long tunnels.
|
||||
#187
|
||||
You're in a long narrow east-west passage.
|
||||
#188
|
||||
You're in Rotunda.
|
||||
#189
|
||||
You're in phone booth.
|
||||
#190
|
||||
You're at Devil's Chair.
|
||||
#191
|
||||
You're in a dead-end crack.
|
||||
#192
|
||||
You're on gravel beach.
|
||||
#193
|
||||
You're in Flower Room.
|
||||
#194
|
||||
You are at east end of short E/W corridor.
|
||||
#195
|
||||
You are at east end of short E/W corridor.
|
||||
#196
|
||||
You're in Arched Hall.
|
||||
#197
|
||||
You're in the Vestibule, a short east-west passage between two rooms.
|
||||
#198
|
||||
You're in the Fairy Grotto.
|
||||
#199
|
||||
You have approached the lower end of a steep passage.
|
||||
#200
|
||||
You're in the Crystal Palace.
|
||||
#201
|
||||
You are following a yellow sandstone path.
|
||||
#202
|
||||
You're in the Rainbow Room.
|
||||
#203
|
||||
You're in a steeply sloping passage. It is very cold here.
|
||||
#204
|
||||
You're in the Hall of Ice.
|
||||
#205
|
||||
You are over the Rainbow (Room).
|
||||
#206
|
||||
You're in Green Lake Room.
|
||||
#207
|
||||
You're in red rock crawl.
|
||||
#208
|
||||
You're on south side of Lost River Canyon.
|
||||
#209
|
||||
You're at end of Lost River Canyon.
|
||||
#210
|
||||
You're at niche in ledge above Lost River.
|
||||
#211
|
||||
A very narrow and treacherous ledge.
|
||||
#212
|
||||
You're in phone booth.
|
||||
#213
|
||||
You're at the east end of a level passage at a hole in the floor.
|
||||
#214
|
||||
You're in dark cove.
|
||||
#215
|
||||
You're in dry basin.
|
||||
#216
|
||||
You're in old spillway.
|
||||
#217
|
||||
You're in the Winery.
|
||||
#218
|
||||
You're at limestone pinnacles.
|
||||
#219
|
||||
You're in Gothic Cathedral.
|
||||
#220
|
||||
You're at the east portal of the Gothic Cathedral.
|
||||
#221
|
||||
You're at the west portal of the Gothic Cathedral.
|
||||
#222
|
||||
You are at the foot of the Altar, an immense, broad stalagmite.
|
||||
#223
|
||||
You're on top of stalagmite.
|
||||
#224
|
||||
You're in the Crypt.
|
||||
#225
|
||||
You're in Gothic Chapel.
|
||||
#226
|
||||
You are on the floor of the Rainbow Room.
|
||||
#227
|
||||
You are at approach to River Styx.
|
||||
#228
|
||||
You're at the River Styx.
|
||||
#229
|
||||
You're on the east side of the river's sticks.
|
||||
#230
|
||||
You're on ledge above limestone pinnacles.
|
||||
#231
|
||||
You are very neatly skewered on the point of a sharp rock.
|
||||
#232
|
||||
You have poled your boat across the calm water.
|
||||
#233
|
||||
You have poled your boat across the dark water.
|
||||
#234
|
||||
You have poled your boat across the Blue Grotto.
|
||||
#235
|
||||
You're at Dante's Rest.
|
||||
#236
|
||||
You're at east end of Lost River Canyon.
|
||||
#237
|
||||
The staircase is now unclimbable.
|
||||
#238
|
||||
You're in the caretaker's pantry.
|
||||
#239
|
||||
You're on a small rise over the bay.
|
||||
#240
|
||||
You are on the highest pinnacle of the castle in the bay.
|
||||
Steps lead down into the garden.
|
||||
#241
|
||||
You are in the outer courtyard of the elves.
|
||||
#242
|
||||
You are in the living maze. There are red berries here.
|
||||
#243
|
||||
You are surrounded by a tall hedge with sharp iridescent leaves
|
||||
and metallic orange flowers.
|
||||
#244
|
||||
You are in the center of the living maze. The plants here are
|
||||
dormant this season, but still carry brilliant yellow leaves.
|
||||
#245
|
||||
Unlike the other areas of the hedge system, this area seems to
|
||||
have no metallic gleam; nevertheless it is still breathtaking.
|
||||
The trees and bushes are all variegated shades of green, the
|
||||
evergreens being a rich dark shade while the seasonal bushes
|
||||
are a lighter yellowish green, making a startling contrast.
|
||||
#246
|
||||
You are near the edge of the maze. You sample the blueberries
|
||||
on the bushes. They are delicious.
|
||||
#247
|
||||
You are at the western end of the living maze. Beside the
|
||||
shrubs forming the walls are tastefully planted beds of
|
||||
violets and brilliant purple pansies.
|
||||
To the west is the inner garden.
|
||||
#248
|
||||
You're in the inner courtyard of the elves.
|
||||
@@ -1,539 +0,0 @@
|
||||
#1
|
||||
#2
|
||||
/Brass lantern
|
||||
/There is a shiny brass lamp nearby.
|
||||
/There is a lamp shining nearby.
|
||||
/
|
||||
#3
|
||||
/*Grate
|
||||
/The grate is locked.
|
||||
/The grate is open.
|
||||
/
|
||||
#4
|
||||
/Wicker cage
|
||||
/There is a small wicker cage discarded nearby.
|
||||
/
|
||||
#5
|
||||
/Black rod
|
||||
/A three foot black rod with a rusty star on an end lies nearby.
|
||||
/
|
||||
#6
|
||||
/Black rod
|
||||
/A three foot black rod with a rusty mark on an end lies nearby.
|
||||
/
|
||||
#7
|
||||
/*Steps
|
||||
/Rough stone steps lead down the pit.
|
||||
/Rough stone steps lead up the dome.
|
||||
/
|
||||
#8
|
||||
#9
|
||||
/Wooden pole
|
||||
/A wooden pole is lying nearby.
|
||||
/A wooden pole has been stuck in the mud here.
|
||||
/
|
||||
#10
|
||||
/Velvet pillow
|
||||
/A small velvet pillow lies on the floor.
|
||||
/
|
||||
#11
|
||||
/*Snake
|
||||
/A huge green fierce snake bars the way!
|
||||
/<$$< (Chased away)
|
||||
/
|
||||
#12
|
||||
/*Fissure
|
||||
/<$$<
|
||||
/A crystal bridge now spans the fissure.
|
||||
/The crystal bridge has vanished!
|
||||
/
|
||||
#13
|
||||
/*Stone tablet
|
||||
/A massive stone tablet imbedded in the wall reads:
|
||||
"Congratulations on bringing light into the Dark-Room!"
|
||||
/
|
||||
#14
|
||||
/Giant clam >grunt!<
|
||||
/There is an enormous clam here with its shell tightly closed.
|
||||
/
|
||||
#15
|
||||
/Giant oyster >groan!<
|
||||
/There is an enormous oyster here with its shell tightly closed.
|
||||
/Interesting. There seems to be something written on the underside of
|
||||
the oyster.
|
||||
/
|
||||
#16
|
||||
/"Spelunker Today"
|
||||
/There are a few recent issues of "Spelunker Today" magazine here.
|
||||
/
|
||||
#17
|
||||
#18
|
||||
#19
|
||||
/Tasty food
|
||||
/There is food here.
|
||||
/
|
||||
#20
|
||||
/Small bottle
|
||||
/There is a small bottle here.
|
||||
/There is an empty bottle here.
|
||||
/There is a small bottle here.
|
||||
/There is a broken bottle here.
|
||||
/There is a small bottle here.
|
||||
/
|
||||
#21
|
||||
/*Chasm - troll bridge
|
||||
/A rickety wooden bridge extends across the chasm, vanishing into the
|
||||
mist. A sign posted on the bridge reads, "Stop! Pay troll!"
|
||||
/The wreckage of a bridge (and a dead bear) can be seen at the bottom
|
||||
of the chasm.
|
||||
/
|
||||
#22
|
||||
/*Chasm2 & decrepit natural bridge
|
||||
/A decrepit natural bridge spans the chasm. A message scrawled into
|
||||
the rock wall reads: "Bridge out of repair. Maximum load: 35 Foonts."
|
||||
/The remnants of a natural bridge partially overhang the chasm.
|
||||
/
|
||||
#23
|
||||
/*Mirror
|
||||
/<$$<
|
||||
/
|
||||
#24
|
||||
/*plant
|
||||
/There is a tiny little plant in the pit, murmuring "Water, water, ..."
|
||||
/The plant spurts into furious growth for a few seconds.
|
||||
/There is a 12-foot-tall beanstalk stretching up out of the pit,
|
||||
bellowing "Water!! Water!!"
|
||||
/The plant grows explosively, almost filling the bottom of the pit.
|
||||
/There is a gigantic beanstalk stretching all the way up to the hole.
|
||||
/You've over-watered the plant! It's shriveling up! It's, it's...
|
||||
/
|
||||
#25
|
||||
/*Phony plant (seen in twopit room only when tall enough)
|
||||
/<$$<
|
||||
/The top of a 12-foot-tall beanstalk is poking out of the west pit.
|
||||
/There is a huge beanstalk growing out of the west pit up to the hole.
|
||||
/
|
||||
#26
|
||||
/*Stalactite
|
||||
/<$$<
|
||||
/
|
||||
#27
|
||||
/*shadowy figure
|
||||
/The shadowy figure seems to be trying to attract your attention.
|
||||
/
|
||||
#28
|
||||
/Dwarf's axe
|
||||
/There is a little axe here.
|
||||
/There is a little axe lying beside the bear.
|
||||
/There is a little axe lying beside the Wumpus.
|
||||
/There is a little axe lying beside the dog.
|
||||
/
|
||||
#29
|
||||
/*Cave drawings
|
||||
/<$$<
|
||||
/
|
||||
#30
|
||||
/*pirate
|
||||
/<$$<
|
||||
/
|
||||
#31
|
||||
/*dragon
|
||||
/A huge green fierce dragon bars the way!
|
||||
/Congratulations! You have just vanquished a dragon with your bare
|
||||
hands! (Unbelievable, isn't it?)
|
||||
/The body of a huge green dead dragon is lying off to one side.
|
||||
/
|
||||
#32
|
||||
#33
|
||||
/*Troll
|
||||
/A burly troll stands by the bridge and insists you throw him a
|
||||
treasure before you may cross.
|
||||
/The troll steps out from beneath the bridge and blocks your way.
|
||||
/<$$< (Chased away)
|
||||
/
|
||||
#34
|
||||
/*phony troll
|
||||
/The troll is nowhere to be seen.
|
||||
/
|
||||
#35
|
||||
/<$$< (Bear uses rtext 141)
|
||||
/There is a ferocious cave bear eying you from the far end of the room!
|
||||
/There is a gentle cave bear sitting placidly in one corner.
|
||||
/There is a contented-looking bear wandering about nearby.
|
||||
/<$$< (Dead)
|
||||
/
|
||||
#36
|
||||
/*Message in second maze
|
||||
/There is a message scrawled in the dust in a flowery script, reading:
|
||||
"This is not the maze where the pirate leaves his treasure chest."
|
||||
/
|
||||
#37
|
||||
/*Volcano and/or geyser
|
||||
/<$$<
|
||||
/
|
||||
#38
|
||||
/*Vending machine
|
||||
/There is a massive vending machine here. The instructions on it
|
||||
read: "Insert coins to receive fresh batteries."
|
||||
/There is a massive vending machine here.
|
||||
/
|
||||
#39
|
||||
/Batteries
|
||||
/There are fresh batteries here.
|
||||
/Some worn-out batteries have been discarded nearby.
|
||||
/Some worn-out batteries have been discarded nearby.
|
||||
/
|
||||
#40
|
||||
/*Carpet and/or moss
|
||||
/<$$<
|
||||
/
|
||||
#41
|
||||
/*Rusty door
|
||||
/The way north is barred by a massive, rusty, iron door.
|
||||
/The way north leads through a massive, rusty, iron door.
|
||||
/
|
||||
#42
|
||||
/*Tiny door
|
||||
/The only way past the wall is through a tiny locked door.
|
||||
/The only way past the wall is through a tiny open door.
|
||||
/
|
||||
#43
|
||||
/*Tiny door-2
|
||||
/The door is locked.
|
||||
/The door is open.
|
||||
/
|
||||
#44
|
||||
/*Phone booth door
|
||||
/<$$<
|
||||
/
|
||||
#45
|
||||
#46
|
||||
/Beautiful flowers
|
||||
/There are some beautiful flowers here!
|
||||
/On the other side of the room a swarm of bees eagerly buzzes over
|
||||
a bunch of fresh flowers.
|
||||
/
|
||||
#47
|
||||
/Silken cloak
|
||||
/There is a silken cloak here!
|
||||
/<$$< (wearing cloak)
|
||||
/A lovely silken cloak lies partially buried under a pile of
|
||||
loose rocks.
|
||||
/
|
||||
#48
|
||||
/Wooden boat
|
||||
/There is a small wooden boat here.
|
||||
/You are in a wooden boat.
|
||||
/
|
||||
#49
|
||||
/*Sticks at Styx
|
||||
/<$$<
|
||||
/
|
||||
#50
|
||||
/Large gold nugget
|
||||
/There is a large sparkling nugget of gold here!
|
||||
/
|
||||
#51
|
||||
/Several diamonds
|
||||
/There are diamonds here!
|
||||
/
|
||||
#52
|
||||
/Silver horn
|
||||
/There is a silver horn here!
|
||||
/
|
||||
#53
|
||||
/Precious jewelry
|
||||
/There is precious jewelry here!
|
||||
/<$$< (wearing jewelry)
|
||||
/
|
||||
#54
|
||||
/Rare coins
|
||||
/There are many coins here!
|
||||
/
|
||||
#55
|
||||
/Treasure chest
|
||||
/The pirate's treasure chest is here!
|
||||
/
|
||||
#56
|
||||
/Golden eggs
|
||||
/There is a large nest here, full of golden eggs!
|
||||
/The nest of golden eggs has vanished!
|
||||
/Done!
|
||||
/
|
||||
#57
|
||||
/Jeweled trident
|
||||
/There is a jewel-encrusted trident here!
|
||||
/
|
||||
#58
|
||||
/Ming vase
|
||||
/There is a delicate, precious, ming vase here!
|
||||
/The vase is now resting, delicately, on a velvet pillow.
|
||||
/The floor is littered with worthless shards of pottery.
|
||||
/The ming vase drops with a delicate crash.
|
||||
/
|
||||
#59
|
||||
/Egg-sized emerald
|
||||
/There is an emerald here the size of a plover's egg!
|
||||
/
|
||||
#60
|
||||
/Platinum pyramid
|
||||
/There is a platinum pyramid here, 8 inches on a side!
|
||||
/
|
||||
#61
|
||||
/Glistening pearl
|
||||
/Off to one side lies a glistening pearl!
|
||||
/
|
||||
#62
|
||||
/Persian rug
|
||||
/There is a persian rug spread out on the floor!
|
||||
/The dragon is sprawled out on a persian rug!!
|
||||
/
|
||||
#63
|
||||
/Rare spices
|
||||
/There are rare spices here!
|
||||
/
|
||||
#64
|
||||
/Golden chain
|
||||
/There is a golden chain lying in a heap on the floor!
|
||||
/The bear is locked to the wall with a golden chain!
|
||||
/There is a golden chain locked to the wall!
|
||||
/
|
||||
#65
|
||||
/Gleaming sword
|
||||
/There is a gleaming sword here!
|
||||
/A gleaming sword is stuck into the anvil!
|
||||
/You grasp the sword's handle and give a mighty heave, but with a
|
||||
loud clang the sword blade shatters into several fragments.
|
||||
/Rusty shards of a elven sword lie scattered about.
|
||||
/A very clean sword is stuck into the anvil!
|
||||
/An oily sword is stuck into the anvil.
|
||||
/
|
||||
#66
|
||||
/Elfin crown
|
||||
/An ancient crown of elfin kings lies here!
|
||||
/<$$< (wearing crown)
|
||||
/
|
||||
#67
|
||||
/Ruby slippers
|
||||
/There is a pair of ruby slippers here.
|
||||
/<$$< (wearing slippers)
|
||||
/There is a pair of ruby slippers here.
|
||||
/
|
||||
#68
|
||||
/Delicate lyre
|
||||
/There is a delicate lyre here!
|
||||
/
|
||||
#69
|
||||
/Star sapphire
|
||||
/There is a star sapphire here!
|
||||
/
|
||||
#70
|
||||
/Holy Grail
|
||||
/There is an ornate silver chalice here!
|
||||
/
|
||||
#71
|
||||
/Oaken cask
|
||||
/There is an oaken cask here.
|
||||
/There is an empty oaken cask here.
|
||||
/There is an oaken cask here.
|
||||
/<$$< (Unused)
|
||||
/There is an oaken cask here.
|
||||
/
|
||||
#72
|
||||
/Golden ring
|
||||
/There is a small gold ring here.
|
||||
/<$$< (wearing ring)
|
||||
/On the Wumpus' finger is a small gold ring.
|
||||
/
|
||||
#73
|
||||
/Four-leafed clover
|
||||
/There is a four-leafed clover here!
|
||||
/<$$< (wearing clover)
|
||||
/
|
||||
#74
|
||||
/Gold tree
|
||||
/There is a gold statue of a tree here.
|
||||
/
|
||||
#75
|
||||
/Silver droplet
|
||||
/There is a single droplet of silver on the ground here.
|
||||
/
|
||||
#76
|
||||
#77
|
||||
#78
|
||||
#79
|
||||
#80
|
||||
#81
|
||||
/Clear water
|
||||
/
|
||||
#82
|
||||
/Cool water
|
||||
/
|
||||
#83
|
||||
/Thick, black oil
|
||||
/
|
||||
#84
|
||||
/Thick, black oil
|
||||
/
|
||||
#85
|
||||
/Vintage wine
|
||||
/
|
||||
#86
|
||||
/Vintage wine
|
||||
/
|
||||
#87
|
||||
/*Bumblebees
|
||||
/<$$<
|
||||
/Some bumblebees are swarming around a bunch of fresh flowers.
|
||||
/
|
||||
#88
|
||||
/*Hollow wall
|
||||
/Your footsteps echo hollowly throughout the chamber.
|
||||
/<$$<
|
||||
/
|
||||
#89
|
||||
/*Wall with safe
|
||||
/A steel safe is embedded in the wall.
|
||||
/
|
||||
#90
|
||||
/Tiny brass key
|
||||
/There is a tiny brass key here.
|
||||
/There is a tiny brass key on the shelf.
|
||||
/
|
||||
#91
|
||||
/*Anvil
|
||||
/<$$<
|
||||
/
|
||||
#92
|
||||
/*rocks on cloak
|
||||
/<$$< (ON CLOAK)
|
||||
/<$$< (AFTER ROCK SLIDE)
|
||||
/
|
||||
#93
|
||||
/*telephone booth
|
||||
/The telephone booth is empty.
|
||||
|
||||
The phone is ringing.
|
||||
/The phone booth is occupied by a gnome. He is talking excitedly
|
||||
to someone at the other end.
|
||||
/The telephone booth is empty.
|
||||
/<$$<
|
||||
/
|
||||
#94
|
||||
/*Telephone
|
||||
/The phone is ringing.
|
||||
/The telephone is out of order.
|
||||
/The telephone is out of order. It is badly dented.
|
||||
/<$$<
|
||||
/
|
||||
#95
|
||||
/Lead slugs
|
||||
/There are some lead slugs here!
|
||||
/
|
||||
#96
|
||||
/Sweet honeycomb
|
||||
/There is a sweet honeycomb here!
|
||||
/
|
||||
#97
|
||||
/*Beehive
|
||||
/There is an active beehive nearby. The bees hum protectively
|
||||
around the hive.
|
||||
/There is an empty beehive nearby.
|
||||
/
|
||||
#98
|
||||
/*Black dog
|
||||
/A hideous black dog bares his teeth and growls at your approach.
|
||||
/Nearby, a large black dog is in a deep slumber.
|
||||
/
|
||||
#99
|
||||
/*Dreaded Wumpus
|
||||
/In the corner, a Wumpus is sleeping peacefully.
|
||||
/A sleepy Wumpus is ambling towards you. He wants to invite you to
|
||||
dinner. He wants you to *be* the dinner!
|
||||
/The Wumpus is still on your trail! And he's getting closer!!
|
||||
/The Wumpus is only a few steps behind you! All this exercise is
|
||||
making him veerrrrry hungry!
|
||||
/The Wumpus almost has you in his grasp! You can feel his hot breath
|
||||
on your neck!
|
||||
/"Chomp, chomp." Crunch! Chew! Slurp! Smack! Yum!!!
|
||||
/Nearby is the smashed body of a defunct Wumpus.
|
||||
/
|
||||
#100
|
||||
#101
|
||||
/Little bird in cage
|
||||
/A cheerful little bird is sitting here singing.
|
||||
/There is a little bird in the cage.
|
||||
/
|
||||
#102
|
||||
/Set of keys
|
||||
/There are some keys on the ground here.
|
||||
/
|
||||
#103
|
||||
/*Fountain
|
||||
/There is a fountain of sparkling vintage wine here!
|
||||
/
|
||||
#104
|
||||
/*Bats & guano in bat-cave
|
||||
/<$$<
|
||||
/
|
||||
#105
|
||||
/*gnome in phone booth
|
||||
/<$$<
|
||||
/
|
||||
#106
|
||||
/Colored mushrooms
|
||||
/There are some oddly-colored mushrooms here.
|
||||
/
|
||||
#107
|
||||
/Tiny cakes
|
||||
/There are some tiny cakes on the shelf.
|
||||
/
|
||||
#108
|
||||
/Leather Sack
|
||||
/There is a leather sack here.
|
||||
/
|
||||
#109
|
||||
#110
|
||||
/Rare book
|
||||
/There is a dusty, leather-bound volume here.
|
||||
/
|
||||
#111
|
||||
/Rare book
|
||||
/There is a dusty, leather-bound volume here.
|
||||
/
|
||||
#112
|
||||
/Steel wall-safe
|
||||
/The safe door is locked.
|
||||
/The safe door is open.
|
||||
/
|
||||
#113
|
||||
/Faded poster
|
||||
/Taped to the wall is a faded poster.
|
||||
/There is a faded poster here.
|
||||
/
|
||||
#114
|
||||
/Whiskbroom
|
||||
/There is a small whiskbroom here.
|
||||
/
|
||||
#115
|
||||
/*Carving on dusty rocks
|
||||
/<$$<
|
||||
/<$$<
|
||||
/
|
||||
#116
|
||||
/*Billboard
|
||||
/
|
||||
/
|
||||
#117
|
||||
#118
|
||||
/Small metal canister
|
||||
/There is a heavy, grey, metal canister here.
|
||||
/
|
||||
#119
|
||||
/Glowing stone
|
||||
/Nearby, a strange, greenish stone is glowing brightly.
|
||||
/
|
||||
#120
|
||||
/Quartz sphere
|
||||
/There is a polished sphere of pure quartz here!
|
||||
/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,141 +0,0 @@
|
||||
/* program DATABASE.C */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
#include "advtext.h"
|
||||
|
||||
static char oline[256];
|
||||
|
||||
_PROTOTYPE(void rdupto, (FILE *, int, int, char *));
|
||||
_PROTOTYPE(void rdskip, (FILE *, int, int));
|
||||
|
||||
/*
|
||||
Function to scan a file up to a specified
|
||||
point and either print or return a string.
|
||||
*/
|
||||
void rdupto(fdi, uptoc, print, string)
|
||||
FILE *fdi;
|
||||
int uptoc, print;
|
||||
char *string;
|
||||
{
|
||||
int c, i;
|
||||
static _CONST unsigned char key[4] = {'c' | 0x80, 'L' | 0x80,
|
||||
'y' | 0x80, 'D' | 0x80};
|
||||
|
||||
i = 1;
|
||||
while ((c = getc(fdi)) != uptoc && c != EOF) {
|
||||
if (c == '\n')
|
||||
i = 1;
|
||||
if (c >= 0x80)
|
||||
c ^= key[i++ & 3];
|
||||
if (c == '\r')
|
||||
continue;
|
||||
if (print)
|
||||
putchar(c);
|
||||
else
|
||||
*string++ = (char) c;
|
||||
}
|
||||
if (!print)
|
||||
*string = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Function to read a file skipping
|
||||
a given character a specified number
|
||||
of times, with or without repositioning
|
||||
the file.
|
||||
*/
|
||||
void rdskip(fdi, skipc, n)
|
||||
FILE *fdi;
|
||||
int skipc, n;
|
||||
{
|
||||
int c;
|
||||
|
||||
while (n--)
|
||||
while ((c = getc(fdi)) != skipc)
|
||||
if (c == EOF)
|
||||
bug(32);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to request a yes or no answer to a question.
|
||||
*/
|
||||
boolean yes(msg1, msg2, msg3)
|
||||
int msg1, msg2, msg3;
|
||||
{
|
||||
char answer[INPUTBUFLEN];
|
||||
|
||||
if (msg1)
|
||||
rspeak(msg1);
|
||||
do {
|
||||
switch (*ask("\n> ", answer, sizeof(answer))) {
|
||||
case 'n':
|
||||
case 'N':
|
||||
if (msg3)
|
||||
rspeak(msg3);
|
||||
return (FALSE);
|
||||
case 'y':
|
||||
case 'Y':
|
||||
if (msg2)
|
||||
rspeak(msg2);
|
||||
return (TRUE);
|
||||
default:
|
||||
fputs("Please answer Y (yes) or N (no).", stdout);
|
||||
}
|
||||
} while (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Print a location description from "advent4.txt"
|
||||
*/
|
||||
void rspeak(msg)
|
||||
int msg;
|
||||
{
|
||||
if (msg == 54)
|
||||
printf("ok.\n");
|
||||
else {
|
||||
fseek(fd4, idx4[msg - 1], 0);
|
||||
rdupto(fd4, '#', 1, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Print an item message for a given state from "advent3.txt"
|
||||
*/
|
||||
void pspeak(item, state)
|
||||
int item, state;
|
||||
{
|
||||
fseek(fd3, idx3[item - 1], 0);
|
||||
rdskip(fd3, '/', state + 2);
|
||||
rdupto(fd3, '/', FALSE, oline);
|
||||
if (strncmp(oline, "<$$<", 4) != 0)
|
||||
printf("%s", oline);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Print a long location description from "advent1.txt"
|
||||
*/
|
||||
void desclg(loc)
|
||||
int loc;
|
||||
{
|
||||
fseek(fd1, idx1[loc - 1], 0);
|
||||
rdupto(fd1, '#', 1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Print a short location description from "advent2.txt"
|
||||
*/
|
||||
void descsh(loc)
|
||||
int loc;
|
||||
{
|
||||
fseek(fd2, idx2[loc - 1], 0);
|
||||
rdupto(fd2, '#', 1, 0);
|
||||
return;
|
||||
}
|
||||
@@ -1,676 +0,0 @@
|
||||
/* program ENGLISH.C */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
|
||||
#define ALL 109
|
||||
|
||||
#define ENTER 3
|
||||
#define CRAWL 17
|
||||
#define JUMP 39
|
||||
#define CLIMB 56
|
||||
#define XYZZY 62
|
||||
#define PLUGH 65
|
||||
#define PLOVER 71
|
||||
#define PHUCE 82
|
||||
|
||||
_PROTOTYPE(static void getwords, (void));
|
||||
_PROTOTYPE(static void clrlin, (void));
|
||||
_PROTOTYPE(static void doobj, (int *));
|
||||
_PROTOTYPE(static boolean doiobj, (void));
|
||||
_PROTOTYPE(static boolean do_scoop_up, (void));
|
||||
_PROTOTYPE(static boolean check_next, (void));
|
||||
|
||||
static char buffer[INPUTBUFLEN] = {'\0', '\0', '\0', '\0'};
|
||||
static char *txt[MAXWORDS] = {buffer, buffer, buffer, buffer};
|
||||
static char *cindex = buffer;
|
||||
static boolean pflag;
|
||||
static int vrbkey, words[MAXWORDS] = {0, 0, 0, 0}, word, wdx = 0;
|
||||
static int takdir[20] = {2, 6, 9, 10, 11, 13, 14, 17, 23, 25,
|
||||
33, 34, 36, 37, 39, 78, 79, 80, 89, -1};
|
||||
|
||||
static int vkey[60] = {
|
||||
0, 199, 9, 0, 130, 0, 197, 0, 0, 243,
|
||||
0, 0, 89, 140, 0, 5, 0, 227, 0, 0,
|
||||
0, 31, 42, 0, 0, 0, 0, 172, 1, 0,
|
||||
0, 0, 254, 0, 69, 0, 0, 92, 0, 0,
|
||||
138, 137, 149, 239, 45, 74, 183, 0, 0, 112,
|
||||
241, 0, 114, 0, 30, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static int ptab[260] = {
|
||||
0, 3028, 3065, 3009, -3005, 5071, 5070, 5058, -5020, 19055,
|
||||
19108, 19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094,
|
||||
19112, 19002, 19118, 2062, 2066, 2047, 2067, 2053, 2065, -2010,
|
||||
-3114, 4034, 4011, 4101, 4035, 4099, 4098, 4017, 4104, 4014,
|
||||
4015, -4087, 3083, 3085, -3081, 5055, 5108, 5020, 5071, 5070,
|
||||
5058, 5004, 5048, 5091, 5112, 5099, 5118, 19055, 19108, 19020,
|
||||
19071, 19070, 19058, 19004, 19048, 19091, 19112, 19099,-19118, 3028,
|
||||
3065, 3009, 3005, -3018, 19055, 19108, 19038, 19020, 19071, 19070,
|
||||
19058, 19004, 19004, 19048, 19091, 19094, 19112, 19002,-19118, 3028,
|
||||
3065, -3018, 19055, 19108, 19038, 19020, 19071, 19070, 19058, 19004,
|
||||
19048, 19091, 19094, 19112, 19118, 2062, 2066, 2047, 2067, 2053,
|
||||
2065, -2010, 3102, -3090, 19055, 19108, 19020, 19071, 19070, 19058,
|
||||
19004, 19048, 19091, 19014, 19015, 19112, 19118, 19120, 19120, -9999,
|
||||
3090, 3102, 3028, 3057, 3065, 3009, -3005,-29999, 2052, -2068,
|
||||
2024, 2065, 2091, 2042, 2073, 5071, 5070, 5058, -5020, 30999,
|
||||
2062, 2066, 2047, 2067, 2053, 2065, 2010, 2073, 19055, 19108,
|
||||
19038, 19020, 19071, 19070, 19058, 19004, 19048, 19091, 19094, 19112,
|
||||
19002,-19118, 2014, 2015, 2013, 2999, 5014, 5015, 5013, 5999,
|
||||
5110, 5113, -5999, 5055, 5108, 5020, 5071, 5070, 5058, 5004,
|
||||
5048, 5091, 5014, 5015, 5112, 5099, -5118, 3102, -3090, 6066,
|
||||
6047, 6067, 6053, 6072, 6073, 5055, 5108, 5020, 5071, 5070,
|
||||
5004, 5004, 5048, 5091, 5112, 5099, 5118, 19055, 19108, 19020,
|
||||
19071, 19070, 19058, 19004, 19048, 19091,-19118, 4034, 4011, 4101,
|
||||
4035, 4099, 4098, 4017, 4104, 4027, 4087, 9999,-30999, 2002,
|
||||
-6002, 3102, -3090, 9999, 4034, 4011, 4101, 4035, 4099, 4087,
|
||||
4098, 4017, 4104, -4027, -5999, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static int adjkey[40] = {
|
||||
0, 15, 38, 64, 4, 63, 1, 61, 62, 67,
|
||||
9, 27, 53, 46, 47, 60, 31, 39, 40, 6,
|
||||
43, 26, 32, 28, 34, 50, 49, 45, 44, 10,
|
||||
20, 25, 21, 36, 37, 30, 33, 0, 0, 0
|
||||
};
|
||||
|
||||
static int adjtab[70] = {
|
||||
0, 5, 98, -83, 2, -90, 66, 41, -90, -39,
|
||||
41, 14, 15, 50, -11, 50, 64, 56, 72, -74,
|
||||
-19, 119, 59, 73, -118, -119, -70, -41, 95, -118,
|
||||
-118, -58, -71, -120, 110, -108, -120, -73, -62, -60,
|
||||
110, 54, -63, -67, -41, -27, -47, 52, -75, -69,
|
||||
65, 112, -3, 41, 72, 90, 20, 101, 107, -118,
|
||||
-55, -10, -38, -4, 48, 9, -71, -39, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
Analyze a two word sentence
|
||||
*/
|
||||
int english()
|
||||
{
|
||||
|
||||
char *ch_ptr, *word1, *word2;
|
||||
int type, val, type2, val2, adj, k, kk;
|
||||
static int iwest = 0;
|
||||
|
||||
if (!(words[++wdx])) {
|
||||
getwords();
|
||||
wdx = 0;
|
||||
}
|
||||
pflag = FALSE;
|
||||
word = words[wdx];
|
||||
if (word < 0) { /* check first word */
|
||||
printf("I didn't understand the word \"%s\"\n", txt[wdx]);
|
||||
words[wdx+1] = 0;
|
||||
return (FALSE); /* didn't know it */
|
||||
}
|
||||
type2 = val2 = -1;
|
||||
type = CLASS(word);
|
||||
clrlin();
|
||||
val = VAL(word);
|
||||
if (words[wdx + 1] && CLASS(words[wdx + 1]) != CONJUNCTION) {
|
||||
|
||||
/* 'SAY' or 'CALL'. If no next word, pass on to higher powers. */
|
||||
if (type == ACTION && (val == SAY || val == YELL)) {
|
||||
word = words[++wdx];
|
||||
if (!(word == XYZZY || word == PLUGH
|
||||
|| word == PLOVER || word == PHUCE)) {
|
||||
if (val == SAY)
|
||||
printf("Okay, \"%s\".\n", txt[wdx]);
|
||||
else {
|
||||
for (ch_ptr = txt[wdx]; *ch_ptr; ch_ptr++)
|
||||
if (islower(*ch_ptr))
|
||||
*ch_ptr = toupper(*ch_ptr);
|
||||
printf("Okay, \"%s\"!!!!!\n", txt[wdx]);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
word1 = txt[wdx];
|
||||
word2 = txt[wdx + 1];
|
||||
|
||||
/* Special stuff for 'ENTER'. Can't go into water. 'ENTER
|
||||
BOAT' means 'TAKE BOAT' */
|
||||
if (word == ENTER) {
|
||||
if (CLASS(words[wdx + 1]) == NOUN && VAL(words[wdx + 1]) == BOAT)
|
||||
word = TAKE + 2000;
|
||||
else if ((strcmp(word2, "stream") == 0)
|
||||
|| (strcmp(word2, "water") == 0)
|
||||
|| (strcmp(word2, "reservoir") == 0)
|
||||
|| (strcmp(word2, "ocean") == 0)
|
||||
|| (strcmp(word2, "sea") == 0)
|
||||
|| (strcmp(word2, "pool") == 0)) {
|
||||
rspeak(liqloc(g.loc) == WATER ? 70 : 43);
|
||||
wdx++;
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
type2 = CLASS(words[wdx + 1]);
|
||||
val2 = VAL(words[wdx + 1]);
|
||||
|
||||
/* 'LEAVE' is motion verb, unsless leaving an object.
|
||||
E.G., 'LEAVE BOAT' or 'LEAVE BOTTLE'. BUt make sure
|
||||
to leave ('DROP') only totable objects. */
|
||||
if (strcmp(word1, "leave") == 0 && type2 == NOUN) {
|
||||
if (!hinged(val2) || g.fixed[val2])
|
||||
word = LEAVE + 2000;
|
||||
|
||||
/* IF 'LIGHT LAMP', Light must be taken as an
|
||||
action verb, not a noun. */
|
||||
} else if (strcmp(word1, "light") == 0
|
||||
&& VAL(words[wdx + 1]) == LAMP) {
|
||||
word = ON + 2000;
|
||||
|
||||
/* 'WATER PLANT' becomes 'POUR WATER', If we are at
|
||||
plant. 'OIL DOOR' becomes 'POUR OIL', etc., etc. */
|
||||
} else if ((strcmp(word1, "water") == 0 || strcmp(word1, "oil") == 0)
|
||||
&& (strcmp(word2, "plant") == 0 || strcmp(word2, "door") == 0
|
||||
|| strcmp(word2, "sword") == 0 || strcmp(word2, "anvil") == 0)
|
||||
&& at(val2)) {
|
||||
words[wdx + 1] = word;
|
||||
txt[wdx + 1] = txt[wdx];
|
||||
word = POUR + 2000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* This is the 'inner' loop. Dispatching of all word in a clause
|
||||
after the first comes through here. */
|
||||
do {
|
||||
switch (CLASS(word)) {
|
||||
case MOTION:
|
||||
{
|
||||
boolean do_part2;
|
||||
int i;
|
||||
|
||||
do_part2 = FALSE;
|
||||
type = CLASS(verbs[vrbx]);
|
||||
val = VAL(verbs[vrbx]);
|
||||
if (!vrbx)
|
||||
do_part2 = TRUE;
|
||||
else {
|
||||
if (type > ACTION) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
if (type == ACTION) {
|
||||
if (val == GO)
|
||||
do_part2 = TRUE;
|
||||
else {
|
||||
if (val == TAKE) {
|
||||
for (i = 0; i < 20; i++)
|
||||
if (takdir[i] == val)
|
||||
do_part2 = TRUE;
|
||||
}
|
||||
if (!do_part2) {
|
||||
word = vocab(txt[wdx], 1);
|
||||
if (word)
|
||||
words[wdx--] = word;
|
||||
}
|
||||
}
|
||||
} else if (type != CRAWL && type != JUMP
|
||||
&& type != CLIMB)
|
||||
do_part2 = TRUE;
|
||||
if (do_part2) {
|
||||
verbs[1] = word;
|
||||
vrbx = 1;
|
||||
if (strcmp(txt[wdx], "west") == 0) {
|
||||
iwest++;
|
||||
if (iwest == 10)
|
||||
rspeak(17);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NOUN:
|
||||
if (pflag) {
|
||||
if (!doiobj())
|
||||
return (FALSE);
|
||||
} else {
|
||||
word = VAL(word);
|
||||
if (word == ALL) {
|
||||
if (!do_scoop_up())
|
||||
return (FALSE);
|
||||
} else {
|
||||
doobj(&word);
|
||||
if (word > 0) {
|
||||
objs[++objx] = word;
|
||||
otxt[objx] = txt[wdx];
|
||||
} else {
|
||||
clrlin();
|
||||
pflag = FALSE;
|
||||
wdx++;
|
||||
while (words[wdx]) {
|
||||
if (CLASS(words[wdx]) == CONJUNCTION)
|
||||
break;
|
||||
wdx++;
|
||||
}
|
||||
if (words[wdx] == 0)
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION:
|
||||
if (vrbx == 0)
|
||||
vrbx++;
|
||||
else {
|
||||
if (VAL(verbs[vrbx]) == TAKE) {
|
||||
val = VAL(word);
|
||||
if (val == DRINK || val == INVENTORY
|
||||
|| val == SCORE || val == NOTHING
|
||||
|| val == LOOK);
|
||||
else if (val == GO && (
|
||||
strcmp(txt[wdx], "walk") == 0
|
||||
|| strcmp(txt[wdx], "run") == 0
|
||||
|| strcmp(txt[wdx], "hike") == 0));
|
||||
else {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
} else if (objx || CLASS(words[wdx - 1]) == CONJUNCTION) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
verbs[vrbx] = word;
|
||||
vtxt[vrbx] = txt[wdx];
|
||||
break;
|
||||
case MISC:
|
||||
if (vrbx) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
verbs[1] = word;
|
||||
vrbx = 1;
|
||||
break;
|
||||
case PREPOSITION:
|
||||
if (CLASS(verbs[vrbx]) != ACTION || iobx) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
vrbkey = vkey[VAL(verbs[vrbx])];
|
||||
if (!vrbkey) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
prep = VAL(word);
|
||||
pflag = TRUE;
|
||||
break;
|
||||
case ADJACTIVE:
|
||||
/* Adjective handler. Scarf the next word, make sure it is
|
||||
a valid object for this object. Then call getobj to see
|
||||
if it is really there, Then link into object code. */
|
||||
adj = VAL(word);
|
||||
if (!check_next())
|
||||
return (FALSE);
|
||||
else if (CLASS(word) == CONJUNCTION) {
|
||||
printf("%s what?\n", txt[wdx - 1]);
|
||||
return (FALSE);
|
||||
} else {
|
||||
if (CLASS(word) != NOUN)
|
||||
word = vocab(txt[wdx], NOUN);
|
||||
if (word == -1 || CLASS(word) != NOUN || VAL(word) == ALL) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
words[wdx] = word;
|
||||
kk = VAL(word);
|
||||
for (k = adjkey[adj]; adjtab[k] >= 0; k++) {
|
||||
if (kk == abs(adjtab[k]))
|
||||
break;
|
||||
}
|
||||
if (adjtab[k] < 0) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONJUNCTION:
|
||||
if (!check_next())
|
||||
return (FALSE);
|
||||
switch (CLASS(word)) {
|
||||
case MOTION:
|
||||
case ACTION:
|
||||
case MISC:
|
||||
words[wdx--] = 0;
|
||||
break;
|
||||
case NOUN:
|
||||
case ADJACTIVE:
|
||||
break;
|
||||
case PREPOSITION:
|
||||
case CONJUNCTION:
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
default:
|
||||
bug(33);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bug(33);
|
||||
}
|
||||
word = words[++wdx];
|
||||
if (word < 0) {
|
||||
if (pct(50))
|
||||
printf("I don't understand the word %s?\n", txt[wdx]);
|
||||
else
|
||||
printf("Mumble ? %s\n", txt[wdx]);
|
||||
|
||||
words[wdx+1] = 0;
|
||||
return (FALSE);
|
||||
}
|
||||
type = CLASS(word);
|
||||
if (type == NOUN) {
|
||||
/* It's not the first: Make sure he included a comma or
|
||||
'and'. Differenctiate between direct & indirect objects.
|
||||
Check for special case of multiple ofjects: 'feed bear
|
||||
honey' or 'throw troll nugget'. */
|
||||
if ((pflag ? iobx : objx)
|
||||
&& CLASS(words[wdx - 1]) != CONJUNCTION) {
|
||||
val = VAL(verbs[vrbx]);
|
||||
if (!living(objs[objx]) || (val != THROW && val != FEED)) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
iobx++;
|
||||
iobjs[iobx] = objs[objx];
|
||||
objs[objx] = 0;
|
||||
objx++;
|
||||
}
|
||||
}
|
||||
} while (word);
|
||||
|
||||
if (verbs[1] == 0) {
|
||||
if (objs[1] == 0) {
|
||||
rspeak(confuz());
|
||||
clrlin();
|
||||
} else if (objs[2])
|
||||
printf("What do you want to do with them?\n");
|
||||
else
|
||||
printf("What do you want to do with %s?\n", otxt[1]);
|
||||
return (FALSE);
|
||||
} else if (objx > 1 && iobx > 1) {
|
||||
rspeak(confuz());
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
retrieve input line (max INPUTBUFLEN chars), convert to lower case
|
||||
& rescan for first two words (max. WORDSIZE-1 chars).
|
||||
*/
|
||||
static void getwords()
|
||||
{
|
||||
static int wdx = 0;
|
||||
int i, term_loc;
|
||||
char terminator;
|
||||
|
||||
if (*cindex == '\0') {
|
||||
while (!*ask("\n> ", buffer, sizeof(buffer))) ;
|
||||
for (cindex = buffer; *cindex; cindex++)
|
||||
if (isupper(*cindex))
|
||||
*cindex = tolower(*cindex);
|
||||
cindex = buffer;
|
||||
}
|
||||
wdx = 0;
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
for (i = 0; i < MAXWORDS; i++) {
|
||||
txt[i] = &buffer[sizeof(buffer)-1];
|
||||
words[i] = 0;
|
||||
}
|
||||
do {
|
||||
while (*cindex == ' ')
|
||||
cindex++;
|
||||
txt[wdx] = cindex;
|
||||
term_loc = strcspn(cindex, " ,.;\n");
|
||||
cindex += term_loc;
|
||||
terminator = *cindex;
|
||||
*cindex++ = '\0';
|
||||
if ((strcmp(txt[wdx], "a") != 0)
|
||||
&& (strcmp(txt[wdx], "the") != 0)
|
||||
&& (strcmp(txt[wdx], "an") != 0)) {
|
||||
words[wdx] = vocab(txt[wdx], 0);
|
||||
wdx++;
|
||||
}
|
||||
if (terminator == ',') {
|
||||
txt[wdx] = "and";
|
||||
words[wdx] = vocab(txt[wdx], 0);
|
||||
wdx++;
|
||||
}
|
||||
}
|
||||
while ((terminator != ';') && (terminator != '.')
|
||||
&& (terminator != '\0') && (terminator != '\n'));
|
||||
if (terminator == '\0')
|
||||
cindex--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* CLRIN, clears out all surrent syntax args in preparation for
|
||||
* new input line
|
||||
*/
|
||||
|
||||
static void clrlin()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXWORDS; i++) {
|
||||
verbs[i] = 0;
|
||||
vtxt[i] = &buffer[sizeof(buffer)-1];
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXITEMS; i++) {
|
||||
objs[i] = 0;
|
||||
otxt[i] = &buffer[sizeof(buffer)-1];
|
||||
iobjs[i] = 0;
|
||||
iotxt[i] = &buffer[sizeof(buffer)-1];
|
||||
}
|
||||
vrbx = 0;
|
||||
objx = 0;
|
||||
iobx = 0;
|
||||
prep = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to process an object.
|
||||
*/
|
||||
static void doobj(object)
|
||||
int *object;
|
||||
{
|
||||
int msg;
|
||||
|
||||
if (holding(*object))
|
||||
return;
|
||||
if (blind()) {
|
||||
printf("I see no %s here.\n", txt[wdx]);
|
||||
*object = 0;
|
||||
return;
|
||||
}
|
||||
/* Is object here? if so, transitive */
|
||||
if (g.fixed[*object] == g.loc || athand(*object))
|
||||
return;
|
||||
else if (here(*object)) {
|
||||
msg = plural(*object) ? 373 : 335;
|
||||
*object = 0;
|
||||
rspeak(msg);
|
||||
}
|
||||
/* Did he give grate as destination? */
|
||||
else if (*object == GRATE) {
|
||||
if (g.loc == 1 || g.loc == 4 || g.loc == 7) {
|
||||
verbs[1] = DEPRESSION;
|
||||
vrbx = 1;
|
||||
return;
|
||||
} else if (g.loc > 9 && g.loc < 15) {
|
||||
verbs[1] = ENTRANCE;
|
||||
vrbx = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Is it a dwarf he is after? */
|
||||
else if (dcheck() && g.dflag >= 2) {
|
||||
*object = DWARF;
|
||||
}
|
||||
/* Is he trying to get/use a liquid? */
|
||||
else if (liqloc(g.loc) == *object
|
||||
|| (liq(BOTTLE) == *object && athand(BOTTLE))
|
||||
|| (liq(CASK) == *object && athand(CASK)));
|
||||
else if (*object == PLANT && at(PLANT2) &&
|
||||
g.prop[PLANT2] == 0) {
|
||||
*object = PLANT2;
|
||||
} else if (*object == ROCKS && at(CARVNG)) {
|
||||
*object = CARVNG;
|
||||
}
|
||||
/* Is he trying to grab a knife? */
|
||||
else if (*object == KNIFE && g.knfloc == g.loc) {
|
||||
rspeak(116);
|
||||
g.knfloc = -1;
|
||||
}
|
||||
/* Is he trying to get at dynamite? */
|
||||
else if (*object == ROD && athand(ROD2)) {
|
||||
*object = ROD2;
|
||||
} else if (*object == DOOR && (at(SAFE) || at(TDOOR)
|
||||
|| at(TDOOR2) || at(PDOOR))) {
|
||||
if (at(TDOOR2))
|
||||
*object = TDOOR2;
|
||||
else if (at(PDOOR))
|
||||
*object = PDOOR;
|
||||
else if (at(SAFE))
|
||||
*object = SAFE;
|
||||
else
|
||||
*object = TDOOR;
|
||||
} else if (*object == BOOK && athand(BOOK2)) {
|
||||
*object = BOOK2;
|
||||
} else if (!(verbs[vrbx] == FIND || verbs[vrbx] == INVENTORY)) {
|
||||
*object = 0;
|
||||
printf("I see no %s here.\n", txt[wdx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static boolean doiobj()
|
||||
{
|
||||
char dk[INPUTBUFLEN], dkk[INPUTBUFLEN];
|
||||
int kk;
|
||||
boolean ok;
|
||||
|
||||
/* checks object is valid for this preposition */
|
||||
ok = TRUE;
|
||||
word = VAL(word);
|
||||
if (word != ALL) {
|
||||
doobj(&word);
|
||||
if (word > 0) {
|
||||
iobjs[++iobx] = word;
|
||||
iotxt[iobx] = txt[wdx];
|
||||
} else
|
||||
ok = FALSE;
|
||||
}
|
||||
kk = abs(ptab[vrbkey]) / 1000;
|
||||
if (kk == prep) {
|
||||
/* preprosition is valid with this verb now check object of
|
||||
preprosition */
|
||||
|
||||
if (word == 0 || CLASS(word) == CONJUNCTION) {
|
||||
/* no object following prepresition: check special cases */
|
||||
|
||||
pflag = FALSE;
|
||||
strcpy(dk, txt[--wdx]);
|
||||
strcpy(dkk, vtxt[vrbx]);
|
||||
ok = FALSE;
|
||||
if ((strcmp(dk, "on") == 0
|
||||
|| strcmp(dk, "off") == 0)
|
||||
&& (strcmp(dkk, "turn") == 0
|
||||
|| objs[objx] == LAMP))
|
||||
ok = TRUE;
|
||||
if (strcmp(dkk, "take") == 0
|
||||
|| strcmp(dkk, "put") == 0)
|
||||
ok = TRUE;
|
||||
if (strcmp(dk, "up") == 0
|
||||
&& strcmp(dkk, "pick") == 0)
|
||||
ok = TRUE;
|
||||
if (strcmp(dk, "down") == 0
|
||||
&& (strcmp(dkk, "put") == 0 || verbs[vrbx] == THROW) )
|
||||
ok = TRUE;
|
||||
} else {
|
||||
/* object follows preposition See if it's plausible. */
|
||||
|
||||
kk = abs(ptab[vrbkey]) % 1000;
|
||||
if (kk == word && kk == ALL) {
|
||||
if (!do_scoop_up())
|
||||
return (FALSE);
|
||||
} else if (!(kk == word || kk == 999)) {
|
||||
vrbkey++;
|
||||
ok = ptab[vrbkey - 1] < 0 ? FALSE : TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ok);
|
||||
}
|
||||
|
||||
static boolean do_scoop_up()
|
||||
{
|
||||
int i, val;
|
||||
|
||||
val = VAL(verbs[vrbx]);
|
||||
if (val == DROP || val == PUT || val == LEAVE) {
|
||||
for (i = 1; i < MAXOBJ; i++) {
|
||||
if (!athand(i) || g.fixed[i])
|
||||
continue;
|
||||
if (i > WATER && i <= WINE + 1)
|
||||
continue;
|
||||
if (toting(i)) {
|
||||
objs[++objx] = i;
|
||||
otxt[objx] = "BUG???";
|
||||
if (objx >= 44)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val == TAKE || val == PICK || val == GET) {
|
||||
if (blind()) {
|
||||
rspeak(357);
|
||||
return (FALSE);
|
||||
} else {
|
||||
for (i = 1; i < MAXOBJ; i++) {
|
||||
if (!athand(i) || g.fixed[i])
|
||||
continue;
|
||||
if (i > WATER && i <= WINE + 1)
|
||||
continue;
|
||||
if (!toting(i)) {
|
||||
objs[++objx] = i;
|
||||
otxt[objx] = "BUG???";
|
||||
if (objx >= 44)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static boolean check_next()
|
||||
{
|
||||
|
||||
word = words[wdx + 1];
|
||||
if (word > 0)
|
||||
return (TRUE);
|
||||
else if (word == 0)
|
||||
rspeak(confuz());
|
||||
else {
|
||||
if (pct(50))
|
||||
printf("I don't understand the word %s?\n", txt[wdx]);
|
||||
else
|
||||
printf("Mumble ? %s\n", txt[wdx]);
|
||||
words[wdx+1] = 0;
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
Initialization of adventure play variables
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "advent.h" /* #define preprocessor equates */
|
||||
#define EXTERN /* define, not declare, in advdec.h */
|
||||
#include "advdec.h"
|
||||
|
||||
int plac[MAXOBJ] = {
|
||||
0, 0, 3, 8, 10, 11, 0, 14, 0, 148, /* 0 - 9 */
|
||||
96, 19, 17, 101, 103, 0, 106, 0, 0, 238, /* 10 - 19 */
|
||||
238, 117, 190, 109, 25, 23, 111, 35, 0, 97, /* 20 - 29 */
|
||||
0, 119, 0, 117, 0, 130, 0, 126, 140, 0, /* 30 - 39 */
|
||||
96, 94, 158, 160, 188, 0, 155, 174, 166, 228, /* 40 - 49 */
|
||||
18, 204, 27, 29, 30, 0, 92, 168, 97, 100, /* 50 - 59 */
|
||||
101, 0, 119, 127, 130, 141, 144, 205, 28, 182, /* 60 - 69 */
|
||||
225, 230, 0, 147, 241, 248, 0, 0, 0, 0, /* 70 - 79 */
|
||||
0, 0, 0, 0, 0, 0, 0, 193, 102, 0, /* 80 - 89 */
|
||||
159, 141, 172, 188, 189, 0, 0, 193, 227, 174, /* 90 - 99 */
|
||||
0, 13, 238, 217, 171, 0, 146, 159, 3, 0, /* 100 - 109 */
|
||||
0, 0, 0, 3, 180, 39, 5, 0, 110, 169, /* 110 - 119 */
|
||||
200
|
||||
};
|
||||
|
||||
int fixd[MAXOBJ] = {
|
||||
0, 0, 0, 9, 0, 0, 0, 15, 0, 0, /* 0 - 9 */
|
||||
0, -1, 27, -1, 0, 0, 0, -1, 0, 0, /* 10 - 19 */
|
||||
0, 122, 235, -1, -1, 67, -1, 110, 0, -1, /* 20 - 29 */
|
||||
-1, 121, 0, 122, 0, -1, -1, -1, -1, 0, /* 30 - 39 */
|
||||
-1, -1, 166, 167, 189, 0, 0, -1, 0, 229, /* 40 - 49 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 59 */
|
||||
0, 0, 121, 0, -1, 0, 0, 0, 0, 0, /* 60 - 69 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 79 */
|
||||
0, 0, 0, 0, 0, 0, 0, -1, 194, -1, /* 80 - 89 */
|
||||
0, -1, 174, -1, -1, 0, 0, -1, -1, -1, /* 90 - 99 */
|
||||
0, 0, 0, -1, -1, -1, 0, 0, 0, 0, /* 100 - 109 */
|
||||
0, 0, -1, 0, 0, -1, -1, 0, 0, 0, /* 110 - 119 */
|
||||
0
|
||||
};
|
||||
|
||||
struct playinfo g = {
|
||||
0, /* turns */
|
||||
1, /* loc */
|
||||
1, /* oldloc */
|
||||
1, /* oldloc2 */
|
||||
1, /* newloc */
|
||||
{ /* loc_attrib[MAXLOC] */
|
||||
0, 73, 65, 73, 73, /* 0 - 4 */
|
||||
65, 65, 73, 1601, 33, /* 5 - 9 */
|
||||
32, 32, 32, 1824, 32, /* 10 - 14 */
|
||||
0, 2, 0, 0, 2816, /* 15 - 19 */
|
||||
2, 2, 2, 0, 10, /* 20 - 24 */
|
||||
0, 2, 0, 0, 0, /* 25 - 29 */
|
||||
0, 2, 2, 8, 0, /* 30 - 34 */
|
||||
0, 0, 0, 8, 0, /* 35 - 39 */
|
||||
2, 0, 256, 256, 256, /* 40 - 44 */
|
||||
256, 272, 272, 272, 256, /* 45 - 49 */
|
||||
256, 0, 256, 256, 272, /* 50 - 54 */
|
||||
256, 272, 0, 16, 2, /* 55 - 59 */
|
||||
0, 0, 0, 0, 0, /* 60 - 64 */
|
||||
0, 0, 0, 0, 0, /* 65 - 69 */
|
||||
0, 0, 0, 0, 0, /* 70 - 74 */
|
||||
0, 0, 0, 0, 2, /* 75 - 79 */
|
||||
256, 256, 272, 0, 0, /* 80 - 84 */
|
||||
16, 272, 0, 0, 2, /* 85 - 89 */
|
||||
2, 0, 0, 0, 0, /* 90 - 94 */
|
||||
8, 0, 0, 1280, 513, /* 95 - 99 */
|
||||
513, 512, 0, 0, 0, /* 00 - 04 */
|
||||
0, 0, 0, 768, 0, /* 105 - 109 */
|
||||
0, 0, 0, 8, 0, /* 110 - 114 */
|
||||
1, 1, 0, 0, 0, /* 115 - 119 */
|
||||
0, 0, 16, 16, 16, /* 120 - 124 */
|
||||
16, 17, 16, 16, 16, /* 125 - 129 */
|
||||
16, 0, 0, 0, 0, /* 130 - 134 */
|
||||
0, 0, 0, 0, 0, /* 135 - 139 */
|
||||
0, 1040, 16, 0, 0, /* 140 - 144 */
|
||||
2, 65, 65, 65, 65, /* 145 - 149 */
|
||||
65, 65, 65, 65, 65, /* 150 - 154 */
|
||||
65, 3, 2625, 2113, 65, /* 155 - 159 */
|
||||
65, 3, 3, 3, 3, /* 160 - 164 */
|
||||
3, 41, 41, 9, 9, /* 165 - 169 */
|
||||
0, 0, 0, 0, 0, /* 170 - 174 */
|
||||
0, 0, 0, 2, 0, /* 175 - 179 */
|
||||
0, 2, 0, 0, 0, /* 180 - 184 */
|
||||
0, 0, 0, 0, 16, /* 185 - 189 */
|
||||
0, 0, 9, 0, 0, /* 190 - 194 */
|
||||
0, 0, 0, 9, 2, /* 195 - 199 */
|
||||
1, 1, 2304, 0, 0, /* 200 - 204 */
|
||||
0, 8, 8, 8, 0, /* 205 - 209 */
|
||||
0, 0, 1, 0, 9, /* 210 - 214 */
|
||||
0, 0, 12, 0, 0, /* 215 - 219 */
|
||||
0, 0, 0, 0, 0, /* 220 - 224 */
|
||||
0, 2, 2625, 73, 73, /* 225 - 229 */
|
||||
0, 2, 2, 2, 2, /* 230 - 234 */
|
||||
0, 0, 2, 65, 3137, /* 235 - 239 */
|
||||
65, 65, 65, 65, 65, /* 240 - 244 */
|
||||
65, 65, 65, 65 /* 245 - 249 */
|
||||
}, /* loc_attrib[MAXLOC] */
|
||||
{0 }, /* place[MAXOBJ] */
|
||||
{0 }, /* fixed[MAXOBJ] */
|
||||
{ /* weight[MAXOBJ] */
|
||||
0, 0, 1, 0, 1, 2, 2, 0, 0, 2, /* 0 - 9 */
|
||||
1, 0, 0, 0, 7, 7, 1, 0, 0, 2, /* 10 - 19 */
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* 20 - 29 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, /* 30 - 39 */
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, /* 40 - 49 */
|
||||
6, 1, 2, 2, 3, 5, 4, 3, 2, 3, /* 50 - 59 */
|
||||
4, 1, 3, 1, 3, 2, 1, 1, 2, 2, /* 60 - 69 */
|
||||
2, 3, 1, 1, 3, 1, 0, 0, 0, 0, /* 70 - 79 */
|
||||
0, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 70 - 79 */
|
||||
1, 0, 0, 0, 0, 3, 2, 0, 0, 0, /* 80 - 89 */
|
||||
0, 2, 1, 0, 0, 0, 1, 1, 2, 0, /* 100 - 109 */
|
||||
3, 3, 0, 1, 1, 0, 0, 0, 3, 1, /* 110 - 119 */
|
||||
2, 0, 0 /* 120 - 129 */
|
||||
}, /* weight[MAXOBJ] */
|
||||
{0 }, /* atloc[MAXLOC] */
|
||||
{0 }, /* link[MAXOBJ * 2] */
|
||||
{0 }, /* holder[MAXOBJ] */
|
||||
{0 }, /* hlink[MAXOBJ] */
|
||||
{0 }, /* visited[MAXLOC] */
|
||||
{0 }, /* prop[MAXOBJ] */
|
||||
{ /* obj_state[MAXOBJ] */
|
||||
0, 0, 32800, 26, 32770, /* 0 - 4 */
|
||||
32, 32, 8192, 0, 0, /* 5 - 9 */
|
||||
32, 512, 0, 256, 770, /* 10 - 14 */
|
||||
770, 288, 512, 0, 160, /* 15 - 19 */
|
||||
32802, 0, 0, 0, 128, /* 20 - 24 */
|
||||
0, 0, 0, 32, 8192, /* 25 - 29 */
|
||||
512, 512, 0, 512, 0, /* 30 - 34 */
|
||||
512, 256, 0, 32768, 8224, /* 35 - 39 */
|
||||
0, 18, 26, 26, 2, /* 40 - 44 */
|
||||
0, 8320, 18464, 32768, 0, /* 45 - 49 */
|
||||
16384, 16416, 16416, 26656, 24608, /* 50 - 54 */
|
||||
49240, 24608, 16384, 49184, 16416, /* 55 - 59 */
|
||||
16416, 16416, 16384, 16544, 16442, /* 60 - 64 */
|
||||
16416, 18464, 26656, 16416, 16416, /* 65 - 69 */
|
||||
49184, 49154, 18464, 18464, 16416, /* 70 - 74 */
|
||||
16416, 0, 0, 0, 0, /* 75 - 79 */
|
||||
0, 0, 0, 0, 0, /* 80 - 84 */
|
||||
0, 0, 8704, 0, 0, /* 85 - 89 */
|
||||
0, 0, 0, 0, 32768, /* 90 - 94 */
|
||||
0, 128, 0, 0, 0, /* 95 - 99 */
|
||||
0, 160, 8224, 0, 0, /* 100 - 104 */
|
||||
0, 8352, 8352, 32870, 0, /* 105 - 109 */
|
||||
16674, 258, 32858, 288, 32, /* 110 - 114 */
|
||||
256, 0, 0, 32866, 16416, /* 115 - 119 */
|
||||
16416, 0, 0 /* 120 - 123 */
|
||||
}, /* obj_state[MAXOBJ] */
|
||||
{ /* points[MAXOBJ] */
|
||||
0, 0, 0, 0, 0, /* 0 - 4 */
|
||||
0, 0, 0, 0, 0, /* 5 - 9 */
|
||||
0, 0, 0, 0, 0, /* 10 - 14 */
|
||||
0, 1000108, 0, 0, 0, /* 15 - 19 */
|
||||
0, 0, 0, 0, 0, /* 20 - 24 */
|
||||
0, 0, 0, 0, 0, /* 25 - 29 */
|
||||
0, 0, 0, 0, 0, /* 30 - 34 */
|
||||
0, 0, 0, 0, 0, /* 35 - 39 */
|
||||
0, 0, 0, 0, 0, /* 40 - 44 */
|
||||
0, 0, -3000112, 0, 0, /* 45 - 49 */
|
||||
-2000055, -2000112, -2000112, -1000112, -5000112, /* 50 - 54 */
|
||||
5000003, -3000112, -2000055, 2000003, -3000112, /* 55 - 59 */
|
||||
-4000112, -4000112, 3000003, -1000112, -4000112, /* 60 - 64 */
|
||||
-4000112, -2000112, -3000112, -1000112, -1000112, /* 65 - 69 */
|
||||
-2000112, -3012055, -4000112, -1000112, -5000112, /* 70 - 74 */
|
||||
-5000112, 0, 0, 0, 0, /* 75 - 79 */
|
||||
0, 0, 0, 0, 0, /* 80 - 84 */
|
||||
0, 0, 0, 0, 0, /* 85 - 89 */
|
||||
0, 0, 0, 0, 0, /* 90 - 94 */
|
||||
0, 0, 0, 0, 0, /* 95 - 99 */
|
||||
0, 0, 0, 0, 0, /* 100 - 104 */
|
||||
0, 0, 0, 0, 0, /* 105 - 109 */
|
||||
-2000112, 0, 0, 0, 0, /* 110 - 114 */
|
||||
0, 0, 0, 0, -4000118, /* 115 - 119 */
|
||||
-2000112, 0 /* 120 - 122 */
|
||||
}, /* points[MAXOBJ] */
|
||||
{0 }, /* hinted[HNTMAX+1] */
|
||||
{ /* hints[HNTMAX+1][5] */
|
||||
{ 0, 0, 0, 0, 0 }, /* 0 */
|
||||
{ 0, 9999, 4, 0, 0 }, /* 1 */
|
||||
{ 0, 9999, 10, 0, 0 }, /* 2 */
|
||||
{ 0, 9999, 5, 0, 0 }, /* 3 */
|
||||
{ 0, 0, 0, 0, 0 }, /* 4 */
|
||||
{ 0, 0, 0, 0, 0 }, /* 5 */
|
||||
{ 0, 0, 0, 0, 0 }, /* 6 */
|
||||
{ 0, 15, 4, 176, 177 }, /* 7 */
|
||||
{ 0, 8, 5, 178, 179 }, /* 8 */
|
||||
{ 0, 13, 3, 180, 181 }, /* 9 */
|
||||
{ 0, 6, 10, 211, 212 }, /* 10 */
|
||||
{ 0, 6, 5, 213, 214 }, /* 11 */
|
||||
{ 0, 4, 2, 62, 63 }, /* 12 */
|
||||
{ 0, 5, 2, 18, 19 }, /* 13 */
|
||||
{ 0, 4, 2, 62, 233 }, /* 14 */
|
||||
{ 0, 6, 5, 274, 275 }, /* 15 */
|
||||
{ 0, 10, 5, 289, 290 }, /* 16 */
|
||||
{ 0, 8, 2, 20, 21 }, /* 17 */
|
||||
{ 0, 5, 2, 404, 405 } /* 18 */
|
||||
}, /* hints[HNTMAX+1][5] */
|
||||
{0 }, /* hintlc[HNTMAX+1] */
|
||||
0, /* tally */
|
||||
0, /* tally2 */
|
||||
0, /* limit */
|
||||
0, /* lmwarn */
|
||||
0, /* wzdark */
|
||||
0, /* closing */
|
||||
0, /* closed */
|
||||
0, /* holding */
|
||||
0, /* detail */
|
||||
0, /* knfloc */
|
||||
30, /* clock */
|
||||
50, /* clock2 */
|
||||
0, /* panic */
|
||||
{ 0, 19, 27, 33, 44, 64, 114 }, /* dloc[DWARFMAX+1] */
|
||||
0, /* dflag */
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }, /* dseen[DWARFMAX+1] */
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }, /* odloc[DWARFMAX+1] */
|
||||
18, /* daltloc */
|
||||
0, /* dkill */
|
||||
114, /* chloc */
|
||||
140, /* chloc2 */
|
||||
0, /* bonus */
|
||||
0, /* numdie */
|
||||
0, /* foobar */
|
||||
0, /* combo */
|
||||
0, /* terse */
|
||||
5, /* abbnum */
|
||||
100, /* health */
|
||||
0, /* chase */
|
||||
FALSE, /* flg239 */
|
||||
0 /* lastglob */
|
||||
};
|
||||
|
||||
/*
|
||||
Initialization of adventure play variables
|
||||
*/
|
||||
void initialize()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = MAXOBJ; i > 0; i--) {
|
||||
g.fixed[i] = fixd[i];
|
||||
if (fixd[i] > 0) {
|
||||
drop(i + MAXOBJ, fixd[i]);
|
||||
drop(i, plac[i]);
|
||||
}
|
||||
if ((plac[i] != 0) && (fixd[i] <= 0))
|
||||
drop(i, plac[i]);
|
||||
}
|
||||
|
||||
for (i = 1; i <= MAXOBJ; i++) {
|
||||
if (treasr(i)) {
|
||||
g.prop[i] = -1;
|
||||
g.tally++;
|
||||
}
|
||||
}
|
||||
|
||||
newtravel = TRUE;
|
||||
g.place[BOOK] = -1;
|
||||
insert(BOOK, SAFE);
|
||||
g.place[WATER] = -1;
|
||||
insert(WATER, BOTTLE);
|
||||
g.prop[BOTTLE] = 8;
|
||||
return;
|
||||
}
|
||||
@@ -1,597 +0,0 @@
|
||||
/* program ITVERB.C */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
|
||||
_PROTOTYPE(void needobj, (void));
|
||||
_PROTOTYPE(void ivtake, (void));
|
||||
_PROTOTYPE(void ivopen, (void));
|
||||
_PROTOTYPE(void ivkill, (void));
|
||||
_PROTOTYPE(void ivdrink, (void));
|
||||
_PROTOTYPE(void ivquit, (void));
|
||||
_PROTOTYPE(void ivfoo, (void));
|
||||
_PROTOTYPE(void inventory, (void));
|
||||
_PROTOTYPE(void addobj, (int obj));
|
||||
_PROTOTYPE(void ivpour, (void));
|
||||
_PROTOTYPE(void ivfill, (void));
|
||||
_PROTOTYPE(void ivbrief, (void));
|
||||
_PROTOTYPE(void ivread, (void));
|
||||
_PROTOTYPE(void ivcombo, (void));
|
||||
_PROTOTYPE(void iveat, (void));
|
||||
/*
|
||||
Routines to process intransitive verbs
|
||||
*/
|
||||
void itverb()
|
||||
{
|
||||
int i;
|
||||
|
||||
newtravel = FALSE;
|
||||
switch (verb) {
|
||||
case DROP:
|
||||
case SAY:
|
||||
case WAVE:
|
||||
case CALM:
|
||||
case RUB:
|
||||
case THROW:
|
||||
case FIND:
|
||||
case FEED:
|
||||
case BREAK:
|
||||
case WAKE:
|
||||
case WEAR:
|
||||
case HIT:
|
||||
case DIAL:
|
||||
case PLAY:
|
||||
case PICK:
|
||||
case PUT:
|
||||
case TURN: needobj(); break;
|
||||
case TAKE:
|
||||
case YANK:
|
||||
case GET:
|
||||
case INSRT:
|
||||
case REMOVE:
|
||||
case BURN: ivtake(); break;
|
||||
case OPEN:
|
||||
case CLOSE:
|
||||
case LOCK:
|
||||
case UNLOCK: ivopen(); break;
|
||||
case NOTHING: rspeak(54); break;
|
||||
case ON:
|
||||
case OFF: trverb(); break;
|
||||
case WALK: actspk(verb); break;
|
||||
case KILL: ivkill(); break;
|
||||
case POUR: ivpour(); break;
|
||||
case EAT: iveat(); break;
|
||||
case DRINK: ivdrink(); break;
|
||||
case QUIT: ivquit(); break;
|
||||
case INVENTORY: inventory(); break;
|
||||
case FILL: ivfill(); break;
|
||||
case BLAST: ivblast(); break;
|
||||
case SCORE: score(TRUE); break;
|
||||
case FOO: ivfoo(); break;
|
||||
case BRIEF: ivbrief(); break;
|
||||
case READ: ivread(); break;
|
||||
case SUSPEND:
|
||||
if (g.closing)
|
||||
rspeak(378);
|
||||
else
|
||||
saveadv("advent.sav");
|
||||
break;
|
||||
case RESTORE: restore("advent.sav"); break;
|
||||
case ANSWER:
|
||||
if ((g.loc != 189) || (g.prop[PHONE] != 0))
|
||||
needobj();
|
||||
else {
|
||||
object = PHONE;
|
||||
itverb();
|
||||
}
|
||||
break;
|
||||
case BLOW: rspeak(268); break;
|
||||
/* Action verb 'LEAVE' has no object */
|
||||
case LEAVE: bug(29); break;
|
||||
/* Call if no phone is handy, yell. */
|
||||
case YELL:
|
||||
if (!here(PHONE))
|
||||
needobj();
|
||||
else if (!g.closed)
|
||||
rspeak(271);
|
||||
else {
|
||||
rspeak(283);
|
||||
normend();
|
||||
}
|
||||
break;
|
||||
/* Health. give him a diagnosis. */
|
||||
case HEALTH:
|
||||
if (g.numdie)
|
||||
fprintf(stdout, "You have been killed %d times otherwise\n",
|
||||
g.numdie);
|
||||
if (g.health >= 95) {
|
||||
if (pct(50))
|
||||
rspeak(348);
|
||||
else
|
||||
rspeak(349);
|
||||
} else {
|
||||
fprintf(stdout,
|
||||
"Your health rating is %2d out of a possible 100.\n",
|
||||
g.health);
|
||||
rspeak(381 + (100 - g.health) / 20);
|
||||
}
|
||||
break;
|
||||
case LOOK: ivlook(); break;
|
||||
case COMBO:
|
||||
if (at(SAFE))
|
||||
ivcombo();
|
||||
break;
|
||||
case SWEEP:
|
||||
/* Dust/sweep */
|
||||
if (!at(CARVNG) || !athand(BRUSH) || (g.prop[CARVNG] == 1))
|
||||
rspeak(342);
|
||||
else {
|
||||
g.prop[CARVNG] = 1;
|
||||
rspeak(363);
|
||||
rspeak(372);
|
||||
}
|
||||
break;
|
||||
case TERSE:
|
||||
/* Terse/unterse. supress all long_form descriptions. */
|
||||
g.terse = !g.terse;
|
||||
g.detail = 3;
|
||||
rspeak(54);
|
||||
break;
|
||||
case WIZ:
|
||||
is_wiz = !is_wiz;
|
||||
case MAP:
|
||||
rspeak(54);
|
||||
break;
|
||||
case GATE:
|
||||
if (is_wiz) {
|
||||
static char buf[INPUTBUFLEN];
|
||||
sscanf(ask("Location ? ", buf, sizeof(buf)), "%d", &g.loc);
|
||||
}
|
||||
rspeak(54);
|
||||
break;
|
||||
case PIRLOC:
|
||||
if (is_wiz) {
|
||||
fprintf(stdout, "The dwarfs are at locations:\n");
|
||||
for (i = 1; i < DWARFMAX; i++)
|
||||
fprintf(stdout, " %4d", g.dloc[i]);
|
||||
fprintf(stdout, "\nThe pirate is at location %4d\n",
|
||||
g.dloc[DWARFMAX]);
|
||||
}
|
||||
rspeak(54);
|
||||
break;
|
||||
default:
|
||||
printf("This intransitive not implemented yet\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to indicate no reasonable
|
||||
object for verb found. Used mostly by
|
||||
intransitive verbs.
|
||||
*/
|
||||
void needobj()
|
||||
{
|
||||
printf("%s what?\n", vtxt[vrbx]);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
CARRY, TAKE etc.
|
||||
*/
|
||||
void ivtake()
|
||||
{
|
||||
int anobj, item;
|
||||
|
||||
anobj = 0;
|
||||
for (item = 1; item < MAXOBJ; ++item)
|
||||
if (g.place[item] == g.loc)
|
||||
if (anobj == 0)
|
||||
anobj = item;
|
||||
else {
|
||||
needobj();
|
||||
return;
|
||||
}
|
||||
|
||||
if (anobj == 0 || (dcheck() && g.dflag >= 2) || blind())
|
||||
needobj();
|
||||
else {
|
||||
object = anobj;
|
||||
if (verb == YANK)
|
||||
vyank();
|
||||
else if (verb == WEAR)
|
||||
vwear();
|
||||
else
|
||||
vtake();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
OPEN, LOCK, UNLOCK
|
||||
*/
|
||||
void ivopen()
|
||||
{
|
||||
int obj_cnt, item;
|
||||
|
||||
for (item = 1, obj_cnt = 0; item < MAXOBJ; item++) {
|
||||
if ((g.place[item] == g.loc) && (hinged(item))) {
|
||||
object = item;
|
||||
obj_cnt++;
|
||||
}
|
||||
}
|
||||
if (obj_cnt != 1)
|
||||
needobj();
|
||||
else if (verb == LOCK)
|
||||
vlock();
|
||||
else if (verb == UNLOCK)
|
||||
vunlock();
|
||||
else if (verb == SHUT)
|
||||
vclose();
|
||||
else
|
||||
vopen();
|
||||
}
|
||||
|
||||
/*
|
||||
ATTACK, KILL etc
|
||||
*/
|
||||
boolean previous_obj;
|
||||
|
||||
void ivkill()
|
||||
{
|
||||
previous_obj = FALSE;
|
||||
if (dcheck() && g.dflag >= 2)
|
||||
object = DWARF;
|
||||
if (here(SNAKE))
|
||||
addobj(SNAKE);
|
||||
if (at(DRAGON) && g.prop[DRAGON] == 0)
|
||||
addobj(DRAGON);
|
||||
if (at(TROLL))
|
||||
addobj(TROLL);
|
||||
if (here(GNOME))
|
||||
addobj(GNOME);
|
||||
if (here(BEAR) && g.prop[BEAR] == 0)
|
||||
addobj(BEAR);
|
||||
if (here(WUMPUS) && g.prop[WUMPUS] == 0)
|
||||
addobj(WUMPUS);
|
||||
/* Can't attack bird by throwing axe */
|
||||
if (here(BIRD) && verb != THROW)
|
||||
addobj(BIRD);
|
||||
/* Clam and oyster both treated as clam for intransitive case; no
|
||||
harm done. */
|
||||
if (here(CLAM) || here(OYSTER))
|
||||
addobj(CLAM);
|
||||
|
||||
if ((previous_obj) || (object == 0))
|
||||
rspeak(44);
|
||||
else
|
||||
vkill();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
POUR if no object, assume liq in container, if holding one.
|
||||
*/
|
||||
void ivpour()
|
||||
{
|
||||
if ((holding(BOTTLE)) && (liq(BOTTLE) != 0) && !holding(CASK))
|
||||
object = BOTTLE;
|
||||
if ((holding(CASK)) && (liq(CASK) != 0) && !holding(BOTTLE))
|
||||
object = CASK;
|
||||
|
||||
if (object == 0)
|
||||
needobj();
|
||||
else
|
||||
trverb();
|
||||
}
|
||||
|
||||
/*
|
||||
EAT. intransitive: assume edible if present, else ask what.
|
||||
If he as more than one edible, or none, 'EAT' is ambiguous
|
||||
without an explicit object.
|
||||
*/
|
||||
void iveat()
|
||||
{
|
||||
int i;
|
||||
|
||||
previous_obj = FALSE;
|
||||
for (i = 1; i < MAXOBJ; i++) {
|
||||
if ((here(i)) && (edible(i)))
|
||||
addobj(i);
|
||||
}
|
||||
if ((previous_obj) || (object == 0))
|
||||
needobj();
|
||||
else
|
||||
trverb();
|
||||
}
|
||||
|
||||
/*
|
||||
DRINK. If no object, assume water or wine and look for them here.
|
||||
If potable is in bottle or cask, drink that. If not, see if there
|
||||
is something drinkable nearby (stream, lake, wine fountain, etc.),
|
||||
and drink that. If he has stuff in both containers, ask which.
|
||||
*/
|
||||
void ivdrink()
|
||||
{
|
||||
int ll;
|
||||
|
||||
previous_obj = FALSE;
|
||||
ll = liqloc(g.loc);
|
||||
if ((ll == WATER) || (ll == WINE)) {
|
||||
object = ll;
|
||||
iobj = -1;
|
||||
}
|
||||
ll = liq(BOTTLE);
|
||||
if ((athand(BOTTLE)) && ((ll == WATER) || (ll == WINE))) {
|
||||
object = ll;
|
||||
iobj = BOTTLE;
|
||||
}
|
||||
ll = liq(CASK);
|
||||
if ((athand(CASK)) && ((ll == WATER) || (ll == WINE))
|
||||
&& iobj != BOTTLE) {
|
||||
object = ll;
|
||||
iobj = CASK;
|
||||
} else
|
||||
object = 0;
|
||||
|
||||
if (object == 0)
|
||||
needobj();
|
||||
else
|
||||
trverb();
|
||||
}
|
||||
|
||||
/*
|
||||
QUIT intransitive only. Verify intent and exit if that's what he wants
|
||||
*/
|
||||
void ivquit()
|
||||
{
|
||||
gaveup = yes(22, 54, 54);
|
||||
if (gaveup)
|
||||
normend();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
INVENTORY
|
||||
*/
|
||||
void inventory()
|
||||
{
|
||||
int i, msg;
|
||||
boolean init_msg;
|
||||
|
||||
init_msg = TRUE;
|
||||
msg = 98;
|
||||
for (i = 1; i < MAXOBJ; i++) {
|
||||
if (!holding(i) || wearng(i) || i == BEAR || i == BOAT)
|
||||
continue;
|
||||
if (init_msg)
|
||||
rspeak(99);
|
||||
pspeak(i, -1);
|
||||
init_msg = FALSE;
|
||||
msg = 0;
|
||||
lookin(i);
|
||||
}
|
||||
|
||||
/* Tell him what he is wearing */
|
||||
init_msg = TRUE;
|
||||
for (i = 1; i < MAXOBJ; i++) {
|
||||
if (wearng(i)) {
|
||||
if (init_msg)
|
||||
fprintf(stdout, "\nYou are wearing:\n");
|
||||
fprintf(stdout, " ");
|
||||
pspeak(i, -1);
|
||||
msg = 0;
|
||||
init_msg = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (holding(BOAT)) {
|
||||
rspeak(221);
|
||||
lookin(BOAT);
|
||||
}
|
||||
if (holding(BEAR))
|
||||
msg = 141;
|
||||
|
||||
if (msg)
|
||||
rspeak(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
FILL bottle or cask must be empty, and some liquid avaible
|
||||
*/
|
||||
void ivfill()
|
||||
{
|
||||
if ((g.prop[CASK] == 1) && !here(CASK))
|
||||
object = CASK;
|
||||
if ((g.prop[BOTTLE] == 1) && !here(BOTTLE))
|
||||
object = BOTTLE;
|
||||
|
||||
if ((here(BOTTLE) && here(CASK)) || (object == 0))
|
||||
needobj();
|
||||
else
|
||||
trverb();
|
||||
}
|
||||
|
||||
/*
|
||||
BLAST etc.
|
||||
*/
|
||||
void ivblast()
|
||||
{
|
||||
if (!g.closed)
|
||||
actspk(verb);
|
||||
else {
|
||||
g.bonus = 135;
|
||||
if (g.place[ROD2] == 212 && g.loc == 116)
|
||||
g.bonus = 133;
|
||||
if (g.place[ROD2] == 116 && g.loc != 116)
|
||||
g.bonus = 134;
|
||||
rspeak(g.bonus);
|
||||
normend();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Handle fee fie foe foo...
|
||||
*/
|
||||
void ivfoo()
|
||||
{
|
||||
int k;
|
||||
int msg;
|
||||
|
||||
k = VAL(vocab(vtxt[vrbx], MISC));
|
||||
if (g.foobar != 1 - k) {
|
||||
if (g.foobar == 0)
|
||||
msg = 42;
|
||||
else
|
||||
msg = 151;
|
||||
rspeak(msg);
|
||||
return;
|
||||
}
|
||||
g.foobar = k;
|
||||
if (k != 4)
|
||||
return;
|
||||
g.foobar = 0;
|
||||
if (g.place[EGGS] == plac[EGGS] ||
|
||||
(toting(EGGS) && g.loc == plac[EGGS])) {
|
||||
rspeak(42);
|
||||
return;
|
||||
}
|
||||
/* Bring back troll if we steal the eggs back from him before
|
||||
crossing */
|
||||
if (g.place[EGGS] == 0 && g.place[TROLL] == 0 && g.prop[TROLL] == 0)
|
||||
g.prop[TROLL] = 1;
|
||||
|
||||
if (here(EGGS))
|
||||
k = 1;
|
||||
else if (g.loc == plac[EGGS])
|
||||
k = 0;
|
||||
else
|
||||
k = 2;
|
||||
move(EGGS, plac[EGGS]);
|
||||
pspeak(EGGS, k);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
brief/unbrief. intransitive only.
|
||||
suppress long descriptions after first time.
|
||||
*/
|
||||
void ivbrief()
|
||||
{
|
||||
int msg;
|
||||
|
||||
g.detail = 3;
|
||||
g.terse = FALSE;
|
||||
if (g.abbnum != 10000) {
|
||||
msg = 156;
|
||||
g.abbnum = 10000;
|
||||
} else {
|
||||
msg = 374;
|
||||
g.abbnum = 5;
|
||||
}
|
||||
rspeak(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
read etc...
|
||||
*/
|
||||
void ivread()
|
||||
{
|
||||
previous_obj = FALSE;
|
||||
if (here(BOOK))
|
||||
object = BOOK;
|
||||
if (here(BOOK2))
|
||||
addobj(BOOK2);
|
||||
if (here(BILLBD))
|
||||
addobj(BILLBD);
|
||||
if (here(CARVNG))
|
||||
addobj(CARVNG);
|
||||
if (here(MAGAZINE))
|
||||
addobj(MAGAZINE);
|
||||
if (here(MESSAGE))
|
||||
addobj(MESSAGE);
|
||||
if (here(OYSTER))
|
||||
addobj(OYSTER);
|
||||
if (here(POSTER))
|
||||
addobj(POSTER);
|
||||
if (here(TABLET))
|
||||
addobj(TABLET);
|
||||
|
||||
if (previous_obj || object == 0 || dark())
|
||||
needobj();
|
||||
else
|
||||
vread();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
LOOK. can't give more detail. Pretend it wasn't dark (though it may "now"
|
||||
be dark) so he won't fall into a pit staring into the gloom.
|
||||
*/
|
||||
void ivlook()
|
||||
{
|
||||
if (g.detail++ < 3)
|
||||
rspeak(15);
|
||||
g.wzdark = FALSE;
|
||||
g.visited[g.loc] = 0;
|
||||
g.newloc = g.loc;
|
||||
newtravel = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
COMBO: trying to open safe. (see comments for fee fie foe foo)
|
||||
*/
|
||||
void ivcombo()
|
||||
{
|
||||
int k, msg;
|
||||
|
||||
k = VAL(vocab(vtxt[vrbx], MISC)) - 10;
|
||||
msg = 42;
|
||||
if (g.combo != 1 - k) {
|
||||
if (g.combo != 0)
|
||||
msg = 366;
|
||||
rspeak(msg);
|
||||
return;
|
||||
}
|
||||
g.combo = k;
|
||||
if (k != 3)
|
||||
rspeak(371);
|
||||
else {
|
||||
g.combo = 0;
|
||||
bitoff(SAFE, LOCKBT);
|
||||
biton(SAFE, OPENBT);
|
||||
g.prop[SAFE] = 1;
|
||||
if (g.prop[BOOK] < 0) {
|
||||
g.tally--;
|
||||
g.prop[BOOK] = 0;
|
||||
/* If remaining treasures too elusive, zap his lamp. this
|
||||
duplicates some code, must be done here since book is
|
||||
contained ins safe & tally stuff only works for thing
|
||||
deposited at a location. */
|
||||
if ((g.tally == g.tally2) && (g.tally != 0))
|
||||
g.limit = (g.limit < 35) ? g.limit : 35;
|
||||
}
|
||||
rspeak(365);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ensure uniqueness as objects are searched
|
||||
out for an intransitive verb
|
||||
*/
|
||||
void addobj(obj)
|
||||
int obj;
|
||||
{
|
||||
if (!previous_obj) {
|
||||
if (object != 0)
|
||||
previous_obj = TRUE;
|
||||
else
|
||||
object = obj;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
SCORE
|
||||
|
||||
Calculate what the player's score would be if he quit now.
|
||||
This may be the end of the game, or he may just be wondering
|
||||
how he is doing.
|
||||
|
||||
The present scoring algorithm is as follows:
|
||||
(treasure points are explained in a following comment)
|
||||
objective: points: present total possible:
|
||||
getting well into cave 25 25
|
||||
total possible for treasures (+mag) 426
|
||||
reaching "closing" 20 20
|
||||
"closed": quit/killed 10
|
||||
klutzed 20
|
||||
wrong way 25
|
||||
success 30 30
|
||||
total: 501
|
||||
(points can also be deducted for using hints or deaths.)
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
|
||||
void score(scorng)
|
||||
boolean scorng;
|
||||
{
|
||||
int cur_score, max_score, qk[3];
|
||||
int obj, num_treas, k, i;
|
||||
long t;
|
||||
char *kk2c;
|
||||
|
||||
cur_score = 0;
|
||||
max_score = 0;
|
||||
num_treas = 0;
|
||||
|
||||
/** First tally up the treasures. Must be in building and not broken.
|
||||
give the poor guy partial score just for finding each treasure.
|
||||
Gets full score, qk[3], for obj if:
|
||||
obj is at loc qk[1], and
|
||||
obj has prop value of qk[2]
|
||||
|
||||
weight total possible
|
||||
magazine 1 (absolute) 1
|
||||
|
||||
all the following are multiplied by 5 (range 5-25):
|
||||
book 2
|
||||
cask 3 (with wine only)
|
||||
chain 4 (must enter via styx)
|
||||
chest 5
|
||||
cloak 3
|
||||
clover 1
|
||||
coins 5
|
||||
crown 2
|
||||
crystal-ball 2
|
||||
diamonds 2
|
||||
eggs 3
|
||||
emerald 3
|
||||
grail 2
|
||||
horn 2
|
||||
jewels 1
|
||||
lyre 1
|
||||
nugget 2
|
||||
pearl 4
|
||||
pyramid 4
|
||||
radium 4
|
||||
ring 4
|
||||
rug 3
|
||||
sapphire 1
|
||||
shoes 3
|
||||
spices 1
|
||||
sword 4
|
||||
trident 2
|
||||
vase 2
|
||||
droplet 5
|
||||
tree 5
|
||||
total: 85 * 5 = 425 + 1 ==> 426
|
||||
*/
|
||||
|
||||
for (obj = 1; obj < MAXOBJ; obj++) {
|
||||
if (g.points[obj] == 0)
|
||||
continue;
|
||||
t = g.points[obj];
|
||||
qk[0] = (int) (t < 0L ? -((t = -t) % 1000) : (t % 1000));
|
||||
t /= 1000;
|
||||
qk[1] = (int) (t % 1000);
|
||||
qk[2] = (int) (t / 1000);
|
||||
k = 0;
|
||||
if (treasr(obj)) {
|
||||
num_treas++;
|
||||
k = qk[2] * 2;
|
||||
if (g.prop[obj] >= 0)
|
||||
cur_score += k;
|
||||
qk[2] *= 5;
|
||||
}
|
||||
if ((g.place[obj] == qk[0]) && (g.prop[obj] == qk[1])
|
||||
&& ((g.place[obj] != -CHEST) || (g.place[CHEST] == 3))
|
||||
&& ((g.place[obj] != -SHIELD) || (g.place[SHIELD] == -SAFE))
|
||||
)
|
||||
cur_score += qk[2] - k;
|
||||
max_score += qk[2];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Now look at how he finished and how far he got. Maxdie and numdie tell us
|
||||
how well he survived. Gaveup says whether he exited via quit. Dflag will
|
||||
tell us if he ever got suitably deep into the cave. Closing still indicates
|
||||
whether he reached the endgame. And if he got as far as "cave closed"
|
||||
(indicated by "closed"), then bonus is zero for mundane exits or 133, 134,
|
||||
135 if he blew it (so to speak).
|
||||
*/
|
||||
|
||||
if (g.dflag)
|
||||
cur_score += 25;
|
||||
max_score += 25;
|
||||
if (g.closing)
|
||||
cur_score += 20;
|
||||
max_score += 20;
|
||||
if (g.closed) {
|
||||
if (g.bonus == 0)
|
||||
cur_score += 10;
|
||||
else if (g.bonus == 135)
|
||||
cur_score += 20;
|
||||
else if (g.bonus == 134)
|
||||
cur_score += 25;
|
||||
else if (g.bonus == 133)
|
||||
cur_score += 30;
|
||||
}
|
||||
max_score += 30;
|
||||
|
||||
/* Deduct points for hints, deaths and quiting.
|
||||
hints < hntmin are special; see database description
|
||||
*/
|
||||
for (i = 1; i <= HNTMAX; i++)
|
||||
if (g.hinted[i])
|
||||
cur_score -= g.hints[i][2];
|
||||
cur_score -= g.numdie * 10;
|
||||
if (gaveup)
|
||||
cur_score -= 4;
|
||||
|
||||
fprintf(stdout, "You have found %3d out of %3d Treasures,",
|
||||
num_treas - g.tally, num_treas);
|
||||
fprintf(stdout, " using %4d turns\n", g.turns);
|
||||
fprintf(stdout, "For a score of: %4d", cur_score);
|
||||
fprintf(stdout, " out of a possible %4d\n", max_score);
|
||||
|
||||
if (cur_score < 110) {
|
||||
fprintf(stdout, "You are obviously a rank amateur.");
|
||||
if (!scorng)
|
||||
fprintf(stdout, " Better luck next time.");
|
||||
fputc('\n', stdout);
|
||||
k = 110 - cur_score;
|
||||
} else if (cur_score < 152) {
|
||||
fprintf(stdout,
|
||||
"Your score qualifies you as a Novice Class Adventurer.\n");
|
||||
k = 152 - cur_score;
|
||||
} else if (cur_score < 200) {
|
||||
fprintf(stdout,
|
||||
"You have achieved the rating: \"Experienced Adventurer\".\n");
|
||||
k = 200 - cur_score;
|
||||
} else if (cur_score < 277) {
|
||||
fprintf(stdout,
|
||||
"You may now consider yourself a \"Seasoned Adventurer\".\n");
|
||||
k = 277 - cur_score;
|
||||
} else if (cur_score < 345) {
|
||||
fprintf(stdout,
|
||||
"You have reached \"Junior Master\" status.\n");
|
||||
k = 345 - cur_score;
|
||||
} else if (cur_score < 451) {
|
||||
fprintf(stdout,
|
||||
"Your score puts you in Master Adventurer Class C.\n");
|
||||
k = 451 - cur_score;
|
||||
} else if (cur_score < 471) {
|
||||
fprintf(stdout,
|
||||
"Your score puts you in Master Adventurer Class B.\n");
|
||||
k = 471 - cur_score;
|
||||
} else if (cur_score < 501) {
|
||||
fprintf(stdout,
|
||||
"Your score puts you in Master Adventurer Class A.\n");
|
||||
k = 501 - cur_score;
|
||||
} else {
|
||||
fprintf(stdout,
|
||||
"All of Adventuredom gives tribute to you, Adventurer Grandmaster!\n");
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (!scorng) {
|
||||
kk2c = (k == 1) ? "." : "s.";
|
||||
printf("\nTo acheive the next higher rating,");
|
||||
if (cur_score == 501)
|
||||
printf(" would be a neat trick!\n\n CONGRATULATIONS!!\n");
|
||||
else
|
||||
printf(" you need %3d more point%s\n", k, kk2c);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/** program SETUP.C *
|
||||
* execution will read the four adventure text files *
|
||||
* files; "advent1.txt", "advent2.txt", "advent3.txt" & *
|
||||
* "advent4.txt". it will create the file "advtext.h" *
|
||||
* which is an Index Sequential Access Method (ISAM) *
|
||||
* header to be #included into "advent.c" before the *
|
||||
* header "advdec.h" is #included. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "advent.h"
|
||||
|
||||
_PROTOTYPE(int main, (void));
|
||||
_PROTOTYPE(void file_error, (char *));
|
||||
_PROTOTYPE(void encode, (unsigned char *));
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
FILE *isam, *src, *dest;
|
||||
char itxt[255];
|
||||
int cnt, i;
|
||||
long llen;
|
||||
char filename[12];
|
||||
static char *headername[] = {
|
||||
"idx1[MAXLOC]", "idx2[MAXLOC]", "idx3[MAXOBJ]", "idx4[MAXMSG]",
|
||||
};
|
||||
|
||||
long x29 = (1L << 29), x30 = (1L << 30);
|
||||
if (!(x30 / 2 == x29 && 0L < x30 && x29 < x30)) {
|
||||
fprintf(stderr, "Sorry, advent needs 32-bit `long int's.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
isam = fopen("advtext.h", "w");
|
||||
if (!isam) {
|
||||
fprintf(stderr, "Sorry, I can't open advtext.h...\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(isam, "\n/*\theader: ADVTEXT.H\t\t\t\t\t*/\n\n\n");
|
||||
|
||||
for (i = 1; i <= 4; i++) {
|
||||
cnt = -1;
|
||||
llen = 0L;
|
||||
sprintf(filename, "advent%d.txt", i);
|
||||
src = fopen(filename, "r");
|
||||
if (!src)
|
||||
file_error(filename);
|
||||
sprintf(filename, "advent%d.dat", i);
|
||||
dest = fopen(filename, "w");
|
||||
if (!dest)
|
||||
file_error(filename);
|
||||
fprintf(isam, "long\t%s = {\n\t", headername[i - 1]);
|
||||
while (fgets(itxt, 255, src)) {
|
||||
encode((unsigned char *) itxt);
|
||||
if (fprintf(dest, "%s\n", itxt) == EOF)
|
||||
file_error(filename);
|
||||
if (itxt[0] == '#') {
|
||||
if (llen)
|
||||
fprintf(isam, "%ld,%s\t", llen,
|
||||
&"\0\0\0\0\0\0\0\n"[++cnt & 7]);
|
||||
llen = ftell(dest);
|
||||
if (llen <= 0) {
|
||||
fprintf(stderr, "ftell err in %s\n", filename);
|
||||
exit(EXIT_FAILURE);
|
||||
} /* if (!llen) */
|
||||
} /* if (itxt[0]) */
|
||||
} /* while fgets */
|
||||
if (fprintf(isam, "%ld\n\t};\n\n", llen) == EOF)
|
||||
file_error("advtext.h");
|
||||
fclose(src);
|
||||
if (fclose(dest) == EOF)
|
||||
file_error(filename);
|
||||
}
|
||||
|
||||
if (fclose(isam) == EOF)
|
||||
file_error("advtext.h");
|
||||
return EXIT_SUCCESS;
|
||||
} /* main */
|
||||
|
||||
void file_error(filename)
|
||||
char *filename;
|
||||
{
|
||||
perror(filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_CONST unsigned char key[4] = {'c' | 0x80, 'L' | 0x80, 'y' | 0x80, 'D' | 0x80};
|
||||
|
||||
void encode(msg)
|
||||
unsigned char *msg;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; msg[i]; i++)
|
||||
msg[i] ^= key[i & 3];
|
||||
msg[--i] = '\0';
|
||||
return;
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
/* module TRAVEL.C *
|
||||
* Routine to handle motion requests */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
#include "advcave.h"
|
||||
|
||||
struct trav travel[MAXTRAV];
|
||||
static int kalflg;
|
||||
static int bcrossing = 0;
|
||||
static int phuce[2][4] = {158, 160, 167, 166,
|
||||
160, 158, 166, 167};
|
||||
|
||||
_PROTOTYPE(static void goback, (void));
|
||||
_PROTOTYPE(static void ck_kal, (void));
|
||||
_PROTOTYPE(static void dotrav, (void));
|
||||
_PROTOTYPE(static void badmove, (void));
|
||||
_PROTOTYPE(static void spcmove, (int rdest));
|
||||
|
||||
void domove()
|
||||
{
|
||||
gettrav(g.loc, travel);
|
||||
switch (motion) {
|
||||
case NULLX:
|
||||
break;
|
||||
case BACK:
|
||||
goback();
|
||||
break;
|
||||
case CAVE:
|
||||
if (outside(g.loc))
|
||||
rspeak(57);
|
||||
else
|
||||
rspeak(58);
|
||||
break;
|
||||
default:
|
||||
g.oldloc2 = g.oldloc;
|
||||
g.oldloc = g.loc;
|
||||
dotrav();
|
||||
}
|
||||
newtravel = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to handle request to return
|
||||
from whence we came!
|
||||
*/
|
||||
static void goback()
|
||||
{
|
||||
int kk, k2, want, temp;
|
||||
struct trav strav[MAXTRAV];
|
||||
|
||||
want = forced(g.oldloc) ? g.oldloc2 : g.oldloc;
|
||||
g.oldloc2 = g.oldloc;
|
||||
g.oldloc = g.loc;
|
||||
k2 = 0;
|
||||
if (want == g.loc) {
|
||||
rspeak(91);
|
||||
ck_kal();
|
||||
return;
|
||||
}
|
||||
for (kk = 0; travel[kk].tdest != -1; ++kk) {
|
||||
if (!travel[kk].tcond && travel[kk].tdest == want) {
|
||||
motion = travel[kk].tverb;
|
||||
dotrav();
|
||||
return;
|
||||
}
|
||||
if (!travel[kk].tcond) {
|
||||
temp = travel[kk].tdest;
|
||||
gettrav(temp, strav);
|
||||
if (forced(temp) && strav[0].tdest == want)
|
||||
k2 = temp;
|
||||
}
|
||||
}
|
||||
if (k2) {
|
||||
motion = travel[k2].tverb;
|
||||
dotrav();
|
||||
} else
|
||||
rspeak(140);
|
||||
ck_kal();
|
||||
return;
|
||||
}
|
||||
|
||||
static void ck_kal()
|
||||
{
|
||||
if (g.newloc >= 242 && g.newloc <= 247) {
|
||||
if (g.newloc == 242)
|
||||
kalflg = 0;
|
||||
else if (g.newloc == (g.oldloc + 1))
|
||||
kalflg++;
|
||||
else
|
||||
kalflg = -10;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to figure out a new location
|
||||
given current location and a motion.
|
||||
*/
|
||||
static void dotrav()
|
||||
{
|
||||
unsigned char mvflag, hitflag, kk;
|
||||
int rdest, rverb, rcond, robject;
|
||||
int pctt;
|
||||
|
||||
g.newloc = g.loc;
|
||||
mvflag = hitflag = 0;
|
||||
pctt = ranz(100);
|
||||
|
||||
for (kk = 0; travel[kk].tdest >= 0 && !mvflag; ++kk) {
|
||||
rdest = travel[kk].tdest;
|
||||
rverb = travel[kk].tverb;
|
||||
rcond = travel[kk].tcond;
|
||||
robject = rcond % 100;
|
||||
|
||||
if ((rverb != 1) && (rverb != motion) && !hitflag)
|
||||
continue;
|
||||
++hitflag;
|
||||
switch (rcond / 100) {
|
||||
case 0:
|
||||
if ((rcond == 0) || (pctt < rcond))
|
||||
++mvflag;
|
||||
break;
|
||||
case 1:
|
||||
if (robject == 0)
|
||||
++mvflag;
|
||||
else if (toting(robject))
|
||||
++mvflag;
|
||||
break;
|
||||
case 2:
|
||||
if (toting(robject) || at(robject))
|
||||
++mvflag;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
if (g.prop[robject] != (rcond / 100) - 3)
|
||||
++mvflag;
|
||||
break;
|
||||
default:
|
||||
bug(37);
|
||||
}
|
||||
}
|
||||
if (!mvflag)
|
||||
badmove();
|
||||
else if (rdest > 500)
|
||||
rspeak(rdest - 500);
|
||||
else if (rdest > 300)
|
||||
spcmove(rdest);
|
||||
else {
|
||||
g.newloc = rdest;
|
||||
ck_kal();
|
||||
}
|
||||
newtravel = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
The player tried a poor move option.
|
||||
*/
|
||||
static void badmove()
|
||||
{
|
||||
int msg;
|
||||
|
||||
msg = 12;
|
||||
if (motion >= 43 && motion <= 50)
|
||||
msg = 9;
|
||||
if (motion == 29 || motion == 30)
|
||||
msg = 9;
|
||||
if (motion == 7 || motion == 36 || motion == 37)
|
||||
msg = 10;
|
||||
if (motion == 11 || motion == 19)
|
||||
msg = 11;
|
||||
if (motion == 62 || motion == 65 || motion == 82)
|
||||
msg = 42;
|
||||
if (motion == 17)
|
||||
msg = 80;
|
||||
rspeak(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to handle very special movement.
|
||||
*/
|
||||
static void spcmove(rdest)
|
||||
int rdest;
|
||||
{
|
||||
int load, obj, k;
|
||||
|
||||
switch (rdest - 300) {
|
||||
case 1: /* plover movement via alcove */
|
||||
load = burden(0);
|
||||
if (!load || (load == burden(EMERALD) && holding(EMERALD)))
|
||||
g.newloc = (99 + 100) - g.loc;
|
||||
else
|
||||
rspeak(117);
|
||||
break;
|
||||
case 2: /* trying to remove plover, bad
|
||||
route */
|
||||
if (enclosed(EMERALD))
|
||||
extract(EMERALD);
|
||||
drop(EMERALD, g.loc);
|
||||
g.newloc = 33;
|
||||
break;
|
||||
case 3: /* troll bridge */
|
||||
if (g.prop[TROLL] == 1) {
|
||||
pspeak(TROLL, 1);
|
||||
g.prop[TROLL] = 0;
|
||||
move(TROLL2, 0);
|
||||
move((TROLL2 + MAXOBJ), 0);
|
||||
move(TROLL, plac[TROLL]);
|
||||
move((TROLL + MAXOBJ), fixd[TROLL]);
|
||||
juggle(CHASM);
|
||||
g.newloc = g.loc;
|
||||
} else {
|
||||
g.newloc = plac[TROLL] + fixd[TROLL] - g.loc;
|
||||
if (g.prop[TROLL] == 0)
|
||||
g.prop[TROLL] = 1;
|
||||
if (toting(BEAR)) {
|
||||
rspeak(162);
|
||||
g.prop[CHASM] = 1;
|
||||
g.prop[TROLL] = 2;
|
||||
drop(BEAR, g.newloc);
|
||||
g.fixed[BEAR] = -1;
|
||||
g.prop[BEAR] = 3;
|
||||
if (g.prop[SPICES] < 0)
|
||||
++g.tally2;
|
||||
g.oldloc2 = g.newloc;
|
||||
death();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* Growing or shrinking in area of tiny door. Each time he
|
||||
does this, everything must be moved to the new loc.
|
||||
Presumably, all his possesions are shrunk or streched along
|
||||
with him. Phuce[2][4] is an array containg four pairs of
|
||||
"here" (K) and "there" (KK) locations. */
|
||||
k = phuce[0][g.loc - 161];
|
||||
g.newloc = phuce[1][g.loc - 161];
|
||||
for (obj = 1; obj < MAXOBJ; obj++) {
|
||||
if (obj == BOAT)
|
||||
continue;
|
||||
if (g.place[obj] == k && (g.fixed[obj] == 0 || g.fixed[obj] == -1))
|
||||
move(obj, g.newloc);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
/* Phone booth in rotunda. Trying to shove past gnome, to get
|
||||
into phone booth. */
|
||||
if ((g.prop[BOOTH] == 0 && pct(35)) || g.visited[g.loc] == 1) {
|
||||
rspeak(263);
|
||||
g.prop[BOOTH] = 1;
|
||||
move(GNOME, 188);
|
||||
} else {
|
||||
if (g.prop[BOOTH] == 1)
|
||||
rspeak(253);
|
||||
else
|
||||
g.newloc = 189;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
/* Collapsing clay bridge. He can cross with three (or fewer)
|
||||
thing. If more, of if carrying obviously heavy things, he
|
||||
may end up in the drink. */
|
||||
g.newloc = g.loc == 235 ? 190 : 235;
|
||||
bcrossing++;
|
||||
load = burden(0);
|
||||
if (load > 4) {
|
||||
k = (load + bcrossing) * 6 - 10;
|
||||
if (!pct(k))
|
||||
rspeak(318);
|
||||
else {
|
||||
rspeak(319);
|
||||
g.newloc = 236;
|
||||
if (holding(LAMP))
|
||||
move(LAMP, 236);
|
||||
if (toting(AXE) && enclosed(AXE))
|
||||
extract(AXE);
|
||||
if (holding(AXE))
|
||||
move(AXE, 208);
|
||||
for (obj = 1; obj < MAXOBJ; obj++)
|
||||
if (toting(obj))
|
||||
destroy(obj);
|
||||
g.prop[CHASM2] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/* Kaleidoscope code is here. */
|
||||
if (kalflg == 5) {
|
||||
g.newloc = 248;
|
||||
g.oldloc = 247;
|
||||
} else {
|
||||
g.newloc = 242 + ranz(5);
|
||||
g.oldloc = g.newloc - 1;
|
||||
kalflg = g.newloc == 242 ? 0 : -10;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bug(38);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to fill travel array for a given location
|
||||
*/
|
||||
void gettrav(loc, travel)
|
||||
int loc;
|
||||
struct trav *travel;
|
||||
{
|
||||
int i;
|
||||
long t, *lptr;
|
||||
|
||||
lptr = cave[loc - 1];
|
||||
for (i = 0; i < MAXTRAV; i++) {
|
||||
t = *lptr++;
|
||||
if (!(t)) {
|
||||
travel->tdest = -1; /* end of array */
|
||||
return; /* terminate for loop */
|
||||
}
|
||||
travel->tverb = (int) (t % 1000);
|
||||
t /= 1000;
|
||||
travel->tdest = (int) (t % 1000);
|
||||
t /= 1000;
|
||||
travel->tcond = (int) (t % 1000);
|
||||
travel++;
|
||||
}
|
||||
bug(25);
|
||||
return;
|
||||
}
|
||||
@@ -1,729 +0,0 @@
|
||||
/* program TURN.C */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "advent.h"
|
||||
#include "advdec.h"
|
||||
|
||||
_PROTOTYPE(void descitem, (void));
|
||||
_PROTOTYPE(void domove, (void));
|
||||
_PROTOTYPE(void goback, (void));
|
||||
_PROTOTYPE(void copytrv, (struct trav *, struct trav *));
|
||||
_PROTOTYPE(void dotrav, (void));
|
||||
_PROTOTYPE(void badmove, (void));
|
||||
_PROTOTYPE(void spcmove, (int));
|
||||
_PROTOTYPE(void death, (void));
|
||||
_PROTOTYPE(void dwarves, (void));
|
||||
_PROTOTYPE(void dopirate, (void));
|
||||
_PROTOTYPE(int stimer, (void));
|
||||
_PROTOTYPE(void do_hint, (int));
|
||||
|
||||
|
||||
/*
|
||||
Routine to take 1 turn
|
||||
*/
|
||||
void turn()
|
||||
{
|
||||
int i, hint;
|
||||
static int waste = 0;
|
||||
|
||||
if (newtravel) {
|
||||
/* If closing, then he can't leave except via the main office. */
|
||||
if (outside(g.newloc) && g.newloc != 0 && g.closing) {
|
||||
rspeak(130);
|
||||
g.newloc = g.loc;
|
||||
if (!g.panic)
|
||||
g.clock2 = 15;
|
||||
g.panic = TRUE;
|
||||
}
|
||||
/* See if a dwarf has seen him and has come from where he wants
|
||||
to go. */
|
||||
if (g.newloc != g.loc && !forced(g.loc) && g.loc_attrib[g.loc] & NOPIRAT == 0)
|
||||
for (i = 1; i < (DWARFMAX - 1); ++i)
|
||||
if (g.odloc[i] == g.newloc && g.dseen[i]) {
|
||||
g.newloc = g.loc;
|
||||
rspeak(2);
|
||||
break;
|
||||
}
|
||||
|
||||
g.loc = g.newloc;
|
||||
dwarves(); /* & special dwarf(pirate who
|
||||
steals) */
|
||||
|
||||
/* Check for death */
|
||||
if (g.loc == 0) {
|
||||
death();
|
||||
return;
|
||||
}
|
||||
/* Check for forced move */
|
||||
if (forced(g.loc)) {
|
||||
desclg(g.loc);
|
||||
++g.visited[g.loc];
|
||||
domove();
|
||||
return;
|
||||
}
|
||||
/* Check for wandering in dark */
|
||||
if (g.wzdark && dark() && pct(35)) {
|
||||
rspeak(23);
|
||||
g.oldloc2 = g.loc;
|
||||
death();
|
||||
return;
|
||||
}
|
||||
/* see if he is wasting his batteies out in the open */
|
||||
if (outside(g.loc) && g.prop[LAMP]) {
|
||||
waste++;
|
||||
if (waste > 11) {
|
||||
rspeak(324);
|
||||
waste = 0;
|
||||
}
|
||||
} else
|
||||
waste = 0;
|
||||
|
||||
/* If wumpus is chasing stooge, see if wumpus gets him */
|
||||
if (g.chase) {
|
||||
g.chase++;
|
||||
g.prop[WUMPUS] = g.chase / 2;
|
||||
move(WUMPUS, g.loc);
|
||||
if (g.chase >= 10) {
|
||||
if (dark())
|
||||
rspeak(270);
|
||||
pspeak(WUMPUS, 5);
|
||||
death();
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* check for radiation poisoning. */
|
||||
g.health += (outside(g.loc)) ? 3 : 1;
|
||||
if (g.health > 100)
|
||||
g.health = 100;
|
||||
if (here(RADIUM) && (g.place[RADIUM] != -SHIELD || ajar(SHIELD)))
|
||||
g.health -= 7;
|
||||
if (g.health < 60) {
|
||||
rspeak(391 + (60 - g.health) / 10);
|
||||
if (g.health < 0) {
|
||||
death();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((g.oldloc == 188) && (g.loc != 188 && g.loc != 189)
|
||||
&& (g.prop[BOOTH] == 1)) {
|
||||
move(GNOME, 0);
|
||||
g.prop[BOOTH] = 0;
|
||||
}
|
||||
/* Describe his situation */
|
||||
describe();
|
||||
if (!blind()) {
|
||||
++g.visited[g.loc];
|
||||
descitem();
|
||||
}
|
||||
} /* end of newtravel start for
|
||||
second entry point */
|
||||
/* Check if this location is eligible for any hints. If been here
|
||||
long enough, branch to help section. Ignore "hints" < HNTMIN
|
||||
(special stuff, see database notes. */
|
||||
for (hint = HNTMIN; hint <= HNTMAX; hint++) {
|
||||
if (g.hinted[hint])
|
||||
continue;
|
||||
if (g.loc_attrib[g.loc] / 256 != hint - 6)
|
||||
g.hintlc[hint] = -1;
|
||||
g.hintlc[hint]++;
|
||||
if (g.hintlc[hint] >= g.hints[hint][1])
|
||||
do_hint(hint);
|
||||
}
|
||||
|
||||
if (g.closed) {
|
||||
if (g.prop[OYSTER] < 0 && toting(OYSTER))
|
||||
pspeak(OYSTER, 1);
|
||||
for (i = 1; i < MAXOBJ; ++i)
|
||||
if (toting(i) && g.prop[i] < 0)
|
||||
g.prop[i] = -1 - g.prop[i];
|
||||
}
|
||||
g.wzdark = dark();
|
||||
if (g.knfloc > 0 && g.knfloc != g.loc)
|
||||
g.knfloc = 0;
|
||||
++g.turns;
|
||||
i = rand();
|
||||
|
||||
if (stimer()) /* as the grains of sand slip
|
||||
by */
|
||||
return;
|
||||
|
||||
while (!english()) /* retrieve player instructions */
|
||||
;
|
||||
|
||||
vrbx = 1;
|
||||
objx = objs[1] ? 1 : 0;
|
||||
iobx = iobjs[1] ? 1 : 0;
|
||||
verb = VAL(verbs[vrbx]);
|
||||
do {
|
||||
object = objx ? objs[objx] : 0;
|
||||
iobj = iobx ? iobjs[iobx] : 0;
|
||||
if (object && (objs[2] || iobjs[2])) {
|
||||
pspeak(object, -1);
|
||||
printf(" ");
|
||||
}
|
||||
switch (CLASS(verbs[vrbx])) {
|
||||
case MOTION:
|
||||
motion = verb;
|
||||
domove();
|
||||
break;
|
||||
case NOUN:
|
||||
bug(22);
|
||||
case ACTION:
|
||||
if (object || iobj)
|
||||
trverb();
|
||||
else
|
||||
itverb();
|
||||
break;
|
||||
case MISC:
|
||||
rspeak(verb);
|
||||
if (verb == 51)
|
||||
g.hinted[1] = TRUE;
|
||||
break;
|
||||
default:
|
||||
bug(22);
|
||||
}
|
||||
if (objx) {
|
||||
objx++;
|
||||
if (objs[objx] == 0)
|
||||
objx = 0;
|
||||
}
|
||||
if ((!objx || !objs[objx]) && iobx) {
|
||||
iobx++;
|
||||
if (iobjs[iobx] == 0)
|
||||
iobx = 0;
|
||||
if (iobx && iobjs[1])
|
||||
objx = 1;
|
||||
}
|
||||
} while (objx || iobx);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to describe current location
|
||||
*/
|
||||
void describe()
|
||||
{
|
||||
if (toting(BEAR))
|
||||
rspeak(141);
|
||||
if (dark())
|
||||
rspeak(16);
|
||||
else if ((g.terse && verb != LOOK) || g.visited[g.loc] % g.abbnum)
|
||||
descsh(g.loc);
|
||||
else
|
||||
desclg(g.loc);
|
||||
if (g.loc == 33 && pct(25) && !g.closing)
|
||||
rspeak(8);
|
||||
if (g.loc == 147 && !g.visited[g.loc])
|
||||
rspeak(216);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to describe visible items
|
||||
*/
|
||||
void descitem()
|
||||
{
|
||||
int i, state;
|
||||
|
||||
for (i = 1; i < MAXOBJ; ++i) {
|
||||
if (at(i)) {
|
||||
if (i == STEPS && toting(NUGGET))
|
||||
continue;
|
||||
if (g.prop[i] < 0) {
|
||||
if (g.closed)
|
||||
continue;
|
||||
else {
|
||||
g.prop[i] = 0;
|
||||
if (i == RUG || i == CHAIN
|
||||
|| i == SWORD || i == CASK)
|
||||
g.prop[i] = 1;
|
||||
if (i == CLOAK || i == RING)
|
||||
g.prop[i] = 2;
|
||||
--g.tally;
|
||||
}
|
||||
}
|
||||
if (i == STEPS && g.loc == g.fixed[STEPS])
|
||||
state = 1;
|
||||
else
|
||||
state = g.prop[i] % 8;
|
||||
pspeak(i, state);
|
||||
lookin(i);
|
||||
}
|
||||
}
|
||||
/* If remaining treasures too elusive, zap his lamp */
|
||||
if (g.tally == g.tally2 && g.tally != 0 && g.limit > 35)
|
||||
g.limit = 35;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to handle player's demise via
|
||||
waking up the dwarves...
|
||||
*/
|
||||
void dwarfend()
|
||||
{
|
||||
rspeak(136);
|
||||
normend();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
normal end of game
|
||||
*/
|
||||
void normend()
|
||||
{
|
||||
score(FALSE);
|
||||
gaveup = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Routine to handle the passing on of one
|
||||
of the player's incarnations...
|
||||
*/
|
||||
void death()
|
||||
{
|
||||
int yea, j;
|
||||
|
||||
if (!g.closing) {
|
||||
if (g.limit < 0) {
|
||||
rspeak(185);
|
||||
normend();
|
||||
return;
|
||||
}
|
||||
yea = yes(81 + g.numdie * 2, 82 + g.numdie * 2, 54);
|
||||
if (++g.numdie >= MAXDIE || !yea)
|
||||
normend();
|
||||
if (g.chase) {
|
||||
g.chase = FALSE;
|
||||
g.prop[WUMPUS] = 0;
|
||||
move(WUMPUS, 174);
|
||||
}
|
||||
if (toting(LAMP))
|
||||
g.prop[LAMP] = 0;
|
||||
for (j = 1; j < MAXOBJ; ++j) {
|
||||
if (toting(j))
|
||||
drop(j, j == LAMP ? 1 : g.oldloc2);
|
||||
if (wearng(j)) {
|
||||
g.prop[j] = 0;
|
||||
bitoff(j, WEARBT);
|
||||
}
|
||||
}
|
||||
g.newloc = 3;
|
||||
g.oldloc = g.loc;
|
||||
g.health = 100;
|
||||
return;
|
||||
}
|
||||
/* Closing -- no resurrection... */
|
||||
rspeak(131);
|
||||
++g.numdie;
|
||||
normend();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
dwarf stuff.
|
||||
*/
|
||||
void dwarves()
|
||||
{
|
||||
int i, j, k, attack, stick, dtotal;
|
||||
|
||||
/* See if dwarves allowed here */
|
||||
if (g.newloc == 0 || forced(g.newloc) || g.loc_attrib[g.newloc] & NOPIRAT)
|
||||
return;
|
||||
|
||||
/* See if dwarves are active. */
|
||||
if (!g.dflag) {
|
||||
if (inside(g.newloc))
|
||||
++g.dflag;
|
||||
return;
|
||||
}
|
||||
/* If first close encounter (of 3rd kind) */
|
||||
if (g.dflag == 1) {
|
||||
if (!inside(g.newloc) || pct(85))
|
||||
return;
|
||||
++g.dflag;
|
||||
|
||||
/* kill 0, 1 or 2 of the dwarfs */
|
||||
for (i = 1; i < 3; ++i)
|
||||
if (pct(50))
|
||||
g.dloc[(ranz(DWARFMAX - 1)) + 1] = 0;
|
||||
|
||||
/* If any of the survivors is at location, use alternate choise */
|
||||
for (i = 1; i <= DWARFMAX; ++i) {
|
||||
if (g.dloc[i] == g.newloc)
|
||||
g.dloc[i] = g.daltloc;
|
||||
g.odloc[i] = g.dloc[i];
|
||||
}
|
||||
rspeak(3);
|
||||
drop(AXE, g.newloc);
|
||||
return;
|
||||
}
|
||||
/* Things are in full swing. Move each dwarf at random, except if
|
||||
he's seen us then he sticks with us. Dwarfs never go to
|
||||
locations outside or meet the bear or following him into dead
|
||||
end in maze. And of couse, dead dwarves don't do much of
|
||||
anything. */
|
||||
|
||||
dtotal = attack = stick = 0;
|
||||
for (i = 1; i <= DWARFMAX; ++i) {
|
||||
if (g.dloc[i] == 0)
|
||||
continue;
|
||||
/* Move a dwarf at random. we don't have a matrix around to do
|
||||
it as in the original version... */
|
||||
do
|
||||
j = ranz(106) + 15;
|
||||
/* allowed area */
|
||||
while (j == g.odloc[i] || j == g.dloc[i]
|
||||
|| g.loc_attrib[j] & NOPIRAT);
|
||||
|
||||
if (j == 0)
|
||||
bug(36);
|
||||
g.odloc[i] = g.dloc[i];
|
||||
g.dloc[i] = j;
|
||||
|
||||
g.dseen[i] = ((g.dseen[i] && inside(g.newloc))
|
||||
|| g.dloc[i] == g.newloc
|
||||
|| g.odloc[i] == g.newloc);
|
||||
|
||||
if (g.dseen[i]) {
|
||||
g.dloc[i] = g.newloc;
|
||||
if (i == DWARFMAX)
|
||||
dopirate();
|
||||
else {
|
||||
++dtotal;
|
||||
if (g.odloc[i] == g.dloc[i]) {
|
||||
++attack;
|
||||
if (g.knfloc >= 0)
|
||||
g.knfloc = g.newloc;
|
||||
if (ranz(1000) < (45 * (g.dflag - 2)))
|
||||
++stick;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know shat's happing, let's tell the poor sucker about it */
|
||||
if (dtotal == 0)
|
||||
return;
|
||||
if (dtotal > 1)
|
||||
printf("There are %d threatening little dwarves in the room with you!\n", dtotal);
|
||||
else
|
||||
rspeak(4);
|
||||
if (attack == 0)
|
||||
return;
|
||||
if (g.dflag == 2)
|
||||
++g.dflag;
|
||||
if (attack > 1) {
|
||||
printf("%d of them throw knives at you!!\n", attack);
|
||||
k = 6;
|
||||
} else {
|
||||
rspeak(5);
|
||||
k = 52;
|
||||
}
|
||||
if (stick <= 1) {
|
||||
rspeak(stick + k);
|
||||
if (stick == 0)
|
||||
return;
|
||||
} else
|
||||
printf("%d of them get you !!!\n", stick);
|
||||
g.oldloc2 = g.newloc;
|
||||
death();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
pirate stuff
|
||||
*/
|
||||
void dopirate()
|
||||
{
|
||||
int j;
|
||||
boolean k;
|
||||
|
||||
if (g.newloc == g.chloc || g.prop[CHEST] >= 0)
|
||||
return;
|
||||
k = FALSE;
|
||||
/* Pirate won't take pyramid from plover room or dark room (too
|
||||
easy! ) */
|
||||
for (j = 1; j < MAXOBJ; ++j)
|
||||
if (treasr(j) && !(j == CASK && liq(CASK) == WINE)
|
||||
&& !(j == PYRAMID && (g.newloc == g.place[PYRAMID]
|
||||
|| g.newloc == g.place[EMERALD]))) {
|
||||
if (toting(j) && athand(j))
|
||||
goto stealit;
|
||||
if (here(j))
|
||||
k = TRUE;
|
||||
}
|
||||
if (g.tally == g.tally2 + 1 && k == FALSE && g.place[CHEST] == 0 &&
|
||||
athand(LAMP) && g.prop[LAMP] == 1) {
|
||||
rspeak(186);
|
||||
move(CHEST, g.chloc);
|
||||
move(MESSAGE, g.chloc2);
|
||||
g.dloc[DWARFMAX] = g.chloc;
|
||||
g.odloc[DWARFMAX] = g.chloc;
|
||||
g.dseen[DWARFMAX] = 0;
|
||||
return;
|
||||
}
|
||||
if (g.odloc[DWARFMAX] != g.dloc[DWARFMAX] && pct(30))
|
||||
rspeak(127);
|
||||
return;
|
||||
|
||||
stealit:
|
||||
|
||||
rspeak(128);
|
||||
/* don't steal chest back from troll! */
|
||||
if (g.place[MESSAGE] == 0)
|
||||
move(CHEST, g.chloc);
|
||||
move(MESSAGE, g.chloc2);
|
||||
for (j = 1; j < MAXOBJ; ++j) {
|
||||
if (!treasr(j) || !athand(j)
|
||||
|| (j == PYRAMID &&
|
||||
(g.newloc == plac[PYRAMID] || g.newloc == plac[EMERALD]))
|
||||
|| (j == CASK && (liq(CASK) != WINE)))
|
||||
continue;
|
||||
if (enclosed(j))
|
||||
extract(j);
|
||||
if (wearng(j)) {
|
||||
g.prop[j] = 0;
|
||||
bitoff(j, WEARBT);
|
||||
}
|
||||
insert(j, CHEST);
|
||||
}
|
||||
g.dloc[DWARFMAX] = g.chloc;
|
||||
g.odloc[DWARFMAX] = g.chloc;
|
||||
g.dseen[DWARFMAX] = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
special time limit stuff...
|
||||
*/
|
||||
int stimer()
|
||||
{
|
||||
int i, spk;
|
||||
static int clock3;
|
||||
|
||||
g.foobar = g.foobar > 0 ? -g.foobar : 0;
|
||||
g.combo = g.combo > 0 ? -g.combo : 0;
|
||||
if (g.turns > 310 && g.abbnum != 10000 && !g.terse)
|
||||
rspeak(273);
|
||||
|
||||
/* Bump all the right clocks for reconning battery life and closing */
|
||||
if (g.closed) {
|
||||
clock3--;
|
||||
if (clock3 == 0) {
|
||||
g.prop[PHONE] = 0;
|
||||
g.prop[BOOTH] = 0;
|
||||
rspeak(284);
|
||||
} else if (clock3 < -7) {
|
||||
rspeak(254);
|
||||
normend();
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
if (g.tally == 0 && inside(g.loc) && g.loc != Y2)
|
||||
--g.clock;
|
||||
if (g.clock == 0) {
|
||||
/* Start closing the cave */
|
||||
g.prop[GRATE] = 0;
|
||||
biton(GRATE, LOCKBT);
|
||||
bitoff(GRATE, OPENBT);
|
||||
g.prop[FISSURE] = 0;
|
||||
g.prop[TDOOR] = 0;
|
||||
biton(TDOOR, LOCKBT);
|
||||
bitoff(TDOOR, OPENBT);
|
||||
g.prop[TDOOR2] = 0;
|
||||
biton(TDOOR2, LOCKBT);
|
||||
bitoff(TDOOR2, OPENBT);
|
||||
for (i = 1; i <= DWARFMAX; ++i) {
|
||||
g.dseen[i] = FALSE;
|
||||
g.dloc[i] = 0;
|
||||
}
|
||||
move(TROLL, 0);
|
||||
move((TROLL + MAXOBJ), 0);
|
||||
move(TROLL2, plac[TROLL]);
|
||||
move((TROLL2 + MAXOBJ), fixd[TROLL]);
|
||||
juggle(CHASM);
|
||||
if (g.prop[BEAR] != 3)
|
||||
destroy(BEAR);
|
||||
g.prop[CHAIN] = 0;
|
||||
g.fixed[CHAIN] = 0;
|
||||
g.prop[AXE] = 0;
|
||||
g.fixed[AXE] = 0;
|
||||
rspeak(129);
|
||||
g.clock = -1;
|
||||
g.closing = TRUE;
|
||||
return (FALSE);
|
||||
}
|
||||
if (g.clock < 0)
|
||||
--g.clock2;
|
||||
if (g.clock2 == 0) {
|
||||
/* Set up storage room... and close the cave... */
|
||||
g.prop[BOTTLE] = put(BOTTLE, 115, 8);
|
||||
g.holder[BOTTLE] = WATER;
|
||||
g.place[WATER] = -BOTTLE;
|
||||
g.hlink[WATER] = 0;
|
||||
bitoff(BOTTLE, OPENBT);
|
||||
g.prop[PLANT] = put(PLANT, 115, 0);
|
||||
g.prop[OYSTER] = put(OYSTER, 115, 0);
|
||||
g.prop[LAMP] = put(LAMP, 115, 0);
|
||||
g.prop[ROD] = put(ROD, 115, 0);
|
||||
g.prop[DWARF] = put(DWARF, 115, 0);
|
||||
g.loc = 115;
|
||||
g.oldloc = 115;
|
||||
g.newloc = 115;
|
||||
/* Leave the grate with normal (non-negative property). */
|
||||
put(GRATE, 116, 0);
|
||||
biton(GRATE, LOCKBT);
|
||||
bitoff(GRATE, OPENBT);
|
||||
g.prop[SNAKE] = put(SNAKE, 116, 1);
|
||||
g.prop[BIRD] = put(BIRD, 116, 1);
|
||||
g.prop[CAGE] = put(CAGE, 116, 0);
|
||||
g.prop[ROD2] = put(ROD2, 116, 0);
|
||||
g.prop[PILLOW] = put(PILLOW, 116, 0);
|
||||
|
||||
g.prop[BOOTH] = put(BOOTH, 116, -3);
|
||||
g.fixed[BOOTH] = 115;
|
||||
g.prop[PHONE] = put(PHONE, 212, -4);
|
||||
|
||||
g.prop[MIRROR] = put(MIRROR, 115, 0);
|
||||
g.fixed[MIRROR] = 116;
|
||||
g.prop[BOOK2] = put(BOOK2, 115, 0);
|
||||
|
||||
for (i = 1; i < MAXOBJ; ++i) {
|
||||
if (toting(i) && enclosed(i))
|
||||
extract(i);
|
||||
if (toting(i))
|
||||
destroy(i);
|
||||
}
|
||||
rspeak(132);
|
||||
g.closed = TRUE;
|
||||
clock3 = 20 + ranz(20);
|
||||
newtravel = TRUE;
|
||||
return (TRUE);
|
||||
}
|
||||
if (g.prop[LAMP] == 1)
|
||||
--g.limit;
|
||||
if (g.limit == 0) {
|
||||
--g.limit;
|
||||
g.prop[LAMP] = 0;
|
||||
if (here(LAMP))
|
||||
rspeak(184);
|
||||
return (FALSE);
|
||||
}
|
||||
if (g.limit < 0 && outside(g.loc)) {
|
||||
rspeak(185);
|
||||
normend();
|
||||
return (TRUE);
|
||||
}
|
||||
if (g.limit <= 40) {
|
||||
if (g.lmwarn || !here(LAMP))
|
||||
return (FALSE);
|
||||
g.lmwarn = TRUE;
|
||||
spk = 187;
|
||||
if (g.prop[BATTERIES] == 1)
|
||||
spk = 323;
|
||||
if (g.place[BATTERIES] == 0)
|
||||
spk = 183;
|
||||
if (g.prop[VEND] == 1)
|
||||
spk = 189;
|
||||
rspeak(spk);
|
||||
return (FALSE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* HINTS
|
||||
come here if he's been long enough at required location(s)
|
||||
for some unused hint, hint number is in variable "hint".
|
||||
Branch to quick test for additional conditions, then
|
||||
do neet stuff. If conditions are met and we want to offer
|
||||
hint. Clear hintlc if no action is taken.
|
||||
*/
|
||||
|
||||
#define MASE 1
|
||||
#define DARK 2
|
||||
#define WITT 3
|
||||
#define H_SWORD 4
|
||||
#define SLIDE 5
|
||||
#define H_GRATE 6
|
||||
#define H_BIRD 7
|
||||
#define H_ELFIN 8
|
||||
#define RNBOW 9
|
||||
#define STYX 10
|
||||
#define H_SNAKE 11
|
||||
#define CASTLE 12
|
||||
|
||||
void do_hint(hint)
|
||||
int hint;
|
||||
{
|
||||
g.hintlc[hint] = 0;
|
||||
switch (hint + 1 - HNTMIN) {
|
||||
case MASE:
|
||||
if (!at(g.loc) && !at(g.oldloc)
|
||||
&& !at(g.loc) && burden(0) > 1)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case DARK:
|
||||
if (g.prop[EMERALD] != -1 && g.prop[PYRAMID] == -1)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case WITT:
|
||||
break;
|
||||
case H_SWORD:
|
||||
if ((g.prop[SWORD] == 1 || g.prop[SWORD] == 5)
|
||||
&& !toting(CROWN))
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case SLIDE:
|
||||
break;
|
||||
case H_GRATE:
|
||||
if (g.prop[GRATE] == 0 && !athand(KEYS))
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case H_BIRD:
|
||||
if (here(BIRD) && athand(ROD) && object == BIRD)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case H_ELFIN:
|
||||
if (!g.visited[159])
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case RNBOW:
|
||||
if (!toting(SHOES) || g.visited[205])
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case STYX:
|
||||
if (!athand(LYRE) && g.prop[DOG] != 1)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case H_SNAKE:
|
||||
if (here(SNAKE) && !here(BIRD))
|
||||
break;
|
||||
else
|
||||
return;
|
||||
case CASTLE:
|
||||
break;
|
||||
default:
|
||||
printf(" TRYING TO PRINT HINT # %d\n", hint);
|
||||
bug(27);
|
||||
}
|
||||
if (!yes(g.hints[hint][3], 0, 54))
|
||||
return;
|
||||
printf("\nI am prepared to give you a hint,");
|
||||
printf(" but it will cost you %2d points\n", g.hints[hint][2]);
|
||||
g.hinted[hint] = yes(175, g.hints[hint][4], 54);
|
||||
if (g.hinted[hint] && g.limit > 30)
|
||||
g.limit += 30 * g.hints[hint][2];
|
||||
return;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user