Compare commits
1393 Commits
BOB_TEST_M
...
NETSCAPE_7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c148d97e6a | ||
|
|
384b279496 | ||
|
|
1811c2387a | ||
|
|
e6ae73f9f0 | ||
|
|
d5031a8aef | ||
|
|
95d0d37196 | ||
|
|
74cab2329e | ||
|
|
0dedc35ab2 | ||
|
|
f2278f43c8 | ||
|
|
a3ec84f29e | ||
|
|
272f0cdff1 | ||
|
|
4e45b1229b | ||
|
|
677515217e | ||
|
|
b024b7b966 | ||
|
|
e426696a61 | ||
|
|
353c943969 | ||
|
|
c7f4d2143b | ||
|
|
ae544884a8 | ||
|
|
bac8a2e954 | ||
|
|
264bed2362 | ||
|
|
8aa8ecf518 | ||
|
|
771dce7edb | ||
|
|
349f4a6b8d | ||
|
|
9dabd83bf4 | ||
|
|
45a622cb72 | ||
|
|
ca8249f841 | ||
|
|
00ce8402e3 | ||
|
|
66342c6a59 | ||
|
|
5d25e03a26 | ||
|
|
69b31d008b | ||
|
|
d59df3769a | ||
|
|
4f6ada6fdd | ||
|
|
e3de493e7f | ||
|
|
79e2c79078 | ||
|
|
353ffb4a99 | ||
|
|
4b444ea78d | ||
|
|
2c47e8bf69 | ||
|
|
68d49e4a49 | ||
|
|
148c6b76df | ||
|
|
241692a655 | ||
|
|
43be988a2e | ||
|
|
d95ca38926 | ||
|
|
59ad949615 | ||
|
|
e1d31b52f2 | ||
|
|
122962f241 | ||
|
|
ec4d65f5e9 | ||
|
|
3a35be5840 | ||
|
|
918de790d5 | ||
|
|
b588ad7abb | ||
|
|
6d2beab5f0 | ||
|
|
484c0bffbf | ||
|
|
d093302786 | ||
|
|
454a094105 | ||
|
|
3dd881e4eb | ||
|
|
e9685da5ad | ||
|
|
d550f7da85 | ||
|
|
b18105a673 | ||
|
|
b8e0da4c99 | ||
|
|
cebbf97ddf | ||
|
|
c3e6ac982b | ||
|
|
4d3789a510 | ||
|
|
cac9370e7e | ||
|
|
7e6052e43a | ||
|
|
5c9f6ba852 | ||
|
|
adc5ea66d1 | ||
|
|
f6a2d615ee | ||
|
|
935bccd809 | ||
|
|
11fe7c9c82 | ||
|
|
8dc8007734 | ||
|
|
52510b1a61 | ||
|
|
4136782b8e | ||
|
|
16bf0837e9 | ||
|
|
ee1c750ef3 | ||
|
|
24582d244c | ||
|
|
15600e9cc9 | ||
|
|
e2be3f623e | ||
|
|
360da12882 | ||
|
|
45232b694d | ||
|
|
11557cd4cd | ||
|
|
af1ab5cd9a | ||
|
|
1b3ae36bfa | ||
|
|
8b33852684 | ||
|
|
e695b6ea1b | ||
|
|
bd34e4a9a6 | ||
|
|
902c609a39 | ||
|
|
e6ce4cecd3 | ||
|
|
1dd6ca0bf2 | ||
|
|
38307cf9a3 | ||
|
|
2dbf05edde | ||
|
|
dc7f020878 | ||
|
|
ef3496fef8 | ||
|
|
f2b5f60354 | ||
|
|
6d7c54437c | ||
|
|
640a950f34 | ||
|
|
5cec851236 | ||
|
|
26c36cf57f | ||
|
|
f2042f5fed | ||
|
|
411f2bcd84 | ||
|
|
7dbf267463 | ||
|
|
384e1cac18 | ||
|
|
2aed97ba78 | ||
|
|
193e733bfc | ||
|
|
fa426c3455 | ||
|
|
72e5b38215 | ||
|
|
3a8a360848 | ||
|
|
73fe2c170b | ||
|
|
1500211a00 | ||
|
|
f510f3c40f | ||
|
|
79241cbf70 | ||
|
|
4722528d28 | ||
|
|
ad609ac775 | ||
|
|
854492cb27 | ||
|
|
bc9da123c9 | ||
|
|
57c1713df6 | ||
|
|
f7e01beec6 | ||
|
|
fdeb12057d | ||
|
|
8622949487 | ||
|
|
c8a3883144 | ||
|
|
615ded5cba | ||
|
|
53fbb8a4ab | ||
|
|
dd4a48af0d | ||
|
|
334bb84b34 | ||
|
|
6ea542727d | ||
|
|
2c819ea8fa | ||
|
|
8276dd65a0 | ||
|
|
f59687321c | ||
|
|
51cafd0876 | ||
|
|
b200f2abe5 | ||
|
|
99cd8efa51 | ||
|
|
71a1b018b2 | ||
|
|
3adbf31222 | ||
|
|
79c43413c5 | ||
|
|
234d339b8f | ||
|
|
1ea10514a6 | ||
|
|
1377350cdc | ||
|
|
a07b2410b5 | ||
|
|
66b816aec1 | ||
|
|
a5499898ab | ||
|
|
fb6cf5001c | ||
|
|
c06c1c81c1 | ||
|
|
7379db6d0f | ||
|
|
8dfd0be2f4 | ||
|
|
d31db38e1b | ||
|
|
c7e7547ac6 | ||
|
|
07cd809b3c | ||
|
|
c63941f459 | ||
|
|
447244b1b8 | ||
|
|
da5dcb0a53 | ||
|
|
5381e01d9e | ||
|
|
9a8046b3bc | ||
|
|
6c82147405 | ||
|
|
723215b09c | ||
|
|
bbb08f932f | ||
|
|
aaccceee2b | ||
|
|
ba88c2a01f | ||
|
|
f8ecb38366 | ||
|
|
8f768a393f | ||
|
|
b41feead2f | ||
|
|
0c65f033df | ||
|
|
fb016f49df | ||
|
|
c8176f72e4 | ||
|
|
4ac1389355 | ||
|
|
82aaad64fd | ||
|
|
27b63a8651 | ||
|
|
3c9a1c48a9 | ||
|
|
9e81647dfb | ||
|
|
c02c587d59 | ||
|
|
59abfcd74a | ||
|
|
8a9fe70b5f | ||
|
|
287eecfb21 | ||
|
|
47ab7a80c9 | ||
|
|
8210c82fbf | ||
|
|
ccfd0b4ed3 | ||
|
|
9f7559c26f | ||
|
|
96af7cd26d | ||
|
|
365c00df70 | ||
|
|
ff19348c83 | ||
|
|
3dcf34cddb | ||
|
|
461e0fabb2 | ||
|
|
ab6df0d151 | ||
|
|
bfb453b032 | ||
|
|
96d04c8a88 | ||
|
|
8138f9f75d | ||
|
|
253808b572 | ||
|
|
838efbaffc | ||
|
|
d0dc76f1cd | ||
|
|
d784760253 | ||
|
|
4ecba27f46 | ||
|
|
737a2983d9 | ||
|
|
8988f6da45 | ||
|
|
f21b437b1c | ||
|
|
d3e6e4734a | ||
|
|
66853862b5 | ||
|
|
3b36f91f6d | ||
|
|
8a6110386c | ||
|
|
9c664d18c0 | ||
|
|
9d6f298def | ||
|
|
3555d6cf63 | ||
|
|
9148e88703 | ||
|
|
29313725bb | ||
|
|
1ca5f2df20 | ||
|
|
c103108810 | ||
|
|
5ca9ccb8b5 | ||
|
|
05118109bc | ||
|
|
ee2f062637 | ||
|
|
6fb5cd2313 | ||
|
|
cf00b52da2 | ||
|
|
8023d5b6a3 | ||
|
|
3caa15fea0 | ||
|
|
51a8ec8ac7 | ||
|
|
2a8076c485 | ||
|
|
90d90b777c | ||
|
|
d027b325ef | ||
|
|
148c919829 | ||
|
|
17ce578faa | ||
|
|
654d90b6b8 | ||
|
|
92f366df0e | ||
|
|
859b9bf284 | ||
|
|
ce0af0ef4e | ||
|
|
8bbe93efd9 | ||
|
|
25b4c3389a | ||
|
|
06d700b8d4 | ||
|
|
639474a89e | ||
|
|
ce1e3c03b5 | ||
|
|
239db03a1d | ||
|
|
9dcf945f94 | ||
|
|
098a6b94b7 | ||
|
|
fb6cc8e082 | ||
|
|
b3b11437a8 | ||
|
|
306252b88f | ||
|
|
3e3feeebb2 | ||
|
|
ef5e271ffd | ||
|
|
71eb38c4d9 | ||
|
|
e23dff8f91 | ||
|
|
3d08029c45 | ||
|
|
6a02131f6c | ||
|
|
4df00a3088 | ||
|
|
e6af590601 | ||
|
|
44d41aa222 | ||
|
|
93b7ef8f0c | ||
|
|
5ada44a604 | ||
|
|
f1e23fb653 | ||
|
|
10ecd2cb1c | ||
|
|
62eda89c24 | ||
|
|
c1df55f01b | ||
|
|
8ee6840c00 | ||
|
|
1fdfd53ba4 | ||
|
|
4cc53df442 | ||
|
|
3e06338d30 | ||
|
|
5ec9d0dafa | ||
|
|
6c54fb56fc | ||
|
|
608973612d | ||
|
|
10ce09d738 | ||
|
|
a92f30d9c3 | ||
|
|
88346339f0 | ||
|
|
77698771ed | ||
|
|
ff93b8dcda | ||
|
|
be0bcee8f3 | ||
|
|
f5057e6483 | ||
|
|
09049016ea | ||
|
|
eafd14d1f0 | ||
|
|
6033805e92 | ||
|
|
2b5c8e9cbd | ||
|
|
58e659e1e9 | ||
|
|
46d05f5f74 | ||
|
|
f3996f782c | ||
|
|
2d45da0f14 | ||
|
|
8c8adeec08 | ||
|
|
9371bccc37 | ||
|
|
a1f63a989a | ||
|
|
49ac50f0c2 | ||
|
|
e1b79228fa | ||
|
|
d9a050b6c1 | ||
|
|
0335eb8910 | ||
|
|
204e2b5863 | ||
|
|
a0bc28a6f0 | ||
|
|
20f52a464a | ||
|
|
99e1cc2ee7 | ||
|
|
7a453fda9c | ||
|
|
42936b4b40 | ||
|
|
ff1b8f2964 | ||
|
|
15ab5b9a2e | ||
|
|
c374ea8952 | ||
|
|
f97c54d160 | ||
|
|
f07bfa94eb | ||
|
|
c64b227676 | ||
|
|
8176e540c2 | ||
|
|
a025d90adb | ||
|
|
48933113ab | ||
|
|
99dd57db43 | ||
|
|
4656a50b00 | ||
|
|
27d41038fa | ||
|
|
08fcc4efa9 | ||
|
|
1c43d58ca0 | ||
|
|
d35f1c396d | ||
|
|
6798a8a496 | ||
|
|
073f0dcac1 | ||
|
|
e54f9a1948 | ||
|
|
ad7d6a84eb | ||
|
|
2607c79153 | ||
|
|
498e49324c | ||
|
|
ac467dfb2f | ||
|
|
f12373b8d5 | ||
|
|
0a50be934d | ||
|
|
f9c5aa5879 | ||
|
|
205be5ebc7 | ||
|
|
3f782d2982 | ||
|
|
dedb6e44a9 | ||
|
|
01d73157aa | ||
|
|
9bcf6107c1 | ||
|
|
b0100e4d87 | ||
|
|
75a1d85212 | ||
|
|
6b3f3a6e88 | ||
|
|
9f5554c942 | ||
|
|
7a969df31e | ||
|
|
73e99cd734 | ||
|
|
48b621a0d7 | ||
|
|
034c7403c1 | ||
|
|
8a24b2305c | ||
|
|
8f8d06a1fe | ||
|
|
463bf075db | ||
|
|
418629f9d5 | ||
|
|
b5d5402be6 | ||
|
|
b4a2bbf3f2 | ||
|
|
f28341d7b8 | ||
|
|
f565d2710a | ||
|
|
1ab282c09c | ||
|
|
b413625b22 | ||
|
|
6dd25d57b7 | ||
|
|
7ca15ca9f9 | ||
|
|
d8d51f3fc0 | ||
|
|
c30c45478b | ||
|
|
b473eb7b46 | ||
|
|
c94b3e468f | ||
|
|
dd891e72f6 | ||
|
|
7bba6c9005 | ||
|
|
6ae72b82cb | ||
|
|
99beaa40ee | ||
|
|
09abd13db8 | ||
|
|
96e7c17494 | ||
|
|
a401e3ecba | ||
|
|
6c0f61c5a2 | ||
|
|
170660efc8 | ||
|
|
d56b6fd084 | ||
|
|
18f184a211 | ||
|
|
150f8f03e3 | ||
|
|
8ed155c7ba | ||
|
|
cc36111653 | ||
|
|
a66b9d84db | ||
|
|
57d568048a | ||
|
|
9a471b1f2f | ||
|
|
106d1530e9 | ||
|
|
4cf91c1b48 | ||
|
|
15c656b10b | ||
|
|
7cb24c9de3 | ||
|
|
527788efa4 | ||
|
|
cac2e2c5d4 | ||
|
|
0865ca0b65 | ||
|
|
168b1d9d62 | ||
|
|
87c57eb05c | ||
|
|
88dbfb8ef3 | ||
|
|
2b4245627a | ||
|
|
d3b53fc01e | ||
|
|
b8d2b60148 | ||
|
|
e974827d29 | ||
|
|
8d58c6c22a | ||
|
|
812ae457cb | ||
|
|
e5ed010bad | ||
|
|
b091abdb95 | ||
|
|
d8344db317 | ||
|
|
a3b6cbfd26 | ||
|
|
2639e2de42 | ||
|
|
148b9b56d7 | ||
|
|
30aaf9a866 | ||
|
|
d03db64f78 | ||
|
|
162e114cdd | ||
|
|
50e9a1cd12 | ||
|
|
aad7e440e1 | ||
|
|
485d22cd1c | ||
|
|
27b1c3bc88 | ||
|
|
c95102f0f0 | ||
|
|
70385b3718 | ||
|
|
e0192c396e | ||
|
|
8fb90c754e | ||
|
|
9a512b60f0 | ||
|
|
fff521cbd6 | ||
|
|
39375575a6 | ||
|
|
d23a86c5c3 | ||
|
|
087a8d3d50 | ||
|
|
246c3064c1 | ||
|
|
2ea2d4de49 | ||
|
|
0e2ab4c13f | ||
|
|
5cb1e89f42 | ||
|
|
7d244ddadf | ||
|
|
f7aa411272 | ||
|
|
b6f33143fe | ||
|
|
23938e1717 | ||
|
|
ed6d2aba83 | ||
|
|
1170c07f03 | ||
|
|
15f32e23c9 | ||
|
|
284c90077f | ||
|
|
53e7ffd9da | ||
|
|
fc905321c3 | ||
|
|
364c30f59a | ||
|
|
bece21038b | ||
|
|
88de7c2871 | ||
|
|
3d229b7740 | ||
|
|
cbc343bcad | ||
|
|
f8110798ca | ||
|
|
0a0fbe2b15 | ||
|
|
55a8e79021 | ||
|
|
7cb0d3f5dc | ||
|
|
6204f58f95 | ||
|
|
7a35619362 | ||
|
|
69fdcdef0c | ||
|
|
3afe010889 | ||
|
|
d8d07f6235 | ||
|
|
642c729f4e | ||
|
|
2ff622ca46 | ||
|
|
a733dd87e2 | ||
|
|
843fa93fba | ||
|
|
93ea8d41f1 | ||
|
|
ebadae9792 | ||
|
|
2637ca49a6 | ||
|
|
22b4aee6eb | ||
|
|
0b3c166594 | ||
|
|
ff060bf719 | ||
|
|
2ff8ef790d | ||
|
|
b903fd496a | ||
|
|
e497d8f399 | ||
|
|
d717db1875 | ||
|
|
4fcf400300 | ||
|
|
295383061e | ||
|
|
d0f40241a4 | ||
|
|
dfd5d6c9ec | ||
|
|
e6ddc2474b | ||
|
|
93cdc87a79 | ||
|
|
12ecf6bcb0 | ||
|
|
b4d784f8d8 | ||
|
|
0a404730ea | ||
|
|
9f22569679 | ||
|
|
3aadc3f62c | ||
|
|
b3565ee5a2 | ||
|
|
685a627533 | ||
|
|
cca1a6a27b | ||
|
|
8c1ce051a9 | ||
|
|
3cf2173b4a | ||
|
|
529f8521a0 | ||
|
|
b3362334e8 | ||
|
|
f8dc8bd65b | ||
|
|
8f7826ad96 | ||
|
|
c1c82a4bf0 | ||
|
|
754ab85e59 | ||
|
|
9165c56436 | ||
|
|
ae6ef0fdcb | ||
|
|
f9a16cd243 | ||
|
|
fa11ccfde9 | ||
|
|
86f432ff5d | ||
|
|
3f7e61ce94 | ||
|
|
71868732bb | ||
|
|
d392c2ff2f | ||
|
|
625fbbe83b | ||
|
|
c1f2efd43e | ||
|
|
0ef43da159 | ||
|
|
3b19241611 | ||
|
|
66b707f9ce | ||
|
|
2ffecc5625 | ||
|
|
9d6c62d59b | ||
|
|
b7b4b2f45b | ||
|
|
8d3089dd17 | ||
|
|
256d2ce004 | ||
|
|
780d805419 | ||
|
|
c469567b9a | ||
|
|
a4de0a2603 | ||
|
|
36574a7556 | ||
|
|
be6ce362bd | ||
|
|
bc06dc9fd9 | ||
|
|
b0d670a1bc | ||
|
|
ccf19469e2 | ||
|
|
809492f2af | ||
|
|
baf10331b3 | ||
|
|
1bca56362e | ||
|
|
ea000b5701 | ||
|
|
ab1fa0d555 | ||
|
|
0d09ea3339 | ||
|
|
37ec5826d5 | ||
|
|
e25c13eb4a | ||
|
|
bd61327cdd | ||
|
|
71c13892eb | ||
|
|
8a3ae50022 | ||
|
|
5e7a7f7db5 | ||
|
|
1e502bbf38 | ||
|
|
fd8db7de55 | ||
|
|
641c28f51e | ||
|
|
71fb0333e3 | ||
|
|
46fdd2e57c | ||
|
|
73b3c9ec10 | ||
|
|
e772c6a373 | ||
|
|
d49716cc16 | ||
|
|
bfd72020ce | ||
|
|
45d310c534 | ||
|
|
443455d190 | ||
|
|
6b7774434c | ||
|
|
afd9eb05a3 | ||
|
|
79b9d48b8a | ||
|
|
da914522df | ||
|
|
31126db321 | ||
|
|
4a14b96c8e | ||
|
|
f2462d5e0b | ||
|
|
61eb91d637 | ||
|
|
faa2be8068 | ||
|
|
4811d76344 | ||
|
|
0489976ef5 | ||
|
|
80b1c385f2 | ||
|
|
694206f300 | ||
|
|
5ff90e973b | ||
|
|
128e42c9dd | ||
|
|
641f4eb20b | ||
|
|
a14d66bb1f | ||
|
|
a8bcd7ecec | ||
|
|
bd5650ab43 | ||
|
|
79ac763969 | ||
|
|
6218a087c3 | ||
|
|
6c076d2bd5 | ||
|
|
0fe0c70ad3 | ||
|
|
2aa0bfec52 | ||
|
|
77f1f8f1df | ||
|
|
3f71f67714 | ||
|
|
6122646715 | ||
|
|
27640dbd20 | ||
|
|
06234068c2 | ||
|
|
09df9a43cd | ||
|
|
4f01124326 | ||
|
|
9ab4d01371 | ||
|
|
8556706ac2 | ||
|
|
113fc7d204 | ||
|
|
6b608c92ae | ||
|
|
b2b18152d1 | ||
|
|
dbd893968e | ||
|
|
1c3f5eac5b | ||
|
|
70ff3fdd2c | ||
|
|
2f7cfac5a6 | ||
|
|
ed50252be8 | ||
|
|
7d6679d157 | ||
|
|
6f8c6a62b9 | ||
|
|
e2747f8c64 | ||
|
|
f25a0d5a5c | ||
|
|
70a1b8abe7 | ||
|
|
8af267ad6a | ||
|
|
a6b0dcd241 | ||
|
|
623e2a09c2 | ||
|
|
c8f1a5e385 | ||
|
|
f699f6b31d | ||
|
|
4a62f540f1 | ||
|
|
70eae9b6d2 | ||
|
|
af3c3a24e3 | ||
|
|
0db2ffc3af | ||
|
|
b440081fa2 | ||
|
|
1f286b0218 | ||
|
|
ef3972ac83 | ||
|
|
8394ac5fb2 | ||
|
|
db5ef2f455 | ||
|
|
b7e98f8495 | ||
|
|
60b9930469 | ||
|
|
eac3e2e9aa | ||
|
|
1acf8aa761 | ||
|
|
5d51407505 | ||
|
|
e63bb9d794 | ||
|
|
eb15ad393e | ||
|
|
8232e89286 | ||
|
|
c698a87201 | ||
|
|
619380c3c0 | ||
|
|
231f605b15 | ||
|
|
f715a3b168 | ||
|
|
2b3cc7e607 | ||
|
|
a0b5cde66a | ||
|
|
20cb6cb693 | ||
|
|
168886b9ad | ||
|
|
0399e58fdf | ||
|
|
06d29ea249 | ||
|
|
7e5c288be8 | ||
|
|
6fb3b48978 | ||
|
|
61e874fa84 | ||
|
|
7d78857470 | ||
|
|
619bc7e159 | ||
|
|
69e6810d1e | ||
|
|
75ba7f14e5 | ||
|
|
cce7fdff34 | ||
|
|
bf6cc01b52 | ||
|
|
bcb095f8a9 | ||
|
|
bd7dff22a8 | ||
|
|
972cceb99c | ||
|
|
7e1e6c7215 | ||
|
|
4b60d7372d | ||
|
|
57052515de | ||
|
|
dff5676e1b | ||
|
|
8b6b478b81 | ||
|
|
6756ed03f7 | ||
|
|
b762f8fe07 | ||
|
|
3a341d46ca | ||
|
|
106518fe50 | ||
|
|
cc7cfafe27 | ||
|
|
8503fd95ac | ||
|
|
d7c55ba002 | ||
|
|
3c981d26f8 | ||
|
|
d6ac34c459 | ||
|
|
8bff0a3a2c | ||
|
|
ad80341982 | ||
|
|
5729030ee1 | ||
|
|
d314cdc629 | ||
|
|
a22348496f | ||
|
|
a46e91bf0d | ||
|
|
4f992a26fb | ||
|
|
eaa2ea31bd | ||
|
|
12293d26da | ||
|
|
a1a530fb8d | ||
|
|
f93de378fe | ||
|
|
84f47ba861 | ||
|
|
c0b0d51402 | ||
|
|
b8e76d926a | ||
|
|
92d7706b2f | ||
|
|
cae49d7651 | ||
|
|
ff07968863 | ||
|
|
0aa9d241d4 | ||
|
|
2a7aacb79b | ||
|
|
1122710c52 | ||
|
|
964142a3a3 | ||
|
|
eb31acfa17 | ||
|
|
58f9ceadcb | ||
|
|
b82e3dd3d7 | ||
|
|
9a2febfed4 | ||
|
|
963096e847 | ||
|
|
d0734c2a24 | ||
|
|
7d08b37835 | ||
|
|
eddc65a611 | ||
|
|
2deeb9d762 | ||
|
|
b904c4673f | ||
|
|
28dc3cc184 | ||
|
|
968f595848 | ||
|
|
c25de96b99 | ||
|
|
1ad8ee4834 | ||
|
|
dd826b760f | ||
|
|
8c45a0d797 | ||
|
|
c3218394e4 | ||
|
|
4a8b42df43 | ||
|
|
cdae846961 | ||
|
|
01f6ba274d | ||
|
|
1361e7e34c | ||
|
|
5b3948723c | ||
|
|
7359ab3a7a | ||
|
|
27f4fc61c4 | ||
|
|
00521a78a1 | ||
|
|
c058e66325 | ||
|
|
f2d72b7f87 | ||
|
|
978551c1f7 | ||
|
|
de87376b96 | ||
|
|
c57068e4c1 | ||
|
|
a623ac4e0e | ||
|
|
9afb0e7d74 | ||
|
|
e0b2480d0e | ||
|
|
b5bebe6668 | ||
|
|
d945ef7ecf | ||
|
|
225f0aa962 | ||
|
|
e43da87623 | ||
|
|
dfab04f55c | ||
|
|
458ff6f480 | ||
|
|
3c64131dd8 | ||
|
|
a1f4627d40 | ||
|
|
17138832e5 | ||
|
|
17531efb1a | ||
|
|
41e6f47bfa | ||
|
|
2c9614fb10 | ||
|
|
6afd739cf1 | ||
|
|
2457823369 | ||
|
|
aeaefb716d | ||
|
|
d4beef1773 | ||
|
|
928f583b71 | ||
|
|
0282fc286e | ||
|
|
04cc039c07 | ||
|
|
7f1f83e834 | ||
|
|
b423f4baff | ||
|
|
4a96596e09 | ||
|
|
ad33f31373 | ||
|
|
080e80a637 | ||
|
|
53d656a9a1 | ||
|
|
89b0d7af2c | ||
|
|
1c4cdfade6 | ||
|
|
63f6028c4e | ||
|
|
246b3f7e9f | ||
|
|
e45a686be7 | ||
|
|
1dce744290 | ||
|
|
5df1afe6e6 | ||
|
|
da482534b3 | ||
|
|
be64be1dfd | ||
|
|
afe8df3d75 | ||
|
|
3ee011d02b | ||
|
|
bd5ddb70ea | ||
|
|
d6c39cca3a | ||
|
|
2fe6680b3f | ||
|
|
1347bd1e96 | ||
|
|
b9c5c653e6 | ||
|
|
d6b4715e32 | ||
|
|
ecbe515d79 | ||
|
|
44cab4adea | ||
|
|
a2dc91d683 | ||
|
|
9607a311ed | ||
|
|
804ae553c3 | ||
|
|
be7d4fdde0 | ||
|
|
6aed6f697f | ||
|
|
624fe1566b | ||
|
|
ec1577308a | ||
|
|
e3aa3a71cb | ||
|
|
90dcf11081 | ||
|
|
132e190048 | ||
|
|
dc9928eb7c | ||
|
|
428ff1c549 | ||
|
|
c61baaa999 | ||
|
|
edee1b6680 | ||
|
|
885c533ef0 | ||
|
|
de0519cd67 | ||
|
|
c5ac50d5e2 | ||
|
|
4cb5382fca | ||
|
|
0bc0799597 | ||
|
|
9e0f7ffb8a | ||
|
|
cfa280641e | ||
|
|
a911b0b748 | ||
|
|
be9c8fa239 | ||
|
|
0d32d05921 | ||
|
|
bf7b44d54f | ||
|
|
a2b5d31397 | ||
|
|
6d0476c328 | ||
|
|
2cd31bb596 | ||
|
|
637548fb10 | ||
|
|
26949a54c9 | ||
|
|
3c7053730f | ||
|
|
ee3c3f96d7 | ||
|
|
9039f3c7b0 | ||
|
|
a000b7234a | ||
|
|
218651a65b | ||
|
|
423460521b | ||
|
|
732eb22602 | ||
|
|
28a1c909e4 | ||
|
|
da24b92c2a | ||
|
|
204f826da0 | ||
|
|
4516f9102e | ||
|
|
ab56848021 | ||
|
|
69d2a48ff1 | ||
|
|
c5b72f03a1 | ||
|
|
d455161f02 | ||
|
|
764bd4bf65 | ||
|
|
5a4cd2828d | ||
|
|
303b3fe0e3 | ||
|
|
cb4a0b5b63 | ||
|
|
80b989b275 | ||
|
|
5dbd73bf67 | ||
|
|
0481dc4c6e | ||
|
|
d525363520 | ||
|
|
748665aa52 | ||
|
|
c4da75c128 | ||
|
|
2795a668d6 | ||
|
|
1b6ec3d818 | ||
|
|
83d6027167 | ||
|
|
5c6d280101 | ||
|
|
3528882472 | ||
|
|
d630028f35 | ||
|
|
3b629c5fe4 | ||
|
|
21346b8835 | ||
|
|
cdca1f405a | ||
|
|
ce1fd5d84c | ||
|
|
5f87a200ec | ||
|
|
66d54a8b6d | ||
|
|
5f02b8269b | ||
|
|
b4fff11fed | ||
|
|
3243c72cb2 | ||
|
|
0c5d530ffc | ||
|
|
2fcaf0e746 | ||
|
|
2f87640ce4 | ||
|
|
be372b62a6 | ||
|
|
76c08bd2ed | ||
|
|
da5d212dfc | ||
|
|
5c41eb1716 | ||
|
|
91b9b7e794 | ||
|
|
4da30258e7 | ||
|
|
295058cc41 | ||
|
|
7774ce5dcf | ||
|
|
5f60368f08 | ||
|
|
ca60e23706 | ||
|
|
bf883ac38d | ||
|
|
cfa1d71b55 | ||
|
|
3a72186992 | ||
|
|
af6aa2ea05 | ||
|
|
114aae699d | ||
|
|
f9848fb7b1 | ||
|
|
856aebbbd6 | ||
|
|
526ec82985 | ||
|
|
67a384bafa | ||
|
|
d7a3ed9aa3 | ||
|
|
77a9c7a763 | ||
|
|
9065957d3d | ||
|
|
9188b6c365 | ||
|
|
fe32f8706e | ||
|
|
e79695d563 | ||
|
|
ed20e5e6fd | ||
|
|
612499e4d0 | ||
|
|
d41a137af5 | ||
|
|
6692771666 | ||
|
|
5f0ca989b0 | ||
|
|
cbc76df7dc | ||
|
|
68df67103c | ||
|
|
5980efcab5 | ||
|
|
7452c85b9c | ||
|
|
1e1f13f227 | ||
|
|
1bfdcafcb0 | ||
|
|
b78558faa1 | ||
|
|
9861f30e1d | ||
|
|
ed501b059e | ||
|
|
5204f1360e | ||
|
|
b07b40ca0e | ||
|
|
4ad7f1e776 | ||
|
|
f2459da232 | ||
|
|
55b08dd44e | ||
|
|
ffbc7660a6 | ||
|
|
cf51d1ad90 | ||
|
|
fe7fca9da1 | ||
|
|
cd24c92cb2 | ||
|
|
be65bb26c2 | ||
|
|
90ddac64b6 | ||
|
|
e6f6feeecc | ||
|
|
b4e1ea9f95 | ||
|
|
2c7a49f756 | ||
|
|
f6370ccef4 | ||
|
|
8fb0709493 | ||
|
|
07160b3d82 | ||
|
|
dda6dbadfe | ||
|
|
26aaabc693 | ||
|
|
52844744bf | ||
|
|
006631235e | ||
|
|
678f5fafba | ||
|
|
e20087bf71 | ||
|
|
7d4fc36816 | ||
|
|
8a4bb68747 | ||
|
|
4e211fa8a0 | ||
|
|
4618d9b438 | ||
|
|
c0a5bc3dda | ||
|
|
a02f3f6976 | ||
|
|
6cd2d41b36 | ||
|
|
93608b2018 | ||
|
|
fab25ee31b | ||
|
|
d8ef8c6365 | ||
|
|
cb972e1f0e | ||
|
|
af14ded3fc | ||
|
|
6aa16322cb | ||
|
|
5a0d585550 | ||
|
|
447d10c73f | ||
|
|
a514b9a490 | ||
|
|
2dac4a584c | ||
|
|
2d65aaeb5c | ||
|
|
81cfb6b041 | ||
|
|
658d17a08a | ||
|
|
7ed400413d | ||
|
|
8f84341661 | ||
|
|
f4b6547ce1 | ||
|
|
fba63e7c60 | ||
|
|
8514da82d2 | ||
|
|
2e5b4e7927 | ||
|
|
47d9eca542 | ||
|
|
eaeb0298a2 | ||
|
|
327ecc2f83 | ||
|
|
63384d1830 | ||
|
|
9349315a9a | ||
|
|
6927396daf | ||
|
|
072579ba85 | ||
|
|
a76e8d6662 | ||
|
|
0810edec5f | ||
|
|
e952bcd424 | ||
|
|
6884165424 | ||
|
|
a521a1b0e2 | ||
|
|
72a95558c8 | ||
|
|
050a707758 | ||
|
|
052d83d570 | ||
|
|
682e0c7c38 | ||
|
|
c399a0d6b1 | ||
|
|
213e72aaf3 | ||
|
|
919dac4da6 | ||
|
|
022fbb7508 | ||
|
|
5e3510d4b1 | ||
|
|
ae1a1cd55d | ||
|
|
d44e782fba | ||
|
|
21b640baee | ||
|
|
aa9bee63fc | ||
|
|
35b56c75c2 | ||
|
|
6991439448 | ||
|
|
7bee723d56 | ||
|
|
df2a5275d4 | ||
|
|
aff4e0bb2f | ||
|
|
b81d803390 | ||
|
|
ab6ac0a31d | ||
|
|
472d6e0cfb | ||
|
|
d0c0a6a921 | ||
|
|
72900e0edb | ||
|
|
cbe2249b39 | ||
|
|
ab0aa7118c | ||
|
|
a4c3785f50 | ||
|
|
28fea7fe7d | ||
|
|
ba98c54594 | ||
|
|
2250ff40dc | ||
|
|
e2b8fd356a | ||
|
|
a33ccabd1e | ||
|
|
3c96562702 | ||
|
|
80bafa48f9 | ||
|
|
ef779b7b11 | ||
|
|
b1ac5dd228 | ||
|
|
db876e378d | ||
|
|
ea4c27d979 | ||
|
|
9bed9c8290 | ||
|
|
6d752f5d9b | ||
|
|
8fc073e52b | ||
|
|
5a31496eb0 | ||
|
|
3519bd22cf | ||
|
|
cb38baf4c8 | ||
|
|
dd53284abb | ||
|
|
0b3df0b317 | ||
|
|
fd5e4b32c1 | ||
|
|
b8ed7d5184 | ||
|
|
6c88206d50 | ||
|
|
6300150636 | ||
|
|
fa48dfcca2 | ||
|
|
8ae38475b0 | ||
|
|
d8b7e7f848 | ||
|
|
89fbc40586 | ||
|
|
3fca8a4975 | ||
|
|
e9031b6800 | ||
|
|
efbd75a0b3 | ||
|
|
cb74781241 | ||
|
|
62ca5a2c59 | ||
|
|
bb399b0937 | ||
|
|
1bff3d0f84 | ||
|
|
a672bca9fe | ||
|
|
8b85480c73 | ||
|
|
c22abfef1a | ||
|
|
a65215f7d3 | ||
|
|
4c2e366f9b | ||
|
|
fcc1b296a8 | ||
|
|
954a04b866 | ||
|
|
2b62bd490c | ||
|
|
969733934b | ||
|
|
92504d633b | ||
|
|
6345f05f54 | ||
|
|
aaef08a0d4 | ||
|
|
bc513f36aa | ||
|
|
344a2a950f | ||
|
|
afd9deff38 | ||
|
|
21c1975abf | ||
|
|
f01bb5c354 | ||
|
|
5738f2de70 | ||
|
|
b1bcc03db3 | ||
|
|
f57bfe8089 | ||
|
|
9696b2257b | ||
|
|
6308211d36 | ||
|
|
087b513af8 | ||
|
|
55781765c2 | ||
|
|
0b880c3f33 | ||
|
|
07c3528f53 | ||
|
|
433f63c85f | ||
|
|
2c9d5ffb80 | ||
|
|
57359a5752 | ||
|
|
dd0a7ce7ea | ||
|
|
0d02bd205a | ||
|
|
8cf733bbc1 | ||
|
|
b5cb98b819 | ||
|
|
90402b9a8c | ||
|
|
6423619c8f | ||
|
|
9209ff62fe | ||
|
|
a0d1145f8e | ||
|
|
74e73e10f3 | ||
|
|
238feddbd6 | ||
|
|
a978be0193 | ||
|
|
cb5b4b1b01 | ||
|
|
3ec439a1fd | ||
|
|
c16ff0faf0 | ||
|
|
506b99572b | ||
|
|
4679a340c1 | ||
|
|
9bc7ddddf4 | ||
|
|
a9d5b91669 | ||
|
|
64a4b4e041 | ||
|
|
bb57de0d36 | ||
|
|
ade3fc802f | ||
|
|
c478573816 | ||
|
|
6d80075884 | ||
|
|
3eb34b884b | ||
|
|
4353adcf44 | ||
|
|
8ce8efd86e | ||
|
|
22af3d19b0 | ||
|
|
3e667aeba3 | ||
|
|
9717ee655a | ||
|
|
8bf0331753 | ||
|
|
131bb3f6bb | ||
|
|
b0533dc7a4 | ||
|
|
2464767a0e | ||
|
|
b3ff479e57 | ||
|
|
8edc1bfe80 | ||
|
|
9151441b62 | ||
|
|
e90f36f1ba | ||
|
|
b085bafb64 | ||
|
|
ab66163d40 | ||
|
|
f72164b69a | ||
|
|
0a3fb441b8 | ||
|
|
ace6774c42 | ||
|
|
90cc2ae2ad | ||
|
|
486c6118e2 | ||
|
|
84438fad56 | ||
|
|
c9db4ed2fd | ||
|
|
0dd4d12051 | ||
|
|
584cad73f4 | ||
|
|
e851fcf629 | ||
|
|
c8cd4c0142 | ||
|
|
eed8ea112d | ||
|
|
0cdefef72b | ||
|
|
7bc93da4c9 | ||
|
|
6505f6ae3f | ||
|
|
327e48530d | ||
|
|
ecc5bf01f7 | ||
|
|
56e1aee489 | ||
|
|
01f4d66b6b | ||
|
|
e5e4f0b26c | ||
|
|
a792c0ba44 | ||
|
|
9f7c157dc0 | ||
|
|
a1c5d620cf | ||
|
|
647489f91d | ||
|
|
79017aee7c | ||
|
|
7093aeefa2 | ||
|
|
9187ea31c1 | ||
|
|
959b0bd890 | ||
|
|
e9b4d1c37e | ||
|
|
4de9db38fa | ||
|
|
95537ada6b | ||
|
|
c7287e9c01 | ||
|
|
d096ea5ef8 | ||
|
|
5cff0b49e8 | ||
|
|
1986167e81 | ||
|
|
16c69a134c | ||
|
|
1baf46f180 | ||
|
|
9e403beae8 | ||
|
|
888df6e957 | ||
|
|
05920ee992 | ||
|
|
0194225d8b | ||
|
|
97c9c1ece8 | ||
|
|
50d2799bf8 | ||
|
|
509866e746 | ||
|
|
11f00a6636 | ||
|
|
00c4fb82f8 | ||
|
|
b73ef7a9df | ||
|
|
484eac2e03 | ||
|
|
edc01d68be | ||
|
|
c863d44ace | ||
|
|
e418971eda | ||
|
|
dd7b6b45f5 | ||
|
|
a1721de603 | ||
|
|
a696f04d4d | ||
|
|
c3af0047a7 | ||
|
|
f4637ef0de | ||
|
|
cb3a2e0996 | ||
|
|
a5212f8062 | ||
|
|
9c851a6d41 | ||
|
|
9ff0d77979 | ||
|
|
72108100e8 | ||
|
|
e3a4480ddc | ||
|
|
4a76d52d77 | ||
|
|
256c0c9094 | ||
|
|
02d880cb36 | ||
|
|
1b3fa859b9 | ||
|
|
a6bb24d4c8 | ||
|
|
7c9a240e91 | ||
|
|
5cee5838bf | ||
|
|
0726835c64 | ||
|
|
320ca6ca28 | ||
|
|
4072445f12 | ||
|
|
3f8bb42c7e | ||
|
|
44eccf3e99 | ||
|
|
bca9d10196 | ||
|
|
5d265597f7 | ||
|
|
533e58886e | ||
|
|
afd1e054ec | ||
|
|
42f8892aeb | ||
|
|
c6b05ab2a7 | ||
|
|
8d79ab9138 | ||
|
|
8a331877f7 | ||
|
|
bf5f91136e | ||
|
|
92dc132e55 | ||
|
|
6320031aac | ||
|
|
324d0ddc3b | ||
|
|
95cb3a686d | ||
|
|
51fa48e028 | ||
|
|
030dc46ba9 | ||
|
|
a3ae03ad37 | ||
|
|
514f134015 | ||
|
|
8a410b6fe1 | ||
|
|
509d393ae1 | ||
|
|
1f51267cb5 | ||
|
|
2e507a2491 | ||
|
|
17d4973104 | ||
|
|
8da15e1c80 | ||
|
|
19e0851b35 | ||
|
|
3106d5e24d | ||
|
|
ff9eb3391c | ||
|
|
ee124649b2 | ||
|
|
902cd5e269 | ||
|
|
40e5a9d113 | ||
|
|
8df34cd68e | ||
|
|
8e808c44ee | ||
|
|
cfcaa9c909 | ||
|
|
4023b25ccc | ||
|
|
168b044abc | ||
|
|
01a5f01e3f | ||
|
|
93cb40a1c2 | ||
|
|
e33240dbef | ||
|
|
5c8009f90e | ||
|
|
812bb1716c | ||
|
|
dd51cc7727 | ||
|
|
9b5a6028f2 | ||
|
|
83f74adbed | ||
|
|
6d7ba532c9 | ||
|
|
719f6148dd | ||
|
|
5d62c3cc6a | ||
|
|
aae80b929a | ||
|
|
c3c7fa242d | ||
|
|
8d102035fa | ||
|
|
aa91314590 | ||
|
|
f1d171d635 | ||
|
|
b3068b50ef | ||
|
|
7579ba6446 | ||
|
|
eaa65c0868 | ||
|
|
09e6ecc483 | ||
|
|
cbe5acd88b | ||
|
|
44309b6b69 | ||
|
|
e232ba020c | ||
|
|
aaf2e134b8 | ||
|
|
29c0a861b1 | ||
|
|
699a315d5e | ||
|
|
6e2c371544 | ||
|
|
6c1e42594e | ||
|
|
45b43ac004 | ||
|
|
b502b8efc1 | ||
|
|
52bc62de79 | ||
|
|
7beecd0046 | ||
|
|
959f48bb82 | ||
|
|
9392bde1e3 | ||
|
|
d4bc26bd24 | ||
|
|
aa4c21982b | ||
|
|
9820819552 | ||
|
|
880f61a67c | ||
|
|
521e7835df | ||
|
|
c5bd386711 | ||
|
|
e85e0624e7 | ||
|
|
9821e88608 | ||
|
|
b4b60272e8 | ||
|
|
fc89f1262e | ||
|
|
3e5989752f | ||
|
|
a40574c03f | ||
|
|
f6cf35ca4e | ||
|
|
33244035e4 | ||
|
|
1071f10c04 | ||
|
|
e6328bd509 | ||
|
|
d86149a289 | ||
|
|
14eda85230 | ||
|
|
57e6b9c547 | ||
|
|
82d1070192 | ||
|
|
c0392aee23 | ||
|
|
02822617db | ||
|
|
172fc515a3 | ||
|
|
eac3008773 | ||
|
|
52cca6ed36 | ||
|
|
02f579ce4a | ||
|
|
9ed956dcca | ||
|
|
96d8a8ece0 | ||
|
|
bf9337f3d8 | ||
|
|
4ce66d0295 | ||
|
|
5b7d330067 | ||
|
|
9c4bd18276 | ||
|
|
36ca27b46a | ||
|
|
998811395f | ||
|
|
e7acea9915 | ||
|
|
65d1906f81 | ||
|
|
fce95b6677 | ||
|
|
2ec240eb5c | ||
|
|
21202829f3 | ||
|
|
df8ed489af | ||
|
|
759cc84ac4 | ||
|
|
5e7aa6a1c8 | ||
|
|
943efc9e9f | ||
|
|
b7b3e572b6 | ||
|
|
2b12789fbf | ||
|
|
aaa9ecf79b | ||
|
|
9ac4527500 | ||
|
|
d9d21ee90f | ||
|
|
0068546bf3 | ||
|
|
0d8ecd0d21 | ||
|
|
a41a9d2a9e | ||
|
|
39b506ab01 | ||
|
|
bd004663da | ||
|
|
6ee8dd438a | ||
|
|
a8674b4e10 | ||
|
|
31f63c43ed | ||
|
|
4eb038a1c4 | ||
|
|
094f94cb44 | ||
|
|
82b127ba0b | ||
|
|
93d7608437 | ||
|
|
efe7a90161 | ||
|
|
3c852822ad | ||
|
|
195ec35e03 | ||
|
|
ffc3fedbde | ||
|
|
70903d0a21 | ||
|
|
ce8692fe97 | ||
|
|
a41718dcc7 | ||
|
|
133c46acb5 | ||
|
|
a7ee21f18d | ||
|
|
ea39f306d9 | ||
|
|
c71efb01ce | ||
|
|
e0a60c50f5 | ||
|
|
efec05ce41 | ||
|
|
b5d53cbfd1 | ||
|
|
07e496302c | ||
|
|
329777865b | ||
|
|
bde5680d10 | ||
|
|
60f04d9ed1 | ||
|
|
a44296e6f4 | ||
|
|
4fd072f9b3 | ||
|
|
02d6beada3 | ||
|
|
cf4ae53af2 | ||
|
|
c5bcf9cb2d | ||
|
|
31012ea782 | ||
|
|
3045303bda | ||
|
|
664f7b6ba9 | ||
|
|
ae1c53e386 | ||
|
|
0b3bab9d61 | ||
|
|
7234c2c8d4 | ||
|
|
a86b530963 | ||
|
|
7798a03d15 | ||
|
|
bc50d32b62 | ||
|
|
8fa83f72eb | ||
|
|
c27c3fcdcc | ||
|
|
735a2536da | ||
|
|
f24f902979 | ||
|
|
64dd27f57c | ||
|
|
33ecf1d294 | ||
|
|
918dad7488 | ||
|
|
0d3b70b536 | ||
|
|
6ebf49f699 | ||
|
|
b1df11336d | ||
|
|
6497384abd | ||
|
|
af6d4e6058 | ||
|
|
d0ddeb0ea7 | ||
|
|
177c560d03 | ||
|
|
b5137cca5b | ||
|
|
5b4d8f10d0 | ||
|
|
15861e0899 | ||
|
|
459491e786 | ||
|
|
a25e0f514e | ||
|
|
c5eb29c591 | ||
|
|
5551933833 | ||
|
|
6f7df30dbe | ||
|
|
c7bae18605 | ||
|
|
cbac461555 | ||
|
|
e7af3755e5 | ||
|
|
cf1554a393 | ||
|
|
45fcc528e6 | ||
|
|
6fb703b7e6 | ||
|
|
c90c704127 | ||
|
|
bc2f5778ac | ||
|
|
5820b9d970 | ||
|
|
26432dcb35 | ||
|
|
a060ea6240 | ||
|
|
fdfe478178 | ||
|
|
cea9c992fa | ||
|
|
e510dfda65 | ||
|
|
3349bf4f6c | ||
|
|
50de85c1f1 | ||
|
|
f5acf31b44 | ||
|
|
9a5c5ad50c | ||
|
|
bd887d65a7 | ||
|
|
dfc2a9baa4 | ||
|
|
785b3a8b97 | ||
|
|
e089b55ded | ||
|
|
56eaff5f89 | ||
|
|
b1b0b5e26f | ||
|
|
5f9959cb6a | ||
|
|
d0d165e336 | ||
|
|
673fac74ae | ||
|
|
849a03fcf4 | ||
|
|
43b89a87c3 | ||
|
|
2b462d89ac | ||
|
|
7f02e46de6 | ||
|
|
6ea3a5d455 | ||
|
|
6fd3021383 | ||
|
|
75ffa9f160 | ||
|
|
ae776da105 | ||
|
|
add60686df | ||
|
|
318c4d4e32 | ||
|
|
e93a97fc87 | ||
|
|
758b75177d | ||
|
|
045bea67fd | ||
|
|
d78f3e282e | ||
|
|
f6400c0959 | ||
|
|
9507ed70ae | ||
|
|
358d670381 | ||
|
|
76ee3df50c | ||
|
|
d37950ff50 | ||
|
|
a31ba917d3 | ||
|
|
72cf8919f4 | ||
|
|
a533e6f79e | ||
|
|
e8755c4945 | ||
|
|
e661aff94e | ||
|
|
11af650b54 | ||
|
|
7bdf727629 | ||
|
|
804d8b6a74 | ||
|
|
4699ab09d6 | ||
|
|
a7ec286d93 | ||
|
|
10b1eb2d72 | ||
|
|
f9b23c4cbf | ||
|
|
8a360f6c9d | ||
|
|
b3f041a340 | ||
|
|
f1ccc4dde2 | ||
|
|
42d216f822 | ||
|
|
9e65ef69a5 | ||
|
|
36cdd5f3ff | ||
|
|
d0f31fb261 | ||
|
|
f8e3cddf0a | ||
|
|
4604325dfc | ||
|
|
34ed215e04 | ||
|
|
fa5c5eeb7d | ||
|
|
3317bd174a | ||
|
|
04958e3f9b | ||
|
|
92ff2b7272 | ||
|
|
58150531b4 | ||
|
|
0869043d48 | ||
|
|
c8e259b919 | ||
|
|
c74d723da4 | ||
|
|
d3fb5163a2 | ||
|
|
4ce3a9d36f | ||
|
|
e629278774 | ||
|
|
22d56d374f | ||
|
|
587635d6b6 | ||
|
|
551965e5db | ||
|
|
1e111acc39 | ||
|
|
c461ca32b7 | ||
|
|
a0bac4e516 | ||
|
|
8e4140b79c | ||
|
|
7f3448f68f | ||
|
|
0ee3a71577 | ||
|
|
b1e2b1e3bf | ||
|
|
2ade79cfe2 | ||
|
|
f57fa35533 | ||
|
|
c89366eb3e | ||
|
|
204c694be1 | ||
|
|
b148ba5407 | ||
|
|
9090496ade | ||
|
|
1d66a32348 | ||
|
|
d8a4df2f50 | ||
|
|
daca085785 | ||
|
|
992e77fb04 | ||
|
|
fbe8d4409c | ||
|
|
4743655549 | ||
|
|
08b55a8c92 | ||
|
|
358a7fceee | ||
|
|
6f907b6f81 | ||
|
|
be52de925f | ||
|
|
d7072a40f3 | ||
|
|
7d36c6511d | ||
|
|
9d9d6d8619 | ||
|
|
239695399c | ||
|
|
c1b3007458 | ||
|
|
731717a2fe | ||
|
|
c92d888b06 | ||
|
|
3722e59eaa | ||
|
|
7341a8a72f | ||
|
|
d87745cb1f | ||
|
|
26fe20452e | ||
|
|
fa18c05f79 | ||
|
|
a48dbb8e4c | ||
|
|
e317dd137f | ||
|
|
8946cfe8c2 | ||
|
|
4a01af29d0 | ||
|
|
c14766db45 | ||
|
|
e885f1dd15 | ||
|
|
bab75062ce | ||
|
|
49443b5f2c | ||
|
|
895a74da95 | ||
|
|
446b07e818 | ||
|
|
7fbc9919c2 | ||
|
|
6320f9759f | ||
|
|
72b6ef5cdc | ||
|
|
024577fbad | ||
|
|
6e8bb30a03 |
80
mozilla/build/mac/build_scripts/BuildMozilla.pl
Normal file
80
mozilla/build/mac/build_scripts/BuildMozilla.pl
Normal file
@@ -0,0 +1,80 @@
|
||||
#!perl
|
||||
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Simon Fraser <sfraser@netscape.com>
|
||||
#
|
||||
|
||||
require 5.004;
|
||||
|
||||
use strict;
|
||||
|
||||
use Cwd;
|
||||
use Moz::BuildUtils;
|
||||
use Moz::BuildCore;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Where have the build options gone?
|
||||
#
|
||||
# The various build flags have been centralized into one place.
|
||||
# The master list of options is in MozBuildFlags.txt. However,
|
||||
# you should never need to edit that file, or this one.
|
||||
#
|
||||
# To customize what gets built, or where to start the build,
|
||||
# edit the $prefs_file_name file in
|
||||
# System Folder:Preferences:Mozilla build prefs:
|
||||
# Documentation is provided in that file.
|
||||
#-------------------------------------------------------------
|
||||
|
||||
my($prefs_file_name) = "Mozilla opt build prefs";
|
||||
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptions.h";
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# hashes to hold build options
|
||||
#-------------------------------------------------------------
|
||||
my(%build);
|
||||
my(%options);
|
||||
my(%filepaths);
|
||||
my(%optiondefines);
|
||||
|
||||
# Hash of input files for this build. Eventually, there will be
|
||||
# input files for manifests, and projects too.
|
||||
my(%inputfiles) = (
|
||||
"buildflags", "MozillaBuildFlags.txt",
|
||||
"checkoutdata", "MozillaCheckoutList.txt",
|
||||
"buildprogress", "¥ Mozilla opt progress",
|
||||
"buildmodule", "MozillaBuildList.pm",
|
||||
"checkouttime", "Mozilla last checkout"
|
||||
);
|
||||
#-------------------------------------------------------------
|
||||
# end build hashes
|
||||
#-------------------------------------------------------------
|
||||
|
||||
# set the build root directory, which is the the dir above mozilla
|
||||
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
|
||||
|
||||
# Set up all the flags on $main::, like DEBUG, CARBON etc.
|
||||
# Override the defaults using the preferences files.
|
||||
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", $config_header_file_name);
|
||||
|
||||
my($do_checkout) = 0;
|
||||
my($do_build) = 1;
|
||||
|
||||
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);
|
||||
80
mozilla/build/mac/build_scripts/BuildMozillaDebug.pl
Normal file
80
mozilla/build/mac/build_scripts/BuildMozillaDebug.pl
Normal file
@@ -0,0 +1,80 @@
|
||||
#!perl
|
||||
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Simon Fraser <sfraser@netscape.com>
|
||||
#
|
||||
|
||||
require 5.004;
|
||||
|
||||
use strict;
|
||||
|
||||
use Cwd;
|
||||
use Moz::BuildUtils;
|
||||
use Moz::BuildCore;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Where have the build options gone?
|
||||
#
|
||||
# The various build flags have been centralized into one place.
|
||||
# The master list of options is in MozBuildFlags.txt. However,
|
||||
# you should never need to edit that file, or this one.
|
||||
#
|
||||
# To customize what gets built, or where to start the build,
|
||||
# edit the $prefs_file_name file in
|
||||
# System Folder:Preferences:Mozilla build prefs:
|
||||
# Documentation is provided in that file.
|
||||
#-------------------------------------------------------------
|
||||
|
||||
my($prefs_file_name) = "Mozilla debug build prefs";
|
||||
my($config_header_file_name) = ":mozilla:config:mac:DefinesOptionsDebug.h";
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# hashes to hold build options
|
||||
#-------------------------------------------------------------
|
||||
my(%build);
|
||||
my(%options);
|
||||
my(%filepaths);
|
||||
my(%optiondefines);
|
||||
|
||||
# Hash of input files for this build. Eventually, there will be
|
||||
# input files for manifests, and projects too.
|
||||
my(%inputfiles) = (
|
||||
"buildflags", "MozillaBuildFlags.txt",
|
||||
"checkoutdata", "MozillaCheckoutList.txt",
|
||||
"buildprogress", "¥ Mozilla debug progress",
|
||||
"buildmodule", "MozillaBuildList.pm",
|
||||
"checkouttime", "Mozilla last checkout"
|
||||
);
|
||||
#-------------------------------------------------------------
|
||||
# end build hashes
|
||||
#-------------------------------------------------------------
|
||||
|
||||
# set the build root directory, which is the the dir above mozilla
|
||||
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
|
||||
|
||||
# Set up all the flags on $main::, like DEBUG, CARBON etc.
|
||||
# Override the defaults using the preferences files.
|
||||
SetupDefaultBuildOptions(1, ":mozilla:dist:viewer_debug:", $config_header_file_name);
|
||||
|
||||
my($do_pull) = 0; # overridden by flags and prefs
|
||||
my($do_build) = 1;
|
||||
|
||||
RunBuild($do_pull, $do_build, \%inputfiles, $prefs_file_name);
|
||||
595
mozilla/build/mac/build_scripts/Moz/BuildCore.pm
Normal file
595
mozilla/build/mac/build_scripts/Moz/BuildCore.pm
Normal file
@@ -0,0 +1,595 @@
|
||||
#!perl -w
|
||||
package Moz::BuildCore;
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
use strict;
|
||||
use vars qw( @ISA @EXPORT );
|
||||
|
||||
# perl includes
|
||||
use Cwd;
|
||||
use POSIX;
|
||||
use Time::Local;
|
||||
use File::Basename;
|
||||
use LWP::Simple;
|
||||
|
||||
# homegrown
|
||||
use Moz::Moz;
|
||||
use Moz::Jar;
|
||||
use Moz::BuildFlags;
|
||||
use Moz::BuildUtils;
|
||||
use Moz::CodeWarriorLib;
|
||||
|
||||
# use MozillaBuildList; # eventually, this should go away, and be replaced by data input
|
||||
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
RunBuild
|
||||
);
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// DoPrebuildCheck
|
||||
#//
|
||||
#// Check the build tools etc before running the build.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub DoPrebuildCheck()
|
||||
{
|
||||
SanityCheckBuildOptions();
|
||||
|
||||
# launch codewarrior and persist its location. Have to call this before first
|
||||
# call to getCodeWarriorPath().
|
||||
my($ide_path_file) = $main::filepaths{"idepath"};
|
||||
$ide_path_file = full_path_to($ide_path_file);
|
||||
LaunchCodeWarrior($ide_path_file);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SanityCheckBuildOptions
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SanityCheckBuildOptions()
|
||||
{
|
||||
my($bad_options) = 0;
|
||||
|
||||
# Jar options
|
||||
if (!$main::options{chrome_jars} && !$main::options{chrome_files})
|
||||
{
|
||||
print "Warning: Both \$options{chrome_jars} and \$options{chrome_files} are off. You won't get any chrome.\n";
|
||||
$bad_options = 1;
|
||||
}
|
||||
|
||||
if (!$main::options{chrome_jars} && $main::options{use_jars})
|
||||
{
|
||||
print "Warning: \$options{chrome_jars} is off but \$options{use_jars} is on. Your build won't run (expects jars, got files).\n";
|
||||
$bad_options = 1;
|
||||
}
|
||||
|
||||
if (!$main::options{chrome_files} && !$main::options{use_jars})
|
||||
{
|
||||
print "Warning: \$options{chrome_jars} is off but \$options{chrome_files} is on. Your build won't run (expects files, got jars).\n";
|
||||
$bad_options = 1;
|
||||
}
|
||||
|
||||
if ($main::options{ldap_experimental} && !$main::options{ldap})
|
||||
{
|
||||
print "Warning: \$options{ldap_experimental} is on but \$options{ldap} is off. LDAP experimental features will not be built.\n";
|
||||
$bad_options = 1;
|
||||
}
|
||||
|
||||
if ($main::options{wsp} && !$main::options{xmlextras})
|
||||
{
|
||||
print "Warning: \$options{wsp} is on but \$options{xmlextras} is off. wsp will not be built.\n";
|
||||
$bad_options = 1;
|
||||
}
|
||||
|
||||
if ($bad_options) {
|
||||
print "Build will start in 5 seconds. Press command-. to stop\n";
|
||||
|
||||
DelayFor(5);
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GenBuildSystemInfo
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub GenBuildSystemInfo()
|
||||
{
|
||||
# always rebuild the configuration program.
|
||||
BuildProjectClean(":mozilla:build:mac:tools:BuildSystemInfo:BuildSystemInfo.mcp", "BuildSystemInfo");
|
||||
|
||||
# delete the configuration file.
|
||||
unlink(":mozilla:build:mac:BuildSystemInfo.pm");
|
||||
|
||||
# run the program.
|
||||
system(":mozilla:build:mac:BuildSystemInfo");
|
||||
|
||||
# wait for the file to be created.
|
||||
while (!(-e ":mozilla:build:mac:BuildSystemInfo.pm")) { WaitNextEvent(); }
|
||||
|
||||
# wait for BuildSystemInfo to finish, so that we see correct results.
|
||||
while (IsProcessRunning("BuildSystemInfo")) { WaitNextEvent(); }
|
||||
|
||||
# now, evaluate the contents of the file.
|
||||
open(F, ":mozilla:build:mac:BuildSystemInfo.pm");
|
||||
while (<F>) { eval; }
|
||||
close(F);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Make library aliases
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub MakeLibAliases()
|
||||
{
|
||||
my($dist_dir) = GetBinDirectory();
|
||||
|
||||
#// ProfilerLib
|
||||
if ($main::PROFILE)
|
||||
{
|
||||
my($profilerlibpath) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Profiler:Profiler Common:ProfilerLib");
|
||||
MakeAlias("$profilerlibpath", "$dist_dir"."Essential Files:");
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ConfigureBuildSystem
|
||||
#//
|
||||
#// defines some build-system configuration variables.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ConfigureBuildSystem()
|
||||
{
|
||||
#// In the future, we may want to do configurations based on the actual build system itself.
|
||||
#// GenBuildSystemInfo();
|
||||
|
||||
#// For now, if we discover a newer header file than existed in Universal Interfaces 3.2,
|
||||
#// we'll assume that 3.3 or later is in use.
|
||||
my($universal_interfaces) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:Universal:Interfaces:CIncludes:");
|
||||
if (-e ($universal_interfaces . "ControlDefinitions.h")) {
|
||||
$main::UNIVERSAL_INTERFACES_VERSION = 0x0330;
|
||||
}
|
||||
|
||||
#// Rename IC SDK folder in the Mac OS Support folder
|
||||
my($ic_sdk_folder) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:ICProgKit2.0.2");
|
||||
if( -e $ic_sdk_folder)
|
||||
{
|
||||
my($new_ic_folder_name) = Moz::CodeWarriorLib::getCodeWarriorPath("MacOS Support:(ICProgKit2.0.2)");
|
||||
rename ($ic_sdk_folder, $new_ic_folder_name);
|
||||
# note that CodeWarrior doesn't descend into folders with () the name
|
||||
print "Mozilla no longer needs the Internet Config SDK to build:\n Renaming the 'ICProgKit2.0.2' folder to '(ICProgKit2.0.2)'\n";
|
||||
}
|
||||
|
||||
printf("UNIVERSAL_INTERFACES_VERSION = 0x%04X\n", $main::UNIVERSAL_INTERFACES_VERSION);
|
||||
|
||||
# alias required CodeWarrior libs into the Essential Files folder (only the Profiler lib now)
|
||||
MakeLibAliases();
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// CheckOutModule. Takes variable number of args; first two are required
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub CheckOutModule($$$$)
|
||||
{
|
||||
my($session, $module, $revision, $date) = @_;
|
||||
|
||||
my($result) = $session->checkout($module, $revision, $date);
|
||||
|
||||
# result of 1 is success
|
||||
if ($result) { return; }
|
||||
|
||||
my($checkout_err) = $session->getLastError();
|
||||
if ($checkout_err == 708) {
|
||||
die "Error: Checkout was cancelled.\n";
|
||||
} elsif ($checkout_err == 911) {
|
||||
die "Error: CVS session settings are incorrect. Check your password, and the CVS root settings.\n";
|
||||
} elsif ($checkout_err == 703) {
|
||||
die "Error: CVS checkout failed. Unknown module, unknown tag, bad username, or other CVS error.\n";
|
||||
} elsif ($checkout_err == 711) {
|
||||
print "Checkout of '$module' failed.\n";
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getScriptFolder
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getScriptFolder()
|
||||
{
|
||||
return dirname($0);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getScriptFolder
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub get_url_contents($)
|
||||
{
|
||||
my($url) = @_;
|
||||
|
||||
my($url_contents) = LWP::Simple::get($url);
|
||||
$url_contents =~ s/\r\n/\n/g; # normalize linebreaks
|
||||
$url_contents =~ s/\r/\n/g; # normalize linebreaks
|
||||
return $url_contents;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// get_files_from_content
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub uniq
|
||||
{
|
||||
my $lastval;
|
||||
grep(($_ ne $lastval, $lastval = $_)[$[], @_);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// get_files_from_content
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub get_files_from_content($)
|
||||
{
|
||||
my($content) = @_;
|
||||
|
||||
my(@jscalls) = grep (/return js_file_menu[^{]*/, split(/\n/, $content));
|
||||
my $i;
|
||||
|
||||
for ($i = 0; $i < @jscalls ; $i++)
|
||||
{
|
||||
$jscalls[$i] =~ s/.*\(|\).*//g;
|
||||
my(@callparams) = split(/,/, $jscalls[$i]);
|
||||
my ($repos, $dir, $file, $rev) = grep(s/['\s]//g, @callparams);
|
||||
$jscalls[$i] = "$dir/$file";
|
||||
}
|
||||
|
||||
&uniq(sort(@jscalls));
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getLastUpdateTime
|
||||
#//
|
||||
#// Get the last time we updated. Return 0 on failure
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getLastUpdateTime($)
|
||||
{
|
||||
my($timestamp_file) = @_;
|
||||
|
||||
my($time_string);
|
||||
|
||||
local(*TIMESTAMP_FILE);
|
||||
unless (open(TIMESTAMP_FILE, "< $timestamp_file")) { return 0; }
|
||||
|
||||
while (<TIMESTAMP_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
# ignore comments and empty lines
|
||||
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
|
||||
next;
|
||||
}
|
||||
|
||||
$time_string = $line;
|
||||
}
|
||||
|
||||
# get the epoch seconds
|
||||
my($last_update_secs) = $time_string;
|
||||
$last_update_secs =~ s/\s#.+$//;
|
||||
|
||||
print "FAST_UPDATE found that you last updated at ".localtime($last_update_secs)."\n";
|
||||
|
||||
# how long ago was this, in hours?
|
||||
my($gm_now) = time();
|
||||
my($update_hours) = 1 + ceil(($gm_now - $last_update_secs) / (60 * 60));
|
||||
|
||||
return $update_hours;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// saveCheckoutTimestamp
|
||||
#//
|
||||
#// Create a file on disk containing the current time. Param is time(), which is an Epoch seconds
|
||||
#// (and therefore in GMT).
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub saveCheckoutTimestamp($$)
|
||||
{
|
||||
my($gm_secs, $timestamp_file) = @_;
|
||||
|
||||
local(*TIMESTAMP_FILE);
|
||||
open(TIMESTAMP_FILE, ">$timestamp_file") || die "Failed to open $timestamp_file\n";
|
||||
print(TIMESTAMP_FILE "# time of last checkout or update, in GMT. Used by FAST_UPDATE\n");
|
||||
print(TIMESTAMP_FILE "$gm_secs \# around ".localtime()." local time\n");
|
||||
close(TIMESTAMP_FILE);
|
||||
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// FastUpdate
|
||||
#//
|
||||
#// Use Bonsai url data to update only those dirs which have new files
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub FastUpdate($$)
|
||||
{
|
||||
my($modules, $timestamp_file) = @_; # list of modules to check out
|
||||
|
||||
my($num_hours) = getLastUpdateTime($timestamp_file);
|
||||
if ($num_hours == 0 || $num_hours > 170) {
|
||||
print "Can't fast_update; last update was too long ago, or never. Doing normal checkout.\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
print "Doing fast update, pulling files changed in the last $num_hours hours\n";
|
||||
|
||||
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
|
||||
my($session) = Moz::MacCVS->new( $cvsfile );
|
||||
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
|
||||
|
||||
# activate MacCVS
|
||||
ActivateApplication('Mcvs');
|
||||
|
||||
my($checkout_start_time) = time();
|
||||
|
||||
#print "Time now is $checkout_start_time ($checkout_start_time + 0)\n";
|
||||
|
||||
my($this_co);
|
||||
foreach $this_co (@$modules)
|
||||
{
|
||||
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
|
||||
|
||||
# assume that things pulled by date wont change
|
||||
if ($date ne "") {
|
||||
print "$module is pulled by date, so ignoring in FastUpdate.\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my($search_type) = "hours";
|
||||
my($min_date) = "";
|
||||
my($max_date) = "";
|
||||
my($url) = "http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&module=${module}&branch=${revision}&branchtype=match&dir=&file=&filetype=match&who=&whotype=match&sortby=Date&hours=${num_hours}&date=${search_type}&mindate=${min_date}&maxdate=${max_date}&cvsroot=%2Fcvsroot";
|
||||
|
||||
if ($revision eq "") {
|
||||
print "Getting list of checkins to $module from Bonsai...\n";
|
||||
} else {
|
||||
print "Getting list of checkins to $module on branch $revision from Bonsai...\n";
|
||||
}
|
||||
my(@files) = &get_files_from_content(&get_url_contents($url));
|
||||
|
||||
if ($#files > 0)
|
||||
{
|
||||
my(@cvs_co_list);
|
||||
|
||||
my($co_file);
|
||||
foreach $co_file (@files)
|
||||
{
|
||||
print "Updating $co_file\n";
|
||||
push(@cvs_co_list, $co_file);
|
||||
}
|
||||
|
||||
my($result) = $session->update($revision, \@cvs_co_list);
|
||||
# result of 1 is success
|
||||
if (!$result) { die "Error: Fast update failed\n"; }
|
||||
} else {
|
||||
print "No files in this module changed\n";
|
||||
}
|
||||
}
|
||||
|
||||
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Checkout
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub CheckoutModules($$$)
|
||||
{
|
||||
my($modules, $pull_date, $timestamp_file) = @_; # list of modules to check out
|
||||
|
||||
my($start_time) = TimeStart();
|
||||
|
||||
# assertRightDirectory();
|
||||
my($cvsfile) = AskAndPersistFile($main::filepaths{"sessionpath"});
|
||||
my($session) = Moz::MacCVS->new( $cvsfile );
|
||||
unless (defined($session)) { die "Error: Checkout aborted. Cannot create session file: $session" }
|
||||
|
||||
my($checkout_start_time) = time();
|
||||
|
||||
# activate MacCVS
|
||||
ActivateApplication('Mcvs');
|
||||
|
||||
my($this_co);
|
||||
foreach $this_co (@$modules)
|
||||
{
|
||||
my($module, $revision, $date) = ($this_co->[0], $this_co->[1], $this_co->[2]);
|
||||
if ($date eq "") {
|
||||
$date = $pull_date;
|
||||
}
|
||||
CheckOutModule($session, $module, $revision, $date);
|
||||
# print "Checking out $module with ref $revision, date $date\n";
|
||||
}
|
||||
|
||||
saveCheckoutTimestamp($checkout_start_time, $timestamp_file);
|
||||
TimeEnd($start_time, "Checkout");
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ReadCheckoutModulesFile
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ReadCheckoutModulesFile($$)
|
||||
{
|
||||
my($modules_file, $co_list) = @_;
|
||||
|
||||
my($checkout_file) = getScriptFolder().":".$modules_file;
|
||||
local(*CHECKOUT_FILE);
|
||||
open(CHECKOUT_FILE, "< $checkout_file") || die "Error: failed to open checkout list $checkout_file\n";
|
||||
while (<CHECKOUT_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
# ignore comments and empty lines
|
||||
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
|
||||
next;
|
||||
}
|
||||
|
||||
my(@cvs_co) = ["", "", ""];
|
||||
|
||||
my($module, $revision, $date) = (0, 1, 2);
|
||||
|
||||
if ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*\,\s*([^#]+)/)
|
||||
{
|
||||
@cvs_co[$module] = $1;
|
||||
@cvs_co[$revision] = $2;
|
||||
@cvs_co[$date] = $3;
|
||||
}
|
||||
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*([^#,\s]+)\s*(#.+)?/)
|
||||
{
|
||||
@cvs_co[$module] = $1;
|
||||
@cvs_co[$revision] = $2;
|
||||
}
|
||||
elsif ($line =~ /\s*([^#,\s]+)\s*\,\s*,\s*([^#,]+)/)
|
||||
{
|
||||
@cvs_co[$module] = $1;
|
||||
@cvs_co[$date] = $2;
|
||||
}
|
||||
elsif ($line =~ /\s*([^#,\s]+)/)
|
||||
{
|
||||
@cvs_co[$module] = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error: unrecognized line '$line' in $modules_file\n";
|
||||
}
|
||||
|
||||
# strip surrounding space from date
|
||||
@cvs_co[$date] =~ s/^\s*|\s*$//g;
|
||||
|
||||
# print "Going to check out '@cvs_co[$module]', '@cvs_co[$revision]', '@cvs_co[$date]'\n";
|
||||
push(@$co_list, \@cvs_co);
|
||||
}
|
||||
|
||||
close(CHECKOUT_FILE);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// PullFromCVS
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub PullFromCVS($$)
|
||||
{
|
||||
unless ( $main::build{pull} ) { return; }
|
||||
|
||||
my($modules_file, $timestamp_file) = @_;
|
||||
|
||||
StartBuildModule("pull");
|
||||
|
||||
my(@cvs_co_list);
|
||||
ReadCheckoutModulesFile($modules_file, \@cvs_co_list);
|
||||
|
||||
if ($main::FAST_UPDATE && $main::options{pull_by_date})
|
||||
{
|
||||
die "Error: you can't use FAST_UPDATE if you are pulling by date.\n";
|
||||
}
|
||||
|
||||
my($did_fast_update) = $main::FAST_UPDATE && FastUpdate(\@cvs_co_list, $timestamp_file);
|
||||
if (!$did_fast_update)
|
||||
{
|
||||
my($pull_date) = "";
|
||||
if ($main::options{pull_by_date})
|
||||
{
|
||||
# acceptable CVS date formats are (in local time):
|
||||
# ISO8601 (e.g. "1972-09-24 20:05") and Internet (e.g. "24 Sep 1972 20:05").
|
||||
# Perl's localtime() string format also seems to work.
|
||||
$pull_date = localtime().""; # force string interp.
|
||||
print "Pulling by date $pull_date\n";
|
||||
}
|
||||
|
||||
CheckoutModules(\@cvs_co_list, $pull_date, $timestamp_file);
|
||||
}
|
||||
|
||||
EndBuildModule("pull");
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// RunBuild
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub RunBuild($$$$)
|
||||
{
|
||||
my($do_pull, $do_build, $input_files, $build_prefs) = @_;
|
||||
|
||||
InitBuildProgress($input_files->{"buildprogress"});
|
||||
|
||||
# if we are pulling, we probably want to do a full build, so clear the build progress
|
||||
if ($do_pull) {
|
||||
ClearBuildProgress();
|
||||
}
|
||||
|
||||
# read local prefs, and the build progress file, and set flags to say what to build
|
||||
SetupBuildParams(\%main::build,
|
||||
\%main::options,
|
||||
\%main::optiondefines,
|
||||
\%main::filepaths,
|
||||
$input_files->{"buildflags"},
|
||||
$build_prefs);
|
||||
|
||||
# If we were told to pull, make sure we do, overriding prefs etc.
|
||||
if ($do_pull)
|
||||
{
|
||||
$main::build{"pull"} = 1;
|
||||
}
|
||||
|
||||
# transfer this flag
|
||||
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = $main::CLOSE_PROJECTS_FIRST;
|
||||
|
||||
# setup the build log
|
||||
SetupBuildLog($main::filepaths{"buildlogfilepath"}, $main::USE_TIMESTAMPED_LOGS);
|
||||
StopForErrors();
|
||||
|
||||
if ($main::LOG_TO_FILE) {
|
||||
RedirectOutputToFile($main::filepaths{"scriptlogfilepath"});
|
||||
}
|
||||
|
||||
# run a pre-build check to see that the tools etc are in order
|
||||
DoPrebuildCheck();
|
||||
|
||||
# do the pull
|
||||
PullFromCVS($input_files->{"checkoutdata"}, $input_files->{"checkouttime"});
|
||||
|
||||
unless ($do_build) { return; }
|
||||
|
||||
my($build_start) = TimeStart();
|
||||
|
||||
# check the build environment
|
||||
ConfigureBuildSystem();
|
||||
|
||||
# here we load and call methods in the build module indirectly.
|
||||
# we have to use indirection because the build module can be named
|
||||
# differently for different builds.
|
||||
chdir(dirname($0)); # change to the script dir
|
||||
my($build_module) = $input_files->{"buildmodule"};
|
||||
# load the build module
|
||||
require $build_module;
|
||||
{ # scope for no strict 'refs'
|
||||
no strict 'refs';
|
||||
|
||||
my($package_name) = $build_module;
|
||||
$package_name =~ s/\.pm$//;
|
||||
|
||||
chdir($main::MOZ_SRC);
|
||||
&{$package_name."::BuildDist"}();
|
||||
|
||||
chdir($main::MOZ_SRC);
|
||||
&{$package_name."::BuildProjects"}();
|
||||
}
|
||||
|
||||
# the build finished, so clear the build progress state
|
||||
ClearBuildProgress();
|
||||
|
||||
TimeEnd($build_start, "Build");
|
||||
print "Build complete\n";
|
||||
}
|
||||
|
||||
1;
|
||||
425
mozilla/build/mac/build_scripts/Moz/BuildFlags.pm
Normal file
425
mozilla/build/mac/build_scripts/Moz/BuildFlags.pm
Normal file
@@ -0,0 +1,425 @@
|
||||
#!perl -w
|
||||
package Moz::BuildFlags;
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
# Package that attempts to read a file from the Preferences folder,
|
||||
# and get build settings out of it
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
|
||||
use Cwd;
|
||||
use File::Basename;
|
||||
|
||||
use Moz::Moz;
|
||||
use Moz::Prefs;
|
||||
|
||||
use vars qw(@ISA @EXPORT);
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
SetupBuildParams
|
||||
InitBuildProgress
|
||||
WriteBuildProgress
|
||||
ClearBuildProgress
|
||||
ReadBuildProgress
|
||||
);
|
||||
|
||||
|
||||
my(@build_flags);
|
||||
my(@options_flags);
|
||||
my(@filepath_flags);
|
||||
|
||||
my(%arrays_list) = (
|
||||
"build_flags", \@build_flags,
|
||||
"options_flags", \@options_flags,
|
||||
"filepath_flags", \@filepath_flags
|
||||
);
|
||||
|
||||
my($progress_file) = "¥ÊBuild progress";
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# appendArrayFlag
|
||||
#
|
||||
# Set a flag in the array
|
||||
#-------------------------------------------------------------------------------
|
||||
sub appendArrayFlag(@)
|
||||
{
|
||||
my($array_name) = shift;
|
||||
my($setting) = shift;
|
||||
my($value) = shift;
|
||||
|
||||
my(@optional_values);
|
||||
foreach (@_) {
|
||||
push(@optional_values, $_);
|
||||
}
|
||||
|
||||
my(@this_flag) = [$setting, $value, @optional_values];
|
||||
my($flags_array) = $arrays_list{$array_name};
|
||||
if ($flags_array)
|
||||
{
|
||||
push(@{$flags_array}, @this_flag) || die "Failed to append\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error: unknown build flags array $array_name\n";
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# readFlagsFile
|
||||
#
|
||||
# Read the file of build flags from disk. File path is relative to the
|
||||
# script directory.
|
||||
#-------------------------------------------------------------------------------
|
||||
sub readFlagsFile($)
|
||||
{
|
||||
my($flags_file) = @_;
|
||||
|
||||
my($file_path) = $0;
|
||||
$file_path =~ s/[^:]+$/$flags_file/;
|
||||
|
||||
print "Reading build flags from '$file_path'\n";
|
||||
|
||||
local(*FLAGS_FILE);
|
||||
open(FLAGS_FILE, "< $file_path") || die "Error: failed to open flags file $file_path\n";
|
||||
|
||||
my($cur_array) = "";
|
||||
|
||||
while(<FLAGS_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
# ignore comments and empty lines
|
||||
if ($line =~ /^\#/ || $line =~ /^\s*$/) {
|
||||
next;
|
||||
}
|
||||
|
||||
# 1-word line, probably array name
|
||||
if ($line =~ /^([^#\s]+)\s*$/)
|
||||
{
|
||||
$cur_array = $1;
|
||||
next;
|
||||
}
|
||||
elsif ($line =~ /^([^#\s]+)\s+\"(.+)\"(\s+#.+)?$/) # quoted option, possible comment
|
||||
{
|
||||
my($flag) = $1;
|
||||
my($setting) = $2;
|
||||
|
||||
appendArrayFlag($cur_array, $flag, $setting);
|
||||
}
|
||||
elsif ($line =~ /^([^#\s]+)((\s+[^#\s]+)+)(\s+#.+)?$/) # multiple word line, possible comment
|
||||
{
|
||||
my($flag) = $1;
|
||||
|
||||
appendArrayFlag($cur_array, $flag, split(' ', $2));
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error: unknown build flag at '$line'\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close(FLAGS_FILE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# flagsArrayToHash
|
||||
#
|
||||
# Utility routine to migrate flag from a 2D array to a hash, where
|
||||
# item[n][0] is the hash entry name, and item[n][1] is the hash entry value.
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub flagsArrayToHash($$)
|
||||
{
|
||||
my($src_array, $dest_hash) = @_;
|
||||
|
||||
my($item);
|
||||
foreach $item (@$src_array)
|
||||
{
|
||||
$dest_hash->{$item->[0]} = $item->[1];
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------
|
||||
# printHash
|
||||
#
|
||||
# Utility routine to print a hash
|
||||
#-----------------------------------------------
|
||||
sub printHash($)
|
||||
{
|
||||
my($hash_ref) = @_;
|
||||
|
||||
print "Printing hash:\n";
|
||||
|
||||
my($key, $value);
|
||||
|
||||
while (($key, $value) = each (%$hash_ref))
|
||||
{
|
||||
print " $key $value\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------
|
||||
# printBuildArray
|
||||
#
|
||||
# Utility routine to print a 2D array
|
||||
#-----------------------------------------------
|
||||
sub printBuildArray($)
|
||||
{
|
||||
my($build_array) = @_;
|
||||
|
||||
my($entry);
|
||||
foreach $entry (@$build_array)
|
||||
{
|
||||
print "$entry->[0] = $entry->[1]\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# SetBuildFlags
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetBuildFlags($)
|
||||
{
|
||||
my($build) = @_;
|
||||
|
||||
flagsArrayToHash(\@build_flags, $build);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# SetBuildOptions
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetBuildOptions($)
|
||||
{
|
||||
my($options) = @_;
|
||||
|
||||
flagsArrayToHash(\@options_flags, $options);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# SetFilepathFlags
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetFilepathFlags($)
|
||||
{
|
||||
my($filepath) = @_;
|
||||
|
||||
flagsArrayToHash(\@filepath_flags, $filepath);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# SetOptionDefines
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetOptionDefines($)
|
||||
{
|
||||
my($optiondefines) = @_;
|
||||
|
||||
foreach my $entry (@options_flags)
|
||||
{
|
||||
if (defined($entry->[2])) {
|
||||
$optiondefines->{$entry->[0]}{$entry->[2]} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# PropagateAllFlags
|
||||
#-------------------------------------------------------------------------------
|
||||
sub PropagateAllFlags($)
|
||||
{
|
||||
my($build_array) = @_;
|
||||
|
||||
# if "all" is set, set all the flags to 1
|
||||
unless ($build_array->[0][0] eq "all") { die "Error: 'all' must come first in the flags array\n"; }
|
||||
|
||||
if ($build_array->[0][1] == 1)
|
||||
{
|
||||
my($index);
|
||||
foreach $index (@$build_array)
|
||||
{
|
||||
$index->[1] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// _getBuildProgressFile
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub _getBuildProgressFile()
|
||||
{
|
||||
return $progress_file;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// setBuildProgressStart
|
||||
#//
|
||||
#// This automagically sets $build{"all"} to 0
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub setBuildProgressStart($$)
|
||||
{
|
||||
my($build_array, $name) = @_;
|
||||
|
||||
my($index);
|
||||
foreach $index (@$build_array)
|
||||
{
|
||||
$index->[1] = 0;
|
||||
if ($index->[0] eq $name) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
print "Building from module after $name, as specified by build progress\n";
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// InitBuildProgress
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub InitBuildProgress($)
|
||||
{
|
||||
my($prog_file) = @_;
|
||||
if ($prog_file ne "") {
|
||||
$progress_file = full_path_to($prog_file);
|
||||
print "Writing build progress to $progress_file\n";
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// WriteBuildProgress
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub WriteBuildProgress($)
|
||||
{
|
||||
my($module_built) = @_;
|
||||
|
||||
my($progress_file) = _getBuildProgressFile();
|
||||
|
||||
if ($progress_file ne "")
|
||||
{
|
||||
open(PROGRESS_FILE, ">>$progress_file") || die "Failed to open $progress_file\n";
|
||||
print(PROGRESS_FILE "$module_built\n");
|
||||
close(PROGRESS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ClearBuildProgress
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ClearBuildProgress()
|
||||
{
|
||||
my($progress_file) = _getBuildProgressFile();
|
||||
if ($progress_file ne "") {
|
||||
unlink $progress_file;
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// WipeBuildProgress
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub WipeBuildProgress()
|
||||
{
|
||||
print "Ignoring build progress\n";
|
||||
ClearBuildProgress();
|
||||
$progress_file = "";
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ReadBuildProgress
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ReadBuildProgress($)
|
||||
{
|
||||
my($build_array) = @_;
|
||||
my($progress_file) = _getBuildProgressFile();
|
||||
|
||||
my($last_module);
|
||||
|
||||
if (open(PROGRESS_FILE, "< $progress_file"))
|
||||
{
|
||||
print "Getting build progress from $progress_file\n";
|
||||
|
||||
while (<PROGRESS_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
$last_module = $line;
|
||||
}
|
||||
|
||||
close(PROGRESS_FILE);
|
||||
}
|
||||
|
||||
if ($last_module)
|
||||
{
|
||||
setBuildProgressStart($build_array, $last_module);
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# clearOldBuildSettings
|
||||
#-------------------------------------------------------------------------------
|
||||
sub clearOldBuildSettings($$$$)
|
||||
{
|
||||
my($build, $options, $optiondefines, $filepaths) = @_;
|
||||
|
||||
# empty the arrays in case we're being called twice
|
||||
@build_flags = ();
|
||||
@options_flags = ();
|
||||
@filepath_flags = ();
|
||||
|
||||
# and empty the hashes
|
||||
%$build = ();
|
||||
%$options = ();
|
||||
%$optiondefines = ();
|
||||
%$filepaths = ();
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# SetupBuildParams
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetupBuildParams($$$$$$)
|
||||
{
|
||||
my($build, $options, $optiondefines, $filepaths, $flags_file, $prefs_file) = @_;
|
||||
|
||||
# Empty the hashes and arrays, to wipe out any stale data.
|
||||
# Needed because these structures persist across two build scripts
|
||||
# called using 'do' from a parent script.
|
||||
clearOldBuildSettings($build, $options, $optiondefines, $filepaths);
|
||||
|
||||
# Read from the flags file, which sets up the various arrays
|
||||
readFlagsFile($flags_file);
|
||||
|
||||
# If 'all' is set in the build array, propagate that to all entries
|
||||
PropagateAllFlags(\@build_flags);
|
||||
|
||||
# read the user pref file, that can change values in the array
|
||||
ReadMozUserPrefs($prefs_file, \@build_flags, \@options_flags, \@filepath_flags);
|
||||
|
||||
# If build progress exists, this clears flags in the array up to a certain point
|
||||
if ($main::USE_BUILD_PROGRESS) {
|
||||
ReadBuildProgress(\@build_flags);
|
||||
} else {
|
||||
WipeBuildProgress();
|
||||
}
|
||||
|
||||
# printBuildArray(\@build_flags);
|
||||
# printBuildArray(\@options_flags);
|
||||
|
||||
SetBuildFlags($build);
|
||||
SetBuildOptions($options);
|
||||
SetOptionDefines($optiondefines);
|
||||
SetFilepathFlags($filepaths);
|
||||
|
||||
# printHash($build);
|
||||
# printHash($options);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
786
mozilla/build/mac/build_scripts/Moz/BuildUtils.pm
Normal file
786
mozilla/build/mac/build_scripts/Moz/BuildUtils.pm
Normal file
@@ -0,0 +1,786 @@
|
||||
|
||||
package Moz::BuildUtils;
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
# Package that contains build util functions specific to the Mozilla build
|
||||
# process.
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
|
||||
use Cwd;
|
||||
use File::Path;
|
||||
use File::Basename;
|
||||
|
||||
use Mac::Events;
|
||||
use Mac::StandardFile;
|
||||
|
||||
use Moz::Moz;
|
||||
use Moz::BuildFlags;
|
||||
use Moz::MacCVS;
|
||||
#use Moz::ProjectXML; #optional; required for static build only
|
||||
|
||||
use vars qw(@ISA @EXPORT);
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
SetupDefaultBuildOptions
|
||||
SetupBuildRootDir
|
||||
StartBuildModule
|
||||
EndBuildModule
|
||||
GetBinDirectory
|
||||
BuildOneProjectWithOutput
|
||||
BuildOneProject
|
||||
BuildProject
|
||||
BuildProjectClean
|
||||
BuildIDLProject
|
||||
BuildFolderResourceAliases
|
||||
AskAndPersistFile
|
||||
DelayFor
|
||||
TimeStart
|
||||
TimeEnd
|
||||
EmptyTree
|
||||
SetupBuildLog
|
||||
SetBuildNumber
|
||||
SetTimeBomb
|
||||
UpdateConfigHeader
|
||||
);
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SetupDefaultBuildOptions
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SetupDefaultBuildOptions($$$)
|
||||
{
|
||||
my($debug, $bin_dir, $config_header_file_name) = @_;
|
||||
|
||||
# Here we set up defaults for the various build flags.
|
||||
# If you want to override any of these, it's best to do
|
||||
# so via the relevant preferences file, which lives in
|
||||
# System Folder:Preferences:Mozilla build prefs:{build prefs file}.
|
||||
# For the name of the prefs file, see the .pl script that you
|
||||
# run to start this build. The prefs files are created when
|
||||
# you run the build, and contain some documentation.
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# configuration variables that globally affect what is built
|
||||
#-------------------------------------------------------------
|
||||
$main::DEBUG = $debug;
|
||||
$main::PROFILE = 0;
|
||||
$main::RUNTIME = 0; # turn on to just build runtime support and NSPR projects
|
||||
$main::GC_LEAK_DETECTOR = 0; # turn on to use GC leak detection
|
||||
$main::MOZILLA_OFFICIAL = 0; # generate build number
|
||||
$main::LOG_TO_FILE = 0; # write perl output to a file
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# configuration variables that affect the manner of building,
|
||||
# but possibly affecting the outcome.
|
||||
#-------------------------------------------------------------
|
||||
$main::ALIAS_SYM_FILES = $main::DEBUG;
|
||||
$main::CLOBBER_LIBS = 1; # turn on to clobber existing libs and .xSYM files before
|
||||
# building each project
|
||||
# The following two options will delete all dist files (if you have $main::build{dist} turned on),
|
||||
# but leave the directory structure intact.
|
||||
$main::CLOBBER_DIST_ALL = 1; # turn on to clobber all aliases/files inside dist (headers/xsym/libs)
|
||||
$main::CLOBBER_DIST_LIBS = 0; # turn on to clobber only aliases/files for libraries/sym files in dist
|
||||
$main::CLOBBER_IDL_PROJECTS = 0; # turn on to clobber all IDL projects.
|
||||
$main::CLOBBER_PROJECTS = 0; # turn on to remove object code from each project before building it
|
||||
|
||||
$main::UNIVERSAL_INTERFACES_VERSION = 0x0320;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# configuration variables that are preferences for the build,
|
||||
# style and do not affect what is built.
|
||||
#-------------------------------------------------------------
|
||||
$main::CLOSE_PROJECTS_FIRST = 0;
|
||||
# 1 = close then make (for development),
|
||||
# 0 = make then close (for tinderbox).
|
||||
$main::USE_TIMESTAMPED_LOGS = 0;
|
||||
$main::USE_BUILD_PROGRESS = 1; # track build progress for restartable builds
|
||||
#-------------------------------------------------------------
|
||||
# END OF CONFIG SWITCHES
|
||||
#-------------------------------------------------------------
|
||||
|
||||
$main::BIN_DIRECTORY = $bin_dir;
|
||||
$main::DEFINESOPTIONS_FILE = $config_header_file_name;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SetupBuildRootDir
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SetupBuildRootDir($)
|
||||
{
|
||||
my($rel_path_to_script) = @_;
|
||||
|
||||
my($cur_dir) = cwd();
|
||||
$cur_dir =~ s/$rel_path_to_script$//;
|
||||
chdir($cur_dir) || die "Error: failed to set build root directory to '$cur_dir'.\nYou probably need to put 'mozilla' one level down (in a folder).\n";
|
||||
$main::MOZ_SRC = cwd();
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// StartBuildModule
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub StartBuildModule($)
|
||||
{
|
||||
my($module) = @_;
|
||||
|
||||
print("---- Start of $module ----\n");
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// EndBuildModule
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub EndBuildModule($)
|
||||
{
|
||||
my($module) = @_;
|
||||
WriteBuildProgress($module);
|
||||
print("---- End of $module ----\n");
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# GetBinDirectory
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
sub GetBinDirectory()
|
||||
{
|
||||
if ($main::BIN_DIRECTORY eq "") { die "Dist directory not set\n"; }
|
||||
return $main::BIN_DIRECTORY;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# AskAndPersistFile stores the information about the user pick inside
|
||||
# the file $session_storage
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
sub AskAndPersistFile($)
|
||||
{
|
||||
my ($sessionStorage) = @_;
|
||||
my $cvsfile;
|
||||
|
||||
if (( -e $sessionStorage) &&
|
||||
open( SESSIONFILE, $sessionStorage ))
|
||||
{
|
||||
# Read in the path if available
|
||||
$cvsfile = <SESSIONFILE>;
|
||||
chomp $cvsfile;
|
||||
close SESSIONFILE;
|
||||
if ( ! -e $cvsfile )
|
||||
{
|
||||
print STDERR "$cvsfile has disappeared\n";
|
||||
undef $cvsfile;
|
||||
}
|
||||
}
|
||||
unless (defined ($cvsfile))
|
||||
{
|
||||
# make sure that MacPerl is a front process
|
||||
ActivateApplication('McPL');
|
||||
MacPerl::Answer("Could not find your MacCVS session file. Please choose one", "OK");
|
||||
|
||||
# prompt user for the file name, and store it
|
||||
my $macFile = StandardGetFile( 0, "McvD");
|
||||
if ( $macFile->sfGood() )
|
||||
{
|
||||
$cvsfile = $macFile->sfFile();
|
||||
# save the choice if we can
|
||||
if ( open (SESSIONFILE, ">" . $sessionStorage))
|
||||
{
|
||||
printf SESSIONFILE $cvsfile, "\n";
|
||||
close SESSIONFILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
print STDERR "Could not open storage file $sessionStorage for saving $cvsfile\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cvsfile;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# BuildIDLProject
|
||||
#
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildIDLProject($$)
|
||||
{
|
||||
my ($project_path, $module_name) = @_;
|
||||
|
||||
if ($main::CLOBBER_IDL_PROJECTS)
|
||||
{
|
||||
my (@suffix_list) = (".mcp", ".xml");
|
||||
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
|
||||
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
|
||||
|
||||
my($datafolder_path);
|
||||
if ($suffix eq ".xml")
|
||||
{
|
||||
$datafolder_path = $project_dir . "_" . $project_name . " Data:";
|
||||
}
|
||||
else {
|
||||
$datafolder_path = $project_dir . $project_name . " Data:";
|
||||
}
|
||||
|
||||
print STDERR "Deleting IDL data folder: $datafolder_path\n";
|
||||
EmptyTree($datafolder_path);
|
||||
}
|
||||
|
||||
BuildOneProject($project_path, "headers", 0, 0, 0);
|
||||
BuildOneProject($project_path, $module_name.".xpt", 1, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# CreateStaticLibTargets
|
||||
#
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
sub CreateXMLStaticLibTargets($)
|
||||
{
|
||||
my($xml_path) = @_;
|
||||
|
||||
my (@suffix_list) = (".xml");
|
||||
my ($project_name, $project_dir, $suffix) = fileparse($xml_path, @suffix_list);
|
||||
if ($suffix eq "") { die "XML munging: $xml_path must end in .xml\n"; }
|
||||
|
||||
#sniff the file to see if we need to fix up broken Pro5-exported XML
|
||||
print "Parsing $xml_path\n";
|
||||
|
||||
my $ide_version = Moz::ProjectXML::SniffProjectXMLIDEVersion($xml_path);
|
||||
if ($ide_version eq "4.0")
|
||||
{
|
||||
my $new_file = $project_dir.$project_name."2.xml";
|
||||
|
||||
print "Cleaning up Pro 5 xml to $new_file\n";
|
||||
|
||||
Moz::ProjectXML::CleanupPro5XML($xml_path, $new_file);
|
||||
|
||||
unlink $xml_path;
|
||||
rename ($new_file, $xml_path);
|
||||
}
|
||||
|
||||
my $doc = Moz::ProjectXML::ParseXMLDocument($xml_path);
|
||||
my @target_list = Moz::ProjectXML::GetTargetsList($doc);
|
||||
my $target;
|
||||
|
||||
my %target_hash; # for easy lookups below
|
||||
foreach $target (@target_list) { $target_hash{$target} = 1; }
|
||||
|
||||
foreach $target (@target_list)
|
||||
{
|
||||
if ($target =~ /(.+).shlb$/) # if this is a shared lib target
|
||||
{
|
||||
my $target_base = $1;
|
||||
my $static_target = $target_base.".o";
|
||||
|
||||
# ensure that this does not exist already
|
||||
if ($target_hash{$static_target}) {
|
||||
print "Static target $static_target already exists in project. Not making\n";
|
||||
next;
|
||||
}
|
||||
|
||||
print "Making static target '$static_target' from target '$target'\n";
|
||||
|
||||
Moz::ProjectXML::CloneTarget($doc, $target, $static_target);
|
||||
Moz::ProjectXML::SetAsStaticLibraryTarget($doc, $static_target, $static_target);
|
||||
}
|
||||
}
|
||||
|
||||
print "Writing XML file to $xml_path\n";
|
||||
my $temp_path = $project_dir."_".$project_name.".xml";
|
||||
Moz::ProjectXML::WriteXMLDocument($doc, $temp_path, $ide_version);
|
||||
Moz::ProjectXML::DisposeXMLDocument($doc);
|
||||
|
||||
if (-e $temp_path)
|
||||
{
|
||||
unlink $xml_path;
|
||||
rename ($temp_path, $xml_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error: Failed to add new targets to XML project\n";
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ProcessProjectXML
|
||||
#//
|
||||
#// Helper routine to allow for XML pre-processing. This should read in the XML, process it,
|
||||
#// and replace the original file with the processed version.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ProcessProjectXML($)
|
||||
{
|
||||
my($xml_path) = @_;
|
||||
|
||||
# we need to manually load Moz::ProjectXML, becaues not everyone will have the
|
||||
# required perl modules in their distro.
|
||||
my($cur_dir) = cwd();
|
||||
|
||||
chdir(dirname($0)); # change to the script dir
|
||||
eval "require Moz::ProjectXML";
|
||||
if ($@) { die "Error: could not do Project XML munging because you do not have the correct XML modules installed. Error is:\n################\n $@################"; }
|
||||
|
||||
chdir($cur_dir);
|
||||
|
||||
CreateXMLStaticLibTargets($xml_path);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Build one project, and make the alias. Parameters are project path, target name, shared library
|
||||
#// name, make shlb alias (boolean), make xSYM alias (boolean), and is component (boolean).
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildOneProjectWithOutput($$$$$$)
|
||||
{
|
||||
my ($project_path, $target_name, $output_name, $alias_lib, $alias_xSYM, $component) = @_;
|
||||
|
||||
unless ($project_path =~ m/^$main::BUILD_ROOT.+/) { return; }
|
||||
|
||||
my (@suffix_list) = (".mcp", ".xml");
|
||||
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
|
||||
if ($suffix eq "") { die "Error: Project, $project_path must end in .xml or .mcp\n"; }
|
||||
|
||||
my($dist_dir) = GetBinDirectory();
|
||||
|
||||
# Put libraries in "Essential Files" folder, Components in "Components" folder
|
||||
my($output_dir) = $component ? "Components:" : "Essential Files:";
|
||||
my($output_path) = $dist_dir.$output_dir;
|
||||
|
||||
if ($main::options{static_build})
|
||||
{
|
||||
if ($output_name =~ /\.o$/ || $output_name =~ /\.[Ll]ib$/)
|
||||
{
|
||||
$alias_xSYM = 0;
|
||||
$alias_lib = 1;
|
||||
$output_path = $main::DEBUG ? ":mozilla:dist:static_libs_debug:" : ":mozilla:dist:static_libs:";
|
||||
}
|
||||
}
|
||||
|
||||
# if the flag is on to export projects to XML, export and munge them
|
||||
if ($main::EXPORT_PROJECTS && !($project_path =~ /IDL\.mcp$/))
|
||||
{
|
||||
my $xml_out_path = $project_path;
|
||||
|
||||
$xml_out_path =~ s/\.mcp$/\.xml/;
|
||||
|
||||
# only do this if project is newer?
|
||||
if (! -e $xml_out_path)
|
||||
{
|
||||
ExportProjectToXML(full_path_to($project_path), full_path_to($xml_out_path));
|
||||
ProcessProjectXML($xml_out_path);
|
||||
}
|
||||
}
|
||||
|
||||
# if the flag is set to use XML projects, default to XML if the file
|
||||
# is present.
|
||||
if ($main::USE_XML_PROJECTS && !($project_path =~ /IDL\.mcp$/))
|
||||
{
|
||||
my $xml_project_path = $project_dir.$project_name.".xml";
|
||||
if (-e $xml_project_path)
|
||||
{
|
||||
$project_path = $xml_project_path;
|
||||
$suffix = ".xml";
|
||||
}
|
||||
}
|
||||
|
||||
if ($suffix eq ".xml")
|
||||
{
|
||||
my($xml_path) = $project_path;
|
||||
# Prepend an "_" onto the name of the generated project file so it doesn't conflict
|
||||
$project_path = $project_dir . "_" . $project_name . ".mcp";
|
||||
my($project_modtime) = (-e $project_path ? GetFileModDate($project_path) : 0);
|
||||
my($xml_modtime) = (-e $xml_path ? GetFileModDate($xml_path) : 0);
|
||||
|
||||
if ($xml_modtime > $project_modtime)
|
||||
{
|
||||
print("Importing $project_path from $project_name.xml.\n");
|
||||
unlink($project_path);
|
||||
# Might want to delete the "xxx.mcp Data" dir ???
|
||||
ImportXMLProject(full_path_to($xml_path), full_path_to($project_path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($main::CLOBBER_LIBS)
|
||||
{
|
||||
unlink "$project_dir$output_name"; # it's OK if these fail
|
||||
unlink "$project_dir$output_name.xSYM";
|
||||
}
|
||||
|
||||
DoBuildProject($project_path, $target_name, $main::CLOBBER_PROJECTS);
|
||||
|
||||
$alias_lib ? MakeAlias("$project_dir$output_name", "$output_path") : 0;
|
||||
$alias_xSYM ? MakeAlias("$project_dir$output_name.xSYM", "$output_path") : 0;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// For compatiblity with existing scripts, BuildOneProject now just calls
|
||||
#// BuildOneProjectWithOutput, with the output name and target name identical.
|
||||
#// Note that this routine assumes that the target name and the shared libary name
|
||||
#// are the same.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildOneProject($$$$$)
|
||||
{
|
||||
my ($project_path, $target_name, $alias_lib, $alias_xSYM, $component) = @_;
|
||||
|
||||
BuildOneProjectWithOutput($project_path, $target_name, $target_name,
|
||||
$alias_lib, $alias_xSYM, $component);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// For compatiblity with existing scripts, BuildProject now just calls
|
||||
#// BuildOneProjectWithOutput, with the output name and target name identical.
|
||||
#// Note that this routine assumes that the target name and the shared libary name
|
||||
#// are the same. No aliases of the output are made.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildProject($$)
|
||||
{
|
||||
my ($project_path, $target_name) = @_;
|
||||
|
||||
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Identical to BuildProject but clobbers the project before building it.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildProjectClean($$)
|
||||
{
|
||||
my ($project_path, $target_name) = @_;
|
||||
my ($save_clobber_flag) = $main::CLOBBER_PROJECTS;
|
||||
$main::CLOBBER_PROJECTS = 1;
|
||||
BuildOneProjectWithOutput($project_path, $target_name, $target_name, 0, 0, 0);
|
||||
$main::CLOBBER_PROJECTS = $save_clobber_flag;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Make resource aliases for one directory
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub BuildFolderResourceAliases($$)
|
||||
{
|
||||
my($src_dir, $dest_dir) = @_;
|
||||
|
||||
# get a list of all the resource files
|
||||
opendir(SRCDIR, $src_dir) || die("can't open $src_dir");
|
||||
my(@resource_files) = readdir(SRCDIR);
|
||||
closedir(SRCDIR);
|
||||
|
||||
# make aliases for each one into the dest directory
|
||||
print("Placing aliases to all files from $src_dir in $dest_dir\n");
|
||||
for ( @resource_files )
|
||||
{
|
||||
next if $_ eq "CVS";
|
||||
#print(" Doing $_\n");
|
||||
if (-l $src_dir.$_)
|
||||
{
|
||||
print(" $_ is an alias\n");
|
||||
next;
|
||||
}
|
||||
my($file_name) = $src_dir . $_;
|
||||
MakeAlias($file_name, $dest_dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// DelayFor
|
||||
#//
|
||||
#// Delay for the given number of seconds, allowing the script to be cancelled
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub DelayFor($)
|
||||
{
|
||||
my($delay_secs) = @_;
|
||||
|
||||
STDOUT->autoflush(1);
|
||||
|
||||
my($end_time) = time() + $delay_secs;
|
||||
|
||||
my($last_time) = 0;
|
||||
my($cur_time) = time();
|
||||
|
||||
while ($cur_time < $end_time)
|
||||
{
|
||||
$cur_time = time();
|
||||
if ($cur_time > $last_time)
|
||||
{
|
||||
print ".";
|
||||
$last_time = $cur_time;
|
||||
}
|
||||
|
||||
WaitNextEvent();
|
||||
}
|
||||
|
||||
print "\n";
|
||||
STDOUT->autoflush(0);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// TimeStart
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub TimeStart()
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// TimeEnd
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub TimeEnd($$)
|
||||
{
|
||||
use integer;
|
||||
|
||||
my($start_time, $operation_name) = @_;
|
||||
my($end_time) = time();
|
||||
|
||||
my($tot_sec) = $end_time - $start_time;
|
||||
|
||||
my($seconds) = $tot_sec;
|
||||
|
||||
my($hours) = $seconds / (60 * 60);
|
||||
$seconds -= $hours * (60 * 60);
|
||||
|
||||
my($minutes) = $seconds / 60;
|
||||
$seconds -= $minutes * 60;
|
||||
|
||||
print "$operation_name took $hours hours $minutes minutes and $seconds seconds\n";
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Remove all files from a tree, leaving directories intact (except "CVS").
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub EmptyTree($)
|
||||
{
|
||||
my ($root) = @_;
|
||||
#print "EmptyTree($root)\n";
|
||||
opendir(DIR, $root);
|
||||
my $sub;
|
||||
foreach $sub (readdir(DIR))
|
||||
{
|
||||
my $fullpathname = $root.$sub; # -f, -d only work on full paths
|
||||
|
||||
# Don't call empty tree for the alias of a directory.
|
||||
# -d returns true for the alias of a directory, false for a broken alias)
|
||||
|
||||
if (-d $fullpathname)
|
||||
{
|
||||
if (-l $fullpathname) # delete aliases
|
||||
{
|
||||
unlink $fullpathname;
|
||||
next;
|
||||
}
|
||||
EmptyTree($fullpathname.":");
|
||||
if ($sub eq "CVS")
|
||||
{
|
||||
#print "rmdir $fullpathname\n";
|
||||
rmdir $fullpathname;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unless (unlink $fullpathname) { die "Failed to delete $fullpathname\n"; }
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Recurse through a directory hierarchy, looking for MANIFEST files.
|
||||
#// Currently unused.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub ScanForManifestFiles($$$$)
|
||||
{
|
||||
my($dir, $theme_root, $theme_name, $dist_dir) = @_;
|
||||
|
||||
opendir(DIR, $dir) or die "Cannot open dir $dir\n";
|
||||
my @files = readdir(DIR);
|
||||
closedir DIR;
|
||||
|
||||
my $file;
|
||||
|
||||
foreach $file (@files)
|
||||
{
|
||||
my $filepath = $dir.":".$file;
|
||||
|
||||
if (-d $filepath)
|
||||
{
|
||||
# print "Looking for MANIFEST files in $filepath\n";
|
||||
ScanForManifestFiles($filepath, $theme_root, $theme_name, $dist_dir);
|
||||
}
|
||||
elsif ($file eq "MANIFEST")
|
||||
{
|
||||
# print "Doing manifest file $filepath\n";
|
||||
|
||||
# Get the dest path from the first line of the file
|
||||
|
||||
open(MANIFEST, $filepath) || die "Could not open file $file";
|
||||
# Read in the path if available
|
||||
my($dest_line) = <MANIFEST>;
|
||||
chomp $dest_line;
|
||||
close MANIFEST;
|
||||
|
||||
$dest_line =~ s|^#!dest[\t ]+|| || die "No destination line found in $filepath\n";
|
||||
|
||||
my($dest_path) = $dist_dir."chrome:skins:$theme_name:$dest_line";
|
||||
# print " Destination is $dest_path\n";
|
||||
|
||||
InstallResources($filepath, "$dest_path", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------
|
||||
# SetupBuildLog
|
||||
#-----------------------------------------------
|
||||
sub SetupBuildLog($$)
|
||||
{
|
||||
my($logfile_path, $timestamped_log) = @_;
|
||||
|
||||
my($logdir) = "";
|
||||
my($logfile) = $logfile_path;
|
||||
|
||||
if ($logfile_path =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
|
||||
{
|
||||
$logdir = $1;
|
||||
$logfile = $2;
|
||||
|
||||
mkpath($logdir);
|
||||
}
|
||||
|
||||
if ($timestamped_log)
|
||||
{
|
||||
#Use time-stamped names so that you don't clobber your previous log file!
|
||||
my $now = localtime();
|
||||
while ($now =~ s@:@.@) {} # replace all colons by periods
|
||||
OpenErrorLog("${logdir}${now}");
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenErrorLog("${logdir}${logfile}");
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------
|
||||
# SetBuildNumber
|
||||
#-----------------------------------------------
|
||||
sub SetBuildNumber($$)
|
||||
{
|
||||
my($build_num_file, $files_to_touch) = @_;
|
||||
|
||||
# Make sure we add the config dir to search, to pick up mozBDate.pm
|
||||
# Need to do this dynamically, because this module can be used before
|
||||
# mozilla/config has been checked out.
|
||||
|
||||
my ($inc_path) = $0; # $0 is the path to the parent script
|
||||
$inc_path =~ s/:build:mac:build_scripts:.+$/:config/;
|
||||
push(@INC, $inc_path);
|
||||
|
||||
require mozBDate;
|
||||
|
||||
mozBDate::UpdateBuildNumber($build_num_file, $main::MOZILLA_OFFICIAL);
|
||||
|
||||
my($file);
|
||||
foreach $file (@$files_to_touch)
|
||||
{
|
||||
print "Writing build number to $file from ${file}.in\n";
|
||||
mozBDate::SubstituteBuildNumber($file, $build_num_file, "${file}.in");
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------
|
||||
# SetTimeBomb
|
||||
#-----------------------------------------------
|
||||
sub SetTimeBomb($$)
|
||||
{
|
||||
my ($warn_days, $bomb_days) = @_;
|
||||
|
||||
system("perl :mozilla:config:mac-set-timebomb.pl $warn_days $bomb_days");
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Regenerate a configuration header file if necessary
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub UpdateConfigHeader($)
|
||||
{
|
||||
my($config_path) = @_;
|
||||
|
||||
my($config, $oldconfig) = ("", "");
|
||||
my($define, $definevalue, $defines);
|
||||
my($k, $l,);
|
||||
|
||||
foreach $k (keys(%main::options))
|
||||
{
|
||||
if ($main::options{$k})
|
||||
{
|
||||
foreach $l (keys(%{$main::optiondefines{$k}}))
|
||||
{
|
||||
$my::defines{$l} = $main::optiondefines{$k}{$l};
|
||||
print "Setting up my::defines{$l}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $config_headerfile = current_directory().$config_path;
|
||||
if (-e $config_headerfile)
|
||||
{
|
||||
open(CONFIG_HEADER, "< $config_headerfile") || die "$config_headerfile: $!\n";
|
||||
my($line);
|
||||
while ($line = <CONFIG_HEADER>)
|
||||
{
|
||||
if ($line =~ m/#define\s+([^\s]*)\s+([^\s]*)\s*\n/)
|
||||
{
|
||||
$define = $1;
|
||||
$definevalue = $2;
|
||||
|
||||
#canonicalize so that whitespace changes are not significant
|
||||
my $canon_value = "#define " . $define . " " . $definevalue . "\n";
|
||||
$oldconfig .= $canon_value;
|
||||
|
||||
if (exists ($my::defines{$define}) and ($my::defines{$define} == $definevalue))
|
||||
{
|
||||
delete $my::defines{$define};
|
||||
$config .= $canon_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(CONFIG_HEADER);
|
||||
}
|
||||
|
||||
if (%my::defines)
|
||||
{
|
||||
foreach $k (keys(%my::defines))
|
||||
{
|
||||
$config .= "#define " . $k . " " . $my::defines{$k} . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
my $file_name = basename($config_headerfile);
|
||||
if (($config ne $oldconfig) || (!-e $config_headerfile))
|
||||
{
|
||||
printf("Writing new configuration header $file_name\n");
|
||||
open(CONFIG_HEADER, "> $config_headerfile") || die "$config_headerfile: $!\n";
|
||||
print(CONFIG_HEADER "/* This file is auto-generated based on build options. Do not edit. */\n");
|
||||
print CONFIG_HEADER ($config);
|
||||
close(CONFIG_HEADER);
|
||||
|
||||
MacPerl::SetFileInfo("CWIE", "TEXT", $config_headerfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Configuration header $file_name is up-to-date\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
660
mozilla/build/mac/build_scripts/Moz/CodeWarriorLib.pm
Normal file
660
mozilla/build/mac/build_scripts/Moz/CodeWarriorLib.pm
Normal file
@@ -0,0 +1,660 @@
|
||||
#!perl
|
||||
package Moz::CodeWarriorLib;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CodeWarriorLib - supply interface to CodeWarrior
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#!perl
|
||||
use CodeWarriorLib;
|
||||
CodeWarriorLib::activate();
|
||||
$had_errors = CodeWarriorLib::build_project(
|
||||
$project_path, $target_name, $recent_errors_file, $clean_build
|
||||
);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Replaces the AppleScript library I<CodeWarriorLib>.
|
||||
|
||||
=over 4
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
|
||||
use Cwd;
|
||||
use File::Basename;
|
||||
|
||||
use Mac::Types;
|
||||
use Mac::Events;
|
||||
use Mac::AppleEvents;
|
||||
use Mac::AppleEvents::Simple;
|
||||
use Mac::Processes;
|
||||
use Mac::MoreFiles;
|
||||
use Mac::StandardFile;
|
||||
|
||||
|
||||
use vars qw($VERSION);
|
||||
$VERSION = '1.02';
|
||||
|
||||
my($app) = 'CWIE';
|
||||
my($scriptDir) = cwd(); # could use $0 for this
|
||||
my($ide_loc_file) = "";
|
||||
|
||||
# 0 == don't switch CWIE to front app in do_event(), 1 == do switch
|
||||
# note: activate() still switches when called
|
||||
$Mac::AppleEvents::Simple::SWITCH = 0;
|
||||
# $Mac::AppleEvents::Simple::WARN = 1;
|
||||
|
||||
# supply your own path to the source here
|
||||
#_test('PowerPudgeIV:mozilla:mozilla:');
|
||||
|
||||
# If you want to understand the gobbldeygook that's used to build Apple Events,
|
||||
# you should start by reading the AEGizmos documentation.
|
||||
|
||||
=pod
|
||||
|
||||
=item _get_project($full_path)
|
||||
|
||||
A private routine returning a reference to the open project with the given name,
|
||||
or else the empty string (when that project is not open)
|
||||
|
||||
full_path is a string identifying the project to be built and is of the form,
|
||||
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
|
||||
|
||||
=cut
|
||||
|
||||
sub _get_project ($) {
|
||||
my(
|
||||
$full_path, $candidate_projects
|
||||
) = @_;
|
||||
$candidate_projects = _doc_named(basename($full_path, '*'));
|
||||
if ($candidate_projects) {
|
||||
my($cps) = _get_dobj($candidate_projects);
|
||||
my($num) = AECountItems($cps);
|
||||
if ($num) { # is a list
|
||||
foreach (1 .. AECountItems($cps)) {
|
||||
my($cp) = AEGetNthDesc($cps, $_);
|
||||
if (lc $full_path eq lc _full_path($cp)) {
|
||||
return($cp);
|
||||
}
|
||||
}
|
||||
} else { # is only one, not a list
|
||||
if (lc $full_path eq lc _full_path($cps)) {
|
||||
return($cps);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item build_project
|
||||
|
||||
Build a selected target of a project, saving any errors to a file, if supplied.
|
||||
|
||||
full_path is a string identifying the project to be built and is of the form,
|
||||
e.g., "HD:ProjectFolder:MyProject.mcp". It must be supplied.
|
||||
|
||||
If target_name is the empty string, the current target of the selected project
|
||||
will be built, else, target_name should be a string matching a target name in
|
||||
the selected project.
|
||||
|
||||
If error_path is the empty string, errors will not be saved to a file,
|
||||
else, error_path should be the full path of a file to save error messages into.
|
||||
|
||||
=cut
|
||||
|
||||
$CodeWarriorLib::CLOSE_PROJECTS_FIRST = 0; # If true we close then make. If false, make then close.
|
||||
my $last_project_built = "";
|
||||
my $last_project_was_closed = 0;
|
||||
|
||||
sub build_project ($;$$$) {
|
||||
my(
|
||||
$full_path, $target_name, $error_path,
|
||||
$remove_object, $p, $project_was_closed, $had_errors
|
||||
) = @_;
|
||||
_close_errors_window();
|
||||
|
||||
if ($CodeWarriorLib::CLOSE_PROJECTS_FIRST && ($last_project_built ne $full_path))
|
||||
{
|
||||
# If we're in "close first" mode, we don't close if the current project
|
||||
# is the same as the previous one.
|
||||
if ($last_project_was_closed) {
|
||||
$p = _get_project($last_project_built);
|
||||
_close($p);
|
||||
}
|
||||
$last_project_built = $full_path;
|
||||
$last_project_was_closed = 0; # now refers to the new project
|
||||
}
|
||||
$project_was_closed = 0;
|
||||
while (1) {
|
||||
$p = _get_project($full_path);
|
||||
if (!$p) {
|
||||
if ($project_was_closed) {
|
||||
print "### Error - request for project document failed after opening\n";
|
||||
die "### possibly CW Pro 4 bug: be sure to close your Find window\n";
|
||||
}
|
||||
$project_was_closed = 1;
|
||||
$last_project_was_closed = 1;
|
||||
_open_file($full_path);
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$had_errors = 0;
|
||||
if ($target_name eq '') {
|
||||
if ($remove_object) {_remove_object($p)}
|
||||
_build($p);
|
||||
} else {
|
||||
if ($remove_object) {_remove_object($p, $target_name)}
|
||||
_build($p, $target_name);
|
||||
}
|
||||
|
||||
if ($error_path ne '') {
|
||||
_save_errors_window($error_path);
|
||||
}
|
||||
$had_errors = _close_errors_window();
|
||||
|
||||
if (!$CodeWarriorLib::CLOSE_PROJECTS_FIRST)
|
||||
{
|
||||
if ($project_was_closed) {
|
||||
$p = _get_project($full_path);
|
||||
_close($p);
|
||||
}
|
||||
}
|
||||
|
||||
return($had_errors);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item appIsRunning()
|
||||
|
||||
=cut
|
||||
sub _appIsRunning($)
|
||||
{
|
||||
my ($appSignature) = @_;
|
||||
my ($psi);
|
||||
my ($found) = 0;
|
||||
my ($appPSN);
|
||||
|
||||
foreach $psi (values(%Process))
|
||||
{
|
||||
if ($psi->processSignature() eq $appSignature)
|
||||
{
|
||||
$appPSN = $psi->processNumber();
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item appIsFrontmost()
|
||||
|
||||
=cut
|
||||
sub _appIsFrontmost($)
|
||||
{
|
||||
my ($appSignature) = @_;
|
||||
my ($psi);
|
||||
my ($found) = 0;
|
||||
my ($appPSN);
|
||||
|
||||
foreach $psi (values(%Process))
|
||||
{
|
||||
if ($psi->processSignature() eq $appSignature)
|
||||
{
|
||||
$appPSN = $psi->processNumber();
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return (GetFrontProcess() == $appPSN);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item activate()
|
||||
|
||||
Launches CodeWarrior and brings it to the front.
|
||||
|
||||
Once found, path will be saved in $idepath_file for future reference.
|
||||
Edit or delete this file to change the location of the IDE. If app is
|
||||
moved, C<activate()> will prompt for a new location.
|
||||
|
||||
First looks for an open CodeWarrior app. Second, tries to open previously
|
||||
saved location in ':idepath.txt'. Third, tries to find it and allow user
|
||||
to choose it with Navigation Services (if present). Fourth, uses good old
|
||||
GUSI routines built-in to MacPerl for a Choose Directory dialog box.
|
||||
|
||||
=cut
|
||||
|
||||
sub activate ($) {
|
||||
|
||||
$ide_loc_file = $_[0]; # save in global
|
||||
|
||||
my($filepath, $appath, $psi) = ($ide_loc_file);
|
||||
|
||||
foreach $psi (values(%Process)) {
|
||||
if ($psi->processSignature() eq $app) {
|
||||
$appath = $psi->processAppSpec();
|
||||
_save_appath($filepath, $appath);
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$appath || !-x $appath) {
|
||||
$appath = _read_appath($filepath);
|
||||
}
|
||||
|
||||
if (!$appath || ! -x $appath)
|
||||
{
|
||||
# make sure that MacPerl is a front process
|
||||
#ActivateApplication('McPL');
|
||||
MacPerl::Answer("Please locate the CodeWarrior application.", "OK");
|
||||
|
||||
# prompt user for the file name, and store it
|
||||
my $macFile = StandardGetFile( 0, "APPL");
|
||||
if ( $macFile->sfGood() )
|
||||
{
|
||||
$appath = $macFile->sfFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Operation canceled\n";
|
||||
}
|
||||
|
||||
# if (eval {require Mac::Navigation}) {
|
||||
# my($options, $nav);
|
||||
# Mac::Navigation->import();
|
||||
# $options = NavGetDefaultDialogOptions();
|
||||
# $options->message('Where is CodeWarrior IDE?');
|
||||
# $options->windowTitle('Find CodeWarrior IDE');
|
||||
# $nav = NavChooseObject($Application{$app}, $options);
|
||||
# die "CodeWarrior IDE not found.\n" if (!$nav || !$nav->file(1));
|
||||
# $appath = $nav->file(1);
|
||||
# } else {
|
||||
# local(*D);
|
||||
# my $cwd = `pwd`;
|
||||
# $appath = _get_folder(
|
||||
# 'Where is the CW IDE folder?',
|
||||
# dirname($Application{$app})
|
||||
# );
|
||||
# die "CodeWarrior IDE not found.\n" if !$appath;
|
||||
# opendir(D, $appath) or die $!;
|
||||
# chdir($appath);
|
||||
# foreach my $file (sort readdir (D)) {
|
||||
# my(@app) = MacPerl::GetFileInfo($file);
|
||||
# if ($app[0] && $app[1] &&
|
||||
# $app[1] eq 'APPL' && $app[0] eq $app
|
||||
# ) {
|
||||
# $appath .= $file;
|
||||
# last;
|
||||
# }
|
||||
# }
|
||||
# chomp($cwd);
|
||||
# chdir($cwd);
|
||||
# }
|
||||
_save_appath($filepath, $appath);
|
||||
}
|
||||
|
||||
my($lp) = LaunchParam->new(
|
||||
launchAppSpec => $appath,
|
||||
launchControlFlags => launchContinue() + launchNoFileFlags()
|
||||
);
|
||||
|
||||
unless (LaunchApplication($lp)) {
|
||||
unlink($filepath);
|
||||
die $^E;
|
||||
}
|
||||
|
||||
# wait for CodeWarrior to show up in the list of processes
|
||||
while (!_appIsRunning('CWIE'))
|
||||
{
|
||||
WaitNextEvent();
|
||||
}
|
||||
|
||||
# wait for CodeWarrior to come to the front
|
||||
while (!_appIsFrontmost('CWIE'))
|
||||
{
|
||||
WaitNextEvent();
|
||||
}
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item getCodeWarriorPath()
|
||||
|
||||
Returns a file path relative to the CodeWarrior folder
|
||||
|
||||
=cut
|
||||
|
||||
sub getCodeWarriorPath($)
|
||||
{
|
||||
my($subfolder)=@_;
|
||||
|
||||
my($app_path) = _read_appath($ide_loc_file);
|
||||
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
|
||||
|
||||
my($codewarrior_root) = $app_path;
|
||||
$codewarrior_root =~ s/[^:]*$//;
|
||||
return ($codewarrior_root . $subfolder);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item getCodeWarriorIDEName()
|
||||
|
||||
Returns the name of the CodeWarrior application
|
||||
|
||||
=cut
|
||||
|
||||
sub getCodeWarriorIDEName()
|
||||
{
|
||||
my($subfolder)=@_;
|
||||
|
||||
my($app_path) = _read_appath($ide_loc_file);
|
||||
if ($app_path eq "") { die "Error: Failed to get CodeWarrior IDE path\n"; }
|
||||
|
||||
my(@codewarrior_path) = split(/:/, $app_path);
|
||||
return pop(@codewarrior_path);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item quit()
|
||||
|
||||
Quits CodeWarrior.
|
||||
|
||||
=cut
|
||||
|
||||
sub quit() {
|
||||
|
||||
$last_project_built = "";
|
||||
$last_project_was_closed = 0;
|
||||
|
||||
my($evt) = do_event(qw/aevt quit/, $app);
|
||||
}
|
||||
|
||||
|
||||
sub _build ($;$) {
|
||||
my($evt);
|
||||
if ($_[1]) {
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
|
||||
AEPrint($_[0]) . '}';
|
||||
$evt = do_event(qw/CWIE MAKE/, $app, $prm, $_[1]);
|
||||
} else {
|
||||
my($prm) = q"'----':" . AEPrint($_[0]);
|
||||
$evt = do_event(qw/CWIE MAKE/, $app, $prm);
|
||||
}
|
||||
}
|
||||
|
||||
sub _remove_object ($;$) {
|
||||
my($evt);
|
||||
if ($_[1]) {
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(TRGT), seld:TEXT(@), from:" .
|
||||
AEPrint($_[0]) . '}';
|
||||
$evt = do_event(qw/CWIE RMOB/, $app, $prm, $_[1]);
|
||||
} else {
|
||||
my($prm) = q"'----':" . AEPrint($_[0]);
|
||||
$evt = do_event(qw/CWIE RMOB/, $app, $prm);
|
||||
}
|
||||
}
|
||||
|
||||
sub _open_file ($) {
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(alis), " .
|
||||
q"seld:TEXT(@), from:'null'()}";
|
||||
|
||||
do_event(qw/aevt odoc/, $app, $prm, $_[0]);
|
||||
}
|
||||
|
||||
sub import_project ($$) {
|
||||
my($xml_file, $project_path) = @_;
|
||||
|
||||
my($prm) = "kocl:type(PRJD), rtyp:TEXT(@), data:TEXT(@), &subj:'null'()";
|
||||
|
||||
my($evt) = do_event(qw/core crel/, $app, $prm, $project_path, $xml_file);
|
||||
my($result) = _get_event_result($evt);
|
||||
|
||||
if ($result eq "") {
|
||||
_close(_get_project($project_path));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub export_project ($$) {
|
||||
my($project_path, $xml_out_path) = @_;
|
||||
my($p, $project_was_closed);
|
||||
|
||||
$project_was_closed = 0;
|
||||
while (1) {
|
||||
$p = _get_project($project_path);
|
||||
if (!$p) {
|
||||
if ($project_was_closed) {
|
||||
print "### Error - request for project document failed after opening\n";
|
||||
die "### possibly CW bug: be sure to close your Find window\n";
|
||||
}
|
||||
$project_was_closed = 1;
|
||||
_open_file($project_path);
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# avoid problems with the Project Messages window
|
||||
_close_named_window("Project Messages");
|
||||
|
||||
my($prm) =
|
||||
q"'----':obj {form:indx, want:type(PRJD), " .
|
||||
q"seld:1, from:'null'()}, kfil:TEXT(@)";
|
||||
|
||||
my($evt) = do_event(qw/CWIE EXPT/, $app, $prm, $xml_out_path);
|
||||
|
||||
if ($project_was_closed) {
|
||||
$p = _get_project($project_path);
|
||||
_close($p);
|
||||
}
|
||||
|
||||
return _get_event_result($evt);
|
||||
}
|
||||
|
||||
sub _doc_named ($) {
|
||||
my($prm) =
|
||||
q"'----':obj {form:test, want:type(docu), from:'null'(), " .
|
||||
q"seld:cmpd{relo:'= ', 'obj1':obj {form:prop, want:type" .
|
||||
q"(prop), seld:type(pnam), from:'exmn'()}, 'obj2':TEXT(@)}}";
|
||||
|
||||
my($evt) = do_event(qw/core getd/, $app, $prm, $_[0]);
|
||||
return($evt->{REPLY} eq 'aevt\ansr{}' ? undef : $evt);
|
||||
}
|
||||
|
||||
sub _full_path ($) {
|
||||
my($obj) = $_[0];
|
||||
my($prm) =
|
||||
q"'----':obj {form:prop, want:type(prop), seld:type(FILE), " .
|
||||
q"from:" . AEPrint($_[0]) . q"}, rtyp:type(TEXT)";
|
||||
my($evt) = do_event(qw/core getd/, $app, $prm);
|
||||
|
||||
return MacPerl::MakePath(
|
||||
MacUnpack('fss ', (
|
||||
AEGetParamDesc($evt->{REP}, keyDirectObject()))->data()->get()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
sub _save_errors_window ($) {
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
|
||||
do_event(qw/MMPR SvMs/, $app, $prm, $_[0]);
|
||||
}
|
||||
|
||||
|
||||
sub _close_errors_window () {
|
||||
return _close_named_window('Errors & Warnings');
|
||||
}
|
||||
|
||||
|
||||
sub _close_named_window ($) {
|
||||
my($window_name) = @_;
|
||||
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(cwin), " .
|
||||
q"seld:TEXT(@), from:'null'()}";
|
||||
|
||||
my($evt) = do_event(qw/core clos/, $app, $prm, $window_name);
|
||||
return($evt->{REPLY} eq 'aevt\ansr{}' ? 1 : 0);
|
||||
}
|
||||
|
||||
sub _close () {
|
||||
my($prm) = q"'----':" . AEPrint($_[0]);
|
||||
do_event(qw/core clos/, $app, $prm);
|
||||
}
|
||||
|
||||
sub _get_dobj ($) {
|
||||
return(AEGetParamDesc($_[0]->{REP}, keyDirectObject()));
|
||||
}
|
||||
|
||||
sub _get_folder ($$) {
|
||||
require 'GUSI.ph';
|
||||
my($prompt, $default) = @_;
|
||||
MacPerl::Choose(
|
||||
GUSI::AF_FILE(), 0, $prompt, '',
|
||||
GUSI::CHOOSE_DIR() + ($default ? &GUSI::CHOOSE_DEFAULT : 0),
|
||||
$default
|
||||
);
|
||||
}
|
||||
|
||||
sub _get_event_result ($)
|
||||
{
|
||||
my($evt) = @_;
|
||||
|
||||
my($result) = $evt->{ERROR};
|
||||
|
||||
if ( $result eq "" && $evt->{ERRNO} != 0 )
|
||||
{
|
||||
$result = "unknown error (".$evt->{ERRNO}.")";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
sub _save_appath ($$) {
|
||||
|
||||
my($cwd) = cwd(); # remember the current working dir
|
||||
chdir($scriptDir); # change dir to the script dir
|
||||
|
||||
local(*F);
|
||||
open(F, '>' . $_[0]) or die $!;
|
||||
print F $_[1];
|
||||
close(F);
|
||||
|
||||
chdir($cwd); # restore the cwd
|
||||
}
|
||||
|
||||
sub _read_appath ($) {
|
||||
|
||||
my($filepath) = @_;
|
||||
|
||||
my($cwd) = cwd(); # remember the current working dir
|
||||
chdir($scriptDir); # change dir to the script dir
|
||||
|
||||
if (! -e $filepath) {
|
||||
return "";
|
||||
}
|
||||
|
||||
local(*F);
|
||||
open(F, $filepath);
|
||||
my($appath) = <F>;
|
||||
close(F);
|
||||
|
||||
chdir($cwd); # restore the cwd
|
||||
return($appath);
|
||||
}
|
||||
|
||||
|
||||
sub _test ($) {
|
||||
activate($ide_loc_file);
|
||||
my($path) = $_[0];
|
||||
build_project(
|
||||
"${path}modules:xml:macbuild:XML.mcp", '',
|
||||
"${path}build:mac:Mozilla.BuildLog.part"
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=back
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
=over 4
|
||||
|
||||
=item v1.02, September 23, 1998
|
||||
|
||||
Made fixes in finding and saving location of CodeWarrior IDE.
|
||||
|
||||
=item v1.01, June 1, 1998
|
||||
|
||||
Made fixes to C<chdir()> in C<activate()>, made C<activate()> more robust
|
||||
in finding CodeWarrior IDE, added global variable to NOT switch to IDE
|
||||
for each sent event, a few other fixes.
|
||||
|
||||
=item v1.00, May 30, 1998
|
||||
|
||||
First shot
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Chris Nandor F<E<lt>pudge@pobox.comE<gt>>, and the author of the
|
||||
original I<CodeWarriorLib>, Scott Collins F<E<lt>scc@netscape.comE<gt>>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
BuildProject L<Moz>.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is Mozilla Communicator client code, released
|
||||
March 31, 1998.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
=cut
|
||||
573
mozilla/build/mac/build_scripts/Moz/Jar.pm
Normal file
573
mozilla/build/mac/build_scripts/Moz/Jar.pm
Normal file
@@ -0,0 +1,573 @@
|
||||
#!perl -w
|
||||
package Moz::Jar;
|
||||
|
||||
#
|
||||
# Module for creating jar files, either using a jar manifest, or
|
||||
# simply jarring up folders on disk.
|
||||
#
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
use strict;
|
||||
use Archive::Zip;
|
||||
use File::Path;
|
||||
|
||||
use Mac::Files;
|
||||
|
||||
use Moz::Moz;
|
||||
|
||||
use vars qw( @ISA @EXPORT );
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
CreateJarFileFromDirectory
|
||||
CreateJarFromManifest
|
||||
WriteOutJarFiles
|
||||
SanityCheckJarOptions
|
||||
);
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Add the contents of a directory to the zip file
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub _addDirToJar($$$$)
|
||||
{
|
||||
my($dir, $jar_root, $zip, $compress) = @_;
|
||||
|
||||
opendir(DIR, $dir) or die "Error: Cannot open dir $dir\n";
|
||||
my @files = readdir(DIR);
|
||||
closedir DIR;
|
||||
|
||||
my $unix_jar_root = $jar_root;
|
||||
$unix_jar_root =~ s|:|/|g; # colon to slash conversion
|
||||
|
||||
my $file;
|
||||
|
||||
foreach $file (@files)
|
||||
{
|
||||
my $filepath = $dir.":".$file;
|
||||
|
||||
if (-d $filepath)
|
||||
{
|
||||
print "Adding files to jar from $filepath\n";
|
||||
_addDirToJar($filepath, $jar_root, $zip, $compress);
|
||||
}
|
||||
else
|
||||
{
|
||||
my $member = Archive::Zip::Member->newFromFile($filepath);
|
||||
die "Error: Failed to create zip file member $filepath\n" unless $member;
|
||||
|
||||
my $unixName = $filepath;
|
||||
$unixName =~ s|:|/|g; # colon to slash conversion
|
||||
$unixName =~ s|^$unix_jar_root||; # relativise
|
||||
|
||||
$member->fileName($unixName);
|
||||
|
||||
# print "Adding $file as $unixName\n";
|
||||
|
||||
if ($compress) {
|
||||
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
|
||||
} else {
|
||||
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
|
||||
}
|
||||
|
||||
$zip->addMember($member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Add the contents of a directory to the zip file
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub CreateJarFileFromDirectory($$$)
|
||||
{
|
||||
my($srcdir, $jarpath, $compress) = @_;
|
||||
|
||||
my $zip = Archive::Zip->new();
|
||||
|
||||
_addDirToJar($srcdir, $srcdir, $zip, $compress);
|
||||
|
||||
print "Saving zip file...\n";
|
||||
my $status = $zip->writeToFileNamed($jarpath);
|
||||
if ($status == 0) {
|
||||
print "Zipping completed successfully\n";
|
||||
} else {
|
||||
print "Error saving zip file\n";
|
||||
}
|
||||
|
||||
# set the file type/creator to something reasonable
|
||||
MacPerl::SetFileInfo("ZIP ", "ZIP ", $jarpath);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# printZipContents
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub printZipContents($)
|
||||
{
|
||||
my($zip) = @_;
|
||||
|
||||
my(@members) = $zip->memberNames();
|
||||
|
||||
print "Zip contains:\n";
|
||||
|
||||
my($member);
|
||||
foreach $member (@members)
|
||||
{
|
||||
print " $member\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# safeSaveJarFile
|
||||
#
|
||||
# Archive::Zip has a problem where you cannot save a zip file on top of
|
||||
# an existing zip file that it has open, because it holds references
|
||||
# into that zip. So we have to save to a temp file, then do a swap.
|
||||
#
|
||||
# Note that the zip will become invalid after this operation.
|
||||
# If you want to do further operations on it, you'll have to reread it.
|
||||
#-------------------------------------------------------------------------------
|
||||
sub safeSaveJarFile($$)
|
||||
{
|
||||
my($zip, $full_dest_path) = @_;
|
||||
|
||||
my($temp_file_name) = $full_dest_path."_temp";
|
||||
|
||||
($zip->writeToFileNamed($temp_file_name) == Archive::Zip::AZ_OK) || die "Error: died writing jar to temp file $temp_file_name\n";
|
||||
|
||||
unlink $full_dest_path;
|
||||
|
||||
(rename $temp_file_name, $full_dest_path) || die "Error: Failed to rename $temp_file_name\n";
|
||||
|
||||
MacPerl::SetFileInfo("ZIP ", "ZIP ", $full_dest_path);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# addToJarFile
|
||||
#
|
||||
# Add a file to a jar file
|
||||
#
|
||||
# Parameters:
|
||||
# 1. Jar ID. Unix path of jar file inside chrome.
|
||||
# 2. Abs path to jar.mn file (i.e. source) (mac breaks)
|
||||
# 3. File source, relative to jar.mn path (mac breaks)
|
||||
# 4. Abs path to the resulting .jar file (mac breaks)
|
||||
# 5. Relative file path within the jar (unix breaks)
|
||||
# 6. Reference to hash of jar files
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub addToJarFile($$$$$$$)
|
||||
{
|
||||
my($jar_id, $jar_man_dir, $file_src, $jar_path, $file_jar_path, $override, $jars) = @_;
|
||||
|
||||
# print "addToJarFile with:\n $jar_man_dir\n $file_src\n $jar_path\n $file_jar_path\n";
|
||||
|
||||
unless ($jar_path =~ m/(.+:)([^:]+)$/) { die "Error: Bad jar path $jar_path\n"; }
|
||||
|
||||
my($target_dir) = $1;
|
||||
my($jar_name) = $2;
|
||||
|
||||
$target_dir =~ s/[^:]+$//;
|
||||
|
||||
# print "¥ $target_dir $jar_name\n";
|
||||
|
||||
# find the source file
|
||||
my($src) = $jar_man_dir.":".$file_src;
|
||||
if ((!-e $src) && ($file_src =~ m/.+:([^:]+)$/)) # src does not exist. Fall back to looking for src in jar.mn dir
|
||||
{
|
||||
$file_src = $1;
|
||||
$src = $jar_man_dir.":".$file_src;
|
||||
|
||||
if (!-e $src) {
|
||||
die "Error: Can't find chrome file $src\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($main::options{chrome_jars})
|
||||
{
|
||||
my($zip) = $jars->{$jar_id};
|
||||
unless ($zip) { die "Error: Can't find Zip entry for $jar_id\n"; }
|
||||
|
||||
# print "Adding $file_src to jar file $jar_path at $file_jar_path\n";
|
||||
my($member) = Archive::Zip::Member->newFromFile($src);
|
||||
unless ($member) { die "Error: Failed to create zip file member $src\n"; }
|
||||
|
||||
$member->fileName($file_jar_path);
|
||||
|
||||
my($compress) = 1;
|
||||
if ($compress) {
|
||||
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_DEFLATED);
|
||||
$member->desiredCompressionLevel(Archive::Zip::COMPRESSION_LEVEL_DEFAULT); # defaults to 6
|
||||
} else {
|
||||
$member->desiredCompressionMethod(Archive::Zip::COMPRESSION_STORED);
|
||||
}
|
||||
|
||||
my($old_member) = $zip->memberNamed($file_jar_path);
|
||||
|
||||
if ($override)
|
||||
{
|
||||
if ($old_member)
|
||||
{
|
||||
# print "Overriding $file_jar_path in jar file $jar_id\n";
|
||||
# need to compare mod dates or use the + here
|
||||
$zip->removeMember($old_member);
|
||||
}
|
||||
|
||||
$zip->addMember($member);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($old_member)
|
||||
{
|
||||
#compare dates here
|
||||
my($member_moddate) = $old_member->lastModTime();
|
||||
my($file_moddate) = GetFileModDate($src);
|
||||
|
||||
if ($file_moddate > $member_moddate)
|
||||
{
|
||||
print "Updating older file $file_jar_path in $jar_id\n";
|
||||
$zip->removeMember($old_member);
|
||||
$zip->addMember($member);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$zip->addMember($member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($main::options{chrome_files}) # we install raw files too
|
||||
{
|
||||
my($rel_path) = $file_jar_path;
|
||||
$rel_path =~ s|/|:|g; # slash to colons
|
||||
|
||||
my($dir_name) = $jar_name;
|
||||
$dir_name =~ s/\.jar$//;
|
||||
|
||||
my($dst) = $target_dir.$dir_name.":".$rel_path;
|
||||
|
||||
# print "Aliassing $src\n to\n$dst\n";
|
||||
if ($override)
|
||||
{
|
||||
unlink $dst;
|
||||
MakeAlias($src, $dst); # don't check errors, otherwise we fail on replacement
|
||||
}
|
||||
else
|
||||
{
|
||||
if (-e $dst)
|
||||
{
|
||||
#compare dates here
|
||||
my($dst_moddate) = GetFileModDate($dst);
|
||||
my($file_moddate) = GetFileModDate($src);
|
||||
|
||||
if ($file_moddate > $dst_moddate)
|
||||
{
|
||||
print "Updating older file $rel_path in $dir_name\n";
|
||||
unlink $dst;
|
||||
MakeAlias($src, $dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "File $file_jar_path in $jar_id is more recent. Not updating.\n";
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeAlias($src, $dst);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# setupJarFile
|
||||
#
|
||||
# setup a zip for writing
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub setupJarFile($$$)
|
||||
{
|
||||
my($jar_id, $dest_path, $jar_hash) = @_;
|
||||
|
||||
# print "Creating jar file $jar_id at $jar_path\n";
|
||||
|
||||
my($jar_file) = $jar_id;
|
||||
$jar_file =~ s|/|:|g; # slash to colons
|
||||
my($full_jar_path) = full_path_to($dest_path.":".$jar_file);
|
||||
|
||||
if ($main::options{chrome_jars})
|
||||
{
|
||||
my($zip) = $jar_hash->{$jar_id};
|
||||
if (!$zip) # if we haven't made it already, do so
|
||||
{
|
||||
my($zip) = Archive::Zip->new();
|
||||
$jar_hash->{$jar_id} = $zip;
|
||||
|
||||
# does the jar file exist already? If so, read it in
|
||||
if (-e $full_jar_path)
|
||||
{
|
||||
print "Reading in jar file $jar_id\n";
|
||||
if ($zip->read($full_jar_path) != Archive::Zip::AZ_OK) { die "Error: Failed to re-read $full_jar_path\n"; }
|
||||
|
||||
# printZipContents($zip);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# installing files.
|
||||
# nothing to do. MakeAlias creates dirs as needed.
|
||||
|
||||
# add this jar to the list
|
||||
$jar_hash->{$jar_id} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# closeJarFile
|
||||
#
|
||||
# We're done with this jar file _for this jar.mn_. We may add more entries
|
||||
# to it later, so keep it open in the hash.
|
||||
#-------------------------------------------------------------------------------
|
||||
sub closeJarFile($$)
|
||||
{
|
||||
my($jar_path, $jar_hash) = @_;
|
||||
|
||||
# print "Closing jar file $jar_path\n";
|
||||
|
||||
if ($main::options{chrome_jars})
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
# installing files.
|
||||
# nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# WriteOutJarFiles
|
||||
#
|
||||
# Now we dump out the jars
|
||||
#-------------------------------------------------------------------------------
|
||||
sub WriteOutJarFiles($$)
|
||||
{
|
||||
my($chrome_dir, $jars) = @_;
|
||||
|
||||
unless ($main::options{chrome_jars}) { return; }
|
||||
|
||||
my($full_chrome_path) = full_path_to($chrome_dir);
|
||||
|
||||
my($key);
|
||||
foreach $key (keys %$jars)
|
||||
{
|
||||
my($zip) = $jars->{$key};
|
||||
|
||||
my($rel_path) = $key;
|
||||
$rel_path =~ s/\//:/g;
|
||||
|
||||
my($output_path) = $full_chrome_path.":".$rel_path;
|
||||
|
||||
print "Writing zip file $key to $output_path\n";
|
||||
|
||||
# ensure the target dirs exist
|
||||
my($path) = $output_path;
|
||||
$path =~ s/[^:]+$//;
|
||||
mkpath($path);
|
||||
|
||||
# unlink $output_path; # remove any existing jar
|
||||
safeSaveJarFile($zip, $output_path);
|
||||
# $zip is invalid after this operation, so nuke it here
|
||||
$jars->{$key} = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# registerChromePackage
|
||||
#
|
||||
# Enter a chrome package into the installed-chrome.txt file
|
||||
#-------------------------------------------------------------------------------
|
||||
sub registerChromePackage($$$$$$)
|
||||
{
|
||||
my($jar_file, $file_path, $chrome_dir, $jar_hash, $chrome_type, $pkg_name) = @_;
|
||||
|
||||
my($manifest_subdir) = $jar_file;
|
||||
$manifest_subdir =~ s/:/\//g;
|
||||
|
||||
my($chrome_entry);
|
||||
|
||||
if ($main::options{use_jars}) {
|
||||
$chrome_entry = "$chrome_type,install,url,jar:resource:/chrome/$manifest_subdir!/$chrome_type/$pkg_name";
|
||||
} else {
|
||||
$manifest_subdir =~ s/\.jar$//;
|
||||
$chrome_entry = "$chrome_type,install,url,resource:/chrome/$manifest_subdir/$chrome_type/$pkg_name";
|
||||
}
|
||||
|
||||
# print "Entering $chrome_entry in installed-chrome.txt\n";
|
||||
|
||||
# ensure chrome_dir exists
|
||||
mkpath($chrome_dir);
|
||||
|
||||
my($inst_chrome) = ${chrome_dir}.":installed-chrome.txt";
|
||||
|
||||
if (open(CHROMEFILE, "<$inst_chrome")) {
|
||||
while (<CHROMEFILE>) {
|
||||
chomp;
|
||||
if ($_ eq $chrome_entry) {
|
||||
# $chrome_entry already appears in installed-chrome.txt file
|
||||
# just update the mod date
|
||||
my $now = time;
|
||||
utime($now, $now, $inst_chrome) || die "Error: Couldn't touch $inst_chrome";
|
||||
print "+++ updating chrome $inst_chrome\n+++\t\t$chrome_entry\n";
|
||||
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
close(CHROMEFILE) || die "Error: can't close $inst_chrome: $!";
|
||||
}
|
||||
open(CHROMEFILE, ">>${inst_chrome}") || die "Error: Failed to open $inst_chrome\n";
|
||||
print(CHROMEFILE "${chrome_entry}\n");
|
||||
close(CHROMEFILE) || die "Error: Failed to close $inst_chrome\n";
|
||||
print "+++ adding chrome $inst_chrome\n+++\t\t$chrome_entry\n";
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Create or add to a jar file from a jar.mn file.
|
||||
# Both arguments are relative to the mozilla root dir.
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub CreateJarFromManifest($$$)
|
||||
{
|
||||
my($jar_man_path, $dest_path, $jars) = @_;
|
||||
|
||||
if ($main::options{chrome_jars}) {
|
||||
print "Jarring from $jar_man_path\n";
|
||||
}
|
||||
if ($main::options{chrome_files}) {
|
||||
print "Installing files from $jar_man_path\n";
|
||||
}
|
||||
|
||||
$jar_man_path = full_path_to($jar_man_path);
|
||||
$dest_path = full_path_to($dest_path);
|
||||
|
||||
# if the jars hash is empty, nuke installed-chrome.txt
|
||||
if (! scalar(%$jars))
|
||||
{
|
||||
print "Nuking installed-chrome.txt\n";
|
||||
my($installed_chrome) = $dest_path.":installed-chrome.txt";
|
||||
# unlink $installed_chrome;
|
||||
}
|
||||
|
||||
my $jar_man_dir = "";
|
||||
my $jar_man_file = "";
|
||||
|
||||
if ($jar_man_path =~ /(.+):([^:]+)$/)
|
||||
{
|
||||
$jar_man_dir = $1; # no trailing :
|
||||
$jar_man_file = $2;
|
||||
}
|
||||
|
||||
# Keep a hash of jar files, keyed on relative jar path (e.g. "packages/core.jar")
|
||||
# Entries are open Archive::Zips (if zipping), and installed-chrome entries.
|
||||
|
||||
my($jar_id) = ""; # Current foo/bar.jar from jar.mn file
|
||||
my($jar_file) = ""; # relative path to jar file (from $dest_path), with mac separators
|
||||
my($full_jar_path);
|
||||
|
||||
open(FILE, "<$jar_man_path") || die "Error: could not open \"$jar_man_path\": $!";
|
||||
while (<FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
# print "$line\n";
|
||||
|
||||
if ($line =~ /^\s*\#.*$/) { # skip comments
|
||||
next;
|
||||
}
|
||||
|
||||
if ($line =~/^([\w\d.\-\_\\\/]+)\:\s*$/) # line start jar file entries
|
||||
{
|
||||
$jar_id = $1;
|
||||
$jar_file = $jar_id;
|
||||
$jar_file =~ s|/|:|g; # slash to colons
|
||||
$full_jar_path = $dest_path.":".$jar_file;
|
||||
|
||||
setupJarFile($jar_id, $dest_path, $jars);
|
||||
|
||||
}
|
||||
elsif ($line =~ /^(\+?)\s+([\w\d.\-\_\\\/]+)\s*(\([\w\d.\-\_\\\/]+\))?$\s*/) # jar file entry
|
||||
{
|
||||
my($override) = ($1 eq "+");
|
||||
my($file_dest) = $2;
|
||||
my($file_src) = $3;
|
||||
|
||||
if ($file_src) {
|
||||
$file_src = substr($file_src, 1, -1); #strip the ()
|
||||
} else {
|
||||
$file_src = $file_dest;
|
||||
}
|
||||
|
||||
$file_src =~ s|/|:|g;
|
||||
|
||||
if ($jar_file ne "") # if jar is open, add to jar
|
||||
{
|
||||
if ($file_dest =~ /([\w\d.\-\_]+)\/([\w\d.\-\_\\\/]+)contents.rdf/)
|
||||
{
|
||||
my $chrome_type = $1;
|
||||
my $pkg_name = $2;
|
||||
registerChromePackage($jar_file, $file_dest, $dest_path, $jars, $chrome_type, $pkg_name);
|
||||
}
|
||||
|
||||
addToJarFile($jar_id, $jar_man_dir, $file_src, $full_jar_path, $file_dest, $override, $jars);
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error: bad jar.mn format at $line\n";
|
||||
}
|
||||
}
|
||||
elsif ($line =~ /^\s*$/ ) # blank line
|
||||
{
|
||||
if ($jar_file ne "") #if a jar file is open, close it
|
||||
{
|
||||
closeJarFile($full_jar_path, $jars);
|
||||
|
||||
$jar_file = "";
|
||||
$full_jar_path = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(FILE);
|
||||
|
||||
if ($jar_file ne "") #if a jar file is open, close it
|
||||
{
|
||||
closeJarFile($full_jar_path, $jars);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
228
mozilla/build/mac/build_scripts/Moz/MacCVS.pm
Normal file
228
mozilla/build/mac/build_scripts/Moz/MacCVS.pm
Normal file
@@ -0,0 +1,228 @@
|
||||
#!perl -w
|
||||
package Moz::MacCVS;
|
||||
|
||||
# package Mac::Apps::MacCVS; this should really be the name of the package
|
||||
# but due to our directory hierarchy in mozilla, I am not doing it
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
|
||||
use vars qw($VERSION @ISA @EXPORT);
|
||||
|
||||
use Cwd;
|
||||
|
||||
use File::Basename;
|
||||
|
||||
use Mac::StandardFile;
|
||||
use Mac::AppleEvents;
|
||||
use Mac::AppleEvents::Simple;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(new describe checkout update);
|
||||
$VERSION = "1.00";
|
||||
|
||||
# If you want to understand the gobbldeygook that's used to build Apple Events,
|
||||
# you should start by reading the AEGizmos documentation.
|
||||
|
||||
|
||||
# Architecture:
|
||||
# cvs session object:
|
||||
# name - session name
|
||||
# session_file - session file
|
||||
#
|
||||
#
|
||||
|
||||
my($last_error) = 0;
|
||||
my($gAppSig) = 'Mcvs'; # MacCVS Pro
|
||||
|
||||
#
|
||||
# utility routines
|
||||
#
|
||||
|
||||
|
||||
sub _checkForEventError($)
|
||||
{
|
||||
my($evt) = @_;
|
||||
|
||||
if ($evt->{ERRNO} != 0)
|
||||
{
|
||||
print STDERR "Error. Script returned '$evt->{ERROR} (error $evt->{ERRNO})\n";
|
||||
$last_error = $evt->{ERRNO};
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1; # success
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Session object methods
|
||||
#
|
||||
|
||||
sub new
|
||||
{
|
||||
my ( $proto, $session_file) = @_;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = {};
|
||||
|
||||
if ( defined($session_file) && ( -e $session_file) )
|
||||
{
|
||||
$self->{"name"} = basename( $session_file );
|
||||
$self->{"session_file"} = $session_file;
|
||||
bless $self, $class;
|
||||
return $self;
|
||||
}
|
||||
else
|
||||
{
|
||||
print STDERR "MacCVS->new cvs file < $session_file > does not exist\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# makes sure that the session is open
|
||||
# assertSessionOpen()
|
||||
# returns 1 on success
|
||||
sub assertSessionOpen()
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
$last_error = 0;
|
||||
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(alis), seld:TEXT(@), from:'null'()}";
|
||||
|
||||
my($evt) = do_event(qw/aevt odoc/, $gAppSig, $prm, $self->{session_file});
|
||||
return _checkForEventError($evt);
|
||||
}
|
||||
|
||||
# prints the cvs object, used mostly for debugging
|
||||
sub describe
|
||||
{
|
||||
my($self) = shift;
|
||||
$last_error = 0;
|
||||
print "MacCVS:: name: ", $self->{name}, " session file: ", $self->{session_file}, "\n";
|
||||
}
|
||||
|
||||
# checkout( self, module, revision, date)
|
||||
# MacCVS checkout command
|
||||
# returns 1 on success.
|
||||
sub checkout()
|
||||
{
|
||||
my($self, $module, $revision, $date ) = @_;
|
||||
unless( defined ($module) ) { $module = ""; } # get rid of the pesky undefined warnings
|
||||
unless( defined ($revision) ) { $revision = ""; }
|
||||
unless( defined ($date) ) { $date = ""; }
|
||||
|
||||
$last_error = 0;
|
||||
|
||||
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
|
||||
|
||||
my($revstring) = ($revision ne "") ? $revision : "(none)";
|
||||
my($datestring) = ($date ne "") ? $date : "(none)";
|
||||
|
||||
print "Checking out $module with revision $revstring, date $datestring\n";
|
||||
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
|
||||
q"modl:'TEXT'(@), tagr:'TEXT'(@), tagd:'TEXT'(@) ";
|
||||
|
||||
my($evt) = do_event(qw/MCvs cout/, $gAppSig, $prm, $self->{name}, $module, $revision, $date);
|
||||
return _checkForEventError($evt);
|
||||
}
|
||||
|
||||
|
||||
# update( self, branch tag, list of paths)
|
||||
# MacCVS udate command
|
||||
# returns 1 on success.
|
||||
# NOTE: MacCVS Pro does not correctly support this stuff yet (as of version 2.7d5).
|
||||
sub update()
|
||||
{
|
||||
my($self, $branch, $paths ) = @_;
|
||||
|
||||
$last_error = 0;
|
||||
|
||||
$self->assertSessionOpen() || die "Error: failed to open MacCVS session file at $self->{session_file}\n";
|
||||
|
||||
if ($branch eq "HEAD") {
|
||||
$branch = "";
|
||||
}
|
||||
|
||||
my($paths_list) = "";
|
||||
|
||||
my($path);
|
||||
foreach $path (@$paths)
|
||||
{
|
||||
if ($paths_list ne "") {
|
||||
$paths_list = $paths_list.", ";
|
||||
}
|
||||
|
||||
$paths_list = $paths_list."Ò".$path."Ó";
|
||||
}
|
||||
|
||||
my($prm) =
|
||||
q"'----':obj {form:name, want:type(docu), seld:TEXT(@), from:'null'()}, ".
|
||||
q"tagr:'TEXT'(@), tFls:[";
|
||||
|
||||
$prm = $prm.$paths_list."]";
|
||||
|
||||
my($evt) = do_event(qw/MCvs updt/, $gAppSig, $prm, $self->{name}, $branch);
|
||||
return _checkForEventError($evt);
|
||||
};
|
||||
|
||||
|
||||
sub getLastError()
|
||||
{
|
||||
return $last_error;
|
||||
}
|
||||
|
||||
1;
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MacCVS - Interface to MacCVS
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use MacCVS;
|
||||
$session = MacCVS->new( <session_file_path>) || die "cannot create session";
|
||||
$session->checkout([module] [revision] [date]) || die "Could not check out";
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a MacCVS interface for talking to MacCVS Pro client.
|
||||
MacCVSSession is the class used to manipulate the session
|
||||
|
||||
=item new
|
||||
MacCVS->new( <cvs session file path>);
|
||||
|
||||
Creates a new session. Returns undef on failure.
|
||||
|
||||
=item checkout( <module> [revision] [date] )
|
||||
|
||||
cvs checkout command. Revision and date are optional
|
||||
returns 0 on failure
|
||||
|
||||
=cut
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=over
|
||||
|
||||
=item MacCVS Home Page
|
||||
|
||||
http://www.maccvs.org/
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Aleks Totic atotic@netscape.com
|
||||
Simon Fraser sfraser@netscape.com
|
||||
|
||||
=cut
|
||||
|
||||
__END__
|
||||
603
mozilla/build/mac/build_scripts/Moz/Moz.pm
Normal file
603
mozilla/build/mac/build_scripts/Moz/Moz.pm
Normal file
@@ -0,0 +1,603 @@
|
||||
=head1 NAME
|
||||
|
||||
B<Moz> - routines for automating CodeWarrior builds, and some extra-curricular
|
||||
activities related to building Mozilla
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Moz;
|
||||
|
||||
OpenErrorLog(":::BuildLog");
|
||||
StopForErrors();
|
||||
|
||||
$Moz::QUIET = 1;
|
||||
InstallFromManifest(":projects:MANIFEST", $dist_dir);
|
||||
|
||||
BuildProjectClean(":projects:SomeProject.mcp", "SomeTarget");
|
||||
MakeAlias(":projects:SomeProject.shlb", $dist_dir);
|
||||
|
||||
DontStopForErrors();
|
||||
|
||||
BuildProject(":projects:SomeOtherProject.mcp", "SomeTarget");
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<Moz> comprises the routines needed to slap CodeWarrior around, force it
|
||||
to build a sequence of projects, report the results, and a few other things.
|
||||
This module should only contain functions that are generic to any build,
|
||||
not just the Mozilla build.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
package Moz::Moz;
|
||||
require Exporter;
|
||||
|
||||
use Cwd;
|
||||
|
||||
use File::Copy;
|
||||
use File::Path;
|
||||
use File::Basename;
|
||||
|
||||
use Mac::Types;
|
||||
use Mac::Events;
|
||||
use Mac::Processes;
|
||||
|
||||
use ExtUtils::Manifest 'maniread';
|
||||
|
||||
use Moz::CodeWarriorLib;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT = qw( LaunchCodeWarrior
|
||||
GetCodeWarriorRelativePath
|
||||
current_directory
|
||||
full_path_to
|
||||
DoBuildProject
|
||||
ImportXMLProject
|
||||
ExportProjectToXML
|
||||
OpenErrorLog
|
||||
MakeAlias
|
||||
GetFileModDate
|
||||
StopForErrors
|
||||
DontStopForErrors
|
||||
InstallFromManifest
|
||||
InstallResources
|
||||
RedirectOutputToFile
|
||||
Delay
|
||||
ActivateApplication
|
||||
IsProcessRunning);
|
||||
|
||||
@EXPORT_OK = qw(CloseErrorLog QUIET);
|
||||
|
||||
|
||||
sub current_directory()
|
||||
{
|
||||
my $current_directory = cwd();
|
||||
chop($current_directory) if ( $current_directory =~ m/:$/ );
|
||||
return $current_directory;
|
||||
}
|
||||
|
||||
sub full_path_to($)
|
||||
{
|
||||
my ($path) = @_;
|
||||
if ( $path =~ m/^[^:]+$/ )
|
||||
{
|
||||
$path = ":" . $path;
|
||||
}
|
||||
|
||||
if ( $path =~ m/^:/ )
|
||||
{
|
||||
$path = current_directory() . $path;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
$logging = 0;
|
||||
$recent_errors_file = "";
|
||||
$stop_on_1st_error = 1;
|
||||
$QUIET = 0;
|
||||
|
||||
|
||||
|
||||
=head2 Logging all the errors and warnings - C<OpenErrorLog($log_file)>, C<CloseErrorLog()>
|
||||
|
||||
The warnings and errors generated in the course of building projects can be logged to a file.
|
||||
Tinderbox uses this facility to show why a remote build failed.
|
||||
|
||||
Logging is off by default.
|
||||
Start logging at any point in your build process with C<OpenErrorLog($log_file)>.
|
||||
Stop with C<CloseErrorLog()>.
|
||||
You never need to close the log explicitly, unless you want to just log a couple of projects in the middle of a big list.
|
||||
C<CloseErrorLog()> is not exported by default.
|
||||
|
||||
=cut
|
||||
|
||||
sub CloseErrorLog()
|
||||
{
|
||||
if ( $logging )
|
||||
{
|
||||
close(ERROR_LOG);
|
||||
$logging = 0;
|
||||
StopForErrors() if $stop_on_1st_error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub OpenErrorLog($)
|
||||
{
|
||||
my ($log_file) = @_;
|
||||
|
||||
CloseErrorLog();
|
||||
if ( $log_file )
|
||||
{
|
||||
$log_file = full_path_to($log_file);
|
||||
|
||||
open(ERROR_LOG, ">$log_file") || die "Error: Can't open $log_file\n";
|
||||
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
|
||||
|
||||
$log_file =~ m/.+:(.+)/;
|
||||
$recent_errors_file = full_path_to("$1.part");
|
||||
$logging = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=head2 Stopping before it's too late - C<StopForErrors()>, C<DontStopForErrors()>
|
||||
|
||||
When building a long list of projects, you decide whether to continue building subsequent projects when one fails.
|
||||
By default, your build script will C<die> after the first project that generates an error while building.
|
||||
Change this behavior with C<DontStopForErrors()>.
|
||||
Re-enable it with C<StopForErrors()>.
|
||||
|
||||
=cut
|
||||
|
||||
sub StopForErrors()
|
||||
{
|
||||
$stop_on_1st_error = 1;
|
||||
|
||||
# Can't stop for errors unless we notice them.
|
||||
# Can't notice them unless we are logging.
|
||||
# If the user didn't explicitly request logging, log to a temporary file.
|
||||
|
||||
if ( ! $recent_errors_file )
|
||||
{
|
||||
OpenErrorLog("${TMPDIR}BuildResults");
|
||||
}
|
||||
}
|
||||
|
||||
sub DontStopForErrors()
|
||||
{
|
||||
$stop_on_1st_error = 0;
|
||||
}
|
||||
|
||||
sub log_message($)
|
||||
{
|
||||
if ( $logging )
|
||||
{
|
||||
my ($message) = @_;
|
||||
print ERROR_LOG $message;
|
||||
}
|
||||
}
|
||||
|
||||
sub log_message_with_time($)
|
||||
{
|
||||
if ( $logging )
|
||||
{
|
||||
my ($message) = @_;
|
||||
my $time_stamp = localtime();
|
||||
log_message("$message ($time_stamp)\n");
|
||||
}
|
||||
}
|
||||
|
||||
sub log_recent_errors($)
|
||||
{
|
||||
my ($project_name) = @_;
|
||||
my $found_errors = 0;
|
||||
|
||||
if ( $logging )
|
||||
{
|
||||
open(RECENT_ERRORS, "<$recent_errors_file");
|
||||
|
||||
while( <RECENT_ERRORS> )
|
||||
{
|
||||
if ( /^Error/ || /^CouldnÕt find project file/ || /^Link Error/ )
|
||||
{
|
||||
# if (!$found_errors)
|
||||
# print $_;
|
||||
$found_errors = 1;
|
||||
}
|
||||
print ERROR_LOG $_;
|
||||
}
|
||||
|
||||
close(RECENT_ERRORS);
|
||||
unlink("$recent_errors_file");
|
||||
}
|
||||
|
||||
if ( $stop_on_1st_error && $found_errors )
|
||||
{
|
||||
print ERROR_LOG "### Build failed.\n";
|
||||
die "### Errors encountered building \"$project_name\".\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub DoBuildProject($$$)
|
||||
{
|
||||
my ($project_path, $target_name, $clean_build) = @_;
|
||||
$project_path = full_path_to($project_path);
|
||||
|
||||
# $project_path =~ m/.+:(.+)/;
|
||||
# my $project_name = $1;
|
||||
|
||||
log_message_with_time("### Building \"$project_path\"");
|
||||
|
||||
# Check that the given project exists
|
||||
if (! -e $project_path)
|
||||
{
|
||||
print ERROR_LOG "### Build failed.\n";
|
||||
die "### Can't find project file \"$project_path\".\n";
|
||||
}
|
||||
|
||||
print "Building \"$project_path\[$target_name\]\"\n";
|
||||
|
||||
$had_errors = Moz::CodeWarriorLib::build_project(
|
||||
$project_path, $target_name, $recent_errors_file, $clean_build
|
||||
);
|
||||
WaitNextEvent();
|
||||
|
||||
# $had_errors =
|
||||
#MacPerl::DoAppleScript(<<END_OF_APPLESCRIPT);
|
||||
# tell (load script file "$CodeWarriorLib") to BuildProject("$project_path", "$project_name", "$target_name", "$recent_errors_file", $clean_build)
|
||||
#END_OF_APPLESCRIPT
|
||||
|
||||
# Append any errors to the globally accumulated log file
|
||||
# if ( $had_errors ) # Removed this test, because we want warnings, too. -- jrm
|
||||
{
|
||||
log_recent_errors($project_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub ImportXMLProject($$)
|
||||
{
|
||||
my ($xml_path, $project_path) = @_;
|
||||
|
||||
# my ($codewarrior_ide_name) = Moz::CodeWarriorLib::getCodeWarriorIDEName();
|
||||
# my $ascript = <<EOS;
|
||||
# tell application "$codewarrior_ide_name"
|
||||
# make new (project document) as ("$project_path") with data ("$xml_path")
|
||||
# end tell
|
||||
#EOS
|
||||
# print $ascript."\n";
|
||||
# my($result) = MacPerl::DoAppleScript($ascript);
|
||||
# unless ($result) { die "Error: ImportXMLProject AppleScript failed $^E $result\n"; }
|
||||
#
|
||||
|
||||
my($import_error) = Moz::CodeWarriorLib::import_project($xml_path, $project_path);
|
||||
if ($import_error ne "") {
|
||||
die "Error: ImportXMLProject failed with error $import_error\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub ExportProjectToXML($$)
|
||||
{
|
||||
my ($project_path, $xml_path) = @_;
|
||||
|
||||
my (@suffix_list) = (".mcp");
|
||||
my ($project_name, $project_dir, $suffix) = fileparse($project_path, @suffix_list);
|
||||
if ($suffix eq "") { die "Project: $project_path doesn't look like a project file.\n"; }
|
||||
|
||||
if (-e $xml_path) {
|
||||
print "$xml_path exists - not exporting $project_path\n";
|
||||
}
|
||||
else {
|
||||
print "Exporting $project_path to $xml_path\n";
|
||||
my($export_error) = Moz::CodeWarriorLib::export_project($project_path, $xml_path);
|
||||
if ($export_error ne "") {
|
||||
die "Error: export_project failed with error '$export_error'\n";
|
||||
}
|
||||
|
||||
if (! -e $xml_path) {
|
||||
die "Error: XML export to $xml_path failed\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=head2 Miscellaneous
|
||||
|
||||
C<MakeAlias($old_file, $new_file)> functions like C<symlink()>, except with better argument defaulting and more explicit error messages.
|
||||
|
||||
=cut
|
||||
|
||||
sub MakeAlias($$)
|
||||
{
|
||||
my ($old_file, $new_file) = @_;
|
||||
|
||||
# if the directory to hold $new_file doesn't exist, create it
|
||||
if ( ($new_file =~ m/(.+:)/) && !-d $1 )
|
||||
{
|
||||
mkpath($1);
|
||||
}
|
||||
|
||||
# if a leaf name wasn't specified for $new_file, use the leaf from $old_file
|
||||
if ( ($new_file =~ m/:$/) && ($old_file =~ m/.+:(.+)/) )
|
||||
{
|
||||
$new_file .= $1;
|
||||
}
|
||||
|
||||
my $message = "Can't create a Finder alias (at \"$new_file\")\n for \"$old_file\"; because ";
|
||||
|
||||
die "Error: $message \"$old_file\" doesn't exist.\n" unless -e $old_file;
|
||||
die "Error: $message I won't replace an existing (non-alias) file with an alias.\n" if ( -e $new_file && ! -l $new_file );
|
||||
|
||||
# now: $old_file exists; $new_file doesn't (or else, is an alias already)
|
||||
|
||||
if ( -l $new_file )
|
||||
{
|
||||
# ...then see if it already points to $old_file
|
||||
my $current_target = full_path_to(readlink($new_file));
|
||||
my $new_target = full_path_to($old_file);
|
||||
|
||||
return if ( $current_target eq $new_target );
|
||||
# if the desired alias already exists and points to the right thing, then we're done
|
||||
|
||||
unlink $new_file;
|
||||
}
|
||||
|
||||
symlink($old_file, $new_file) || die "Error: $message symlink returned an unexpected error.\n";
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
C<InstallFromManifest()>
|
||||
|
||||
=cut
|
||||
|
||||
sub InstallFromManifest($;$$)
|
||||
{
|
||||
my ($manifest_file, $dest_dir, $flat) = @_;
|
||||
|
||||
$flat = 0 unless defined($flat); # if $flat, all rel. paths in MANIFEST get aliased to the root of $dest_dir
|
||||
|
||||
$dest_dir ||= ":";
|
||||
|
||||
$manifest_file =~ m/(.+):/;
|
||||
my $source_dir = $1;
|
||||
|
||||
chop($dest_dir) if $dest_dir =~ m/:$/;
|
||||
|
||||
#Mac::Events->import();
|
||||
WaitNextEvent();
|
||||
if ($flat)
|
||||
{
|
||||
print "Doing manifest on \"$manifest_file\" FLAT\n" unless $QUIET;
|
||||
}
|
||||
else
|
||||
{
|
||||
print "Doing manifest on \"$manifest_file\"\n" unless $QUIET;
|
||||
}
|
||||
|
||||
my $read = maniread(full_path_to($manifest_file));
|
||||
foreach $file (keys %$read)
|
||||
{
|
||||
next unless $file;
|
||||
|
||||
$subdir = ":";
|
||||
if (!$flat && ($file =~ /:.+:/ ))
|
||||
{
|
||||
$subdir = $&;
|
||||
}
|
||||
|
||||
$file = ":$file" unless $file =~ m/^:/;
|
||||
MakeAlias("$source_dir$file", "$dest_dir$subdir");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
C<InstallResources()>
|
||||
|
||||
=cut
|
||||
|
||||
# parameters are path to MANIFEST file, destination dir, true (to make copies) or false (to make aliases)
|
||||
sub InstallResources($;$;$)
|
||||
{
|
||||
my ($manifest_file, $dest_dir, $copy_files) = @_;
|
||||
|
||||
$dest_dir ||= ":";
|
||||
mkpath($dest_dir) if !-d $dest_dir;
|
||||
|
||||
$manifest_file =~ m/(.+):/;
|
||||
my $source_dir = $1;
|
||||
|
||||
chop($dest_dir) if $dest_dir =~ m/:$/;
|
||||
|
||||
WaitNextEvent();
|
||||
print "Installing resources from \"$manifest_file\"\n" unless $QUIET;
|
||||
|
||||
my $read = maniread(full_path_to($manifest_file));
|
||||
foreach $file (keys %$read)
|
||||
{
|
||||
next unless $file;
|
||||
|
||||
if ($copy_files)
|
||||
{
|
||||
copy("$source_dir:$file", "$dest_dir:$file");
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeAlias("$source_dir:$file", "$dest_dir:$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// Delay
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub Delay($)
|
||||
{
|
||||
my ($delay_seconds) = @_;
|
||||
|
||||
$now = time;
|
||||
|
||||
$exit_time = $now + $delay_seconds;
|
||||
|
||||
while ($exit_time > $now) {
|
||||
$now = time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetFileModDate
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetFileModDate($)
|
||||
{
|
||||
my($filePath)=@_;
|
||||
my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
|
||||
$atime,$mtime,$ctime,$blksize,$blocks) = stat($filePath);
|
||||
return $mtime;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// LaunchCodeWarrior
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub LaunchCodeWarrior($)
|
||||
{
|
||||
my($idepath_file) = @_; # full path to IDE location file
|
||||
my($cur_dir) = cwd();
|
||||
|
||||
# this both launches and writes the IDE path file
|
||||
Moz::CodeWarriorLib::activate($idepath_file);
|
||||
|
||||
chdir($cur_dir);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetCodeWarriorRelativePath
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetCodeWarriorRelativePath($)
|
||||
{
|
||||
my($rel_path) = @_;
|
||||
return Moz::CodeWarriorLib::getCodeWarriorPath($rel_path);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// RedirectOutputToFile
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub RedirectOutputToFile($)
|
||||
{
|
||||
my($log_file) = @_;
|
||||
|
||||
# ensure that folders in the path exist
|
||||
my($logdir) = "";
|
||||
my($logfile) = $log_file;
|
||||
|
||||
if ($log_file =~ /(.+?:)([^:]+)$/) # ? for non-greedy match
|
||||
{
|
||||
$logdir = $1;
|
||||
$logfile = $2;
|
||||
|
||||
mkpath($logdir);
|
||||
}
|
||||
|
||||
print "Output is now being redirected to the file '$log_file'\n";
|
||||
|
||||
open(STDOUT, "> $log_file") || die "Can't redirect stdout";
|
||||
open(STDERR, ">&STDOUT") || die "Can't dup stdout";
|
||||
select(STDERR); $| = 1; # make unbuffered
|
||||
select(STDOUT); $| = 1; # make unbuffered
|
||||
|
||||
MacPerl::SetFileInfo("CWIE", "TEXT", $log_file);
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ActivateApplication
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub ActivateApplication($)
|
||||
{
|
||||
my ($appSignature) = @_;
|
||||
my ($psi, $found);
|
||||
my ($appPSN);
|
||||
|
||||
$found = 0;
|
||||
|
||||
foreach $psi (values(%Process))
|
||||
{
|
||||
if ($psi->processSignature() eq $appSignature)
|
||||
{
|
||||
$appPSN = $psi->processNumber();
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found == 0 || SameProcess($appPSN, GetFrontProcess()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetFrontProcess($appPSN);
|
||||
|
||||
while (GetFrontProcess() != $appPSN)
|
||||
{
|
||||
WaitNextEvent();
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// IsProcessRunning
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub IsProcessRunning($)
|
||||
{
|
||||
my($processName, $psn, $psi) = @_;
|
||||
while ( ($psn, $psi) = each(%Process) ) {
|
||||
if ($psi->processName eq $processName) { return 1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Scott Collins <scc@netscape.com>, Simon Fraser <sfraser@netscape.com>, Chris Yeh <cyeh@netscape.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
BuildMozillaDebug.pl (et al), BuildList.pm, CodeWarriorLib (an AppleScript library)
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is Mozilla Communicator client code, released
|
||||
March 31, 1998.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
=cut
|
||||
272
mozilla/build/mac/build_scripts/Moz/Prefs.pm
Normal file
272
mozilla/build/mac/build_scripts/Moz/Prefs.pm
Normal file
@@ -0,0 +1,272 @@
|
||||
|
||||
package Moz::Prefs;
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
# Package that attempts to read a file from the Preferences folder,
|
||||
# and get build settings out of it
|
||||
|
||||
use strict;
|
||||
|
||||
use Exporter;
|
||||
use File::Path;
|
||||
|
||||
use Mac::Files;
|
||||
|
||||
use vars qw(@ISA @EXPORT);
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(ReadMozUserPrefs);
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# GetPrefsFolder
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub GetPrefsFolder()
|
||||
{
|
||||
my($prefs_folder) = FindFolder(kOnSystemDisk, kPreferencesFolderType, 1);
|
||||
return $prefs_folder.":Mozilla build prefs";
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# SetArrayValue
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub SetArrayValue($$$)
|
||||
{
|
||||
my($array_ref, $index1, $index2) = @_;
|
||||
|
||||
my($index);
|
||||
foreach $index (@$array_ref)
|
||||
{
|
||||
if ($index->[0] eq $index1)
|
||||
{
|
||||
$index->[1] = $index2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# WriteDefaultPrefsFile
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub WriteDefaultPrefsFile($)
|
||||
{
|
||||
my($file_path) = @_;
|
||||
|
||||
my($file_contents);
|
||||
$file_contents = <<'EOS';
|
||||
% You can use this file to customize the Mozilla build system.
|
||||
% The following kinds of lines are allowable:
|
||||
% Comment lines, which start with a '%' in the first column
|
||||
% Lines which modify the default build settings. For the list of flags,
|
||||
% see MozBuildFlags.pm. Examples are:
|
||||
%
|
||||
% build pull 0 % don't pull
|
||||
% options mng 1 % turn mng on
|
||||
%
|
||||
% Line containing the special 'buildfrom' flag, which specifies
|
||||
% where to start the build. Example:
|
||||
%
|
||||
% buildfrom nglayout % where to start the build
|
||||
%
|
||||
% Lines which specify the location of the files used to store paths
|
||||
% to the CodeWarrior IDE, and the MacCVS Pro session file. Note quoting
|
||||
% of paths containing whitespace. Examples:
|
||||
%
|
||||
% filepath idepath ::codewarrior.txt
|
||||
% filepath sessionpath ":Some folder:MacCVS session path.txt"
|
||||
%
|
||||
% Lines which modify the build settings like %main::DEBUG.
|
||||
% Any lines which do not match either of the above are assumed
|
||||
% to set variables on $main::. Examples:
|
||||
%
|
||||
% MOZILLA_OFFICIAL 1
|
||||
%
|
||||
EOS
|
||||
|
||||
$file_contents =~ s/%/#/g;
|
||||
|
||||
local(*PREFS_FILE);
|
||||
|
||||
open(PREFS_FILE, "> $file_path") || die "Could not write default prefs file\n";
|
||||
print PREFS_FILE ($file_contents);
|
||||
close(PREFS_FILE);
|
||||
|
||||
MacPerl::SetFileInfo("McPL", "TEXT", $file_path);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# HandlePrefSet
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub HandlePrefSet($$$$)
|
||||
{
|
||||
my($flags, $name, $value, $desc) = @_;
|
||||
|
||||
if (SetArrayValue($flags, $name, $value)) {
|
||||
print "Prefs set $desc flag '$name' to '$value'\n";
|
||||
} else {
|
||||
die "$desc setting '$name' is not a valid option\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# HandleBuildFromPref
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
sub HandleBuildFromPref($$)
|
||||
{
|
||||
my($build_array, $name) = @_;
|
||||
|
||||
my($setting) = 0;
|
||||
my($index);
|
||||
foreach $index (@$build_array)
|
||||
{
|
||||
if ($index->[0] eq $name) {
|
||||
$setting = 1;
|
||||
}
|
||||
|
||||
$index->[1] = $setting;
|
||||
}
|
||||
|
||||
if ($setting == 1) {
|
||||
print "Building from $name onwards, as specified by prefs\n";
|
||||
} else {
|
||||
printf "Failed to find buildfrom setting '$name'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# ReadPrefsFile
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub ReadPrefsFile($$$$$)
|
||||
{
|
||||
my($file_path, $build_flags, $options_flags, $filepath_flags, $create_if_missing) = @_;
|
||||
|
||||
local(*PREFS_FILE);
|
||||
|
||||
if (open(PREFS_FILE, "< $file_path"))
|
||||
{
|
||||
print "Reading build prefs from '$file_path'\n";
|
||||
|
||||
while (<PREFS_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
if ($line =~ /^\#/ || $line =~ /^\s*$/) { # ignore comments and empty lines
|
||||
next;
|
||||
}
|
||||
|
||||
if (($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\"(.+)\"(\s+#.+)?/) ||
|
||||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+\'(.+)\'(\s+#.+)?/) ||
|
||||
($line =~ /^\s*([^#\s]+)\s+([^#\s]+)\s+([^#\s]+)(\s+#.+)?/))
|
||||
{
|
||||
my($array_name) = $1;
|
||||
my($option_name) = $2;
|
||||
my($option_value) = $3;
|
||||
|
||||
# print "Read '$array_name' '$option_name' '$option_value'\n";
|
||||
|
||||
if ($array_name eq "build")
|
||||
{
|
||||
HandlePrefSet($build_flags, $option_name, $option_value, "Build");
|
||||
}
|
||||
elsif ($array_name eq "options")
|
||||
{
|
||||
HandlePrefSet($options_flags, $option_name, $option_value, "Options");
|
||||
}
|
||||
elsif ($array_name eq "filepath" && $option_name && $option_value)
|
||||
{
|
||||
HandlePrefSet($filepath_flags, $option_name, $option_value, "Filepath");
|
||||
}
|
||||
else
|
||||
{
|
||||
print "Unknown pref option at $line\n";
|
||||
}
|
||||
}
|
||||
elsif ($line =~ /^\s*buildfrom\s+([^#\s]+)(\s+#.+)?/)
|
||||
{
|
||||
my($build_start) = $1;
|
||||
HandleBuildFromPref($build_flags, $build_start);
|
||||
}
|
||||
elsif ($line =~ /^\s*([^#\s]+)\s+([^#\s]+)(\s+#.+)?/)
|
||||
{
|
||||
my($build_var) = $1;
|
||||
my($var_setting) = $2;
|
||||
|
||||
print "Setting \$main::$build_var to $var_setting\n";
|
||||
eval "\$main::$build_var = \"$var_setting\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "Unrecognized input line at $line\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close(PREFS_FILE);
|
||||
}
|
||||
elsif ($create_if_missing)
|
||||
{
|
||||
print "No prefs file found at $file_path; using defaults\n";
|
||||
|
||||
my($folder_path) = $file_path;
|
||||
$folder_path =~ s/[^:]+$//;
|
||||
mkpath($folder_path);
|
||||
WriteDefaultPrefsFile($file_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# ReadMozUserPrefs
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
sub ReadMozUserPrefs($$$$)
|
||||
{
|
||||
my($prefs_file_name, $build_flags, $options_flags, $filepath_flags) = @_;
|
||||
|
||||
if ($prefs_file_name eq "") { return; }
|
||||
|
||||
# if local prefs exist, just use those. Othewise, look in the prefs folder
|
||||
if (-e $prefs_file_name)
|
||||
{
|
||||
# read local prefs
|
||||
ReadPrefsFile($prefs_file_name, $build_flags, $options_flags, $filepath_flags, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
# first read prefs folder prefs
|
||||
my($prefs_path) = GetPrefsFolder();
|
||||
$prefs_path .= ":$prefs_file_name";
|
||||
|
||||
ReadPrefsFile($prefs_path, $build_flags, $options_flags, $filepath_flags, 1);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
932
mozilla/build/mac/build_scripts/Moz/ProjectXML.pm
Normal file
932
mozilla/build/mac/build_scripts/Moz/ProjectXML.pm
Normal file
@@ -0,0 +1,932 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Simon Fraser <sfraser@netscape.com>
|
||||
#
|
||||
|
||||
package Moz::ProjectXML;
|
||||
|
||||
require 5.004;
|
||||
require Exporter;
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
|
||||
use Cwd;
|
||||
use XML::DOM;
|
||||
|
||||
use vars qw(@ISA @EXPORT);
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
ParseXMLDocument
|
||||
DisposeXMLDocument
|
||||
WriteXMLDocument
|
||||
CleanupPro5XML
|
||||
GetTargetsList
|
||||
CloneTarget
|
||||
SetAsSharedLibraryTarget
|
||||
SetAsStaticLibraryTarget
|
||||
AddTarget
|
||||
RemoveTarget
|
||||
GetTargetSetting
|
||||
SetTargetSetting
|
||||
getChildElementTextContents
|
||||
);
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# A module for reading, manipulating, and writing XML-format CodeWarrior project files.
|
||||
#
|
||||
# Sample usage:
|
||||
#
|
||||
# use ProjectXML;
|
||||
#
|
||||
# my $doc = ProjectXML::ParseXMLDocument("Test.mcp.xml");
|
||||
# ProjectXML::CloneTarget($doc, "Test.shlb", "Test.lib");
|
||||
# ProjectXML::SetAsStaticLibraryTarget($doc, "Test.lib", "TestOutput.lib");
|
||||
# ProjectXML::WriteXMLDocument($doc, "Test_out.xml");
|
||||
# ProjectXML::DisposeXMLDocument($doc);
|
||||
#
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// ParseXMLDocument
|
||||
#// Note that the caller must call DisposeXMLDocument on the returned doc
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub ParseXMLDocument($)
|
||||
{
|
||||
my($doc_path) = @_;
|
||||
|
||||
my $parser = new XML::DOM::Parser(ErrorContext => 2);
|
||||
my $doc = $parser->parsefile($doc_path);
|
||||
|
||||
return $doc;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// DisposeXMLDocument
|
||||
#// Needed to avoid memory leaks - cleanup circular references for garbage collection
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub DisposeXMLDocument($)
|
||||
{
|
||||
my($doc) = @_;
|
||||
|
||||
$doc->dispose();
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// WriteXMLDocument
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
|
||||
sub _pro5_tag_compression($$)
|
||||
{
|
||||
return 1; # Pro 5 is broken and can't import XML with <foo/> style tags
|
||||
}
|
||||
|
||||
sub _pro6plus_tag_compression($$)
|
||||
{
|
||||
return 0; # Pro 6 can deal with empty XML tags like <foo/>
|
||||
}
|
||||
|
||||
sub WriteXMLDocument($$$)
|
||||
{
|
||||
my($doc, $file_path, $ide_version) = @_;
|
||||
|
||||
if ($ide_version eq "4.0")
|
||||
{
|
||||
XML::DOM::setTagCompression(\&_pro5_tag_compression);
|
||||
}
|
||||
else
|
||||
{
|
||||
XML::DOM::setTagCompression(\&_pro6plus_tag_compression);
|
||||
}
|
||||
|
||||
$doc->printToFile($file_path);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// CleanupPro5XML
|
||||
#// XML Projects exported by Pro 5 contain garbage data under the MWMerge_MacOS_skipResources
|
||||
#// setting. This routine cleans this up, saving the result to a new file
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub CleanupPro5XML($$)
|
||||
{
|
||||
my($xml_path, $out_path) = @_;
|
||||
|
||||
local(*XML_FILE);
|
||||
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
|
||||
|
||||
local(*CLEANED_FILE);
|
||||
open(CLEANED_FILE, "> $out_path") || die "Error: failed to open file $out_path for writing\n";
|
||||
|
||||
my $in_skip_resources_settings = 0;
|
||||
|
||||
while(<XML_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
|
||||
if ($line =~ /^<\?codewarrior/) # is processing inst line
|
||||
{
|
||||
my $test_line = $line;
|
||||
chomp($test_line);
|
||||
|
||||
my $out_line = $test_line;
|
||||
if ($test_line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
|
||||
{
|
||||
my $export_version = $1;
|
||||
my $ide_version = $2;
|
||||
|
||||
$ide_version = "4.0_mozilla"; # pseudo IDE version so we know we touched it
|
||||
$out_line = "<?codewarrior exportversion=\"".$export_version."\" ideversion=\"".$ide_version."\"?>";
|
||||
}
|
||||
|
||||
print CLEANED_FILE "$out_line\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($line =~ /MWMerge_MacOS_skipResources/)
|
||||
{
|
||||
$in_skip_resources_settings = 1;
|
||||
print CLEANED_FILE "$line";
|
||||
}
|
||||
elsif($in_skip_resources_settings && $line =~ /<!-- Settings for/)
|
||||
{
|
||||
# leaving bad settings lines. Write closing tag
|
||||
print CLEANED_FILE " <!-- Corrupted setting entries removed by script -->\n";
|
||||
print CLEANED_FILE " </SETTING>\n\n";
|
||||
|
||||
print CLEANED_FILE "$line";
|
||||
|
||||
$in_skip_resources_settings = 0;
|
||||
}
|
||||
elsif (!$in_skip_resources_settings)
|
||||
{
|
||||
print CLEANED_FILE "$line";
|
||||
}
|
||||
}
|
||||
|
||||
close(XML_FILE);
|
||||
close(CLEANED_FILE);
|
||||
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# SniffProjectXMLIDEVersion
|
||||
#
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
sub SniffProjectXMLIDEVersion($)
|
||||
{
|
||||
my($xml_path) = @_;
|
||||
|
||||
my $found_version = "";
|
||||
|
||||
local(*XML_FILE);
|
||||
open(XML_FILE, "< $xml_path") || die "Error: failed to open file $xml_path\n";
|
||||
|
||||
while(<XML_FILE>)
|
||||
{
|
||||
my($line) = $_;
|
||||
chomp($line);
|
||||
|
||||
if ($line =~ /^<\?codewarrior/) # is processing inst line
|
||||
{
|
||||
unless ($line =~ /^<\?codewarrior\s+exportversion=\"(.+)\"\s+ideversion=\"(.+)\"\s*\?>$/)
|
||||
{
|
||||
die "Error: Failed to find ideversion in $xml_path in line $line\n";
|
||||
}
|
||||
|
||||
my $export_version = $1;
|
||||
my $ide_version = $2;
|
||||
|
||||
$found_version = $ide_version;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
close(XML_FILE);
|
||||
|
||||
return $found_version;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetTargetsList
|
||||
#// Returns an array of target names
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetTargetsList($)
|
||||
{
|
||||
my($doc) = @_;
|
||||
|
||||
my $nodes = $doc->getElementsByTagName("TARGET");
|
||||
my $n = $nodes->getLength;
|
||||
|
||||
my @target_names;
|
||||
|
||||
for (my $i = 0; $i < $n; $i++)
|
||||
{
|
||||
my ($node) = $nodes->item($i);
|
||||
|
||||
my($target_name) = getChildElementTextContents($node, "NAME");
|
||||
push(@target_names, $target_name);
|
||||
}
|
||||
|
||||
return @target_names;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// CloneTarget
|
||||
#// Clone the named target, renaming it to 'new_name'
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub CloneTarget($$$)
|
||||
{
|
||||
my($doc, $target_name, $new_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
|
||||
# clone here
|
||||
my $target_clone = $target_node->cloneNode(1); # deep clone
|
||||
|
||||
# -- munge target settings --
|
||||
|
||||
# set the target name field
|
||||
setChildElementTextContents($doc, $target_clone, "NAME", $new_name);
|
||||
|
||||
# set the targetname pref
|
||||
setTargetNodeSetting($doc, $target_clone, "Targetname", $new_name);
|
||||
|
||||
# -- insert new target subtree --
|
||||
|
||||
my $target_list = $target_node->getParentNode();
|
||||
$target_list->appendChild($target_clone);
|
||||
|
||||
# -- now add to targetorder --
|
||||
my (@target_order_nodes) = getChildOfDocument($doc, "TARGETORDER");
|
||||
|
||||
my $target_order = @target_order_nodes[0];
|
||||
|
||||
my $new_order = $doc->createElement("ORDEREDTARGET");
|
||||
my $order_name = $doc->createElement("NAME");
|
||||
|
||||
$new_order->appendChild($order_name);
|
||||
|
||||
setChildElementTextContents($doc, $new_order, "NAME", $new_name);
|
||||
$target_order->appendChild($new_order);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SetAsSharedLibraryTarget
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SetAsSharedLibraryTarget($$$)
|
||||
{
|
||||
my($doc, $target_name, $output_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "SharedLibrary");
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1936223330"); #'shlb'
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// AddFileToTarget
|
||||
#//
|
||||
#// Add a file to the specified target(s).
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub AddFileToTarget($$$)
|
||||
{
|
||||
my($doc, $target_list, $file_name) = @_;
|
||||
|
||||
# the file must be added in 3 places:
|
||||
# 1. in <TARGET><FILELIST><FILE> (with linkage flags if necessary)
|
||||
# 2. in <TARGET><LINKORDER><FILEREF>
|
||||
# 3. in <GROUPLIST><GROUP><FILEREF>
|
||||
die "Write me\n";
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// RemoveFileFromTarget
|
||||
#//
|
||||
#// Remove a file from the specified target, removing it from the entire project
|
||||
#// if no other targets reference it.
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub RemoveFileFromTarget($$$)
|
||||
{
|
||||
my($doc, $target_node, $file_name) = @_;
|
||||
|
||||
# the file must be removed in 3 places:
|
||||
# 1. in <TARGET><FILELIST><FILE>
|
||||
# 2. in <TARGET><LINKORDER><FILEREF>
|
||||
# 3. in <GROUPLIST><GROUP><FILEREF>
|
||||
|
||||
# first, remove from <FILELIST>
|
||||
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
|
||||
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
|
||||
|
||||
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
|
||||
unless ($file_node) { return; }
|
||||
|
||||
$filelist_node->removeChild($file_node);
|
||||
|
||||
# next, remove from <LINKORDER>
|
||||
my $linkorder_node = getFirstChildElement($target_node, "LINKORDER");
|
||||
unless ($linkorder_node) { die "Error: failed to find LINKORDER node\n"; }
|
||||
|
||||
my $fileref_node = getChildNodeByGrandchildContents($doc, $linkorder_node, "FILEREF", "PATH", $file_name);
|
||||
unless ($fileref_node) { die "Error: link order node for file $file_name not found\n"; }
|
||||
|
||||
$linkorder_node->removeChild($fileref_node);
|
||||
|
||||
# last, remove from <GROUPLIST>
|
||||
# <GROUPLIST> is cross-target, so we have to be careful here.
|
||||
my $grouplist_node = getChildOfDocument($doc, "GROUPLIST");
|
||||
unless ($grouplist_node) { die "Error: failed to find GROUPLIST node\n"; }
|
||||
|
||||
# if the file isn't in any other targets, remove it from the groups
|
||||
if (!GetFileInUse($doc, $file_name))
|
||||
{
|
||||
print "File $file_name is in no other targest. Removing from project\n";
|
||||
|
||||
my @group_nodes;
|
||||
getChildElementsOfType($doc, $grouplist_node, "GROUP", \@group_nodes);
|
||||
my $group_node;
|
||||
foreach $group_node (@group_nodes)
|
||||
{
|
||||
my @fileref_nodes;
|
||||
getChildElementsOfType($doc, $group_node, "FILEREF", \@fileref_nodes);
|
||||
|
||||
my $fileref_node;
|
||||
foreach $fileref_node (@fileref_nodes)
|
||||
{
|
||||
my $path_name = getChildElementTextContents($fileref_node, "PATH");
|
||||
if ($path_name eq $file_name)
|
||||
{
|
||||
print "Removing $file_name from project group list\n";
|
||||
$group_node->removeChild($fileref_node);
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# can a file appear in more than one group?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SetAsStaticLibraryTarget
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SetAsStaticLibraryTarget($$$)
|
||||
{
|
||||
my($doc, $target_name, $output_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_type", "Library");
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_filetype", "1061109567"); #'????'
|
||||
setTargetNodeSetting($doc, $target_node, "MWProject_PPC_outfile", $output_name);
|
||||
|
||||
# static targets don't need any library linkage, so we can remove linkage
|
||||
# with all .shlb and .Lib files.
|
||||
|
||||
my(@obsolete_files) = ("NSStdLibStubs", "InterfacesStubs", "InterfaceLib", "InternetConfigLib");
|
||||
|
||||
print " Removing libraries etc. from target\n";
|
||||
|
||||
# get all files in target
|
||||
my @target_files = GetTargetFilesList($doc, $target_name);
|
||||
my $target_file;
|
||||
foreach $target_file (@target_files)
|
||||
{
|
||||
if ($target_file =~ /(\.shlb|\.lib|\.Lib|\.o|\.exp)$/)
|
||||
{
|
||||
RemoveFileFromTarget($doc, $target_node, $target_file);
|
||||
}
|
||||
}
|
||||
|
||||
print " Removing stub libraries from target\n";
|
||||
|
||||
# then remove files with known names
|
||||
my $obs_file;
|
||||
foreach $obs_file (@obsolete_files)
|
||||
{
|
||||
RemoveFileFromTarget($doc, $target_node, $obs_file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// AddTarget
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub AddTarget($$)
|
||||
{
|
||||
my($doc, $target_name) = @_;
|
||||
|
||||
die "Write me\n";
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// RemoveTarget
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub RemoveTarget($$)
|
||||
{
|
||||
my($doc, $target_name) = @_;
|
||||
|
||||
die "Write me\n";
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetTargetSetting
|
||||
#// Get the value for the specified setting in the specified target
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetTargetSetting($$$)
|
||||
{
|
||||
my($doc, $target_name, $setting_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
return getTargetNodeSetting($target_node, "VALUE");
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// SetTargetSetting
|
||||
#// Set the value for the specified setting in the specified target
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub SetTargetSetting($$$$)
|
||||
{
|
||||
my($doc, $target_name, $setting_name, $new_value) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
setTargetNodeSetting($doc, $target_node, "VALUE", $new_value);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetTargetFilesList
|
||||
#// Return an array of the files in the target (in filelist order)
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetTargetFilesList($$)
|
||||
{
|
||||
my($doc, $target_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
|
||||
my @files_list;
|
||||
|
||||
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
|
||||
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
|
||||
|
||||
my @file_nodes;
|
||||
getChildElementsOfType($doc, $filelist_node, "FILE", \@file_nodes);
|
||||
|
||||
my $node;
|
||||
foreach $node (@file_nodes)
|
||||
{
|
||||
my $file_name = getChildElementTextContents($node, "PATH");
|
||||
push(@files_list, $file_name);
|
||||
}
|
||||
|
||||
return @files_list;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// FileIsInTarget
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub FileIsInTarget($$$)
|
||||
{
|
||||
my($doc, $file_name, $target_name) = @_;
|
||||
|
||||
my $target_node = getTargetNode($doc, $target_name);
|
||||
unless ($target_node) { die "Error: no target found called $target_name\n"; }
|
||||
|
||||
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
|
||||
if ($file_node) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetFileTargetsList
|
||||
#// Return an array of the targets that a file is in (expensive)
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetFileTargetsList($$)
|
||||
{
|
||||
my ($doc, $file_name) = @_;
|
||||
|
||||
my @target_list;
|
||||
|
||||
my @targets = GetTargetsList($doc);
|
||||
my $target;
|
||||
|
||||
foreach $target (@targets)
|
||||
{
|
||||
if (FileIsInTarget($doc, $file_name, $target))
|
||||
{
|
||||
push(@target_list, $target);
|
||||
}
|
||||
}
|
||||
|
||||
return @target_list;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetTargetFileNode
|
||||
#//
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetTargetFileNode($$$)
|
||||
{
|
||||
my($doc, $target_node, $file_name) = @_;
|
||||
|
||||
my $filelist_node = getFirstChildElement($target_node, "FILELIST");
|
||||
unless ($filelist_node) { die "Error: failed to find FILELIST node\n"; }
|
||||
|
||||
my $file_node = getChildNodeByGrandchildContents($doc, $filelist_node, "FILE", "PATH", $file_name);
|
||||
|
||||
return $file_node;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// GetFileInUse
|
||||
#// Return true if the file is used by any target
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub GetFileInUse($$)
|
||||
{
|
||||
my($doc, $file_name) = @_;
|
||||
|
||||
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
|
||||
|
||||
my $target_node = $targetlist_node->getFirstChild();
|
||||
|
||||
while ($target_node)
|
||||
{
|
||||
if ($target_node->getNodeTypeName eq "ELEMENT_NODE" &&
|
||||
$target_node->getTagName() eq "TARGET")
|
||||
{
|
||||
# if this is a target node
|
||||
my $file_node = GetTargetFileNode($doc, $target_node, $file_name);
|
||||
if ($file_node) {
|
||||
return 1; # found it
|
||||
}
|
||||
}
|
||||
|
||||
$target_node = $target_node->getNextSibling();
|
||||
}
|
||||
|
||||
# not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getChildOfDocument
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getChildOfDocument($$)
|
||||
{
|
||||
my($doc, $child_type) = @_;
|
||||
|
||||
return getFirstChildElement($doc->getDocumentElement(), $child_type);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getFirstChildElement
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getFirstChildElement($$)
|
||||
{
|
||||
my($node, $element_name) = @_;
|
||||
|
||||
my $found_node;
|
||||
|
||||
unless ($node) { die "getFirstChildElement called with empty node\n"; }
|
||||
|
||||
#look for the first "element_name" child
|
||||
|
||||
my $child_node = $node->getFirstChild();
|
||||
|
||||
while ($child_node)
|
||||
{
|
||||
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
|
||||
$child_node->getTagName() eq $element_name)
|
||||
{
|
||||
$found_node = $child_node;
|
||||
last;
|
||||
}
|
||||
|
||||
$child_node = $child_node->getNextSibling();
|
||||
}
|
||||
|
||||
return $found_node;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getChildElementsOfType
|
||||
#//
|
||||
#// Return an array of refs to child nodes of the given type
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getChildElementsOfType($$$$)
|
||||
{
|
||||
my($doc, $node, $child_type, $array_ref) = @_;
|
||||
|
||||
my $child_node = $node->getFirstChild();
|
||||
|
||||
while ($child_node)
|
||||
{
|
||||
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
|
||||
$child_node->getTagName() eq $child_type)
|
||||
{
|
||||
push(@$array_ref, $child_node);
|
||||
}
|
||||
|
||||
$child_node = $child_node->getNextSibling();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getChildElementTextContents
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Given <FOOPY><NERD>Hi!</NERD></FOOPY>, where $node is <FOOPY>,
|
||||
# returns "Hi!". If > 1 <NERD> node, returns the contents of the first.
|
||||
#
|
||||
sub getChildElementTextContents($$)
|
||||
{
|
||||
my($node, $tag_name) = @_;
|
||||
|
||||
my $first_element = getFirstChildElement($node, $tag_name);
|
||||
my $text_node = $first_element->getFirstChild();
|
||||
|
||||
my $text_contents = "";
|
||||
|
||||
# concat adjacent text nodes
|
||||
while ($text_node)
|
||||
{
|
||||
if ($text_node->getNodeTypeName() ne "TEXT_NODE")
|
||||
{
|
||||
last;
|
||||
}
|
||||
|
||||
$text_contents = $text_contents.$text_node->getData();
|
||||
$text_node = $text_node->getNextSibling();
|
||||
}
|
||||
|
||||
return $text_contents;
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// setChildElementTextContents
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub setChildElementTextContents($$$$)
|
||||
{
|
||||
my($doc, $node, $tag_name, $contents_text) = @_;
|
||||
|
||||
my $first_element = getFirstChildElement($node, $tag_name);
|
||||
my $new_text_node = $doc->createTextNode($contents_text);
|
||||
|
||||
# replace all child elements with a text element
|
||||
removeAllChildren($first_element);
|
||||
|
||||
$first_element->appendChild($new_text_node);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getChildNodeByContents
|
||||
#//
|
||||
#// Consider <foo><bar><baz>Foopy</baz></bar><bar><baz>Loopy</baz></bar></foo>
|
||||
#// This function, when called with getChildNodeByContents($foonode, "bar", "baz", "Loopy")
|
||||
#// returns the second <bar> node.
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getChildNodeByGrandchildContents($$$$$)
|
||||
{
|
||||
my($doc, $node, $child_type, $gc_type, $gc_contents) = @_; # gc = grandchild
|
||||
|
||||
my $found_node;
|
||||
my $child_node = $node->getFirstChild();
|
||||
while ($child_node)
|
||||
{
|
||||
if ($child_node->getNodeTypeName eq "ELEMENT_NODE" &&
|
||||
$child_node->getTagName() eq $child_type)
|
||||
{
|
||||
# check for a child of this node of type
|
||||
my $child_contents = getChildElementTextContents($child_node, $gc_type);
|
||||
|
||||
if ($child_contents eq $gc_contents)
|
||||
{
|
||||
$found_node = $child_node;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$child_node = $child_node->getNextSibling();
|
||||
}
|
||||
|
||||
return $found_node;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getTargetNode
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getTargetNode($$)
|
||||
{
|
||||
my($doc, $target_name) = @_;
|
||||
|
||||
my $targetlist_node = getChildOfDocument($doc, "TARGETLIST");
|
||||
return getChildNodeByGrandchildContents($doc, $targetlist_node, "TARGET", "NAME", $target_name);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getTargetNamedSettingNode
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getTargetNamedSettingNode($$)
|
||||
{
|
||||
my($target_node, $setting_name) = @_;
|
||||
|
||||
my $setting_node;
|
||||
|
||||
my $settinglist_node = getFirstChildElement($target_node, "SETTINGLIST");
|
||||
my $child_node = $settinglist_node->getFirstChild();
|
||||
|
||||
while ($child_node)
|
||||
{
|
||||
if ($child_node->getNodeTypeName ne "ELEMENT_NODE")
|
||||
{
|
||||
$child_node = $child_node->getNextSibling();
|
||||
next;
|
||||
}
|
||||
|
||||
if ($child_node->getTagName() eq "SETTING")
|
||||
{
|
||||
my $set_name = getChildElementTextContents($child_node, "NAME");
|
||||
|
||||
if ($set_name eq $setting_name)
|
||||
{
|
||||
$setting_node = $child_node;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$child_node = $child_node->getNextSibling();
|
||||
}
|
||||
|
||||
return $setting_node;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// getTargetNodeSetting
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub getTargetNodeSetting($$)
|
||||
{
|
||||
my($target_node, $setting_name) = @_;
|
||||
|
||||
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
|
||||
return getChildElementTextContents($setting_node, "VALUE");
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// setTargetNodeSetting
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub setTargetNodeSetting($$$$)
|
||||
{
|
||||
my($doc, $target_node, $setting_name, $new_value) = @_;
|
||||
|
||||
my $setting_node = getTargetNamedSettingNode($target_node, $setting_name);
|
||||
|
||||
setChildElementTextContents($doc, $setting_node, "VALUE", $new_value);
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// elementInArray
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub elementInArray($$)
|
||||
{
|
||||
my($element, $array) = @_;
|
||||
my $test;
|
||||
foreach $test (@$array)
|
||||
{
|
||||
if ($test eq $element) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// removeAllChildren
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub removeAllChildren($)
|
||||
{
|
||||
my($node) = @_;
|
||||
|
||||
my $child_node = $node->getFirstChild();
|
||||
|
||||
while ($child_node)
|
||||
{
|
||||
$node->removeChild($child_node);
|
||||
$child_node = $node->getFirstChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// dumpNodeData
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub dumpNodeData($)
|
||||
{
|
||||
my($node) = @_;
|
||||
|
||||
unless ($node) { die "Null node passed to dumpNodeData\n"; }
|
||||
|
||||
print "Dumping node $node\n";
|
||||
|
||||
my($node_type) = $node->getNodeTypeName();
|
||||
|
||||
if ($node_type eq "ELEMENT_NODE")
|
||||
{
|
||||
my($node_name) = $node->getTagName();
|
||||
print "Element $node_name\n";
|
||||
}
|
||||
elsif ($node_type eq "TEXT_NODE")
|
||||
{
|
||||
my($node_data) = $node->getData;
|
||||
# my(@node_vals) = unpack("C*", $node_data);
|
||||
print "Text '$node_data'\n"; # may contain LF chars
|
||||
}
|
||||
else
|
||||
{
|
||||
print "Node $node_type\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
#// dumpNodeTree
|
||||
#//--------------------------------------------------------------------------------------------------
|
||||
sub dumpNodeTree($)
|
||||
{
|
||||
my($node) = @_;
|
||||
|
||||
my($child_node) = $node->getFirstChild();
|
||||
|
||||
unless ($child_node) { return; }
|
||||
|
||||
# recurse
|
||||
dumpNodeData($child_node);
|
||||
|
||||
# then go through child nodes
|
||||
while ($child_node)
|
||||
{
|
||||
dumpNodeTree($child_node);
|
||||
|
||||
$child_node = $child_node->getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
90
mozilla/build/mac/build_scripts/MozillaBuildFlags.txt
Normal file
90
mozilla/build/mac/build_scripts/MozillaBuildFlags.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# These 3 lists are the 'master lists' to control what gets built.
|
||||
#
|
||||
# Ordering in these arrays is important; it has to reflect the order in
|
||||
# which the build occurs.
|
||||
#
|
||||
# Setting containing spaces must be quoted with double quotes.
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
build_flags
|
||||
all 1
|
||||
pull 0
|
||||
dist 0
|
||||
config 0
|
||||
xpidl 0
|
||||
idl 0
|
||||
stubs 0
|
||||
runtime 0
|
||||
common 0
|
||||
imglib 0
|
||||
libimg2 0
|
||||
necko 0
|
||||
security 0
|
||||
browserutils 0
|
||||
intl 0
|
||||
nglayout 0
|
||||
accessiblity 0
|
||||
editor 0
|
||||
embedding 0
|
||||
viewer 0
|
||||
xpapp 0
|
||||
extensions 0
|
||||
plugins 0
|
||||
mailnews 0
|
||||
apprunner 0
|
||||
resources 0
|
||||
|
||||
options_flags
|
||||
pull_by_date 0
|
||||
chrome_jars 1
|
||||
chrome_files 0
|
||||
use_jars 1
|
||||
transformiix 1
|
||||
mathml 0 MOZ_MATHML
|
||||
svg 0 MOZ_SVG
|
||||
# svg requires libart, which is an lgpl library. You need to pull it
|
||||
# explicitly.
|
||||
libart_lgpl 0
|
||||
mng 1
|
||||
ldap 1 MOZ_LDAP_XPCOM
|
||||
ldap_experimental 0 MOZ_LDAP_XPCOM_EXPERIMENTAL
|
||||
xmlextras 1
|
||||
wsp 0 MOZ_WSP
|
||||
inspector 1
|
||||
mailextras 1
|
||||
xptlink 0
|
||||
psm 0 MOZ_PSM
|
||||
embedding_test 1
|
||||
embedding_chrome 0
|
||||
embedding_xulprefs 0
|
||||
embedding_xulsecurity 0
|
||||
carbon 0 TARGET_CARBON
|
||||
useimg2 1 USE_IMG2
|
||||
lowmem 0 MOZ_MAC_LOWMEM
|
||||
accessible 1 ACCESSIBILITY
|
||||
bidi 1 IBMBIDI
|
||||
p3p 0
|
||||
jsd 1
|
||||
venkman 1
|
||||
moz_logging 1 MOZ_LOGGING
|
||||
chatzilla 1
|
||||
content_packs 1
|
||||
xml_rpc 1
|
||||
cview 1
|
||||
help 1
|
||||
timeline 0 MOZ_TIMELINE
|
||||
static_build 0 MOZ_STATIC_COMPONENT_LIBS
|
||||
string_debug 0 DEBUG_STRING
|
||||
string_stats 0 DEBUG_STRING_STATS
|
||||
xpctools 0 XPC_TOOLS_SUPPORT
|
||||
smime 1
|
||||
mdn 1
|
||||
print_preview 1 NS_PRINT_PREVIEW
|
||||
moz_xul 1 MOZ_XUL
|
||||
|
||||
filepath_flags
|
||||
idepath ":CodeWarrior IDE Path.txt"
|
||||
sessionpath ":Mozilla session path.txt"
|
||||
buildlogfilepath ":Build Logs:Mozilla build log.txt" # this is a path
|
||||
scriptlogfilepath ":Build Logs:Mozilla script log.txt"
|
||||
2536
mozilla/build/mac/build_scripts/MozillaBuildList.pm
Normal file
2536
mozilla/build/mac/build_scripts/MozillaBuildList.pm
Normal file
File diff suppressed because it is too large
Load Diff
22
mozilla/build/mac/build_scripts/MozillaCheckoutList.txt
Normal file
22
mozilla/build/mac/build_scripts/MozillaCheckoutList.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
# List of modules to check out. Format is
|
||||
# module, (tag), (date)
|
||||
# where tag and date are optional (non-trailing commas are required)
|
||||
#
|
||||
# Examples:
|
||||
# mozilla/nsprpub, NSPRPUB_CLIENT_TAG
|
||||
# mozilla/gc, , 10/25/2000 12:00:00
|
||||
#
|
||||
|
||||
mozilla/nsprpub, NETSCAPE_7_0_RTM
|
||||
mozilla/security/nss, NETSCAPE_7_0_RTM
|
||||
mozilla/security/manager, NETSCAPE_7_0_RTM
|
||||
mozilla/accessible, NETSCAPE_7_0_RTM
|
||||
mozilla/directory/c-sdk, NETSCAPE_7_0_RTM
|
||||
mozilla/lib/mac/Instrumentation, NETSCAPE_7_0_RTM
|
||||
mozilla/gfx2, NETSCAPE_7_0_RTM
|
||||
mozilla/modules/libpr0n, NETSCAPE_7_0_RTM
|
||||
SeaMonkeyAll, NETSCAPE_7_0_RTM
|
||||
|
||||
## You need this if you want to be able to use SVG
|
||||
## Note that this library is under the LGPL, not the MPL
|
||||
#mozilla/other-licenses/libart_lgpl
|
||||
79
mozilla/build/mac/build_scripts/PullMozilla.pl
Normal file
79
mozilla/build/mac/build_scripts/PullMozilla.pl
Normal file
@@ -0,0 +1,79 @@
|
||||
#!perl
|
||||
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Simon Fraser <sfraser@netscape.com>
|
||||
#
|
||||
|
||||
require 5.004;
|
||||
|
||||
use strict;
|
||||
|
||||
use Cwd;
|
||||
use Moz::BuildUtils;
|
||||
use Moz::BuildCore;
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# Where have the build options gone?
|
||||
#
|
||||
# The various build flags have been centralized into one place.
|
||||
# The master list of options is in MozBuildFlags.txt. However,
|
||||
# you should never need to edit that file, or this one.
|
||||
#
|
||||
# To customize what gets built, or where to start the build,
|
||||
# edit the $prefs_file_name file in
|
||||
# System Folder:Preferences:Mozilla build prefs:
|
||||
# Documentation is provided in that file.
|
||||
#-------------------------------------------------------------
|
||||
|
||||
my($prefs_file_name) = "Mozilla pull prefs";
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# hashes to hold build options
|
||||
#-------------------------------------------------------------
|
||||
my(%build);
|
||||
my(%options);
|
||||
my(%filepaths);
|
||||
my(%optiondefines);
|
||||
|
||||
# Hash of input files for this build. Eventually, there will be
|
||||
# input files for manifests, and projects too.
|
||||
my(%inputfiles) = (
|
||||
"buildflags", "MozillaBuildFlags.txt",
|
||||
"checkoutdata", "MozillaCheckoutList.txt",
|
||||
"buildprogress", "",
|
||||
"buildmodule", "MozillaBuildList.pm",
|
||||
"checkouttime", "Mozilla last checkout"
|
||||
);
|
||||
#-------------------------------------------------------------
|
||||
# end build hashes
|
||||
#-------------------------------------------------------------
|
||||
|
||||
# set the build root directory, which is the the dir above mozilla
|
||||
SetupBuildRootDir(":mozilla:build:mac:build_scripts");
|
||||
|
||||
# Set up all the flags on $main::, like DEBUG, CARBON etc.
|
||||
# Override the defaults using the preferences files.
|
||||
SetupDefaultBuildOptions(0, ":mozilla:dist:viewer:", "");
|
||||
|
||||
my($do_checkout) = 1;
|
||||
my($do_build) = 0;
|
||||
|
||||
RunBuild($do_checkout, $do_build, \%inputfiles, $prefs_file_name);
|
||||
511
mozilla/client.mak
Normal file
511
mozilla/client.mak
Normal file
@@ -0,0 +1,511 @@
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=.
|
||||
|
||||
!if !defined(MOZ_TOP)
|
||||
#enable builds from changed top level directories
|
||||
MOZ_TOP=mozilla
|
||||
!endif
|
||||
|
||||
MOZ_SRC_FLIPPED = $(MOZ_SRC:\=/)
|
||||
MOZ_DIST_FLIPPED = $(MOZ_SRC_FLIPPED)/mozilla/dist
|
||||
!ifdef MOZ_DEBUG
|
||||
MOZ_OBJDIR = WIN32_D.OBJ
|
||||
!else
|
||||
MOZ_OBJDIR = WIN32_O.OBJ
|
||||
!endif
|
||||
|
||||
#
|
||||
# Command macro defines
|
||||
#
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to do the pull.
|
||||
#//------------------------------------------------------------------------
|
||||
# uncomment these, modify branch tag, and check in to branch for milestones
|
||||
MOZ_BRANCH=NETSCAPE_7_0_RTM
|
||||
NSPR_CO_TAG=NETSCAPE_7_0_RTM
|
||||
PSM_CO_TAG=NETSCAPE_7_0_RTM
|
||||
NSS_CO_TAG=NETSCAPE_7_0_RTM
|
||||
LDAPCSDK_CO_TAG=NETSCAPE_7_0_RTM
|
||||
ACCESSIBLE_CO_TAG=NETSCAPE_7_0_RTM
|
||||
IMGLIB2_CO_TAG=NETSCAPE_7_0_RTM
|
||||
GFX2_CO_TAG=NETSCAPE_7_0_RTM
|
||||
|
||||
|
||||
!ifdef MOZ_BRANCH
|
||||
CVS_BRANCH=-r $(MOZ_BRANCH)
|
||||
!endif
|
||||
|
||||
!ifdef MOZ_DATE
|
||||
CVS_BRANCH=$(CVS_BRANCH) -D "$(MOZ_DATE)"
|
||||
!endif
|
||||
|
||||
# default pull is "quiet" but it can be overridden with MOZ_CVS_VERBOSE
|
||||
!ifndef MOZ_CVS_VERBOSE
|
||||
CVS_FLAGS=-q
|
||||
!endif
|
||||
|
||||
# honor any user-defined CVS flags
|
||||
!ifdef MOZ_CVS_FLAGS
|
||||
CVS_FLAGS=$(CVS_FLAGS) $(MOZ_CVS_FLAGS)
|
||||
!endif
|
||||
|
||||
# let's be explicit about CVSROOT... some windows cvs clients
|
||||
# are too stupid to correctly work without the -d option
|
||||
#
|
||||
# if they are too stupid, they should fail. I am
|
||||
# commenting this out because this does not work
|
||||
# under 4nt. (%'s are evaluted differently)
|
||||
#
|
||||
# If it breaks you, mail dougt@netscape.com
|
||||
# and leaf@mozilla.org
|
||||
#
|
||||
!if 0
|
||||
!if defined(CVSROOT)
|
||||
CVS_FLAGS=$(CVS_FLAGS) -d "$(CVSROOT)"
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!ifndef MOZ_CO_FLAGS
|
||||
MOZ_CO_FLAGS = -P
|
||||
!endif
|
||||
|
||||
CVSCO = cvs $(CVS_FLAGS) co $(MOZ_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull NSPR.
|
||||
#// If no NSPR_CO_TAG is specified, use the default static tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifndef NSPR_CO_FLAGS
|
||||
NSPR_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
NSPR_CO_FLAGS=$(NSPR_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
|
||||
CVSCO_NSPR = cvs $(CVS_FLAGS) co $(NSPR_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull NSS and PSM libs.
|
||||
#// If no NSS_CO_TAG or PSM_CO_TAG is specified, use the default static tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifndef NSS_CO_FLAGS
|
||||
NSS_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
NSS_CO_FLAGS=$(NSS_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_NSS = cvs $(CVS_FLAGS) co $(NSS_CO_FLAGS)
|
||||
|
||||
!ifndef PSM_CO_FLAGS
|
||||
PSM_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
PSM_CO_FLAGS=$(PSM_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_PSM = cvs $(CVS_FLAGS) co $(PSM_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull LDAP C SDK client libs.
|
||||
#// If no LDAPCSDK_CO_TAG is specified, use the default tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
|
||||
!ifndef LDAPCSDK_CO_FLAGS
|
||||
LDAPCSDK_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
LDAPCSDK_CO_FLAGS=$(LDAPCSDK_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_LDAPCSDK = cvs $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull accessibility libs.
|
||||
#// If no ACCESSIBLE_CO_TAG is specified, use the default tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifndef ACCESSIBLE_CO_FLAGS
|
||||
ACCESSIBLE_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
ACCESSIBLE_CO_FLAGS=$(ACCESSIBLE_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_ACCESSIBLE = cvs $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull new image library.
|
||||
#// If no IMGLIB2_CO_TAG is specified, use the default tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifndef IMGLIB2_CO_FLAGS
|
||||
IMGLIB2_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
IMGLIB2_CO_FLAGS=$(IMGLIB2_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_IMGLIB2 = cvs $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull new image library.
|
||||
#// If no GFX2_CO_TAG is specified, use the default tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifndef GFX2_CO_FLAGS
|
||||
GFX2_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
GFX2_CO_FLAGS=$(GFX2_CO_FLAGS) $(CVS_BRANCH)
|
||||
|
||||
CVSCO_GFX2 = cvs $(CVS_FLAGS) co $(GFX2_CO_FLAGS)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Figure out how to pull the internal libart
|
||||
#// (only pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
|
||||
#// If no MOZ_INTERNAL_LIBART_CO_TAG is specified, use the default tag
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!if defined(MOZ_SVG) && !defined(MOZ_INTERNAL_LIBART_LGPL)
|
||||
ERR_MESSAGE = ^
|
||||
You are trying to build Mozilla with SVG support (MOZ_SVG=1), but you ^
|
||||
haven not specified that mozilla/other-licenses/libart_lgpl should be ^
|
||||
pulled and built. At the moment Mozilla SVG builds need this patched ^
|
||||
version of libart. You either need to disable SVG support (unset MOZ_SVG) ^
|
||||
or enable pulling and building by setting MOZ_INTERNAL_LIBART_LGPL=1.^
|
||||
^
|
||||
If you choose to pull and build libart, note that it is only licensed^
|
||||
under the terms of the LGPL, not the MPL. (Which is why you have to opt^
|
||||
in explicitly.)
|
||||
!endif
|
||||
|
||||
!if defined(MOZ_INTERNAL_LIBART_LGPL)
|
||||
|
||||
!ifndef MOZ_INTERNAL_LIBART_CO_FLAGS
|
||||
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_CO_FLAGS)
|
||||
!endif
|
||||
|
||||
!if "$(MOZ_INTERNAL_LIBART_CO_TAG)" != ""
|
||||
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) -r $(MOZ_INTERNAL_LIBART_CO_TAG)
|
||||
!else
|
||||
MOZ_INTERNAL_LIBART_CO_FLAGS=$(MOZ_INTERNAL_LIBART_CO_FLAGS) $(CVS_BRANCH)
|
||||
!endif
|
||||
|
||||
CVSCO_MOZ_INTERNAL_LIBART = cvs $(CVS_FLAGS) co $(MOZ_INTERNAL_LIBART_CO_FLAGS)
|
||||
|
||||
!endif
|
||||
|
||||
## The master target
|
||||
############################################################
|
||||
|
||||
pull_and_build_all: pull_all build_all_dep
|
||||
|
||||
|
||||
## Rules for pulling the source from the cvs repository
|
||||
############################################################
|
||||
|
||||
pull_clobber_and_build_all: pull_all clobber_all build_all
|
||||
|
||||
!if !defined(MOZ_INTERNAL_LIBART_LGPL)
|
||||
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_seamonkey
|
||||
!else
|
||||
pull_all: pull_nspr pull_psm pull_ldapcsdk pull_accessible pull_gfx2 pull_imglib2 pull_moz_internal_libart pull_seamonkey
|
||||
!endif
|
||||
|
||||
pull_nspr: pull_clientmak
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_NSPR) mozilla/nsprpub
|
||||
|
||||
pull_nss:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_NSS) mozilla/security/coreconf
|
||||
$(CVSCO_NSS) mozilla/security/nss
|
||||
|
||||
pull_psm: pull_nss
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_PSM) mozilla/security/manager
|
||||
$(CVSCO_PSM) mozilla/security/makefile.win
|
||||
|
||||
pull_ldapcsdk:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_LDAPCSDK) mozilla/directory/c-sdk
|
||||
|
||||
pull_accessible:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_ACCESSIBLE) mozilla/accessible
|
||||
|
||||
pull_gfx2:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_GFX2) mozilla/gfx2
|
||||
|
||||
pull_imglib2:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_IMGLIB2) mozilla/modules/libpr0n
|
||||
|
||||
!if defined(MOZ_INTERNAL_LIBART_LGPL)
|
||||
pull_moz_internal_libart:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO_MOZ_INTERNAL_LIBART) mozilla/other-licenses/libart_lgpl
|
||||
!endif
|
||||
|
||||
pull_xpconnect: pull_nspr
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO) mozilla/include
|
||||
$(CVSCO) mozilla/config
|
||||
$(CVSCO) -l mozilla/js
|
||||
$(CVSCO) -l mozilla/js/src
|
||||
$(CVSCO) mozilla/js/src/fdlibm
|
||||
$(CVSCO) mozilla/js/src/xpconnect
|
||||
$(CVSCO) mozilla/modules/libreg
|
||||
$(CVSCO) mozilla/xpcom
|
||||
$(CVSCO) mozilla/string
|
||||
|
||||
# pull either layout only or seamonkey the browser
|
||||
pull_layout:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO) RaptorWin
|
||||
|
||||
pull_seamonkey: pull_clientmak
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO) SeaMonkeyAll
|
||||
|
||||
pull_clientmak:
|
||||
cd $(MOZ_SRC)\.
|
||||
$(CVSCO) mozilla/client.mak
|
||||
|
||||
############################################################
|
||||
|
||||
# nmake has to be hardcoded, or we have to depend on mozilla/config
|
||||
# being pulled already to figure out what $(NMAKE) should be.
|
||||
|
||||
clobber_all: clobber_nspr clobber_ldapcsdk clobber_psm clobber_seamonkey
|
||||
|
||||
build_all: build_nspr build_ldapcsdk build_seamonkey
|
||||
|
||||
build_all_dep: depend libs
|
||||
|
||||
distclean:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
|
||||
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
|
||||
gmake -f gmakefile.win distclean MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)
|
||||
nmake /f client.mak clobber_psm
|
||||
nmake /f client.mak clobber_seamonkey
|
||||
|
||||
clobber_ldapcsdk:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
|
||||
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) \
|
||||
SHELL=sh
|
||||
|
||||
clobber_nspr:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
|
||||
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
|
||||
|
||||
clobber_psm:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
clobber_xpconnect:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
-rd /s /q dist
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
|
||||
gmake -f gmakefile.win clobber_all MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
|
||||
nmake -f makefile.win clobber_all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
|
||||
nmake -f makefile.win clobber_all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
|
||||
nmake -f makefile.win clobber_all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
|
||||
nmake -f makefile.win clobber_all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js
|
||||
nmake -f makefile.win clobber_all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
clobber_seamonkey:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
-rd /s /q dist
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
depend: export
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
nmake -f makefile.win depend
|
||||
|
||||
depend_xpconnect:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
|
||||
nmake -f makefile.win depend
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
|
||||
nmake -f makefile.win depend
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
|
||||
nmake -f makefile.win depend
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
|
||||
nmake -f makefile.win depend
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
|
||||
nmake -f makefile.win depend
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
|
||||
nmake -f makefile.win depend
|
||||
|
||||
build_nspr:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\nsprpub
|
||||
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED)
|
||||
|
||||
build_ldapcsdk:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\directory\c-sdk
|
||||
gmake -f gmakefile.win MOZ_SRC_FLIPPED=$(MOZ_SRC_FLIPPED) SHELL=sh
|
||||
|
||||
build_psm:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\security
|
||||
nmake -f makefile.win
|
||||
|
||||
build_xpconnect: build_nspr
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\include
|
||||
nmake -f makefile.win all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\modules\libreg
|
||||
nmake -f makefile.win all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
|
||||
nmake -f makefile.win export
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\string
|
||||
nmake -f makefile.win all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\xpcom
|
||||
nmake -f makefile.win libs
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src
|
||||
nmake -f makefile.win all
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\js\src\xpconnect
|
||||
nmake -f makefile.win all
|
||||
|
||||
build_seamonkey:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
nmake -f makefile.win all
|
||||
|
||||
build_client:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win all
|
||||
|
||||
build_layout:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win all
|
||||
|
||||
build_dist:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win all
|
||||
|
||||
libs:
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
nmake -f makefile.win libs
|
||||
|
||||
export: build_nspr build_ldapcsdk
|
||||
@cd $(MOZ_SRC)\$(MOZ_TOP)\.
|
||||
nmake -f makefile.win export
|
||||
|
||||
clobber_dist:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
clobber_client:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
clobber_layout:
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake -f makefile.win clobber_all
|
||||
|
||||
browse_info::
|
||||
cd $(MOZ_SRC)\$(MOZ_TOP)
|
||||
-dir /s /b *.sbr > sbrlist.tmp
|
||||
-bscmake /Es /o mozilla.bsc @sbrlist.tmp
|
||||
-rm sbrlist.tmp
|
||||
|
||||
regchrome::
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake /f makefile.win regchrome
|
||||
|
||||
deliver::
|
||||
@cd $(MOZ_SRC)\mozilla\.
|
||||
nmake /f makefile.win splitsymbols
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Utility stuff...
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
# Verify that MOZ_SRC is set correctly
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
# Check to see if it is set at all
|
||||
!if "$(MOZ_SRC)"==""
|
||||
MOZ_SRC = $(MAKEDIR)\..
|
||||
!endif
|
||||
|
||||
#
|
||||
# create a temp file at the root and make sure it is visible from MOZ_SRC
|
||||
#
|
||||
!if [copy $(MAKEDIR)\client.mak $(MAKEDIR)\xyzzy.tmp > NUL] == 0
|
||||
!endif
|
||||
|
||||
!if !EXIST( $(MOZ_SRC)\mozilla\xyzzy.tmp )
|
||||
ERR_MESSAGE=$(ERR_MESSAGE)^
|
||||
MOZ_SRC isn't set correctly: [$(MOZ_SRC)\mozilla]!=[$(MAKEDIR)]
|
||||
!endif
|
||||
|
||||
!if [del $(MAKEDIR)\xyzzy.tmp]
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
# Verify that MOZ_BITS is set
|
||||
#//------------------------------------------------------------------------
|
||||
!if !defined(MOZ_BITS)
|
||||
ERR_MESSAGE=$(ERR_MESSAGE)^
|
||||
Environment variable MOZ_BITS isn't set.
|
||||
!endif
|
||||
|
||||
!if !defined(MOZ_TOOLS)
|
||||
ERR_MESSAGE=$(ERR_MESSAGE)^
|
||||
Environment variable MOZ_TOOLS isn't set.
|
||||
!endif
|
||||
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#// Display error
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!if "$(ERR_MESSAGE)" != ""
|
||||
ERR_MESSAGE = ^
|
||||
client.mak: ^
|
||||
$(ERR_MESSAGE) ^
|
||||
^
|
||||
client.mak: usage^
|
||||
^
|
||||
nmake -f client.mak [MOZ_BRANCH=<cvs_branch_name>] ^
|
||||
[MOZ_DATE=<cvs_date>]^
|
||||
[pull_and_build_all]^
|
||||
[pull_all]^
|
||||
[build_all]^
|
||||
^
|
||||
Environment variables:^
|
||||
^
|
||||
MOZ_BITS set to 32^
|
||||
MOZ_TOOLS set to the directory containing the needed tools ^
|
||||
|
||||
!ERROR $(ERR_MESSAGE)
|
||||
|
||||
!endif
|
||||
650
mozilla/client.mk
Normal file
650
mozilla/client.mk
Normal file
@@ -0,0 +1,650 @@
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Stephen Lamm
|
||||
|
||||
# Build the Mozilla client.
|
||||
#
|
||||
# This needs CVSROOT set to work, e.g.,
|
||||
# setenv CVSROOT :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
|
||||
# or
|
||||
# setenv CVSROOT :pserver:username%somedomain.org@cvs.mozilla.org:/cvsroot
|
||||
#
|
||||
# To checkout and build a tree,
|
||||
# 1. cvs co mozilla/client.mk
|
||||
# 2. cd mozilla
|
||||
# 3. gmake -f client.mk
|
||||
#
|
||||
# Other targets (gmake -f client.mk [targets...]),
|
||||
# checkout
|
||||
# build
|
||||
# clean (realclean is now the same as clean)
|
||||
# distclean
|
||||
#
|
||||
# See http://www.mozilla.org/build/unix.html for more information.
|
||||
#
|
||||
# Options:
|
||||
# MOZ_OBJDIR - Destination object directory
|
||||
# MOZ_CO_DATE - Date tag to use for checkout (default: none)
|
||||
# MOZ_CO_MODULE - Module to checkout (default: SeaMonkeyAll)
|
||||
# MOZ_CVS_FLAGS - Flags to pass cvs (default: -q -z3)
|
||||
# MOZ_CO_FLAGS - Flags to pass after 'cvs co' (default: -P)
|
||||
# MOZ_MAKE_FLAGS - Flags to pass to $(MAKE)
|
||||
# MOZ_CO_BRANCH - Branch tag (Deprecated. Use MOZ_CO_TAG below.)
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# Checkout Tags
|
||||
#
|
||||
# For branches, uncomment the MOZ_CO_TAG line with the proper tag,
|
||||
# and commit this file on that tag.
|
||||
MOZ_CO_TAG = NETSCAPE_7_0_RTM
|
||||
NSPR_CO_TAG = NETSCAPE_7_0_RTM
|
||||
PSM_CO_TAG = NETSCAPE_7_0_RTM
|
||||
NSS_CO_TAG = NETSCAPE_7_0_RTM
|
||||
LDAPCSDK_CO_TAG = NETSCAPE_7_0_RTM
|
||||
ACCESSIBLE_CO_TAG = NETSCAPE_7_0_RTM
|
||||
GFX2_CO_TAG = NETSCAPE_7_0_RTM
|
||||
IMGLIB2_CO_TAG = NETSCAPE_7_0_RTM
|
||||
BUILD_MODULES = all
|
||||
|
||||
#######################################################################
|
||||
# Defines
|
||||
#
|
||||
CVS = cvs
|
||||
|
||||
CWD := $(shell pwd)
|
||||
|
||||
ifeq "$(CWD)" "/"
|
||||
CWD := /.
|
||||
endif
|
||||
|
||||
ifneq (, $(wildcard client.mk))
|
||||
# Ran from mozilla directory
|
||||
ROOTDIR := $(shell dirname $(CWD))
|
||||
TOPSRCDIR := $(CWD)
|
||||
else
|
||||
# Ran from mozilla/.. directory (?)
|
||||
ROOTDIR := $(CWD)
|
||||
TOPSRCDIR := $(CWD)/mozilla
|
||||
endif
|
||||
|
||||
# on os2, TOPSRCDIR may have two forward slashes in a row, which doesn't
|
||||
# work; replace first instance with one forward slash
|
||||
TOPSRCDIR := $(shell echo "$(TOPSRCDIR)" | sed -e 's%//%/%')
|
||||
|
||||
ifndef TOPSRCDIR_MOZ
|
||||
TOPSRCDIR_MOZ=$(TOPSRCDIR)
|
||||
endif
|
||||
|
||||
# if ROOTDIR equals only drive letter (i.e. "C:"), set to "/"
|
||||
DIRNAME := $(shell echo "$(ROOTDIR)" | sed -e 's/^.://')
|
||||
ifeq ($(DIRNAME),)
|
||||
ROOTDIR := /.
|
||||
endif
|
||||
|
||||
AUTOCONF := autoconf
|
||||
MKDIR := mkdir
|
||||
SH := /bin/sh
|
||||
ifndef MAKE
|
||||
MAKE := gmake
|
||||
endif
|
||||
|
||||
CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
|
||||
ifdef CONFIG_GUESS_SCRIPT
|
||||
CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
|
||||
else
|
||||
_IS_FIRST_CHECKOUT := 1
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS
|
||||
|
||||
# Add the CVS root to CVS_FLAGS if needed
|
||||
CVS_ROOT_IN_TREE := $(shell cat $(TOPSRCDIR)/CVS/Root 2>/dev/null)
|
||||
ifneq ($(CVS_ROOT_IN_TREE),)
|
||||
ifneq ($(CVS_ROOT_IN_TREE),$(CVSROOT))
|
||||
CVS_FLAGS := -d $(CVS_ROOT_IN_TREE)
|
||||
endif
|
||||
endif
|
||||
|
||||
CVSCO = $(strip $(CVS) $(CVS_FLAGS) co $(CVS_CO_FLAGS))
|
||||
CVSCO_LOGFILE := $(ROOTDIR)/cvsco.log
|
||||
CVSCO_LOGFILE := $(shell echo $(CVSCO_LOGFILE) | sed s%//%/%)
|
||||
|
||||
ifdef MOZ_CO_TAG
|
||||
CVS_CO_FLAGS := -r $(MOZ_CO_TAG)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# Load mozconfig Options
|
||||
|
||||
# See build pages, http://www.mozilla.org/build/unix.html,
|
||||
# for how to set up mozconfig.
|
||||
MOZCONFIG_LOADER := mozilla/build/autoconf/mozconfig2client-mk
|
||||
MOZCONFIG_FINDER := mozilla/build/autoconf/mozconfig-find
|
||||
MOZCONFIG_MODULES := mozilla/build/unix/modules.mk
|
||||
run_for_side_effects := \
|
||||
$(shell cd $(ROOTDIR); \
|
||||
if test "$(_IS_FIRST_CHECKOUT)"; then \
|
||||
$(CVSCO) $(MOZCONFIG_FINDER) $(MOZCONFIG_LOADER) $(MOZCONFIG_MODULES); \
|
||||
else true; \
|
||||
fi; \
|
||||
$(MOZCONFIG_LOADER) $(TOPSRCDIR) mozilla/.mozconfig.mk > mozilla/.mozconfig.out)
|
||||
include $(TOPSRCDIR)/.mozconfig.mk
|
||||
include $(TOPSRCDIR)/build/unix/modules.mk
|
||||
|
||||
####################################
|
||||
# Options that may come from mozconfig
|
||||
|
||||
# Change CVS flags if anonymous root is requested
|
||||
ifdef MOZ_CO_USE_MIRROR
|
||||
CVS_FLAGS := -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
|
||||
endif
|
||||
|
||||
# MOZ_CVS_FLAGS - Basic CVS flags
|
||||
ifeq "$(origin MOZ_CVS_FLAGS)" "undefined"
|
||||
CVS_FLAGS := $(CVS_FLAGS) -q -z 3
|
||||
else
|
||||
CVS_FLAGS := $(MOZ_CVS_FLAGS)
|
||||
endif
|
||||
|
||||
# This option is deprecated. The best way to have client.mk pull a tag
|
||||
# is to set MOZ_CO_TAG (see above) and commit that change on the tag.
|
||||
ifdef MOZ_CO_BRANCH
|
||||
$(warning Use MOZ_CO_TAG instead of MOZ_CO_BRANCH)
|
||||
CVS_CO_FLAGS := -r $(MOZ_CO_BRANCH)
|
||||
endif
|
||||
|
||||
# MOZ_CO_FLAGS - Anything that we should use on all checkouts
|
||||
ifeq "$(origin MOZ_CO_FLAGS)" "undefined"
|
||||
CVS_CO_FLAGS := $(CVS_CO_FLAGS) -P
|
||||
else
|
||||
CVS_CO_FLAGS := $(CVS_CO_FLAGS) $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_CO_DATE
|
||||
CVS_CO_DATE_FLAGS := -D "$(MOZ_CO_DATE)"
|
||||
endif
|
||||
|
||||
ifdef MOZ_OBJDIR
|
||||
OBJDIR := $(MOZ_OBJDIR)
|
||||
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
|
||||
else
|
||||
OBJDIR := $(TOPSRCDIR)
|
||||
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for PSM
|
||||
#
|
||||
PSM_CO_MODULE= mozilla/security/manager
|
||||
PSM_CO_FLAGS := -P -A
|
||||
ifdef MOZ_CO_FLAGS
|
||||
PSM_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef PSM_CO_TAG
|
||||
PSM_CO_FLAGS := $(PSM_CO_FLAGS) -r $(PSM_CO_TAG)
|
||||
endif
|
||||
CVSCO_PSM = $(CVS) $(CVS_FLAGS) co $(PSM_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(PSM_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for NSS
|
||||
#
|
||||
NSS_CO_MODULE = mozilla/security/nss \
|
||||
mozilla/security/coreconf \
|
||||
$(NULL)
|
||||
|
||||
NSS_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
NSS_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef NSS_CO_TAG
|
||||
NSS_CO_FLAGS := $(NSS_CO_FLAGS) -r $(NSS_CO_TAG)
|
||||
endif
|
||||
# Cannot pull static tags by date
|
||||
ifeq ($(NSS_CO_TAG),NSS_CLIENT_TAG)
|
||||
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(NSS_CO_MODULE)
|
||||
else
|
||||
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSS_CO_MODULE)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for NSPR
|
||||
#
|
||||
NSPR_CO_MODULE = mozilla/nsprpub
|
||||
NSPR_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
NSPR_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef NSPR_CO_TAG
|
||||
NSPR_CO_FLAGS := $(NSPR_CO_FLAGS) -r $(NSPR_CO_TAG)
|
||||
endif
|
||||
# Cannot pull static tags by date
|
||||
ifeq ($(NSPR_CO_TAG),NSPRPUB_CLIENT_TAG)
|
||||
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(NSPR_CO_MODULE)
|
||||
else
|
||||
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSPR_CO_MODULE)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for the C LDAP SDK
|
||||
#
|
||||
LDAPCSDK_CO_MODULE = mozilla/directory/c-sdk
|
||||
LDAPCSDK_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
LDAPCSDK_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef LDAPCSDK_CO_TAG
|
||||
LDAPCSDK_CO_FLAGS := $(LDAPCSDK_CO_FLAGS) -r $(LDAPCSDK_CO_TAG)
|
||||
endif
|
||||
CVSCO_LDAPCSDK = $(CVS) $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(LDAPCSDK_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for the C LDAP SDK
|
||||
#
|
||||
ACCESSIBLE_CO_MODULE = mozilla/accessible
|
||||
ACCESSIBLE_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
ACCESSIBLE_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef ACCESSIBLE_CO_TAG
|
||||
ACCESSIBLE_CO_FLAGS := $(ACCESSIBLE_CO_FLAGS) -r $(ACCESSIBLE_CO_TAG)
|
||||
endif
|
||||
CVSCO_ACCESSIBLE = $(CVS) $(CVS_FLAGS) co $(ACCESSIBLE_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(ACCESSIBLE_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for gfx2
|
||||
#
|
||||
GFX2_CO_MODULE = mozilla/gfx2
|
||||
GFX2_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
GFX2_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef GFX2_CO_TAG
|
||||
GFX2_CO_FLAGS := $(GFX2_CO_FLAGS) -r $(GFX2_CO_TAG)
|
||||
endif
|
||||
CVSCO_GFX2 = $(CVS) $(CVS_FLAGS) co $(GFX2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(GFX2_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for new image library
|
||||
#
|
||||
IMGLIB2_CO_MODULE = mozilla/modules/libpr0n
|
||||
IMGLIB2_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
IMGLIB2_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
ifdef IMGLIB2_CO_TAG
|
||||
IMGLIB2_CO_FLAGS := $(IMGLIB2_CO_FLAGS) -r $(IMGLIB2_CO_TAG)
|
||||
endif
|
||||
CVSCO_IMGLIB2 = $(CVS) $(CVS_FLAGS) co $(IMGLIB2_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(IMGLIB2_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for standalone modules
|
||||
#
|
||||
ifneq ($(BUILD_MODULES),all)
|
||||
MOZ_CO_MODULE := $(filter-out $(NSPRPUB_DIR) security directory/c-sdk, $(BUILD_MODULE_CVS))
|
||||
MOZ_CO_MODULE += allmakefiles.sh client.mk aclocal.m4 configure configure.in
|
||||
MOZ_CO_MODULE += Makefile.in
|
||||
MOZ_CO_MODULE := $(addprefix mozilla/, $(MOZ_CO_MODULE))
|
||||
|
||||
NOSUBDIRS_MODULE := $(addprefix mozilla/, $(BUILD_MODULE_CVS_NS))
|
||||
ifneq ($(NOSUBDIRS_MODULE),)
|
||||
CVSCO_NOSUBDIRS := $(CVSCO) -l $(CVS_CO_DATE_FLAGS) $(NOSUBDIRS_MODULE)
|
||||
endif
|
||||
|
||||
ifeq (,$(filter $(NSPRPUB_DIR), $(BUILD_MODULE_CVS)))
|
||||
CVSCO_NSPR :=
|
||||
endif
|
||||
ifeq (,$(filter security security/manager, $(BUILD_MODULE_CVS)))
|
||||
CVSCO_PSM :=
|
||||
CVSCO_NSS :=
|
||||
endif
|
||||
ifeq (,$(filter directory/c-sdk, $(BUILD_MODULE_CVS)))
|
||||
CVSCO_LDAPCSDK :=
|
||||
endif
|
||||
ifeq (,$(filter accessible, $(BUILD_MODULE_CVS)))
|
||||
CVSCO_ACCESSIBLE :=
|
||||
endif
|
||||
ifeq (,$(filter gfx2, $(BUILD_MODULE_CVS)))
|
||||
CVSCO_GFX2 :=
|
||||
endif
|
||||
ifeq (,$(filter modules/libpr0n, $(BUILD_MODULE_CVS)))
|
||||
CVSCO_IMGLIB2 :=
|
||||
endif
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for SeaMonkey
|
||||
#
|
||||
ifeq ($(MOZ_CO_MODULE),)
|
||||
MOZ_CO_MODULE := SeaMonkeyAll
|
||||
endif
|
||||
CVSCO_SEAMONKEY := $(CVSCO) $(CVS_CO_DATE_FLAGS) $(MOZ_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defined for libart (pulled and built if MOZ_INTERNAL_LIBART_LGPL is set)
|
||||
#
|
||||
CVSCO_LIBART := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/other-licenses/libart_lgpl
|
||||
|
||||
ifdef MOZ_INTERNAL_LIBART_LGPL
|
||||
FASTUPDATE_LIBART := fast_update $(CVSCO_LIBART)
|
||||
CHECKOUT_LIBART := cvs_co $(CVSCO_LIBART)
|
||||
else
|
||||
CHECKOUT_LIBART := true
|
||||
FASTUPDATE_LIBART := true
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for Calendar (pulled and built if MOZ_CALENDAR is set)
|
||||
#
|
||||
CVSCO_CALENDAR := $(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/calendar
|
||||
|
||||
ifdef MOZ_CALENDAR
|
||||
FASTUPDATE_CALENDAR := fast_update $(CVSCO_CALENDAR)
|
||||
CHECKOUT_CALENDAR := cvs_co $(CVSCO_CALENDAR)
|
||||
else
|
||||
CHECKOUT_CALENDAR := true
|
||||
FASTUPDATE_CALENDAR := true
|
||||
endif
|
||||
|
||||
|
||||
# because some cygwin tools can't handle native dos-drive paths & vice-versa
|
||||
# force configure to use a relative path for --srcdir
|
||||
# need a better check for win32
|
||||
# and we need to get OBJDIR earlier
|
||||
ifdef MOZ_TOOLS
|
||||
_tmpobjdir := $(shell cygpath -u $(OBJDIR))
|
||||
_abs2rel := $(shell cygpath -w $(TOPSRCDIR)/build/unix/abs2rel.pl | sed -e 's|\\|/|g')
|
||||
_OBJ2SRCPATH := $(shell $(_abs2rel) $(TOPSRCDIR) $(_tmpobjdir))
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# Rules
|
||||
#
|
||||
|
||||
# Print out any options loaded from mozconfig.
|
||||
all build checkout clean depend distclean export libs install realclean::
|
||||
@if test -f .mozconfig.out; then \
|
||||
cat .mozconfig.out; \
|
||||
rm -f .mozconfig.out; \
|
||||
else true; \
|
||||
fi
|
||||
|
||||
ifdef _IS_FIRST_CHECKOUT
|
||||
all:: checkout build
|
||||
else
|
||||
all:: checkout alldep
|
||||
endif
|
||||
|
||||
# Windows equivalents
|
||||
pull_all: checkout
|
||||
build_all: build
|
||||
build_all_dep: alldep
|
||||
build_all_depend: alldep
|
||||
clobber clobber_all: clean
|
||||
pull_and_build_all: checkout alldep
|
||||
|
||||
# Do everything from scratch
|
||||
everything: checkout clean build
|
||||
|
||||
####################################
|
||||
# CVS checkout
|
||||
#
|
||||
checkout::
|
||||
# @: Backup the last checkout log.
|
||||
@if test -f $(CVSCO_LOGFILE) ; then \
|
||||
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo "Removing local configures" ; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
|
||||
mozilla/directory/c-sdk/configure
|
||||
endif
|
||||
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
|
||||
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
|
||||
@cd $(ROOTDIR) && $(MAKE) -f mozilla/client.mk real_checkout
|
||||
|
||||
real_checkout:
|
||||
# @: Start the checkout. Split the output to the tty and a log file. \
|
||||
# : If it fails, touch an error file because "tee" hides the error.
|
||||
@failed=.cvs-failed.tmp; rm -f $$failed*; \
|
||||
cvs_co() { echo "$$@" ; \
|
||||
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
|
||||
if test -f $$failed; then false; else true; fi; }; \
|
||||
cvs_co $(CVSCO_NSPR) && \
|
||||
cvs_co $(CVSCO_NSS) && \
|
||||
cvs_co $(CVSCO_PSM) && \
|
||||
cvs_co $(CVSCO_LDAPCSDK) && \
|
||||
cvs_co $(CVSCO_ACCESSIBLE) && \
|
||||
cvs_co $(CVSCO_GFX2) && \
|
||||
cvs_co $(CVSCO_IMGLIB2) && \
|
||||
$(CHECKOUT_CALENDAR) && \
|
||||
$(CHECKOUT_LIBART) && \
|
||||
cvs_co $(CVSCO_SEAMONKEY) && \
|
||||
cvs_co $(CVSCO_NOSUBDIRS)
|
||||
@echo "checkout finish: "`date` | tee -a $(CVSCO_LOGFILE)
|
||||
# @: Check the log for conflicts. ;
|
||||
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
|
||||
if test "$$conflicts" ; then \
|
||||
echo "$(MAKE): *** Conflicts during checkout." ;\
|
||||
echo "$$conflicts" ;\
|
||||
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
|
||||
false; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo Generating configures using $(AUTOCONF) ; \
|
||||
cd $(TOPSRCDIR) && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
|
||||
endif
|
||||
|
||||
fast-update:
|
||||
# @: Backup the last checkout log.
|
||||
@if test -f $(CVSCO_LOGFILE) ; then \
|
||||
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo "Removing local configures" ; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
|
||||
mozilla/directory/c-sdk/configure
|
||||
endif
|
||||
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
|
||||
@echo '$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk'; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(CVSCO) mozilla/client.mk mozilla/build/unix/modules.mk
|
||||
@cd $(TOPSRCDIR) && \
|
||||
$(MAKE) -f client.mk real_fast-update
|
||||
|
||||
real_fast-update:
|
||||
# @: Start the update. Split the output to the tty and a log file. \
|
||||
# : If it fails, touch an error file because "tee" hides the error.
|
||||
@failed=.fast_update-failed.tmp; rm -f $$failed*; \
|
||||
fast_update() { (config/cvsco-fast-update.pl $$@ || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
|
||||
if test -f $$failed; then false; else true; fi; }; \
|
||||
cvs_co() { echo "$$@" ; \
|
||||
("$$@" || touch $$failed) 2>&1 | tee -a $(CVSCO_LOGFILE) && \
|
||||
if test -f $$failed; then false; else true; fi; }; \
|
||||
fast_update $(CVSCO_NSPR) && \
|
||||
cd $(ROOTDIR) && \
|
||||
failed=mozilla/.fast_update-failed.tmp && \
|
||||
cvs_co $(CVSCO_NSS) && \
|
||||
failed=.fast_update-failed.tmp && \
|
||||
cd mozilla && \
|
||||
fast_update $(CVSCO_PSM) && \
|
||||
fast_update $(CVSCO_LDAPCSDK) && \
|
||||
fast_update $(CVSCO_ACCESSIBLE) && \
|
||||
fast_update $(CVSCO_GFX2) && \
|
||||
fast_update $(CVSCO_IMGLIB2) && \
|
||||
$(FASTUPDATE_CALENDAR) && \
|
||||
$(FASTUPDATE_LIBART) && \
|
||||
fast_update $(CVSCO_SEAMONKEY) && \
|
||||
fast_update $(CVSCO_NOSUBDIRS)
|
||||
@echo "fast_update finish: "`date` | tee -a $(CVSCO_LOGFILE)
|
||||
# @: Check the log for conflicts. ;
|
||||
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
|
||||
if test "$$conflicts" ; then \
|
||||
echo "$(MAKE): *** Conflicts during fast-update." ;\
|
||||
echo "$$conflicts" ;\
|
||||
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
|
||||
false; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo Generating configures using $(AUTOCONF) ; \
|
||||
cd $(TOPSRCDIR) && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# Web configure
|
||||
|
||||
WEBCONFIG_FILE := $(HOME)/.mozconfig
|
||||
|
||||
MOZCONFIG2CONFIGURATOR := build/autoconf/mozconfig2configurator
|
||||
webconfig:
|
||||
@cd $(TOPSRCDIR); \
|
||||
url=`$(MOZCONFIG2CONFIGURATOR) $(TOPSRCDIR)`; \
|
||||
echo Running mozilla with the following url: ;\
|
||||
echo ;\
|
||||
echo $$url ;\
|
||||
mozilla -remote "openURL($$url)" || \
|
||||
netscape -remote "openURL($$url)" || \
|
||||
mozilla $$url || \
|
||||
netscape $$url ;\
|
||||
echo ;\
|
||||
echo 1. Fill out the form on the browser. ;\
|
||||
echo 2. Save the results to $(WEBCONFIG_FILE)
|
||||
|
||||
#####################################################
|
||||
# First Checkout
|
||||
|
||||
ifdef _IS_FIRST_CHECKOUT
|
||||
# First time, do build target in a new process to pick up new files.
|
||||
build::
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk build
|
||||
else
|
||||
|
||||
#####################################################
|
||||
# After First Checkout
|
||||
|
||||
|
||||
####################################
|
||||
# Configure
|
||||
|
||||
CONFIG_STATUS := $(wildcard $(OBJDIR)/config.status)
|
||||
CONFIG_CACHE := $(wildcard $(OBJDIR)/config.cache)
|
||||
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
EXTRA_CONFIG_DEPS := \
|
||||
$(TOPSRCDIR)/aclocal.m4 \
|
||||
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
|
||||
$(NULL)
|
||||
|
||||
$(TOPSRCDIR)/configure: $(TOPSRCDIR)/configure.in $(EXTRA_CONFIG_DEPS)
|
||||
@echo Generating $@ using autoconf
|
||||
cd $(TOPSRCDIR); $(AUTOCONF)
|
||||
endif
|
||||
|
||||
CONFIG_STATUS_DEPS_L10N := $(wildcard $(TOPSRCDIR)/l10n/makefiles.all)
|
||||
|
||||
CONFIG_STATUS_DEPS := \
|
||||
$(TOPSRCDIR)/configure \
|
||||
$(TOPSRCDIR)/allmakefiles.sh \
|
||||
$(TOPSRCDIR)/.mozconfig.mk \
|
||||
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/directory/c-sdk/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/mailnews/makefiles) \
|
||||
$(CONFIG_STATUS_DEPS_L10N) \
|
||||
$(wildcard $(TOPSRCDIR)/themes/makefiles) \
|
||||
$(NULL)
|
||||
|
||||
# configure uses the program name to determine @srcdir@. Calling it without
|
||||
# $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
|
||||
# path of $(TOPSRCDIR).
|
||||
ifeq ($(TOPSRCDIR),$(OBJDIR))
|
||||
CONFIGURE := ./configure
|
||||
else
|
||||
CONFIGURE := $(TOPSRCDIR)/configure
|
||||
endif
|
||||
|
||||
ifdef _OBJ2SRCPATH
|
||||
CONFIGURE_ARGS := --srcdir=$(_OBJ2SRCPATH) $(CONFIGURE_ARGS)
|
||||
endif
|
||||
|
||||
$(OBJDIR)/Makefile $(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
|
||||
@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
|
||||
@echo cd $(OBJDIR);
|
||||
@echo $(CONFIGURE) $(CONFIGURE_ARGS)
|
||||
@cd $(OBJDIR) && $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
|
||||
|| ( echo "*** Fix above errors and then restart with\
|
||||
\"$(MAKE) -f client.mk build\"" && exit 1 )
|
||||
@touch $(OBJDIR)/Makefile
|
||||
|
||||
ifdef CONFIG_STATUS
|
||||
$(OBJDIR)/config/autoconf.mk: $(TOPSRCDIR)/config/autoconf.mk.in
|
||||
cd $(OBJDIR); \
|
||||
CONFIG_FILES=config/autoconf.mk ./config.status
|
||||
endif
|
||||
|
||||
|
||||
####################################
|
||||
# Depend
|
||||
|
||||
depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE) export && $(MOZ_MAKE) depend
|
||||
|
||||
####################################
|
||||
# Build it
|
||||
|
||||
build:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE)
|
||||
|
||||
####################################
|
||||
# Other targets
|
||||
|
||||
# Pass these target onto the real build system
|
||||
install export libs clean realclean distclean alldep:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE) $@
|
||||
|
||||
cleansrcdir:
|
||||
@cd $(TOPSRCDIR); \
|
||||
if [ -f webshell/embed/gtk/Makefile ]; then \
|
||||
$(MAKE) -C webshell/embed/gtk distclean; \
|
||||
fi; \
|
||||
if [ -f Makefile ]; then \
|
||||
$(MAKE) distclean ; \
|
||||
else \
|
||||
echo "Removing object files from srcdir..."; \
|
||||
rm -fr `find . -type d \( -name .deps -print -o -name CVS \
|
||||
-o -exec test ! -d {}/CVS \; \) -prune \
|
||||
-o \( -name '*.[ao]' -o -name '*.so' \) -type f -print`; \
|
||||
build/autoconf/clean-config.sh; \
|
||||
fi;
|
||||
|
||||
# (! IS_FIRST_CHECKOUT)
|
||||
endif
|
||||
|
||||
.PHONY: checkout real_checkout depend build export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything
|
||||
@@ -1,80 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
export:: private_export
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
ifdef NISCC_TEST
|
||||
DEFINES += -DNISCC_TEST
|
||||
endif
|
||||
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
# don't want the 32 in the shared library name
|
||||
SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
|
||||
|
||||
RES = $(OBJDIR)/$(LIBRARY_NAME).res
|
||||
RESNAME = $(LIBRARY_NAME).rc
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib \
|
||||
-lsqlite3 \
|
||||
$(NULL)
|
||||
else # ! NS_USE_GCC
|
||||
EXTRA_SHARED_LIBS += \
|
||||
$(DIST)/lib/sqlite3.lib \
|
||||
$(NULL)
|
||||
endif # NS_USE_GCC
|
||||
|
||||
else
|
||||
|
||||
|
||||
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
|
||||
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib/ \
|
||||
-lsqlite3 \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), BeOS)
|
||||
EXTRA_SHARED_LIBS += -lbe
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),SunOS)
|
||||
# The -R '$ORIGIN' linker option instructs this library to search for its
|
||||
# dependencies in the same directory where it resides.
|
||||
MKSHLIB += -R '$$ORIGIN'
|
||||
endif
|
||||
|
||||
endif
|
||||
@@ -1,49 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Red Hat, Inc.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Red Hat, Inc.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
MODULE = rdb
|
||||
MAPFILE = $(OBJDIR)/rdb.def
|
||||
|
||||
CSRCS = \
|
||||
rdb.c \
|
||||
$(NULL)
|
||||
|
||||
|
||||
REQUIRES = dbm nss sqlite nspr
|
||||
|
||||
LIBRARY_NAME = rdb
|
||||
@@ -1,807 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Red Hat, Inc.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Red Hat, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Relyea (rrelyea@redhat.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* This file implements PKCS 11 on top of our existing security modules
|
||||
*
|
||||
* For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
|
||||
* This implementation has two slots:
|
||||
* slot 1 is our generic crypto support. It does not require login.
|
||||
* It supports Public Key ops, and all they bulk ciphers and hashes.
|
||||
* It can also support Private Key ops for imported Private keys. It does
|
||||
* not have any token storage.
|
||||
* slot 2 is our private key support. It requires a login before use. It
|
||||
* can store Private Keys and Certs as token objects. Currently only private
|
||||
* keys and their associated Certificates are saved on the token.
|
||||
*
|
||||
* In this implementation, session objects are only visible to the session
|
||||
* that created or generated them.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#include "mcom_db.h"
|
||||
#include "errno.h"
|
||||
#ifndef DARWIN
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "sys/stat.h"
|
||||
#include "fcntl.h"
|
||||
#ifdef _WINDOWS
|
||||
#include "direct.h"
|
||||
#define usleep(x)
|
||||
#else
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the following data structures should be moved to a 'rdb.h'.
|
||||
*/
|
||||
#define STATIC_CMD_SIZE 2048
|
||||
struct RDBStr {
|
||||
DB db;
|
||||
int (*xactstart)(DB *db);
|
||||
int (*xactdone)(DB *db, PRBool abort);
|
||||
int version;
|
||||
int (*dbinitcomplete)(DB *db);
|
||||
int flags;
|
||||
int index;
|
||||
unsigned char *dataPool;
|
||||
int dataPoolSize;
|
||||
unsigned char *keyPool;
|
||||
int keyPoolSize;
|
||||
sqlite3_stmt *delStmt;
|
||||
sqlite3_stmt *getStmt;
|
||||
sqlite3_stmt *seqStmt;
|
||||
sqlite3_stmt *insertStmt;
|
||||
sqlite3_stmt *replaceStmt;
|
||||
sqlite3_stmt *beginStmt;
|
||||
sqlite3_stmt *rollbackStmt;
|
||||
sqlite3_stmt *commitStmt;
|
||||
};
|
||||
|
||||
|
||||
typedef struct RDBStr RDB;
|
||||
#define DB_RDB ((DBTYPE) 0xff)
|
||||
#define RDB_RDONLY 1
|
||||
#define RDB_RDWR 2
|
||||
#define RDB_CREATE 4
|
||||
|
||||
#define DBM_OK 0
|
||||
#define DBM_ERROR -1
|
||||
#define DBM_END 1
|
||||
|
||||
#define DEL_CMD "DELETE FROM nssTable WHERE key=$KEY;"
|
||||
#define GET_CMD "SELECT ALL * FROM nssTable WHERE key=$KEY;"
|
||||
#define SEQ_CMD "SELECT ALL * FROM nssTable LIMIT 1 OFFSET $OFFSET;"
|
||||
#define INSERT_CMD "INSERT INTO nssTable VALUES ( $KEY, $DATA );"
|
||||
#define REPLACE_CMD "REPLACE INTO nssTable VALUES ( $KEY, $DATA );"
|
||||
#define BEGIN_CMD "BEGIN EXCLUSIVE TRANSACTION;"
|
||||
#define ROLLBACK_CMD "ROLLBACK TRANSACTION;"
|
||||
#define COMMIT_CMD "COMMIT TRANSACTION;"
|
||||
#define INIT_CMD \
|
||||
"CREATE TABLE nssTable (Key PRIMARY KEY UNIQUE ON CONFLICT ABORT, Data);"
|
||||
#define IN_INIT_CMD "CREATE TABLE nssInit (dummy);"
|
||||
#define DONE_INIT_CMD "DROP TABLE nssInit;"
|
||||
#define CHECK_TABLE_CMD "SELECT ALL * FROM %s LIMIT 0;"
|
||||
|
||||
static int rdbupdateStmt(sqlite3 *db, sqlite3_stmt **stmt, const char *cmd)
|
||||
{
|
||||
sqlite3_finalize(*stmt);
|
||||
return sqlite3_prepare(db, cmd, -1, stmt, NULL);
|
||||
}
|
||||
|
||||
#define MAX_RETRIES 10
|
||||
static int rdbdone(int err, int *count)
|
||||
{
|
||||
/* allow as many rows as the database wants to give */
|
||||
if (err == SQLITE_ROW) {
|
||||
*count = 0;
|
||||
return 0;
|
||||
}
|
||||
if (err != SQLITE_BUSY) {
|
||||
return 1;
|
||||
}
|
||||
/* err == SQLITE_BUSY, Dont' retry forever in this case */
|
||||
if (++(*count) >= MAX_RETRIES) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdbmapSQLError(sqlite3 *db, int sqlerr)
|
||||
{
|
||||
if ((sqlerr == SQLITE_OK) ||
|
||||
(sqlerr == SQLITE_DONE)) {
|
||||
return DBM_OK;
|
||||
} else {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int rdbxactstart(DB *db)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int sqlerr;
|
||||
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
if (rdb->flags == RDB_RDONLY) {
|
||||
errno = EPERM;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->beginStmt, BEGIN_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = rdb->beginStmt;
|
||||
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
return rdbmapSQLError(psqlDB, sqlerr);
|
||||
}
|
||||
|
||||
int rdbxactdone(DB *db, PRBool abort)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int sqlerr;
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
if (rdb->flags == RDB_RDONLY) {
|
||||
errno = EPERM;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->rollbackStmt, ROLLBACK_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->commitStmt, COMMIT_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = abort ? rdb->rollbackStmt : rdb->commitStmt;
|
||||
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
return rdbmapSQLError(psqlDB, sqlerr);
|
||||
}
|
||||
|
||||
int rdbclose(DB *db)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
int sqlerr = SQLITE_OK;
|
||||
|
||||
sqlite3_finalize(rdb->delStmt);
|
||||
sqlite3_finalize(rdb->getStmt);
|
||||
sqlite3_finalize(rdb->seqStmt);
|
||||
sqlite3_finalize(rdb->insertStmt);
|
||||
sqlite3_finalize(rdb->replaceStmt);
|
||||
sqlite3_finalize(rdb->beginStmt);
|
||||
sqlite3_finalize(rdb->rollbackStmt);
|
||||
sqlite3_finalize(rdb->commitStmt);
|
||||
|
||||
sqlerr = sqlite3_close(psqlDB);
|
||||
/* assert sqlerr == SQLITE_OK */
|
||||
free(rdb);
|
||||
return DBM_OK;
|
||||
}
|
||||
|
||||
|
||||
int rdbdel(const DB *db, const DBT *key, uint flags)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int sqlerr;
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
if (rdb->flags == RDB_RDONLY) {
|
||||
errno = EPERM;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->delStmt, DEL_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = rdb->delStmt;
|
||||
|
||||
sqlite3_bind_blob(stmt, 1, key->data, key->size, SQLITE_STATIC);
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_bind_null(stmt,1);
|
||||
|
||||
return rdbmapSQLError(psqlDB, sqlerr);
|
||||
}
|
||||
|
||||
void
|
||||
setData(DBT *dbt,const char *blobData, int blobSize,
|
||||
unsigned char **poolPtr, int *poolSizePtr)
|
||||
{
|
||||
int size = blobSize < 2048 ? blobSize : 2048;
|
||||
|
||||
if (size > *poolSizePtr) {
|
||||
*poolPtr = realloc(*poolPtr,size);
|
||||
*poolSizePtr = size;
|
||||
}
|
||||
memcpy(*poolPtr, blobData, blobSize);
|
||||
dbt->data = *poolPtr;
|
||||
dbt->size = blobSize;
|
||||
}
|
||||
|
||||
|
||||
int rdbget(const DB *db, const DBT *key, DBT *data, uint flags)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int found = 0;
|
||||
int sqlerr;
|
||||
int ret;
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->getStmt, GET_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = rdb->getStmt;
|
||||
|
||||
sqlite3_bind_blob(stmt, 1, key->data, key->size, SQLITE_STATIC);
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
if (sqlerr == SQLITE_ROW) {
|
||||
/* we only asked for 1, this will return the last one */
|
||||
int blobSize = sqlite3_column_bytes(stmt, 1);
|
||||
const char *blobData = sqlite3_column_blob(stmt, 1);
|
||||
setData(data,blobData,blobSize, &rdb->dataPool, &rdb->dataPoolSize);
|
||||
found = 1;
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_bind_null(stmt,1);
|
||||
|
||||
ret = rdbmapSQLError(psqlDB, sqlerr);
|
||||
if ((ret == 0) && (!found)) {
|
||||
ret = DBM_END;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rdbput(const DB *db, const DBT *key, const DBT *data, uint flag)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int sqlerr;
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
if (rdb->flags == RDB_RDONLY) {
|
||||
errno = EPERM;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->insertStmt, INSERT_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->replaceStmt, REPLACE_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = (flag == R_NOOVERWRITE) ? rdb->insertStmt : rdb->replaceStmt;
|
||||
|
||||
sqlite3_bind_blob(stmt, 1, key->data, key->size, SQLITE_STATIC);
|
||||
sqlite3_bind_blob(stmt, 2, data->data, data->size, SQLITE_STATIC);
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_bind_null(stmt,1);
|
||||
sqlite3_bind_null(stmt,0);
|
||||
|
||||
return rdbmapSQLError(psqlDB, sqlerr);
|
||||
}
|
||||
|
||||
int rdbseq(const DB *db, DBT *key, DBT *data, uint flags)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
RDB *rdb = (RDB *)db;
|
||||
sqlite3_stmt *stmt;
|
||||
int retry = 0;
|
||||
int found = 0;
|
||||
int sqlerr;
|
||||
int ret;
|
||||
|
||||
if (psqlDB == NULL) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
if (flags == R_FIRST) {
|
||||
rdb->index = 0;
|
||||
} else if (flags == R_NEXT) {
|
||||
rdb->index++;
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
sqlerr = rdbupdateStmt(psqlDB, &rdb->seqStmt, SEQ_CMD);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
return DBM_ERROR;
|
||||
}
|
||||
stmt = rdb->seqStmt;
|
||||
|
||||
sqlite3_bind_int(stmt, 1, rdb->index);
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
usleep(5);
|
||||
}
|
||||
if (sqlerr == SQLITE_ROW) {
|
||||
/* we only asked for 1, this will return the last one */
|
||||
int blobSize = sqlite3_column_bytes(stmt, 0);
|
||||
const char *blobData = sqlite3_column_blob(stmt, 0);
|
||||
setData(key,blobData,blobSize, &rdb->keyPool, &rdb->keyPoolSize);
|
||||
blobSize = sqlite3_column_bytes(stmt, 1);
|
||||
blobData = sqlite3_column_blob(stmt, 1);
|
||||
setData(data,blobData,blobSize, &rdb->dataPool, &rdb->dataPoolSize);
|
||||
found = 1;
|
||||
}
|
||||
} while (!rdbdone(sqlerr,&retry));
|
||||
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_bind_null(stmt,1);
|
||||
|
||||
ret = rdbmapSQLError(psqlDB, sqlerr);
|
||||
if ((ret == 0) && (!found)) {
|
||||
ret = DBM_END;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int rdbsync(const DB *db, uint flags)
|
||||
{
|
||||
return DBM_OK;
|
||||
}
|
||||
|
||||
|
||||
int rdbfd(const DB *db)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return DBM_ERROR;
|
||||
}
|
||||
|
||||
int rdbinitcomplete(DB *db)
|
||||
{
|
||||
sqlite3 *psqlDB = (sqlite3 *)db->internal;
|
||||
int sqlerr;
|
||||
|
||||
sqlerr = sqlite3_exec(psqlDB, DONE_INIT_CMD, NULL, 0, NULL);
|
||||
/* deal with the error! */
|
||||
return DBM_OK;
|
||||
}
|
||||
|
||||
|
||||
static int grdbstatus = 0;
|
||||
int rdbstatus(void)
|
||||
{
|
||||
return grdbstatus;
|
||||
}
|
||||
|
||||
static int tableExists(sqlite3 *sqlDB, const char *tableName)
|
||||
{
|
||||
int sqlerr;
|
||||
char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
|
||||
|
||||
if (cmd == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sqlerr =
|
||||
sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
|
||||
sqlite3_free(cmd);
|
||||
|
||||
return (sqlerr == SQLITE_OK) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static int rdbIsDirectory(const char *dir)
|
||||
{
|
||||
struct stat sbuf;
|
||||
int rc;
|
||||
|
||||
rc = stat(dir,&sbuf);
|
||||
if (rc == 0) {
|
||||
return ((sbuf.st_mode & S_IFDIR) == S_IFDIR);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rdbRmFile(const char *fileName)
|
||||
{
|
||||
int rc = unlink(fileName);
|
||||
if ((rc < 0) && (errno == EPERM)) {
|
||||
chmod(fileName,0644);
|
||||
rc = unlink(fileName);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define MAX_RECURSE_LEVEL 15
|
||||
#define DIR_MODE 0755
|
||||
#ifdef _WINDOWS
|
||||
#define MKDIR(x,y) mkdir(x)
|
||||
#else
|
||||
#define MKDIR(x,y) mkdir(x,y)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a directory. Create any missing or broken
|
||||
* components we need along the way. If we already have a
|
||||
* directory, return success.
|
||||
*/
|
||||
int rdbMakedir(const char *directory, int level, int mode)
|
||||
{
|
||||
int rc;
|
||||
char *buf, *cp;
|
||||
#ifdef _WINDOWS
|
||||
char *cp1;
|
||||
#endif
|
||||
|
||||
/* prevent arbitrary stack overflow */
|
||||
if (level > MAX_RECURSE_LEVEL) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
umask(0);
|
||||
|
||||
/* just try it first */
|
||||
rc = MKDIR(directory, mode);
|
||||
if (rc != 0) {
|
||||
if (errno == EEXIST) {
|
||||
if (rdbIsDirectory(directory)) {
|
||||
/* we have a directory, use it */
|
||||
return 0;
|
||||
} else { /* must be a file */
|
||||
/* remove the file and try again */
|
||||
rc = rdbRmFile(directory);
|
||||
if (rc == 0) {
|
||||
rc = MKDIR(directory, mode);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
/* if we fail because on of the subdirectory entries was a
|
||||
* file, or one of the subdirectory entries didn't exist,
|
||||
* move back one component and try the whole thing again
|
||||
*/
|
||||
if ((errno != ENOENT) && (errno != ENOTDIR)) {
|
||||
return rc;
|
||||
}
|
||||
buf = (char *)malloc(strlen(directory)+1);
|
||||
strcpy(buf,directory);
|
||||
cp = strrchr(buf,'/');
|
||||
#ifdef _WINDOWS
|
||||
cp1 = strrchr(buf,'\\');
|
||||
if (cp1 > cp) {
|
||||
cp = cp1;
|
||||
}
|
||||
#endif
|
||||
if (cp) {
|
||||
*cp = 0;
|
||||
rc = rdbMakedir(buf,level+1, mode);
|
||||
if (rc == 0) {
|
||||
rc = MKDIR(directory, mode);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char *rdbBuildFileName(const char *appName, const char *prefix,
|
||||
const char *type, int flags)
|
||||
{
|
||||
const char *home = getenv("HOME");
|
||||
char *dir, *dbname;
|
||||
char *prefixDir = NULL;
|
||||
const char *prefixName = NULL;
|
||||
|
||||
/*
|
||||
* build up the name of our database file.
|
||||
* if create is set, make sure the directory path exists.
|
||||
*/
|
||||
if (prefix) {
|
||||
/*
|
||||
* prefix may have directory elements in it. If it does, we need
|
||||
* to break out the directory versus the actual prefix portions
|
||||
* so we can make sure the directory is created before we try to
|
||||
* create the db file.
|
||||
*/
|
||||
const char *end = strrchr(prefix,'/');
|
||||
#ifdef WINDOWS
|
||||
/* windows has two possible directory field separators. Make sure
|
||||
* we pick the one that is furthest down the string. (this code
|
||||
* will also pick the non-null value. */
|
||||
const char *end2 = strrchr(prefix,'\\');
|
||||
/* find the last directory path element */
|
||||
if (end2 > end) {
|
||||
end = end2;
|
||||
}
|
||||
#endif
|
||||
/* if the directory path exists, split the components */
|
||||
if (end) {
|
||||
prefixDir = strdup(prefix);
|
||||
if (prefixDir == NULL) return NULL;
|
||||
prefixDir[prefix-end] = 0;
|
||||
prefixName = end+1;
|
||||
} else {
|
||||
prefixName = prefix;
|
||||
}
|
||||
}
|
||||
/* build the directory portion */
|
||||
if (prefixDir) {
|
||||
dir = sqlite3_mprintf("%s/.nssdb/%s/%s",home,appName,prefixDir);
|
||||
free(prefixDir);
|
||||
} else {
|
||||
dir = sqlite3_mprintf("%s/.nssdb/%s",home,appName);
|
||||
}
|
||||
if (dir == NULL) return NULL;
|
||||
/* if we are creating, make sure the directory is created as well */
|
||||
if (flags == RDB_CREATE) {
|
||||
rdbMakedir(dir,0, DIR_MODE);
|
||||
}
|
||||
/* build the full dbname */
|
||||
dbname = sqlite3_mprintf("%s/%s%sS.sqldb",dir,prefixName? prefixName:"",type);
|
||||
sqlite3_free(dir);
|
||||
return dbname;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* rdbopen */
|
||||
DB * rdbopen(const char *appName, const char *prefix, const char *type,
|
||||
int flags)
|
||||
{
|
||||
char *name = rdbBuildFileName(appName, prefix, type, flags);
|
||||
sqlite3 *psqlDB = NULL;
|
||||
RDB *rdb = NULL;
|
||||
int sqlerr = SQLITE_OK;
|
||||
int inTransaction = 0;
|
||||
int inInit = 0;
|
||||
|
||||
if (name == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sqlerr = sqlite3_open(name,&psqlDB );
|
||||
sqlite3_free(name);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sqlerr = sqlite3_busy_timeout(psqlDB, 1000);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
sqlerr = sqlite3_exec(psqlDB, BEGIN_CMD, NULL, 0, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
inTransaction = 1;
|
||||
|
||||
if (!tableExists(psqlDB,"nssTable")) {
|
||||
if (flags != RDB_CREATE) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_exec(psqlDB, INIT_CMD, NULL, 0, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
/* hack. don't create the init on secmod db files */
|
||||
if (strcmp(type,"secmod") != 0) {
|
||||
sqlerr = sqlite3_exec(psqlDB, IN_INIT_CMD, NULL, 0, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* if the nssInit table exists, then someone else is initing the
|
||||
* nss database. We don't want to complete the open until the init
|
||||
* is completed. */
|
||||
if (tableExists(psqlDB,"nssInit")) {
|
||||
inInit = 1;
|
||||
}
|
||||
}
|
||||
rdb = (RDB *) malloc(sizeof(RDB));
|
||||
rdb->db.internal = psqlDB;
|
||||
rdb->db.type = DB_RDB;
|
||||
rdb->db.close = rdbclose;
|
||||
rdb->db.del = rdbdel;
|
||||
rdb->db.get = rdbget;
|
||||
rdb->db.put = rdbput;
|
||||
rdb->db.seq = rdbseq;
|
||||
rdb->db.sync = rdbsync;
|
||||
rdb->db.fd = rdbfd;
|
||||
rdb->version = 1;
|
||||
rdb->index = 0;
|
||||
rdb->flags = flags;
|
||||
rdb->xactstart = rdbxactstart;
|
||||
rdb->xactdone = rdbxactdone;
|
||||
rdb->dbinitcomplete = rdbinitcomplete;
|
||||
rdb->dataPool = NULL;
|
||||
rdb->dataPoolSize = 0;
|
||||
rdb->keyPool = NULL;
|
||||
rdb->keyPoolSize = 0;
|
||||
sqlerr = sqlite3_prepare(psqlDB, DEL_CMD, sizeof(DEL_CMD),
|
||||
&rdb->delStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, GET_CMD, sizeof(GET_CMD),
|
||||
&rdb->getStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, SEQ_CMD, sizeof(SEQ_CMD),
|
||||
&rdb->seqStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, INSERT_CMD, sizeof(INSERT_CMD),
|
||||
&rdb->insertStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, REPLACE_CMD, sizeof(REPLACE_CMD),
|
||||
&rdb->replaceStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, BEGIN_CMD, sizeof(BEGIN_CMD),
|
||||
&rdb->beginStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, ROLLBACK_CMD, sizeof(ROLLBACK_CMD),
|
||||
&rdb->rollbackStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_prepare(psqlDB, COMMIT_CMD, sizeof(COMMIT_CMD),
|
||||
&rdb->commitStmt, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
sqlerr = sqlite3_exec(psqlDB, COMMIT_CMD, NULL, 0, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
inTransaction = 0;
|
||||
if (inInit) {
|
||||
while (tableExists(psqlDB,"nssInit")) {
|
||||
usleep(5);
|
||||
}
|
||||
}
|
||||
return &rdb->db;
|
||||
|
||||
cleanup:
|
||||
/* lots of stuff to do */
|
||||
if (inTransaction) {
|
||||
sqlerr = sqlite3_exec(psqlDB, ROLLBACK_CMD, NULL, 0, NULL);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (rdb) {
|
||||
if (rdb->delStmt) {
|
||||
sqlite3_finalize(rdb->delStmt);
|
||||
}
|
||||
if (rdb->getStmt) {
|
||||
sqlite3_finalize(rdb->getStmt);
|
||||
}
|
||||
if (rdb->seqStmt) {
|
||||
sqlite3_finalize(rdb->seqStmt);
|
||||
}
|
||||
if (rdb->insertStmt) {
|
||||
sqlite3_finalize(rdb->insertStmt);
|
||||
}
|
||||
if (rdb->replaceStmt) {
|
||||
sqlite3_finalize(rdb->replaceStmt);
|
||||
}
|
||||
if (rdb->beginStmt) {
|
||||
sqlite3_finalize(rdb->beginStmt);
|
||||
}
|
||||
if (rdb->rollbackStmt) {
|
||||
sqlite3_finalize(rdb->rollbackStmt);
|
||||
}
|
||||
if (rdb->commitStmt) {
|
||||
sqlite3_finalize(rdb->commitStmt);
|
||||
}
|
||||
free(rdb);
|
||||
}
|
||||
if (psqlDB) {
|
||||
sqlite3_close(psqlDB);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
;+#
|
||||
;+# ***** BEGIN LICENSE BLOCK *****
|
||||
;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
;+#
|
||||
;+# The contents of this file are subject to the Mozilla Public License Version
|
||||
;+# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
;+# the License. You may obtain a copy of the License at
|
||||
;+# http://www.mozilla.org/MPL/
|
||||
;+#
|
||||
;+# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
;+# for the specific language governing rights and limitations under the
|
||||
;+# License.
|
||||
;+#
|
||||
;+# The Original Code is Red Hat, Inc.
|
||||
;+#
|
||||
;+# The Initial Developer of the Original Code is
|
||||
;+# Red Hat, Inc.
|
||||
;+# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
;+# the Initial Developer. All Rights Reserved.
|
||||
;+#
|
||||
;+# Contributor(s):
|
||||
;+#
|
||||
;+# Alternatively, the contents of this file may be used under the terms of
|
||||
;+# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
;+# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
;+# of those above. If you wish to allow use of your version of this file only
|
||||
;+# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
;+# use your version of this file under the terms of the MPL, indicate your
|
||||
;+# decision by deleting the provisions above and replace them with the notice
|
||||
;+# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
;+# the provisions above, a recipient may use your version of this file under
|
||||
;+# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
;+#
|
||||
;+# ***** END LICENSE BLOCK *****
|
||||
;+#
|
||||
;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
|
||||
;+# 1. For all unix platforms, the string ";-" means "remove this line"
|
||||
;+# 2. For all unix platforms, the string " DATA " will be removed from any
|
||||
;+# line on which it occurs.
|
||||
;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
|
||||
;+# On AIX, lines containing ";+" will be removed.
|
||||
;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
|
||||
;+# 5. For all unix platforms, after the above processing has taken place,
|
||||
;+# all characters after the first ";" on the line will be removed.
|
||||
;+# And for AIX, the first ";" will also be removed.
|
||||
;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
|
||||
;+# directives are hidden behind ";", ";+", and ";-"
|
||||
;+
|
||||
;+RDB_1.0 { # RDB 1.0
|
||||
;+ global:
|
||||
LIBRARY rdb ;-
|
||||
EXPORTS ;-
|
||||
rdbopen;
|
||||
rdbstatus;
|
||||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
@@ -1,102 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert Relyea (rrelyea@redhat.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nss.h"
|
||||
#include <winver.h>
|
||||
|
||||
#define MY_LIBNAME "rdb"
|
||||
#define MY_FILEDESCRIPTION "NSS Multiaccess Database Library"
|
||||
|
||||
#define STRINGIZE(x) #x
|
||||
#define STRINGIZE2(x) STRINGIZE(x)
|
||||
#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define MY_DEBUG_STR " (debug)"
|
||||
#define MY_FILEFLAGS_1 VS_FF_DEBUG
|
||||
#else
|
||||
#define MY_DEBUG_STR ""
|
||||
#define MY_FILEFLAGS_1 0x0L
|
||||
#endif
|
||||
#if NSS_BETA
|
||||
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
|
||||
#else
|
||||
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
|
||||
#endif
|
||||
|
||||
#ifdef WINNT
|
||||
#define MY_FILEOS VOS_NT_WINDOWS32
|
||||
#else
|
||||
#define MY_FILEOS VOS__WINDOWS32
|
||||
#endif
|
||||
|
||||
#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version-information resource
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS MY_FILEFLAGS_2
|
||||
FILEOS MY_FILEOS
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L // not used
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Mozilla\0"
|
||||
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
|
||||
VALUE "FileVersion", NSS_VERSION "\0"
|
||||
VALUE "InternalName", MY_INTERNAL_NAME "\0"
|
||||
VALUE "LegalCopyright", "Copyright \251 2005 Red Hat, Inc.\0"
|
||||
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
|
||||
VALUE "ProductName", "Network Security Services\0"
|
||||
VALUE "ProductVersion", NSS_VERSION "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -1,95 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
export:: private_export
|
||||
|
||||
# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
|
||||
# pkcs11c.c in 64-bit mode for unknown reasons. A workaround is
|
||||
# to compile it with optimizations turned on. (Bugzilla bug #63815)
|
||||
ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
|
||||
ifeq ($(USE_64),1)
|
||||
ifndef BUILD_OPT
|
||||
$(OBJDIR)/pkcs11.o: pkcs11.c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ -c -O2 $(CFLAGS) $<
|
||||
$(OBJDIR)/pkcs11c.o: pkcs11c.c
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ -c -O2 $(CFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -1,166 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "sechash.h"
|
||||
#include "secport.h"
|
||||
#include "alghmac.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#define HMAC_PAD_SIZE 64
|
||||
|
||||
struct HMACContextStr {
|
||||
void *hash;
|
||||
const SECHashObject *hashobj;
|
||||
unsigned char ipad[HMAC_PAD_SIZE];
|
||||
unsigned char opad[HMAC_PAD_SIZE];
|
||||
};
|
||||
|
||||
void
|
||||
HMAC_Destroy(HMACContext *cx)
|
||||
{
|
||||
if (cx == NULL)
|
||||
return;
|
||||
|
||||
if (cx->hash != NULL)
|
||||
cx->hashobj->destroy(cx->hash, PR_TRUE);
|
||||
PORT_ZFree(cx, sizeof(HMACContext));
|
||||
}
|
||||
|
||||
HMACContext *
|
||||
HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS)
|
||||
{
|
||||
HMACContext *cx;
|
||||
unsigned int i;
|
||||
unsigned char hashed_secret[HASH_LENGTH_MAX];
|
||||
|
||||
/* required by FIPS 198 Section 3 */
|
||||
if (isFIPS && secret_len < hash_obj->length/2) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
|
||||
if (cx == NULL)
|
||||
return NULL;
|
||||
cx->hashobj = hash_obj;
|
||||
|
||||
cx->hash = cx->hashobj->create();
|
||||
if (cx->hash == NULL)
|
||||
goto loser;
|
||||
|
||||
if (secret_len > HMAC_PAD_SIZE) {
|
||||
cx->hashobj->begin( cx->hash);
|
||||
cx->hashobj->update(cx->hash, secret, secret_len);
|
||||
PORT_Assert(cx->hashobj->length <= sizeof hashed_secret);
|
||||
cx->hashobj->end( cx->hash, hashed_secret, &secret_len,
|
||||
sizeof hashed_secret);
|
||||
if (secret_len != cx->hashobj->length)
|
||||
goto loser;
|
||||
secret = (const unsigned char *)&hashed_secret[0];
|
||||
}
|
||||
|
||||
PORT_Memset(cx->ipad, 0x36, sizeof cx->ipad);
|
||||
PORT_Memset(cx->opad, 0x5c, sizeof cx->opad);
|
||||
|
||||
/* fold secret into padding */
|
||||
for (i = 0; i < secret_len; i++) {
|
||||
cx->ipad[i] ^= secret[i];
|
||||
cx->opad[i] ^= secret[i];
|
||||
}
|
||||
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
|
||||
return cx;
|
||||
|
||||
loser:
|
||||
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
|
||||
HMAC_Destroy(cx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Begin(HMACContext *cx)
|
||||
{
|
||||
/* start inner hash */
|
||||
cx->hashobj->begin(cx->hash);
|
||||
cx->hashobj->update(cx->hash, cx->ipad, sizeof(cx->ipad));
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
|
||||
{
|
||||
cx->hashobj->update(cx->hash, data, data_len);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
|
||||
unsigned int max_result_len)
|
||||
{
|
||||
if (max_result_len < cx->hashobj->length) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
cx->hashobj->end(cx->hash, result, result_len, max_result_len);
|
||||
if (*result_len != cx->hashobj->length)
|
||||
return SECFailure;
|
||||
|
||||
cx->hashobj->begin(cx->hash);
|
||||
cx->hashobj->update(cx->hash, cx->opad, sizeof(cx->opad));
|
||||
cx->hashobj->update(cx->hash, result, *result_len);
|
||||
cx->hashobj->end(cx->hash, result, result_len, max_result_len);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
HMACContext *
|
||||
HMAC_Clone(HMACContext *cx)
|
||||
{
|
||||
HMACContext *newcx;
|
||||
|
||||
newcx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
|
||||
if (newcx == NULL)
|
||||
goto loser;
|
||||
|
||||
newcx->hashobj = cx->hashobj;
|
||||
newcx->hash = cx->hashobj->clone(cx->hash);
|
||||
if (newcx->hash == NULL)
|
||||
goto loser;
|
||||
PORT_Memcpy(newcx->ipad, cx->ipad, sizeof(cx->ipad));
|
||||
PORT_Memcpy(newcx->opad, cx->opad, sizeof(cx->opad));
|
||||
return newcx;
|
||||
|
||||
loser:
|
||||
HMAC_Destroy(newcx);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _ALGHMAC_H_
|
||||
#define _ALGHMAC_H_
|
||||
|
||||
typedef struct HMACContextStr HMACContext;
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/* destroy HMAC context */
|
||||
extern void
|
||||
HMAC_Destroy(HMACContext *cx);
|
||||
|
||||
/* create HMAC context
|
||||
* hashObj hash object from SECRawHashObjects[]
|
||||
* secret the secret with which the HMAC is performed.
|
||||
* secret_len the length of the secret.
|
||||
* isFIPS true if conforming to FIPS 198.
|
||||
*
|
||||
* NULL is returned if an error occurs.
|
||||
*/
|
||||
extern HMACContext *
|
||||
HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
|
||||
unsigned int secret_len, PRBool isFIPS);
|
||||
|
||||
/* reset HMAC for a fresh round */
|
||||
extern void
|
||||
HMAC_Begin(HMACContext *cx);
|
||||
|
||||
/* update HMAC
|
||||
* cx HMAC Context
|
||||
* data the data to perform HMAC on
|
||||
* data_len the length of the data to process
|
||||
*/
|
||||
extern void
|
||||
HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len);
|
||||
|
||||
/* Finish HMAC -- place the results within result
|
||||
* cx HMAC context
|
||||
* result buffer for resulting hmac'd data
|
||||
* result_len where the resultant hmac length is stored
|
||||
* max_result_len maximum possible length that can be stored in result
|
||||
*/
|
||||
extern SECStatus
|
||||
HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
|
||||
unsigned int max_result_len);
|
||||
|
||||
/* clone a copy of the HMAC state. this is usefult when you would
|
||||
* need to keep a running hmac but also need to extract portions
|
||||
* partway through the process.
|
||||
*/
|
||||
extern HMACContext *
|
||||
HMAC_Clone(HMACContext *cx);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
@@ -1,85 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* cdbhdl.h - certificate database handle
|
||||
* private to the certdb module
|
||||
*
|
||||
* $Id: cdbhdl.h,v 1.9 2004-04-25 15:03:16 gerv%gerv.net Exp $
|
||||
*/
|
||||
#ifndef _CDBHDL_H_
|
||||
#define _CDBHDL_H_
|
||||
|
||||
#include "nspr.h"
|
||||
#include "mcom_db.h"
|
||||
#include "pcertt.h"
|
||||
|
||||
/*
|
||||
* Handle structure for open certificate databases
|
||||
*/
|
||||
struct NSSLOWCERTCertDBHandleStr {
|
||||
DB *permCertDB;
|
||||
PZMonitor *dbMon;
|
||||
PRBool dbVerify;
|
||||
};
|
||||
|
||||
#ifdef DBM_USING_NSPR
|
||||
#define NO_RDONLY PR_RDONLY
|
||||
#define NO_RDWR PR_RDWR
|
||||
#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
|
||||
#else
|
||||
#define NO_RDONLY O_RDONLY
|
||||
#define NO_RDWR O_RDWR
|
||||
#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
|
||||
#endif
|
||||
|
||||
typedef DB * (*rdbfunc)(const char *appName, const char *prefix,
|
||||
const char *type, int flags);
|
||||
typedef int (*rdbstatusfunc)(void);
|
||||
|
||||
#define RDB_FAIL 1
|
||||
#define RDB_RETRY 2
|
||||
|
||||
DB * rdbopen(const char *appName, const char *prefix,
|
||||
const char *type, int flags, int *status);
|
||||
|
||||
DB *dbsopen (const char *dbname , int flags, int mode, DBTYPE type,
|
||||
const void * appData);
|
||||
SECStatus db_Copy(DB *dest,DB *src);
|
||||
int db_BeginTransaction(DB *db);
|
||||
int db_FinishTransaction(DB *db, PRBool abort);
|
||||
int db_InitComplete(DB *db);
|
||||
|
||||
#endif
|
||||
@@ -1,98 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
|
||||
CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
|
||||
CRYPTODIR=../freebl
|
||||
ifdef MOZILLA_SECURITY_BUILD
|
||||
CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX)
|
||||
CRYPTODIR=../crypto
|
||||
endif
|
||||
|
||||
EXTRA_LIBS += \
|
||||
$(CRYPTOLIB) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
# can't do this in manifest.mn because OS_TARGET isn't defined there.
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
# don't want the 32 in the shared library name
|
||||
SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
|
||||
|
||||
RES = $(OBJDIR)/$(LIBRARY_NAME).res
|
||||
RESNAME = $(LIBRARY_NAME).rc
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
-lnspr4 \
|
||||
$(NULL)
|
||||
else # ! NS_USE_GCC
|
||||
|
||||
EXTRA_SHARED_LIBS += \
|
||||
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
|
||||
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
|
||||
$(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
|
||||
$(NULL)
|
||||
endif # NS_USE_GCC
|
||||
|
||||
else
|
||||
|
||||
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
|
||||
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib/ \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
-lnspr4 \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),SunOS)
|
||||
# The -R '$ORIGIN' linker option instructs this library to search for its
|
||||
# dependencies in the same directory where it resides.
|
||||
MKSHLIB += -R '$$ORIGIN'
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),WINCE)
|
||||
DEFINES += -DDBM_USING_NSPR
|
||||
endif
|
||||
@@ -1,420 +0,0 @@
|
||||
/*
|
||||
* NSS utility functions
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: dbinit.c,v 1.25.8.1 2005-06-20 23:17:12 relyea%netscape.com Exp $ */
|
||||
|
||||
#include <ctype.h>
|
||||
#include "seccomon.h"
|
||||
#include "prinit.h"
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
#include "pcertt.h"
|
||||
#include "lowkeyi.h"
|
||||
#include "pcert.h"
|
||||
#include "cdbhdl.h"
|
||||
#include "pkcs11i.h"
|
||||
|
||||
#define ALWAYS_MULTIACCESS "CommonClient"
|
||||
|
||||
static char *
|
||||
sftk_certdb_name_cb(void *arg, int dbVersion)
|
||||
{
|
||||
const char *configdir = (const char *)arg;
|
||||
const char *dbver;
|
||||
char *smpname = NULL;
|
||||
char *dbname = NULL;
|
||||
|
||||
switch (dbVersion) {
|
||||
case 8:
|
||||
dbver = "8";
|
||||
break;
|
||||
case 7:
|
||||
dbver = "7";
|
||||
break;
|
||||
case 6:
|
||||
dbver = "6";
|
||||
break;
|
||||
case 5:
|
||||
dbver = "5";
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
dbver = "";
|
||||
break;
|
||||
}
|
||||
|
||||
/* make sure we return something allocated with PORT_ so we have properly
|
||||
* matched frees at the end */
|
||||
smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
|
||||
if (smpname) {
|
||||
dbname = PORT_Strdup(smpname);
|
||||
PR_smprintf_free(smpname);
|
||||
}
|
||||
return dbname;
|
||||
}
|
||||
|
||||
static char *
|
||||
sftk_keydb_name_cb(void *arg, int dbVersion)
|
||||
{
|
||||
const char *configdir = (const char *)arg;
|
||||
const char *dbver;
|
||||
char *smpname = NULL;
|
||||
char *dbname = NULL;
|
||||
|
||||
switch (dbVersion) {
|
||||
case 4:
|
||||
dbver = "4";
|
||||
break;
|
||||
case 3:
|
||||
dbver = "3";
|
||||
break;
|
||||
case 1:
|
||||
dbver = "1";
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
dbver = "";
|
||||
break;
|
||||
}
|
||||
|
||||
smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver);
|
||||
if (smpname) {
|
||||
dbname = PORT_Strdup(smpname);
|
||||
PR_smprintf_free(smpname);
|
||||
}
|
||||
return dbname;
|
||||
}
|
||||
|
||||
const char *
|
||||
sftk_EvaluateConfigDir(const char *configdir,char **appName)
|
||||
{
|
||||
#ifdef ALWAYS_MULTIACCESS
|
||||
*appName = PORT_Strdup(ALWAYS_MULTIACCESS);
|
||||
#else
|
||||
if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
|
||||
char *cdir;
|
||||
|
||||
*appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
|
||||
if (*appName == NULL) {
|
||||
return configdir;
|
||||
}
|
||||
cdir = *appName;
|
||||
while (*cdir && *cdir != ':') {
|
||||
cdir++;
|
||||
}
|
||||
if (*cdir == ':') {
|
||||
*cdir = 0;
|
||||
cdir++;
|
||||
}
|
||||
configdir = cdir;
|
||||
}
|
||||
#endif
|
||||
return configdir;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
sftk_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
|
||||
NSSLOWCERTCertDBHandle **certdbPtr)
|
||||
{
|
||||
NSSLOWCERTCertDBHandle *certdb = NULL;
|
||||
CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED;
|
||||
SECStatus rv;
|
||||
char * name = NULL;
|
||||
char * appName = NULL;
|
||||
|
||||
if (prefix == NULL) {
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
configdir = sftk_EvaluateConfigDir(configdir, &appName);
|
||||
|
||||
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
|
||||
if (name == NULL) goto loser;
|
||||
|
||||
certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
|
||||
if (certdb == NULL)
|
||||
goto loser;
|
||||
|
||||
/* fix when we get the DB in */
|
||||
rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
|
||||
sftk_certdb_name_cb, (void *)name, PR_FALSE);
|
||||
if (rv == SECSuccess) {
|
||||
crv = CKR_OK;
|
||||
*certdbPtr = certdb;
|
||||
certdb = NULL;
|
||||
}
|
||||
loser:
|
||||
if (certdb) PR_Free(certdb);
|
||||
if (name) PR_smprintf_free(name);
|
||||
if (appName) PORT_Free(appName);
|
||||
return crv;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
sftk_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
|
||||
NSSLOWKEYDBHandle **keydbPtr)
|
||||
{
|
||||
NSSLOWKEYDBHandle *keydb;
|
||||
char * name = NULL;
|
||||
char * appName = NULL;
|
||||
|
||||
if (prefix == NULL) {
|
||||
prefix = "";
|
||||
}
|
||||
configdir = sftk_EvaluateConfigDir(configdir, &appName);
|
||||
|
||||
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
|
||||
if (name == NULL)
|
||||
return CKR_HOST_MEMORY;
|
||||
keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix,
|
||||
sftk_keydb_name_cb, (void *)name);
|
||||
PR_smprintf_free(name);
|
||||
if (appName) PORT_Free(appName);
|
||||
if (keydb == NULL)
|
||||
return CKR_NETSCAPE_KEYDB_FAILED;
|
||||
*keydbPtr = keydb;
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OK there are now lots of options here, lets go through them all:
|
||||
*
|
||||
* configdir - base directory where all the cert, key, and module datbases live.
|
||||
* certPrefix - prefix added to the beginning of the cert database example: "
|
||||
* "https-server1-"
|
||||
* keyPrefix - prefix added to the beginning of the key database example: "
|
||||
* "https-server1-"
|
||||
* secmodName - name of the security module database (usually "secmod.db").
|
||||
* readOnly - Boolean: true if the databases are to be openned read only.
|
||||
* nocertdb - Don't open the cert DB and key DB's, just initialize the
|
||||
* Volatile certdb.
|
||||
* nomoddb - Don't open the security module DB, just initialize the
|
||||
* PKCS #11 module.
|
||||
* forceOpen - Continue to force initializations even if the databases cannot
|
||||
* be opened.
|
||||
*/
|
||||
CK_RV
|
||||
sftk_DBInit(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, PRBool readOnly,
|
||||
PRBool noCertDB, PRBool noKeyDB, PRBool forceOpen,
|
||||
NSSLOWCERTCertDBHandle **certdbPtr, NSSLOWKEYDBHandle **keydbPtr)
|
||||
{
|
||||
CK_RV crv = CKR_OK;
|
||||
|
||||
|
||||
if (!noCertDB) {
|
||||
crv = sftk_OpenCertDB(configdir, certPrefix, readOnly, certdbPtr);
|
||||
if (crv != CKR_OK) {
|
||||
if (!forceOpen) goto loser;
|
||||
crv = CKR_OK;
|
||||
}
|
||||
}
|
||||
if (!noKeyDB) {
|
||||
|
||||
crv = sftk_OpenKeyDB(configdir, keyPrefix, readOnly, keydbPtr);
|
||||
if (crv != CKR_OK) {
|
||||
if (!forceOpen) goto loser;
|
||||
crv = CKR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
loser:
|
||||
return crv;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sftk_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
|
||||
NSSLOWKEYDBHandle *keyHandle)
|
||||
{
|
||||
if (certHandle) {
|
||||
nsslowcert_ClosePermCertDB(certHandle);
|
||||
PORT_Free(certHandle);
|
||||
}
|
||||
|
||||
if (keyHandle) {
|
||||
nsslowkey_CloseKeyDB(keyHandle);
|
||||
}
|
||||
}
|
||||
|
||||
static int rdbmapflags(int flags);
|
||||
static rdbfunc sftk_rdbfunc = NULL;
|
||||
static rdbstatusfunc sftk_rdbstatusfunc = NULL;
|
||||
|
||||
/* NOTE: SHLIB_SUFFIX is defined on the command line */
|
||||
#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX
|
||||
|
||||
DB * rdbopen(const char *appName, const char *prefix,
|
||||
const char *type, int flags, int *status)
|
||||
{
|
||||
PRLibrary *lib;
|
||||
DB *db;
|
||||
|
||||
if (sftk_rdbfunc) {
|
||||
db = (*sftk_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
|
||||
if (!db && status && sftk_rdbstatusfunc) {
|
||||
*status = (*sftk_rdbstatusfunc)();
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
/*
|
||||
* try to open the library.
|
||||
*/
|
||||
lib = PR_LoadLibrary(RDBLIB);
|
||||
|
||||
if (!lib) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the entry points */
|
||||
sftk_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
|
||||
sftk_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
|
||||
if (sftk_rdbfunc) {
|
||||
db = (*sftk_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
|
||||
if (!db && status && sftk_rdbstatusfunc) {
|
||||
*status = (*sftk_rdbstatusfunc)();
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
/* couldn't find the entry point, unload the library and fail */
|
||||
PR_UnloadLibrary(lib);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* the following data structures are from rdb.h.
|
||||
*/
|
||||
struct RDBStr {
|
||||
DB db;
|
||||
int (*xactstart)(DB *db);
|
||||
int (*xactdone)(DB *db, PRBool abort);
|
||||
int version;
|
||||
int (*dbinitcomplete)(DB *db);
|
||||
};
|
||||
|
||||
#define DB_RDB ((DBTYPE) 0xff)
|
||||
#define RDB_RDONLY 1
|
||||
#define RDB_RDWR 2
|
||||
#define RDB_CREATE 4
|
||||
|
||||
static int
|
||||
rdbmapflags(int flags) {
|
||||
switch (flags) {
|
||||
case NO_RDONLY:
|
||||
return RDB_RDONLY;
|
||||
case NO_RDWR:
|
||||
return RDB_RDWR;
|
||||
case NO_CREATE:
|
||||
return RDB_CREATE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
db_IsRDB(DB *db)
|
||||
{
|
||||
return (PRBool) db->type == DB_RDB;
|
||||
}
|
||||
|
||||
int
|
||||
db_BeginTransaction(DB *db)
|
||||
{
|
||||
struct RDBStr *rdb = (struct RDBStr *)db;
|
||||
if (db->type != DB_RDB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rdb->xactstart(db);
|
||||
}
|
||||
|
||||
int
|
||||
db_FinishTransaction(DB *db, PRBool abort)
|
||||
{
|
||||
struct RDBStr *rdb = (struct RDBStr *)db;
|
||||
if (db->type != DB_RDB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rdb->xactdone(db, abort);
|
||||
}
|
||||
|
||||
int
|
||||
db_InitComplete(DB *db)
|
||||
{
|
||||
struct RDBStr *rdb = (struct RDBStr *)db;
|
||||
if (db->type != DB_RDB) {
|
||||
return 0;
|
||||
}
|
||||
/* we should have addes a version number to the RDBS structure. Since we
|
||||
* didn't, we detect that we have and 'extended' structure if the rdbstatus
|
||||
* func exists */
|
||||
if (!sftk_rdbstatusfunc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rdb->dbinitcomplete(db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SECStatus
|
||||
db_Copy(DB *dest,DB *src)
|
||||
{
|
||||
int ret;
|
||||
DBT key,data;
|
||||
ret = (*src->seq)(src, &key, &data, R_FIRST);
|
||||
if (ret) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
do {
|
||||
(void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
|
||||
} while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
|
||||
(void)(*dest->sync)(dest,0);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@@ -1,664 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Berkeley DB 1.85 Shim code to handle blobs.
|
||||
*
|
||||
* $Id: dbmshim.c,v 1.11 2005-03-29 18:21:18 nelsonb%netscape.com Exp $
|
||||
*/
|
||||
#include "mcom_db.h"
|
||||
#include "secitem.h"
|
||||
#include "secder.h"
|
||||
#include "prprf.h"
|
||||
#include "cdbhdl.h"
|
||||
|
||||
/* Call to SFTK_FreeSlot below */
|
||||
|
||||
#include "pcertt.h"
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
#include "nssb64.h"
|
||||
#include "blapi.h"
|
||||
#include "sechash.h"
|
||||
|
||||
#include "pkcs11i.h"
|
||||
|
||||
/*
|
||||
* Blob block:
|
||||
* Byte 0 CERTDB Version -+ -+
|
||||
* Byte 1 certDBEntryTypeBlob | BLOB_HEAD_LEN |
|
||||
* Byte 2 flags (always '0'); | |
|
||||
* Byte 3 reserved (always '0'); -+ |
|
||||
* Byte 4 LSB length | <--BLOB_LENGTH_START | BLOB_BUF_LEN
|
||||
* Byte 5 . | |
|
||||
* Byte 6 . | BLOB_LENGTH_LEN |
|
||||
* Byte 7 MSB length | |
|
||||
* Byte 8 blob_filename -+ -+ <-- BLOB_NAME_START |
|
||||
* Byte 9 . | BLOB_NAME_LEN |
|
||||
* . . | |
|
||||
* Byte 37 . -+ -+
|
||||
*/
|
||||
#define DBS_BLOCK_SIZE (16*1024) /* 16 k */
|
||||
#define DBS_MAX_ENTRY_SIZE (DBS_BLOCK_SIZE - (2048)) /* 14 k */
|
||||
#define DBS_CACHE_SIZE DBS_BLOCK_SIZE*8
|
||||
#define ROUNDDIV(x,y) (x+(y-1))/y
|
||||
#define BLOB_HEAD_LEN 4
|
||||
#define BLOB_LENGTH_START BLOB_HEAD_LEN
|
||||
#define BLOB_LENGTH_LEN 4
|
||||
#define BLOB_NAME_START BLOB_LENGTH_START+BLOB_LENGTH_LEN
|
||||
#define BLOB_NAME_LEN 1+ROUNDDIV(SHA1_LENGTH,3)*4+1
|
||||
#define BLOB_BUF_LEN BLOB_HEAD_LEN+BLOB_LENGTH_LEN+BLOB_NAME_LEN
|
||||
|
||||
/* a Shim data structure. This data structure has a db built into it. */
|
||||
typedef struct DBSStr DBS;
|
||||
|
||||
struct DBSStr {
|
||||
DB db;
|
||||
char *blobdir;
|
||||
int mode;
|
||||
PRBool readOnly;
|
||||
PRFileMap *dbs_mapfile;
|
||||
unsigned char *dbs_addr;
|
||||
PRUint32 dbs_len;
|
||||
char staticBlobArea[BLOB_BUF_LEN];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* return true if the Datablock contains a blobtype
|
||||
*/
|
||||
static PRBool
|
||||
dbs_IsBlob(DBT *blobData)
|
||||
{
|
||||
unsigned char *addr = (unsigned char *)blobData->data;
|
||||
if (blobData->size < BLOB_BUF_LEN) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return addr && ((certDBEntryType) addr[1] == certDBEntryTypeBlob);
|
||||
}
|
||||
|
||||
/*
|
||||
* extract the filename in the blob of the real data set.
|
||||
* This value is not malloced (does not need to be freed by the caller.
|
||||
*/
|
||||
static const char *
|
||||
dbs_getBlobFileName(DBT *blobData)
|
||||
{
|
||||
char *addr = (char *)blobData->data;
|
||||
|
||||
return &addr[BLOB_NAME_START];
|
||||
}
|
||||
|
||||
/*
|
||||
* extract the size of the actual blob from the blob record
|
||||
*/
|
||||
static PRUint32
|
||||
dbs_getBlobSize(DBT *blobData)
|
||||
{
|
||||
unsigned char *addr = (unsigned char *)blobData->data;
|
||||
|
||||
return (PRUint32)(addr[BLOB_LENGTH_START+3] << 24) |
|
||||
(addr[BLOB_LENGTH_START+2] << 16) |
|
||||
(addr[BLOB_LENGTH_START+1] << 8) |
|
||||
addr[BLOB_LENGTH_START];
|
||||
}
|
||||
|
||||
|
||||
/* We are using base64 data for the filename, but base64 data can include a
|
||||
* '/' which is interpreted as a path separator on many platforms. Replace it
|
||||
* with an inocuous '-'. We don't need to convert back because we never actual
|
||||
* decode the filename.
|
||||
*/
|
||||
|
||||
static void
|
||||
dbs_replaceSlash(char *cp, int len)
|
||||
{
|
||||
while (len--) {
|
||||
if (*cp == '/') *cp = '-';
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create a blob record from a key, data and return it in blobData.
|
||||
* NOTE: The data element is static data (keeping with the dbm model).
|
||||
*/
|
||||
static void
|
||||
dbs_mkBlob(DBS *dbsp,const DBT *key, const DBT *data, DBT *blobData)
|
||||
{
|
||||
unsigned char sha1_data[SHA1_LENGTH];
|
||||
char *b = dbsp->staticBlobArea;
|
||||
PRUint32 length = data->size;
|
||||
SECItem sha1Item;
|
||||
|
||||
b[0] = CERT_DB_FILE_VERSION; /* certdb version number */
|
||||
b[1] = (char) certDBEntryTypeBlob; /* type */
|
||||
b[2] = 0; /* flags */
|
||||
b[3] = 0; /* reserved */
|
||||
b[BLOB_LENGTH_START] = length & 0xff;
|
||||
b[BLOB_LENGTH_START+1] = (length >> 8) & 0xff;
|
||||
b[BLOB_LENGTH_START+2] = (length >> 16) & 0xff;
|
||||
b[BLOB_LENGTH_START+3] = (length >> 24) & 0xff;
|
||||
sha1Item.data = sha1_data;
|
||||
sha1Item.len = SHA1_LENGTH;
|
||||
SHA1_HashBuf(sha1_data,key->data,key->size);
|
||||
b[BLOB_NAME_START]='b'; /* Make sure we start with a alpha */
|
||||
NSSBase64_EncodeItem(NULL,&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1,&sha1Item);
|
||||
b[BLOB_BUF_LEN-1] = 0;
|
||||
dbs_replaceSlash(&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1);
|
||||
blobData->data = b;
|
||||
blobData->size = BLOB_BUF_LEN;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* construct a path to the actual blob. The string returned must be
|
||||
* freed by the caller with PR_smprintf_free.
|
||||
*
|
||||
* Note: this file does lots of consistancy checks on the DBT. The
|
||||
* routines that call this depend on these checks, so they don't worry
|
||||
* about them (success of this routine implies a good blobdata record).
|
||||
*/
|
||||
static char *
|
||||
dbs_getBlobFilePath(char *blobdir,DBT *blobData)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (blobdir == NULL) {
|
||||
PR_SetError(SEC_ERROR_BAD_DATABASE,0);
|
||||
return NULL;
|
||||
}
|
||||
if (!dbs_IsBlob(blobData)) {
|
||||
PR_SetError(SEC_ERROR_BAD_DATABASE,0);
|
||||
return NULL;
|
||||
}
|
||||
name = dbs_getBlobFileName(blobData);
|
||||
if (!name || *name == 0) {
|
||||
PR_SetError(SEC_ERROR_BAD_DATABASE,0);
|
||||
return NULL;
|
||||
}
|
||||
return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a blob file pointed to by the blob record.
|
||||
*/
|
||||
static void
|
||||
dbs_removeBlob(DBS *dbsp, DBT *blobData)
|
||||
{
|
||||
char *file;
|
||||
|
||||
file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
PR_Delete(file);
|
||||
PR_smprintf_free(file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory modes are slightly different, the 'x' bit needs to be on to
|
||||
* access them. Copy all the read bits to 'x' bits
|
||||
*/
|
||||
static int
|
||||
dbs_DirMode(int mode)
|
||||
{
|
||||
int x_bits = (mode >> 2) & 0111;
|
||||
return mode | x_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* write a data blob to it's file. blobdData is the blob record that will be
|
||||
* stored in the database. data is the actual data to go out on disk.
|
||||
*/
|
||||
static int
|
||||
dbs_writeBlob(DBS *dbsp, int mode, DBT *blobData, const DBT *data)
|
||||
{
|
||||
char *file = NULL;
|
||||
PRFileDesc *filed;
|
||||
PRStatus status;
|
||||
int len;
|
||||
int error = 0;
|
||||
|
||||
file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
|
||||
if (!file) {
|
||||
goto loser;
|
||||
}
|
||||
if (PR_Access(dbsp->blobdir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
|
||||
status = PR_MkDir(dbsp->blobdir,dbs_DirMode(mode));
|
||||
if (status != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
filed = PR_OpenFile(file,PR_CREATE_FILE|PR_TRUNCATE|PR_WRONLY, mode);
|
||||
if (filed == NULL) {
|
||||
error = PR_GetError();
|
||||
goto loser;
|
||||
}
|
||||
len = PR_Write(filed,data->data,data->size);
|
||||
error = PR_GetError();
|
||||
PR_Close(filed);
|
||||
if (len < (int)data->size) {
|
||||
goto loser;
|
||||
}
|
||||
PR_smprintf_free(file);
|
||||
return 0;
|
||||
|
||||
loser:
|
||||
if (file) {
|
||||
PR_Delete(file);
|
||||
PR_smprintf_free(file);
|
||||
}
|
||||
/* don't let close or delete reset the error */
|
||||
PR_SetError(error,0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* we need to keep a address map in memory between calls to DBM.
|
||||
* remember what we have mapped can close it when we get another dbm
|
||||
* call.
|
||||
*
|
||||
* NOTE: Not all platforms support mapped files. This code is designed to
|
||||
* detect this at runtime. If map files aren't supported the OS will indicate
|
||||
* this by failing the PR_Memmap call. In this case we emulate mapped files
|
||||
* by just reading in the file into regular memory. We signal this state by
|
||||
* making dbs_mapfile NULL and dbs_addr non-NULL.
|
||||
*/
|
||||
|
||||
static void
|
||||
dbs_freemap(DBS *dbsp)
|
||||
{
|
||||
if (dbsp->dbs_mapfile) {
|
||||
PR_MemUnmap(dbsp->dbs_addr,dbsp->dbs_len);
|
||||
PR_CloseFileMap(dbsp->dbs_mapfile);
|
||||
dbsp->dbs_mapfile = NULL;
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
} else if (dbsp->dbs_addr) {
|
||||
PORT_Free(dbsp->dbs_addr);
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len)
|
||||
{
|
||||
dbsp->dbs_mapfile = mapfile;
|
||||
dbsp->dbs_addr = addr;
|
||||
dbsp->dbs_len = len;
|
||||
}
|
||||
|
||||
/*
|
||||
* platforms that cannot map the file need to read it into a temp buffer.
|
||||
*/
|
||||
static unsigned char *
|
||||
dbs_EmulateMap(PRFileDesc *filed, int len)
|
||||
{
|
||||
unsigned char *addr;
|
||||
PRInt32 dataRead;
|
||||
|
||||
addr = PORT_Alloc(len);
|
||||
if (addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dataRead = PR_Read(filed,addr,len);
|
||||
if (dataRead != len) {
|
||||
PORT_Free(addr);
|
||||
if (dataRead > 0) {
|
||||
/* PR_Read didn't set an error, we need to */
|
||||
PR_SetError(SEC_ERROR_BAD_DATABASE,0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pull a database record off the disk
|
||||
* data points to the blob record on input and the real record (if we could
|
||||
* read it) on output. if there is an error data is not modified.
|
||||
*/
|
||||
static int
|
||||
dbs_readBlob(DBS *dbsp, DBT *data)
|
||||
{
|
||||
char *file = NULL;
|
||||
PRFileDesc *filed = NULL;
|
||||
PRFileMap *mapfile = NULL;
|
||||
unsigned char *addr = NULL;
|
||||
int error;
|
||||
int len = -1;
|
||||
|
||||
file = dbs_getBlobFilePath(dbsp->blobdir, data);
|
||||
if (!file) {
|
||||
goto loser;
|
||||
}
|
||||
filed = PR_OpenFile(file,PR_RDONLY,0);
|
||||
PR_smprintf_free(file); file = NULL;
|
||||
if (filed == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
len = dbs_getBlobSize(data);
|
||||
mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY);
|
||||
if (mapfile == NULL) {
|
||||
/* USE PR_GetError instead of PORT_GetError here
|
||||
* because we are getting the error from PR_xxx
|
||||
* function */
|
||||
if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) {
|
||||
goto loser;
|
||||
}
|
||||
addr = dbs_EmulateMap(filed, len);
|
||||
} else {
|
||||
addr = PR_MemMap(mapfile, 0, len);
|
||||
}
|
||||
if (addr == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
PR_Close(filed);
|
||||
dbs_setmap(dbsp,mapfile,addr,len);
|
||||
|
||||
data->data = addr;
|
||||
data->size = len;
|
||||
return 0;
|
||||
|
||||
loser:
|
||||
/* preserve the error code */
|
||||
error = PR_GetError();
|
||||
if (addr) {
|
||||
if (mapfile) {
|
||||
PORT_Assert(len != -1);
|
||||
PR_MemUnmap(addr,len);
|
||||
} else {
|
||||
PORT_Free(addr);
|
||||
}
|
||||
}
|
||||
if (mapfile) {
|
||||
PR_CloseFileMap(mapfile);
|
||||
}
|
||||
if (filed) {
|
||||
PR_Close(filed);
|
||||
}
|
||||
PR_SetError(error,0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* actual DBM shims
|
||||
*/
|
||||
static int
|
||||
dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
ret = (* db->get)(db, key, data, flags);
|
||||
if ((ret == 0) && dbs_IsBlob(data)) {
|
||||
ret = dbs_readBlob(dbsp,data);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags)
|
||||
{
|
||||
DBT blob;
|
||||
int ret = 0;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
/* If the db is readonly, just pass the data down to rdb and let it fail */
|
||||
if (!dbsp->readOnly) {
|
||||
DBT oldData;
|
||||
int ret1;
|
||||
|
||||
/* make sure the current record is deleted if it's a blob */
|
||||
ret1 = (*db->get)(db,key,&oldData,0);
|
||||
if ((ret1 == 0) && flags == R_NOOVERWRITE) {
|
||||
/* let DBM return the error to maintain consistancy */
|
||||
return (* db->put)(db, key, data, flags);
|
||||
}
|
||||
if ((ret1 == 0) && dbs_IsBlob(&oldData)) {
|
||||
dbs_removeBlob(dbsp, &oldData);
|
||||
}
|
||||
|
||||
if (data->size > DBS_MAX_ENTRY_SIZE) {
|
||||
dbs_mkBlob(dbsp,key,data,&blob);
|
||||
ret = dbs_writeBlob(dbsp, dbsp->mode, &blob, data);
|
||||
data = &blob;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = (* db->put)(db, key, data, flags);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_sync(const DB *dbs, unsigned int flags)
|
||||
{
|
||||
DB *db = (DB *)dbs->internal;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
return (* db->sync)(db, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_del(const DB *dbs, const DBT *key, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
if (!dbsp->readOnly) {
|
||||
DBT oldData;
|
||||
ret = (*db->get)(db,key,&oldData,0);
|
||||
if ((ret == 0) && dbs_IsBlob(&oldData)) {
|
||||
dbs_removeBlob(dbsp,&oldData);
|
||||
}
|
||||
}
|
||||
|
||||
return (* db->del)(db, key, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
ret = (* db->seq)(db, key, data, flags);
|
||||
if ((ret == 0) && dbs_IsBlob(data)) {
|
||||
/* don't return a blob read as an error so traversals keep going */
|
||||
(void) dbs_readBlob(dbsp,data);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_close(DB *dbs)
|
||||
{
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
int ret;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
ret = (* db->close)(db);
|
||||
PORT_Free(dbsp->blobdir);
|
||||
PORT_Free(dbsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dbs_fd(const DB *dbs)
|
||||
{
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
return (* db->fd)(db);
|
||||
}
|
||||
|
||||
/*
|
||||
* the naming convention we use is
|
||||
* change the .xxx into .dir. (for nss it's always .db);
|
||||
* if no .extension exists or is equal to .dir, add a .dir
|
||||
* the returned data must be freed.
|
||||
*/
|
||||
#define DIRSUFFIX ".dir"
|
||||
static char *
|
||||
dbs_mkBlobDirName(const char *dbname)
|
||||
{
|
||||
int dbname_len = PORT_Strlen(dbname);
|
||||
int dbname_end = dbname_len;
|
||||
const char *cp;
|
||||
char *blobDir = NULL;
|
||||
|
||||
/* scan back from the end looking for either a directory separator, a '.',
|
||||
* or the end of the string. NOTE: Windows should check for both separators
|
||||
* here. For now this is safe because we know NSS always uses a '.'
|
||||
*/
|
||||
for (cp = &dbname[dbname_len];
|
||||
(cp > dbname) && (*cp != '.') && (*cp != *PATH_SEPARATOR) ;
|
||||
cp--)
|
||||
/* Empty */ ;
|
||||
if (*cp == '.') {
|
||||
dbname_end = cp - dbname;
|
||||
if (PORT_Strcmp(cp,DIRSUFFIX) == 0) {
|
||||
dbname_end = dbname_len;
|
||||
}
|
||||
}
|
||||
blobDir = PORT_ZAlloc(dbname_end+sizeof(DIRSUFFIX));
|
||||
if (blobDir == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memcpy(blobDir,dbname,dbname_end);
|
||||
PORT_Memcpy(&blobDir[dbname_end],DIRSUFFIX,sizeof(DIRSUFFIX));
|
||||
return blobDir;
|
||||
}
|
||||
|
||||
#define DBM_DEFAULT 0
|
||||
static const HASHINFO dbs_hashInfo = {
|
||||
DBS_BLOCK_SIZE, /* bucket size, must be greater than = to
|
||||
* or maximum entry size (+ header)
|
||||
* we allow before blobing */
|
||||
DBM_DEFAULT, /* Fill Factor */
|
||||
DBM_DEFAULT, /* number of elements */
|
||||
DBS_CACHE_SIZE, /* cache size */
|
||||
DBM_DEFAULT, /* hash function */
|
||||
DBM_DEFAULT, /* byte order */
|
||||
};
|
||||
|
||||
/*
|
||||
* the open function. NOTE: this is the only exposed function in this file.
|
||||
* everything else is called through the function table pointer.
|
||||
*/
|
||||
DB *
|
||||
dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
|
||||
const void *userData)
|
||||
{
|
||||
DB *db = NULL,*dbs = NULL;
|
||||
DBS *dbsp = NULL;
|
||||
|
||||
/* NOTE: we are overriding userData with dbs_hashInfo. since all known
|
||||
* callers pass 0, this is ok, otherwise we should merge the two */
|
||||
|
||||
dbsp = (DBS *)PORT_ZAlloc(sizeof(DBS));
|
||||
if (!dbsp) {
|
||||
return NULL;
|
||||
}
|
||||
dbs = &dbsp->db;
|
||||
|
||||
dbsp->blobdir=dbs_mkBlobDirName(dbname);
|
||||
if (dbsp->blobdir == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
dbsp->mode = mode;
|
||||
dbsp->readOnly = (PRBool)(flags == NO_RDONLY);
|
||||
dbsp->dbs_mapfile = NULL;
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
|
||||
/* the real dbm call */
|
||||
db = dbopen(dbname, flags, mode, type, &dbs_hashInfo);
|
||||
if (db == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
dbs->internal = (void *) db;
|
||||
dbs->type = type;
|
||||
dbs->close = dbs_close;
|
||||
dbs->get = dbs_get;
|
||||
dbs->del = dbs_del;
|
||||
dbs->put = dbs_put;
|
||||
dbs->seq = dbs_seq;
|
||||
dbs->sync = dbs_sync;
|
||||
dbs->fd = dbs_fd;
|
||||
|
||||
return dbs;
|
||||
loser:
|
||||
if (db) {
|
||||
(*db->close)(db);
|
||||
}
|
||||
if (dbsp && dbsp->blobdir) {
|
||||
PORT_Free(dbsp->blobdir);
|
||||
}
|
||||
if (dbsp) {
|
||||
PORT_Free(dbsp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,687 +0,0 @@
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Elliptic Curve Cryptography library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Sun Microsystems, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com> and
|
||||
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
|
||||
#include "blapi.h"
|
||||
#include "secoid.h"
|
||||
#include "secitem.h"
|
||||
#include "secerr.h"
|
||||
#include "ec.h"
|
||||
#include "ecl-curve.h"
|
||||
|
||||
#define CHECK_OK(func) if (func == NULL) goto cleanup
|
||||
#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
|
||||
|
||||
/* Initializes a SECItem from a hexadecimal string */
|
||||
static SECItem *
|
||||
hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
int byteval = 0;
|
||||
int tmp = PORT_Strlen(str);
|
||||
|
||||
if ((tmp % 2) != 0) return NULL;
|
||||
|
||||
item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2);
|
||||
if (item->data == NULL) return NULL;
|
||||
item->len = tmp/2;
|
||||
|
||||
while (str[i]) {
|
||||
if ((str[i] >= '0') && (str[i] <= '9'))
|
||||
tmp = str[i] - '0';
|
||||
else if ((str[i] >= 'a') && (str[i] <= 'f'))
|
||||
tmp = str[i] - 'a' + 10;
|
||||
else if ((str[i] >= 'A') && (str[i] <= 'F'))
|
||||
tmp = str[i] - 'A' + 10;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
byteval = byteval * 16 + tmp;
|
||||
if ((i % 2) != 0) {
|
||||
item->data[i/2] = byteval;
|
||||
byteval = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/* Copy all of the fields from srcParams into dstParams
|
||||
*/
|
||||
SECStatus
|
||||
EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
|
||||
const ECParams *srcParams)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
dstParams->arena = arena;
|
||||
dstParams->type = srcParams->type;
|
||||
dstParams->fieldID.size = srcParams->fieldID.size;
|
||||
dstParams->fieldID.type = srcParams->fieldID.type;
|
||||
if (srcParams->fieldID.type == ec_field_GFp) {
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime,
|
||||
&srcParams->fieldID.u.prime));
|
||||
} else {
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly,
|
||||
&srcParams->fieldID.u.poly));
|
||||
}
|
||||
dstParams->fieldID.k1 = srcParams->fieldID.k1;
|
||||
dstParams->fieldID.k2 = srcParams->fieldID.k2;
|
||||
dstParams->fieldID.k3 = srcParams->fieldID.k3;
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a,
|
||||
&srcParams->curve.a));
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b,
|
||||
&srcParams->curve.b));
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed,
|
||||
&srcParams->curve.seed));
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base,
|
||||
&srcParams->base));
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order,
|
||||
&srcParams->order));
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding,
|
||||
&srcParams->DEREncoding));
|
||||
dstParams->name = srcParams->name;
|
||||
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID,
|
||||
&srcParams->curveOID));
|
||||
dstParams->cofactor = srcParams->cofactor;
|
||||
|
||||
return SECSuccess;
|
||||
|
||||
cleanup:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
|
||||
ECParams *params)
|
||||
{
|
||||
SECOidTag tag;
|
||||
SECItem oid = { siBuffer, NULL, 0};
|
||||
const ECCurveParams *curveParams;
|
||||
char genenc[2 + 2 * 2 * MAX_ECKEY_LEN];
|
||||
|
||||
#if EC_DEBUG
|
||||
int i;
|
||||
|
||||
printf("Encoded params in EC_DecodeParams: ");
|
||||
for (i = 0; i < encodedParams->len; i++) {
|
||||
printf("%02x:", encodedParams->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
|
||||
(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
return SECFailure;
|
||||
};
|
||||
|
||||
oid.len = encodedParams->len - 2;
|
||||
oid.data = encodedParams->data + 2;
|
||||
if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
|
||||
((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
params->arena = arena;
|
||||
params->cofactor = 0;
|
||||
params->type = ec_params_named;
|
||||
params->name = ECCurve_noName;
|
||||
|
||||
/* For named curves, fill out curveOID */
|
||||
params->curveOID.len = oid.len;
|
||||
params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
|
||||
if (params->curveOID.data == NULL) goto cleanup;
|
||||
memcpy(params->curveOID.data, oid.data, oid.len);
|
||||
|
||||
#if EC_DEBUG
|
||||
printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
|
||||
#endif
|
||||
|
||||
switch (tag) {
|
||||
|
||||
#define GF2M_POPULATE \
|
||||
if ((params->name < ECCurve_noName) || \
|
||||
(params->name > ECCurve_pastLastCurve)) goto cleanup; \
|
||||
CHECK_OK(curveParams); \
|
||||
params->fieldID.size = curveParams->size; \
|
||||
params->fieldID.type = ec_field_GF2m; \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, \
|
||||
curveParams->irr)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, \
|
||||
curveParams->curvea)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, \
|
||||
curveParams->curveb)); \
|
||||
genenc[0] = '0'; \
|
||||
genenc[1] = '4'; \
|
||||
genenc[2] = '\0'; \
|
||||
CHECK_OK(strcat(genenc, curveParams->genx)); \
|
||||
CHECK_OK(strcat(genenc, curveParams->geny)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, \
|
||||
genenc)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, \
|
||||
curveParams->order)); \
|
||||
params->cofactor = curveParams->cofactor;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB163V1:
|
||||
/* Populate params for c2pnb163v1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB163V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB163V2:
|
||||
/* Populate params for c2pnb163v2 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB163V2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB163V3:
|
||||
/* Populate params for c2pnb163v3 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB163V3;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB176V1:
|
||||
/* Populate params for c2pnb176v1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB176V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB191V1:
|
||||
/* Populate params for c2tnb191v1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB191V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB191V2:
|
||||
/* Populate params for c2tnb191v2 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB191V2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB191V3:
|
||||
/* Populate params for c2tnb191v3 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB191V3;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB208W1:
|
||||
/* Populate params for c2pnb208w1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB208W1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB239V1:
|
||||
/* Populate params for c2tnb239v1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB239V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB239V2:
|
||||
/* Populate params for c2tnb239v2 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB239V2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB239V3:
|
||||
/* Populate params for c2tnb239v3 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB239V3;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB272W1:
|
||||
/* Populate params for c2pnb272w1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB272W1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB304W1:
|
||||
/* Populate params for c2pnb304w1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB304W1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB359V1:
|
||||
/* Populate params for c2tnb359v1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB359V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2PNB368W1:
|
||||
/* Populate params for c2pnb368w1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_PNB368W1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_C2TNB431R1:
|
||||
/* Populate params for c2tnb431r1 */
|
||||
params->name = ECCurve_X9_62_CHAR2_TNB431R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT113R1:
|
||||
/* Populate params for sect113r1 */
|
||||
params->name = ECCurve_SECG_CHAR2_113R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT113R2:
|
||||
/* Populate params for sect113r2 */
|
||||
params->name = ECCurve_SECG_CHAR2_113R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT131R1:
|
||||
/* Populate params for sect131r1 */
|
||||
params->name = ECCurve_SECG_CHAR2_131R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT131R2:
|
||||
/* Populate params for sect131r2 */
|
||||
params->name = ECCurve_SECG_CHAR2_131R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT163K1:
|
||||
/* Populate params for sect163k1
|
||||
* (the NIST K-163 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_163K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT163R1:
|
||||
/* Populate params for sect163r1 */
|
||||
params->name = ECCurve_SECG_CHAR2_163R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT163R2:
|
||||
/* Populate params for sect163r2
|
||||
* (the NIST B-163 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_163R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT193R1:
|
||||
/* Populate params for sect193r1 */
|
||||
params->name = ECCurve_SECG_CHAR2_193R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT193R2:
|
||||
/* Populate params for sect193r2 */
|
||||
params->name = ECCurve_SECG_CHAR2_193R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT233K1:
|
||||
/* Populate params for sect233k1
|
||||
* (the NIST K-233 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_233K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT233R1:
|
||||
/* Populate params for sect233r1
|
||||
* (the NIST B-233 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_233R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT239K1:
|
||||
/* Populate params for sect239k1 */
|
||||
params->name = ECCurve_SECG_CHAR2_239K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT283K1:
|
||||
/* Populate params for sect283k1
|
||||
* (the NIST K-283 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_283K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT283R1:
|
||||
/* Populate params for sect283r1
|
||||
* (the NIST B-283 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_283R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT409K1:
|
||||
/* Populate params for sect409k1
|
||||
* (the NIST K-409 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_409K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT409R1:
|
||||
/* Populate params for sect409r1
|
||||
* (the NIST B-409 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_409R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT571K1:
|
||||
/* Populate params for sect571k1
|
||||
* (the NIST K-571 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_571K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECT571R1:
|
||||
/* Populate params for sect571r1
|
||||
* (the NIST B-571 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_CHAR2_571R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GF2M_POPULATE
|
||||
break;
|
||||
|
||||
#define GFP_POPULATE \
|
||||
if ((params->name < ECCurve_noName) || \
|
||||
(params->name > ECCurve_pastLastCurve)) goto cleanup; \
|
||||
CHECK_OK(curveParams); \
|
||||
params->fieldID.size = curveParams->size; \
|
||||
params->fieldID.type = ec_field_GFp; \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, \
|
||||
curveParams->irr)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, \
|
||||
curveParams->curvea)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, \
|
||||
curveParams->curveb)); \
|
||||
genenc[0] = '0'; \
|
||||
genenc[1] = '4'; \
|
||||
genenc[2] = '\0'; \
|
||||
CHECK_OK(strcat(genenc, curveParams->genx)); \
|
||||
CHECK_OK(strcat(genenc, curveParams->geny)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, \
|
||||
genenc)); \
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, \
|
||||
curveParams->order)); \
|
||||
params->cofactor = curveParams->cofactor;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME192V1:
|
||||
/* Populate params for prime192v1 aka secp192r1
|
||||
* (the NIST P-192 curve)
|
||||
*/
|
||||
params->name = ECCurve_X9_62_PRIME_192V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME192V2:
|
||||
/* Populate params for prime192v2 */
|
||||
params->name = ECCurve_X9_62_PRIME_192V2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME192V3:
|
||||
/* Populate params for prime192v3 */
|
||||
params->name = ECCurve_X9_62_PRIME_192V3;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME239V1:
|
||||
/* Populate params for prime239v1 */
|
||||
params->name = ECCurve_X9_62_PRIME_239V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME239V2:
|
||||
/* Populate params for prime239v2 */
|
||||
params->name = ECCurve_X9_62_PRIME_239V2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME239V3:
|
||||
/* Populate params for prime239v3 */
|
||||
params->name = ECCurve_X9_62_PRIME_239V3;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_ANSIX962_EC_PRIME256V1:
|
||||
/* Populate params for prime256v1 aka secp256r1
|
||||
* (the NIST P-256 curve)
|
||||
*/
|
||||
params->name = ECCurve_X9_62_PRIME_256V1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP112R1:
|
||||
/* Populate params for secp112r1 */
|
||||
params->name = ECCurve_SECG_PRIME_112R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP112R2:
|
||||
/* Populate params for secp112r2 */
|
||||
params->name = ECCurve_SECG_PRIME_112R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP128R1:
|
||||
/* Populate params for secp128r1 */
|
||||
params->name = ECCurve_SECG_PRIME_128R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP128R2:
|
||||
/* Populate params for secp128r2 */
|
||||
params->name = ECCurve_SECG_PRIME_128R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP160K1:
|
||||
/* Populate params for secp160k1 */
|
||||
params->name = ECCurve_SECG_PRIME_160K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP160R1:
|
||||
/* Populate params for secp160r1 */
|
||||
params->name = ECCurve_SECG_PRIME_160R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP160R2:
|
||||
/* Populate params for secp160r1 */
|
||||
params->name = ECCurve_SECG_PRIME_160R2;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP192K1:
|
||||
/* Populate params for secp192k1 */
|
||||
params->name = ECCurve_SECG_PRIME_192K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP224K1:
|
||||
/* Populate params for secp224k1 */
|
||||
params->name = ECCurve_SECG_PRIME_224K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP224R1:
|
||||
/* Populate params for secp224r1
|
||||
* (the NIST P-224 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_PRIME_224R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP256K1:
|
||||
/* Populate params for secp256k1 */
|
||||
params->name = ECCurve_SECG_PRIME_256K1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP384R1:
|
||||
/* Populate params for secp384r1
|
||||
* (the NIST P-384 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_PRIME_384R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP521R1:
|
||||
/* Populate params for secp521r1
|
||||
* (the NIST P-521 curve)
|
||||
*/
|
||||
params->name = ECCurve_SECG_PRIME_521R1;
|
||||
curveParams = ecCurve_map[params->name];
|
||||
GFP_POPULATE
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
cleanup:
|
||||
if (!params->cofactor) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
#if EC_DEBUG
|
||||
printf("Unrecognized curve, returning NULL params\n");
|
||||
#endif
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
|
||||
{
|
||||
PRArenaPool *arena;
|
||||
ECParams *params;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
/* Initialize an arena for the ECParams structure */
|
||||
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
|
||||
return SECFailure;
|
||||
|
||||
params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
|
||||
if (!params) {
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Copy the encoded params */
|
||||
SECITEM_AllocItem(arena, &(params->DEREncoding),
|
||||
encodedParams->len);
|
||||
memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
|
||||
|
||||
/* Fill out the rest of the ECParams structure based on
|
||||
* the encoded params
|
||||
*/
|
||||
rv = EC_FillParams(arena, encodedParams, params);
|
||||
if (rv == SECFailure) {
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
return SECFailure;
|
||||
} else {
|
||||
*ecparams = params;;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,996 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* This file implements PKCS 11 on top of our existing security modules
|
||||
*
|
||||
* For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
|
||||
* This implementation has two slots:
|
||||
* slot 1 is our generic crypto support. It does not require login
|
||||
* (unless you've enabled FIPS). It supports Public Key ops, and all they
|
||||
* bulk ciphers and hashes. It can also support Private Key ops for imported
|
||||
* Private keys. It does not have any token storage.
|
||||
* slot 2 is our private key support. It requires a login before use. It
|
||||
* can store Private Keys and Certs as token objects. Currently only private
|
||||
* keys and their associated Certificates are saved on the token.
|
||||
*
|
||||
* In this implementation, session objects are only visible to the session
|
||||
* that created or generated them.
|
||||
*/
|
||||
#include "seccomon.h"
|
||||
#include "softoken.h"
|
||||
#include "lowkeyi.h"
|
||||
#include "pcert.h"
|
||||
#include "pkcs11.h"
|
||||
#include "pkcs11i.h"
|
||||
|
||||
|
||||
/*
|
||||
* ******************** Password Utilities *******************************
|
||||
*/
|
||||
static PRBool isLoggedIn = PR_FALSE;
|
||||
static PRBool fatalError = PR_FALSE;
|
||||
|
||||
/* Fips required checks before any useful crypto graphic services */
|
||||
static CK_RV sftk_fipsCheck(void) {
|
||||
if (isLoggedIn != PR_TRUE)
|
||||
return CKR_USER_NOT_LOGGED_IN;
|
||||
if (fatalError)
|
||||
return CKR_DEVICE_ERROR;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
||||
#define SFTK_FIPSCHECK() \
|
||||
CK_RV rv; \
|
||||
if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
|
||||
|
||||
#define SFTK_FIPSFATALCHECK() \
|
||||
if (fatalError) return CKR_DEVICE_ERROR;
|
||||
|
||||
|
||||
/* grab an attribute out of a raw template */
|
||||
void *
|
||||
fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < (int) ulCount; i++) {
|
||||
if (pTemplate[i].type == type) {
|
||||
return pTemplate[i].pValue;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#define __PASTE(x,y) x##y
|
||||
|
||||
/* ------------- forward declare all the NSC_ functions ------------- */
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
|
||||
#include "pkcs11f.h"
|
||||
|
||||
/* ------------- forward declare all the FIPS functions ------------- */
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
|
||||
#include "pkcs11f.h"
|
||||
|
||||
/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
|
||||
static CK_FUNCTION_LIST sftk_fipsTable = {
|
||||
{ 1, 10 },
|
||||
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
|
||||
|
||||
|
||||
#include "pkcs11f.h"
|
||||
|
||||
};
|
||||
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
|
||||
#undef __PASTE
|
||||
|
||||
static CK_RV
|
||||
fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_OBJECT_CLASS objClass;
|
||||
CK_ATTRIBUTE class;
|
||||
class.type = CKA_CLASS;
|
||||
class.pValue = &objClass;
|
||||
class.ulValueLen = sizeof(objClass);
|
||||
rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
|
||||
if (rv == CKR_OK) {
|
||||
if ((objClass == CKO_PRIVATE_KEY) || (objClass == CKO_SECRET_KEY)) {
|
||||
rv = sftk_fipsCheck();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Start of PKCS 11 functions
|
||||
*
|
||||
**********************************************************************/
|
||||
/* return the function list */
|
||||
CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
|
||||
*pFunctionList = &sftk_fipsTable;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/* sigh global so pkcs11 can read it */
|
||||
PRBool nsf_init = PR_FALSE;
|
||||
|
||||
/* FC_Initialize initializes the PKCS #11 library. */
|
||||
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
|
||||
CK_RV crv;
|
||||
|
||||
if (nsf_init) {
|
||||
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
crv = nsc_CommonInitialize(pReserved, PR_TRUE);
|
||||
|
||||
/* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
|
||||
if (crv != CKR_OK) {
|
||||
fatalError = PR_TRUE;
|
||||
return crv;
|
||||
}
|
||||
|
||||
fatalError = PR_FALSE; /* any error has been reset */
|
||||
|
||||
crv = sftk_fipsPowerUpSelfTest();
|
||||
if (crv != CKR_OK) {
|
||||
nsc_CommonFinalize(NULL, PR_TRUE);
|
||||
fatalError = PR_TRUE;
|
||||
return crv;
|
||||
}
|
||||
nsf_init = PR_TRUE;
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
|
||||
CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
|
||||
CK_RV crv;
|
||||
if (!nsf_init) {
|
||||
return CKR_OK;
|
||||
}
|
||||
crv = nsc_CommonFinalize (pReserved, PR_TRUE);
|
||||
nsf_init = (PRBool) !(crv == CKR_OK);
|
||||
return crv;
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetInfo returns general information about PKCS #11. */
|
||||
CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
|
||||
return NSC_GetInfo(pInfo);
|
||||
}
|
||||
|
||||
/* FC_GetSlotList obtains a list of slots in the system. */
|
||||
CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
|
||||
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
|
||||
return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
|
||||
NSC_FIPS_MODULE);
|
||||
}
|
||||
|
||||
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
|
||||
CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
|
||||
|
||||
CK_RV crv;
|
||||
|
||||
crv = NSC_GetSlotInfo(slotID,pInfo);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*FC_GetTokenInfo obtains information about a particular token in the system.*/
|
||||
CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
|
||||
CK_RV crv;
|
||||
|
||||
crv = NSC_GetTokenInfo(slotID,pInfo);
|
||||
pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED;
|
||||
return crv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
|
||||
CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
|
||||
CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
|
||||
/* FIPS Slot supports all functions */
|
||||
return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetMechanismInfo obtains information about a particular mechanism
|
||||
* possibly supported by a token. */
|
||||
CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
|
||||
CK_MECHANISM_INFO_PTR pInfo) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
|
||||
/* FIPS Slot supports all functions */
|
||||
return NSC_GetMechanismInfo(slotID,type,pInfo);
|
||||
}
|
||||
|
||||
|
||||
/* FC_InitToken initializes a token. */
|
||||
CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
|
||||
CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
|
||||
return CKR_HOST_MEMORY; /*is this the right function for not implemented*/
|
||||
}
|
||||
|
||||
|
||||
/* FC_InitPIN initializes the normal user's PIN. */
|
||||
CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
|
||||
CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
|
||||
return NSC_InitPIN(hSession,pPin,ulPinLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SetPIN modifies the PIN of user that is currently logged in. */
|
||||
/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
|
||||
CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
|
||||
CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
|
||||
CK_RV rv;
|
||||
if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
|
||||
return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
|
||||
}
|
||||
|
||||
/* FC_OpenSession opens a session between an application and a token. */
|
||||
CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
|
||||
CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
|
||||
}
|
||||
|
||||
|
||||
/* FC_CloseSession closes a session between an application and a token. */
|
||||
CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
|
||||
return NSC_CloseSession(hSession);
|
||||
}
|
||||
|
||||
|
||||
/* FC_CloseAllSessions closes all sessions with a token. */
|
||||
CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
|
||||
return NSC_CloseAllSessions (slotID);
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetSessionInfo obtains information about the session. */
|
||||
CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
|
||||
CK_SESSION_INFO_PTR pInfo) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
|
||||
rv = NSC_GetSessionInfo(hSession,pInfo);
|
||||
if (rv == CKR_OK) {
|
||||
if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
|
||||
pInfo->state = CKS_RO_USER_FUNCTIONS;
|
||||
}
|
||||
if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
|
||||
pInfo->state = CKS_RW_USER_FUNCTIONS;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* FC_Login logs a user into a token. */
|
||||
CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
|
||||
CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = NSC_Login(hSession,userType,pPin,usPinLen);
|
||||
if (rv == CKR_OK)
|
||||
isLoggedIn = PR_TRUE;
|
||||
else if (rv == CKR_USER_ALREADY_LOGGED_IN)
|
||||
{
|
||||
isLoggedIn = PR_TRUE;
|
||||
|
||||
/* Provide FIPS PUB 140-1 power-up self-tests on demand. */
|
||||
rv = sftk_fipsPowerUpSelfTest();
|
||||
if (rv == CKR_OK)
|
||||
return CKR_USER_ALREADY_LOGGED_IN;
|
||||
else
|
||||
fatalError = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* FC_Logout logs a user out from a token. */
|
||||
CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
|
||||
SFTK_FIPSCHECK();
|
||||
|
||||
rv = NSC_Logout(hSession);
|
||||
isLoggedIn = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* FC_CreateObject creates a new object. */
|
||||
CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
|
||||
CK_OBJECT_HANDLE_PTR phObject) {
|
||||
CK_OBJECT_CLASS * classptr;
|
||||
SFTK_FIPSCHECK();
|
||||
classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
|
||||
if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
|
||||
|
||||
/* FIPS can't create keys from raw key material */
|
||||
if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
return NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* FC_CopyObject copies an object, creating a new object for the copy. */
|
||||
CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount,
|
||||
CK_OBJECT_HANDLE_PTR phNewObject) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = fips_login_if_key_object(hSession, hObject);
|
||||
if (rv != CKR_OK) {
|
||||
return rv;
|
||||
}
|
||||
return NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DestroyObject destroys an object. */
|
||||
CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hObject) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = fips_login_if_key_object(hSession, hObject);
|
||||
if (rv != CKR_OK) {
|
||||
return rv;
|
||||
}
|
||||
return NSC_DestroyObject(hSession,hObject);
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetObjectSize gets the size of an object in bytes. */
|
||||
CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = fips_login_if_key_object(hSession, hObject);
|
||||
if (rv != CKR_OK) {
|
||||
return rv;
|
||||
}
|
||||
return NSC_GetObjectSize(hSession, hObject, pusSize);
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetAttributeValue obtains the value of one or more object attributes. */
|
||||
CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = fips_login_if_key_object(hSession, hObject);
|
||||
if (rv != CKR_OK) {
|
||||
return rv;
|
||||
}
|
||||
return NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SetAttributeValue modifies the value of one or more object attributes */
|
||||
CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
|
||||
CK_RV rv;
|
||||
SFTK_FIPSFATALCHECK();
|
||||
rv = fips_login_if_key_object(hSession, hObject);
|
||||
if (rv != CKR_OK) {
|
||||
return rv;
|
||||
}
|
||||
return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* FC_FindObjectsInit initializes a search for token and session objects
|
||||
* that match a template. */
|
||||
CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
|
||||
CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
|
||||
/* let publically readable object be found */
|
||||
int i;
|
||||
CK_RV rv;
|
||||
PRBool needLogin = PR_FALSE;
|
||||
|
||||
SFTK_FIPSFATALCHECK();
|
||||
|
||||
for (i=0; i < usCount; i++) {
|
||||
CK_OBJECT_CLASS class;
|
||||
if (pTemplate[i].type != CKA_CLASS) {
|
||||
continue;
|
||||
}
|
||||
if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
|
||||
continue;
|
||||
}
|
||||
if (pTemplate[i].pValue == NULL) {
|
||||
continue;
|
||||
}
|
||||
class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
|
||||
if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
|
||||
needLogin = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needLogin) {
|
||||
if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
|
||||
}
|
||||
return NSC_FindObjectsInit(hSession,pTemplate,usCount);
|
||||
}
|
||||
|
||||
|
||||
/* FC_FindObjects continues a search for token and session objects
|
||||
* that match a template, obtaining additional object handles. */
|
||||
CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
|
||||
CK_ULONG_PTR pusObjectCount) {
|
||||
/* let publically readable object be found */
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
|
||||
pusObjectCount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Encrypt ************************
|
||||
*/
|
||||
|
||||
/* FC_EncryptInit initializes an encryption operation. */
|
||||
CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_EncryptInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
/* FC_Encrypt encrypts single-part data. */
|
||||
CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
|
||||
CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
|
||||
CK_ULONG_PTR pusEncryptedDataLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
|
||||
pusEncryptedDataLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_EncryptUpdate continues a multiple-part encryption operation. */
|
||||
CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,
|
||||
CK_ULONG_PTR pusEncryptedPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
|
||||
pusEncryptedPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_EncryptFinal finishes a multiple-part encryption operation. */
|
||||
CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_EncryptFinal(hSession,pLastEncryptedPart,
|
||||
pusLastEncryptedPartLen);
|
||||
}
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Decrypt ************************
|
||||
*/
|
||||
|
||||
|
||||
/* FC_DecryptInit initializes a decryption operation. */
|
||||
CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DecryptInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
/* FC_Decrypt decrypts encrypted data in a single part. */
|
||||
CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
|
||||
CK_ULONG_PTR pusDataLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
|
||||
pusDataLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DecryptUpdate continues a multiple-part decryption operation. */
|
||||
CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
|
||||
CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
|
||||
pPart,pusPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DecryptFinal finishes a multiple-part decryption operation. */
|
||||
CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Digest (HASH) ************************
|
||||
*/
|
||||
|
||||
/* FC_DigestInit initializes a message-digesting operation. */
|
||||
CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_DigestInit(hSession, pMechanism);
|
||||
}
|
||||
|
||||
|
||||
/* FC_Digest digests data in a single part. */
|
||||
CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
|
||||
CK_ULONG_PTR pusDigestLen) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DigestUpdate continues a multiple-part message-digesting operation. */
|
||||
CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
|
||||
CK_ULONG usPartLen) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_DigestUpdate(hSession,pPart,usPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DigestFinal finishes a multiple-part message-digesting operation. */
|
||||
CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
|
||||
CK_ULONG_PTR pusDigestLen) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Sign ************************
|
||||
*/
|
||||
|
||||
/* FC_SignInit initializes a signature (private key encryption) operation,
|
||||
* where the signature is (will be) an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature */
|
||||
CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_Sign signs (encrypts with private key) data in a single part,
|
||||
* where the signature is (will be) an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature */
|
||||
CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
|
||||
CK_ULONG_PTR pusSignatureLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SignUpdate continues a multiple-part signature operation,
|
||||
* where the signature is (will be) an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature */
|
||||
CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
|
||||
CK_ULONG usPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignUpdate(hSession,pPart,usPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SignFinal finishes a multiple-part signature operation,
|
||||
* returning the signature. */
|
||||
CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
|
||||
CK_ULONG_PTR pusSignatureLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
|
||||
}
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Sign Recover ************************
|
||||
*/
|
||||
/* FC_SignRecoverInit initializes a signature operation,
|
||||
* where the (digest) data can be recovered from the signature.
|
||||
* E.g. encryption with the user's private key */
|
||||
CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignRecoverInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SignRecover signs data in a single operation
|
||||
* where the (digest) data can be recovered from the signature.
|
||||
* E.g. encryption with the user's private key */
|
||||
CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
|
||||
CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
|
||||
}
|
||||
|
||||
/*
|
||||
************** Crypto Functions: verify ************************
|
||||
*/
|
||||
|
||||
/* FC_VerifyInit initializes a verification operation,
|
||||
* where the signature is an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature (e.g. DSA) */
|
||||
CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_VerifyInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_Verify verifies a signature in a single-part operation,
|
||||
* where the signature is an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature */
|
||||
CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
|
||||
CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
|
||||
/* make sure we're legal */
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_VerifyUpdate continues a multiple-part verification operation,
|
||||
* where the signature is an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature */
|
||||
CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
|
||||
CK_ULONG usPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_VerifyUpdate(hSession,pPart,usPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_VerifyFinal finishes a multiple-part verification operation,
|
||||
* checking the signature. */
|
||||
CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
|
||||
}
|
||||
|
||||
/*
|
||||
************** Crypto Functions: Verify Recover ************************
|
||||
*/
|
||||
|
||||
/* FC_VerifyRecoverInit initializes a signature verification operation,
|
||||
* where the data is recovered from the signature.
|
||||
* E.g. Decryption with the user's public key */
|
||||
CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_VerifyRecover verifies a signature in a single-part operation,
|
||||
* where the data is recovered from the signature.
|
||||
* E.g. Decryption with the user's public key */
|
||||
CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
|
||||
CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
|
||||
pusDataLen);
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** Key Functions: ************************
|
||||
*/
|
||||
|
||||
/* FC_GenerateKey generates a secret key, creating a new key object. */
|
||||
CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
|
||||
CK_OBJECT_HANDLE_PTR phKey) {
|
||||
CK_BBOOL *boolptr;
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
|
||||
/* all secret keys must be sensitive, if the upper level code tries to say
|
||||
* otherwise, reject it. */
|
||||
boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
|
||||
if (boolptr != NULL) {
|
||||
if (!(*boolptr)) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_GenerateKeyPair generates a public-key/private-key pair,
|
||||
* creating new key objects. */
|
||||
CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
|
||||
CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
|
||||
CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
|
||||
CK_OBJECT_HANDLE_PTR phPrivateKey) {
|
||||
CK_BBOOL *boolptr;
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
|
||||
/* all private keys must be sensitive, if the upper level code tries to say
|
||||
* otherwise, reject it. */
|
||||
boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate,
|
||||
usPrivateKeyAttributeCount, CKA_SENSITIVE);
|
||||
if (boolptr != NULL) {
|
||||
if (!(*boolptr)) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
return NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
|
||||
usPublicKeyAttributeCount,pPrivateKeyTemplate,
|
||||
usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_WrapKey wraps (i.e., encrypts) a key. */
|
||||
CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
|
||||
CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
|
||||
CK_ULONG_PTR pusWrappedKeyLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
|
||||
pusWrappedKeyLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
|
||||
CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
|
||||
CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount,
|
||||
CK_OBJECT_HANDLE_PTR phKey) {
|
||||
CK_BBOOL *boolptr;
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
|
||||
/* all secret keys must be sensitive, if the upper level code tries to say
|
||||
* otherwise, reject it. */
|
||||
boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
|
||||
usAttributeCount, CKA_SENSITIVE);
|
||||
if (boolptr != NULL) {
|
||||
if (!(*boolptr)) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
|
||||
usWrappedKeyLen,pTemplate,usAttributeCount,phKey);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DeriveKey derives a key from a base key, creating a new key object. */
|
||||
CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount,
|
||||
CK_OBJECT_HANDLE_PTR phKey) {
|
||||
CK_BBOOL *boolptr;
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
|
||||
/* all secret keys must be sensitive, if the upper level code tries to say
|
||||
* otherwise, reject it. */
|
||||
boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
|
||||
usAttributeCount, CKA_SENSITIVE);
|
||||
if (boolptr != NULL) {
|
||||
if (!(*boolptr)) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
|
||||
usAttributeCount, phKey);
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** Radom Functions: ************************
|
||||
*/
|
||||
|
||||
/* FC_SeedRandom mixes additional seed material into the token's random number
|
||||
* generator. */
|
||||
CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
|
||||
CK_ULONG usSeedLen) {
|
||||
CK_RV crv;
|
||||
|
||||
SFTK_FIPSFATALCHECK();
|
||||
crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
|
||||
if (crv != CKR_OK) {
|
||||
fatalError = PR_TRUE;
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
|
||||
/* FC_GenerateRandom generates random data. */
|
||||
CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) {
|
||||
CK_RV crv;
|
||||
|
||||
SFTK_FIPSFATALCHECK();
|
||||
crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen);
|
||||
if (crv != CKR_OK) {
|
||||
fatalError = PR_TRUE;
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
|
||||
/* FC_GetFunctionStatus obtains an updated status of a function running
|
||||
* in parallel with an application. */
|
||||
CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_GetFunctionStatus(hSession);
|
||||
}
|
||||
|
||||
|
||||
/* FC_CancelFunction cancels a function running in parallel */
|
||||
CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_CancelFunction(hSession);
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** Version 1.1 Functions: ************************
|
||||
*/
|
||||
|
||||
/* FC_GetOperationState saves the state of the cryptographic
|
||||
*operation in a session. */
|
||||
CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_SetOperationState restores the state of the cryptographic operation
|
||||
* in a session. */
|
||||
CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
|
||||
CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
|
||||
hEncryptionKey,hAuthenticationKey);
|
||||
}
|
||||
|
||||
/* FC_FindObjectsFinal finishes a search for token and session objects. */
|
||||
CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
|
||||
/* let publically readable object be found */
|
||||
SFTK_FIPSFATALCHECK();
|
||||
return NSC_FindObjectsFinal(hSession);
|
||||
}
|
||||
|
||||
|
||||
/* Dual-function cryptographic operations */
|
||||
|
||||
/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption
|
||||
* operation. */
|
||||
CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
|
||||
CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
|
||||
CK_ULONG_PTR pulEncryptedPartLen) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
|
||||
pulEncryptedPartLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting
|
||||
* operation. */
|
||||
CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
|
||||
CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) {
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
|
||||
pPart,pulPartLen);
|
||||
}
|
||||
|
||||
/* FC_SignEncryptUpdate continues a multiple-part signing and encryption
|
||||
* operation. */
|
||||
CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
|
||||
CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
|
||||
CK_ULONG_PTR pulEncryptedPartLen) {
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
|
||||
pulEncryptedPartLen);
|
||||
}
|
||||
|
||||
/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify
|
||||
* operation. */
|
||||
CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
|
||||
CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) {
|
||||
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
|
||||
pData,pulDataLen);
|
||||
}
|
||||
|
||||
|
||||
/* FC_DigestKey continues a multi-part message-digesting operation,
|
||||
* by digesting the value of a secret key as part of the data already digested.
|
||||
*/
|
||||
CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
|
||||
SFTK_FIPSCHECK();
|
||||
return NSC_DigestKey(hSession,hKey);
|
||||
}
|
||||
|
||||
|
||||
CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
|
||||
CK_VOID_PTR pReserved)
|
||||
{
|
||||
return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* private.h - Private data structures for the software token library
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: keydbi.h,v 1.6 2004-04-27 23:04:38 gerv%gerv.net Exp $ */
|
||||
|
||||
#ifndef _KEYDBI_H_
|
||||
#define _KEYDBI_H_
|
||||
|
||||
#include "nspr.h"
|
||||
#include "seccomon.h"
|
||||
#include "mcom_db.h"
|
||||
|
||||
/*
|
||||
* Handle structure for open key databases
|
||||
*/
|
||||
struct NSSLOWKEYDBHandleStr {
|
||||
DB *db;
|
||||
DB *updatedb; /* used when updating an old version */
|
||||
SECItem *global_salt; /* password hashing salt for this db */
|
||||
int version; /* version of the database */
|
||||
char *appname; /* multiaccess app name */
|
||||
char *dbname; /* name of the openned DB */
|
||||
PRBool readOnly; /* is the DB read only */
|
||||
};
|
||||
|
||||
/*
|
||||
** Typedef for callback for traversing key database.
|
||||
** "key" is the key used to index the data in the database (nickname)
|
||||
** "data" is the key data
|
||||
** "pdata" is the user's data
|
||||
*/
|
||||
typedef SECStatus (* NSSLOWKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
|
||||
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
** Traverse the entire key database, and pass the nicknames and keys to a
|
||||
** user supplied function.
|
||||
** "f" is the user function to call for each key
|
||||
** "udata" is the user's data, which is passed through to "f"
|
||||
*/
|
||||
extern SECStatus nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
|
||||
NSSLOWKEYTraverseKeysFunc f,
|
||||
void *udata);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _KEYDBI_H_ */
|
||||
@@ -1,625 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Certificate handling code
|
||||
*
|
||||
* $Id: lowcert.c,v 1.18 2004-04-25 15:03:16 gerv%gerv.net Exp $
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secder.h"
|
||||
#include "nssilock.h"
|
||||
#include "prmon.h"
|
||||
#include "prtime.h"
|
||||
#include "lowkeyi.h"
|
||||
#include "pcert.h"
|
||||
#include "secasn1.h"
|
||||
#include "secoid.h"
|
||||
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
extern SECStatus EC_FillParams(PRArenaPool *arena,
|
||||
const SECItem *encodedParams,
|
||||
ECParams *params);
|
||||
#endif
|
||||
|
||||
static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) },
|
||||
{ SEC_ASN1_INLINE, offsetof(NSSLOWCERTSubjectPublicKeyInfo,algorithm),
|
||||
SECOID_AlgorithmIDTemplate },
|
||||
{ SEC_ASN1_BIT_STRING,
|
||||
offsetof(NSSLOWCERTSubjectPublicKeyInfo,subjectPublicKey), },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template nsslowcert_RSAPublicKeyTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.modulus), },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.publicExponent), },
|
||||
{ 0, }
|
||||
};
|
||||
static const SEC_ASN1Template nsslowcert_DSAPublicKeyTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dsa.publicValue), },
|
||||
{ 0, }
|
||||
};
|
||||
static const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dh.publicValue), },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/*
|
||||
* See bugzilla bug 125359
|
||||
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||
* all of the templates above that en/decode into integers must be converted
|
||||
* from ASN.1's signed integer type. This is done by marking either the
|
||||
* source or destination (encoding or decoding, respectively) type as
|
||||
* siUnsignedInteger.
|
||||
*/
|
||||
|
||||
static void
|
||||
prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||
{
|
||||
pubk->u.rsa.modulus.type = siUnsignedInteger;
|
||||
pubk->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_low_dsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||
{
|
||||
pubk->u.dsa.publicValue.type = siUnsignedInteger;
|
||||
pubk->u.dsa.params.prime.type = siUnsignedInteger;
|
||||
pubk->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||
pubk->u.dsa.params.base.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
static void
|
||||
prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
|
||||
{
|
||||
pubk->u.dh.prime.type = siUnsignedInteger;
|
||||
pubk->u.dh.base.type = siUnsignedInteger;
|
||||
pubk->u.dh.publicValue.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow use of default cert database, so that apps(such as mozilla) don't
|
||||
* have to pass the handle all over the place.
|
||||
*/
|
||||
static NSSLOWCERTCertDBHandle *default_pcert_db_handle = 0;
|
||||
|
||||
void
|
||||
nsslowcert_SetDefaultCertDB(NSSLOWCERTCertDBHandle *handle)
|
||||
{
|
||||
default_pcert_db_handle = handle;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSSLOWCERTCertDBHandle *
|
||||
nsslowcert_GetDefaultCertDB(void)
|
||||
{
|
||||
return(default_pcert_db_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* simple cert decoder to avoid the cost of asn1 engine
|
||||
*/
|
||||
static unsigned char *
|
||||
nsslowcert_dataStart(unsigned char *buf, unsigned int length,
|
||||
unsigned int *data_length, PRBool includeTag,
|
||||
unsigned char* rettag) {
|
||||
unsigned char tag;
|
||||
unsigned int used_length= 0;
|
||||
|
||||
tag = buf[used_length++];
|
||||
|
||||
if (rettag) {
|
||||
*rettag = tag;
|
||||
}
|
||||
|
||||
/* blow out when we come to the end */
|
||||
if (tag == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*data_length = buf[used_length++];
|
||||
|
||||
if (*data_length&0x80) {
|
||||
int len_count = *data_length & 0x7f;
|
||||
|
||||
*data_length = 0;
|
||||
|
||||
while (len_count-- > 0) {
|
||||
*data_length = (*data_length << 8) | buf[used_length++];
|
||||
}
|
||||
}
|
||||
|
||||
if (*data_length > (length-used_length) ) {
|
||||
*data_length = length-used_length;
|
||||
return NULL;
|
||||
}
|
||||
if (includeTag) *data_length += used_length;
|
||||
|
||||
return (buf + (includeTag ? 0 : used_length));
|
||||
}
|
||||
|
||||
static void SetTimeType(SECItem* item, unsigned char tagtype)
|
||||
{
|
||||
switch (tagtype) {
|
||||
case SEC_ASN1_UTC_TIME:
|
||||
item->type = siUTCTime;
|
||||
break;
|
||||
|
||||
case SEC_ASN1_GENERALIZED_TIME:
|
||||
item->type = siGeneralizedTime;
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nsslowcert_GetValidityFields(unsigned char *buf,int buf_length,
|
||||
SECItem *notBefore, SECItem *notAfter)
|
||||
{
|
||||
unsigned char tagtype;
|
||||
notBefore->data = nsslowcert_dataStart(buf,buf_length,
|
||||
¬Before->len,PR_FALSE, &tagtype);
|
||||
if (notBefore->data == NULL) return SECFailure;
|
||||
SetTimeType(notBefore, tagtype);
|
||||
buf_length -= (notBefore->data-buf) + notBefore->len;
|
||||
buf = notBefore->data + notBefore->len;
|
||||
notAfter->data = nsslowcert_dataStart(buf,buf_length,
|
||||
¬After->len,PR_FALSE, &tagtype);
|
||||
if (notAfter->data == NULL) return SECFailure;
|
||||
SetTimeType(notAfter, tagtype);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
nsslowcert_GetCertFields(unsigned char *cert,int cert_length,
|
||||
SECItem *issuer, SECItem *serial, SECItem *derSN, SECItem *subject,
|
||||
SECItem *valid, SECItem *subjkey)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned int buf_length;
|
||||
unsigned char *dummy;
|
||||
unsigned int dummylen;
|
||||
|
||||
/* get past the signature wrap */
|
||||
buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE, NULL);
|
||||
if (buf == NULL) return SECFailure;
|
||||
/* get into the raw cert data */
|
||||
buf = nsslowcert_dataStart(buf,buf_length,&buf_length,PR_FALSE, NULL);
|
||||
if (buf == NULL) return SECFailure;
|
||||
/* skip past any optional version number */
|
||||
if ((buf[0] & 0xa0) == 0xa0) {
|
||||
dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL);
|
||||
if (dummy == NULL) return SECFailure;
|
||||
buf_length -= (dummy-buf) + dummylen;
|
||||
buf = dummy + dummylen;
|
||||
}
|
||||
/* serial number */
|
||||
if (derSN) {
|
||||
derSN->data=nsslowcert_dataStart(buf,buf_length,&derSN->len,PR_TRUE, NULL);
|
||||
}
|
||||
serial->data = nsslowcert_dataStart(buf,buf_length,&serial->len,PR_FALSE, NULL);
|
||||
if (serial->data == NULL) return SECFailure;
|
||||
buf_length -= (serial->data-buf) + serial->len;
|
||||
buf = serial->data + serial->len;
|
||||
/* skip the OID */
|
||||
dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL);
|
||||
if (dummy == NULL) return SECFailure;
|
||||
buf_length -= (dummy-buf) + dummylen;
|
||||
buf = dummy + dummylen;
|
||||
/* issuer */
|
||||
issuer->data = nsslowcert_dataStart(buf,buf_length,&issuer->len,PR_TRUE, NULL);
|
||||
if (issuer->data == NULL) return SECFailure;
|
||||
buf_length -= (issuer->data-buf) + issuer->len;
|
||||
buf = issuer->data + issuer->len;
|
||||
|
||||
/* only wanted issuer/SN */
|
||||
if (valid == NULL) {
|
||||
return SECSuccess;
|
||||
}
|
||||
/* validity */
|
||||
valid->data = nsslowcert_dataStart(buf,buf_length,&valid->len,PR_FALSE, NULL);
|
||||
if (valid->data == NULL) return SECFailure;
|
||||
buf_length -= (valid->data-buf) + valid->len;
|
||||
buf = valid->data + valid->len;
|
||||
/*subject */
|
||||
subject->data=nsslowcert_dataStart(buf,buf_length,&subject->len,PR_TRUE, NULL);
|
||||
if (subject->data == NULL) return SECFailure;
|
||||
buf_length -= (subject->data-buf) + subject->len;
|
||||
buf = subject->data + subject->len;
|
||||
/* subject key info */
|
||||
subjkey->data=nsslowcert_dataStart(buf,buf_length,&subjkey->len,PR_TRUE, NULL);
|
||||
if (subjkey->data == NULL) return SECFailure;
|
||||
buf_length -= (subjkey->data-buf) + subjkey->len;
|
||||
buf = subjkey->data + subjkey->len;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
|
||||
{
|
||||
int rv;
|
||||
NSSLOWCERTValidity validity;
|
||||
|
||||
rv = nsslowcert_GetValidityFields(c->validity.data,c->validity.len,
|
||||
&validity.notBefore,&validity.notAfter);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* convert DER not-before time */
|
||||
rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore);
|
||||
if (rv) {
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
/* convert DER not-after time */
|
||||
rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter);
|
||||
if (rv) {
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
return(SECSuccess);
|
||||
}
|
||||
|
||||
/*
|
||||
* is certa newer than certb? If one is expired, pick the other one.
|
||||
*/
|
||||
PRBool
|
||||
nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
|
||||
{
|
||||
PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
|
||||
SECStatus rv;
|
||||
PRBool newerbefore, newerafter;
|
||||
|
||||
rv = nsslowcert_GetCertTimes(certa, ¬BeforeA, ¬AfterA);
|
||||
if ( rv != SECSuccess ) {
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
rv = nsslowcert_GetCertTimes(certb, ¬BeforeB, ¬AfterB);
|
||||
if ( rv != SECSuccess ) {
|
||||
return(PR_TRUE);
|
||||
}
|
||||
|
||||
newerbefore = PR_FALSE;
|
||||
if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
|
||||
newerbefore = PR_TRUE;
|
||||
}
|
||||
|
||||
newerafter = PR_FALSE;
|
||||
if ( LL_CMP(notAfterA, >, notAfterB) ) {
|
||||
newerafter = PR_TRUE;
|
||||
}
|
||||
|
||||
if ( newerbefore && newerafter ) {
|
||||
return(PR_TRUE);
|
||||
}
|
||||
|
||||
if ( ( !newerbefore ) && ( !newerafter ) ) {
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
/* get current time */
|
||||
now = PR_Now();
|
||||
|
||||
if ( newerbefore ) {
|
||||
/* cert A was issued after cert B, but expires sooner */
|
||||
/* if A is expired, then pick B */
|
||||
if ( LL_CMP(notAfterA, <, now ) ) {
|
||||
return(PR_FALSE);
|
||||
}
|
||||
return(PR_TRUE);
|
||||
} else {
|
||||
/* cert B was issued after cert A, but expires sooner */
|
||||
/* if B is expired, then pick A */
|
||||
if ( LL_CMP(notAfterB, <, now ) ) {
|
||||
return(PR_TRUE);
|
||||
}
|
||||
return(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
#define SOFT_DEFAULT_CHUNKSIZE 2048
|
||||
|
||||
|
||||
static SECStatus
|
||||
nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
|
||||
SECItem *key)
|
||||
{
|
||||
unsigned int len = sn->len + issuer->len;
|
||||
|
||||
|
||||
if (arena) {
|
||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
|
||||
} else {
|
||||
if (len > key->len) {
|
||||
key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
|
||||
}
|
||||
}
|
||||
if ( !key->data ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
key->len = len;
|
||||
/* copy the serialNumber */
|
||||
PORT_Memcpy(key->data, sn->data, sn->len);
|
||||
|
||||
/* copy the issuer */
|
||||
PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
|
||||
|
||||
return(SECSuccess);
|
||||
|
||||
loser:
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* take a DER certificate and decode it into a certificate structure
|
||||
*/
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
|
||||
{
|
||||
NSSLOWCERTCertificate *cert;
|
||||
int rv;
|
||||
|
||||
/* allocate the certificate structure */
|
||||
cert = nsslowcert_CreateCert();
|
||||
|
||||
if ( !cert ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* point to passed in DER data */
|
||||
cert->derCert = *derSignedCert;
|
||||
cert->nickname = NULL;
|
||||
cert->certKey.data = NULL;
|
||||
cert->referenceCount = 1;
|
||||
|
||||
/* decode the certificate info */
|
||||
rv = nsslowcert_GetCertFields(cert->derCert.data, cert->derCert.len,
|
||||
&cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject,
|
||||
&cert->validity, &cert->derSubjKeyInfo);
|
||||
|
||||
/* cert->subjectKeyID; x509v3 subject key identifier */
|
||||
cert->subjectKeyID.data = NULL;
|
||||
cert->subjectKeyID.len = 0;
|
||||
cert->dbEntry = NULL;
|
||||
cert ->trust = NULL;
|
||||
|
||||
/* generate and save the database key for the cert */
|
||||
cert->certKey.data = cert->certKeySpace;
|
||||
cert->certKey.len = sizeof(cert->certKeySpace);
|
||||
rv = nsslowcert_KeyFromIssuerAndSN(NULL, &cert->derIssuer,
|
||||
&cert->serialNumber, &cert->certKey);
|
||||
if ( rv ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the nickname */
|
||||
if ( nickname == NULL ) {
|
||||
cert->nickname = NULL;
|
||||
} else {
|
||||
/* copy and install the nickname */
|
||||
cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
|
||||
sizeof(cert->nicknameSpace));
|
||||
}
|
||||
|
||||
#ifdef FIXME
|
||||
/* initialize the subjectKeyID */
|
||||
rv = cert_GetKeyID(cert);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the email address */
|
||||
cert->emailAddr = CERT_GetCertificateEmailAddress(cert);
|
||||
|
||||
#endif
|
||||
|
||||
cert->referenceCount = 1;
|
||||
|
||||
return(cert);
|
||||
|
||||
loser:
|
||||
if (cert) {
|
||||
nsslowcert_DestroyCertificate(cert);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
char *
|
||||
nsslowcert_FixupEmailAddr(char *emailAddr)
|
||||
{
|
||||
char *retaddr;
|
||||
char *str;
|
||||
|
||||
if ( emailAddr == NULL ) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* copy the string */
|
||||
str = retaddr = PORT_Strdup(emailAddr);
|
||||
if ( str == NULL ) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* make it lower case */
|
||||
while ( *str ) {
|
||||
*str = tolower( *str );
|
||||
str++;
|
||||
}
|
||||
|
||||
return(retaddr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate a database key, based on serial number and issuer, from a
|
||||
* DER certificate.
|
||||
*/
|
||||
SECStatus
|
||||
nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key)
|
||||
{
|
||||
int rv;
|
||||
NSSLOWCERTCertKey certkey;
|
||||
|
||||
PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
|
||||
|
||||
rv = nsslowcert_GetCertFields(derCert->data, derCert->len,
|
||||
&certkey.derIssuer, &certkey.serialNumber, NULL, NULL, NULL, NULL);
|
||||
|
||||
if ( rv ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return(nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
|
||||
&certkey.serialNumber, key));
|
||||
loser:
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
NSSLOWKEYPublicKey *
|
||||
nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
|
||||
{
|
||||
NSSLOWCERTSubjectPublicKeyInfo spki;
|
||||
NSSLOWKEYPublicKey *pubk;
|
||||
SECItem os;
|
||||
SECStatus rv;
|
||||
PRArenaPool *arena;
|
||||
SECOidTag tag;
|
||||
SECItem newDerSubjKeyInfo;
|
||||
|
||||
arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
return NULL;
|
||||
|
||||
pubk = (NSSLOWKEYPublicKey *)
|
||||
PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
|
||||
if (pubk == NULL) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pubk->arena = arena;
|
||||
PORT_Memset(&spki,0,sizeof(spki));
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newDerSubjKeyInfo, &cert->derSubjKeyInfo);
|
||||
if ( rv != SECSuccess ) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we haven't bothered decoding the spki struct yet, do it now */
|
||||
rv = SEC_QuickDERDecodeItem(arena, &spki,
|
||||
nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert bit string length from bits to bytes */
|
||||
os = spki.subjectPublicKey;
|
||||
DER_ConvertBitString (&os);
|
||||
|
||||
tag = SECOID_GetAlgorithmTag(&spki.algorithm);
|
||||
switch ( tag ) {
|
||||
case SEC_OID_X500_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
pubk->keyType = NSSLOWKEYRSAKey;
|
||||
prepare_low_rsa_pub_key_for_asn1(pubk);
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk,
|
||||
nsslowcert_RSAPublicKeyTemplate, &os);
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
break;
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
pubk->keyType = NSSLOWKEYDSAKey;
|
||||
prepare_low_dsa_pub_key_for_asn1(pubk);
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk,
|
||||
nsslowcert_DSAPublicKeyTemplate, &os);
|
||||
if (rv == SECSuccess) return pubk;
|
||||
break;
|
||||
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
|
||||
pubk->keyType = NSSLOWKEYDHKey;
|
||||
prepare_low_dh_pub_key_for_asn1(pubk);
|
||||
rv = SEC_QuickDERDecodeItem(arena, pubk,
|
||||
nsslowcert_DHPublicKeyTemplate, &os);
|
||||
if (rv == SECSuccess) return pubk;
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
pubk->keyType = NSSLOWKEYECKey;
|
||||
/* Since PKCS#11 directly takes the DER encoding of EC params
|
||||
* and public value, we don't need any decoding here.
|
||||
*/
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.ec.ecParams.DEREncoding,
|
||||
&spki.algorithm.parameters);
|
||||
if ( rv != SECSuccess )
|
||||
break;
|
||||
|
||||
/* Fill out the rest of the ecParams structure
|
||||
* based on the encoded params
|
||||
*/
|
||||
if (EC_FillParams(arena, &pubk->u.ec.ecParams.DEREncoding,
|
||||
&pubk->u.ec.ecParams) != SECSuccess)
|
||||
break;
|
||||
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &os);
|
||||
if (rv == SECSuccess) return pubk;
|
||||
break;
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
default:
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
nsslowkey_DestroyPublicKey (pubk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,492 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "lowkeyi.h"
|
||||
#include "secoid.h"
|
||||
#include "secitem.h"
|
||||
#include "secder.h"
|
||||
#include "base64.h"
|
||||
#include "secasn1.h"
|
||||
#include "pcert.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
extern SECStatus EC_CopyParams(PRArenaPool *arena,
|
||||
ECParams *dstParams,
|
||||
const ECParams *srcParams);
|
||||
#endif
|
||||
|
||||
const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(PQGParams,base) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
|
||||
};
|
||||
|
||||
const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
|
||||
/* XXX This is just a placeholder for later when we support
|
||||
* generic curves and need full-blown support for parsing EC
|
||||
* parameters. For now, we only support named curves in which
|
||||
* EC params are simply encoded as an object ID and we don't
|
||||
* use nsslowkey_ECParamsTemplate.
|
||||
*/
|
||||
const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = {
|
||||
{ SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) },
|
||||
{ SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
|
||||
/* NOTE: The SECG specification allows the private key structure
|
||||
* to contain curve parameters but recommends that they be stored
|
||||
* in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
|
||||
* instead.
|
||||
*/
|
||||
const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) },
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) },
|
||||
/* XXX The following template works for now since we only
|
||||
* support named curves for which the parameters are
|
||||
* encoded as an object ID. When we support generic curves,
|
||||
* we'll need to define nsslowkey_ECParamsTemplate
|
||||
*/
|
||||
#if 1
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID),
|
||||
SEC_ObjectIDTemplate },
|
||||
#else
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams),
|
||||
nsslowkey_ECParamsTemplate },
|
||||
#endif
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue),
|
||||
SEC_BitStringTemplate },
|
||||
{ 0, }
|
||||
};
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
/*
|
||||
* See bugzilla bug 125359
|
||||
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||
* all of the templates above that en/decode into integers must be converted
|
||||
* from ASN.1's signed integer type. This is done by marking either the
|
||||
* source or destination (encoding or decoding, respectively) type as
|
||||
* siUnsignedInteger.
|
||||
*/
|
||||
|
||||
void
|
||||
prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||
{
|
||||
key->u.rsa.modulus.type = siUnsignedInteger;
|
||||
key->u.rsa.publicExponent.type = siUnsignedInteger;
|
||||
key->u.rsa.privateExponent.type = siUnsignedInteger;
|
||||
key->u.rsa.prime1.type = siUnsignedInteger;
|
||||
key->u.rsa.prime2.type = siUnsignedInteger;
|
||||
key->u.rsa.exponent1.type = siUnsignedInteger;
|
||||
key->u.rsa.exponent2.type = siUnsignedInteger;
|
||||
key->u.rsa.coefficient.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
void
|
||||
prepare_low_pqg_params_for_asn1(PQGParams *params)
|
||||
{
|
||||
params->prime.type = siUnsignedInteger;
|
||||
params->subPrime.type = siUnsignedInteger;
|
||||
params->base.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
void
|
||||
prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||
{
|
||||
key->u.dsa.publicValue.type = siUnsignedInteger;
|
||||
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||
key->u.dsa.params.prime.type = siUnsignedInteger;
|
||||
key->u.dsa.params.subPrime.type = siUnsignedInteger;
|
||||
key->u.dsa.params.base.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
void
|
||||
prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||
{
|
||||
key->u.dsa.privateValue.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
void
|
||||
prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||
{
|
||||
key->u.dh.prime.type = siUnsignedInteger;
|
||||
key->u.dh.base.type = siUnsignedInteger;
|
||||
key->u.dh.publicValue.type = siUnsignedInteger;
|
||||
key->u.dh.privateValue.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
void
|
||||
prepare_low_ecparams_for_asn1(ECParams *params)
|
||||
{
|
||||
params->DEREncoding.type = siUnsignedInteger;
|
||||
params->curveOID.type = siUnsignedInteger;
|
||||
}
|
||||
|
||||
void
|
||||
prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
|
||||
{
|
||||
key->u.ec.version.type = siUnsignedInteger;
|
||||
key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
|
||||
key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
|
||||
key->u.ec.privateValue.type = siUnsignedInteger;
|
||||
key->u.ec.publicValue.type = siUnsignedInteger;
|
||||
}
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
|
||||
void
|
||||
nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
|
||||
{
|
||||
if (privk && privk->arena) {
|
||||
PORT_FreeArena(privk->arena, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
|
||||
{
|
||||
if (pubk && pubk->arena) {
|
||||
PORT_FreeArena(pubk->arena, PR_FALSE);
|
||||
}
|
||||
}
|
||||
unsigned
|
||||
nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
|
||||
{
|
||||
unsigned char b0;
|
||||
|
||||
/* interpret modulus length as key strength... in
|
||||
* fortezza that's the public key length */
|
||||
|
||||
switch (pubk->keyType) {
|
||||
case NSSLOWKEYRSAKey:
|
||||
b0 = pubk->u.rsa.modulus.data[0];
|
||||
return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
|
||||
{
|
||||
|
||||
unsigned char b0;
|
||||
|
||||
switch (privk->keyType) {
|
||||
case NSSLOWKEYRSAKey:
|
||||
b0 = privk->u.rsa.modulus.data[0];
|
||||
return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NSSLOWKEYPublicKey *
|
||||
nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
|
||||
{
|
||||
NSSLOWKEYPublicKey *pubk;
|
||||
PLArenaPool *arena;
|
||||
|
||||
|
||||
arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL) {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(privk->keyType) {
|
||||
case NSSLOWKEYRSAKey:
|
||||
case NSSLOWKEYNullKey:
|
||||
pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof (NSSLOWKEYPublicKey));
|
||||
if (pubk != NULL) {
|
||||
SECStatus rv;
|
||||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
if (privk->keyType == NSSLOWKEYNullKey) return pubk;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
|
||||
&privk->u.rsa.modulus);
|
||||
if (rv == SECSuccess) {
|
||||
rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
|
||||
&privk->u.rsa.publicExponent);
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
}
|
||||
nsslowkey_DestroyPublicKey (pubk);
|
||||
} else {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
}
|
||||
break;
|
||||
case NSSLOWKEYDSAKey:
|
||||
pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof(NSSLOWKEYPublicKey));
|
||||
if (pubk != NULL) {
|
||||
SECStatus rv;
|
||||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
|
||||
&privk->u.dsa.publicValue);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
|
||||
&privk->u.dsa.params.prime);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
|
||||
&privk->u.dsa.params.subPrime);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
|
||||
&privk->u.dsa.params.base);
|
||||
if (rv == SECSuccess) return pubk;
|
||||
}
|
||||
break;
|
||||
case NSSLOWKEYDHKey:
|
||||
pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof(NSSLOWKEYPublicKey));
|
||||
if (pubk != NULL) {
|
||||
SECStatus rv;
|
||||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
|
||||
&privk->u.dh.publicValue);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
|
||||
&privk->u.dh.prime);
|
||||
if (rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
|
||||
&privk->u.dh.base);
|
||||
if (rv == SECSuccess) return pubk;
|
||||
}
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
case NSSLOWKEYECKey:
|
||||
pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof(NSSLOWKEYPublicKey));
|
||||
if (pubk != NULL) {
|
||||
SECStatus rv;
|
||||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
|
||||
&privk->u.ec.publicValue);
|
||||
if (rv != SECSuccess) break;
|
||||
pubk->u.ec.ecParams.arena = arena;
|
||||
/* Copy the rest of the params */
|
||||
rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams),
|
||||
&(privk->u.ec.ecParams));
|
||||
if (rv == SECSuccess) return pubk;
|
||||
}
|
||||
break;
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
/* No Fortezza in Low Key implementations (Fortezza keys aren't
|
||||
* stored in our data base */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSSLOWKEYPrivateKey *
|
||||
nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
|
||||
{
|
||||
NSSLOWKEYPrivateKey *returnKey = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
PLArenaPool *poolp;
|
||||
|
||||
if(!privKey) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if(!poolp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
|
||||
if(!returnKey) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
returnKey->keyType = privKey->keyType;
|
||||
returnKey->arena = poolp;
|
||||
|
||||
switch(privKey->keyType) {
|
||||
case NSSLOWKEYRSAKey:
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
|
||||
&(privKey->u.rsa.modulus));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version),
|
||||
&(privKey->u.rsa.version));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent),
|
||||
&(privKey->u.rsa.publicExponent));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent),
|
||||
&(privKey->u.rsa.privateExponent));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1),
|
||||
&(privKey->u.rsa.prime1));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2),
|
||||
&(privKey->u.rsa.prime2));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1),
|
||||
&(privKey->u.rsa.exponent1));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2),
|
||||
&(privKey->u.rsa.exponent2));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient),
|
||||
&(privKey->u.rsa.coefficient));
|
||||
if(rv != SECSuccess) break;
|
||||
break;
|
||||
case NSSLOWKEYDSAKey:
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
|
||||
&(privKey->u.dsa.publicValue));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue),
|
||||
&(privKey->u.dsa.privateValue));
|
||||
if(rv != SECSuccess) break;
|
||||
returnKey->u.dsa.params.arena = poolp;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime),
|
||||
&(privKey->u.dsa.params.prime));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime),
|
||||
&(privKey->u.dsa.params.subPrime));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base),
|
||||
&(privKey->u.dsa.params.base));
|
||||
if(rv != SECSuccess) break;
|
||||
break;
|
||||
case NSSLOWKEYDHKey:
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
|
||||
&(privKey->u.dh.publicValue));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue),
|
||||
&(privKey->u.dh.privateValue));
|
||||
if(rv != SECSuccess) break;
|
||||
returnKey->u.dsa.params.arena = poolp;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime),
|
||||
&(privKey->u.dh.prime));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base),
|
||||
&(privKey->u.dh.base));
|
||||
if(rv != SECSuccess) break;
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
case NSSLOWKEYECKey:
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version),
|
||||
&(privKey->u.ec.version));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue),
|
||||
&(privKey->u.ec.publicValue));
|
||||
if(rv != SECSuccess) break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue),
|
||||
&(privKey->u.ec.privateValue));
|
||||
if(rv != SECSuccess) break;
|
||||
returnKey->u.ec.ecParams.arena = poolp;
|
||||
/* Copy the rest of the params */
|
||||
rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams),
|
||||
&(privKey->u.ec.ecParams));
|
||||
if (rv != SECSuccess) break;
|
||||
break;
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
default:
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
loser:
|
||||
|
||||
if(rv != SECSuccess) {
|
||||
PORT_FreeArena(poolp, PR_TRUE);
|
||||
returnKey = NULL;
|
||||
}
|
||||
|
||||
return returnKey;
|
||||
}
|
||||
@@ -1,274 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: lowkeyi.h,v 1.10 2004-04-27 23:04:38 gerv%gerv.net Exp $ */
|
||||
|
||||
#ifndef _LOWKEYI_H_
|
||||
#define _LOWKEYI_H_
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
#include "pcertt.h"
|
||||
#include "lowkeyti.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
* See bugzilla bug 125359
|
||||
* Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
|
||||
* all of the templates above that en/decode into integers must be converted
|
||||
* from ASN.1's signed integer type. This is done by marking either the
|
||||
* source or destination (encoding or decoding, respectively) type as
|
||||
* siUnsignedInteger.
|
||||
*/
|
||||
extern void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||
extern void prepare_low_pqg_params_for_asn1(PQGParams *params);
|
||||
extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||
extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||
extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
|
||||
extern void prepare_low_ecparams_for_asn1(ECParams *params);
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
|
||||
typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
|
||||
|
||||
/*
|
||||
** Open a key database.
|
||||
*/
|
||||
extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDB(PRBool readOnly,
|
||||
const char *domain,
|
||||
const char *prefix,
|
||||
NSSLOWKEYDBNameFunc namecb,
|
||||
void *cbarg);
|
||||
|
||||
|
||||
/*
|
||||
* Clear out all the keys in the existing database
|
||||
*/
|
||||
extern SECStatus nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle);
|
||||
|
||||
/*
|
||||
** Close the specified key database.
|
||||
*/
|
||||
extern void nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle);
|
||||
|
||||
/*
|
||||
* Get the version number of the database
|
||||
*/
|
||||
extern int nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle);
|
||||
|
||||
/*
|
||||
** Support a default key database.
|
||||
*/
|
||||
extern void nsslowkey_SetDefaultKeyDB(NSSLOWKEYDBHandle *handle);
|
||||
extern NSSLOWKEYDBHandle *nsslowkey_GetDefaultKeyDB(void);
|
||||
|
||||
/* set the alg id of the key encryption algorithm */
|
||||
extern void nsslowkey_SetDefaultKeyDBAlg(SECOidTag alg);
|
||||
|
||||
/*
|
||||
* given a password and salt, produce a hash of the password
|
||||
*/
|
||||
extern SECItem *nsslowkey_HashPassword(char *pw, SECItem *salt);
|
||||
|
||||
/*
|
||||
* Derive the actual password value for a key database from the
|
||||
* password string value. The derivation uses global salt value
|
||||
* stored in the key database.
|
||||
*/
|
||||
extern SECItem *
|
||||
nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *handle, char *pw);
|
||||
|
||||
/*
|
||||
** Delete a key from the database
|
||||
*/
|
||||
extern SECStatus nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *pubkey);
|
||||
|
||||
/*
|
||||
** Store a key in the database, indexed by its public key modulus.
|
||||
** "pk" is the private key to store
|
||||
** "f" is a the callback function for getting the password
|
||||
** "arg" is the argument for the callback
|
||||
*/
|
||||
extern SECStatus nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
|
||||
NSSLOWKEYPrivateKey *pk,
|
||||
SECItem *pubKeyData,
|
||||
char *nickname,
|
||||
SECItem *arg);
|
||||
|
||||
/* does the key for this cert exist in the database filed by modulus */
|
||||
extern PRBool nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle,
|
||||
NSSLOWCERTCertificate *cert);
|
||||
/* does a key with this ID already exist? */
|
||||
extern PRBool nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id);
|
||||
|
||||
|
||||
extern SECStatus nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle);
|
||||
extern SECStatus nsslowkey_SetKeyDBPassword(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *pwitem);
|
||||
extern SECStatus nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *pwitem);
|
||||
extern SECStatus nsslowkey_ChangeKeyDBPassword(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *oldpwitem,
|
||||
SECItem *newpwitem);
|
||||
|
||||
/*
|
||||
** Destroy a private key object.
|
||||
** "key" the object
|
||||
** "freeit" if PR_TRUE then free the object as well as its sub-objects
|
||||
*/
|
||||
extern void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key);
|
||||
|
||||
/*
|
||||
** Destroy a public key object.
|
||||
** "key" the object
|
||||
** "freeit" if PR_TRUE then free the object as well as its sub-objects
|
||||
*/
|
||||
extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
|
||||
|
||||
/*
|
||||
** Return the modulus length of "pubKey".
|
||||
*/
|
||||
extern unsigned int nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubKey);
|
||||
|
||||
|
||||
/*
|
||||
** Return the modulus length of "privKey".
|
||||
*/
|
||||
extern unsigned int nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privKey);
|
||||
|
||||
|
||||
/*
|
||||
** Convert a low private key "privateKey" into a public low key
|
||||
*/
|
||||
extern NSSLOWKEYPublicKey
|
||||
*nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey);
|
||||
|
||||
/*
|
||||
* Set the Key Database password.
|
||||
* handle is a handle to the key database
|
||||
* pwitem is the new password
|
||||
* algorithm is the algorithm by which the key database
|
||||
* password is to be encrypted.
|
||||
* On failure, SECFailure is returned, otherwise SECSuccess is
|
||||
* returned.
|
||||
*/
|
||||
extern SECStatus
|
||||
nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *pwitem,
|
||||
SECOidTag algorithm);
|
||||
|
||||
/* Check the key database password.
|
||||
* handle is a handle to the key database
|
||||
* pwitem is the suspect password
|
||||
* algorithm is the algorithm by which the key database
|
||||
* password is to be encrypted.
|
||||
* The password is checked against plaintext to see if it is the
|
||||
* actual password. If it is not, SECFailure is returned.
|
||||
*/
|
||||
extern SECStatus
|
||||
nsslowkey_CheckKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *pwitem,
|
||||
SECOidTag algorithm);
|
||||
|
||||
/* Change the key database password and/or algorithm by which
|
||||
* the password is stored with.
|
||||
* handle is a handle to the key database
|
||||
* old_pwitem is the current password
|
||||
* new_pwitem is the new password
|
||||
* old_algorithm is the algorithm by which the key database
|
||||
* password is currently encrypted.
|
||||
* new_algorithm is the algorithm with which the new password
|
||||
* is to be encrypted.
|
||||
* A return of anything but SECSuccess indicates failure.
|
||||
*/
|
||||
extern SECStatus
|
||||
nsslowkey_ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *oldpwitem, SECItem *newpwitem,
|
||||
SECOidTag old_algorithm);
|
||||
|
||||
SECStatus
|
||||
nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
|
||||
NSSLOWKEYPrivateKey *privkey,
|
||||
SECItem *pubKeyData,
|
||||
char *nickname,
|
||||
SECItem *arg);
|
||||
|
||||
/* Store key by modulus and specify an encryption algorithm to use.
|
||||
* handle is the pointer to the key database,
|
||||
* privkey is the private key to be stored,
|
||||
* f and arg are the function and arguments to the callback
|
||||
* to get a password,
|
||||
* algorithm is the algorithm which the privKey is to be stored.
|
||||
* A return of anything but SECSuccess indicates failure.
|
||||
*/
|
||||
extern SECStatus
|
||||
nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
|
||||
NSSLOWKEYPrivateKey *privkey,
|
||||
SECItem *pubKeyData,
|
||||
char *nickname,
|
||||
SECItem *arg,
|
||||
SECOidTag algorithm,
|
||||
PRBool update);
|
||||
|
||||
/* Find key by modulus. This function is the inverse of store key
|
||||
* by modulus. An attempt to locate the key with "modulus" is
|
||||
* performed. If the key is found, the private key is returned,
|
||||
* else NULL is returned.
|
||||
* modulus is the modulus to locate
|
||||
*/
|
||||
extern NSSLOWKEYPrivateKey *
|
||||
nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
|
||||
SECItem *arg);
|
||||
|
||||
extern char *
|
||||
nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
|
||||
SECItem *modulus, SECItem *pwitem);
|
||||
|
||||
|
||||
/* Make a copy of a low private key in it's own arena.
|
||||
* a return of NULL indicates an error.
|
||||
*/
|
||||
extern NSSLOWKEYPrivateKey *
|
||||
nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey);
|
||||
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _LOWKEYI_H_ */
|
||||
@@ -1,163 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef _LOWKEYTI_H_
|
||||
#define _LOWKEYTI_H_ 1
|
||||
|
||||
#include "blapit.h"
|
||||
#include "prtypes.h"
|
||||
#include "plarena.h"
|
||||
#include "secitem.h"
|
||||
#include "secasn1t.h"
|
||||
#include "secoidt.h"
|
||||
/*#include "secmodt.h"
|
||||
#include "pkcs11t.h" */
|
||||
|
||||
|
||||
/*
|
||||
* a key in/for the data base
|
||||
*/
|
||||
struct NSSLOWKEYDBKeyStr {
|
||||
PLArenaPool *arena;
|
||||
int version;
|
||||
char *nickname;
|
||||
SECItem salt;
|
||||
SECItem derPK;
|
||||
};
|
||||
typedef struct NSSLOWKEYDBKeyStr NSSLOWKEYDBKey;
|
||||
|
||||
typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle;
|
||||
|
||||
#ifdef NSS_USE_KEY4_DB
|
||||
#define NSSLOWKEY_DB_FILE_VERSION 4
|
||||
#else
|
||||
#define NSSLOWKEY_DB_FILE_VERSION 3
|
||||
#endif
|
||||
|
||||
#define NSSLOWKEY_VERSION 0 /* what we *create* */
|
||||
|
||||
/*
|
||||
** Typedef for callback to get a password "key".
|
||||
*/
|
||||
extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[];
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
|
||||
extern const SEC_ASN1Template nsslowkey_ECParamsTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[];
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
|
||||
extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
|
||||
extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
|
||||
|
||||
/*
|
||||
* PKCS #8 attributes
|
||||
*/
|
||||
struct NSSLOWKEYAttributeStr {
|
||||
SECItem attrType;
|
||||
SECItem *attrValue;
|
||||
};
|
||||
typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute;
|
||||
|
||||
/*
|
||||
** A PKCS#8 private key info object
|
||||
*/
|
||||
struct NSSLOWKEYPrivateKeyInfoStr {
|
||||
PLArenaPool *arena;
|
||||
SECItem version;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem privateKey;
|
||||
NSSLOWKEYAttribute **attributes;
|
||||
};
|
||||
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
|
||||
#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
|
||||
|
||||
/*
|
||||
** A PKCS#8 private key info object
|
||||
*/
|
||||
struct NSSLOWKEYEncryptedPrivateKeyInfoStr {
|
||||
PLArenaPool *arena;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem encryptedData;
|
||||
};
|
||||
typedef struct NSSLOWKEYEncryptedPrivateKeyInfoStr NSSLOWKEYEncryptedPrivateKeyInfo;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NSSLOWKEYNullKey = 0,
|
||||
NSSLOWKEYRSAKey = 1,
|
||||
NSSLOWKEYDSAKey = 2,
|
||||
NSSLOWKEYDHKey = 4,
|
||||
NSSLOWKEYECKey = 5
|
||||
} NSSLOWKEYType;
|
||||
|
||||
/*
|
||||
** An RSA public key object.
|
||||
*/
|
||||
struct NSSLOWKEYPublicKeyStr {
|
||||
PLArenaPool *arena;
|
||||
NSSLOWKEYType keyType ;
|
||||
union {
|
||||
RSAPublicKey rsa;
|
||||
DSAPublicKey dsa;
|
||||
DHPublicKey dh;
|
||||
ECPublicKey ec;
|
||||
} u;
|
||||
};
|
||||
typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
|
||||
|
||||
/*
|
||||
** Low Level private key object
|
||||
** This is only used by the raw Crypto engines (crypto), keydb (keydb),
|
||||
** and PKCS #11. Everyone else uses the high level key structure.
|
||||
*/
|
||||
struct NSSLOWKEYPrivateKeyStr {
|
||||
PLArenaPool *arena;
|
||||
NSSLOWKEYType keyType;
|
||||
union {
|
||||
RSAPrivateKey rsa;
|
||||
DSAPrivateKey dsa;
|
||||
DHPrivateKey dh;
|
||||
ECPrivateKey ec;
|
||||
} u;
|
||||
};
|
||||
typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
|
||||
|
||||
#endif /* _LOWKEYTI_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _SECPKCS5_H_
|
||||
#define _SECPKCS5_H_
|
||||
|
||||
#include "plarena.h"
|
||||
#include "secitem.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
#include "hasht.h"
|
||||
|
||||
typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
|
||||
|
||||
/* used for V2 PKCS 12 Draft Spec */
|
||||
typedef enum {
|
||||
pbeBitGenIDNull = 0,
|
||||
pbeBitGenCipherKey = 0x01,
|
||||
pbeBitGenCipherIV = 0x02,
|
||||
pbeBitGenIntegrityKey = 0x03
|
||||
} PBEBitGenID;
|
||||
|
||||
typedef enum {
|
||||
NSSPKCS5_PBKDF1 = 0,
|
||||
NSSPKCS5_PBKDF2 = 1,
|
||||
NSSPKCS5_PKCS12_V2 = 2
|
||||
} NSSPKCS5PBEType;
|
||||
|
||||
typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter;
|
||||
|
||||
struct NSSPKCS5PBEParameterStr {
|
||||
PRArenaPool *poolp;
|
||||
SECItem salt; /* octet string */
|
||||
SECItem iteration; /* integer */
|
||||
|
||||
/* used locally */
|
||||
int iter;
|
||||
int keyLen;
|
||||
int ivLen;
|
||||
HASH_HashType hashType;
|
||||
NSSPKCS5PBEType pbeType;
|
||||
PBEBitGenID keyID;
|
||||
SECOidTag encAlg;
|
||||
PRBool is2KeyDES;
|
||||
};
|
||||
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
/* Create a PKCS5 Algorithm ID
|
||||
* The algorithm ID is set up using the PKCS #5 parameter structure
|
||||
* algorithm is the PBE algorithm ID for the desired algorithm
|
||||
* pbe is a pbe param block with all the info needed to create the
|
||||
* algorithm id.
|
||||
* If an error occurs or the algorithm specified is not supported
|
||||
* or is not a password based encryption algorithm, NULL is returned.
|
||||
* Otherwise, a pointer to the algorithm id is returned.
|
||||
*/
|
||||
extern SECAlgorithmID *
|
||||
nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
|
||||
NSSPKCS5PBEParameter *pbe);
|
||||
|
||||
/*
|
||||
* Convert an Algorithm ID to a PBE Param.
|
||||
* NOTE: this does not suppport PKCS 5 v2 because it's only used for the
|
||||
* keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
|
||||
*/
|
||||
NSSPKCS5PBEParameter *
|
||||
nsspkcs5_AlgidToParam(SECAlgorithmID *algid);
|
||||
|
||||
/*
|
||||
* Convert an Algorithm ID to a PBE Param.
|
||||
* NOTE: this does not suppport PKCS 5 v2 because it's only used for the
|
||||
* keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
|
||||
*/
|
||||
NSSPKCS5PBEParameter *
|
||||
nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
|
||||
|
||||
|
||||
/* Encrypt/Decrypt data using password based encryption.
|
||||
* algid is the PBE algorithm identifier,
|
||||
* pwitem is the password,
|
||||
* src is the source for encryption/decryption,
|
||||
* encrypt is PR_TRUE for encryption, PR_FALSE for decryption.
|
||||
* The key and iv are generated based upon PKCS #5 then the src
|
||||
* is either encrypted or decrypted. If an error occurs, NULL
|
||||
* is returned, otherwise the ciphered contents is returned.
|
||||
*/
|
||||
extern SECItem *
|
||||
nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem,
|
||||
SECItem *src, PRBool encrypt, PRBool *update);
|
||||
|
||||
extern SECItem *
|
||||
nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem,
|
||||
SECItem *iv, PRBool faulty3DES);
|
||||
|
||||
/* Destroys PBE parameter */
|
||||
extern void
|
||||
nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *param);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif
|
||||
@@ -1,89 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
MODULE = nss
|
||||
|
||||
REQUIRES = dbm
|
||||
|
||||
LIBRARY_NAME = softokn
|
||||
LIBRARY_VERSION = 3
|
||||
MAPFILE = $(OBJDIR)/softokn.def
|
||||
|
||||
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSOFTOKEN_LIB_NAME=\"$(notdir $(SHARED_LIBRARY))\"
|
||||
|
||||
|
||||
EXPORTS = \
|
||||
pkcs11.h \
|
||||
pkcs11f.h \
|
||||
pkcs11p.h \
|
||||
pkcs11t.h \
|
||||
pkcs11n.h \
|
||||
pkcs11u.h \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
pk11pars.h \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
alghmac.c \
|
||||
dbinit.c \
|
||||
dbmshim.c \
|
||||
ecdecode.c \
|
||||
fipstest.c \
|
||||
fipstokn.c \
|
||||
keydb.c \
|
||||
lowcert.c \
|
||||
lowkey.c \
|
||||
lowpbe.c \
|
||||
padbuf.c \
|
||||
pcertdb.c \
|
||||
pk11db.c \
|
||||
pkcs11.c \
|
||||
pkcs11c.c \
|
||||
pkcs11u.c \
|
||||
rawhash.c \
|
||||
rsawrapr.c \
|
||||
softkver.c \
|
||||
tlsprf.c \
|
||||
$(NULL)
|
||||
|
||||
ifdef NSS_ENABLE_ECC
|
||||
DEFINES += -DNSS_ENABLE_ECC
|
||||
endif
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "blapit.h"
|
||||
#include "secport.h"
|
||||
#include "secerr.h"
|
||||
|
||||
/*
|
||||
* Prepare a buffer for DES encryption, growing to the appropriate boundary,
|
||||
* filling with the appropriate padding.
|
||||
*
|
||||
* NOTE: If arena is non-NULL, we re-allocate from there, otherwise
|
||||
* we assume (and use) XP memory (re)allocation.
|
||||
*/
|
||||
unsigned char *
|
||||
DES_PadBuffer(PRArenaPool *arena, unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int *outlen)
|
||||
{
|
||||
unsigned char *outbuf;
|
||||
unsigned int des_len;
|
||||
unsigned int i;
|
||||
unsigned char des_pad_len;
|
||||
|
||||
/*
|
||||
* We need from 1 to DES_KEY_LENGTH bytes -- we *always* grow.
|
||||
* The extra bytes contain the value of the length of the padding:
|
||||
* if we have 2 bytes of padding, then the padding is "0x02, 0x02".
|
||||
*/
|
||||
des_len = (inlen + DES_KEY_LENGTH) & ~(DES_KEY_LENGTH - 1);
|
||||
|
||||
if (arena != NULL) {
|
||||
outbuf = (unsigned char*)PORT_ArenaGrow (arena, inbuf, inlen, des_len);
|
||||
} else {
|
||||
outbuf = (unsigned char*)PORT_Realloc (inbuf, des_len);
|
||||
}
|
||||
|
||||
if (outbuf == NULL) {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
des_pad_len = des_len - inlen;
|
||||
for (i = inlen; i < des_len; i++)
|
||||
outbuf[i] = des_pad_len;
|
||||
|
||||
*outlen = des_len;
|
||||
return outbuf;
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _PCERTDB_H_
|
||||
#define _PCERTDB_H_
|
||||
|
||||
#include "plarena.h"
|
||||
#include "prlong.h"
|
||||
#include "pcertt.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
** Add a DER encoded certificate to the permanent database.
|
||||
** "derCert" is the DER encoded certificate.
|
||||
** "nickname" is the nickname to use for the cert
|
||||
** "trust" is the trust parameters for the cert
|
||||
*/
|
||||
SECStatus nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *handle,
|
||||
NSSLOWCERTCertificate *cert,
|
||||
char *nickname, NSSLOWCERTCertTrust *trust);
|
||||
SECStatus nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
|
||||
NSSLOWCERTCertificate *cert, char *nickname);
|
||||
|
||||
SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert);
|
||||
|
||||
typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *cert,
|
||||
SECItem *k, void *pdata);
|
||||
/*
|
||||
** Traverse the entire permanent database, and pass the certs off to a
|
||||
** user supplied function.
|
||||
** "certfunc" is the user function to call for each certificate
|
||||
** "udata" is the user's data, which is passed through to "certfunc"
|
||||
*/
|
||||
SECStatus
|
||||
nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
|
||||
PermCertCallback certfunc,
|
||||
void *udata );
|
||||
|
||||
PRBool
|
||||
nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
|
||||
|
||||
certDBEntryRevocation *
|
||||
nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
|
||||
SECItem *crlKey, PRBool isKRL);
|
||||
|
||||
SECStatus
|
||||
nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,SECItem *derName,
|
||||
PRBool isKRL);
|
||||
SECStatus
|
||||
nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl ,
|
||||
SECItem *derKey, char *url, PRBool isKRL);
|
||||
|
||||
NSSLOWCERTCertDBHandle *nsslowcert_GetDefaultCertDB();
|
||||
NSSLOWKEYPublicKey *nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *);
|
||||
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_NewTempCertificate(NSSLOWCERTCertDBHandle *handle, SECItem *derCert,
|
||||
char *nickname, PRBool isperm, PRBool copyDER);
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_DupCertificate(NSSLOWCERTCertificate *cert);
|
||||
void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert);
|
||||
void nsslowcert_DestroyTrust(NSSLOWCERTTrust *Trust);
|
||||
|
||||
/*
|
||||
* Lookup a certificate in the databases without locking
|
||||
* "certKey" is the database key to look for
|
||||
*
|
||||
* XXX - this should be internal, but pkcs 11 needs to call it during a
|
||||
* traversal.
|
||||
*/
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
|
||||
|
||||
/*
|
||||
* Lookup trust for a certificate in the databases without locking
|
||||
* "certKey" is the database key to look for
|
||||
*
|
||||
* XXX - this should be internal, but pkcs 11 needs to call it during a
|
||||
* traversal.
|
||||
*/
|
||||
NSSLOWCERTTrust *
|
||||
nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
|
||||
|
||||
/*
|
||||
** Generate a certificate key from the issuer and serialnumber, then look it
|
||||
** up in the database. Return the cert if found.
|
||||
** "issuerAndSN" is the issuer and serial number to look for
|
||||
*/
|
||||
extern NSSLOWCERTCertificate *
|
||||
nsslowcert_FindCertByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
|
||||
|
||||
/*
|
||||
** Generate a certificate key from the issuer and serialnumber, then look it
|
||||
** up in the database. Return the cert if found.
|
||||
** "issuerAndSN" is the issuer and serial number to look for
|
||||
*/
|
||||
extern NSSLOWCERTTrust *
|
||||
nsslowcert_FindTrustByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
|
||||
|
||||
/*
|
||||
** Find a certificate in the database by a DER encoded certificate
|
||||
** "derCert" is the DER encoded certificate
|
||||
*/
|
||||
extern NSSLOWCERTCertificate *
|
||||
nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
|
||||
|
||||
/* convert an email address to lower case */
|
||||
char *nsslowcert_FixupEmailAddr(char *emailAddr);
|
||||
|
||||
/*
|
||||
** Decode a DER encoded certificate into an NSSLOWCERTCertificate structure
|
||||
** "derSignedCert" is the DER encoded signed certificate
|
||||
** "copyDER" is true if the DER should be copied, false if the
|
||||
** existing copy should be referenced
|
||||
** "nickname" is the nickname to use in the database. If it is NULL
|
||||
** then a temporary nickname is generated.
|
||||
*/
|
||||
extern NSSLOWCERTCertificate *
|
||||
nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, char *nickname);
|
||||
|
||||
SECStatus
|
||||
nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
|
||||
|
||||
certDBEntrySMime *
|
||||
nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle,
|
||||
char *emailAddr);
|
||||
void
|
||||
nsslowcert_DestroyDBEntry(certDBEntry *entry);
|
||||
|
||||
SECStatus
|
||||
nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
|
||||
const char *domain, const char *prefix,
|
||||
NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile);
|
||||
|
||||
void
|
||||
nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle);
|
||||
|
||||
/*
|
||||
* is certa newer than certb? If one is expired, pick the other one.
|
||||
*/
|
||||
PRBool
|
||||
nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb);
|
||||
|
||||
|
||||
SECStatus
|
||||
nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
|
||||
certDBEntryType type,
|
||||
SECStatus (* callback)(SECItem *data, SECItem *key,
|
||||
certDBEntryType type, void *pdata),
|
||||
void *udata );
|
||||
SECStatus
|
||||
nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
|
||||
SECItem *derSubject,
|
||||
NSSLOWCERTCertCallback cb, void *cbarg);
|
||||
int
|
||||
nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
|
||||
SECItem *derSubject);
|
||||
SECStatus
|
||||
nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
|
||||
char *nickname, NSSLOWCERTCertCallback cb, void *cbarg);
|
||||
|
||||
int
|
||||
nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
|
||||
char *nickname);
|
||||
SECStatus
|
||||
nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert,
|
||||
NSSLOWCERTCertTrust *trust);
|
||||
|
||||
SECStatus
|
||||
nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
|
||||
SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime);
|
||||
|
||||
/*
|
||||
* Change the trust attributes of a certificate and make them permanent
|
||||
* in the database.
|
||||
*/
|
||||
SECStatus
|
||||
nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
|
||||
NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust);
|
||||
|
||||
PRBool
|
||||
nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle);
|
||||
|
||||
void
|
||||
nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value);
|
||||
|
||||
PRBool
|
||||
nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust);
|
||||
|
||||
void
|
||||
nsslowcert_DestroyFreeLists(void);
|
||||
|
||||
void
|
||||
nsslowcert_DestroyGlobalLocks(void);
|
||||
|
||||
void
|
||||
pkcs11_freeNickname(char *nickname, char *space);
|
||||
|
||||
char *
|
||||
pkcs11_copyNickname(char *nickname, char *space, int spaceLen);
|
||||
|
||||
void
|
||||
pkcs11_freeStaticData(unsigned char *data, unsigned char *space);
|
||||
|
||||
unsigned char *
|
||||
pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
|
||||
int spaceLen);
|
||||
NSSLOWCERTCertificate *
|
||||
nsslowcert_CreateCert(void);
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _PCERTDB_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,446 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* certt.h - public data structures for the certificate library
|
||||
*
|
||||
* $Id: pcertt.h,v 1.13 2004-04-25 15:03:16 gerv%gerv.net Exp $
|
||||
*/
|
||||
#ifndef _PCERTT_H_
|
||||
#define _PCERTT_H_
|
||||
|
||||
#include "prclist.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
#include "plarena.h"
|
||||
#include "prcvar.h"
|
||||
#include "nssilock.h"
|
||||
#include "prio.h"
|
||||
#include "prmon.h"
|
||||
|
||||
/* Non-opaque objects */
|
||||
typedef struct NSSLOWCERTCertDBHandleStr NSSLOWCERTCertDBHandle;
|
||||
typedef struct NSSLOWCERTCertKeyStr NSSLOWCERTCertKey;
|
||||
|
||||
typedef struct NSSLOWCERTTrustStr NSSLOWCERTTrust;
|
||||
typedef struct NSSLOWCERTCertTrustStr NSSLOWCERTCertTrust;
|
||||
typedef struct NSSLOWCERTCertificateStr NSSLOWCERTCertificate;
|
||||
typedef struct NSSLOWCERTCertificateListStr NSSLOWCERTCertificateList;
|
||||
typedef struct NSSLOWCERTIssuerAndSNStr NSSLOWCERTIssuerAndSN;
|
||||
typedef struct NSSLOWCERTSignedDataStr NSSLOWCERTSignedData;
|
||||
typedef struct NSSLOWCERTSubjectPublicKeyInfoStr NSSLOWCERTSubjectPublicKeyInfo;
|
||||
typedef struct NSSLOWCERTValidityStr NSSLOWCERTValidity;
|
||||
|
||||
/*
|
||||
** An X.509 validity object
|
||||
*/
|
||||
struct NSSLOWCERTValidityStr {
|
||||
PRArenaPool *arena;
|
||||
SECItem notBefore;
|
||||
SECItem notAfter;
|
||||
};
|
||||
|
||||
/*
|
||||
* A serial number and issuer name, which is used as a database key
|
||||
*/
|
||||
struct NSSLOWCERTCertKeyStr {
|
||||
SECItem serialNumber;
|
||||
SECItem derIssuer;
|
||||
};
|
||||
|
||||
/*
|
||||
** A signed data object. Used to implement the "signed" macro used
|
||||
** in the X.500 specs.
|
||||
*/
|
||||
struct NSSLOWCERTSignedDataStr {
|
||||
SECItem data;
|
||||
SECAlgorithmID signatureAlgorithm;
|
||||
SECItem signature;
|
||||
};
|
||||
|
||||
/*
|
||||
** An X.509 subject-public-key-info object
|
||||
*/
|
||||
struct NSSLOWCERTSubjectPublicKeyInfoStr {
|
||||
PRArenaPool *arena;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem subjectPublicKey;
|
||||
};
|
||||
|
||||
typedef struct _certDBEntryCert certDBEntryCert;
|
||||
typedef struct _certDBEntryRevocation certDBEntryRevocation;
|
||||
|
||||
struct NSSLOWCERTCertTrustStr {
|
||||
unsigned int sslFlags;
|
||||
unsigned int emailFlags;
|
||||
unsigned int objectSigningFlags;
|
||||
};
|
||||
|
||||
/*
|
||||
** PKCS11 Trust representation
|
||||
*/
|
||||
struct NSSLOWCERTTrustStr {
|
||||
NSSLOWCERTTrust *next;
|
||||
NSSLOWCERTCertDBHandle *dbhandle;
|
||||
SECItem dbKey; /* database key for this cert */
|
||||
certDBEntryCert *dbEntry; /* database entry struct */
|
||||
NSSLOWCERTCertTrust *trust;
|
||||
SECItem *derCert; /* original DER for the cert */
|
||||
unsigned char dbKeySpace[512];
|
||||
};
|
||||
|
||||
/*
|
||||
** An X.509 certificate object (the unsigned form)
|
||||
*/
|
||||
struct NSSLOWCERTCertificateStr {
|
||||
/* the arena is used to allocate any data structures that have the same
|
||||
* lifetime as the cert. This is all stuff that hangs off of the cert
|
||||
* structure, and is all freed at the same time. I is used when the
|
||||
* cert is decoded, destroyed, and at some times when it changes
|
||||
* state
|
||||
*/
|
||||
NSSLOWCERTCertificate *next;
|
||||
NSSLOWCERTCertDBHandle *dbhandle;
|
||||
|
||||
SECItem derCert; /* original DER for the cert */
|
||||
SECItem derIssuer; /* DER for issuer name */
|
||||
SECItem derSN;
|
||||
SECItem serialNumber;
|
||||
SECItem derSubject; /* DER for subject name */
|
||||
SECItem derSubjKeyInfo;
|
||||
NSSLOWCERTSubjectPublicKeyInfo *subjectPublicKeyInfo;
|
||||
SECItem certKey; /* database key for this cert */
|
||||
SECItem validity;
|
||||
certDBEntryCert *dbEntry; /* database entry struct */
|
||||
SECItem subjectKeyID; /* x509v3 subject key identifier */
|
||||
char *nickname;
|
||||
char *emailAddr;
|
||||
NSSLOWCERTCertTrust *trust;
|
||||
|
||||
/* the reference count is modified whenever someone looks up, dups
|
||||
* or destroys a certificate
|
||||
*/
|
||||
int referenceCount;
|
||||
|
||||
char nicknameSpace[200];
|
||||
unsigned char certKeySpace[512];
|
||||
};
|
||||
|
||||
#define SEC_CERTIFICATE_VERSION_1 0 /* default created */
|
||||
#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */
|
||||
#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */
|
||||
|
||||
#define SEC_CRL_VERSION_1 0 /* default */
|
||||
#define SEC_CRL_VERSION_2 1 /* v2 extensions */
|
||||
|
||||
struct NSSLOWCERTIssuerAndSNStr {
|
||||
SECItem derIssuer;
|
||||
SECItem serialNumber;
|
||||
};
|
||||
|
||||
typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg);
|
||||
|
||||
/* This is the typedef for the callback passed to nsslowcert_OpenCertDB() */
|
||||
/* callback to return database name based on version number */
|
||||
typedef char * (*NSSLOWCERTDBNameFunc)(void *arg, int dbVersion);
|
||||
|
||||
/* XXX Lisa thinks the template declarations belong in cert.h, not here? */
|
||||
|
||||
#include "secasn1t.h" /* way down here because I expect template stuff to
|
||||
* move out of here anyway */
|
||||
|
||||
/*
|
||||
* Certificate Database related definitions and data structures
|
||||
*/
|
||||
|
||||
/* version number of certificate database */
|
||||
#define CERT_DB_FILE_VERSION 8
|
||||
#define CERT_DB_V7_FILE_VERSION 7
|
||||
#define CERT_DB_CONTENT_VERSION 2
|
||||
|
||||
#define SEC_DB_ENTRY_HEADER_LEN 3
|
||||
#define SEC_DB_KEY_HEADER_LEN 1
|
||||
|
||||
/* All database entries have this form:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 version
|
||||
* 1 type
|
||||
* 2 flags
|
||||
*/
|
||||
|
||||
/* database entry types */
|
||||
typedef enum {
|
||||
certDBEntryTypeVersion = 0,
|
||||
certDBEntryTypeCert = 1,
|
||||
certDBEntryTypeNickname = 2,
|
||||
certDBEntryTypeSubject = 3,
|
||||
certDBEntryTypeRevocation = 4,
|
||||
certDBEntryTypeKeyRevocation = 5,
|
||||
certDBEntryTypeSMimeProfile = 6,
|
||||
certDBEntryTypeContentVersion = 7,
|
||||
certDBEntryTypeBlob = 8
|
||||
} certDBEntryType;
|
||||
|
||||
typedef struct {
|
||||
certDBEntryType type;
|
||||
unsigned int version;
|
||||
unsigned int flags;
|
||||
PRArenaPool *arena;
|
||||
} certDBEntryCommon;
|
||||
|
||||
/*
|
||||
* Certificate entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 sslFlags-msb
|
||||
* 1 sslFlags-lsb
|
||||
* 2 emailFlags-msb
|
||||
* 3 emailFlags-lsb
|
||||
* 4 objectSigningFlags-msb
|
||||
* 5 objectSigningFlags-lsb
|
||||
* 6 derCert-len-msb
|
||||
* 7 derCert-len-lsb
|
||||
* 8 nickname-len-msb
|
||||
* 9 nickname-len-lsb
|
||||
* ... derCert
|
||||
* ... nickname
|
||||
*
|
||||
* NOTE: the nickname string as stored in the database is null terminated,
|
||||
* in other words, the last byte of the db entry is always 0
|
||||
* if a nickname is present.
|
||||
* NOTE: if nickname is not present, then nickname-len-msb and
|
||||
* nickname-len-lsb will both be zero.
|
||||
*/
|
||||
struct _certDBEntryCert {
|
||||
certDBEntryCommon common;
|
||||
certDBEntryCert *next;
|
||||
NSSLOWCERTCertTrust trust;
|
||||
SECItem derCert;
|
||||
char *nickname;
|
||||
char nicknameSpace[200];
|
||||
unsigned char derCertSpace[2048];
|
||||
};
|
||||
|
||||
/*
|
||||
* Certificate Nickname entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 subjectname-len-msb
|
||||
* 1 subjectname-len-lsb
|
||||
* 2... subjectname
|
||||
*
|
||||
* The database key for this type of entry is a nickname string
|
||||
* The "subjectname" value is the DER encoded DN of the identity
|
||||
* that matches this nickname.
|
||||
*/
|
||||
typedef struct {
|
||||
certDBEntryCommon common;
|
||||
char *nickname;
|
||||
SECItem subjectName;
|
||||
} certDBEntryNickname;
|
||||
|
||||
#define DB_NICKNAME_ENTRY_HEADER_LEN 2
|
||||
|
||||
/*
|
||||
* Certificate Subject entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 ncerts-msb
|
||||
* 1 ncerts-lsb
|
||||
* 2 nickname-msb
|
||||
* 3 nickname-lsb
|
||||
* 4 emailAddr-msb
|
||||
* 5 emailAddr-lsb
|
||||
* ... nickname
|
||||
* ... emailAddr
|
||||
* ...+2*i certkey-len-msb
|
||||
* ...+1+2*i certkey-len-lsb
|
||||
* ...+2*ncerts+2*i keyid-len-msb
|
||||
* ...+1+2*ncerts+2*i keyid-len-lsb
|
||||
* ... certkeys
|
||||
* ... keyids
|
||||
*
|
||||
* The database key for this type of entry is the DER encoded subject name
|
||||
* The "certkey" value is an array of certificate database lookup keys that
|
||||
* points to the database entries for the certificates that matche
|
||||
* this subject.
|
||||
*
|
||||
*/
|
||||
typedef struct _certDBEntrySubject {
|
||||
certDBEntryCommon common;
|
||||
SECItem derSubject;
|
||||
unsigned int ncerts;
|
||||
char *nickname;
|
||||
SECItem *certKeys;
|
||||
SECItem *keyIDs;
|
||||
char **emailAddrs;
|
||||
unsigned int nemailAddrs;
|
||||
} certDBEntrySubject;
|
||||
|
||||
#define DB_SUBJECT_ENTRY_HEADER_LEN 6
|
||||
|
||||
/*
|
||||
* Certificate SMIME profile entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 subjectname-len-msb
|
||||
* 1 subjectname-len-lsb
|
||||
* 2 smimeoptions-len-msb
|
||||
* 3 smimeoptions-len-lsb
|
||||
* 4 options-date-len-msb
|
||||
* 5 options-date-len-lsb
|
||||
* 6... subjectname
|
||||
* ... smimeoptions
|
||||
* ... options-date
|
||||
*
|
||||
* The database key for this type of entry is the email address string
|
||||
* The "subjectname" value is the DER encoded DN of the identity
|
||||
* that matches this nickname.
|
||||
* The "smimeoptions" value is a string that represents the algorithm
|
||||
* capabilities on the remote user.
|
||||
* The "options-date" is the date that the smime options value was created.
|
||||
* This is generally the signing time of the signed message that contained
|
||||
* the options. It is a UTCTime value.
|
||||
*/
|
||||
typedef struct {
|
||||
certDBEntryCommon common;
|
||||
char *emailAddr;
|
||||
SECItem subjectName;
|
||||
SECItem smimeOptions;
|
||||
SECItem optionsDate;
|
||||
} certDBEntrySMime;
|
||||
|
||||
#define DB_SMIME_ENTRY_HEADER_LEN 6
|
||||
|
||||
/*
|
||||
* Crl/krl entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 derCert-len-msb
|
||||
* 1 derCert-len-lsb
|
||||
* 2 url-len-msb
|
||||
* 3 url-len-lsb
|
||||
* ... derCert
|
||||
* ... url
|
||||
*
|
||||
* NOTE: the url string as stored in the database is null terminated,
|
||||
* in other words, the last byte of the db entry is always 0
|
||||
* if a nickname is present.
|
||||
* NOTE: if url is not present, then url-len-msb and
|
||||
* url-len-lsb will both be zero.
|
||||
*/
|
||||
#define DB_CRL_ENTRY_HEADER_LEN 4
|
||||
struct _certDBEntryRevocation {
|
||||
certDBEntryCommon common;
|
||||
SECItem derCrl;
|
||||
char *url; /* where to load the crl from */
|
||||
};
|
||||
|
||||
/*
|
||||
* Database Version Entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* only the low level header...
|
||||
*
|
||||
* The database key for this type of entry is the string "Version"
|
||||
*/
|
||||
typedef struct {
|
||||
certDBEntryCommon common;
|
||||
} certDBEntryVersion;
|
||||
|
||||
#define SEC_DB_VERSION_KEY "Version"
|
||||
#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY)
|
||||
|
||||
/*
|
||||
* Database Content Version Entry:
|
||||
*
|
||||
* byte offset field
|
||||
* ----------- -----
|
||||
* 0 contentVersion
|
||||
*
|
||||
* The database key for this type of entry is the string "ContentVersion"
|
||||
*/
|
||||
typedef struct {
|
||||
certDBEntryCommon common;
|
||||
char contentVersion;
|
||||
} certDBEntryContentVersion;
|
||||
|
||||
#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion"
|
||||
#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
|
||||
|
||||
typedef union {
|
||||
certDBEntryCommon common;
|
||||
certDBEntryVersion version;
|
||||
certDBEntryCert cert;
|
||||
certDBEntryNickname nickname;
|
||||
certDBEntrySubject subject;
|
||||
certDBEntryRevocation revocation;
|
||||
} certDBEntry;
|
||||
|
||||
/* length of the fixed part of a database entry */
|
||||
#define DBCERT_V4_HEADER_LEN 7
|
||||
#define DB_CERT_V5_ENTRY_HEADER_LEN 7
|
||||
#define DB_CERT_V6_ENTRY_HEADER_LEN 7
|
||||
#define DB_CERT_ENTRY_HEADER_LEN 10
|
||||
|
||||
/* common flags for all types of certificates */
|
||||
#define CERTDB_VALID_PEER (1<<0)
|
||||
#define CERTDB_TRUSTED (1<<1)
|
||||
#define CERTDB_SEND_WARN (1<<2)
|
||||
#define CERTDB_VALID_CA (1<<3)
|
||||
#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */
|
||||
#define CERTDB_NS_TRUSTED_CA (1<<5)
|
||||
#define CERTDB_USER (1<<6)
|
||||
#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */
|
||||
#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
|
||||
#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
|
||||
#define CERTDB_NOT_TRUSTED (1<<10) /* explicitly don't trust this cert */
|
||||
#define CERTDB_TRUSTED_UNKNOWN (1<<11) /* accept trust from another source */
|
||||
|
||||
/* bits not affected by the CKO_NETSCAPE_TRUST object */
|
||||
#define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | CERTDB_VALID_PEER | \
|
||||
CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \
|
||||
CERTDB_GOVT_APPROVED_CA)
|
||||
|
||||
#endif /* _PCERTT_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,862 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* The following handles the loading, unloading and management of
|
||||
* various PCKS #11 modules
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* this header file contains routines for parsing PKCS #11 module spec
|
||||
* strings. It contains 'C' code and should only be included in one module.
|
||||
* Currently it is included in both softoken and the wrapper.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include "pkcs11.h"
|
||||
#include "seccomon.h"
|
||||
#include "prprf.h"
|
||||
#include "secmodt.h"
|
||||
#include "pk11init.h"
|
||||
|
||||
#define SECMOD_ARG_LIBRARY_PARAMETER "library="
|
||||
#define SECMOD_ARG_NAME_PARAMETER "name="
|
||||
#define SECMOD_ARG_MODULE_PARAMETER "parameters="
|
||||
#define SECMOD_ARG_NSS_PARAMETER "NSS="
|
||||
#define SECMOD_ARG_FORTEZZA_FLAG "FORTEZZA"
|
||||
#define SECMOD_ARG_ESCAPE '\\'
|
||||
|
||||
struct secmodargSlotFlagTable {
|
||||
char *name;
|
||||
int len;
|
||||
unsigned long value;
|
||||
};
|
||||
|
||||
#define SFTK_DEFAULT_CIPHER_ORDER 0
|
||||
#define SFTK_DEFAULT_TRUST_ORDER 50
|
||||
|
||||
|
||||
#define SECMOD_ARG_ENTRY(arg,flag) \
|
||||
{ #arg , sizeof(#arg)-1, flag }
|
||||
static struct secmodargSlotFlagTable secmod_argSlotFlagTable[] = {
|
||||
SECMOD_ARG_ENTRY(RSA,SECMOD_RSA_FLAG),
|
||||
SECMOD_ARG_ENTRY(DSA,SECMOD_RSA_FLAG),
|
||||
SECMOD_ARG_ENTRY(RC2,SECMOD_RC4_FLAG),
|
||||
SECMOD_ARG_ENTRY(RC4,SECMOD_RC2_FLAG),
|
||||
SECMOD_ARG_ENTRY(DES,SECMOD_DES_FLAG),
|
||||
SECMOD_ARG_ENTRY(DH,SECMOD_DH_FLAG),
|
||||
SECMOD_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG),
|
||||
SECMOD_ARG_ENTRY(RC5,SECMOD_RC5_FLAG),
|
||||
SECMOD_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG),
|
||||
SECMOD_ARG_ENTRY(MD5,SECMOD_MD5_FLAG),
|
||||
SECMOD_ARG_ENTRY(MD2,SECMOD_MD2_FLAG),
|
||||
SECMOD_ARG_ENTRY(SSL,SECMOD_SSL_FLAG),
|
||||
SECMOD_ARG_ENTRY(TLS,SECMOD_TLS_FLAG),
|
||||
SECMOD_ARG_ENTRY(AES,SECMOD_AES_FLAG),
|
||||
SECMOD_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG),
|
||||
SECMOD_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG),
|
||||
};
|
||||
|
||||
#define SECMOD_HANDLE_STRING_ARG(param,target,value,command) \
|
||||
if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \
|
||||
param += sizeof(value)-1; \
|
||||
target = secmod_argFetchValue(param,&next); \
|
||||
param += next; \
|
||||
command ;\
|
||||
} else
|
||||
|
||||
#define SECMOD_HANDLE_FINAL_ARG(param) \
|
||||
{ param = secmod_argSkipParameter(param); } param = secmod_argStrip(param);
|
||||
|
||||
|
||||
static int secmod_argSlotFlagTableSize =
|
||||
sizeof(secmod_argSlotFlagTable)/sizeof(secmod_argSlotFlagTable[0]);
|
||||
|
||||
|
||||
static PRBool secmod_argGetPair(char c) {
|
||||
switch (c) {
|
||||
case '\'': return c;
|
||||
case '\"': return c;
|
||||
case '<': return '>';
|
||||
case '{': return '}';
|
||||
case '[': return ']';
|
||||
case '(': return ')';
|
||||
default: break;
|
||||
}
|
||||
return ' ';
|
||||
}
|
||||
|
||||
static PRBool secmod_argIsBlank(char c) {
|
||||
return isspace(c);
|
||||
}
|
||||
|
||||
static PRBool secmod_argIsEscape(char c) {
|
||||
return c == '\\';
|
||||
}
|
||||
|
||||
static PRBool secmod_argIsQuote(char c) {
|
||||
switch (c) {
|
||||
case '\'':
|
||||
case '\"':
|
||||
case '<':
|
||||
case '{': /* } end curly to keep vi bracket matching working */
|
||||
case '(': /* ) */
|
||||
case '[': /* ] */ return PR_TRUE;
|
||||
default: break;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool secmod_argHasChar(char *v, char c)
|
||||
{
|
||||
for ( ;*v; v++) {
|
||||
if (*v == c) return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool secmod_argHasBlanks(char *v)
|
||||
{
|
||||
for ( ;*v; v++) {
|
||||
if (secmod_argIsBlank(*v)) return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static char *secmod_argStrip(char *c) {
|
||||
while (*c && secmod_argIsBlank(*c)) c++;
|
||||
return c;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_argFindEnd(char *string) {
|
||||
char endChar = ' ';
|
||||
PRBool lastEscape = PR_FALSE;
|
||||
|
||||
if (secmod_argIsQuote(*string)) {
|
||||
endChar = secmod_argGetPair(*string);
|
||||
string++;
|
||||
}
|
||||
|
||||
for (;*string; string++) {
|
||||
if (lastEscape) {
|
||||
lastEscape = PR_FALSE;
|
||||
continue;
|
||||
}
|
||||
if (secmod_argIsEscape(*string) && !lastEscape) {
|
||||
lastEscape = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
if ((endChar == ' ') && secmod_argIsBlank(*string)) break;
|
||||
if (*string == endChar) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_argFetchValue(char *string, int *pcount)
|
||||
{
|
||||
char *end = secmod_argFindEnd(string);
|
||||
char *retString, *copyString;
|
||||
PRBool lastEscape = PR_FALSE;
|
||||
|
||||
*pcount = (end - string)+1;
|
||||
|
||||
if (*pcount == 0) return NULL;
|
||||
|
||||
copyString = retString = (char *)PORT_Alloc(*pcount);
|
||||
if (retString == NULL) return NULL;
|
||||
|
||||
if (secmod_argIsQuote(*string)) string++;
|
||||
for (; string < end; string++) {
|
||||
if (secmod_argIsEscape(*string) && !lastEscape) {
|
||||
lastEscape = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
lastEscape = PR_FALSE;
|
||||
*copyString++ = *string;
|
||||
}
|
||||
*copyString = 0;
|
||||
return retString;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_argSkipParameter(char *string)
|
||||
{
|
||||
char *end;
|
||||
/* look for the end of the <name>= */
|
||||
for (;*string; string++) {
|
||||
if (*string == '=') { string++; break; }
|
||||
if (secmod_argIsBlank(*string)) return(string);
|
||||
}
|
||||
|
||||
end = secmod_argFindEnd(string);
|
||||
if (*end) end++;
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
static SECStatus
|
||||
secmod_argParseModuleSpec(char *modulespec, char **lib, char **mod,
|
||||
char **parameters, char **nss)
|
||||
{
|
||||
int next;
|
||||
modulespec = secmod_argStrip(modulespec);
|
||||
|
||||
*lib = *mod = *parameters = *nss = 0;
|
||||
|
||||
while (*modulespec) {
|
||||
SECMOD_HANDLE_STRING_ARG(modulespec,*lib,SECMOD_ARG_LIBRARY_PARAMETER,;)
|
||||
SECMOD_HANDLE_STRING_ARG(modulespec,*mod,SECMOD_ARG_NAME_PARAMETER,;)
|
||||
SECMOD_HANDLE_STRING_ARG(modulespec,*parameters,
|
||||
SECMOD_ARG_MODULE_PARAMETER,;)
|
||||
SECMOD_HANDLE_STRING_ARG(modulespec,*nss,SECMOD_ARG_NSS_PARAMETER,;)
|
||||
SECMOD_HANDLE_FINAL_ARG(modulespec)
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
secmod_argGetParamValue(char *paramName,char *parameters)
|
||||
{
|
||||
char searchValue[256];
|
||||
int paramLen = strlen(paramName);
|
||||
char *returnValue = NULL;
|
||||
int next;
|
||||
|
||||
if ((parameters == NULL) || (*parameters == 0)) return NULL;
|
||||
|
||||
PORT_Assert(paramLen+2 < sizeof(searchValue));
|
||||
|
||||
PORT_Strcpy(searchValue,paramName);
|
||||
PORT_Strcat(searchValue,"=");
|
||||
while (*parameters) {
|
||||
if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) {
|
||||
parameters += paramLen+1;
|
||||
returnValue = secmod_argFetchValue(parameters,&next);
|
||||
break;
|
||||
} else {
|
||||
parameters = secmod_argSkipParameter(parameters);
|
||||
}
|
||||
parameters = secmod_argStrip(parameters);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
secmod_argNextFlag(char *flags)
|
||||
{
|
||||
for (; *flags ; flags++) {
|
||||
if (*flags == ',') {
|
||||
flags++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
secmod_argHasFlag(char *label, char *flag, char *parameters)
|
||||
{
|
||||
char *flags,*index;
|
||||
int len = strlen(flag);
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
flags = secmod_argGetParamValue(label,parameters);
|
||||
if (flags == NULL) return PR_FALSE;
|
||||
|
||||
for (index=flags; *index; index=secmod_argNextFlag(index)) {
|
||||
if (PORT_Strncasecmp(index,flag,len) == 0) {
|
||||
found=PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PORT_Free(flags);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
secmod_argSetNewCipherFlags(unsigned long *newCiphers,char *cipherList)
|
||||
{
|
||||
newCiphers[0] = newCiphers[1] = 0;
|
||||
if ((cipherList == NULL) || (*cipherList == 0)) return;
|
||||
|
||||
for (;*cipherList; cipherList=secmod_argNextFlag(cipherList)) {
|
||||
if (PORT_Strncasecmp(cipherList,SECMOD_ARG_FORTEZZA_FLAG,
|
||||
sizeof(SECMOD_ARG_FORTEZZA_FLAG)-1) == 0) {
|
||||
newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
|
||||
}
|
||||
|
||||
/* add additional flags here as necessary */
|
||||
/* direct bit mapping escape */
|
||||
if (*cipherList == 0) {
|
||||
if (cipherList[1] == 'l') {
|
||||
newCiphers[1] |= atoi(&cipherList[2]);
|
||||
} else {
|
||||
newCiphers[0] |= atoi(&cipherList[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
|
||||
*/
|
||||
static long
|
||||
secmod_argDecodeNumber(char *num)
|
||||
{
|
||||
int radix = 10;
|
||||
unsigned long value = 0;
|
||||
long retValue = 0;
|
||||
int sign = 1;
|
||||
int digit;
|
||||
|
||||
if (num == NULL) return retValue;
|
||||
|
||||
num = secmod_argStrip(num);
|
||||
|
||||
if (*num == '-') {
|
||||
sign = -1;
|
||||
num++;
|
||||
}
|
||||
|
||||
if (*num == '0') {
|
||||
radix = 8;
|
||||
num++;
|
||||
if ((*num == 'x') || (*num == 'X')) {
|
||||
radix = 16;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( ;*num; num++ ) {
|
||||
if (isdigit(*num)) {
|
||||
digit = *num - '0';
|
||||
} else if ((*num >= 'a') && (*num <= 'f')) {
|
||||
digit = *num - 'a' + 10;
|
||||
} else if ((*num >= 'A') && (*num <= 'F')) {
|
||||
digit = *num - 'A' + 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (digit >= radix) break;
|
||||
value = value*radix + digit;
|
||||
}
|
||||
|
||||
retValue = ((int) value) * sign;
|
||||
return retValue;
|
||||
}
|
||||
|
||||
static long
|
||||
secmod_argReadLong(char *label,char *params, long defValue, PRBool *isdefault)
|
||||
{
|
||||
char *value;
|
||||
long retValue;
|
||||
if (isdefault) *isdefault = PR_FALSE;
|
||||
|
||||
value = secmod_argGetParamValue(label,params);
|
||||
if (value == NULL) {
|
||||
if (isdefault) *isdefault = PR_TRUE;
|
||||
return defValue;
|
||||
}
|
||||
retValue = secmod_argDecodeNumber(value);
|
||||
if (value) PORT_Free(value);
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
secmod_argSlotFlags(char *label,char *params)
|
||||
{
|
||||
char *flags,*index;
|
||||
unsigned long retValue = 0;
|
||||
int i;
|
||||
PRBool all = PR_FALSE;
|
||||
|
||||
flags = secmod_argGetParamValue(label,params);
|
||||
if (flags == NULL) return 0;
|
||||
|
||||
if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE;
|
||||
|
||||
for (index=flags; *index; index=secmod_argNextFlag(index)) {
|
||||
for (i=0; i < secmod_argSlotFlagTableSize; i++) {
|
||||
if (all || (PORT_Strncasecmp(index, secmod_argSlotFlagTable[i].name,
|
||||
secmod_argSlotFlagTable[i].len) == 0)) {
|
||||
retValue |= secmod_argSlotFlagTable[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
PORT_Free(flags);
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
secmod_argDecodeSingleSlotInfo(char *name, char *params,
|
||||
PK11PreSlotInfo *slotInfo)
|
||||
{
|
||||
char *askpw;
|
||||
|
||||
slotInfo->slotID=secmod_argDecodeNumber(name);
|
||||
slotInfo->defaultFlags=secmod_argSlotFlags("slotFlags",params);
|
||||
slotInfo->timeout=secmod_argReadLong("timeout",params, 0, NULL);
|
||||
|
||||
askpw = secmod_argGetParamValue("askpw",params);
|
||||
slotInfo->askpw = 0;
|
||||
|
||||
if (askpw) {
|
||||
if (PORT_Strcasecmp(askpw,"every") == 0) {
|
||||
slotInfo->askpw = -1;
|
||||
} else if (PORT_Strcasecmp(askpw,"timeout") == 0) {
|
||||
slotInfo->askpw = 1;
|
||||
}
|
||||
PORT_Free(askpw);
|
||||
slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
|
||||
}
|
||||
slotInfo->hasRootCerts = secmod_argHasFlag("rootFlags", "hasRootCerts",
|
||||
params);
|
||||
slotInfo->hasRootTrust = secmod_argHasFlag("rootFlags", "hasRootTrust",
|
||||
params);
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_argGetName(char *inString, int *next)
|
||||
{
|
||||
char *name=NULL;
|
||||
char *string;
|
||||
int len;
|
||||
|
||||
/* look for the end of the <name>= */
|
||||
for (string = inString;*string; string++) {
|
||||
if (*string == '=') { break; }
|
||||
if (secmod_argIsBlank(*string)) break;
|
||||
}
|
||||
|
||||
len = string - inString;
|
||||
|
||||
*next = len;
|
||||
if (*string == '=') (*next) += 1;
|
||||
if (len > 0) {
|
||||
name = PORT_Alloc(len+1);
|
||||
PORT_Strncpy(name,inString,len);
|
||||
name[len] = 0;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static PK11PreSlotInfo *
|
||||
secmod_argParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount)
|
||||
{
|
||||
char *slotIndex;
|
||||
PK11PreSlotInfo *slotInfo = NULL;
|
||||
int i=0,count = 0,next;
|
||||
|
||||
*retCount = 0;
|
||||
if ((slotParams == NULL) || (*slotParams == 0)) return NULL;
|
||||
|
||||
/* first count the number of slots */
|
||||
for (slotIndex = secmod_argStrip(slotParams); *slotIndex;
|
||||
slotIndex = secmod_argStrip(secmod_argSkipParameter(slotIndex))) {
|
||||
count++;
|
||||
}
|
||||
|
||||
/* get the data structures */
|
||||
if (arena) {
|
||||
slotInfo = (PK11PreSlotInfo *)
|
||||
PORT_ArenaAlloc(arena,count*sizeof(PK11PreSlotInfo));
|
||||
PORT_Memset(slotInfo,0,count*sizeof(PK11PreSlotInfo));
|
||||
} else {
|
||||
slotInfo = (PK11PreSlotInfo *)
|
||||
PORT_ZAlloc(count*sizeof(PK11PreSlotInfo));
|
||||
}
|
||||
if (slotInfo == NULL) return NULL;
|
||||
|
||||
for (slotIndex = secmod_argStrip(slotParams), i = 0;
|
||||
*slotIndex && i < count ; ) {
|
||||
char *name;
|
||||
name = secmod_argGetName(slotIndex,&next);
|
||||
slotIndex += next;
|
||||
|
||||
if (!secmod_argIsBlank(*slotIndex)) {
|
||||
char *args = secmod_argFetchValue(slotIndex,&next);
|
||||
slotIndex += next;
|
||||
if (args) {
|
||||
secmod_argDecodeSingleSlotInfo(name,args,&slotInfo[i]);
|
||||
i++;
|
||||
PORT_Free(args);
|
||||
}
|
||||
}
|
||||
if (name) PORT_Free(name);
|
||||
slotIndex = secmod_argStrip(slotIndex);
|
||||
}
|
||||
*retCount = i;
|
||||
return slotInfo;
|
||||
}
|
||||
|
||||
static char *secmod_nullString = "";
|
||||
|
||||
static char *
|
||||
secmod_formatValue(PRArenaPool *arena, char *value, char quote)
|
||||
{
|
||||
char *vp,*vp2,*retval;
|
||||
int size = 0, escapes = 0;
|
||||
|
||||
for (vp=value; *vp ;vp++) {
|
||||
if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) escapes++;
|
||||
size++;
|
||||
}
|
||||
if (arena) {
|
||||
retval = PORT_ArenaZAlloc(arena,size+escapes+1);
|
||||
} else {
|
||||
retval = PORT_ZAlloc(size+escapes+1);
|
||||
}
|
||||
if (retval == NULL) return NULL;
|
||||
vp2 = retval;
|
||||
for (vp=value; *vp; vp++) {
|
||||
if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE))
|
||||
*vp2++ = SECMOD_ARG_ESCAPE;
|
||||
*vp2++ = *vp;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char *secmod_formatPair(char *name,char *value, char quote)
|
||||
{
|
||||
char openQuote = quote;
|
||||
char closeQuote = secmod_argGetPair(quote);
|
||||
char *newValue = NULL;
|
||||
char *returnValue;
|
||||
PRBool need_quote = PR_FALSE;
|
||||
|
||||
if (!value || (*value == 0)) return secmod_nullString;
|
||||
|
||||
if (secmod_argHasBlanks(value) || secmod_argIsQuote(value[0]))
|
||||
need_quote=PR_TRUE;
|
||||
|
||||
if ((need_quote && secmod_argHasChar(value,closeQuote))
|
||||
|| secmod_argHasChar(value,SECMOD_ARG_ESCAPE)) {
|
||||
value = newValue = secmod_formatValue(NULL, value,quote);
|
||||
if (newValue == NULL) return secmod_nullString;
|
||||
}
|
||||
if (need_quote) {
|
||||
returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote);
|
||||
} else {
|
||||
returnValue = PR_smprintf("%s=%s",name,value);
|
||||
}
|
||||
if (returnValue == NULL) returnValue = secmod_nullString;
|
||||
|
||||
if (newValue) PORT_Free(newValue);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static char *secmod_formatIntPair(char *name, unsigned long value,
|
||||
unsigned long def)
|
||||
{
|
||||
char *returnValue;
|
||||
|
||||
if (value == def) return secmod_nullString;
|
||||
|
||||
returnValue = PR_smprintf("%s=%d",name,value);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static void
|
||||
secmod_freePair(char *pair)
|
||||
{
|
||||
if (pair && pair != secmod_nullString) {
|
||||
PR_smprintf_free(pair);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\
|
||||
sizeof("moduleDBOnly")+sizeof("critical")
|
||||
static char *
|
||||
secmod_mkNSSFlags(PRBool internal, PRBool isFIPS,
|
||||
PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
|
||||
{
|
||||
char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
|
||||
PRBool first = PR_TRUE;
|
||||
|
||||
PORT_Memset(flags,0,MAX_FLAG_SIZE);
|
||||
if (internal) {
|
||||
PORT_Strcat(flags,"internal");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (isFIPS) {
|
||||
if (!first) PORT_Strcat(flags,",");
|
||||
PORT_Strcat(flags,"FIPS");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (isModuleDB) {
|
||||
if (!first) PORT_Strcat(flags,",");
|
||||
PORT_Strcat(flags,"moduleDB");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (isModuleDBOnly) {
|
||||
if (!first) PORT_Strcat(flags,",");
|
||||
PORT_Strcat(flags,"moduleDBOnly");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (isCritical) {
|
||||
if (!first) PORT_Strcat(flags,",");
|
||||
PORT_Strcat(flags,"critical");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
|
||||
{
|
||||
char *cipher = NULL;
|
||||
int i;
|
||||
|
||||
for (i=0; i < sizeof(ssl0)*8; i++) {
|
||||
if (ssl0 & (1<<i)) {
|
||||
char *string;
|
||||
if ((1<<i) == SECMOD_FORTEZZA_FLAG) {
|
||||
string = PR_smprintf("%s","FORTEZZA");
|
||||
} else {
|
||||
string = PR_smprintf("0h0x%08x",1<<i);
|
||||
}
|
||||
if (cipher) {
|
||||
char *tmp;
|
||||
tmp = PR_smprintf("%s,%s",cipher,string);
|
||||
PR_smprintf_free(cipher);
|
||||
PR_smprintf_free(string);
|
||||
cipher = tmp;
|
||||
} else {
|
||||
cipher = string;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i < sizeof(ssl0)*8; i++) {
|
||||
if (ssl1 & (1<<i)) {
|
||||
if (cipher) {
|
||||
char *tmp;
|
||||
tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i);
|
||||
PR_smprintf_free(cipher);
|
||||
cipher = tmp;
|
||||
} else {
|
||||
cipher = PR_smprintf("0l0x%08x",1<<i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_mkSlotFlags(unsigned long defaultFlags)
|
||||
{
|
||||
char *flags=NULL;
|
||||
int i,j;
|
||||
|
||||
for (i=0; i < sizeof(defaultFlags)*8; i++) {
|
||||
if (defaultFlags & (1<<i)) {
|
||||
char *string = NULL;
|
||||
|
||||
for (j=0; j < secmod_argSlotFlagTableSize; j++) {
|
||||
if (secmod_argSlotFlagTable[j].value == ( 1UL << i )) {
|
||||
string = secmod_argSlotFlagTable[j].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (string) {
|
||||
if (flags) {
|
||||
char *tmp;
|
||||
tmp = PR_smprintf("%s,%s",flags,string);
|
||||
PR_smprintf_free(flags);
|
||||
flags = tmp;
|
||||
} else {
|
||||
flags = PR_smprintf("%s",string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define SECMOD_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust")
|
||||
|
||||
static char *
|
||||
secmod_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
|
||||
{
|
||||
char *flags= (char *)PORT_ZAlloc(SECMOD_MAX_ROOT_FLAG_SIZE);
|
||||
PRBool first = PR_TRUE;
|
||||
|
||||
PORT_Memset(flags,0,SECMOD_MAX_ROOT_FLAG_SIZE);
|
||||
if (hasRootCerts) {
|
||||
PORT_Strcat(flags,"hasRootCerts");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if (hasRootTrust) {
|
||||
if (!first) PORT_Strcat(flags,",");
|
||||
PORT_Strcat(flags,"hasRootTrust");
|
||||
first = PR_FALSE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_mkSlotString(unsigned long slotID, unsigned long defaultFlags,
|
||||
unsigned long timeout, unsigned char askpw_in,
|
||||
PRBool hasRootCerts, PRBool hasRootTrust) {
|
||||
char *askpw,*flags,*rootFlags,*slotString;
|
||||
char *flagPair,*rootFlagsPair;
|
||||
|
||||
switch (askpw_in) {
|
||||
case 0xff:
|
||||
askpw = "every";
|
||||
break;
|
||||
case 1:
|
||||
askpw = "timeout";
|
||||
break;
|
||||
default:
|
||||
askpw = "any";
|
||||
break;
|
||||
}
|
||||
flags = secmod_mkSlotFlags(defaultFlags);
|
||||
rootFlags = secmod_mkRootFlags(hasRootCerts,hasRootTrust);
|
||||
flagPair=secmod_formatPair("slotFlags",flags,'\'');
|
||||
rootFlagsPair=secmod_formatPair("rootFlags",rootFlags,'\'');
|
||||
if (flags) PR_smprintf_free(flags);
|
||||
if (rootFlags) PORT_Free(rootFlags);
|
||||
if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
|
||||
slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
|
||||
(PRUint32)slotID,flagPair,askpw,timeout,
|
||||
rootFlagsPair);
|
||||
} else {
|
||||
slotString = PR_smprintf("0x%08lx=[%s %s]",
|
||||
(PRUint32)slotID,flagPair,rootFlagsPair);
|
||||
}
|
||||
secmod_freePair(flagPair);
|
||||
secmod_freePair(rootFlagsPair);
|
||||
return slotString;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS,
|
||||
PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical,
|
||||
unsigned long trustOrder, unsigned long cipherOrder,
|
||||
unsigned long ssl0, unsigned long ssl1) {
|
||||
int slotLen, i;
|
||||
char *slotParams, *ciphers, *nss, *nssFlags, *tmp;
|
||||
char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair;
|
||||
|
||||
|
||||
/* now let's build up the string
|
||||
* first the slot infos
|
||||
*/
|
||||
slotLen=0;
|
||||
for (i=0; i < (int)slotCount; i++) {
|
||||
slotLen += PORT_Strlen(slotStrings[i])+1;
|
||||
}
|
||||
slotLen += 1; /* space for the final NULL */
|
||||
|
||||
slotParams = (char *)PORT_ZAlloc(slotLen);
|
||||
PORT_Memset(slotParams,0,slotLen);
|
||||
for (i=0; i < (int)slotCount; i++) {
|
||||
PORT_Strcat(slotParams,slotStrings[i]);
|
||||
PORT_Strcat(slotParams," ");
|
||||
PR_smprintf_free(slotStrings[i]);
|
||||
slotStrings[i]=NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* now the NSS structure
|
||||
*/
|
||||
nssFlags = secmod_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly,
|
||||
isCritical);
|
||||
/* for now only the internal module is critical */
|
||||
ciphers = secmod_mkCipherFlags(ssl0, ssl1);
|
||||
|
||||
trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder,
|
||||
SFTK_DEFAULT_TRUST_ORDER);
|
||||
cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder,
|
||||
SFTK_DEFAULT_CIPHER_ORDER);
|
||||
slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */
|
||||
if (slotParams) PORT_Free(slotParams);
|
||||
cipherPair=secmod_formatPair("ciphers",ciphers,'\'');
|
||||
if (ciphers) PR_smprintf_free(ciphers);
|
||||
flagPair=secmod_formatPair("Flags",nssFlags,'\'');
|
||||
if (nssFlags) PORT_Free(nssFlags);
|
||||
nss = PR_smprintf("%s %s %s %s %s",trustOrderPair,
|
||||
cipherOrderPair,slotPair,cipherPair,flagPair);
|
||||
secmod_freePair(trustOrderPair);
|
||||
secmod_freePair(cipherOrderPair);
|
||||
secmod_freePair(slotPair);
|
||||
secmod_freePair(cipherPair);
|
||||
secmod_freePair(flagPair);
|
||||
tmp = secmod_argStrip(nss);
|
||||
if (*tmp == '\0') {
|
||||
PR_smprintf_free(nss);
|
||||
nss = NULL;
|
||||
}
|
||||
return nss;
|
||||
}
|
||||
|
||||
static char *
|
||||
secmod_mkNewModuleSpec(char *dllName, char *commonName, char *parameters,
|
||||
char *NSS) {
|
||||
char *moduleSpec;
|
||||
char *lib,*name,*param,*nss;
|
||||
|
||||
/*
|
||||
* now the final spec
|
||||
*/
|
||||
lib = secmod_formatPair("library",dllName,'\"');
|
||||
name = secmod_formatPair("name",commonName,'\"');
|
||||
param = secmod_formatPair("parameters",parameters,'\"');
|
||||
nss = secmod_formatPair("NSS",NSS,'\"');
|
||||
moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
|
||||
secmod_freePair(lib);
|
||||
secmod_freePair(name);
|
||||
secmod_freePair(param);
|
||||
secmod_freePair(nss);
|
||||
return (moduleSpec);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,323 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* RSA Labs
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
|
||||
* is granted provided that it is identified as "RSA Security In.c Public-Key
|
||||
* Cryptography Standards (PKCS)" in all material mentioning or referencing
|
||||
* this document.
|
||||
*
|
||||
* The latest version of this header can be found at:
|
||||
* http://www.rsalabs.com/pkcs/pkcs-11/index.html
|
||||
*/
|
||||
#ifndef _PKCS11_H_
|
||||
#define _PKCS11_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Before including this file (pkcs11.h) (or pkcs11t.h by
|
||||
* itself), 6 platform-specific macros must be defined. These
|
||||
* macros are described below, and typical definitions for them
|
||||
* are also given. Be advised that these definitions can depend
|
||||
* on both the platform and the compiler used (and possibly also
|
||||
* on whether a PKCS #11 library is linked statically or
|
||||
* dynamically).
|
||||
*
|
||||
* In addition to defining these 6 macros, the packing convention
|
||||
* for PKCS #11 structures should be set. The PKCS #11
|
||||
* convention on packing is that structures should be 1-byte
|
||||
* aligned.
|
||||
*
|
||||
* In a Win32 environment, this might be done by using the
|
||||
* following preprocessor directive before including pkcs11.h
|
||||
* or pkcs11t.h:
|
||||
*
|
||||
* #pragma pack(push, cryptoki, 1)
|
||||
*
|
||||
* and using the following preprocessor directive after including
|
||||
* pkcs11.h or pkcs11t.h:
|
||||
*
|
||||
* #pragma pack(pop, cryptoki)
|
||||
*
|
||||
* In a Win16 environment, this might be done by using the
|
||||
* following preprocessor directive before including pkcs11.h
|
||||
* or pkcs11t.h:
|
||||
*
|
||||
* #pragma pack(1)
|
||||
*
|
||||
* In a UNIX environment, you're on your own here. You might
|
||||
* not need to do anything.
|
||||
*
|
||||
*
|
||||
* Now for the macros:
|
||||
*
|
||||
*
|
||||
* 1. CK_PTR: The indirection string for making a pointer to an
|
||||
* object. It can be used like this:
|
||||
*
|
||||
* typedef CK_BYTE CK_PTR CK_BYTE_PTR;
|
||||
*
|
||||
* In a Win32 environment, it might be defined by
|
||||
*
|
||||
* #define CK_PTR *
|
||||
*
|
||||
* In a Win16 environment, it might be defined by
|
||||
*
|
||||
* #define CK_PTR far *
|
||||
*
|
||||
* In a UNIX environment, it might be defined by
|
||||
*
|
||||
* #define CK_PTR *
|
||||
*
|
||||
*
|
||||
* 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
|
||||
* an exportable PKCS #11 library function definition out of a
|
||||
* return type and a function name. It should be used in the
|
||||
* following fashion to define the exposed PKCS #11 functions in
|
||||
* a PKCS #11 library:
|
||||
*
|
||||
* CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
|
||||
* CK_VOID_PTR pReserved
|
||||
* )
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* For defining a function in a Win32 PKCS #11 .dll, it might be
|
||||
* defined by
|
||||
*
|
||||
* #define CK_DEFINE_FUNCTION(returnType, name) \
|
||||
* returnType __declspec(dllexport) name
|
||||
*
|
||||
* For defining a function in a Win16 PKCS #11 .dll, it might be
|
||||
* defined by
|
||||
*
|
||||
* #define CK_DEFINE_FUNCTION(returnType, name) \
|
||||
* returnType __export _far _pascal name
|
||||
*
|
||||
* In a UNIX environment, it might be defined by
|
||||
*
|
||||
* #define CK_DEFINE_FUNCTION(returnType, name) \
|
||||
* returnType name
|
||||
*
|
||||
*
|
||||
* 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
|
||||
* an importable PKCS #11 library function declaration out of a
|
||||
* return type and a function name. It should be used in the
|
||||
* following fashion:
|
||||
*
|
||||
* extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
|
||||
* CK_VOID_PTR pReserved
|
||||
* );
|
||||
*
|
||||
* For declaring a function in a Win32 PKCS #11 .dll, it might
|
||||
* be defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION(returnType, name) \
|
||||
* returnType __declspec(dllimport) name
|
||||
*
|
||||
* For declaring a function in a Win16 PKCS #11 .dll, it might
|
||||
* be defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION(returnType, name) \
|
||||
* returnType __export _far _pascal name
|
||||
*
|
||||
* In a UNIX environment, it might be defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION(returnType, name) \
|
||||
* returnType name
|
||||
*
|
||||
*
|
||||
* 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
|
||||
* which makes a PKCS #11 API function pointer declaration or
|
||||
* function pointer type declaration out of a return type and a
|
||||
* function name. It should be used in the following fashion:
|
||||
*
|
||||
* // Define funcPtr to be a pointer to a PKCS #11 API function
|
||||
* // taking arguments args and returning CK_RV.
|
||||
* CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
|
||||
*
|
||||
* or
|
||||
*
|
||||
* // Define funcPtrType to be the type of a pointer to a
|
||||
* // PKCS #11 API function taking arguments args and returning
|
||||
* // CK_RV, and then define funcPtr to be a variable of type
|
||||
* // funcPtrType.
|
||||
* typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
|
||||
* funcPtrType funcPtr;
|
||||
*
|
||||
* For accessing functions in a Win32 PKCS #11 .dll, in might be
|
||||
* defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
|
||||
* returnType __declspec(dllimport) (* name)
|
||||
*
|
||||
* For accessing functions in a Win16 PKCS #11 .dll, it might be
|
||||
* defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
|
||||
* returnType __export _far _pascal (* name)
|
||||
*
|
||||
* In a UNIX environment, it might be defined by
|
||||
*
|
||||
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
|
||||
* returnType (* name)
|
||||
*
|
||||
*
|
||||
* 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
|
||||
* a function pointer type for an application callback out of
|
||||
* a return type for the callback and a name for the callback.
|
||||
* It should be used in the following fashion:
|
||||
*
|
||||
* CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
|
||||
*
|
||||
* to declare a function pointer, myCallback, to a callback
|
||||
* which takes arguments args and returns a CK_RV. It can also
|
||||
* be used like this:
|
||||
*
|
||||
* typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
|
||||
* myCallbackType myCallback;
|
||||
*
|
||||
* In a Win32 environment, it might be defined by
|
||||
*
|
||||
* #define CK_CALLBACK_FUNCTION(returnType, name) \
|
||||
* returnType (* name)
|
||||
*
|
||||
* In a Win16 environment, it might be defined by
|
||||
*
|
||||
* #define CK_CALLBACK_FUNCTION(returnType, name) \
|
||||
* returnType _far _pascal (* name)
|
||||
*
|
||||
* In a UNIX environment, it might be defined by
|
||||
*
|
||||
* #define CK_CALLBACK_FUNCTION(returnType, name) \
|
||||
* returnType (* name)
|
||||
*
|
||||
*
|
||||
* 6. NULL_PTR: This macro is the value of a NULL pointer.
|
||||
*
|
||||
* In any ANSI/ISO C environment (and in many others as well),
|
||||
* this should be defined by
|
||||
*
|
||||
* #ifndef NULL_PTR
|
||||
* #define NULL_PTR 0
|
||||
* #endif
|
||||
*/
|
||||
|
||||
|
||||
/* All the various PKCS #11 types and #define'd values are in the
|
||||
* file pkcs11t.h. */
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#define __PASTE(x,y) x##y
|
||||
|
||||
|
||||
/* packing defines */
|
||||
#include "pkcs11p.h"
|
||||
/* ==============================================================
|
||||
* Define the "extern" form of all the entry points.
|
||||
* ==============================================================
|
||||
*/
|
||||
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) \
|
||||
CK_DECLARE_FUNCTION(CK_RV, name)
|
||||
|
||||
/* pkcs11f.h has all the information about the PKCS #11
|
||||
* function prototypes. */
|
||||
#include "pkcs11f.h"
|
||||
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
|
||||
/* ==============================================================
|
||||
* Define the typedef form of all the entry points. That is, for
|
||||
* each PKCS #11 function C_XXX, define a type CK_C_XXX which is
|
||||
* a pointer to that kind of function.
|
||||
* ==============================================================
|
||||
*/
|
||||
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) \
|
||||
typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
|
||||
|
||||
/* pkcs11f.h has all the information about the PKCS #11
|
||||
* function prototypes. */
|
||||
#include "pkcs11f.h"
|
||||
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
|
||||
/* ==============================================================
|
||||
* Define structed vector of entry points. A CK_FUNCTION_LIST
|
||||
* contains a CK_VERSION indicating a library's PKCS #11 version
|
||||
* and then a whole slew of function pointers to the routines in
|
||||
* the library. This type was declared, but not defined, in
|
||||
* pkcs11t.h.
|
||||
* ==============================================================
|
||||
*/
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) \
|
||||
__PASTE(CK_,name) name;
|
||||
|
||||
struct CK_FUNCTION_LIST {
|
||||
|
||||
CK_VERSION version; /* PKCS #11 version */
|
||||
|
||||
/* Pile all the function pointers into the CK_FUNCTION_LIST. */
|
||||
/* pkcs11f.h has all the information about the PKCS #11
|
||||
* function prototypes. */
|
||||
#include "pkcs11f.h"
|
||||
|
||||
};
|
||||
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
|
||||
#undef __PASTE
|
||||
|
||||
/* unpack */
|
||||
#include "pkcs11u.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,937 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
|
||||
* is granted provided that it is identified as "RSA Security In.c Public-Key
|
||||
* Cryptography Standards (PKCS)" in all material mentioning or referencing
|
||||
* this document.
|
||||
*/
|
||||
/* This function contains pretty much everything about all the */
|
||||
/* PKCS #11 function prototypes. Because this information is */
|
||||
/* used for more than just declaring function prototypes, the */
|
||||
/* order of the functions appearing herein is important, and */
|
||||
/* should not be altered. */
|
||||
|
||||
|
||||
|
||||
/* General-purpose */
|
||||
|
||||
/* C_Initialize initializes the PKCS #11 library. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Initialize)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
|
||||
* cast to CK_C_INITIALIZE_ARGS_PTR
|
||||
* and dereferenced */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Finalize indicates that an application is done with the
|
||||
* PKCS #11 library. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Finalize)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetInfo returns general information about PKCS #11. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetInfo)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_INFO_PTR pInfo /* location that receives information */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetFunctionList returns the function list. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
|
||||
* function list */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Slot and token management */
|
||||
|
||||
/* C_GetSlotList obtains a list of slots in the system. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_BBOOL tokenPresent, /* only slots with tokens? */
|
||||
CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
|
||||
CK_ULONG_PTR pulCount /* receives number of slots */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetSlotInfo obtains information about a particular slot in
|
||||
* the system. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID, /* the ID of the slot */
|
||||
CK_SLOT_INFO_PTR pInfo /* receives the slot information */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetTokenInfo obtains information about a particular token
|
||||
* in the system. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID, /* ID of the token's slot */
|
||||
CK_TOKEN_INFO_PTR pInfo /* receives the token information */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetMechanismList obtains a list of mechanism types
|
||||
* supported by a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID, /* ID of token's slot */
|
||||
CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
|
||||
CK_ULONG_PTR pulCount /* gets # of mechs. */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetMechanismInfo obtains information about a particular
|
||||
* mechanism possibly supported by a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID, /* ID of the token's slot */
|
||||
CK_MECHANISM_TYPE type, /* type of mechanism */
|
||||
CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_InitToken initializes a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_InitToken)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
|
||||
CK_SLOT_ID slotID, /* ID of the token's slot */
|
||||
CK_CHAR_PTR pPin, /* the SO's initial PIN */
|
||||
CK_ULONG ulPinLen, /* length in bytes of the PIN */
|
||||
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_InitPIN initializes the normal user's PIN. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_InitPIN)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_CHAR_PTR pPin, /* the normal user's PIN */
|
||||
CK_ULONG ulPinLen /* length in bytes of the PIN */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SetPIN modifies the PIN of the user who is logged in. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SetPIN)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_CHAR_PTR pOldPin, /* the old PIN */
|
||||
CK_ULONG ulOldLen, /* length of the old PIN */
|
||||
CK_CHAR_PTR pNewPin, /* the new PIN */
|
||||
CK_ULONG ulNewLen /* length of the new PIN */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Session management */
|
||||
|
||||
/* C_OpenSession opens a session between an application and a
|
||||
* token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_OpenSession)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID, /* the slot's ID */
|
||||
CK_FLAGS flags, /* from CK_SESSION_INFO */
|
||||
CK_VOID_PTR pApplication, /* passed to callback */
|
||||
CK_NOTIFY Notify, /* callback function */
|
||||
CK_SESSION_HANDLE_PTR phSession /* gets session handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_CloseSession closes a session between an application and a
|
||||
* token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_CloseSession)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession /* the session's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_CloseAllSessions closes all sessions with a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SLOT_ID slotID /* the token's slot */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetSessionInfo obtains information about the session. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_SESSION_INFO_PTR pInfo /* receives session info */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetOperationState obtains the state of the cryptographic operation
|
||||
* in a session. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pOperationState, /* gets state */
|
||||
CK_ULONG_PTR pulOperationStateLen /* gets state length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SetOperationState restores the state of the cryptographic
|
||||
* operation in a session. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pOperationState, /* holds state */
|
||||
CK_ULONG ulOperationStateLen, /* holds state length */
|
||||
CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
|
||||
CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Login logs a user into a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Login)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_USER_TYPE userType, /* the user type */
|
||||
CK_CHAR_PTR pPin, /* the user's PIN */
|
||||
CK_ULONG ulPinLen /* the length of the PIN */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Logout logs a user out from a token. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Logout)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession /* the session's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Object management */
|
||||
|
||||
/* C_CreateObject creates a new object. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_CreateObject)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
|
||||
CK_ULONG ulCount, /* attributes in template */
|
||||
CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_CopyObject copies an object, creating a new object for the
|
||||
* copy. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_CopyObject)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
|
||||
CK_ULONG ulCount, /* attributes in template */
|
||||
CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DestroyObject destroys an object. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject /* the object's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetObjectSize gets the size of an object in bytes. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
||||
CK_ULONG_PTR pulSize /* receives size of object */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GetAttributeValue obtains the value of one or more object
|
||||
* attributes. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
|
||||
CK_ULONG ulCount /* attributes in template */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SetAttributeValue modifies the value of one or more object
|
||||
* attributes */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
|
||||
CK_ULONG ulCount /* attributes in template */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_FindObjectsInit initializes a search for token and session
|
||||
* objects that match a template. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
|
||||
CK_ULONG ulCount /* attrs in search template */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_FindObjects continues a search for token and session
|
||||
* objects that match a template, obtaining additional object
|
||||
* handles. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_FindObjects)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
|
||||
CK_ULONG ulMaxObjectCount, /* max handles to get */
|
||||
CK_ULONG_PTR pulObjectCount /* actual # returned */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_FindObjectsFinal finishes a search for token and session
|
||||
* objects. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession /* the session's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Encryption and decryption */
|
||||
|
||||
/* C_EncryptInit initializes an encryption operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* handle of encryption key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Encrypt encrypts single-part data. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Encrypt)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pData, /* the plaintext data */
|
||||
CK_ULONG ulDataLen, /* bytes of plaintext */
|
||||
CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
|
||||
CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_EncryptUpdate continues a multiple-part encryption
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pPart, /* the plaintext data */
|
||||
CK_ULONG ulPartLen, /* plaintext data len */
|
||||
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
|
||||
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_EncryptFinal finishes a multiple-part encryption
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session handle */
|
||||
CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
|
||||
CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DecryptInit initializes a decryption operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* handle of decryption key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Decrypt decrypts encrypted data in a single part. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Decrypt)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pEncryptedData, /* ciphertext */
|
||||
CK_ULONG ulEncryptedDataLen, /* ciphertext length */
|
||||
CK_BYTE_PTR pData, /* gets plaintext */
|
||||
CK_ULONG_PTR pulDataLen /* gets p-text size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DecryptUpdate continues a multiple-part decryption
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pEncryptedPart, /* encrypted data */
|
||||
CK_ULONG ulEncryptedPartLen, /* input length */
|
||||
CK_BYTE_PTR pPart, /* gets plaintext */
|
||||
CK_ULONG_PTR pulPartLen /* p-text size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DecryptFinal finishes a multiple-part decryption
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pLastPart, /* gets plaintext */
|
||||
CK_ULONG_PTR pulLastPartLen /* p-text size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Message digesting */
|
||||
|
||||
/* C_DigestInit initializes a message-digesting operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DigestInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Digest digests data in a single part. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Digest)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pData, /* data to be digested */
|
||||
CK_ULONG ulDataLen, /* bytes of data to digest */
|
||||
CK_BYTE_PTR pDigest, /* gets the message digest */
|
||||
CK_ULONG_PTR pulDigestLen /* gets digest length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DigestUpdate continues a multiple-part message-digesting
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pPart, /* data to be digested */
|
||||
CK_ULONG ulPartLen /* bytes of data to be digested */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DigestKey continues a multi-part message-digesting
|
||||
* operation, by digesting the value of a secret key as part of
|
||||
* the data already digested. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DigestKey)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hKey /* secret key to digest */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DigestFinal finishes a multiple-part message-digesting
|
||||
* operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pDigest, /* gets the message digest */
|
||||
CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Signing and MACing */
|
||||
|
||||
/* C_SignInit initializes a signature (private key encryption)
|
||||
* operation, where the signature is (will be) an appendix to
|
||||
* the data, and plaintext cannot be recovered from the
|
||||
*signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* handle of signature key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Sign signs (encrypts with private key) data in a single
|
||||
* part, where the signature is (will be) an appendix to the
|
||||
* data, and plaintext cannot be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Sign)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pData, /* the data to sign */
|
||||
CK_ULONG ulDataLen, /* count of bytes to sign */
|
||||
CK_BYTE_PTR pSignature, /* gets the signature */
|
||||
CK_ULONG_PTR pulSignatureLen /* gets signature length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SignUpdate continues a multiple-part signature operation,
|
||||
* where the signature is (will be) an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pPart, /* the data to sign */
|
||||
CK_ULONG ulPartLen /* count of bytes to sign */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SignFinal finishes a multiple-part signature operation,
|
||||
* returning the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pSignature, /* gets the signature */
|
||||
CK_ULONG_PTR pulSignatureLen /* gets signature length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SignRecoverInit initializes a signature operation, where
|
||||
* the data can be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* handle of the signature key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SignRecover signs data in a single operation, where the
|
||||
* data can be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignRecover)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pData, /* the data to sign */
|
||||
CK_ULONG ulDataLen, /* count of bytes to sign */
|
||||
CK_BYTE_PTR pSignature, /* gets the signature */
|
||||
CK_ULONG_PTR pulSignatureLen /* gets signature length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Verifying signatures and MACs */
|
||||
|
||||
/* C_VerifyInit initializes a verification operation, where the
|
||||
* signature is an appendix to the data, and plaintext cannot
|
||||
* cannot be recovered from the signature (e.g. DSA). */
|
||||
CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* verification key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_Verify verifies a signature in a single-part operation,
|
||||
* where the signature is an appendix to the data, and plaintext
|
||||
* cannot be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_Verify)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pData, /* signed data */
|
||||
CK_ULONG ulDataLen, /* length of signed data */
|
||||
CK_BYTE_PTR pSignature, /* signature */
|
||||
CK_ULONG ulSignatureLen /* signature length*/
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_VerifyUpdate continues a multiple-part verification
|
||||
* operation, where the signature is an appendix to the data,
|
||||
* and plaintext cannot be recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pPart, /* signed data */
|
||||
CK_ULONG ulPartLen /* length of signed data */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_VerifyFinal finishes a multiple-part verification
|
||||
* operation, checking the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pSignature, /* signature to verify */
|
||||
CK_ULONG ulSignatureLen /* signature length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_VerifyRecoverInit initializes a signature verification
|
||||
* operation, where the data is recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
|
||||
CK_OBJECT_HANDLE hKey /* verification key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_VerifyRecover verifies a signature in a single-part
|
||||
* operation, where the data is recovered from the signature. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pSignature, /* signature to verify */
|
||||
CK_ULONG ulSignatureLen, /* signature length */
|
||||
CK_BYTE_PTR pData, /* gets signed data */
|
||||
CK_ULONG_PTR pulDataLen /* gets signed data len */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Dual-function cryptographic operations */
|
||||
|
||||
/* C_DigestEncryptUpdate continues a multiple-part digesting
|
||||
* and encryption operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pPart, /* the plaintext data */
|
||||
CK_ULONG ulPartLen, /* plaintext length */
|
||||
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
|
||||
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DecryptDigestUpdate continues a multiple-part decryption and
|
||||
* digesting operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
|
||||
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
|
||||
CK_BYTE_PTR pPart, /* gets plaintext */
|
||||
CK_ULONG_PTR pulPartLen /* gets plaintext len */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_SignEncryptUpdate continues a multiple-part signing and
|
||||
* encryption operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pPart, /* the plaintext data */
|
||||
CK_ULONG ulPartLen, /* plaintext length */
|
||||
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
|
||||
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DecryptVerifyUpdate continues a multiple-part decryption and
|
||||
* verify operation. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
|
||||
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
|
||||
CK_BYTE_PTR pPart, /* gets plaintext */
|
||||
CK_ULONG_PTR pulPartLen /* gets p-text length */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Key management */
|
||||
|
||||
/* C_GenerateKey generates a secret key, creating a new key
|
||||
* object. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* key generation mech. */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
|
||||
CK_ULONG ulCount, /* # of attrs in template */
|
||||
CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GenerateKeyPair generates a public-key/private-key pair,
|
||||
* creating new key objects. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session
|
||||
* handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* key-gen
|
||||
* mech. */
|
||||
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
|
||||
* for pub.
|
||||
* key */
|
||||
CK_ULONG ulPublicKeyAttributeCount, /* # pub.
|
||||
* attrs. */
|
||||
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
|
||||
* for priv.
|
||||
* key */
|
||||
CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
|
||||
* attrs. */
|
||||
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
|
||||
* key
|
||||
* handle */
|
||||
CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
|
||||
* priv. key
|
||||
* handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_WrapKey wraps (i.e., encrypts) a key. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_WrapKey)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
|
||||
CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
|
||||
CK_OBJECT_HANDLE hKey, /* key to be wrapped */
|
||||
CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
|
||||
CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
|
||||
* key object. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
|
||||
CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
|
||||
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
|
||||
CK_ULONG ulWrappedKeyLen, /* wrapped key len */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
|
||||
CK_ULONG ulAttributeCount, /* template length */
|
||||
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_DeriveKey derives a key from a base key, creating a new key
|
||||
* object. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* session's handle */
|
||||
CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
|
||||
CK_OBJECT_HANDLE hBaseKey, /* base key */
|
||||
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
|
||||
CK_ULONG ulAttributeCount, /* template length */
|
||||
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Random number generation */
|
||||
|
||||
/* C_SeedRandom mixes additional seed material into the token's
|
||||
* random number generator. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR pSeed, /* the seed material */
|
||||
CK_ULONG ulSeedLen /* length of seed material */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_GenerateRandom generates random data. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_BYTE_PTR RandomData, /* receives the random data */
|
||||
CK_ULONG ulRandomLen /* # of bytes to generate */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Parallel function management */
|
||||
|
||||
/* C_GetFunctionStatus is a legacy function; it obtains an
|
||||
* updated status of a function running in parallel with an
|
||||
* application. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession /* the session's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/* C_CancelFunction is a legacy function; it cancels a function
|
||||
* running in parallel. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_SESSION_HANDLE hSession /* the session's handle */
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Functions added in for PKCS #11 Version 2.01 or later */
|
||||
|
||||
/* C_WaitForSlotEvent waits for a slot event (token insertion,
|
||||
* removal, etc.) to occur. */
|
||||
CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
|
||||
#ifdef CK_NEED_ARG_LIST
|
||||
(
|
||||
CK_FLAGS flags, /* blocking/nonblocking flag */
|
||||
CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
|
||||
CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
|
||||
);
|
||||
#endif
|
||||
@@ -1,697 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* Internal data structures and functions used by pkcs11.c
|
||||
*/
|
||||
#ifndef _PKCS11I_H_
|
||||
#define _PKCS11I_H_ 1
|
||||
|
||||
#include "nssilock.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
#include "lowkeyti.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "pcertt.h"
|
||||
|
||||
|
||||
/*
|
||||
* Configuration Defines
|
||||
*
|
||||
* The following defines affect the space verse speed trade offs of
|
||||
* the PKCS #11 module. For the most part the current settings are optimized
|
||||
* for web servers, where we want faster speed and lower lock contention at
|
||||
* the expense of space.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The attribute allocation strategy is static allocation:
|
||||
* Attributes are pre-allocated as part of the session object and used from
|
||||
* the object array.
|
||||
*/
|
||||
#define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in
|
||||
* the object (must me the absolute max) */
|
||||
#define ATTR_SPACE 50 /* Maximum size of attribute data before extra
|
||||
* data needs to be allocated. This is set to
|
||||
* enough space to hold an SSL MASTER secret */
|
||||
|
||||
#define NSC_STRICT PR_FALSE /* forces the code to do strict template
|
||||
* matching when doing C_FindObject on token
|
||||
* objects. This will slow down search in
|
||||
* NSS. */
|
||||
/* default search block allocations and increments */
|
||||
#define NSC_CERT_BLOCK_SIZE 50
|
||||
#define NSC_SEARCH_BLOCK_SIZE 5
|
||||
#define NSC_SLOT_LIST_BLOCK_SIZE 10
|
||||
|
||||
#define NSC_FIPS_MODULE 1
|
||||
#define NSC_NON_FIPS_MODULE 0
|
||||
|
||||
/* these are data base storage hashes, not cryptographic hashes.. The define
|
||||
* the effective size of the various object hash tables */
|
||||
/* clients care more about memory usage than lookup performance on
|
||||
* cyrptographic objects. Clients also have less objects around to play with
|
||||
*
|
||||
* we eventually should make this configurable at runtime! Especially now that
|
||||
* NSS is a shared library.
|
||||
*/
|
||||
#define SPACE_ATTRIBUTE_HASH_SIZE 32
|
||||
#define SPACE_TOKEN_OBJECT_HASH_SIZE 32
|
||||
#define SPACE_SESSION_HASH_SIZE 32
|
||||
#define TIME_ATTRIBUTE_HASH_SIZE 32
|
||||
#define TIME_TOKEN_OBJECT_HASH_SIZE 1024
|
||||
#define TIME_SESSION_HASH_SIZE 1024
|
||||
#define MAX_OBJECT_LIST_SIZE 800
|
||||
/* how many objects to keep on the free list
|
||||
* before we start freeing them */
|
||||
#define MAX_KEY_LEN 256
|
||||
|
||||
#define MULTIACCESS "multiaccess:"
|
||||
|
||||
/*
|
||||
* LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number.
|
||||
* With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0.
|
||||
* With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0.
|
||||
*
|
||||
* HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS
|
||||
* 1024 9 512 2
|
||||
* 1024 5 32 32
|
||||
* 1024 1 2 512
|
||||
* 1024 0 1 1024
|
||||
* 4096 11 2048 2
|
||||
* 4096 9 512 8
|
||||
* 4096 5 32 128
|
||||
* 4096 1 2 2048
|
||||
* 4096 0 1 4096
|
||||
*/
|
||||
#define LOG2_BUCKETS_PER_SESSION_LOCK 1
|
||||
#define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK))
|
||||
/* NOSPREAD sessionID to hash table index macro has been slower. */
|
||||
|
||||
/* define typedefs, double as forward declarations as well */
|
||||
typedef struct SFTKAttributeStr SFTKAttribute;
|
||||
typedef struct SFTKObjectListStr SFTKObjectList;
|
||||
typedef struct SFTKObjectFreeListStr SFTKObjectFreeList;
|
||||
typedef struct SFTKObjectListElementStr SFTKObjectListElement;
|
||||
typedef struct SFTKObjectStr SFTKObject;
|
||||
typedef struct SFTKSessionObjectStr SFTKSessionObject;
|
||||
typedef struct SFTKTokenObjectStr SFTKTokenObject;
|
||||
typedef struct SFTKSessionStr SFTKSession;
|
||||
typedef struct SFTKSlotStr SFTKSlot;
|
||||
typedef struct SFTKSessionContextStr SFTKSessionContext;
|
||||
typedef struct SFTKSearchResultsStr SFTKSearchResults;
|
||||
typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo;
|
||||
typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
|
||||
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
|
||||
|
||||
/* define function pointer typdefs for pointer tables */
|
||||
typedef void (*SFTKDestroy)(void *, PRBool);
|
||||
typedef void (*SFTKBegin)(void *);
|
||||
typedef SECStatus (*SFTKCipher)(void *,void *,unsigned int *,unsigned int,
|
||||
void *, unsigned int);
|
||||
typedef SECStatus (*SFTKVerify)(void *,void *,unsigned int,void *,unsigned int);
|
||||
typedef void (*SFTKHash)(void *,void *,unsigned int);
|
||||
typedef void (*SFTKEnd)(void *,void *,unsigned int *,unsigned int);
|
||||
typedef void (*SFTKFree)(void *);
|
||||
|
||||
/* Value to tell if an attribute is modifiable or not.
|
||||
* NEVER: attribute is only set on creation.
|
||||
* ONCOPY: attribute is set on creation and can only be changed on copy.
|
||||
* SENSITIVE: attribute can only be changed to TRUE.
|
||||
* ALWAYS: attribute can always be changed.
|
||||
*/
|
||||
typedef enum {
|
||||
SFTK_NEVER = 0,
|
||||
SFTK_ONCOPY = 1,
|
||||
SFTK_SENSITIVE = 2,
|
||||
SFTK_ALWAYS = 3
|
||||
} SFTKModifyType;
|
||||
|
||||
/*
|
||||
* Free Status Enum... tell us more information when we think we're
|
||||
* deleting an object.
|
||||
*/
|
||||
typedef enum {
|
||||
SFTK_DestroyFailure,
|
||||
SFTK_Destroyed,
|
||||
SFTK_Busy
|
||||
} SFTKFreeStatus;
|
||||
|
||||
/*
|
||||
* attribute values of an object.
|
||||
*/
|
||||
struct SFTKAttributeStr {
|
||||
SFTKAttribute *next;
|
||||
SFTKAttribute *prev;
|
||||
PRBool freeAttr;
|
||||
PRBool freeData;
|
||||
/*must be called handle to make sftkqueue_find work */
|
||||
CK_ATTRIBUTE_TYPE handle;
|
||||
CK_ATTRIBUTE attrib;
|
||||
unsigned char space[ATTR_SPACE];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* doubly link list of objects
|
||||
*/
|
||||
struct SFTKObjectListStr {
|
||||
SFTKObjectList *next;
|
||||
SFTKObjectList *prev;
|
||||
SFTKObject *parent;
|
||||
};
|
||||
|
||||
struct SFTKObjectFreeListStr {
|
||||
SFTKObject *head;
|
||||
PZLock *lock;
|
||||
int count;
|
||||
};
|
||||
|
||||
/*
|
||||
* PKCS 11 crypto object structure
|
||||
*/
|
||||
struct SFTKObjectStr {
|
||||
SFTKObject *next;
|
||||
SFTKObject *prev;
|
||||
CK_OBJECT_CLASS objclass;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
int refCount;
|
||||
PZLock *refLock;
|
||||
SFTKSlot *slot;
|
||||
void *objectInfo;
|
||||
SFTKFree infoFree;
|
||||
};
|
||||
|
||||
struct SFTKTokenObjectStr {
|
||||
SFTKObject obj;
|
||||
SECItem dbKey;
|
||||
};
|
||||
|
||||
struct SFTKSessionObjectStr {
|
||||
SFTKObject obj;
|
||||
SFTKObjectList sessionList;
|
||||
PZLock *attributeLock;
|
||||
SFTKSession *session;
|
||||
PRBool wasDerived;
|
||||
int nextAttr;
|
||||
SFTKAttribute attrList[MAX_OBJS_ATTRS];
|
||||
PRBool optimizeSpace;
|
||||
unsigned int hashSize;
|
||||
SFTKAttribute *head[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* struct to deal with a temparary list of objects
|
||||
*/
|
||||
struct SFTKObjectListElementStr {
|
||||
SFTKObjectListElement *next;
|
||||
SFTKObject *object;
|
||||
};
|
||||
|
||||
/*
|
||||
* Area to hold Search results
|
||||
*/
|
||||
struct SFTKSearchResultsStr {
|
||||
CK_OBJECT_HANDLE *handles;
|
||||
int size;
|
||||
int index;
|
||||
int array_size;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* the universal crypto/hash/sign/verify context structure
|
||||
*/
|
||||
typedef enum {
|
||||
SFTK_ENCRYPT,
|
||||
SFTK_DECRYPT,
|
||||
SFTK_HASH,
|
||||
SFTK_SIGN,
|
||||
SFTK_SIGN_RECOVER,
|
||||
SFTK_VERIFY,
|
||||
SFTK_VERIFY_RECOVER
|
||||
} SFTKContextType;
|
||||
|
||||
|
||||
#define SFTK_MAX_BLOCK_SIZE 16
|
||||
/* currently SHA512 is the biggest hash length */
|
||||
#define SFTK_MAX_MAC_LENGTH 64
|
||||
#define SFTK_INVALID_MAC_SIZE 0xffffffff
|
||||
|
||||
struct SFTKSessionContextStr {
|
||||
SFTKContextType type;
|
||||
PRBool multi; /* is multipart */
|
||||
PRBool doPad; /* use PKCS padding for block ciphers */
|
||||
unsigned int blockSize; /* blocksize for padding */
|
||||
unsigned int padDataLength; /* length of the valid data in padbuf */
|
||||
unsigned char padBuf[SFTK_MAX_BLOCK_SIZE];
|
||||
unsigned char macBuf[SFTK_MAX_BLOCK_SIZE];
|
||||
CK_ULONG macSize; /* size of a general block cipher mac*/
|
||||
void *cipherInfo;
|
||||
void *hashInfo;
|
||||
unsigned int cipherInfoLen;
|
||||
CK_MECHANISM_TYPE currentMech;
|
||||
SFTKCipher update;
|
||||
SFTKHash hashUpdate;
|
||||
SFTKEnd end;
|
||||
SFTKDestroy destroy;
|
||||
SFTKDestroy hashdestroy;
|
||||
SFTKVerify verify;
|
||||
unsigned int maxLen;
|
||||
SFTKObject *key;
|
||||
};
|
||||
|
||||
/*
|
||||
* Sessions (have objects)
|
||||
*/
|
||||
struct SFTKSessionStr {
|
||||
SFTKSession *next;
|
||||
SFTKSession *prev;
|
||||
CK_SESSION_HANDLE handle;
|
||||
int refCount;
|
||||
PZLock *objectLock;
|
||||
int objectIDCount;
|
||||
CK_SESSION_INFO info;
|
||||
CK_NOTIFY notify;
|
||||
CK_VOID_PTR appData;
|
||||
SFTKSlot *slot;
|
||||
SFTKSearchResults *search;
|
||||
SFTKSessionContext *enc_context;
|
||||
SFTKSessionContext *hash_context;
|
||||
SFTKSessionContext *sign_context;
|
||||
SFTKObjectList *objects[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* slots (have sessions and objects)
|
||||
*
|
||||
* The array of sessionLock's protect the session hash table (head[])
|
||||
* as well as the reference count of session objects in that bucket
|
||||
* (head[]->refCount), objectLock protects all elements of the token
|
||||
* object hash table (tokObjects[], tokenIDCount, and tokenHashTable),
|
||||
* and slotLock protects the remaining protected elements:
|
||||
* password, isLoggedIn, ssoLoggedIn, and sessionCount
|
||||
*/
|
||||
struct SFTKSlotStr {
|
||||
CK_SLOT_ID slotID;
|
||||
PZLock *slotLock;
|
||||
PZLock **sessionLock;
|
||||
unsigned int numSessionLocks;
|
||||
unsigned long sessionLockMask;
|
||||
PZLock *objectLock;
|
||||
SECItem *password;
|
||||
PRBool hasTokens;
|
||||
PRBool isLoggedIn;
|
||||
PRBool ssoLoggedIn;
|
||||
PRBool needLogin;
|
||||
PRBool DB_loaded;
|
||||
PRBool readOnly;
|
||||
PRBool optimizeSpace;
|
||||
NSSLOWCERTCertDBHandle *certDB;
|
||||
NSSLOWKEYDBHandle *keyDB;
|
||||
int minimumPinLen;
|
||||
PRInt32 sessionIDCount; /* atomically incremented */
|
||||
int sessionIDConflict; /* not protected by a lock */
|
||||
int sessionCount;
|
||||
PRInt32 rwSessionCount; /* set by atomic operations */
|
||||
int tokenIDCount;
|
||||
int index;
|
||||
PLHashTable *tokenHashTable;
|
||||
SFTKObject **tokObjects;
|
||||
unsigned int tokObjHashSize;
|
||||
SFTKSession **head;
|
||||
unsigned int sessHashSize;
|
||||
char tokDescription[33];
|
||||
char slotDescription[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* special joint operations Contexts
|
||||
*/
|
||||
struct SFTKHashVerifyInfoStr {
|
||||
SECOidTag hashOid;
|
||||
NSSLOWKEYPublicKey *key;
|
||||
};
|
||||
|
||||
struct SFTKHashSignInfoStr {
|
||||
SECOidTag hashOid;
|
||||
NSSLOWKEYPrivateKey *key;
|
||||
};
|
||||
|
||||
/* context for the Final SSLMAC message */
|
||||
struct SFTKSSLMACInfoStr {
|
||||
void *hashContext;
|
||||
SFTKBegin begin;
|
||||
SFTKHash update;
|
||||
SFTKEnd end;
|
||||
CK_ULONG macSize;
|
||||
int padSize;
|
||||
unsigned char key[MAX_KEY_LEN];
|
||||
unsigned int keySize;
|
||||
};
|
||||
|
||||
/*
|
||||
* session handle modifiers
|
||||
*/
|
||||
#define SFTK_SESSION_SLOT_MASK 0xff000000L
|
||||
|
||||
/*
|
||||
* object handle modifiers
|
||||
*/
|
||||
#define SFTK_TOKEN_MASK 0x80000000L
|
||||
#define SFTK_TOKEN_MAGIC 0x80000000L
|
||||
#define SFTK_TOKEN_TYPE_MASK 0x70000000L
|
||||
/* keydb (high bit == 0) */
|
||||
#define SFTK_TOKEN_TYPE_PRIV 0x10000000L
|
||||
#define SFTK_TOKEN_TYPE_PUB 0x20000000L
|
||||
#define SFTK_TOKEN_TYPE_KEY 0x30000000L
|
||||
/* certdb (high bit == 1) */
|
||||
#define SFTK_TOKEN_TYPE_TRUST 0x40000000L
|
||||
#define SFTK_TOKEN_TYPE_CRL 0x50000000L
|
||||
#define SFTK_TOKEN_TYPE_SMIME 0x60000000L
|
||||
#define SFTK_TOKEN_TYPE_CERT 0x70000000L
|
||||
|
||||
#define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC|SFTK_TOKEN_TYPE_CRL|1)
|
||||
/* how big a password/pin we can deal with */
|
||||
#define SFTK_MAX_PIN 255
|
||||
|
||||
/* slot ID's */
|
||||
#define NETSCAPE_SLOT_ID 1
|
||||
#define PRIVATE_KEY_SLOT_ID 2
|
||||
#define FIPS_SLOT_ID 3
|
||||
|
||||
/* slot helper macros */
|
||||
#define sftk_SlotFromSession(sp) ((sp)->slot)
|
||||
#define sftk_isToken(id) (((id) & SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC)
|
||||
|
||||
/* the session hash multiplier (see bug 201081) */
|
||||
#define SHMULTIPLIER 1791398085
|
||||
|
||||
/* queueing helper macros */
|
||||
#define sftk_hash(value,size) \
|
||||
((PRUint32)((value) * SHMULTIPLIER) & (size-1))
|
||||
#define sftkqueue_add(element,id,head,hash_size) \
|
||||
{ int tmp = sftk_hash(id,hash_size); \
|
||||
(element)->next = (head)[tmp]; \
|
||||
(element)->prev = NULL; \
|
||||
if ((head)[tmp]) (head)[tmp]->prev = (element); \
|
||||
(head)[tmp] = (element); }
|
||||
#define sftkqueue_find(element,id,head,hash_size) \
|
||||
for( (element) = (head)[sftk_hash(id,hash_size)]; (element) != NULL; \
|
||||
(element) = (element)->next) { \
|
||||
if ((element)->handle == (id)) { break; } }
|
||||
#define sftkqueue_is_queued(element,id,head,hash_size) \
|
||||
( ((element)->next) || ((element)->prev) || \
|
||||
((head)[sftk_hash(id,hash_size)] == (element)) )
|
||||
#define sftkqueue_delete(element,id,head,hash_size) \
|
||||
if ((element)->next) (element)->next->prev = (element)->prev; \
|
||||
if ((element)->prev) (element)->prev->next = (element)->next; \
|
||||
else (head)[sftk_hash(id,hash_size)] = ((element)->next); \
|
||||
(element)->next = NULL; \
|
||||
(element)->prev = NULL; \
|
||||
|
||||
#define sftkqueue_init_element(element) \
|
||||
(element)->prev = NULL;
|
||||
|
||||
#define sftkqueue_add2(element, id, index, head) \
|
||||
{ \
|
||||
(element)->next = (head)[index]; \
|
||||
if ((head)[index]) \
|
||||
(head)[index]->prev = (element); \
|
||||
(head)[index] = (element); \
|
||||
}
|
||||
|
||||
#define sftkqueue_find2(element, id, index, head) \
|
||||
for ( (element) = (head)[index]; \
|
||||
(element) != NULL; \
|
||||
(element) = (element)->next) { \
|
||||
if ((element)->handle == (id)) { break; } \
|
||||
}
|
||||
|
||||
#define sftkqueue_delete2(element, id, index, head) \
|
||||
if ((element)->next) (element)->next->prev = (element)->prev; \
|
||||
if ((element)->prev) (element)->prev->next = (element)->next; \
|
||||
else (head)[index] = ((element)->next);
|
||||
|
||||
#define sftkqueue_clear_deleted_element(element) \
|
||||
(element)->next = NULL; \
|
||||
(element)->prev = NULL; \
|
||||
|
||||
|
||||
/* sessionID (handle) is used to determine session lock bucket */
|
||||
#ifdef NOSPREAD
|
||||
/* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */
|
||||
#define SFTK_SESSION_LOCK(slot,handle) \
|
||||
((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \
|
||||
& (slot)->sessionLockMask])
|
||||
#else
|
||||
/* SPREAD: ID & (perbucket-1) */
|
||||
#define SFTK_SESSION_LOCK(slot,handle) \
|
||||
((slot)->sessionLock[(handle) & (slot)->sessionLockMask])
|
||||
#endif
|
||||
|
||||
/* expand an attribute & secitem structures out */
|
||||
#define sftk_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
|
||||
#define sftk_item_expand(ip) (ip)->data,(ip)->len
|
||||
|
||||
typedef struct sftk_token_parametersStr {
|
||||
CK_SLOT_ID slotID;
|
||||
char *configdir;
|
||||
char *certPrefix;
|
||||
char *keyPrefix;
|
||||
char *tokdes;
|
||||
char *slotdes;
|
||||
int minPW;
|
||||
PRBool readOnly;
|
||||
PRBool noCertDB;
|
||||
PRBool noKeyDB;
|
||||
PRBool forceOpen;
|
||||
PRBool pwRequired;
|
||||
PRBool optimizeSpace;
|
||||
} sftk_token_parameters;
|
||||
|
||||
typedef struct sftk_parametersStr {
|
||||
char *configdir;
|
||||
char *secmodName;
|
||||
char *man;
|
||||
char *libdes;
|
||||
PRBool readOnly;
|
||||
PRBool noModDB;
|
||||
PRBool noCertDB;
|
||||
PRBool forceOpen;
|
||||
PRBool pwRequired;
|
||||
PRBool optimizeSpace;
|
||||
sftk_token_parameters *tokens;
|
||||
int token_count;
|
||||
} sftk_parameters;
|
||||
|
||||
|
||||
/* machine dependent path stuff used by dbinit.c and pk11db.c */
|
||||
#ifdef macintosh
|
||||
#define PATH_SEPARATOR ":"
|
||||
#define SECMOD_DB "Security Modules"
|
||||
#define CERT_DB_FMT "%sCertificates%s"
|
||||
#define KEY_DB_FMT "%sKey Database%s"
|
||||
#else
|
||||
#define PATH_SEPARATOR "/"
|
||||
#define SECMOD_DB "secmod.db"
|
||||
#define CERT_DB_FMT "%scert%s.db"
|
||||
#define KEY_DB_FMT "%skey%s.db"
|
||||
#endif
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
extern int nsf_init;
|
||||
extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
|
||||
extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
|
||||
extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
|
||||
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
|
||||
/* shared functions between PKCS11.c and SFTKFIPS.c */
|
||||
extern CK_RV SFTK_SlotInit(char *configdir,sftk_token_parameters *params,
|
||||
int moduleIndex);
|
||||
|
||||
/* internal utility functions used by pkcs11.c */
|
||||
extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object,
|
||||
CK_ATTRIBUTE_TYPE type);
|
||||
extern void sftk_FreeAttribute(SFTKAttribute *attribute);
|
||||
extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
|
||||
void *valPtr,
|
||||
CK_ULONG length);
|
||||
extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
|
||||
SFTKObject *object, CK_ATTRIBUTE_TYPE type);
|
||||
extern unsigned int sftk_GetLengthInBits(unsigned char *buf,
|
||||
unsigned int bufLen);
|
||||
extern CK_RV sftk_ConstrainAttribute(SFTKObject *object,
|
||||
CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple);
|
||||
extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
|
||||
extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
|
||||
extern void sftk_DeleteAttributeType(SFTKObject *object,
|
||||
CK_ATTRIBUTE_TYPE type);
|
||||
extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
|
||||
SFTKObject *object, CK_ATTRIBUTE_TYPE type);
|
||||
extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item,
|
||||
SFTKObject *object,
|
||||
CK_ATTRIBUTE_TYPE type);
|
||||
extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type,
|
||||
CK_OBJECT_CLASS inClass);
|
||||
extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass);
|
||||
extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
|
||||
extern void sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type);
|
||||
extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
|
||||
CK_ULONG *longData);
|
||||
extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
|
||||
void *value, unsigned int len);
|
||||
extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
|
||||
void *value, unsigned int len);
|
||||
extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth);
|
||||
|
||||
extern SFTKObject *sftk_NewObject(SFTKSlot *slot);
|
||||
extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject);
|
||||
extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object);
|
||||
extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object);
|
||||
extern void sftk_ReferenceObject(SFTKObject *object);
|
||||
extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle,
|
||||
SFTKSession *session);
|
||||
extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object);
|
||||
extern void sftk_AddObject(SFTKSession *session, SFTKObject *object);
|
||||
|
||||
extern CK_RV sftk_searchObjectList(SFTKSearchResults *search,
|
||||
SFTKObject **head, unsigned int size,
|
||||
PZLock *lock, CK_ATTRIBUTE_PTR inTemplate,
|
||||
int count, PRBool isLoggedIn);
|
||||
extern SFTKObjectListElement *sftk_FreeObjectListElement(
|
||||
SFTKObjectListElement *objectList);
|
||||
extern void sftk_FreeObjectList(SFTKObjectListElement *objectList);
|
||||
extern void sftk_FreeSearch(SFTKSearchResults *search);
|
||||
extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session);
|
||||
|
||||
extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID);
|
||||
extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle);
|
||||
extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle);
|
||||
extern void sftk_FreeSession(SFTKSession *session);
|
||||
extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
|
||||
CK_VOID_PTR pApplication, CK_FLAGS flags);
|
||||
extern void sftk_update_state(SFTKSlot *slot,SFTKSession *session);
|
||||
extern void sftk_update_all_states(SFTKSlot *slot);
|
||||
extern void sftk_FreeContext(SFTKSessionContext *context);
|
||||
extern void sftk_InitFreeLists(void);
|
||||
extern void sftk_CleanupFreeLists(void);
|
||||
|
||||
extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,
|
||||
CK_KEY_TYPE key_type, CK_RV *crvp);
|
||||
extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
|
||||
CK_KEY_TYPE key_type, CK_RV *crvp);
|
||||
extern void sftk_FormatDESKey(unsigned char *key, int length);
|
||||
extern PRBool sftk_CheckDESKey(unsigned char *key);
|
||||
extern PRBool sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
|
||||
|
||||
extern CK_RV secmod_parseParameters(char *param, sftk_parameters *parsed,
|
||||
PRBool isFIPS);
|
||||
extern void secmod_freeParams(sftk_parameters *params);
|
||||
extern char *secmod_getSecmodName(char *params, char **domain,
|
||||
char **filename, PRBool *rw);
|
||||
extern char ** secmod_ReadPermDB(const char *domain, const char *filename,
|
||||
const char *dbname, char *params, PRBool rw);
|
||||
extern SECStatus secmod_DeletePermDB(const char *domain, const char *filename,
|
||||
const char *dbname, char *args, PRBool rw);
|
||||
extern SECStatus secmod_AddPermDB(const char *domain, const char *filename,
|
||||
const char *dbname, char *module, PRBool rw);
|
||||
extern SECStatus secmod_ReleasePermDBData(const char *domain,
|
||||
const char *filename, const char *dbname, char **specList, PRBool rw);
|
||||
/* mechanism allows this operation */
|
||||
extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op);
|
||||
/*
|
||||
* OK there are now lots of options here, lets go through them all:
|
||||
*
|
||||
* configdir - base directory where all the cert, key, and module datbases live.
|
||||
* certPrefix - prefix added to the beginning of the cert database example: "
|
||||
* "https-server1-"
|
||||
* keyPrefix - prefix added to the beginning of the key database example: "
|
||||
* "https-server1-"
|
||||
* secmodName - name of the security module database (usually "secmod.db").
|
||||
* readOnly - Boolean: true if the databases are to be openned read only.
|
||||
* nocertdb - Don't open the cert DB and key DB's, just initialize the
|
||||
* Volatile certdb.
|
||||
* nomoddb - Don't open the security module DB, just initialize the
|
||||
* PKCS #11 module.
|
||||
* forceOpen - Continue to force initializations even if the databases cannot
|
||||
* be opened.
|
||||
*/
|
||||
CK_RV sftk_DBInit(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, PRBool readOnly, PRBool noCertDB,
|
||||
PRBool noKeyDB, PRBool forceOpen,
|
||||
NSSLOWCERTCertDBHandle **certDB, NSSLOWKEYDBHandle **keyDB);
|
||||
|
||||
void sftk_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
|
||||
NSSLOWKEYDBHandle *keyHandle);
|
||||
|
||||
const char *sftk_EvaluateConfigDir(const char *configdir, char **domain);
|
||||
|
||||
/*
|
||||
* narrow objects
|
||||
*/
|
||||
SFTKSessionObject * sftk_narrowToSessionObject(SFTKObject *);
|
||||
SFTKTokenObject * sftk_narrowToTokenObject(SFTKObject *);
|
||||
|
||||
/*
|
||||
* token object utilities
|
||||
*/
|
||||
void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle);
|
||||
PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey,
|
||||
CK_OBJECT_HANDLE handle);
|
||||
PRBool sftk_tokenMatch(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class,
|
||||
CK_ATTRIBUTE_PTR theTemplate,int count);
|
||||
CK_OBJECT_HANDLE sftk_mkHandle(SFTKSlot *slot,
|
||||
SECItem *dbKey, CK_OBJECT_HANDLE class);
|
||||
SFTKObject * sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey,
|
||||
CK_OBJECT_HANDLE handle);
|
||||
SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
|
||||
|
||||
/****************************************
|
||||
* implement TLS Pseudo Random Function (PRF)
|
||||
*/
|
||||
|
||||
extern SECStatus
|
||||
sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS);
|
||||
|
||||
extern CK_RV
|
||||
sftk_TLSPRFInit(SFTKSessionContext *context,
|
||||
SFTKObject * key,
|
||||
CK_KEY_TYPE key_type);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _PKCS11I_H_ */
|
||||
@@ -1,236 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dr Stephen Henson <stephen.henson@gemplus.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _PKCS11N_H_
|
||||
#define _PKCS11N_H_
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.12 $ $Date: 2005-01-20 02:25:50 $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* pkcs11n.h
|
||||
*
|
||||
* This file contains the NSS-specific type definitions for Cryptoki
|
||||
* (PKCS#11).
|
||||
*/
|
||||
|
||||
/*
|
||||
* NSSCK_VENDOR_NETSCAPE
|
||||
*
|
||||
* Cryptoki reserves the high half of all the number spaces for
|
||||
* vendor-defined use. I'd like to keep all of our Netscape-
|
||||
* specific values together, but not in the oh-so-obvious
|
||||
* 0x80000001, 0x80000002, etc. area. So I've picked an offset,
|
||||
* and constructed values for the beginnings of our spaces.
|
||||
*
|
||||
* Note that some "historical" Netscape values don't fall within
|
||||
* this range.
|
||||
*/
|
||||
#define NSSCK_VENDOR_NETSCAPE 0x4E534350 /* NSCP */
|
||||
|
||||
/*
|
||||
* Netscape-defined object classes
|
||||
*
|
||||
*/
|
||||
#define CKO_NETSCAPE (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
#define CKO_NETSCAPE_CRL (CKO_NETSCAPE + 1)
|
||||
#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2)
|
||||
#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3)
|
||||
#define CKO_NETSCAPE_BUILTIN_ROOT_LIST (CKO_NETSCAPE + 4)
|
||||
|
||||
/*
|
||||
* Netscape-defined key types
|
||||
*
|
||||
*/
|
||||
#define CKK_NETSCAPE (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
#define CKK_NETSCAPE_PKCS8 (CKK_NETSCAPE + 1)
|
||||
/*
|
||||
* Netscape-defined certificate types
|
||||
*
|
||||
*/
|
||||
#define CKC_NETSCAPE (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
/*
|
||||
* Netscape-defined object attributes
|
||||
*
|
||||
*/
|
||||
#define CKA_NETSCAPE (CKA_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
#define CKA_NETSCAPE_URL (CKA_NETSCAPE + 1)
|
||||
#define CKA_NETSCAPE_EMAIL (CKA_NETSCAPE + 2)
|
||||
#define CKA_NETSCAPE_SMIME_INFO (CKA_NETSCAPE + 3)
|
||||
#define CKA_NETSCAPE_SMIME_TIMESTAMP (CKA_NETSCAPE + 4)
|
||||
#define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5)
|
||||
#define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6)
|
||||
#define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7)
|
||||
#define CKA_NETSCAPE_KRL (CKA_NETSCAPE + 8)
|
||||
|
||||
#define CKA_NETSCAPE_PQG_COUNTER (CKA_NETSCAPE + 20)
|
||||
#define CKA_NETSCAPE_PQG_SEED (CKA_NETSCAPE + 21)
|
||||
#define CKA_NETSCAPE_PQG_H (CKA_NETSCAPE + 22)
|
||||
#define CKA_NETSCAPE_PQG_SEED_BITS (CKA_NETSCAPE + 23)
|
||||
|
||||
/*
|
||||
* Trust attributes:
|
||||
*
|
||||
* If trust goes standard, these probably will too. So I'll
|
||||
* put them all in one place.
|
||||
*/
|
||||
|
||||
#define CKA_TRUST (CKA_NETSCAPE + 0x2000)
|
||||
|
||||
/* "Usage" key information */
|
||||
#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1)
|
||||
#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2)
|
||||
#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3)
|
||||
#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4)
|
||||
#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5)
|
||||
#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6)
|
||||
#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7)
|
||||
|
||||
/* "Purpose" trust information */
|
||||
#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8)
|
||||
#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9)
|
||||
#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10)
|
||||
#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11)
|
||||
#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12)
|
||||
#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13)
|
||||
#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14)
|
||||
#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15)
|
||||
#define CKA_TRUST_STEP_UP_APPROVED (CKA_TRUST + 16)
|
||||
|
||||
#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100)
|
||||
#define CKA_CERT_MD5_HASH (CKA_TRUST + 101)
|
||||
|
||||
/* Netscape trust stuff */
|
||||
/* XXX fgmr new ones here-- step-up, etc. */
|
||||
|
||||
/* HISTORICAL: define used to pass in the database key for DSA private keys */
|
||||
#define CKA_NETSCAPE_DB 0xD5A0DB00L
|
||||
#define CKA_NETSCAPE_TRUST 0x80000001L
|
||||
|
||||
/*
|
||||
* Netscape-defined crypto mechanisms
|
||||
*
|
||||
*/
|
||||
#define CKM_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
#define CKM_NETSCAPE_AES_KEY_WRAP (CKM_NETSCAPE + 1)
|
||||
#define CKM_NETSCAPE_AES_KEY_WRAP_PAD (CKM_NETSCAPE + 2)
|
||||
|
||||
/*
|
||||
* HISTORICAL:
|
||||
* Do not attempt to use these. They are only used by NETSCAPE's internal
|
||||
* PKCS #11 interface. Most of these are place holders for other mechanism
|
||||
* and will change in the future.
|
||||
*/
|
||||
#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L
|
||||
#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL
|
||||
#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL
|
||||
|
||||
#define CKM_TLS_PRF_GENERAL 0x80000373L
|
||||
|
||||
/*
|
||||
* Netscape-defined return values
|
||||
*
|
||||
*/
|
||||
#define CKR_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
#define CKR_NETSCAPE_CERTDB_FAILED (CKR_NETSCAPE + 1)
|
||||
#define CKR_NETSCAPE_KEYDB_FAILED (CKR_NETSCAPE + 2)
|
||||
|
||||
/*
|
||||
* Trust info
|
||||
*
|
||||
* This isn't part of the Cryptoki standard (yet), so I'm putting
|
||||
* all the definitions here. Some of this would move to nssckt.h
|
||||
* if trust info were made part of the standard. In view of this
|
||||
* possibility, I'm putting my (Netscape) values in the netscape
|
||||
* vendor space, like everything else.
|
||||
*/
|
||||
|
||||
typedef CK_ULONG CK_TRUST;
|
||||
|
||||
/* The following trust types are defined: */
|
||||
#define CKT_VENDOR_DEFINED 0x80000000
|
||||
|
||||
#define CKT_NETSCAPE (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
|
||||
|
||||
/* If trust goes standard, these'll probably drop out of vendor space. */
|
||||
#define CKT_NETSCAPE_TRUSTED (CKT_NETSCAPE + 1)
|
||||
#define CKT_NETSCAPE_TRUSTED_DELEGATOR (CKT_NETSCAPE + 2)
|
||||
#define CKT_NETSCAPE_UNTRUSTED (CKT_NETSCAPE + 3)
|
||||
#define CKT_NETSCAPE_MUST_VERIFY (CKT_NETSCAPE + 4)
|
||||
#define CKT_NETSCAPE_TRUST_UNKNOWN (CKT_NETSCAPE + 5) /* default */
|
||||
|
||||
/*
|
||||
* These may well remain Netscape-specific; I'm only using them
|
||||
* to cache resolution data.
|
||||
*/
|
||||
#define CKT_NETSCAPE_VALID (CKT_NETSCAPE + 10)
|
||||
#define CKT_NETSCAPE_VALID_DELEGATOR (CKT_NETSCAPE + 11)
|
||||
|
||||
|
||||
/*
|
||||
* These are not really PKCS #11 values specifically. They are the 'loadable'
|
||||
* module spec NSS uses. The are available for others to use as well, but not
|
||||
* part of the formal PKCS #11 spec.
|
||||
*
|
||||
* The function 'FIND' returns an array of PKCS #11 initialization strings
|
||||
* The function 'ADD' takes a PKCS #11 initialization string and stores it.
|
||||
* The function 'DEL' takes a 'name= library=' value and deletes the associated
|
||||
* string.
|
||||
* The function 'RELEASE' frees the array returned by 'FIND'
|
||||
*/
|
||||
#define SECMOD_MODULE_DB_FUNCTION_FIND 0
|
||||
#define SECMOD_MODULE_DB_FUNCTION_ADD 1
|
||||
#define SECMOD_MODULE_DB_FUNCTION_DEL 2
|
||||
#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
|
||||
typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
|
||||
char *parameters, void *moduleSpec);
|
||||
|
||||
#endif /* _PKCS11N_H_ */
|
||||
@@ -1,54 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
|
||||
* is granted provided that it is identified as "RSA Security Inc. Public-Key
|
||||
* Cryptography Standards (PKCS)" in all material mentioning or referencing
|
||||
* this document.
|
||||
*/
|
||||
/* these data types are platform/implementation dependent. */
|
||||
/*
|
||||
* Packing was removed from the shipped RSA header files, even
|
||||
* though it's still needed. put in a central file to help merging..
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4103)
|
||||
#endif
|
||||
#pragma pack(push, cryptoki, 1)
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/*
|
||||
* Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
|
||||
* is granted provided that it is identified as "RSA Security Inc. Public-Key
|
||||
* Cryptography Standards (PKCS)" in all material mentioning or referencing
|
||||
* this document.
|
||||
*/
|
||||
/*
|
||||
* reset any packing set by pkcs11p.h
|
||||
*/
|
||||
|
||||
#if defined (_WIN32)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4103)
|
||||
#endif
|
||||
#pragma pack(pop, cryptoki)
|
||||
#endif
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nspr.h"
|
||||
#include "sechash.h"
|
||||
#include "blapi.h" /* below the line */
|
||||
|
||||
|
||||
static void *
|
||||
null_hash_new_context(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
null_hash_clone_context(void *v)
|
||||
{
|
||||
PORT_Assert(v == NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
null_hash_begin(void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
null_hash_update(void *v, const unsigned char *input, unsigned int length)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
|
||||
unsigned int maxOut)
|
||||
{
|
||||
*outLen = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
null_hash_destroy_context(void *v, PRBool b)
|
||||
{
|
||||
PORT_Assert(v == NULL);
|
||||
}
|
||||
|
||||
|
||||
const SECHashObject SECRawHashObjects[] = {
|
||||
{ 0,
|
||||
(void * (*)(void)) null_hash_new_context,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) null_hash_destroy_context,
|
||||
(void (*)(void *)) null_hash_begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *,
|
||||
unsigned int)) null_hash_end
|
||||
},
|
||||
{ MD2_LENGTH,
|
||||
(void * (*)(void)) MD2_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) MD2_DestroyContext,
|
||||
(void (*)(void *)) MD2_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) MD2_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End
|
||||
},
|
||||
{ MD5_LENGTH,
|
||||
(void * (*)(void)) MD5_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) MD5_DestroyContext,
|
||||
(void (*)(void *)) MD5_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) MD5_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End
|
||||
},
|
||||
{ SHA1_LENGTH,
|
||||
(void * (*)(void)) SHA1_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) SHA1_DestroyContext,
|
||||
(void (*)(void *)) SHA1_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) SHA1_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End
|
||||
},
|
||||
{ SHA256_LENGTH,
|
||||
(void * (*)(void)) SHA256_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) SHA256_DestroyContext,
|
||||
(void (*)(void *)) SHA256_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) SHA256_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA256_End
|
||||
},
|
||||
{ SHA384_LENGTH,
|
||||
(void * (*)(void)) SHA384_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) SHA384_DestroyContext,
|
||||
(void (*)(void *)) SHA384_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) SHA384_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA384_End
|
||||
},
|
||||
{ SHA512_LENGTH,
|
||||
(void * (*)(void)) SHA512_NewContext,
|
||||
(void * (*)(void *)) null_hash_clone_context,
|
||||
(void (*)(void *, PRBool)) SHA512_DestroyContext,
|
||||
(void (*)(void *)) SHA512_Begin,
|
||||
(void (*)(void *, const unsigned char *, unsigned int)) SHA512_Update,
|
||||
(void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA512_End
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,879 +0,0 @@
|
||||
/*
|
||||
* PKCS#1 encoding and decoding functions.
|
||||
* This file is believed to contain no code licensed from other parties.
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: rsawrapr.c,v 1.8 2005-04-04 09:27:42 julien.pierre.bugs%sun.com Exp $ */
|
||||
|
||||
#include "blapi.h"
|
||||
#include "softoken.h"
|
||||
#include "sechash.h"
|
||||
|
||||
#include "lowkeyi.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#define RSA_BLOCK_MIN_PAD_LEN 8
|
||||
#define RSA_BLOCK_FIRST_OCTET 0x00
|
||||
#define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
|
||||
#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
|
||||
#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
|
||||
|
||||
#define OAEP_SALT_LEN 8
|
||||
#define OAEP_PAD_LEN 8
|
||||
#define OAEP_PAD_OCTET 0x00
|
||||
|
||||
#define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */
|
||||
|
||||
static SHA1Context *
|
||||
SHA1_CloneContext(SHA1Context *original)
|
||||
{
|
||||
SHA1Context * clone = NULL;
|
||||
unsigned char *pBuf;
|
||||
int sha1ContextSize = SHA1_FlattenSize(original);
|
||||
SECStatus frv;
|
||||
unsigned char buf[FLAT_BUFSIZE];
|
||||
|
||||
PORT_Assert(sizeof buf >= sha1ContextSize);
|
||||
if (sizeof buf >= sha1ContextSize) {
|
||||
pBuf = buf;
|
||||
} else {
|
||||
pBuf = PORT_Alloc(sha1ContextSize);
|
||||
if (!pBuf)
|
||||
goto done;
|
||||
}
|
||||
|
||||
frv = SHA1_Flatten(original, pBuf);
|
||||
if (frv == SECSuccess) {
|
||||
clone = SHA1_Resurrect(pBuf, NULL);
|
||||
memset(pBuf, 0, sha1ContextSize);
|
||||
}
|
||||
done:
|
||||
if (pBuf != buf)
|
||||
PORT_Free(pBuf);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify data by XORing it with a special hash of salt.
|
||||
*/
|
||||
static SECStatus
|
||||
oaep_xor_with_h1(unsigned char *data, unsigned int datalen,
|
||||
unsigned char *salt, unsigned int saltlen)
|
||||
{
|
||||
SHA1Context *sha1cx;
|
||||
unsigned char *dp, *dataend;
|
||||
unsigned char end_octet;
|
||||
|
||||
sha1cx = SHA1_NewContext();
|
||||
if (sha1cx == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a hash of salt started; we will use it several times,
|
||||
* adding in a different end octet (x00, x01, x02, ...).
|
||||
*/
|
||||
SHA1_Begin (sha1cx);
|
||||
SHA1_Update (sha1cx, salt, saltlen);
|
||||
end_octet = 0;
|
||||
|
||||
dp = data;
|
||||
dataend = data + datalen;
|
||||
|
||||
while (dp < dataend) {
|
||||
SHA1Context *sha1cx_h1;
|
||||
unsigned int sha1len, sha1off;
|
||||
unsigned char sha1[SHA1_LENGTH];
|
||||
|
||||
/*
|
||||
* Create hash of (salt || end_octet)
|
||||
*/
|
||||
sha1cx_h1 = SHA1_CloneContext (sha1cx);
|
||||
SHA1_Update (sha1cx_h1, &end_octet, 1);
|
||||
SHA1_End (sha1cx_h1, sha1, &sha1len, sizeof(sha1));
|
||||
SHA1_DestroyContext (sha1cx_h1, PR_TRUE);
|
||||
PORT_Assert (sha1len == SHA1_LENGTH);
|
||||
|
||||
/*
|
||||
* XOR that hash with the data.
|
||||
* When we have fewer than SHA1_LENGTH octets of data
|
||||
* left to xor, use just the low-order ones of the hash.
|
||||
*/
|
||||
sha1off = 0;
|
||||
if ((dataend - dp) < SHA1_LENGTH)
|
||||
sha1off = SHA1_LENGTH - (dataend - dp);
|
||||
while (sha1off < SHA1_LENGTH)
|
||||
*dp++ ^= sha1[sha1off++];
|
||||
|
||||
/*
|
||||
* Bump for next hash chunk.
|
||||
*/
|
||||
end_octet++;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify salt by XORing it with a special hash of data.
|
||||
*/
|
||||
static SECStatus
|
||||
oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen,
|
||||
unsigned char *data, unsigned int datalen)
|
||||
{
|
||||
unsigned char sha1[SHA1_LENGTH];
|
||||
unsigned char *psalt, *psha1, *saltend;
|
||||
SECStatus rv;
|
||||
|
||||
/*
|
||||
* Create a hash of data.
|
||||
*/
|
||||
rv = SHA1_HashBuf (sha1, data, datalen);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* XOR the low-order octets of that hash with salt.
|
||||
*/
|
||||
PORT_Assert (saltlen <= SHA1_LENGTH);
|
||||
saltend = salt + saltlen;
|
||||
psalt = salt;
|
||||
psha1 = sha1 + SHA1_LENGTH - saltlen;
|
||||
while (psalt < saltend) {
|
||||
*psalt++ ^= *psha1++;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* Format one block of data for public/private key encryption using
|
||||
* the rules defined in PKCS #1.
|
||||
*/
|
||||
static unsigned char *
|
||||
rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
|
||||
SECItem *data)
|
||||
{
|
||||
unsigned char *block;
|
||||
unsigned char *bp;
|
||||
int padLen;
|
||||
int i;
|
||||
|
||||
block = (unsigned char *) PORT_Alloc(modulusLen);
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
|
||||
bp = block;
|
||||
|
||||
/*
|
||||
* All RSA blocks start with two octets:
|
||||
* 0x00 || BlockType
|
||||
*/
|
||||
*bp++ = RSA_BLOCK_FIRST_OCTET;
|
||||
*bp++ = (unsigned char) blockType;
|
||||
|
||||
switch (blockType) {
|
||||
|
||||
/*
|
||||
* Blocks intended for private-key operation.
|
||||
*/
|
||||
case RSA_BlockPrivate0: /* essentially unused */
|
||||
case RSA_BlockPrivate: /* preferred method */
|
||||
/*
|
||||
* 0x00 || BT || Pad || 0x00 || ActualData
|
||||
* 1 1 padLen 1 data->len
|
||||
* Pad is either all 0x00 or all 0xff bytes, depending on blockType.
|
||||
*/
|
||||
padLen = modulusLen - data->len - 3;
|
||||
PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
|
||||
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
|
||||
PORT_Free (block);
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memset (bp,
|
||||
blockType == RSA_BlockPrivate0
|
||||
? RSA_BLOCK_PRIVATE0_PAD_OCTET
|
||||
: RSA_BLOCK_PRIVATE_PAD_OCTET,
|
||||
padLen);
|
||||
bp += padLen;
|
||||
*bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
|
||||
PORT_Memcpy (bp, data->data, data->len);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Blocks intended for public-key operation.
|
||||
*/
|
||||
case RSA_BlockPublic:
|
||||
|
||||
/*
|
||||
* 0x00 || BT || Pad || 0x00 || ActualData
|
||||
* 1 1 padLen 1 data->len
|
||||
* Pad is all non-zero random bytes.
|
||||
*/
|
||||
padLen = modulusLen - data->len - 3;
|
||||
PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
|
||||
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
|
||||
PORT_Free (block);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < padLen; i++) {
|
||||
/* Pad with non-zero random data. */
|
||||
do {
|
||||
RNG_GenerateGlobalRandomBytes(bp + i, 1);
|
||||
} while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
|
||||
}
|
||||
bp += padLen;
|
||||
*bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
|
||||
PORT_Memcpy (bp, data->data, data->len);
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
* Blocks intended for public-key operation, using
|
||||
* Optimal Asymmetric Encryption Padding (OAEP).
|
||||
*/
|
||||
case RSA_BlockOAEP:
|
||||
/*
|
||||
* 0x00 || BT || Modified2(Salt) || Modified1(PaddedData)
|
||||
* 1 1 OAEP_SALT_LEN OAEP_PAD_LEN + data->len [+ N]
|
||||
*
|
||||
* where:
|
||||
* PaddedData is "Pad1 || ActualData [|| Pad2]"
|
||||
* Salt is random data.
|
||||
* Pad1 is all zeros.
|
||||
* Pad2, if present, is random data.
|
||||
* (The "modified" fields are all the same length as the original
|
||||
* unmodified values; they are just xor'd with other values.)
|
||||
*
|
||||
* Modified1 is an XOR of PaddedData with a special octet
|
||||
* string constructed of iterated hashing of Salt (see below).
|
||||
* Modified2 is an XOR of Salt with the low-order octets of
|
||||
* the hash of Modified1 (see farther below ;-).
|
||||
*
|
||||
* Whew!
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Salt
|
||||
*/
|
||||
RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
|
||||
bp += OAEP_SALT_LEN;
|
||||
|
||||
/*
|
||||
* Pad1
|
||||
*/
|
||||
PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
|
||||
bp += OAEP_PAD_LEN;
|
||||
|
||||
/*
|
||||
* Data
|
||||
*/
|
||||
PORT_Memcpy (bp, data->data, data->len);
|
||||
bp += data->len;
|
||||
|
||||
/*
|
||||
* Pad2
|
||||
*/
|
||||
if (bp < (block + modulusLen))
|
||||
RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
|
||||
|
||||
/*
|
||||
* Now we have the following:
|
||||
* 0x00 || BT || Salt || PaddedData
|
||||
* (From this point on, "Pad1 || Data [|| Pad2]" is treated
|
||||
* as the one entity PaddedData.)
|
||||
*
|
||||
* We need to turn PaddedData into Modified1.
|
||||
*/
|
||||
if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN,
|
||||
modulusLen - 2 - OAEP_SALT_LEN,
|
||||
block + 2, OAEP_SALT_LEN) != SECSuccess) {
|
||||
PORT_Free (block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have:
|
||||
* 0x00 || BT || Salt || Modified1(PaddedData)
|
||||
*
|
||||
* The remaining task is to turn Salt into Modified2.
|
||||
*/
|
||||
if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN,
|
||||
block + 2 + OAEP_SALT_LEN,
|
||||
modulusLen - 2 - OAEP_SALT_LEN) != SECSuccess) {
|
||||
PORT_Free (block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_Assert (0);
|
||||
PORT_Free (block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
rsa_FormatBlock(SECItem *result, unsigned modulusLen,
|
||||
RSA_BlockType blockType, SECItem *data)
|
||||
{
|
||||
/*
|
||||
* XXX For now assume that the data length fits in a single
|
||||
* XXX encryption block; the ASSERTs below force this.
|
||||
* XXX To fix it, each case will have to loop over chunks whose
|
||||
* XXX lengths satisfy the assertions, until all data is handled.
|
||||
* XXX (Unless RSA has more to say about how to handle data
|
||||
* XXX which does not fit in a single encryption block?)
|
||||
* XXX And I do not know what the result is supposed to be,
|
||||
* XXX so the interface to this function may need to change
|
||||
* XXX to allow for returning multiple blocks, if they are
|
||||
* XXX not wanted simply concatenated one after the other.
|
||||
*/
|
||||
|
||||
switch (blockType) {
|
||||
case RSA_BlockPrivate0:
|
||||
case RSA_BlockPrivate:
|
||||
case RSA_BlockPublic:
|
||||
/*
|
||||
* 0x00 || BT || Pad || 0x00 || ActualData
|
||||
*
|
||||
* The "3" below is the first octet + the second octet + the 0x00
|
||||
* octet that always comes just before the ActualData.
|
||||
*/
|
||||
PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
|
||||
|
||||
result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
|
||||
if (result->data == NULL) {
|
||||
result->len = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
result->len = modulusLen;
|
||||
|
||||
break;
|
||||
|
||||
case RSA_BlockOAEP:
|
||||
/*
|
||||
* 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
|
||||
*
|
||||
* The "2" below is the first octet + the second octet.
|
||||
* (The other fields do not contain the clear values, but are
|
||||
* the same length as the clear values.)
|
||||
*/
|
||||
PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
|
||||
+ OAEP_PAD_LEN)));
|
||||
|
||||
result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
|
||||
if (result->data == NULL) {
|
||||
result->len = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
result->len = modulusLen;
|
||||
|
||||
break;
|
||||
|
||||
case RSA_BlockRaw:
|
||||
/*
|
||||
* Pad || ActualData
|
||||
* Pad is zeros. The application is responsible for recovering
|
||||
* the actual data.
|
||||
*/
|
||||
if (data->len > modulusLen ) {
|
||||
return SECFailure;
|
||||
}
|
||||
result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
|
||||
result->len = modulusLen;
|
||||
PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_Assert (0);
|
||||
result->data = NULL;
|
||||
result->len = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_Sign(NSSLOWKEYPrivateKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int maxOutputLen,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
|
||||
SECItem formatted;
|
||||
SECItem unformatted;
|
||||
|
||||
if (maxOutputLen < modulus_len)
|
||||
return SECFailure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
return SECFailure;
|
||||
|
||||
unformatted.len = input_len;
|
||||
unformatted.data = input;
|
||||
formatted.data = NULL;
|
||||
rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
|
||||
&unformatted);
|
||||
if (rv != SECSuccess)
|
||||
goto done;
|
||||
|
||||
rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
|
||||
*output_len = modulus_len;
|
||||
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (formatted.data != NULL)
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSign(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * sign,
|
||||
unsigned int sign_len,
|
||||
unsigned char * hash,
|
||||
unsigned int hash_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
unsigned int i;
|
||||
unsigned char * buffer;
|
||||
|
||||
modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
if (sign_len != modulus_len)
|
||||
goto failure;
|
||||
if (hash_len > modulus_len - 8)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/*
|
||||
* check the padding that was used
|
||||
*/
|
||||
if (buffer[0] != 0 || buffer[1] != 1)
|
||||
goto loser;
|
||||
for (i = 2; i < modulus_len - hash_len - 1; i++) {
|
||||
if (buffer[i] == 0)
|
||||
break;
|
||||
if (buffer[i] != 0xff)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure we get the same results
|
||||
*/
|
||||
if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
|
||||
goto loser;
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSignRecover(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * data,
|
||||
unsigned int * data_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * sign,
|
||||
unsigned int sign_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
unsigned int i;
|
||||
unsigned char * buffer;
|
||||
|
||||
if (sign_len != modulus_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
*data_len = 0;
|
||||
|
||||
/*
|
||||
* check the padding that was used
|
||||
*/
|
||||
if (buffer[0] != 0 || buffer[1] != 1)
|
||||
goto loser;
|
||||
for (i = 2; i < modulus_len; i++) {
|
||||
if (buffer[i] == 0) {
|
||||
*data_len = modulus_len - i - 1;
|
||||
break;
|
||||
}
|
||||
if (buffer[i] != 0xff)
|
||||
goto loser;
|
||||
}
|
||||
if (*data_len == 0)
|
||||
goto loser;
|
||||
if (*data_len > max_output_len)
|
||||
goto loser;
|
||||
|
||||
/*
|
||||
* make sure we get the same results
|
||||
*/
|
||||
PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_EncryptBlock(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
SECItem formatted;
|
||||
SECItem unformatted;
|
||||
|
||||
formatted.data = NULL;
|
||||
if (max_output_len < modulus_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
unformatted.len = input_len;
|
||||
unformatted.data = input;
|
||||
formatted.data = NULL;
|
||||
rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
|
||||
&unformatted);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
*output_len = modulus_len;
|
||||
return SECSuccess;
|
||||
|
||||
failure:
|
||||
if (formatted.data != NULL)
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_DecryptBlock(NSSLOWKEYPrivateKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
|
||||
unsigned int i;
|
||||
unsigned char * buffer;
|
||||
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
if (input_len != modulus_len)
|
||||
goto failure;
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
if (buffer[0] != 0 || buffer[1] != 2)
|
||||
goto loser;
|
||||
*output_len = 0;
|
||||
for (i = 2; i < modulus_len; i++) {
|
||||
if (buffer[i] == 0) {
|
||||
*output_len = modulus_len - i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*output_len == 0)
|
||||
goto loser;
|
||||
if (*output_len > max_output_len)
|
||||
goto loser;
|
||||
|
||||
PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
/*
|
||||
* added to make pkcs #11 happy
|
||||
* RAW is RSA_X_509
|
||||
*/
|
||||
SECStatus
|
||||
RSA_SignRaw(NSSLOWKEYPrivateKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int maxOutputLen,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
|
||||
SECItem formatted;
|
||||
SECItem unformatted;
|
||||
|
||||
if (maxOutputLen < modulus_len)
|
||||
return SECFailure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
return SECFailure;
|
||||
|
||||
unformatted.len = input_len;
|
||||
unformatted.data = input;
|
||||
formatted.data = NULL;
|
||||
rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
|
||||
if (rv != SECSuccess)
|
||||
goto done;
|
||||
|
||||
rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
|
||||
*output_len = modulus_len;
|
||||
|
||||
done:
|
||||
if (formatted.data != NULL)
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSignRaw(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * sign,
|
||||
unsigned int sign_len,
|
||||
unsigned char * hash,
|
||||
unsigned int hash_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
unsigned char * buffer;
|
||||
|
||||
if (sign_len != modulus_len)
|
||||
goto failure;
|
||||
if (hash_len > modulus_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/*
|
||||
* make sure we get the same results
|
||||
*/
|
||||
/* NOTE: should we verify the leading zeros? */
|
||||
if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
|
||||
goto loser;
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * data,
|
||||
unsigned int * data_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * sign,
|
||||
unsigned int sign_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
|
||||
if (sign_len != modulus_len)
|
||||
goto failure;
|
||||
if (max_output_len < modulus_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
*data_len = modulus_len;
|
||||
return SECSuccess;
|
||||
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_EncryptRaw(NSSLOWKEYPublicKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
|
||||
SECItem formatted;
|
||||
SECItem unformatted;
|
||||
|
||||
formatted.data = NULL;
|
||||
if (max_output_len < modulus_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
|
||||
unformatted.len = input_len;
|
||||
unformatted.data = input;
|
||||
formatted.data = NULL;
|
||||
rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
*output_len = modulus_len;
|
||||
return SECSuccess;
|
||||
|
||||
failure:
|
||||
if (formatted.data != NULL)
|
||||
PORT_ZFree(formatted.data, modulus_len);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
|
||||
unsigned char * output,
|
||||
unsigned int * output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char * input,
|
||||
unsigned int input_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
|
||||
|
||||
if (modulus_len <= 0)
|
||||
goto failure;
|
||||
if (modulus_len > max_output_len)
|
||||
goto failure;
|
||||
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
|
||||
if (key->keyType != NSSLOWKEYRSAKey)
|
||||
goto failure;
|
||||
if (input_len != modulus_len)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
|
||||
if (rv != SECSuccess)
|
||||
goto failure;
|
||||
|
||||
*output_len = modulus_len;
|
||||
return SECSuccess;
|
||||
|
||||
failure:
|
||||
return SECFailure;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* Library identity and versioning */
|
||||
|
||||
#include "nss.h"
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define _DEBUG_STRING " (debug)"
|
||||
#else
|
||||
#define _DEBUG_STRING ""
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version information for the 'ident' and 'what commands
|
||||
*
|
||||
* NOTE: the first component of the concatenated rcsid string
|
||||
* must not end in a '$' to prevent rcs keyword substitution.
|
||||
*/
|
||||
const char __nss_softokn_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
|
||||
" " __DATE__ " " __TIME__ " $";
|
||||
const char __nss_softokn_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
|
||||
" " __DATE__ " " __TIME__;
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* softoken.h - private data structures and prototypes for the softoken lib
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: softoken.h,v 1.7 2005-03-29 18:21:18 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#ifndef _SOFTOKEN_H_
|
||||
#define _SOFTOKEN_H_
|
||||
|
||||
#include "blapi.h"
|
||||
#include "lowkeyti.h"
|
||||
#include "softoknt.h"
|
||||
#include "secoidt.h"
|
||||
|
||||
#include "pkcs11t.h" /* CK_RV Required for sftk_fipsPowerUpSelfTest(). */
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
** RSA encryption/decryption. When encrypting/decrypting the output
|
||||
** buffer must be at least the size of the public key modulus.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Format some data into a PKCS#1 encryption block, preparing the
|
||||
** data for RSA encryption.
|
||||
** "result" where the formatted block is stored (memory is allocated)
|
||||
** "modulusLen" the size of the formatted block
|
||||
** "blockType" what block type to use (SEC_RSABlock*)
|
||||
** "data" the data to format
|
||||
*/
|
||||
extern SECStatus RSA_FormatBlock(SECItem *result,
|
||||
unsigned int modulusLen,
|
||||
RSA_BlockType blockType,
|
||||
SECItem *data);
|
||||
/*
|
||||
** Similar, but just returns a pointer to the allocated memory, *and*
|
||||
** will *only* format one block, even if we (in the future) modify
|
||||
** RSA_FormatBlock() to loop over multiples of modulusLen.
|
||||
*/
|
||||
extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen,
|
||||
RSA_BlockType blockType,
|
||||
SECItem *data);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* convenience wrappers for doing single RSA operations. They create the
|
||||
* RSA context internally and take care of the formatting
|
||||
* requirements. Blinding happens automagically within RSA_SignHash and
|
||||
* RSA_DecryptBlock.
|
||||
*/
|
||||
extern
|
||||
SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
unsigned char *input, unsigned int inputLen);
|
||||
extern
|
||||
SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign,
|
||||
unsigned int signLength, unsigned char *hash,
|
||||
unsigned int hashLength);
|
||||
extern
|
||||
SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data,
|
||||
unsigned int *data_len,unsigned int max_output_len,
|
||||
unsigned char *sign, unsigned int sign_len);
|
||||
extern
|
||||
SECStatus RSA_EncryptBlock(NSSLOWKEYPublicKey *key, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
unsigned char *input, unsigned int inputLen);
|
||||
extern
|
||||
SECStatus RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/*
|
||||
* added to make pkcs #11 happy
|
||||
* RAW is RSA_X_509
|
||||
*/
|
||||
extern
|
||||
SECStatus RSA_SignRaw( NSSLOWKEYPrivateKey *key, unsigned char *output,
|
||||
unsigned int *output_len, unsigned int maxOutputLen,
|
||||
unsigned char *input, unsigned int input_len);
|
||||
extern
|
||||
SECStatus RSA_CheckSignRaw( NSSLOWKEYPublicKey *key, unsigned char *sign,
|
||||
unsigned int sign_len, unsigned char *hash,
|
||||
unsigned int hash_len);
|
||||
extern
|
||||
SECStatus RSA_CheckSignRecoverRaw( NSSLOWKEYPublicKey *key, unsigned char *data,
|
||||
unsigned int *data_len, unsigned int max_output_len,
|
||||
unsigned char *sign, unsigned int sign_len);
|
||||
extern
|
||||
SECStatus RSA_EncryptRaw( NSSLOWKEYPublicKey *key, unsigned char *output,
|
||||
unsigned int *output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char *input, unsigned int input_len);
|
||||
extern
|
||||
SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
|
||||
unsigned int *output_len,
|
||||
unsigned int max_output_len,
|
||||
unsigned char *input, unsigned int input_len);
|
||||
|
||||
/*
|
||||
** Prepare a buffer for DES encryption, growing to the appropriate boundary,
|
||||
** filling with the appropriate padding.
|
||||
** We add from 1 to DES_KEY_LENGTH bytes -- we *always* grow.
|
||||
** The extra bytes contain the value of the length of the padding:
|
||||
** if we have 2 bytes of padding, then the padding is "0x02, 0x02".
|
||||
**
|
||||
** NOTE: If arena is non-NULL, we re-allocate from there, otherwise
|
||||
** we assume (and use) PR memory (re)allocation.
|
||||
** Maybe this belongs in util?
|
||||
*/
|
||||
extern unsigned char * DES_PadBuffer(PRArenaPool *arena, unsigned char *inbuf,
|
||||
unsigned int inlen, unsigned int *outlen);
|
||||
|
||||
|
||||
/****************************************/
|
||||
/*
|
||||
** Power-Up selftests required for FIPS and invoked only
|
||||
** under PKCS #11 FIPS mode.
|
||||
*/
|
||||
extern CK_RV sftk_fipsPowerUpSelfTest( void );
|
||||
|
||||
/*
|
||||
** make known fixed PKCS #11 key types to their sizes in bytes
|
||||
*/
|
||||
unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _SOFTOKEN_H_ */
|
||||
@@ -1,61 +0,0 @@
|
||||
;+#
|
||||
;+# ***** BEGIN LICENSE BLOCK *****
|
||||
;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
;+#
|
||||
;+# The contents of this file are subject to the Mozilla Public License Version
|
||||
;+# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
;+# the License. You may obtain a copy of the License at
|
||||
;+# http://www.mozilla.org/MPL/
|
||||
;+#
|
||||
;+# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
;+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
;+# for the specific language governing rights and limitations under the
|
||||
;+# License.
|
||||
;+#
|
||||
;+# The Original Code is the Netscape security libraries.
|
||||
;+#
|
||||
;+# The Initial Developer of the Original Code is
|
||||
;+# Netscape Communications Corporation.
|
||||
;+# Portions created by the Initial Developer are Copyright (C) 2000
|
||||
;+# the Initial Developer. All Rights Reserved.
|
||||
;+#
|
||||
;+# Contributor(s):
|
||||
;+# Dr Stephen Henson <stephen.henson@gemplus.com>
|
||||
;+#
|
||||
;+# Alternatively, the contents of this file may be used under the terms of
|
||||
;+# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
;+# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
;+# of those above. If you wish to allow use of your version of this file only
|
||||
;+# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
;+# use your version of this file under the terms of the MPL, indicate your
|
||||
;+# decision by deleting the provisions above and replace them with the notice
|
||||
;+# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
;+# the provisions above, a recipient may use your version of this file under
|
||||
;+# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
;+#
|
||||
;+# ***** END LICENSE BLOCK *****
|
||||
;+#
|
||||
;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
|
||||
;+# 1. For all unix platforms, the string ";-" means "remove this line"
|
||||
;+# 2. For all unix platforms, the string " DATA " will be removed from any
|
||||
;+# line on which it occurs.
|
||||
;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
|
||||
;+# On AIX, lines containing ";+" will be removed.
|
||||
;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
|
||||
;+# 5. For all unix platforms, after the above processing has taken place,
|
||||
;+# all characters after the first ";" on the line will be removed.
|
||||
;+# And for AIX, the first ";" will also be removed.
|
||||
;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
|
||||
;+# directives are hidden behind ";", ";+", and ";-"
|
||||
;+NSS_3.4 { # NSS 3.4 release
|
||||
;+ global:
|
||||
LIBRARY softokn3 ;-
|
||||
EXPORTS ;-
|
||||
C_GetFunctionList; Make this function like a real PKCS #11 module as well
|
||||
FC_GetFunctionList;
|
||||
NSC_GetFunctionList;
|
||||
NSC_ModuleDBFunc;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
@@ -1,101 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nss.h"
|
||||
#include <winver.h>
|
||||
|
||||
#define MY_LIBNAME "softokn"
|
||||
#define MY_FILEDESCRIPTION "NSS PKCS #11 Library"
|
||||
|
||||
#define STRINGIZE(x) #x
|
||||
#define STRINGIZE2(x) STRINGIZE(x)
|
||||
#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define MY_DEBUG_STR " (debug)"
|
||||
#define MY_FILEFLAGS_1 VS_FF_DEBUG
|
||||
#else
|
||||
#define MY_DEBUG_STR ""
|
||||
#define MY_FILEFLAGS_1 0x0L
|
||||
#endif
|
||||
#if NSS_BETA
|
||||
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
|
||||
#else
|
||||
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
|
||||
#endif
|
||||
|
||||
#ifdef WINNT
|
||||
#define MY_FILEOS VOS_NT_WINDOWS32
|
||||
#else
|
||||
#define MY_FILEOS VOS__WINDOWS32
|
||||
#endif
|
||||
|
||||
#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version-information resource
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS MY_FILEFLAGS_2
|
||||
FILEOS MY_FILEOS
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L // not used
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Netscape Communications Corporation\0"
|
||||
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
|
||||
VALUE "FileVersion", NSS_VERSION "\0"
|
||||
VALUE "InternalName", MY_INTERNAL_NAME "\0"
|
||||
VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0"
|
||||
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
|
||||
VALUE "ProductName", "Network Security Services\0"
|
||||
VALUE "ProductVersion", NSS_VERSION "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* softoknt.h - public data structures for the software token library
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: softoknt.h,v 1.3 2004-04-27 23:04:38 gerv%gerv.net Exp $ */
|
||||
|
||||
#ifndef _SOFTOKNT_H_
|
||||
#define _SOFTOKNT_H_
|
||||
|
||||
/*
|
||||
* RSA block types
|
||||
*
|
||||
* The actual values are important -- they are fixed, *not* arbitrary.
|
||||
* The explicit value assignments are not needed (because C would give
|
||||
* us those same values anyway) but are included as a reminder...
|
||||
*/
|
||||
typedef enum {
|
||||
RSA_BlockPrivate0 = 0, /* unused, really */
|
||||
RSA_BlockPrivate = 1, /* pad for a private-key operation */
|
||||
RSA_BlockPublic = 2, /* pad for a public-key operation */
|
||||
RSA_BlockOAEP = 3, /* use OAEP padding */
|
||||
/* XXX is this only for a public-key
|
||||
operation? If so, add "Public" */
|
||||
RSA_BlockRaw = 4, /* simply justify the block appropriately */
|
||||
RSA_BlockTotal
|
||||
} RSA_BlockType;
|
||||
|
||||
#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
|
||||
|
||||
#endif /* _SOFTOKNT_H_ */
|
||||
@@ -1,337 +0,0 @@
|
||||
/* tlsprf.c - TLS Pseudo Random Function (PRF) implementation
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: tlsprf.c,v 1.5 2005-03-29 18:21:18 nelsonb%netscape.com Exp $ */
|
||||
|
||||
#include "pkcs11i.h"
|
||||
#include "sechash.h"
|
||||
#include "alghmac.h"
|
||||
|
||||
#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
|
||||
|
||||
#define PHASH_STATE_MAX_LEN 20
|
||||
|
||||
/* TLS P_hash function */
|
||||
static SECStatus
|
||||
sftk_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
|
||||
SECItem *seed, SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
unsigned char state[PHASH_STATE_MAX_LEN];
|
||||
unsigned char outbuf[PHASH_STATE_MAX_LEN];
|
||||
unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
|
||||
unsigned int remaining;
|
||||
unsigned char *res;
|
||||
SECStatus status;
|
||||
HMACContext *cx;
|
||||
SECStatus rv = SECFailure;
|
||||
const SECHashObject *hashObj = &SECRawHashObjects[hashType];
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
remaining = result->len;
|
||||
res = result->data;
|
||||
|
||||
if (label != NULL)
|
||||
label_len = PORT_Strlen(label);
|
||||
|
||||
cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
|
||||
if (cx == NULL)
|
||||
goto loser;
|
||||
|
||||
/* initialize the state = A(1) = HMAC_hash(secret, seed) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* generate a block at a time until we're done */
|
||||
while (remaining > 0) {
|
||||
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
if (label_len)
|
||||
HMAC_Update(cx, (unsigned char *)label, label_len);
|
||||
HMAC_Update(cx, seed->data, seed->len);
|
||||
status = HMAC_Finish(cx, outbuf, &outbuf_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
|
||||
HMAC_Begin(cx);
|
||||
HMAC_Update(cx, state, state_len);
|
||||
status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
chunk_size = PR_MIN(outbuf_len, remaining);
|
||||
PORT_Memcpy(res, &outbuf, chunk_size);
|
||||
res += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
}
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
/* if (cx) HMAC_Destroy(cx); */
|
||||
/* clear out state so it's not left on the stack */
|
||||
if (cx) HMAC_Destroy(cx);
|
||||
PORT_Memset(state, 0, sizeof(state));
|
||||
PORT_Memset(outbuf, 0, sizeof(outbuf));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
|
||||
SECItem *result, PRBool isFIPS)
|
||||
{
|
||||
SECStatus rv = SECFailure, status;
|
||||
unsigned int i;
|
||||
SECItem tmp = { siBuffer, NULL, 0};
|
||||
SECItem S1;
|
||||
SECItem S2;
|
||||
|
||||
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
|
||||
PORT_Assert((seed != NULL) && (seed->data != NULL));
|
||||
PORT_Assert((result != NULL) && (result->data != NULL));
|
||||
|
||||
S1.type = siBuffer;
|
||||
S1.len = (secret->len / 2) + (secret->len & 1);
|
||||
S1.data = secret->data;
|
||||
|
||||
S2.type = siBuffer;
|
||||
S2.len = S1.len;
|
||||
S2.data = secret->data + (secret->len - S2.len);
|
||||
|
||||
tmp.data = (unsigned char*)PORT_Alloc(result->len);
|
||||
if (tmp.data == NULL)
|
||||
goto loser;
|
||||
tmp.len = result->len;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
status = sftk_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
|
||||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
for (i = 0; i < result->len; i++)
|
||||
result->data[i] ^= tmp.data[i];
|
||||
|
||||
rv = SECSuccess;
|
||||
|
||||
loser:
|
||||
if (tmp.data != NULL)
|
||||
PORT_ZFree(tmp.data, tmp.len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void sftk_TLSPRFNull(void *data, PRBool freeit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
PRUint32 cxSize; /* size of allocated block, in bytes. */
|
||||
PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */
|
||||
unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */
|
||||
PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */
|
||||
PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */
|
||||
SECStatus cxRv; /* records failure of void functions. */
|
||||
PRBool cxIsFIPS; /* true if conforming to FIPS 198. */
|
||||
unsigned char cxBuf[512]; /* actual size may be larger than 512. */
|
||||
} TLSPRFContext;
|
||||
|
||||
static void
|
||||
sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data,
|
||||
unsigned int data_len)
|
||||
{
|
||||
PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen;
|
||||
|
||||
if (cx->cxRv != SECSuccess) /* function has previously failed. */
|
||||
return;
|
||||
if (bytesUsed + data_len > cx->cxBufSize) {
|
||||
/* We don't use realloc here because
|
||||
** (a) realloc doesn't zero out the old block, and
|
||||
** (b) if realloc fails, we lose the old block.
|
||||
*/
|
||||
PRUint32 newBufSize = bytesUsed + data_len + 512;
|
||||
unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize);
|
||||
if (!newBuf) {
|
||||
cx->cxRv = SECFailure;
|
||||
return;
|
||||
}
|
||||
PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed);
|
||||
if (cx->cxBufPtr != cx->cxBuf) {
|
||||
PORT_ZFree(cx->cxBufPtr, bytesUsed);
|
||||
}
|
||||
cx->cxBufPtr = newBuf;
|
||||
cx->cxBufSize = newBufSize;
|
||||
}
|
||||
PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len);
|
||||
cx->cxDataLen += data_len;
|
||||
}
|
||||
|
||||
static void
|
||||
sftk_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout,
|
||||
unsigned int *pDigestLen, unsigned int maxDigestLen)
|
||||
{
|
||||
*pDigestLen = 0; /* tells Verify that no data has been input yet. */
|
||||
}
|
||||
|
||||
/* Compute the PRF values from the data previously input. */
|
||||
static SECStatus
|
||||
sftk_TLSPRFUpdate(TLSPRFContext *cx,
|
||||
unsigned char *sig, /* output goes here. */
|
||||
unsigned int * sigLen, /* how much output. */
|
||||
unsigned int maxLen, /* output buffer size */
|
||||
unsigned char *hash, /* unused. */
|
||||
unsigned int hashLen) /* unused. */
|
||||
{
|
||||
SECStatus rv;
|
||||
SECItem sigItem;
|
||||
SECItem seedItem;
|
||||
SECItem secretItem;
|
||||
|
||||
if (cx->cxRv != SECSuccess)
|
||||
return cx->cxRv;
|
||||
|
||||
secretItem.data = cx->cxBufPtr;
|
||||
secretItem.len = cx->cxKeyLen;
|
||||
|
||||
seedItem.data = cx->cxBufPtr + cx->cxKeyLen;
|
||||
seedItem.len = cx->cxDataLen;
|
||||
|
||||
sigItem.data = sig;
|
||||
sigItem.len = maxLen;
|
||||
|
||||
rv = sftk_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
|
||||
if (rv == SECSuccess && sigLen != NULL)
|
||||
*sigLen = sigItem.len;
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
sftk_TLSPRFVerify(TLSPRFContext *cx,
|
||||
unsigned char *sig, /* input, for comparison. */
|
||||
unsigned int sigLen, /* length of sig. */
|
||||
unsigned char *hash, /* data to be verified. */
|
||||
unsigned int hashLen) /* size of hash data. */
|
||||
{
|
||||
unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen);
|
||||
unsigned int tmpLen = sigLen;
|
||||
SECStatus rv;
|
||||
|
||||
if (!tmp)
|
||||
return SECFailure;
|
||||
if (hashLen) {
|
||||
/* hashLen is non-zero when the user does a one-step verify.
|
||||
** In this case, none of the data has been input yet.
|
||||
*/
|
||||
sftk_TLSPRFHashUpdate(cx, hash, hashLen);
|
||||
}
|
||||
rv = sftk_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0);
|
||||
if (rv == SECSuccess) {
|
||||
rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen));
|
||||
}
|
||||
PORT_ZFree(tmp, sigLen);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
sftk_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit)
|
||||
{
|
||||
if (freeit) {
|
||||
if (cx->cxBufPtr != cx->cxBuf)
|
||||
PORT_ZFree(cx->cxBufPtr, cx->cxBufSize);
|
||||
PORT_ZFree(cx, cx->cxSize);
|
||||
}
|
||||
}
|
||||
|
||||
CK_RV
|
||||
sftk_TLSPRFInit(SFTKSessionContext *context,
|
||||
SFTKObject * key,
|
||||
CK_KEY_TYPE key_type)
|
||||
{
|
||||
SFTKAttribute * keyVal;
|
||||
TLSPRFContext * prf_cx;
|
||||
CK_RV crv = CKR_HOST_MEMORY;
|
||||
PRUint32 keySize;
|
||||
PRUint32 blockSize;
|
||||
|
||||
if (key_type != CKK_GENERIC_SECRET)
|
||||
return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */
|
||||
|
||||
context->multi = PR_TRUE;
|
||||
|
||||
keyVal = sftk_FindAttribute(key, CKA_VALUE);
|
||||
keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen;
|
||||
blockSize = keySize + sizeof(TLSPRFContext);
|
||||
prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize);
|
||||
if (!prf_cx)
|
||||
goto done;
|
||||
prf_cx->cxSize = blockSize;
|
||||
prf_cx->cxKeyLen = keySize;
|
||||
prf_cx->cxDataLen = 0;
|
||||
prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf);
|
||||
prf_cx->cxRv = SECSuccess;
|
||||
prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
|
||||
prf_cx->cxBufPtr = prf_cx->cxBuf;
|
||||
if (keySize)
|
||||
PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize);
|
||||
|
||||
context->hashInfo = (void *) prf_cx;
|
||||
context->cipherInfo = (void *) prf_cx;
|
||||
context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate;
|
||||
context->end = (SFTKEnd) sftk_TLSPRFEnd;
|
||||
context->update = (SFTKCipher) sftk_TLSPRFUpdate;
|
||||
context->verify = (SFTKVerify) sftk_TLSPRFVerify;
|
||||
context->destroy = (SFTKDestroy) sftk_TLSPRFNull;
|
||||
context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy;
|
||||
crv = CKR_OK;
|
||||
|
||||
done:
|
||||
if (keyVal)
|
||||
sftk_FreeAttribute(keyVal);
|
||||
return crv;
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
include config.mk
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
@@ -1,553 +0,0 @@
|
||||
/*
|
||||
** 2005 February 15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains C code routines that used to generate VDBE code
|
||||
** that implements the ALTER TABLE command.
|
||||
**
|
||||
** $Id: alter.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** The code in this file only exists if we are not omitting the
|
||||
** ALTER TABLE logic from the build.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||
|
||||
|
||||
/*
|
||||
** This function is used by SQL generated to implement the
|
||||
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
|
||||
** CREATE INDEX command. The second is a table name. The table name in
|
||||
** the CREATE TABLE or CREATE INDEX statement is replaced with the second
|
||||
** argument and the result returned. Examples:
|
||||
**
|
||||
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
|
||||
** -> 'CREATE TABLE def(a, b, c)'
|
||||
**
|
||||
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
|
||||
** -> 'CREATE INDEX i ON def(a, b, c)'
|
||||
*/
|
||||
static void renameTableFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
unsigned char const *zSql = sqlite3_value_text(argv[0]);
|
||||
unsigned char const *zTableName = sqlite3_value_text(argv[1]);
|
||||
|
||||
int token;
|
||||
Token tname;
|
||||
char const *zCsr = zSql;
|
||||
int len = 0;
|
||||
char *zRet;
|
||||
|
||||
/* The principle used to locate the table name in the CREATE TABLE
|
||||
** statement is that the table name is the first token that is immediatedly
|
||||
** followed by a left parenthesis - TK_LP.
|
||||
*/
|
||||
if( zSql ){
|
||||
do {
|
||||
/* Store the token that zCsr points to in tname. */
|
||||
tname.z = zCsr;
|
||||
tname.n = len;
|
||||
|
||||
/* Advance zCsr to the next token. Store that token type in 'token',
|
||||
** and it's length in 'len' (to be used next iteration of this loop).
|
||||
*/
|
||||
do {
|
||||
zCsr += len;
|
||||
len = sqlite3GetToken(zCsr, &token);
|
||||
} while( token==TK_SPACE );
|
||||
assert( len>0 );
|
||||
} while( token!=TK_LP );
|
||||
|
||||
zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql,
|
||||
zTableName, tname.z+tname.n);
|
||||
sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
/* This function is used by SQL generated to implement the ALTER TABLE
|
||||
** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
|
||||
** statement. The second is a table name. The table name in the CREATE
|
||||
** TRIGGER statement is replaced with the second argument and the result
|
||||
** returned. This is analagous to renameTableFunc() above, except for CREATE
|
||||
** TRIGGER, not CREATE INDEX and CREATE TABLE.
|
||||
*/
|
||||
static void renameTriggerFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
unsigned char const *zSql = sqlite3_value_text(argv[0]);
|
||||
unsigned char const *zTableName = sqlite3_value_text(argv[1]);
|
||||
|
||||
int token;
|
||||
Token tname;
|
||||
int dist = 3;
|
||||
char const *zCsr = zSql;
|
||||
int len = 0;
|
||||
char *zRet;
|
||||
|
||||
/* The principle used to locate the table name in the CREATE TRIGGER
|
||||
** statement is that the table name is the first token that is immediatedly
|
||||
** preceded by either TK_ON or TK_DOT and immediatedly followed by one
|
||||
** of TK_WHEN, TK_BEGIN or TK_FOR.
|
||||
*/
|
||||
if( zSql ){
|
||||
do {
|
||||
/* Store the token that zCsr points to in tname. */
|
||||
tname.z = zCsr;
|
||||
tname.n = len;
|
||||
|
||||
/* Advance zCsr to the next token. Store that token type in 'token',
|
||||
** and it's length in 'len' (to be used next iteration of this loop).
|
||||
*/
|
||||
do {
|
||||
zCsr += len;
|
||||
len = sqlite3GetToken(zCsr, &token);
|
||||
}while( token==TK_SPACE );
|
||||
assert( len>0 );
|
||||
|
||||
/* Variable 'dist' stores the number of tokens read since the most
|
||||
** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
|
||||
** token is read and 'dist' equals 2, the condition stated above
|
||||
** to be met.
|
||||
**
|
||||
** Note that ON cannot be a database, table or column name, so
|
||||
** there is no need to worry about syntax like
|
||||
** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
|
||||
*/
|
||||
dist++;
|
||||
if( token==TK_DOT || token==TK_ON ){
|
||||
dist = 0;
|
||||
}
|
||||
} while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
|
||||
|
||||
/* Variable tname now contains the token that is the old table-name
|
||||
** in the CREATE TRIGGER statement.
|
||||
*/
|
||||
zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql,
|
||||
zTableName, tname.z+tname.n);
|
||||
sqlite3_result_text(context, zRet, -1, sqlite3FreeX);
|
||||
}
|
||||
}
|
||||
#endif /* !SQLITE_OMIT_TRIGGER */
|
||||
|
||||
/*
|
||||
** Register built-in functions used to help implement ALTER TABLE
|
||||
*/
|
||||
void sqlite3AlterFunctions(sqlite3 *db){
|
||||
static const struct {
|
||||
char *zName;
|
||||
signed char nArg;
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
|
||||
} aFuncs[] = {
|
||||
{ "sqlite_rename_table", 2, renameTableFunc},
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
{ "sqlite_rename_trigger", 2, renameTriggerFunc},
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
|
||||
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
|
||||
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
|
||||
SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate the text of a WHERE expression which can be used to select all
|
||||
** temporary triggers on table pTab from the sqlite_temp_master table. If
|
||||
** table pTab has no temporary triggers, or is itself stored in the
|
||||
** temporary database, NULL is returned.
|
||||
*/
|
||||
static char *whereTempTriggers(Parse *pParse, Table *pTab){
|
||||
Trigger *pTrig;
|
||||
char *zWhere = 0;
|
||||
char *tmp = 0;
|
||||
if( pTab->iDb!=1 ){
|
||||
for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
|
||||
if( pTrig->iDb==1 ){
|
||||
if( !zWhere ){
|
||||
zWhere = sqlite3MPrintf("name=%Q", pTrig->name);
|
||||
}else{
|
||||
tmp = zWhere;
|
||||
zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name);
|
||||
sqliteFree(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return zWhere;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to drop and reload the internal representation of table
|
||||
** pTab from the database, including triggers and temporary triggers.
|
||||
** Argument zName is the name of the table in the database schema at
|
||||
** the time the generated code is executed. This can be different from
|
||||
** pTab->zName if this function is being called to code part of an
|
||||
** "ALTER TABLE RENAME TO" statement.
|
||||
*/
|
||||
static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
|
||||
Vdbe *v;
|
||||
char *zWhere;
|
||||
int iDb;
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
Trigger *pTrig;
|
||||
#endif
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( !v ) return;
|
||||
iDb = pTab->iDb;
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
/* Drop any table triggers from the internal schema. */
|
||||
for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
|
||||
assert( pTrig->iDb==iDb || pTrig->iDb==1 );
|
||||
sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Drop the table and index from the internal schema */
|
||||
sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
|
||||
|
||||
/* Reload the table, index and permanent trigger schemas. */
|
||||
zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
|
||||
if( !zWhere ) return;
|
||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
/* Now, if the table is not stored in the temp database, reload any temp
|
||||
** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
|
||||
*/
|
||||
if( (zWhere=whereTempTriggers(pParse, pTab)) ){
|
||||
sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
|
||||
** command.
|
||||
*/
|
||||
void sqlite3AlterRenameTable(
|
||||
Parse *pParse, /* Parser context. */
|
||||
SrcList *pSrc, /* The table to rename. */
|
||||
Token *pName /* The new table name. */
|
||||
){
|
||||
int iDb; /* Database that contains the table */
|
||||
char *zDb; /* Name of database iDb */
|
||||
Table *pTab; /* Table being renamed */
|
||||
char *zName = 0; /* NULL-terminated version of pName */
|
||||
sqlite3 *db = pParse->db; /* Database connection */
|
||||
Vdbe *v;
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
char *zWhere = 0; /* Where clause to locate temp triggers */
|
||||
#endif
|
||||
|
||||
assert( pSrc->nSrc==1 );
|
||||
|
||||
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
if( !pTab ) goto exit_rename_table;
|
||||
iDb = pTab->iDb;
|
||||
zDb = db->aDb[iDb].zName;
|
||||
|
||||
/* Get a NULL terminated version of the new table name. */
|
||||
zName = sqlite3NameFromToken(pName);
|
||||
if( !zName ) goto exit_rename_table;
|
||||
|
||||
/* Check that a table or index named 'zName' does not already exist
|
||||
** in database iDb. If so, this is an error.
|
||||
*/
|
||||
if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"there is already another table or index with this name: %s", zName);
|
||||
goto exit_rename_table;
|
||||
}
|
||||
|
||||
/* Make sure it is not a system table being altered, or a reserved name
|
||||
** that the table is being renamed to.
|
||||
*/
|
||||
if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
|
||||
goto exit_rename_table;
|
||||
}
|
||||
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
|
||||
goto exit_rename_table;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
/* Invoke the authorization callback. */
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
|
||||
goto exit_rename_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Begin a transaction and code the VerifyCookie for database iDb.
|
||||
** Then modify the schema cookie (since the ALTER TABLE modifies the
|
||||
** schema).
|
||||
*/
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ){
|
||||
goto exit_rename_table;
|
||||
}
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
sqlite3ChangeCookie(db, v, iDb);
|
||||
|
||||
/* Modify the sqlite_master table to use the new table name. */
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s SET "
|
||||
#ifdef SQLITE_OMIT_TRIGGER
|
||||
"sql = sqlite_rename_table(sql, %Q), "
|
||||
#else
|
||||
"sql = CASE "
|
||||
"WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
|
||||
"ELSE sqlite_rename_table(sql, %Q) END, "
|
||||
#endif
|
||||
"tbl_name = %Q, "
|
||||
"name = CASE "
|
||||
"WHEN type='table' THEN %Q "
|
||||
"WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
|
||||
"'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
|
||||
"ELSE name END "
|
||||
"WHERE tbl_name=%Q AND "
|
||||
"(type='table' OR type='index' OR type='trigger');",
|
||||
zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
zName,
|
||||
#endif
|
||||
zName, strlen(pTab->zName), pTab->zName
|
||||
);
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
/* If the sqlite_sequence table exists in this database, then update
|
||||
** it with the new table name.
|
||||
*/
|
||||
if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
|
||||
zDb, zName, pTab->zName);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
/* If there are TEMP triggers on this table, modify the sqlite_temp_master
|
||||
** table. Don't do this if the table being ALTERed is itself located in
|
||||
** the temp database.
|
||||
*/
|
||||
if( (zWhere=whereTempTriggers(pParse, pTab)) ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE sqlite_temp_master SET "
|
||||
"sql = sqlite_rename_trigger(sql, %Q), "
|
||||
"tbl_name = %Q "
|
||||
"WHERE %s;", zName, zName, zWhere);
|
||||
sqliteFree(zWhere);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Drop and reload the internal table schema. */
|
||||
reloadTableSchema(pParse, pTab, zName);
|
||||
|
||||
exit_rename_table:
|
||||
sqlite3SrcListDelete(pSrc);
|
||||
sqliteFree(zName);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is called after an "ALTER TABLE ... ADD" statement
|
||||
** has been parsed. Argument pColDef contains the text of the new
|
||||
** column definition.
|
||||
**
|
||||
** The Table structure pParse->pNewTable was extended to include
|
||||
** the new column during parsing.
|
||||
*/
|
||||
void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
Table *pNew; /* Copy of pParse->pNewTable */
|
||||
Table *pTab; /* Table being altered */
|
||||
int iDb; /* Database number */
|
||||
const char *zDb; /* Database name */
|
||||
const char *zTab; /* Table name */
|
||||
char *zCol; /* Null-terminated column definition */
|
||||
Column *pCol; /* The new column */
|
||||
Expr *pDflt; /* Default value for the new column */
|
||||
Vdbe *v;
|
||||
|
||||
if( pParse->nErr ) return;
|
||||
pNew = pParse->pNewTable;
|
||||
assert( pNew );
|
||||
|
||||
iDb = pNew->iDb;
|
||||
zDb = pParse->db->aDb[iDb].zName;
|
||||
zTab = pNew->zName;
|
||||
pCol = &pNew->aCol[pNew->nCol-1];
|
||||
pDflt = pCol->pDflt;
|
||||
pTab = sqlite3FindTable(pParse->db, zTab, zDb);
|
||||
assert( pTab );
|
||||
|
||||
/* If the default value for the new column was specified with a
|
||||
** literal NULL, then set pDflt to 0. This simplifies checking
|
||||
** for an SQL NULL default below.
|
||||
*/
|
||||
if( pDflt && pDflt->op==TK_NULL ){
|
||||
pDflt = 0;
|
||||
}
|
||||
|
||||
/* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
|
||||
** If there is a NOT NULL constraint, then the default value for the
|
||||
** column must not be NULL.
|
||||
*/
|
||||
if( pCol->isPrimKey ){
|
||||
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
|
||||
return;
|
||||
}
|
||||
if( pNew->pIndex ){
|
||||
sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
|
||||
return;
|
||||
}
|
||||
if( pCol->notNull && !pDflt ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Cannot add a NOT NULL column with default value NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure the default expression is something that sqlite3ValueFromExpr()
|
||||
** can handle (i.e. not CURRENT_TIME etc.)
|
||||
*/
|
||||
if( pDflt ){
|
||||
sqlite3_value *pVal;
|
||||
if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
|
||||
/* malloc() has failed */
|
||||
return;
|
||||
}
|
||||
if( !pVal ){
|
||||
sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
|
||||
return;
|
||||
}
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
|
||||
/* Modify the CREATE TABLE statement. */
|
||||
zCol = sqliteStrNDup(pColDef->z, pColDef->n);
|
||||
if( zCol ){
|
||||
char *zEnd = &zCol[pColDef->n-1];
|
||||
while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
|
||||
*zEnd-- = '\0';
|
||||
}
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s SET "
|
||||
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) "
|
||||
"WHERE type = 'table' AND name = %Q",
|
||||
zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
|
||||
zTab
|
||||
);
|
||||
sqliteFree(zCol);
|
||||
}
|
||||
|
||||
/* If the default value of the new column is NULL, then set the file
|
||||
** format to 2. If the default value of the new column is not NULL,
|
||||
** the file format becomes 3.
|
||||
*/
|
||||
if( (v=sqlite3GetVdbe(pParse)) ){
|
||||
int f = (pDflt?3:2);
|
||||
|
||||
/* Only set the file format to $f if it is currently less than $f. */
|
||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, f, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, f, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
|
||||
}
|
||||
|
||||
/* Reload the schema of the modified table. */
|
||||
reloadTableSchema(pParse, pTab, pTab->zName);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is called by the parser after the table-name in
|
||||
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
|
||||
** pSrc is the full-name of the table being altered.
|
||||
**
|
||||
** This routine makes a (partial) copy of the Table structure
|
||||
** for the table being altered and sets Parse.pNewTable to point
|
||||
** to it. Routines called by the parser as the column definition
|
||||
** is parsed (i.e. sqlite3AddColumn()) add the new Column data to
|
||||
** the copy. The copy of the Table structure is deleted by tokenize.c
|
||||
** after parsing is finished.
|
||||
**
|
||||
** Routine sqlite3AlterFinishAddColumn() will be called to complete
|
||||
** coding the "ALTER TABLE ... ADD" statement.
|
||||
*/
|
||||
void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
|
||||
Table *pNew;
|
||||
Table *pTab;
|
||||
Vdbe *v;
|
||||
int iDb;
|
||||
int i;
|
||||
int nAlloc;
|
||||
|
||||
/* Look up the table being altered. */
|
||||
assert( !pParse->pNewTable );
|
||||
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
if( !pTab ) goto exit_begin_add_column;
|
||||
|
||||
/* Make sure this is not an attempt to ALTER a view. */
|
||||
if( pTab->pSelect ){
|
||||
sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
|
||||
goto exit_begin_add_column;
|
||||
}
|
||||
|
||||
assert( pTab->addColOffset>0 );
|
||||
iDb = pTab->iDb;
|
||||
|
||||
/* Put a copy of the Table struct in Parse.pNewTable for the
|
||||
** sqlite3AddColumn() function and friends to modify.
|
||||
*/
|
||||
pNew = (Table *)sqliteMalloc(sizeof(Table));
|
||||
if( !pNew ) goto exit_begin_add_column;
|
||||
pParse->pNewTable = pNew;
|
||||
pNew->nCol = pTab->nCol;
|
||||
assert( pNew->nCol>0 );
|
||||
nAlloc = (((pNew->nCol-1)/8)*8)+8;
|
||||
assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
|
||||
pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc);
|
||||
pNew->zName = sqliteStrDup(pTab->zName);
|
||||
if( !pNew->aCol || !pNew->zName ){
|
||||
goto exit_begin_add_column;
|
||||
}
|
||||
memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
|
||||
for(i=0; i<pNew->nCol; i++){
|
||||
Column *pCol = &pNew->aCol[i];
|
||||
pCol->zName = sqliteStrDup(pCol->zName);
|
||||
pCol->zType = 0;
|
||||
pCol->pDflt = 0;
|
||||
}
|
||||
pNew->iDb = iDb;
|
||||
pNew->addColOffset = pTab->addColOffset;
|
||||
pNew->nRef = 1;
|
||||
|
||||
/* Begin a transaction and increment the schema cookie. */
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( !v ) goto exit_begin_add_column;
|
||||
sqlite3ChangeCookie(pParse->db, v, iDb);
|
||||
|
||||
exit_begin_add_column:
|
||||
sqlite3SrcListDelete(pSrc);
|
||||
return;
|
||||
}
|
||||
#endif /* SQLITE_ALTER_TABLE */
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
** 2003 April 6
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||
**
|
||||
** $Id: attach.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** This routine is called by the parser to process an ATTACH statement:
|
||||
**
|
||||
** ATTACH DATABASE filename AS dbname
|
||||
**
|
||||
** The pFilename and pDbname arguments are the tokens that define the
|
||||
** filename and dbname in the ATTACH statement.
|
||||
*/
|
||||
void sqlite3Attach(
|
||||
Parse *pParse, /* The parser context */
|
||||
Token *pFilename, /* Name of database file */
|
||||
Token *pDbname, /* Name of the database to use internally */
|
||||
int keyType, /* 0: no key. 1: TEXT, 2: BLOB */
|
||||
Token *pKey /* Text of the key for keytype 1 and 2 */
|
||||
){
|
||||
Db *aNew;
|
||||
int rc, i;
|
||||
char *zFile = 0;
|
||||
char *zName = 0;
|
||||
sqlite3 *db;
|
||||
Vdbe *v;
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( !v ) return;
|
||||
sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
||||
if( pParse->explain ) return;
|
||||
db = pParse->db;
|
||||
if( db->nDb>=MAX_ATTACHED+2 ){
|
||||
sqlite3ErrorMsg(pParse, "too many attached databases - max %d",
|
||||
MAX_ATTACHED);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
zFile = sqlite3NameFromToken(pFilename);
|
||||
if( zFile==0 ){
|
||||
goto attach_end;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
|
||||
goto attach_end;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
|
||||
zName = sqlite3NameFromToken(pDbname);
|
||||
if( zName==0 ){
|
||||
goto attach_end;
|
||||
}
|
||||
for(i=0; i<db->nDb; i++){
|
||||
char *z = db->aDb[i].zName;
|
||||
if( z && sqlite3StrICmp(z, zName)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "database %s is already in use", zName);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
goto attach_end;
|
||||
}
|
||||
}
|
||||
|
||||
if( db->aDb==db->aDbStatic ){
|
||||
aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
|
||||
if( aNew==0 ){
|
||||
goto attach_end;
|
||||
}
|
||||
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
|
||||
}else{
|
||||
aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
|
||||
if( aNew==0 ){
|
||||
goto attach_end;
|
||||
}
|
||||
}
|
||||
db->aDb = aNew;
|
||||
aNew = &db->aDb[db->nDb++];
|
||||
memset(aNew, 0, sizeof(*aNew));
|
||||
sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
|
||||
aNew->zName = zName;
|
||||
zName = 0;
|
||||
aNew->safety_level = 3;
|
||||
rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
|
||||
if( rc ){
|
||||
sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
|
||||
}
|
||||
#if SQLITE_HAS_CODEC
|
||||
{
|
||||
extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
|
||||
char *zKey;
|
||||
int nKey;
|
||||
if( keyType==0 ){
|
||||
/* No key specified. Use the key from the main database */
|
||||
extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
}else if( keyType==1 ){
|
||||
/* Key specified as text */
|
||||
zKey = sqlite3NameFromToken(pKey);
|
||||
nKey = strlen(zKey);
|
||||
}else{
|
||||
/* Key specified as a BLOB */
|
||||
char *zTemp;
|
||||
assert( keyType==2 );
|
||||
pKey->z++;
|
||||
pKey->n--;
|
||||
zTemp = sqlite3NameFromToken(pKey);
|
||||
zKey = sqlite3HexToBlob(zTemp);
|
||||
sqliteFree(zTemp);
|
||||
}
|
||||
sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
if( keyType ){
|
||||
sqliteFree(zKey);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
db->flags &= ~SQLITE_Initialized;
|
||||
if( pParse->nErr==0 && rc==SQLITE_OK ){
|
||||
rc = sqlite3ReadSchema(pParse);
|
||||
}
|
||||
if( rc ){
|
||||
int i = db->nDb - 1;
|
||||
assert( i>=2 );
|
||||
if( db->aDb[i].pBt ){
|
||||
sqlite3BtreeClose(db->aDb[i].pBt);
|
||||
db->aDb[i].pBt = 0;
|
||||
}
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
if( 0==pParse->nErr ){
|
||||
pParse->nErr++;
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
attach_end:
|
||||
sqliteFree(zFile);
|
||||
sqliteFree(zName);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called by the parser to process a DETACH statement:
|
||||
**
|
||||
** DETACH DATABASE dbname
|
||||
**
|
||||
** The pDbname argument is the name of the database in the DETACH statement.
|
||||
*/
|
||||
void sqlite3Detach(Parse *pParse, Token *pDbname){
|
||||
int i;
|
||||
sqlite3 *db;
|
||||
Vdbe *v;
|
||||
Db *pDb = 0;
|
||||
char *zName;
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( !v ) return;
|
||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
||||
if( pParse->explain ) return;
|
||||
db = pParse->db;
|
||||
zName = sqlite3NameFromToken(pDbname);
|
||||
if( zName==0 ) return;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
pDb = &db->aDb[i];
|
||||
if( pDb->pBt==0 ) continue;
|
||||
if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
|
||||
}
|
||||
if( i>=db->nDb ){
|
||||
sqlite3ErrorMsg(pParse, "no such database: %z", zName);
|
||||
return;
|
||||
}
|
||||
if( i<2 ){
|
||||
sqlite3ErrorMsg(pParse, "cannot detach database %z", zName);
|
||||
return;
|
||||
}
|
||||
sqliteFree(zName);
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
|
||||
return;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
sqlite3BtreeClose(pDb->pBt);
|
||||
pDb->pBt = 0;
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a DbFixer structure. This routine must be called prior
|
||||
** to passing the structure to one of the sqliteFixAAAA() routines below.
|
||||
**
|
||||
** The return value indicates whether or not fixation is required. TRUE
|
||||
** means we do need to fix the database references, FALSE means we do not.
|
||||
*/
|
||||
int sqlite3FixInit(
|
||||
DbFixer *pFix, /* The fixer to be initialized */
|
||||
Parse *pParse, /* Error messages will be written here */
|
||||
int iDb, /* This is the database that must be used */
|
||||
const char *zType, /* "view", "trigger", or "index" */
|
||||
const Token *pName /* Name of the view, trigger, or index */
|
||||
){
|
||||
sqlite3 *db;
|
||||
|
||||
if( iDb<0 || iDb==1 ) return 0;
|
||||
db = pParse->db;
|
||||
assert( db->nDb>iDb );
|
||||
pFix->pParse = pParse;
|
||||
pFix->zDb = db->aDb[iDb].zName;
|
||||
pFix->zType = zType;
|
||||
pFix->pName = pName;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** The following set of routines walk through the parse tree and assign
|
||||
** a specific database to all table references where the database name
|
||||
** was left unspecified in the original SQL statement. The pFix structure
|
||||
** must have been initialized by a prior call to sqlite3FixInit().
|
||||
**
|
||||
** These routines are used to make sure that an index, trigger, or
|
||||
** view in one database does not refer to objects in a different database.
|
||||
** (Exception: indices, triggers, and views in the TEMP database are
|
||||
** allowed to refer to anything.) If a reference is explicitly made
|
||||
** to an object in a different database, an error message is added to
|
||||
** pParse->zErrMsg and these routines return non-zero. If everything
|
||||
** checks out, these routines return 0.
|
||||
*/
|
||||
int sqlite3FixSrcList(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
SrcList *pList /* The Source list to check and modify */
|
||||
){
|
||||
int i;
|
||||
const char *zDb;
|
||||
struct SrcList_item *pItem;
|
||||
|
||||
if( pList==0 ) return 0;
|
||||
zDb = pFix->zDb;
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pItem->zDatabase==0 ){
|
||||
pItem->zDatabase = sqliteStrDup(zDb);
|
||||
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %T cannot reference objects in database %s",
|
||||
pFix->zType, pFix->pName, pItem->zDatabase);
|
||||
return 1;
|
||||
}
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
|
||||
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
|
||||
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
|
||||
int sqlite3FixSelect(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
Select *pSelect /* The SELECT statement to be fixed to one database */
|
||||
){
|
||||
while( pSelect ){
|
||||
if( sqlite3FixExprList(pFix, pSelect->pEList) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
|
||||
return 1;
|
||||
}
|
||||
pSelect = pSelect->pPrior;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqlite3FixExpr(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
Expr *pExpr /* The expression to be fixed to one database */
|
||||
){
|
||||
while( pExpr ){
|
||||
if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExprList(pFix, pExpr->pList) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExpr(pFix, pExpr->pRight) ){
|
||||
return 1;
|
||||
}
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqlite3FixExprList(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
ExprList *pList /* The expression to be fixed to one database */
|
||||
){
|
||||
int i;
|
||||
struct ExprList_item *pItem;
|
||||
if( pList==0 ) return 0;
|
||||
for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
|
||||
if( sqlite3FixExpr(pFix, pItem->pExpr) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
int sqlite3FixTriggerStep(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
TriggerStep *pStep /* The trigger step be fixed to one database */
|
||||
){
|
||||
while( pStep ){
|
||||
if( sqlite3FixSelect(pFix, pStep->pSelect) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExpr(pFix, pStep->pWhere) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3FixExprList(pFix, pStep->pExprList) ){
|
||||
return 1;
|
||||
}
|
||||
pStep = pStep->pNext;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
** 2003 January 11
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the sqlite3_set_authorizer()
|
||||
** API. This facility is an optional feature of the library. Embedded
|
||||
** systems that do not need this facility may omit it by recompiling
|
||||
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
|
||||
**
|
||||
** $Id: auth.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** All of the code in this file may be omitted by defining a single
|
||||
** macro.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
|
||||
/*
|
||||
** Set or clear the access authorization function.
|
||||
**
|
||||
** The access authorization function is be called during the compilation
|
||||
** phase to verify that the user has read and/or write access permission on
|
||||
** various fields of the database. The first argument to the auth function
|
||||
** is a copy of the 3rd argument to this routine. The second argument
|
||||
** to the auth function is one of these constants:
|
||||
**
|
||||
** SQLITE_CREATE_INDEX
|
||||
** SQLITE_CREATE_TABLE
|
||||
** SQLITE_CREATE_TEMP_INDEX
|
||||
** SQLITE_CREATE_TEMP_TABLE
|
||||
** SQLITE_CREATE_TEMP_TRIGGER
|
||||
** SQLITE_CREATE_TEMP_VIEW
|
||||
** SQLITE_CREATE_TRIGGER
|
||||
** SQLITE_CREATE_VIEW
|
||||
** SQLITE_DELETE
|
||||
** SQLITE_DROP_INDEX
|
||||
** SQLITE_DROP_TABLE
|
||||
** SQLITE_DROP_TEMP_INDEX
|
||||
** SQLITE_DROP_TEMP_TABLE
|
||||
** SQLITE_DROP_TEMP_TRIGGER
|
||||
** SQLITE_DROP_TEMP_VIEW
|
||||
** SQLITE_DROP_TRIGGER
|
||||
** SQLITE_DROP_VIEW
|
||||
** SQLITE_INSERT
|
||||
** SQLITE_PRAGMA
|
||||
** SQLITE_READ
|
||||
** SQLITE_SELECT
|
||||
** SQLITE_TRANSACTION
|
||||
** SQLITE_UPDATE
|
||||
**
|
||||
** The third and fourth arguments to the auth function are the name of
|
||||
** the table and the column that are being accessed. The auth function
|
||||
** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
|
||||
** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
|
||||
** means that the SQL statement will never-run - the sqlite3_exec() call
|
||||
** will return with an error. SQLITE_IGNORE means that the SQL statement
|
||||
** should run but attempts to read the specified column will return NULL
|
||||
** and attempts to write the column will be ignored.
|
||||
**
|
||||
** Setting the auth function to NULL disables this hook. The default
|
||||
** setting of the auth function is NULL.
|
||||
*/
|
||||
int sqlite3_set_authorizer(
|
||||
sqlite3 *db,
|
||||
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
|
||||
void *pArg
|
||||
){
|
||||
db->xAuth = xAuth;
|
||||
db->pAuthArg = pArg;
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write an error message into pParse->zErrMsg that explains that the
|
||||
** user-supplied authorization function returned an illegal value.
|
||||
*/
|
||||
static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
|
||||
sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
|
||||
"authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
|
||||
"or SQLITE_DENY", rc);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
** The pExpr should be a TK_COLUMN expression. The table referred to
|
||||
** is in pTabList or else it is the NEW or OLD table of a trigger.
|
||||
** Check to see if it is OK to read this particular column.
|
||||
**
|
||||
** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
|
||||
** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
|
||||
** then generate an error.
|
||||
*/
|
||||
void sqlite3AuthRead(
|
||||
Parse *pParse, /* The parser context */
|
||||
Expr *pExpr, /* The expression to check authorization on */
|
||||
SrcList *pTabList /* All table that pExpr might refer to */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
int rc;
|
||||
Table *pTab; /* The table being read */
|
||||
const char *zCol; /* Name of the column of the table */
|
||||
int iSrc; /* Index in pTabList->a[] of table being read */
|
||||
const char *zDBase; /* Name of database being accessed */
|
||||
TriggerStack *pStack; /* The stack of current triggers */
|
||||
|
||||
if( db->xAuth==0 ) return;
|
||||
assert( pExpr->op==TK_COLUMN );
|
||||
for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
|
||||
if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
|
||||
}
|
||||
if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){
|
||||
pTab = pTabList->a[iSrc].pTab;
|
||||
}else if( (pStack = pParse->trigStack)!=0 ){
|
||||
/* This must be an attempt to read the NEW or OLD pseudo-tables
|
||||
** of a trigger.
|
||||
*/
|
||||
assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
|
||||
pTab = pStack->pTab;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
if( pTab==0 ) return;
|
||||
if( pExpr->iColumn>=0 ){
|
||||
assert( pExpr->iColumn<pTab->nCol );
|
||||
zCol = pTab->aCol[pExpr->iColumn].zName;
|
||||
}else if( pTab->iPKey>=0 ){
|
||||
assert( pTab->iPKey<pTab->nCol );
|
||||
zCol = pTab->aCol[pTab->iPKey].zName;
|
||||
}else{
|
||||
zCol = "ROWID";
|
||||
}
|
||||
assert( pExpr->iDb<db->nDb );
|
||||
zDBase = db->aDb[pExpr->iDb].zName;
|
||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase,
|
||||
pParse->zAuthContext);
|
||||
if( rc==SQLITE_IGNORE ){
|
||||
pExpr->op = TK_NULL;
|
||||
}else if( rc==SQLITE_DENY ){
|
||||
if( db->nDb>2 || pExpr->iDb!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",
|
||||
zDBase, pTab->zName, zCol);
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
|
||||
}
|
||||
pParse->rc = SQLITE_AUTH;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
sqliteAuthBadReturnCode(pParse, rc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Do an authorization check using the code and arguments given. Return
|
||||
** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
|
||||
** is returned, then the error count and error message in pParse are
|
||||
** modified appropriately.
|
||||
*/
|
||||
int sqlite3AuthCheck(
|
||||
Parse *pParse,
|
||||
int code,
|
||||
const char *zArg1,
|
||||
const char *zArg2,
|
||||
const char *zArg3
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
int rc;
|
||||
|
||||
/* Don't do any authorization checks if the database is initialising. */
|
||||
if( db->init.busy ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
if( db->xAuth==0 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
|
||||
if( rc==SQLITE_DENY ){
|
||||
sqlite3ErrorMsg(pParse, "not authorized");
|
||||
pParse->rc = SQLITE_AUTH;
|
||||
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
|
||||
rc = SQLITE_DENY;
|
||||
sqliteAuthBadReturnCode(pParse, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Push an authorization context. After this routine is called, the
|
||||
** zArg3 argument to authorization callbacks will be zContext until
|
||||
** popped. Or if pParse==0, this routine is a no-op.
|
||||
*/
|
||||
void sqlite3AuthContextPush(
|
||||
Parse *pParse,
|
||||
AuthContext *pContext,
|
||||
const char *zContext
|
||||
){
|
||||
pContext->pParse = pParse;
|
||||
if( pParse ){
|
||||
pContext->zAuthContext = pParse->zAuthContext;
|
||||
pParse->zAuthContext = zContext;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Pop an authorization context that was previously pushed
|
||||
** by sqlite3AuthContextPush
|
||||
*/
|
||||
void sqlite3AuthContextPop(AuthContext *pContext){
|
||||
if( pContext->pParse ){
|
||||
pContext->pParse->zAuthContext = pContext->zAuthContext;
|
||||
pContext->pParse = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
** 2001 September 15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the interface that the sqlite B-Tree file
|
||||
** subsystem. See comments in the source code for a detailed description
|
||||
** of what each interface routine does.
|
||||
**
|
||||
** @(#) $Id: btree.h,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#ifndef _BTREE_H_
|
||||
#define _BTREE_H_
|
||||
|
||||
/* TODO: This definition is just included so other modules compile. It
|
||||
** needs to be revisited.
|
||||
*/
|
||||
#define SQLITE_N_BTREE_META 10
|
||||
|
||||
/*
|
||||
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
|
||||
** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_AUTOVACUUM
|
||||
#define SQLITE_DEFAULT_AUTOVACUUM 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Forward declarations of structure
|
||||
*/
|
||||
typedef struct Btree Btree;
|
||||
typedef struct BtCursor BtCursor;
|
||||
|
||||
|
||||
int sqlite3BtreeOpen(
|
||||
const char *zFilename, /* Name of database file to open */
|
||||
Btree **, /* Return open Btree* here */
|
||||
int flags /* Flags */
|
||||
);
|
||||
|
||||
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
|
||||
** following values.
|
||||
**
|
||||
** NOTE: These values must match the corresponding PAGER_ values in
|
||||
** pager.h.
|
||||
*/
|
||||
#define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */
|
||||
#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */
|
||||
#define BTREE_MEMORY 4 /* In-memory DB. No argument */
|
||||
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
int sqlite3BtreeSetSafetyLevel(Btree*,int);
|
||||
int sqlite3BtreeSetPageSize(Btree*,int,int);
|
||||
int sqlite3BtreeGetPageSize(Btree*);
|
||||
int sqlite3BtreeGetReserve(Btree*);
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
int sqlite3BtreeBeginTrans(Btree*,int);
|
||||
int sqlite3BtreeCommit(Btree*);
|
||||
int sqlite3BtreeRollback(Btree*);
|
||||
int sqlite3BtreeBeginStmt(Btree*);
|
||||
int sqlite3BtreeCommitStmt(Btree*);
|
||||
int sqlite3BtreeRollbackStmt(Btree*);
|
||||
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
|
||||
int sqlite3BtreeIsInTrans(Btree*);
|
||||
int sqlite3BtreeIsInStmt(Btree*);
|
||||
int sqlite3BtreeSync(Btree*, const char *zMaster);
|
||||
int sqlite3BtreeReset(Btree *);
|
||||
|
||||
const char *sqlite3BtreeGetFilename(Btree *);
|
||||
const char *sqlite3BtreeGetDirname(Btree *);
|
||||
const char *sqlite3BtreeGetJournalname(Btree *);
|
||||
int sqlite3BtreeCopyFile(Btree *, Btree *);
|
||||
|
||||
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
|
||||
** of the following flags:
|
||||
*/
|
||||
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
|
||||
#define BTREE_ZERODATA 2 /* Table has keys only - no data */
|
||||
#define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */
|
||||
|
||||
int sqlite3BtreeDropTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTable(Btree*, int);
|
||||
int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
|
||||
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||
|
||||
int sqlite3BtreeCursor(
|
||||
Btree*, /* BTree containing table to open */
|
||||
int iTable, /* Index of root page */
|
||||
int wrFlag, /* 1 for writing. 0 for read-only */
|
||||
int(*)(void*,int,const void*,int,const void*), /* Key comparison function */
|
||||
void*, /* First argument to compare function */
|
||||
BtCursor **ppCursor /* Returned cursor */
|
||||
);
|
||||
|
||||
void sqlite3BtreeSetCompare(
|
||||
BtCursor *,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void*
|
||||
);
|
||||
|
||||
int sqlite3BtreeCloseCursor(BtCursor*);
|
||||
int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
|
||||
int sqlite3BtreeDelete(BtCursor*);
|
||||
int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
|
||||
const void *pData, int nData);
|
||||
int sqlite3BtreeFirst(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeLast(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeNext(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeEof(BtCursor*);
|
||||
int sqlite3BtreeFlags(BtCursor*);
|
||||
int sqlite3BtreePrevious(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
|
||||
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
|
||||
const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
|
||||
const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
|
||||
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
|
||||
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
|
||||
|
||||
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
|
||||
struct Pager *sqlite3BtreePager(Btree*);
|
||||
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
|
||||
void sqlite3BtreeCursorList(Btree*);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3BtreePageDump(Btree*, int, int recursive);
|
||||
#else
|
||||
#define sqlite3BtreePageDump(X,Y,Z) SQLITE_OK
|
||||
#endif
|
||||
|
||||
#endif /* _BTREE_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
** 2005 May 23
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** of user defined functions and collation sequences.
|
||||
**
|
||||
** $Id: callback.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** Invoke the 'collation needed' callback to request a collation sequence
|
||||
** in the database text encoding of name zName, length nName.
|
||||
** If the collation sequence
|
||||
*/
|
||||
static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
|
||||
assert( !db->xCollNeeded || !db->xCollNeeded16 );
|
||||
if( nName<0 ) nName = strlen(zName);
|
||||
if( db->xCollNeeded ){
|
||||
char *zExternal = sqliteStrNDup(zName, nName);
|
||||
if( !zExternal ) return;
|
||||
db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
|
||||
sqliteFree(zExternal);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( db->xCollNeeded16 ){
|
||||
char const *zExternal;
|
||||
sqlite3_value *pTmp = sqlite3GetTransientValue(db);
|
||||
sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
|
||||
zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
|
||||
if( !zExternal ) return;
|
||||
db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called if the collation factory fails to deliver a
|
||||
** collation function in the best encoding but there may be other versions
|
||||
** of this collation function (for other text encodings) available. Use one
|
||||
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
|
||||
** possible.
|
||||
*/
|
||||
static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
|
||||
CollSeq *pColl2;
|
||||
char *z = pColl->zName;
|
||||
int n = strlen(z);
|
||||
int i;
|
||||
static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
|
||||
for(i=0; i<3; i++){
|
||||
pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
|
||||
if( pColl2->xCmp!=0 ){
|
||||
memcpy(pColl, pColl2, sizeof(CollSeq));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is responsible for invoking the collation factory callback
|
||||
** or substituting a collation sequence of a different encoding when the
|
||||
** requested collation sequence is not available in the database native
|
||||
** encoding.
|
||||
**
|
||||
** If it is not NULL, then pColl must point to the database native encoding
|
||||
** collation sequence with name zName, length nName.
|
||||
**
|
||||
** The return value is either the collation sequence to be used in database
|
||||
** db for collation type name zName, length nName, or NULL, if no collation
|
||||
** sequence can be found.
|
||||
*/
|
||||
CollSeq *sqlite3GetCollSeq(
|
||||
sqlite3* db,
|
||||
CollSeq *pColl,
|
||||
const char *zName,
|
||||
int nName
|
||||
){
|
||||
CollSeq *p;
|
||||
|
||||
p = pColl;
|
||||
if( !p ){
|
||||
p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
|
||||
}
|
||||
if( !p || !p->xCmp ){
|
||||
/* No collation sequence of this type for this encoding is registered.
|
||||
** Call the collation factory to see if it can supply us with one.
|
||||
*/
|
||||
callCollNeeded(db, zName, nName);
|
||||
p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0);
|
||||
}
|
||||
if( p && !p->xCmp && synthCollSeq(db, p) ){
|
||||
p = 0;
|
||||
}
|
||||
assert( !p || p->xCmp );
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called on a collation sequence before it is used to
|
||||
** check that it is defined. An undefined collation sequence exists when
|
||||
** a database is loaded that contains references to collation sequences
|
||||
** that have not been defined by sqlite3_create_collation() etc.
|
||||
**
|
||||
** If required, this routine calls the 'collation needed' callback to
|
||||
** request a definition of the collating sequence. If this doesn't work,
|
||||
** an equivalent collating sequence that uses a text encoding different
|
||||
** from the main database is substituted, if one is available.
|
||||
*/
|
||||
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
|
||||
if( pColl ){
|
||||
const char *zName = pColl->zName;
|
||||
CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
|
||||
if( !p ){
|
||||
if( pParse->nErr==0 ){
|
||||
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
|
||||
}
|
||||
pParse->nErr++;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Locate and return an entry from the db.aCollSeq hash table. If the entry
|
||||
** specified by zName and nName is not found and parameter 'create' is
|
||||
** true, then create a new entry. Otherwise return NULL.
|
||||
**
|
||||
** Each pointer stored in the sqlite3.aCollSeq hash table contains an
|
||||
** array of three CollSeq structures. The first is the collation sequence
|
||||
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
|
||||
**
|
||||
** Stored immediately after the three collation sequences is a copy of
|
||||
** the collation sequence name. A pointer to this string is stored in
|
||||
** each collation sequence structure.
|
||||
*/
|
||||
static CollSeq * findCollSeqEntry(
|
||||
sqlite3 *db,
|
||||
const char *zName,
|
||||
int nName,
|
||||
int create
|
||||
){
|
||||
CollSeq *pColl;
|
||||
if( nName<0 ) nName = strlen(zName);
|
||||
pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
|
||||
|
||||
if( 0==pColl && create ){
|
||||
pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
|
||||
if( pColl ){
|
||||
CollSeq *pDel = 0;
|
||||
pColl[0].zName = (char*)&pColl[3];
|
||||
pColl[0].enc = SQLITE_UTF8;
|
||||
pColl[1].zName = (char*)&pColl[3];
|
||||
pColl[1].enc = SQLITE_UTF16LE;
|
||||
pColl[2].zName = (char*)&pColl[3];
|
||||
pColl[2].enc = SQLITE_UTF16BE;
|
||||
memcpy(pColl[0].zName, zName, nName);
|
||||
pColl[0].zName[nName] = 0;
|
||||
pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
|
||||
|
||||
/* If a malloc() failure occured in sqlite3HashInsert(), it will
|
||||
** return the pColl pointer to be deleted (because it wasn't added
|
||||
** to the hash table).
|
||||
*/
|
||||
assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) );
|
||||
sqliteFree(pDel);
|
||||
}
|
||||
}
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** Parameter zName points to a UTF-8 encoded string nName bytes long.
|
||||
** Return the CollSeq* pointer for the collation sequence named zName
|
||||
** for the encoding 'enc' from the database 'db'.
|
||||
**
|
||||
** If the entry specified is not found and 'create' is true, then create a
|
||||
** new entry. Otherwise return NULL.
|
||||
*/
|
||||
CollSeq *sqlite3FindCollSeq(
|
||||
sqlite3 *db,
|
||||
u8 enc,
|
||||
const char *zName,
|
||||
int nName,
|
||||
int create
|
||||
){
|
||||
CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
|
||||
assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
|
||||
if( pColl ) pColl += enc-1;
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** Locate a user function given a name, a number of arguments and a flag
|
||||
** indicating whether the function prefers UTF-16 over UTF-8. Return a
|
||||
** pointer to the FuncDef structure that defines that function, or return
|
||||
** NULL if the function does not exist.
|
||||
**
|
||||
** If the createFlag argument is true, then a new (blank) FuncDef
|
||||
** structure is created and liked into the "db" structure if a
|
||||
** no matching function previously existed. When createFlag is true
|
||||
** and the nArg parameter is -1, then only a function that accepts
|
||||
** any number of arguments will be returned.
|
||||
**
|
||||
** If createFlag is false and nArg is -1, then the first valid
|
||||
** function found is returned. A function is valid if either xFunc
|
||||
** or xStep is non-zero.
|
||||
**
|
||||
** If createFlag is false, then a function with the required name and
|
||||
** number of arguments may be returned even if the eTextRep flag does not
|
||||
** match that requested.
|
||||
*/
|
||||
FuncDef *sqlite3FindFunction(
|
||||
sqlite3 *db, /* An open database */
|
||||
const char *zName, /* Name of the function. Not null-terminated */
|
||||
int nName, /* Number of characters in the name */
|
||||
int nArg, /* Number of arguments. -1 means any number */
|
||||
u8 enc, /* Preferred text encoding */
|
||||
int createFlag /* Create new entry if true and does not otherwise exist */
|
||||
){
|
||||
FuncDef *p; /* Iterator variable */
|
||||
FuncDef *pFirst; /* First function with this name */
|
||||
FuncDef *pBest = 0; /* Best match found so far */
|
||||
int bestmatch = 0;
|
||||
|
||||
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
if( nArg<-1 ) nArg = -1;
|
||||
|
||||
pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
|
||||
for(p=pFirst; p; p=p->pNext){
|
||||
/* During the search for the best function definition, bestmatch is set
|
||||
** as follows to indicate the quality of the match with the definition
|
||||
** pointed to by pBest:
|
||||
**
|
||||
** 0: pBest is NULL. No match has been found.
|
||||
** 1: A variable arguments function that prefers UTF-8 when a UTF-16
|
||||
** encoding is requested, or vice versa.
|
||||
** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
|
||||
** requested, or vice versa.
|
||||
** 3: A variable arguments function using the same text encoding.
|
||||
** 4: A function with the exact number of arguments requested that
|
||||
** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
|
||||
** 5: A function with the exact number of arguments requested that
|
||||
** prefers UTF-16LE when UTF-16BE is requested, or vice versa.
|
||||
** 6: An exact match.
|
||||
**
|
||||
** A larger value of 'matchqual' indicates a more desirable match.
|
||||
*/
|
||||
if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
|
||||
int match = 1; /* Quality of this match */
|
||||
if( p->nArg==nArg || nArg==-1 ){
|
||||
match = 4;
|
||||
}
|
||||
if( enc==p->iPrefEnc ){
|
||||
match += 2;
|
||||
}
|
||||
else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
|
||||
(enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
|
||||
match += 1;
|
||||
}
|
||||
|
||||
if( match>bestmatch ){
|
||||
pBest = p;
|
||||
bestmatch = match;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the createFlag parameter is true, and the seach did not reveal an
|
||||
** exact match for the name, number of arguments and encoding, then add a
|
||||
** new entry to the hash table and return it.
|
||||
*/
|
||||
if( createFlag && bestmatch<6 &&
|
||||
(pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
|
||||
pBest->nArg = nArg;
|
||||
pBest->pNext = pFirst;
|
||||
pBest->zName = (char*)&pBest[1];
|
||||
pBest->iPrefEnc = enc;
|
||||
memcpy(pBest->zName, zName, nName);
|
||||
pBest->zName[nName] = 0;
|
||||
if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
|
||||
sqliteFree(pBest);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
|
||||
return pBest;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
# don't want the 32 in the shared library name
|
||||
SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
|
||||
|
||||
RES = $(OBJDIR)/sqlite.res
|
||||
RESNAME = sqlite.rc
|
||||
|
||||
|
||||
else
|
||||
|
||||
ifeq ($(OS_ARCH), BeOS)
|
||||
EXTRA_SHARED_LIBS += -lbe
|
||||
endif
|
||||
|
||||
|
||||
CFLAGS += -DHAVE_USLEEP=1
|
||||
|
||||
ifeq ($(OS_TARGET),SunOS)
|
||||
# The -R '$ORIGIN' linker option instructs this library to search for its
|
||||
# dependencies in the same directory where it resides.
|
||||
MKSHLIB += -R '$$ORIGIN'
|
||||
endif
|
||||
|
||||
endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,447 +0,0 @@
|
||||
/*
|
||||
** 2001 September 15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains C code routines that are called by the parser
|
||||
** in order to generate code for DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** Look up every table that is named in pSrc. If any table is not found,
|
||||
** add an error message to pParse->zErrMsg and return NULL. If all tables
|
||||
** are found, return a pointer to the last table.
|
||||
*/
|
||||
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
Table *pTab = 0;
|
||||
int i;
|
||||
struct SrcList_item *pItem;
|
||||
for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
|
||||
pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
|
||||
sqlite3DeleteTable(pParse->db, pItem->pTab);
|
||||
pItem->pTab = pTab;
|
||||
if( pTab ){
|
||||
pTab->nRef++;
|
||||
}
|
||||
}
|
||||
return pTab;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to make sure the given table is writable. If it is not
|
||||
** writable, generate an error message and return 1. If it is
|
||||
** writable return 0;
|
||||
*/
|
||||
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
|
||||
&& pParse->nested==0 ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
|
||||
return 1;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
if( !viewOk && pTab->pSelect ){
|
||||
sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code that will open a table for reading.
|
||||
*/
|
||||
void sqlite3OpenTableForReading(
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
int iCur, /* The cursor number of the table */
|
||||
Table *pTab /* The table to be opened */
|
||||
){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
VdbeComment((v, "# %s", pTab->zName));
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Generate code for a DELETE FROM statement.
|
||||
**
|
||||
** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
|
||||
** \________/ \________________/
|
||||
** pTabList pWhere
|
||||
*/
|
||||
void sqlite3DeleteFrom(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* The table from which we should delete things */
|
||||
Expr *pWhere /* The WHERE clause. May be null */
|
||||
){
|
||||
Vdbe *v; /* The virtual database engine */
|
||||
Table *pTab; /* The table from which records will be deleted */
|
||||
const char *zDb; /* Name of database holding pTab */
|
||||
int end, addr = 0; /* A couple addresses of generated code */
|
||||
int i; /* Loop counter */
|
||||
WhereInfo *pWInfo; /* Information about the WHERE clause */
|
||||
Index *pIdx; /* For looping over indices of the table */
|
||||
int iCur; /* VDBE Cursor number for pTab */
|
||||
sqlite3 *db; /* Main database structure */
|
||||
AuthContext sContext; /* Authorization context */
|
||||
int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */
|
||||
NameContext sNC; /* Name context to resolve expressions in */
|
||||
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
int isView; /* True if attempting to delete from a view */
|
||||
int triggers_exist = 0; /* True if any triggers exist */
|
||||
#endif
|
||||
|
||||
sContext.pParse = 0;
|
||||
if( pParse->nErr || sqlite3_malloc_failed ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
db = pParse->db;
|
||||
assert( pTabList->nSrc==1 );
|
||||
|
||||
/* Locate the table which we want to delete. This table has to be
|
||||
** put in an SrcList structure because some of the subroutines we
|
||||
** will be calling are designed to work with multiple tables and expect
|
||||
** an SrcList* parameter instead of just a Table* parameter.
|
||||
*/
|
||||
pTab = sqlite3SrcListLookup(pParse, pTabList);
|
||||
if( pTab==0 ) goto delete_from_cleanup;
|
||||
|
||||
/* Figure out if we have any triggers and if the table being
|
||||
** deleted from is a view
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
|
||||
isView = pTab->pSelect!=0;
|
||||
#else
|
||||
# define triggers_exist 0
|
||||
# define isView 0
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_VIEW
|
||||
# undef isView
|
||||
# define isView 0
|
||||
#endif
|
||||
|
||||
if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
assert( pTab->iDb<db->nDb );
|
||||
zDb = db->aDb[pTab->iDb].zName;
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
|
||||
/* If pTab is really a view, make sure it has been initialized.
|
||||
*/
|
||||
if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
|
||||
/* Allocate a cursor used to store the old.* data for a trigger.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
oldIdx = pParse->nTab++;
|
||||
}
|
||||
|
||||
/* Resolve the column names in the WHERE clause.
|
||||
*/
|
||||
assert( pTabList->nSrc==1 );
|
||||
iCur = pTabList->a[0].iCursor = pParse->nTab++;
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
sNC.pParse = pParse;
|
||||
sNC.pSrcList = pTabList;
|
||||
if( sqlite3ExprResolveNames(&sNC, pWhere) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
|
||||
/* Start the view context
|
||||
*/
|
||||
if( isView ){
|
||||
sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
|
||||
}
|
||||
|
||||
/* Begin generating code.
|
||||
*/
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
|
||||
sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb);
|
||||
|
||||
/* If we are trying to delete from a view, construct that view into
|
||||
** a temporary table.
|
||||
*/
|
||||
if( isView ){
|
||||
Select *pView = sqlite3SelectDup(pTab->pSelect);
|
||||
sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
|
||||
sqlite3SelectDelete(pView);
|
||||
}
|
||||
|
||||
/* Initialize the counter of the number of rows deleted, if
|
||||
** we are counting rows.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
** It is easier just to erase the whole table. Note, however, that
|
||||
** this means that the row change count will be incorrect.
|
||||
*/
|
||||
if( pWhere==0 && !triggers_exist ){
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
/* If counting rows deleted, just count the total number of
|
||||
** entries in the table. */
|
||||
int endOfLoop = sqlite3VdbeMakeLabel(v);
|
||||
int addr;
|
||||
if( !isView ){
|
||||
sqlite3OpenTableForReading(v, iCur, pTab);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
|
||||
addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
|
||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
if( !isView ){
|
||||
sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The usual case: There is a WHERE clause so we have to scan through
|
||||
** the table and pick which records to delete.
|
||||
*/
|
||||
else{
|
||||
/* Ensure all required collation sequences are available. */
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin the database scan
|
||||
*/
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
|
||||
/* Remember the rowid of every item to be deleted.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* End the database scan loop.
|
||||
*/
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
|
||||
/* Open the pseudo-table used to store OLD if there are triggers.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
||||
}
|
||||
|
||||
/* Delete every item whose key was written to the list during the
|
||||
** database scan. We have to delete items after the scan is complete
|
||||
** because deleting an item can change the scan order.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
end = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* This is the beginning of the delete loop when there are
|
||||
** row triggers.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
||||
if( !isView ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqlite3OpenTableForReading(v, iCur, pTab);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
|
||||
if( !isView ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
|
||||
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
|
||||
-1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||
addr);
|
||||
}
|
||||
|
||||
if( !isView ){
|
||||
/* Open cursors for the table we are deleting from and all its
|
||||
** indices. If there are row triggers, this happens inside the
|
||||
** OP_ListRead loop because the cursor have to all be closed
|
||||
** before the trigger fires. If there are no row triggers, the
|
||||
** cursors are opened only once on the outside the loop.
|
||||
*/
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
|
||||
|
||||
/* This is the beginning of the delete loop when there are no
|
||||
** row triggers */
|
||||
if( !triggers_exist ){
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
||||
}
|
||||
|
||||
/* Delete the row */
|
||||
sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
|
||||
}
|
||||
|
||||
/* If there are row triggers, close all cursors then invoke
|
||||
** the AFTER triggers
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
if( !isView ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
|
||||
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||
addr);
|
||||
}
|
||||
|
||||
/* End of the delete loop */
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqlite3VdbeResolveLabel(v, end);
|
||||
sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
|
||||
/* Close the cursors after the loop if there are no row triggers */
|
||||
if( !triggers_exist ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of rows that were deleted. If this routine is
|
||||
** generating code because of a call to sqlite3NestedParse(), do not
|
||||
** invoke the callback function.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
|
||||
}
|
||||
|
||||
delete_from_cleanup:
|
||||
sqlite3AuthContextPop(&sContext);
|
||||
sqlite3SrcListDelete(pTabList);
|
||||
sqlite3ExprDelete(pWhere);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine generates VDBE code that causes a single row of a
|
||||
** single table to be deleted.
|
||||
**
|
||||
** The VDBE must be in a particular state when this routine is called.
|
||||
** These are the requirements:
|
||||
**
|
||||
** 1. A read/write cursor pointing to pTab, the table containing the row
|
||||
** to be deleted, must be opened as cursor number "base".
|
||||
**
|
||||
** 2. Read/write cursors for all indices of pTab must be open as
|
||||
** cursor number base+i for the i-th index.
|
||||
**
|
||||
** 3. The record number of the row to be deleted must be on the top
|
||||
** of the stack.
|
||||
**
|
||||
** This routine pops the top of the stack to remove the record number
|
||||
** and then generates code to remove both the table record and all index
|
||||
** entries that point to that record.
|
||||
*/
|
||||
void sqlite3GenerateRowDelete(
|
||||
sqlite3 *db, /* The database containing the index */
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
Table *pTab, /* Table containing the row to be deleted */
|
||||
int iCur, /* Cursor number for the table */
|
||||
int count /* Increment the row change counter */
|
||||
){
|
||||
int addr;
|
||||
addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
|
||||
sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
|
||||
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine generates VDBE code that causes the deletion of all
|
||||
** index entries associated with a single row of a single table.
|
||||
**
|
||||
** The VDBE must be in a particular state when this routine is called.
|
||||
** These are the requirements:
|
||||
**
|
||||
** 1. A read/write cursor pointing to pTab, the table containing the row
|
||||
** to be deleted, must be opened as cursor number "iCur".
|
||||
**
|
||||
** 2. Read/write cursors for all indices of pTab must be open as
|
||||
** cursor number iCur+i for the i-th index.
|
||||
**
|
||||
** 3. The "iCur" cursor must be pointing to the row that is to be
|
||||
** deleted.
|
||||
*/
|
||||
void sqlite3GenerateRowIndexDelete(
|
||||
sqlite3 *db, /* The database containing the index */
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
Table *pTab, /* Table containing the row to be deleted */
|
||||
int iCur, /* Cursor number for the table */
|
||||
char *aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
|
||||
){
|
||||
int i;
|
||||
Index *pIdx;
|
||||
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
|
||||
sqlite3GenerateIndexKey(v, pIdx, iCur);
|
||||
sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate code that will assemble an index key and put it on the top
|
||||
** of the tack. The key with be for index pIdx which is an index on pTab.
|
||||
** iCur is the index of a cursor open on the pTab table and pointing to
|
||||
** the entry that needs indexing.
|
||||
*/
|
||||
void sqlite3GenerateIndexKey(
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
Index *pIdx, /* The index for which to generate a key */
|
||||
int iCur /* Cursor number for the pIdx->pTable table */
|
||||
){
|
||||
int j;
|
||||
Table *pTab = pIdx->pTable;
|
||||
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||
for(j=0; j<pIdx->nColumn; j++){
|
||||
int idx = pIdx->aiColumn[j];
|
||||
if( idx==pTab->iPKey ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, j, 0);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
|
||||
sqlite3ColumnDefault(v, pTab, idx);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
|
||||
sqlite3IndexAffinityStr(v, pIdx);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,387 +0,0 @@
|
||||
/*
|
||||
** 2001 September 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the implementation of generic hash-tables
|
||||
** used in SQLite.
|
||||
**
|
||||
** $Id: hash.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* Turn bulk memory into a hash table object by initializing the
|
||||
** fields of the Hash structure.
|
||||
**
|
||||
** "pNew" is a pointer to the hash table that is to be initialized.
|
||||
** keyClass is one of the constants SQLITE_HASH_INT, SQLITE_HASH_POINTER,
|
||||
** SQLITE_HASH_BINARY, or SQLITE_HASH_STRING. The value of keyClass
|
||||
** determines what kind of key the hash table will use. "copyKey" is
|
||||
** true if the hash table should make its own private copy of keys and
|
||||
** false if it should just use the supplied pointer. CopyKey only makes
|
||||
** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
|
||||
** for other key classes.
|
||||
*/
|
||||
void sqlite3HashInit(Hash *pNew, int keyClass, int copyKey){
|
||||
assert( pNew!=0 );
|
||||
assert( keyClass>=SQLITE_HASH_STRING && keyClass<=SQLITE_HASH_BINARY );
|
||||
pNew->keyClass = keyClass;
|
||||
#if 0
|
||||
if( keyClass==SQLITE_HASH_POINTER || keyClass==SQLITE_HASH_INT ) copyKey = 0;
|
||||
#endif
|
||||
pNew->copyKey = copyKey;
|
||||
pNew->first = 0;
|
||||
pNew->count = 0;
|
||||
pNew->htsize = 0;
|
||||
pNew->ht = 0;
|
||||
}
|
||||
|
||||
/* Remove all entries from a hash table. Reclaim all memory.
|
||||
** Call this routine to delete a hash table or to reset a hash table
|
||||
** to the empty state.
|
||||
*/
|
||||
void sqlite3HashClear(Hash *pH){
|
||||
HashElem *elem; /* For looping over all elements of the table */
|
||||
|
||||
assert( pH!=0 );
|
||||
elem = pH->first;
|
||||
pH->first = 0;
|
||||
if( pH->ht ) sqliteFree(pH->ht);
|
||||
pH->ht = 0;
|
||||
pH->htsize = 0;
|
||||
while( elem ){
|
||||
HashElem *next_elem = elem->next;
|
||||
if( pH->copyKey && elem->pKey ){
|
||||
sqliteFree(elem->pKey);
|
||||
}
|
||||
sqliteFree(elem);
|
||||
elem = next_elem;
|
||||
}
|
||||
pH->count = 0;
|
||||
}
|
||||
|
||||
#if 0 /* NOT USED */
|
||||
/*
|
||||
** Hash and comparison functions when the mode is SQLITE_HASH_INT
|
||||
*/
|
||||
static int intHash(const void *pKey, int nKey){
|
||||
return nKey ^ (nKey<<8) ^ (nKey>>8);
|
||||
}
|
||||
static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
return n2 - n1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* NOT USED */
|
||||
/*
|
||||
** Hash and comparison functions when the mode is SQLITE_HASH_POINTER
|
||||
*/
|
||||
static int ptrHash(const void *pKey, int nKey){
|
||||
uptr x = Addr(pKey);
|
||||
return x ^ (x<<8) ^ (x>>8);
|
||||
}
|
||||
static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
if( pKey1==pKey2 ) return 0;
|
||||
if( pKey1<pKey2 ) return -1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Hash and comparison functions when the mode is SQLITE_HASH_STRING
|
||||
*/
|
||||
static int strHash(const void *pKey, int nKey){
|
||||
const char *z = (const char *)pKey;
|
||||
int h = 0;
|
||||
if( nKey<=0 ) nKey = strlen(z);
|
||||
while( nKey > 0 ){
|
||||
h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
|
||||
nKey--;
|
||||
}
|
||||
return h & 0x7fffffff;
|
||||
}
|
||||
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
if( n1!=n2 ) return 1;
|
||||
return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Hash and comparison functions when the mode is SQLITE_HASH_BINARY
|
||||
*/
|
||||
static int binHash(const void *pKey, int nKey){
|
||||
int h = 0;
|
||||
const char *z = (const char *)pKey;
|
||||
while( nKey-- > 0 ){
|
||||
h = (h<<3) ^ h ^ *(z++);
|
||||
}
|
||||
return h & 0x7fffffff;
|
||||
}
|
||||
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
if( n1!=n2 ) return 1;
|
||||
return memcmp(pKey1,pKey2,n1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the appropriate hash function given the key class.
|
||||
**
|
||||
** The C syntax in this function definition may be unfamilar to some
|
||||
** programmers, so we provide the following additional explanation:
|
||||
**
|
||||
** The name of the function is "hashFunction". The function takes a
|
||||
** single parameter "keyClass". The return value of hashFunction()
|
||||
** is a pointer to another function. Specifically, the return value
|
||||
** of hashFunction() is a pointer to a function that takes two parameters
|
||||
** with types "const void*" and "int" and returns an "int".
|
||||
*/
|
||||
static int (*hashFunction(int keyClass))(const void*,int){
|
||||
#if 0 /* HASH_INT and HASH_POINTER are never used */
|
||||
switch( keyClass ){
|
||||
case SQLITE_HASH_INT: return &intHash;
|
||||
case SQLITE_HASH_POINTER: return &ptrHash;
|
||||
case SQLITE_HASH_STRING: return &strHash;
|
||||
case SQLITE_HASH_BINARY: return &binHash;;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
if( keyClass==SQLITE_HASH_STRING ){
|
||||
return &strHash;
|
||||
}else{
|
||||
assert( keyClass==SQLITE_HASH_BINARY );
|
||||
return &binHash;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the appropriate hash function given the key class.
|
||||
**
|
||||
** For help in interpreted the obscure C code in the function definition,
|
||||
** see the header comment on the previous function.
|
||||
*/
|
||||
static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
|
||||
#if 0 /* HASH_INT and HASH_POINTER are never used */
|
||||
switch( keyClass ){
|
||||
case SQLITE_HASH_INT: return &intCompare;
|
||||
case SQLITE_HASH_POINTER: return &ptrCompare;
|
||||
case SQLITE_HASH_STRING: return &strCompare;
|
||||
case SQLITE_HASH_BINARY: return &binCompare;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
if( keyClass==SQLITE_HASH_STRING ){
|
||||
return &strCompare;
|
||||
}else{
|
||||
assert( keyClass==SQLITE_HASH_BINARY );
|
||||
return &binCompare;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Link an element into the hash table
|
||||
*/
|
||||
static void insertElement(
|
||||
Hash *pH, /* The complete hash table */
|
||||
struct _ht *pEntry, /* The entry into which pNew is inserted */
|
||||
HashElem *pNew /* The element to be inserted */
|
||||
){
|
||||
HashElem *pHead; /* First element already in pEntry */
|
||||
pHead = pEntry->chain;
|
||||
if( pHead ){
|
||||
pNew->next = pHead;
|
||||
pNew->prev = pHead->prev;
|
||||
if( pHead->prev ){ pHead->prev->next = pNew; }
|
||||
else { pH->first = pNew; }
|
||||
pHead->prev = pNew;
|
||||
}else{
|
||||
pNew->next = pH->first;
|
||||
if( pH->first ){ pH->first->prev = pNew; }
|
||||
pNew->prev = 0;
|
||||
pH->first = pNew;
|
||||
}
|
||||
pEntry->count++;
|
||||
pEntry->chain = pNew;
|
||||
}
|
||||
|
||||
|
||||
/* Resize the hash table so that it cantains "new_size" buckets.
|
||||
** "new_size" must be a power of 2. The hash table might fail
|
||||
** to resize if sqliteMalloc() fails.
|
||||
*/
|
||||
static void rehash(Hash *pH, int new_size){
|
||||
struct _ht *new_ht; /* The new hash table */
|
||||
HashElem *elem, *next_elem; /* For looping over existing elements */
|
||||
int (*xHash)(const void*,int); /* The hash function */
|
||||
|
||||
assert( (new_size & (new_size-1))==0 );
|
||||
new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
|
||||
if( new_ht==0 ) return;
|
||||
if( pH->ht ) sqliteFree(pH->ht);
|
||||
pH->ht = new_ht;
|
||||
pH->htsize = new_size;
|
||||
xHash = hashFunction(pH->keyClass);
|
||||
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
|
||||
int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
|
||||
next_elem = elem->next;
|
||||
insertElement(pH, &new_ht[h], elem);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function (for internal use only) locates an element in an
|
||||
** hash table that matches the given key. The hash for this key has
|
||||
** already been computed and is passed as the 4th parameter.
|
||||
*/
|
||||
static HashElem *findElementGivenHash(
|
||||
const Hash *pH, /* The pH to be searched */
|
||||
const void *pKey, /* The key we are searching for */
|
||||
int nKey,
|
||||
int h /* The hash for this key. */
|
||||
){
|
||||
HashElem *elem; /* Used to loop thru the element list */
|
||||
int count; /* Number of elements left to test */
|
||||
int (*xCompare)(const void*,int,const void*,int); /* comparison function */
|
||||
|
||||
if( pH->ht ){
|
||||
struct _ht *pEntry = &pH->ht[h];
|
||||
elem = pEntry->chain;
|
||||
count = pEntry->count;
|
||||
xCompare = compareFunction(pH->keyClass);
|
||||
while( count-- && elem ){
|
||||
if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
|
||||
return elem;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove a single entry from the hash table given a pointer to that
|
||||
** element and a hash on the element's key.
|
||||
*/
|
||||
static void removeElementGivenHash(
|
||||
Hash *pH, /* The pH containing "elem" */
|
||||
HashElem* elem, /* The element to be removed from the pH */
|
||||
int h /* Hash value for the element */
|
||||
){
|
||||
struct _ht *pEntry;
|
||||
if( elem->prev ){
|
||||
elem->prev->next = elem->next;
|
||||
}else{
|
||||
pH->first = elem->next;
|
||||
}
|
||||
if( elem->next ){
|
||||
elem->next->prev = elem->prev;
|
||||
}
|
||||
pEntry = &pH->ht[h];
|
||||
if( pEntry->chain==elem ){
|
||||
pEntry->chain = elem->next;
|
||||
}
|
||||
pEntry->count--;
|
||||
if( pEntry->count<=0 ){
|
||||
pEntry->chain = 0;
|
||||
}
|
||||
if( pH->copyKey && elem->pKey ){
|
||||
sqliteFree(elem->pKey);
|
||||
}
|
||||
sqliteFree( elem );
|
||||
pH->count--;
|
||||
}
|
||||
|
||||
/* Attempt to locate an element of the hash table pH with a key
|
||||
** that matches pKey,nKey. Return the data for this element if it is
|
||||
** found, or NULL if there is no match.
|
||||
*/
|
||||
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
|
||||
int h; /* A hash on key */
|
||||
HashElem *elem; /* The element that matches key */
|
||||
int (*xHash)(const void*,int); /* The hash function */
|
||||
|
||||
if( pH==0 || pH->ht==0 ) return 0;
|
||||
xHash = hashFunction(pH->keyClass);
|
||||
assert( xHash!=0 );
|
||||
h = (*xHash)(pKey,nKey);
|
||||
assert( (pH->htsize & (pH->htsize-1))==0 );
|
||||
elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
|
||||
return elem ? elem->data : 0;
|
||||
}
|
||||
|
||||
/* Insert an element into the hash table pH. The key is pKey,nKey
|
||||
** and the data is "data".
|
||||
**
|
||||
** If no element exists with a matching key, then a new
|
||||
** element is created. A copy of the key is made if the copyKey
|
||||
** flag is set. NULL is returned.
|
||||
**
|
||||
** If another element already exists with the same key, then the
|
||||
** new data replaces the old data and the old data is returned.
|
||||
** The key is not copied in this instance. If a malloc fails, then
|
||||
** the new data is returned and the hash table is unchanged.
|
||||
**
|
||||
** If the "data" parameter to this function is NULL, then the
|
||||
** element corresponding to "key" is removed from the hash table.
|
||||
*/
|
||||
void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
|
||||
int hraw; /* Raw hash value of the key */
|
||||
int h; /* the hash of the key modulo hash table size */
|
||||
HashElem *elem; /* Used to loop thru the element list */
|
||||
HashElem *new_elem; /* New element added to the pH */
|
||||
int (*xHash)(const void*,int); /* The hash function */
|
||||
|
||||
assert( pH!=0 );
|
||||
xHash = hashFunction(pH->keyClass);
|
||||
assert( xHash!=0 );
|
||||
hraw = (*xHash)(pKey, nKey);
|
||||
assert( (pH->htsize & (pH->htsize-1))==0 );
|
||||
h = hraw & (pH->htsize-1);
|
||||
elem = findElementGivenHash(pH,pKey,nKey,h);
|
||||
if( elem ){
|
||||
void *old_data = elem->data;
|
||||
if( data==0 ){
|
||||
removeElementGivenHash(pH,elem,h);
|
||||
}else{
|
||||
elem->data = data;
|
||||
}
|
||||
return old_data;
|
||||
}
|
||||
if( data==0 ) return 0;
|
||||
new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
|
||||
if( new_elem==0 ) return data;
|
||||
if( pH->copyKey && pKey!=0 ){
|
||||
new_elem->pKey = sqliteMallocRaw( nKey );
|
||||
if( new_elem->pKey==0 ){
|
||||
sqliteFree(new_elem);
|
||||
return data;
|
||||
}
|
||||
memcpy((void*)new_elem->pKey, pKey, nKey);
|
||||
}else{
|
||||
new_elem->pKey = (void*)pKey;
|
||||
}
|
||||
new_elem->nKey = nKey;
|
||||
pH->count++;
|
||||
if( pH->htsize==0 ){
|
||||
rehash(pH,8);
|
||||
if( pH->htsize==0 ){
|
||||
pH->count = 0;
|
||||
sqliteFree(new_elem);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
if( pH->count > pH->htsize ){
|
||||
rehash(pH,pH->htsize*2);
|
||||
}
|
||||
assert( pH->htsize>0 );
|
||||
assert( (pH->htsize & (pH->htsize-1))==0 );
|
||||
h = hraw & (pH->htsize-1);
|
||||
insertElement(pH, &pH->ht[h], new_elem);
|
||||
new_elem->data = data;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
** 2001 September 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** used in SQLite.
|
||||
**
|
||||
** $Id: hash.h,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_HASH_H_
|
||||
#define _SQLITE_HASH_H_
|
||||
|
||||
/* Forward declarations of structures. */
|
||||
typedef struct Hash Hash;
|
||||
typedef struct HashElem HashElem;
|
||||
|
||||
/* A complete hash table is an instance of the following structure.
|
||||
** The internals of this structure are intended to be opaque -- client
|
||||
** code should not attempt to access or modify the fields of this structure
|
||||
** directly. Change this structure only by using the routines below.
|
||||
** However, many of the "procedures" and "functions" for modifying and
|
||||
** accessing this structure are really macros, so we can't really make
|
||||
** this structure opaque.
|
||||
*/
|
||||
struct Hash {
|
||||
char keyClass; /* SQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
|
||||
char copyKey; /* True if copy of key made on insert */
|
||||
int count; /* Number of entries in this table */
|
||||
HashElem *first; /* The first element of the array */
|
||||
int htsize; /* Number of buckets in the hash table */
|
||||
struct _ht { /* the hash table */
|
||||
int count; /* Number of entries with this hash */
|
||||
HashElem *chain; /* Pointer to first entry with this hash */
|
||||
} *ht;
|
||||
};
|
||||
|
||||
/* Each element in the hash table is an instance of the following
|
||||
** structure. All elements are stored on a single doubly-linked list.
|
||||
**
|
||||
** Again, this structure is intended to be opaque, but it can't really
|
||||
** be opaque because it is used by macros.
|
||||
*/
|
||||
struct HashElem {
|
||||
HashElem *next, *prev; /* Next and previous elements in the table */
|
||||
void *data; /* Data associated with this element */
|
||||
void *pKey; int nKey; /* Key associated with this element */
|
||||
};
|
||||
|
||||
/*
|
||||
** There are 4 different modes of operation for a hash table:
|
||||
**
|
||||
** SQLITE_HASH_INT nKey is used as the key and pKey is ignored.
|
||||
**
|
||||
** SQLITE_HASH_POINTER pKey is used as the key and nKey is ignored.
|
||||
**
|
||||
** SQLITE_HASH_STRING pKey points to a string that is nKey bytes long
|
||||
** (including the null-terminator, if any). Case
|
||||
** is ignored in comparisons.
|
||||
**
|
||||
** SQLITE_HASH_BINARY pKey points to binary data nKey bytes long.
|
||||
** memcmp() is used to compare keys.
|
||||
**
|
||||
** A copy of the key is made for SQLITE_HASH_STRING and SQLITE_HASH_BINARY
|
||||
** if the copyKey parameter to HashInit is 1.
|
||||
*/
|
||||
/* #define SQLITE_HASH_INT 1 // NOT USED */
|
||||
/* #define SQLITE_HASH_POINTER 2 // NOT USED */
|
||||
#define SQLITE_HASH_STRING 3
|
||||
#define SQLITE_HASH_BINARY 4
|
||||
|
||||
/*
|
||||
** Access routines. To delete, insert a NULL pointer.
|
||||
*/
|
||||
void sqlite3HashInit(Hash*, int keytype, int copyKey);
|
||||
void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
|
||||
void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
|
||||
void sqlite3HashClear(Hash*);
|
||||
|
||||
/*
|
||||
** Macros for looping over all elements of a hash table. The idiom is
|
||||
** like this:
|
||||
**
|
||||
** Hash h;
|
||||
** HashElem *p;
|
||||
** ...
|
||||
** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
|
||||
** SomeStructure *pData = sqliteHashData(p);
|
||||
** // do something with pData
|
||||
** }
|
||||
*/
|
||||
#define sqliteHashFirst(H) ((H)->first)
|
||||
#define sqliteHashNext(E) ((E)->next)
|
||||
#define sqliteHashData(E) ((E)->data)
|
||||
#define sqliteHashKey(E) ((E)->pKey)
|
||||
#define sqliteHashKeysize(E) ((E)->nKey)
|
||||
|
||||
/*
|
||||
** Number of entries in a hash table
|
||||
*/
|
||||
#define sqliteHashCount(H) ((H)->count)
|
||||
|
||||
#endif /* _SQLITE_HASH_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
/* Hash score: 153 */
|
||||
static int keywordCode(const char *z, int n){
|
||||
static const char zText[515] =
|
||||
"ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER"
|
||||
"AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYAND"
|
||||
"EFERRABLEXCLUSIVEXISTSTATEMENTATTACHAVINGLOBEFOREIGNOREINDEXAUTOINCREMENT"
|
||||
"BEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETECASECOLLATECOLUMN"
|
||||
"COMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP"
|
||||
"RAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMITFROMFULLGROUPDATE"
|
||||
"IMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDEREPLACEOUTERESTRICT"
|
||||
"RIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE";
|
||||
static const unsigned char aHash[127] = {
|
||||
89, 79, 102, 88, 0, 4, 0, 0, 109, 0, 75, 0, 0,
|
||||
92, 43, 0, 90, 0, 101, 104, 94, 0, 0, 10, 0, 0,
|
||||
108, 0, 105, 100, 0, 28, 47, 0, 40, 0, 0, 63, 69,
|
||||
0, 62, 19, 0, 0, 32, 81, 0, 103, 72, 0, 0, 34,
|
||||
0, 60, 33, 0, 8, 0, 110, 37, 12, 0, 76, 39, 25,
|
||||
64, 0, 0, 31, 80, 52, 30, 49, 20, 86, 0, 35, 0,
|
||||
73, 26, 0, 70, 0, 0, 0, 0, 46, 65, 22, 85, 29,
|
||||
67, 84, 0, 1, 0, 9, 98, 57, 18, 0, 107, 74, 96,
|
||||
53, 6, 83, 0, 0, 48, 91, 0, 99, 0, 68, 0, 0,
|
||||
15, 0, 111, 50, 55, 0, 2, 54, 0, 106,
|
||||
};
|
||||
static const unsigned char aNext[111] = {
|
||||
0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0,
|
||||
0, 11, 0, 0, 0, 7, 0, 5, 13, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0,
|
||||
0, 16, 0, 23, 51, 0, 0, 0, 0, 44, 58, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 71, 41, 0, 0, 24, 59, 21,
|
||||
0, 78, 0, 66, 0, 0, 82, 45, 0, 0, 0, 0, 0,
|
||||
0, 0, 38, 93, 95, 0, 0, 97, 0, 14, 27, 77, 0,
|
||||
56, 87, 0, 36, 0, 61, 0,
|
||||
};
|
||||
static const unsigned char aLen[111] = {
|
||||
5, 5, 4, 4, 9, 2, 3, 8, 2, 6, 4, 3, 7,
|
||||
11, 2, 7, 5, 5, 4, 5, 3, 5, 10, 6, 4, 6,
|
||||
7, 6, 7, 9, 3, 3, 10, 9, 6, 9, 6, 6, 4,
|
||||
6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6, 7,
|
||||
3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 7, 6, 6,
|
||||
8, 10, 9, 6, 5, 12, 12, 17, 6, 5, 4, 6, 8,
|
||||
2, 4, 7, 4, 5, 4, 4, 5, 6, 9, 6, 7, 4,
|
||||
2, 6, 3, 6, 4, 5, 7, 5, 8, 5, 8, 3, 4,
|
||||
5, 6, 5, 6, 6, 4, 5,
|
||||
};
|
||||
static const unsigned short int aOffset[111] = {
|
||||
0, 4, 7, 10, 10, 14, 19, 21, 26, 27, 32, 34, 36,
|
||||
42, 51, 52, 57, 61, 65, 67, 71, 74, 78, 86, 91, 94,
|
||||
99, 105, 108, 113, 118, 122, 124, 133, 141, 146, 155, 160, 165,
|
||||
168, 170, 170, 174, 178, 180, 185, 187, 189, 198, 201, 205, 211,
|
||||
217, 217, 220, 223, 227, 229, 230, 234, 241, 247, 251, 258, 264,
|
||||
270, 278, 285, 294, 300, 305, 317, 317, 333, 337, 342, 346, 352,
|
||||
353, 360, 363, 370, 373, 378, 382, 386, 389, 395, 404, 410, 417,
|
||||
420, 420, 423, 426, 432, 436, 440, 447, 451, 459, 464, 472, 474,
|
||||
478, 483, 489, 494, 500, 506, 509,
|
||||
};
|
||||
static const unsigned char aCode[111] = {
|
||||
TK_ABORT, TK_TABLE, TK_JOIN_KW, TK_TEMP, TK_TEMP,
|
||||
TK_OR, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT,
|
||||
TK_THEN, TK_END, TK_DEFAULT, TK_TRANSACTION,TK_ON,
|
||||
TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EACH, TK_CHECK,
|
||||
TK_KEY, TK_AFTER, TK_REFERENCES, TK_ESCAPE, TK_ELSE,
|
||||
TK_EXCEPT, TK_TRIGGER, TK_LIKE_KW, TK_EXPLAIN, TK_INITIALLY,
|
||||
TK_ALL, TK_AND, TK_DEFERRABLE, TK_EXCLUSIVE, TK_EXISTS,
|
||||
TK_STATEMENT, TK_ATTACH, TK_HAVING, TK_LIKE_KW, TK_BEFORE,
|
||||
TK_FOR, TK_FOREIGN, TK_IGNORE, TK_REINDEX, TK_INDEX,
|
||||
TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, TK_JOIN_KW,
|
||||
TK_RENAME, TK_BETWEEN, TK_NOT, TK_NOTNULL, TK_NULL,
|
||||
TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED,
|
||||
TK_DELETE, TK_CASE, TK_COLLATE, TK_COLUMNKW, TK_COMMIT,
|
||||
TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, TK_CREATE, TK_JOIN_KW,
|
||||
TK_CTIME_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRAGMA, TK_MATCH,
|
||||
TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS, TK_DROP,
|
||||
TK_PRIMARY, TK_FAIL, TK_LIMIT, TK_FROM, TK_JOIN_KW,
|
||||
TK_GROUP, TK_UPDATE, TK_IMMEDIATE, TK_INSERT, TK_INSTEAD,
|
||||
TK_INTO, TK_OF, TK_OFFSET, TK_SET, TK_ISNULL,
|
||||
TK_JOIN, TK_ORDER, TK_REPLACE, TK_JOIN_KW, TK_RESTRICT,
|
||||
TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION,
|
||||
TK_UNIQUE, TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW,
|
||||
TK_WHERE,
|
||||
};
|
||||
int h, i;
|
||||
if( n<2 ) return TK_ID;
|
||||
h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
|
||||
(sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
|
||||
n) % 127;
|
||||
for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
|
||||
if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
|
||||
return aCode[i];
|
||||
}
|
||||
}
|
||||
return TK_ID;
|
||||
}
|
||||
int sqlite3KeywordCode(const char *z, int n){
|
||||
return keywordCode(z, n);
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
** 2001 September 15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** Main file for the SQLite library. The routines in this file
|
||||
** implement the programmer interface to the library. Routines in
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: legacy.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** Execute SQL code. Return one of the SQLITE_ success/failure
|
||||
** codes. Also write an error message into memory obtained from
|
||||
** malloc() and make *pzErrMsg point to that message.
|
||||
**
|
||||
** If the SQL is a query, then for each row in the query result
|
||||
** the xCallback() function is called. pArg becomes the first
|
||||
** argument to xCallback(). If xCallback=NULL then no callback
|
||||
** is invoked, even for queries.
|
||||
*/
|
||||
int sqlite3_exec(
|
||||
sqlite3 *db, /* The database on which the SQL executes */
|
||||
const char *zSql, /* The SQL to be executed */
|
||||
sqlite3_callback xCallback, /* Invoke this callback routine */
|
||||
void *pArg, /* First argument to xCallback() */
|
||||
char **pzErrMsg /* Write error messages here */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
const char *zLeftover;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char **azCols = 0;
|
||||
|
||||
int nRetry = 0;
|
||||
int nChange = 0;
|
||||
int nCallback;
|
||||
|
||||
if( zSql==0 ) return SQLITE_OK;
|
||||
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
|
||||
int nCol;
|
||||
char **azVals = 0;
|
||||
|
||||
pStmt = 0;
|
||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( pStmt ) sqlite3_finalize(pStmt);
|
||||
continue;
|
||||
}
|
||||
if( !pStmt ){
|
||||
/* this happens for a comment or white-space */
|
||||
zSql = zLeftover;
|
||||
continue;
|
||||
}
|
||||
|
||||
db->nChange += nChange;
|
||||
nCallback = 0;
|
||||
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
azCols = sqliteMalloc(2*nCol*sizeof(const char *));
|
||||
if( nCol && !azCols ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto exec_out;
|
||||
}
|
||||
|
||||
while( 1 ){
|
||||
int i;
|
||||
rc = sqlite3_step(pStmt);
|
||||
|
||||
/* Invoke the callback function if required */
|
||||
if( xCallback && (SQLITE_ROW==rc ||
|
||||
(SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){
|
||||
if( 0==nCallback ){
|
||||
for(i=0; i<nCol; i++){
|
||||
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
||||
}
|
||||
nCallback++;
|
||||
}
|
||||
if( rc==SQLITE_ROW ){
|
||||
azVals = &azCols[nCol];
|
||||
for(i=0; i<nCol; i++){
|
||||
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
|
||||
}
|
||||
}
|
||||
if( xCallback(pArg, nCol, azVals, azCols) ){
|
||||
rc = SQLITE_ABORT;
|
||||
goto exec_out;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_ROW ){
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( db->pVdbe==0 ){
|
||||
nChange = db->nChange;
|
||||
}
|
||||
if( rc!=SQLITE_SCHEMA ){
|
||||
nRetry = 0;
|
||||
zSql = zLeftover;
|
||||
while( isspace((unsigned char)zSql[0]) ) zSql++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sqliteFree(azCols);
|
||||
azCols = 0;
|
||||
}
|
||||
|
||||
exec_out:
|
||||
if( pStmt ) sqlite3_finalize(pStmt);
|
||||
if( azCols ) sqliteFree(azCols);
|
||||
|
||||
if( sqlite3_malloc_failed ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
|
||||
*pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
|
||||
if( *pzErrMsg ){
|
||||
strcpy(*pzErrMsg, sqlite3_errmsg(db));
|
||||
}
|
||||
}else if( pzErrMsg ){
|
||||
*pzErrMsg = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,88 +0,0 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
EXPORTS = \
|
||||
sqlite3.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = sqlite
|
||||
|
||||
CSRCS = \
|
||||
alter.c \
|
||||
attach.c \
|
||||
auth.c \
|
||||
btree.c \
|
||||
build.c \
|
||||
callback.c \
|
||||
date.c \
|
||||
delete.c \
|
||||
expr.c \
|
||||
func.c \
|
||||
hash.c \
|
||||
insert.c \
|
||||
legacy.c \
|
||||
main.c \
|
||||
opcodes.c \
|
||||
os_unix.c \
|
||||
os_win.c \
|
||||
pager.c \
|
||||
parse.c \
|
||||
pragma.c \
|
||||
prepare.c \
|
||||
printf.c \
|
||||
random.c \
|
||||
select.c \
|
||||
table.c \
|
||||
tokenize.c \
|
||||
trigger.c \
|
||||
update.c \
|
||||
utf.c \
|
||||
util.c \
|
||||
vacuum.c \
|
||||
vdbe.c \
|
||||
vdbeapi.c \
|
||||
vdbeaux.c \
|
||||
vdbemem.c \
|
||||
where.c \
|
||||
$(NULL)
|
||||
|
||||
|
||||
MAPFILE = $(OBJDIR)/sqlite.def
|
||||
|
||||
LIBRARY_NAME = sqlite
|
||||
LIBRARY_VERSION = 3
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* NSS utility functions
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: nss.h,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $ */
|
||||
|
||||
#ifndef __nss_h_
|
||||
#define __nss_h_
|
||||
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
/*
|
||||
* NSS's major version, minor version, patch level, and whether
|
||||
* this is a beta release.
|
||||
*
|
||||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>] [<Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.10.1 Beta"
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 10
|
||||
#define NSS_VPATCH 1
|
||||
#define NSS_BETA PR_TRUE
|
||||
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* __nss_h_ */
|
||||
@@ -1,135 +0,0 @@
|
||||
/* Automatically generated. Do not edit */
|
||||
/* See the mkopcodec.awk script for details. */
|
||||
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|
||||
const char *const sqlite3OpcodeNames[] = { "?",
|
||||
/* 1 */ "MemLoad",
|
||||
/* 2 */ "Column",
|
||||
/* 3 */ "SetCookie",
|
||||
/* 4 */ "IfMemPos",
|
||||
/* 5 */ "MoveGt",
|
||||
/* 6 */ "AggFocus",
|
||||
/* 7 */ "RowKey",
|
||||
/* 8 */ "AggNext",
|
||||
/* 9 */ "OpenWrite",
|
||||
/* 10 */ "If",
|
||||
/* 11 */ "Pop",
|
||||
/* 12 */ "AggContextPush",
|
||||
/* 13 */ "CollSeq",
|
||||
/* 14 */ "OpenRead",
|
||||
/* 15 */ "Expire",
|
||||
/* 16 */ "SortReset",
|
||||
/* 17 */ "AutoCommit",
|
||||
/* 18 */ "Sort",
|
||||
/* 19 */ "ListRewind",
|
||||
/* 20 */ "IntegrityCk",
|
||||
/* 21 */ "SortInsert",
|
||||
/* 22 */ "Function",
|
||||
/* 23 */ "Noop",
|
||||
/* 24 */ "Return",
|
||||
/* 25 */ "NewRowid",
|
||||
/* 26 */ "Variable",
|
||||
/* 27 */ "String",
|
||||
/* 28 */ "ParseSchema",
|
||||
/* 29 */ "AggFunc",
|
||||
/* 30 */ "Close",
|
||||
/* 31 */ "ListWrite",
|
||||
/* 32 */ "CreateIndex",
|
||||
/* 33 */ "IsUnique",
|
||||
/* 34 */ "IdxIsNull",
|
||||
/* 35 */ "NotFound",
|
||||
/* 36 */ "MustBeInt",
|
||||
/* 37 */ "Halt",
|
||||
/* 38 */ "Rowid",
|
||||
/* 39 */ "IdxLT",
|
||||
/* 40 */ "AddImm",
|
||||
/* 41 */ "Statement",
|
||||
/* 42 */ "RowData",
|
||||
/* 43 */ "MemMax",
|
||||
/* 44 */ "Push",
|
||||
/* 45 */ "NotExists",
|
||||
/* 46 */ "OpenTemp",
|
||||
/* 47 */ "MemIncr",
|
||||
/* 48 */ "Gosub",
|
||||
/* 49 */ "AggSet",
|
||||
/* 50 */ "Integer",
|
||||
/* 51 */ "SortNext",
|
||||
/* 52 */ "Prev",
|
||||
/* 53 */ "CreateTable",
|
||||
/* 54 */ "Last",
|
||||
/* 55 */ "IdxRowid",
|
||||
/* 56 */ "ResetCount",
|
||||
/* 57 */ "Callback",
|
||||
/* 58 */ "ContextPush",
|
||||
/* 59 */ "DropTrigger",
|
||||
/* 60 */ "DropIndex",
|
||||
/* 61 */ "IdxGE",
|
||||
/* 62 */ "Or",
|
||||
/* 63 */ "And",
|
||||
/* 64 */ "Not",
|
||||
/* 65 */ "IdxDelete",
|
||||
/* 66 */ "Vacuum",
|
||||
/* 67 */ "MoveLe",
|
||||
/* 68 */ "IsNull",
|
||||
/* 69 */ "NotNull",
|
||||
/* 70 */ "Ne",
|
||||
/* 71 */ "Eq",
|
||||
/* 72 */ "Gt",
|
||||
/* 73 */ "Le",
|
||||
/* 74 */ "Lt",
|
||||
/* 75 */ "Ge",
|
||||
/* 76 */ "IfNot",
|
||||
/* 77 */ "BitAnd",
|
||||
/* 78 */ "BitOr",
|
||||
/* 79 */ "ShiftLeft",
|
||||
/* 80 */ "ShiftRight",
|
||||
/* 81 */ "Add",
|
||||
/* 82 */ "Subtract",
|
||||
/* 83 */ "Multiply",
|
||||
/* 84 */ "Divide",
|
||||
/* 85 */ "Remainder",
|
||||
/* 86 */ "Concat",
|
||||
/* 87 */ "Negative",
|
||||
/* 88 */ "DropTable",
|
||||
/* 89 */ "BitNot",
|
||||
/* 90 */ "String8",
|
||||
/* 91 */ "MakeRecord",
|
||||
/* 92 */ "Delete",
|
||||
/* 93 */ "AggContextPop",
|
||||
/* 94 */ "ListRead",
|
||||
/* 95 */ "ListReset",
|
||||
/* 96 */ "Dup",
|
||||
/* 97 */ "Goto",
|
||||
/* 98 */ "Clear",
|
||||
/* 99 */ "IdxGT",
|
||||
/* 100 */ "MoveLt",
|
||||
/* 101 */ "VerifyCookie",
|
||||
/* 102 */ "Pull",
|
||||
/* 103 */ "SetNumColumns",
|
||||
/* 104 */ "AbsValue",
|
||||
/* 105 */ "Transaction",
|
||||
/* 106 */ "AggGet",
|
||||
/* 107 */ "ContextPop",
|
||||
/* 108 */ "Next",
|
||||
/* 109 */ "AggInit",
|
||||
/* 110 */ "IdxInsert",
|
||||
/* 111 */ "Distinct",
|
||||
/* 112 */ "AggReset",
|
||||
/* 113 */ "Insert",
|
||||
/* 114 */ "Destroy",
|
||||
/* 115 */ "ReadCookie",
|
||||
/* 116 */ "ForceInt",
|
||||
/* 117 */ "OpenPseudo",
|
||||
/* 118 */ "Null",
|
||||
/* 119 */ "Blob",
|
||||
/* 120 */ "MemStore",
|
||||
/* 121 */ "Rewind",
|
||||
/* 122 */ "MoveGe",
|
||||
/* 123 */ "Found",
|
||||
/* 124 */ "NullRow",
|
||||
/* 125 */ "NotUsed_125",
|
||||
/* 126 */ "NotUsed_126",
|
||||
/* 127 */ "NotUsed_127",
|
||||
/* 128 */ "Real",
|
||||
/* 129 */ "HexBlob",
|
||||
};
|
||||
#endif
|
||||
@@ -1,144 +0,0 @@
|
||||
/* Automatically generated. Do not edit */
|
||||
/* See the mkopcodeh.awk script for details */
|
||||
#define OP_MemLoad 1
|
||||
#define OP_HexBlob 129 /* same as TK_BLOB */
|
||||
#define OP_Column 2
|
||||
#define OP_SetCookie 3
|
||||
#define OP_IfMemPos 4
|
||||
#define OP_Real 128 /* same as TK_FLOAT */
|
||||
#define OP_MoveGt 5
|
||||
#define OP_Ge 75 /* same as TK_GE */
|
||||
#define OP_AggFocus 6
|
||||
#define OP_RowKey 7
|
||||
#define OP_AggNext 8
|
||||
#define OP_Eq 71 /* same as TK_EQ */
|
||||
#define OP_OpenWrite 9
|
||||
#define OP_NotNull 69 /* same as TK_NOTNULL */
|
||||
#define OP_If 10
|
||||
#define OP_String8 90 /* same as TK_STRING */
|
||||
#define OP_Pop 11
|
||||
#define OP_AggContextPush 12
|
||||
#define OP_CollSeq 13
|
||||
#define OP_OpenRead 14
|
||||
#define OP_Expire 15
|
||||
#define OP_SortReset 16
|
||||
#define OP_AutoCommit 17
|
||||
#define OP_Gt 72 /* same as TK_GT */
|
||||
#define OP_Sort 18
|
||||
#define OP_ListRewind 19
|
||||
#define OP_IntegrityCk 20
|
||||
#define OP_SortInsert 21
|
||||
#define OP_Function 22
|
||||
#define OP_And 63 /* same as TK_AND */
|
||||
#define OP_Subtract 82 /* same as TK_MINUS */
|
||||
#define OP_Noop 23
|
||||
#define OP_Return 24
|
||||
#define OP_Remainder 85 /* same as TK_REM */
|
||||
#define OP_NewRowid 25
|
||||
#define OP_Multiply 83 /* same as TK_STAR */
|
||||
#define OP_Variable 26
|
||||
#define OP_String 27
|
||||
#define OP_ParseSchema 28
|
||||
#define OP_AggFunc 29
|
||||
#define OP_Close 30
|
||||
#define OP_ListWrite 31
|
||||
#define OP_CreateIndex 32
|
||||
#define OP_IsUnique 33
|
||||
#define OP_IdxIsNull 34
|
||||
#define OP_NotFound 35
|
||||
#define OP_MustBeInt 36
|
||||
#define OP_Halt 37
|
||||
#define OP_Rowid 38
|
||||
#define OP_IdxLT 39
|
||||
#define OP_AddImm 40
|
||||
#define OP_Statement 41
|
||||
#define OP_RowData 42
|
||||
#define OP_MemMax 43
|
||||
#define OP_Push 44
|
||||
#define OP_Or 62 /* same as TK_OR */
|
||||
#define OP_NotExists 45
|
||||
#define OP_OpenTemp 46
|
||||
#define OP_MemIncr 47
|
||||
#define OP_Gosub 48
|
||||
#define OP_Divide 84 /* same as TK_SLASH */
|
||||
#define OP_AggSet 49
|
||||
#define OP_Integer 50
|
||||
#define OP_SortNext 51
|
||||
#define OP_Prev 52
|
||||
#define OP_Concat 86 /* same as TK_CONCAT */
|
||||
#define OP_BitAnd 77 /* same as TK_BITAND */
|
||||
#define OP_CreateTable 53
|
||||
#define OP_Last 54
|
||||
#define OP_IsNull 68 /* same as TK_ISNULL */
|
||||
#define OP_IdxRowid 55
|
||||
#define OP_ShiftRight 80 /* same as TK_RSHIFT */
|
||||
#define OP_ResetCount 56
|
||||
#define OP_Callback 57
|
||||
#define OP_ContextPush 58
|
||||
#define OP_DropTrigger 59
|
||||
#define OP_DropIndex 60
|
||||
#define OP_IdxGE 61
|
||||
#define OP_IdxDelete 65
|
||||
#define OP_Vacuum 66
|
||||
#define OP_MoveLe 67
|
||||
#define OP_IfNot 76
|
||||
#define OP_DropTable 88
|
||||
#define OP_MakeRecord 91
|
||||
#define OP_Delete 92
|
||||
#define OP_AggContextPop 93
|
||||
#define OP_ListRead 94
|
||||
#define OP_ListReset 95
|
||||
#define OP_ShiftLeft 79 /* same as TK_LSHIFT */
|
||||
#define OP_Dup 96
|
||||
#define OP_Goto 97
|
||||
#define OP_Clear 98
|
||||
#define OP_IdxGT 99
|
||||
#define OP_MoveLt 100
|
||||
#define OP_Le 73 /* same as TK_LE */
|
||||
#define OP_VerifyCookie 101
|
||||
#define OP_Pull 102
|
||||
#define OP_Not 64 /* same as TK_NOT */
|
||||
#define OP_SetNumColumns 103
|
||||
#define OP_AbsValue 104
|
||||
#define OP_Transaction 105
|
||||
#define OP_Negative 87 /* same as TK_UMINUS */
|
||||
#define OP_Ne 70 /* same as TK_NE */
|
||||
#define OP_AggGet 106
|
||||
#define OP_ContextPop 107
|
||||
#define OP_BitOr 78 /* same as TK_BITOR */
|
||||
#define OP_Next 108
|
||||
#define OP_AggInit 109
|
||||
#define OP_IdxInsert 110
|
||||
#define OP_Distinct 111
|
||||
#define OP_Lt 74 /* same as TK_LT */
|
||||
#define OP_AggReset 112
|
||||
#define OP_Insert 113
|
||||
#define OP_Destroy 114
|
||||
#define OP_ReadCookie 115
|
||||
#define OP_ForceInt 116
|
||||
#define OP_OpenPseudo 117
|
||||
#define OP_Null 118
|
||||
#define OP_Blob 119
|
||||
#define OP_Add 81 /* same as TK_PLUS */
|
||||
#define OP_MemStore 120
|
||||
#define OP_Rewind 121
|
||||
#define OP_MoveGe 122
|
||||
#define OP_BitNot 89 /* same as TK_BITNOT */
|
||||
#define OP_Found 123
|
||||
#define OP_NullRow 124
|
||||
|
||||
/* The following opcode values are never used */
|
||||
#define OP_NotUsed_125 125
|
||||
#define OP_NotUsed_126 126
|
||||
#define OP_NotUsed_127 127
|
||||
|
||||
#define NOPUSH_MASK_0 65400
|
||||
#define NOPUSH_MASK_1 61871
|
||||
#define NOPUSH_MASK_2 64446
|
||||
#define NOPUSH_MASK_3 65363
|
||||
#define NOPUSH_MASK_4 65535
|
||||
#define NOPUSH_MASK_5 46015
|
||||
#define NOPUSH_MASK_6 64254
|
||||
#define NOPUSH_MASK_7 7987
|
||||
#define NOPUSH_MASK_8 0
|
||||
#define NOPUSH_MASK_9 0
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
** 2001 September 16
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This header file (together with is companion C source-code file
|
||||
** "os.c") attempt to abstract the underlying operating system so that
|
||||
** the SQLite library will work on both POSIX and windows systems.
|
||||
*/
|
||||
#ifndef _SQLITE_OS_H_
|
||||
#define _SQLITE_OS_H_
|
||||
|
||||
/*
|
||||
** Figure out if we are dealing with Unix, Windows or MacOS.
|
||||
**
|
||||
** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
|
||||
** The MacOS build is designed to use CodeWarrior (tested with v8)
|
||||
*/
|
||||
#if !defined(OS_UNIX) && !defined(OS_TEST) && !defined(OS_OTHER)
|
||||
# define OS_OTHER 0
|
||||
# ifndef OS_WIN
|
||||
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
|
||||
# define OS_WIN 1
|
||||
# define OS_UNIX 0
|
||||
# else
|
||||
# define OS_WIN 0
|
||||
# define OS_UNIX 1
|
||||
# endif
|
||||
# else
|
||||
# define OS_UNIX 0
|
||||
# endif
|
||||
#else
|
||||
# ifndef OS_WIN
|
||||
# define OS_WIN 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Invoke the appropriate operating-system specific header file.
|
||||
*/
|
||||
#if OS_TEST
|
||||
# include "os_test.h"
|
||||
#endif
|
||||
#if OS_UNIX
|
||||
# include "os_unix.h"
|
||||
#endif
|
||||
#if OS_WIN
|
||||
# include "os_win.h"
|
||||
#endif
|
||||
|
||||
/* os_other.c and os_other.h are not delivered with SQLite. These files
|
||||
** are place-holders that can be filled in by third-party developers to
|
||||
** implement backends to their on proprietary operating systems.
|
||||
*/
|
||||
#if OS_OTHER
|
||||
# include "os_other.h"
|
||||
#endif
|
||||
|
||||
/* If the SET_FULLSYNC macro is not defined above, then make it
|
||||
** a no-op
|
||||
*/
|
||||
#ifndef SET_FULLSYNC
|
||||
# define SET_FULLSYNC(x,y)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Temporary files are named starting with this prefix followed by 16 random
|
||||
** alphanumeric characters, and no file extension. They are stored in the
|
||||
** OS's standard temporary file directory, and are deleted prior to exit.
|
||||
** If sqlite is being embedded in another program, you may wish to change the
|
||||
** prefix to reflect your program's name, so that if your program exits
|
||||
** prematurely, old temporary files can be easily identified. This can be done
|
||||
** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
|
||||
*/
|
||||
#ifndef TEMP_FILE_PREFIX
|
||||
# define TEMP_FILE_PREFIX "sqlite_"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The following values may be passed as the second argument to
|
||||
** sqlite3OsLock(). The various locks exhibit the following semantics:
|
||||
**
|
||||
** SHARED: Any number of processes may hold a SHARED lock simultaneously.
|
||||
** RESERVED: A single process may hold a RESERVED lock on a file at
|
||||
** any time. Other processes may hold and obtain new SHARED locks.
|
||||
** PENDING: A single process may hold a PENDING lock on a file at
|
||||
** any one time. Existing SHARED locks may persist, but no new
|
||||
** SHARED locks may be obtained by other processes.
|
||||
** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
|
||||
**
|
||||
** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
|
||||
** process that requests an EXCLUSIVE lock may actually obtain a PENDING
|
||||
** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
|
||||
** sqlite3OsLock().
|
||||
*/
|
||||
#define NO_LOCK 0
|
||||
#define SHARED_LOCK 1
|
||||
#define RESERVED_LOCK 2
|
||||
#define PENDING_LOCK 3
|
||||
#define EXCLUSIVE_LOCK 4
|
||||
|
||||
/*
|
||||
** File Locking Notes: (Mostly about windows but also some info for Unix)
|
||||
**
|
||||
** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
|
||||
** those functions are not available. So we use only LockFile() and
|
||||
** UnlockFile().
|
||||
**
|
||||
** LockFile() prevents not just writing but also reading by other processes.
|
||||
** A SHARED_LOCK is obtained by locking a single randomly-chosen
|
||||
** byte out of a specific range of bytes. The lock byte is obtained at
|
||||
** random so two separate readers can probably access the file at the
|
||||
** same time, unless they are unlucky and choose the same lock byte.
|
||||
** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range.
|
||||
** There can only be one writer. A RESERVED_LOCK is obtained by locking
|
||||
** a single byte of the file that is designated as the reserved lock byte.
|
||||
** A PENDING_LOCK is obtained by locking a designated byte different from
|
||||
** the RESERVED_LOCK byte.
|
||||
**
|
||||
** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
|
||||
** which means we can use reader/writer locks. When reader/writer locks
|
||||
** are used, the lock is placed on the same range of bytes that is used
|
||||
** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
|
||||
** will support two or more Win95 readers or two or more WinNT readers.
|
||||
** But a single Win95 reader will lock out all WinNT readers and a single
|
||||
** WinNT reader will lock out all other Win95 readers.
|
||||
**
|
||||
** The following #defines specify the range of bytes used for locking.
|
||||
** SHARED_SIZE is the number of bytes available in the pool from which
|
||||
** a random byte is selected for a shared lock. The pool of bytes for
|
||||
** shared locks begins at SHARED_FIRST.
|
||||
**
|
||||
** These #defines are available in os.h so that Unix can use the same
|
||||
** byte ranges for locking. This leaves open the possiblity of having
|
||||
** clients on win95, winNT, and unix all talking to the same shared file
|
||||
** and all locking correctly. To do so would require that samba (or whatever
|
||||
** tool is being used for file sharing) implements locks correctly between
|
||||
** windows and unix. I'm guessing that isn't likely to happen, but by
|
||||
** using the same locking range we are at least open to the possibility.
|
||||
**
|
||||
** Locking in windows is manditory. For this reason, we cannot store
|
||||
** actual data in the bytes used for locking. The pager never allocates
|
||||
** the pages involved in locking therefore. SHARED_SIZE is selected so
|
||||
** that all locks will fit on a single page even at the minimum page size.
|
||||
** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE
|
||||
** is set high so that we don't have to allocate an unused page except
|
||||
** for very large databases. But one should test the page skipping logic
|
||||
** by setting PENDING_BYTE low and running the entire regression suite.
|
||||
**
|
||||
** Changing the value of PENDING_BYTE results in a subtly incompatible
|
||||
** file format. Depending on how it is changed, you might not notice
|
||||
** the incompatibility right away, even running a full regression test.
|
||||
** The default location of PENDING_BYTE is the first byte past the
|
||||
** 1GB boundary.
|
||||
**
|
||||
*/
|
||||
#define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */
|
||||
/* #define PENDING_BYTE 0x5400 // Page 22 - for testing */
|
||||
#define RESERVED_BYTE (PENDING_BYTE+1)
|
||||
#define SHARED_FIRST (PENDING_BYTE+2)
|
||||
#define SHARED_SIZE 510
|
||||
|
||||
|
||||
int sqlite3OsDelete(const char*);
|
||||
int sqlite3OsFileExists(const char*);
|
||||
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
|
||||
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
|
||||
int sqlite3OsOpenReadOnly(const char*, OsFile*);
|
||||
int sqlite3OsOpenDirectory(const char*, OsFile*);
|
||||
int sqlite3OsSyncDirectory(const char*);
|
||||
int sqlite3OsTempFileName(char*);
|
||||
int sqlite3OsIsDirWritable(char*);
|
||||
int sqlite3OsClose(OsFile*);
|
||||
int sqlite3OsRead(OsFile*, void*, int amt);
|
||||
int sqlite3OsWrite(OsFile*, const void*, int amt);
|
||||
int sqlite3OsSeek(OsFile*, i64 offset);
|
||||
int sqlite3OsSync(OsFile*);
|
||||
int sqlite3OsTruncate(OsFile*, i64 size);
|
||||
int sqlite3OsFileSize(OsFile*, i64 *pSize);
|
||||
char *sqlite3OsFullPathname(const char*);
|
||||
int sqlite3OsLock(OsFile*, int);
|
||||
int sqlite3OsUnlock(OsFile*, int);
|
||||
int sqlite3OsCheckReservedLock(OsFile *id);
|
||||
|
||||
|
||||
/* The interface for file I/O is above. Other miscellaneous functions
|
||||
** are below */
|
||||
|
||||
int sqlite3OsRandomSeed(char*);
|
||||
int sqlite3OsSleep(int ms);
|
||||
int sqlite3OsCurrentTime(double*);
|
||||
void sqlite3OsEnterMutex(void);
|
||||
void sqlite3OsLeaveMutex(void);
|
||||
|
||||
#endif /* _SQLITE_OS_H_ */
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
** 2004 May 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This file contains macros and a little bit of code that is common to
|
||||
** all of the platform-specific files (os_*.c) and is #included into those
|
||||
** files.
|
||||
**
|
||||
** This file should be #included by the os_*.c files only. It is not a
|
||||
** general purpose header file.
|
||||
*/
|
||||
|
||||
/*
|
||||
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
|
||||
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
|
||||
** switch. The following code should catch this problem at compile-time.
|
||||
*/
|
||||
#ifdef MEMORY_DEBUG
|
||||
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
|
||||
#endif
|
||||
|
||||
|
||||
int sqlite3_os_trace = 0;
|
||||
#ifdef SQLITE_DEBUG
|
||||
static int last_page = 0;
|
||||
#define SEEK(X) last_page=(X)
|
||||
#define TRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
|
||||
#define TRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
|
||||
#define TRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
|
||||
#define TRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
|
||||
#define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
|
||||
#define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
|
||||
#define TRACE7(X,Y,Z,A,B,C,D) \
|
||||
if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
|
||||
#else
|
||||
#define SEEK(X)
|
||||
#define TRACE1(X)
|
||||
#define TRACE2(X,Y)
|
||||
#define TRACE3(X,Y,Z)
|
||||
#define TRACE4(X,Y,Z,A)
|
||||
#define TRACE5(X,Y,Z,A,B)
|
||||
#define TRACE6(X,Y,Z,A,B,C)
|
||||
#define TRACE7(X,Y,Z,A,B,C,D)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macros for performance tracing. Normally turned off. Only works
|
||||
** on i486 hardware.
|
||||
*/
|
||||
#ifdef SQLITE_PERFORMANCE_TRACE
|
||||
__inline__ unsigned long long int hwtime(void){
|
||||
unsigned long long int x;
|
||||
__asm__("rdtsc\n\t"
|
||||
"mov %%edx, %%ecx\n\t"
|
||||
:"=A" (x));
|
||||
return x;
|
||||
}
|
||||
static unsigned long long int g_start;
|
||||
static unsigned int elapse;
|
||||
#define TIMER_START g_start=hwtime()
|
||||
#define TIMER_END elapse=hwtime()-g_start
|
||||
#define TIMER_ELAPSED elapse
|
||||
#else
|
||||
#define TIMER_START
|
||||
#define TIMER_END
|
||||
#define TIMER_ELAPSED 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If we compile with the SQLITE_TEST macro set, then the following block
|
||||
** of code will give us the ability to simulate a disk I/O error. This
|
||||
** is used for testing the I/O recovery logic.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3_io_error_pending = 0;
|
||||
int sqlite3_diskfull_pending = 0;
|
||||
#define SimulateIOError(A) \
|
||||
if( sqlite3_io_error_pending ) \
|
||||
if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
|
||||
static void local_ioerr(){
|
||||
sqlite3_io_error_pending = 0; /* Really just a place to set a breakpoint */
|
||||
}
|
||||
#define SimulateDiskfullError \
|
||||
if( sqlite3_diskfull_pending ) \
|
||||
if( sqlite3_diskfull_pending-- == 1 ){ local_ioerr(); return SQLITE_FULL; }
|
||||
#else
|
||||
#define SimulateIOError(A)
|
||||
#define SimulateDiskfullError
|
||||
#endif
|
||||
|
||||
/*
|
||||
** When testing, keep a count of the number of open files.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3_open_file_count = 0;
|
||||
#define OpenCounter(X) sqlite3_open_file_count+=(X)
|
||||
#else
|
||||
#define OpenCounter(X)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
** 2004 May 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This header file defined OS-specific features for Unix.
|
||||
*/
|
||||
#ifndef _SQLITE_OS_UNIX_H_
|
||||
#define _SQLITE_OS_UNIX_H_
|
||||
|
||||
/*
|
||||
** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
|
||||
** to the compiler command line.
|
||||
*/
|
||||
|
||||
/*
|
||||
** These #defines should enable >2GB file support on Posix if the
|
||||
** underlying operating system supports it. If the OS lacks
|
||||
** large file support, or if the OS is windows, these should be no-ops.
|
||||
**
|
||||
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
|
||||
** on the compiler command line. This is necessary if you are compiling
|
||||
** on a recent machine (ex: RedHat 7.2) but you want your code to work
|
||||
** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
|
||||
** without this option, LFS is enable. But LFS does not exist in the kernel
|
||||
** in RedHat 6.0, so the code won't work. Hence, for maximum binary
|
||||
** portability you should omit LFS.
|
||||
**
|
||||
** Similar is true for MacOS. LFS is only supported on MacOS 9 and later.
|
||||
*/
|
||||
#ifndef SQLITE_DISABLE_LFS
|
||||
# define _LARGE_FILE 1
|
||||
# ifndef _FILE_OFFSET_BITS
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
# endif
|
||||
# define _LARGEFILE_SOURCE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** standard include files.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
** The OsFile structure is a operating-system independing representation
|
||||
** of an open file handle. It is defined differently for each architecture.
|
||||
**
|
||||
** This is the definition for Unix.
|
||||
**
|
||||
** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
|
||||
** PENDING_LOCK or EXCLUSIVE_LOCK.
|
||||
*/
|
||||
typedef struct OsFile OsFile;
|
||||
struct OsFile {
|
||||
struct Pager *pPager; /* The pager that owns this OsFile. Might be 0 */
|
||||
struct openCnt *pOpen; /* Info about all open fd's on this inode */
|
||||
struct lockInfo *pLock; /* Info about locks on this inode */
|
||||
int h; /* The file descriptor */
|
||||
unsigned char locktype; /* The type of lock held on this fd */
|
||||
unsigned char isOpen; /* True if needs to be closed */
|
||||
unsigned char fullSync; /* Use F_FULLSYNC if available */
|
||||
int dirfd; /* File descriptor for the directory */
|
||||
};
|
||||
|
||||
/*
|
||||
** A macro to set the OsFile.fullSync flag, if it exists.
|
||||
*/
|
||||
#define SET_FULLSYNC(x,y) ((x).fullSync = (y))
|
||||
|
||||
/*
|
||||
** Maximum number of characters in a temporary file name
|
||||
*/
|
||||
#define SQLITE_TEMPNAME_SIZE 200
|
||||
|
||||
/*
|
||||
** Minimum interval supported by sqlite3OsSleep().
|
||||
*/
|
||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
# define SQLITE_MIN_SLEEP_MS 1
|
||||
#else
|
||||
# define SQLITE_MIN_SLEEP_MS 1000
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Default permissions when creating a new file
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
|
||||
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _SQLITE_OS_UNIX_H_ */
|
||||
@@ -1,767 +0,0 @@
|
||||
/*
|
||||
** 2004 May 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This file contains code that is specific to windows.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
#if OS_WIN /* This file is used for windows only */
|
||||
|
||||
#include <winbase.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# include <sys/cygwin.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macros used to determine whether or not to use threads.
|
||||
*/
|
||||
#if defined(THREADSAFE) && THREADSAFE
|
||||
# define SQLITE_W32_THREADS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Include code that is common to all os_*.c files
|
||||
*/
|
||||
#include "os_common.h"
|
||||
|
||||
/*
|
||||
** Do not include any of the File I/O interface procedures if the
|
||||
** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
|
||||
** will be in-memory only)
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
|
||||
/*
|
||||
** Delete the named file
|
||||
*/
|
||||
int sqlite3OsDelete(const char *zFilename){
|
||||
DeleteFileA(zFilename);
|
||||
TRACE2("DELETE \"%s\"\n", zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the named file exists.
|
||||
*/
|
||||
int sqlite3OsFileExists(const char *zFilename){
|
||||
return GetFileAttributesA(zFilename) != 0xffffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to open a file for both reading and writing. If that
|
||||
** fails, try opening it read-only. If the file does not exist,
|
||||
** try to create it.
|
||||
**
|
||||
** On success, a handle for the open file is written to *id
|
||||
** and *pReadonly is set to 0 if the file was opened for reading and
|
||||
** writing or 1 if the file was opened read-only. The function returns
|
||||
** SQLITE_OK.
|
||||
**
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id and *pReadonly unchanged.
|
||||
*/
|
||||
int sqlite3OsOpenReadWrite(
|
||||
const char *zFilename,
|
||||
OsFile *id,
|
||||
int *pReadonly
|
||||
){
|
||||
HANDLE h;
|
||||
assert( !id->isOpen );
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
*pReadonly = 1;
|
||||
}else{
|
||||
*pReadonly = 0;
|
||||
}
|
||||
id->h = h;
|
||||
id->locktype = NO_LOCK;
|
||||
id->sharedLockByte = 0;
|
||||
id->isOpen = 1;
|
||||
OpenCounter(+1);
|
||||
TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Attempt to open a new file for exclusive access by this process.
|
||||
** The file will be opened for both reading and writing. To avoid
|
||||
** a potential security problem, we do not allow the file to have
|
||||
** previously existed. Nor do we allow the file to be a symbolic
|
||||
** link.
|
||||
**
|
||||
** If delFlag is true, then make arrangements to automatically delete
|
||||
** the file when it is closed.
|
||||
**
|
||||
** On success, write the file handle into *id and return SQLITE_OK.
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
HANDLE h;
|
||||
int fileflags;
|
||||
assert( !id->isOpen );
|
||||
if( delFlag ){
|
||||
fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
|
||||
| FILE_FLAG_DELETE_ON_CLOSE;
|
||||
}else{
|
||||
fileflags = FILE_FLAG_RANDOM_ACCESS;
|
||||
}
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
fileflags,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
id->h = h;
|
||||
id->locktype = NO_LOCK;
|
||||
id->sharedLockByte = 0;
|
||||
id->isOpen = 1;
|
||||
OpenCounter(+1);
|
||||
TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to open a new file for read-only access.
|
||||
**
|
||||
** On success, write the file handle into *id and return SQLITE_OK.
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
HANDLE h;
|
||||
assert( !id->isOpen );
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
id->h = h;
|
||||
id->locktype = NO_LOCK;
|
||||
id->sharedLockByte = 0;
|
||||
id->isOpen = 1;
|
||||
OpenCounter(+1);
|
||||
TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to open a file descriptor for the directory that contains a
|
||||
** file. This file descriptor can be used to fsync() the directory
|
||||
** in order to make sure the creation of a new file is actually written
|
||||
** to disk.
|
||||
**
|
||||
** This routine is only meaningful for Unix. It is a no-op under
|
||||
** windows since windows does not support hard links.
|
||||
**
|
||||
** On success, a handle for a previously open file is at *id is
|
||||
** updated with the new directory file descriptor and SQLITE_OK is
|
||||
** returned.
|
||||
**
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id unchanged.
|
||||
*/
|
||||
int sqlite3OsOpenDirectory(
|
||||
const char *zDirname,
|
||||
OsFile *id
|
||||
){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the following global variable points to a string which is the
|
||||
** name of a directory, then that directory will be used to store
|
||||
** temporary files.
|
||||
*/
|
||||
char *sqlite3_temp_directory = 0;
|
||||
|
||||
/*
|
||||
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||
** hold at least SQLITE_TEMPNAME_SIZE characters.
|
||||
*/
|
||||
int sqlite3OsTempFileName(char *zBuf){
|
||||
static char zChars[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
int i, j;
|
||||
char zTempPath[SQLITE_TEMPNAME_SIZE];
|
||||
if( sqlite3_temp_directory ){
|
||||
strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
|
||||
zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
|
||||
}else{
|
||||
GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
|
||||
}
|
||||
for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
|
||||
zTempPath[i] = 0;
|
||||
for(;;){
|
||||
sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
|
||||
j = strlen(zBuf);
|
||||
sqlite3Randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
if( !sqlite3OsFileExists(zBuf) ) break;
|
||||
}
|
||||
TRACE2("TEMP FILENAME: %s\n", zBuf);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
int sqlite3OsClose(OsFile *id){
|
||||
if( id->isOpen ){
|
||||
TRACE2("CLOSE %d\n", id->h);
|
||||
CloseHandle(id->h);
|
||||
OpenCounter(-1);
|
||||
id->isOpen = 0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read data from a file into a buffer. Return SQLITE_OK if all
|
||||
** bytes were read successfully and SQLITE_IOERR if anything goes
|
||||
** wrong.
|
||||
*/
|
||||
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
|
||||
DWORD got;
|
||||
assert( id->isOpen );
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
TRACE3("READ %d lock=%d\n", id->h, id->locktype);
|
||||
if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
|
||||
got = 0;
|
||||
}
|
||||
if( got==(DWORD)amt ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Write data from a buffer into a file. Return SQLITE_OK on success
|
||||
** or some other error code on failure.
|
||||
*/
|
||||
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
|
||||
int rc = 0;
|
||||
DWORD wrote;
|
||||
assert( id->isOpen );
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
SimulateDiskfullError;
|
||||
TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
|
||||
assert( amt>0 );
|
||||
while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
|
||||
amt -= wrote;
|
||||
pBuf = &((char*)pBuf)[wrote];
|
||||
}
|
||||
if( !rc || amt>(int)wrote ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move the read/write pointer in a file.
|
||||
*/
|
||||
int sqlite3OsSeek(OsFile *id, i64 offset){
|
||||
LONG upperBits = offset>>32;
|
||||
LONG lowerBits = offset & 0xffffffff;
|
||||
DWORD rc;
|
||||
assert( id->isOpen );
|
||||
SEEK(offset/1024 + 1);
|
||||
rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
|
||||
TRACE3("SEEK %d %lld\n", id->h, offset);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure all writes to a particular file are committed to disk.
|
||||
*/
|
||||
int sqlite3OsSync(OsFile *id){
|
||||
assert( id->isOpen );
|
||||
TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
|
||||
if( FlushFileBuffers(id->h) ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Sync the directory zDirname. This is a no-op on operating systems other
|
||||
** than UNIX.
|
||||
*/
|
||||
int sqlite3OsSyncDirectory(const char *zDirname){
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate an open file to a specified size
|
||||
*/
|
||||
int sqlite3OsTruncate(OsFile *id, i64 nByte){
|
||||
LONG upperBits = nByte>>32;
|
||||
assert( id->isOpen );
|
||||
TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
|
||||
SetEndOfFile(id->h);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine the current size of a file in bytes
|
||||
*/
|
||||
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
|
||||
DWORD upperBits, lowerBits;
|
||||
assert( id->isOpen );
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
lowerBits = GetFileSize(id->h, &upperBits);
|
||||
*pSize = (((i64)upperBits)<<32) + lowerBits;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
|
||||
** Return false (zero) for Win95, Win98, or WinME.
|
||||
**
|
||||
** Here is an interesting observation: Win95, Win98, and WinME lack
|
||||
** the LockFileEx() API. But we can still statically link against that
|
||||
** API as long as we don't call it win running Win95/98/ME. A call to
|
||||
** this routine is used to determine if the host is Win95/98/ME or
|
||||
** WinNT/2K/XP so that we will know whether or not we can safely call
|
||||
** the LockFileEx() API.
|
||||
*/
|
||||
static int isNT(void){
|
||||
static int osType = 0; /* 0=unknown 1=win95 2=winNT */
|
||||
if( osType==0 ){
|
||||
OSVERSIONINFO sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
GetVersionEx(&sInfo);
|
||||
osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
|
||||
}
|
||||
return osType==2;
|
||||
}
|
||||
|
||||
/*
|
||||
** Acquire a reader lock.
|
||||
** Different API routines are called depending on whether or not this
|
||||
** is Win95 or WinNT.
|
||||
*/
|
||||
static int getReadLock(OsFile *id){
|
||||
int res;
|
||||
if( isNT() ){
|
||||
OVERLAPPED ovlp;
|
||||
ovlp.Offset = SHARED_FIRST;
|
||||
ovlp.OffsetHigh = 0;
|
||||
ovlp.hEvent = 0;
|
||||
res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
|
||||
}else{
|
||||
int lk;
|
||||
sqlite3Randomness(sizeof(lk), &lk);
|
||||
id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
|
||||
res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
** Undo a readlock
|
||||
*/
|
||||
static int unlockReadLock(OsFile *id){
|
||||
int res;
|
||||
if( isNT() ){
|
||||
res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
|
||||
}else{
|
||||
res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** Check that a given pathname is a directory and is writable
|
||||
**
|
||||
*/
|
||||
int sqlite3OsIsDirWritable(char *zBuf){
|
||||
int fileAttr;
|
||||
if(! zBuf ) return 0;
|
||||
if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
|
||||
fileAttr = GetFileAttributesA(zBuf);
|
||||
if( fileAttr == 0xffffffff ) return 0;
|
||||
if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||
|
||||
/*
|
||||
** Lock the file with the lock specified by parameter locktype - one
|
||||
** of the following:
|
||||
**
|
||||
** (1) SHARED_LOCK
|
||||
** (2) RESERVED_LOCK
|
||||
** (3) PENDING_LOCK
|
||||
** (4) EXCLUSIVE_LOCK
|
||||
**
|
||||
** Sometimes when requesting one lock state, additional lock states
|
||||
** are inserted in between. The locking might fail on one of the later
|
||||
** transitions leaving the lock state different from what it started but
|
||||
** still short of its goal. The following chart shows the allowed
|
||||
** transitions and the inserted intermediate states:
|
||||
**
|
||||
** UNLOCKED -> SHARED
|
||||
** SHARED -> RESERVED
|
||||
** SHARED -> (PENDING) -> EXCLUSIVE
|
||||
** RESERVED -> (PENDING) -> EXCLUSIVE
|
||||
** PENDING -> EXCLUSIVE
|
||||
**
|
||||
** This routine will only increase a lock. The sqlite3OsUnlock() routine
|
||||
** erases all locks at once and returns us immediately to locking level 0.
|
||||
** It is not possible to lower the locking level one step at a time. You
|
||||
** must go straight to locking level 0.
|
||||
*/
|
||||
int sqlite3OsLock(OsFile *id, int locktype){
|
||||
int rc = SQLITE_OK; /* Return code from subroutines */
|
||||
int res = 1; /* Result of a windows lock call */
|
||||
int newLocktype; /* Set id->locktype to this value before exiting */
|
||||
int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
|
||||
|
||||
assert( id->isOpen );
|
||||
TRACE5("LOCK %d %d was %d(%d)\n",
|
||||
id->h, locktype, id->locktype, id->sharedLockByte);
|
||||
|
||||
/* If there is already a lock of this type or more restrictive on the
|
||||
** OsFile, do nothing. Don't use the end_lock: exit path, as
|
||||
** sqlite3OsEnterMutex() hasn't been called yet.
|
||||
*/
|
||||
if( id->locktype>=locktype ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Make sure the locking sequence is correct
|
||||
*/
|
||||
assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
|
||||
assert( locktype!=PENDING_LOCK );
|
||||
assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
|
||||
|
||||
/* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
|
||||
** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
|
||||
** the PENDING_LOCK byte is temporary.
|
||||
*/
|
||||
newLocktype = id->locktype;
|
||||
if( id->locktype==NO_LOCK
|
||||
|| (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
|
||||
){
|
||||
int cnt = 3;
|
||||
while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
|
||||
/* Try 3 times to get the pending lock. The pending lock might be
|
||||
** held by another reader process who will release it momentarily.
|
||||
*/
|
||||
TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
|
||||
Sleep(1);
|
||||
}
|
||||
gotPendingLock = res;
|
||||
}
|
||||
|
||||
/* Acquire a shared lock
|
||||
*/
|
||||
if( locktype==SHARED_LOCK && res ){
|
||||
assert( id->locktype==NO_LOCK );
|
||||
res = getReadLock(id);
|
||||
if( res ){
|
||||
newLocktype = SHARED_LOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire a RESERVED lock
|
||||
*/
|
||||
if( locktype==RESERVED_LOCK && res ){
|
||||
assert( id->locktype==SHARED_LOCK );
|
||||
res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
|
||||
if( res ){
|
||||
newLocktype = RESERVED_LOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Acquire a PENDING lock
|
||||
*/
|
||||
if( locktype==EXCLUSIVE_LOCK && res ){
|
||||
newLocktype = PENDING_LOCK;
|
||||
gotPendingLock = 0;
|
||||
}
|
||||
|
||||
/* Acquire an EXCLUSIVE lock
|
||||
*/
|
||||
if( locktype==EXCLUSIVE_LOCK && res ){
|
||||
assert( id->locktype>=SHARED_LOCK );
|
||||
res = unlockReadLock(id);
|
||||
TRACE2("unreadlock = %d\n", res);
|
||||
res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
|
||||
if( res ){
|
||||
newLocktype = EXCLUSIVE_LOCK;
|
||||
}else{
|
||||
TRACE2("error-code = %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are holding a PENDING lock that ought to be released, then
|
||||
** release it now.
|
||||
*/
|
||||
if( gotPendingLock && locktype==SHARED_LOCK ){
|
||||
UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
|
||||
}
|
||||
|
||||
/* Update the state of the lock has held in the file descriptor then
|
||||
** return the appropriate result code.
|
||||
*/
|
||||
if( res ){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
|
||||
locktype, newLocktype);
|
||||
rc = SQLITE_BUSY;
|
||||
}
|
||||
id->locktype = newLocktype;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine checks if there is a RESERVED lock held on the specified
|
||||
** file by this or any other process. If such a lock is held, return
|
||||
** non-zero, otherwise zero.
|
||||
*/
|
||||
int sqlite3OsCheckReservedLock(OsFile *id){
|
||||
int rc;
|
||||
assert( id->isOpen );
|
||||
if( id->locktype>=RESERVED_LOCK ){
|
||||
rc = 1;
|
||||
TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
|
||||
}else{
|
||||
rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
|
||||
if( rc ){
|
||||
UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
|
||||
}
|
||||
rc = !rc;
|
||||
TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Lower the locking level on file descriptor id to locktype. locktype
|
||||
** must be either NO_LOCK or SHARED_LOCK.
|
||||
**
|
||||
** If the locking level of the file descriptor is already at or below
|
||||
** the requested locking level, this routine is a no-op.
|
||||
**
|
||||
** It is not possible for this routine to fail if the second argument
|
||||
** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
|
||||
** might return SQLITE_IOERR;
|
||||
*/
|
||||
int sqlite3OsUnlock(OsFile *id, int locktype){
|
||||
int type;
|
||||
int rc = SQLITE_OK;
|
||||
assert( id->isOpen );
|
||||
assert( locktype<=SHARED_LOCK );
|
||||
TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
|
||||
id->locktype, id->sharedLockByte);
|
||||
type = id->locktype;
|
||||
if( type>=EXCLUSIVE_LOCK ){
|
||||
UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
|
||||
if( locktype==SHARED_LOCK && !getReadLock(id) ){
|
||||
/* This should never happen. We should always be able to
|
||||
** reacquire the read lock */
|
||||
rc = SQLITE_IOERR;
|
||||
}
|
||||
}
|
||||
if( type>=RESERVED_LOCK ){
|
||||
UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
|
||||
}
|
||||
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
|
||||
unlockReadLock(id);
|
||||
}
|
||||
if( type>=PENDING_LOCK ){
|
||||
UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
|
||||
}
|
||||
id->locktype = locktype;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Turn a relative pathname into a full pathname. Return a pointer
|
||||
** to the full pathname stored in space obtained from sqliteMalloc().
|
||||
** The calling function is responsible for freeing this space once it
|
||||
** is no longer needed.
|
||||
*/
|
||||
char *sqlite3OsFullPathname(const char *zRelative){
|
||||
char *zNotUsed;
|
||||
char *zFull;
|
||||
int nByte;
|
||||
#ifdef __CYGWIN__
|
||||
nByte = strlen(zRelative) + MAX_PATH + 1001;
|
||||
zFull = sqliteMalloc( nByte );
|
||||
if( zFull==0 ) return 0;
|
||||
if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
|
||||
#else
|
||||
nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
|
||||
zFull = sqliteMalloc( nByte );
|
||||
if( zFull==0 ) return 0;
|
||||
GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
|
||||
#endif
|
||||
return zFull;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_DISKIO */
|
||||
/***************************************************************************
|
||||
** Everything above deals with file I/O. Everything that follows deals
|
||||
** with other miscellanous aspects of the operating system interface
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
** Get information to seed the random number generator. The seed
|
||||
** is written into the buffer zBuf[256]. The calling function must
|
||||
** supply a sufficiently large buffer.
|
||||
*/
|
||||
int sqlite3OsRandomSeed(char *zBuf){
|
||||
/* We have to initialize zBuf to prevent valgrind from reporting
|
||||
** errors. The reports issued by valgrind are incorrect - we would
|
||||
** prefer that the randomness be increased by making use of the
|
||||
** uninitialized space in zBuf - but valgrind errors tend to worry
|
||||
** some users. Rather than argue, it seems easier just to initialize
|
||||
** the whole array and silence valgrind, even if that means less randomness
|
||||
** in the random seed.
|
||||
**
|
||||
** When testing, initializing zBuf[] to zero is all we do. That means
|
||||
** that we always use the same random number sequence.* This makes the
|
||||
** tests repeatable.
|
||||
*/
|
||||
memset(zBuf, 0, 256);
|
||||
GetSystemTime((LPSYSTEMTIME)zBuf);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sleep for a little while. Return the amount of time slept.
|
||||
*/
|
||||
int sqlite3OsSleep(int ms){
|
||||
Sleep(ms);
|
||||
return ms;
|
||||
}
|
||||
|
||||
/*
|
||||
** Static variables used for thread synchronization
|
||||
*/
|
||||
static int inMutex = 0;
|
||||
#ifdef SQLITE_W32_THREADS
|
||||
static CRITICAL_SECTION cs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The following pair of routine implement mutual exclusion for
|
||||
** multi-threaded processes. Only a single thread is allowed to
|
||||
** executed code that is surrounded by EnterMutex() and LeaveMutex().
|
||||
**
|
||||
** SQLite uses only a single Mutex. There is not much critical
|
||||
** code and what little there is executes quickly and without blocking.
|
||||
*/
|
||||
void sqlite3OsEnterMutex(){
|
||||
#ifdef SQLITE_W32_THREADS
|
||||
static int isInit = 0;
|
||||
while( !isInit ){
|
||||
static long lock = 0;
|
||||
if( InterlockedIncrement(&lock)==1 ){
|
||||
InitializeCriticalSection(&cs);
|
||||
isInit = 1;
|
||||
}else{
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
EnterCriticalSection(&cs);
|
||||
#endif
|
||||
assert( !inMutex );
|
||||
inMutex = 1;
|
||||
}
|
||||
void sqlite3OsLeaveMutex(){
|
||||
assert( inMutex );
|
||||
inMutex = 0;
|
||||
#ifdef SQLITE_W32_THREADS
|
||||
LeaveCriticalSection(&cs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** The following variable, if set to a non-zero value, becomes the result
|
||||
** returned from sqlite3OsCurrentTime(). This is used for testing.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3_current_time = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Find the current time (in Universal Coordinated Time). Write the
|
||||
** current time and date as a Julian Day number into *prNow and
|
||||
** return 0. Return 1 if the time and date cannot be found.
|
||||
*/
|
||||
int sqlite3OsCurrentTime(double *prNow){
|
||||
FILETIME ft;
|
||||
/* FILETIME structure is a 64-bit value representing the number of
|
||||
100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
|
||||
*/
|
||||
double now;
|
||||
GetSystemTimeAsFileTime( &ft );
|
||||
now = ((double)ft.dwHighDateTime) * 4294967296.0;
|
||||
*prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
|
||||
#ifdef SQLITE_TEST
|
||||
if( sqlite3_current_time ){
|
||||
*prNow = sqlite3_current_time/86400.0 + 2440587.5;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* OS_WIN */
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
** 2004 May 22
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This header file defines OS-specific features for Win32
|
||||
*/
|
||||
#ifndef _SQLITE_OS_WIN_H_
|
||||
#define _SQLITE_OS_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
|
||||
/*
|
||||
** The OsFile structure is a operating-system independing representation
|
||||
** of an open file handle. It is defined differently for each architecture.
|
||||
**
|
||||
** This is the definition for Win32.
|
||||
*/
|
||||
typedef struct OsFile OsFile;
|
||||
struct OsFile {
|
||||
HANDLE h; /* Handle for accessing the file */
|
||||
unsigned char locktype; /* Type of lock currently held on this file */
|
||||
unsigned char isOpen; /* True if needs to be closed */
|
||||
short sharedLockByte; /* Randomly chosen byte used as a shared lock */
|
||||
};
|
||||
|
||||
|
||||
#define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
||||
#define SQLITE_MIN_SLEEP_MS 1
|
||||
|
||||
|
||||
#endif /* _SQLITE_OS_WIN_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
** 2001 September 15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the interface that the sqlite page cache
|
||||
** subsystem. The page cache subsystem reads and writes a file a page
|
||||
** at a time and provides a journal for rollback.
|
||||
**
|
||||
** @(#) $Id: pager.h,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
** The default size of a database page.
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_PAGE_SIZE
|
||||
# define SQLITE_DEFAULT_PAGE_SIZE 1024
|
||||
#endif
|
||||
|
||||
/* Maximum page size. The upper bound on this value is 32768. This a limit
|
||||
** imposed by necessity of storing the value in a 2-byte unsigned integer
|
||||
** and the fact that the page size must be a power of 2.
|
||||
**
|
||||
** This value is used to initialize certain arrays on the stack at
|
||||
** various places in the code. On embedded machines where stack space
|
||||
** is limited and the flexibility of having large pages is not needed,
|
||||
** it makes good sense to reduce the maximum page size to something more
|
||||
** reasonable, like 1024.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_PAGE_SIZE
|
||||
# define SQLITE_MAX_PAGE_SIZE 8192
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Maximum number of pages in one database.
|
||||
*/
|
||||
#define SQLITE_MAX_PAGE 1073741823
|
||||
|
||||
/*
|
||||
** The type used to represent a page number. The first page in a file
|
||||
** is called page 1. 0 is used to represent "not a page".
|
||||
*/
|
||||
typedef unsigned int Pgno;
|
||||
|
||||
/*
|
||||
** Each open file is managed by a separate instance of the "Pager" structure.
|
||||
*/
|
||||
typedef struct Pager Pager;
|
||||
|
||||
/*
|
||||
** Allowed values for the flags parameter to sqlite3pager_open().
|
||||
**
|
||||
** NOTE: This values must match the corresponding BTREE_ values in btree.h.
|
||||
*/
|
||||
#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
|
||||
#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
|
||||
|
||||
|
||||
/*
|
||||
** See source code comments for a detailed description of the following
|
||||
** routines:
|
||||
*/
|
||||
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
|
||||
int nExtra, int flags);
|
||||
void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
|
||||
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
|
||||
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
|
||||
int sqlite3pager_set_pagesize(Pager*, int);
|
||||
void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
|
||||
void sqlite3pager_set_cachesize(Pager*, int);
|
||||
int sqlite3pager_close(Pager *pPager);
|
||||
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
|
||||
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
|
||||
int sqlite3pager_ref(void*);
|
||||
int sqlite3pager_unref(void*);
|
||||
Pgno sqlite3pager_pagenumber(void*);
|
||||
int sqlite3pager_write(void*);
|
||||
int sqlite3pager_iswriteable(void*);
|
||||
int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void*);
|
||||
int sqlite3pager_pagecount(Pager*);
|
||||
int sqlite3pager_truncate(Pager*,Pgno);
|
||||
int sqlite3pager_begin(void*, int exFlag);
|
||||
int sqlite3pager_commit(Pager*);
|
||||
int sqlite3pager_sync(Pager*,const char *zMaster, Pgno);
|
||||
int sqlite3pager_rollback(Pager*);
|
||||
int sqlite3pager_isreadonly(Pager*);
|
||||
int sqlite3pager_stmt_begin(Pager*);
|
||||
int sqlite3pager_stmt_commit(Pager*);
|
||||
int sqlite3pager_stmt_rollback(Pager*);
|
||||
void sqlite3pager_dont_rollback(void*);
|
||||
void sqlite3pager_dont_write(Pager*, Pgno);
|
||||
int *sqlite3pager_stats(Pager*);
|
||||
void sqlite3pager_set_safety_level(Pager*,int);
|
||||
const char *sqlite3pager_filename(Pager*);
|
||||
const char *sqlite3pager_dirname(Pager*);
|
||||
const char *sqlite3pager_journalname(Pager*);
|
||||
int sqlite3pager_rename(Pager*, const char *zNewName);
|
||||
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
|
||||
int sqlite3pager_movepage(Pager*,void*,Pgno);
|
||||
int sqlite3pager_reset(Pager*);
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
int sqlite3pager_lockstate(Pager*);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
void sqlite3pager_refdump(Pager*);
|
||||
int pager3_refinfo_enable;
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,140 +0,0 @@
|
||||
#define TK_END_OF_FILE 1
|
||||
#define TK_ILLEGAL 2
|
||||
#define TK_SPACE 3
|
||||
#define TK_UNCLOSED_STRING 4
|
||||
#define TK_COMMENT 5
|
||||
#define TK_FUNCTION 6
|
||||
#define TK_COLUMN 7
|
||||
#define TK_AGG_FUNCTION 8
|
||||
#define TK_CONST_FUNC 9
|
||||
#define TK_SEMI 10
|
||||
#define TK_EXPLAIN 11
|
||||
#define TK_BEGIN 12
|
||||
#define TK_TRANSACTION 13
|
||||
#define TK_DEFERRED 14
|
||||
#define TK_IMMEDIATE 15
|
||||
#define TK_EXCLUSIVE 16
|
||||
#define TK_COMMIT 17
|
||||
#define TK_END 18
|
||||
#define TK_ROLLBACK 19
|
||||
#define TK_CREATE 20
|
||||
#define TK_TABLE 21
|
||||
#define TK_TEMP 22
|
||||
#define TK_LP 23
|
||||
#define TK_RP 24
|
||||
#define TK_AS 25
|
||||
#define TK_COMMA 26
|
||||
#define TK_ID 27
|
||||
#define TK_ABORT 28
|
||||
#define TK_AFTER 29
|
||||
#define TK_ASC 30
|
||||
#define TK_ATTACH 31
|
||||
#define TK_BEFORE 32
|
||||
#define TK_CASCADE 33
|
||||
#define TK_CONFLICT 34
|
||||
#define TK_DATABASE 35
|
||||
#define TK_DESC 36
|
||||
#define TK_DETACH 37
|
||||
#define TK_EACH 38
|
||||
#define TK_FAIL 39
|
||||
#define TK_FOR 40
|
||||
#define TK_IGNORE 41
|
||||
#define TK_INITIALLY 42
|
||||
#define TK_INSTEAD 43
|
||||
#define TK_LIKE_KW 44
|
||||
#define TK_MATCH 45
|
||||
#define TK_KEY 46
|
||||
#define TK_OF 47
|
||||
#define TK_OFFSET 48
|
||||
#define TK_PRAGMA 49
|
||||
#define TK_RAISE 50
|
||||
#define TK_REPLACE 51
|
||||
#define TK_RESTRICT 52
|
||||
#define TK_ROW 53
|
||||
#define TK_STATEMENT 54
|
||||
#define TK_TRIGGER 55
|
||||
#define TK_VACUUM 56
|
||||
#define TK_VIEW 57
|
||||
#define TK_REINDEX 58
|
||||
#define TK_RENAME 59
|
||||
#define TK_CTIME_KW 60
|
||||
#define TK_ALTER 61
|
||||
#define TK_OR 62
|
||||
#define TK_AND 63
|
||||
#define TK_NOT 64
|
||||
#define TK_IS 65
|
||||
#define TK_BETWEEN 66
|
||||
#define TK_IN 67
|
||||
#define TK_ISNULL 68
|
||||
#define TK_NOTNULL 69
|
||||
#define TK_NE 70
|
||||
#define TK_EQ 71
|
||||
#define TK_GT 72
|
||||
#define TK_LE 73
|
||||
#define TK_LT 74
|
||||
#define TK_GE 75
|
||||
#define TK_ESCAPE 76
|
||||
#define TK_BITAND 77
|
||||
#define TK_BITOR 78
|
||||
#define TK_LSHIFT 79
|
||||
#define TK_RSHIFT 80
|
||||
#define TK_PLUS 81
|
||||
#define TK_MINUS 82
|
||||
#define TK_STAR 83
|
||||
#define TK_SLASH 84
|
||||
#define TK_REM 85
|
||||
#define TK_CONCAT 86
|
||||
#define TK_UMINUS 87
|
||||
#define TK_UPLUS 88
|
||||
#define TK_BITNOT 89
|
||||
#define TK_STRING 90
|
||||
#define TK_JOIN_KW 91
|
||||
#define TK_CONSTRAINT 92
|
||||
#define TK_DEFAULT 93
|
||||
#define TK_NULL 94
|
||||
#define TK_PRIMARY 95
|
||||
#define TK_UNIQUE 96
|
||||
#define TK_CHECK 97
|
||||
#define TK_REFERENCES 98
|
||||
#define TK_COLLATE 99
|
||||
#define TK_AUTOINCR 100
|
||||
#define TK_ON 101
|
||||
#define TK_DELETE 102
|
||||
#define TK_UPDATE 103
|
||||
#define TK_INSERT 104
|
||||
#define TK_SET 105
|
||||
#define TK_DEFERRABLE 106
|
||||
#define TK_FOREIGN 107
|
||||
#define TK_DROP 108
|
||||
#define TK_UNION 109
|
||||
#define TK_ALL 110
|
||||
#define TK_INTERSECT 111
|
||||
#define TK_EXCEPT 112
|
||||
#define TK_SELECT 113
|
||||
#define TK_DISTINCT 114
|
||||
#define TK_DOT 115
|
||||
#define TK_FROM 116
|
||||
#define TK_JOIN 117
|
||||
#define TK_USING 118
|
||||
#define TK_ORDER 119
|
||||
#define TK_BY 120
|
||||
#define TK_GROUP 121
|
||||
#define TK_HAVING 122
|
||||
#define TK_LIMIT 123
|
||||
#define TK_WHERE 124
|
||||
#define TK_INTO 125
|
||||
#define TK_VALUES 126
|
||||
#define TK_INTEGER 127
|
||||
#define TK_FLOAT 128
|
||||
#define TK_BLOB 129
|
||||
#define TK_REGISTER 130
|
||||
#define TK_VARIABLE 131
|
||||
#define TK_EXISTS 132
|
||||
#define TK_CASE 133
|
||||
#define TK_WHEN 134
|
||||
#define TK_THEN 135
|
||||
#define TK_ELSE 136
|
||||
#define TK_INDEX 137
|
||||
#define TK_TO 138
|
||||
#define TK_ADD 139
|
||||
#define TK_COLUMNKW 140
|
||||
@@ -1,933 +0,0 @@
|
||||
/*
|
||||
** 2003 April 6
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the PRAGMA command.
|
||||
**
|
||||
** $Id: pragma.c,v 1.1.2.1 2005-06-20 23:27:49 relyea%netscape.com Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* Ignore this whole file if pragmas are disabled
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
# include "pager.h"
|
||||
# include "btree.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Interpret the given string as a safety level. Return 0 for OFF,
|
||||
** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
|
||||
** unrecognized string argument.
|
||||
**
|
||||
** Note that the values returned are one less that the values that
|
||||
** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
|
||||
** to support legacy SQL code. The safety level used to be boolean
|
||||
** and older scripts may have used numbers 0 for OFF and 1 for ON.
|
||||
*/
|
||||
static int getSafetyLevel(const u8 *z){
|
||||
/* 123456789 123456789 */
|
||||
static const char zText[] = "onoffalseyestruefull";
|
||||
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
|
||||
static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
|
||||
static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
|
||||
int i, n;
|
||||
if( isdigit(*z) ){
|
||||
return atoi(z);
|
||||
}
|
||||
n = strlen(z);
|
||||
for(i=0; i<sizeof(iLength); i++){
|
||||
if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
|
||||
return iValue[i];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Interpret the given string as a boolean value.
|
||||
*/
|
||||
static int getBoolean(const u8 *z){
|
||||
return getSafetyLevel(z)&1;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** Interpret the given string as a temp db location. Return 1 for file
|
||||
** backed temporary databases, 2 for the Red-Black tree in memory database
|
||||
** and 0 to use the compile-time default.
|
||||
*/
|
||||
static int getTempStore(const char *z){
|
||||
if( z[0]>='0' && z[0]<='2' ){
|
||||
return z[0] - '0';
|
||||
}else if( sqlite3StrICmp(z, "file")==0 ){
|
||||
return 1;
|
||||
}else if( sqlite3StrICmp(z, "memory")==0 ){
|
||||
return 2;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_PAGER_PRAGMAS */
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** Invalidate temp storage, either when the temp storage is changed
|
||||
** from default, or when 'file' and the temp_store_directory has changed
|
||||
*/
|
||||
static int invalidateTempStorage(Parse *pParse){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->aDb[1].pBt!=0 ){
|
||||
if( db->flags & SQLITE_InTrans ){
|
||||
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
|
||||
"from within a transaction");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
sqlite3BtreeClose(db->aDb[1].pBt);
|
||||
db->aDb[1].pBt = 0;
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_PAGER_PRAGMAS */
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** If the TEMP database is open, close it and mark the database schema
|
||||
** as needing reloading. This must be done when using the TEMP_STORE
|
||||
** or DEFAULT_TEMP_STORE pragmas.
|
||||
*/
|
||||
static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
int ts = getTempStore(zStorageType);
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->temp_store==ts ) return SQLITE_OK;
|
||||
if( invalidateTempStorage( pParse ) != SQLITE_OK ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
db->temp_store = ts;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_PAGER_PRAGMAS */
|
||||
|
||||
/*
|
||||
** Generate code to return a single integer value.
|
||||
*/
|
||||
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, value, 0);
|
||||
if( pParse->explain==0 ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
/*
|
||||
** Check to see if zRight and zLeft refer to a pragma that queries
|
||||
** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
|
||||
** Also, implement the pragma.
|
||||
*/
|
||||
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
static const struct sPragmaType {
|
||||
const char *zName; /* Name of the pragma */
|
||||
int mask; /* Mask for the db->flags value */
|
||||
} aPragma[] = {
|
||||
{ "vdbe_trace", SQLITE_VdbeTrace },
|
||||
{ "sql_trace", SQLITE_SqlTrace },
|
||||
{ "vdbe_listing", SQLITE_VdbeListing },
|
||||
{ "full_column_names", SQLITE_FullColNames },
|
||||
{ "short_column_names", SQLITE_ShortColNames },
|
||||
{ "count_changes", SQLITE_CountRows },
|
||||
{ "empty_result_callbacks", SQLITE_NullCallback },
|
||||
/* The following is VERY experimental */
|
||||
{ "writable_schema", SQLITE_WriteSchema },
|
||||
{ "omit_readlock", SQLITE_NoReadlock },
|
||||
};
|
||||
int i;
|
||||
const struct sPragmaType *p;
|
||||
for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
|
||||
if( sqlite3StrICmp(zLeft, p->zName)==0 ){
|
||||
sqlite3 *db = pParse->db;
|
||||
Vdbe *v;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v ){
|
||||
if( zRight==0 ){
|
||||
returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
|
||||
}else{
|
||||
if( getBoolean(zRight) ){
|
||||
db->flags |= p->mask;
|
||||
}else{
|
||||
db->flags &= ~p->mask;
|
||||
}
|
||||
}
|
||||
/* If one of these pragmas is executed, any prepared statements
|
||||
** need to be recompiled.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
** Pragmas are of this form:
|
||||
**
|
||||
** PRAGMA [database.]id [= value]
|
||||
**
|
||||
** The identifier might also be a string. The value is a string, and
|
||||
** identifier, or a number. If minusFlag is true, then the value is
|
||||
** a number that was preceded by a minus sign.
|
||||
**
|
||||
** If the left side is "database.id" then pId1 is the database name
|
||||
** and pId2 is the id. If the left side is just "id" then pId1 is the
|
||||
** id and pId2 is any empty string.
|
||||
*/
|
||||
void sqlite3Pragma(
|
||||
Parse *pParse,
|
||||
Token *pId1, /* First part of [database.]id field */
|
||||
Token *pId2, /* Second part of [database.]id field, or NULL */
|
||||
Token *pValue, /* Token for <value>, or NULL */
|
||||
int minusFlag /* True if a '-' sign preceded <value> */
|
||||
){
|
||||
char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
|
||||
char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
|
||||
const char *zDb = 0; /* The database name */
|
||||
Token *pId; /* Pointer to <id> token */
|
||||
int iDb; /* Database index for <database> */
|
||||
sqlite3 *db = pParse->db;
|
||||
Db *pDb;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) return;
|
||||
|
||||
/* Interpret the [database.] part of the pragma statement. iDb is the
|
||||
** index of the database this pragma is being applied to in db.aDb[]. */
|
||||
iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
|
||||
if( iDb<0 ) return;
|
||||
pDb = &db->aDb[iDb];
|
||||
|
||||
zLeft = sqlite3NameFromToken(pId);
|
||||
if( !zLeft ) return;
|
||||
if( minusFlag ){
|
||||
zRight = sqlite3MPrintf("-%T", pValue);
|
||||
}else{
|
||||
zRight = sqlite3NameFromToken(pValue);
|
||||
}
|
||||
|
||||
zDb = ((iDb>0)?pDb->zName:0);
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
|
||||
goto pragma_out;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** PRAGMA [database.]default_cache_size
|
||||
** PRAGMA [database.]default_cache_size=N
|
||||
**
|
||||
** The first form reports the current persistent setting for the
|
||||
** page cache size. The value returned is the maximum number of
|
||||
** pages in the page cache. The second form sets both the current
|
||||
** page cache size value and the persistent page cache size value
|
||||
** stored in the database file.
|
||||
**
|
||||
** The default cache size is stored in meta-value 2 of page 1 of the
|
||||
** database file. The cache size is actually the absolute value of
|
||||
** this memory location. The sign of meta-value 2 determines the
|
||||
** synchronous setting. A negative value means synchronous is off
|
||||
** and a positive value means synchronous is on.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
||||
static const VdbeOpList getCacheSize[] = {
|
||||
{ OP_ReadCookie, 0, 2, 0}, /* 0 */
|
||||
{ OP_AbsValue, 0, 0, 0},
|
||||
{ OP_Dup, 0, 0, 0},
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
{ OP_Ne, 0, 6, 0},
|
||||
{ OP_Integer, 0, 0, 0}, /* 5 */
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
int addr;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
if( !zRight ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
|
||||
}else{
|
||||
int size = atoi(zRight);
|
||||
if( size<0 ) size = -size;
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
|
||||
addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
|
||||
pDb->cache_size = size;
|
||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]page_size
|
||||
** PRAGMA [database.]page_size=N
|
||||
**
|
||||
** The first form reports the current setting for the
|
||||
** database page size in bytes. The second form sets the
|
||||
** database page size value. The value can only be set if
|
||||
** the database has not yet been created.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"page_size")==0 ){
|
||||
Btree *pBt = pDb->pBt;
|
||||
if( !zRight ){
|
||||
int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
|
||||
returnSingleInt(pParse, "page_size", size);
|
||||
}else{
|
||||
sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1);
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]auto_vacuum
|
||||
** PRAGMA [database.]auto_vacuum=N
|
||||
**
|
||||
** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
|
||||
Btree *pBt = pDb->pBt;
|
||||
if( !zRight ){
|
||||
int auto_vacuum =
|
||||
pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
|
||||
returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
|
||||
}else{
|
||||
sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight));
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** PRAGMA [database.]cache_size
|
||||
** PRAGMA [database.]cache_size=N
|
||||
**
|
||||
** The first form reports the current local setting for the
|
||||
** page cache size. The local setting can be different from
|
||||
** the persistent cache size value that is stored in the database
|
||||
** file itself. The value returned is the maximum number of
|
||||
** pages in the page cache. The second form sets the local
|
||||
** page cache size value. It does not change the persistent
|
||||
** cache size stored on the disk so the cache size will revert
|
||||
** to its default value when the database is closed and reopened.
|
||||
** N should be a positive integer.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "cache_size", pDb->cache_size);
|
||||
}else{
|
||||
int size = atoi(zRight);
|
||||
if( size<0 ) size = -size;
|
||||
pDb->cache_size = size;
|
||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA temp_store
|
||||
** PRAGMA temp_store = "default"|"memory"|"file"
|
||||
**
|
||||
** Return or set the local value of the temp_store flag. Changing
|
||||
** the local value does not make changes to the disk file and the default
|
||||
** value will be restored the next time the database is opened.
|
||||
**
|
||||
** Note that it is possible for the library compile-time options to
|
||||
** override this setting
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "temp_store", db->temp_store);
|
||||
}else{
|
||||
changeTempStorage(pParse, zRight);
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA temp_store_directory
|
||||
** PRAGMA temp_store_directory = ""|"directory_name"
|
||||
**
|
||||
** Return or set the local value of the temp_store_directory flag. Changing
|
||||
** the value sets a specific directory to be used for temporary files.
|
||||
** Setting to a null string reverts to the default temporary directory search.
|
||||
** If temporary directory is changed, then invalidateTempStorage.
|
||||
**
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
|
||||
if( !zRight ){
|
||||
if( sqlite3_temp_directory ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
}else{
|
||||
if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){
|
||||
sqlite3ErrorMsg(pParse, "not a writable directory");
|
||||
goto pragma_out;
|
||||
}
|
||||
if( TEMP_STORE==0
|
||||
|| (TEMP_STORE==1 && db->temp_store<=1)
|
||||
|| (TEMP_STORE==2 && db->temp_store==1)
|
||||
){
|
||||
invalidateTempStorage(pParse);
|
||||
}
|
||||
sqliteFree(sqlite3_temp_directory);
|
||||
if( zRight[0] ){
|
||||
sqlite3_temp_directory = zRight;
|
||||
zRight = 0;
|
||||
}else{
|
||||
sqlite3_temp_directory = 0;
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
/*
|
||||
** PRAGMA [database.]synchronous
|
||||
** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
|
||||
**
|
||||
** Return or set the local value of the synchronous flag. Changing
|
||||
** the local value does not make changes to the disk file and the
|
||||
** default value will be restored the next time the database is
|
||||
** opened.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
if( !zRight ){
|
||||
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
|
||||
}else{
|
||||
if( !db->autoCommit ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight)+1;
|
||||
sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||
|
||||
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
|
||||
if( flagPragma(pParse, zLeft, zRight) ){
|
||||
/* The flagPragma() subroutine also generates any necessary code
|
||||
** there is nothing more to do here */
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
|
||||
|
||||
#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
|
||||
/*
|
||||
** PRAGMA table_info(<table>)
|
||||
**
|
||||
** Return a single row for each column of the named table. The columns of
|
||||
** the returned data set are:
|
||||
**
|
||||
** cid: Column id (numbered from left to right, starting at 0)
|
||||
** name: Column name
|
||||
** type: Column declaration type.
|
||||
** notnull: True if 'NOT NULL' is part of column declaration
|
||||
** dflt_value: The default value for the column, if any.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
|
||||
Table *pTab;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
int i;
|
||||
sqlite3VdbeSetNumCols(v, 6);
|
||||
sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
||||
pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
|
||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
pIdx = sqlite3FindIndex(db, zRight, zDb);
|
||||
if( pIdx ){
|
||||
int i;
|
||||
pTab = pIdx->pTable;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
int cnum = pIdx->aiColumn[i];
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
|
||||
assert( pTab->nCol>cnum );
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pIdx = pTab->pIndex;
|
||||
if( pIdx ){
|
||||
int i = 0;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
|
||||
while(pIdx){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
++i;
|
||||
pIdx = pIdx->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqlite3StrICmp(zLeft, "database_list")==0 ){
|
||||
int i;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
sqlite3VdbeSetNumCols(v, 3);
|
||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt==0 ) continue;
|
||||
assert( db->aDb[i].zName!=0 );
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
||||
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
|
||||
int i = 0;
|
||||
HashElem *p;
|
||||
sqlite3VdbeSetNumCols(v, 2);
|
||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
||||
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
|
||||
|
||||
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
||||
if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
|
||||
FKey *pFK;
|
||||
Table *pTab;
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
if( pTab ){
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pFK = pTab->pFKey;
|
||||
if( pFK ){
|
||||
int i = 0;
|
||||
sqlite3VdbeSetNumCols(v, 5);
|
||||
sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
|
||||
while(pFK){
|
||||
int j;
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, j, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
||||
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->aCol[j].zCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
|
||||
}
|
||||
++i;
|
||||
pFK = pFK->pNextFrom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
|
||||
|
||||
#ifndef NDEBUG
|
||||
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
|
||||
extern void sqlite3ParserTrace(FILE*, char *);
|
||||
if( getBoolean(zRight) ){
|
||||
sqlite3ParserTrace(stdout, "parser: ");
|
||||
}else{
|
||||
sqlite3ParserTrace(0, 0);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
|
||||
int i, j, addr;
|
||||
|
||||
/* Code that initializes the integrity check program. Set the
|
||||
** error count 0
|
||||
*/
|
||||
static const VdbeOpList initCode[] = {
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
{ OP_MemStore, 0, 1, 0},
|
||||
};
|
||||
|
||||
/* Code that appears at the end of the integrity check. If no error
|
||||
** messages have been generated, output OK. Otherwise output the
|
||||
** error message
|
||||
*/
|
||||
static const VdbeOpList endCode[] = {
|
||||
{ OP_MemLoad, 0, 0, 0},
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
{ OP_Ne, 0, 0, 0}, /* 2 */
|
||||
{ OP_String8, 0, 0, "ok"},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
|
||||
/* Initialize the VDBE program */
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
HashElem *x;
|
||||
int cnt = 0;
|
||||
|
||||
if( OMIT_TEMPDB && i==1 ) continue;
|
||||
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
|
||||
/* Do an integrity check of the B-Tree
|
||||
*/
|
||||
for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx;
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
|
||||
cnt++;
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
assert( cnt>0 );
|
||||
sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
|
||||
addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0,
|
||||
sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
|
||||
P3_DYNAMIC);
|
||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
|
||||
/* Make sure all the indices are constructed correctly.
|
||||
*/
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx;
|
||||
int loopTop;
|
||||
|
||||
if( pTab->pIndex==0 ) continue;
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
|
||||
loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
int jmp2;
|
||||
static const VdbeOpList idxErr[] = {
|
||||
{ OP_MemIncr, 0, 0, 0},
|
||||
{ OP_String8, 0, 0, "rowid "},
|
||||
{ OP_Rowid, 1, 0, 0},
|
||||
{ OP_String8, 0, 0, " missing from index "},
|
||||
{ OP_String8, 0, 0, 0}, /* 4 */
|
||||
{ OP_Concat, 2, 0, 0},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
sqlite3GenerateIndexKey(v, pIdx, 1);
|
||||
jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
||||
sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
|
||||
sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
|
||||
sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
static const VdbeOpList cntIdx[] = {
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
{ OP_MemStore, 2, 1, 0},
|
||||
{ OP_Rewind, 0, 0, 0}, /* 2 */
|
||||
{ OP_MemIncr, 2, 0, 0},
|
||||
{ OP_Next, 0, 0, 0}, /* 4 */
|
||||
{ OP_MemLoad, 1, 0, 0},
|
||||
{ OP_MemLoad, 2, 0, 0},
|
||||
{ OP_Eq, 0, 0, 0}, /* 7 */
|
||||
{ OP_MemIncr, 0, 0, 0},
|
||||
{ OP_String8, 0, 0, "wrong # of entries in index "},
|
||||
{ OP_String8, 0, 0, 0}, /* 10 */
|
||||
{ OP_Concat, 0, 0, 0},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
if( pIdx->tnum==0 ) continue;
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
||||
sqlite3VdbeChangeP1(v, addr+2, j+2);
|
||||
sqlite3VdbeChangeP2(v, addr+2, addr+5);
|
||||
sqlite3VdbeChangeP1(v, addr+4, j+2);
|
||||
sqlite3VdbeChangeP2(v, addr+4, addr+3);
|
||||
sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
|
||||
sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
|
||||
sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
/*
|
||||
** PRAGMA encoding
|
||||
** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
|
||||
**
|
||||
** In it's first form, this pragma returns the encoding of the main
|
||||
** database. If the database is not initialized, it is initialized now.
|
||||
**
|
||||
** The second form of this pragma is a no-op if the main database file
|
||||
** has not already been initialized. In this case it sets the default
|
||||
** encoding that will be used for the main database file if a new file
|
||||
** is created. If an existing main database file is opened, then the
|
||||
** default text encoding for the existing database is used.
|
||||
**
|
||||
** In all cases new databases created using the ATTACH command are
|
||||
** created to use the same default text encoding as the main database. If
|
||||
** the main database has not been initialized and/or created when ATTACH
|
||||
** is executed, this is done before the ATTACH operation.
|
||||
**
|
||||
** In the second form this pragma sets the text encoding to be used in
|
||||
** new database files created using this database handle. It is only
|
||||
** useful if invoked immediately after the main database i
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "encoding")==0 ){
|
||||
static struct EncName {
|
||||
char *zName;
|
||||
u8 enc;
|
||||
} encnames[] = {
|
||||
{ "UTF-8", SQLITE_UTF8 },
|
||||
{ "UTF8", SQLITE_UTF8 },
|
||||
{ "UTF-16le", SQLITE_UTF16LE },
|
||||
{ "UTF16le", SQLITE_UTF16LE },
|
||||
{ "UTF-16be", SQLITE_UTF16BE },
|
||||
{ "UTF16be", SQLITE_UTF16BE },
|
||||
{ "UTF-16", 0 /* Filled in at run-time */ },
|
||||
{ "UTF16", 0 /* Filled in at run-time */ },
|
||||
{ 0, 0 }
|
||||
};
|
||||
struct EncName *pEnc;
|
||||
encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
|
||||
if( !zRight ){ /* "PRAGMA encoding" */
|
||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||
if( pEnc->enc==pParse->db->enc ){
|
||||
sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}else{ /* "PRAGMA encoding = XXX" */
|
||||
/* Only change the value of sqlite.enc if the database handle is not
|
||||
** initialized. If the main database exists, the new sqlite.enc value
|
||||
** will be overwritten when the schema is next loaded. If it does not
|
||||
** already exists, it will be created to use the new encoding value.
|
||||
*/
|
||||
if( !(pParse->db->flags&SQLITE_Initialized) ){
|
||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
|
||||
pParse->db->enc = pEnc->enc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !pEnc->zName ){
|
||||
sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
|
||||
#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
|
||||
/*
|
||||
** PRAGMA [database.]schema_version
|
||||
** PRAGMA [database.]schema_version = <integer>
|
||||
**
|
||||
** PRAGMA [database.]user_version
|
||||
** PRAGMA [database.]user_version = <integer>
|
||||
**
|
||||
** The pragma's schema_version and user_version are used to set or get
|
||||
** the value of the schema-version and user-version, respectively. Both
|
||||
** the schema-version and the user-version are 32-bit signed integers
|
||||
** stored in the database header.
|
||||
**
|
||||
** The schema-cookie is usually only manipulated internally by SQLite. It
|
||||
** is incremented by SQLite whenever the database schema is modified (by
|
||||
** creating or dropping a table or index). The schema version is used by
|
||||
** SQLite each time a query is executed to ensure that the internal cache
|
||||
** of the schema used when compiling the SQL query matches the schema of
|
||||
** the database against which the compiled query is actually executed.
|
||||
** Subverting this mechanism by using "PRAGMA schema_version" to modify
|
||||
** the schema-version is potentially dangerous and may lead to program
|
||||
** crashes or database corruption. Use with caution!
|
||||
**
|
||||
** The user-version is not used internally by SQLite. It may be used by
|
||||
** applications for any purpose.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "schema_version")==0 ||
|
||||
sqlite3StrICmp(zLeft, "user_version")==0 ){
|
||||
|
||||
int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
|
||||
if( zLeft[0]=='s' || zLeft[0]=='S' ){
|
||||
iCookie = 0;
|
||||
}else{
|
||||
iCookie = 5;
|
||||
}
|
||||
|
||||
if( zRight ){
|
||||
/* Write the specified cookie value */
|
||||
static const VdbeOpList setCookie[] = {
|
||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||
{ OP_Integer, 0, 0, 0}, /* 1 */
|
||||
{ OP_SetCookie, 0, 0, 0}, /* 2 */
|
||||
};
|
||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
|
||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||
sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
|
||||
sqlite3VdbeChangeP1(v, addr+2, iDb);
|
||||
sqlite3VdbeChangeP2(v, addr+2, iCookie);
|
||||
}else{
|
||||
/* Read the specified cookie value */
|
||||
static const VdbeOpList readCookie[] = {
|
||||
{ OP_ReadCookie, 0, 0, 0}, /* 0 */
|
||||
{ OP_Callback, 1, 0, 0}
|
||||
};
|
||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
|
||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||
sqlite3VdbeChangeP2(v, addr, iCookie);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
/*
|
||||
** Report the current state of file logs for all databases
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
|
||||
static const char *const azLockName[] = {
|
||||
"unlocked", "shared", "reserved", "pending", "exclusive"
|
||||
};
|
||||
int i;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 2);
|
||||
sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *pBt;
|
||||
Pager *pPager;
|
||||
if( db->aDb[i].zName==0 ) continue;
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);
|
||||
pBt = db->aDb[i].pBt;
|
||||
if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);
|
||||
}else{
|
||||
int j = sqlite3pager_lockstate(pPager);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0,
|
||||
(j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_SSE
|
||||
/*
|
||||
** Check to see if the sqlite_statements table exists. Create it
|
||||
** if it does not.
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){
|
||||
extern int sqlite3CreateStatementsTable(Parse*);
|
||||
sqlite3CreateStatementsTable(pParse);
|
||||
}else
|
||||
#endif
|
||||
|
||||
{}
|
||||
|
||||
if( v ){
|
||||
/* Code an OP_Expire at the end of each PRAGMA program to cause
|
||||
** the VDBE implementing the pragma to expire. Most (all?) pragmas
|
||||
** are only valid for a single execution.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
|
||||
}
|
||||
pragma_out:
|
||||
sqliteFree(zLeft);
|
||||
sqliteFree(zRight);
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user