Compare commits
1424 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6245ca5d9 | ||
|
|
a5f07cbea0 | ||
|
|
81a28d7a6f | ||
|
|
2989b462a5 | ||
|
|
ab15ebaae8 | ||
|
|
f6aacbfe6d | ||
|
|
25e6573317 | ||
|
|
c589f09115 | ||
|
|
8c69b6621c | ||
|
|
a8fe4b7a5f | ||
|
|
6eaa1b36fc | ||
|
|
434a483d50 | ||
|
|
8fb6134aa5 | ||
|
|
533c82ce92 | ||
|
|
fca0e799c2 | ||
|
|
2f91039c70 | ||
|
|
02d630c37f | ||
|
|
8d3e1becf0 | ||
|
|
383ad8b8a6 | ||
|
|
7ec064b88e | ||
|
|
472bbb750c | ||
|
|
d1df571746 | ||
|
|
438adb6c25 | ||
|
|
f5e760268b | ||
|
|
8ab246297b | ||
|
|
aaf71d8453 | ||
|
|
5f2e76b8c7 | ||
|
|
3f197952bd | ||
|
|
0e569e4a27 | ||
|
|
0767e69199 | ||
|
|
d041590218 | ||
|
|
25a9a1f62b | ||
|
|
f891cc9415 | ||
|
|
20601f3477 | ||
|
|
6c33ec4045 | ||
|
|
f9f289aba5 | ||
|
|
d760b5c979 | ||
|
|
cf908574cf | ||
|
|
5c92622ad6 | ||
|
|
3a30f34f1a | ||
|
|
f86ecd4a06 | ||
|
|
38a9edba20 | ||
|
|
1e5f939381 | ||
|
|
b68a8a6b34 | ||
|
|
efb3d3292f | ||
|
|
fbea7eca65 | ||
|
|
755e2819b0 | ||
|
|
e44a00ae0d | ||
|
|
a1e0bb5a09 | ||
|
|
ef49d8a6ca | ||
|
|
e99b8eae65 | ||
|
|
ab877a2dde | ||
|
|
b50ac8f73e | ||
|
|
53f21f6ee7 | ||
|
|
d85f245800 | ||
|
|
527137e3ee | ||
|
|
d934e7e3dd | ||
|
|
8828da5f56 | ||
|
|
b4d0588d06 | ||
|
|
eab61cd0b2 | ||
|
|
4db9705dd8 | ||
|
|
ddd9b39bd4 | ||
|
|
bdf2f7e711 | ||
|
|
4adf78bad3 | ||
|
|
c60aec9c20 | ||
|
|
7b465b663a | ||
|
|
94eaab7710 | ||
|
|
0b3f3657c8 | ||
|
|
c1131a28ad | ||
|
|
6853e627f1 | ||
|
|
e9b95e4f6c | ||
|
|
903a255836 | ||
|
|
b95e6376d0 | ||
|
|
32ebde4612 | ||
|
|
e653578db3 | ||
|
|
ae81b82fb8 | ||
|
|
9e5322d23a | ||
|
|
3a6e468d9a | ||
|
|
4ffbdcc0f5 | ||
|
|
e9e7bb968b | ||
|
|
ff3b235580 | ||
|
|
b898c8fce6 | ||
|
|
8bc52d0692 | ||
|
|
9ec4fa7b50 | ||
|
|
3552497ae5 | ||
|
|
5c5d310a0a | ||
|
|
887b9d4113 | ||
|
|
514b18722a | ||
|
|
65ba3e2f50 | ||
|
|
a4e6ae101a | ||
|
|
5a105cdb7d | ||
|
|
8ad100a55b | ||
|
|
3504801778 | ||
|
|
c923fe71b4 | ||
|
|
ba2db7262b | ||
|
|
5d3083c3fb | ||
|
|
74567f7ef1 | ||
|
|
1ff3583e41 | ||
|
|
ad9ceecf9c | ||
|
|
074d584a04 | ||
|
|
2f7f2a5fca | ||
|
|
608dacf689 | ||
|
|
452506fc41 | ||
|
|
6ccff2cbde | ||
|
|
52e9fe9296 | ||
|
|
8f1631b797 | ||
|
|
f4769e44a3 | ||
|
|
e297ea999e | ||
|
|
07e2882366 | ||
|
|
9a7e5ed3b0 | ||
|
|
7dd4001b40 | ||
|
|
20091df725 | ||
|
|
e8e0e23d20 | ||
|
|
f33a43efdf | ||
|
|
002a4dcad0 | ||
|
|
a8b95ce6ed | ||
|
|
4dcad1d294 | ||
|
|
f8acc29fca | ||
|
|
eec44dad17 | ||
|
|
45723584c5 | ||
|
|
ab1bbe5492 | ||
|
|
5902040874 | ||
|
|
3a570dc80a | ||
|
|
01cc526318 | ||
|
|
d9867551fc | ||
|
|
b53d6284eb | ||
|
|
cc2567e32f | ||
|
|
e93bf37e86 | ||
|
|
4b603f1cd6 | ||
|
|
4e67a6216b | ||
|
|
d28ed9c98e | ||
|
|
a1ef0d19b1 | ||
|
|
a8c108bca1 | ||
|
|
609acbf43d | ||
|
|
13945b2a61 | ||
|
|
9a1ce86969 | ||
|
|
36eccc5174 | ||
|
|
adea540e38 | ||
|
|
81cadd74d2 | ||
|
|
565c4771b6 | ||
|
|
ee1d6e4ed0 | ||
|
|
b14bd4df58 | ||
|
|
6b8a5ab622 | ||
|
|
5df25e78db | ||
|
|
17e2c24645 | ||
|
|
f7f2a36925 | ||
|
|
010c4fc0b5 | ||
|
|
99cec89cb3 | ||
|
|
f8937b2d3b | ||
|
|
c1ffdc5801 | ||
|
|
0961c2fc0d | ||
|
|
3fc4c3a9f1 | ||
|
|
a4f2c8419f | ||
|
|
c7eb151ad0 | ||
|
|
0920ad152f | ||
|
|
16d6963ef6 | ||
|
|
da799d92fa | ||
|
|
90efeb5ddb | ||
|
|
b8afa21fad | ||
|
|
864e49a12c | ||
|
|
2fc80399b7 | ||
|
|
806704c237 | ||
|
|
3e52aaf212 | ||
|
|
15f3ad4dbd | ||
|
|
54d02f158d | ||
|
|
700f942692 | ||
|
|
2d294e080c | ||
|
|
9b490f71b0 | ||
|
|
88367a5fb8 | ||
|
|
0465c41c84 | ||
|
|
e122e42354 | ||
|
|
3c66913cd2 | ||
|
|
e674680ddd | ||
|
|
59090133c0 | ||
|
|
7337b343cd | ||
|
|
67c6994370 | ||
|
|
5dd7318db7 | ||
|
|
217208a36d | ||
|
|
6083295f46 | ||
|
|
53c6c12886 | ||
|
|
c1e667222a | ||
|
|
3f94dfa25f | ||
|
|
38fd861fff | ||
|
|
c4149423f9 | ||
|
|
b4af75c07f | ||
|
|
83312d7c6c | ||
|
|
1837644c4a | ||
|
|
2c1fd3c395 | ||
|
|
d33cc2b5e3 | ||
|
|
78b3bf56f7 | ||
|
|
95cea79e39 | ||
|
|
b56658bdad | ||
|
|
0295912479 | ||
|
|
b7598ceefa | ||
|
|
3448ce56f4 | ||
|
|
9b9e2f1748 | ||
|
|
a0d2f9a12d | ||
|
|
f077d1ad62 | ||
|
|
94723e27ad | ||
|
|
5a3dea451d | ||
|
|
f92f022eda | ||
|
|
9406696578 | ||
|
|
83f4cd156e | ||
|
|
49c8e53ee2 | ||
|
|
b760e25458 | ||
|
|
0535644b30 | ||
|
|
cbd959c473 | ||
|
|
ff4bd3977a | ||
|
|
fd5eaf323f | ||
|
|
074653973e | ||
|
|
6a0296791d | ||
|
|
04f9a37c71 | ||
|
|
905cbf0bf8 | ||
|
|
e39f925655 | ||
|
|
e4626e94f4 | ||
|
|
dc0c768760 | ||
|
|
e03209979b | ||
|
|
c5eed9a1ae | ||
|
|
a79401b31d | ||
|
|
cc558f0603 | ||
|
|
3a7c4d89de | ||
|
|
adb8a55b46 | ||
|
|
e077cce617 | ||
|
|
cf9195c808 | ||
|
|
69e87633bc | ||
|
|
7b7d46be89 | ||
|
|
a687d4f574 | ||
|
|
0a70a3f4d8 | ||
|
|
7464e647de | ||
|
|
712077a760 | ||
|
|
ec74e8a443 | ||
|
|
4785e6df74 | ||
|
|
0aca8577b5 | ||
|
|
fb462ab272 | ||
|
|
b53e277ba1 | ||
|
|
b2d1129f27 | ||
|
|
c5aa1b139a | ||
|
|
c591cc50eb | ||
|
|
fb45259967 | ||
|
|
7a15d4ff67 | ||
|
|
86fd7c5af6 | ||
|
|
bca179e8bd | ||
|
|
2f4c30fd85 | ||
|
|
36d9b2311d | ||
|
|
783c636c73 | ||
|
|
dd7868364d | ||
|
|
ed02c95d50 | ||
|
|
123e5bd998 | ||
|
|
7db3b75b3e | ||
|
|
f662cefd85 | ||
|
|
e3c26b2573 | ||
|
|
541e585d8e | ||
|
|
cb6c4b883d | ||
|
|
471426fb3b | ||
|
|
6cc4a62c0e | ||
|
|
b0243da77c | ||
|
|
21189a42a7 | ||
|
|
927aaa0f27 | ||
|
|
ce39dfe425 | ||
|
|
8af99d1893 | ||
|
|
f43f46c175 | ||
|
|
6c85cbecf1 | ||
|
|
b7bcaf940d | ||
|
|
3f0816e3d9 | ||
|
|
829e21733b | ||
|
|
e40bef3c0a | ||
|
|
1224a14ae4 | ||
|
|
ae8adeb90a | ||
|
|
3bb23e5c8b | ||
|
|
bef41ada0d | ||
|
|
d2cbb14d7c | ||
|
|
b4ada906c0 | ||
|
|
adce862c27 | ||
|
|
98deeaef15 | ||
|
|
e4dde849ae | ||
|
|
33e28c9948 | ||
|
|
507fd9d15b | ||
|
|
82dc6426b4 | ||
|
|
e49b83bb12 | ||
|
|
99860de3c9 | ||
|
|
865ed8a1e5 | ||
|
|
dac48972d5 | ||
|
|
872b1f3e4c | ||
|
|
317c733572 | ||
|
|
c7286112ef | ||
|
|
b2fd0ca1cb | ||
|
|
8c4738d5a7 | ||
|
|
b90c9ecb13 | ||
|
|
d0d9486f44 | ||
|
|
eb72eae304 | ||
|
|
59ed5cb398 | ||
|
|
8acb491eef | ||
|
|
2f8f51d1e4 | ||
|
|
498a2c9b16 | ||
|
|
0a76546ae9 | ||
|
|
c648b589be | ||
|
|
72173ffaca | ||
|
|
25133bd74b | ||
|
|
7c3002bf27 | ||
|
|
ec93a0e219 | ||
|
|
9f0ac16942 | ||
|
|
b2120e223a | ||
|
|
2c3691d53d | ||
|
|
3c8cecda1f | ||
|
|
a8330e0049 | ||
|
|
5f6a654d3e | ||
|
|
e707d29dd6 | ||
|
|
02962ba848 | ||
|
|
8a62fec3ee | ||
|
|
437173f430 | ||
|
|
fcedd45c3c | ||
|
|
4e5d88ce26 | ||
|
|
b0849613bf | ||
|
|
fb390d3505 | ||
|
|
f839f96578 | ||
|
|
c359ac9128 | ||
|
|
856aacf388 | ||
|
|
db7f023417 | ||
|
|
330c190958 | ||
|
|
e74e8a184a | ||
|
|
d4e3cb4c03 | ||
|
|
00f4f8d54c | ||
|
|
126185aaa7 | ||
|
|
ffccb56914 | ||
|
|
bd1e54bc0b | ||
|
|
eb20f3c8f5 | ||
|
|
95699e1730 | ||
|
|
32de8cd062 | ||
|
|
2351a3fc9f | ||
|
|
1b39201966 | ||
|
|
186f3e2f0c | ||
|
|
01a509fa26 | ||
|
|
2ccd47596b | ||
|
|
82303fc3ca | ||
|
|
918150048a | ||
|
|
a99ac8d3f4 | ||
|
|
2566b30c38 | ||
|
|
4d2ef6e5b6 | ||
|
|
6e903b0b32 | ||
|
|
5762295ec3 | ||
|
|
10d680cff4 | ||
|
|
ce364b2d7a | ||
|
|
1565698169 | ||
|
|
9326234109 | ||
|
|
364685e195 | ||
|
|
d8f5c59a59 | ||
|
|
05bcf7089e | ||
|
|
33208fb557 | ||
|
|
dedf83a19b | ||
|
|
a5e1325879 | ||
|
|
f0ec774d9c | ||
|
|
8c2143d4d8 | ||
|
|
04f38adf73 | ||
|
|
2f5d380943 | ||
|
|
1aafe34a08 | ||
|
|
19fba3cd24 | ||
|
|
3b59297b36 | ||
|
|
53d65b5500 | ||
|
|
ee014e5b10 | ||
|
|
e1f13129e8 | ||
|
|
b5b1d1a66b | ||
|
|
7df001be94 | ||
|
|
384625c1a6 | ||
|
|
687c82558c | ||
|
|
a139ed74f2 | ||
|
|
aa7c5e7ceb | ||
|
|
b63241d451 | ||
|
|
a0eb1d151f | ||
|
|
dd61035645 | ||
|
|
1e89d5d2fe | ||
|
|
690c723e5f | ||
|
|
5326a31249 | ||
|
|
491ad6db50 | ||
|
|
c0b892fee8 | ||
|
|
83c8d678aa | ||
|
|
f2b10f6469 | ||
|
|
587e52855a | ||
|
|
ca1dbe10ed | ||
|
|
67ed7d9d49 | ||
|
|
e780b94bd3 | ||
|
|
e285ffcd05 | ||
|
|
bbae0fc9ef | ||
|
|
a9ba47101a | ||
|
|
a8c50c06e3 | ||
|
|
2af40a5013 | ||
|
|
daa1a7398f | ||
|
|
f5472574a7 | ||
|
|
591dcaf681 | ||
|
|
b6d19aefa0 | ||
|
|
a7dd11c6da | ||
|
|
8a13456f3a | ||
|
|
1a925b8e60 | ||
|
|
2eac3a6dec | ||
|
|
64c991da2a | ||
|
|
7beada58cd | ||
|
|
8b936b617f | ||
|
|
73cd5e5212 | ||
|
|
c2da35319d | ||
|
|
643160f6e7 | ||
|
|
29f9e4e400 | ||
|
|
174b3eddc0 | ||
|
|
8ea1c9a418 | ||
|
|
68e327ae7b | ||
|
|
24c835b0b6 | ||
|
|
ca40e581eb | ||
|
|
03f8b54565 | ||
|
|
a75e1e3292 | ||
|
|
9e3e21efeb | ||
|
|
993d37b90b | ||
|
|
1907b96d69 | ||
|
|
8dcffd4d07 | ||
|
|
5df0b03c95 | ||
|
|
cb61b8dc4c | ||
|
|
2ffba736e9 | ||
|
|
03fbd79049 | ||
|
|
6801782096 | ||
|
|
e609c468d9 | ||
|
|
241844eab0 | ||
|
|
b5f918cbd6 | ||
|
|
2a429030ff | ||
|
|
9b9cd3dd20 | ||
|
|
9958e09dbc | ||
|
|
a5e6d72339 | ||
|
|
133ccbe408 | ||
|
|
88cab1e4a3 | ||
|
|
97f908e483 | ||
|
|
d421117620 | ||
|
|
a24b23622e | ||
|
|
19366be186 | ||
|
|
a35ee96336 | ||
|
|
249c6818f1 | ||
|
|
ea37fb9187 | ||
|
|
f8be324ace | ||
|
|
5b0fc31b1c | ||
|
|
608810a3e7 | ||
|
|
76aed0141c | ||
|
|
5b2f35167f | ||
|
|
77b615ceba | ||
|
|
494fc9a857 | ||
|
|
065d743019 | ||
|
|
3a10d1c493 | ||
|
|
24271c542b | ||
|
|
d655a26c9d | ||
|
|
36cd1ad5c9 | ||
|
|
a2606bad09 | ||
|
|
3fd18faaf6 | ||
|
|
8c41469140 | ||
|
|
cee69980b0 | ||
|
|
60d2f8662c | ||
|
|
0d7b28e52e | ||
|
|
9cd22ab862 | ||
|
|
b8cbbc2c28 | ||
|
|
84c3c2ebe7 | ||
|
|
93752b8a39 | ||
|
|
225e60ce34 | ||
|
|
d5e9d0000d | ||
|
|
d5115a71a1 | ||
|
|
2a097fc5ed | ||
|
|
e9fd7d9fad | ||
|
|
24a0def8cd | ||
|
|
116df55e21 | ||
|
|
4ea952d5c0 | ||
|
|
d0538a81bb | ||
|
|
858cebed7d | ||
|
|
225f222c9f | ||
|
|
d7f1d200ab | ||
|
|
f85c097449 | ||
|
|
ecf1c79aad | ||
|
|
df40181417 | ||
|
|
0ca8324f59 | ||
|
|
0fa89d8e81 | ||
|
|
61e3c011f5 | ||
|
|
696d34069a | ||
|
|
0bad8e4237 | ||
|
|
aaa468563b | ||
|
|
7414733bea | ||
|
|
96f34cd5c4 | ||
|
|
0efda1a79e | ||
|
|
b6b039d84e | ||
|
|
fbeb5fb483 | ||
|
|
81598083e7 | ||
|
|
98545d2cdf | ||
|
|
ddebdd9a8f | ||
|
|
4e87d341f7 | ||
|
|
aa0bcaaf2b | ||
|
|
230b894779 | ||
|
|
4a843976e0 | ||
|
|
df5ccbd2b2 | ||
|
|
eee0d2391c | ||
|
|
6c9498147f | ||
|
|
a48c671957 | ||
|
|
354f2dd094 | ||
|
|
c87cdc9160 | ||
|
|
0b814f9ea3 | ||
|
|
7668631d1b | ||
|
|
ea8440d742 | ||
|
|
adad8e46c9 | ||
|
|
f54d59ba4a | ||
|
|
2eace48d9a | ||
|
|
fa989f42c1 | ||
|
|
aa496b75c2 | ||
|
|
460cd40aa5 | ||
|
|
51d7cc07f1 | ||
|
|
35105534e7 | ||
|
|
3ddf10e5ca | ||
|
|
f08736405e | ||
|
|
c05d011fba | ||
|
|
83b8237046 | ||
|
|
d8aeb8dd2a | ||
|
|
84c8506e90 | ||
|
|
c1aacf0be3 | ||
|
|
acd6501610 | ||
|
|
8ffec99b07 | ||
|
|
610121480c | ||
|
|
ba3d0255fc | ||
|
|
0002bdddfa | ||
|
|
a7e506d698 | ||
|
|
94fe42a945 | ||
|
|
3479849dc4 | ||
|
|
5eaa1b435c | ||
|
|
ae3d0aba15 | ||
|
|
42c405ad23 | ||
|
|
33c75fd9aa | ||
|
|
fbaee7a853 | ||
|
|
d52a0f3bca | ||
|
|
fac047480d | ||
|
|
e599246803 | ||
|
|
393adf7acd | ||
|
|
8bca4099c7 | ||
|
|
e1f3d64c4a | ||
|
|
64c8b69948 | ||
|
|
e94010b239 | ||
|
|
825aa7d8d8 | ||
|
|
bb0d9ce226 | ||
|
|
7ec552676c | ||
|
|
09923991e5 | ||
|
|
3f0950ea01 | ||
|
|
e9f61c8787 | ||
|
|
9390431ce4 | ||
|
|
06c903b26c | ||
|
|
fa105b1d3a | ||
|
|
b8f174a5ce | ||
|
|
59f9c8e8c9 | ||
|
|
9dfb2d2814 | ||
|
|
3913c387c9 | ||
|
|
8fe2308b34 | ||
|
|
d547a44332 | ||
|
|
096a890097 | ||
|
|
482e57812b | ||
|
|
21e47f8d04 | ||
|
|
fc27eb188f | ||
|
|
b4b536d782 | ||
|
|
a76899624a | ||
|
|
1a19fc17b2 | ||
|
|
ecde936aee | ||
|
|
154e25ff60 | ||
|
|
c1ffa5b1c5 | ||
|
|
669b0a5835 | ||
|
|
ebff5c40a2 | ||
|
|
013df1cc3b | ||
|
|
05da981f05 | ||
|
|
bb82fdb543 | ||
|
|
f48b4c8897 | ||
|
|
9cd1dfe898 | ||
|
|
cfbcb1de66 | ||
|
|
58d9badfe2 | ||
|
|
12a4af47c2 | ||
|
|
ee1f884229 | ||
|
|
c4286dc6ee | ||
|
|
b73ab2d885 | ||
|
|
056d2ad312 | ||
|
|
362efb24c1 | ||
|
|
7fbeca05c9 | ||
|
|
e5b47b4328 | ||
|
|
05bae43c3c | ||
|
|
f8b5028cd1 | ||
|
|
b5384e93ed | ||
|
|
cdff41c12e | ||
|
|
ce8f78a7bb | ||
|
|
ab90d6e62a | ||
|
|
0052fe7bbc | ||
|
|
4973174534 | ||
|
|
44d16327c1 | ||
|
|
f03c31db82 | ||
|
|
c60015a260 | ||
|
|
64f125f353 | ||
|
|
8b040f812a | ||
|
|
c16eb94945 | ||
|
|
d61b7d13e4 | ||
|
|
d56c6f312c | ||
|
|
ef079e183b | ||
|
|
929eb9dc6c | ||
|
|
6ed283946c | ||
|
|
ceb6d4e11d | ||
|
|
19a5975d5a | ||
|
|
20f3f4ac16 | ||
|
|
786bfc3bb7 | ||
|
|
3a3eabb57a | ||
|
|
ecd3e728b7 | ||
|
|
3e76df7481 | ||
|
|
3cfe12c1b7 | ||
|
|
4d410cfce9 | ||
|
|
8111e27905 | ||
|
|
d8dda9de84 | ||
|
|
8baf865c94 | ||
|
|
7aff3d5852 | ||
|
|
34fa178243 | ||
|
|
e913574e02 | ||
|
|
c9e70d4c0a | ||
|
|
e8ef3da713 | ||
|
|
d0d80170a2 | ||
|
|
d99f5a470c | ||
|
|
d3800d59d5 | ||
|
|
cae5264a4c | ||
|
|
42e950aa69 | ||
|
|
0030c1bd6c | ||
|
|
a404b1512a | ||
|
|
38deedc1b5 | ||
|
|
c88e14fe26 | ||
|
|
40951d81a7 | ||
|
|
6665c2431b | ||
|
|
c774b16976 | ||
|
|
77ba3ab99c | ||
|
|
ed2c01405f | ||
|
|
daaee738fc | ||
|
|
47c6215c22 | ||
|
|
5f280ff557 | ||
|
|
b9e80983a5 | ||
|
|
f5927f5b32 | ||
|
|
c92fc340a2 | ||
|
|
50d08dc1e1 | ||
|
|
54e903a543 | ||
|
|
84114e341d | ||
|
|
f193c57a63 | ||
|
|
18b99e3f69 | ||
|
|
1179257bfd | ||
|
|
98705aa51c | ||
|
|
679592720a | ||
|
|
3c7ebaedcd | ||
|
|
04e442070d | ||
|
|
2207f5e201 | ||
|
|
926e14b362 | ||
|
|
aa0c5e87e8 | ||
|
|
a6b2115963 | ||
|
|
0f9ee792d9 | ||
|
|
eade213197 | ||
|
|
6cab66354d | ||
|
|
0eeb4f5d5b | ||
|
|
245ab4d0ac | ||
|
|
4acfe655d5 | ||
|
|
45c4a0b354 | ||
|
|
7df70c000a | ||
|
|
0f3981bea9 | ||
|
|
aa52972660 | ||
|
|
e4347a43b9 | ||
|
|
553af2f702 | ||
|
|
e61cfaf5c1 | ||
|
|
89c94b5578 | ||
|
|
eeac8727bc | ||
|
|
8c69f1fb25 | ||
|
|
aec8763a8e | ||
|
|
58557b5aff | ||
|
|
cf450e1b4c | ||
|
|
64c7ee7e6b | ||
|
|
e89b9f6a2a | ||
|
|
b1ef1b24ce | ||
|
|
a790ec5884 | ||
|
|
19ea44208f | ||
|
|
c02ec54269 | ||
|
|
6f460bace6 | ||
|
|
40dc7e6e1d | ||
|
|
c60da7355e | ||
|
|
9399225b81 | ||
|
|
5363cb05f6 | ||
|
|
f15df6bb7a | ||
|
|
6315130e60 | ||
|
|
39cf857db9 | ||
|
|
e83474f2eb | ||
|
|
249300aebe | ||
|
|
02d87b3aa3 | ||
|
|
92ab03afc8 | ||
|
|
d066e25744 | ||
|
|
3ac5aa4a95 | ||
|
|
ab2fe68fd8 | ||
|
|
18cf214528 | ||
|
|
0424613ba2 | ||
|
|
c428d9e76a | ||
|
|
37f793c631 | ||
|
|
ce148944c7 | ||
|
|
76d660ebd3 | ||
|
|
ca93cc563e | ||
|
|
0304f4a759 | ||
|
|
ba4081c1fc | ||
|
|
e051f1b510 | ||
|
|
5813089e0b | ||
|
|
5e1feddcb6 | ||
|
|
a299e551fe | ||
|
|
18e39300e6 | ||
|
|
b734954a63 | ||
|
|
4181184acf | ||
|
|
725d460e4b | ||
|
|
a777f7b9b5 | ||
|
|
c30075142f | ||
|
|
5b0dc80bf7 | ||
|
|
66d536ed07 | ||
|
|
6854a2ade6 | ||
|
|
6de1326ba4 | ||
|
|
65ee333ae0 | ||
|
|
2661f2f7c4 | ||
|
|
3a8182c105 | ||
|
|
60152827e3 | ||
|
|
8e86dca256 | ||
|
|
c6710c7a70 | ||
|
|
04bc3f0a63 | ||
|
|
a9d3af8821 | ||
|
|
6717457390 | ||
|
|
352b4ea5b9 | ||
|
|
822f2e3ddf | ||
|
|
b7726d924e | ||
|
|
6f07e22210 | ||
|
|
09d1484b22 | ||
|
|
e3d884479a | ||
|
|
7a234cdae5 | ||
|
|
39105dac1b | ||
|
|
00b8acdf49 | ||
|
|
9e0576587b | ||
|
|
467c31ea0a | ||
|
|
352083cb23 | ||
|
|
cddc003e70 | ||
|
|
e29b623db3 | ||
|
|
4663e339b8 | ||
|
|
afacb3406d | ||
|
|
a4b4cc290c | ||
|
|
75ff9d841b | ||
|
|
b9e41844c0 | ||
|
|
64bca50d54 | ||
|
|
2547f1f7e5 | ||
|
|
9d9a4e874d | ||
|
|
ca81b168d9 | ||
|
|
48208883de | ||
|
|
dab03e34f5 | ||
|
|
4e6303d397 | ||
|
|
482cb65690 | ||
|
|
44384a4602 | ||
|
|
5c94371f9a | ||
|
|
e104c79374 | ||
|
|
7c05877df2 | ||
|
|
e457b02142 | ||
|
|
ef1b844e7b | ||
|
|
df6dfb4ab8 | ||
|
|
9357dcf68e | ||
|
|
9aef9bca3d | ||
|
|
f96681c5e4 | ||
|
|
c51f051257 | ||
|
|
5d5990dc8f | ||
|
|
c3e0734dbc | ||
|
|
c6dd35f03d | ||
|
|
968d55aafa | ||
|
|
92f20d53fb | ||
|
|
6630c1cbf5 | ||
|
|
1d7e321c10 | ||
|
|
8c937da5f2 | ||
|
|
5fecb27c1e | ||
|
|
63760fa1cd | ||
|
|
12a1256c1d | ||
|
|
f6c18bc9ed | ||
|
|
3e1ea1c025 | ||
|
|
e923f8188d | ||
|
|
0eba00447e | ||
|
|
dd8e82f797 | ||
|
|
f79efbab6f | ||
|
|
f488e7358d | ||
|
|
0856c1a03e | ||
|
|
a452d9ee2d | ||
|
|
af531f0449 | ||
|
|
213f763630 | ||
|
|
0649b6af90 | ||
|
|
1d418728b0 | ||
|
|
bd39b48f19 | ||
|
|
5e1e458ecb | ||
|
|
db69432dcd | ||
|
|
7709ee622c | ||
|
|
a757ed886a | ||
|
|
6740ad3706 | ||
|
|
7609e35f10 | ||
|
|
3d962315f2 | ||
|
|
db3b14c960 | ||
|
|
20d28e6031 | ||
|
|
77172463a3 | ||
|
|
2bfda1be11 | ||
|
|
e426776598 | ||
|
|
ca253d5911 | ||
|
|
00af90ab3c | ||
|
|
a9ea3cd76d | ||
|
|
d21876cdb8 | ||
|
|
54c465f25d | ||
|
|
e295947d04 | ||
|
|
32a1753e61 | ||
|
|
1fcf6f038e | ||
|
|
ec39b59a03 | ||
|
|
95f748c54e | ||
|
|
08cf0629f5 | ||
|
|
11adda400f | ||
|
|
8968bf2e36 | ||
|
|
858ff187f5 | ||
|
|
18cab09a95 | ||
|
|
1c528eeee9 | ||
|
|
ad88e7626b | ||
|
|
e4c3232f42 | ||
|
|
7ee8e5bf86 | ||
|
|
cbb2b59a90 | ||
|
|
69a27a4ec6 | ||
|
|
69ae372b51 | ||
|
|
813a3b438f | ||
|
|
fbe6d5defa | ||
|
|
98199faa0b | ||
|
|
010ca705df | ||
|
|
6c5064b5c3 | ||
|
|
97c9d444ae | ||
|
|
31f2931281 | ||
|
|
6b783965c4 | ||
|
|
b201c1f600 | ||
|
|
769e457d94 | ||
|
|
b3ff4878f8 | ||
|
|
0c97aa9e14 | ||
|
|
270e944e30 | ||
|
|
112262cb24 | ||
|
|
6d62d2fb56 | ||
|
|
29bbcab6b4 | ||
|
|
fdd7d04744 | ||
|
|
edd309e537 | ||
|
|
40c2614ef4 | ||
|
|
ed0c143242 | ||
|
|
1512d5ce64 | ||
|
|
f23f9a03c8 | ||
|
|
b90626021b | ||
|
|
fb7e2901b7 | ||
|
|
992ff49b43 | ||
|
|
f441949515 | ||
|
|
00bcfe0b7e | ||
|
|
85663f2c18 | ||
|
|
223b6f1ba4 | ||
|
|
6a8062a30d | ||
|
|
69d605f410 | ||
|
|
c22feee634 | ||
|
|
bcb971f930 | ||
|
|
f53faffb91 | ||
|
|
545a679aed | ||
|
|
2097c09a9b | ||
|
|
c24d047b9c | ||
|
|
6644d98d9e | ||
|
|
1f2e0df865 | ||
|
|
95f5b36772 | ||
|
|
4d1bb15e31 | ||
|
|
b8e302eb53 | ||
|
|
871f9979c6 | ||
|
|
efe06e1efd | ||
|
|
73eb306cfd | ||
|
|
9398bf946c | ||
|
|
5d1d69453a | ||
|
|
1a6d504a38 | ||
|
|
3f323a61fe | ||
|
|
d5da2f7b37 | ||
|
|
3a7abc2c77 | ||
|
|
0fd01780e9 | ||
|
|
df577886e4 | ||
|
|
8812ce7b27 | ||
|
|
4b2e21e7ee | ||
|
|
aa4a9c5250 | ||
|
|
3a8029f033 | ||
|
|
2a2487514a | ||
|
|
a630da6400 | ||
|
|
a6a5bb7c20 | ||
|
|
af94377667 | ||
|
|
0522725754 | ||
|
|
de11d82856 | ||
|
|
04a667b076 | ||
|
|
832fb114a7 | ||
|
|
94ccfa8c5d | ||
|
|
053980bb19 | ||
|
|
13740b7ed1 | ||
|
|
d9068ad5a1 | ||
|
|
e8adcf88cd | ||
|
|
91b8932eb1 | ||
|
|
59d18adc4c | ||
|
|
b17be7e14b | ||
|
|
c0430f42b8 | ||
|
|
6244e44999 | ||
|
|
752e598a16 | ||
|
|
e6ad2c8792 | ||
|
|
1355cfe131 | ||
|
|
4d27c96033 | ||
|
|
f79405b5e1 | ||
|
|
aaa1c3c400 | ||
|
|
ec86134a0d | ||
|
|
2fb1124b0f | ||
|
|
4408034bcd | ||
|
|
2f62b1299f | ||
|
|
62b427ec55 | ||
|
|
894031bbd9 | ||
|
|
5c4aeb779f | ||
|
|
5f56b28629 | ||
|
|
d299c28ecc | ||
|
|
3451c5a9b3 | ||
|
|
e5577d5541 | ||
|
|
b99c23af40 | ||
|
|
519365cfa5 | ||
|
|
8737e1ee20 | ||
|
|
fbfbf94deb | ||
|
|
d67cfd146a | ||
|
|
bd3bd83dda | ||
|
|
3b7925eb7d | ||
|
|
76160f784a | ||
|
|
2296647e01 | ||
|
|
249aff45c2 | ||
|
|
06d9156b8d | ||
|
|
ddbc4647fa | ||
|
|
dec289e821 | ||
|
|
26e0de41c3 | ||
|
|
2d9b9fecd5 | ||
|
|
be2fa90b94 | ||
|
|
84c3fb07b0 | ||
|
|
a925c32cca | ||
|
|
1a5364bd19 | ||
|
|
64ad448adc | ||
|
|
ca5884873e | ||
|
|
344888addd | ||
|
|
8857aeb223 | ||
|
|
5ec05f0a28 | ||
|
|
72e962cf55 | ||
|
|
6a76c60e6c | ||
|
|
e93e5349cb | ||
|
|
657cfe721b | ||
|
|
f285d4f4f3 | ||
|
|
bf3a0902ef | ||
|
|
9a189be740 | ||
|
|
9ff411f7f7 | ||
|
|
a381eb8ddb | ||
|
|
17616eac17 | ||
|
|
a584320357 | ||
|
|
5aef2c0d55 | ||
|
|
973800b52f | ||
|
|
d7f0287235 | ||
|
|
b37f09aa2e | ||
|
|
66fb32d267 | ||
|
|
485dda9774 | ||
|
|
d89d456655 | ||
|
|
c59b6f704c | ||
|
|
79706a8e48 | ||
|
|
2e8b33824f | ||
|
|
aca3f961db | ||
|
|
335e878be8 | ||
|
|
d12ea887bc | ||
|
|
d98beea894 | ||
|
|
198fd7b0bd | ||
|
|
0a4cb86976 | ||
|
|
57b7fe4e6f | ||
|
|
6f074b71bb | ||
|
|
f5f1878ba1 | ||
|
|
b26141e2c5 | ||
|
|
a2b6c1930d | ||
|
|
8bb5edc1c9 | ||
|
|
454bc86479 | ||
|
|
3a47bf7265 | ||
|
|
8203ec4b11 | ||
|
|
0b8e4738f9 | ||
|
|
d38e683a6f | ||
|
|
c3f140033c | ||
|
|
1c09a4adb2 | ||
|
|
a07dca7cd2 | ||
|
|
b7ebc662eb | ||
|
|
f30dabb2ac | ||
|
|
e2e5f5cd9d | ||
|
|
27b7f3b43a | ||
|
|
4b88647966 | ||
|
|
d43fd8a038 | ||
|
|
2abd56f428 | ||
|
|
1bf9b3b06f | ||
|
|
dfd059173d | ||
|
|
b931ed8563 | ||
|
|
88abf70386 | ||
|
|
5de8b54c51 | ||
|
|
f4f2987273 | ||
|
|
8f58d0dbc8 | ||
|
|
12e091842f | ||
|
|
81d3b1c825 | ||
|
|
32fb5dfef7 | ||
|
|
ca221e6c21 | ||
|
|
fe460d47b0 | ||
|
|
448b4516ff | ||
|
|
f684aec4f3 | ||
|
|
cbc920d474 | ||
|
|
b104df742d | ||
|
|
8e5aaada2e | ||
|
|
c1f74f152b | ||
|
|
279ab5e62f | ||
|
|
e1205e4d15 | ||
|
|
ea7cd31751 | ||
|
|
a79409afa9 | ||
|
|
dda48ccd0f | ||
|
|
f36b494aeb | ||
|
|
395c1f44bd | ||
|
|
411493b1f7 | ||
|
|
a14bf1946d | ||
|
|
8a9cad44a5 | ||
|
|
6665aca024 | ||
|
|
c993ac6932 | ||
|
|
a357424a25 | ||
|
|
5078a54b52 | ||
|
|
84711b18bc | ||
|
|
84778a5b46 | ||
|
|
3415b15a56 | ||
|
|
8314b7f5e6 | ||
|
|
32e94947dc | ||
|
|
b0ad55a08a | ||
|
|
87504abb07 | ||
|
|
789259d2e7 | ||
|
|
83b9f42796 | ||
|
|
ccd7fe8de5 | ||
|
|
2175c9dae1 | ||
|
|
10e135af70 | ||
|
|
4d9b223ac2 | ||
|
|
6696beed45 | ||
|
|
d787e00a3b | ||
|
|
e6e87891a9 | ||
|
|
930a07c3f5 | ||
|
|
0d0bd331ae | ||
|
|
5a3e82f9f5 | ||
|
|
9cbae55a6e | ||
|
|
cf7c1874fe | ||
|
|
47908a8907 | ||
|
|
8fd402bfcf | ||
|
|
d2e2cb0d27 | ||
|
|
98ba262a48 | ||
|
|
768b41017c | ||
|
|
bd7d9140f9 | ||
|
|
b1ca5eb58a | ||
|
|
f0b7952caa | ||
|
|
b1a657a00d | ||
|
|
d9711a5798 | ||
|
|
10abe4f26e | ||
|
|
84e7ad922b | ||
|
|
4698dd9a02 | ||
|
|
c90ea2bd6d | ||
|
|
fdec7fe203 | ||
|
|
18cb92ab18 | ||
|
|
86c0af514b | ||
|
|
2aadc8bb5b | ||
|
|
ae42d69d72 | ||
|
|
5284e1b60e | ||
|
|
05563e9ef2 | ||
|
|
458cf9070b | ||
|
|
245e1b4fdb | ||
|
|
87c1947d49 | ||
|
|
8b8d59eefb | ||
|
|
dbe79d3451 | ||
|
|
10152506fe | ||
|
|
aaac71d38f | ||
|
|
415535e47b | ||
|
|
3475caf8f5 | ||
|
|
f1307515b7 | ||
|
|
ab931be45b | ||
|
|
d9574c2f14 | ||
|
|
1d23c74361 | ||
|
|
0654e1c4ef | ||
|
|
ed4e8830d7 | ||
|
|
c9f70b381d | ||
|
|
b4671902f2 | ||
|
|
76e97c4002 | ||
|
|
1aefe491fb | ||
|
|
04a9217dcf | ||
|
|
fa446a563e | ||
|
|
2eb09b66ef | ||
|
|
80be6e69a9 | ||
|
|
009d5fb41f | ||
|
|
f86655fddd | ||
|
|
0ded557af6 | ||
|
|
72b9861635 | ||
|
|
5f88e8887a | ||
|
|
ddb68acebe | ||
|
|
2d96276e24 | ||
|
|
86c2bdfd5d | ||
|
|
cba3a1741a | ||
|
|
5568d82c26 | ||
|
|
1c0bf23ba2 | ||
|
|
8250760617 | ||
|
|
59948a6e1c | ||
|
|
55c43da5d8 | ||
|
|
809ee79592 | ||
|
|
629e37dde1 | ||
|
|
bc530fe89f | ||
|
|
fc73ad644f | ||
|
|
9c17a685bd | ||
|
|
986b5e257e | ||
|
|
97ee01ad89 | ||
|
|
d12e53ea09 | ||
|
|
8220180133 | ||
|
|
a206a23980 | ||
|
|
0a87c91692 | ||
|
|
865c3a2383 | ||
|
|
f03304a9c7 | ||
|
|
bdde31d787 | ||
|
|
0575c0a667 | ||
|
|
bfd471f53e | ||
|
|
6f8ba620c2 | ||
|
|
84d7c981dc | ||
|
|
24324d83e8 | ||
|
|
b7ccd48dd8 | ||
|
|
94073ecf7b | ||
|
|
776d0f3459 | ||
|
|
262430f705 | ||
|
|
e4ff4e6898 | ||
|
|
593f74b9cb | ||
|
|
298a771494 | ||
|
|
2d8b65e837 | ||
|
|
51d9b435cd | ||
|
|
f35e21e2e4 | ||
|
|
683bcb9154 | ||
|
|
11c570cfb4 | ||
|
|
c4679ad0f1 | ||
|
|
2f7a9997c8 | ||
|
|
8595d31ee8 | ||
|
|
026c5f7617 | ||
|
|
222e3de4be | ||
|
|
910bd45756 | ||
|
|
a0cd439788 | ||
|
|
838e8c9166 | ||
|
|
695aa2d5a2 | ||
|
|
e2a186af10 | ||
|
|
5d4b0c9026 | ||
|
|
461764cbbe | ||
|
|
de374ba6b1 | ||
|
|
3b8848fa4e | ||
|
|
3cac997e19 | ||
|
|
be7eecafd2 | ||
|
|
c891967b6f | ||
|
|
2ea321d85a | ||
|
|
c285051c08 | ||
|
|
2ce73dbe85 | ||
|
|
07c46dac87 | ||
|
|
d9c6b09ac4 | ||
|
|
2ea5fa0710 | ||
|
|
bcd88403e2 | ||
|
|
d1e4a866ad | ||
|
|
5cbf75324d | ||
|
|
2bda554be4 | ||
|
|
2fad3d34b7 | ||
|
|
cc8005b4e7 | ||
|
|
77cd030ac3 | ||
|
|
ed54768f5f | ||
|
|
83082f04a4 | ||
|
|
687c5ef794 | ||
|
|
103849419a | ||
|
|
7d5d89856d | ||
|
|
0a27bd065e | ||
|
|
1b5e57e935 | ||
|
|
b22c884231 | ||
|
|
a2ae4a8a0f | ||
|
|
dc8adc3b48 | ||
|
|
5ccee900a0 | ||
|
|
178152f604 | ||
|
|
369010406e | ||
|
|
a790fa46f4 | ||
|
|
6ce5af574f | ||
|
|
81b2d877fb | ||
|
|
3764c12b1f | ||
|
|
9b8eb4d690 | ||
|
|
8d13ca1f11 | ||
|
|
645cc8cf49 | ||
|
|
1c21b7943d | ||
|
|
172f006020 | ||
|
|
6aeb45187b | ||
|
|
a43a7dfa58 | ||
|
|
efae3da41d | ||
|
|
fe37c35018 | ||
|
|
4b36f34d6d | ||
|
|
3df62878c3 | ||
|
|
71cc095cb2 | ||
|
|
43e4a2a289 | ||
|
|
fdbf76d4f4 | ||
|
|
c8ad9b8375 | ||
|
|
41016bfc46 | ||
|
|
c39b06866e | ||
|
|
2323664a37 | ||
|
|
4968232490 | ||
|
|
00728c24e7 | ||
|
|
90e165aa0c | ||
|
|
7629d36a53 | ||
|
|
8555125a1a | ||
|
|
3f64753779 | ||
|
|
14002c8eba | ||
|
|
a2120986ff | ||
|
|
f1e1fb4bde | ||
|
|
8c9479c6bb | ||
|
|
6690680538 | ||
|
|
d743f03552 | ||
|
|
2742fdfda2 | ||
|
|
0a61b0df12 | ||
|
|
343328c6b8 | ||
|
|
d3631907d6 | ||
|
|
87cfcfd374 | ||
|
|
522dfe3422 | ||
|
|
c545563d46 | ||
|
|
7a37c906a1 | ||
|
|
5b721607b1 | ||
|
|
2ef9cfa5b8 | ||
|
|
7d7797b141 | ||
|
|
401926283a | ||
|
|
2201a0808e | ||
|
|
05454818dc | ||
|
|
43deefa435 | ||
|
|
21ca2d833b | ||
|
|
bb3fd02930 | ||
|
|
c923cdbd5b | ||
|
|
019b456605 | ||
|
|
7d489192fd | ||
|
|
44a0de1861 | ||
|
|
a01d5876fa | ||
|
|
15399da9fe | ||
|
|
6da916d4ac | ||
|
|
e540144b2e | ||
|
|
76793dc969 | ||
|
|
6ac7f9f144 | ||
|
|
08fee75201 | ||
|
|
85de7d7c0c | ||
|
|
d4c6b90ca3 | ||
|
|
4bd188c438 | ||
|
|
2d12315c94 | ||
|
|
7f71fd13ae | ||
|
|
01cd2fdaf3 | ||
|
|
819adfff6f | ||
|
|
f5d2bc8a36 | ||
|
|
9db7bf5f52 | ||
|
|
410b618d18 | ||
|
|
4287732797 | ||
|
|
0cff7a8aa7 | ||
|
|
fb83d28768 | ||
|
|
342e1b7338 | ||
|
|
c2fa70ddfd | ||
|
|
8a38d5663a | ||
|
|
dd9e71843b | ||
|
|
94cfec07fd | ||
|
|
e6b7ab5749 | ||
|
|
0c50722270 | ||
|
|
b34e8c3c36 | ||
|
|
2c06be915d | ||
|
|
73aa262647 | ||
|
|
6ff5f718b6 | ||
|
|
e1cb7ce017 | ||
|
|
01bed1828b | ||
|
|
a75560d828 | ||
|
|
ec82517c89 | ||
|
|
31ffe954b6 | ||
|
|
872d60f6e4 | ||
|
|
757f0769d8 | ||
|
|
17b2740289 | ||
|
|
f6f8237a74 | ||
|
|
0bd084011a | ||
|
|
2689f4d02b | ||
|
|
3dd20ff2f8 | ||
|
|
f79751c299 | ||
|
|
813505cc13 | ||
|
|
9f35575ca3 | ||
|
|
520f367319 | ||
|
|
b6dc3b517b | ||
|
|
f0c11b1917 | ||
|
|
40cd036941 | ||
|
|
793200e5e9 | ||
|
|
6966768a55 | ||
|
|
7d46f9250c | ||
|
|
3b7cd5d89a | ||
|
|
fe98cf8dc5 | ||
|
|
e96cd730d1 | ||
|
|
4110f33cde | ||
|
|
8e79c64750 | ||
|
|
05708fc63e | ||
|
|
9d2174b6f5 | ||
|
|
e8bff10f07 | ||
|
|
ae922a36a4 | ||
|
|
673a6d15d9 | ||
|
|
0bbc812f48 | ||
|
|
d01eaf0421 | ||
|
|
a30b56ebe7 | ||
|
|
8bd66202c3 | ||
|
|
6e5d67e827 | ||
|
|
f32339e700 | ||
|
|
20c6bfad1e | ||
|
|
c8063ff034 | ||
|
|
50d49d9c2e | ||
|
|
cefe611ce5 | ||
|
|
d882773789 | ||
|
|
a280b4e661 | ||
|
|
d77eac25b2 | ||
|
|
603c7ccea8 | ||
|
|
f077bc0f48 | ||
|
|
64f9370691 | ||
|
|
06c4716396 | ||
|
|
e2bf701454 | ||
|
|
8700fae12a | ||
|
|
c929529f9f | ||
|
|
340120853f | ||
|
|
6cc56d8e83 | ||
|
|
3c3fc50c79 | ||
|
|
2adc9062d8 | ||
|
|
6344edc36f | ||
|
|
6970bd96d1 | ||
|
|
445520bf38 | ||
|
|
d63b0adabd | ||
|
|
8efd8f7f47 | ||
|
|
bed3ad104e | ||
|
|
36bb88e1b9 | ||
|
|
dbe23aadae | ||
|
|
161c38ba60 | ||
|
|
a66d097cbe | ||
|
|
68b973a913 | ||
|
|
3ca507a6eb | ||
|
|
24ba1b64e9 | ||
|
|
c58e10565e | ||
|
|
6a4a35549b | ||
|
|
904ff7d07b | ||
|
|
e5681bb121 | ||
|
|
d0ac235c8f | ||
|
|
bed005b639 | ||
|
|
78c7bb8e26 | ||
|
|
f93d5f9ffe | ||
|
|
3b318ed095 | ||
|
|
2ca1758832 | ||
|
|
d9dac6772f | ||
|
|
1da44d2e96 | ||
|
|
5fe8bc0b4d | ||
|
|
42605ce8bc | ||
|
|
7a47324c78 | ||
|
|
124baa4ccb | ||
|
|
9c1e9f0b6a | ||
|
|
2d98de1b3a | ||
|
|
240f3fbe2f | ||
|
|
966cca4bd4 | ||
|
|
288424ad63 | ||
|
|
2cffa7ce31 | ||
|
|
91e615bfec | ||
|
|
d7d80a74d5 | ||
|
|
9a33582204 | ||
|
|
6557910ccf | ||
|
|
8a46ed83cc | ||
|
|
c2430126d7 | ||
|
|
5eede9d4d9 | ||
|
|
cb420a1dfc | ||
|
|
30158c77e9 | ||
|
|
0184604aaf | ||
|
|
ee618d7540 | ||
|
|
75199de534 | ||
|
|
6ff4388ffa | ||
|
|
c6ab3cf6d9 | ||
|
|
794298063d | ||
|
|
e480659765 | ||
|
|
bcd2714038 | ||
|
|
2b63e68bbf | ||
|
|
f3cd4206b8 | ||
|
|
5253d1ab77 | ||
|
|
cc4b78d59f | ||
|
|
64a474a49b | ||
|
|
297a50a063 | ||
|
|
c4319e678f | ||
|
|
7271c7ff35 | ||
|
|
c85dfb148a | ||
|
|
19765903dc | ||
|
|
98500d70a8 | ||
|
|
22f721dbf2 | ||
|
|
fa9dbd6b62 | ||
|
|
73278c0a16 | ||
|
|
75990a46a7 | ||
|
|
40d324f102 | ||
|
|
c41226d847 | ||
|
|
1c5d5e58c6 | ||
|
|
082e725b33 | ||
|
|
a43c00c569 | ||
|
|
53d508072b | ||
|
|
2939cab06d | ||
|
|
8be979d9ae | ||
|
|
9e56521b4b | ||
|
|
cb0f89646f | ||
|
|
80264be428 | ||
|
|
9a36562347 | ||
|
|
95d839f15c | ||
|
|
312c2c42b6 | ||
|
|
9228c53cf5 | ||
|
|
2da02dd774 | ||
|
|
2ed2b9a3e4 | ||
|
|
bd336ba272 | ||
|
|
25b12b8839 | ||
|
|
433fb54b25 | ||
|
|
0bbbee96b7 | ||
|
|
ba0909e96a | ||
|
|
658b5b414a | ||
|
|
70918a6645 | ||
|
|
e4db374421 | ||
|
|
01fe1d2137 | ||
|
|
31e6ea7f5d | ||
|
|
e9c2b5c84d | ||
|
|
158ea66c6c | ||
|
|
1a01afab23 | ||
|
|
85c33b9602 | ||
|
|
93cfb02acb | ||
|
|
fba4088941 | ||
|
|
f7d3cc0e58 | ||
|
|
e66ec79b18 | ||
|
|
99142385da | ||
|
|
e874738d3d | ||
|
|
8938414f0c | ||
|
|
ae3ae3df76 | ||
|
|
7be46ce487 | ||
|
|
fc0e97a70e | ||
|
|
cc0b4c3b62 | ||
|
|
6ccefea62a | ||
|
|
44e1254d1c | ||
|
|
5210998688 | ||
|
|
c199b8499d | ||
|
|
f13dff6977 | ||
|
|
f01a4ca4e2 | ||
|
|
75aa0fbf70 | ||
|
|
d1b70ffa03 | ||
|
|
e00d4805d7 | ||
|
|
edffb50b98 | ||
|
|
4405b78d60 |
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
src/*.exe
|
||||
src/bitcoin
|
||||
src/bitcoind
|
||||
.*.swp
|
||||
*.*~*
|
||||
*.bak
|
||||
*.rej
|
||||
*.orig
|
||||
*.o
|
||||
*.patch
|
||||
.bitcoin
|
||||
#compilation and Qt preprocessor part
|
||||
*.qm
|
||||
Makefile
|
||||
bitcoin-qt
|
||||
#resources cpp
|
||||
qrc_*.cpp
|
||||
#qt creator
|
||||
*.pro.user
|
||||
#mac specific
|
||||
.DS_Store
|
||||
@@ -1,19 +1,19 @@
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Copyright (c) 2009-2011 Bitcoin Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
9
INSTALL
Normal file
@@ -0,0 +1,9 @@
|
||||
Building Bitcoin
|
||||
|
||||
See doc/readme-qt.rst for instructions on building Bitcoin QT,
|
||||
the intended-for-end-users, nice-graphical-interface, reference
|
||||
implementation of Bitcoin.
|
||||
|
||||
See doc/build-*.txt for instructions on building bitcoind,
|
||||
the intended-for-services, no-graphical-interface, reference
|
||||
implementation of Bitcoin.
|
||||
42
README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
Bitcoin integration/staging tree
|
||||
|
||||
Development process
|
||||
===================
|
||||
|
||||
Developers work in their own trees, then submit pull requests when
|
||||
they think their feature or bug fix is ready.
|
||||
|
||||
If it is a simple/trivial/non-controversial change, then one of the
|
||||
bitcoin development team members simply pulls it.
|
||||
|
||||
If it is a more complicated or potentially controversial
|
||||
change, then the patch submitter will be asked to start a
|
||||
discussion (if they haven't already) on the mailing list:
|
||||
http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development
|
||||
|
||||
The patch will be accepted if there is broad consensus that it is a
|
||||
good thing. Developers should expect to rework and resubmit patches
|
||||
if they don't match the project's coding conventions (see coding.txt)
|
||||
or are controversial.
|
||||
|
||||
The master branch is regularly built and tested, but is not guaranteed
|
||||
to be completely stable. Tags are regularly created to indicate new
|
||||
official, stable release versions of Bitcoin. If you would like to
|
||||
help test the Bitcoin core, please contact QA@BitcoinTesting.org.
|
||||
|
||||
Feature branches are created when there are major new features being
|
||||
worked on by several people.
|
||||
|
||||
From time to time a pull request will become outdated. If this occurs, and
|
||||
the pull is no longer automatically mergeable; a comment on the pull will
|
||||
be used to issue a warning of closure. The pull will be closed 15 days
|
||||
after the warning if action is not taken by the author. Pull requests closed
|
||||
in this manner will have their corresponding issue labeled 'stagnant'.
|
||||
|
||||
Issues with no commits will be given a similar warning, and closed after
|
||||
15 days from their last activity. Issues closed in this manner will be
|
||||
labeled 'stale'.
|
||||
|
||||
Requests to reopen closed pull requests and/or issues can be submitted to
|
||||
QA@BitcoinTesting.org.
|
||||
201
base58.h
@@ -1,201 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
//
|
||||
// Why base-58 instead of standard base-64 encoding?
|
||||
// - Don't want 0OIl characters that look the same in some fonts and
|
||||
// could be used to create visually identical looking account numbers.
|
||||
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
// - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
|
||||
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
|
||||
inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn0 = 0;
|
||||
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
vector<unsigned char> vchTmp(pend-pbegin+1, 0);
|
||||
reverse_copy(pbegin, pend, vchTmp.begin());
|
||||
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn;
|
||||
bn.setvch(vchTmp);
|
||||
|
||||
// Convert bignum to string
|
||||
string str;
|
||||
str.reserve((pend - pbegin) * 138 / 100 + 1);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
while (bn > bn0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
|
||||
throw bignum_error("EncodeBase58 : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getulong();
|
||||
str += pszBase58[c];
|
||||
}
|
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
|
||||
str += pszBase58[0];
|
||||
|
||||
// Convert little endian string to big endian
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
inline string EncodeBase58(const vector<unsigned char>& vch)
|
||||
{
|
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size());
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
vchRet.clear();
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn = 0;
|
||||
CBigNum bnChar;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++)
|
||||
{
|
||||
const char* p1 = strchr(pszBase58, *p);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
bnChar.setulong(p1 - pszBase58);
|
||||
if (!BN_mul(&bn, &bn, &bn58, pctx))
|
||||
throw bignum_error("DecodeBase58 : BN_mul failed");
|
||||
bn += bnChar;
|
||||
}
|
||||
|
||||
// Get bignum as little endian data
|
||||
vector<unsigned char> vchTmp = bn.getvch();
|
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
|
||||
vchTmp.erase(vchTmp.end()-1);
|
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0;
|
||||
for (const char* p = psz; *p == pszBase58[0]; p++)
|
||||
nLeadingZeros++;
|
||||
vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
|
||||
|
||||
// Convert little endian data to big endian
|
||||
reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
|
||||
{
|
||||
// add 4-byte hash check to the end
|
||||
vector<unsigned char> vch(vchIn);
|
||||
uint256 hash = Hash(vch.begin(), vch.end());
|
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return EncodeBase58(vch);
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet)
|
||||
{
|
||||
if (!DecodeBase58(psz, vchRet))
|
||||
return false;
|
||||
if (vchRet.size() < 4)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
|
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
vchRet.resize(vchRet.size()-4);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58Check(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const unsigned char ADDRESSVERSION = 0;
|
||||
|
||||
inline string Hash160ToAddress(uint160 hash160)
|
||||
{
|
||||
// add 1-byte version number to the front
|
||||
vector<unsigned char> vch(1, ADDRESSVERSION);
|
||||
vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
|
||||
return EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
|
||||
{
|
||||
vector<unsigned char> vch;
|
||||
if (!DecodeBase58Check(psz, vch))
|
||||
return false;
|
||||
if (vch.empty())
|
||||
return false;
|
||||
unsigned char nVersion = vch[0];
|
||||
if (vch.size() != sizeof(hash160Ret) + 1)
|
||||
return false;
|
||||
memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
|
||||
return (nVersion <= ADDRESSVERSION);
|
||||
}
|
||||
|
||||
inline bool AddressToHash160(const string& str, uint160& hash160Ret)
|
||||
{
|
||||
return AddressToHash160(str.c_str(), hash160Ret);
|
||||
}
|
||||
|
||||
inline bool IsValidBitcoinAddress(const char* psz)
|
||||
{
|
||||
uint160 hash160;
|
||||
return AddressToHash160(psz, hash160);
|
||||
}
|
||||
|
||||
inline bool IsValidBitcoinAddress(const string& str)
|
||||
{
|
||||
return IsValidBitcoinAddress(str.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
return Hash160ToAddress(Hash160(vchPubKey));
|
||||
}
|
||||
276
bitcoin-qt.pro
Normal file
@@ -0,0 +1,276 @@
|
||||
TEMPLATE = app
|
||||
TARGET =
|
||||
VERSION = 0.5.0
|
||||
INCLUDEPATH += src src/json src/qt
|
||||
DEFINES += QT_GUI BOOST_THREAD_USE_LIB
|
||||
CONFIG += no_include_pwd
|
||||
|
||||
# for boost 1.37, add -mt to the boost libraries
|
||||
# use: qmake BOOST_LIB_SUFFIX=-mt
|
||||
# for boost thread win32 with _win32 sufix
|
||||
# use: BOOST_THREAD_LIB_SUFFIX=_win32-...
|
||||
# or when linking against a specific BerkelyDB version: BDB_LIB_SUFFIX=-4.8
|
||||
|
||||
# Dependency library locations can be customized with BOOST_INCLUDE_PATH,
|
||||
# BOOST_LIB_PATH, BDB_INCLUDE_PATH, BDB_LIB_PATH
|
||||
# OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively
|
||||
|
||||
OBJECTS_DIR = build
|
||||
MOC_DIR = build
|
||||
UI_DIR = build
|
||||
|
||||
# use: qmake "RELEASE=1"
|
||||
contains(RELEASE, 1) {
|
||||
# Mac: compile for maximum compatibility (10.5, 32-bit)
|
||||
macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk
|
||||
|
||||
!windows:!macx {
|
||||
# Linux: static link
|
||||
LIBS += -Wl,-Bstatic
|
||||
}
|
||||
}
|
||||
|
||||
# use: qmake "USE_UPNP=1" ( enabled by default; default)
|
||||
# or: qmake "USE_UPNP=0" (disabled by default)
|
||||
# or: qmake "USE_UPNP=-" (not supported)
|
||||
# miniupnpc (http://miniupnp.free.fr/files/) must be installed for support
|
||||
contains(USE_UPNP, -) {
|
||||
message(Building without UPNP support)
|
||||
} else {
|
||||
message(Building with UPNP support)
|
||||
count(USE_UPNP, 0) {
|
||||
USE_UPNP=1
|
||||
}
|
||||
DEFINES += USE_UPNP=$$USE_UPNP STATICLIB
|
||||
INCLUDEPATH += $$MINIUPNPC_INCLUDE_PATH
|
||||
LIBS += $$join(MINIUPNPC_LIB_PATH,,-L,) -lminiupnpc
|
||||
win32:LIBS += -liphlpapi
|
||||
}
|
||||
|
||||
# use: qmake "USE_DBUS=1"
|
||||
contains(USE_DBUS, 1) {
|
||||
message(Building with DBUS (Freedesktop notifications) support)
|
||||
DEFINES += USE_DBUS
|
||||
QT += dbus
|
||||
}
|
||||
|
||||
# use: qmake "USE_SSL=1"
|
||||
contains(USE_SSL, 1) {
|
||||
message(Building with SSL support for RPC)
|
||||
DEFINES += USE_SSL
|
||||
}
|
||||
|
||||
contains(BITCOIN_NEED_QT_PLUGINS, 1) {
|
||||
DEFINES += BITCOIN_NEED_QT_PLUGINS
|
||||
QTPLUGIN += qcncodecs qjpcodecs qtwcodecs qkrcodecs
|
||||
}
|
||||
|
||||
!windows {
|
||||
# for extra security against potential buffer overflows
|
||||
QMAKE_CXXFLAGS += -fstack-protector
|
||||
QMAKE_LFLAGS += -fstack-protector
|
||||
# do not enable this on windows, as it will result in a non-working executable!
|
||||
}
|
||||
|
||||
# disable quite some warnings because bitcoin core "sins" a lot
|
||||
QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wno-strict-aliasing -Wno-invalid-offsetof -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-char-subscripts -Wno-unused-value -Wno-sequence-point -Wno-parentheses -Wno-unknown-pragmas -Wno-switch
|
||||
|
||||
# Input
|
||||
DEPENDPATH += src/qt src src json/include
|
||||
HEADERS += src/qt/bitcoingui.h \
|
||||
src/qt/transactiontablemodel.h \
|
||||
src/qt/addresstablemodel.h \
|
||||
src/qt/optionsdialog.h \
|
||||
src/qt/sendcoinsdialog.h \
|
||||
src/qt/addressbookpage.h \
|
||||
src/qt/aboutdialog.h \
|
||||
src/qt/editaddressdialog.h \
|
||||
src/qt/bitcoinaddressvalidator.h \
|
||||
src/base58.h \
|
||||
src/bignum.h \
|
||||
src/util.h \
|
||||
src/uint256.h \
|
||||
src/serialize.h \
|
||||
src/strlcpy.h \
|
||||
src/main.h \
|
||||
src/net.h \
|
||||
src/key.h \
|
||||
src/db.h \
|
||||
src/script.h \
|
||||
src/noui.h \
|
||||
src/init.h \
|
||||
src/headers.h \
|
||||
src/irc.h \
|
||||
src/json/json_spirit_writer_template.h \
|
||||
src/json/json_spirit_writer.h \
|
||||
src/json/json_spirit_value.h \
|
||||
src/json/json_spirit_utils.h \
|
||||
src/json/json_spirit_stream_reader.h \
|
||||
src/json/json_spirit_reader_template.h \
|
||||
src/json/json_spirit_reader.h \
|
||||
src/json/json_spirit_error_position.h \
|
||||
src/json/json_spirit.h \
|
||||
src/qt/clientmodel.h \
|
||||
src/qt/guiutil.h \
|
||||
src/qt/transactionrecord.h \
|
||||
src/qt/guiconstants.h \
|
||||
src/qt/optionsmodel.h \
|
||||
src/qt/monitoreddatamapper.h \
|
||||
src/qtui.h \
|
||||
src/qt/transactiondesc.h \
|
||||
src/qt/transactiondescdialog.h \
|
||||
src/qt/bitcoinamountfield.h \
|
||||
src/wallet.h \
|
||||
src/keystore.h \
|
||||
src/qt/transactionfilterproxy.h \
|
||||
src/qt/transactionview.h \
|
||||
src/qt/walletmodel.h \
|
||||
src/bitcoinrpc.h \
|
||||
src/qt/overviewpage.h \
|
||||
src/qt/csvmodelwriter.h \
|
||||
src/crypter.h \
|
||||
src/qt/sendcoinsentry.h \
|
||||
src/qt/qvalidatedlineedit.h \
|
||||
src/qt/bitcoinunits.h \
|
||||
src/qt/qvaluecombobox.h \
|
||||
src/qt/askpassphrasedialog.h \
|
||||
src/protocol.h \
|
||||
src/qt/notificator.h
|
||||
|
||||
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||
src/qt/transactiontablemodel.cpp \
|
||||
src/qt/addresstablemodel.cpp \
|
||||
src/qt/optionsdialog.cpp \
|
||||
src/qt/sendcoinsdialog.cpp \
|
||||
src/qt/addressbookpage.cpp \
|
||||
src/qt/aboutdialog.cpp \
|
||||
src/qt/editaddressdialog.cpp \
|
||||
src/qt/bitcoinaddressvalidator.cpp \
|
||||
src/util.cpp \
|
||||
src/script.cpp \
|
||||
src/main.cpp \
|
||||
src/init.cpp \
|
||||
src/net.cpp \
|
||||
src/irc.cpp \
|
||||
src/db.cpp \
|
||||
src/json/json_spirit_writer.cpp \
|
||||
src/json/json_spirit_value.cpp \
|
||||
src/json/json_spirit_reader.cpp \
|
||||
src/qt/clientmodel.cpp \
|
||||
src/qt/guiutil.cpp \
|
||||
src/qt/transactionrecord.cpp \
|
||||
src/qt/optionsmodel.cpp \
|
||||
src/qt/monitoreddatamapper.cpp \
|
||||
src/qt/transactiondesc.cpp \
|
||||
src/qt/transactiondescdialog.cpp \
|
||||
src/qt/bitcoinstrings.cpp \
|
||||
src/qt/bitcoinamountfield.cpp \
|
||||
src/wallet.cpp \
|
||||
src/keystore.cpp \
|
||||
src/qt/transactionfilterproxy.cpp \
|
||||
src/qt/transactionview.cpp \
|
||||
src/qt/walletmodel.cpp \
|
||||
src/bitcoinrpc.cpp \
|
||||
src/qt/overviewpage.cpp \
|
||||
src/qt/csvmodelwriter.cpp \
|
||||
src/crypter.cpp \
|
||||
src/qt/sendcoinsentry.cpp \
|
||||
src/qt/qvalidatedlineedit.cpp \
|
||||
src/qt/bitcoinunits.cpp \
|
||||
src/qt/qvaluecombobox.cpp \
|
||||
src/qt/askpassphrasedialog.cpp \
|
||||
src/protocol.cpp \
|
||||
src/qt/notificator.cpp
|
||||
|
||||
RESOURCES += \
|
||||
src/qt/bitcoin.qrc
|
||||
|
||||
FORMS += \
|
||||
src/qt/forms/sendcoinsdialog.ui \
|
||||
src/qt/forms/addressbookpage.ui \
|
||||
src/qt/forms/aboutdialog.ui \
|
||||
src/qt/forms/editaddressdialog.ui \
|
||||
src/qt/forms/transactiondescdialog.ui \
|
||||
src/qt/forms/overviewpage.ui \
|
||||
src/qt/forms/sendcoinsentry.ui \
|
||||
src/qt/forms/askpassphrasedialog.ui
|
||||
|
||||
CODECFORTR = UTF-8
|
||||
|
||||
# for lrelease/lupdate
|
||||
# also add new translations to src/qt/bitcoin.qrc under translations/
|
||||
TRANSLATIONS = $$files(src/qt/locale/bitcoin_*.ts)
|
||||
|
||||
isEmpty(QMAKE_LRELEASE) {
|
||||
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe
|
||||
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
|
||||
}
|
||||
isEmpty(TS_DIR):TS_DIR = src/qt/locale
|
||||
# automatically build translations, so they can be included in resource file
|
||||
TSQM.name = lrelease ${QMAKE_FILE_IN}
|
||||
TSQM.input = TRANSLATIONS
|
||||
TSQM.output = $$TS_DIR/${QMAKE_FILE_BASE}.qm
|
||||
TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN}
|
||||
TSQM.CONFIG = no_link
|
||||
QMAKE_EXTRA_COMPILERS += TSQM
|
||||
PRE_TARGETDEPS += compiler_TSQM_make_all
|
||||
|
||||
# "Other files" to show in Qt Creator
|
||||
OTHER_FILES += \
|
||||
doc/*.rst doc/*.txt doc/README README.md
|
||||
|
||||
# platform specific defaults, if not overridden on command line
|
||||
isEmpty(BOOST_LIB_SUFFIX) {
|
||||
macx:BOOST_LIB_SUFFIX = -mt
|
||||
windows:BOOST_LIB_SUFFIX = -mgw44-mt-1_43
|
||||
}
|
||||
|
||||
isEmpty(BOOST_THREAD_LIB_SUFFIX) {
|
||||
BOOST_THREAD_LIB_SUFFIX = $$BOOST_LIB_SUFFIX
|
||||
}
|
||||
|
||||
isEmpty(BDB_LIB_PATH) {
|
||||
macx:BDB_LIB_PATH = /opt/local/lib/db48
|
||||
}
|
||||
|
||||
isEmpty(BDB_LIB_SUFFIX) {
|
||||
macx:BDB_LIB_SUFFIX = -4.8
|
||||
}
|
||||
|
||||
isEmpty(BDB_INCLUDE_PATH) {
|
||||
macx:BDB_INCLUDE_PATH = /opt/local/include/db48
|
||||
}
|
||||
|
||||
isEmpty(BOOST_LIB_PATH) {
|
||||
macx:BOOST_LIB_PATH = /opt/local/lib
|
||||
}
|
||||
|
||||
isEmpty(BOOST_INCLUDE_PATH) {
|
||||
macx:BOOST_INCLUDE_PATH = /opt/local/include
|
||||
}
|
||||
|
||||
windows:LIBS += -lws2_32 -lgdi32
|
||||
windows:DEFINES += WIN32
|
||||
windows:RC_FILE = src/qt/res/bitcoin-qt.rc
|
||||
|
||||
macx:HEADERS += src/qt/macdockiconhandler.h
|
||||
macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm
|
||||
macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
|
||||
macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3
|
||||
macx:ICON = src/qt/res/icons/bitcoin.icns
|
||||
macx:TARGET = "Bitcoin-Qt"
|
||||
|
||||
# Set libraries and includes at end, to use platform-defined defaults if not overridden
|
||||
INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH
|
||||
LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,)
|
||||
LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX
|
||||
LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX
|
||||
|
||||
contains(RELEASE, 1) {
|
||||
!windows:!macx {
|
||||
# Linux: turn dynamic linking back on for c/c++ runtime libraries
|
||||
LIBS += -Wl,-Bdynamic
|
||||
}
|
||||
}
|
||||
|
||||
system($$QMAKE_LRELEASE -silent $$_PRO_FILE_)
|
||||
2
bugs.txt
@@ -1,2 +0,0 @@
|
||||
Known bugs:
|
||||
- Window flickers when blocks are added (problem with repainting?)
|
||||
@@ -1,91 +0,0 @@
|
||||
Bitcoin v0.2.0 BETA
|
||||
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com).
|
||||
|
||||
|
||||
WINDOWS BUILD NOTES
|
||||
===================
|
||||
|
||||
Compilers Supported
|
||||
-------------------
|
||||
MinGW GCC
|
||||
Microsoft Visual C++ 6.0 SP6
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
Libraries you need to download separately and build:
|
||||
|
||||
default path download
|
||||
wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/
|
||||
or prebuilt: http://wxpack.sourceforge.net
|
||||
OpenSSL \openssl http://www.openssl.org/source/
|
||||
Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||
Boost \boost http://www.boost.org/users/download/
|
||||
|
||||
Their licenses:
|
||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||
OpenSSL Old BSD license with the problematic advertising requirement
|
||||
Berkeley DB New BSD license with additional requirement that linked software must be free open source
|
||||
Boost MIT-like license
|
||||
|
||||
Versions used in this release:
|
||||
MinGW GCC 3.4.5
|
||||
wxWidgets 2.8.9
|
||||
OpenSSL 0.9.8k
|
||||
Berkeley DB 4.7.25.NC
|
||||
Boost 1.34.1
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
The UI layout is edited with wxFormBuilder. The project file is
|
||||
uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
|
||||
classes that do the rote work of constructing all the UI elements.
|
||||
|
||||
The release is built with GCC and then "strip bitcoin.exe" to strip the debug
|
||||
symbols, which reduces the executable size by about 90%.
|
||||
|
||||
|
||||
OpenSSL
|
||||
-------
|
||||
Bitcoin does not use any encryption. If you want to do a no-everything
|
||||
build of OpenSSL to exclude encryption routines, a few patches are required.
|
||||
(instructions for OpenSSL v0.9.8k)
|
||||
|
||||
Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around
|
||||
the openssl/rsa.h include:
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
Edit ms\mingw32.bat and replace the Configure line's parameters with this
|
||||
no-everything list. You have to put this in the batch file because batch
|
||||
files can't take more than nine command line parameters.
|
||||
perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh
|
||||
|
||||
Also REM out the following line in ms\mingw32.bat after the mingw32-make
|
||||
line. The build fails after it's already finished building libeay32, which
|
||||
is all we care about, but the failure aborts the script before it runs
|
||||
dllwrap to generate libeay32.dll.
|
||||
REM if errorlevel 1 goto end
|
||||
|
||||
Build
|
||||
cd \openssl
|
||||
ms\mingw32.bat
|
||||
|
||||
If you want to use it with MSVC, generate the .lib file
|
||||
lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib
|
||||
|
||||
|
||||
Berkeley DB
|
||||
-----------
|
||||
Using MinGW and MSYS:
|
||||
cd \db\build_unix
|
||||
sh ../dist/configure --enable-mingw --enable-cxx
|
||||
make
|
||||
@@ -1,67 +0,0 @@
|
||||
Bitcoin v0.2.0 BETA
|
||||
|
||||
Copyright (c) 2009 Satoshi Nakamoto
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com).
|
||||
|
||||
|
||||
UNIX BUILD NOTES
|
||||
================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
apt-get install build-essential
|
||||
apt-get install libgtk2.0-dev
|
||||
apt-get install libssl-dev
|
||||
apt-get install libdb4.7-dev
|
||||
apt-get install libdb4.7++-dev
|
||||
apt-get install libboost-dev
|
||||
|
||||
You need to download wxWidgets from http://www.wxwidgets.org/downloads/
|
||||
and build it yourself.
|
||||
|
||||
Licenses of statically linked libraries:
|
||||
wxWidgets LGPL 2.1 with very liberal exceptions
|
||||
Berkeley DB New BSD license with additional requirement that linked software must be free open source
|
||||
Boost MIT-like license
|
||||
|
||||
Versions used in this release:
|
||||
GCC 4.3.3
|
||||
OpenSSL 0.9.8k
|
||||
wxWidgets 2.8.9
|
||||
Berkeley DB 4.7.25.NC
|
||||
Boost 1.40.0
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
The UI layout is edited with wxFormBuilder. The project file is
|
||||
uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
|
||||
classes that do the rote work of constructing all the UI elements.
|
||||
|
||||
The release is built with GCC and then "strip bitcoin" to strip the debug
|
||||
symbols, which reduces the executable size by about 90%.
|
||||
|
||||
|
||||
wxWidgets
|
||||
---------
|
||||
cd /usr/local/wxWidgets-2.8.9
|
||||
mkdir buildgtk
|
||||
cd buildgtk
|
||||
../configure --with-gtk --enable-debug --disable-shared --enable-monolithic
|
||||
make
|
||||
su
|
||||
make install
|
||||
ldconfig
|
||||
|
||||
|
||||
Boost
|
||||
-----
|
||||
If you want to build Boost yourself,
|
||||
cd /usr/local/boost_1_40_0
|
||||
su
|
||||
./bootstrap.sh
|
||||
./bjam install
|
||||
@@ -1,7 +0,0 @@
|
||||
Changes after 0.1.5:
|
||||
--------------------
|
||||
+ Options dialog layout changed - added the UI options panel
|
||||
+ Minimize to tray feature
|
||||
+ Startup on system boot feature
|
||||
+ Ask before closing
|
||||
+ NSIS installer
|
||||
324
contrib/bitrpc/bitrpc.py
Normal file
@@ -0,0 +1,324 @@
|
||||
from jsonrpc import ServiceProxy
|
||||
import sys
|
||||
import string
|
||||
|
||||
# ===== BEGIN USER SETTINGS =====
|
||||
# if you do not set these you will be prompted for a password for every command
|
||||
rpcuser = ""
|
||||
rpcpass = ""
|
||||
# ====== END USER SETTINGS ======
|
||||
|
||||
|
||||
if rpcpass == "":
|
||||
access = ServiceProxy("http://127.0.0.1:8332")
|
||||
else:
|
||||
access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332")
|
||||
cmd = sys.argv[1].lower()
|
||||
|
||||
if cmd == "backupwallet":
|
||||
try:
|
||||
path = raw_input("Enter destination path/filename: ")
|
||||
print access.backupwallet(path)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getaccount":
|
||||
try:
|
||||
addr = raw_input("Enter a Bitcoin address: ")
|
||||
print access.getaccount(addr)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getaccountaddress":
|
||||
try:
|
||||
acct = raw_input("Enter an account name: ")
|
||||
print access.getaccountaddress(acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getaddressesbyaccount":
|
||||
try:
|
||||
acct = raw_input("Enter an account name: ")
|
||||
print access.getaddressesbyaccount(acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getbalance":
|
||||
try:
|
||||
acct = raw_input("Enter an account (optional): ")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
try:
|
||||
print access.getbalance(acct, mc)
|
||||
except:
|
||||
print access.getbalance()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getblockbycount":
|
||||
try:
|
||||
height = raw_input("Height: ")
|
||||
print access.getblockbycount(height)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getblockcount":
|
||||
try:
|
||||
print access.getblockcount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getblocknumber":
|
||||
try:
|
||||
print access.getblocknumber()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getconnectioncount":
|
||||
try:
|
||||
print access.getconnectioncount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getdifficulty":
|
||||
try:
|
||||
print access.getdifficulty()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getgenerate":
|
||||
try:
|
||||
print access.getgenerate()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "gethashespersec":
|
||||
try:
|
||||
print access.gethashespersec()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getinfo":
|
||||
try:
|
||||
print access.getinfo()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getnewaddress":
|
||||
try:
|
||||
acct = raw_input("Enter an account name: ")
|
||||
try:
|
||||
print access.getnewaddress(acct)
|
||||
except:
|
||||
print access.getnewaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getreceivedbyaccount":
|
||||
try:
|
||||
acct = raw_input("Enter an account (optional): ")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
try:
|
||||
print access.getreceivedbyaccount(acct, mc)
|
||||
except:
|
||||
print access.getreceivedbyaccount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getreceivedbyaddress":
|
||||
try:
|
||||
addr = raw_input("Enter a Bitcoin address (optional): ")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
try:
|
||||
print access.getreceivedbyaddress(addr, mc)
|
||||
except:
|
||||
print access.getreceivedbyaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "gettransaction":
|
||||
try:
|
||||
txid = raw_input("Enter a transaction ID: ")
|
||||
print access.gettransaction(txid)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "getwork":
|
||||
try:
|
||||
data = raw_input("Data (optional): ")
|
||||
try:
|
||||
print access.gettransaction(data)
|
||||
except:
|
||||
print access.gettransaction()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "help":
|
||||
try:
|
||||
cmd = raw_input("Command (optional): ")
|
||||
try:
|
||||
print access.help(cmd)
|
||||
except:
|
||||
print access.help()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "listaccounts":
|
||||
try:
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
try:
|
||||
print access.listaccounts(mc)
|
||||
except:
|
||||
print access.listaccounts()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "listreceivedbyaccount":
|
||||
try:
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
incemp = raw_input("Include empty? (true/false, optional): ")
|
||||
try:
|
||||
print access.listreceivedbyaccount(mc, incemp)
|
||||
except:
|
||||
print access.listreceivedbyaccount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "listreceivedbyaddress":
|
||||
try:
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
incemp = raw_input("Include empty? (true/false, optional): ")
|
||||
try:
|
||||
print access.listreceivedbyaddress(mc, incemp)
|
||||
except:
|
||||
print access.listreceivedbyaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "listtransactions":
|
||||
try:
|
||||
acct = raw_input("Account (optional): ")
|
||||
count = raw_input("Number of transactions (optional): ")
|
||||
frm = raw_input("Skip (optional):")
|
||||
try:
|
||||
print access.listtransactions(acct, count, frm)
|
||||
except:
|
||||
print access.listtransactions()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "move":
|
||||
try:
|
||||
frm = raw_input("From: ")
|
||||
to = raw_input("To: ")
|
||||
amt = raw_input("Amount:")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
comment = raw_input("Comment (optional): ")
|
||||
try:
|
||||
print access.move(frm, to, amt, mc, comment)
|
||||
except:
|
||||
print access.move(frm, to, amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "sendfrom":
|
||||
try:
|
||||
frm = raw_input("From: ")
|
||||
to = raw_input("To: ")
|
||||
amt = raw_input("Amount:")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
comment = raw_input("Comment (optional): ")
|
||||
commentto = raw_input("Comment-to (optional): ")
|
||||
try:
|
||||
print access.sendfrom(frm, to, amt, mc, comment, commentto)
|
||||
except:
|
||||
print access.sendfrom(frm, to, amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "sendmany":
|
||||
try:
|
||||
frm = raw_input("From: ")
|
||||
to = raw_input("To (in format address1:amount1,address2:amount2,...): ")
|
||||
mc = raw_input("Minimum confirmations (optional): ")
|
||||
comment = raw_input("Comment (optional): ")
|
||||
try:
|
||||
print access.sendmany(frm,to,mc,comment)
|
||||
except:
|
||||
print access.sendmany(frm,to)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "sendtoaddress":
|
||||
try:
|
||||
to = raw_input("To (in format address1:amount1,address2:amount2,...): ")
|
||||
amt = raw_input("Amount:")
|
||||
comment = raw_input("Comment (optional): ")
|
||||
commentto = raw_input("Comment-to (optional): ")
|
||||
try:
|
||||
print access.sendtoaddress(to,amt,comment,commentto)
|
||||
except:
|
||||
print access.sendtoaddress(to,amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "setaccount":
|
||||
try:
|
||||
addr = raw_input("Address: ")
|
||||
acct = raw_input("Account:")
|
||||
print access.setaccount(addr,acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "setgenerate":
|
||||
try:
|
||||
gen= raw_input("Generate? (true/false): ")
|
||||
cpus = raw_input("Max processors/cores (-1 for unlimited, optional):")
|
||||
try:
|
||||
print access.setgenerate(gen, cpus)
|
||||
except:
|
||||
print access.setgenerate(gen)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "settxfee":
|
||||
try:
|
||||
amt = raw_input("Amount:")
|
||||
print access.settxfee(amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "stop":
|
||||
try:
|
||||
print access.stop()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "validateaddress":
|
||||
try:
|
||||
addr = raw_input("Address: ")
|
||||
print access.validateaddress(addr)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "walletpassphrase":
|
||||
try:
|
||||
pwd = raw_input("Enter wallet passphrase: ")
|
||||
access.walletpassphrase(pwd, 60)
|
||||
print "\n---Wallet unlocked---\n"
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
elif cmd == "walletpassphrasechange":
|
||||
try:
|
||||
pwd = raw_input("Enter old wallet passphrase: ")
|
||||
pwd2 = raw_input("Enter new wallet passphrase: ")
|
||||
access.walletpassphrasechange(pwd, pwd2)
|
||||
print
|
||||
print "\n---Passphrase changed---\n"
|
||||
except:
|
||||
print
|
||||
print "\n---An error occurred---\n"
|
||||
print
|
||||
|
||||
else:
|
||||
print "Command not found or not supported"
|
||||
31
contrib/gitian-descriptors/README
Normal file
@@ -0,0 +1,31 @@
|
||||
Gavin's notes on getting gitian builds up and running:
|
||||
|
||||
You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization.
|
||||
|
||||
You probably need to enable hardware virtualization in your machine's BIOS.
|
||||
|
||||
You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites:
|
||||
sudo apt-get install apache2 git apt-cacher-ng python-vm-builder qemu-kvm
|
||||
|
||||
Sanity checks:
|
||||
sudo service apt-cacher-ng status # Should return apt-cacher-ng is running
|
||||
ls -l /dev/kvm # Should show a /dev/kvm device
|
||||
|
||||
Once you've got the right hardware and software:
|
||||
|
||||
git clone git://github.com/bitcoin/bitcoin.git
|
||||
git clone git://github.com/devrandom/gitian-builder.git
|
||||
mkdir gitian-builder/inputs
|
||||
wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' -O gitian-builder/inputs/miniupnpc-1.6.tar.gz
|
||||
|
||||
cd gitian-builder
|
||||
bin/make-base-vm --arch i386
|
||||
bin/make-base-vm --arch amd64
|
||||
cd ..
|
||||
|
||||
# To build
|
||||
cd bitcoin
|
||||
git pull
|
||||
cd ../gitian-builder
|
||||
git pull
|
||||
./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian.yml
|
||||
38
contrib/gitian-descriptors/boost-win32.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: "boost"
|
||||
suites:
|
||||
- "lucid"
|
||||
architectures:
|
||||
- "i386"
|
||||
packages:
|
||||
- "mingw32"
|
||||
- "faketime"
|
||||
- "zip"
|
||||
reference_datetime: "2011-01-30 00:00:00"
|
||||
remotes: []
|
||||
files:
|
||||
- "boost_1_47_0.tar.bz2"
|
||||
script: |
|
||||
TMPDIR="$HOME/tmpdir"
|
||||
mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include
|
||||
tar xjf boost_1_47_0.tar.bz2
|
||||
cd boost_1_47_0
|
||||
echo "using gcc : 4.4 : i586-mingw32msvc-g++
|
||||
:
|
||||
<rc>i586-mingw32msvc-windres
|
||||
<archiver>i586-mingw32msvc-ar
|
||||
<cxxflags>-frandom-seed=boost1
|
||||
;" > user-config.jam
|
||||
./bootstrap.sh --without-icu
|
||||
./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi variant=release link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage
|
||||
for lib in chrono date_time exception filesystem graph iostreams math_c99f math_c99l math_c99 math_tr1f math_tr1l math_tr1 prg_exec_monitor program_options random regex serialization signals system test_exec_monitor thread_win32 unit_test_framework wave wserialization; do
|
||||
mkdir $lib
|
||||
(cd $lib ; ar xf ../stage/lib/libboost_${lib}-mt-s.a)
|
||||
mv $lib $TMPDIR/bin/$GBUILD_BITS
|
||||
done
|
||||
cp -a boost $TMPDIR/include
|
||||
cd $TMPDIR
|
||||
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
|
||||
export FAKETIME=$REFERENCE_DATETIME
|
||||
zip -r boost-win32-1.47.0-gitian.zip *
|
||||
cp boost-win32-1.47.0-gitian.zip $OUTDIR
|
||||
88
contrib/gitian-descriptors/gitian-win32.yml
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: "bitcoin"
|
||||
suites:
|
||||
- "lucid"
|
||||
architectures:
|
||||
- "i386"
|
||||
packages:
|
||||
- "mingw32"
|
||||
- "git-core"
|
||||
- "unzip"
|
||||
- "nsis"
|
||||
- "faketime"
|
||||
- "wine"
|
||||
reference_datetime: "2011-01-30 00:00:00"
|
||||
remotes:
|
||||
- "url": "https://github.com/bitcoin/bitcoin.git"
|
||||
"dir": "bitcoin"
|
||||
files:
|
||||
- "qt-win32-4.7.4-gitian.zip"
|
||||
- "boost-win32-1.47.0-gitian.zip"
|
||||
- "openssl-1.0.0e.tar.gz"
|
||||
- "db-4.8.30.NC.tar.gz"
|
||||
- "miniupnpc-1.6.tar.gz"
|
||||
script: |
|
||||
#
|
||||
mkdir $HOME/qt
|
||||
cd $HOME/qt
|
||||
unzip ../build/qt-win32-4.7.4-gitian.zip
|
||||
cd $HOME/build/
|
||||
export PATH=$PATH:$HOME/qt/bin/
|
||||
#
|
||||
mkdir boost_1_47_0
|
||||
cd boost_1_47_0
|
||||
mkdir -p stage/lib
|
||||
unzip ../boost-win32-1.47.0-gitian.zip
|
||||
cd bin/$GBUILD_BITS
|
||||
for lib in *; do
|
||||
i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o
|
||||
i586-mingw32msvc-ranlib ../../stage/lib/libboost_${lib}-mt-s.a
|
||||
done
|
||||
cd ../..
|
||||
mv include/boost .
|
||||
cd ..
|
||||
#
|
||||
tar xzf openssl-1.0.0e.tar.gz
|
||||
cd openssl-1.0.0e
|
||||
./Configure --cross-compile-prefix=i586-mingw32msvc- mingw
|
||||
make
|
||||
cd ..
|
||||
#
|
||||
tar xzf db-4.8.30.NC.tar.gz
|
||||
cd db-4.8.30.NC/build_unix
|
||||
../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include"
|
||||
make $MAKEOPTS
|
||||
cd ../..
|
||||
#
|
||||
tar xzf miniupnpc-1.6.tar.gz
|
||||
cd miniupnpc-1.6
|
||||
sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw
|
||||
sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw
|
||||
make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar
|
||||
cd ..
|
||||
mv miniupnpc-1.6 miniupnpc
|
||||
#
|
||||
cd bitcoin
|
||||
mkdir -p $OUTDIR/src
|
||||
cp -a . $OUTDIR/src
|
||||
rm -rf $OUTDIR/src/.git
|
||||
cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt
|
||||
cp $OUTDIR/src/COPYING $OUTDIR/license.txt
|
||||
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
|
||||
export FAKETIME=$REFERENCE_DATETIME
|
||||
export TZ=UTC
|
||||
$HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.0e OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.0e/include INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin
|
||||
make $MAKEOPTS
|
||||
cp release/bitcoin-qt.exe $OUTDIR/
|
||||
#
|
||||
cd src
|
||||
sed 's/$(DEBUGFLAGS)/-frandom-seed=bitcoin/' -i makefile.linux-mingw
|
||||
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
|
||||
export FAKETIME=$REFERENCE_DATETIME
|
||||
export TZ=UTC
|
||||
make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0
|
||||
i586-mingw32msvc-strip bitcoind.exe
|
||||
makensis ../share/setup.nsi
|
||||
cp ../share/bitcoin-*-win32-setup.exe $OUTDIR/
|
||||
mkdir $OUTDIR/daemon
|
||||
cp bitcoind.exe $OUTDIR/daemon
|
||||
48
contrib/gitian-descriptors/gitian.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: "bitcoin"
|
||||
suites:
|
||||
- "lucid"
|
||||
architectures:
|
||||
- "i386"
|
||||
- "amd64"
|
||||
packages:
|
||||
- "libdb4.8++-dev"
|
||||
- "qt4-qmake"
|
||||
- "libqt4-dev"
|
||||
- "libboost-system-dev"
|
||||
- "libboost-filesystem-dev"
|
||||
- "libboost-program-options-dev"
|
||||
- "libboost-thread-dev"
|
||||
- "libssl-dev"
|
||||
- "git-core"
|
||||
- "unzip"
|
||||
reference_datetime: "2011-01-30 00:00:00"
|
||||
remotes:
|
||||
- "url": "https://github.com/bitcoin/bitcoin.git"
|
||||
"dir": "bitcoin"
|
||||
files:
|
||||
- "miniupnpc-1.6.tar.gz"
|
||||
script: |
|
||||
INSTDIR="$HOME/install"
|
||||
export LIBRARY_PATH="$INSTDIR/lib"
|
||||
#
|
||||
tar xzf miniupnpc-1.6.tar.gz
|
||||
cd miniupnpc-1.6
|
||||
INSTALLPREFIX=$INSTDIR make $MAKEOPTS install
|
||||
cd ..
|
||||
#
|
||||
cd bitcoin
|
||||
mkdir -p $OUTDIR/src
|
||||
cp -a . $OUTDIR/src
|
||||
rm -rf $OUTDIR/src/.git
|
||||
cp $OUTDIR/src/doc/README $OUTDIR
|
||||
cp $OUTDIR/src/COPYING $OUTDIR
|
||||
cd src
|
||||
sed 's/$(DEBUGFLAGS)//' -i makefile.unix
|
||||
make -f makefile.unix STATIC=1 DEFS="-I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0
|
||||
mkdir -p $OUTDIR/bin/$GBUILD_BITS
|
||||
install -s bitcoind $OUTDIR/bin/$GBUILD_BITS
|
||||
cd ..
|
||||
qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1
|
||||
make $MAKEOPTS
|
||||
install bitcoin-qt $OUTDIR/bin/$GBUILD_BITS
|
||||
54
contrib/gitian-descriptors/qt-win32.yml
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: "qt"
|
||||
suites:
|
||||
- "lucid"
|
||||
architectures:
|
||||
- "i386"
|
||||
packages:
|
||||
- "mingw32"
|
||||
- "zip"
|
||||
- "faketime"
|
||||
reference_datetime: "2011-01-30 00:00:00"
|
||||
remotes: []
|
||||
files:
|
||||
- "qt-everywhere-opensource-src-4.7.4.tar.gz"
|
||||
script: |
|
||||
INSTDIR="$HOME/qt/"
|
||||
mkdir $INSTDIR
|
||||
SRCDIR="$INSTDIR/src/"
|
||||
mkdir $SRCDIR
|
||||
#
|
||||
tar xzf qt-everywhere-opensource-src-4.7.4.tar.gz
|
||||
cd qt-everywhere-opensource-src-4.7.4
|
||||
sed 's/$TODAY/2011-01-30/' -i configure
|
||||
sed 's/i686-pc-mingw32-/i586-mingw32msvc-/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed --posix 's|QMAKE_CFLAGS\t\t= -pipe|QMAKE_CFLAGS\t\t= -pipe -isystem /usr/i586-mingw32msvc/include/ -frandom-seed=qtbuild|' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed 's/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed 's/QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads/QMAKE_LFLAGS_EXCEPTIONS_ON = -lmingwthrd/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed --posix 's/QMAKE_MOC\t\t= i586-mingw32msvc-moc/QMAKE_MOC\t\t= moc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed --posix 's/QMAKE_RCC\t\t= i586-mingw32msvc-rcc/QMAKE_RCC\t\t= rcc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
sed --posix 's/QMAKE_UIC\t\t= i586-mingw32msvc-uic/QMAKE_UIC\t\t= uic/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
# ar adds timestamps to every object file included in the static library
|
||||
# providing -D as ar argument is supposed to solve it, but doesn't work as qmake strips off the arguments and adds -M to pass a script...
|
||||
# which somehow cannot be combined with other flags.
|
||||
# use faketime only for ar, as it confuses make/qmake into hanging sometimes
|
||||
sed --posix "s|QMAKE_LIB\t\t= i586-mingw32msvc-ar -ru|QMAKE_LIB\t\t= $HOME/ar -Dr|" -i mkspecs/unsupported/win32-g++-cross/qmake.conf
|
||||
echo '#!/bin/bash' > $HOME/ar
|
||||
echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar
|
||||
echo 'i586-mingw32msvc-ar "$@"' >> $HOME/ar
|
||||
chmod +x $HOME/ar
|
||||
#export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
|
||||
export FAKETIME=$REFERENCE_DATETIME
|
||||
export TZ=UTC
|
||||
./configure -prefix $INSTDIR -confirm-license -release -opensource -static -no-qt3support -xplatform unsupported/win32-g++-cross -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -opengl no -nomake examples -nomake demos -nomake docs
|
||||
find . -name *.prl | xargs -l sed 's|/\.||' -i
|
||||
find . -name *.prl | xargs -l sed 's|/$||' -i
|
||||
make $MAKEOPTS install
|
||||
cp -a bin $SRCDIR/
|
||||
cd $INSTDIR
|
||||
find . -name *.prl | xargs -l sed 's|/$||' -i
|
||||
#sed 's|QMAKE_PRL_LIBS.*|QMAKE_PRL_LIBS = -lQtDeclarative -lQtScript -lQtSvg -lQtSql -lQtXmlPatterns -lQtGui -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lmsimg32 -lQtNetwork -lQtCore -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32|' -i imports/Qt/labs/particles/qmlparticlesplugin.prl
|
||||
|
||||
# as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date
|
||||
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
|
||||
zip -r $OUTDIR/qt-win32-4.7.4-gitian.zip *
|
||||
BIN
contrib/gitian-downloader/bluematt-key.pgp
Normal file
BIN
contrib/gitian-downloader/devrandom-key.pgp
Normal file
BIN
contrib/gitian-downloader/gavinandresen-key.pgp
Normal file
30
contrib/gitian-downloader/linux-download-config
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: bitcoin
|
||||
urls:
|
||||
- http://bitcoin.org/bitcoin-latest-linux-gitian.zip
|
||||
rss:
|
||||
- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
|
||||
xpath: //item/link/text()
|
||||
pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip
|
||||
signers:
|
||||
0A82509767C7D4A5D14DA2301AE1D35043E08E54:
|
||||
weight: 40
|
||||
name: BlueMatt
|
||||
key: bluematt
|
||||
BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
|
||||
weight: 40
|
||||
name: Devrandom
|
||||
key: devrandom
|
||||
D762373D24904A3E42F33B08B9A408E71DAAC974:
|
||||
weight: 40
|
||||
name: Sipa
|
||||
key: sipa
|
||||
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
|
||||
weight: 40
|
||||
name: tcatm
|
||||
key: tcatm
|
||||
01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
|
||||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
minimum_weight: 120
|
||||
BIN
contrib/gitian-downloader/sipa-key.pgp
Normal file
BIN
contrib/gitian-downloader/tcatm-key.pgp
Normal file
30
contrib/gitian-downloader/win32-download-config
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: bitcoin
|
||||
urls:
|
||||
- http://bitcoin.org/bitcoin-latest-win32-gitian.zip
|
||||
rss:
|
||||
- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
|
||||
xpath: //item/link/text()
|
||||
pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip
|
||||
signers:
|
||||
0A82509767C7D4A5D14DA2301AE1D35043E08E54:
|
||||
weight: 40
|
||||
name: BlueMatt
|
||||
key: bluematt
|
||||
BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
|
||||
weight: 40
|
||||
name: Devrandom
|
||||
key: devrandom
|
||||
D762373D24904A3E42F33B08B9A408E71DAAC974:
|
||||
weight: 40
|
||||
name: Sipa
|
||||
key: sipa
|
||||
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
|
||||
weight: 40
|
||||
name: tcatm
|
||||
key: tcatm
|
||||
01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
|
||||
weight: 40
|
||||
name: "Gavin Andresen"
|
||||
key: gavinandresen
|
||||
minimum_weight: 120
|
||||
674
contrib/macdeploy/LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
BIN
contrib/macdeploy/background.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
contrib/macdeploy/background.psd
Normal file
32
contrib/macdeploy/fancy.plist
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>window_bounds</key>
|
||||
<array>
|
||||
<integer>300</integer>
|
||||
<integer>300</integer>
|
||||
<integer>800</integer>
|
||||
<integer>620</integer>
|
||||
</array>
|
||||
<key>background_picture</key>
|
||||
<string>background.png</string>
|
||||
<key>icon_size</key>
|
||||
<integer>96</integer>
|
||||
<key>applications_symlink</key>
|
||||
<true/>
|
||||
<key>items_position</key>
|
||||
<dict>
|
||||
<key>Applications</key>
|
||||
<array>
|
||||
<integer>370</integer>
|
||||
<integer>156</integer>
|
||||
</array>
|
||||
<key>Bitcoin-Qt.app</key>
|
||||
<array>
|
||||
<integer>128</integer>
|
||||
<integer>156</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
341
contrib/macdeploy/macdeployqtplus
Executable file
@@ -0,0 +1,341 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import subprocess, sys, re, os, shutil, os.path
|
||||
from time import sleep
|
||||
from argparse import ArgumentParser
|
||||
|
||||
qt_conf="""[Paths]
|
||||
translations=Resources
|
||||
plugins=PlugIns
|
||||
"""
|
||||
|
||||
ap = ArgumentParser(description="""Front-end to macdeployqt with some additional functions.
|
||||
|
||||
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
|
||||
Note, that the "dist" folder will be deleted before deploying on each run.
|
||||
|
||||
Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.""")
|
||||
|
||||
ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed")
|
||||
ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug")
|
||||
ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment")
|
||||
ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries")
|
||||
ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used")
|
||||
ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work")
|
||||
ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace")
|
||||
ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument")
|
||||
|
||||
config = ap.parse_args()
|
||||
|
||||
verbose = config.verbose[0]
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
app_bundle = config.app_bundle[0]
|
||||
|
||||
if not os.path.exists(app_bundle):
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not find app bundle \"%s\"\n" % (app_bundle))
|
||||
sys.exit(1)
|
||||
|
||||
app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0]
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
for p in config.add_resources:
|
||||
if verbose >= 3:
|
||||
print "Checking for \"%s\"..." % p
|
||||
if not os.path.exists(p):
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not find additional resource file \"%s\"\n" % (p))
|
||||
sys.exit(1)
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if len(config.add_qt_tr) == 0:
|
||||
add_qt_tr = []
|
||||
else:
|
||||
qt_tr_dir = os.path.join(os.getenv("QTDIR", ""), "translations")
|
||||
add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")]
|
||||
for lng_file in add_qt_tr:
|
||||
p = os.path.join(qt_tr_dir, lng_file)
|
||||
if verbose >= 3:
|
||||
print "Checking for \"%s\"..." % p
|
||||
if not os.path.exists(p):
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not find Qt translation file \"%s\"\n" % (lng_file))
|
||||
sys.exit(1)
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if len(config.fancy) == 1:
|
||||
if verbose >= 3:
|
||||
print "Fancy: Importing plistlib..."
|
||||
try:
|
||||
import plistlib
|
||||
except ImportError:
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n")
|
||||
sys.exit(1)
|
||||
|
||||
if verbose >= 3:
|
||||
print "Fancy: Importing appscript..."
|
||||
try:
|
||||
import appscript
|
||||
except ImportError:
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n")
|
||||
sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n")
|
||||
sys.exit(1)
|
||||
|
||||
p = config.fancy[0]
|
||||
if verbose >= 3:
|
||||
print "Fancy: Loading \"%s\"..." % p
|
||||
if not os.path.exists(p):
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
fancy = plistlib.readPlist(p)
|
||||
except:
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not parse fancy disk image plist at \"%s\"\n" % (p))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4)
|
||||
assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str)
|
||||
assert not fancy.has_key("icon_size") or isinstance(fancy["icon_size"], int)
|
||||
assert not fancy.has_key("applications_symlink") or isinstance(fancy["applications_symlink"], bool)
|
||||
if fancy.has_key("items_position"):
|
||||
assert isinstance(fancy["items_position"], dict)
|
||||
for key, value in fancy["items_position"].iteritems():
|
||||
assert isinstance(value, list) and len(value) == 2 and isinstance(value[0], int) and isinstance(value[1], int)
|
||||
except:
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p))
|
||||
sys.exit(1)
|
||||
|
||||
if fancy.has_key("background_picture"):
|
||||
bp = fancy["background_picture"]
|
||||
if verbose >= 3:
|
||||
print "Fancy: Resolving background picture \"%s\"..." % bp
|
||||
if not os.path.exists(bp):
|
||||
bp = os.path.join(os.path.dirname(p), bp)
|
||||
if not os.path.exists(bp):
|
||||
if verbose >= 1:
|
||||
sys.stderr.write("Error: Could not find background picture at \"%s\" or \"%s\"\n" % (fancy["background_picture"], bp))
|
||||
sys.exit(1)
|
||||
else:
|
||||
fancy["background_picture"] = bp
|
||||
else:
|
||||
fancy = None
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if os.path.exists("dist"):
|
||||
if verbose >= 2:
|
||||
print "+ Removing old dist folder +"
|
||||
|
||||
shutil.rmtree("dist")
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
target = os.path.join("dist", app_bundle)
|
||||
target_res = os.path.join(target, "Contents", "Resources")
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Copying source bundle +"
|
||||
if verbose >= 3:
|
||||
print app_bundle, "->", target
|
||||
|
||||
os.mkdir("dist")
|
||||
shutil.copytree(app_bundle, target)
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
macdeployqt_args = ["macdeployqt", target, "-verbose=%d" % verbose]
|
||||
if not config.plugins:
|
||||
macdeployqt_args.append("-no-plugins")
|
||||
if not config.strip:
|
||||
macdeployqt_args.append("-no-strip")
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Running macdeployqt +"
|
||||
|
||||
ret = subprocess.call(macdeployqt_args)
|
||||
if ret != 0:
|
||||
sys.exit(ret)
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Installing qt.conf +"
|
||||
|
||||
f = open(os.path.join(target_res, "qt.conf"), "wb")
|
||||
f.write(qt_conf)
|
||||
f.close()
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if len(add_qt_tr) > 0 and verbose >= 2:
|
||||
print "+ Adding Qt translations +"
|
||||
|
||||
for lng_file in add_qt_tr:
|
||||
if verbose >= 3:
|
||||
print os.path.join(qt_tr_dir, lng_file), "->", os.path.join(target_res, lng_file)
|
||||
shutil.copy2(os.path.join(qt_tr_dir, lng_file), os.path.join(target_res, lng_file))
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if len(config.add_resources) > 0 and verbose >= 2:
|
||||
print "+ Adding additional resources +"
|
||||
|
||||
for p in config.add_resources:
|
||||
t = os.path.join(target_res, os.path.basename(p))
|
||||
if verbose >= 3:
|
||||
print p, "->", t
|
||||
if os.path.isdir(p):
|
||||
shutil.copytree(p, t)
|
||||
else:
|
||||
shutil.copy2(p, t)
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if config.dmg is not None:
|
||||
def runHDIUtil(verb, image_basename, **kwargs):
|
||||
hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"]
|
||||
if kwargs.has_key("capture_stdout"):
|
||||
del kwargs["capture_stdout"]
|
||||
run = subprocess.check_output
|
||||
else:
|
||||
if verbose < 2:
|
||||
hdiutil_args.append("-quiet")
|
||||
elif verbose >= 3:
|
||||
hdiutil_args.append("-verbose")
|
||||
run = subprocess.check_call
|
||||
|
||||
for key, value in kwargs.iteritems():
|
||||
hdiutil_args.append("-" + key)
|
||||
if not value is True:
|
||||
hdiutil_args.append(str(value))
|
||||
|
||||
return run(hdiutil_args)
|
||||
|
||||
if verbose >= 2:
|
||||
if fancy is None:
|
||||
print "+ Creating .dmg disk image +"
|
||||
else:
|
||||
print "+ Preparing .dmg disk image +"
|
||||
|
||||
if config.dmg != "":
|
||||
dmg_name = config.dmg
|
||||
else:
|
||||
spl = app_bundle_name.split(" ")
|
||||
dmg_name = spl[0] + "".join(p.capitalize() for p in spl[1:])
|
||||
|
||||
if fancy is None:
|
||||
try:
|
||||
runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=app_bundle_name, ov=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
sys.exit(e.returncode)
|
||||
else:
|
||||
if verbose >= 3:
|
||||
print "Determining size of \"dist\"..."
|
||||
size = 0
|
||||
for path, dirs, files in os.walk("dist"):
|
||||
for file in files:
|
||||
size += os.path.getsize(os.path.join(path, file))
|
||||
size += int(size * 0.1)
|
||||
|
||||
if verbose >= 3:
|
||||
print "Creating temp image for modification..."
|
||||
try:
|
||||
runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=app_bundle_name, ov=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
sys.exit(e.returncode)
|
||||
|
||||
if verbose >= 3:
|
||||
print "Attaching temp image..."
|
||||
try:
|
||||
output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
sys.exit(e.returncode)
|
||||
|
||||
m = re.search("/Volumes/(.+$)", output)
|
||||
disk_root = m.group(0)
|
||||
disk_name = m.group(1)
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Applying fancy settings +"
|
||||
|
||||
if fancy.has_key("background_picture"):
|
||||
bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"]))
|
||||
if verbose >= 3:
|
||||
print fancy["background_picture"], "->", bg_path
|
||||
shutil.copy2(fancy["background_picture"], bg_path)
|
||||
else:
|
||||
bg_path = None
|
||||
|
||||
if fancy.get("applications_symlink", False):
|
||||
os.symlink("/Applications", os.path.join(disk_root, "Applications"))
|
||||
|
||||
finder = appscript.app("Finder")
|
||||
disk = finder.disks[disk_name]
|
||||
disk.open()
|
||||
window = disk.container_window
|
||||
window.current_view.set(appscript.k.icon_view)
|
||||
window.toolbar_visible.set(False)
|
||||
window.statusbar_visible.set(False)
|
||||
if fancy.has_key("window_bounds"):
|
||||
window.bounds.set(fancy["window_bounds"])
|
||||
view_options = window.icon_view_options
|
||||
view_options.arrangement.set(appscript.k.not_arranged)
|
||||
if fancy.has_key("icon_size"):
|
||||
view_options.icon_size.set(fancy["icon_size"])
|
||||
if bg_path is not None:
|
||||
view_options.background_picture.set(disk.files[os.path.basename(bg_path)])
|
||||
if fancy.has_key("items_position"):
|
||||
for name, position in fancy["items_position"].iteritems():
|
||||
window.items[name].position.set(position)
|
||||
disk.close()
|
||||
if bg_path is not None:
|
||||
subprocess.call(["SetFile", "-a", "V", bg_path])
|
||||
disk.update(registering_applications=False)
|
||||
sleep(2)
|
||||
disk.eject()
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Finalizing .dmg disk image +"
|
||||
|
||||
try:
|
||||
runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
sys.exit(e.returncode)
|
||||
|
||||
os.unlink(dmg_name + ".temp.dmg")
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
if verbose >= 2:
|
||||
print "+ Done +"
|
||||
|
||||
sys.exit(0)
|
||||
26
contrib/macdeploy/notes.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
macdeployqtplus works best on OS X Lion, for Snow Leopard you'd need to install
|
||||
Python 2.7 and make it your default Python installation.
|
||||
|
||||
You will need the appscript package for the fancy disk image creation to work.
|
||||
Install it by invoking "sudo easy_install appscript".
|
||||
|
||||
Ths script should be invoked in the target directory like this:
|
||||
$source_dir/contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr de,es,ru -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist
|
||||
|
||||
During the process, the disk image window will pop up briefly where the fancy
|
||||
settings are applied. This is normal, please do not interfere.
|
||||
|
||||
You can also set up Qt Creator for invoking the script. For this, go to the
|
||||
"Projects" tab on the left side, switch to "Run Settings" above and add a
|
||||
deploy configuration. Next add a deploy step choosing "Custom Process Step".
|
||||
Fill in the following.
|
||||
|
||||
Enable custom process step: [x]
|
||||
Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus
|
||||
Working directory: %{buildDir}
|
||||
Command arguments: Bitcoin-Qt.app -add-qt-tr de,ru -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist
|
||||
|
||||
After that you can start the deployment process through the menu with
|
||||
Build -> Deploy Project "bitcoin-qt"
|
||||
|
||||
43
contrib/miniupnpc/Portfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
|
||||
# $Id$
|
||||
|
||||
PortSystem 1.0
|
||||
|
||||
name miniupnpc
|
||||
epoch 2
|
||||
version 1.6
|
||||
revision 2
|
||||
categories net
|
||||
platforms darwin
|
||||
license BSD
|
||||
maintainers singingwolfboy openmaintainer
|
||||
description Lightweight client for UPnP protocol
|
||||
long_description \
|
||||
${description}
|
||||
|
||||
homepage http://miniupnp.free.fr/
|
||||
master_sites http://miniupnp.free.fr/files/download.php?file=${distname}${extract.suffix}&dummy=
|
||||
checksums md5 88055f2d4a061cfd4cfe25a9eae22f67 \
|
||||
sha1 ef8f2edb17f2e7c5b8dc67ee80a65c199d823e0a \
|
||||
rmd160 d86b75b331a3fb5525c71708548f311977c0598f
|
||||
|
||||
use_configure no
|
||||
|
||||
variant universal {}
|
||||
if {[variant_isset universal]} {
|
||||
set archflags ${configure.universal_cflags}
|
||||
} else {
|
||||
set archflags ${configure.cc_archflags}
|
||||
}
|
||||
|
||||
build.args-append CC="${configure.cc} ${archflags}"
|
||||
|
||||
post-patch {
|
||||
reinplace "s|-Wl,-install_name,|-Wl,-install_name,${prefix}/lib/|" ${worksrcpath}/Makefile
|
||||
}
|
||||
|
||||
destroot.destdir PREFIX=${prefix} INSTALLPREFIX=${destroot}${prefix}
|
||||
|
||||
livecheck.type regex
|
||||
livecheck.url http://miniupnp.free.fr/files/
|
||||
livecheck.regex ${name}-(\\d+(\\.\\d{1,4})+)${extract.suffix}
|
||||
6
contrib/pyminer/README
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
This is a 'getwork' CPU mining client for bitcoin.
|
||||
|
||||
It is pure-python, and therefore very, very slow. The purpose is to
|
||||
provide a reference implementation of a miner, for study.
|
||||
|
||||
32
contrib/pyminer/example-config.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#
|
||||
# RPC login details
|
||||
#
|
||||
host=127.0.0.1
|
||||
port=8332
|
||||
|
||||
rpcuser=myusername
|
||||
rpcpass=mypass
|
||||
|
||||
|
||||
#
|
||||
# mining details
|
||||
#
|
||||
|
||||
threads=4
|
||||
|
||||
# periodic rate for requesting new work, if solution not found
|
||||
scantime=60
|
||||
|
||||
|
||||
#
|
||||
# misc.
|
||||
#
|
||||
|
||||
# not really used right now
|
||||
logdir=/tmp/pyminer
|
||||
|
||||
# set to 1, to enable hashmeter output
|
||||
hashmeter=0
|
||||
|
||||
|
||||
252
contrib/pyminer/pyminer.py
Executable file
@@ -0,0 +1,252 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) 2011 The Bitcoin developers
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
import time
|
||||
import json
|
||||
import pprint
|
||||
import hashlib
|
||||
import struct
|
||||
import re
|
||||
import base64
|
||||
import httplib
|
||||
import sys
|
||||
from multiprocessing import Process
|
||||
|
||||
ERR_SLEEP = 15
|
||||
MAX_NONCE = 1000000L
|
||||
|
||||
settings = {}
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
class BitcoinRPC:
|
||||
OBJID = 1
|
||||
|
||||
def __init__(self, host, port, username, password):
|
||||
authpair = "%s:%s" % (username, password)
|
||||
self.authhdr = "Basic %s" % (base64.b64encode(authpair))
|
||||
self.conn = httplib.HTTPConnection(host, port, False, 30)
|
||||
def rpc(self, method, params=None):
|
||||
self.OBJID += 1
|
||||
obj = { 'version' : '1.1',
|
||||
'method' : method,
|
||||
'id' : self.OBJID }
|
||||
if params is None:
|
||||
obj['params'] = []
|
||||
else:
|
||||
obj['params'] = params
|
||||
self.conn.request('POST', '/', json.dumps(obj),
|
||||
{ 'Authorization' : self.authhdr,
|
||||
'Content-type' : 'application/json' })
|
||||
|
||||
resp = self.conn.getresponse()
|
||||
if resp is None:
|
||||
print "JSON-RPC: no response"
|
||||
return None
|
||||
|
||||
body = resp.read()
|
||||
resp_obj = json.loads(body)
|
||||
if resp_obj is None:
|
||||
print "JSON-RPC: cannot JSON-decode body"
|
||||
return None
|
||||
if 'error' in resp_obj and resp_obj['error'] != None:
|
||||
return resp_obj['error']
|
||||
if 'result' not in resp_obj:
|
||||
print "JSON-RPC: no result in object"
|
||||
return None
|
||||
|
||||
return resp_obj['result']
|
||||
def getblockcount(self):
|
||||
return self.rpc('getblockcount')
|
||||
def getwork(self, data=None):
|
||||
return self.rpc('getwork', data)
|
||||
|
||||
def uint32(x):
|
||||
return x & 0xffffffffL
|
||||
|
||||
def bytereverse(x):
|
||||
return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
|
||||
(((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
|
||||
|
||||
def bufreverse(in_buf):
|
||||
out_words = []
|
||||
for i in range(0, len(in_buf), 4):
|
||||
word = struct.unpack('@I', in_buf[i:i+4])[0]
|
||||
out_words.append(struct.pack('@I', bytereverse(word)))
|
||||
return ''.join(out_words)
|
||||
|
||||
def wordreverse(in_buf):
|
||||
out_words = []
|
||||
for i in range(0, len(in_buf), 4):
|
||||
out_words.append(in_buf[i:i+4])
|
||||
out_words.reverse()
|
||||
return ''.join(out_words)
|
||||
|
||||
class Miner:
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
self.max_nonce = MAX_NONCE
|
||||
|
||||
def work(self, datastr, targetstr):
|
||||
# decode work data hex string to binary
|
||||
static_data = datastr.decode('hex')
|
||||
static_data = bufreverse(static_data)
|
||||
|
||||
# the first 76b of 80b do not change
|
||||
blk_hdr = static_data[:76]
|
||||
|
||||
# decode 256-bit target value
|
||||
targetbin = targetstr.decode('hex')
|
||||
targetbin = targetbin[::-1] # byte-swap and dword-swap
|
||||
targetbin_str = targetbin.encode('hex')
|
||||
target = long(targetbin_str, 16)
|
||||
|
||||
# pre-hash first 76b of block header
|
||||
static_hash = hashlib.sha256()
|
||||
static_hash.update(blk_hdr)
|
||||
|
||||
for nonce in xrange(self.max_nonce):
|
||||
|
||||
# encode 32-bit nonce value
|
||||
nonce_bin = struct.pack("<I", nonce)
|
||||
|
||||
# hash final 4b, the nonce value
|
||||
hash1_o = static_hash.copy()
|
||||
hash1_o.update(nonce_bin)
|
||||
hash1 = hash1_o.digest()
|
||||
|
||||
# sha256 hash of sha256 hash
|
||||
hash_o = hashlib.sha256()
|
||||
hash_o.update(hash1)
|
||||
hash = hash_o.digest()
|
||||
|
||||
# quick test for winning solution: high 32 bits zero?
|
||||
if hash[-4:] != '\0\0\0\0':
|
||||
continue
|
||||
|
||||
# convert binary hash to 256-bit Python long
|
||||
hash = bufreverse(hash)
|
||||
hash = wordreverse(hash)
|
||||
|
||||
hash_str = hash.encode('hex')
|
||||
l = long(hash_str, 16)
|
||||
|
||||
# proof-of-work test: hash < target
|
||||
if l < target:
|
||||
print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,)
|
||||
return (nonce + 1, nonce_bin)
|
||||
else:
|
||||
print time.asctime(), "PROOF-OF-WORK false positive %064x" % (l,)
|
||||
# return (nonce + 1, nonce_bin)
|
||||
|
||||
return (nonce + 1, None)
|
||||
|
||||
def submit_work(self, rpc, original_data, nonce_bin):
|
||||
nonce_bin = bufreverse(nonce_bin)
|
||||
nonce = nonce_bin.encode('hex')
|
||||
solution = original_data[:152] + nonce + original_data[160:256]
|
||||
param_arr = [ solution ]
|
||||
result = rpc.getwork(param_arr)
|
||||
print time.asctime(), "--> Upstream RPC result:", result
|
||||
|
||||
def iterate(self, rpc):
|
||||
work = rpc.getwork()
|
||||
if work is None:
|
||||
time.sleep(ERR_SLEEP)
|
||||
return
|
||||
if 'data' not in work or 'target' not in work:
|
||||
time.sleep(ERR_SLEEP)
|
||||
return
|
||||
|
||||
time_start = time.time()
|
||||
|
||||
(hashes_done, nonce_bin) = self.work(work['data'],
|
||||
work['target'])
|
||||
|
||||
time_end = time.time()
|
||||
time_diff = time_end - time_start
|
||||
|
||||
self.max_nonce = long(
|
||||
(hashes_done * settings['scantime']) / time_diff)
|
||||
if self.max_nonce > 0xfffffffaL:
|
||||
self.max_nonce = 0xfffffffaL
|
||||
|
||||
if settings['hashmeter']:
|
||||
print "HashMeter(%d): %d hashes, %.2f Khash/sec" % (
|
||||
self.id, hashes_done,
|
||||
(hashes_done / 1000.0) / time_diff)
|
||||
|
||||
if nonce_bin is not None:
|
||||
self.submit_work(rpc, work['data'], nonce_bin)
|
||||
|
||||
def loop(self):
|
||||
rpc = BitcoinRPC(settings['host'], settings['port'],
|
||||
settings['rpcuser'], settings['rpcpass'])
|
||||
if rpc is None:
|
||||
return
|
||||
|
||||
while True:
|
||||
self.iterate(rpc)
|
||||
|
||||
def miner_thread(id):
|
||||
miner = Miner(id)
|
||||
miner.loop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
print "Usage: pyminer.py CONFIG-FILE"
|
||||
sys.exit(1)
|
||||
|
||||
f = open(sys.argv[1])
|
||||
for line in f:
|
||||
# skip comment lines
|
||||
m = re.search('^\s*#', line)
|
||||
if m:
|
||||
continue
|
||||
|
||||
# parse key=value lines
|
||||
m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
|
||||
if m is None:
|
||||
continue
|
||||
settings[m.group(1)] = m.group(2)
|
||||
f.close()
|
||||
|
||||
if 'host' not in settings:
|
||||
settings['host'] = '127.0.0.1'
|
||||
if 'port' not in settings:
|
||||
settings['port'] = 8332
|
||||
if 'threads' not in settings:
|
||||
settings['threads'] = 1
|
||||
if 'hashmeter' not in settings:
|
||||
settings['hashmeter'] = 0
|
||||
if 'scantime' not in settings:
|
||||
settings['scantime'] = 30L
|
||||
if 'rpcuser' not in settings or 'rpcpass' not in settings:
|
||||
print "Missing username and/or password in cfg file"
|
||||
sys.exit(1)
|
||||
|
||||
settings['port'] = int(settings['port'])
|
||||
settings['threads'] = int(settings['threads'])
|
||||
settings['hashmeter'] = int(settings['hashmeter'])
|
||||
settings['scantime'] = long(settings['scantime'])
|
||||
|
||||
thr_list = []
|
||||
for thr_id in range(settings['threads']):
|
||||
p = Process(target=miner_thread, args=(thr_id,))
|
||||
p.start()
|
||||
thr_list.append(p)
|
||||
time.sleep(1) # stagger threads
|
||||
|
||||
print settings['threads'], "mining threads started"
|
||||
|
||||
print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port'])
|
||||
try:
|
||||
for thr_proc in thr_list:
|
||||
thr_proc.join()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port'])
|
||||
|
||||
5
contrib/wallettools/walletchangepass.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from jsonrpc import ServiceProxy
|
||||
access = ServiceProxy("http://127.0.0.1:8332")
|
||||
pwd = raw_input("Enter old wallet passphrase: ")
|
||||
pwd2 = raw_input("Enter new wallet passphrase: ")
|
||||
access.walletpassphrasechange(pwd, pwd2)
|
||||
4
contrib/wallettools/walletunlock.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from jsonrpc import ServiceProxy
|
||||
access = ServiceProxy("http://127.0.0.1:8332")
|
||||
pwd = raw_input("Enter wallet passphrase: ")
|
||||
access.walletpassphrase(pwd, 60)
|
||||
33
doc/README
Normal file
@@ -0,0 +1,33 @@
|
||||
Bitcoin 0.5.0 BETA
|
||||
|
||||
Copyright (c) 2009-2011 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com).
|
||||
|
||||
|
||||
Intro
|
||||
-----
|
||||
Bitcoin is a free open source peer-to-peer electronic cash system that is
|
||||
completely decentralized, without the need for a central server or trusted
|
||||
parties. Users hold the crypto keys to their own money and transact directly
|
||||
with each other, with the help of a P2P network to check for double-spending.
|
||||
|
||||
|
||||
Setup
|
||||
-----
|
||||
You need the Qt4 run-time libraries to run bitcoin-qt. On Debian or Ubuntu:
|
||||
sudo apt-get install libqtgui4
|
||||
|
||||
Unpack the files into a directory and run:
|
||||
bin/32/bitcoin-qt (GUI, 32-bit)
|
||||
bin/32/bitcoind (headless, 32-bit)
|
||||
bin/64/bitcoin-qt (GUI, 64-bit)
|
||||
bin/64/bitcoind (headless, 64-bit)
|
||||
|
||||
|
||||
See the documentation at the bitcoin wiki:
|
||||
https://en.bitcoin.it/wiki/Main_Page
|
||||
for help and more information.
|
||||
35
doc/README_windows.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
Bitcoin 0.5.0 BETA
|
||||
|
||||
Copyright (c) 2009-2011 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com).
|
||||
|
||||
|
||||
Intro
|
||||
-----
|
||||
Bitcoin is a free open source peer-to-peer electronic cash system that is
|
||||
completely decentralized, without the need for a central server or trusted
|
||||
parties. Users hold the crypto keys to their own money and transact directly
|
||||
with each other, with the help of a P2P network to check for double-spending.
|
||||
|
||||
|
||||
Setup
|
||||
-----
|
||||
Unpack the files into a directory and run bitcoin-qt.exe.
|
||||
|
||||
If you have Microsoft Security Essentials, you need to add bitcoin.exe to its
|
||||
"Excluded processes" list. Microsoft Security Essentials->Settings tab,
|
||||
select Excluded processes, press Add, select bitcoin.exe, OK, Save changes.
|
||||
|
||||
The software automatically finds other nodes to connect to. You can
|
||||
enable Universal Plug and Play using a menu entry or set your firewall
|
||||
to forward port 8333 (TCP) to your computer so you can receive
|
||||
incoming connections. Bitcoin works without incoming connections,
|
||||
but allowing incoming connections helps the Bitcoin network.
|
||||
|
||||
See the bitcoin wiki at:
|
||||
https://en.bitcoin.it/wiki/Main_Page
|
||||
for more help and information.
|
||||
73
doc/assets-attribution.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
|
||||
src/qt/res/src/*.svg
|
||||
Designer: Wladimir van der Laan
|
||||
License: Creative Commons Attribution
|
||||
|
||||
Icon: src/qt/res/icons/send.png
|
||||
Icon Pack: Vista Style Arrow
|
||||
Designer: Icons Land
|
||||
License: Freeware Non-commercial
|
||||
Site: http://findicons.com/icon/231371/right3green
|
||||
|
||||
Icon: src/qt/res/icons/address-book.png
|
||||
Icon Pack: Farm-Fresh Web
|
||||
Designer: FatCow Web Hosting
|
||||
License: Creative Commons Attribution (by)
|
||||
Site: http://findicons.com/icon/163938/book_open
|
||||
|
||||
Icon: src/qt/res/icons/connect*.png, src/qt/res/icons/synced.png, src/qt/res/icons/lock_*.png
|
||||
Icon Pack: Human-O2
|
||||
Designer: schollidesign
|
||||
License: GNU/GPL
|
||||
Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0
|
||||
|
||||
Icon: src/qt/res/icons/transaction*.png
|
||||
Designer: md2k7
|
||||
Site: https://forum.bitcoin.org/index.php?topic=15276.0
|
||||
License: You are free to do with these icons as you wish, including selling,
|
||||
copying, modifying etc.
|
||||
|
||||
Icon: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png,
|
||||
src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png,
|
||||
src/qt/res/icons/add.png, src/qt/res/icons/edit.png,
|
||||
src/qt/res/icons/remove.png (edited)
|
||||
Designer: http://www.everaldo.com
|
||||
Icon Pack: Crystal SVG
|
||||
License: LGPL
|
||||
|
||||
Icon: src/qt/res/icons/receive.png, src/qt/res/icons/history.png,
|
||||
src/qt/res/icons/export.png
|
||||
Designer: Oxygen team
|
||||
Icon Pack: Oxygen
|
||||
License: Creative Common Attribution-ShareAlike 3.0 License or LGPL
|
||||
Site: http://www.oxygen-icons.org/
|
||||
|
||||
Icon: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png
|
||||
Designer: Bitboy (optimized for 16x16 by Wladimir van der Laan)
|
||||
License: Public Domain
|
||||
Site: http://forum.bitcoin.org/?topic=1756.0
|
||||
|
||||
Icon: src/qt/res/icons/overview.png
|
||||
Icon Pack: Primo
|
||||
Designer: Jack Cai
|
||||
License: Creative Commons Attribution No Derivatives (by-nd)
|
||||
Site: http://findicons.com/icon/175944/home?id=176221#
|
||||
|
||||
Icon: scripts/img/reload.xcf (modified),src/qt/res/movies/update_spinner.mng
|
||||
Icon Pack: Kids
|
||||
Designer: Everaldo (Everaldo Coelho)
|
||||
License: GNU/GPL
|
||||
Site: http://findicons.com/icon/17102/reload?id=17102
|
||||
|
||||
Image: src/qt/res/images/splash2.jpg (Wallet image)
|
||||
Designer: Crobbo (forum)
|
||||
Site: https://bitcointalk.org/index.php?topic=32273.0
|
||||
License: Public domain
|
||||
|
||||
Icon: src/qt/res/icons/key.png
|
||||
Designer: VisualPharm (Ivan Boyko)
|
||||
Icon Pack: Must Have
|
||||
Site: http://findicons.com/icon/51009/key?id=51009
|
||||
License: Creative Commons Attribution (by)
|
||||
|
||||
|
||||
84
doc/build-msw.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
Copyright (c) 2009-2011 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP
|
||||
software written by Thomas Bernard.
|
||||
|
||||
|
||||
See readme-qt.rst for instructions on building Bitcoin QT, the
|
||||
graphical user interface.
|
||||
|
||||
WINDOWS BUILD NOTES
|
||||
===================
|
||||
|
||||
Compilers Supported
|
||||
-------------------
|
||||
TODO: What works?
|
||||
Note: releases are cross-compiled using mingw running on Linux.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
Libraries you need to download separately and build:
|
||||
|
||||
default path download
|
||||
OpenSSL \openssl-1.0.0d-mgw http://www.openssl.org/source/
|
||||
Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html
|
||||
Boost \boost-1.47.0-mgw http://www.boost.org/users/download/
|
||||
miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/
|
||||
|
||||
Their licenses:
|
||||
OpenSSL Old BSD license with the problematic advertising requirement
|
||||
Berkeley DB New BSD license with additional requirement that linked software must be free open source
|
||||
Boost MIT-like license
|
||||
miniupnpc New (3-clause) BSD license
|
||||
|
||||
Versions used in this release:
|
||||
OpenSSL 1.0.0e
|
||||
Berkeley DB 4.8.30.NC
|
||||
Boost 1.47.0
|
||||
miniupnpc 1.6
|
||||
|
||||
|
||||
OpenSSL
|
||||
-------
|
||||
MSYS shell:
|
||||
un-tar sources with MSYS 'tar xfz' to avoid issue with symlinks (OpenSSL ticket 2377)
|
||||
change 'MAKE' env. variable from 'C:\MinGW32\bin\mingw32-make.exe' to '/c/MinGW32/bin/mingw32-make.exe'
|
||||
|
||||
cd /c/openssl-1.0.0e-mgw
|
||||
./config
|
||||
make
|
||||
|
||||
Berkeley DB
|
||||
-----------
|
||||
MSYS shell:
|
||||
cd /c/db-4.8.30.NC-mgw/build_unix
|
||||
sh ../dist/configure --enable-mingw --enable-cxx
|
||||
make
|
||||
|
||||
Boost
|
||||
-----
|
||||
DOS prompt:
|
||||
downloaded boost jam 3.1.18
|
||||
cd \boost-1.47.0-mgw
|
||||
bjam toolset=gcc --build-type=complete stage
|
||||
|
||||
MiniUPnPc
|
||||
---------
|
||||
UPnP support is optional, make with USE_UPNP= to disable it.
|
||||
|
||||
MSYS shell:
|
||||
cd /c/miniupnpc-1.6-mgw
|
||||
make -f Makefile.mingw
|
||||
mkdir miniupnpc
|
||||
cp *.h miniupnpc/
|
||||
|
||||
Bitcoin
|
||||
-------
|
||||
DOS prompt:
|
||||
cd \bitcoin\src
|
||||
mingw32-make -f makefile.mingw
|
||||
strip bitcoind.exe
|
||||
56
doc/build-osx.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
Copyright (c) 2011 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying file
|
||||
license.txt or http://www.opensource.org/licenses/mit-license.php. This
|
||||
product includes software developed by the OpenSSL Project for use in the
|
||||
OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic
|
||||
software written by Eric Young (eay@cryptsoft.com) and UPnP software written by
|
||||
Thomas Bernard.
|
||||
|
||||
|
||||
Mac OS X bitcoind build instructions
|
||||
Laszlo Hanyecz <solar@heliacal.net>
|
||||
Douglas Huff <dhuff@jrbobdobbs.org>
|
||||
|
||||
|
||||
See readme-qt.rst for instructions on building Bitcoin QT, the
|
||||
graphical user interface.
|
||||
|
||||
Tested on 10.5 and 10.6 intel. PPC is not supported because it's big-endian.
|
||||
|
||||
All of the commands should be executed in Terminal.app.. it's in
|
||||
/Applications/Utilities
|
||||
|
||||
You need to install XCode with all the options checked so that the compiler and
|
||||
everything is available in /usr not just /Developer I think it comes on the DVD
|
||||
but you can get the current version from http://developer.apple.com
|
||||
|
||||
|
||||
1. Clone the github tree to get the source code:
|
||||
|
||||
git clone git@github.com:bitcoin/bitcoin.git bitcoin
|
||||
|
||||
2. Download and install MacPorts from http://www.macports.org/
|
||||
|
||||
2a. (for 10.7 Lion)
|
||||
Edit /opt/local/etc/macports/macports.conf and uncomment "build_arch i386"
|
||||
|
||||
3. Install dependencies from MacPorts
|
||||
|
||||
sudo port install boost db48 openssl
|
||||
|
||||
Install the right version of miniupnpc:
|
||||
pushd bitcoin/contrib/minipupnpc; sudo port install; popd
|
||||
(this will be unnecessary soon, you will just port install miniupnpc
|
||||
along with the rest of the dependencies).
|
||||
|
||||
4. Now you should be able to build bitcoind:
|
||||
|
||||
cd bitcoin/src
|
||||
make -f makefile.osx
|
||||
|
||||
Run:
|
||||
./bitcoind --help # for a list of command-line options.
|
||||
Run
|
||||
./bitcoind -daemon # to start the bitcoin daemon.
|
||||
Run
|
||||
./bitcoind help # When the daemon is running, to get a list of RPC commands
|
||||
150
doc/build-unix.txt
Normal file
@@ -0,0 +1,150 @@
|
||||
Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
Copyright (c) 2011 Bitcoin Developers
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (http://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP
|
||||
software written by Thomas Bernard.
|
||||
|
||||
|
||||
UNIX BUILD NOTES
|
||||
================
|
||||
|
||||
To Build
|
||||
--------
|
||||
|
||||
cd src/
|
||||
make -f makefile.unix # Headless bitcoin
|
||||
|
||||
See readme-qt.rst for instructions on building Bitcoin QT,
|
||||
the graphical bitcoin.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Library Purpose Description
|
||||
------- ------- -----------
|
||||
libssl SSL Support Secure communications
|
||||
libdb4.8 Berkeley DB Blockchain & wallet storage
|
||||
libboost Boost C++ Library
|
||||
miniupnpc UPnP Support Optional firewall-jumping support
|
||||
|
||||
miniupnpc may be used for UPnP port mapping. It can be downloaded from
|
||||
http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and
|
||||
turned off by default. Set USE_UPNP to a different value to control this:
|
||||
USE_UPNP= No UPnP support - miniupnp not required
|
||||
USE_UPNP=0 (the default) UPnP support turned off by default at runtime
|
||||
USE_UPNP=1 UPnP support turned on by default at runtime
|
||||
|
||||
Licenses of statically linked libraries:
|
||||
Berkeley DB New BSD license with additional requirement that linked
|
||||
software must be free open source
|
||||
Boost MIT-like license
|
||||
miniupnpc New (3-clause) BSD license
|
||||
|
||||
Versions used in this release:
|
||||
GCC 4.3.3
|
||||
OpenSSL 0.9.8g
|
||||
Berkeley DB 4.8.30.NC
|
||||
Boost 1.37
|
||||
miniupnpc 1.6
|
||||
|
||||
|
||||
Dependency Build Instructions: Ubuntu & Debian
|
||||
----------------------------------------------
|
||||
sudo apt-get install build-essential
|
||||
sudo apt-get install libssl-dev
|
||||
sudo apt-get install libdb4.8-dev
|
||||
sudo apt-get install libdb4.8++-dev
|
||||
Boost 1.40+: sudo apt-get install libboost-all-dev
|
||||
or Boost 1.37: sudo apt-get install libboost1.37-dev
|
||||
|
||||
If using Boost 1.37, append -mt to the boost libraries in the makefile.
|
||||
|
||||
|
||||
Dependency Build Instructions: Gentoo
|
||||
-------------------------------------
|
||||
|
||||
Note: If you just want to install bitcoind on Gentoo, you can add the Bitcoin
|
||||
overlay and use your package manager:
|
||||
layman -a bitcoin && emerge bitcoind
|
||||
|
||||
emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8
|
||||
|
||||
Take the following steps to build (no UPnP support):
|
||||
cd ${BITCOIN_DIR}/src
|
||||
make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8'
|
||||
strip bitcoind
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
The release is built with GCC and then "strip bitcoind" to strip the debug
|
||||
symbols, which reduces the executable size by about 90%.
|
||||
|
||||
|
||||
miniupnpc
|
||||
---------
|
||||
tar -xzvf miniupnpc-1.6.tar.gz
|
||||
cd miniupnpc-1.6
|
||||
make
|
||||
sudo su
|
||||
make install
|
||||
|
||||
|
||||
Berkeley DB
|
||||
-----------
|
||||
You need Berkeley DB 4.8. If you have to build Berkeley DB yourself:
|
||||
../dist/configure --enable-cxx
|
||||
make
|
||||
|
||||
|
||||
Boost
|
||||
-----
|
||||
If you need to build Boost yourself:
|
||||
sudo su
|
||||
./bootstrap.sh
|
||||
./bjam install
|
||||
|
||||
|
||||
Security
|
||||
--------
|
||||
To help make your bitcoin installation more secure by making certain attacks impossible to
|
||||
exploit even if a vulnerability is found, you can take the following measures:
|
||||
|
||||
* Position Independent Executable
|
||||
Build position independent code to take advantage of Address Space Layout Randomization
|
||||
offered by some kernels. An attacker who is able to cause execution of code at an arbitrary
|
||||
memory location is thwarted if he doesn't know where anything useful is located.
|
||||
The stack and heap are randomly located by default but this allows the code section to be
|
||||
randomly located as well.
|
||||
|
||||
On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error
|
||||
such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;"
|
||||
|
||||
To build with PIE, use:
|
||||
make -f makefile.unix ... -e PIE=1
|
||||
|
||||
To test that you have built PIE executable, install scanelf, part of paxutils, and use:
|
||||
scanelf -e ./bitcoin
|
||||
|
||||
The output should contain:
|
||||
TYPE
|
||||
ET_DYN
|
||||
|
||||
* Non-executable Stack
|
||||
If the stack is executable then trivial stack based buffer overflow exploits are possible if
|
||||
vulnerable buffers are found. By default, bitcoin should be built with a non-executable stack
|
||||
but if one of the libraries it uses asks for an executable stack or someone makes a mistake
|
||||
and uses a compiler extension which requires an executable stack, it will silently build an
|
||||
executable without the non-executable stack protection.
|
||||
|
||||
To verify that the stack is non-executable after compiling use:
|
||||
scanelf -e ./bitcoin
|
||||
|
||||
the output should contain:
|
||||
STK/REL/PTL
|
||||
RW- R-- RW-
|
||||
|
||||
The STK RW- means that the stack is readable and writeable but not executable.
|
||||
99
doc/coding.txt
Normal file
@@ -0,0 +1,99 @@
|
||||
Please be consistent with the existing coding style.
|
||||
|
||||
Block style:
|
||||
|
||||
bool Function(char* psz, int n)
|
||||
{
|
||||
// Comment summarising what this section of code does
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// When something fails, return early
|
||||
if (!Something())
|
||||
return false;
|
||||
...
|
||||
}
|
||||
|
||||
// Success return is usually at the end
|
||||
return true;
|
||||
}
|
||||
|
||||
- ANSI/Allman block style
|
||||
- 4 space indenting, no tabs
|
||||
- No extra spaces inside parenthesis; please don't do ( this )
|
||||
- No space after function names, one space after if, for and while
|
||||
|
||||
Variable names begin with the type in lowercase, like nSomeVariable.
|
||||
Please don't put the first word of the variable name in lowercase like
|
||||
someVariable.
|
||||
|
||||
Common types:
|
||||
n integer number: short, unsigned short, int, unsigned int,
|
||||
int64, uint64, sometimes char if used as a number
|
||||
d double, float
|
||||
f flag
|
||||
hash uint256
|
||||
p pointer or array, one p for each level of indirection
|
||||
psz pointer to null terminated string
|
||||
str string object
|
||||
v vector or similar list objects
|
||||
map map or multimap
|
||||
set set or multiset
|
||||
bn CBigNum
|
||||
|
||||
-------------------------
|
||||
Locking/mutex usage notes
|
||||
|
||||
The code is multi-threaded, and uses mutexes and the
|
||||
CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures.
|
||||
|
||||
Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main
|
||||
and then cs_wallet, while thread 2 locks them in the opposite order:
|
||||
result, deadlock as each waits for the other to release its lock) are
|
||||
a problem. Compile with -DDEBUG_LOCKORDER to get lock order
|
||||
inconsistencies reported in the debug.log file.
|
||||
|
||||
Re-architecting the core code so there are better-defined interfaces
|
||||
between the various components is a goal, with any necessary locking
|
||||
done by the components (e.g. see the self-contained CKeyStore class
|
||||
and its cs_KeyStore lock for example).
|
||||
|
||||
-------
|
||||
Threads
|
||||
|
||||
StartNode : Starts other threads.
|
||||
|
||||
ThreadGetMyExternalIP : Determines outside-the-firewall IP address,
|
||||
sends addr message to connected peers when it determines it.
|
||||
|
||||
ThreadIRCSeed : Joins IRC bootstrapping channel, watching for new
|
||||
peers and advertising this node's IP address.
|
||||
|
||||
ThreadSocketHandler : Sends/Receives data from peers on port 8333.
|
||||
|
||||
ThreadMessageHandler : Higher-level message handling (sending and
|
||||
receiving).
|
||||
|
||||
ThreadOpenConnections : Initiates new connections to peers.
|
||||
|
||||
ThreadTopUpKeyPool : replenishes the keystore's keypool.
|
||||
|
||||
ThreadCleanWalletPassphrase : re-locks an encrypted wallet after user
|
||||
has unlocked it for a period of time.
|
||||
|
||||
SendingDialogStartTransfer : used by pay-via-ip-address code (obsolete)
|
||||
|
||||
ThreadDelayedRepaint : repaint the gui
|
||||
|
||||
ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used
|
||||
in 500ms.
|
||||
|
||||
ThreadRPCServer : Remote procedure call handler, listens on port 8332
|
||||
for connections and services them.
|
||||
|
||||
ThreadBitcoinMiner : Generates bitcoins
|
||||
|
||||
ThreadMapPort : Universal plug-and-play startup/shutdown
|
||||
|
||||
Shutdown : Does an orderly shutdown of everything
|
||||
|
||||
ExitTimeout : Windows-only, sleeps 5 seconds then exits application
|
||||
178
doc/readme-qt.rst
Normal file
@@ -0,0 +1,178 @@
|
||||
Bitcoin-qt: Qt4 GUI for Bitcoin
|
||||
===============================
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
- All functionality of the Wx GUI, including wallet encryption
|
||||
|
||||
- Compatibility with Linux (both GNOME and KDE), MacOSX and Windows
|
||||
|
||||
- Notification on incoming / outgoing transactions (compatible with FreeDesktop and other desktop notification schemes)
|
||||
|
||||
- General interface improvements: Splash screen, tabbed interface
|
||||
|
||||
- Overview page with current balance, unconfirmed balance, and such
|
||||
|
||||
- Better transaction list with status icons, real-time filtering and a context menu
|
||||
|
||||
- Asks for confirmation before sending coins, for your own safety
|
||||
|
||||
- CSV export of transactions and address book (for Excel bookkeeping)
|
||||
|
||||
- Shows alternative icon when connected to testnet, so you never accidentally send real coins during testing
|
||||
|
||||
- Shows a progress bar on initial block download, so that you don't have to wonder how many blocks it needs to download to be up to date
|
||||
|
||||
- Sendmany support, send to multiple recipients at the same time
|
||||
|
||||
- Multiple unit support, can show subdivided bitcoins (uBTC, mBTC) for users that like large numbers
|
||||
|
||||
- Support for English, German, Russian and Dutch languages
|
||||
|
||||
- Address books and transaction table can be sorted by any column
|
||||
|
||||
- Accepts "bitcoin:" URLs from browsers and other sources through drag and drop
|
||||
|
||||
Build instructions
|
||||
===================
|
||||
|
||||
Debian
|
||||
-------
|
||||
|
||||
First, make sure that the required packages for Qt4 development of your
|
||||
distribution are installed, for Debian and Ubuntu these are:
|
||||
|
||||
::
|
||||
|
||||
apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \
|
||||
libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \
|
||||
libssl-dev libdb4.8++-dev
|
||||
|
||||
then execute the following:
|
||||
|
||||
::
|
||||
|
||||
qmake
|
||||
make
|
||||
|
||||
Alternatively, install Qt Creator and open the `bitcoin-qt.pro` file.
|
||||
|
||||
An executable named `bitcoin-qt` will be built.
|
||||
|
||||
|
||||
Windows
|
||||
--------
|
||||
|
||||
Windows build instructions:
|
||||
|
||||
- Download the `QT Windows SDK`_ and install it. You don't need the Symbian stuff, just the desktop Qt.
|
||||
|
||||
- Download and extract the `dependencies archive`_ [#]_, or compile openssl, boost and dbcxx yourself.
|
||||
|
||||
- Copy the contents of the folder "deps" to "X:\\QtSDK\\mingw", replace X:\\ with the location where you installed the Qt SDK. Make sure that the contents of "deps\\include" end up in the current "include" directory.
|
||||
|
||||
- Open the .pro file in QT creator and build as normal (ctrl-B)
|
||||
|
||||
.. _`QT Windows SDK`: http://qt.nokia.com/downloads/sdk-windows-cpp
|
||||
.. _`dependencies archive`: https://download.visucore.com/bitcoin/qtgui_deps_1.zip
|
||||
.. [#] PGP signature: https://download.visucore.com/bitcoin/qtgui_deps_1.zip.sig (signed with RSA key ID `610945D0`_)
|
||||
.. _`610945D0`: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x610945D0
|
||||
|
||||
|
||||
Mac OS X
|
||||
--------
|
||||
|
||||
- Download and install the `Qt Mac OS X SDK`_. It is recommended to also install Apple's Xcode with UNIX tools.
|
||||
|
||||
- Download and install `MacPorts`_.
|
||||
|
||||
- Execute the following commands in a terminal to get the dependencies:
|
||||
|
||||
::
|
||||
|
||||
sudo port selfupdate
|
||||
sudo port install boost db48
|
||||
|
||||
- Open the .pro file in Qt Creator and build as normal (cmd-B)
|
||||
|
||||
.. _`Qt Mac OS X SDK`: http://qt.nokia.com/downloads/sdk-mac-os-cpp
|
||||
.. _`MacPorts`: http://www.macports.org/install.php
|
||||
|
||||
|
||||
Build configuration options
|
||||
============================
|
||||
|
||||
UPNnP port forwarding
|
||||
---------------------
|
||||
|
||||
To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable bitcoin experience), pass the following argument to qmake:
|
||||
|
||||
::
|
||||
|
||||
qmake "USE_UPNP=1"
|
||||
|
||||
(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**)
|
||||
|
||||
This requires miniupnpc for UPnP port mapping. It can be downloaded from
|
||||
http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default.
|
||||
|
||||
Set USE_UPNP to a different value to control this:
|
||||
|
||||
+------------+--------------------------------------------------------------------------+
|
||||
| USE_UPNP=- | no UPnP support, miniupnpc not required; |
|
||||
+------------+--------------------------------------------------------------------------+
|
||||
| USE_UPNP=0 | (the default) built with UPnP, support turned off by default at runtime; |
|
||||
+------------+--------------------------------------------------------------------------+
|
||||
| USE_UPNP=1 | build with UPnP support turned on by default at runtime. |
|
||||
+------------+--------------------------------------------------------------------------+
|
||||
|
||||
Mac OS X users: miniupnpc is currently outdated on MacPorts. An updated Portfile is provided in contrib/miniupnpc within this project.
|
||||
You can execute the following commands in a terminal to install it:
|
||||
|
||||
::
|
||||
|
||||
cd <location of bitcoin-qt>/contrib/miniupnpc
|
||||
sudo port install
|
||||
|
||||
Notification support for recent (k)ubuntu versions
|
||||
---------------------------------------------------
|
||||
|
||||
To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the
|
||||
FreeDesktop notification interface through DBUS using the following qmake option:
|
||||
|
||||
::
|
||||
|
||||
qmake "USE_DBUS=1"
|
||||
|
||||
Berkely DB version warning
|
||||
==========================
|
||||
|
||||
A warning for people using the *static binary* version of Bitcoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**).
|
||||
|
||||
The static binary version of Bitcoin is linked against libdb4.8 (see also `this Debian issue`_).
|
||||
|
||||
Now the nasty thing is that databases from 5.X are not compatible with 4.X.
|
||||
|
||||
If the globally installed development package of Berkely DB installed on your system is 5.X, any source you
|
||||
build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded,
|
||||
and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without
|
||||
significant hassle!
|
||||
|
||||
.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425
|
||||
|
||||
Ubuntu 11.10 warning
|
||||
====================
|
||||
|
||||
Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package
|
||||
installed causes bitcoin-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but
|
||||
isn't yet fixed.
|
||||
|
||||
Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably
|
||||
disable screen reader functionality for Qt apps:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get remove qt-at-spi
|
||||
|
||||
.. _`launchpad bug 857790`: https://bugs.launchpad.net/ubuntu/+source/qt-at-spi/+bug/857790
|
||||
131
doc/release-process.txt
Normal file
@@ -0,0 +1,131 @@
|
||||
* update (commit) version in sources
|
||||
src/serialize.h
|
||||
share/setup.nsi
|
||||
|
||||
* update (commit) version in OSX app bundle
|
||||
contrib/Bitcoin.app/Contents/Info.plist
|
||||
|
||||
* CFBundleShortVersionString should have value like 0.5.0
|
||||
* CFBundleVersion should have value like 500
|
||||
|
||||
* tag version in git
|
||||
|
||||
git tag -a v0.5.0
|
||||
|
||||
* write release notes. git shortlog helps a lot:
|
||||
|
||||
git shortlog --no-merges v0.4.0..
|
||||
|
||||
* create source-only archive
|
||||
|
||||
git archive --format=tar --prefix=bitcoin-0.5.0/ HEAD | \
|
||||
gzip -9c > ~/tmp/bitcoin-0.5.0-src.tar.gz
|
||||
|
||||
* perform gitian builds
|
||||
|
||||
* From a directory containing the bitcoin source, gitian-builder and gitian.sigs
|
||||
export SIGNER=(your gitian key, ie bluematt, sipa, etc)
|
||||
export VERSION=0.5.0
|
||||
cd ./gitian-builder
|
||||
|
||||
* Fetch and build inputs:
|
||||
mkdir -p inputs; cd inputs/
|
||||
wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.6.tar.gz' -O miniupnpc-1.6.tar.gz
|
||||
wget 'http://www.openssl.org/source/openssl-1.0.0e.tar.gz'
|
||||
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
|
||||
wget 'http://downloads.sourceforge.net/project/boost/boost/1.47.0/boost_1_47_0.tar.bz2'
|
||||
wget 'http://download.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz'
|
||||
cd ..
|
||||
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-win32.yml
|
||||
cp build/out/boost-win32-1.47.0-gitian.zip inputs/
|
||||
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win32.yml
|
||||
cp build/out/qt-win32-4.7.4-gitian.zip inputs/
|
||||
|
||||
* Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32:
|
||||
./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian.yml
|
||||
./bin/gsign --signer $SIGNER --release $VERSION --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml
|
||||
cd build/out
|
||||
zip bitcoin-$VERSION-linux-gitian.zip *
|
||||
mv bitcoin-$VERSION-linux-gitian.zip ../../
|
||||
./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
|
||||
./bin/gsign --signer $SIGNER --release $VERSION-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
|
||||
cd build/out
|
||||
zip bitcoin-$VERSION-win32-gitian.zip *
|
||||
mv bitcoin-$VERSION-win32-gitian.zip ../../
|
||||
|
||||
Build output expected:
|
||||
1. linux 32-bit and 64-bit binaries + source (bitcoin-$VERSION-linux-gitian.zip)
|
||||
2. windows 32-bit binary, installer + source (bitcoin-$VERSION-win32-gitian.zip)
|
||||
3. Gitian signatures (in gitian.sigs/$VERSION[-win32]/(your gitian key)/
|
||||
|
||||
* repackage gitian builds for release as stand-alone zip/tar/installer exe
|
||||
|
||||
* Linux .tar.gz:
|
||||
mkdir bitcoin-$VERSION-linux
|
||||
cd bitcoin-$VERSION-linux
|
||||
unzip bitcoin-$VERSION-linux-gitian.zip
|
||||
cd ..; tar czvf bitcoin-$VERSION-linux.tar.gz bitcoin-$VERSION-linux
|
||||
|
||||
* Windows .zip and setup.exe:
|
||||
mkdir bitcoin-$VERSION-win32
|
||||
cd bitcoin-$VERSION-win32
|
||||
unzip bitcoin-$VERSION-win32-gitian.zip
|
||||
mv bitcoin-$VERSION-win32-setup.exe ..
|
||||
cd ..; zip bitcoin-$VERSION-win32.zip bitcoin-$VERSION-win32
|
||||
|
||||
|
||||
* perform Mac build
|
||||
See this blog post for how Gavin set up his build environment and
|
||||
patched macdeployqt to build the OSX release:
|
||||
http://gavintech.blogspot.com/2011/11/deploying-bitcoin-qt-on-osx.html
|
||||
qmake USE_SSL=1 USE_UPNP=1 bitcoin-qt.pro
|
||||
make
|
||||
export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files
|
||||
contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr de,es,ru -dmg -fancy contrib/macdeploy/fancy.plist
|
||||
|
||||
Build output expected:
|
||||
Bitcoin-Qt.dmg
|
||||
|
||||
* upload source and builds to SourceForge
|
||||
|
||||
* create SHA1SUMS for builds, and PGP-sign it
|
||||
|
||||
* update bitcoin.org version
|
||||
|
||||
* update forum version
|
||||
|
||||
* update wiki
|
||||
|
||||
* update wiki download links
|
||||
|
||||
* release gitian-signed gitian archives
|
||||
|
||||
* Collect enough gitian signatures to meet minimum_weight (see contrib/gitian-downloader/*-download-config)
|
||||
|
||||
* From a directory containing bitcoin source, gitian.sigs and gitian zips
|
||||
export VERSION=0.5.0
|
||||
mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian
|
||||
unzip ../bitcoin-$VERSION-linux-gitian.zip
|
||||
mkdir gitian
|
||||
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
|
||||
for file in `ls ../gitian.sigs/$VERSION/`; do
|
||||
cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert
|
||||
cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig
|
||||
done
|
||||
zip bitcoin-$VERSION-linux-gitian.zip *
|
||||
cp bitcoin-$VERSION-linux-gitian.zip ../
|
||||
cd ..
|
||||
mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian
|
||||
unzip ../bitcoin-$VERSION-linux-gitian.zip
|
||||
mkdir gitian
|
||||
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
|
||||
for file in `ls ../gitian.sigs/$VERSION/`; do
|
||||
cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert
|
||||
cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig
|
||||
done
|
||||
zip bitcoin-$VERSION-linux-gitian.zip *
|
||||
cp bitcoin-$VERSION-linux-gitian.zip ../
|
||||
|
||||
* Upload gitian zips to SourceForge
|
||||
|
||||
|
||||
8
irc.h
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
extern bool RecvLine(SOCKET hSocket, string& strLine);
|
||||
extern void ThreadIRCSeed(void* parg);
|
||||
|
||||
extern int nGotIRCAddresses;
|
||||
168
key.h
@@ -1,168 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
// secp160k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 192;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 41;
|
||||
// const unsigned int SIGNATURE_SIZE = 48;
|
||||
//
|
||||
// secp192k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 222;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 49;
|
||||
// const unsigned int SIGNATURE_SIZE = 57;
|
||||
//
|
||||
// secp224k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 250;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 57;
|
||||
// const unsigned int SIGNATURE_SIZE = 66;
|
||||
//
|
||||
// secp256k1:
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 279;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 65;
|
||||
// const unsigned int SIGNATURE_SIZE = 72;
|
||||
//
|
||||
// see www.keylength.com
|
||||
// script supports up to 75 for single byte push
|
||||
|
||||
|
||||
|
||||
class key_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
|
||||
// secure_allocator is defined in serialize.h
|
||||
typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
||||
|
||||
|
||||
|
||||
class CKey
|
||||
{
|
||||
protected:
|
||||
EC_KEY* pkey;
|
||||
bool fSet;
|
||||
|
||||
public:
|
||||
CKey()
|
||||
{
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
|
||||
CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
|
||||
CKey& operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
|
||||
void MakeNewKey()
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
bool SetPrivKey(const CPrivKey& vchPrivKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
CPrivKey GetPrivKey() const
|
||||
{
|
||||
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
||||
CPrivKey vchPrivKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
||||
return vchPrivKey;
|
||||
}
|
||||
|
||||
bool SetPubKey(const vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<unsigned char> GetPubKey() const
|
||||
{
|
||||
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
vector<unsigned char> vchPubKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
bool Sign(uint256 hash, vector<unsigned char>& vchSig)
|
||||
{
|
||||
vchSig.clear();
|
||||
unsigned char pchSig[10000];
|
||||
unsigned int nSize = 0;
|
||||
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
|
||||
return false;
|
||||
vchSig.resize(nSize);
|
||||
memcpy(&vchSig[0], pchSig, nSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetPrivKey(vchPrivKey))
|
||||
return false;
|
||||
return key.Sign(hash, vchSig);
|
||||
}
|
||||
|
||||
static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetPubKey(vchPubKey))
|
||||
return false;
|
||||
return key.Verify(hash, vchSig);
|
||||
}
|
||||
};
|
||||
81
makefile
@@ -1,81 +0,0 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
ifneq "$(BUILD)" "debug"
|
||||
ifneq "$(BUILD)" "release"
|
||||
BUILD=debug
|
||||
endif
|
||||
endif
|
||||
ifeq "$(BUILD)" "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
endif
|
||||
|
||||
|
||||
|
||||
INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include"
|
||||
LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib"
|
||||
LIBS= \
|
||||
-l db_cxx \
|
||||
-l eay32 \
|
||||
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
|
||||
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
|
||||
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
|
||||
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
|
||||
|
||||
|
||||
all: bitcoin.exe
|
||||
|
||||
|
||||
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/util.o: util.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/script.o: script.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/db.o: db.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/net.o: net.cpp $(HEADERS) net.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/market.o: market.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/uibase.o: uibase.cpp uibase.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/sha.o: sha.cpp sha.h
|
||||
g++ -c $(CFLAGS) -O3 -o $@ $<
|
||||
|
||||
obj/irc.o: irc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
|
||||
|
||||
|
||||
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o
|
||||
|
||||
bitcoin.exe: headers.h.gch $(OBJS)
|
||||
-kill /f bitcoin.exe
|
||||
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
-del /Q obj\*
|
||||
-del /Q headers.h.gch
|
||||
@@ -1,89 +0,0 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
ifneq "$(BUILD)" "debug"
|
||||
ifneq "$(BUILD)" "release"
|
||||
BUILD=debug
|
||||
endif
|
||||
endif
|
||||
ifeq "$(BUILD)" "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
endif
|
||||
|
||||
|
||||
|
||||
INCLUDEPATHS= \
|
||||
-I"/usr/include" \
|
||||
-I"/usr/local/include/wx-2.8" \
|
||||
-I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8"
|
||||
|
||||
LIBPATHS= \
|
||||
-L"/usr/lib" \
|
||||
-L"/usr/local/lib"
|
||||
|
||||
LIBS= \
|
||||
-Wl,-Bstatic \
|
||||
-l boost_system -l boost_filesystem \
|
||||
-l db_cxx \
|
||||
-l wx_gtk2$(D)-2.8 \
|
||||
-Wl,-Bdynamic \
|
||||
-l crypto \
|
||||
-l gtk-x11-2.0 -l gthread-2.0 -l SM
|
||||
|
||||
WXDEFS=-D__WXGTK__ -DNOPCH
|
||||
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
|
||||
|
||||
|
||||
all: bitcoin
|
||||
|
||||
|
||||
headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/util.o: util.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/script.o: script.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/db.o: db.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/net.o: net.cpp $(HEADERS) net.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/market.o: market.cpp $(HEADERS) market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/uibase.o: uibase.cpp uibase.h
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
obj/sha.o: sha.cpp sha.h
|
||||
g++ -c $(CFLAGS) -O3 -o $@ $<
|
||||
|
||||
obj/irc.o: irc.cpp $(HEADERS)
|
||||
g++ -c $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
|
||||
|
||||
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \
|
||||
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o
|
||||
|
||||
bitcoin: headers.h.gch $(OBJS)
|
||||
g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
-rm obj/*
|
||||
-rm headers.h.gch
|
||||
77
makefile.vc
@@ -1,77 +0,0 @@
|
||||
# Copyright (c) 2009 Satoshi Nakamoto
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release"
|
||||
BUILD=debug
|
||||
!ENDIF
|
||||
!IF "$(BUILD)" == "debug"
|
||||
D=d
|
||||
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
|
||||
!ENDIF
|
||||
|
||||
|
||||
|
||||
INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include"
|
||||
LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib"
|
||||
LIBS= \
|
||||
libdb47s$(D).lib \
|
||||
libeay32.lib \
|
||||
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
|
||||
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
|
||||
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
|
||||
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h
|
||||
|
||||
|
||||
|
||||
all: bitcoin.exe
|
||||
|
||||
|
||||
obj\util.obj: util.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\script.obj: script.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\db.obj: db.cpp $(HEADERS) market.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\net.obj: net.cpp $(HEADERS) net.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\main.obj: main.cpp $(HEADERS) net.h market.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\market.obj: market.cpp $(HEADERS) market.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\uibase.obj: uibase.cpp uibase.h
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\sha.obj: sha.cpp sha.h
|
||||
cl $(CFLAGS) /O2 /Fo$@ %s
|
||||
|
||||
obj\irc.obj: irc.cpp $(HEADERS)
|
||||
cl $(CFLAGS) /Fo$@ %s
|
||||
|
||||
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
|
||||
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
|
||||
|
||||
|
||||
|
||||
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \
|
||||
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res
|
||||
|
||||
bitcoin.exe: $(OBJS)
|
||||
-kill /f bitcoin.exe & sleep 1
|
||||
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
|
||||
|
||||
clean:
|
||||
-del /Q obj\*
|
||||
-del *.ilk
|
||||
-del *.pdb
|
||||
264
market.cpp
@@ -1,264 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Global state variables
|
||||
//
|
||||
|
||||
//// later figure out how these are persisted
|
||||
map<uint256, CProduct> mapMyProducts;
|
||||
|
||||
|
||||
|
||||
|
||||
map<uint256, CProduct> mapProducts;
|
||||
CCriticalSection cs_mapProducts;
|
||||
|
||||
bool AdvertInsert(const CProduct& product)
|
||||
{
|
||||
uint256 hash = product.GetHash();
|
||||
bool fNew = false;
|
||||
bool fUpdated = false;
|
||||
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
{
|
||||
// Insert or find existing product
|
||||
pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product));
|
||||
CProduct* pproduct = &(*(item.first)).second;
|
||||
fNew = item.second;
|
||||
|
||||
// Update if newer
|
||||
if (product.nSequence > pproduct->nSequence)
|
||||
{
|
||||
*pproduct = product;
|
||||
fUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
//if (fNew)
|
||||
// NotifyProductAdded(hash);
|
||||
//else if (fUpdated)
|
||||
// NotifyProductUpdated(hash);
|
||||
|
||||
return (fNew || fUpdated);
|
||||
}
|
||||
|
||||
void AdvertErase(const CProduct& product)
|
||||
{
|
||||
uint256 hash = product.GetHash();
|
||||
CRITICAL_BLOCK(cs_mapProducts)
|
||||
mapProducts.erase(hash);
|
||||
//NotifyProductDeleted(hash);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
unsigned int Union(T& v1, T& v2)
|
||||
{
|
||||
// v1 = v1 union v2
|
||||
// v1 and v2 must be sorted
|
||||
// returns the number of elements added to v1
|
||||
|
||||
///// need to check that this is equivalent, then delete this comment
|
||||
//vector<unsigned short> vUnion(v1.size() + v2.size());
|
||||
//vUnion.erase(set_union(v1.begin(), v1.end(),
|
||||
// v2.begin(), v2.end(),
|
||||
// vUnion.begin()),
|
||||
// vUnion.end());
|
||||
|
||||
T vUnion;
|
||||
vUnion.reserve(v1.size() + v2.size());
|
||||
set_union(v1.begin(), v1.end(),
|
||||
v2.begin(), v2.end(),
|
||||
back_inserter(vUnion));
|
||||
unsigned int nAdded = vUnion.size() - v1.size();
|
||||
if (nAdded > 0)
|
||||
v1 = vUnion;
|
||||
return nAdded;
|
||||
}
|
||||
|
||||
void CUser::AddAtom(unsigned short nAtom, bool fOrigin)
|
||||
{
|
||||
// Ignore duplicates
|
||||
if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) ||
|
||||
find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end())
|
||||
return;
|
||||
|
||||
//// instead of zero atom, should change to free atom that propagates,
|
||||
//// limited to lower than a certain value like 5 so conflicts quickly
|
||||
// The zero atom never propagates,
|
||||
// new atoms always propagate through the user that created them
|
||||
if (nAtom == 0 || fOrigin)
|
||||
{
|
||||
vector<unsigned short> vTmp(1, nAtom);
|
||||
Union(vAtomsIn, vTmp);
|
||||
if (fOrigin)
|
||||
vAtomsOut.push_back(nAtom);
|
||||
return;
|
||||
}
|
||||
|
||||
vAtomsNew.push_back(nAtom);
|
||||
|
||||
if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty())
|
||||
{
|
||||
// Select atom to flow through to vAtomsOut
|
||||
vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]);
|
||||
|
||||
// Merge vAtomsNew into vAtomsIn
|
||||
sort(vAtomsNew.begin(), vAtomsNew.end());
|
||||
Union(vAtomsIn, vAtomsNew);
|
||||
vAtomsNew.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin)
|
||||
{
|
||||
CReviewDB reviewdb;
|
||||
map<uint256, vector<unsigned short> > pmapPropagate[2];
|
||||
pmapPropagate[0][hashUserStart] = vAtoms;
|
||||
|
||||
for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)
|
||||
{
|
||||
map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];
|
||||
map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];
|
||||
|
||||
for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)
|
||||
{
|
||||
const uint256& hashUser = (*mi).first;
|
||||
const vector<unsigned short>& vReceived = (*mi).second;
|
||||
|
||||
///// this would be a lot easier on the database if it put the new atom at the beginning of the list,
|
||||
///// so the change would be right next to the vector size.
|
||||
|
||||
// Read user
|
||||
CUser user;
|
||||
reviewdb.ReadUser(hashUser, user);
|
||||
unsigned int nIn = user.vAtomsIn.size();
|
||||
unsigned int nNew = user.vAtomsNew.size();
|
||||
unsigned int nOut = user.vAtomsOut.size();
|
||||
|
||||
// Add atoms received
|
||||
foreach(unsigned short nAtom, vReceived)
|
||||
user.AddAtom(nAtom, fOrigin);
|
||||
fOrigin = false;
|
||||
|
||||
// Don't bother writing to disk if no changes
|
||||
if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew)
|
||||
continue;
|
||||
|
||||
// Propagate
|
||||
if (user.vAtomsOut.size() > nOut)
|
||||
foreach(const uint256& hash, user.vLinksOut)
|
||||
mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end());
|
||||
|
||||
// Write back
|
||||
if (!reviewdb.WriteUser(hashUser, user))
|
||||
return false;
|
||||
}
|
||||
mapFrom.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CReview::AcceptReview()
|
||||
{
|
||||
// Timestamp
|
||||
nTime = GetTime();
|
||||
|
||||
// Check signature
|
||||
if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig))
|
||||
return false;
|
||||
|
||||
CReviewDB reviewdb;
|
||||
|
||||
// Add review text to recipient
|
||||
vector<CReview> vReviews;
|
||||
reviewdb.ReadReviews(hashTo, vReviews);
|
||||
vReviews.push_back(*this);
|
||||
if (!reviewdb.WriteReviews(hashTo, vReviews))
|
||||
return false;
|
||||
|
||||
// Add link from sender
|
||||
CUser user;
|
||||
uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end());
|
||||
reviewdb.ReadUser(hashFrom, user);
|
||||
user.vLinksOut.push_back(hashTo);
|
||||
if (!reviewdb.WriteUser(hashFrom, user))
|
||||
return false;
|
||||
|
||||
reviewdb.Close();
|
||||
|
||||
// Propagate atoms to recipient
|
||||
vector<unsigned short> vZeroAtom(1, 0);
|
||||
if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool CProduct::CheckSignature()
|
||||
{
|
||||
return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig));
|
||||
}
|
||||
|
||||
bool CProduct::CheckProduct()
|
||||
{
|
||||
if (!CheckSignature())
|
||||
return false;
|
||||
|
||||
// Make sure it's a summary product
|
||||
if (!mapDetails.empty() || !vOrderForm.empty())
|
||||
return false;
|
||||
|
||||
// Look up seller's atom count
|
||||
CReviewDB reviewdb("r");
|
||||
CUser user;
|
||||
reviewdb.ReadUser(GetUserHash(), user);
|
||||
nAtoms = user.GetAtomCount();
|
||||
reviewdb.Close();
|
||||
|
||||
////// delme, this is now done by AdvertInsert
|
||||
//// Store to memory
|
||||
//CRITICAL_BLOCK(cs_mapProducts)
|
||||
// mapProducts[GetHash()] = *this;
|
||||
|
||||
return true;
|
||||
}
|
||||
182
market.h
@@ -1,182 +0,0 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
class CUser;
|
||||
class CReview;
|
||||
class CProduct;
|
||||
|
||||
static const unsigned int nFlowthroughRate = 2;
|
||||
|
||||
|
||||
|
||||
|
||||
bool AdvertInsert(const CProduct& product);
|
||||
void AdvertErase(const CProduct& product);
|
||||
bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CUser
|
||||
{
|
||||
public:
|
||||
vector<unsigned short> vAtomsIn;
|
||||
vector<unsigned short> vAtomsNew;
|
||||
vector<unsigned short> vAtomsOut;
|
||||
vector<uint256> vLinksOut;
|
||||
|
||||
CUser()
|
||||
{
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(vAtomsIn);
|
||||
READWRITE(vAtomsNew);
|
||||
READWRITE(vAtomsOut);
|
||||
READWRITE(vLinksOut);
|
||||
)
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
vAtomsIn.clear();
|
||||
vAtomsNew.clear();
|
||||
vAtomsOut.clear();
|
||||
vLinksOut.clear();
|
||||
}
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
|
||||
|
||||
int GetAtomCount() const
|
||||
{
|
||||
return (vAtomsIn.size() + vAtomsNew.size());
|
||||
}
|
||||
|
||||
void AddAtom(unsigned short nAtom, bool fOrigin);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CReview
|
||||
{
|
||||
public:
|
||||
int nVersion;
|
||||
uint256 hashTo;
|
||||
map<string, string> mapValue;
|
||||
vector<unsigned char> vchPubKeyFrom;
|
||||
vector<unsigned char> vchSig;
|
||||
|
||||
// memory only
|
||||
unsigned int nTime;
|
||||
int nAtoms;
|
||||
|
||||
|
||||
CReview()
|
||||
{
|
||||
nVersion = 1;
|
||||
hashTo = 0;
|
||||
nTime = 0;
|
||||
nAtoms = 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
if (!(nType & SER_DISK))
|
||||
READWRITE(hashTo);
|
||||
READWRITE(mapValue);
|
||||
READWRITE(vchPubKeyFrom);
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(vchSig);
|
||||
)
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
|
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
|
||||
|
||||
|
||||
bool AcceptReview();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CProduct
|
||||
{
|
||||
public:
|
||||
int nVersion;
|
||||
CAddress addr;
|
||||
map<string, string> mapValue;
|
||||
map<string, string> mapDetails;
|
||||
vector<pair<string, string> > vOrderForm;
|
||||
unsigned int nSequence;
|
||||
vector<unsigned char> vchPubKeyFrom;
|
||||
vector<unsigned char> vchSig;
|
||||
|
||||
// disk only
|
||||
int nAtoms;
|
||||
|
||||
// memory only
|
||||
set<unsigned int> setSources;
|
||||
|
||||
CProduct()
|
||||
{
|
||||
nVersion = 1;
|
||||
nAtoms = 0;
|
||||
nSequence = 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
READWRITE(this->nVersion);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(addr);
|
||||
READWRITE(mapValue);
|
||||
if (!(nType & SER_GETHASH))
|
||||
{
|
||||
READWRITE(mapDetails);
|
||||
READWRITE(vOrderForm);
|
||||
READWRITE(nSequence);
|
||||
}
|
||||
READWRITE(vchPubKeyFrom);
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(vchSig);
|
||||
if (nType & SER_DISK)
|
||||
READWRITE(nAtoms);
|
||||
)
|
||||
|
||||
uint256 GetHash() const { return SerializeHash(*this); }
|
||||
uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
|
||||
uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
|
||||
|
||||
|
||||
bool CheckSignature();
|
||||
bool CheckProduct();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern map<uint256, CProduct> mapProducts;
|
||||
extern CCriticalSection cs_mapProducts;
|
||||
extern map<uint256, CProduct> mapMyProducts;
|
||||
1127
script.cpp
63
scripts/qt/extract_strings_qt.py
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
Extract _("...") strings for translation and convert to Qt4 stringdefs so that
|
||||
they can be picked up by Qt linguist.
|
||||
'''
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
OUT_CPP="src/qt/bitcoinstrings.cpp"
|
||||
EMPTY=['""']
|
||||
|
||||
def parse_po(text):
|
||||
"""
|
||||
Parse 'po' format produced by xgettext.
|
||||
Return a list of (msgid,msgstr) tuples.
|
||||
"""
|
||||
messages = []
|
||||
msgid = []
|
||||
msgstr = []
|
||||
in_msgid = False
|
||||
in_msgstr = False
|
||||
|
||||
for line in text.split('\n'):
|
||||
line = line.rstrip('\r')
|
||||
if line.startswith('msgid '):
|
||||
if in_msgstr:
|
||||
messages.append((msgid, msgstr))
|
||||
in_msgstr = False
|
||||
# message start
|
||||
in_msgid = True
|
||||
|
||||
msgid = [line[6:]]
|
||||
elif line.startswith('msgstr '):
|
||||
in_msgid = False
|
||||
in_msgstr = True
|
||||
msgstr = [line[7:]]
|
||||
elif line.startswith('"'):
|
||||
if in_msgid:
|
||||
msgid.append(line)
|
||||
if in_msgstr:
|
||||
msgstr.append(line)
|
||||
|
||||
if in_msgstr:
|
||||
messages.append((msgid, msgstr))
|
||||
|
||||
return messages
|
||||
|
||||
files = ['src/base58.h', 'src/bignum.h', 'src/db.cpp', 'src/db.h', 'src/headers.h', 'src/init.cpp', 'src/init.h', 'src/irc.cpp', 'src/irc.h', 'src/key.h', 'src/main.cpp', 'src/main.h', 'src/net.cpp', 'src/net.h', 'src/noui.h', 'src/script.cpp', 'src/script.h', 'src/serialize.h', 'src/strlcpy.h', 'src/uint256.h', 'src/util.cpp', 'src/util.h']
|
||||
|
||||
# xgettext -n --keyword=_ $FILES
|
||||
child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE)
|
||||
(out, err) = child.communicate()
|
||||
|
||||
messages = parse_po(out)
|
||||
|
||||
f = open(OUT_CPP, 'w')
|
||||
f.write('#include <QtGlobal>\n')
|
||||
f.write('// Automatically generated by extract_strings.py\n')
|
||||
f.write('static const char *bitcoin_strings[] = {')
|
||||
for (msgid, msgstr) in messages:
|
||||
if msgid != EMPTY:
|
||||
f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid)))
|
||||
f.write('};')
|
||||
f.close()
|
||||
BIN
scripts/qt/img/reload.xcf
Normal file
43
scripts/qt/make_spinner.py
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
# W.J. van der Laan, 2011
|
||||
# Make spinning .mng animation from a .png
|
||||
# Requires imagemagick 6.7+
|
||||
from __future__ import division
|
||||
from os import path
|
||||
from PIL import Image
|
||||
from subprocess import Popen
|
||||
|
||||
SRC='img/reload_scaled.png'
|
||||
DST='../../src/qt/res/movies/update_spinner.mng'
|
||||
TMPDIR='/tmp'
|
||||
TMPNAME='tmp-%03i.png'
|
||||
NUMFRAMES=35
|
||||
FRAMERATE=10.0
|
||||
CONVERT='convert'
|
||||
CLOCKWISE=True
|
||||
DSIZE=(16,16)
|
||||
|
||||
im_src = Image.open(SRC)
|
||||
|
||||
if CLOCKWISE:
|
||||
im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
|
||||
def frame_to_filename(frame):
|
||||
return path.join(TMPDIR, TMPNAME % frame)
|
||||
|
||||
frame_files = []
|
||||
for frame in xrange(NUMFRAMES):
|
||||
rotation = (frame + 0.5) / NUMFRAMES * 360.0
|
||||
if CLOCKWISE:
|
||||
rotation = -rotation
|
||||
im_new = im_src.rotate(rotation, Image.BICUBIC)
|
||||
im_new.thumbnail(DSIZE, Image.ANTIALIAS)
|
||||
outfile = frame_to_filename(frame)
|
||||
im_new.save(outfile, 'png')
|
||||
frame_files.append(outfile)
|
||||
|
||||
p = Popen([CONVERT, "-delay", str(FRAMERATE), "-dispose", "2"] + frame_files + [DST])
|
||||
p.communicate()
|
||||
|
||||
|
||||
|
||||
9
scripts/qt/make_windows_icon.py
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# create multiresolution windows icon
|
||||
ICON_SRC=../../src/qt/res/icons/bitcoin.png
|
||||
ICON_DST=../../src/qt/res/icons/bitcoin.ico
|
||||
convert ${ICON_SRC} -resize 16x16 bitcoin-16.png
|
||||
convert ${ICON_SRC} -resize 32x32 bitcoin-32.png
|
||||
convert ${ICON_SRC} -resize 48x48 bitcoin-48.png
|
||||
convert bitcoin-16.png bitcoin-32.png bitcoin-48.png ${ICON_DST}
|
||||
|
||||
554
sha.cpp
@@ -1,554 +0,0 @@
|
||||
// This file is public domain
|
||||
// SHA routines extracted as a standalone file from:
|
||||
// Crypto++: a C++ Class Library of Cryptographic Schemes
|
||||
// Version 5.5.2 (9/24/2007)
|
||||
// http://www.cryptopp.com
|
||||
|
||||
// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
|
||||
|
||||
// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
|
||||
// Both are in the public domain.
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
#include "sha.h"
|
||||
|
||||
namespace CryptoPP
|
||||
{
|
||||
|
||||
// start of Steve Reid's code
|
||||
|
||||
#define blk0(i) (W[i] = data[i])
|
||||
#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
|
||||
|
||||
void SHA1::InitState(HashWordType *state)
|
||||
{
|
||||
state[0] = 0x67452301L;
|
||||
state[1] = 0xEFCDAB89L;
|
||||
state[2] = 0x98BADCFEL;
|
||||
state[3] = 0x10325476L;
|
||||
state[4] = 0xC3D2E1F0L;
|
||||
}
|
||||
|
||||
#define f1(x,y,z) (z^(x&(y^z)))
|
||||
#define f2(x,y,z) (x^y^z)
|
||||
#define f3(x,y,z) ((x&y)|(z&(x|y)))
|
||||
#define f4(x,y,z) (x^y^z)
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
|
||||
#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
|
||||
#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
|
||||
#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
|
||||
|
||||
void SHA1::Transform(word32 *state, const word32 *data)
|
||||
{
|
||||
word32 W[16];
|
||||
/* Copy context->state[] to working vars */
|
||||
word32 a = state[0];
|
||||
word32 b = state[1];
|
||||
word32 c = state[2];
|
||||
word32 d = state[3];
|
||||
word32 e = state[4];
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
}
|
||||
|
||||
// end of Steve Reid's code
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void SHA224::InitState(HashWordType *state)
|
||||
{
|
||||
static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
|
||||
memcpy(state, s, sizeof(s));
|
||||
}
|
||||
|
||||
void SHA256::InitState(HashWordType *state)
|
||||
{
|
||||
static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
||||
memcpy(state, s, sizeof(s));
|
||||
}
|
||||
|
||||
static const word32 SHA256_K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
|
||||
|
||||
#define Ch(x,y,z) (z^(x&(y^z)))
|
||||
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
||||
|
||||
#define a(i) T[(0-i)&7]
|
||||
#define b(i) T[(1-i)&7]
|
||||
#define c(i) T[(2-i)&7]
|
||||
#define d(i) T[(3-i)&7]
|
||||
#define e(i) T[(4-i)&7]
|
||||
#define f(i) T[(5-i)&7]
|
||||
#define g(i) T[(6-i)&7]
|
||||
#define h(i) T[(7-i)&7]
|
||||
|
||||
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\
|
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
|
||||
|
||||
// for SHA256
|
||||
#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
|
||||
#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
|
||||
#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
|
||||
#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
|
||||
|
||||
void SHA256::Transform(word32 *state, const word32 *data)
|
||||
{
|
||||
word32 W[16];
|
||||
word32 T[8];
|
||||
/* Copy context->state[] to working vars */
|
||||
memcpy(T, state, sizeof(T));
|
||||
/* 64 operations, partially loop unrolled */
|
||||
for (unsigned int j=0; j<64; j+=16)
|
||||
{
|
||||
R( 0); R( 1); R( 2); R( 3);
|
||||
R( 4); R( 5); R( 6); R( 7);
|
||||
R( 8); R( 9); R(10); R(11);
|
||||
R(12); R(13); R(14); R(15);
|
||||
}
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a(0);
|
||||
state[1] += b(0);
|
||||
state[2] += c(0);
|
||||
state[3] += d(0);
|
||||
state[4] += e(0);
|
||||
state[5] += f(0);
|
||||
state[6] += g(0);
|
||||
state[7] += h(0);
|
||||
}
|
||||
|
||||
/*
|
||||
// smaller but slower
|
||||
void SHA256_Transform(word32 *state, const word32 *data)
|
||||
{
|
||||
word32 T[20];
|
||||
word32 W[32];
|
||||
unsigned int i = 0, j = 0;
|
||||
word32 *t = T+8;
|
||||
|
||||
memcpy(t, state, 8*4);
|
||||
word32 e = t[4], a = t[0];
|
||||
|
||||
do
|
||||
{
|
||||
word32 w = data[j];
|
||||
W[j] = w;
|
||||
w += K[j];
|
||||
w += t[7];
|
||||
w += S1(e);
|
||||
w += Ch(e, t[5], t[6]);
|
||||
e = t[3] + w;
|
||||
t[3] = t[3+8] = e;
|
||||
w += S0(t[0]);
|
||||
a = w + Maj(a, t[1], t[2]);
|
||||
t[-1] = t[7] = a;
|
||||
--t;
|
||||
++j;
|
||||
if (j%8 == 0)
|
||||
t += 8;
|
||||
} while (j<16);
|
||||
|
||||
do
|
||||
{
|
||||
i = j&0xf;
|
||||
word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7];
|
||||
W[i+16] = W[i] = w;
|
||||
w += K[j];
|
||||
w += t[7];
|
||||
w += S1(e);
|
||||
w += Ch(e, t[5], t[6]);
|
||||
e = t[3] + w;
|
||||
t[3] = t[3+8] = e;
|
||||
w += S0(t[0]);
|
||||
a = w + Maj(a, t[1], t[2]);
|
||||
t[-1] = t[7] = a;
|
||||
|
||||
w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7];
|
||||
W[(i+1)+16] = W[(i+1)] = w;
|
||||
w += K[j+1];
|
||||
w += (t-1)[7];
|
||||
w += S1(e);
|
||||
w += Ch(e, (t-1)[5], (t-1)[6]);
|
||||
e = (t-1)[3] + w;
|
||||
(t-1)[3] = (t-1)[3+8] = e;
|
||||
w += S0((t-1)[0]);
|
||||
a = w + Maj(a, (t-1)[1], (t-1)[2]);
|
||||
(t-1)[-1] = (t-1)[7] = a;
|
||||
|
||||
t-=2;
|
||||
j+=2;
|
||||
if (j%8 == 0)
|
||||
t += 8;
|
||||
} while (j<64);
|
||||
|
||||
state[0] += a;
|
||||
state[1] += t[1];
|
||||
state[2] += t[2];
|
||||
state[3] += t[3];
|
||||
state[4] += e;
|
||||
state[5] += t[5];
|
||||
state[6] += t[6];
|
||||
state[7] += t[7];
|
||||
}
|
||||
*/
|
||||
|
||||
#undef S0
|
||||
#undef S1
|
||||
#undef s0
|
||||
#undef s1
|
||||
#undef R
|
||||
|
||||
// *************************************************************
|
||||
|
||||
#ifdef WORD64_AVAILABLE
|
||||
|
||||
void SHA384::InitState(HashWordType *state)
|
||||
{
|
||||
static const word64 s[8] = {
|
||||
W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
|
||||
W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
|
||||
W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
|
||||
W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)};
|
||||
memcpy(state, s, sizeof(s));
|
||||
}
|
||||
|
||||
void SHA512::InitState(HashWordType *state)
|
||||
{
|
||||
static const word64 s[8] = {
|
||||
W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
|
||||
W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
|
||||
W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
|
||||
W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)};
|
||||
memcpy(state, s, sizeof(s));
|
||||
}
|
||||
|
||||
CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = {
|
||||
W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
|
||||
W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
|
||||
W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
|
||||
W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
|
||||
W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
|
||||
W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
|
||||
W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
|
||||
W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
|
||||
W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
|
||||
W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
|
||||
W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
|
||||
W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
|
||||
W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
|
||||
W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
|
||||
W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
|
||||
W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
|
||||
W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
|
||||
W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
|
||||
W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
|
||||
W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
|
||||
W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
|
||||
W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
|
||||
W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
|
||||
W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
|
||||
W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
|
||||
W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
|
||||
W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
|
||||
W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
|
||||
W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
|
||||
W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
|
||||
W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
|
||||
W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
|
||||
W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
|
||||
W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
|
||||
W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
|
||||
W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
|
||||
W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
|
||||
W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
|
||||
W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
|
||||
W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
|
||||
// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version
|
||||
CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
__asm__ __volatile__
|
||||
(
|
||||
".intel_syntax noprefix;"
|
||||
AS1( push ebx)
|
||||
AS2( mov ebx, eax)
|
||||
#else
|
||||
AS1( push ebx)
|
||||
AS1( push esi)
|
||||
AS1( push edi)
|
||||
AS2( lea ebx, SHA512_K)
|
||||
#endif
|
||||
|
||||
AS2( mov eax, esp)
|
||||
AS2( and esp, 0xfffffff0)
|
||||
AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state
|
||||
AS1( push eax)
|
||||
AS2( xor eax, eax)
|
||||
AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying
|
||||
AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8
|
||||
|
||||
AS2( movq mm4, [ecx+0*8])
|
||||
AS2( movq [edi+0*8], mm4)
|
||||
AS2( movq mm0, [ecx+1*8])
|
||||
AS2( movq [edi+1*8], mm0)
|
||||
AS2( movq mm0, [ecx+2*8])
|
||||
AS2( movq [edi+2*8], mm0)
|
||||
AS2( movq mm0, [ecx+3*8])
|
||||
AS2( movq [edi+3*8], mm0)
|
||||
AS2( movq mm5, [ecx+4*8])
|
||||
AS2( movq [edi+4*8], mm5)
|
||||
AS2( movq mm0, [ecx+5*8])
|
||||
AS2( movq [edi+5*8], mm0)
|
||||
AS2( movq mm0, [ecx+6*8])
|
||||
AS2( movq [edi+6*8], mm0)
|
||||
AS2( movq mm0, [ecx+7*8])
|
||||
AS2( movq [edi+7*8], mm0)
|
||||
ASJ( jmp, 0, f)
|
||||
|
||||
#define SSE2_S0_S1(r, a, b, c) \
|
||||
AS2( movq mm6, r)\
|
||||
AS2( psrlq r, a)\
|
||||
AS2( movq mm7, r)\
|
||||
AS2( psllq mm6, 64-c)\
|
||||
AS2( pxor mm7, mm6)\
|
||||
AS2( psrlq r, b-a)\
|
||||
AS2( pxor mm7, r)\
|
||||
AS2( psllq mm6, c-b)\
|
||||
AS2( pxor mm7, mm6)\
|
||||
AS2( psrlq r, c-b)\
|
||||
AS2( pxor r, mm7)\
|
||||
AS2( psllq mm6, b-a)\
|
||||
AS2( pxor r, mm6)
|
||||
|
||||
#define SSE2_s0(r, a, b, c) \
|
||||
AS2( movdqa xmm6, r)\
|
||||
AS2( psrlq r, a)\
|
||||
AS2( movdqa xmm7, r)\
|
||||
AS2( psllq xmm6, 64-c)\
|
||||
AS2( pxor xmm7, xmm6)\
|
||||
AS2( psrlq r, b-a)\
|
||||
AS2( pxor xmm7, r)\
|
||||
AS2( psrlq r, c-b)\
|
||||
AS2( pxor r, xmm7)\
|
||||
AS2( psllq xmm6, c-a)\
|
||||
AS2( pxor r, xmm6)
|
||||
|
||||
#define SSE2_s1(r, a, b, c) \
|
||||
AS2( movdqa xmm6, r)\
|
||||
AS2( psrlq r, a)\
|
||||
AS2( movdqa xmm7, r)\
|
||||
AS2( psllq xmm6, 64-c)\
|
||||
AS2( pxor xmm7, xmm6)\
|
||||
AS2( psrlq r, b-a)\
|
||||
AS2( pxor xmm7, r)\
|
||||
AS2( psllq xmm6, c-b)\
|
||||
AS2( pxor xmm7, xmm6)\
|
||||
AS2( psrlq r, c-b)\
|
||||
AS2( pxor r, xmm7)
|
||||
|
||||
ASL(SHA512_Round)
|
||||
// k + w is in mm0, a is in mm4, e is in mm5
|
||||
AS2( paddq mm0, [edi+7*8]) // h
|
||||
AS2( movq mm2, [edi+5*8]) // f
|
||||
AS2( movq mm3, [edi+6*8]) // g
|
||||
AS2( pxor mm2, mm3)
|
||||
AS2( pand mm2, mm5)
|
||||
SSE2_S0_S1(mm5,14,18,41)
|
||||
AS2( pxor mm2, mm3)
|
||||
AS2( paddq mm0, mm2) // h += Ch(e,f,g)
|
||||
AS2( paddq mm5, mm0) // h += S1(e)
|
||||
AS2( movq mm2, [edi+1*8]) // b
|
||||
AS2( movq mm1, mm2)
|
||||
AS2( por mm2, mm4)
|
||||
AS2( pand mm2, [edi+2*8]) // c
|
||||
AS2( pand mm1, mm4)
|
||||
AS2( por mm1, mm2)
|
||||
AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c)
|
||||
AS2( paddq mm5, [edi+3*8]) // e = d + h
|
||||
AS2( movq [edi+3*8], mm5)
|
||||
AS2( movq [edi+11*8], mm5)
|
||||
SSE2_S0_S1(mm4,28,34,39) // S0(a)
|
||||
AS2( paddq mm4, mm1) // a = temp + S0(a)
|
||||
AS2( movq [edi-8], mm4)
|
||||
AS2( movq [edi+7*8], mm4)
|
||||
AS1( ret)
|
||||
|
||||
// first 16 rounds
|
||||
ASL(0)
|
||||
AS2( movq mm0, [edx+eax*8])
|
||||
AS2( movq [esi+eax*8], mm0)
|
||||
AS2( movq [esi+eax*8+16*8], mm0)
|
||||
AS2( paddq mm0, [ebx+eax*8])
|
||||
ASC( call, SHA512_Round)
|
||||
AS1( inc eax)
|
||||
AS2( sub edi, 8)
|
||||
AS2( test eax, 7)
|
||||
ASJ( jnz, 0, b)
|
||||
AS2( add edi, 8*8)
|
||||
AS2( cmp eax, 16)
|
||||
ASJ( jne, 0, b)
|
||||
|
||||
// rest of the rounds
|
||||
AS2( movdqu xmm0, [esi+(16-2)*8])
|
||||
ASL(1)
|
||||
// data expansion, W[i-2] already in xmm0
|
||||
AS2( movdqu xmm3, [esi])
|
||||
AS2( paddq xmm3, [esi+(16-7)*8])
|
||||
AS2( movdqa xmm2, [esi+(16-15)*8])
|
||||
SSE2_s1(xmm0, 6, 19, 61)
|
||||
AS2( paddq xmm0, xmm3)
|
||||
SSE2_s0(xmm2, 1, 7, 8)
|
||||
AS2( paddq xmm0, xmm2)
|
||||
AS2( movdq2q mm0, xmm0)
|
||||
AS2( movhlps xmm1, xmm0)
|
||||
AS2( paddq mm0, [ebx+eax*8])
|
||||
AS2( movlps [esi], xmm0)
|
||||
AS2( movlps [esi+8], xmm1)
|
||||
AS2( movlps [esi+8*16], xmm0)
|
||||
AS2( movlps [esi+8*17], xmm1)
|
||||
// 2 rounds
|
||||
ASC( call, SHA512_Round)
|
||||
AS2( sub edi, 8)
|
||||
AS2( movdq2q mm0, xmm1)
|
||||
AS2( paddq mm0, [ebx+eax*8+8])
|
||||
ASC( call, SHA512_Round)
|
||||
// update indices and loop
|
||||
AS2( add esi, 16)
|
||||
AS2( add eax, 2)
|
||||
AS2( sub edi, 8)
|
||||
AS2( test eax, 7)
|
||||
ASJ( jnz, 1, b)
|
||||
// do housekeeping every 8 rounds
|
||||
AS2( mov esi, 0xf)
|
||||
AS2( and esi, eax)
|
||||
AS2( lea esi, [esp+4+20*8+8+esi*8])
|
||||
AS2( add edi, 8*8)
|
||||
AS2( cmp eax, 80)
|
||||
ASJ( jne, 1, b)
|
||||
|
||||
#define SSE2_CombineState(i) \
|
||||
AS2( movq mm0, [edi+i*8])\
|
||||
AS2( paddq mm0, [ecx+i*8])\
|
||||
AS2( movq [ecx+i*8], mm0)
|
||||
|
||||
SSE2_CombineState(0)
|
||||
SSE2_CombineState(1)
|
||||
SSE2_CombineState(2)
|
||||
SSE2_CombineState(3)
|
||||
SSE2_CombineState(4)
|
||||
SSE2_CombineState(5)
|
||||
SSE2_CombineState(6)
|
||||
SSE2_CombineState(7)
|
||||
|
||||
AS1( pop esp)
|
||||
AS1( emms)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
AS1( pop ebx)
|
||||
".att_syntax prefix;"
|
||||
:
|
||||
: "a" (SHA512_K), "c" (state), "d" (data)
|
||||
: "%esi", "%edi", "memory", "cc"
|
||||
);
|
||||
#else
|
||||
AS1( pop edi)
|
||||
AS1( pop esi)
|
||||
AS1( pop ebx)
|
||||
AS1( ret)
|
||||
#endif
|
||||
}
|
||||
#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
|
||||
|
||||
void SHA512::Transform(word64 *state, const word64 *data)
|
||||
{
|
||||
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
|
||||
if (HasSSE2())
|
||||
{
|
||||
SHA512_SSE2_Transform(state, data);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
|
||||
#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
|
||||
#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
|
||||
#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
|
||||
|
||||
#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\
|
||||
d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
|
||||
|
||||
word64 W[16];
|
||||
word64 T[8];
|
||||
/* Copy context->state[] to working vars */
|
||||
memcpy(T, state, sizeof(T));
|
||||
/* 80 operations, partially loop unrolled */
|
||||
for (unsigned int j=0; j<80; j+=16)
|
||||
{
|
||||
R( 0); R( 1); R( 2); R( 3);
|
||||
R( 4); R( 5); R( 6); R( 7);
|
||||
R( 8); R( 9); R(10); R(11);
|
||||
R(12); R(13); R(14); R(15);
|
||||
}
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a(0);
|
||||
state[1] += b(0);
|
||||
state[2] += c(0);
|
||||
state[3] += d(0);
|
||||
state[4] += e(0);
|
||||
state[5] += f(0);
|
||||
state[6] += g(0);
|
||||
state[7] += h(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
177
sha.h
@@ -1,177 +0,0 @@
|
||||
// This file is public domain
|
||||
// SHA routines extracted as a standalone file from:
|
||||
// Crypto++: a C++ Class Library of Cryptographic Schemes
|
||||
// Version 5.5.2 (9/24/2007)
|
||||
// http://www.cryptopp.com
|
||||
#ifndef CRYPTOPP_SHA_H
|
||||
#define CRYPTOPP_SHA_H
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace CryptoPP
|
||||
{
|
||||
|
||||
//
|
||||
// Dependencies
|
||||
//
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word16;
|
||||
typedef unsigned int word32;
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef unsigned __int64 word64;
|
||||
#else
|
||||
typedef unsigned long long word64;
|
||||
#endif
|
||||
|
||||
template <class T> inline T rotlFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return T((x<<y) | (x>>(sizeof(T)*8-y)));
|
||||
}
|
||||
|
||||
template <class T> inline T rotrFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return T((x>>y) | (x<<(sizeof(T)*8-y)));
|
||||
}
|
||||
|
||||
// ************** endian reversal ***************
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1400
|
||||
#define CRYPTOPP_FAST_ROTATE(x) 1
|
||||
#elif _MSC_VER >= 1300
|
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
|
||||
#else
|
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
|
||||
#endif
|
||||
#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
|
||||
(defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
|
||||
#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
|
||||
#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions
|
||||
#define CRYPTOPP_FAST_ROTATE(x) 1
|
||||
#else
|
||||
#define CRYPTOPP_FAST_ROTATE(x) 0
|
||||
#endif
|
||||
|
||||
inline byte ByteReverse(byte value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
inline word16 ByteReverse(word16 value)
|
||||
{
|
||||
#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
|
||||
return bswap_16(value);
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1300
|
||||
return _byteswap_ushort(value);
|
||||
#else
|
||||
return rotlFixed(value, 8U);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline word32 ByteReverse(word32 value)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
|
||||
return value;
|
||||
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
|
||||
return bswap_32(value);
|
||||
#elif defined(__MWERKS__) && TARGET_CPU_PPC
|
||||
return (word32)__lwbrx(&value,0);
|
||||
#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
|
||||
return _byteswap_ulong(value);
|
||||
#elif CRYPTOPP_FAST_ROTATE(32)
|
||||
// 5 instructions with rotate instruction, 9 without
|
||||
return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
|
||||
#else
|
||||
// 6 instructions with rotate instruction, 8 without
|
||||
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
|
||||
return rotlFixed(value, 16U);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WORD64_AVAILABLE
|
||||
inline word64 ByteReverse(word64 value)
|
||||
{
|
||||
#if defined(__GNUC__) && defined(__x86_64__)
|
||||
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
|
||||
return value;
|
||||
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
|
||||
return bswap_64(value);
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1300
|
||||
return _byteswap_uint64(value);
|
||||
#elif defined(CRYPTOPP_SLOW_WORD64)
|
||||
return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
|
||||
#else
|
||||
value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
|
||||
value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
|
||||
return rotlFixed(value, 32U);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// SHA
|
||||
//
|
||||
|
||||
// http://www.weidai.com/scan-mirror/md.html#SHA-1
|
||||
class SHA1
|
||||
{
|
||||
public:
|
||||
typedef word32 HashWordType;
|
||||
static void InitState(word32 *state);
|
||||
static void Transform(word32 *digest, const word32 *data);
|
||||
static const char * StaticAlgorithmName() {return "SHA-1";}
|
||||
};
|
||||
|
||||
typedef SHA1 SHA; // for backwards compatibility
|
||||
|
||||
// implements the SHA-256 standard
|
||||
class SHA256
|
||||
{
|
||||
public:
|
||||
typedef word32 HashWordType;
|
||||
static void InitState(word32 *state);
|
||||
static void Transform(word32 *digest, const word32 *data);
|
||||
static const char * StaticAlgorithmName() {return "SHA-256";}
|
||||
};
|
||||
|
||||
// implements the SHA-224 standard
|
||||
class SHA224
|
||||
{
|
||||
public:
|
||||
typedef word32 HashWordType;
|
||||
static void InitState(word32 *state);
|
||||
static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);}
|
||||
static const char * StaticAlgorithmName() {return "SHA-224";}
|
||||
};
|
||||
|
||||
#ifdef WORD64_AVAILABLE
|
||||
|
||||
// implements the SHA-512 standard
|
||||
class SHA512
|
||||
{
|
||||
public:
|
||||
typedef word64 HashWordType;
|
||||
static void InitState(word64 *state);
|
||||
static void Transform(word64 *digest, const word64 *data);
|
||||
static const char * StaticAlgorithmName() {return "SHA-512";}
|
||||
};
|
||||
|
||||
// implements the SHA-384 standard
|
||||
class SHA384
|
||||
{
|
||||
public:
|
||||
typedef word64 HashWordType;
|
||||
static void InitState(word64 *state);
|
||||
static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);}
|
||||
static const char * StaticAlgorithmName() {return "SHA-384";}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
BIN
share/pixmaps/bitcoin.ico
Normal file
|
After Width: | Height: | Size: 299 KiB |
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
BIN
share/pixmaps/favicon.ico
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
share/pixmaps/nsis-header.bmp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
share/pixmaps/nsis-wizard.bmp
Normal file
|
After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
@@ -1,25 +1,28 @@
|
||||
# Auto-generated by EclipseNSIS Script Wizard
|
||||
# 3.10.2009 19:00:28
|
||||
|
||||
Name Bitcoin
|
||||
|
||||
RequestExecutionLevel highest
|
||||
SetCompressor /SOLID lzma
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.2.0
|
||||
!define VERSION 0.5.0
|
||||
!define COMPANY "Bitcoin project"
|
||||
!define URL http://www.bitcoin.org/
|
||||
|
||||
# MUI Symbol Definitions
|
||||
!define MUI_ICON "src\rc\bitcoin.ico"
|
||||
!define MUI_ICON "../share/pixmaps/bitcoin.ico"
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_RIGHT
|
||||
!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp"
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin
|
||||
!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe
|
||||
!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin-qt.exe
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
|
||||
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
|
||||
|
||||
# Included files
|
||||
@@ -42,12 +45,13 @@ Var StartMenuGroup
|
||||
!insertmacro MUI_LANGUAGE English
|
||||
|
||||
# Installer attributes
|
||||
OutFile bitcoin-0.2.0-win32-setup.exe
|
||||
OutFile bitcoin-0.5.0-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\Bitcoin
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
BrandingText " "
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.2.0.0
|
||||
VIProductVersion 0.5.0.0
|
||||
VIAddVersionKey ProductName Bitcoin
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
@@ -62,13 +66,13 @@ ShowUninstDetails show
|
||||
Section -Main SEC0000
|
||||
SetOutPath $INSTDIR
|
||||
SetOverwrite on
|
||||
File bitcoin.exe
|
||||
File libeay32.dll
|
||||
File mingwm10.dll
|
||||
File license.txt
|
||||
File readme.txt
|
||||
File ../release/bitcoin-qt.exe
|
||||
File /oname=license.txt ../COPYING
|
||||
File /oname=readme.txt ../doc/README_windows.txt
|
||||
SetOutPath $INSTDIR\daemon
|
||||
File ../src/bitcoind.exe
|
||||
SetOutPath $INSTDIR\src
|
||||
File /r src\*.*
|
||||
File /r /x *.exe /x *.o ../src\*.*
|
||||
SetOutPath $INSTDIR
|
||||
WriteRegStr HKCU "${REGKEY}\Components" Main 1
|
||||
SectionEnd
|
||||
@@ -79,7 +83,7 @@ Section -post SEC0001
|
||||
WriteUninstaller $INSTDIR\uninstall.exe
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
CreateDirectory $SMPROGRAMS\$StartMenuGroup
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin-qt.exe
|
||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)"
|
||||
@@ -107,11 +111,10 @@ done${UNSECTION_ID}:
|
||||
|
||||
# Uninstaller sections
|
||||
Section /o -un.Main UNSEC0000
|
||||
Delete /REBOOTOK $INSTDIR\bitcoin.exe
|
||||
Delete /REBOOTOK $INSTDIR\libeay32.dll
|
||||
Delete /REBOOTOK $INSTDIR\mingwm10.dll
|
||||
Delete /REBOOTOK $INSTDIR\bitcoin-qt.exe
|
||||
Delete /REBOOTOK $INSTDIR\license.txt
|
||||
Delete /REBOOTOK $INSTDIR\readme.txt
|
||||
RMDir /r /REBOOTOK $INSTDIR\daemon
|
||||
RMDir /r /REBOOTOK $INSTDIR\src
|
||||
DeleteRegValue HKCU "${REGKEY}\Components" Main
|
||||
SectionEnd
|
||||
15
share/ui.rc
Normal file
@@ -0,0 +1,15 @@
|
||||
bitcoin ICON "pixmaps/bitcoin.ico"
|
||||
|
||||
#include "wx/msw/wx.rc"
|
||||
|
||||
check ICON "pixmaps/check.ico"
|
||||
send16 BITMAP "pixmaps/send16.bmp"
|
||||
send16mask BITMAP "pixmaps/send16mask.bmp"
|
||||
send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp"
|
||||
send20 BITMAP "pixmaps/send20.bmp"
|
||||
send20mask BITMAP "pixmaps/send20mask.bmp"
|
||||
addressbook16 BITMAP "pixmaps/addressbook16.bmp"
|
||||
addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp"
|
||||
addressbook20 BITMAP "pixmaps/addressbook20.bmp"
|
||||
addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp"
|
||||
favicon ICON "pixmaps/favicon.ico"
|
||||
308
src/base58.h
Normal file
@@ -0,0 +1,308 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin Developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
//
|
||||
// Why base-58 instead of standard base-64 encoding?
|
||||
// - Don't want 0OIl characters that look the same in some fonts and
|
||||
// could be used to create visually identical looking account numbers.
|
||||
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
// - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
#ifndef BITCOIN_BASE58_H
|
||||
#define BITCOIN_BASE58_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "bignum.h"
|
||||
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
|
||||
inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn0 = 0;
|
||||
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
|
||||
reverse_copy(pbegin, pend, vchTmp.begin());
|
||||
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn;
|
||||
bn.setvch(vchTmp);
|
||||
|
||||
// Convert bignum to std::string
|
||||
std::string str;
|
||||
// Expected size increase from base58 conversion is approximately 137%
|
||||
// use 138% to be safe
|
||||
str.reserve((pend - pbegin) * 138 / 100 + 1);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
while (bn > bn0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
|
||||
throw bignum_error("EncodeBase58 : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getulong();
|
||||
str += pszBase58[c];
|
||||
}
|
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
|
||||
str += pszBase58[0];
|
||||
|
||||
// Convert little endian std::string to big endian
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size());
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
vchRet.clear();
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn = 0;
|
||||
CBigNum bnChar;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++)
|
||||
{
|
||||
const char* p1 = strchr(pszBase58, *p);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
bnChar.setulong(p1 - pszBase58);
|
||||
if (!BN_mul(&bn, &bn, &bn58, pctx))
|
||||
throw bignum_error("DecodeBase58 : BN_mul failed");
|
||||
bn += bnChar;
|
||||
}
|
||||
|
||||
// Get bignum as little endian data
|
||||
std::vector<unsigned char> vchTmp = bn.getvch();
|
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
|
||||
vchTmp.erase(vchTmp.end()-1);
|
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0;
|
||||
for (const char* p = psz; *p == pszBase58[0]; p++)
|
||||
nLeadingZeros++;
|
||||
vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
|
||||
|
||||
// Convert little endian data to big endian
|
||||
reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
|
||||
{
|
||||
// add 4-byte hash check to the end
|
||||
std::vector<unsigned char> vch(vchIn);
|
||||
uint256 hash = Hash(vch.begin(), vch.end());
|
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return EncodeBase58(vch);
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
if (!DecodeBase58(psz, vchRet))
|
||||
return false;
|
||||
if (vchRet.size() < 4)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
|
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
vchRet.resize(vchRet.size()-4);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58Check(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CBase58Data
|
||||
{
|
||||
protected:
|
||||
unsigned char nVersion;
|
||||
std::vector<unsigned char> vchData;
|
||||
|
||||
CBase58Data()
|
||||
{
|
||||
nVersion = 0;
|
||||
vchData.clear();
|
||||
}
|
||||
|
||||
~CBase58Data()
|
||||
{
|
||||
if (!vchData.empty())
|
||||
memset(&vchData[0], 0, vchData.size());
|
||||
}
|
||||
|
||||
void SetData(int nVersionIn, const void* pdata, size_t nSize)
|
||||
{
|
||||
nVersion = nVersionIn;
|
||||
vchData.resize(nSize);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], pdata, nSize);
|
||||
}
|
||||
|
||||
void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
|
||||
{
|
||||
SetData(nVersionIn, (void*)pbegin, pend - pbegin);
|
||||
}
|
||||
|
||||
public:
|
||||
bool SetString(const char* psz)
|
||||
{
|
||||
std::vector<unsigned char> vchTemp;
|
||||
DecodeBase58Check(psz, vchTemp);
|
||||
if (vchTemp.empty())
|
||||
{
|
||||
vchData.clear();
|
||||
nVersion = 0;
|
||||
return false;
|
||||
}
|
||||
nVersion = vchTemp[0];
|
||||
vchData.resize(vchTemp.size() - 1);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], &vchTemp[1], vchData.size());
|
||||
memset(&vchTemp[0], 0, vchTemp.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetString(const std::string& str)
|
||||
{
|
||||
return SetString(str.c_str());
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::vector<unsigned char> vch(1, nVersion);
|
||||
vch.insert(vch.end(), vchData.begin(), vchData.end());
|
||||
return EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
int CompareTo(const CBase58Data& b58) const
|
||||
{
|
||||
if (nVersion < b58.nVersion) return -1;
|
||||
if (nVersion > b58.nVersion) return 1;
|
||||
if (vchData < b58.vchData) return -1;
|
||||
if (vchData > b58.vchData) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
|
||||
bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
|
||||
bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
};
|
||||
|
||||
|
||||
class CBitcoinAddress : public CBase58Data
|
||||
{
|
||||
public:
|
||||
bool SetHash160(const uint160& hash160)
|
||||
{
|
||||
SetData(fTestNet ? 111 : 0, &hash160, 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
return SetHash160(Hash160(vchPubKey));
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
int nExpectedSize = 20;
|
||||
bool fExpectTestNet = false;
|
||||
switch(nVersion)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 111:
|
||||
fExpectTestNet = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
|
||||
}
|
||||
|
||||
CBitcoinAddress()
|
||||
{
|
||||
}
|
||||
|
||||
CBitcoinAddress(uint160 hash160In)
|
||||
{
|
||||
SetHash160(hash160In);
|
||||
}
|
||||
|
||||
CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
SetPubKey(vchPubKey);
|
||||
}
|
||||
|
||||
CBitcoinAddress(const std::string& strAddress)
|
||||
{
|
||||
SetString(strAddress);
|
||||
}
|
||||
|
||||
CBitcoinAddress(const char* pszAddress)
|
||||
{
|
||||
SetString(pszAddress);
|
||||
}
|
||||
|
||||
uint160 GetHash160() const
|
||||
{
|
||||
assert(vchData.size() == 20);
|
||||
uint160 hash160;
|
||||
memcpy(&hash160, &vchData[0], 20);
|
||||
return hash160;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
2564
src/bitcoinrpc.cpp
Normal file
7
src/bitcoinrpc.h
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
void ThreadRPCServer(void* parg);
|
||||
int CommandLineRPC(int argc, char *argv[]);
|
||||
132
src/crypter.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2011 The Bitcoin Developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "headers.h"
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "crypter.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
bool CCrypter::SetKeyFromPassphrase(const std::string& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
|
||||
{
|
||||
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
|
||||
return false;
|
||||
|
||||
// Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
|
||||
// Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
|
||||
// Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
|
||||
mlock(&chKey[0], sizeof chKey);
|
||||
mlock(&chIV[0], sizeof chIV);
|
||||
|
||||
int i = 0;
|
||||
if (nDerivationMethod == 0)
|
||||
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
|
||||
(unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
|
||||
|
||||
if (i != WALLET_CRYPTO_KEY_SIZE)
|
||||
{
|
||||
memset(&chKey, 0, sizeof chKey);
|
||||
memset(&chIV, 0, sizeof chIV);
|
||||
return false;
|
||||
}
|
||||
|
||||
fKeySet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
|
||||
{
|
||||
if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
|
||||
return false;
|
||||
|
||||
// Try to keep the keydata out of swap
|
||||
// Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
|
||||
// Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
|
||||
mlock(&chKey[0], sizeof chKey);
|
||||
mlock(&chIV[0], sizeof chIV);
|
||||
|
||||
memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
|
||||
memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
|
||||
|
||||
fKeySet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext)
|
||||
{
|
||||
if (!fKeySet)
|
||||
return false;
|
||||
|
||||
// max ciphertext len for a n bytes of plaintext is
|
||||
// n + AES_BLOCK_SIZE - 1 bytes
|
||||
int nLen = vchPlaintext.size();
|
||||
int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
|
||||
vchCiphertext = std::vector<unsigned char> (nCLen);
|
||||
|
||||
EVP_CIPHER_CTX ctx;
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
|
||||
|
||||
EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
|
||||
EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
vchCiphertext.resize(nCLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
|
||||
{
|
||||
if (!fKeySet)
|
||||
return false;
|
||||
|
||||
// plaintext will always be equal to or lesser than length of ciphertext
|
||||
int nLen = vchCiphertext.size();
|
||||
int nPLen = nLen, nFLen = 0;
|
||||
|
||||
vchPlaintext = CKeyingMaterial(nPLen);
|
||||
|
||||
EVP_CIPHER_CTX ctx;
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
|
||||
|
||||
EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
|
||||
EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
vchPlaintext.resize(nPLen + nFLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
|
||||
{
|
||||
CCrypter cKeyCrypter;
|
||||
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
||||
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
||||
if(!cKeyCrypter.SetKey(vMasterKey, chIV))
|
||||
return false;
|
||||
return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext);
|
||||
}
|
||||
|
||||
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext)
|
||||
{
|
||||
CCrypter cKeyCrypter;
|
||||
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
|
||||
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
|
||||
if(!cKeyCrypter.SetKey(vMasterKey, chIV))
|
||||
return false;
|
||||
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
|
||||
}
|
||||
96
src/crypter.h
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) 2011 The Bitcoin Developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef __CRYPTER_H__
|
||||
#define __CRYPTER_H__
|
||||
|
||||
#include "key.h"
|
||||
|
||||
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
|
||||
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
|
||||
|
||||
/*
|
||||
Private key encryption is done based on a CMasterKey,
|
||||
which holds a salt and random encryption key.
|
||||
|
||||
CMasterKeys is encrypted using AES-256-CBC using a key
|
||||
derived using derivation method nDerivationMethod
|
||||
(0 == EVP_sha512()) and derivation iterations nDeriveIterations.
|
||||
vchOtherDerivationParameters is provided for alternative algorithms
|
||||
which may require more parameters (such as scrypt).
|
||||
|
||||
Wallet Private Keys are then encrypted using AES-256-CBC
|
||||
with the double-sha256 of the private key as the IV, and the
|
||||
master key's key as the encryption key.
|
||||
*/
|
||||
|
||||
class CMasterKey
|
||||
{
|
||||
public:
|
||||
std::vector<unsigned char> vchCryptedKey;
|
||||
std::vector<unsigned char> vchSalt;
|
||||
// 0 = EVP_sha512()
|
||||
// 1 = scrypt()
|
||||
unsigned int nDerivationMethod;
|
||||
unsigned int nDeriveIterations;
|
||||
// Use this for more parameters to key derivation,
|
||||
// such as the various parameters to scrypt
|
||||
std::vector<unsigned char> vchOtherDerivationParameters;
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
READWRITE(vchCryptedKey);
|
||||
READWRITE(vchSalt);
|
||||
READWRITE(nDerivationMethod);
|
||||
READWRITE(nDeriveIterations);
|
||||
READWRITE(vchOtherDerivationParameters);
|
||||
)
|
||||
CMasterKey()
|
||||
{
|
||||
// 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
|
||||
// ie slightly lower than the lowest hardware we need bother supporting
|
||||
nDeriveIterations = 25000;
|
||||
nDerivationMethod = 0;
|
||||
vchOtherDerivationParameters = std::vector<unsigned char>(0);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||
|
||||
class CCrypter
|
||||
{
|
||||
private:
|
||||
unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
|
||||
unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
|
||||
bool fKeySet;
|
||||
|
||||
public:
|
||||
bool SetKeyFromPassphrase(const std::string &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
|
||||
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
|
||||
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
|
||||
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
|
||||
|
||||
void CleanKey()
|
||||
{
|
||||
memset(&chKey, 0, sizeof chKey);
|
||||
memset(&chIV, 0, sizeof chIV);
|
||||
munlock(&chKey, sizeof chKey);
|
||||
munlock(&chIV, sizeof chIV);
|
||||
fKeySet = false;
|
||||
}
|
||||
|
||||
CCrypter()
|
||||
{
|
||||
fKeySet = false;
|
||||
}
|
||||
|
||||
~CCrypter()
|
||||
{
|
||||
CleanKey();
|
||||
}
|
||||
};
|
||||
|
||||
bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
|
||||
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext);
|
||||
|
||||
#endif
|
||||
1712
db.cpp → src/db.cpp
920
db.h → src/db.h
@@ -1,436 +1,484 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <db_cxx.h>
|
||||
class CTransaction;
|
||||
class CTxIndex;
|
||||
class CDiskBlockIndex;
|
||||
class CDiskTxPos;
|
||||
class COutPoint;
|
||||
class CUser;
|
||||
class CReview;
|
||||
class CAddress;
|
||||
class CWalletTx;
|
||||
|
||||
extern map<string, string> mapAddressBook;
|
||||
extern bool fClient;
|
||||
|
||||
|
||||
extern unsigned int nWalletDBUpdated;
|
||||
extern DbEnv dbenv;
|
||||
|
||||
|
||||
extern void DBFlush(bool fShutdown);
|
||||
|
||||
|
||||
|
||||
|
||||
class CDB
|
||||
{
|
||||
protected:
|
||||
Db* pdb;
|
||||
string strFile;
|
||||
vector<DbTxn*> vTxn;
|
||||
bool fReadOnly;
|
||||
|
||||
explicit CDB(const char* pszFile, const char* pszMode="r+");
|
||||
~CDB() { Close(); }
|
||||
public:
|
||||
void Close();
|
||||
private:
|
||||
CDB(const CDB&);
|
||||
void operator=(const CDB&);
|
||||
|
||||
protected:
|
||||
template<typename K, typename T>
|
||||
bool Read(const K& key, T& value)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Read
|
||||
Dbt datValue;
|
||||
datValue.set_flags(DB_DBT_MALLOC);
|
||||
int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
if (datValue.get_data() == NULL)
|
||||
return false;
|
||||
|
||||
// Unserialize value
|
||||
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
|
||||
ssValue >> value;
|
||||
|
||||
// Clear and free memory
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
free(datValue.get_data());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
template<typename K, typename T>
|
||||
bool Write(const K& key, const T& value, bool fOverwrite=true)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (fReadOnly)
|
||||
assert(("Write called on database in read-only mode", false));
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Value
|
||||
CDataStream ssValue(SER_DISK);
|
||||
ssValue.reserve(10000);
|
||||
ssValue << value;
|
||||
Dbt datValue(&ssValue[0], ssValue.size());
|
||||
|
||||
// Write
|
||||
int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
|
||||
|
||||
// Clear memory in case it was a private key
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
bool Erase(const K& key)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (fReadOnly)
|
||||
assert(("Erase called on database in read-only mode", false));
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Erase
|
||||
int ret = pdb->del(GetTxn(), &datKey, 0);
|
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
return (ret == 0 || ret == DB_NOTFOUND);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
bool Exists(const K& key)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Exists
|
||||
int ret = pdb->exists(GetTxn(), &datKey, 0);
|
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
Dbc* GetCursor()
|
||||
{
|
||||
if (!pdb)
|
||||
return NULL;
|
||||
Dbc* pcursor = NULL;
|
||||
int ret = pdb->cursor(NULL, &pcursor, 0);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return pcursor;
|
||||
}
|
||||
|
||||
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
|
||||
{
|
||||
// Read at cursor
|
||||
Dbt datKey;
|
||||
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
|
||||
{
|
||||
datKey.set_data(&ssKey[0]);
|
||||
datKey.set_size(ssKey.size());
|
||||
}
|
||||
Dbt datValue;
|
||||
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
|
||||
{
|
||||
datValue.set_data(&ssValue[0]);
|
||||
datValue.set_size(ssValue.size());
|
||||
}
|
||||
datKey.set_flags(DB_DBT_MALLOC);
|
||||
datValue.set_flags(DB_DBT_MALLOC);
|
||||
int ret = pcursor->get(&datKey, &datValue, fFlags);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
|
||||
return 99999;
|
||||
|
||||
// Convert to streams
|
||||
ssKey.SetType(SER_DISK);
|
||||
ssKey.clear();
|
||||
ssKey.write((char*)datKey.get_data(), datKey.get_size());
|
||||
ssValue.SetType(SER_DISK);
|
||||
ssValue.clear();
|
||||
ssValue.write((char*)datValue.get_data(), datValue.get_size());
|
||||
|
||||
// Clear and free memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
free(datKey.get_data());
|
||||
free(datValue.get_data());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DbTxn* GetTxn()
|
||||
{
|
||||
if (!vTxn.empty())
|
||||
return vTxn.back();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
bool TxnBegin()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
DbTxn* ptxn = NULL;
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
|
||||
if (!ptxn || ret != 0)
|
||||
return false;
|
||||
vTxn.push_back(ptxn);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TxnCommit()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (vTxn.empty())
|
||||
return false;
|
||||
int ret = vTxn.back()->commit(0);
|
||||
vTxn.pop_back();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool TxnAbort()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (vTxn.empty())
|
||||
return false;
|
||||
int ret = vTxn.back()->abort();
|
||||
vTxn.pop_back();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool ReadVersion(int& nVersion)
|
||||
{
|
||||
nVersion = 0;
|
||||
return Read(string("version"), nVersion);
|
||||
}
|
||||
|
||||
bool WriteVersion(int nVersion)
|
||||
{
|
||||
return Write(string("version"), nVersion);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CTxDB : public CDB
|
||||
{
|
||||
public:
|
||||
CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
|
||||
private:
|
||||
CTxDB(const CTxDB&);
|
||||
void operator=(const CTxDB&);
|
||||
public:
|
||||
bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
|
||||
bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
|
||||
bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
|
||||
bool EraseTxIndex(const CTransaction& tx);
|
||||
bool ContainsTx(uint256 hash);
|
||||
bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
|
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
|
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx);
|
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
|
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
|
||||
bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
|
||||
bool EraseBlockIndex(uint256 hash);
|
||||
bool ReadHashBestChain(uint256& hashBestChain);
|
||||
bool WriteHashBestChain(uint256 hashBestChain);
|
||||
bool LoadBlockIndex();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CReviewDB : public CDB
|
||||
{
|
||||
public:
|
||||
CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { }
|
||||
private:
|
||||
CReviewDB(const CReviewDB&);
|
||||
void operator=(const CReviewDB&);
|
||||
public:
|
||||
bool ReadUser(uint256 hash, CUser& user)
|
||||
{
|
||||
return Read(make_pair(string("user"), hash), user);
|
||||
}
|
||||
|
||||
bool WriteUser(uint256 hash, const CUser& user)
|
||||
{
|
||||
return Write(make_pair(string("user"), hash), user);
|
||||
}
|
||||
|
||||
bool ReadReviews(uint256 hash, vector<CReview>& vReviews);
|
||||
bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CMarketDB : public CDB
|
||||
{
|
||||
public:
|
||||
CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { }
|
||||
private:
|
||||
CMarketDB(const CMarketDB&);
|
||||
void operator=(const CMarketDB&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CAddrDB : public CDB
|
||||
{
|
||||
public:
|
||||
CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
|
||||
private:
|
||||
CAddrDB(const CAddrDB&);
|
||||
void operator=(const CAddrDB&);
|
||||
public:
|
||||
bool WriteAddress(const CAddress& addr);
|
||||
bool LoadAddresses();
|
||||
};
|
||||
|
||||
bool LoadAddresses();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CWalletDB : public CDB
|
||||
{
|
||||
public:
|
||||
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { }
|
||||
private:
|
||||
CWalletDB(const CWalletDB&);
|
||||
void operator=(const CWalletDB&);
|
||||
public:
|
||||
bool ReadName(const string& strAddress, string& strName)
|
||||
{
|
||||
strName = "";
|
||||
return Read(make_pair(string("name"), strAddress), strName);
|
||||
}
|
||||
|
||||
bool WriteName(const string& strAddress, const string& strName)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
mapAddressBook[strAddress] = strName;
|
||||
return Write(make_pair(string("name"), strAddress), strName);
|
||||
}
|
||||
|
||||
bool EraseName(const string& strAddress)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
mapAddressBook.erase(strAddress);
|
||||
return Erase(make_pair(string("name"), strAddress));
|
||||
}
|
||||
|
||||
bool ReadTx(uint256 hash, CWalletTx& wtx)
|
||||
{
|
||||
return Read(make_pair(string("tx"), hash), wtx);
|
||||
}
|
||||
|
||||
bool WriteTx(uint256 hash, const CWalletTx& wtx)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(make_pair(string("tx"), hash), wtx);
|
||||
}
|
||||
|
||||
bool EraseTx(uint256 hash)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Erase(make_pair(string("tx"), hash));
|
||||
}
|
||||
|
||||
bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
|
||||
{
|
||||
vchPrivKey.clear();
|
||||
return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
|
||||
}
|
||||
|
||||
bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
|
||||
}
|
||||
|
||||
bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
vchPubKey.clear();
|
||||
return Read(string("defaultkey"), vchPubKey);
|
||||
}
|
||||
|
||||
bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(string("defaultkey"), vchPubKey);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ReadSetting(const string& strKey, T& value)
|
||||
{
|
||||
return Read(make_pair(string("setting"), strKey), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool WriteSetting(const string& strKey, const T& value)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(make_pair(string("setting"), strKey), value);
|
||||
}
|
||||
|
||||
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
|
||||
};
|
||||
|
||||
bool LoadWallet(bool& fFirstRunRet);
|
||||
|
||||
inline bool SetAddressBookName(const string& strAddress, const string& strName)
|
||||
{
|
||||
return CWalletDB().WriteName(strAddress, strName);
|
||||
}
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_DB_H
|
||||
#define BITCOIN_DB_H
|
||||
|
||||
#include "key.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <db_cxx.h>
|
||||
|
||||
class CTxIndex;
|
||||
class CDiskBlockIndex;
|
||||
class CDiskTxPos;
|
||||
class COutPoint;
|
||||
class CAddress;
|
||||
class CWalletTx;
|
||||
class CWallet;
|
||||
class CAccount;
|
||||
class CAccountingEntry;
|
||||
class CBlockLocator;
|
||||
|
||||
|
||||
extern unsigned int nWalletDBUpdated;
|
||||
extern DbEnv dbenv;
|
||||
|
||||
|
||||
extern void DBFlush(bool fShutdown);
|
||||
void ThreadFlushWalletDB(void* parg);
|
||||
bool BackupWallet(const CWallet& wallet, const std::string& strDest);
|
||||
|
||||
|
||||
|
||||
|
||||
class CDB
|
||||
{
|
||||
protected:
|
||||
Db* pdb;
|
||||
std::string strFile;
|
||||
std::vector<DbTxn*> vTxn;
|
||||
bool fReadOnly;
|
||||
|
||||
explicit CDB(const char* pszFile, const char* pszMode="r+");
|
||||
~CDB() { Close(); }
|
||||
public:
|
||||
void Close();
|
||||
private:
|
||||
CDB(const CDB&);
|
||||
void operator=(const CDB&);
|
||||
|
||||
protected:
|
||||
template<typename K, typename T>
|
||||
bool Read(const K& key, T& value)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Read
|
||||
Dbt datValue;
|
||||
datValue.set_flags(DB_DBT_MALLOC);
|
||||
int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
if (datValue.get_data() == NULL)
|
||||
return false;
|
||||
|
||||
// Unserialize value
|
||||
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
|
||||
ssValue >> value;
|
||||
|
||||
// Clear and free memory
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
free(datValue.get_data());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
template<typename K, typename T>
|
||||
bool Write(const K& key, const T& value, bool fOverwrite=true)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (fReadOnly)
|
||||
assert(!"Write called on database in read-only mode");
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Value
|
||||
CDataStream ssValue(SER_DISK);
|
||||
ssValue.reserve(10000);
|
||||
ssValue << value;
|
||||
Dbt datValue(&ssValue[0], ssValue.size());
|
||||
|
||||
// Write
|
||||
int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
|
||||
|
||||
// Clear memory in case it was a private key
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
bool Erase(const K& key)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (fReadOnly)
|
||||
assert(!"Erase called on database in read-only mode");
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Erase
|
||||
int ret = pdb->del(GetTxn(), &datKey, 0);
|
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
return (ret == 0 || ret == DB_NOTFOUND);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
bool Exists(const K& key)
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
|
||||
// Key
|
||||
CDataStream ssKey(SER_DISK);
|
||||
ssKey.reserve(1000);
|
||||
ssKey << key;
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
|
||||
// Exists
|
||||
int ret = pdb->exists(GetTxn(), &datKey, 0);
|
||||
|
||||
// Clear memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
Dbc* GetCursor()
|
||||
{
|
||||
if (!pdb)
|
||||
return NULL;
|
||||
Dbc* pcursor = NULL;
|
||||
int ret = pdb->cursor(NULL, &pcursor, 0);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return pcursor;
|
||||
}
|
||||
|
||||
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
|
||||
{
|
||||
// Read at cursor
|
||||
Dbt datKey;
|
||||
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
|
||||
{
|
||||
datKey.set_data(&ssKey[0]);
|
||||
datKey.set_size(ssKey.size());
|
||||
}
|
||||
Dbt datValue;
|
||||
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
|
||||
{
|
||||
datValue.set_data(&ssValue[0]);
|
||||
datValue.set_size(ssValue.size());
|
||||
}
|
||||
datKey.set_flags(DB_DBT_MALLOC);
|
||||
datValue.set_flags(DB_DBT_MALLOC);
|
||||
int ret = pcursor->get(&datKey, &datValue, fFlags);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
|
||||
return 99999;
|
||||
|
||||
// Convert to streams
|
||||
ssKey.SetType(SER_DISK);
|
||||
ssKey.clear();
|
||||
ssKey.write((char*)datKey.get_data(), datKey.get_size());
|
||||
ssValue.SetType(SER_DISK);
|
||||
ssValue.clear();
|
||||
ssValue.write((char*)datValue.get_data(), datValue.get_size());
|
||||
|
||||
// Clear and free memory
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
memset(datValue.get_data(), 0, datValue.get_size());
|
||||
free(datKey.get_data());
|
||||
free(datValue.get_data());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DbTxn* GetTxn()
|
||||
{
|
||||
if (!vTxn.empty())
|
||||
return vTxn.back();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
bool TxnBegin()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
DbTxn* ptxn = NULL;
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
|
||||
if (!ptxn || ret != 0)
|
||||
return false;
|
||||
vTxn.push_back(ptxn);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TxnCommit()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (vTxn.empty())
|
||||
return false;
|
||||
int ret = vTxn.back()->commit(0);
|
||||
vTxn.pop_back();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool TxnAbort()
|
||||
{
|
||||
if (!pdb)
|
||||
return false;
|
||||
if (vTxn.empty())
|
||||
return false;
|
||||
int ret = vTxn.back()->abort();
|
||||
vTxn.pop_back();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool ReadVersion(int& nVersion)
|
||||
{
|
||||
nVersion = 0;
|
||||
return Read(std::string("version"), nVersion);
|
||||
}
|
||||
|
||||
bool WriteVersion(int nVersion)
|
||||
{
|
||||
return Write(std::string("version"), nVersion);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CTxDB : public CDB
|
||||
{
|
||||
public:
|
||||
CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
|
||||
private:
|
||||
CTxDB(const CTxDB&);
|
||||
void operator=(const CTxDB&);
|
||||
public:
|
||||
bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
|
||||
bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
|
||||
bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
|
||||
bool EraseTxIndex(const CTransaction& tx);
|
||||
bool ContainsTx(uint256 hash);
|
||||
bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
|
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
|
||||
bool ReadDiskTx(uint256 hash, CTransaction& tx);
|
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
|
||||
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
|
||||
bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
|
||||
bool EraseBlockIndex(uint256 hash);
|
||||
bool ReadHashBestChain(uint256& hashBestChain);
|
||||
bool WriteHashBestChain(uint256 hashBestChain);
|
||||
bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
|
||||
bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
|
||||
bool LoadBlockIndex();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CAddrDB : public CDB
|
||||
{
|
||||
public:
|
||||
CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
|
||||
private:
|
||||
CAddrDB(const CAddrDB&);
|
||||
void operator=(const CAddrDB&);
|
||||
public:
|
||||
bool WriteAddress(const CAddress& addr);
|
||||
bool EraseAddress(const CAddress& addr);
|
||||
bool LoadAddresses();
|
||||
};
|
||||
|
||||
bool LoadAddresses();
|
||||
|
||||
|
||||
|
||||
class CKeyPool
|
||||
{
|
||||
public:
|
||||
int64 nTime;
|
||||
std::vector<unsigned char> vchPubKey;
|
||||
|
||||
CKeyPool()
|
||||
{
|
||||
nTime = GetTime();
|
||||
}
|
||||
|
||||
CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
|
||||
{
|
||||
nTime = GetTime();
|
||||
vchPubKey = vchPubKeyIn;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(nTime);
|
||||
READWRITE(vchPubKey);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
enum DBErrors
|
||||
{
|
||||
DB_LOAD_OK,
|
||||
DB_CORRUPT,
|
||||
DB_TOO_NEW,
|
||||
DB_LOAD_FAIL,
|
||||
};
|
||||
|
||||
class CWalletDB : public CDB
|
||||
{
|
||||
public:
|
||||
CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
|
||||
{
|
||||
}
|
||||
private:
|
||||
CWalletDB(const CWalletDB&);
|
||||
void operator=(const CWalletDB&);
|
||||
public:
|
||||
bool ReadName(const std::string& strAddress, std::string& strName)
|
||||
{
|
||||
strName = "";
|
||||
return Read(std::make_pair(std::string("name"), strAddress), strName);
|
||||
}
|
||||
|
||||
bool WriteName(const std::string& strAddress, const std::string& strName);
|
||||
|
||||
bool EraseName(const std::string& strAddress);
|
||||
|
||||
bool ReadTx(uint256 hash, CWalletTx& wtx)
|
||||
{
|
||||
return Read(std::make_pair(std::string("tx"), hash), wtx);
|
||||
}
|
||||
|
||||
bool WriteTx(uint256 hash, const CWalletTx& wtx)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::make_pair(std::string("tx"), hash), wtx);
|
||||
}
|
||||
|
||||
bool EraseTx(uint256 hash)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Erase(std::make_pair(std::string("tx"), hash));
|
||||
}
|
||||
|
||||
bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
|
||||
{
|
||||
vchPrivKey.clear();
|
||||
return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
|
||||
}
|
||||
|
||||
bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
|
||||
}
|
||||
|
||||
bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
|
||||
return false;
|
||||
if (fEraseUnencryptedKey)
|
||||
{
|
||||
Erase(std::make_pair(std::string("key"), vchPubKey));
|
||||
Erase(std::make_pair(std::string("wkey"), vchPubKey));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
|
||||
}
|
||||
|
||||
bool WriteBestBlock(const CBlockLocator& locator)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::string("bestblock"), locator);
|
||||
}
|
||||
|
||||
bool ReadBestBlock(CBlockLocator& locator)
|
||||
{
|
||||
return Read(std::string("bestblock"), locator);
|
||||
}
|
||||
|
||||
bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
vchPubKey.clear();
|
||||
return Read(std::string("defaultkey"), vchPubKey);
|
||||
}
|
||||
|
||||
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::string("defaultkey"), vchPubKey);
|
||||
}
|
||||
|
||||
bool ReadPool(int64 nPool, CKeyPool& keypool)
|
||||
{
|
||||
return Read(std::make_pair(std::string("pool"), nPool), keypool);
|
||||
}
|
||||
|
||||
bool WritePool(int64 nPool, const CKeyPool& keypool)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::make_pair(std::string("pool"), nPool), keypool);
|
||||
}
|
||||
|
||||
bool ErasePool(int64 nPool)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Erase(std::make_pair(std::string("pool"), nPool));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ReadSetting(const std::string& strKey, T& value)
|
||||
{
|
||||
return Read(std::make_pair(std::string("setting"), strKey), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool WriteSetting(const std::string& strKey, const T& value)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::make_pair(std::string("setting"), strKey), value);
|
||||
}
|
||||
|
||||
bool ReadAccount(const std::string& strAccount, CAccount& account);
|
||||
bool WriteAccount(const std::string& strAccount, const CAccount& account);
|
||||
bool WriteAccountingEntry(const CAccountingEntry& acentry);
|
||||
int64 GetAccountCreditDebit(const std::string& strAccount);
|
||||
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
|
||||
|
||||
int LoadWallet(CWallet* pwallet);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,112 +1,98 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4804)
|
||||
#pragma warning(disable:4805)
|
||||
#pragma warning(disable:4717)
|
||||
#endif
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
#define _WIN32_IE 0x0400
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
|
||||
#include <wx/wx.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/snglinst.h>
|
||||
#include <wx/taskbar.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/utils.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
#include <memory>
|
||||
#define BOUNDSCHECK 1
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <boost/tuple/tuple_io.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#endif
|
||||
|
||||
#pragma hdrstop
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
|
||||
|
||||
#include "strlcpy.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
#include "key.h"
|
||||
#include "bignum.h"
|
||||
#include "base58.h"
|
||||
#include "script.h"
|
||||
#include "db.h"
|
||||
#include "net.h"
|
||||
#include "irc.h"
|
||||
#include "main.h"
|
||||
#include "market.h"
|
||||
#include "uibase.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "xpm/addressbook16.xpm"
|
||||
#include "xpm/addressbook20.xpm"
|
||||
#include "xpm/bitcoin16.xpm"
|
||||
#include "xpm/bitcoin20.xpm"
|
||||
#include "xpm/bitcoin32.xpm"
|
||||
#include "xpm/bitcoin48.xpm"
|
||||
#include "xpm/check.xpm"
|
||||
#include "xpm/send16.xpm"
|
||||
#include "xpm/send16noshadow.xpm"
|
||||
#include "xpm/send20.xpm"
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4804)
|
||||
#pragma warning(disable:4805)
|
||||
#pragma warning(disable:4717)
|
||||
#endif
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
#define _WIN32_IE 0x0400
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
|
||||
// Include boost/foreach here as it defines __STDC_LIMIT_MACROS on some systems.
|
||||
#include <boost/foreach.hpp>
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
|
||||
#endif
|
||||
|
||||
#if (defined(__unix__) || defined(unix)) && !defined(USG)
|
||||
#include <sys/param.h> // to get BSD define
|
||||
#endif
|
||||
#ifdef MAC_OSX
|
||||
#ifndef BSD
|
||||
#define BSD 1
|
||||
#endif
|
||||
#endif
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <db_cxx.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef BSD
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
#include "bignum.h"
|
||||
#include "base58.h"
|
||||
#include "main.h"
|
||||
#ifdef QT_GUI
|
||||
#include "qtui.h"
|
||||
#else
|
||||
#include "noui.h"
|
||||
#endif
|
||||
520
src/init.cpp
Normal file
@@ -0,0 +1,520 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "headers.h"
|
||||
#include "db.h"
|
||||
#include "bitcoinrpc.h"
|
||||
#include "net.h"
|
||||
#include "init.h"
|
||||
#include "strlcpy.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
|
||||
#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
|
||||
#define _BITCOIN_QT_PLUGINS_INCLUDED
|
||||
#define __INSURE__
|
||||
#include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qcncodecs)
|
||||
Q_IMPORT_PLUGIN(qjpcodecs)
|
||||
Q_IMPORT_PLUGIN(qtwcodecs)
|
||||
Q_IMPORT_PLUGIN(qkrcodecs)
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
CWallet* pwalletMain;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shutdown
|
||||
//
|
||||
|
||||
void ExitTimeout(void* parg)
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep(5000);
|
||||
ExitProcess(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shutdown(void* parg)
|
||||
{
|
||||
static CCriticalSection cs_Shutdown;
|
||||
static bool fTaken;
|
||||
bool fFirstThread;
|
||||
CRITICAL_BLOCK(cs_Shutdown)
|
||||
{
|
||||
fFirstThread = !fTaken;
|
||||
fTaken = true;
|
||||
}
|
||||
static bool fExit;
|
||||
if (fFirstThread)
|
||||
{
|
||||
fShutdown = true;
|
||||
nTransactionsUpdated++;
|
||||
DBFlush(false);
|
||||
StopNode();
|
||||
DBFlush(true);
|
||||
boost::filesystem::remove(GetPidFile());
|
||||
UnregisterWallet(pwalletMain);
|
||||
delete pwalletMain;
|
||||
CreateThread(ExitTimeout, NULL);
|
||||
Sleep(50);
|
||||
printf("Bitcoin exiting\n\n");
|
||||
fExit = true;
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!fExit)
|
||||
Sleep(500);
|
||||
Sleep(100);
|
||||
ExitThread(0);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSIGTERM(int)
|
||||
{
|
||||
fRequestShutdown = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Start
|
||||
//
|
||||
#if !defined(QT_GUI)
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
bool fRet = false;
|
||||
fRet = AppInit(argc, argv);
|
||||
|
||||
if (fRet && fDaemon)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool AppInit(int argc, char* argv[])
|
||||
{
|
||||
bool fRet = false;
|
||||
try
|
||||
{
|
||||
fRet = AppInit2(argc, argv);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintException(&e, "AppInit()");
|
||||
} catch (...) {
|
||||
PrintException(NULL, "AppInit()");
|
||||
}
|
||||
if (!fRet)
|
||||
Shutdown(NULL);
|
||||
return fRet;
|
||||
}
|
||||
|
||||
bool AppInit2(int argc, char* argv[])
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
// Turn off microsoft heap dump noise
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
||||
#endif
|
||||
#if _MSC_VER >= 1400
|
||||
// Disable confusing "helpful" text message on abort, ctrl-c
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
umask(077);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
// Clean shutdown on SIGTERM
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = HandleSIGTERM;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
if (mapArgs.count("-datadir"))
|
||||
{
|
||||
if (filesystem::is_directory(filesystem::system_complete(mapArgs["-datadir"])))
|
||||
{
|
||||
filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
|
||||
strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error: Specified directory does not exist\n");
|
||||
Shutdown(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
|
||||
|
||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||
{
|
||||
string strUsage = string() +
|
||||
_("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
|
||||
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
|
||||
" bitcoin [options] \t " + "\n" +
|
||||
" bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
|
||||
" bitcoin [options] help \t\t " + _("List commands\n") +
|
||||
" bitcoin [options] help <command> \t\t " + _("Get help for a command\n") +
|
||||
_("Options:\n") +
|
||||
" -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
|
||||
" -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)\n") +
|
||||
" -gen \t\t " + _("Generate coins\n") +
|
||||
" -gen=0 \t\t " + _("Don't generate coins\n") +
|
||||
" -min \t\t " + _("Start minimized\n") +
|
||||
" -datadir=<dir> \t\t " + _("Specify data directory\n") +
|
||||
" -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)\n") +
|
||||
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
|
||||
" -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
|
||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||
" -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
|
||||
" -nolisten \t " + _("Don't accept connections from outside\n") +
|
||||
" -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)\n") +
|
||||
" -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)\n") +
|
||||
#ifdef USE_UPNP
|
||||
#if USE_UPNP
|
||||
" -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") +
|
||||
#else
|
||||
" -upnp \t " + _("Attempt to use UPnP to map the listening port\n") +
|
||||
#endif
|
||||
#endif
|
||||
" -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
|
||||
#ifdef GUI
|
||||
" -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
" -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
|
||||
#endif
|
||||
" -testnet \t\t " + _("Use the test network\n") +
|
||||
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
|
||||
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
|
||||
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
|
||||
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
|
||||
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
|
||||
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
|
||||
" -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
|
||||
|
||||
#ifdef USE_SSL
|
||||
strUsage += string() +
|
||||
_("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
|
||||
" -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
|
||||
" -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
|
||||
" -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
|
||||
" -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
|
||||
#endif
|
||||
|
||||
strUsage += string() +
|
||||
" -? \t\t " + _("This help message\n");
|
||||
|
||||
// Remove tabs
|
||||
strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
|
||||
fprintf(stderr, "%s", strUsage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fDebug = GetBoolArg("-debug");
|
||||
fAllowDNS = GetBoolArg("-dns");
|
||||
|
||||
#ifndef WIN32
|
||||
fDaemon = GetBoolArg("-daemon");
|
||||
#else
|
||||
fDaemon = false;
|
||||
#endif
|
||||
|
||||
if (fDaemon)
|
||||
fServer = true;
|
||||
else
|
||||
fServer = GetBoolArg("-server");
|
||||
|
||||
/* force fServer when running without GUI */
|
||||
#if !defined(QT_GUI)
|
||||
fServer = true;
|
||||
#endif
|
||||
fPrintToConsole = GetBoolArg("-printtoconsole");
|
||||
fPrintToDebugger = GetBoolArg("-printtodebugger");
|
||||
|
||||
fTestNet = GetBoolArg("-testnet");
|
||||
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
|
||||
fNoListen = GetBoolArg("-nolisten") || fTOR;
|
||||
fLogTimestamps = GetBoolArg("-logtimestamps");
|
||||
|
||||
#ifndef QT_GUI
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!IsSwitchChar(argv[i][0]))
|
||||
fCommandLine = true;
|
||||
|
||||
if (fCommandLine)
|
||||
{
|
||||
int ret = CommandLineRPC(argc, argv);
|
||||
exit(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
if (fDaemon)
|
||||
{
|
||||
// Daemonize
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
{
|
||||
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
|
||||
return false;
|
||||
}
|
||||
if (pid > 0)
|
||||
{
|
||||
CreatePidFile(GetPidFile(), pid);
|
||||
return true;
|
||||
}
|
||||
|
||||
pid_t sid = setsid();
|
||||
if (sid < 0)
|
||||
fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fDebug && !pszSetDataDir[0])
|
||||
ShrinkDebugFile();
|
||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
printf("Bitcoin version %s\n", FormatFullVersion().c_str());
|
||||
printf("Default data directory %s\n", GetDefaultDataDir().c_str());
|
||||
|
||||
if (GetBoolArg("-loadblockindextest"))
|
||||
{
|
||||
CTxDB txdb("r");
|
||||
txdb.LoadBlockIndex();
|
||||
PrintBlockTree();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure only a single bitcoin process is using the data directory.
|
||||
string strLockFile = GetDataDir() + "/.lock";
|
||||
FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
|
||||
if (file) fclose(file);
|
||||
static boost::interprocess::file_lock lock(strLockFile.c_str());
|
||||
if (!lock.try_lock())
|
||||
{
|
||||
wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind to the port early so we can tell if another instance is already running.
|
||||
string strErrors;
|
||||
if (!fNoListen)
|
||||
{
|
||||
if (!BindListenPort(strErrors))
|
||||
{
|
||||
wxMessageBox(strErrors, "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Load data files
|
||||
//
|
||||
if (fDaemon)
|
||||
fprintf(stdout, "bitcoin server starting\n");
|
||||
strErrors = "";
|
||||
int64 nStart;
|
||||
|
||||
InitMessage(_("Loading addresses..."));
|
||||
printf("Loading addresses...\n");
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadAddresses())
|
||||
strErrors += _("Error loading addr.dat \n");
|
||||
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||
|
||||
InitMessage(_("Loading block index..."));
|
||||
printf("Loading block index...\n");
|
||||
nStart = GetTimeMillis();
|
||||
if (!LoadBlockIndex())
|
||||
strErrors += _("Error loading blkindex.dat \n");
|
||||
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||
|
||||
InitMessage(_("Loading wallet..."));
|
||||
printf("Loading wallet...\n");
|
||||
nStart = GetTimeMillis();
|
||||
bool fFirstRun;
|
||||
pwalletMain = new CWallet("wallet.dat");
|
||||
int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
|
||||
if (nLoadWalletRet != DB_LOAD_OK)
|
||||
{
|
||||
if (nLoadWalletRet == DB_CORRUPT)
|
||||
strErrors += _("Error loading wallet.dat: Wallet corrupted \n");
|
||||
else if (nLoadWalletRet == DB_TOO_NEW)
|
||||
strErrors += _("Error loading wallet.dat: Wallet requires newer version of Bitcoin \n");
|
||||
else
|
||||
strErrors += _("Error loading wallet.dat \n");
|
||||
}
|
||||
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||
|
||||
RegisterWallet(pwalletMain);
|
||||
|
||||
CBlockIndex *pindexRescan = pindexBest;
|
||||
if (GetBoolArg("-rescan"))
|
||||
pindexRescan = pindexGenesisBlock;
|
||||
else
|
||||
{
|
||||
CWalletDB walletdb("wallet.dat");
|
||||
CBlockLocator locator;
|
||||
if (walletdb.ReadBestBlock(locator))
|
||||
pindexRescan = locator.GetBlockIndex();
|
||||
}
|
||||
if (pindexBest != pindexRescan)
|
||||
{
|
||||
InitMessage(_("Rescanning..."));
|
||||
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
|
||||
nStart = GetTimeMillis();
|
||||
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
|
||||
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
InitMessage(_("Done loading"));
|
||||
printf("Done loading\n");
|
||||
|
||||
//// debug print
|
||||
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
|
||||
printf("nBestHeight = %d\n", nBestHeight);
|
||||
printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
|
||||
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
|
||||
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
|
||||
|
||||
if (!strErrors.empty())
|
||||
{
|
||||
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add wallet transactions that aren't already in a block to mapTransactions
|
||||
pwalletMain->ReacceptWalletTransactions();
|
||||
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
|
||||
{
|
||||
PrintBlockTree();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-timeout"))
|
||||
{
|
||||
int nNewTimeout = GetArg("-timeout", 5000);
|
||||
if (nNewTimeout > 0 && nNewTimeout < 600000)
|
||||
nConnectTimeout = nNewTimeout;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-printblock"))
|
||||
{
|
||||
string strMatch = mapArgs["-printblock"];
|
||||
int nFound = 0;
|
||||
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
|
||||
{
|
||||
uint256 hash = (*mi).first;
|
||||
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
|
||||
{
|
||||
CBlockIndex* pindex = (*mi).second;
|
||||
CBlock block;
|
||||
block.ReadFromDisk(pindex);
|
||||
block.BuildMerkleTree();
|
||||
block.print();
|
||||
printf("\n");
|
||||
nFound++;
|
||||
}
|
||||
}
|
||||
if (nFound == 0)
|
||||
printf("No blocks matching %s were found\n", strMatch.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fGenerateBitcoins = GetBoolArg("-gen");
|
||||
|
||||
if (mapArgs.count("-proxy"))
|
||||
{
|
||||
fUseProxy = true;
|
||||
addrProxy = CAddress(mapArgs["-proxy"]);
|
||||
if (!addrProxy.IsValid())
|
||||
{
|
||||
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapArgs.count("-addnode"))
|
||||
{
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
|
||||
{
|
||||
CAddress addr(strAddr, fAllowDNS);
|
||||
addr.nTime = 0; // so it won't relay unless successfully connected
|
||||
if (addr.IsValid())
|
||||
AddAddress(addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetBoolArg("-nodnsseed"))
|
||||
printf("DNS seeding disabled\n");
|
||||
else
|
||||
DNSAddressSeed();
|
||||
|
||||
if (mapArgs.count("-paytxfee"))
|
||||
{
|
||||
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
|
||||
{
|
||||
wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
if (nTransactionFee > 0.25 * COIN)
|
||||
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
|
||||
if (fHaveUPnP)
|
||||
{
|
||||
#if USE_UPNP
|
||||
if (GetBoolArg("-noupnp"))
|
||||
fUseUPnP = false;
|
||||
#else
|
||||
if (GetBoolArg("-upnp"))
|
||||
fUseUPnP = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Start the node
|
||||
//
|
||||
if (!CheckDiskSpace())
|
||||
return false;
|
||||
|
||||
RandAddSeedPerfmon();
|
||||
|
||||
if (!CreateThread(StartNode, NULL))
|
||||
wxMessageBox(_("Error: CreateThread(StartNode) failed"), "Bitcoin");
|
||||
|
||||
if (fServer)
|
||||
CreateThread(ThreadRPCServer, NULL);
|
||||
|
||||
#if !defined(QT_GUI)
|
||||
while (1)
|
||||
Sleep(5000);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
14
src/init.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_INIT_H
|
||||
#define BITCOIN_INIT_H
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
|
||||
void Shutdown(void* parg);
|
||||
bool AppInit(int argc, char* argv[]);
|
||||
bool AppInit2(int argc, char* argv[]);
|
||||
|
||||
#endif
|
||||
@@ -1,322 +1,449 @@
|
||||
// Copyright (c) 2009 Satoshi Nakamoto
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h"
|
||||
|
||||
int nGotIRCAddresses = 0;
|
||||
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ircaddr
|
||||
{
|
||||
int ip;
|
||||
short port;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
string EncodeAddress(const CAddress& addr)
|
||||
{
|
||||
struct ircaddr tmp;
|
||||
tmp.ip = addr.ip;
|
||||
tmp.port = addr.port;
|
||||
|
||||
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
|
||||
return string("u") + EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
bool DecodeAddress(string str, CAddress& addr)
|
||||
{
|
||||
vector<unsigned char> vch;
|
||||
if (!DecodeBase58Check(str.substr(1), vch))
|
||||
return false;
|
||||
|
||||
struct ircaddr tmp;
|
||||
if (vch.size() != sizeof(tmp))
|
||||
return false;
|
||||
memcpy(&tmp, &vch[0], sizeof(tmp));
|
||||
|
||||
addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static bool Send(SOCKET hSocket, const char* pszSend)
|
||||
{
|
||||
if (strstr(pszSend, "PONG") != pszSend)
|
||||
printf("IRC SENDING: %s\n", pszSend);
|
||||
const char* psz = pszSend;
|
||||
const char* pszEnd = psz + strlen(psz);
|
||||
while (psz < pszEnd)
|
||||
{
|
||||
int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
psz += ret;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
{
|
||||
strLine = "";
|
||||
loop
|
||||
{
|
||||
char c;
|
||||
int nBytes = recv(hSocket, &c, 1, 0);
|
||||
if (nBytes > 0)
|
||||
{
|
||||
if (c == '\n')
|
||||
continue;
|
||||
if (c == '\r')
|
||||
return true;
|
||||
strLine += c;
|
||||
}
|
||||
else if (nBytes <= 0)
|
||||
{
|
||||
if (!strLine.empty())
|
||||
return true;
|
||||
// socket closed
|
||||
printf("IRC socket closed\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket error
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||
{
|
||||
printf("IRC recv failed: %d\n", nErr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RecvLineIRC(SOCKET hSocket, string& strLine)
|
||||
{
|
||||
loop
|
||||
{
|
||||
bool fRet = RecvLine(hSocket, strLine);
|
||||
if (fRet)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords[0] == "PING")
|
||||
{
|
||||
strLine[1] = 'O';
|
||||
strLine += '\r';
|
||||
Send(hSocket, strLine.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return fRet;
|
||||
}
|
||||
}
|
||||
|
||||
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
|
||||
{
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return 0;
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
if (psz1 && strLine.find(psz1) != -1)
|
||||
return 1;
|
||||
if (psz2 && strLine.find(psz2) != -1)
|
||||
return 2;
|
||||
if (psz3 && strLine.find(psz3) != -1)
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
bool Wait(int nSeconds)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
printf("IRC waiting %d seconds to reconnect\n", nSeconds);
|
||||
for (int i = 0; i < nSeconds; i++)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
Sleep(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ThreadIRCSeed(void* parg)
|
||||
{
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
int nErrorWait = 10;
|
||||
int nRetryWait = 10;
|
||||
bool fNameInUse = false;
|
||||
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
|
||||
|
||||
while (!fShutdown)
|
||||
{
|
||||
CAddress addrConnect("216.155.130.130:6667");
|
||||
if (!fTOR)
|
||||
{
|
||||
struct hostent* phostent = gethostbyname("chat.freenode.net");
|
||||
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
|
||||
addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667));
|
||||
}
|
||||
|
||||
SOCKET hSocket;
|
||||
if (!ConnectSocket(addrConnect, hSocket))
|
||||
{
|
||||
printf("IRC connect failed\n");
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
|
||||
{
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
string strMyName;
|
||||
if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse)
|
||||
strMyName = EncodeAddress(addrLocalHost);
|
||||
else
|
||||
strMyName = strprintf("x%u", GetRand(1000000000));
|
||||
|
||||
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
|
||||
Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
|
||||
|
||||
int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
|
||||
if (nRet != 1)
|
||||
{
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
if (nRet == 2)
|
||||
{
|
||||
printf("IRC name already in use\n");
|
||||
fNameInUse = true;
|
||||
Wait(10);
|
||||
continue;
|
||||
}
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
Sleep(500);
|
||||
|
||||
Send(hSocket, "JOIN #bitcoin\r");
|
||||
Send(hSocket, "WHO #bitcoin\r");
|
||||
|
||||
int64 nStart = GetTime();
|
||||
string strLine;
|
||||
while (!fShutdown && RecvLineIRC(hSocket, strLine))
|
||||
{
|
||||
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
|
||||
continue;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 2)
|
||||
continue;
|
||||
|
||||
char pszName[10000];
|
||||
pszName[0] = '\0';
|
||||
|
||||
if (vWords[1] == "352" && vWords.size() >= 8)
|
||||
{
|
||||
// index 7 is limited to 16 characters
|
||||
// could get full length name at index 10, but would be different from join messages
|
||||
strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
|
||||
printf("IRC got who\n");
|
||||
}
|
||||
|
||||
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
|
||||
{
|
||||
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
|
||||
strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
|
||||
if (strchr(pszName, '!'))
|
||||
*strchr(pszName, '!') = '\0';
|
||||
printf("IRC got join\n");
|
||||
}
|
||||
|
||||
if (pszName[0] == 'u')
|
||||
{
|
||||
CAddress addr;
|
||||
if (DecodeAddress(pszName, addr))
|
||||
{
|
||||
addr.nTime = GetAdjustedTime() - 51 * 60;
|
||||
CAddrDB addrdb;
|
||||
if (AddAddress(addrdb, addr))
|
||||
printf("IRC got new address\n");
|
||||
nGotIRCAddresses++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("IRC decode failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
|
||||
// IRC usually blocks TOR, so only try once
|
||||
if (fTOR)
|
||||
return;
|
||||
|
||||
if (GetTime() - nStart > 20 * 60)
|
||||
{
|
||||
nErrorWait /= 3;
|
||||
nRetryWait /= 3;
|
||||
}
|
||||
|
||||
nRetryWait = nRetryWait * 11 / 10;
|
||||
if (!Wait(nRetryWait += 60))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
WSADATA wsadata;
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
|
||||
{
|
||||
printf("Error at WSAStartup()\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ThreadIRCSeed(NULL);
|
||||
|
||||
WSACleanup();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "headers.h"
|
||||
#include "irc.h"
|
||||
#include "net.h"
|
||||
#include "strlcpy.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int nGotIRCAddresses = 0;
|
||||
bool fGotExternalIP = false;
|
||||
|
||||
void ThreadIRCSeed2(void* parg);
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ircaddr
|
||||
{
|
||||
int ip;
|
||||
short port;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
string EncodeAddress(const CAddress& addr)
|
||||
{
|
||||
struct ircaddr tmp;
|
||||
tmp.ip = addr.ip;
|
||||
tmp.port = addr.port;
|
||||
|
||||
vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
|
||||
return string("u") + EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
bool DecodeAddress(string str, CAddress& addr)
|
||||
{
|
||||
vector<unsigned char> vch;
|
||||
if (!DecodeBase58Check(str.substr(1), vch))
|
||||
return false;
|
||||
|
||||
struct ircaddr tmp;
|
||||
if (vch.size() != sizeof(tmp))
|
||||
return false;
|
||||
memcpy(&tmp, &vch[0], sizeof(tmp));
|
||||
|
||||
addr = CAddress(tmp.ip, ntohs(tmp.port), NODE_NETWORK);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static bool Send(SOCKET hSocket, const char* pszSend)
|
||||
{
|
||||
if (strstr(pszSend, "PONG") != pszSend)
|
||||
printf("IRC SENDING: %s\n", pszSend);
|
||||
const char* psz = pszSend;
|
||||
const char* pszEnd = psz + strlen(psz);
|
||||
while (psz < pszEnd)
|
||||
{
|
||||
int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
psz += ret;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
{
|
||||
strLine = "";
|
||||
loop
|
||||
{
|
||||
char c;
|
||||
int nBytes = recv(hSocket, &c, 1, 0);
|
||||
if (nBytes > 0)
|
||||
{
|
||||
if (c == '\n')
|
||||
continue;
|
||||
if (c == '\r')
|
||||
return true;
|
||||
strLine += c;
|
||||
if (strLine.size() >= 9000)
|
||||
return true;
|
||||
}
|
||||
else if (nBytes <= 0)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
if (nBytes < 0)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr == WSAEMSGSIZE)
|
||||
continue;
|
||||
if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
|
||||
{
|
||||
Sleep(10);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!strLine.empty())
|
||||
return true;
|
||||
if (nBytes == 0)
|
||||
{
|
||||
// socket closed
|
||||
printf("IRC socket closed\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket error
|
||||
int nErr = WSAGetLastError();
|
||||
printf("IRC recv failed: %d\n", nErr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RecvLineIRC(SOCKET hSocket, string& strLine)
|
||||
{
|
||||
loop
|
||||
{
|
||||
bool fRet = RecvLine(hSocket, strLine);
|
||||
if (fRet)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() >= 1 && vWords[0] == "PING")
|
||||
{
|
||||
strLine[1] = 'O';
|
||||
strLine += '\r';
|
||||
Send(hSocket, strLine.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return fRet;
|
||||
}
|
||||
}
|
||||
|
||||
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL)
|
||||
{
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
strLine.reserve(10000);
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return 0;
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
if (psz1 && strLine.find(psz1) != -1)
|
||||
return 1;
|
||||
if (psz2 && strLine.find(psz2) != -1)
|
||||
return 2;
|
||||
if (psz3 && strLine.find(psz3) != -1)
|
||||
return 3;
|
||||
if (psz4 && strLine.find(psz4) != -1)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
bool Wait(int nSeconds)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
printf("IRC waiting %d seconds to reconnect\n", nSeconds);
|
||||
for (int i = 0; i < nSeconds; i++)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
Sleep(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet)
|
||||
{
|
||||
strRet.clear();
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 2)
|
||||
continue;
|
||||
|
||||
if (vWords[1] == psz1)
|
||||
{
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
strRet = strLine;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
|
||||
{
|
||||
Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());
|
||||
|
||||
string strLine;
|
||||
if (!RecvCodeLine(hSocket, "302", strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 4)
|
||||
return false;
|
||||
|
||||
string str = vWords[3];
|
||||
if (str.rfind("@") == string::npos)
|
||||
return false;
|
||||
string strHost = str.substr(str.rfind("@")+1);
|
||||
|
||||
// Hybrid IRC used by lfnet always returns IP when you userhost yourself,
|
||||
// but in case another IRC is ever used this should work.
|
||||
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
|
||||
if (fUseProxy)
|
||||
return false;
|
||||
CAddress addr(strHost, 0, true);
|
||||
if (!addr.IsValid())
|
||||
return false;
|
||||
ipRet = addr.ip;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ThreadIRCSeed(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));
|
||||
try
|
||||
{
|
||||
ThreadIRCSeed2(parg);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "ThreadIRCSeed()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "ThreadIRCSeed()");
|
||||
}
|
||||
printf("ThreadIRCSeed exiting\n");
|
||||
}
|
||||
|
||||
void ThreadIRCSeed2(void* parg)
|
||||
{
|
||||
/* Dont advertise on IRC if we don't allow incoming connections */
|
||||
if (mapArgs.count("-connect") || fNoListen)
|
||||
return;
|
||||
|
||||
if (GetBoolArg("-noirc"))
|
||||
return;
|
||||
printf("ThreadIRCSeed started\n");
|
||||
int nErrorWait = 10;
|
||||
int nRetryWait = 10;
|
||||
bool fNameInUse = false;
|
||||
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
|
||||
|
||||
while (!fShutdown)
|
||||
{
|
||||
//CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net
|
||||
CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org
|
||||
if (!fTOR)
|
||||
{
|
||||
//struct hostent* phostent = gethostbyname("chat.freenode.net");
|
||||
CAddress addrIRC("irc.lfnet.org", 6667, true);
|
||||
if (addrIRC.IsValid())
|
||||
addrConnect = addrIRC;
|
||||
}
|
||||
|
||||
SOCKET hSocket;
|
||||
if (!ConnectSocket(addrConnect, hSocket))
|
||||
{
|
||||
printf("IRC connect failed\n");
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
|
||||
{
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
string strMyName;
|
||||
if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse)
|
||||
strMyName = EncodeAddress(addrLocalHost);
|
||||
else
|
||||
strMyName = strprintf("x%u", GetRand(1000000000));
|
||||
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
|
||||
Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());
|
||||
|
||||
int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
|
||||
if (nRet != 1)
|
||||
{
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
if (nRet == 2)
|
||||
{
|
||||
printf("IRC name already in use\n");
|
||||
fNameInUse = true;
|
||||
Wait(10);
|
||||
continue;
|
||||
}
|
||||
nErrorWait = nErrorWait * 11 / 10;
|
||||
if (Wait(nErrorWait += 60))
|
||||
continue;
|
||||
else
|
||||
return;
|
||||
}
|
||||
Sleep(500);
|
||||
|
||||
// Get our external IP from the IRC server and re-nick before joining the channel
|
||||
CAddress addrFromIRC;
|
||||
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
|
||||
{
|
||||
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
|
||||
if (!fUseProxy && addrFromIRC.IsRoutable())
|
||||
{
|
||||
// IRC lets you to re-nick
|
||||
fGotExternalIP = true;
|
||||
addrLocalHost.ip = addrFromIRC.ip;
|
||||
strMyName = EncodeAddress(addrLocalHost);
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (fTestNet) {
|
||||
Send(hSocket, "JOIN #bitcoinTEST\r");
|
||||
Send(hSocket, "WHO #bitcoinTEST\r");
|
||||
} else {
|
||||
// randomly join #bitcoin00-#bitcoin99
|
||||
int channel_number = GetRandInt(100);
|
||||
Send(hSocket, strprintf("JOIN #bitcoin%02d\r", channel_number).c_str());
|
||||
Send(hSocket, strprintf("WHO #bitcoin%02d\r", channel_number).c_str());
|
||||
}
|
||||
|
||||
int64 nStart = GetTime();
|
||||
string strLine;
|
||||
strLine.reserve(10000);
|
||||
while (!fShutdown && RecvLineIRC(hSocket, strLine))
|
||||
{
|
||||
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
|
||||
continue;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 2)
|
||||
continue;
|
||||
|
||||
char pszName[10000];
|
||||
pszName[0] = '\0';
|
||||
|
||||
if (vWords[1] == "352" && vWords.size() >= 8)
|
||||
{
|
||||
// index 7 is limited to 16 characters
|
||||
// could get full length name at index 10, but would be different from join messages
|
||||
strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
|
||||
printf("IRC got who\n");
|
||||
}
|
||||
|
||||
if (vWords[1] == "JOIN" && vWords[0].size() > 1)
|
||||
{
|
||||
// :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
|
||||
strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
|
||||
if (strchr(pszName, '!'))
|
||||
*strchr(pszName, '!') = '\0';
|
||||
printf("IRC got join\n");
|
||||
}
|
||||
|
||||
if (pszName[0] == 'u')
|
||||
{
|
||||
CAddress addr;
|
||||
if (DecodeAddress(pszName, addr))
|
||||
{
|
||||
addr.nTime = GetAdjustedTime();
|
||||
if (AddAddress(addr, 51 * 60))
|
||||
printf("IRC got new address: %s\n", addr.ToString().c_str());
|
||||
nGotIRCAddresses++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("IRC decode failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
|
||||
// IRC usually blocks TOR, so only try once
|
||||
if (fTOR)
|
||||
return;
|
||||
|
||||
if (GetTime() - nStart > 20 * 60)
|
||||
{
|
||||
nErrorWait /= 3;
|
||||
nRetryWait /= 3;
|
||||
}
|
||||
|
||||
nRetryWait = nRetryWait * 11 / 10;
|
||||
if (!Wait(nRetryWait += 60))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
WSADATA wsadata;
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
|
||||
{
|
||||
printf("Error at WSAStartup()\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ThreadIRCSeed(NULL);
|
||||
|
||||
WSACleanup();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
14
src/irc.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_IRC_H
|
||||
#define BITCOIN_IRC_H
|
||||
|
||||
bool RecvLine(SOCKET hSocket, std::string& strLine);
|
||||
void ThreadIRCSeed(void* parg);
|
||||
|
||||
extern int nGotIRCAddresses;
|
||||
extern bool fGotExternalIP;
|
||||
|
||||
#endif
|
||||
24
src/json/LICENSE.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2007 - 2009 John W. Wilkinson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
18
src/json/json_spirit.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef JSON_SPIRIT
|
||||
#define JSON_SPIRIT
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_writer.h"
|
||||
#include "json_spirit_utils.h"
|
||||
|
||||
#endif
|
||||
54
src/json/json_spirit_error_position.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef JSON_SPIRIT_ERROR_POSITION
|
||||
#define JSON_SPIRIT_ERROR_POSITION
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
|
||||
// Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
|
||||
// functions that return a bool.
|
||||
//
|
||||
struct Error_position
|
||||
{
|
||||
Error_position();
|
||||
Error_position( unsigned int line, unsigned int column, const std::string& reason );
|
||||
bool operator==( const Error_position& lhs ) const;
|
||||
unsigned int line_;
|
||||
unsigned int column_;
|
||||
std::string reason_;
|
||||
};
|
||||
|
||||
inline Error_position::Error_position()
|
||||
: line_( 0 )
|
||||
, column_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
|
||||
: line_( line )
|
||||
, column_( column )
|
||||
, reason_( reason )
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Error_position::operator==( const Error_position& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( reason_ == lhs.reason_ ) &&
|
||||
( line_ == lhs.line_ ) &&
|
||||
( column_ == lhs.column_ );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
137
src/json/json_spirit_reader.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
|
||||
bool json_spirit::read( const std::string& s, Value& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, Value& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, Value& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, Value& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool json_spirit::read( const std::string& s, mValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, mValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, mValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, mValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wmValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
||||
62
src/json/json_spirit_reader.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef JSON_SPIRIT_READER
|
||||
#define JSON_SPIRIT_READER
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// functions to reads a JSON values
|
||||
|
||||
bool read( const std::string& s, Value& value );
|
||||
bool read( std::istream& is, Value& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
void read_or_throw( const std::string& s, Value& value );
|
||||
void read_or_throw( std::istream& is, Value& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wValue& value );
|
||||
bool read( std::wistream& is, wValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wValue& value );
|
||||
void read_or_throw( std::wistream& is, wValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
#endif
|
||||
|
||||
bool read( const std::string& s, mValue& value );
|
||||
bool read( std::istream& is, mValue& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
void read_or_throw( const std::string& s, mValue& value );
|
||||
void read_or_throw( std::istream& is, mValue& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wmValue& value );
|
||||
bool read( std::wistream& is, wmValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wmValue& value );
|
||||
void read_or_throw( std::wistream& is, wmValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
612
src/json/json_spirit_reader_template.h
Normal file
@@ -0,0 +1,612 @@
|
||||
#ifndef JSON_SPIRIT_READER_TEMPLATE
|
||||
#define JSON_SPIRIT_READER_TEMPLATE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
|
||||
//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 103800
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_escape_char.hpp>
|
||||
#include <boost/spirit/include/classic_multi_pass.hpp>
|
||||
#include <boost/spirit/include/classic_position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit::classic
|
||||
#else
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/escape_char.hpp>
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit
|
||||
#endif
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >();
|
||||
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
|
||||
|
||||
template< class Iter_type >
|
||||
bool is_eq( Iter_type first, Iter_type last, const char* c_str )
|
||||
{
|
||||
for( Iter_type i = first; i != last; ++i, ++c_str )
|
||||
{
|
||||
if( *c_str == 0 ) return false;
|
||||
|
||||
if( *i != *c_str ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class Char_type >
|
||||
Char_type hex_to_num( const Char_type c )
|
||||
{
|
||||
if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
|
||||
if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
|
||||
if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type hex_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type unicode_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
const Char_type c3( *( ++begin ) );
|
||||
const Char_type c4( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 12 ) +
|
||||
( hex_to_num( c2 ) << 8 ) +
|
||||
( hex_to_num( c3 ) << 4 ) +
|
||||
hex_to_num( c4 );
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
void append_esc_char_and_incr_iter( String_type& s,
|
||||
typename String_type::const_iterator& begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
const Char_type c2( *begin );
|
||||
|
||||
switch( c2 )
|
||||
{
|
||||
case 't': s += '\t'; break;
|
||||
case 'b': s += '\b'; break;
|
||||
case 'f': s += '\f'; break;
|
||||
case 'n': s += '\n'; break;
|
||||
case 'r': s += '\r'; break;
|
||||
case '\\': s += '\\'; break;
|
||||
case '/': s += '/'; break;
|
||||
case '"': s += '"'; break;
|
||||
case 'x':
|
||||
{
|
||||
if( end - begin >= 3 ) // expecting "xHH..."
|
||||
{
|
||||
s += hex_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
if( end - begin >= 5 ) // expecting "uHHHH..."
|
||||
{
|
||||
s += unicode_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type substitute_esc_chars( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
if( end - begin < 2 ) return String_type( begin, end );
|
||||
|
||||
String_type result;
|
||||
|
||||
result.reserve( end - begin );
|
||||
|
||||
const Iter_type end_minus_1( end - 1 );
|
||||
|
||||
Iter_type substr_start = begin;
|
||||
Iter_type i = begin;
|
||||
|
||||
for( ; i < end_minus_1; ++i )
|
||||
{
|
||||
if( *i == '\\' )
|
||||
{
|
||||
result.append( substr_start, i );
|
||||
|
||||
++i; // skip the '\'
|
||||
|
||||
append_esc_char_and_incr_iter( result, i, end );
|
||||
|
||||
substr_start = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
result.append( substr_start, end );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type get_str_( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
assert( end - begin >= 2 );
|
||||
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
Iter_type str_without_quotes( ++begin );
|
||||
Iter_type end_without_quotes( --end );
|
||||
|
||||
return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
|
||||
}
|
||||
|
||||
inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
|
||||
{
|
||||
return get_str_< std::string >( begin, end );
|
||||
}
|
||||
|
||||
inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
|
||||
{
|
||||
return get_str_< std::wstring >( begin, end );
|
||||
}
|
||||
|
||||
template< class String_type, class Iter_type >
|
||||
String_type get_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
const String_type tmp( begin, end ); // convert multipass iterators to string iterators
|
||||
|
||||
return get_str( tmp.begin(), tmp.end() );
|
||||
}
|
||||
|
||||
// this class's methods get called by the spirit parse resulting
|
||||
// in the creation of a JSON object or array
|
||||
//
|
||||
// NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Semantic_actions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Value_type::Config_type Config_type;
|
||||
typedef typename Config_type::String_type String_type;
|
||||
typedef typename Config_type::Object_type Object_type;
|
||||
typedef typename Config_type::Array_type Array_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
Semantic_actions( Value_type& value )
|
||||
: value_( value )
|
||||
, current_p_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void begin_obj( Char_type c )
|
||||
{
|
||||
assert( c == '{' );
|
||||
|
||||
begin_compound< Object_type >();
|
||||
}
|
||||
|
||||
void end_obj( Char_type c )
|
||||
{
|
||||
assert( c == '}' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void begin_array( Char_type c )
|
||||
{
|
||||
assert( c == '[' );
|
||||
|
||||
begin_compound< Array_type >();
|
||||
}
|
||||
|
||||
void end_array( Char_type c )
|
||||
{
|
||||
assert( c == ']' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void new_name( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
name_ = get_str< String_type >( begin, end );
|
||||
}
|
||||
|
||||
void new_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
add_to_current( get_str< String_type >( begin, end ) );
|
||||
}
|
||||
|
||||
void new_true( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "true" ) );
|
||||
|
||||
add_to_current( true );
|
||||
}
|
||||
|
||||
void new_false( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "false" ) );
|
||||
|
||||
add_to_current( false );
|
||||
}
|
||||
|
||||
void new_null( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "null" ) );
|
||||
|
||||
add_to_current( Value_type() );
|
||||
}
|
||||
|
||||
void new_int( boost::int64_t i )
|
||||
{
|
||||
add_to_current( i );
|
||||
}
|
||||
|
||||
void new_uint64( boost::uint64_t ui )
|
||||
{
|
||||
add_to_current( ui );
|
||||
}
|
||||
|
||||
void new_real( double d )
|
||||
{
|
||||
add_to_current( d );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Semantic_actions& operator=( const Semantic_actions& );
|
||||
// to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Value_type* add_first( const Value_type& value )
|
||||
{
|
||||
assert( current_p_ == 0 );
|
||||
|
||||
value_ = value;
|
||||
current_p_ = &value_;
|
||||
return current_p_;
|
||||
}
|
||||
|
||||
template< class Array_or_obj >
|
||||
void begin_compound()
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
add_first( Array_or_obj() );
|
||||
}
|
||||
else
|
||||
{
|
||||
stack_.push_back( current_p_ );
|
||||
|
||||
Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
|
||||
|
||||
current_p_ = add_to_current( new_array_or_obj );
|
||||
}
|
||||
}
|
||||
|
||||
void end_compound()
|
||||
{
|
||||
if( current_p_ != &value_ )
|
||||
{
|
||||
current_p_ = stack_.back();
|
||||
|
||||
stack_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
Value_type* add_to_current( const Value_type& value )
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
return add_first( value );
|
||||
}
|
||||
else if( current_p_->type() == array_type )
|
||||
{
|
||||
current_p_->get_array().push_back( value );
|
||||
|
||||
return ¤t_p_->get_array().back();
|
||||
}
|
||||
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
return &Config_type::add( current_p_->get_obj(), name_, value );
|
||||
}
|
||||
|
||||
Value_type& value_; // this is the object or array that is being created
|
||||
Value_type* current_p_; // the child object or array that is currently being constructed
|
||||
|
||||
std::vector< Value_type* > stack_; // previous child objects and arrays
|
||||
|
||||
String_type name_; // of current name/value pair
|
||||
};
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
|
||||
{
|
||||
throw Error_position( i.get_position().line, i.get_position().column, reason );
|
||||
}
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( Iter_type i, const std::string& reason )
|
||||
{
|
||||
throw reason;
|
||||
}
|
||||
|
||||
// the spirit grammer
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
|
||||
|
||||
Json_grammer( Semantic_actions_t& semantic_actions )
|
||||
: actions_( semantic_actions )
|
||||
{
|
||||
}
|
||||
|
||||
static void throw_not_value( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a value" );
|
||||
}
|
||||
|
||||
static void throw_not_array( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an array" );
|
||||
}
|
||||
|
||||
static void throw_not_object( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an object" );
|
||||
}
|
||||
|
||||
static void throw_not_pair( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a pair" );
|
||||
}
|
||||
|
||||
static void throw_not_colon( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "no colon in pair" );
|
||||
}
|
||||
|
||||
static void throw_not_string( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a string" );
|
||||
}
|
||||
|
||||
template< typename ScannerT >
|
||||
class definition
|
||||
{
|
||||
public:
|
||||
|
||||
definition( const Json_grammer& self )
|
||||
{
|
||||
using namespace spirit_namespace;
|
||||
|
||||
typedef typename Value_type::String_type::value_type Char_type;
|
||||
|
||||
// first we convert the semantic action class methods to functors with the
|
||||
// parameter signature expected by spirit
|
||||
|
||||
typedef boost::function< void( Char_type ) > Char_action;
|
||||
typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
|
||||
typedef boost::function< void( double ) > Real_action;
|
||||
typedef boost::function< void( boost::int64_t ) > Int_action;
|
||||
typedef boost::function< void( boost::uint64_t ) > Uint64_action;
|
||||
|
||||
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
|
||||
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
|
||||
Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
|
||||
Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
|
||||
Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
|
||||
Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
|
||||
Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
|
||||
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
|
||||
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
|
||||
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
|
||||
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
|
||||
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
|
||||
|
||||
// actual grammer
|
||||
|
||||
json_
|
||||
= value_ | eps_p[ &throw_not_value ]
|
||||
;
|
||||
|
||||
value_
|
||||
= string_[ new_str ]
|
||||
| number_
|
||||
| object_
|
||||
| array_
|
||||
| str_p( "true" ) [ new_true ]
|
||||
| str_p( "false" )[ new_false ]
|
||||
| str_p( "null" ) [ new_null ]
|
||||
;
|
||||
|
||||
object_
|
||||
= ch_p('{')[ begin_obj ]
|
||||
>> !members_
|
||||
>> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
|
||||
;
|
||||
|
||||
members_
|
||||
= pair_ >> *( ',' >> pair_ )
|
||||
;
|
||||
|
||||
pair_
|
||||
= string_[ new_name ]
|
||||
>> ( ':' | eps_p[ &throw_not_colon ] )
|
||||
>> ( value_ | eps_p[ &throw_not_value ] )
|
||||
;
|
||||
|
||||
array_
|
||||
= ch_p('[')[ begin_array ]
|
||||
>> !elements_
|
||||
>> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
|
||||
;
|
||||
|
||||
elements_
|
||||
= value_ >> *( ',' >> value_ )
|
||||
;
|
||||
|
||||
string_
|
||||
= lexeme_d // this causes white space inside a string to be retained
|
||||
[
|
||||
confix_p
|
||||
(
|
||||
'"',
|
||||
*lex_escape_ch_p,
|
||||
'"'
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
number_
|
||||
= strict_real_p[ new_real ]
|
||||
| int64_p [ new_int ]
|
||||
| uint64_p [ new_uint64 ]
|
||||
;
|
||||
}
|
||||
|
||||
spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
|
||||
|
||||
const spirit_namespace::rule< ScannerT >& start() const { return json_; }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Semantic_actions_t& actions_;
|
||||
};
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
Semantic_actions< Value_type, Iter_type > semantic_actions( value );
|
||||
|
||||
const spirit_namespace::parse_info< Iter_type > info =
|
||||
spirit_namespace::parse( begin, end,
|
||||
Json_grammer< Value_type, Iter_type >( semantic_actions ),
|
||||
spirit_namespace::space_p );
|
||||
|
||||
if( !info.hit )
|
||||
{
|
||||
assert( false ); // in theory exception should already have been thrown
|
||||
throw_error( info.stop, "error" );
|
||||
}
|
||||
|
||||
return info.stop;
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
|
||||
|
||||
const Posn_iter_t posn_begin( begin, end );
|
||||
const Posn_iter_t posn_end( end, end );
|
||||
|
||||
read_range_or_throw( posn_begin, posn_end, value );
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
try
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
|
||||
return true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
void read_string_or_throw( const String_type& s, Value_type& value )
|
||||
{
|
||||
add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
bool read_string( const String_type& s, Value_type& value )
|
||||
{
|
||||
typename String_type::const_iterator begin = s.begin();
|
||||
|
||||
return read_range( begin, s.end(), value );
|
||||
}
|
||||
|
||||
template< class Istream_type >
|
||||
struct Multi_pass_iters
|
||||
{
|
||||
typedef typename Istream_type::char_type Char_type;
|
||||
typedef std::istream_iterator< Char_type, Char_type > istream_iter;
|
||||
typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
|
||||
|
||||
Multi_pass_iters( Istream_type& is )
|
||||
{
|
||||
is.unsetf( std::ios::skipws );
|
||||
|
||||
begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
|
||||
end_ = spirit_namespace::make_multi_pass( istream_iter() );
|
||||
}
|
||||
|
||||
Mp_iter begin_;
|
||||
Mp_iter end_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
bool read_stream( Istream_type& is, Value_type& value )
|
||||
{
|
||||
Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
return read_range( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
void read_stream_or_throw( Istream_type& is, Value_type& value )
|
||||
{
|
||||
const Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
src/json/json_spirit_stream_reader.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef JSON_SPIRIT_READ_STREAM
|
||||
#define JSON_SPIRIT_READ_STREAM
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// these classes allows you to read multiple top level contiguous values from a stream,
|
||||
// the normal stream read functions have a bug that prevent multiple top level values
|
||||
// from being read unless they are separated by spaces
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader( Istream_type& is )
|
||||
: iters_( is )
|
||||
{
|
||||
}
|
||||
|
||||
bool read_next( Value_type& value )
|
||||
{
|
||||
return read_range( iters_.begin_, iters_.end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
|
||||
Mp_iters iters_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader_thrower
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader_thrower( Istream_type& is )
|
||||
: iters_( is )
|
||||
, posn_begin_( iters_.begin_, iters_.end_ )
|
||||
, posn_end_( iters_.end_, iters_.end_ )
|
||||
{
|
||||
}
|
||||
|
||||
void read_next( Value_type& value )
|
||||
{
|
||||
posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
|
||||
|
||||
Mp_iters iters_;
|
||||
Posn_iter_t posn_begin_, posn_end_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
61
src/json/json_spirit_utils.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef JSON_SPIRIT_UTILS
|
||||
#define JSON_SPIRIT_UTILS
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include <map>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
template< class Obj_t, class Map_t >
|
||||
void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
|
||||
{
|
||||
mp_obj.clear();
|
||||
|
||||
for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
mp_obj[ i->name_ ] = i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
template< class Obj_t, class Map_t >
|
||||
void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
|
||||
{
|
||||
obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map< std::string, Value > Mapped_obj;
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef std::map< std::wstring, wValue > wMapped_obj;
|
||||
#endif
|
||||
|
||||
template< class Object_type, class String_type >
|
||||
const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
|
||||
{
|
||||
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
if( i->name_ == name )
|
||||
{
|
||||
return i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
return Object_type::value_type::Value_type::null;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
8
src/json/json_spirit_value.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
/* Copyright (c) 2007 John W Wilkinson
|
||||
|
||||
This source code can be used for any purpose as long as
|
||||
this comment is retained. */
|
||||
|
||||
// json spirit version 2.00
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
534
src/json/json_spirit_value.h
Normal file
@@ -0,0 +1,534 @@
|
||||
#ifndef JSON_SPIRIT_VALUE
|
||||
#define JSON_SPIRIT_VALUE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
|
||||
static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
|
||||
|
||||
template< class Config > // Config determines whether the value uses std::string or std::wstring and
|
||||
// whether JSON Objects are represented as vectors or maps
|
||||
class Value_impl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Config Config_type;
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Object_type Object;
|
||||
typedef typename Config::Array_type Array;
|
||||
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
|
||||
|
||||
Value_impl(); // creates null value
|
||||
Value_impl( Const_str_ptr value );
|
||||
Value_impl( const String_type& value );
|
||||
Value_impl( const Object& value );
|
||||
Value_impl( const Array& value );
|
||||
Value_impl( bool value );
|
||||
Value_impl( int value );
|
||||
Value_impl( boost::int64_t value );
|
||||
Value_impl( boost::uint64_t value );
|
||||
Value_impl( double value );
|
||||
|
||||
Value_impl( const Value_impl& other );
|
||||
|
||||
bool operator==( const Value_impl& lhs ) const;
|
||||
|
||||
Value_impl& operator=( const Value_impl& lhs );
|
||||
|
||||
Value_type type() const;
|
||||
|
||||
bool is_uint64() const;
|
||||
bool is_null() const;
|
||||
|
||||
const String_type& get_str() const;
|
||||
const Object& get_obj() const;
|
||||
const Array& get_array() const;
|
||||
bool get_bool() const;
|
||||
int get_int() const;
|
||||
boost::int64_t get_int64() const;
|
||||
boost::uint64_t get_uint64() const;
|
||||
double get_real() const;
|
||||
|
||||
Object& get_obj();
|
||||
Array& get_array();
|
||||
|
||||
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
|
||||
// or double d = value.get_value< double >();
|
||||
|
||||
static const Value_impl null;
|
||||
|
||||
private:
|
||||
|
||||
void check_type( const Value_type vtype ) const;
|
||||
|
||||
typedef boost::variant< String_type,
|
||||
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
|
||||
bool, boost::int64_t, double > Variant;
|
||||
|
||||
Value_type type_;
|
||||
Variant v_;
|
||||
bool is_uint64_;
|
||||
};
|
||||
|
||||
// vector objects
|
||||
|
||||
template< class Config >
|
||||
struct Pair_impl
|
||||
{
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Value_type Value_type;
|
||||
|
||||
Pair_impl( const String_type& name, const Value_type& value );
|
||||
|
||||
bool operator==( const Pair_impl& lhs ) const;
|
||||
|
||||
String_type name_;
|
||||
Value_type value_;
|
||||
};
|
||||
|
||||
template< class String >
|
||||
struct Config_vector
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_vector > Value_type;
|
||||
typedef Pair_impl < Config_vector > Pair_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::vector< Pair_type > Object_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
obj.push_back( Pair_type( name , value ) );
|
||||
|
||||
return obj.back().value_;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.name_;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.value_;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_vector< std::string > Config;
|
||||
|
||||
typedef Config::Value_type Value;
|
||||
typedef Config::Pair_type Pair;
|
||||
typedef Config::Object_type Object;
|
||||
typedef Config::Array_type Array;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_vector< std::wstring > wConfig;
|
||||
|
||||
typedef wConfig::Value_type wValue;
|
||||
typedef wConfig::Pair_type wPair;
|
||||
typedef wConfig::Object_type wObject;
|
||||
typedef wConfig::Array_type wArray;
|
||||
#endif
|
||||
|
||||
// map objects
|
||||
|
||||
template< class String >
|
||||
struct Config_map
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_map > Value_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::map< String_type, Value_type > Object_type;
|
||||
typedef typename Object_type::value_type Pair_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
return obj[ name ] = value;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.second;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_map< std::string > mConfig;
|
||||
|
||||
typedef mConfig::Value_type mValue;
|
||||
typedef mConfig::Object_type mObject;
|
||||
typedef mConfig::Array_type mArray;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_map< std::wstring > wmConfig;
|
||||
|
||||
typedef wmConfig::Value_type wmValue;
|
||||
typedef wmConfig::Object_type wmObject;
|
||||
typedef wmConfig::Array_type wmArray;
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation
|
||||
|
||||
template< class Config >
|
||||
const Value_impl< Config > Value_impl< Config >::null;
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl()
|
||||
: type_( null_type )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Const_str_ptr value )
|
||||
: type_( str_type )
|
||||
, v_( String_type( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const String_type& value )
|
||||
: type_( str_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Object& value )
|
||||
: type_( obj_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Array& value )
|
||||
: type_( array_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( bool value )
|
||||
: type_( bool_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( int value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< boost::int64_t >( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( boost::int64_t value )
|
||||
: type_( int_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( boost::uint64_t value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< boost::int64_t >( value ) )
|
||||
, is_uint64_( true )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( double value )
|
||||
: type_( real_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
|
||||
: type_( other.type() )
|
||||
, v_( other.v_ )
|
||||
, is_uint64_( other.is_uint64_ )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
|
||||
{
|
||||
Value_impl tmp( lhs );
|
||||
|
||||
std::swap( type_, tmp.type_ );
|
||||
std::swap( v_, tmp.v_ );
|
||||
std::swap( is_uint64_, tmp.is_uint64_ );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
if( type() != lhs.type() ) return false;
|
||||
|
||||
return v_ == lhs.v_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_type Value_impl< Config >::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_uint64() const
|
||||
{
|
||||
return is_uint64_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_null() const
|
||||
{
|
||||
return type() == null_type;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
void Value_impl< Config >::check_type( const Value_type vtype ) const
|
||||
{
|
||||
if( type() != vtype )
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
///// Bitcoin: Tell the types by name instead of by number
|
||||
os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
|
||||
|
||||
throw std::runtime_error( os.str() );
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Config::String_type& Value_impl< Config >::get_str() const
|
||||
{
|
||||
check_type( str_type );
|
||||
|
||||
return *boost::get< String_type >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::get_bool() const
|
||||
{
|
||||
check_type( bool_type );
|
||||
|
||||
return boost::get< bool >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
int Value_impl< Config >::get_int() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< int >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
boost::int64_t Value_impl< Config >::get_int64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return boost::get< boost::int64_t >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
boost::uint64_t Value_impl< Config >::get_uint64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< boost::uint64_t >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
double Value_impl< Config >::get_real() const
|
||||
{
|
||||
if( type() == int_type )
|
||||
{
|
||||
return is_uint64() ? static_cast< double >( get_uint64() )
|
||||
: static_cast< double >( get_int64() );
|
||||
}
|
||||
|
||||
check_type( real_type );
|
||||
|
||||
return boost::get< double >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
|
||||
: name_( name )
|
||||
, value_( value )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
|
||||
}
|
||||
|
||||
// converts a C string, ie. 8 bit char array, to a string object
|
||||
//
|
||||
template < class String_type >
|
||||
String_type to_str( const char* c_str )
|
||||
{
|
||||
String_type result;
|
||||
|
||||
for( const char* p = c_str; *p != 0; ++p )
|
||||
{
|
||||
result += *p;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
namespace internal_
|
||||
{
|
||||
template< typename T >
|
||||
struct Type_to_type
|
||||
{
|
||||
};
|
||||
|
||||
template< class Value >
|
||||
int get_value( const Value& value, Type_to_type< int > )
|
||||
{
|
||||
return value.get_int();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
|
||||
{
|
||||
return value.get_int64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
|
||||
{
|
||||
return value.get_uint64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
double get_value( const Value& value, Type_to_type< double > )
|
||||
{
|
||||
return value.get_real();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
|
||||
{
|
||||
return value.get_str();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
|
||||
{
|
||||
return value.get_array();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
|
||||
{
|
||||
return value.get_obj();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
bool get_value( const Value& value, Type_to_type< bool > )
|
||||
{
|
||||
return value.get_bool();
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
template< typename T >
|
||||
T Value_impl< Config >::get_value() const
|
||||
{
|
||||
return internal_::get_value( *this, internal_::Type_to_type< T >() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||