mirror of
https://gitlab.archlinux.org/pacman/pacman.git
synced 2025-11-03 08:54:41 +01:00
Compare commits
963 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c633c27ea | ||
|
|
fdf53393bc | ||
|
|
34d8beaef8 | ||
|
|
d39271ab56 | ||
|
|
831cc8d9cd | ||
|
|
e708b606ae | ||
|
|
cd8debfbfb | ||
|
|
0fd8455c66 | ||
|
|
908769b540 | ||
|
|
33dbe13a6b | ||
|
|
7bb1c73cfa | ||
|
|
c2aed8aaff | ||
|
|
80a0016de4 | ||
|
|
722be61ca8 | ||
|
|
5de2ad13fd | ||
|
|
c889403cf7 | ||
|
|
537f8c881c | ||
|
|
f6ccb46dc9 | ||
|
|
7cc5012549 | ||
|
|
22cadea56a | ||
|
|
eca2e0f5ed | ||
|
|
1f3793e71a | ||
|
|
9e3aeb30d3 | ||
|
|
5a7204ee18 | ||
|
|
d6b6896a13 | ||
|
|
31af485d7e | ||
|
|
4024bf0490 | ||
|
|
6d5c70cf93 | ||
|
|
e20a502c40 | ||
|
|
2e7162fe87 | ||
|
|
cebb20762d | ||
|
|
e770b5728b | ||
|
|
21fe34c3a1 | ||
|
|
3218360114 | ||
|
|
8abb0cbf0e | ||
|
|
e03c539288 | ||
|
|
f31792adb5 | ||
|
|
f84d0a8282 | ||
|
|
689c413b96 | ||
|
|
b9bf727e33 | ||
|
|
2f1797783e | ||
|
|
a9bec8bed8 | ||
|
|
a5c23f0643 | ||
|
|
fcf4da76e0 | ||
|
|
d6ea5bd26d | ||
|
|
cd7acd7529 | ||
|
|
9bddaac93c | ||
|
|
5211118a06 | ||
|
|
c6e46c9ebb | ||
|
|
c2f9758018 | ||
|
|
5469161dad | ||
|
|
07ccbc2691 | ||
|
|
a66cba1b08 | ||
|
|
d4f499f563 | ||
|
|
df5dc0c9de | ||
|
|
f38de43eb6 | ||
|
|
9375715ae4 | ||
|
|
e2ca25623b | ||
|
|
cd4a3d03a0 | ||
|
|
5c136d85db | ||
|
|
c034a3322b | ||
|
|
a724235b61 | ||
|
|
1d6583a58d | ||
|
|
ce1f453b74 | ||
|
|
2ee7a8d89a | ||
|
|
f63854fa96 | ||
|
|
83c7dc80cb | ||
|
|
fd936c9e73 | ||
|
|
169287e494 | ||
|
|
7624101e18 | ||
|
|
a1a8d067e0 | ||
|
|
7cf5e1aebf | ||
|
|
c72ca3d539 | ||
|
|
3cb1669e07 | ||
|
|
0fa695d0e3 | ||
|
|
50a2db4834 | ||
|
|
fb72eede20 | ||
|
|
c1bb41a037 | ||
|
|
252183b409 | ||
|
|
fea9abc8db | ||
|
|
e910d45ac0 | ||
|
|
9604570add | ||
|
|
6ea97963b3 | ||
|
|
5343ec7661 | ||
|
|
43a09d1663 | ||
|
|
b65c7afc17 | ||
|
|
c781a85387 | ||
|
|
a5a9080219 | ||
|
|
18d00097a2 | ||
|
|
599520e489 | ||
|
|
4291500c82 | ||
|
|
47ea63ff3b | ||
|
|
765e29b67c | ||
|
|
ad65462a05 | ||
|
|
9ff29545e5 | ||
|
|
8d9890d3f4 | ||
|
|
ab50864a75 | ||
|
|
9813107c33 | ||
|
|
00c0329531 | ||
|
|
88f348f2b1 | ||
|
|
875c017e4d | ||
|
|
2a0d188d6b | ||
|
|
fa72c2cdc2 | ||
|
|
4742f5929d | ||
|
|
8ca96447dd | ||
|
|
6aee32102f | ||
|
|
774c7eb24d | ||
|
|
a671fa497c | ||
|
|
eadf389607 | ||
|
|
8454daa7fe | ||
|
|
686fae6d74 | ||
|
|
d721bae443 | ||
|
|
760bea5432 | ||
|
|
8d3bd4ec13 | ||
|
|
132ec4c3b9 | ||
|
|
3802cab563 | ||
|
|
f98541400b | ||
|
|
2015f0d1d9 | ||
|
|
137ea39fa1 | ||
|
|
9cdfd18739 | ||
|
|
71f9de64c6 | ||
|
|
8ee084dbb3 | ||
|
|
d069d9714a | ||
|
|
a8e2578feb | ||
|
|
b8a7277061 | ||
|
|
8089081ef9 | ||
|
|
c74495a3b2 | ||
|
|
4d2317dafb | ||
|
|
220a3ce2b8 | ||
|
|
8d11aa3cdf | ||
|
|
85508b478e | ||
|
|
7fb8a299c2 | ||
|
|
7b6f7bbe09 | ||
|
|
16623a7ea5 | ||
|
|
4838d250e5 | ||
|
|
bb5e6c3b76 | ||
|
|
8a373096f5 | ||
|
|
088649534e | ||
|
|
dfa4dcb16d | ||
|
|
34bbe4cf7b | ||
|
|
5312e683fc | ||
|
|
8ad893732d | ||
|
|
b42d0852f3 | ||
|
|
e0607f6ae2 | ||
|
|
e03fa67445 | ||
|
|
23f128ad5e | ||
|
|
663c74150a | ||
|
|
ef1fb0ef81 | ||
|
|
c26e5b81e5 | ||
|
|
947dfda515 | ||
|
|
9e22e75fa1 | ||
|
|
bf0e8e6b43 | ||
|
|
8fa02036c3 | ||
|
|
726712aa08 | ||
|
|
978b197120 | ||
|
|
0d877ec429 | ||
|
|
08b0b6de96 | ||
|
|
556c56d4d5 | ||
|
|
6eac7258cd | ||
|
|
0fd6d354a6 | ||
|
|
d5b0f0c26f | ||
|
|
906dc0ce24 | ||
|
|
697377aae3 | ||
|
|
d8621b981e | ||
|
|
dcc1b22cb3 | ||
|
|
1142a32c7f | ||
|
|
960b64553d | ||
|
|
6fdc589fc6 | ||
|
|
5b6526a2ad | ||
|
|
b46bdeea14 | ||
|
|
3c67127018 | ||
|
|
0c5dbdbfec | ||
|
|
4c5bf09eec | ||
|
|
456ebe8f8e | ||
|
|
9809102237 | ||
|
|
e28aff4d87 | ||
|
|
aa8a674b6b | ||
|
|
19d373c9b9 | ||
|
|
4b3df10d5d | ||
|
|
2c72c8b822 | ||
|
|
2627b423ff | ||
|
|
70e6875ad9 | ||
|
|
5d4a3f101c | ||
|
|
5301d3fe8f | ||
|
|
29d4dcf767 | ||
|
|
501242a35b | ||
|
|
0ee1beca12 | ||
|
|
c99ebca83e | ||
|
|
002acb4674 | ||
|
|
cbb7e180c7 | ||
|
|
a5759cb0d7 | ||
|
|
b76409609c | ||
|
|
4ceb1c5bf9 | ||
|
|
60ebee7a6e | ||
|
|
7000bf9198 | ||
|
|
e8e872c8f9 | ||
|
|
16718a216e | ||
|
|
568a89d580 | ||
|
|
c261210ccf | ||
|
|
46a1ac6429 | ||
|
|
e8deba3b87 | ||
|
|
0adb74b293 | ||
|
|
dd3fe853b3 | ||
|
|
19e61a9e07 | ||
|
|
be503c6eac | ||
|
|
6946d7d1b7 | ||
|
|
af747ef34a | ||
|
|
edbe6c2bdc | ||
|
|
75fe6ef104 | ||
|
|
486643083c | ||
|
|
1586b23080 | ||
|
|
ec50ec8a15 | ||
|
|
5780350751 | ||
|
|
ae97082e98 | ||
|
|
48f4efd9a1 | ||
|
|
ccd3a3eb9f | ||
|
|
1ee2032b7f | ||
|
|
2d0e2bf255 | ||
|
|
b8c9385b8b | ||
|
|
877578762c | ||
|
|
8566034866 | ||
|
|
deac973188 | ||
|
|
445aa3b52c | ||
|
|
bbab90836b | ||
|
|
3c41030964 | ||
|
|
fd9ff672b0 | ||
|
|
acf95f6b3b | ||
|
|
137a4086de | ||
|
|
488ca24265 | ||
|
|
5782b8356c | ||
|
|
e49abc9860 | ||
|
|
b0dac754d2 | ||
|
|
289fdf0d1d | ||
|
|
f6c55b3c3f | ||
|
|
1ada16f017 | ||
|
|
2d7a41539b | ||
|
|
94204d1089 | ||
|
|
ff487212a2 | ||
|
|
2e5e496eb0 | ||
|
|
a187fa4562 | ||
|
|
4b0bc2cf97 | ||
|
|
aa9aa343cb | ||
|
|
2bed2090fb | ||
|
|
53d9633449 | ||
|
|
0f302df5ed | ||
|
|
3d4529335c | ||
|
|
1a17249159 | ||
|
|
366adc3bb0 | ||
|
|
23e3c48526 | ||
|
|
15b6cecdd5 | ||
|
|
8ab106eb9b | ||
|
|
61dd7e03be | ||
|
|
dbbe76b83d | ||
|
|
9302593cfb | ||
|
|
c9a7b7e0bf | ||
|
|
d38c098787 | ||
|
|
83b734a103 | ||
|
|
d5536d3eb3 | ||
|
|
d568a4335b | ||
|
|
99c7b1b088 | ||
|
|
9a9e0203de | ||
|
|
1545a04253 | ||
|
|
e4af5e3c97 | ||
|
|
ae7067440c | ||
|
|
f9423cfa5d | ||
|
|
1040ad4e71 | ||
|
|
b0ae59724e | ||
|
|
d4e5de4bf6 | ||
|
|
54067c390f | ||
|
|
4dbac804a3 | ||
|
|
4e6848dbea | ||
|
|
e374e6829c | ||
|
|
721b785e73 | ||
|
|
edeafcc988 | ||
|
|
bf3aec8c32 | ||
|
|
b520c6312f | ||
|
|
2408d46c1b | ||
|
|
eb5da52c0e | ||
|
|
b630f455d2 | ||
|
|
cb0f2bd038 | ||
|
|
30c9dbcdeb | ||
|
|
6aef45ee1a | ||
|
|
81d233b793 | ||
|
|
d2cb52de12 | ||
|
|
f3fc9af2b7 | ||
|
|
e7e0c13762 | ||
|
|
b543c055b9 | ||
|
|
b8f2d713e0 | ||
|
|
eb21e9eb93 | ||
|
|
f34e48a988 | ||
|
|
f9cb4f3b9c | ||
|
|
22a5128985 | ||
|
|
0aded7487f | ||
|
|
156d41a186 | ||
|
|
ba532bda6b | ||
|
|
ff8de12151 | ||
|
|
965539adbf | ||
|
|
bb94729c09 | ||
|
|
8f92fe47a7 | ||
|
|
578ceb29fa | ||
|
|
9f1c5f0251 | ||
|
|
d9b5cb238d | ||
|
|
fc5be14dac | ||
|
|
2108d95526 | ||
|
|
008bd33e38 | ||
|
|
92b8c09000 | ||
|
|
7879a5b3e5 | ||
|
|
068f8cec42 | ||
|
|
e0f889e2ea | ||
|
|
5baec6d5e9 | ||
|
|
97fb8ada30 | ||
|
|
0927206fc4 | ||
|
|
adc6ca1f2c | ||
|
|
00da25a5ea | ||
|
|
bfe9b56e1f | ||
|
|
68602f4931 | ||
|
|
dff6982c83 | ||
|
|
660bd1caa1 | ||
|
|
3c46420367 | ||
|
|
cf3d5e4830 | ||
|
|
b5b2f0b1bf | ||
|
|
27e3125c8d | ||
|
|
ba869597fb | ||
|
|
0c9f4329f8 | ||
|
|
43413894d4 | ||
|
|
c3161925c2 | ||
|
|
295a3491ad | ||
|
|
33466000d6 | ||
|
|
c8574baa7c | ||
|
|
7885931c96 | ||
|
|
9917930ae1 | ||
|
|
bd2e95b00b | ||
|
|
2e48101999 | ||
|
|
325be32acd | ||
|
|
bbac318d7a | ||
|
|
54c630f6ec | ||
|
|
10fc538c70 | ||
|
|
841e531c51 | ||
|
|
3b22183a4d | ||
|
|
8391716b8a | ||
|
|
aa12a773b8 | ||
|
|
50de87e0e6 | ||
|
|
5167160c0c | ||
|
|
ba0d225d93 | ||
|
|
926280cfc7 | ||
|
|
a82a5cf3f7 | ||
|
|
4ba0561fe7 | ||
|
|
f917a4a55a | ||
|
|
63660afbc7 | ||
|
|
3b20561748 | ||
|
|
ea96b56722 | ||
|
|
e7d8e2b5ac | ||
|
|
4ccafc484d | ||
|
|
09cfe2a4c0 | ||
|
|
9eb07a81fa | ||
|
|
7ed0d60a0d | ||
|
|
95121cc4f1 | ||
|
|
2aa85c3bfd | ||
|
|
92febc847c | ||
|
|
c6263da168 | ||
|
|
21281e9b69 | ||
|
|
018fa2b48c | ||
|
|
a31426d3ea | ||
|
|
0108884952 | ||
|
|
d5f703729f | ||
|
|
bd2473797e | ||
|
|
6201f6e5ac | ||
|
|
4dd9ccbc78 | ||
|
|
17ad845c41 | ||
|
|
287f7a575e | ||
|
|
dfacd8473e | ||
|
|
107eabdfb3 | ||
|
|
207ba1e05f | ||
|
|
ca5af32b99 | ||
|
|
f617b6acd4 | ||
|
|
77ca6e4062 | ||
|
|
e8d757b6ba | ||
|
|
fb9db2df5d | ||
|
|
83d5512bf1 | ||
|
|
9e5e86aa14 | ||
|
|
95da285f56 | ||
|
|
8da9be0955 | ||
|
|
4060c5c77f | ||
|
|
0acd794226 | ||
|
|
62d5a71fba | ||
|
|
aa4c61f999 | ||
|
|
e8a3e3d81a | ||
|
|
194dea2de1 | ||
|
|
fafcbdeb8c | ||
|
|
89b9e9d1dc | ||
|
|
80e6d8a6fe | ||
|
|
ca5a2771ae | ||
|
|
39fe2d0e39 | ||
|
|
f1e010a5a7 | ||
|
|
29c0d8233b | ||
|
|
4c4890dd1c | ||
|
|
2759858e8c | ||
|
|
acc639adf2 | ||
|
|
6356567ae0 | ||
|
|
7c0ff7f4b7 | ||
|
|
763fb3d9e7 | ||
|
|
804688ab6a | ||
|
|
2f0ca00e55 | ||
|
|
60d958c78b | ||
|
|
be4198b34e | ||
|
|
32413213cb | ||
|
|
d5e93e895b | ||
|
|
25b492aab6 | ||
|
|
5221440b6b | ||
|
|
286dc83451 | ||
|
|
1f1e53c208 | ||
|
|
9f527d2de4 | ||
|
|
fda599df37 | ||
|
|
21faf1682e | ||
|
|
2114ef1874 | ||
|
|
9cf1b2c004 | ||
|
|
88eedef6c6 | ||
|
|
52d2ff648d | ||
|
|
123ecb8e07 | ||
|
|
c6dd581ec5 | ||
|
|
27506aba8f | ||
|
|
46459da39b | ||
|
|
895780bd9a | ||
|
|
87e55a4ee7 | ||
|
|
cd5e4b89f4 | ||
|
|
e892234207 | ||
|
|
f4796c905c | ||
|
|
eac09e1d9f | ||
|
|
c0d9d26070 | ||
|
|
32ebd7ad5d | ||
|
|
bf06efaa78 | ||
|
|
eb7cc246c6 | ||
|
|
c9ca363431 | ||
|
|
863cfb5808 | ||
|
|
d2d00e4543 | ||
|
|
c07593c64c | ||
|
|
a1c50a08c9 | ||
|
|
325e20dea1 | ||
|
|
23850c7c99 | ||
|
|
c8448bb466 | ||
|
|
ec679e09b2 | ||
|
|
a7c1b7a914 | ||
|
|
91a56a7072 | ||
|
|
d107aced37 | ||
|
|
565c931e2c | ||
|
|
bc6ada0877 | ||
|
|
54db3745d6 | ||
|
|
14dc3389fd | ||
|
|
c9e9c1ccfd | ||
|
|
3af0268fdb | ||
|
|
df36fe2e79 | ||
|
|
768b65e934 | ||
|
|
16259d728e | ||
|
|
0cd174efd5 | ||
|
|
a4b23417f9 | ||
|
|
c54af84180 | ||
|
|
ed4032a908 | ||
|
|
41c8263ba2 | ||
|
|
bb878217cd | ||
|
|
04bc3a24eb | ||
|
|
c23ff87893 | ||
|
|
ef0577e3d5 | ||
|
|
3446453c72 | ||
|
|
193b2b33f8 | ||
|
|
db402d6029 | ||
|
|
eda65967ec | ||
|
|
96e9cf35f1 | ||
|
|
5d11605958 | ||
|
|
5d618438c4 | ||
|
|
a7298c36fd | ||
|
|
d9aa7025ea | ||
|
|
8c00dd7341 | ||
|
|
4c1f41a7c1 | ||
|
|
0d24994934 | ||
|
|
6949012590 | ||
|
|
db2562113b | ||
|
|
be3ce88bb2 | ||
|
|
f66ae5334e | ||
|
|
f6b3c9d803 | ||
|
|
ecf0e37fc5 | ||
|
|
6029a77ac0 | ||
|
|
bd746568f6 | ||
|
|
03aa44a3ec | ||
|
|
f77933ea1e | ||
|
|
9594f513a4 | ||
|
|
37aeb43644 | ||
|
|
de442b6867 | ||
|
|
167a598265 | ||
|
|
bd744d067d | ||
|
|
8cd41ec62b | ||
|
|
4114e25df1 | ||
|
|
1e0b2f6629 | ||
|
|
566dc23357 | ||
|
|
75c80caebc | ||
|
|
82208c0239 | ||
|
|
9d4d81783d | ||
|
|
d649dc669d | ||
|
|
91876c21f1 | ||
|
|
44bcb73327 | ||
|
|
d6785a5726 | ||
|
|
d8f395fb56 | ||
|
|
11dff8a50e | ||
|
|
9d96bed9d6 | ||
|
|
a0cfed7df2 | ||
|
|
627ede8779 | ||
|
|
c1d6cec2e2 | ||
|
|
42c859e4cc | ||
|
|
01beca5df7 | ||
|
|
7ddc967d7c | ||
|
|
6dd593c293 | ||
|
|
19c3179b7e | ||
|
|
62c11e450a | ||
|
|
3f0303dc92 | ||
|
|
926d998a75 | ||
|
|
faf0246437 | ||
|
|
5002227296 | ||
|
|
1e3c088c2e | ||
|
|
ca8319aec9 | ||
|
|
7ee01c8666 | ||
|
|
aec4241af2 | ||
|
|
e123e04741 | ||
|
|
04e8048725 | ||
|
|
4e263f24c6 | ||
|
|
13c9745302 | ||
|
|
b275e5184e | ||
|
|
dc339faf6a | ||
|
|
50296576d0 | ||
|
|
60c1f2857b | ||
|
|
699937e94d | ||
|
|
cb9489119e | ||
|
|
235562a85e | ||
|
|
963f7fe02f | ||
|
|
51353edc61 | ||
|
|
a3d7230e4d | ||
|
|
b52ed49d75 | ||
|
|
31b9862600 | ||
|
|
24e0bd215c | ||
|
|
c792262b13 | ||
|
|
9c066dff43 | ||
|
|
85c055da73 | ||
|
|
e1f6fe652d | ||
|
|
eab8cf6241 | ||
|
|
f0c351b3fa | ||
|
|
d02efd2f20 | ||
|
|
1660ed3cf9 | ||
|
|
7e9ad22ac2 | ||
|
|
d3f5ab0e70 | ||
|
|
793b9c3b42 | ||
|
|
e4773b1b82 | ||
|
|
8bf2c753f5 | ||
|
|
d9cf14ff1d | ||
|
|
ee207d7c7b | ||
|
|
95e1a1ef82 | ||
|
|
38b6de937c | ||
|
|
8122fae51a | ||
|
|
b00269d9c8 | ||
|
|
879e4665c4 | ||
|
|
3e19cd366a | ||
|
|
ab07dfdeb9 | ||
|
|
37634d22e5 | ||
|
|
db14815f46 | ||
|
|
99a5017f55 | ||
|
|
17ed9eb734 | ||
|
|
2b556d89de | ||
|
|
cbd6c300b5 | ||
|
|
8d5d7f6761 | ||
|
|
8a02abcf19 | ||
|
|
b694d84554 | ||
|
|
1431d244f7 | ||
|
|
574e45df28 | ||
|
|
7c75564af9 | ||
|
|
2025279eb6 | ||
|
|
d981f93f18 | ||
|
|
4ccf49d3e7 | ||
|
|
0bf4ae726d | ||
|
|
03b9bf08ac | ||
|
|
7f1360b440 | ||
|
|
f4992960ad | ||
|
|
0c43198ee0 | ||
|
|
22e478d203 | ||
|
|
85c80542a5 | ||
|
|
32413ad44b | ||
|
|
dce82f9d19 | ||
|
|
7e87614665 | ||
|
|
fbb0945bfb | ||
|
|
9506409c3f | ||
|
|
71da296d01 | ||
|
|
c3835c157a | ||
|
|
bbeced26f6 | ||
|
|
e8de265f80 | ||
|
|
0e2db97a42 | ||
|
|
79548e0d78 | ||
|
|
73717f89df | ||
|
|
6650c43fca | ||
|
|
0c5e80c3b4 | ||
|
|
80eca94c8e | ||
|
|
0e18cefe38 | ||
|
|
300dd62e0a | ||
|
|
7305768d54 | ||
|
|
e0a7682607 | ||
|
|
e05fd5e060 | ||
|
|
357b9a24a9 | ||
|
|
07647d3d43 | ||
|
|
fa0c1e1419 | ||
|
|
8dbb80cfe9 | ||
|
|
f1fadecfb3 | ||
|
|
d06d993d56 | ||
|
|
7b41952bfc | ||
|
|
537a335cc7 | ||
|
|
9ff6dc93af | ||
|
|
d920e7053c | ||
|
|
b9f98ae97c | ||
|
|
4d65332ccd | ||
|
|
235ce32563 | ||
|
|
2401468f51 | ||
|
|
ec01a22f7d | ||
|
|
d39d3b3a09 | ||
|
|
d174cc8943 | ||
|
|
34ae6ce4e5 | ||
|
|
7a5e41925f | ||
|
|
b929e74f2e | ||
|
|
060d06d2f7 | ||
|
|
00fbdabc55 | ||
|
|
80d3709e65 | ||
|
|
dd694f433b | ||
|
|
5293d57840 | ||
|
|
6103183253 | ||
|
|
d8b09e6656 | ||
|
|
ee72c016ab | ||
|
|
d8f0c3e5b9 | ||
|
|
b26432dbdb | ||
|
|
b0dc547fcb | ||
|
|
fb8437b588 | ||
|
|
fcf0cefd1a | ||
|
|
3ebb7b94d9 | ||
|
|
912ea363de | ||
|
|
d8ee8d0c99 | ||
|
|
61ba5c961e | ||
|
|
ce3fbcb18d | ||
|
|
2041586829 | ||
|
|
87b0818246 | ||
|
|
ffdc2c5396 | ||
|
|
f3a280bc67 | ||
|
|
2e9602716c | ||
|
|
2330a64589 | ||
|
|
1afddd74a9 | ||
|
|
e6ff630763 | ||
|
|
0475b2501a | ||
|
|
0b0fe51a2c | ||
|
|
620d2d9d58 | ||
|
|
b2488eb356 | ||
|
|
e5c714f501 | ||
|
|
cfde337b7b | ||
|
|
cfaff6e0c1 | ||
|
|
894773eb5b | ||
|
|
e2fe052576 | ||
|
|
fe961e6590 | ||
|
|
08cddb4b4b | ||
|
|
bf79c02440 | ||
|
|
9bfd6ff275 | ||
|
|
bd3d1a17c2 | ||
|
|
01cc55a1f4 | ||
|
|
cd793c5ab7 | ||
|
|
28dbd5551e | ||
|
|
b6f6a165c4 | ||
|
|
5acfa65ffb | ||
|
|
8e60adc916 | ||
|
|
11fb1d30f4 | ||
|
|
42f4a5081e | ||
|
|
f27fad9b89 | ||
|
|
a7da2a47c3 | ||
|
|
0deeb9991c | ||
|
|
b9601b1e59 | ||
|
|
953808a9ee | ||
|
|
4763341ea1 | ||
|
|
1601532a53 | ||
|
|
8014dc648f | ||
|
|
b449878fea | ||
|
|
236f1795e9 | ||
|
|
47a4741a3c | ||
|
|
e4f6edf237 | ||
|
|
1e07af1b0a | ||
|
|
fe19a0c58d | ||
|
|
15f4144e12 | ||
|
|
135d862eb6 | ||
|
|
6fb2035dd0 | ||
|
|
c71efe6d62 | ||
|
|
f5299d1752 | ||
|
|
6268e66efa | ||
|
|
ccabeafb3d | ||
|
|
3dc87ec59a | ||
|
|
edce7555a6 | ||
|
|
aa4d3298fb | ||
|
|
c2edd31eae | ||
|
|
fac9ac6c40 | ||
|
|
4d68092e2f | ||
|
|
6be08f76f6 | ||
|
|
819b4cd54e | ||
|
|
77da9dc974 | ||
|
|
cb8eae24c9 | ||
|
|
d895cae16c | ||
|
|
aabb7c3cdd | ||
|
|
7ae25ac67f | ||
|
|
333373f90e | ||
|
|
5be7b6a1b2 | ||
|
|
d4def1c193 | ||
|
|
19b3ee6d39 | ||
|
|
deaed047fd | ||
|
|
6fa7e8aff5 | ||
|
|
cd2370754a | ||
|
|
83e14aeebd | ||
|
|
e6464f0cb6 | ||
|
|
4e9d88aa05 | ||
|
|
e65a752475 | ||
|
|
ffe7f6d161 | ||
|
|
8a434aeb46 | ||
|
|
62c76cf825 | ||
|
|
b01c2aefd9 | ||
|
|
bce495e56f | ||
|
|
1d3b17e251 | ||
|
|
5097b162fc | ||
|
|
00b6694068 | ||
|
|
3f34e0936a | ||
|
|
480a9ff82f | ||
|
|
ffa4c6fc8f | ||
|
|
6c917e433e | ||
|
|
30740d9d2f | ||
|
|
086bbc5b62 | ||
|
|
8bec8a3f6a | ||
|
|
bad86247f7 | ||
|
|
e25afaf673 | ||
|
|
e205003635 | ||
|
|
3bb3b1555a | ||
|
|
77268f352f | ||
|
|
7fa35f32d8 | ||
|
|
19445e42e6 | ||
|
|
6f468c2465 | ||
|
|
6a656c7429 | ||
|
|
452ee39de1 | ||
|
|
f7f8964c23 | ||
|
|
50e9543908 | ||
|
|
2f8be5f8db | ||
|
|
714609639f | ||
|
|
9652c27710 | ||
|
|
31fcdec619 | ||
|
|
e8ec7e54e5 | ||
|
|
841c60f2b3 | ||
|
|
76a05e94c1 | ||
|
|
916c7085d8 | ||
|
|
b847d1d8e7 | ||
|
|
9749fb033c | ||
|
|
ae2c9bba5a | ||
|
|
af2c0a1537 | ||
|
|
20127e732c | ||
|
|
759c48cd34 | ||
|
|
1340ed7925 | ||
|
|
a15fd48016 | ||
|
|
7bfaa358ea | ||
|
|
1645dfd3d1 | ||
|
|
230bd5c2fd | ||
|
|
b7b3f9c5e7 | ||
|
|
d78f45ae0c | ||
|
|
ea6aeef8ba | ||
|
|
0da98ec6ba | ||
|
|
5273e38fb2 | ||
|
|
da8cd388c4 | ||
|
|
57090d8cba | ||
|
|
af284d5fdb | ||
|
|
88df07717d | ||
|
|
14cc790c59 | ||
|
|
0c180cb7cc | ||
|
|
fe824f87b9 | ||
|
|
5c5b28833c | ||
|
|
d5acf7a44a | ||
|
|
c3493360af | ||
|
|
08191b13f2 | ||
|
|
1c5b94e6bb | ||
|
|
b82a0d83ce | ||
|
|
6405ecb259 | ||
|
|
7e767b7e90 | ||
|
|
8f5dbd5614 | ||
|
|
a8285350cc | ||
|
|
c2134fde2b | ||
|
|
2194eddf30 | ||
|
|
23923200c3 | ||
|
|
d4ba5bdda6 | ||
|
|
d63313efe1 | ||
|
|
49de11b340 | ||
|
|
2d9e7dc2bc | ||
|
|
70b2c5f5ef | ||
|
|
c7f159c1c9 | ||
|
|
968486ecc0 | ||
|
|
e049bb8bd6 | ||
|
|
e7ad883ebe | ||
|
|
c69d71d55b | ||
|
|
fb0f880f0a | ||
|
|
dcfc247a2c | ||
|
|
3e903d34cc | ||
|
|
217aaaf3ea | ||
|
|
ed511b141f | ||
|
|
e5f23e0ebb | ||
|
|
d79872b4c7 | ||
|
|
e9c7c3b90d | ||
|
|
95b0a868f2 | ||
|
|
071ba05534 | ||
|
|
4d24da8cda | ||
|
|
372e26118f | ||
|
|
807f014d77 | ||
|
|
2c11e5da1d | ||
|
|
55ca38b4cd | ||
|
|
64e4f627c1 | ||
|
|
3b804cb654 | ||
|
|
122e16106f | ||
|
|
0fc9545546 | ||
|
|
5477f2597b | ||
|
|
dfcf918763 | ||
|
|
8ab44c7986 | ||
|
|
1bb0085dfe | ||
|
|
31a55df3d9 | ||
|
|
c9ab8a7f6c | ||
|
|
0308df07d3 | ||
|
|
141d7f234f | ||
|
|
043f250d0e | ||
|
|
2f7e92ad04 | ||
|
|
d5ff21c221 | ||
|
|
adfab9c899 | ||
|
|
37242ceb30 | ||
|
|
80ee9994f0 | ||
|
|
3a6bb2735b | ||
|
|
d43f54e5c4 | ||
|
|
8eb8995aa7 | ||
|
|
d1ac6ffc13 | ||
|
|
2379eb1fa6 | ||
|
|
028490ddcf | ||
|
|
5ef0c3caa5 | ||
|
|
8561ad2256 | ||
|
|
ec15e859a4 | ||
|
|
3b3152fc50 | ||
|
|
3f99cfba1b | ||
|
|
9388808964 | ||
|
|
de570d1a65 | ||
|
|
2091f7ab16 | ||
|
|
cfbc4fe809 | ||
|
|
61e806b96a | ||
|
|
c0ee713704 | ||
|
|
106d0fc541 | ||
|
|
5f80d7afbd | ||
|
|
8a72761743 | ||
|
|
a86015f73f | ||
|
|
4245c6b222 | ||
|
|
b370f0ca42 | ||
|
|
aade18cf3b | ||
|
|
9020bcee37 | ||
|
|
9e50e5314c | ||
|
|
3a2a752e1e | ||
|
|
ce7456b4cc | ||
|
|
d8c2ab0e6f | ||
|
|
15b667ef36 | ||
|
|
3d3c7ebb0d | ||
|
|
9085aa4322 | ||
|
|
247b9af02b | ||
|
|
c02b16c4cc | ||
|
|
4d4f46ba2a | ||
|
|
bf1c8e3a3c | ||
|
|
3d2c8e1fd0 | ||
|
|
ab84249a58 | ||
|
|
26da037fd5 | ||
|
|
8287312c29 | ||
|
|
36f702ba82 | ||
|
|
74c8943682 | ||
|
|
12e00af531 | ||
|
|
403c175dbc | ||
|
|
228221003d | ||
|
|
9263cc5874 | ||
|
|
1152052b3e | ||
|
|
429b956fb2 | ||
|
|
d3726bbd26 | ||
|
|
2e2c614f0e | ||
|
|
48861f509a | ||
|
|
d7bd40045c | ||
|
|
e81faa9d6d | ||
|
|
640324f1d4 | ||
|
|
8e533b0363 | ||
|
|
4ad6939980 | ||
|
|
0f22bef8c3 | ||
|
|
2d9dad5e14 | ||
|
|
a79661225a | ||
|
|
15eea825e6 | ||
|
|
b1b9ca01f0 | ||
|
|
05e954d2cd | ||
|
|
bcde027091 | ||
|
|
c4d8da4727 | ||
|
|
6e3ea82f9b | ||
|
|
58832b0d7c | ||
|
|
66f3b93331 | ||
|
|
29498b6a2a | ||
|
|
a774e4d5e2 | ||
|
|
9108bfe080 | ||
|
|
bcbb6a56a1 | ||
|
|
ec24d814ab | ||
|
|
28cb22e3c2 | ||
|
|
1438377401 | ||
|
|
96a4d1ca04 | ||
|
|
df9d19ba73 | ||
|
|
24abcddc57 | ||
|
|
ef6b6fe065 | ||
|
|
5cc099a8ab | ||
|
|
897e2b121a | ||
|
|
eb19d41d5f | ||
|
|
7b8f8753b1 | ||
|
|
dcb3b9f85f | ||
|
|
96ac9c5299 | ||
|
|
b36b87656e | ||
|
|
de7ccedbe7 | ||
|
|
2436351d6e | ||
|
|
dfcea1456d | ||
|
|
ec831e05f5 | ||
|
|
00513823dc | ||
|
|
d7d4f47d63 | ||
|
|
93f9052557 | ||
|
|
af1c986383 | ||
|
|
71328479f3 | ||
|
|
b7f8f5d26a | ||
|
|
58782b1c55 | ||
|
|
37e85c0031 | ||
|
|
ab3d8478c2 | ||
|
|
9574bfd6c8 | ||
|
|
cbbd3781c2 | ||
|
|
47762ab687 | ||
|
|
b1e495b88d | ||
|
|
bc3e73fc8f | ||
|
|
c91d948486 | ||
|
|
0b3d04719d | ||
|
|
aa7e42db11 | ||
|
|
5cfa4ec47e | ||
|
|
0c41663c7b | ||
|
|
9ca423b981 | ||
|
|
5df5d2c411 | ||
|
|
477fd794a0 | ||
|
|
a36d4b2831 | ||
|
|
cbc25c22fc | ||
|
|
ce3125196d | ||
|
|
7ea58d09f6 | ||
|
|
4fadcbfab2 | ||
|
|
dc08eca368 | ||
|
|
9555ec714a | ||
|
|
e5dd8c2ac5 | ||
|
|
5bcc058d42 | ||
|
|
a975523fb9 | ||
|
|
dece66ac18 | ||
|
|
3b4e74cb3b | ||
|
|
28dd29dedb | ||
|
|
296e630edd | ||
|
|
84ac55b052 | ||
|
|
0f988beff8 | ||
|
|
c5716d0e72 | ||
|
|
9de33488bf | ||
|
|
b8c8447971 | ||
|
|
ee3b70c4a9 | ||
|
|
9f9cf95692 | ||
|
|
e19091b2bf | ||
|
|
87acfef166 | ||
|
|
fa601c41ed |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
*~
|
||||
*.o
|
||||
ABOUT-NLS
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.h
|
||||
@@ -9,9 +10,11 @@ config.status
|
||||
config.status.lineno
|
||||
configure
|
||||
configure.lineno
|
||||
cov-int
|
||||
cscope.in.out
|
||||
cscope.out
|
||||
cscope.po.out
|
||||
intl
|
||||
libtool
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
24
HACKING
24
HACKING
@@ -6,15 +6,17 @@ concerns when hacking on pacman. If you are interested in contributing, please
|
||||
read link:submitting-patches.html[submitting-patches] and
|
||||
link:translation-help.html[translation-help] as well.
|
||||
|
||||
Coding style
|
||||
Coding Style
|
||||
------------
|
||||
|
||||
1. All code should be indented with tabs. (Ignore the use of only spaces in
|
||||
this file) By default, source files contain the following VIM modeline:
|
||||
this file.) A tab size of two spaces is used when calculating line widths,
|
||||
which should be a maximum of 80 characters. By default, source files
|
||||
contain the following Vim modeline:
|
||||
+
|
||||
[source,C]
|
||||
-------------------------------------------
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
-------------------------------------------
|
||||
|
||||
2. When opening new blocks such as 'while', 'if', or 'for', leave the opening
|
||||
@@ -73,15 +75,7 @@ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
|
||||
NOT
|
||||
return(0);
|
||||
|
||||
6. The sizeof() operator should accept a type, not a value. (TODO: in certain
|
||||
cases, it may be better- should this be a set guideline? Read "The Practice
|
||||
of Programming")
|
||||
|
||||
sizeof(alpm_list_t);
|
||||
NOT
|
||||
sizeof(*mylist);
|
||||
|
||||
7. When using strcmp() (or any function that returns 0 on success) in a
|
||||
6. When using strcmp() (or any function that returns 0 on success) in a
|
||||
conditional statement, use != 0 or == 0 and not the negation (!) operator.
|
||||
It reads much cleaner for humans (using a negative to check for success is
|
||||
confusing) and the compiler will treat it correctly anyway.
|
||||
@@ -90,7 +84,7 @@ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
|
||||
NOT
|
||||
if(!strcmp(a, b))
|
||||
|
||||
8. Use spaces around almost all arithmetic, comparison and assignment
|
||||
7. Use spaces around almost all arithmetic, comparison and assignment
|
||||
operators and after all ',;:' separators.
|
||||
|
||||
foobar[2 * size + 1] = function(a, 6);
|
||||
@@ -101,7 +95,7 @@ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
|
||||
NOT
|
||||
for(a=0;a<n&&n>0;a++,n--) {}
|
||||
|
||||
9. Declare all variables at the start of the block.
|
||||
8. Declare all variables at the start of the block.
|
||||
[source,C]
|
||||
-------------------------------------------
|
||||
int SYMEXPORT alpm_db_remove_server(alpm_db_t *db, const char *url)
|
||||
@@ -202,5 +196,5 @@ For example, to run valgrind:
|
||||
valgrind --leak-check=full -- src/pacman/.libs/lt-pacman -Syu
|
||||
|
||||
/////
|
||||
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
|
||||
vim:set syntax=asciidoc noet spell spelllang=en_us:
|
||||
/////
|
||||
|
||||
221
INSTALL
221
INSTALL
@@ -1,28 +1,25 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
You will need to build and install two libraries before you can
|
||||
properly build pacman.
|
||||
|
||||
libarchive
|
||||
http://code.google.com/p/libarchive/
|
||||
|
||||
libcurl
|
||||
http://curl.haxx.se/libcurl/
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
instructions are generic. Run `./configure --help` for specific
|
||||
options.
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
@@ -51,7 +48,7 @@ may remove or edit it.
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
@@ -62,12 +59,22 @@ The simplest way to compile this package is:
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
@@ -76,12 +83,22 @@ The simplest way to compile this package is:
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
@@ -94,25 +111,41 @@ is an example:
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
@@ -123,16 +156,47 @@ Documentation and other data files still use the regular prefix.
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
@@ -144,14 +208,58 @@ find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
HP-UX `make' updates targets which have the same time stamps as
|
||||
their prerequisites, which makes it generally unusable when shipped
|
||||
generated files such as `configure' are involved. Use GNU `make'
|
||||
instead.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
@@ -159,7 +267,8 @@ type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
@@ -177,9 +286,9 @@ eventually be run) with `--host=TYPE'.
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
@@ -188,7 +297,7 @@ A warning: not all `configure' scripts look for a site script.
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
@@ -200,18 +309,27 @@ causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
an Autoconf limitation. Until the limitation is lifted, you can use
|
||||
this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
@@ -238,6 +356,15 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
|
||||
64
Makefile.am
64
Makefile.am
@@ -13,43 +13,48 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-doc --disable-git-version
|
||||
|
||||
# Some files automatically included, so they aren't specified below:
|
||||
# AUTHORS, COPYING, NEWS, README
|
||||
EXTRA_DIST = HACKING
|
||||
EXTRA_DIST = HACKING test/tap.sh
|
||||
|
||||
# Sample makepkg prototype files
|
||||
pkgdatadir = ${datadir}/${PACKAGE}
|
||||
dist_pkgdata_DATA = \
|
||||
proto/PKGBUILD.proto \
|
||||
proto/PKGBUILD-split.proto \
|
||||
proto/proto.install \
|
||||
proto/ChangeLog.proto
|
||||
proto/PKGBUILD-vcs.proto \
|
||||
proto/proto.install
|
||||
|
||||
# run the pactest test suite and vercmp tests
|
||||
check-local: test-pacman test-pacsort test-vercmp test-parseopts
|
||||
$(top_srcdir)/test/pacman/tests/TESTS: $(wildcard test/pacman/tests/*.py)
|
||||
@printf "TESTS += %s\n" $^ | LC_ALL=C sort -u > "$@"
|
||||
|
||||
test-pacman: test/pacman src/pacman
|
||||
LC_ALL=C $(PYTHON) $(top_srcdir)/test/pacman/pactest.py --debug=1 \
|
||||
--test $(top_srcdir)/test/pacman/tests/*.py \
|
||||
TESTS = test/scripts/parseopts_test.sh \
|
||||
test/scripts/human_to_size_test.sh \
|
||||
test/scripts/makepkg-template_test.sh \
|
||||
test/scripts/pacman-db-upgrade-v9.py \
|
||||
test/util/pacsorttest.sh \
|
||||
test/util/vercmptest.sh
|
||||
include $(top_srcdir)/test/pacman/tests/TESTS
|
||||
|
||||
TEST_SUITE_LOG = test/test-suite.log
|
||||
TEST_EXTENSIONS = .py
|
||||
AM_TESTS_ENVIRONMENT = \
|
||||
PMTEST_UTIL_DIR=$(top_builddir)/src/util/; export PMTEST_UTIL_DIR; \
|
||||
PMTEST_SCRIPT_DIR=$(top_builddir)/scripts/; export PMTEST_SCRIPT_DIR; \
|
||||
PMTEST_SCRIPTLIB_DIR=$(top_srcdir)/scripts/library/; export PMTEST_SCRIPTLIB_DIR;
|
||||
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||
$(top_srcdir)/build-aux/tap-driver.sh
|
||||
PY_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||
$(top_srcdir)/build-aux/tap-driver.sh
|
||||
PY_LOG_COMPILER = $(PYTHON) $(top_srcdir)/test/pacman/pactest.py
|
||||
AM_PY_LOG_FLAGS = \
|
||||
--scriptlet-shell $(SCRIPTLET_SHELL) \
|
||||
--ldconfig $(LDCONFIG) \
|
||||
-p $(top_builddir)/src/pacman/pacman
|
||||
--bindir $(top_builddir)/src/pacman \
|
||||
--bindir $(top_builddir)/scripts
|
||||
|
||||
test-pacsort: test/util src/util
|
||||
$(BASH_SHELL) $(top_srcdir)/test/util/pacsorttest.sh \
|
||||
$(top_builddir)/src/util/pacsort
|
||||
|
||||
test-vercmp: test/util src/util
|
||||
$(BASH_SHELL) $(top_srcdir)/test/util/vercmptest.sh \
|
||||
$(top_builddir)/src/util/vercmp
|
||||
|
||||
test-parseopts: test/scripts scripts
|
||||
$(BASH_SHELL) $(top_srcdir)/test/scripts/parseopts_test.sh \
|
||||
$(top_srcdir)/scripts/library/parseopts.sh
|
||||
$(BASH_SHELL) $(top_srcdir)/test/scripts/human_to_size_test.sh \
|
||||
$(top_srcdir)/scripts/library/human_to_size.sh
|
||||
|
||||
# create the pacman DB and cache directories upon install
|
||||
# create the pacman DB, cache, makepkg-template and system hook directories upon install
|
||||
install-data-local:
|
||||
for dir in "$(DESTDIR)$(localstatedir)/lib/pacman" "$(DESTDIR)$(localstatedir)/cache/pacman/pkg"; do \
|
||||
for dir in "$(DESTDIR)$(localstatedir)/lib/pacman" "$(DESTDIR)$(localstatedir)/cache/pacman/pkg" \
|
||||
"$(DESTDIR)$(datarootdir)/makepkg-template" "$(DESTDIR)$(datarootdir)/libalpm/hooks"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
|
||||
@@ -58,6 +63,11 @@ update-po:
|
||||
$(MAKE) -C scripts/po update-po
|
||||
$(MAKE) -C src/pacman/po update-po
|
||||
|
||||
.PHONY: test-pacman test-pacsort test-vercmp test-parseopts update-po
|
||||
update-copyright:
|
||||
for file in $(shell sh -c 'git grep -l "Copyright .* Pacman Development" | grep -v "\.po"'); do \
|
||||
sed -i -e "/Copyright (/s/-$(OLD)/-$(NEW)/" -e "/Copyright (/s/ $(OLD)/ $(OLD)-$(NEW)/" "$$file"; \
|
||||
done
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
.PHONY: update-po update-copyright
|
||||
|
||||
# vim:set noet:
|
||||
|
||||
209
NEWS
209
NEWS
@@ -1,5 +1,212 @@
|
||||
VERSION DESCRIPTION
|
||||
-----------------------------------------------------------------------------
|
||||
5.0.2 - fix database file checks with -Qkk and non-standard root
|
||||
(FS#48563)
|
||||
- improve optdepend detection for status messages (FS#44957)
|
||||
- make Y/N prompt multi-byte-character aware (FS#47992)
|
||||
- properly detect dependency cycles with --recursive (FS#41031)
|
||||
- improve free disk space calculation (FS#37402)
|
||||
- extract database files with --dbonly (FS#52052)
|
||||
- repo-add:
|
||||
- do not alter the database if only verifying signature
|
||||
(FS#48085)
|
||||
- fix error for directories containing whitespace (FS#50285)
|
||||
- makepkg:
|
||||
- fix building packages with only architecture-specific
|
||||
sources (FS#48340)
|
||||
- ignore PKGBUILD architecture for --printsrcinfo
|
||||
- do not die on non-empty directories under !emptydirs
|
||||
(FS#48515)
|
||||
- preserve checksum type for architecture-specific sources
|
||||
5.0.1 - fix alignment issues with wide character locales (FS#47980)
|
||||
- fix removal of .pacnew files (FS#47993)
|
||||
- fix triggering of Install hooks (FS#47996)
|
||||
- fix handling of stdin scripts called by pacman
|
||||
- hook activity is logged
|
||||
- documentataion updates for alpm-hooks (FS#48080)
|
||||
- makepkg:
|
||||
- increase robustness of variable array checks
|
||||
- makepkg -g does not perform current architecture checks
|
||||
- do not run prepare() with --noextract
|
||||
- all directories in the packaging directory are cleared
|
||||
before each build
|
||||
- fix translations issues (FS#48057, FS#48298)
|
||||
- repo-add:
|
||||
- fix checking for non-existent database
|
||||
- contrib:
|
||||
- zsh_completion: updated makepkg options
|
||||
5.0.0 - pacman can run hooks pre- and post-transaction. See the
|
||||
alpm-hooks(5) man page for details and an example hook (FS#2985)
|
||||
- pacman can now sync and read .files databases (-Fy) and do basic
|
||||
searching for files in sync repos (-Fs, -Fo) (FS#23787)
|
||||
- pacman can check the validity of the local and sync databases
|
||||
(-Dk and -Dkk respectively). This replaces the 'testdb'
|
||||
software (FS#42444)
|
||||
- the package description output (-Si ,-Qi) is now correctly
|
||||
aligned regardless of locale (FS#43983, FS#45997)
|
||||
- ensure internal package version matches database version after
|
||||
downloading (FS#45687)
|
||||
- improved signal handling and lock file removal (FS#45995,
|
||||
FS#46375, FS#47011)
|
||||
- print more information when encountering dependency errors
|
||||
- improved configuration parsing with a new ini parser
|
||||
- handle a symlink to a directory being replaced by a directory
|
||||
- The 'pkgbase' variable is now recorded in the local package db
|
||||
- Remove support for ".pacorig" files. Instead, packages files
|
||||
are extracted as a ".pacnew" and the original stays in place
|
||||
- prevent install scriptlets using stdin for user interaction
|
||||
- provides are considered when displaying optdepends install
|
||||
status (FS#36412)
|
||||
- always update corrupt database whether or not a newer version
|
||||
is found on the remote server
|
||||
- fix build issues when libarchive was in a non-standard location
|
||||
- Many issues found using Coverity were address (primarily freeing
|
||||
memory on error conditions)
|
||||
- The pactest suite was upgraded to allow parallel testing using
|
||||
the tap.sh library
|
||||
- makepkg:
|
||||
- makepkg is in the process of being split into a library. This
|
||||
allows various areas to be extended by adding a file into
|
||||
libmakepkg (e.g. package/PKGBUILD checking, adjusting
|
||||
files before creating the final package).
|
||||
- PKGBUILD variables checked to be arrays or not as appropriate
|
||||
- pkgver() and prepare() are now run with --noextract (FS#43498,
|
||||
FS#46800)
|
||||
- the ability to build a single package in a PKGBUILD has been
|
||||
removed
|
||||
- the output when checking checksums for architecture specific
|
||||
sources is improved (FS#43444)
|
||||
- improved handling of bazaar sources (FS#43448)
|
||||
- fix source package signing with SRCPKGDIR set
|
||||
- add option to compress png images with optipng
|
||||
- add --packagelist option, which lists all packages build from
|
||||
a PKGBUILD
|
||||
- add --printsrcinfo flag to print SRCINFO file for a PKGBUILD
|
||||
- record build information in a .BUILDINFO file
|
||||
- add whirlpool to list of hashing options (FS#45859)
|
||||
- makepkg-template:
|
||||
- support multiple --template-dir
|
||||
- added a testsuite
|
||||
- repo-add:
|
||||
- Always generate the .files database
|
||||
- Only update database if the entire operation succeeds
|
||||
- unarmored package signatures are rejected
|
||||
- contrib:
|
||||
- checkupdates: give error when fakeroot is missing
|
||||
- checkupdates: provide packages versions in output
|
||||
- checkupdates: fix failure in some locales (FS#40405)
|
||||
- paccache: Add -q/--quiet
|
||||
- pacdiff: do not require DIFFPROG for -o/--output (FS#46184)
|
||||
- zsh_completion: updated to fix many missing options
|
||||
4.2.1 - Remove warnings about incorrect directory ownership until
|
||||
packaging files with dynamic users/groups is improved
|
||||
- Do not require a specific automake version when building from
|
||||
the source tarball (FS#43655)
|
||||
- A number of typos and translation errors have been fixed
|
||||
(FS#43257, FS#43280, FS#43279, FS#43617, FS#43739)
|
||||
- set sane umask in pacman-db-upgrade (FS#43200) and make it
|
||||
more verbose
|
||||
- Use correct permissions when creating the log file
|
||||
- Fix memory management for file list storage
|
||||
- Set package origin when adding to db cache
|
||||
- makepkg:
|
||||
- Fix error when encountering an expired PGP key (FS#43269)
|
||||
- Fix error extracting PKGBUILD attributes (FS#43387)
|
||||
- Fix removal of static libraries when the shared library
|
||||
uses the absolute path in symbolic links (FS#43395)
|
||||
- Improve Bazaar cloning (FS#43448)
|
||||
- Fix issues with architecture dependant checksum
|
||||
verification (FS#43192)
|
||||
- Fix .SRCINFO file with architecture dependant fields
|
||||
(FS#43247)
|
||||
- Fix compatibility with older bash versions
|
||||
- Allow git checkouts to be downloaded into directory ending
|
||||
with ".git".
|
||||
- contrib:
|
||||
- updpkgsums no longer changes file permissions (FS#43272)
|
||||
- paccache does not remove all packages on libalpm error
|
||||
(FS#43286)
|
||||
4.2.0 - symlinks to directories on the filesystem are no longer
|
||||
treated as directories
|
||||
- pacman-db-upgrade - fix local database for files installed
|
||||
into directory symlinks
|
||||
- added --assume-installed option to help upgrades where not all
|
||||
installed packages have been rebuilt
|
||||
- --unrequired now filters needed optdepends too. Use twice
|
||||
to only filter direct dependencies
|
||||
- improved dependency resolving ensures correct ordering when
|
||||
installing updates (FS#32764)
|
||||
- A new configure keyword Usage can limit what operations a
|
||||
repository is used for
|
||||
- NoExtract and NoUpgrade can use inverted pattern matches
|
||||
(FS#31749)
|
||||
- Group queries can be filtered with --explicit/--deps (FS#19716)
|
||||
- Filesystem checking now only produces a warning for altered
|
||||
backup files (FS#34739)
|
||||
- pacman prints a warning if an installed directory has different
|
||||
permission to that already on the filesystem (FS#34740)
|
||||
- both current and new versions are displayed when querying
|
||||
updates
|
||||
- --print-format now implies --print
|
||||
- package scriptlets are not run when using --dbonly
|
||||
- invalid option combinations cause pacman to abort (FS#20950)
|
||||
- improve output when a package is missing a required signature
|
||||
(FS#28014)
|
||||
- PGP signature key IDs are listed with -Sii (FS#34742)
|
||||
- indicate ignored packages in -Qu output
|
||||
- use appropriate file size units with -Si/-Qi
|
||||
- plugged several memory leaks
|
||||
- read filelists from a packages .MTREE file if possible
|
||||
- ensure packages have all the required metadata before installing
|
||||
(FS#35514)
|
||||
- always remove lock file on exit (FS#35603)
|
||||
- fix overflow in integrity checking progress bar (FS#36608)
|
||||
- ensure downloads use correct filename even if the mirror uses a
|
||||
redirect (FS#36791)
|
||||
- cache PGP key IDs during availability checking (FS#38042)
|
||||
- fix reading responses with leading whitespace (FS#39976)
|
||||
- fix potential issues when handling of UTF8 filenames
|
||||
(FS#40805, FS#40762)
|
||||
- makepkg:
|
||||
- PKGBUILDs can now specify architecture specific sources,
|
||||
dependencies, etc.
|
||||
- A .SRCINFO file is added to source packages for easy parsing
|
||||
- VCS package building attempts to be incremental (FS#35050)
|
||||
- bzr sources can have a '+' in them (FS#35244)
|
||||
- allow sources containing "::"
|
||||
- add --noprepare option
|
||||
- add -C/--cleanbuild option (FS#17175)
|
||||
- add --noarchive option
|
||||
- remove --asroot and enforce fakeroot usage
|
||||
- all PKGBUILDs require a package() function
|
||||
- PKGBUILDs can no longer be read from stdin
|
||||
- enable make style environmental overrides
|
||||
- Read CARCH environmental variable (FS#35030)
|
||||
- makedepends and checkdepends are installed together (FS#31557)
|
||||
- added support for sha224 checksums (FS#36776)
|
||||
- remove warning when license is not specified in PKGBUILD
|
||||
(FS#37011)
|
||||
- only remove static libraries if they have a shared version
|
||||
- prevent makepkg creating armored signatures (FS#38503)
|
||||
- support stripping kernel modules
|
||||
- support the kernel.org PGP signing scheme (FS#31592)
|
||||
- sign created source package when using --sign
|
||||
- enforce source signatures to be trusted or have their full
|
||||
fingerprint listed in the validpgpkeys array of the PKGBUILD
|
||||
- look for configuration in XDG_CONFIG_HOME/pacman/makepkg.conf
|
||||
(FS#43030)
|
||||
- ensure vcs tools are available when source entries require
|
||||
them
|
||||
- disallow pkgver/pkgrel/epoch overrides in split packages
|
||||
- improve parsing of PKGBUILD variables (FS#40361)
|
||||
- makepkg-template - new package build templating utility
|
||||
(FS#10375)
|
||||
- repo-add:
|
||||
- add option to remove package files from disk
|
||||
- contrib:
|
||||
- checkupdates: rename CHECKUPDATE_DB to CHECKUPDATES_DB
|
||||
- pacdiff: add a "Quit" option, and many other improvements
|
||||
- pacsysclean is removed
|
||||
4.1.2 - validate %FILEPATH% when parsing repos to prevent arbitary
|
||||
file overwrites from malicious databases
|
||||
- makepkg:
|
||||
@@ -655,7 +862,7 @@ VERSION DESCRIPTION
|
||||
- fix overzealous use of macros
|
||||
- entire codebase builds with -pedantic GCC option
|
||||
- libalpm-specific changes:
|
||||
- moved location of sync DBs into their own folder to thwart
|
||||
- moved location of sync DBs into their own directory to thwart
|
||||
deletion and remove naming limitations
|
||||
- REQUIREDBY entries are no longer used in local DB but are
|
||||
computed on the fly when needed, which should resolve
|
||||
|
||||
85
README
85
README
@@ -507,3 +507,88 @@ API CHANGES BETWEEN 4.0 AND 4.1
|
||||
ALPM_EVENT_OPTDEP_REQUIRED, ALPM_EVENT_DATABASE_MISSING,
|
||||
ALPM_EVENT_KEYRING_START, ALPM_EVENT_KEYRING_DONE, ALPM_EVENT_KEY_DOWNLOAD_START,
|
||||
ALPM_EVENT_KEY_DOWNLOAD_DONE, ALPM_PROGRESS_KEYRING_START
|
||||
|
||||
|
||||
API CHANGES BETWEEN 4.1 AND 4.2
|
||||
===============================
|
||||
|
||||
[CHANGED]
|
||||
- alpm_filelist_t - removed member resolved_path
|
||||
- alpm_filelist_contains - now returns alpm_file_t
|
||||
- event callback
|
||||
- alpm_event_t renamed to alpm_event_type_t
|
||||
- alpm_event_t union added
|
||||
- alpm_event_cb now takes only an alpm_event_t parameter
|
||||
- alpm_event_any_t, alpm_package_operation_t, alpm_event_package_operation_t,
|
||||
alpm_event_optdep_removal_t, alpm_event_delta_patch_t, alpm_event_scriptlet_info_t,
|
||||
alpm_event_database_missing_t, alpm_event_pkgdownload_t, alpm_event_pacnew_created_t,
|
||||
alpm_event_pacsave_created_t, alpm_event_pacorig_created_t added
|
||||
- ALPM_EVENT_*_START -> ALPM_EVENT_PACKAGE_OPERATION_START
|
||||
- ALPM_EVENT_*_DONE -> ALPM_EVENT_PACKAGE_OPERATION_DONE
|
||||
- question callback
|
||||
- alpm_question_t renamed to alpm_question_type_t
|
||||
- alpm_question_t union added
|
||||
- alpm_cb_question now takes only an alpm_question_t parameter
|
||||
- alpm_question_any_t, alpm_question_install_ignorepkg_t, alpm_question_replace_t
|
||||
alpm_question_conflict_t, alpm_question_corrupted_t, alpm_question_remove_pkgs_t,
|
||||
alpm_question_select_provider_t, alpm_question_import_key_t added
|
||||
|
||||
[ADDED]
|
||||
- memory management
|
||||
- alpm_fileconflict_free()
|
||||
- alpm_depmissing_free()
|
||||
- alpm_conflict_free()
|
||||
- alpm_dep_free()
|
||||
- database usage
|
||||
- alpm_db_usage_t
|
||||
- alpm_db_set_usage()
|
||||
- alpm_db_get_usage()
|
||||
- assume installed
|
||||
- alpm_option_get_assumeinstalled()
|
||||
- alpm_option_add_assumeinstalled()
|
||||
- alpm_option_set_assumeinstalled()
|
||||
- alpm_option_remove_assumeinstalled()
|
||||
- using noupgrade/noextract
|
||||
- alpm_option_match_noupgrade()
|
||||
- alpm_option_match_noextract()
|
||||
- utility functions
|
||||
- alpm_dep_from_string()
|
||||
- alpm_pkg_should_ignore()
|
||||
- alpm_decode_signature()
|
||||
- alpm_extract_keyid()
|
||||
- flags
|
||||
- ALPM_EVENT_RETRIEVE_DONE, ALPM_EVENT_RETRIEVE_FAILED, ALPM_EVENT_PKGDOWNLOAD_START,
|
||||
ALPM_EVENT_PKGDOWNLOAD_DONE, ALPM_EVENT_PKGDOWNLOAD_FAILED, ALPM_EVENT_OPTDEP_REMOVAL,
|
||||
ALPM_EVENT_PACNEW_CREATED, ALPM_EVENT_PACSVAE_CREATED, ALPM_EVENT_PACORIG_CREATED
|
||||
|
||||
|
||||
API CHANGES BETWEEN 4.2 AND 5.0
|
||||
===============================
|
||||
|
||||
[REMOVED]
|
||||
- alpm_siglevel_t - removed members ALPM_SIG_PACKAGE_SET, ALPM_SIG_PACKAGE_TRUST_SET
|
||||
- removed .pacorig generation
|
||||
- ALPM_EVENT_PACORIG_CREATED
|
||||
- alpm_event_pacorig_created_t
|
||||
- alpm_event_t.pacorig_created
|
||||
|
||||
[ADDED]
|
||||
- hook support
|
||||
- alpm_option_get_hookdirs()
|
||||
- alpm_option_set_hookdirs()
|
||||
- alpm_option_add_hookdir()
|
||||
- alpm_option_remove_hookdir()
|
||||
- alpm_event_hook_t, alpm_event_hook_run_t
|
||||
- alpm_hook_when_t
|
||||
- ALPM_EVENT_HOOK_START, ALPM_EVENT_HOOK_DONE
|
||||
- ALPM_EVENT_HOOK_RUN_START, ALPM_EVENT_HOOK_RUN_DONE
|
||||
- ALPM_ERR_TRANS_HOOK_FAILED
|
||||
- different database extension support
|
||||
- alpm_option_get_dbext()
|
||||
- alpm_option_set_dbext()
|
||||
- pkgbase accessor
|
||||
- alpm_pkg_get_base()
|
||||
- transaction events
|
||||
- ALPM_EVENT_TRANSACTION_START, ALPM_EVENT_TRANSACTION_DONE
|
||||
- database unlocking
|
||||
- alpm_unlock()
|
||||
|
||||
22
autoclean.sh
22
autoclean.sh
@@ -1,22 +0,0 @@
|
||||
#!/bin/sh -xu
|
||||
|
||||
[ -f Makefile ] && make distclean
|
||||
|
||||
rm -rf autom4te.cache
|
||||
rm -f config.h.in config.h
|
||||
rm -f config.status
|
||||
rm -f configure
|
||||
rm -f stamp*
|
||||
rm -f aclocal.m4
|
||||
rm -f compile
|
||||
rm -f libtool
|
||||
|
||||
rm -f test/pacman/*.pyc
|
||||
rm -f doc/html/*.html
|
||||
rm -f doc/man3/*.3
|
||||
|
||||
find . \( -name 'Makefile' -o \
|
||||
-name 'Makefile.in' -o \
|
||||
-path '*/po/POTFILES' -o \
|
||||
-path '*/po/stamp-po' -o \
|
||||
-path '*/po/*.gmo' \) -exec rm -f {} +
|
||||
10
autogen.sh
10
autogen.sh
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh -xu
|
||||
#!/bin/sh -x
|
||||
|
||||
aclocal -I m4 --install
|
||||
autoheader
|
||||
automake --foreign
|
||||
autoconf
|
||||
autoreconf -i
|
||||
patch -d build-aux -Np0 -i ltmain-asneeded.patch
|
||||
|
||||
exit 0
|
||||
|
||||
2
build-aux/.gitignore
vendored
Normal file
2
build-aux/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!ltmain-asneeded.patch
|
||||
1505
build-aux/config.guess
vendored
1505
build-aux/config.guess
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,614 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Output a system dependent set of variables, describing how to set the
|
||||
# run time search path of shared libraries in an executable.
|
||||
#
|
||||
# Copyright 1996-2006 Free Software Foundation, Inc.
|
||||
# Taken from GNU libtool, 2001
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# The first argument passed to this file is the canonical host specification,
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
# or
|
||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
|
||||
# should be set by the caller.
|
||||
#
|
||||
# The set of defined variables is at the end of this script.
|
||||
|
||||
# Known limitations:
|
||||
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
|
||||
# than 256 bytes, otherwise the compiler driver will dump core. The only
|
||||
# known workaround is to choose shorter directory names for the build
|
||||
# directory and/or the installation directory.
|
||||
|
||||
# All known linkers require a `.a' archive for static linking (except MSVC,
|
||||
# which needs '.lib').
|
||||
libext=a
|
||||
shrext=.so
|
||||
|
||||
host="$1"
|
||||
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
|
||||
# Code taken from libtool.m4's _LT_CC_BASENAME.
|
||||
|
||||
for cc_temp in $CC""; do
|
||||
case $cc_temp in
|
||||
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
|
||||
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
|
||||
\-*) ;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
|
||||
|
||||
wl=
|
||||
if test "$GCC" = yes; then
|
||||
wl='-Wl,'
|
||||
else
|
||||
case "$host_os" in
|
||||
aix*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
darwin*)
|
||||
case $cc_basename in
|
||||
xlc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
mingw* | pw32* | os2*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
newsos6)
|
||||
;;
|
||||
linux*)
|
||||
case $cc_basename in
|
||||
icc* | ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
pgcc | pgf77 | pgf90)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
ccc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
como)
|
||||
wl='-lopt='
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ C*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sco3.2v5*)
|
||||
;;
|
||||
solaris*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sunos4*)
|
||||
wl='-Qoption ld '
|
||||
;;
|
||||
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
unicos*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
uts4*)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
|
||||
|
||||
hardcode_libdir_flag_spec=
|
||||
hardcode_libdir_separator=
|
||||
hardcode_direct=no
|
||||
hardcode_minus_L=no
|
||||
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32*)
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
if test "$GCC" != yes; then
|
||||
with_gnu_ld=no
|
||||
fi
|
||||
;;
|
||||
interix*)
|
||||
# we just hope/assume this is gcc and not c89 (= MSVC++)
|
||||
with_gnu_ld=yes
|
||||
;;
|
||||
openbsd*)
|
||||
with_gnu_ld=no
|
||||
;;
|
||||
esac
|
||||
|
||||
ld_shlibs=yes
|
||||
if test "$with_gnu_ld" = yes; then
|
||||
# Set some defaults for GNU ld with shared library support. These
|
||||
# are reset later if shared libraries are not supported. Putting them
|
||||
# here allows them to be overridden if necessary.
|
||||
# Unlike libtool, we use -rpath here, not --rpath, since the documented
|
||||
# option of GNU ld is called -rpath, not --rpath.
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
case "$host_os" in
|
||||
aix3* | aix4* | aix5*)
|
||||
# On AIX/PPC, the GNU linker is very broken
|
||||
if test "$host_cpu" != ia64; then
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
|
||||
# that the semantics of dynamic libraries on AmigaOS, at least up
|
||||
# to version 4, is to share data among multiple programs linked
|
||||
# with the same dynamic library. Since this doesn't match the
|
||||
# behavior of shared libraries on other platforms, we cannot use
|
||||
# them.
|
||||
ld_shlibs=no
|
||||
;;
|
||||
beos*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
interix3*)
|
||||
hardcode_direct=no
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
linux*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
netbsd*)
|
||||
;;
|
||||
solaris*)
|
||||
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
|
||||
ld_shlibs=no
|
||||
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
|
||||
case `$LD -v 2>&1` in
|
||||
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test "$ld_shlibs" = no; then
|
||||
hardcode_libdir_flag_spec=
|
||||
fi
|
||||
else
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
# Note: this linker hardcodes the directories in LIBPATH if there
|
||||
# are no directories specified by -L.
|
||||
hardcode_minus_L=yes
|
||||
if test "$GCC" = yes; then
|
||||
# Neither direct hardcoding nor static linking is supported with a
|
||||
# broken collect2.
|
||||
hardcode_direct=unsupported
|
||||
fi
|
||||
;;
|
||||
aix4* | aix5*)
|
||||
if test "$host_cpu" = ia64; then
|
||||
# On IA64, the linker does run time linking by default, so we don't
|
||||
# have to do anything special.
|
||||
aix_use_runtimelinking=no
|
||||
else
|
||||
aix_use_runtimelinking=no
|
||||
# Test if we are trying to use run time linking or normal
|
||||
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
|
||||
# need to do runtime linking.
|
||||
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
|
||||
for ld_flag in $LDFLAGS; do
|
||||
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
|
||||
aix_use_runtimelinking=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_separator=':'
|
||||
if test "$GCC" = yes; then
|
||||
case $host_os in aix4.[012]|aix4.[012].*)
|
||||
collect2name=`${CC} -print-prog-name=collect2`
|
||||
if test -f "$collect2name" && \
|
||||
strings "$collect2name" | grep resolve_lib_name >/dev/null
|
||||
then
|
||||
# We have reworked collect2
|
||||
hardcode_direct=yes
|
||||
else
|
||||
# We have old collect2
|
||||
hardcode_direct=unsupported
|
||||
hardcode_minus_L=yes
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_libdir_separator=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Begin _LT_AC_SYS_LIBPATH_AIX.
|
||||
echo 'int main () { return 0; }' > conftest.c
|
||||
${CC} ${LDFLAGS} conftest.c -o conftest
|
||||
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
fi
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath="/usr/lib:/lib"
|
||||
fi
|
||||
rm -f conftest.c conftest
|
||||
# End _LT_AC_SYS_LIBPATH_AIX.
|
||||
if test "$aix_use_runtimelinking" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
else
|
||||
if test "$host_cpu" = ia64; then
|
||||
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
|
||||
else
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
# see comment about different semantics on the GNU ld section
|
||||
ld_shlibs=no
|
||||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec=' '
|
||||
libext=lib
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
hardcode_direct=no
|
||||
if test "$GCC" = yes ; then
|
||||
:
|
||||
else
|
||||
case $cc_basename in
|
||||
xlc*)
|
||||
;;
|
||||
*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
dgux*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
freebsd1*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
freebsd2.2*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
freebsd2*)
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
freebsd* | kfreebsd*-gnu | dragonfly*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
hpux9*)
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
hpux10*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
fi
|
||||
;;
|
||||
hpux11*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
case $host_cpu in
|
||||
hppa*64*|ia64*)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
*)
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
netbsd*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
newsos6)
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
openbsd*)
|
||||
hardcode_direct=yes
|
||||
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
else
|
||||
case "$host_os" in
|
||||
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
os2*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
osf3*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
osf4* | osf5*)
|
||||
if test "$GCC" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
else
|
||||
# Both cc and cxx compiler support -rpath directly
|
||||
hardcode_libdir_flag_spec='-rpath $libdir'
|
||||
fi
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
solaris*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
sysv4)
|
||||
case $host_vendor in
|
||||
sni)
|
||||
hardcode_direct=yes # is this really true???
|
||||
;;
|
||||
siemens)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
motorola)
|
||||
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sysv4.3*)
|
||||
;;
|
||||
sysv4*MP*)
|
||||
if test -d /usr/nec; then
|
||||
ld_shlibs=yes
|
||||
fi
|
||||
;;
|
||||
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6*)
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
|
||||
hardcode_libdir_separator=':'
|
||||
;;
|
||||
uts4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Check dynamic linker characteristics
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
|
||||
libname_spec='lib$name'
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
;;
|
||||
aix4* | aix5*)
|
||||
;;
|
||||
amigaos*)
|
||||
;;
|
||||
beos*)
|
||||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
shrext=.dll
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
shrext=.dylib
|
||||
;;
|
||||
dgux*)
|
||||
;;
|
||||
freebsd1*)
|
||||
;;
|
||||
kfreebsd*-gnu)
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
;;
|
||||
gnu*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
case $host_cpu in
|
||||
ia64*)
|
||||
shrext=.so
|
||||
;;
|
||||
hppa*64*)
|
||||
shrext=.sl
|
||||
;;
|
||||
*)
|
||||
shrext=.sl
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
interix3*)
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
case "$host_os" in
|
||||
irix5* | nonstopux*)
|
||||
libsuff= shlibsuff=
|
||||
;;
|
||||
*)
|
||||
case $LD in
|
||||
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
|
||||
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
|
||||
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
|
||||
*) libsuff= shlibsuff= ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
linux*oldld* | linux*aout* | linux*coff*)
|
||||
;;
|
||||
linux*)
|
||||
;;
|
||||
knetbsd*-gnu)
|
||||
;;
|
||||
netbsd*)
|
||||
;;
|
||||
newsos6)
|
||||
;;
|
||||
nto-qnx*)
|
||||
;;
|
||||
openbsd*)
|
||||
;;
|
||||
os2*)
|
||||
libname_spec='$name'
|
||||
shrext=.dll
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
;;
|
||||
solaris*)
|
||||
;;
|
||||
sunos4*)
|
||||
;;
|
||||
sysv4 | sysv4.3*)
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
|
||||
;;
|
||||
uts4*)
|
||||
;;
|
||||
esac
|
||||
|
||||
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
|
||||
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
|
||||
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
|
||||
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
|
||||
|
||||
# How to pass a linker flag through the compiler.
|
||||
wl="$escaped_wl"
|
||||
|
||||
# Static library suffix (normally "a").
|
||||
libext="$libext"
|
||||
|
||||
# Shared library suffix (normally "so").
|
||||
shlibext="$shlibext"
|
||||
|
||||
# Flag to hardcode \$libdir into a binary during linking.
|
||||
# This must work even if \$libdir does not exist.
|
||||
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
|
||||
|
||||
# Whether we need a single -rpath flag with a separated argument.
|
||||
hardcode_libdir_separator="$hardcode_libdir_separator"
|
||||
|
||||
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_direct="$hardcode_direct"
|
||||
|
||||
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_minus_L="$hardcode_minus_L"
|
||||
|
||||
EOF
|
||||
1739
build-aux/config.sub
vendored
1739
build-aux/config.sub
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,630 +0,0 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u="sed s,\\\\\\\\,/,g"
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
@@ -1,524 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2010-02-06.18; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
33
build-aux/ltmain-asneeded.patch
Normal file
33
build-aux/ltmain-asneeded.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
--- ltmain.sh.orig 2013-06-26 14:31:53.472627840 +1000
|
||||
+++ ltmain.sh 2013-06-26 14:30:56.137038936 +1000
|
||||
@@ -5800,6 +5800,14 @@
|
||||
arg=$func_stripname_result
|
||||
;;
|
||||
|
||||
+ -Wl,*--as-needed*)
|
||||
+ deplibs="$deplibs $wl--as-needed"
|
||||
+ ;;
|
||||
+
|
||||
+ -Wl,*--no-as-needed*)
|
||||
+ deplibs="$deplibs $wl--no-as-needed"
|
||||
+ ;;
|
||||
+
|
||||
-Wl,*)
|
||||
func_stripname '-Wl,' '' "$arg"
|
||||
args=$func_stripname_result
|
||||
@@ -6160,6 +6168,15 @@
|
||||
lib=
|
||||
found=no
|
||||
case $deplib in
|
||||
+ -Wl,--as-needed|-Wl,--no-as-needed)
|
||||
+ if test "$linkmode,$pass" = "prog,link"; then
|
||||
+ compile_deplibs="$deplib $compile_deplibs"
|
||||
+ finalize_deplibs="$deplib $finalize_deplibs"
|
||||
+ else
|
||||
+ deplibs="$deplib $deplibs"
|
||||
+ fi
|
||||
+ continue
|
||||
+ ;;
|
||||
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
|
||||
|-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
|
||||
if test "$linkmode,$pass" = "prog,link"; then
|
||||
9672
build-aux/ltmain.sh
9672
build-aux/ltmain.sh
File diff suppressed because it is too large
Load Diff
@@ -1,215 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2012-06-26.16; # UTC
|
||||
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'automa4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
@@ -1,162 +0,0 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain.
|
||||
#
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
errstatus=0
|
||||
dirmode=
|
||||
|
||||
usage="\
|
||||
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
|
||||
|
||||
Create each directory DIR (with mode MODE, if specified), including all
|
||||
leading file name components.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>."
|
||||
|
||||
# process command line arguments
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
-h | --help | --h*) # -h for help
|
||||
echo "$usage"
|
||||
exit $?
|
||||
;;
|
||||
-m) # -m PERM arg
|
||||
shift
|
||||
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
|
||||
dirmode=$1
|
||||
shift
|
||||
;;
|
||||
--version)
|
||||
echo "$0 $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
--) # stop option processing
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*) # unknown option
|
||||
echo "$usage" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
*) # first non-opt arg
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for file
|
||||
do
|
||||
if test -d "$file"; then
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) exit 0 ;;
|
||||
esac
|
||||
|
||||
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
|
||||
# mkdir -p a/c at the same time, both will detect that a is missing,
|
||||
# one will create a, then the other will try to create a and die with
|
||||
# a "File exists" error. This is a problem when calling mkinstalldirs
|
||||
# from a parallel make. We use --version in the probe to restrict
|
||||
# ourselves to GNU mkdir, which is thread-safe.
|
||||
case $dirmode in
|
||||
'')
|
||||
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
|
||||
echo "mkdir -p -- $*"
|
||||
exec mkdir -p -- "$@"
|
||||
else
|
||||
# On NextStep and OpenStep, the `mkdir' command does not
|
||||
# recognize any option. It will interpret all options as
|
||||
# directories to create, and then abort because `.' already
|
||||
# exists.
|
||||
test -d ./-p && rmdir ./-p
|
||||
test -d ./--version && rmdir ./--version
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
|
||||
test ! -d ./--version; then
|
||||
echo "mkdir -m $dirmode -p -- $*"
|
||||
exec mkdir -m "$dirmode" -p -- "$@"
|
||||
else
|
||||
# Clean up after NextStep and OpenStep mkdir.
|
||||
for d in ./-m ./-p ./--version "./$dirmode";
|
||||
do
|
||||
test -d $d && rmdir $d
|
||||
done
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
for file
|
||||
do
|
||||
case $file in
|
||||
/*) pathcomp=/ ;;
|
||||
*) pathcomp= ;;
|
||||
esac
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set fnord $file
|
||||
shift
|
||||
IFS=$oIFS
|
||||
|
||||
for d
|
||||
do
|
||||
test "x$d" = x && continue
|
||||
|
||||
pathcomp=$pathcomp$d
|
||||
case $pathcomp in
|
||||
-*) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp"
|
||||
|
||||
mkdir "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
errstatus=$lasterr
|
||||
else
|
||||
if test ! -z "$dirmode"; then
|
||||
echo "chmod $dirmode $pathcomp"
|
||||
lasterr=
|
||||
chmod "$dirmode" "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -z "$lasterr"; then
|
||||
errstatus=$lasterr
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
652
build-aux/tap-driver.sh
Executable file
652
build-aux/tap-driver.sh
Executable file
@@ -0,0 +1,652 @@
|
||||
#! /bin/sh
|
||||
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
scriptversion=2011-12-27.17; # UTC
|
||||
|
||||
# Make unconditional expansion of undefined variables an error. This
|
||||
# helps a lot in preventing typo-related bugs.
|
||||
set -u
|
||||
|
||||
me=tap-driver.sh
|
||||
|
||||
fatal ()
|
||||
{
|
||||
echo "$me: fatal: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage_error ()
|
||||
{
|
||||
echo "$me: $*" >&2
|
||||
print_usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--ignore-exit]
|
||||
[--diagnostic-string=STRING] [--merge|--no-merge]
|
||||
[--comments|--no-comments] [--] TEST-COMMAND
|
||||
The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
|
||||
END
|
||||
}
|
||||
|
||||
# TODO: better error handling in option parsing (in particular, ensure
|
||||
# TODO: $log_file, $trs_file and $test_name are defined).
|
||||
test_name= # Used for reporting.
|
||||
log_file= # Where to save the result and output of the test script.
|
||||
trs_file= # Where to save the metadata of the test run.
|
||||
expect_failure=0
|
||||
color_tests=0
|
||||
merge=0
|
||||
ignore_exit=0
|
||||
comments=0
|
||||
diag_string='#'
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) print_usage; exit $?;;
|
||||
--version) echo "$me $scriptversion"; exit $?;;
|
||||
--test-name) test_name=$2; shift;;
|
||||
--log-file) log_file=$2; shift;;
|
||||
--trs-file) trs_file=$2; shift;;
|
||||
--color-tests) color_tests=$2; shift;;
|
||||
--expect-failure) expect_failure=$2; shift;;
|
||||
--enable-hard-errors) shift;; # No-op.
|
||||
--merge) merge=1;;
|
||||
--no-merge) merge=0;;
|
||||
--ignore-exit) ignore_exit=1;;
|
||||
--comments) comments=1;;
|
||||
--no-comments) comments=0;;
|
||||
--diagnostic-string) diag_string=$2; shift;;
|
||||
--) shift; break;;
|
||||
-*) usage_error "invalid option: '$1'";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
test $# -gt 0 || usage_error "missing test command"
|
||||
|
||||
case $expect_failure in
|
||||
yes) expect_failure=1;;
|
||||
*) expect_failure=0;;
|
||||
esac
|
||||
|
||||
if test $color_tests = yes; then
|
||||
init_colors='
|
||||
color_map["red"]="[0;31m" # Red.
|
||||
color_map["grn"]="[0;32m" # Green.
|
||||
color_map["lgn"]="[1;32m" # Light green.
|
||||
color_map["blu"]="[1;34m" # Blue.
|
||||
color_map["mgn"]="[0;35m" # Magenta.
|
||||
color_map["std"]="[m" # No color.
|
||||
color_for_result["ERROR"] = "mgn"
|
||||
color_for_result["PASS"] = "grn"
|
||||
color_for_result["XPASS"] = "red"
|
||||
color_for_result["FAIL"] = "red"
|
||||
color_for_result["XFAIL"] = "lgn"
|
||||
color_for_result["SKIP"] = "blu"'
|
||||
else
|
||||
init_colors=''
|
||||
fi
|
||||
|
||||
# :; is there to work around a bug in bash 3.2 (and earlier) which
|
||||
# does not always set '$?' properly on redirection failure.
|
||||
# See the Autoconf manual for more details.
|
||||
:;{
|
||||
(
|
||||
# Ignore common signals (in this subshell only!), to avoid potential
|
||||
# problems with Korn shells. Some Korn shells are known to propagate
|
||||
# to themselves signals that have killed a child process they were
|
||||
# waiting for; this is done at least for SIGINT (and usually only for
|
||||
# it, in truth). Without the `trap' below, such a behaviour could
|
||||
# cause a premature exit in the current subshell, e.g., in case the
|
||||
# test command it runs gets terminated by a SIGINT. Thus, the awk
|
||||
# script we are piping into would never seen the exit status it
|
||||
# expects on its last input line (which is displayed below by the
|
||||
# last `echo $?' statement), and would thus die reporting an internal
|
||||
# error.
|
||||
# For more information, see the Autoconf manual and the threads:
|
||||
# <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
|
||||
# <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
|
||||
trap : 1 3 2 13 15
|
||||
if test $merge -gt 0; then
|
||||
exec 2>&1
|
||||
else
|
||||
exec 2>&3
|
||||
fi
|
||||
"$@"
|
||||
echo $?
|
||||
) | LC_ALL=C ${AM_TAP_AWK-awk} \
|
||||
-v me="$me" \
|
||||
-v test_script_name="$test_name" \
|
||||
-v log_file="$log_file" \
|
||||
-v trs_file="$trs_file" \
|
||||
-v expect_failure="$expect_failure" \
|
||||
-v merge="$merge" \
|
||||
-v ignore_exit="$ignore_exit" \
|
||||
-v comments="$comments" \
|
||||
-v diag_string="$diag_string" \
|
||||
'
|
||||
# FIXME: the usages of "cat >&3" below could be optimized when using
|
||||
# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
|
||||
|
||||
# Implementation note: in what follows, `result_obj` will be an
|
||||
# associative array that (partly) simulates a TAP result object
|
||||
# from the `TAP::Parser` perl module.
|
||||
|
||||
## ----------- ##
|
||||
## FUNCTIONS ##
|
||||
## ----------- ##
|
||||
|
||||
function fatal(msg)
|
||||
{
|
||||
print me ": " msg | "cat >&2"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function abort(where)
|
||||
{
|
||||
fatal("internal error " where)
|
||||
}
|
||||
|
||||
# Convert a boolean to a "yes"/"no" string.
|
||||
function yn(bool)
|
||||
{
|
||||
return bool ? "yes" : "no";
|
||||
}
|
||||
|
||||
function add_test_result(result)
|
||||
{
|
||||
if (!test_results_index)
|
||||
test_results_index = 0
|
||||
test_results_list[test_results_index] = result
|
||||
test_results_index += 1
|
||||
test_results_seen[result] = 1;
|
||||
}
|
||||
|
||||
# Whether the test script should be re-run by "make recheck".
|
||||
function must_recheck()
|
||||
{
|
||||
for (k in test_results_seen)
|
||||
if (k != "XFAIL" && k != "PASS" && k != "SKIP")
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# Whether the content of the log file associated to this test should
|
||||
# be copied into the "global" test-suite.log.
|
||||
function copy_in_global_log()
|
||||
{
|
||||
for (k in test_results_seen)
|
||||
if (k != "PASS")
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# FIXME: this can certainly be improved ...
|
||||
function get_global_test_result()
|
||||
{
|
||||
if ("ERROR" in test_results_seen)
|
||||
return "ERROR"
|
||||
if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
|
||||
return "FAIL"
|
||||
all_skipped = 1
|
||||
for (k in test_results_seen)
|
||||
if (k != "SKIP")
|
||||
all_skipped = 0
|
||||
if (all_skipped)
|
||||
return "SKIP"
|
||||
return "PASS";
|
||||
}
|
||||
|
||||
function stringify_result_obj(result_obj)
|
||||
{
|
||||
if (result_obj["is_unplanned"] || result_obj["number"] != testno)
|
||||
return "ERROR"
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
return "ERROR"
|
||||
|
||||
if (result_obj["directive"] == "TODO")
|
||||
return result_obj["is_ok"] ? "XPASS" : "XFAIL"
|
||||
|
||||
if (result_obj["directive"] == "SKIP")
|
||||
return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
|
||||
|
||||
if (length(result_obj["directive"]))
|
||||
abort("in function stringify_result_obj()")
|
||||
|
||||
return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
|
||||
}
|
||||
|
||||
function decorate_result(result)
|
||||
{
|
||||
color_name = color_for_result[result]
|
||||
if (color_name)
|
||||
return color_map[color_name] "" result "" color_map["std"]
|
||||
# If we are not using colorized output, or if we do not know how
|
||||
# to colorize the given result, we should return it unchanged.
|
||||
return result
|
||||
}
|
||||
|
||||
function report(result, details)
|
||||
{
|
||||
if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
|
||||
{
|
||||
msg = ": " test_script_name
|
||||
add_test_result(result)
|
||||
}
|
||||
else if (result == "#")
|
||||
{
|
||||
msg = " " test_script_name ":"
|
||||
}
|
||||
else
|
||||
{
|
||||
abort("in function report()")
|
||||
}
|
||||
if (length(details))
|
||||
msg = msg " " details
|
||||
# Output on console might be colorized.
|
||||
print decorate_result(result) msg
|
||||
# Log the result in the log file too, to help debugging (this is
|
||||
# especially true when said result is a TAP error or "Bail out!").
|
||||
print result msg | "cat >&3";
|
||||
}
|
||||
|
||||
function testsuite_error(error_message)
|
||||
{
|
||||
report("ERROR", "- " error_message)
|
||||
}
|
||||
|
||||
function handle_tap_result()
|
||||
{
|
||||
details = result_obj["number"];
|
||||
if (length(result_obj["description"]))
|
||||
details = details " " result_obj["description"]
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
{
|
||||
details = details " # AFTER LATE PLAN";
|
||||
}
|
||||
else if (result_obj["is_unplanned"])
|
||||
{
|
||||
details = details " # UNPLANNED";
|
||||
}
|
||||
else if (result_obj["number"] != testno)
|
||||
{
|
||||
details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
|
||||
details, testno);
|
||||
}
|
||||
else if (result_obj["directive"])
|
||||
{
|
||||
details = details " # " result_obj["directive"];
|
||||
if (length(result_obj["explanation"]))
|
||||
details = details " " result_obj["explanation"]
|
||||
}
|
||||
|
||||
report(stringify_result_obj(result_obj), details)
|
||||
}
|
||||
|
||||
# `skip_reason` should be empty whenever planned > 0.
|
||||
function handle_tap_plan(planned, skip_reason)
|
||||
{
|
||||
planned += 0 # Avoid getting confused if, say, `planned` is "00"
|
||||
if (length(skip_reason) && planned > 0)
|
||||
abort("in function handle_tap_plan()")
|
||||
if (plan_seen)
|
||||
{
|
||||
# Error, only one plan per stream is acceptable.
|
||||
testsuite_error("multiple test plans")
|
||||
return;
|
||||
}
|
||||
planned_tests = planned
|
||||
# The TAP plan can come before or after *all* the TAP results; we speak
|
||||
# respectively of an "early" or a "late" plan. If we see the plan line
|
||||
# after at least one TAP result has been seen, assume we have a late
|
||||
# plan; in this case, any further test result seen after the plan will
|
||||
# be flagged as an error.
|
||||
plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
|
||||
# If testno > 0, we have an error ("too many tests run") that will be
|
||||
# automatically dealt with later, so do not worry about it here. If
|
||||
# $plan_seen is true, we have an error due to a repeated plan, and that
|
||||
# has already been dealt with above. Otherwise, we have a valid "plan
|
||||
# with SKIP" specification, and should report it as a particular kind
|
||||
# of SKIP result.
|
||||
if (planned == 0 && testno == 0)
|
||||
{
|
||||
if (length(skip_reason))
|
||||
skip_reason = "- " skip_reason;
|
||||
report("SKIP", skip_reason);
|
||||
}
|
||||
}
|
||||
|
||||
function extract_tap_comment(line)
|
||||
{
|
||||
if (index(line, diag_string) == 1)
|
||||
{
|
||||
# Strip leading `diag_string` from `line`.
|
||||
line = substr(line, length(diag_string) + 1)
|
||||
# And strip any leading and trailing whitespace left.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
# Return what is left (if any).
|
||||
return line;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
# When this function is called, we know that line is a TAP result line,
|
||||
# so that it matches the (perl) RE "^(not )?ok\b".
|
||||
function setup_result_obj(line)
|
||||
{
|
||||
# Get the result, and remove it from the line.
|
||||
result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
|
||||
sub("^(not )?ok[ \t]*", "", line)
|
||||
|
||||
# If the result has an explicit number, get it and strip it; otherwise,
|
||||
# automatically assing the next progresive number to it.
|
||||
if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
|
||||
{
|
||||
match(line, "^[0-9]+")
|
||||
# The final `+ 0` is to normalize numbers with leading zeros.
|
||||
result_obj["number"] = substr(line, 1, RLENGTH) + 0
|
||||
line = substr(line, RLENGTH + 1)
|
||||
}
|
||||
else
|
||||
{
|
||||
result_obj["number"] = testno
|
||||
}
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
# No further test results are acceptable after a "late" TAP plan
|
||||
# has been seen.
|
||||
result_obj["is_unplanned"] = 1
|
||||
else if (plan_seen && testno > planned_tests)
|
||||
result_obj["is_unplanned"] = 1
|
||||
else
|
||||
result_obj["is_unplanned"] = 0
|
||||
|
||||
# Strip trailing and leading whitespace.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
|
||||
# This will have to be corrected if we have a "TODO"/"SKIP" directive.
|
||||
result_obj["description"] = line
|
||||
result_obj["directive"] = ""
|
||||
result_obj["explanation"] = ""
|
||||
|
||||
if (index(line, "#") == 0)
|
||||
return # No possible directive, nothing more to do.
|
||||
|
||||
# Directives are case-insensitive.
|
||||
rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
|
||||
|
||||
# See whether we have the directive, and if yes, where.
|
||||
pos = match(line, rx "$")
|
||||
if (!pos)
|
||||
pos = match(line, rx "[^a-zA-Z0-9_]")
|
||||
|
||||
# If there was no TAP directive, we have nothing more to do.
|
||||
if (!pos)
|
||||
return
|
||||
|
||||
# Let`s now see if the TAP directive has been escaped. For example:
|
||||
# escaped: ok \# SKIP
|
||||
# not escaped: ok \\# SKIP
|
||||
# escaped: ok \\\\\# SKIP
|
||||
# not escaped: ok \ # SKIP
|
||||
if (substr(line, pos, 1) == "#")
|
||||
{
|
||||
bslash_count = 0
|
||||
for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
|
||||
bslash_count += 1
|
||||
if (bslash_count % 2)
|
||||
return # Directive was escaped.
|
||||
}
|
||||
|
||||
# Strip the directive and its explanation (if any) from the test
|
||||
# description.
|
||||
result_obj["description"] = substr(line, 1, pos - 1)
|
||||
# Now remove the test description from the line, that has been dealt
|
||||
# with already.
|
||||
line = substr(line, pos)
|
||||
# Strip the directive, and save its value (normalized to upper case).
|
||||
sub("^[ \t]*#[ \t]*", "", line)
|
||||
result_obj["directive"] = toupper(substr(line, 1, 4))
|
||||
line = substr(line, 5)
|
||||
# Now get the explanation for the directive (if any), with leading
|
||||
# and trailing whitespace removed.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
result_obj["explanation"] = line
|
||||
}
|
||||
|
||||
function get_test_exit_message(status)
|
||||
{
|
||||
if (status == 0)
|
||||
return ""
|
||||
if (status !~ /^[1-9][0-9]*$/)
|
||||
abort("getting exit status")
|
||||
if (status < 127)
|
||||
exit_details = ""
|
||||
else if (status == 127)
|
||||
exit_details = " (command not found?)"
|
||||
else if (status >= 128 && status <= 255)
|
||||
exit_details = sprintf(" (terminated by signal %d?)", status - 128)
|
||||
else if (status > 256 && status <= 384)
|
||||
# We used to report an "abnormal termination" here, but some Korn
|
||||
# shells, when a child process die due to signal number n, can leave
|
||||
# in $? an exit status of 256+n instead of the more standard 128+n.
|
||||
# Apparently, both behaviours are allowed by POSIX (2008), so be
|
||||
# prepared to handle them both. See also Austing Group report ID
|
||||
# 0000051 <http://www.austingroupbugs.net/view.php?id=51>
|
||||
exit_details = sprintf(" (terminated by signal %d?)", status - 256)
|
||||
else
|
||||
# Never seen in practice.
|
||||
exit_details = " (abnormal termination)"
|
||||
return sprintf("exited with status %d%s", status, exit_details)
|
||||
}
|
||||
|
||||
function write_test_results()
|
||||
{
|
||||
print ":global-test-result: " get_global_test_result() > trs_file
|
||||
print ":recheck: " yn(must_recheck()) > trs_file
|
||||
print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
|
||||
for (i = 0; i < test_results_index; i += 1)
|
||||
print ":test-result: " test_results_list[i] > trs_file
|
||||
close(trs_file);
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
|
||||
## ------- ##
|
||||
## SETUP ##
|
||||
## ------- ##
|
||||
|
||||
'"$init_colors"'
|
||||
|
||||
# Properly initialized once the TAP plan is seen.
|
||||
planned_tests = 0
|
||||
|
||||
COOKED_PASS = expect_failure ? "XPASS": "PASS";
|
||||
COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
|
||||
|
||||
# Enumeration-like constants to remember which kind of plan (if any)
|
||||
# has been seen. It is important that NO_PLAN evaluates "false" as
|
||||
# a boolean.
|
||||
NO_PLAN = 0
|
||||
EARLY_PLAN = 1
|
||||
LATE_PLAN = 2
|
||||
|
||||
testno = 0 # Number of test results seen so far.
|
||||
bailed_out = 0 # Whether a "Bail out!" directive has been seen.
|
||||
|
||||
# Whether the TAP plan has been seen or not, and if yes, which kind
|
||||
# it is ("early" is seen before any test result, "late" otherwise).
|
||||
plan_seen = NO_PLAN
|
||||
|
||||
## --------- ##
|
||||
## PARSING ##
|
||||
## --------- ##
|
||||
|
||||
is_first_read = 1
|
||||
|
||||
while (1)
|
||||
{
|
||||
# Involutions required so that we are able to read the exit status
|
||||
# from the last input line.
|
||||
st = getline
|
||||
if (st < 0) # I/O error.
|
||||
fatal("I/O error while reading from input stream")
|
||||
else if (st == 0) # End-of-input
|
||||
{
|
||||
if (is_first_read)
|
||||
abort("in input loop: only one input line")
|
||||
break
|
||||
}
|
||||
if (is_first_read)
|
||||
{
|
||||
is_first_read = 0
|
||||
nextline = $0
|
||||
continue
|
||||
}
|
||||
else
|
||||
{
|
||||
curline = nextline
|
||||
nextline = $0
|
||||
$0 = curline
|
||||
}
|
||||
# Copy any input line verbatim into the log file.
|
||||
print | "cat >&3"
|
||||
# Parsing of TAP input should stop after a "Bail out!" directive.
|
||||
if (bailed_out)
|
||||
continue
|
||||
|
||||
# TAP test result.
|
||||
if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
|
||||
{
|
||||
testno += 1
|
||||
setup_result_obj($0)
|
||||
handle_tap_result()
|
||||
}
|
||||
# TAP plan (normal or "SKIP" without explanation).
|
||||
else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
|
||||
{
|
||||
# The next two lines will put the number of planned tests in $0.
|
||||
sub("^1\\.\\.", "")
|
||||
sub("[^0-9]*$", "")
|
||||
handle_tap_plan($0, "")
|
||||
continue
|
||||
}
|
||||
# TAP "SKIP" plan, with an explanation.
|
||||
else if ($0 ~ /^1\.\.0+[ \t]*#/)
|
||||
{
|
||||
# The next lines will put the skip explanation in $0, stripping
|
||||
# any leading and trailing whitespace. This is a little more
|
||||
# tricky in truth, since we want to also strip a potential leading
|
||||
# "SKIP" string from the message.
|
||||
sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
|
||||
sub("[ \t]*$", "");
|
||||
handle_tap_plan(0, $0)
|
||||
}
|
||||
# "Bail out!" magic.
|
||||
# Older versions of prove and TAP::Harness (e.g., 3.17) did not
|
||||
# recognize a "Bail out!" directive when preceded by leading
|
||||
# whitespace, but more modern versions (e.g., 3.23) do. So we
|
||||
# emulate the latter, "more modern" behaviour.
|
||||
else if ($0 ~ /^[ \t]*Bail out!/)
|
||||
{
|
||||
bailed_out = 1
|
||||
# Get the bailout message (if any), with leading and trailing
|
||||
# whitespace stripped. The message remains stored in `$0`.
|
||||
sub("^[ \t]*Bail out![ \t]*", "");
|
||||
sub("[ \t]*$", "");
|
||||
# Format the error message for the
|
||||
bailout_message = "Bail out!"
|
||||
if (length($0))
|
||||
bailout_message = bailout_message " " $0
|
||||
testsuite_error(bailout_message)
|
||||
}
|
||||
# Maybe we have too look for dianogtic comments too.
|
||||
else if (comments != 0)
|
||||
{
|
||||
comment = extract_tap_comment($0);
|
||||
if (length(comment))
|
||||
report("#", comment);
|
||||
}
|
||||
}
|
||||
|
||||
## -------- ##
|
||||
## FINISH ##
|
||||
## -------- ##
|
||||
|
||||
# A "Bail out!" directive should cause us to ignore any following TAP
|
||||
# error, as well as a non-zero exit status from the TAP producer.
|
||||
if (!bailed_out)
|
||||
{
|
||||
if (!plan_seen)
|
||||
{
|
||||
testsuite_error("missing test plan")
|
||||
}
|
||||
else if (planned_tests != testno)
|
||||
{
|
||||
bad_amount = testno > planned_tests ? "many" : "few"
|
||||
testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
|
||||
bad_amount, planned_tests, testno))
|
||||
}
|
||||
if (!ignore_exit)
|
||||
{
|
||||
# Fetch exit status from the last line.
|
||||
exit_message = get_test_exit_message(nextline)
|
||||
if (exit_message)
|
||||
testsuite_error(exit_message)
|
||||
}
|
||||
}
|
||||
|
||||
write_test_results()
|
||||
|
||||
exit 0
|
||||
|
||||
} # End of "BEGIN" block.
|
||||
'
|
||||
|
||||
# TODO: document that we consume the file descriptor 3 :-(
|
||||
} 3>"$log_file"
|
||||
|
||||
test $? -eq 0 || fatal "I/O or internal error"
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
62
configure.ac
62
configure.ac
@@ -41,12 +41,12 @@ AC_PREREQ(2.62)
|
||||
# Bugfix releases:
|
||||
# pacman_version_micro += 1
|
||||
|
||||
m4_define([lib_current], [8])
|
||||
m4_define([lib_current], [10])
|
||||
m4_define([lib_revision], [2])
|
||||
m4_define([lib_age], [0])
|
||||
|
||||
m4_define([pacman_version_major], [4])
|
||||
m4_define([pacman_version_minor], [1])
|
||||
m4_define([pacman_version_major], [5])
|
||||
m4_define([pacman_version_minor], [0])
|
||||
m4_define([pacman_version_micro], [2])
|
||||
m4_define([pacman_version],
|
||||
[pacman_version_major.pacman_version_minor.pacman_version_micro])
|
||||
@@ -57,9 +57,10 @@ AC_CONFIG_SRCDIR([config.h.in])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_REQUIRE_AUX_FILE([tap-driver.sh])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([1.11])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
LT_INIT
|
||||
@@ -97,6 +98,11 @@ AC_ARG_WITH(buildscript,
|
||||
AS_HELP_STRING([--with-buildscript=name], [set the build script name used by makepkg]),
|
||||
[BUILDSCRIPT=$withval], [BUILDSCRIPT=PKGBUILD])
|
||||
|
||||
# Help line for buildscript filename
|
||||
AC_ARG_WITH(makepkg-template-dir,
|
||||
AS_HELP_STRING([--with-makepkg-template-dir=name], [set the template dir used by makepkg-template]),
|
||||
[TEMPLATE_DIR=$withval], [TEMPLATE_DIR=/usr/share/makepkg-template])
|
||||
|
||||
# Help line for debug package suffix
|
||||
AC_ARG_WITH(debug-suffix,
|
||||
AS_HELP_STRING([--with-debug-suffix=name], [set the suffix for split debugging symbol packages used by makepkg]),
|
||||
@@ -125,9 +131,9 @@ AC_ARG_WITH(gpgme,
|
||||
[], [with_gpgme=check])
|
||||
|
||||
# Help line for using libcurl
|
||||
AC_ARG_WITH(curl,
|
||||
AC_ARG_WITH(libcurl,
|
||||
AS_HELP_STRING([--with-libcurl], [use libcurl for the internal downloader]),
|
||||
[], [with_curl=check])
|
||||
[], [with_libcurl=check])
|
||||
|
||||
# Help line for documentation
|
||||
AC_ARG_ENABLE(doc,
|
||||
@@ -159,13 +165,32 @@ AC_ARG_ENABLE(git-version,
|
||||
# testing compilation against gpgme).
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Record large file flags in pkgconfig file
|
||||
if test "$enable_largefile" != no; then
|
||||
if test "$ac_cv_sys_file_offset_bits" != 'no'; then
|
||||
LFS_CFLAGS="-D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LFS_CFLAGS)
|
||||
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_INSTALL
|
||||
AC_CHECK_PROGS([PYTHON], [python2.7 python2.6 python2.5 python2 python], [false])
|
||||
AC_CHECK_PROGS([PYTHON], [python2.7 python2 python], [false])
|
||||
AC_PATH_PROGS([BASH_SHELL], [bash bash4], [false])
|
||||
|
||||
# check for perl 5.10.1 (needed by makepkg-template)
|
||||
AC_PATH_PROG([PERL],[perl])
|
||||
AC_DEFUN([AX_PROG_PERL_VERSION],
|
||||
[AC_CACHE_CHECK([for Perl version $1 or later], [ax_cv_prog_perl_version],
|
||||
[AS_IF(["$PERL" -e 'require v$1;' >/dev/null 2>&1],
|
||||
[ax_cv_prog_perl_version=yes],
|
||||
[ax_cv_prog_perl_version=no])])
|
||||
AS_IF([test x"$ax_cv_prog_perl_version" = xyes], [$2], [$3])])
|
||||
AX_PROG_PERL_VERSION([5.10.1], [], [AC_MSG_ERROR([perl is too old])])
|
||||
|
||||
AS_IF([test "x$BASH_SHELL" = "xfalse"],
|
||||
AC_MSG_WARN([*** bash >= 4.1.0 is required for pacman scripts]),
|
||||
[bash_version_major=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[0]]}"'`
|
||||
@@ -283,13 +308,12 @@ PATH_MAX_DEFINED
|
||||
AC_FUNC_FORK
|
||||
AC_FUNC_GETMNTENT
|
||||
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_MKTIME
|
||||
AC_FUNC_STRCOLL
|
||||
AC_CHECK_FUNCS([dup2 getcwd getmntinfo gettimeofday memmove memset \
|
||||
mkdir realpath regcomp rmdir setenv setlocale strcasecmp \
|
||||
strchr strcspn strdup strerror strndup strrchr strsep strstr \
|
||||
strtol swprintf tcflush wcwidth uname])
|
||||
strchr strcspn strdup strerror strndup strnlen strrchr \
|
||||
strsep strstr strtol swprintf tcflush wcwidth uname])
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize],,,[[#include <sys/stat.h>]])
|
||||
|
||||
# For the diskspace code
|
||||
@@ -300,11 +324,11 @@ AC_CHECK_MEMBERS([struct statfs.f_flags],,,[[#include <sys/param.h>
|
||||
|
||||
# Check if we can use symbol visibility support in GCC
|
||||
GCC_VISIBILITY_CC
|
||||
# Check if we have -fgnu89-inline flag
|
||||
GCC_GNU89_INLINE_CC
|
||||
|
||||
# Host-dependant definitions
|
||||
INODECMD="stat -c '%i %n'"
|
||||
OWNERCMD="stat -c '%u:%g'"
|
||||
MODECMD="stat -c '%a'"
|
||||
SIZECMD="stat -c %s"
|
||||
SEDINPLACE="sed --follow-symlinks -i"
|
||||
DUFLAGS="-sk --apparent-size"
|
||||
@@ -314,6 +338,8 @@ STRIP_STATIC="--strip-debug"
|
||||
case "${host_os}" in
|
||||
*bsd*)
|
||||
INODECMD="stat -f '%i %N'"
|
||||
OWNERCMD="stat -f '%u:%g'"
|
||||
MODECMD="stat -f '%Lp'"
|
||||
SIZECMD="stat -f %z"
|
||||
SEDINPLACE="sed -i \"\""
|
||||
DUFLAGS="-sk"
|
||||
@@ -321,6 +347,8 @@ case "${host_os}" in
|
||||
darwin*)
|
||||
host_os_darwin=yes
|
||||
INODECMD="/usr/bin/stat -f '%i %N'"
|
||||
OWNERCMD="/usr/bin/stat -f '%u:%g'"
|
||||
MODECMD="/usr/bin/stat -f '%Lp'"
|
||||
SIZECMD="/usr/bin/stat -f %z"
|
||||
SEDINPLACE="/usr/bin/sed -i ''"
|
||||
DUFLAGS="-sk"
|
||||
@@ -333,6 +361,8 @@ esac
|
||||
AM_CONDITIONAL([DARWIN], test "x$host_os_darwin" = "xyes")
|
||||
AC_PATH_PROGS([DUPATH], [du], [du], [/usr/bin$PATH_SEPARATOR/bin] )
|
||||
AC_SUBST(INODECMD)
|
||||
AC_SUBST(OWNERCMD)
|
||||
AC_SUBST(MODECMD)
|
||||
AC_SUBST(SIZECMD)
|
||||
AC_SUBST(SEDINPLACE)
|
||||
AC_SUBST(DUFLAGS)
|
||||
@@ -457,6 +487,9 @@ AC_DEFINE_UNQUOTED([SRCEXT], "$SRCEXT", [The file extension used by pacman sourc
|
||||
# Set makepkg build script name
|
||||
AC_SUBST(BUILDSCRIPT)
|
||||
AC_DEFINE_UNQUOTED([BUILDSCRIPT], "$BUILDSCRIPT", [The build script name used by makepkg])
|
||||
# Set makepkg-template template directory
|
||||
AC_SUBST(TEMPLATE_DIR)
|
||||
AC_DEFINE_UNQUOTED([TEMPLATE_DIR], "$TEMPLATE_DIR", [The template directory used by makepkg-teplate])
|
||||
# Set makepkg split debugging symbol package suffix
|
||||
AC_SUBST(DEBUGSUFFIX)
|
||||
AC_DEFINE_UNQUOTED([DEBUGSUFFIX], "$DEBUGSUFFIX", [The suffix for debugging symbol packages used by makepkg])
|
||||
@@ -511,6 +544,8 @@ ${PACKAGE_NAME}:
|
||||
Architecture : ${CARCH}
|
||||
Host Type : ${CHOST}
|
||||
File inode command : ${INODECMD}
|
||||
File owner command : ${OWNERCMD}
|
||||
File mode command : ${MODECMD}
|
||||
Filesize command : ${SIZECMD}
|
||||
In-place sed command : ${SEDINPLACE}
|
||||
|
||||
@@ -524,6 +559,7 @@ ${PACKAGE_NAME}:
|
||||
package extension : ${PKGEXT}
|
||||
source pkg extension : ${SRCEXT}
|
||||
build script name : ${BUILDSCRIPT}
|
||||
template directory : ${TEMPLATE_DIR}
|
||||
|
||||
Compilation options:
|
||||
Use libcurl : ${have_libcurl}
|
||||
@@ -536,4 +572,4 @@ ${PACKAGE_NAME}:
|
||||
use git version : ${wantgitver}
|
||||
"
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
# vim:set noet:
|
||||
|
||||
1
contrib/.gitignore
vendored
1
contrib/.gitignore
vendored
@@ -7,7 +7,6 @@ paclist
|
||||
paclog-pkglist
|
||||
pacscripts
|
||||
pacsearch
|
||||
pacsysclean
|
||||
rankmirrors
|
||||
updpkgsums
|
||||
zsh_completion
|
||||
|
||||
@@ -12,7 +12,6 @@ BASHSCRIPTS = \
|
||||
paclist \
|
||||
paclog-pkglist \
|
||||
pacscripts \
|
||||
pacsysclean \
|
||||
rankmirrors \
|
||||
updpkgsums
|
||||
|
||||
@@ -23,14 +22,9 @@ OURSCRIPTS = \
|
||||
$(BASHSCRIPTS) \
|
||||
$(OTHERSCRIPTS)
|
||||
|
||||
OURFILES = \
|
||||
bash_completion \
|
||||
zsh_completion
|
||||
|
||||
EXTRA_DIST = \
|
||||
PKGBUILD.vim \
|
||||
bacman.sh.in \
|
||||
bash_completion.in \
|
||||
checkupdates.sh.in \
|
||||
paccache.sh.in \
|
||||
paclog-pkglist.sh.in \
|
||||
@@ -38,15 +32,13 @@ EXTRA_DIST = \
|
||||
paclist.sh.in \
|
||||
pacscripts.sh.in \
|
||||
pacsearch.in \
|
||||
pacsysclean.sh.in \
|
||||
rankmirrors.sh.in \
|
||||
updpkgsums.sh.in \
|
||||
vimprojects \
|
||||
zsh_completion.in \
|
||||
README
|
||||
|
||||
# Files that should be removed, but which Automake does not know.
|
||||
MOSTLYCLEANFILES = $(OURSCRIPTS) $(OURFILES) *.tmp
|
||||
MOSTLYCLEANFILES = $(OURSCRIPTS) *.tmp
|
||||
|
||||
if USE_GIT_VERSION
|
||||
GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 --dirty | sed s/^v//')
|
||||
@@ -81,20 +73,9 @@ $(OURFILES): Makefile
|
||||
$(AM_V_at)chmod a-w $@.tmp
|
||||
$(AM_V_at)mv $@.tmp $@
|
||||
|
||||
all-am: $(OURSCRIPTS) $(OURFILES)
|
||||
|
||||
install-data-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/bash_completion.d/
|
||||
$(INSTALL_DATA) bash_completion $(DESTDIR)$(sysconfdir)/bash_completion.d/pacman
|
||||
$(MKDIR_P) $(DESTDIR)$(datarootdir)/zsh/site-functions/
|
||||
$(INSTALL_DATA) zsh_completion $(DESTDIR)$(datarootdir)/zsh/site-functions/_pacman
|
||||
|
||||
uninstall-local:
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/bash_completion.d/pacman
|
||||
$(RM) $(DESTDIR)$(datarootdir)/zsh/site-functions/_pacman
|
||||
all-am: $(OURSCRIPTS)
|
||||
|
||||
bacman: $(srcdir)/bacman.sh.in
|
||||
bash_completion: $(srcdir)/bash_completion.in
|
||||
checkupdates: $(srcdir)/checkupdates.sh.in
|
||||
paccache: $(srcdir)/paccache.sh.in $(top_srcdir)/scripts/library/parseopts.sh $(top_srcdir)/scripts/library/size_to_human.sh
|
||||
pacdiff: $(srcdir)/pacdiff.sh.in
|
||||
@@ -102,9 +83,7 @@ paclist: $(srcdir)/paclist.sh.in
|
||||
paclog-pkglist: $(srcdir)/paclog-pkglist.sh.in
|
||||
pacscripts: $(srcdir)/pacscripts.sh.in
|
||||
pacsearch: $(srcdir)/pacsearch.in
|
||||
pacsysclean: $(srcdir)/pacsysclean.sh.in
|
||||
rankmirrors: $(srcdir)/rankmirrors.sh.in
|
||||
updpkgsums: $(srcdir)/updpkgsums.sh.in
|
||||
zsh_completion: $(srcdir)/zsh_completion.in
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
# vim:set noet:
|
||||
|
||||
@@ -211,7 +211,7 @@ hi def link pbValidSha512sums Number
|
||||
|
||||
" options
|
||||
syn keyword pb_k_options options contained
|
||||
syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|zipman\|purge\|upx\|fakeroot\|distcc\|color\|ccache\|check\|sign\|makeflags\|buildflags\)/ contained
|
||||
syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|zipman\|purge\|upx\|optipng\|distcc\|color\|ccache\|check\|sign\|makeflags\|buildflags\)/ contained
|
||||
syn match pbOptionsNeg /\!/ contained
|
||||
syn match pbOptionsDeprec /no/ contained
|
||||
syn region pbOptionsGroup start=/^options=(/ end=/)/ contains=pb_k_options,pbOptions,pbOptionsNeg,pbOptionsDeprec,pbIllegalOption
|
||||
|
||||
@@ -16,7 +16,7 @@ sync databases (for safety on rolling release distributions).
|
||||
paccache - a flexible package cache cleaning utility that allows greater
|
||||
control over which packages are removed.
|
||||
|
||||
pacdiff - a simple pacnew/pacorig/pacsave updater for /etc/.
|
||||
pacdiff - a simple pacnew/pacsave updater for /etc/.
|
||||
|
||||
paclist - list all packages installed from a given repository. Useful for
|
||||
seeing which packages you may have installed from the testing repository,
|
||||
@@ -31,8 +31,6 @@ pacsearch - a colorized search combining both -Ss and -Qs output. Installed
|
||||
packages are easily identified with a *** and local-only packages are also
|
||||
listed.
|
||||
|
||||
pacsysclean - lists installed packages sorted by size.
|
||||
|
||||
rankmirrors - ranks pacman mirrors by their connection and opening speed.
|
||||
|
||||
updpkgsums - performs an in place update of the checksums in a PKGBUILD.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# stored into the pacman database and system files
|
||||
#
|
||||
# Copyright (c) 2008 locci <carlocci_at_gmail_dot_com>
|
||||
# Copyright (c) 2008-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
# Copyright (c) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,9 @@ shopt -s nullglob
|
||||
declare -r myname='bacman'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
USE_COLOR='y'
|
||||
INCLUDE_PACNEW='n'
|
||||
# Required for fakeroot because options are shifted off the array.
|
||||
ARGS=("$@")
|
||||
|
||||
m4_include(../scripts/library/output_format.sh)
|
||||
|
||||
@@ -34,20 +37,32 @@ m4_include(../scripts/library/output_format.sh)
|
||||
# User Friendliness
|
||||
#
|
||||
usage() {
|
||||
echo "This program recreates a package using pacman's db and system files"
|
||||
echo "Usage: $myname [--nocolor] <installed package name>"
|
||||
echo "Example: $myname kernel26"
|
||||
echo "${myname} (pacman) v${myver}"
|
||||
echo
|
||||
echo "Recreate a package using pacman's database and system files"
|
||||
echo
|
||||
echo "Usage: ${myname} [--nocolor] [--pacnew] <installed package name>"
|
||||
echo
|
||||
echo "Example: ${myname} linux-headers"
|
||||
}
|
||||
|
||||
version() {
|
||||
printf "%s %s\n" "$myname" "$myver"
|
||||
echo 'Copyright (C) 2008 locci <carlocci_at_gmail_dot_com>'
|
||||
echo 'Copyright (C) 2008-2016 Pacman Development Team <pacman-dev@archlinux.org>'
|
||||
}
|
||||
|
||||
if [[ $1 == "--nocolor" ]]; then
|
||||
USE_COLOR='n'
|
||||
shift
|
||||
fi
|
||||
while [[ ! -z $1 ]]; do
|
||||
if [[ $1 == "--nocolor" ]]; then
|
||||
USE_COLOR='n'
|
||||
shift
|
||||
elif [[ $1 == "--pacnew" ]]; then
|
||||
INCLUDE_PACNEW='y'
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
m4_include(../scripts/library/term_colors.sh)
|
||||
|
||||
@@ -71,7 +86,7 @@ if (( EUID )); then
|
||||
if [[ -f /usr/bin/fakeroot ]]; then
|
||||
msg "Entering fakeroot environment"
|
||||
export INFAKEROOT="1"
|
||||
/usr/bin/fakeroot -u -- "$0" "$@"
|
||||
/usr/bin/fakeroot -u -- "$0" "${ARGS[@]}"
|
||||
exit $?
|
||||
else
|
||||
warning "installing fakeroot or running $myname as root is required to"
|
||||
@@ -124,7 +139,7 @@ fi
|
||||
|
||||
if [[ ! -d $pkg_dir ]]; then
|
||||
error "package %s is found in pacman database," "${pkg_name}"
|
||||
plain " but \`%s' is not a directory" "${pkg_dir}"
|
||||
plain " but '%s' is not a directory" "${pkg_dir}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -132,7 +147,7 @@ fi
|
||||
# Begin
|
||||
#
|
||||
msg "Package: ${pkg_namver}"
|
||||
work_dir=$(mktemp -d --tmpdir bacman.XXXXXXXXXX)
|
||||
work_dir=$(mktemp -d "${TMPDIR:-/tmp}/bacman.XXXXXXXXXX")
|
||||
cd "$work_dir" || exit 1
|
||||
|
||||
#
|
||||
@@ -140,7 +155,6 @@ cd "$work_dir" || exit 1
|
||||
#
|
||||
msg2 "Copying package files..."
|
||||
|
||||
cat "$pkg_dir"/files |
|
||||
while read i; do
|
||||
if [[ -z $i ]]; then
|
||||
continue
|
||||
@@ -153,24 +167,55 @@ while read i; do
|
||||
|
||||
case "$current" in
|
||||
%FILES%)
|
||||
ret=0
|
||||
if [[ -e /$i ]]; then
|
||||
bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf -
|
||||
local_file="/$i"
|
||||
package_file="$work_dir/$i"
|
||||
|
||||
# Workaround to bsdtar not reporting a missing file as an error
|
||||
if ! [[ -e $work_dir/$i || -L $work_dir/$i ]]; then
|
||||
error "unable to add /$i to the package"
|
||||
plain " If your user does not have permssion to read this file then"
|
||||
plain " you will need to run $myname as root"
|
||||
rm -rf "$work_dir"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
warning "package file /$i is missing"
|
||||
if [[ ! -e $local_file ]]; then
|
||||
warning "package file $local_file is missing"
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
|
||||
%BACKUP%)
|
||||
# Get the MD5 checksum.
|
||||
original_md5="${i##*$'\t'}"
|
||||
# Strip the md5sum after the tab.
|
||||
i="${i%$'\t'*}"
|
||||
local_file="/$i.pacnew"
|
||||
package_file="$work_dir/$i"
|
||||
|
||||
# Include unmodified .pacnew files.
|
||||
local_md5="$(md5sum "$local_file" | cut -d' ' -f1)"
|
||||
if [[ $INCLUDE_PACNEW == 'n' ]] \
|
||||
|| [[ ! -e $local_file ]] \
|
||||
|| [[ $local_md5 != $original_md5 ]]; then
|
||||
# Warn about modified files.
|
||||
local_md5="$(md5sum "/$i" | cut -d' ' -f1)"
|
||||
if [[ $local_md5 != $original_md5 ]]; then
|
||||
warning "package file /$i has been modified"
|
||||
fi
|
||||
# Let the normal file be included in the %FILES% list.
|
||||
continue
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
ret=0
|
||||
bsdtar -cnf - -s'/.pacnew$//' "$local_file" 2> /dev/null | bsdtar -xpf - 2> /dev/null
|
||||
|
||||
# Workaround to bsdtar not reporting a missing file as an error
|
||||
if ! [[ -e $package_file || -L $package_file ]]; then
|
||||
error "unable to add $local_file to the package"
|
||||
plain " If your user does not have permission to read this file, then"
|
||||
plain " you will need to run $myname as root."
|
||||
rm -rf "$work_dir"
|
||||
exit 1
|
||||
fi
|
||||
done < "$pkg_dir"/files
|
||||
|
||||
ret=$?
|
||||
if (( ret )); then
|
||||
@@ -253,7 +298,7 @@ while read i; do
|
||||
|
||||
# files
|
||||
%BACKUP%)
|
||||
# strip the md5sum after the tab
|
||||
# Strip the md5sum after the tab
|
||||
echo "backup = ${i%%$'\t'*}" >> .PKGINFO
|
||||
;;
|
||||
esac
|
||||
@@ -310,4 +355,4 @@ msg "Done."
|
||||
|
||||
exit 0
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -18,13 +18,28 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
declare -r myname='checkupdates'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
m4_include(../scripts/library/output_format.sh)
|
||||
m4_include(../scripts/library/term_colors.sh)
|
||||
|
||||
if (( $# > 0 )); then
|
||||
echo "checkupdates: Safely print a list of pending updates."
|
||||
echo "Use: checkupdates"
|
||||
echo "Export the 'CHECKUPDATES_DB' variable to change the path of the temporary database."
|
||||
echo "${myname} (pacman) v${myver}"
|
||||
echo
|
||||
echo "Safely print a list of pending updates"
|
||||
echo
|
||||
echo "Usage: ${myname}"
|
||||
echo
|
||||
echo 'Note: Export the "CHECKUPDATES_DB" variable to change the path of the temporary database.'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! type -P fakeroot >/dev/null; then
|
||||
error 'Cannot find the fakeroot binary.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z $CHECKUPDATES_DB ]]; then
|
||||
CHECKUPDATES_DB="${TMPDIR:-/tmp}/checkup-db-${USER}/"
|
||||
fi
|
||||
@@ -36,9 +51,9 @@ eval $(awk -F' *= *' '$1 ~ /DBPath/ { print $1 "=" $2 }' @sysconfdir@/pacman.con
|
||||
|
||||
mkdir -p "$CHECKUPDATES_DB"
|
||||
ln -s "${DBPath}/local" "$CHECKUPDATES_DB" &> /dev/null
|
||||
fakeroot pacman -Sy --dbpath "$CHECKUPDATES_DB" --logfile /dev/null &> /dev/null
|
||||
pacman -Qqu --dbpath "$CHECKUPDATES_DB" 2> /dev/null
|
||||
fakeroot -- pacman -Sy --dbpath "$CHECKUPDATES_DB" --logfile /dev/null &> /dev/null
|
||||
pacman -Qu --dbpath "$CHECKUPDATES_DB" 2> /dev/null | grep -v '\[.*\]'
|
||||
|
||||
exit 0
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -23,10 +23,11 @@ shopt -s extglob
|
||||
declare -r myname='paccache'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
declare -a candidates=() cmdopts=() whitelist=() blacklist=()
|
||||
declare -a cachedirs=() candidates=() cmdopts=() whitelist=() blacklist=()
|
||||
declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0
|
||||
declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3 movedir= scanarch=
|
||||
declare delim=$'\n' keep=3 movedir= scanarch=
|
||||
|
||||
QUIET=0
|
||||
USE_COLOR='y'
|
||||
|
||||
m4_include(../scripts/library/output_format.sh)
|
||||
@@ -37,15 +38,33 @@ die() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
get_cachedir_from_config() {
|
||||
local key value
|
||||
|
||||
while IFS=$'= \t' read -r key value _; do
|
||||
if [[ $key = CacheDir ]]; then
|
||||
echo "$value"
|
||||
return 0
|
||||
fi
|
||||
done <"$1"
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# reads a list of files on stdin and prints out deletion candidates
|
||||
pkgfilter() {
|
||||
# there's whitelist and blacklist parameters passed to this
|
||||
# script after the block of awk.
|
||||
|
||||
awk -v keep="$1" -v scanarch="$2" '
|
||||
function basename(str) {
|
||||
sub(".*/", "", str);
|
||||
return str;
|
||||
}
|
||||
|
||||
function parse_filename(filename, parts, count, i, pkgname, arch) {
|
||||
|
||||
count = split(filename, parts, "-")
|
||||
count = split(basename(filename), parts, "-")
|
||||
|
||||
i = 1
|
||||
pkgname = parts[i++]
|
||||
@@ -117,6 +136,8 @@ runcmd() {
|
||||
}
|
||||
|
||||
summarize() {
|
||||
(( QUIET )) && return
|
||||
|
||||
local -i filecount=$1; shift
|
||||
local seenarch= seen= arch= name=
|
||||
local -r pkg_re='(.+)-[^-]+-[0-9]+-([^.]+)\.pkg.*'
|
||||
@@ -133,48 +154,52 @@ summarize() {
|
||||
[[ $pkg =~ $pkg_re ]] && name=${BASH_REMATCH[1]} arch=${BASH_REMATCH[2]}
|
||||
if [[ -z $seen || $seenarch != "$arch" || $seen != "$name" ]]; then
|
||||
seen=$name seenarch=$arch
|
||||
printf '%s (%s):\n' "$name" "$arch"
|
||||
printf '%s (%s):\n' "${name##*/}" "$arch"
|
||||
fi
|
||||
printf ' %s\n' "$pkg"
|
||||
printf ' %s\n' "${pkg##*/}"
|
||||
elif (( verbose >= 2 )); then
|
||||
printf "$PWD/%s$delim" "$pkg"
|
||||
else
|
||||
printf "%s$delim" "$pkg"
|
||||
else
|
||||
printf "%s$delim" "${pkg##*/}"
|
||||
fi
|
||||
done < <(printf '%s\n' "$@" | pacsort --files)
|
||||
fi
|
||||
printf -v output 'finished dry run: %d candidates' "$filecount"
|
||||
fi
|
||||
|
||||
printf '\n' >&2
|
||||
msg "$output (diskspace saved: %s)" "$(size_to_human "$totalsaved")"
|
||||
echo
|
||||
msg "$output (disk space saved: %s)" "$(size_to_human "$totalsaved")"
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
usage: $myname <operation> [options] [targets...]
|
||||
${myname} (pacman) v${myver}
|
||||
|
||||
$myname is a flexible pacman cache cleaning utility, which has numerous
|
||||
options to help control how much, and what, is deleted from any directory
|
||||
containing pacman package tarballs.
|
||||
A flexible pacman cache cleaning utility.
|
||||
|
||||
Usage: ${myname} <operation> [options] [targets...]
|
||||
|
||||
Operations:
|
||||
-d, --dryrun perform a dry run, only finding candidate packages.
|
||||
-m, --move <dir> move candidate packages to 'movedir'.
|
||||
-r, --remove remove candidate packages.
|
||||
-d, --dryrun perform a dry run, only finding candidate packages.
|
||||
-m, --move <dir> move candidate packages to "dir".
|
||||
-r, --remove remove candidate packages.
|
||||
|
||||
Options:
|
||||
-a, --arch <arch> scan for 'arch' (default: all architectures).
|
||||
-c, --cachedir <dir> scan 'cachedir' for packages (default: @localstatedir@/cache/pacman/pkg).
|
||||
-f, --force apply force to mv(1) and rm(1) operations.
|
||||
-h, --help display this help message and exit.
|
||||
-i, --ignore <pkgs> ignore 'pkgs', comma separated. Alternatively, specify '-' to
|
||||
read package names from stdin, newline delimited.
|
||||
-k, --keep <num> keep 'num' of each package in 'cachedir' (default: 3).
|
||||
--nocolor remove color from output.
|
||||
-u, --uninstalled target uninstalled packages.
|
||||
-v, --verbose increase verbosity. specify up to 3 times.
|
||||
-z, --null use null delimiters for candidate names (only with -v and -vv)
|
||||
-a, --arch <arch> scan for "arch" (default: all architectures).
|
||||
-c, --cachedir <dir> scan "dir" for packages. can be used more than once.
|
||||
(default: read from @sysconfdir@/pacman.conf).
|
||||
-f, --force apply force to mv(1) and rm(1) operations.
|
||||
-h, --help display this help message and exit.
|
||||
-i, --ignore <pkgs> ignore "pkgs", comma-separated. Alternatively, specify
|
||||
"-" to read package names from stdin, newline-
|
||||
delimited.
|
||||
-k, --keep <num> keep "num" of each package in the cache (default: 3).
|
||||
--nocolor remove color from output.
|
||||
-q, --quiet minimize output
|
||||
-u, --uninstalled target uninstalled packages.
|
||||
-v, --verbose increase verbosity. specify up to 3 times.
|
||||
-z, --null use null delimiters for candidate names (only with -v
|
||||
and -vv).
|
||||
|
||||
EOF
|
||||
}
|
||||
@@ -184,9 +209,9 @@ version() {
|
||||
echo 'Copyright (C) 2011 Dave Reisner <dreisner@archlinux.org>'
|
||||
}
|
||||
|
||||
OPT_SHORT=':a:c:dfhi:k:m:rsuVvz'
|
||||
OPT_SHORT=':a:c:dfhi:k:m:qrsuVvz'
|
||||
OPT_LONG=('arch:' 'cachedir:' 'dryrun' 'force' 'help' 'ignore:' 'keep:' 'move'
|
||||
'nocolor' 'remove' 'uninstalled' 'version' 'verbose' 'null')
|
||||
'nocolor' 'quiet' 'remove' 'uninstalled' 'version' 'verbose' 'null')
|
||||
|
||||
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
|
||||
exit 1
|
||||
@@ -200,7 +225,7 @@ while :; do
|
||||
scanarch=$2
|
||||
shift ;;
|
||||
-c|--cachedir)
|
||||
cachedir=$2
|
||||
cachedirs+=("$2")
|
||||
shift ;;
|
||||
-d|--dryrun)
|
||||
dryrun=1 ;;
|
||||
@@ -226,15 +251,19 @@ while :; do
|
||||
keep=$(( 10#$keep ))
|
||||
fi
|
||||
shift ;;
|
||||
--nocolor)
|
||||
USE_COLOR='n' ;;
|
||||
-m|--move)
|
||||
move=1 movedir=$2
|
||||
shift ;;
|
||||
--nocolor)
|
||||
USE_COLOR='n' ;;
|
||||
-q|--quiet)
|
||||
QUIET=1 ;;
|
||||
-r|--remove)
|
||||
delete=1 ;;
|
||||
-u|--uninstalled)
|
||||
IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq)
|
||||
# pacman -Qq may exit with an error, thus making ign an empty array
|
||||
(( ${#ign[@]} )) || die 'failed to retrieve the list of installed packages'
|
||||
blacklist+=("${ign[@]}")
|
||||
unset ign ;;
|
||||
-V|--version)
|
||||
@@ -253,6 +282,15 @@ done
|
||||
|
||||
m4_include(../scripts/library/term_colors.sh)
|
||||
|
||||
# setting default cachedir
|
||||
if [[ -z $cachedirs ]]; then
|
||||
if cachedir=$(get_cachedir_from_config "@sysconfdir@/pacman.conf"); then
|
||||
cachedirs=("$cachedir")
|
||||
else
|
||||
cachedirs=("${cachedirs[@]:-@localstatedir@/cache/pacman/pkg}")
|
||||
fi
|
||||
fi
|
||||
|
||||
# remaining args are a whitelist
|
||||
whitelist=("$@")
|
||||
|
||||
@@ -262,32 +300,43 @@ case $(( dryrun+delete+move )) in
|
||||
[^1]) die "only one operation may be used at a time" ;;
|
||||
esac
|
||||
|
||||
[[ -d $cachedir ]] ||
|
||||
die "cachedir '%s' does not exist or is not a directory" "$cachedir"
|
||||
|
||||
[[ $movedir && ! -d $movedir ]] &&
|
||||
die "move-to directory '%s' does not exist or is not a directory" "$movedir"
|
||||
die "destination directory '%s' does not exist or is not a directory" "$movedir"
|
||||
|
||||
if (( move || delete )); then
|
||||
# make it an absolute path since we're about to chdir
|
||||
[[ ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir
|
||||
[[ ! -w $cachedir || ( $movedir && ! -w $movedir ) ]] && needsroot=1
|
||||
[[ $movedir && ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir
|
||||
[[ $movedir && ! -w $movedir ]] && needsroot=1
|
||||
fi
|
||||
|
||||
# unlikely that this will fail, but better make sure
|
||||
cd "$cachedir" >/dev/null || die "failed to chdir to '%s'" "$cachedir"
|
||||
for cachedir in "${cachedirs[@]}"; do
|
||||
[[ -d $cachedir ]] ||
|
||||
die "cachedir '%s' does not exist or is not a directory" "$cachedir"
|
||||
|
||||
# note that these results are returned in an arbitrary order from awk, but
|
||||
# they'll be resorted (in summarize) iff we have a verbosity level set.
|
||||
IFS=$'\n' read -r -d '' -a candidates < \
|
||||
<(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort --files |
|
||||
pkgfilter "$keep" "$scanarch" \
|
||||
"${#whitelist[*]}" "${whitelist[@]}" \
|
||||
"${#blacklist[*]}" "${blacklist[@]}")
|
||||
if (( move || delete )); then
|
||||
[[ ! -w $cachedir ]] && needsroot=1
|
||||
fi
|
||||
|
||||
# unlikely that this will fail, but better make sure
|
||||
pushd "$cachedir" &>/dev/null || die "failed to chdir to '%s'" "$cachedir"
|
||||
|
||||
# note that these results are returned in an arbitrary order from awk, but
|
||||
# they'll be resorted (in summarize) iff we have a verbosity level set.
|
||||
IFS=$'\n' read -r -d '' -a cand < \
|
||||
<(printf '%s\n' "$PWD"/*.pkg.tar?(.+([^.])) | pacsort --files |
|
||||
pkgfilter "$keep" "$scanarch" \
|
||||
"${#whitelist[*]}" "${whitelist[@]}" \
|
||||
"${#blacklist[*]}" "${blacklist[@]}")
|
||||
|
||||
candidates+=("${cand[@]}")
|
||||
unset cand
|
||||
|
||||
popd &>/dev/null
|
||||
done
|
||||
|
||||
if (( ! ${#candidates[*]} )); then
|
||||
msg 'no candidate packages found for pruning'
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# grab this prior to signature scavenging
|
||||
@@ -295,8 +344,8 @@ pkgcount=${#candidates[*]}
|
||||
|
||||
# copy the list, merging in any found sigs
|
||||
for cand in "${candidates[@]}"; do
|
||||
candtemp+=("$cand")
|
||||
[[ -f $cand.sig ]] && candtemp+=("$cand.sig")
|
||||
candtemp+=("$cand")
|
||||
[[ -f $cand.sig ]] && candtemp+=("$cand.sig")
|
||||
done
|
||||
candidates=("${candtemp[@]}")
|
||||
unset candtemp
|
||||
@@ -314,4 +363,4 @@ fi
|
||||
|
||||
summarize "$pkgcount" "${candidates[@]}"
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
# pacdiff : a simple pacnew/pacorig/pacsave updater
|
||||
# pacdiff : a simple pacnew/pacsave updater
|
||||
#
|
||||
# Copyright (c) 2007 Aaron Griffin <aaronmgriffin@gmail.com>
|
||||
# Copyright (c) 2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
# Copyright (c) 2013-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -18,52 +18,129 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
declare -r myname='pacdiff'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
diffprog=${DIFFPROG:-vimdiff}
|
||||
diffprog=${DIFFPROG:-'vim -d'}
|
||||
diffsearchpath=${DIFFSEARCHPATH:-/etc}
|
||||
locate=0
|
||||
USE_COLOR='y'
|
||||
declare -a oldsaves
|
||||
declare -i USE_FIND=0 USE_LOCATE=0 USE_PACDB=0 OUTPUTONLY=0
|
||||
|
||||
m4_include(../scripts/library/output_format.sh)
|
||||
|
||||
m4_include(../scripts/library/term_colors.sh)
|
||||
|
||||
usage() {
|
||||
echo "$myname : a simple pacnew/pacorig/pacsave updater"
|
||||
echo "Usage : $myname [-l]"
|
||||
echo " -l/--locate makes $myname use locate rather than find"
|
||||
echo " DIFFPROG variable allows to override the default vimdiff"
|
||||
echo " DIFFSEARCHPATH allows to override the default /etc path"
|
||||
echo "Example : DIFFPROG=meld DIFFSEARCHPATH=\"/boot /etc /usr\" $myname"
|
||||
cat <<EOF
|
||||
${myname} (pacman) v${myver}
|
||||
|
||||
A simple program to merge or remove pacnew/pacsave files.
|
||||
|
||||
Usage: $myname [-l | -f | -p] [--nocolor]
|
||||
|
||||
Search Options: select one (default: --pacmandb)
|
||||
-l/--locate scan using locate
|
||||
-f/--find scan using find
|
||||
-p/--pacmandb scan active config files from pacman database
|
||||
|
||||
General Options:
|
||||
-o/--output print files instead of merging them
|
||||
--nocolor remove colors from output
|
||||
|
||||
Environment Variables:
|
||||
DIFFPROG override the merge program: (default: 'vim -d')
|
||||
DIFFSEARCHPATH override the search path. (only when using find)
|
||||
(default: /etc)
|
||||
|
||||
Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname
|
||||
Example: $myname --output --locate
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
version() {
|
||||
printf "%s %s\n" "$myname" "$myver"
|
||||
echo 'Copyright (C) 2007 Aaron Griffin <aaronmgriffin@gmail.com>'
|
||||
echo 'Copyright (C) 2013 Pacman Development Team <pacman-dev@archlinux.org>'
|
||||
echo 'Copyright (C) 2013-2016 Pacman Development Team <pacman-dev@archlinux.org>'
|
||||
}
|
||||
|
||||
print_existing() {
|
||||
[[ -f "$1" ]] && printf '%s\0' "$1"
|
||||
}
|
||||
|
||||
print_existing_pacsave(){
|
||||
for f in "${1}"?(.+([0-9])); do
|
||||
[[ -f $f ]] && printf '%s\0' "$f"
|
||||
done
|
||||
}
|
||||
|
||||
cmd() {
|
||||
if [ $locate -eq 1 ]; then
|
||||
locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave
|
||||
else
|
||||
find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave \) -print0
|
||||
if (( USE_LOCATE )); then
|
||||
locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave '*.pacsave.[0-9]*'
|
||||
elif (( USE_FIND )); then
|
||||
find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave -o -name '*.pacsave.[0-9]*' \) -print0
|
||||
elif (( USE_PACDB )); then
|
||||
awk '/^%BACKUP%$/ {
|
||||
while (getline) {
|
||||
if (/^$/) { nextfile }
|
||||
print $1
|
||||
}
|
||||
}' "${pac_db}"/*/files | while read -r bkup; do
|
||||
print_existing "/$bkup.pacnew"
|
||||
print_existing "/$bkup.pacorig"
|
||||
print_existing_pacsave "/$bkup.pacsave"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
case $1 in
|
||||
while [[ -n "$1" ]]; do
|
||||
case "$1" in
|
||||
-l|--locate)
|
||||
locate=1;;
|
||||
USE_LOCATE=1;;
|
||||
-f|--find)
|
||||
USE_FIND=1;;
|
||||
-p|--pacmandb)
|
||||
USE_PACDB=1;;
|
||||
-o|--output)
|
||||
OUTPUTONLY=1;;
|
||||
--nocolor)
|
||||
USE_COLOR='n';;
|
||||
-V|--version)
|
||||
version; exit 0;;
|
||||
version; exit 0;;
|
||||
-h|--help)
|
||||
usage; exit 0;;
|
||||
usage; exit 0;;
|
||||
*)
|
||||
usage; exit 1;;
|
||||
usage; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
m4_include(../scripts/library/term_colors.sh)
|
||||
|
||||
if ! type -p ${diffprog%% *} >/dev/null && (( ! OUTPUTONLY )); then
|
||||
error "Cannot find the $diffprog binary required for viewing differences."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $(( USE_FIND + USE_LOCATE + USE_PACDB )) in
|
||||
0) USE_PACDB=1;; # set the default search option
|
||||
[^1]) error "Only one search option may be used at a time"
|
||||
usage; exit 1;;
|
||||
esac
|
||||
|
||||
if (( USE_PACDB )); then
|
||||
if [[ ! -r @sysconfdir@/pacman.conf ]]; then
|
||||
error "unable to read @sysconfdir@/pacman.conf"
|
||||
usage; exit 1
|
||||
fi
|
||||
|
||||
eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
|
||||
pac_db="${DBPath:-@localstatedir@/lib/pacman/}local"
|
||||
if [[ ! -d "${pac_db}" ]]; then
|
||||
error "unable to read pacman database %s". "${pac_db}"
|
||||
usage; exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# see http://mywiki.wooledge.org/BashFAQ/020
|
||||
@@ -71,6 +148,17 @@ while IFS= read -u 3 -r -d '' pacfile; do
|
||||
file="${pacfile%.pac*}"
|
||||
file_type="pac${pacfile##*.pac}"
|
||||
|
||||
if (( OUTPUTONLY )); then
|
||||
echo "$pacfile"
|
||||
continue
|
||||
fi
|
||||
|
||||
# add matches for pacsave.N to oldsaves array, do not prompt
|
||||
if [[ $file_type = pacsave.+([0-9]) ]]; then
|
||||
oldsaves+=("$pacfile")
|
||||
continue
|
||||
fi
|
||||
|
||||
msg "%s file found for %s" "$file_type" "$file"
|
||||
if [ ! -f "$file" ]; then
|
||||
warning "$file does not exist"
|
||||
@@ -82,21 +170,25 @@ while IFS= read -u 3 -r -d '' pacfile; do
|
||||
msg2 "Files are identical, removing..."
|
||||
rm -v "$pacfile"
|
||||
else
|
||||
ask "(V)iew, (S)kip, (R)emove %s, (O)verwrite with %s: [v/s/r/o] " "$file_type" "$file_type"
|
||||
ask "(V)iew, (S)kip, (R)emove %s, (O)verwrite with %s, (Q)uit: [v/s/r/o/q] " "$file_type" "$file_type"
|
||||
while read c; do
|
||||
case $c in
|
||||
q|Q) exit 0;;
|
||||
r|R) rm -v "$pacfile"; break ;;
|
||||
o|O) mv -v "$pacfile" "$file"; break ;;
|
||||
v|V)
|
||||
$diffprog "$pacfile" "$file"
|
||||
rm -iv "$pacfile"; break ;;
|
||||
$diffprog "$pacfile" "$file"
|
||||
ask "(V)iew, (S)kip, (R)emove %s, (O)verwrite with %s, (Q)uit: [v/s/r/o/q] " "$file_type" "$file_type";
|
||||
continue ;;
|
||||
s|S) break ;;
|
||||
*) ask "Invalid answer. Try again: [v/s/r/o] "; continue ;;
|
||||
*) ask "Invalid answer. Try again: [v/s/r/o/q] "; continue ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
done 3< <(cmd)
|
||||
|
||||
(( ${#oldsaves[@]} )) && warning "Ignoring %s" "${oldsaves[@]}"
|
||||
|
||||
exit 0
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -31,9 +31,13 @@ if ! type gettext &>/dev/null; then
|
||||
fi
|
||||
|
||||
usage() {
|
||||
printf '%s - List all packages installed from a given repo\n' "$myname"
|
||||
printf 'Usage: %s <repo>\n' "$myname"
|
||||
printf 'Example: %s testing\n' "$myname"
|
||||
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
|
||||
echo
|
||||
printf "List all packages installed from a given repository\n" "${myname}"
|
||||
echo
|
||||
printf "Usage: %s <repository>\n" "${myname}"
|
||||
echo
|
||||
printf "Example: %s testing\n" "${myname}"
|
||||
}
|
||||
|
||||
version() {
|
||||
@@ -61,4 +65,4 @@ pacman -Sl $1 | awk -v i="$installed" '$NF == i { print $2,$3 }'
|
||||
# exit with pacman's return value, not awk's
|
||||
exit ${PIPESTATUS[0]}
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
14
contrib/paclog-pkglist.sh.in
Executable file → Normal file
14
contrib/paclog-pkglist.sh.in
Executable file → Normal file
@@ -25,9 +25,15 @@ export TEXTDOMAINDIR='/usr/share/locale'
|
||||
declare logfile=${1:-@localstatedir@/log/pacman.log}
|
||||
|
||||
usage() {
|
||||
printf 'usage: %s [pacman log]\n' "$myname"
|
||||
printf 'example: %s @localstatedir@/log/pacman.log\n' "$myname"
|
||||
printf '\ndefaults to: @localstatedir@/log/pacman.log\n'
|
||||
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
|
||||
echo
|
||||
echo "Parse a log file into a list of currently installed packages"
|
||||
echo
|
||||
printf "Usage: %s [path to pacman log]\n" "${myname}"
|
||||
echo
|
||||
printf "Example: %s @localstatedir@/log/pacman.log\n" "${myname}"
|
||||
echo
|
||||
echo 'Defaults to: @localstatedir@/log/pacman.log'
|
||||
}
|
||||
|
||||
version() {
|
||||
@@ -90,4 +96,4 @@ END {
|
||||
}
|
||||
}' | sort
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
# pacscripts : tries to print out the {pre,post}_{install,remove,upgrade}
|
||||
# scripts of a given package
|
||||
#
|
||||
# Copyright (c) 2009 Giulio "giulivo" Fidente <giulivo.navigante@gmail.com>
|
||||
# Copyright (c) 2009 Xavier Chantry <shiningxc@gmail.com>
|
||||
# Copyright (c) 2009-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
# Copyright (c) 2009-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -46,16 +45,18 @@ error() {
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "This program prints out the {pre,post}_{install,remove,upgrade} scripts"
|
||||
echo "of a given package."
|
||||
echo "Usage: $myname pkgname|pkgfile"
|
||||
echo "${myname} (pacman) v${myver}"
|
||||
echo
|
||||
echo " OPTIONS:"
|
||||
echo "Prints the {pre,post}_{install,remove,upgrade} scripts of a given package."
|
||||
echo
|
||||
echo "Usage: ${myname} <pkgname|pkgfile>"
|
||||
echo
|
||||
echo " Options:"
|
||||
echo " -h, --help Print this help message"
|
||||
echo " -v, --version Print program name and version"
|
||||
echo
|
||||
echo "Example: $myname gconf-editor"
|
||||
echo "Example: $myname gconf-editor-2.24.1-1-x86_64.pkg.tar.gz"
|
||||
echo "Example: ${myname} gconf-editor"
|
||||
echo "Example: ${myname} gconf-editor-3.0.1-3-x86_64.pkg.tar.xz"
|
||||
}
|
||||
|
||||
version() {
|
||||
@@ -69,8 +70,8 @@ spacman() {
|
||||
pacman "$@"
|
||||
else
|
||||
if ! type -p sudo; then
|
||||
error "Cannot find the sudo binary! Is sudo installed?"
|
||||
error "Otherwise try to run the program as root"
|
||||
error "Cannot find the sudo binary!"
|
||||
error "${myname} requires root privileges. Either install \"sudo\" or run as root."
|
||||
exit 1
|
||||
else
|
||||
sudo pacman "$@"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
# pacsearch - Adds color and install information to a 'pacman -Ss' search
|
||||
# pacsearch - Perform a pacman search using both the local and the sync databases
|
||||
#
|
||||
# Copyright (C) 2008-2011 Dan McGee <dan@archlinux.org>
|
||||
# Copyright (C) 2008-2014 Dan McGee <dan@archlinux.org>
|
||||
#
|
||||
# Based off original shell script version:
|
||||
# Copyright (C) 2006-2007 Dan McGee <dan@archlinux.org>
|
||||
@@ -19,23 +19,25 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#TODO: colors flag on commandline
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Term::ANSIColor;
|
||||
|
||||
my $myname = 'pacsearch';
|
||||
my $myver = '@PACKAGE_VERSION@';
|
||||
|
||||
sub usage {
|
||||
print "$myname - Add color and install information to a pacman -Ss search\n";
|
||||
print "Usage: $myname <pattern>\n";
|
||||
print "$myname (pacman) v$myver\n\n";
|
||||
print "Perform a pacman search using both the local and the sync databases.\n\n";
|
||||
print "Usage: $myname [-n] <pattern>\n\n";
|
||||
print "Options:\n";
|
||||
print " -n, --nocolor: turn off coloring\n\n";
|
||||
print "Example: $myname ^gnome\n";
|
||||
}
|
||||
|
||||
sub version {
|
||||
printf "%s %s\n", $myname, $myver;
|
||||
print "Copyright (C) 2008-2011 Dan McGee <dan\@archlinux.org>\n\n";
|
||||
print "Copyright (C) 2008-2014 Dan McGee <dan\@archlinux.org>\n\n";
|
||||
print "Based off original shell script version:\n";
|
||||
print "Copyright (C) 2006-2007 Dan McGee <dan\@archlinux.org>\n";
|
||||
}
|
||||
@@ -53,96 +55,71 @@ if ($ARGV[0] eq "--version" || $ARGV[0] eq "-V") {
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# define our colors to use when printing
|
||||
my $CLR1 = "\e[0;34m";
|
||||
my $CLR2 = "\e[0;32m";
|
||||
my $CLR3 = "\e[0;35m";
|
||||
my $CLR4 = "\e[0;36m";
|
||||
my $CLR5 = "\e[0;31m";
|
||||
my $CLR6 = "\e[0;33m";
|
||||
my $CLR7 = "\e[1;36m";
|
||||
my $INST = "\e[1;31m";
|
||||
my $BASE = "\e[0m";
|
||||
|
||||
# color a "repo/pkgname pkgver" line based on the repository name
|
||||
sub to_color {
|
||||
my $line = shift;
|
||||
# get the installed text colored first
|
||||
$line =~ s/(\[.*\]$)/$INST$1$BASE/;
|
||||
# and now the repo and dealings
|
||||
$line =~ s/(^core\/.*)/$CLR1$1$BASE/;
|
||||
$line =~ s/(^extra\/.*)/$CLR2$1$BASE/;
|
||||
$line =~ s/(^community\/.*)/$CLR3$1$BASE/;
|
||||
$line =~ s/(^testing\/.*)/$CLR4$1$BASE/;
|
||||
$line =~ s/(^community-testing\/.*)/$CLR5$1$BASE/;
|
||||
$line =~ s/(^multilib\/.*)/$CLR6$1$BASE/;
|
||||
$line =~ s/(^local\/.*)/$CLR7$1$BASE/;
|
||||
# any other unknown repository
|
||||
$line =~ s/(^[\w-]*\/.*)/$CLR6$1$BASE/;
|
||||
return $line;
|
||||
# define formatting variables
|
||||
my($BLUE, $CYAN, $GREEN, $MAGENTA, $RED, $YELLOW, $BOLD, $RESET);
|
||||
if ($ARGV[0] eq "--nocolor" || $ARGV[0] eq "-n") {
|
||||
shift;
|
||||
$BLUE = "";
|
||||
$CYAN = "";
|
||||
$GREEN = "";
|
||||
$MAGENTA = "";
|
||||
$RED = "";
|
||||
$YELLOW = "";
|
||||
$BOLD = "";
|
||||
$RESET = "";
|
||||
} else {
|
||||
$BLUE = color('blue');
|
||||
$CYAN = color('cyan');
|
||||
$GREEN = color('green');
|
||||
$MAGENTA = color('magenta');
|
||||
$RED = color('red');
|
||||
$YELLOW = color('yellow');
|
||||
$BOLD = color('bold');
|
||||
$RESET = color('reset');
|
||||
}
|
||||
|
||||
my %allpkgs = ();
|
||||
# localization
|
||||
my $LC_INSTALLED = `gettext pacman installed`;
|
||||
|
||||
my $syncout = `pacman -Ss '@ARGV'`;
|
||||
# split each sync search entry into its own array entry
|
||||
my @syncpkgs = split(/\n^(?=\w)/m, $syncout);
|
||||
# remove the extra \n from the last desc entry
|
||||
if ($#syncpkgs >= 0) {
|
||||
chomp($syncpkgs[$#syncpkgs]);
|
||||
}
|
||||
|
||||
# counter var for packages, used here and in the query loop too
|
||||
my $cnt = 0;
|
||||
foreach $_ (@syncpkgs) {
|
||||
# we grab 4 fields here: repo, name/ver, installed, and desc
|
||||
my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
|
||||
if(not @pkgfields) {
|
||||
# skip any non-matching line and just print it for the user
|
||||
print $_, "\n";
|
||||
next;
|
||||
# Print a "repo/pkgname pkgver (groups) [installed]" line.
|
||||
# We stick to pacman colors.
|
||||
sub print_pkg {
|
||||
my @v = @_;
|
||||
print "$RESET$BOLD";
|
||||
if ( "$v[0]" eq "local" ) {
|
||||
print "$RED";
|
||||
} else {
|
||||
print "$MAGENTA";
|
||||
}
|
||||
# since installed is optional, we should fill it in if necessary
|
||||
$pkgfields[2] = "" if not defined $pkgfields[2];
|
||||
# add a fifth field that indicates original order
|
||||
push (@pkgfields, $cnt++);
|
||||
# add each sync pkg by name/ver to a hash table for quick lookup
|
||||
$allpkgs{$pkgfields[1]} = [ @pkgfields ];
|
||||
print "$v[0]/$RESET$BOLD$v[1] $GREEN$v[2]$BLUE$v[3]$CYAN$v[4]$RESET\n";
|
||||
print "$v[5]";
|
||||
}
|
||||
|
||||
my $queryout = `pacman -Qs '@ARGV'`;
|
||||
# split each querysearch entry into its own array entry
|
||||
my @querypkgs = split(/\n^(?=\w)/m, $queryout);
|
||||
# remove the extra \n from the last desc entry
|
||||
if ($#querypkgs >= 0) {
|
||||
chomp ($querypkgs[$#querypkgs]);
|
||||
}
|
||||
|
||||
foreach $_ (@querypkgs) {
|
||||
# we grab 4 fields here: repo, name/ver, installed, and desc
|
||||
my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
|
||||
# skip any non-matching line
|
||||
next if not defined $pkgfields[1];
|
||||
# since installed is optional, we should fill it in if necessary
|
||||
$pkgfields[2] = "" if not defined $pkgfields[2];
|
||||
# check if the package was listed in the sync out
|
||||
if (not exists $allpkgs{$pkgfields[1]}) {
|
||||
$pkgfields[2] = "[installed]";
|
||||
# add a fifth field that indicates original order (after sync)
|
||||
push (@pkgfields, $cnt++);
|
||||
# add our local-only package to the hash
|
||||
$allpkgs{$pkgfields[1]} = [ @pkgfields ];
|
||||
sub list_pkg {
|
||||
my $db = shift;
|
||||
open (my $out, '-|', 'pacman', $db, '--', @ARGV) or exit 1;
|
||||
my @pkglist = ();
|
||||
while ( readline($out) ) {
|
||||
# We grab the following fields: repo, name, ver, group, installed, and
|
||||
# desc. We grab leading space for 'group' and 'installed' so that we do
|
||||
# not need to test if non-empty when printing.
|
||||
my @pkgfields = /^(.*?)\/(.*?) (.*?)( \(.*?\))?( \[.*\])?$/s;
|
||||
my $desc = readline($out);
|
||||
# since 'group' and 'installed' are optional, we should fill it in if
|
||||
# necessary
|
||||
$pkgfields[3] = "" if not defined $pkgfields[3];
|
||||
$pkgfields[4] = "" if not defined $pkgfields[4];
|
||||
$pkgfields[5] = $desc;
|
||||
push (@pkglist, \@pkgfields);
|
||||
}
|
||||
close ($out);
|
||||
return @pkglist;
|
||||
}
|
||||
|
||||
# sort by original order (the fifth field) and print
|
||||
foreach $_ ( sort{ @{$allpkgs{$a}}[4] <=> @{$allpkgs{$b}}[4] } keys %allpkgs) {
|
||||
my @v = @{$allpkgs{$_}};
|
||||
my $line = "$v[0]/$v[1] $v[2]";
|
||||
$line = to_color($line);
|
||||
# print colorized "repo/pkgname pkgver" string with possible installed text
|
||||
print "$line\n";
|
||||
print "$v[3]\n";
|
||||
}
|
||||
my @sync = list_pkg('-Ss', @ARGV);
|
||||
my %allpkgs = map {$_->[1] . $_->[2] => 1} @sync;
|
||||
my @query = grep { not $allpkgs{$_->[1] . $_->[2]}} list_pkg('-Qs', @ARGV);
|
||||
$_->[4] = " [$LC_INSTALLED]" foreach @query;
|
||||
print_pkg (@{$_}) foreach (@sync, @query);
|
||||
|
||||
#vim: set noet:
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# pacsysclean - Sort installed packages by increasing installed size. Useful for system clean-up.
|
||||
|
||||
declare -r myname='pacsysclean'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
PACMAN_OPTS=
|
||||
|
||||
usage() {
|
||||
echo "$myname - Sort installed packages by increasing installed size."
|
||||
echo
|
||||
echo "Usage: $myname [options]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -o <options> Specify custom pacman query options (e.g., dt)"
|
||||
echo " -h, --help Show this help message and exit"
|
||||
}
|
||||
|
||||
version() {
|
||||
printf "%s %s\n" "$myname" "$myver"
|
||||
echo 'Copyright (C) 2011 Eric Bélanger <snowmaniscool@gmail.com>'
|
||||
}
|
||||
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
case "$1" in
|
||||
-o) PACMAN_OPTS="${2}" ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
-V|--version) version; exit 0 ;;
|
||||
*) usage; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
IFS=$'\n'
|
||||
name="^Name.*: (.*)$"
|
||||
size="^Installed Size.*: (.*) KiB$"
|
||||
|
||||
[[ $PACMAN_OPTS && $PACMAN_OPTS != -* ]] && PACMAN_OPTS="-$PACMAN_OPTS"
|
||||
|
||||
for line in $(LANG=C pacman -Qi $PACMAN_OPTS); do
|
||||
if [[ $line =~ $name ]]; then
|
||||
printf "%s\t" ${BASH_REMATCH[1]}
|
||||
elif [[ $line =~ $size ]]; then
|
||||
printf "%s\n" ${BASH_REMATCH[1]}
|
||||
fi
|
||||
done | sort -g -k2 | awk '
|
||||
BEGIN {
|
||||
split("KiB MiB GiB TiB PiB EiB ZiB YiB", suffix)
|
||||
}
|
||||
function format_size(size) {
|
||||
count = 1
|
||||
while (size + 0 > 1024) {
|
||||
size /= 1024
|
||||
count++
|
||||
}
|
||||
sizestr = sprintf("%.2f %s", size, suffix[count])
|
||||
return sizestr
|
||||
}
|
||||
{
|
||||
printf("%s\t%s\n", format_size($2), $1);
|
||||
}'
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
@@ -21,26 +21,31 @@
|
||||
# traps interrupt key to spit out pre-interrupt info
|
||||
trap finaloutput INT
|
||||
|
||||
declare -r myname='rankmirrors'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
usage() {
|
||||
echo "Usage: rankmirrors [options] MIRRORFILE | URL"
|
||||
echo "${myname} (pacman) v${myver}"
|
||||
echo
|
||||
echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror"
|
||||
echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is"
|
||||
echo "provided."
|
||||
echo
|
||||
echo "Usage: ${myname} [options] MIRRORFILE | URL"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " --version show program's version number and exit"
|
||||
echo " -h, --help show this help message and exit"
|
||||
echo " -n NUM number of servers to output, 0 for all"
|
||||
echo " -t, --times only output mirrors and their response times"
|
||||
echo " -u, --url test a specific url"
|
||||
echo " -u, --url test a specific URL"
|
||||
echo " -v, --verbose be verbose in ouptut"
|
||||
echo " -r, --repo specify a specific repo name instead of guessing"
|
||||
echo " -r, --repo specify a repository name instead of guessing"
|
||||
exit 0
|
||||
}
|
||||
|
||||
version() {
|
||||
echo "rankmirrors (pacman) @PACKAGE_VERSION@"
|
||||
echo "${myname} (pacman) ${myver}"
|
||||
echo "Copyright (c) 2009 Matthew Bruenig <matthewbruenig@gmail.com>."
|
||||
echo
|
||||
echo "This is free software; see the source for copying conditions."
|
||||
@@ -125,9 +130,16 @@ while [[ $1 ]]; do
|
||||
version) version ;;
|
||||
times) TIMESONLY=1 ; shift ;;
|
||||
verbose) VERBOSE=1 ; shift ;;
|
||||
url) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; shift 2;;
|
||||
repo) [[ $2 ]] || err "Must specify repo name."; TARGETREPO="$2"; shift 2;;
|
||||
*) err "\`$1' is an invalid argument."
|
||||
url)
|
||||
CHECKURL=1;
|
||||
[[ $2 ]] || err "Must specify URL.";
|
||||
URL="$2";
|
||||
shift 2;;
|
||||
repo)
|
||||
[[ $2 ]] || err "Must specify repository name.";
|
||||
TARGETREPO="$2";
|
||||
shift 2;;
|
||||
*) err "'$1' is an invalid argument."
|
||||
esac
|
||||
elif [[ ${1:0:1} = - ]]; then
|
||||
|
||||
@@ -143,10 +155,20 @@ while [[ $1 ]]; do
|
||||
h) usage ;;
|
||||
t) TIMESONLY=1 ;;
|
||||
v) VERBOSE=1 ;;
|
||||
u) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; snum=2;;
|
||||
r) [[ $2 ]] || err "Must specify repo name."; TARGETREPO="$2"; snum=2;;
|
||||
n) [[ $2 ]] || err "Must specify number." ; NUM="$2" ; snum=2;;
|
||||
*) err "\`-$1' is an invald argument." ;;
|
||||
u)
|
||||
CHECKURL=1;
|
||||
[[ $2 ]] || err "Must specify URL.";
|
||||
URL="$2";
|
||||
snum=2;;
|
||||
r)
|
||||
[[ $2 ]] || err "Must specify repository name.";
|
||||
TARGETREPO="$2";
|
||||
snum=2;;
|
||||
n)
|
||||
[[ $2 ]] || err "Must specify number.";
|
||||
NUM="$2";
|
||||
snum=2;;
|
||||
*) err "'$1' is an invalid argument." ;;
|
||||
esac
|
||||
done
|
||||
shift $snum
|
||||
@@ -157,34 +179,34 @@ while [[ $1 ]]; do
|
||||
[[ $linearray ]] || err "File is empty."
|
||||
shift
|
||||
else
|
||||
err "\`$1' does not exist."
|
||||
err "'$1' does not exist."
|
||||
fi
|
||||
done
|
||||
|
||||
# Some sanity checks
|
||||
[[ $NUM ]] || NUM=0
|
||||
[[ $FILE && $CHECKURL ]] && err "Cannot specify a url and mirrorfile."
|
||||
[[ $FILE || $CHECKURL || $STDIN ]] || err "Must specify url, mirrorfile, or stdin."
|
||||
[[ $FILE && $CHECKURL ]] && err "Cannot specify a URL and mirrorfile."
|
||||
[[ $FILE || $CHECKURL || $STDIN ]] || err "Must specify URL, mirrorfile, or stdin."
|
||||
|
||||
# Single url handling
|
||||
# Single URL handling
|
||||
if [[ $CHECKURL ]]; then
|
||||
url="$(getfetchurl "$URL")"
|
||||
[[ $url = fail ]] && err "url \`$URL' is malformed."
|
||||
[[ $url = fail ]] && err "URL '$URL' is malformed."
|
||||
[[ $VERBOSE ]] && echo "Testing $url..."
|
||||
time=$(gettime "$url")
|
||||
echo "$URL : $time"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get url results from mirrorfile, fill up the array, and so on
|
||||
# Get URL results from mirrorfile, fill up the array, and so on
|
||||
if [[ $TIMESONLY ]]; then
|
||||
echo "Querying servers, this may take some time..."
|
||||
echo "Querying servers. This may take some time..."
|
||||
elif [[ $FILE ]]; then
|
||||
echo "# Server list generated by rankmirrors on $(date +%Y-%m-%d)"
|
||||
fi
|
||||
|
||||
timesarray=()
|
||||
for line in "${linearray[@]}"; do
|
||||
for line in "${linearray[@]}"; do
|
||||
if [[ $line =~ ^[[:space:]]*# ]]; then
|
||||
[[ $TIMESONLY ]] || echo $line
|
||||
elif [[ $line =~ ^[[:space:]]*Server ]]; then
|
||||
@@ -193,7 +215,7 @@ for line in "${linearray[@]}"; do
|
||||
server="${line#*= }"
|
||||
server="${server%%#*}"
|
||||
url="$(getfetchurl "$server")"
|
||||
[[ $url = fail ]] && err "url \`$URL' is malformed."
|
||||
[[ $url = fail ]] && err "URL '$URL' is malformed."
|
||||
time=$(gettime "$url")
|
||||
timesarray+=("$time $server")
|
||||
|
||||
@@ -209,4 +231,4 @@ for line in "${linearray[@]}"; do
|
||||
done
|
||||
finaloutput
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# vim: set noet:
|
||||
|
||||
@@ -23,12 +23,16 @@ declare -r myname='updpkgsums'
|
||||
declare -r myver='@PACKAGE_VERSION@'
|
||||
|
||||
usage() {
|
||||
printf 'usage: %s [buildfile]\n\n' "$myname"
|
||||
printf ' -h, --help display this help message and exit\n'
|
||||
printf ' -V, --version display version information and exit\n\n'
|
||||
printf '%s will perform an in place update the checksums in the\n' "$myname"
|
||||
printf 'path specified by [buildfile], defaulting to PKGBUILD in the current\n'
|
||||
printf 'working directory.\n'
|
||||
printf "%s (pacman) v%s\n" "${myname}" "${myver}"
|
||||
echo
|
||||
printf "%s will perform an in place update of the checksums in the\n" "${myname}"
|
||||
echo "path specified by [build file], defaulting to PKGBUILD in the current"
|
||||
echo "working directory."
|
||||
echo
|
||||
printf "Usage: %s [build file]\n" "${myname}"
|
||||
echo
|
||||
echo " -h, --help display this help message and exit"
|
||||
echo " -V, --version display version information and exit"
|
||||
}
|
||||
|
||||
version() {
|
||||
@@ -36,6 +40,11 @@ version() {
|
||||
echo 'Copyright (C) 2012-2013 Dave Reisner <dreisner@archlinux.org>'
|
||||
}
|
||||
|
||||
die() {
|
||||
printf "==> ERROR: $1\n" "${@:2}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case $1 in
|
||||
-h|--help) usage; exit ;;
|
||||
-V|--version) version; exit ;;
|
||||
@@ -43,8 +52,7 @@ esac
|
||||
|
||||
buildfile=${1:-PKGBUILD}
|
||||
if [[ ! -f $buildfile ]]; then
|
||||
printf '==> ERROR: %s not found or is not a file\n' "$buildfile"
|
||||
exit 1
|
||||
die "%s not found or is not a file" "$buildfile"
|
||||
fi
|
||||
|
||||
# Resolve any symlinks to avoid replacing the symlink with a file. But, we
|
||||
@@ -67,17 +75,17 @@ fi
|
||||
|
||||
# Check $PWD/ for permission to unlink the $buildfile and write a new one
|
||||
if [[ ! -w . ]]; then
|
||||
printf $'==> ERROR: No write permission in `%s\'\n' "$PWD"
|
||||
exit 1
|
||||
die "No write permission in '%s'" "$PWD"
|
||||
fi
|
||||
|
||||
{
|
||||
# Generate the new sums and try to unlink the file before writing stdin back
|
||||
# into it. This final precaution shouldn't fail based on the previous checks,
|
||||
# but it's better to be extra careful before unlinking files.
|
||||
newsums=$(makepkg -g -p "$buildfile") && rm -f "$buildfile" &&
|
||||
exec awk -v newsums="$newsums" '
|
||||
/^[[:blank:]]*(md|sha)[[:digit:]]+sums=/,/\)[[:blank:]]*(#.*)?$/ {
|
||||
# Generate the new sums
|
||||
export BUILDDIR=$(mktemp -d "${TMPDIR:-/tmp}/updpkgsums.XXXXXX")
|
||||
newbuildfile=$(mktemp "${TMPDIR:-/tmp}/updpkgsums.XXXXXX")
|
||||
|
||||
trap "rm -rf '$BUILDDIR' '$newbuildfile'" EXIT
|
||||
newsums=$(makepkg -g -p "$buildfile") || die 'Failed to generate new checksums'
|
||||
awk -v newsums="$newsums" '
|
||||
/^[[:blank:]]*(md|sha)[[:digit:]]+sums(_[^=]+)?=/,/\)[[:blank:]]*(#.*)?$/ {
|
||||
if (!w) {
|
||||
print newsums
|
||||
w++
|
||||
@@ -87,7 +95,12 @@ fi
|
||||
|
||||
1
|
||||
END { if (!w) print newsums }
|
||||
' > "$buildfile"
|
||||
} < "$buildfile"
|
||||
' "$buildfile" > "$newbuildfile" || die 'Failed to write new PKGBUILD'
|
||||
|
||||
# vim: set ts=2 sw=2 noet:
|
||||
# Rewrite the original buildfile. Use cat instead of mv/cp to preserve
|
||||
# permissions implicitly.
|
||||
if ! cat -- "$newbuildfile" >"$buildfile"; then
|
||||
die "Failed to update %s. The file has not been modified." "$buildfile"
|
||||
fi
|
||||
|
||||
# vim: set noet:
|
||||
|
||||
2
doc/.gitignore
vendored
2
doc/.gitignore
vendored
@@ -1,6 +1,8 @@
|
||||
alpm-hooks.5
|
||||
PKGBUILD.5
|
||||
libalpm.3
|
||||
makepkg.8
|
||||
makepkg-template.1
|
||||
makepkg.conf.5
|
||||
pacman.8
|
||||
pacman-key.8
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
# man_MANS if --enable-asciidoc and/or --enable-doxygen are used.
|
||||
|
||||
ASCIIDOC_MANS = \
|
||||
alpm-hooks.5 \
|
||||
pacman.8 \
|
||||
makepkg.8 \
|
||||
makepkg-template.1 \
|
||||
repo-add.8 \
|
||||
vercmp.8 \
|
||||
pkgdelta.8 \
|
||||
@@ -19,8 +21,10 @@ ASCIIDOC_MANS = \
|
||||
DOXYGEN_MANS = $(wildcard man3/*.3)
|
||||
|
||||
HTML_MANPAGES = \
|
||||
alpm-hooks.5.html \
|
||||
pacman.8.html \
|
||||
makepkg.8.html \
|
||||
makepkg-template.1.html \
|
||||
repo-add.8.html \
|
||||
vercmp.8.html \
|
||||
pkgdelta.8.html \
|
||||
@@ -44,8 +48,10 @@ HTML_DOCS = \
|
||||
EXTRA_DIST = \
|
||||
asciidoc.conf \
|
||||
asciidoc-override.css \
|
||||
alpm-hooks.5.txt \
|
||||
pacman.8.txt \
|
||||
makepkg.8.txt \
|
||||
makepkg-template.1.txt \
|
||||
repo-add.8.txt \
|
||||
vercmp.8.txt \
|
||||
pkgdelta.8.txt \
|
||||
@@ -115,14 +121,14 @@ ASCIIDOC_OPTS = \
|
||||
-a pacman_date="`date +%Y-%m-%d`" \
|
||||
-a pkgdatadir=$(pkgdatadir) \
|
||||
-a localstatedir=$(localstatedir) \
|
||||
-a sysconfdir=$(sysconfdir)
|
||||
-a sysconfdir=$(sysconfdir) \
|
||||
-a datarootdir=$(datarootdir)
|
||||
|
||||
A2X_OPTS = \
|
||||
--no-xmllint \
|
||||
-d manpage \
|
||||
-f manpage \
|
||||
--xsltproc-opts='-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0' \
|
||||
--destination-dir='./'
|
||||
--xsltproc-opts='-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0'
|
||||
|
||||
# These rules are due to the includes and files of the asciidoc text
|
||||
$(ASCIIDOC_MANS): asciidoc.conf footer.txt Makefile.am
|
||||
@@ -145,8 +151,10 @@ $(HTML_OTHER): asciidoc.conf Makefile.am
|
||||
%.3.html: ASCIIDOC_OPTS += -d manpage
|
||||
|
||||
# Dependency rules
|
||||
alpm-hooks.5 alpm-hooks.5.html: alpm-hooks.5.txt
|
||||
pacman.8 pacman.8.html: pacman.8.txt
|
||||
makepkg.8 makepkg.8.html: makepkg.8.txt
|
||||
makepkg-template.1 makepkg-template.1.html: makepkg-template.1.txt
|
||||
repo-add.8 repo-add.8.html: repo-add.8.txt
|
||||
vercmp.8 vercmp.8.html: vercmp.8.txt
|
||||
pkgdelta.8 pkgdelta.8.html: pkgdelta.8.txt
|
||||
@@ -171,4 +179,4 @@ install-data-hook:
|
||||
uninstall-hook:
|
||||
$(RM) $(DESTDIR)$(mandir)/man8/repo-remove.8
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
# vim:set noet:
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
# Maintainer: Joe User <joe.user@example.com>
|
||||
|
||||
pkgname=patch
|
||||
pkgver=2.5.4
|
||||
pkgrel=3
|
||||
pkgver=2.7.1
|
||||
pkgrel=1
|
||||
pkgdesc="A utility to apply patch files to original sources"
|
||||
arch=('i686' 'x86_64')
|
||||
url="https://www.gnu.org/software/patch/patch.html"
|
||||
license=('GPL')
|
||||
groups=('base-devel')
|
||||
depends=('glibc' 'ed')
|
||||
source=(ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.gz)
|
||||
md5sums=('ee5ae84d115f051d87fcaaef3b4ae782')
|
||||
depends=('glibc')
|
||||
makedepends=('ed')
|
||||
optdepends=('ed: for "patch -e" functionality')
|
||||
source=("ftp://ftp.gnu.org/gnu/$pkgname/$pkgname-$pkgver.tar.xz"{,.sig})
|
||||
md5sums=('e9ae5393426d3ad783a300a338c09b72'
|
||||
'SKIP')
|
||||
|
||||
build() {
|
||||
cd "$srcdir"/$pkgname-$pkgver
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir"/$pkgname-$pkgver
|
||||
make prefix="$pkgdir"/usr install
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
make DESTDIR="$pkgdir/" install
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ Options and Directives
|
||||
----------------------
|
||||
The following is a list of standard options and directives available for use
|
||||
in a PKGBUILD. These are all understood and interpreted by makepkg, and most
|
||||
of them will be directly transferred to the built package.
|
||||
of them will be directly transferred to the built package. The mandatory
|
||||
fields for a minimally functional PKGBUILD are *pkgname*, *pkgver*, *pkgrel*
|
||||
and *arch*.
|
||||
|
||||
If you need to create any custom variables for use in your build process, it is
|
||||
recommended to prefix their name with an '_' (underscore).
|
||||
@@ -48,10 +50,12 @@ similar to `$_basekernver`.
|
||||
The version of the software as released from the author (e.g., '2.7.1').
|
||||
The variable is not allowed to contain colons or hyphens.
|
||||
+
|
||||
The `pkgver` variable can be automatically updated by providing a `pkgver()` function
|
||||
in the PKGBUILD that outputs the new package version. This is run after downloading
|
||||
and extracting the sources so can use those files in determining the new `pkgver`.
|
||||
This is most useful when used with sources from version control systems (see below).
|
||||
The `pkgver` variable can be automatically updated by providing a `pkgver()`
|
||||
function in the PKGBUILD that outputs the new package version.
|
||||
This is run after downloading and extracting the sources and running the
|
||||
`prepare()` function (if present), so it can use those files in determining the
|
||||
new `pkgver`. This is most useful when used with sources from version control
|
||||
systems (see below).
|
||||
|
||||
*pkgrel*::
|
||||
This is the release number specific to the Arch Linux release. This
|
||||
@@ -60,10 +64,6 @@ This is most useful when used with sources from version control systems (see bel
|
||||
software release and incremented for intermediate PKGBUILD updates. The
|
||||
variable is not allowed to contain hyphens.
|
||||
|
||||
*pkgdesc*::
|
||||
This should be a brief description of the package and its functionality.
|
||||
Try to keep the description to one line of text and not use the package's name.
|
||||
|
||||
*epoch*::
|
||||
Used to force the package to be seen as newer than any previous versions
|
||||
with a lower epoch, even if the version number would normally not trigger
|
||||
@@ -73,9 +73,14 @@ This is most useful when used with sources from version control systems (see bel
|
||||
version comparison logic. See linkman:pacman[8] for more information on
|
||||
version comparisons.
|
||||
|
||||
*pkgdesc*::
|
||||
This should be a brief description of the package and its functionality.
|
||||
Try to keep the description to one line of text and to not use the package's
|
||||
name.
|
||||
|
||||
*url*::
|
||||
This field contains a URL that is associated with the software being
|
||||
packaged. Typically the project's website.
|
||||
packaged. This is typically the project's web site.
|
||||
|
||||
*license (array)*::
|
||||
This field specifies the license(s) that apply to the package.
|
||||
@@ -91,13 +96,14 @@ This is most useful when used with sources from version control systems (see bel
|
||||
|
||||
*install*::
|
||||
Specifies a special install script that is to be included in the package.
|
||||
This file should reside in the same directory as the PKGBUILD, and will
|
||||
This file should reside in the same directory as the PKGBUILD and will
|
||||
be copied into the package by makepkg. It does not need to be included
|
||||
in the source array (e.g., `install=$pkgname.install`).
|
||||
|
||||
*changelog*::
|
||||
Specifies a changelog file that is to be included in the package.
|
||||
This file should reside in the same directory as the PKGBUILD, and will
|
||||
The changelog file should end in a single newline.
|
||||
This file should reside in the same directory as the PKGBUILD and will
|
||||
be copied into the package by makepkg. It does not need to be included
|
||||
in the source array (e.g., `changelog=$pkgname.changelog`).
|
||||
|
||||
@@ -105,10 +111,14 @@ This is most useful when used with sources from version control systems (see bel
|
||||
An array of source files required to build the package. Source files
|
||||
must either reside in the same directory as the PKGBUILD, or be a
|
||||
fully-qualified URL that makepkg can use to download the file.
|
||||
To make the PKGBUILD as useful as possible, use the `$pkgname` and `$pkgver`
|
||||
variables if possible when specifying the download location. Compressed files
|
||||
will be extracted automatically unless found in
|
||||
the noextract array described below.
|
||||
To simplify the maintenance of PKGBUILDs, use the `$pkgname` and `$pkgver`
|
||||
variables when specifying the download location, if possible.
|
||||
Compressed files will be extracted automatically unless found in the
|
||||
noextract array described below.
|
||||
+
|
||||
Additional architecture-specific sources can be added by appending an
|
||||
underscore and the architecture name e.g., 'source_x86_64=()'. There must be a
|
||||
corresponding integrity array with checksums, e.g. 'md5sums_x86_64=()'.
|
||||
+
|
||||
It is also possible to change the name of the downloaded file, which is helpful
|
||||
with weird URLs and for handling multiple source files with the same
|
||||
@@ -118,12 +128,21 @@ makepkg also supports building developmental versions of packages using sources
|
||||
downloaded from version control systems (VCS). For more information, see
|
||||
<<VCS,Using VCS Sources>> below.
|
||||
+
|
||||
Files in the source array with extensions `.sig`, `.sign` or `.asc` are recognized by
|
||||
makepkg as PGP signatures and will be automatically used to verify the integrity
|
||||
of the corresponding source file.
|
||||
Files in the source array with extensions `.sig`, `.sign` or, `.asc` are
|
||||
recognized by makepkg as PGP signatures and will be automatically used to verify
|
||||
the integrity of the corresponding source file.
|
||||
|
||||
*validpgpkeys (array)*::
|
||||
An array of PGP fingerprints. If this array is non-empty, makepkg will
|
||||
only accept signatures from the keys listed here and will ignore the
|
||||
trust values from the keyring. If the source file was signed with a
|
||||
subkey, makepkg will still use the primary key for comparison.
|
||||
+
|
||||
Only full fingerprints are accepted. They must be uppercase and must not
|
||||
contain whitespace characters.
|
||||
|
||||
*noextract (array)*::
|
||||
An array of filenames corresponding to those from the source array. Files
|
||||
An array of file names corresponding to those from the source array. Files
|
||||
listed here will not be extracted with the rest of the source files. This
|
||||
is useful for packages that use compressed data directly.
|
||||
|
||||
@@ -152,10 +171,10 @@ of the corresponding source file.
|
||||
files should use `arch=('any')`.
|
||||
|
||||
*backup (array)*::
|
||||
An array of filenames, without preceding slashes, that
|
||||
An array of file names, without preceding slashes, that
|
||||
should be backed up if the package is removed or upgraded. This is
|
||||
commonly used for packages placing configuration files in /etc. See
|
||||
Handling Config Files in linkman:pacman[8] for more information.
|
||||
commonly used for packages placing configuration files in '/etc'. See
|
||||
`"Handling Config Files"` in linkman:pacman[8] for more information.
|
||||
|
||||
*depends (array)*::
|
||||
An array of packages this package depends on to run. Entries in
|
||||
@@ -168,18 +187,27 @@ of the corresponding source file.
|
||||
If the dependency name appears to be a library (ends with .so), makepkg will
|
||||
try to find a binary that depends on the library in the built package and
|
||||
append the version needed by the binary. Appending the version yourself
|
||||
disables auto detection.
|
||||
disables automatic detection.
|
||||
+
|
||||
Additional architecture-specific depends can be added by appending an
|
||||
underscore and the architecture name e.g., 'depends_x86_64=()'.
|
||||
|
||||
*makedepends (array)*::
|
||||
An array of packages this package depends on to build but are not
|
||||
needed at runtime. Packages in this list follow the same format as
|
||||
depends.
|
||||
+
|
||||
Additional architecture-specific makedepends can be added by appending an
|
||||
underscore and the architecture name e.g., 'makedepends_x86_64=()'.
|
||||
|
||||
*checkdepends (array)*::
|
||||
An array of packages this package depends on to run its test suite
|
||||
but are not needed at runtime. Packages in this list follow the same
|
||||
format as depends. These dependencies are only considered when the
|
||||
check() function is present and is to be run by makepkg.
|
||||
+
|
||||
Additional architecture-specific checkdepends can be added by appending an
|
||||
underscore and the architecture name e.g., 'checkdepends_x86_64=()'.
|
||||
|
||||
*optdepends (array)*::
|
||||
An array of packages (and accompanying reasons) that are not essential for
|
||||
@@ -188,13 +216,19 @@ disables auto detection.
|
||||
and are not utilized by pacman during dependency resolution. The format
|
||||
for specifying optdepends is:
|
||||
|
||||
optdepends=('fakeroot: for makepkg usage as normal user')
|
||||
optdepends=('python: for library bindings')
|
||||
+
|
||||
Additional architecture-specific optdepends can be added by appending an
|
||||
underscore and the architecture name e.g., 'optdepends_x86_64=()'.
|
||||
|
||||
*conflicts (array)*::
|
||||
An array of packages that will conflict with this package (i.e. they
|
||||
cannot both be installed at the same time). This directive follows the
|
||||
same format as depends. Versioned conflicts are supported using the
|
||||
operators as described in `depends`.
|
||||
+
|
||||
Additional architecture-specific conflicts can be added by appending an
|
||||
underscore and the architecture name e.g., 'conflicts_x86_64=()'.
|
||||
|
||||
*provides (array)*::
|
||||
An array of ``virtual provisions'' this package provides. This allows
|
||||
@@ -209,7 +243,10 @@ only specific versions of a package may be provided.
|
||||
+
|
||||
If the provision name appears to be a library (ends with .so), makepkg will
|
||||
try to find the library in the built package and append the correct
|
||||
version. Appending the version yourself disables auto detection.
|
||||
version. Appending the version yourself disables automatic detection.
|
||||
+
|
||||
Additional architecture-specific provides can be added by appending an
|
||||
underscore and the architecture name e.g., 'provides_x86_64=()'.
|
||||
|
||||
*replaces (array)*::
|
||||
An array of packages this package should replace. This can be used
|
||||
@@ -220,6 +257,9 @@ version. Appending the version yourself disables auto detection.
|
||||
+
|
||||
Sysupgrade is currently the only pacman operation that utilizes this field.
|
||||
A normal sync or upgrade will not use its value.
|
||||
+
|
||||
Additional architecture-specific replaces can be added by appending an
|
||||
underscore and the architecture name e.g., 'replaces_x86_64=()'.
|
||||
|
||||
*options (array)*::
|
||||
This array allows you to override some of makepkg's default behavior
|
||||
@@ -245,7 +285,7 @@ A normal sync or upgrade will not use its value.
|
||||
|
||||
*staticlibs*;;
|
||||
Leave static library (.a) files in packages. Specify `!staticlibs` to
|
||||
remove them.
|
||||
remove them (if they have a shared counterpart).
|
||||
|
||||
*emptydirs*;;
|
||||
Leave empty directories in packages.
|
||||
@@ -256,6 +296,9 @@ A normal sync or upgrade will not use its value.
|
||||
*upx*;;
|
||||
Compress binary executable files using UPX.
|
||||
|
||||
*optipng*;;
|
||||
Optimize PNG images with optipng.
|
||||
|
||||
*ccache*;;
|
||||
Allow the use of ccache during build. More useful in its negative
|
||||
form `!ccache` with select packages that have problems building
|
||||
@@ -287,63 +330,64 @@ A normal sync or upgrade will not use its value.
|
||||
|
||||
Packaging Functions
|
||||
-------------------
|
||||
|
||||
In addition to the above directives, PKGBUILDs require a set of functions that
|
||||
provide instructions to build and install the package. As a minimum, the PKGBUILD
|
||||
must contain a package() function which installs all the package's files into the
|
||||
packaging directory, with optional prepare(), build() and check() being used to
|
||||
create those files from source.
|
||||
provide instructions to build and install the package. As a minimum, the
|
||||
PKGBUILD must contain a `package()` function which installs all the package's
|
||||
files into the packaging directory, with optional `prepare()`, `build()`, and
|
||||
`check()` functions being used to create those files from source.
|
||||
|
||||
*package() Function*::
|
||||
The package() function is used to install files into the directory that
|
||||
The `package()` function is used to install files into the directory that
|
||||
will become the root directory of the built package and is run after all
|
||||
the optional functions listed below. When specified in combination with
|
||||
the fakeroot BUILDENV option in linkman:makepkg.conf[5], fakeroot usage
|
||||
will be limited to running the packaging stage. All other functions will
|
||||
be run as the user calling makepkg.
|
||||
the optional functions listed below. The packaging stage is run using
|
||||
fakeroot to ensure correct file permissions in the resulting package.
|
||||
All other functions will be run as the user calling makepkg.
|
||||
|
||||
*prepare() Function*::
|
||||
An optional prepare() function can be specified in which operations that
|
||||
are to be run in order to prepare the sources for building (such as
|
||||
patching) are performed. This function is run after the source extraction
|
||||
and before the build() function and is skipped when source extraction is
|
||||
skipped.
|
||||
An optional `prepare()` function can be specified in which operations to
|
||||
prepare the sources for building, such as patching, are performed. This
|
||||
function is run after the source extraction and before the `build()`
|
||||
function. The `prepare()` function is skipped when source extraction
|
||||
is skipped.
|
||||
|
||||
*build() Function*::
|
||||
The optional build() function is use to compile and/or adjust the source
|
||||
files in preparation to be installed by the package() function. This is
|
||||
directly sourced and executed by makepkg, so anything that bash or the
|
||||
The optional `build()` function is use to compile and/or adjust the source
|
||||
files in preparation to be installed by the `package()` function. This is
|
||||
directly sourced and executed by makepkg, so anything that Bash or the
|
||||
system has available is available for use here. Be sure any exotic
|
||||
commands used are covered by `makedepends`.
|
||||
commands used are covered by the `makedepends` array.
|
||||
+
|
||||
If you create any variables of your own in the build function, it is
|
||||
recommended to use the bash `local` keyword to scope the variable to inside
|
||||
the build function.
|
||||
If you create any variables of your own in the `build()` function, it is
|
||||
recommended to use the Bash `local` keyword to scope the variable to inside
|
||||
the `build()` function.
|
||||
|
||||
*check() Function*::
|
||||
An optional check() function can be specified in which a package's
|
||||
test-suite may be run. This function is run between the build() and
|
||||
package() functions. Be sure any exotic commands used are covered by
|
||||
`checkdepends`.
|
||||
An optional `check()` function can be specified in which a package's
|
||||
test-suite may be run. This function is run between the `build()` and
|
||||
`package()` functions. Be sure any exotic commands used are covered by the
|
||||
`checkdepends` array.
|
||||
|
||||
All of the above variables such as `$pkgname` and `$pkgver` are available for use
|
||||
in the build function. In addition, makepkg defines the following variables for use
|
||||
during the build and install process:
|
||||
All of the above variables such as `$pkgname` and `$pkgver` are available for
|
||||
use in the packaging functions. In addition, makepkg defines the following
|
||||
variables:
|
||||
|
||||
*srcdir*::
|
||||
This contains the directory where makepkg extracts, or copies, all source
|
||||
files.
|
||||
This contains the directory where makepkg extracts, or copies, all source
|
||||
files.
|
||||
+
|
||||
All of the packaging functions defined above are run starting inside `$srcdir`
|
||||
|
||||
*pkgdir*::
|
||||
This contains the directory where makepkg bundles the installed package
|
||||
(this directory will become the root directory of your built package).
|
||||
This variable should only be used in the package() function.
|
||||
This contains the directory where makepkg bundles the installed package.
|
||||
This directory will become the root directory of your built package. This
|
||||
variable should only be used in the `package()` function.
|
||||
|
||||
*startdir*::
|
||||
This contains the absolute path to the directory where the PKGBUILD is
|
||||
located, which is usually the output of `$(pwd)` when makepkg is started.
|
||||
Use of this variable is deprecated and strongly discouraged.
|
||||
|
||||
|
||||
Package Splitting
|
||||
-----------------
|
||||
makepkg supports building multiple packages from a single PKGBUILD. This is
|
||||
@@ -354,17 +398,25 @@ Each split package uses a corresponding packaging function with name
|
||||
All options and directives for the split packages default to the global values
|
||||
given in the PKGBUILD. Nevertheless, the following ones can be overridden within
|
||||
each split package's packaging function:
|
||||
`pkgver`, `pkgrel`, `epoch`, `pkgdesc`, `arch`, `url`, `license`, `groups`,
|
||||
`depends`, `optdepends`, `provides`, `conflicts`, `replaces`, `backup`,
|
||||
`options`, `install` and `changelog`.
|
||||
`pkgdesc`, `arch`, `url`, `license`, `groups`, `depends`, `optdepends`,
|
||||
`provides`, `conflicts`, `replaces`, `backup`, `options`, `install`, and
|
||||
`changelog`.
|
||||
|
||||
Note that makepkg does not consider split package `depends` when checking
|
||||
if dependencies are installed before package building and with `--syncdeps`.
|
||||
All packages required to make the package are required to be specified in
|
||||
the global `depends` and `makedepends` arrays.
|
||||
|
||||
An optional global directive is available when building a split package:
|
||||
|
||||
*pkgbase*::
|
||||
The name used to refer to the group of packages in the output of makepkg
|
||||
and in the naming of source-only tarballs. If not specified, the first
|
||||
element in the `pkgname` array is used. The variable is not allowed to
|
||||
begin with a hyphen.
|
||||
and in the naming of source-only tarballs. If not specified, the first
|
||||
element in the `pkgname` array is used. Valid characters for this
|
||||
variable are alphanumerics, and any of the following characters:
|
||||
```@ . _ + -`''. Additionally, the variable is not allowed to start with
|
||||
hyphens or dots.
|
||||
|
||||
|
||||
Install/Upgrade/Remove Scripting
|
||||
--------------------------------
|
||||
@@ -374,10 +426,10 @@ itself after installation and perform an opposite action upon removal.
|
||||
|
||||
The exact time the script is run varies with each operation, and should be
|
||||
self-explanatory. Note that during an upgrade operation, none of the install
|
||||
or remove scripts will be called.
|
||||
or remove functions will be called.
|
||||
|
||||
Scripts are passed either one or two ``full version strings'', where a full
|
||||
version string is either 'pkgver-pkgrel' or 'epoch:pkgver-pkgrel' if epoch is
|
||||
version string is either 'pkgver-pkgrel' or 'epoch:pkgver-pkgrel', if epoch is
|
||||
non-zero.
|
||||
|
||||
*pre_install*::
|
||||
@@ -413,25 +465,29 @@ The install script does not need to be specified in the source array. A
|
||||
template install file is available in '{pkgdatadir}' as 'proto.install' for
|
||||
reference with all of the available functions defined.
|
||||
|
||||
|
||||
Using VCS Sources[[VCS]]
|
||||
------------------------
|
||||
Building a developmental version of a package using sources from a version control
|
||||
system (VCS) is enabled by specifying the source in the form
|
||||
`source=('folder::url#fragment')`. Currently makepkg supports the `bzr`, `git`, `hg` and
|
||||
`svn` protocols.
|
||||
Building a developmental version of a package using sources from a version
|
||||
control system (VCS) is enabled by specifying the source in the form
|
||||
`source=('directory::url#fragment')`. Currently makepkg supports the Bazaar, Git,
|
||||
Subversion, and Mercurial version control systems. For other version control
|
||||
systems, manual cloning of upstream repositories must be done in the `prepare()`
|
||||
function.
|
||||
|
||||
The source URL is divided into three components:
|
||||
|
||||
*folder*::
|
||||
(optional) Specifies an alternate folder name for makepkg to download the VCS
|
||||
source into.
|
||||
*directory*::
|
||||
(optional) Specifies an alternate directory name for makepkg to download
|
||||
the VCS source into.
|
||||
|
||||
*url*::
|
||||
The url to the VCS repo. This must include the the vcs in the URL protocol for
|
||||
makepkg to recognize this as a VCS source. If the protocol does not include
|
||||
the VCS name, it can be added by prefixing the URL with `vcs+`. For example,
|
||||
using a git repository over `http` would have a source URL in the form
|
||||
`git+http://...`.
|
||||
The URL to the VCS repository. This must include the VCS in the URL protocol
|
||||
for makepkg to recognize this as a VCS source. If the protocol does not
|
||||
include the VCS name, it can be added by prefixing the URL with `vcs+`. For
|
||||
example, using a Git repository over HTTPS would have a source URL in the
|
||||
form:
|
||||
`git+https://...`.
|
||||
|
||||
*fragment*::
|
||||
(optional) Allows specifying a revision number or branch for makepkg to checkout
|
||||
@@ -451,17 +507,19 @@ The source URL is divided into three components:
|
||||
*svn*;;
|
||||
revision
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
The following is an example PKGBUILD for the 'patch' package. For more
|
||||
examples, look through the build files of your distribution's packages. For
|
||||
those using Arch Linux, consult the ABS tree.
|
||||
those using Arch Linux, consult the Arch Build System (ABS) tree.
|
||||
|
||||
[source,sh]
|
||||
-------------------------------
|
||||
include::PKGBUILD-example.txt[]
|
||||
-------------------------------
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:makepkg[8], linkman:pacman[8], linkman:makepkg.conf[5]
|
||||
|
||||
131
doc/alpm-hooks.5.txt
Normal file
131
doc/alpm-hooks.5.txt
Normal file
@@ -0,0 +1,131 @@
|
||||
/////
|
||||
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
|
||||
/////
|
||||
alpm-hooks(5)
|
||||
=============
|
||||
|
||||
NAME
|
||||
----
|
||||
|
||||
alpm-hooks - alpm hook file format
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
--------
|
||||
[Trigger] (Required, Repeatable)
|
||||
Operation = Install|Upgrade|Remove (Required, Repeatable)
|
||||
Type = File|Package (Required)
|
||||
Target = <Path|PkgName> (Required, Repeatable)
|
||||
|
||||
[Action] (Required)
|
||||
Description = ... (Optional)
|
||||
When = PreTransaction|PostTransaction (Required)
|
||||
Exec = <Command> (Required)
|
||||
Depends = <PkgName> (Optional)
|
||||
AbortOnFail (Optional, PreTransaction only)
|
||||
NeedsTargets (Optional)
|
||||
--------
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
libalpm provides the ability to specify hooks to run before or after
|
||||
transactions based on the packages and/or files being modified. Hooks consist
|
||||
of a single '[Action]' section describing the action to be run and one or more
|
||||
'[Trigger]' section describing which transactions it should be run for. Hook
|
||||
file names are required to have the suffix ".hook". Hooks are run in
|
||||
alphabetical order of their file name.
|
||||
|
||||
TRIGGERS
|
||||
--------
|
||||
|
||||
Hooks must contain at least one '[Trigger]' section that determines which
|
||||
transactions will cause the hook to run. If multiple trigger sections are
|
||||
defined the hook will run if the transaction matches *any* of the triggers.
|
||||
|
||||
*Operation =* Install|Upgrade|Remove::
|
||||
Select the type of operation to match targets against. May be specified
|
||||
multiple times. Installations are considered an upgrade if the package or
|
||||
file is already present on the system regardless of whether the new package
|
||||
version is actually greater than the currently installed version. For File
|
||||
triggers, this is true even if the file changes ownership from one package
|
||||
to another. Required.
|
||||
|
||||
*Type =* File|Package::
|
||||
Select whether targets are matched against transaction packages or files.
|
||||
See CAVEATS for special notes regarding File triggers. Required.
|
||||
|
||||
*Target =* <path|package>::
|
||||
The file path or package name to match against the active transaction.
|
||||
File paths refer to the files in the package archive; the installation root
|
||||
should *not* be included in the path. Shell-style glob patterns are
|
||||
allowed. It is possible to invert matches by prepending a file with an
|
||||
exclamation mark. May be specified multiple times. Required.
|
||||
|
||||
ACTIONS
|
||||
-------
|
||||
|
||||
*Description =* ...::
|
||||
An optional description that describes the action being taken by the
|
||||
hook for use in front-end output.
|
||||
|
||||
*Exec =* <command>::
|
||||
Command to run. Command arguments are split on whitespace. Values
|
||||
containing whitespace should be enclosed in quotes. Required.
|
||||
|
||||
*When =* PreTransaction|PostTransaction::
|
||||
When to run the hook. Required.
|
||||
|
||||
*Depends =* <package>::
|
||||
Packages that must be installed for the hook to run. May be specified
|
||||
multiple times.
|
||||
|
||||
*AbortOnFail*::
|
||||
Causes the transaction to be aborted if the hook exits non-zero. Only
|
||||
applies to PreTransaction hooks.
|
||||
|
||||
*NeedsTargets*::
|
||||
Causes the list of matched trigger targets to be passed to the running hook
|
||||
on 'stdin'.
|
||||
|
||||
OVERRIDING HOOKS
|
||||
----------------
|
||||
|
||||
Hooks may be overridden by placing a file with the same name in a higher
|
||||
priority hook directory. Hooks may be disabled by overriding them with
|
||||
a symlink to '/dev/null'.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
--------
|
||||
# Force disks to sync to reduce the risk of data corruption
|
||||
|
||||
[Trigger]
|
||||
Operation = Install
|
||||
Operation = Upgrade
|
||||
Operation = Remove
|
||||
Type = Package
|
||||
Target = *
|
||||
|
||||
[Action]
|
||||
Depends = coreutils
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/sync
|
||||
--------
|
||||
|
||||
CAVEATS
|
||||
-------
|
||||
|
||||
There are situations when file triggers may act in unexpected ways. Hooks are
|
||||
triggered using the file list of the installed, upgraded, or removed package.
|
||||
When installing or upgrading a file that is extracted with a '.pacnew'
|
||||
extension, the original file name is used in triggering the hook. When
|
||||
removing a package, all files owned by that package can trigger a hook whether
|
||||
or not they were actually present on the file system before package removal.
|
||||
|
||||
PostTransaction hooks will *not* run if the transaction fails to complete for
|
||||
any reason.
|
||||
|
||||
include::footer.txt[]
|
||||
@@ -8,7 +8,7 @@ information on pacman and its related tools.
|
||||
|
||||
Bugs
|
||||
----
|
||||
Bugs? You must be kidding, there are no bugs in this software. But if we
|
||||
Bugs? You must be kidding; there are no bugs in this software. But if we
|
||||
happen to be wrong, send us an email with as much detail as possible to
|
||||
mailto:pacman-dev@archlinux.org[].
|
||||
|
||||
@@ -19,6 +19,7 @@ Authors
|
||||
Current maintainers:
|
||||
|
||||
* Allan McRae <allan@archlinux.org>
|
||||
* Andrew Gregory <andrew.gregory.8@gmail.com>
|
||||
* Dan McGee <dan@archlinux.org>
|
||||
* Dave Reisner <dreisner@archlinux.org>
|
||||
|
||||
|
||||
@@ -21,24 +21,28 @@ option) with a master server through the use of package databases. Prior to
|
||||
this, packages would have to be installed manually using the '\--add' and
|
||||
'\--upgrade' operations.
|
||||
|
||||
Version 3.0 was the switch to a two-part pacman- a backend named libalpm
|
||||
(library for Arch Linux Package Management), and the familiar pacman frontend.
|
||||
Version 3.0 was the switch to a two-part pacman -- a back-end named libalpm
|
||||
(library for Arch Linux Package Management) and the familiar pacman front-end.
|
||||
Speed in many cases was improved, along with dependency and conflict resolution
|
||||
being able to handle a much wider variety of cases. The switch to a
|
||||
library-based program should also make it easier in the future to develop
|
||||
alternative front ends.
|
||||
|
||||
Version 4.0 added package signing and verification capabilities to the entire
|
||||
makepkg/repo-add/pacman toolchain via GNUPG and GPGME.
|
||||
makepkg/repo-add/pacman toolchain via GnuPG and GPGME.
|
||||
|
||||
Version 5.0 added support for pre/post-transaction hooks and sync database file
|
||||
list operations.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Manpages
|
||||
~~~~~~~~
|
||||
There are several manpages available for the programs, utilities, and
|
||||
Man Pages
|
||||
~~~~~~~~~
|
||||
There are several man pages available for the programs, utilities, and
|
||||
configuration files dealing with pacman.
|
||||
|
||||
* linkman:alpm-hooks[5]
|
||||
* linkman:PKGBUILD[5]
|
||||
* linkman:libalpm[3]
|
||||
* linkman:makepkg[8]
|
||||
@@ -71,6 +75,11 @@ Releases
|
||||
[frame="topbot",grid="none",options="header,autowidth"]
|
||||
!======
|
||||
!Version !Date
|
||||
!5.0.2 !2016-06-03
|
||||
!5.0.1 !2016-02-23
|
||||
!5.0.0 !2016-01-30
|
||||
!4.2.1 !2015-02-20
|
||||
!4.2.0 !2014-12-19
|
||||
!4.1.2 !2013-06-18
|
||||
!4.1.1 !2013-05-07
|
||||
!4.1.0 !2013-04-01
|
||||
@@ -98,14 +107,14 @@ Releases
|
||||
!3.2.1 !2008-08-26
|
||||
!3.2.0 !2008-07-30
|
||||
!3.1.4 !2008-04-01
|
||||
!3.1.3 !2008-03-06
|
||||
!3.1.2 !2008-02-20
|
||||
!3.1.1 !2008-01-20
|
||||
!======
|
||||
|
|
||||
[frame="topbot",grid="none",options="header,autowidth"]
|
||||
!======
|
||||
!Version !Date
|
||||
!3.1.3 !2008-03-06
|
||||
!3.1.2 !2008-02-20
|
||||
!3.1.1 !2008-01-20
|
||||
!3.1.0 !2008-01-09
|
||||
!3.0.6 !2007-09-16
|
||||
!3.0.5 !2007-06-17
|
||||
@@ -133,12 +142,12 @@ Releases
|
||||
!2.8 !2004-07-03
|
||||
!2.7.9 !2004-04-30
|
||||
!2.7.8 !2004-04-29
|
||||
!2.7.7 !2004-04-15
|
||||
!======
|
||||
|
|
||||
[frame="topbot",grid="none",options="header,autowidth"]
|
||||
!======
|
||||
!Version !Date
|
||||
!2.7.7 !2004-04-15
|
||||
!2.7.6 !2004-04-04
|
||||
!2.7.5 !2004-03-02
|
||||
!2.7.4 !2004-02-18
|
||||
@@ -172,7 +181,7 @@ Releases
|
||||
|======
|
||||
|
||||
Source code for all releases is available at
|
||||
link:ftp://ftp.archlinux.org/other/pacman/[]. To install, download the newest
|
||||
link:https://sources.archlinux.org/other/pacman/[]. To install, download the newest
|
||||
available source tarball, unpack it in a directory, and run the three magic
|
||||
commands:
|
||||
|
||||
@@ -194,7 +203,7 @@ link:https://mailman.archlinux.org/pipermail/pacman-dev/[view the archives].
|
||||
|
||||
Source Code
|
||||
~~~~~~~~~~~
|
||||
Development of pacman is currently done in GIT. The central repository is
|
||||
Development of pacman is currently done in Git. The central repository is
|
||||
hosted by Arch Linux, although some of the developers have their own trees (ask
|
||||
on the above mailing lists if you are interested in finding the locations of
|
||||
these trees).
|
||||
@@ -238,7 +247,7 @@ Bugs
|
||||
----
|
||||
If you find bugs (which is quite likely), please email them to the pacman-dev
|
||||
mailing last at mailto:pacman-dev@archlinux.org[] with specific information
|
||||
such as your commandline, the nature of the bug, and even the package database
|
||||
such as your command-line, the nature of the bug, and even the package database
|
||||
if it helps.
|
||||
|
||||
You can also post a bug to the Arch Linux bug tracker
|
||||
@@ -247,7 +256,7 @@ bugs under the Pacman project.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
pacman is Copyright (C) 2006-2013 Pacman Development Team
|
||||
pacman is Copyright (C) 2006-2016 Pacman Development Team
|
||||
<pacman-dev@archlinux.org> and Copyright (C) 2002-2006 Judd Vinet
|
||||
<jvinet@zeroflux.org> and is licensed through the GNU General Public License,
|
||||
version 2 or later.
|
||||
|
||||
@@ -34,6 +34,7 @@ See linkman:pacman.conf[5] for more details on configuring libalpm using the
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:pacman[8], linkman:makepkg[8], linkman:pacman.conf[5]
|
||||
linkman:alpm-hooks[5], linkman:makepkg[8], linkman:pacman[8],
|
||||
linkman:pacman.conf[5]
|
||||
|
||||
include::footer.txt[]
|
||||
|
||||
121
doc/makepkg-template.1.txt
Normal file
121
doc/makepkg-template.1.txt
Normal file
@@ -0,0 +1,121 @@
|
||||
/////
|
||||
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
|
||||
/////
|
||||
makepkg-template(1)
|
||||
===================
|
||||
|
||||
Name
|
||||
----
|
||||
makepkg-template - package build templating utility
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
'makepkg-template' [options]
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
'makepkg-template' is a script to ease the work of maintaining multiple similar
|
||||
PKGBUILDs. It allows you to move most of the code from the PKGBUILD into a
|
||||
template file and uses markers to allow in-place updating of existing PKGBUILDs
|
||||
if the template has been changed.
|
||||
|
||||
Template files can contain any code allowed in a PKGBUILD. You can think of
|
||||
them like external files included with "." or "source", but they will be
|
||||
inlined into the PKGBUILD by 'makepkg-template' so you do not depend on the
|
||||
template file when building the package.
|
||||
|
||||
Markers are bash comments in the form of:
|
||||
|
||||
# template start; key=value; key2=value2; ...
|
||||
|
||||
and
|
||||
|
||||
# template end;
|
||||
|
||||
Currently used keys are: name (mandatory) and version. Template names are limited to
|
||||
alphanumerics, "@", "+", ".", "-", and "_". Versions are limited to numbers and ".".
|
||||
|
||||
For initial creation there is a one line short cut which does not need an end marker:
|
||||
|
||||
# template input; key=value;
|
||||
|
||||
Using this short-cut will result in 'makepkg-template' replacing it with start
|
||||
and end markers and the template code on the first run.
|
||||
|
||||
Template files should be stored in one directory and filenames should be
|
||||
"$template_name-$version.template" with a symlink "$template_name.template"
|
||||
pointing to the most recent template. If the version is not set in the marker,
|
||||
'makepkg-template' will automatically use the target of "$template_name.template",
|
||||
otherwise the specified version will be used. This allows for easier
|
||||
verification of untrusted PKGBUILDs if the template is trusted. You verify the
|
||||
non-template code and then use a command similar to this:
|
||||
|
||||
diff -u <(makepkg-template -o -) PKGBUILD
|
||||
|
||||
Template files may also contain markers leading to nested templates in the
|
||||
resulting PKGBUILD. If you use markers in a template, please set the version
|
||||
you used/tested with in the start/input marker so other people can properly
|
||||
recreate from templates.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*-p, \--input* <build script>::
|
||||
Read the package script `build script` instead of the default.
|
||||
|
||||
*-o, \--output* <build script>::
|
||||
Write the updated file to `build script` instead of overwriting the input file.
|
||||
|
||||
*-n, \--newest*::
|
||||
Always use the newest available template file.
|
||||
|
||||
*\--template-dir* <dir>::
|
||||
Change the dir where we are looking for template files. This option may be
|
||||
given multiple times in which case files found in directory given last will
|
||||
take precedence.
|
||||
|
||||
|
||||
Example PKGBUILD
|
||||
----------------
|
||||
|
||||
pkgname=perl-config-simple
|
||||
pkgver=4.58
|
||||
pkgrel=1
|
||||
pkgdesc="simple configuration file class"
|
||||
arch=('any')
|
||||
license=('PerlArtistic' 'GPL')
|
||||
depends=('perl')
|
||||
source=("http://search.cpan.org/CPAN/authors/id/S/SH/SHERZODR/Config-Simple-${pkgver}.tar.gz")
|
||||
md5sums=('f014aec54f0a1e2e880d317180fce502')
|
||||
_distname="Config-Simple"
|
||||
|
||||
# template start; name=perl-module; version=1.0;
|
||||
_distdir="${_distname}-${pkgver}"
|
||||
url="https://metacpan.org/release/${_distname}"
|
||||
options+=('!emptydirs')
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$_distdir"
|
||||
perl Makefile.PL INSTALLDIRS=vendor
|
||||
make
|
||||
}
|
||||
|
||||
check() {
|
||||
cd "$srcdir/$_distdir"
|
||||
make test
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$_distdir"
|
||||
make DESTDIR="$pkgdir" install
|
||||
}
|
||||
# template end;
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:makepkg[8], linkman:PKGBUILD[5]
|
||||
|
||||
include::footer.txt[]
|
||||
@@ -11,7 +11,7 @@ makepkg - package build utility
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
'makepkg' [options]
|
||||
'makepkg' [options] [ENVVAR=value] [ENVVAR+=value] ...
|
||||
|
||||
|
||||
Description
|
||||
@@ -33,13 +33,9 @@ building packages. If you wish to share your build output with others when
|
||||
seeking help or for other purposes, you may wish to run "`LC_ALL=C makepkg`" so
|
||||
your logs and output are not localized.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*\--asroot*::
|
||||
Allow makepkg to run as root. This is for security purposes as it is
|
||||
normally dangerous to do so. This will also disable use of fakeroot and
|
||||
sudo.
|
||||
|
||||
*-A, \--ignorearch*::
|
||||
Ignore a missing or incomplete arch field in the build script. This is
|
||||
for rebuilding packages from source when the PKGBUILD may be slightly
|
||||
@@ -49,7 +45,7 @@ Options
|
||||
Clean up leftover work files and directories after a successful build.
|
||||
|
||||
*\--config* <file>::
|
||||
Use an alternate config file instead of the +{sysconfdir}/makepkg.conf+
|
||||
Use an alternate configuration file instead of the +{sysconfdir}/makepkg.conf+
|
||||
default.
|
||||
|
||||
*-d, \--nodeps*::
|
||||
@@ -68,7 +64,9 @@ Options
|
||||
*\--verifysource*::
|
||||
For each source file in the source array of PKGBUILD, download the file
|
||||
if required and perform the integrity checks. No extraction or build is
|
||||
performed. Useful for performing subsequent offline builds.
|
||||
performed. Dependencies specified in the PKGBUILD will not be handled
|
||||
unless `--syncdeps` is used. Useful for performing subsequent offline
|
||||
builds.
|
||||
|
||||
*-f, \--force*::
|
||||
makepkg will not build a package if a built package already exists in
|
||||
@@ -105,11 +103,11 @@ Options
|
||||
linkman:pacman[8].
|
||||
|
||||
*-L, \--log*::
|
||||
Enable makepkg build logging. This will use the *tee* program to send
|
||||
output of the `build()` function to both the console and to a text file in
|
||||
the build directory named `pkgname-pkgver-pkgrel-arch.log`. As mentioned
|
||||
above, the build log will be localized so you may want to set your locale
|
||||
accordingly if sharing the log output with others.
|
||||
Enable logging. This will use the *tee* program to send the output of each
|
||||
of the PKGBUILD functions to both the console and to a text file in the
|
||||
build directory named `pkgbase-pkgver-pkgrel-arch-<function>.log`.
|
||||
As mentioned above, the logs will be localized so you may want to set your
|
||||
locale accordingly if sharing the log output with others.
|
||||
|
||||
*-m, \--nocolor*::
|
||||
Disable color in output messages.
|
||||
@@ -121,7 +119,8 @@ Options
|
||||
|
||||
*-p* <buildscript>::
|
||||
Read the package script `buildscript` instead of the `PKGBUILD` default;
|
||||
see linkman:PKGBUILD[5].
|
||||
see linkman:PKGBUILD[5]. The `buildscript` must be located in the directory
|
||||
makepkg is called from.
|
||||
|
||||
*-r, \--rmdeps*::
|
||||
Upon successful build, remove any dependencies installed by makepkg
|
||||
@@ -129,8 +128,8 @@ Options
|
||||
|
||||
*-R, \--repackage*::
|
||||
Repackage contents of the package without rebuilding the package. This
|
||||
is useful if you forgot a depend or install file in your PKGBUILD and
|
||||
the build itself will not change.
|
||||
is useful if you forgot, for example, a dependency or install file in your
|
||||
PKGBUILD and the build itself will not change.
|
||||
|
||||
*-s, \--syncdeps*::
|
||||
Install missing dependencies using pacman. When build-time or run-time
|
||||
@@ -147,24 +146,31 @@ Options
|
||||
*-V, \--version*::
|
||||
Display version information.
|
||||
|
||||
*-C, \--cleanbuild*::
|
||||
Remove the $srcdir before building the package.
|
||||
|
||||
*\--allsource*::
|
||||
Do not actually build the package, but build a source-only tarball that
|
||||
includes all sources, including those that are normally download via
|
||||
includes all sources, including those that are normally downloaded via
|
||||
makepkg. This is useful for passing a single tarball to another program
|
||||
such as a chroot or remote builder. It will also satisfy requirements of
|
||||
the GPL when distributing binary packages.
|
||||
|
||||
*\--pkg* <list>::
|
||||
Only build listed packages from a split package. Multiple packages should
|
||||
be comma separated in the list. This option can be specified multiple times.
|
||||
|
||||
*\--check*::
|
||||
Run the check() function in the PKGBUILD, overriding the setting in
|
||||
linkman:makepkg.conf[5].
|
||||
|
||||
*\--noarchive*::
|
||||
Do not create the archive at the end of the build process. This can be
|
||||
useful to test the package() function or if your target distribution does
|
||||
not use pacman.
|
||||
|
||||
*\--nocheck*::
|
||||
Do not run the check() function in the PKGBUILD or handle the checkdepends.
|
||||
|
||||
*\--noprepare*::
|
||||
Do not run the prepare() function in the PKGBUILD.
|
||||
|
||||
*\--sign*::
|
||||
Sign the resulting package with gpg, overriding the setting in
|
||||
linkman:makepkg.conf[5].
|
||||
@@ -183,16 +189,22 @@ Options
|
||||
|
||||
*\--needed*::
|
||||
(Passed to pacman) Tell pacman not to reinstall a target if it is already
|
||||
up to date. (used with -i / --install).
|
||||
up-to-date. (used with '-i' / '\--install').
|
||||
|
||||
*\--asdeps*::
|
||||
(Passed to pacman) Install packages as non-explicitly installed (used
|
||||
with -i / --install).
|
||||
with '-i' / '\--install').
|
||||
|
||||
*\--noprogressbar*::
|
||||
(Passed to pacman) Prevent pacman from displaying a progress bar;
|
||||
useful if you are redirecting makepkg output to file.
|
||||
|
||||
*\--packagelist*::
|
||||
List the packages that would be produced without building. Listed
|
||||
package names do not include PKGEXT.
|
||||
|
||||
*\--printsrcinfo*::
|
||||
Generate and print the SRCINFO file to stdout.
|
||||
|
||||
Additional Features
|
||||
-------------------
|
||||
@@ -204,28 +216,56 @@ set up a development PKGBUILD.
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
*PACMAN*::
|
||||
**PACMAN**::
|
||||
The command that will be used to check for missing dependencies and to
|
||||
install and remove packages. Pacman's -Qq, -Rns, -S, -T, and -U
|
||||
install and remove packages. Pacman's '-Qq', '-Rns', '-S', '-T', and '-U'
|
||||
operations must be supported by this command. If the variable is not
|
||||
set or empty, makepkg will fall back to `pacman'.
|
||||
|
||||
**PKGDEST=**"/path/to/folder"::
|
||||
Folder where the resulting packages will be stored. Overrides the
|
||||
**MAKEPKG_CONF=**"/path/to/file"::
|
||||
Use an alternate config file instead of the +{sysconfdir}/makepkg.conf+
|
||||
default.
|
||||
|
||||
**PKGDEST=**"/path/to/directory"::
|
||||
Directory where the resulting packages will be stored. Overrides the
|
||||
corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**SRCDEST=**"/path/to/folder"::
|
||||
Folder where the downloaded sources will be stored. Overrides the
|
||||
**SRCDEST=**"/path/to/directory"::
|
||||
Directory where the downloaded sources will be stored. Overrides the
|
||||
corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**SRCPKGDEST=**"/path/to/directory"::
|
||||
Directory where source package files will be stored. Overrides the
|
||||
corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**LOGDEST=**"/path/to/directory"::
|
||||
Directory where generated log files will be stored. Overrides the
|
||||
corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**PACKAGER=**"John Doe <john@doe.com>"::
|
||||
String to identify the creator of the resulting package. Overrides
|
||||
the corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**BUILDDIR=**"/path/to/folder"::
|
||||
Folder where the package will be built. Overrides the corresponding
|
||||
**BUILDDIR=**"/path/to/directory"::
|
||||
Directory where the package will be built. Overrides the corresponding
|
||||
value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**CARCH=**"(i686|x86_64)"::
|
||||
Force build for a specific architecture. Useful for cross-compiling.
|
||||
Overrides the corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**PKGEXT=**".pkg.tar.gz", **SRCEXT=**".src.tar.gz"::
|
||||
Sets the compression used when making compiled or source packages.
|
||||
Overrides the corresponding value defined in linkman:makepkg.conf[5].
|
||||
|
||||
**GNUPGHOME=**"/path/to/directory"::
|
||||
Directory where the gpg keyring for signing the built package is stored.
|
||||
|
||||
**GPGKEY=**"keyid"::
|
||||
Specify a key to use when signing packages, overriding the GPGKEY setting
|
||||
in linkman:makepkg.conf[5]
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
See linkman:makepkg.conf[5] for more details on configuring makepkg using the
|
||||
|
||||
@@ -11,14 +11,14 @@ makepkg.conf - makepkg configuration file
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
{sysconfdir}/makepkg.conf, ~/.makepkg.conf
|
||||
{sysconfdir}/makepkg.conf, $XDG_CONFIG_HOME/pacman/makepkg.conf, ~/.makepkg.conf
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
Configuration options for makekpg are stored in makepkg.conf. This file is
|
||||
sourced, so you can include any special compiler flags you wish to use. This is
|
||||
helpful for building for different architectures, or with different
|
||||
Configuration options for makepkg are stored in makepkg.conf. This file is
|
||||
sourced so you can include any special compiler flags you wish to use. This is
|
||||
helpful when building for different architectures or with different
|
||||
optimizations. However, only the variables described below are exported to the
|
||||
build environment.
|
||||
|
||||
@@ -26,8 +26,9 @@ NOTE: This does not guarantee that all package Makefiles will use your exported
|
||||
variables. Some of them are non-standard.
|
||||
|
||||
The system-wide configuration file is found in {sysconfdir}/makepkg.conf.
|
||||
Individual options can be overridden (or added to) on a per user basis in
|
||||
~/.makepkg.conf.
|
||||
Individual options can be overridden (or added to) on a per-user basis in
|
||||
$XDG_CONFIG_HOME/pacman/makepkg.conf or ~/.makepkg.conf, with the former
|
||||
taking priority.
|
||||
|
||||
The default file is fairly well commented, so it may be easiest to simply
|
||||
follow directions given there for customization.
|
||||
@@ -38,25 +39,31 @@ Options
|
||||
**DLAGENTS=(**\'protocol::/path/to/command [options]' ...**)**::
|
||||
Sets the download agents used to fetch source files specified with a URL in
|
||||
the linkman:PKGBUILD[5] file. Options can be specified for each command as
|
||||
well, and any protocol can have a download agent. Several examples are provided
|
||||
in the default makepkg.conf.
|
||||
well, and any protocol can have a download agent. Any spaces in option
|
||||
arguments are required to be escaped to avoid being split. Several
|
||||
examples are provided in the default makepkg.conf.
|
||||
+
|
||||
If present, `%u` will be replaced with the download URL. Otherwise, the
|
||||
download URL will be placed on the end of the command. If present, `%o` will
|
||||
be replaced with the local filename, plus a ``.part'' extension, which allows
|
||||
be replaced with the local file name, plus a ``.part'' extension, which allows
|
||||
makepkg to handle resuming file downloads.
|
||||
|
||||
**VCSCLIENTS=(**\'protocol::package' ...**)**::
|
||||
Sets the packages required to fetch version controlled source files. When
|
||||
required, makepkg will check that these packages are installed or are included
|
||||
in the `depends` or `makedepends` arrays in the PKGBUILD.
|
||||
|
||||
**CARCH=**"carch"::
|
||||
Specifies your computer architecture; possible values include such things
|
||||
as ``i686'', ``x86_64'', ``ppc'', etc. This should be automatically set on
|
||||
installation.
|
||||
|
||||
**CHOST=**"chost"::
|
||||
A string such as ``i686-pc-linux-gnu'', do not touch unless you know what
|
||||
A string such as ``i686-pc-linux-gnu''; do not touch this unless you know what
|
||||
you are doing. This can be commented out by most users if desired.
|
||||
|
||||
**CPPFLAGS=**"cppflags"::
|
||||
Flags used for the C preprocessor; see CFLAGS for more info.
|
||||
Flags used for the C preprocessor; see CFLAGS for more information.
|
||||
|
||||
**CFLAGS=**"cflags"::
|
||||
Flags used for the C compiler. This is a key part to the use of makepkg.
|
||||
@@ -74,27 +81,24 @@ Options
|
||||
available linker flags.
|
||||
|
||||
**MAKEFLAGS=**"makeflags"::
|
||||
This is often used to set the number of jobs used, for example, `-j2`.
|
||||
This is often used to set the number of jobs used; for example, `-j2`.
|
||||
Other flags that make accepts can also be passed.
|
||||
|
||||
**DEBUG_CFLAGS=**"debug_cflags"::
|
||||
Additional compiler flags appended to CFLAGS for use in debugging. Usually
|
||||
Additional compiler flags appended to `CFLAGS` for use in debugging. Usually
|
||||
this would include: ``-g''. Read gcc(1) for more details on the wide
|
||||
variety of compiler flags available.
|
||||
|
||||
**DEBUG_CXXFLAGS=**"debug_cxxflags"::
|
||||
Debug flags used for the C++ compiler; see DEBUG_CFLAGS for more info.
|
||||
|
||||
**BUILDENV=(**fakeroot !distcc color !ccache check !sign**)**::
|
||||
This array contains options that affect the build environment, the defaults
|
||||
**BUILDENV=(**!distcc color !ccache check !sign**)**::
|
||||
This array contains options that affect the build environment; the defaults
|
||||
are shown here. All options should always be left in the array; to enable
|
||||
or disable an option simply remove or place an ``!'' at the front of the
|
||||
or disable an option, simply remove or add an ``!'' at the front of the
|
||||
option. If an option is specified multiple times, the final value takes
|
||||
precedence. Each option works as follows:
|
||||
|
||||
*fakeroot*;;
|
||||
Allow building packages as a non-root user. This is highly recommended.
|
||||
|
||||
*distcc*;;
|
||||
Use the distributed C/C++/ObjC compiler to spread compilation among
|
||||
multiple machines. If this is enabled, `DISTCC_HOSTS` must be specified
|
||||
@@ -112,13 +116,13 @@ Options
|
||||
*check*;;
|
||||
Run the check() function if present in the PKGBUILD. This can be
|
||||
enabled or disabled for individual packages through the use of
|
||||
makepkg's '\--check' and '\--nocheck' options respectively.
|
||||
makepkg's '\--check' and '\--nocheck' options, respectively.
|
||||
|
||||
*sign*;;
|
||||
Generate a PGP signature file using GnuPG. This will execute `gpg
|
||||
--detach-sign --use-agent` on the built package to generate a detached
|
||||
signature file, using the GPG agent if it is available. The signature
|
||||
file will be the entire filename of the package with a ``.sig''
|
||||
Generate a PGP signature file using GnuPG. This will execute 'gpg
|
||||
\--detach-sign \--use-agent' on the built package to generate a detached
|
||||
signature file, using the GPG agent, if it is available. The signature
|
||||
file will be the entire file name of the package with a ``.sig''
|
||||
extension.
|
||||
|
||||
**DISTCC_HOSTS=**"host1 ..."::
|
||||
@@ -126,23 +130,22 @@ Options
|
||||
running in the DistCC cluster. In addition, you will want to modify your
|
||||
`MAKEFLAGS`.
|
||||
|
||||
**BUILDDIR=**"/path/to/folder"::
|
||||
If this value is not set, packages will by default be built in
|
||||
subdirectories of the directory that makepkg is called from. This
|
||||
option allows setting the build location to another folder.
|
||||
**BUILDDIR=**"/path/to/directory"::
|
||||
If this value is not set, packages will, by default, be built in
|
||||
subdirectories of the directory that makepkg is called from. This
|
||||
option allows setting the build location to another directory.
|
||||
Incorrect use of `$startdir` in a PKGBUILD may cause building with
|
||||
this option to fail.
|
||||
|
||||
|
||||
**GPGKEY=**""::
|
||||
Specify a key to use for gpg signing instead of the default key in the
|
||||
Specify a key to use for GPG signing instead of the default key in the
|
||||
keyring. Can be overridden with makepkg's '\--key' option.
|
||||
|
||||
**OPTIONS=(**strip docs libtool staticlibs emptydirs zipman purge !upx**)**::
|
||||
This array contains options that affect the default packaging. They are
|
||||
**OPTIONS=(**strip docs libtool staticlibs emptydirs zipman purge !upx !optipng**)**::
|
||||
This array contains options that affect default packaging. They are
|
||||
equivalent to options that can be placed in the PKGBUILD; the defaults are
|
||||
shown here. All options should always be left in the array; to enable or
|
||||
disable an option simply remove or place an ``!'' at the front of the
|
||||
disable an option, simply remove or add an ``!'' at the front of the
|
||||
option. If an option is specified multiple times, the final value takes
|
||||
precedence. Each option works as follows:
|
||||
|
||||
@@ -162,7 +165,7 @@ Options
|
||||
|
||||
*staticlibs*;;
|
||||
Leave static library (.a) files in packages. Specify `!staticlibs` to
|
||||
remove them.
|
||||
remove them, if they have a shared counterpart.
|
||||
|
||||
*emptydirs*;;
|
||||
Leave empty directories in packages.
|
||||
@@ -176,8 +179,12 @@ Options
|
||||
package.
|
||||
|
||||
*upx*;;
|
||||
Compress binary executable files using UPX. Additional options
|
||||
can be passed to UPX by specifying the `UPXFLAGS` variable.
|
||||
Compress binary executable files using UPX. Additional options
|
||||
can be passed to UPX by specifying the `UPXFLAGS` array variable.
|
||||
|
||||
*optipng*;;
|
||||
Optimize PNG images with optipng. Additional options can be passed
|
||||
to optipng by specifying the `OPTIPNGFLAGS` array variable.
|
||||
|
||||
*debug*;;
|
||||
Add the user-specified debug flags as specified in DEBUG_CFLAGS and
|
||||
@@ -198,51 +205,51 @@ Options
|
||||
for details.
|
||||
|
||||
**STRIP_STATIC=**"--strip-debug"::
|
||||
Options to be used when stripping static libraries. See linkman:strip[1]
|
||||
Options to be used when stripping static libraries. See linkman:strip[1]
|
||||
for details.
|
||||
|
||||
**MAN_DIRS=(**{usr{,/local}{,/share},opt/*}/{man,info} ...**)**::
|
||||
If `zipman` is specified in the OPTIONS array, this variable will
|
||||
If `zipman` is specified in the `OPTIONS` array, this variable will
|
||||
instruct makepkg where to look to compress manual (man and info)
|
||||
pages. If you build packages that are located in opt/, you may need
|
||||
to add the directory to this array. *NOTE:* Do not add the leading
|
||||
slash to the directory name.
|
||||
|
||||
**DOC_DIRS=(**usr/{,share/}{doc,gtk-doc} ...**)**::
|
||||
If `!docs` is specified in the OPTIONS array, this variable will
|
||||
If `!docs` is specified in the `OPTIONS` array, this variable will
|
||||
instruct makepkg where to look to remove docs. If you build packages
|
||||
that are located in opt/, you may need to add the directory to this
|
||||
array. *NOTE:* Do not add the leading slash to the directory name.
|
||||
|
||||
**PURGE_TARGETS=(**usr/{,share}/info/dir .podlist *.pod...**)**::
|
||||
If `purge` is specified in the OPTIONS array, this variable will
|
||||
If `purge` is specified in the `OPTIONS` array, this variable will
|
||||
instruct makepkg which files to remove from the package. This is
|
||||
useful for index files that are added by multiple packages.
|
||||
|
||||
**PKGDEST=**"/path/to/folder"::
|
||||
If this value is not set, packages will by default be placed in the
|
||||
**PKGDEST=**"/path/to/directory"::
|
||||
If this value is not set, packages will, by default, be placed in the
|
||||
current directory (location of the linkman:PKGBUILD[5]). Many people
|
||||
like to keep all their packages in one place so this option allows
|
||||
this behavior. A common location is ``/home/packages''.
|
||||
for this behavior. A common location is ``/home/packages''.
|
||||
|
||||
**SRCDEST=**"/path/to/folder"::
|
||||
**SRCDEST=**"/path/to/directory"::
|
||||
If this value is not set, downloaded source files will only be stored
|
||||
in the current directory. Many people like to keep all source files in
|
||||
a central location for easy cleanup, so this path can be set here.
|
||||
|
||||
**SRCPKGDEST=**"/path/to/folder"::
|
||||
**SRCPKGDEST=**"/path/to/directory"::
|
||||
If this value is not set, source package files will be stored in
|
||||
in the current directory. Many people like to keep all source package files
|
||||
in a central location for easy cleanup, so this path can be set here.
|
||||
|
||||
**LOGDEST=**"/path/to/folder"::
|
||||
**LOGDEST=**"/path/to/directory"::
|
||||
If this value is not set, log files are written to the current
|
||||
directory. This centralizes the log location, facilitating cleanup
|
||||
and compression.
|
||||
|
||||
**PACKAGER=**"John Doe <john@example.com>"::
|
||||
This value is used when querying a package to see who was the builder.
|
||||
It is recommended you change this to your name and email address.
|
||||
It is recommended to change this to your name and email address.
|
||||
|
||||
**COMPRESSGZ=**"(gzip -c -f -n)"::
|
||||
**COMPRESSBZ2=**"(bzip2 -c -f)"::
|
||||
@@ -254,11 +261,12 @@ Options
|
||||
packages in the named format.
|
||||
|
||||
**PKGEXT=**".pkg.tar.gz", **SRCEXT=**".src.tar.gz"::
|
||||
Sets the compression used when making compiled or source packages. The
|
||||
current valid suffixes are `.tar`, `.tar.gz`, `.tar.bz2`, `.tar.xz`,
|
||||
`.tar.lzo`, `.tar.lrz` and `.tar.Z`.
|
||||
Sets the compression used when making compiled or source packages.
|
||||
Valid suffixes are `.tar`, `.tar.gz`, `.tar.bz2`, `.tar.xz`,
|
||||
`.tar.lzo`, `.tar.lrz`, and `.tar.Z`.
|
||||
Do not touch these unless you know what you are doing.
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:makepkg[8], linkman:pacman[8], linkman:PKGBUILD[5]
|
||||
|
||||
@@ -30,6 +30,7 @@ Invoking pacman-key consists of supplying an operation with any potential
|
||||
options and targets to operate on. Depending on the operation, a 'target' may
|
||||
be a valid key identifier, filename, or directory.
|
||||
|
||||
|
||||
Operations
|
||||
----------
|
||||
*-a, \--add*::
|
||||
@@ -101,10 +102,11 @@ Operations
|
||||
*-v, \--verify*::
|
||||
Verify the file(s) specified by the signature(s).
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*\--config* <file>::
|
||||
Use an alternate config file instead of the +{sysconfdir}/pacman.conf+
|
||||
Use an alternate configuration file instead of the +{sysconfdir}/pacman.conf+
|
||||
default.
|
||||
|
||||
*\--gpgdir* <dir>::
|
||||
|
||||
248
doc/pacman.8.txt
248
doc/pacman.8.txt
@@ -13,38 +13,39 @@ Synopsis
|
||||
--------
|
||||
'pacman' <operation> [options] [targets]
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
Pacman is a package management utility that tracks installed packages on a Linux
|
||||
system. It features dependency support, package groups, install and uninstall
|
||||
hooks, and the ability to sync your local machine with a remote ftp server to
|
||||
scripts, and the ability to sync your local machine with a remote repository to
|
||||
automatically upgrade packages. Pacman packages are a zipped tar format.
|
||||
|
||||
Since version 3.0.0, pacman has been the frontend to linkman:libalpm[3], the
|
||||
Since version 3.0.0, pacman has been the front-end to linkman:libalpm[3], the
|
||||
``Arch Linux Package Management'' library. This library allows alternative
|
||||
front ends to be written (for instance, a GUI front end).
|
||||
front-ends to be written (for instance, a GUI front-end).
|
||||
|
||||
Invoking pacman involves specifying an operation with any potential options and
|
||||
targets to operate on. A 'target' is usually a package name, filename, URL, or
|
||||
targets to operate on. A 'target' is usually a package name, file name, URL, or
|
||||
a search string. Targets can be provided as command line arguments.
|
||||
Additionally, if stdin is not from a terminal and a single dash (-) is passed
|
||||
Additionally, if stdin is not from a terminal and a single hyphen (-) is passed
|
||||
as an argument, targets will be read from stdin.
|
||||
|
||||
|
||||
Operations
|
||||
----------
|
||||
*-D, \--database*::
|
||||
Modify the package database. This operation allows you to modify certain
|
||||
attributes of the installed packages in pacman's database. At the
|
||||
moment, you can only change the install reason using '\--asdeps' and
|
||||
'\--asexplicit' options.
|
||||
Operate on the package database. This operation allows you to modify
|
||||
certain attributes of the installed packages in pacman's database. It
|
||||
also allows you to check the databases for internal consistency.
|
||||
See <<DO,Database Options>> below.
|
||||
|
||||
*-Q, \--query*::
|
||||
Query the package database. This operation allows you to view installed
|
||||
packages and their files, as well as meta-information about individual
|
||||
packages (dependencies, conflicts, install date, build date, size). This
|
||||
can be run against the local package database or can be used on
|
||||
individual '.tar.gz' packages. In the first case, if no package names
|
||||
individual package files. In the first case, if no package names
|
||||
are provided in the command line, all installed packages will be
|
||||
queried. Additionally, various filters can be applied on the package
|
||||
list. See <<QO,Query Options>> below.
|
||||
@@ -58,19 +59,19 @@ Operations
|
||||
See <<RO,Remove Options>> below.
|
||||
|
||||
*-S, \--sync*::
|
||||
Synchronize packages. Packages are installed directly from the ftp
|
||||
servers, including all dependencies required to run the packages. For
|
||||
Synchronize packages. Packages are installed directly from the remote
|
||||
repositories, including all dependencies required to run the packages. For
|
||||
example, `pacman -S qt` will download and install qt and all the
|
||||
packages it depends on. If a package name exists in more than one repo, the
|
||||
repo can be explicitly specified to clarify the package to install:
|
||||
`pacman -S testing/qt`. You can also specify version requirements:
|
||||
`pacman -S "bash>=3.2"`. (Quotes are needed, otherwise your shell
|
||||
interprets ">" as redirection to file.)
|
||||
packages it depends on. If a package name exists in more than one
|
||||
repository, the repository can be explicitly specified to clarify the
|
||||
package to install: `pacman -S testing/qt`. You can also specify version
|
||||
requirements: `pacman -S "bash>=3.2"`. Quotes are needed, otherwise the
|
||||
shell interprets ">" as redirection to a file.
|
||||
+
|
||||
In addition to packages, groups can be specified as well. For example, if
|
||||
gnome is a defined package group, then `pacman -S gnome` will provide a
|
||||
prompt allowing you to select which packages to install from a numbered list.
|
||||
The package selection is specified using a space and/or comma separated list of
|
||||
The package selection is specified using a space- and/or comma-separated list of
|
||||
package numbers. Sequential packages may be selected by specifying the first
|
||||
and last package numbers separated by a hyphen (`-`). Excluding packages is
|
||||
achieved by prefixing a number or range of numbers with a caret (`^`).
|
||||
@@ -81,7 +82,7 @@ provide the same functionality as foo will be searched for. If any package is
|
||||
found, it will be installed. A selection prompt is provided if multiple packages
|
||||
providing foo are found.
|
||||
+
|
||||
You can also use `pacman -Su` to upgrade all packages that are out of date. See
|
||||
You can also use `pacman -Su` to upgrade all packages that are out-of-date. See
|
||||
<<SO,Sync Options>> below. When upgrading, pacman performs version comparison
|
||||
to determine which packages need upgrading. This behavior operates as follows:
|
||||
|
||||
@@ -91,7 +92,7 @@ to determine which packages need upgrading. This behavior operates as follows:
|
||||
1 < 1.0 < 1.1 < 1.1.1 < 1.2 < 2.0 < 3.0.0
|
||||
+
|
||||
Additionally, version strings can have an 'epoch' value defined that will
|
||||
overrule any version comparison (unless the epoch values are equal). This is
|
||||
overrule any version comparison, unless the epoch values are equal. This is
|
||||
specified in an `epoch:version-rel` format. For example, `2:1.0-1` is always
|
||||
greater than `1:3.6-1`.
|
||||
|
||||
@@ -104,16 +105,22 @@ greater than `1:3.6-1`.
|
||||
|
||||
*-U, \--upgrade*::
|
||||
Upgrade or add package(s) to the system and install the required
|
||||
dependencies from sync repos. Either a URL or file path can be
|
||||
dependencies from sync repositories. Either a URL or file path can be
|
||||
specified. This is a ``remove-then-add'' process. See <<UO,Upgrade
|
||||
Options>> below; also see <<HCF,Handling Config Files>> for an explanation
|
||||
on how pacman takes care of config files.
|
||||
on how pacman takes care of configuration files.
|
||||
|
||||
*-F, \--files*::
|
||||
Query the files database. This operation allows you to look for packages
|
||||
owning certain files or display files owned by certain packages. Only
|
||||
packages that are part of your sync databases are searched. See
|
||||
<<FO,File Options>> below.
|
||||
|
||||
*-V, \--version*::
|
||||
Display version and exit.
|
||||
|
||||
*-h, \--help*::
|
||||
Display syntax for the given operation. If no operation was supplied
|
||||
Display syntax for the given operation. If no operation was supplied,
|
||||
then the general syntax is shown.
|
||||
|
||||
|
||||
@@ -121,16 +128,17 @@ Options
|
||||
-------
|
||||
*-b, \--dbpath* <path>::
|
||||
Specify an alternative database location (a typical default is
|
||||
+{localstatedir}/lib/pacman+). This should not be used unless you know what you are
|
||||
doing. *NOTE*: if specified, this is an absolute path and the root path is
|
||||
+{localstatedir}/lib/pacman+). This should not be used unless you know what
|
||||
you are doing.
|
||||
*NOTE*: If specified, this is an absolute path, and the root path is
|
||||
not automatically prepended.
|
||||
|
||||
*-r, \--root* <path>::
|
||||
Specify an alternative installation root (default is `/`). This should
|
||||
not be used as a way to install software into `/usr/local` instead of
|
||||
`/usr`. This option is used if you want to install a package on a
|
||||
temporary mounted partition that is "owned" by another system.
|
||||
*NOTE*: if database path or logfile are not specified on either the
|
||||
temporarily mounted partition that is "owned" by another system.
|
||||
*NOTE*: If database path or log file are not specified on either the
|
||||
command line or in linkman:pacman.conf[5], their default location will
|
||||
be inside this root path.
|
||||
|
||||
@@ -142,14 +150,15 @@ Options
|
||||
|
||||
*\--cachedir* <dir>::
|
||||
Specify an alternative package cache location (a typical default is
|
||||
+{localstatedir}/cache/pacman/pkg+). Multiple cache directories can be specified,
|
||||
and they are tried in the order they are passed to pacman. *NOTE*: this
|
||||
is an absolute path, the root path is not automatically prepended.
|
||||
+{localstatedir}/cache/pacman/pkg+). Multiple cache directories can be
|
||||
specified, and they are tried in the order they are passed to pacman.
|
||||
*NOTE*: This is an absolute path, and the root path is not automatically
|
||||
prepended.
|
||||
|
||||
*\--color* <when>::
|
||||
Specify when to enable coloring, can be 'always', 'never' or 'auto'. Always
|
||||
forces colours on, never forces colours off, and auto only automatically enables
|
||||
colours when outputting onto a tty.
|
||||
Specify when to enable coloring. Valid options are 'always', 'never', or
|
||||
'auto'. 'always' forces colors on; 'never' forces colors off; and 'auto' only
|
||||
automatically enables colors when outputting onto a tty.
|
||||
|
||||
*\--config* <file>::
|
||||
Specify an alternate configuration file.
|
||||
@@ -163,8 +172,15 @@ Options
|
||||
typical default is +{sysconfdir}/pacman.d/gnupg+). This directory should contain
|
||||
two files: `pubring.gpg` and `trustdb.gpg`. `pubring.gpg` holds the public keys
|
||||
of all packagers. `trustdb.gpg` contains a so-called trust database, which
|
||||
specifies that the keys are authentic and trusted. *NOTE*: this is an absolute
|
||||
path, the root path is not automatically prepended.
|
||||
specifies that the keys are authentic and trusted. *NOTE*: This is an absolute
|
||||
path, and the root path is not automatically prepended.
|
||||
|
||||
*\--hookdir* <dir>::
|
||||
Specify a alternative directory containing hook files (a typical default is
|
||||
+{sysconfdir}/pacman.d/hooks+). Multiple hook directories can be specified
|
||||
with hooks in later directories taking precedence over hooks in earlier
|
||||
directories. *NOTE*: This is an absolute path, and the root path is not
|
||||
automatically prepended.
|
||||
|
||||
*\--logfile* <file>::
|
||||
Specify an alternate log file. This is an absolute path, regardless of
|
||||
@@ -174,6 +190,10 @@ Options
|
||||
Bypass any and all ``Are you sure?'' messages. It's not a good idea to do
|
||||
this unless you want to run pacman from a script.
|
||||
|
||||
*\--confirm*::
|
||||
Cancels the effects of a previous '\--noconfirm'.
|
||||
|
||||
|
||||
Transaction Options (apply to '-S', '-R' and '-U')
|
||||
--------------------------------------------------
|
||||
*-d, \--nodeps*::
|
||||
@@ -182,8 +202,14 @@ Transaction Options (apply to '-S', '-R' and '-U')
|
||||
dependencies are installed and there are no package conflicts in the
|
||||
system. Specify this option twice to skip all dependency checks.
|
||||
|
||||
*\--assume-installed* <package=version>::
|
||||
Add a virtual package "package" with version "version" to the transaction
|
||||
to satisfy dependencies. This allows to disable specific dependency checks
|
||||
without affecting all dependency checks. To disable all dependency
|
||||
checking, see the '\--nodeps' option.
|
||||
|
||||
*\--dbonly*::
|
||||
Adds/Removes the database entry only, leaves all files in place.
|
||||
Adds/removes the database entry only, leaving all files in place.
|
||||
|
||||
*\--noprogressbar*::
|
||||
Do not show a progress bar when downloading files. This can be useful
|
||||
@@ -197,12 +223,13 @@ Transaction Options (apply to '-S', '-R' and '-U')
|
||||
Only print the targets instead of performing the actual operation (sync,
|
||||
remove or upgrade). Use '\--print-format' to specify how targets are
|
||||
displayed. The default format string is "%l", which displays URLs with
|
||||
'-S', filenames with '-U' and pkgname-pkgver with '-R'.
|
||||
'-S', file names with '-U', and pkgname-pkgver with '-R'.
|
||||
|
||||
*\--print-format* <format>::
|
||||
Specify a printf-like format to control the output of the '\--print'
|
||||
operation. The possible attributes are: %n for pkgname, %v for pkgver,
|
||||
%l for location, %r for repo and %s for size.
|
||||
operation. The possible attributes are: "%n" for pkgname, "%v" for pkgver,
|
||||
"%l" for location, "%r" for repository, and "%s" for size. Implies '\--print'.
|
||||
|
||||
|
||||
Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
--------------------------------------------
|
||||
@@ -210,14 +237,14 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
Bypass file conflict checks and overwrite conflicting files. If the
|
||||
package that is about to be installed contains files that are already
|
||||
installed, this option will cause all those files to be overwritten.
|
||||
Using '--force' will not allow overwriting a directory with a file or
|
||||
Using '\--force' will not allow overwriting a directory with a file or
|
||||
installing packages with conflicting files and directories.
|
||||
This option should be used with care, ideally not at all.
|
||||
|
||||
*\--asdeps*::
|
||||
Install packages non-explicitly; in other words, fake their install reason
|
||||
to be installed as a dependency. This is useful for makepkg and other
|
||||
build from source tools that need to install dependencies before building
|
||||
build-from-source tools that need to install dependencies before building
|
||||
the package.
|
||||
|
||||
*\--asexplicit*::
|
||||
@@ -232,12 +259,12 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||
with a comma.
|
||||
|
||||
*\--ignoregroup* <group>::
|
||||
Directs pacman to ignore upgrades of all packages in 'group' even if
|
||||
Directs pacman to ignore upgrades of all packages in 'group', even if
|
||||
there is one available. Multiple groups can be specified by
|
||||
separating them with a comma.
|
||||
|
||||
*\--needed*::
|
||||
Do not reinstall the targets that are already up to date.
|
||||
Do not reinstall the targets that are already up-to-date.
|
||||
|
||||
|
||||
Query Options[[QO]]
|
||||
@@ -269,8 +296,8 @@ Query Options[[QO]]
|
||||
*-k \--check*::
|
||||
Check that all files owned by the given package(s) are present on the
|
||||
system. If packages are not specified or filter flags are not provided,
|
||||
check all installed packages. Specifying this option twice will perform
|
||||
more detailed file checking (including permissions, file sizes and
|
||||
check all installed packages. Specifying this option twice will perform
|
||||
more detailed file checking (including permissions, file sizes, and
|
||||
modification times) for packages that contain the needed mtree file.
|
||||
|
||||
*-l, \--list*::
|
||||
@@ -279,16 +306,16 @@ Query Options[[QO]]
|
||||
|
||||
*-m, \--foreign*::
|
||||
Restrict or filter output to packages that were not found in the sync
|
||||
database(s). Typically these are packages that were downloaded manually
|
||||
database(s). Typically these are packages that were downloaded manually
|
||||
and installed with '\--upgrade'.
|
||||
|
||||
*-n, \--native*::
|
||||
Restrict or filter output to packages that are found in the sync
|
||||
database(s). This is the inverse filter of '\--foreign'.
|
||||
database(s). This is the inverse filter of '\--foreign'.
|
||||
|
||||
*-o, \--owns* <file>::
|
||||
Search for packages that own the specified file(s). The path can be
|
||||
relative or absolute and one or more files can be specified.
|
||||
relative or absolute, and one or more files can be specified.
|
||||
|
||||
*-p, \--file*::
|
||||
Signifies that the package supplied on the command line is a file and
|
||||
@@ -296,8 +323,8 @@ Query Options[[QO]]
|
||||
This is useful in combination with '\--info' and '\--list'.
|
||||
|
||||
*-q, \--quiet*::
|
||||
Show less information for certain query operations. (This is useful when
|
||||
pacman's output is processed in a script.) Search will only show package
|
||||
Show less information for certain query operations. This is useful when
|
||||
pacman's output is processed in a script. Search will only show package
|
||||
names and not version, group, and description information; owns will
|
||||
only show package names instead of "file is owned by pkg" messages; group
|
||||
will only show package names and omit group names; list will only show
|
||||
@@ -311,13 +338,15 @@ Query Options[[QO]]
|
||||
with descriptions matching ALL of those terms are returned.
|
||||
|
||||
*-t, \--unrequired*::
|
||||
Restrict or filter output to packages not required by any currently
|
||||
installed package.
|
||||
Restrict or filter output to packages not required or optionally required by
|
||||
any currently installed package. Specify this option twice to only filter
|
||||
packages that are direct dependencies (i.e. do not filter optional
|
||||
dependencies).
|
||||
|
||||
*-u, \--upgrades*::
|
||||
Restrict or filter output to packages that are out of date on the local
|
||||
system. (Only package versions are used to find outdated packages,
|
||||
replacements are not checked here.) This option works best if the sync
|
||||
Restrict or filter output to packages that are out-of-date on the local
|
||||
system. Only package versions are used to find outdated packages;
|
||||
replacements are not checked here. This option works best if the sync
|
||||
database is refreshed using '-Sy'.
|
||||
|
||||
|
||||
@@ -325,19 +354,19 @@ Remove Options[[RO]]
|
||||
--------------------
|
||||
*-c, \--cascade*::
|
||||
Remove all target packages, as well as all packages that depend on one
|
||||
or more target packages. This operation is recursive, and must be used
|
||||
with care since it can remove many potentially needed packages.
|
||||
or more target packages. This operation is recursive and must be used
|
||||
with care, since it can remove many potentially needed packages.
|
||||
|
||||
*-n, \--nosave*::
|
||||
Instructs pacman to ignore file backup designations. Normally, when a
|
||||
file is removed from the system the database is checked to see if the
|
||||
file is removed from the system, the database is checked to see if the
|
||||
file should be renamed with a '.pacsave' extension.
|
||||
|
||||
*-s, \--recursive*::
|
||||
Remove each target specified including all of their dependencies, provided
|
||||
that (A) they are not required by other packages; and (B) they were not
|
||||
explicitly installed by the user. This operation is recursive and analogous
|
||||
to a backwards '\--sync' operation, and helps keep a clean system without
|
||||
to a backwards '\--sync' operation, and it helps keep a clean system without
|
||||
orphans. If you want to omit condition (B), pass this option twice.
|
||||
|
||||
*-u, \--unneeded*::
|
||||
@@ -352,7 +381,7 @@ Sync Options[[SO]]
|
||||
Remove packages that are no longer installed from the cache as well as
|
||||
currently unused sync databases to free up disk space. When pacman
|
||||
downloads packages, it saves them in a cache directory. In addition,
|
||||
databases are saved for every sync DB you download from, and are not
|
||||
databases are saved for every sync DB you download from and are not
|
||||
deleted even if they are removed from the configuration file
|
||||
linkman:pacman.conf[5]. Use one '\--clean' switch to only remove
|
||||
packages that are no longer installed; use two to remove all files
|
||||
@@ -377,9 +406,9 @@ linkman:pacman.conf[5].
|
||||
can be specified on the command line.
|
||||
|
||||
*-q, \--quiet*::
|
||||
Show less information for certain sync operations. (This is useful when
|
||||
pacman's output is processed in a script.) Search will only show package
|
||||
names and not repo, version, group, and description information; list
|
||||
Show less information for certain sync operations. This is useful when
|
||||
pacman's output is processed in a script. Search will only show package
|
||||
names and not repository, version, group, and description information; list
|
||||
will only show package names and omit databases and versions; group will
|
||||
only show package names and omit group names.
|
||||
|
||||
@@ -390,38 +419,87 @@ linkman:pacman.conf[5].
|
||||
be returned.
|
||||
|
||||
*-u, \--sysupgrade*::
|
||||
Upgrades all packages that are out of date. Each currently-installed
|
||||
Upgrades all packages that are out-of-date. Each currently-installed
|
||||
package will be examined and upgraded if a newer package exists. A
|
||||
report of all packages to upgrade will be presented and the operation
|
||||
report of all packages to upgrade will be presented, and the operation
|
||||
will not proceed without user confirmation. Dependencies are
|
||||
automatically resolved at this level and will be installed/upgraded if
|
||||
necessary.
|
||||
+
|
||||
Pass this option twice to enable package downgrade; in this case pacman will
|
||||
select sync packages whose version does not match with the local version. This
|
||||
can be useful when the user switches from a testing repo to a stable one.
|
||||
Pass this option twice to enable package downgrades; in this case, pacman will
|
||||
select sync packages whose versions do not match with the local versions. This
|
||||
can be useful when the user switches from a testing repository to a stable one.
|
||||
+
|
||||
Additional targets can also be specified manually, so that '-Su foo' will do a
|
||||
system upgrade and install/upgrade the foo package in the same operation.
|
||||
system upgrade and install/upgrade the "foo" package in the same operation.
|
||||
|
||||
*-w, \--downloadonly*::
|
||||
Retrieve all packages from the server, but do not install/upgrade anything.
|
||||
|
||||
*-y, \--refresh*::
|
||||
Download a fresh copy of the master package list from the server(s)
|
||||
Download a fresh copy of the master package database from the server(s)
|
||||
defined in linkman:pacman.conf[5]. This should typically be used each time
|
||||
you use '\--sysupgrade' or '-u'. Passing two '\--refresh' or '-y' flags
|
||||
will force a refresh of all package lists even if they appear to be up
|
||||
to date.
|
||||
will force a refresh of all package databases, even if they appear to be
|
||||
up-to-date.
|
||||
|
||||
|
||||
Database Options[[QO]]
|
||||
----------------------
|
||||
*\--asdeps* <package>::
|
||||
Mark a package as non-explicitly installed; in other words, set their install
|
||||
reason to be installed as a dependency.
|
||||
|
||||
*\--asexplicit* <package>::
|
||||
Mark a package as explicitly installed; in other words, set their install
|
||||
reason to be explicitly installed. This is useful it you want to keep a
|
||||
package installed even when it was initially installed as a dependency
|
||||
of another package.
|
||||
|
||||
*-k \--check*::
|
||||
Check the local package database is internally consistent. This will
|
||||
check all required files are present and that installed packages have
|
||||
the required dependencies, do not conflict and that multiple packages
|
||||
do not own the same file. Specifying this option twice will perform
|
||||
a check on the sync databases to ensure all specified dependencies
|
||||
are available.
|
||||
|
||||
File Options[[FO]]
|
||||
------------------
|
||||
|
||||
*-y, --refresh*::
|
||||
Download fresh package databases from the server. Use twice to force a
|
||||
refresh even if databases are up to date.
|
||||
|
||||
*-l, \--list*::
|
||||
List the files owned by the queried package.
|
||||
|
||||
*-s, \--search*::
|
||||
Search package file names for matching strings.
|
||||
|
||||
*-x, --regex*::
|
||||
Treat arguments to '--search' as regular expressions.
|
||||
|
||||
*-o, \--owns*::
|
||||
Search for packages that own a particular file.
|
||||
|
||||
*-q, \--quiet*::
|
||||
Show less information for certain file operations. This is useful when
|
||||
pacman's output is processed in a script, however, you may want to use
|
||||
'--machinereadable' instead.
|
||||
|
||||
*--machinereadable*::
|
||||
Use a machine readable output format for '--list', '--search' and
|
||||
'--owns'. The format is 'repository\0pkgname\0pkgver\0path\n' with '\0'
|
||||
being the NULL character and '\n' a linefeed.
|
||||
|
||||
Handling Config Files[[HCF]]
|
||||
----------------------------
|
||||
Pacman uses the same logic as rpm to determine action against files that are
|
||||
designated to be backed up. During an upgrade, 3 md5 hashes are used for each
|
||||
backup file to determine the required action: one for the original file
|
||||
installed, one for the new file that's about to be installed, and one for the
|
||||
actual file existing on the filesystem. After comparing these 3 hashes, the
|
||||
Pacman uses the same logic as 'rpm' to determine action against files that are
|
||||
designated to be backed up. During an upgrade, three MD5 hashes are used for
|
||||
each backup file to determine the required action: one for the original file
|
||||
installed, one for the new file that is about to be installed, and one for the
|
||||
actual file existing on the file system. After comparing these three hashes, the
|
||||
follow scenarios can result:
|
||||
|
||||
original=X, current=X, new=X::
|
||||
@@ -429,13 +507,13 @@ original=X, current=X, new=X::
|
||||
new file.
|
||||
|
||||
original=X, current=X, new=Y::
|
||||
The current file is the same as the original but the new one differs.
|
||||
The current file is the same as the original, but the new one differs.
|
||||
Since the user did not ever modify the file, and the new one may contain
|
||||
improvements or bugfixes, install the new file.
|
||||
improvements or bug fixes, install the new file.
|
||||
|
||||
original=X, current=Y, new=X::
|
||||
Both package versions contain the exact same file, but the one on the
|
||||
filesystem has been modified. Leave the current file in place.
|
||||
file system has been modified. Leave the current file in place.
|
||||
|
||||
original=X, current=Y, new=Y::
|
||||
The new file is identical to the current file. Install the new file.
|
||||
@@ -445,6 +523,12 @@ original=X, current=Y, new=Z::
|
||||
extension and warn the user. The user must then manually merge any
|
||||
necessary changes into the original file.
|
||||
|
||||
original=NULL, current=Y, new=Z::
|
||||
The package was not previously installed, and the file already exists on the
|
||||
file system. Install the new file with a '.pacnew' extension and warn the
|
||||
user. The user must then manually merge any necessary changes into the
|
||||
original file.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
@@ -465,6 +549,7 @@ pacman -Syu gpm::
|
||||
Update package list, upgrade all packages, and then install gpm if it
|
||||
wasn't already installed.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
See linkman:pacman.conf[5] for more details on configuring pacman using the
|
||||
@@ -473,6 +558,7 @@ See linkman:pacman.conf[5] for more details on configuring pacman using the
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:pacman.conf[5], linkman:makepkg[8], linkman:libalpm[3]
|
||||
linkman:alpm-hooks[5], linkman:libalpm[3], linkman:makepkg[8],
|
||||
linkman:pacman.conf[5]
|
||||
|
||||
include::footer.txt[]
|
||||
|
||||
@@ -45,13 +45,14 @@ NOTE: Each directive must be in CamelCase. If the case isn't respected, the
|
||||
directive won't be recognized. For example. noupgrade or NOUPGRADE will not
|
||||
work.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*RootDir =* path/to/root::
|
||||
Set the default root directory for pacman to install to. This option is
|
||||
used if you want to install a package on a temporary mounted partition
|
||||
which is "owned" by another system, or for a chroot install.
|
||||
*NOTE*: If database path or logfile are not specified on either the
|
||||
*NOTE*: If database path or log file are not specified on either the
|
||||
command line or in linkman:pacman.conf[5], their default location will
|
||||
be inside this root path.
|
||||
|
||||
@@ -69,6 +70,15 @@ Options
|
||||
to the first cache directory with write access. *NOTE*: this is an absolute
|
||||
path, the root path is not automatically prepended.
|
||||
|
||||
*HookDir =* path/to/hook/dir::
|
||||
Add directories to search for alpm hooks in addition to the system hook
|
||||
directory (+{datarootdir}/libalpm/hooks/+). A typical default is
|
||||
+{sysconfdir}/pacman.d/hooks+. Multiple directories can be specified with
|
||||
hooks in later directories taking precedence over hooks in earlier
|
||||
directories. *NOTE*: this is an absolute path, the root path is not
|
||||
automatically prepended. For more information on the alpm hooks, see
|
||||
linkman:alpm-hooks[5].
|
||||
|
||||
*GPGDir =* path/to/gpg/dir::
|
||||
Overrides the default location of the directory containing configuration
|
||||
files for GnuPG. A typical default is +{sysconfdir}/pacman.d/gnupg/+.
|
||||
@@ -99,15 +109,15 @@ Options
|
||||
allowed.
|
||||
|
||||
*Include =* path::
|
||||
Include another config file. This file can include repositories or
|
||||
Include another configuration file. This file can include repositories or
|
||||
general configuration options. Wildcards in the specified paths will get
|
||||
expanded based on linkman:glob[7] rules.
|
||||
|
||||
*Architecture =* auto | i686 | x86_64 | ...::
|
||||
If set, pacman will only allow installation of packages of the given
|
||||
architecture (e.g. 'i686', 'x86_64', etc). The special value 'auto' will
|
||||
use the system architecture, provided by in ``uname -m''. If unset, no
|
||||
architecture checks are made. *NOTE*: packages with the special
|
||||
use the system architecture, provided via ``uname -m''. If unset, no
|
||||
architecture checks are made. *NOTE*: Packages with the special
|
||||
architecture 'any' can always be installed, as they are meant to be
|
||||
architecture independent.
|
||||
|
||||
@@ -119,7 +129,7 @@ Options
|
||||
properly.
|
||||
+
|
||||
This option is useful for users who experience problems with built-in
|
||||
http/ftp support, or need the more advanced proxy support that comes with
|
||||
HTTP/FTP support, or need the more advanced proxy support that comes with
|
||||
utilities like wget.
|
||||
|
||||
*NoUpgrade =* file ...::
|
||||
@@ -128,7 +138,10 @@ Options
|
||||
'.pacnew' extension.
|
||||
These files refer to files in the package archive, so do not include the
|
||||
leading slash (the RootDir) when specifying them. Shell-style glob patterns
|
||||
are allowed.
|
||||
are allowed. It is possible to invert matches by prepending a file with
|
||||
an exclamation mark. Inverted files will result in previously blacklisted
|
||||
files being whitelisted again. Subsequent matches will override previous
|
||||
ones. A leading literal exclamation mark or backslash needs to be escaped.
|
||||
|
||||
*NoExtract =* file ...::
|
||||
All files listed with a `NoExtract` directive will never be extracted from
|
||||
@@ -138,7 +151,10 @@ Options
|
||||
from the 'apache' package.
|
||||
These files refer to files in the package archive, so do not include the
|
||||
leading slash (the RootDir) when specifying them. Shell-style glob patterns
|
||||
are allowed.
|
||||
are allowed. It is possible to invert matches by prepending a file with
|
||||
an exclamation mark. Inverted files will result in previously blacklisted
|
||||
files being whitelisted again. Subsequent matches will override previous
|
||||
ones. A leading literal exclamation mark or backslash needs to be escaped.
|
||||
|
||||
*CleanMethod =* KeepInstalled &| KeepCurrent::
|
||||
If set to `KeepInstalled` (the default), the '-Sc' operation will clean
|
||||
@@ -183,6 +199,7 @@ Options
|
||||
and completed percentage of the entire download list rather
|
||||
than the percent of each individual download target. The progress
|
||||
bar is still based solely on the current file download.
|
||||
This option won't work if XferCommand is used.
|
||||
|
||||
*CheckSpace*::
|
||||
Performs an approximate check for adequate available disk space before
|
||||
@@ -192,14 +209,16 @@ Options
|
||||
Displays name, version and size of target packages formatted
|
||||
as a table for upgrade, sync and remove operations.
|
||||
|
||||
|
||||
Repository Sections
|
||||
-------------------
|
||||
Each repository section defines a section name and at least one location where
|
||||
the packages can be found. The section name is defined by the string within
|
||||
square brackets (the two above are 'current' and 'custom'). Locations are
|
||||
defined with the 'Server' directive and follow a URL naming structure. If you
|
||||
want to use a local directory, you can specify the full path with a ``file://''
|
||||
prefix, as shown above.
|
||||
square brackets (the two above are 'core' and 'custom'). Repository names
|
||||
must be unique and the name 'local' is reserved for the database of installed
|
||||
packages. Locations are defined with the 'Server' directive and follow a URL
|
||||
naming structure. If you want to use a local directory, you can specify the
|
||||
full path with a ``file://'' prefix, as shown above.
|
||||
|
||||
A common way to define DB locations utilizes the 'Include' directive. For each
|
||||
repository defined in the configuration file, a single 'Include' directive can
|
||||
@@ -237,6 +256,27 @@ even be used for different architectures.
|
||||
Set the signature verification level for this repository. For more
|
||||
information, see <<SC,Package and Database Signature Checking>> below.
|
||||
|
||||
*Usage =* ...::
|
||||
Set the usage level for this repository. This option takes a list of tokens
|
||||
which must be at least one of the following:
|
||||
*Sync*;;
|
||||
Enables refreshes for this repository.
|
||||
*Search*;;
|
||||
Enables searching for this repository.
|
||||
*Install*;;
|
||||
Enables installation of packages from this repository during a '\--sync'
|
||||
operation.
|
||||
*Upgrade*;;
|
||||
Allows this repository to be a valid source of packages when performing
|
||||
a '\--sysupgrade'.
|
||||
*All*;;
|
||||
Enables all of the above features for the repository. This is the default
|
||||
if not specified.
|
||||
+
|
||||
Note that an enabled repository can be operated on explicitly, regardless of the Usage
|
||||
level set.
|
||||
|
||||
|
||||
Package and Database Signature Checking[[SC]]
|
||||
---------------------------------------------
|
||||
The 'SigLevel' directive is valid in both the `[options]` and repository
|
||||
@@ -300,6 +340,7 @@ The built-in default is the following:
|
||||
SigLevel = Optional TrustedOnly
|
||||
--------
|
||||
|
||||
|
||||
Using Your Own Repository
|
||||
-------------------------
|
||||
If you have numerous custom packages of your own, it is often easier to generate
|
||||
|
||||
@@ -13,17 +13,19 @@ Synopsis
|
||||
--------
|
||||
'pactree' [options] package
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
Pactree produces a dependency tree for a package.
|
||||
|
||||
By default a tree like output is generated, but with the -g option a graphviz
|
||||
By default, a tree-like output is generated, but with the '\--graph' option, a Graphviz
|
||||
description is generated.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*-a, \--ascii*::
|
||||
Use ascii characters for tree formatting. By default, pactree will use unicode
|
||||
Use ASCII characters for tree formatting. By default, pactree will use Unicode
|
||||
line drawing characters if it is able to detect that the locale supports them.
|
||||
|
||||
*-b, \--dbpath*::
|
||||
@@ -38,11 +40,11 @@ Options
|
||||
required.
|
||||
|
||||
*-g, \--graph*::
|
||||
Generate graphviz description. If this option is given, the -c and -l
|
||||
options are ignored.
|
||||
Generate a Graphviz description. If this option is given, the '\--color' and
|
||||
'\--linear' options are ignored.
|
||||
|
||||
*-h, \--help*::
|
||||
Output syntax and command line options.
|
||||
Output syntax and command-line options.
|
||||
|
||||
*-l, \--linear*::
|
||||
Prints package names at the start of each line, one per line.
|
||||
@@ -54,11 +56,12 @@ Options
|
||||
Read package data from sync databases instead of local database.
|
||||
|
||||
*-u, \--unique*::
|
||||
List dependent packages once. Implies --linear.
|
||||
List dependent packages once. Implies '\--linear'.
|
||||
|
||||
*\--config <file>*::
|
||||
Specify an alternate pacman configuration file.
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:pacman[8], linkman:pacman.conf[5], linkman:makepkg[8]
|
||||
|
||||
@@ -25,6 +25,7 @@ significantly.
|
||||
|
||||
'pkgdelta' requires linkman:xdelta3[1] to do its job.
|
||||
|
||||
|
||||
Options
|
||||
-------
|
||||
*--max-delta-size <ratio>*::
|
||||
@@ -35,17 +36,19 @@ Options
|
||||
|
||||
*--min-pkg-size <size>*::
|
||||
Minimal size of the package file in bytes to be considered for delta creation.
|
||||
Default value: 1048576 bytes = 1MiB. This may be any absolute size in bytes, or
|
||||
a human readable value such as `4 MiB` or `3.5MB`.
|
||||
Default value: 1048576 bytes = 1 MiB. This may be any absolute size in bytes or
|
||||
a human-readable value such as `4MiB` or `3.5MB`.
|
||||
|
||||
*-q, \--quiet*::
|
||||
Be quiet. Do not output anything but warnings and errors.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
$ pkgdelta libreoffice-3.3.2-1-x86_64.pkg.tar.xz libreoffice-3.3.2-2-x86_64.pkg.tar.xz
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:pacman[8], linkman:xdelta3[1]
|
||||
|
||||
@@ -8,6 +8,7 @@ Name
|
||||
----
|
||||
repo-add - package database maintenance utility
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
'repo-add' [options] <path-to-db> <package|delta> [<package|delta> ...]
|
||||
@@ -25,20 +26,23 @@ They also handle package deltas produced by linkman:pkgdelta[8].
|
||||
delta file. Multiple packages and/or deltas to add can be specified on the
|
||||
command line.
|
||||
|
||||
If a matching ``.sig'' file is found alongside a package file, the signature
|
||||
will automatically be embedded into the database.
|
||||
|
||||
'repo-remove' will update a package database by removing the package name or
|
||||
delta specified on the command line. Multiple packages and/or delta to remove
|
||||
can be specified on the command line.
|
||||
|
||||
A package database is a tar file, optionally compressed. Valid extensions are
|
||||
``.db'' or ``.files'' followed by an archive extension of ``.tar'',
|
||||
``.tar.gz'', ``.tar.bz2'', ``.tar.xz'', or ``.tar.Z''. The file does not need
|
||||
to exist, but all parent directories must exist.
|
||||
``.db'' followed by an archive extension of ``.tar'', ``.tar.gz'', ``.tar.bz2'',
|
||||
``.tar.xz'', or ``.tar.Z''. The file does not need to exist, but all parent
|
||||
directories must exist.
|
||||
|
||||
|
||||
Common Options
|
||||
--------------
|
||||
*-q, \--quiet*::
|
||||
Force this program to keep quiet and run silent except for warning and
|
||||
Force this program to keep quiet and run silently except for warning and
|
||||
error messages.
|
||||
|
||||
*-s, \--sign*::
|
||||
@@ -58,7 +62,8 @@ Common Options
|
||||
proceed.
|
||||
|
||||
*\--nocolor*::
|
||||
Remove color from repo-add and repo-remove output.
|
||||
Remove color from 'repo-add' and 'repo-remove' output.
|
||||
|
||||
|
||||
repo-add Options
|
||||
----------------
|
||||
@@ -66,15 +71,25 @@ repo-add Options
|
||||
Automatically generate and add a delta file between the old entry and the
|
||||
new one, if the old package file is found next to the new one.
|
||||
|
||||
*-f, \--files*::
|
||||
Tells repo-add also to create and include a list of the files in the
|
||||
specified packages. This is useful for creating databases listing all files
|
||||
in a given sync repository for tools that may use this information.
|
||||
|
||||
*-n, \--new*::
|
||||
Only add packages that are not already in the database. Warnings will be
|
||||
printed upon detection of existing packages, but they will not be re-added.
|
||||
|
||||
*-R, \--remove*::
|
||||
Remove old package files from the disk when updating their entry in the
|
||||
database.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
'repo-add' foo.db.tar.xz <pkg1> [<pkg2> ...]
|
||||
|
||||
This creates two separate databases; a smaller database ``foo.db.tar.xz'' used by
|
||||
pacman and a large database containing package file lists ``foo.files.tar.xz'' for
|
||||
use by other utilities. While pacman can use the large database (if renamed with a
|
||||
db.tar* extension), there is currently no additional benefit for the larger download.
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:makepkg[8], linkman:pacman[8], linkman:pkgdelta[8]
|
||||
|
||||
@@ -8,9 +8,9 @@ please try to follow as much as you can.
|
||||
NOTE: Some of this is paraphrased from the kernel documentation's
|
||||
"SubmittingPatches" file.
|
||||
|
||||
|
||||
Getting the most recent source
|
||||
------------------------------
|
||||
|
||||
Patches need to be submitted in GIT format and are best if they are against the
|
||||
latest version of the code. There are several helpful tutorials for getting
|
||||
started with GIT if you have not worked with it before.
|
||||
@@ -27,7 +27,7 @@ Creating your patch
|
||||
-------------------
|
||||
|
||||
--
|
||||
* use `git commit -s` for creating a commit of your changes.
|
||||
* Use `git commit -s` for creating a commit of your changes.
|
||||
|
||||
The -s allows you to credit yourself by adding a "Signed Off By" line to
|
||||
indicate who has "signed" the patch - who has approved it.
|
||||
@@ -46,7 +46,11 @@ was actually done, and allows better feedback.
|
||||
* Use `git format-patch` to create patches.
|
||||
|
||||
Your commit message will be shown above the patch by default when you will use
|
||||
`git-format-patch`, including the signoff line.
|
||||
`git format-patch`, including the signoff line. Sets of multiple patches that
|
||||
need extra explanation beyond the commit messages may include additional notes
|
||||
in a cover letter. Individual patches may include additional notes between the
|
||||
"---" following the commit message and the beginning of the diff.
|
||||
|
||||
--
|
||||
|
||||
Submitting your patch
|
||||
@@ -56,7 +60,7 @@ Submitting your patch
|
||||
* Send the patch to the pacman-dev mailing list
|
||||
|
||||
The mailing list is the primary queue for review and acceptance. Here you
|
||||
will get feedback, and let me know the details of your patch.
|
||||
will get feedback, and let the reviewers know the details of your patch.
|
||||
|
||||
* No MIME, no links, no compression, no attachments. Just plain text.
|
||||
|
||||
@@ -65,8 +69,10 @@ reasons for this. First, it makes them easier to read with any mail reader,
|
||||
it allows easier review "at a glance", and most importantly, it allows people
|
||||
to comment on exact lines of the patch in reply emails.
|
||||
|
||||
`git send-email` allows you to send git formatted patches in plain text easily
|
||||
and is the preferred method for submission to the mailing list.
|
||||
`git send-email` allows you to send Git-formatted patches in plain text easily
|
||||
and is the preferred method for submission to the mailing list. Mail clients,
|
||||
including Gmail's web interface, have a tendency to break patches by wrapping
|
||||
lines and/or adjusting whitespace and should be avoided.
|
||||
|
||||
--
|
||||
|
||||
@@ -86,10 +92,11 @@ looked at it yet.
|
||||
* Respond to feedback
|
||||
|
||||
When you do get feedback, it usually merits a response, whether this be a
|
||||
resubmit of the patch with corrections or a follow-up email asking for
|
||||
clarifications. When neither of these occurs, don't expect your patch to see
|
||||
resubmission of the patch with corrections or a follow-up email asking for
|
||||
clarifications. When neither of these occurs, don't expect your patch to get
|
||||
further review. The all-volunteer staff don't have time to fix up patches that
|
||||
aren't their own.
|
||||
aren't their own. When resubmitting patches, update the subject line to reflect
|
||||
the version number ('[PATCHv2]'), and send it as a reply to the original thread.
|
||||
|
||||
--
|
||||
|
||||
|
||||
@@ -2,19 +2,17 @@ Pacman - Translating
|
||||
====================
|
||||
|
||||
This document is here to guide you in helping translate pacman messages,
|
||||
libalpm messages, and the manpages for the entire pacman package.
|
||||
libalpm messages, and the manual pages for the entire pacman package.
|
||||
|
||||
We are currently using http://www.transifex.net/[Transifex] as the translation
|
||||
We are currently using http://www.transifex.com/[Transifex] as the translation
|
||||
platform for pacman and libalpm. You will need to sign up for an account there
|
||||
and then register with a translation team on the
|
||||
http://www.transifex.net/projects/p/archlinux-pacman/[pacman project page].
|
||||
http://www.transifex.com/projects/p/archlinux-pacman/[pacman project page].
|
||||
|
||||
NOTE: This may be old information due to our switch to Transifex, but the
|
||||
gettext website is a very useful guide to read before embarking on translation
|
||||
work, as it describes many of the commands in more detail than I will here:
|
||||
https://www.gnu.org/software/gettext/manual/html_node/gettext.html[]. In
|
||||
addition, this site presents a small tutorial that I found useful:
|
||||
http://oriya.sarovar.org/docs/gettext/[].
|
||||
https://www.gnu.org/software/gettext/manual/html_node/gettext.html[].
|
||||
|
||||
|
||||
Translating Messages
|
||||
@@ -23,21 +21,22 @@ Translating Messages
|
||||
Overview
|
||||
~~~~~~~~
|
||||
|
||||
There are two separate message catalogs in pacman- one for the backend
|
||||
(libalpm) and one for the frontend (pacman and scripts). These correspond to
|
||||
There are two separate message catalogs in pacman: one for the back-end
|
||||
(libalpm) and one for the front-end (pacman and scripts). These correspond to
|
||||
the `lib/libalpm/po` and `po` directories in the pacman source, respectively.
|
||||
|
||||
Translation message files are a specially formatted text file containing the
|
||||
original message and the corresponding translation. These po files can then
|
||||
either be hand edited, or modified with a tool such as poedit, gtranslator or
|
||||
either be hand-edited, or modified with a tool such as poedit, gtranslator or
|
||||
kbabel. Using a translation tool tends to make the job easier.
|
||||
|
||||
Please read up on Transifex usage using the
|
||||
http://help.transifex.net/[Transifex Help] if you are not familiar.
|
||||
http://docs.transifex.com/[Transifex Help] if you are not familiar.
|
||||
|
||||
Here is an example set of commands if you have a source code checkout and are
|
||||
not worried about any local translations being overwritten. The .tx/ directory
|
||||
is checked into the git repository so is preconfigured with the two project
|
||||
Transifex provides a command-line client to help with translations. Here is
|
||||
an example set of commands if you have a source code checkout and are not
|
||||
worried about any local translations being overwritten. The .tx/ directory is
|
||||
checked into the git repository so is preconfigured with the two project
|
||||
resources (See `tx status` output for a quick overview).
|
||||
|
||||
tx pull -f
|
||||
@@ -47,8 +46,8 @@ resources (See `tx status` output for a quick overview).
|
||||
|
||||
Or to just push one of the two available resources:
|
||||
|
||||
tx push -r archlinux-pacman.pacman-pot -t -l fi
|
||||
tx push -r archlinux-pacman.libalpm-pot -t -l fi
|
||||
tx push -r archlinux-pacman.pacman-pot -t -l <mylang>
|
||||
tx push -r archlinux-pacman.libalpm-pot -t -l <mylang>
|
||||
|
||||
See the <<Notes,Notes>> section for additional hints on translating.
|
||||
|
||||
@@ -61,8 +60,8 @@ mailing list asking for translations. This email will have a prefix of
|
||||
*[translation]* for anyone looking to set up an email filter.
|
||||
|
||||
At this time, the latest `.po` language files will be made available at the
|
||||
Transifex project page. Each language will have two files available (backend
|
||||
and frontend). Translators interested in helping are encouraged to use the
|
||||
Transifex project page. Each language will have two files available (back-end
|
||||
and front-end). Translators interested in helping are encouraged to use the
|
||||
features of Transifex to let others know they are currently translating their
|
||||
language.
|
||||
|
||||
@@ -99,7 +98,7 @@ Next, update your specific language's translation file:
|
||||
|
||||
At this point, you can do the translation. To submit your changes, either email
|
||||
the new `.po` file to the mailing-list with *[translation]* in the subject, or
|
||||
submit a GIT-formatted patch (please do not include any `.pot` file changes).
|
||||
submit a Git-formatted patch (please do not include any `.pot` file changes).
|
||||
|
||||
As a shortcut, all translation files (including `.pot` files) can be updated
|
||||
with the following command:
|
||||
@@ -130,7 +129,7 @@ Notes[[Notes]]
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
msgid and msgstr 'variables' can be on as many lines as necessary. Line breaks
|
||||
are ignored- if you need a literal line break, use an `\n` in your string. The
|
||||
are ignored; if you need a literal line break, use an `\n` in your string. The
|
||||
following two translations are equivalent:
|
||||
|
||||
msgstr "This is a test translation"
|
||||
@@ -138,7 +137,7 @@ following two translations are equivalent:
|
||||
msgstr ""
|
||||
"This is a test translation"
|
||||
|
||||
If you want to test the translation (for example, the frontend one):
|
||||
If you want to test the translation (for example, the front-end one):
|
||||
|
||||
rm *.gmo stamp-po
|
||||
make
|
||||
@@ -147,18 +146,12 @@ If you want to test the translation (for example, the frontend one):
|
||||
|
||||
Translating Manpages
|
||||
--------------------
|
||||
|
||||
There are currently no efforts underway to include translated manpages in the
|
||||
pacman codebase. However, this is not to say translations are unwelcome. If
|
||||
someone has experience with i18n manpages and how to best include them with our
|
||||
There are currently no efforts underway to include translated manual pages in
|
||||
the pacman codebase. However, this is not to say translations are unwelcome. If
|
||||
someone has experience with i18n man pages and how to best include them with our
|
||||
source, please contact the pacman-dev mailing list at
|
||||
mailto:pacman-dev@archlinux.org[].
|
||||
|
||||
Some community efforts have been made to translate manpages, and these can be
|
||||
found in the link:https://aur.archlinux.org[AUR] (Arch User Repository). Please
|
||||
check there first before undergoing a translation effort to ensure you are not
|
||||
duplicating efforts.
|
||||
|
||||
/////
|
||||
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
|
||||
/////
|
||||
|
||||
@@ -31,7 +31,7 @@ Version comparison operates as follows:
|
||||
1 < 1.0 < 1.1 < 1.1.1 < 1.2 < 2.0 < 3.0.0
|
||||
|
||||
Additionally, version strings can have an 'epoch' value defined that will
|
||||
overrule any version comparison (unless the epoch values are equal). This is
|
||||
overrule any version comparison, unless the epoch values are equal. This is
|
||||
specified in an `epoch:version-rel` format. For example, `2:1.0-1` is always
|
||||
greater than `1:3.6-1`.
|
||||
|
||||
@@ -44,9 +44,10 @@ mainly for supporting versioned dependencies that do not include the 'pkgrel'.
|
||||
Options
|
||||
-------
|
||||
*-h, \--help*::
|
||||
Display syntax for the given operation. If no operation was supplied
|
||||
Display syntax for the given operation. If no operation was supplied,
|
||||
then the general syntax is shown.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
@@ -65,10 +66,12 @@ Examples
|
||||
$ vercmp 4.34 1:001
|
||||
-1
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
There is none.
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:pacman[8], linkman:makepkg[8], linkman:libalpm[3]
|
||||
|
||||
@@ -26,4 +26,4 @@ SED_PROCESS = \
|
||||
%.conf: %.conf.in Makefile
|
||||
$(SED_PROCESS)
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
# vim:set noet:
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#
|
||||
#-- The download utilities that makepkg should use to acquire sources
|
||||
# Format: 'protocol::agent'
|
||||
DLAGENTS=('ftp::/usr/bin/curl -qfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
|
||||
'http::/usr/bin/curl -qb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'https::/usr/bin/curl -qb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
DLAGENTS=('ftp::/usr/bin/curl -gqfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
|
||||
'http::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'https::/usr/bin/curl -gqb "" -fLC - --retry 3 --retry-delay 3 -o %o %u'
|
||||
'rsync::/usr/bin/rsync --no-motd -z %u %o'
|
||||
'scp::/usr/bin/scp -C %u %o')
|
||||
|
||||
@@ -19,6 +19,13 @@ DLAGENTS=('ftp::/usr/bin/curl -qfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o
|
||||
# /usr/bin/lftpget -c
|
||||
# /usr/bin/wget
|
||||
|
||||
#-- The package required by makepkg to download VCS sources
|
||||
# Format: 'protocol::package'
|
||||
VCSCLIENTS=('bzr::bzr'
|
||||
'git::git'
|
||||
'hg::mercurial'
|
||||
'svn::subversion')
|
||||
|
||||
#########################################################################
|
||||
# ARCHITECTURE, COMPILE FLAGS
|
||||
#########################################################################
|
||||
@@ -41,17 +48,16 @@ CHOST="@CHOST@"
|
||||
# BUILD ENVIRONMENT
|
||||
#########################################################################
|
||||
#
|
||||
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)
|
||||
# Defaults: BUILDENV=(!distcc color !ccache check !sign)
|
||||
# A negated environment option will do the opposite of the comments below.
|
||||
#
|
||||
#-- fakeroot: Allow building packages as a non-root user
|
||||
#-- distcc: Use the Distributed C/C++/ObjC compiler
|
||||
#-- color: Colorize output messages
|
||||
#-- ccache: Use ccache to cache compilation
|
||||
#-- check: Run the check() function if present in the PKGBUILD
|
||||
#-- sign: Generate PGP signature file
|
||||
#
|
||||
BUILDENV=(fakeroot !distcc color !ccache check !sign)
|
||||
BUILDENV=(!distcc color !ccache check !sign)
|
||||
#
|
||||
#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,
|
||||
#-- specify a space-delimited list of hosts running in the DistCC cluster.
|
||||
@@ -65,7 +71,7 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
|
||||
# These are default values for the options=() settings
|
||||
#########################################################################
|
||||
#
|
||||
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug)
|
||||
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !optipng !debug)
|
||||
# A negated option will do the opposite of the comments below.
|
||||
#
|
||||
#-- strip: Strip symbols from binaries/libraries
|
||||
@@ -76,9 +82,10 @@ BUILDENV=(fakeroot !distcc color !ccache check !sign)
|
||||
#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
|
||||
#-- purge: Remove files specified by PURGE_TARGETS
|
||||
#-- upx: Compress binary executable files using UPX
|
||||
#-- optipng: Optimize PNG images with optipng
|
||||
#-- debug: Add debugging flags as specified in DEBUG_* variables
|
||||
#
|
||||
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug)
|
||||
OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !optipng !debug)
|
||||
|
||||
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
|
||||
INTEGRITY_CHECK=(md5)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#CacheDir = @localstatedir@/cache/pacman/pkg/
|
||||
#LogFile = @localstatedir@/log/pacman.log
|
||||
#GPGDir = @sysconfdir@/pacman.d/gnupg/
|
||||
#HookDir = @sysconfdir@/pacman.d/hooks/
|
||||
HoldPkg = pacman glibc
|
||||
#XferCommand = /usr/bin/curl -C - -f %u > %o
|
||||
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
|
||||
|
||||
@@ -7,6 +7,7 @@ include_HEADERS = alpm_list.h alpm.h
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-imacros $(top_builddir)/config.h \
|
||||
-DSYSHOOKDIR=\"@datarootdir@/libalpm/hooks/\" \
|
||||
-DLOCALEDIR=\"@localedir@\"
|
||||
|
||||
AM_CFLAGS = -pedantic -D_GNU_SOURCE $(WARNING_CFLAGS)
|
||||
@@ -18,9 +19,6 @@ else
|
||||
AM_CFLAGS += -fvisibility=internal
|
||||
endif
|
||||
endif
|
||||
if ENABLE_GNU89_INLINE_CC
|
||||
AM_CFLAGS += -fgnu89-inline
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libalpm.pc
|
||||
@@ -30,6 +28,7 @@ libalpm_la_SOURCES = \
|
||||
alpm.h alpm.c \
|
||||
alpm_list.h alpm_list.c \
|
||||
backup.h backup.c \
|
||||
base64.h base64.c \
|
||||
be_local.c \
|
||||
be_package.c \
|
||||
be_sync.c \
|
||||
@@ -44,6 +43,8 @@ libalpm_la_SOURCES = \
|
||||
graph.h graph.c \
|
||||
group.h group.c \
|
||||
handle.h handle.c \
|
||||
hook.h hook.c \
|
||||
ini.h ini.c \
|
||||
libarchive-compat.h \
|
||||
log.h log.c \
|
||||
package.h package.c \
|
||||
@@ -63,11 +64,6 @@ libalpm_la_SOURCES += \
|
||||
sha2.h sha2.c
|
||||
endif
|
||||
|
||||
if HAVE_LIBGPGME
|
||||
libalpm_la_SOURCES += \
|
||||
base64.h base64.c
|
||||
endif
|
||||
|
||||
libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO)
|
||||
|
||||
libalpm_la_CFLAGS = \
|
||||
@@ -84,4 +80,4 @@ libalpm_la_LIBADD = \
|
||||
$(LIBCURL_LIBS) \
|
||||
$(LIBSSL_LIBS)
|
||||
|
||||
# vim:set ts=2 sw=2 noet:
|
||||
# vim:set noet:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* add.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -57,6 +57,8 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
|
||||
/* Sanity checks */
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
ASSERT(pkg != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
ASSERT(pkg->origin != ALPM_PKG_FROM_LOCALDB,
|
||||
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
ASSERT(handle == pkg->handle, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
trans = handle->trans;
|
||||
ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
|
||||
@@ -88,7 +90,7 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"),
|
||||
localpkgname, localpkgver);
|
||||
}
|
||||
} else if(cmp < 0) {
|
||||
} else if(cmp < 0 && !(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY)) {
|
||||
/* local version is newer */
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("downgrading package %s (%s => %s)\n"),
|
||||
localpkgname, localpkgver, pkgver);
|
||||
@@ -105,26 +107,42 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
|
||||
}
|
||||
|
||||
static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
|
||||
struct archive_entry *entry, const char *filename, const char *origname)
|
||||
struct archive_entry *entry, const char *filename)
|
||||
{
|
||||
int ret;
|
||||
struct archive *archive_writer;
|
||||
const int archive_flags = ARCHIVE_EXTRACT_OWNER |
|
||||
ARCHIVE_EXTRACT_PERM |
|
||||
ARCHIVE_EXTRACT_TIME;
|
||||
ARCHIVE_EXTRACT_TIME |
|
||||
ARCHIVE_EXTRACT_UNLINK |
|
||||
ARCHIVE_EXTRACT_SECURE_SYMLINKS;
|
||||
|
||||
archive_entry_set_pathname(entry, filename);
|
||||
|
||||
ret = archive_read_extract(archive, entry, archive_flags);
|
||||
archive_writer = archive_write_disk_new();
|
||||
if (archive_writer == NULL) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("cannot allocate disk archive object"));
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: cannot allocate disk archive object");
|
||||
return 1;
|
||||
}
|
||||
|
||||
archive_write_disk_set_options(archive_writer, archive_flags);
|
||||
|
||||
ret = archive_read_extract2(archive, entry, archive_writer);
|
||||
|
||||
archive_write_free(archive_writer);
|
||||
|
||||
if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {
|
||||
/* operation succeeded but a "non-critical" error was encountered */
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
|
||||
origname, archive_error_string(archive));
|
||||
filename, archive_error_string(archive));
|
||||
} else if(ret != ARCHIVE_OK) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not extract %s (%s)\n"),
|
||||
origname, archive_error_string(archive));
|
||||
filename, archive_error_string(archive));
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: could not extract %s (%s)\n",
|
||||
origname, archive_error_string(archive));
|
||||
filename, archive_error_string(archive));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -142,53 +160,66 @@ static int try_rename(alpm_handle_t *handle, const char *src, const char *dest)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
|
||||
struct archive_entry *entry, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg)
|
||||
static int extract_db_file(alpm_handle_t *handle, struct archive *archive,
|
||||
struct archive_entry *entry, alpm_pkg_t *newpkg, const char *entryname)
|
||||
{
|
||||
const char *entryname;
|
||||
mode_t entrymode;
|
||||
char filename[PATH_MAX]; /* the actual file we're extracting */
|
||||
int needbackup = 0, notouch = 0;
|
||||
const char *hash_orig = NULL;
|
||||
char *entryname_orig = NULL;
|
||||
int errors = 0;
|
||||
|
||||
entryname = archive_entry_pathname(entry);
|
||||
entrymode = archive_entry_mode(entry);
|
||||
|
||||
const char *dbfile = NULL;
|
||||
if(strcmp(entryname, ".INSTALL") == 0) {
|
||||
/* the install script goes inside the db */
|
||||
snprintf(filename, PATH_MAX, "%s%s-%s/install",
|
||||
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
dbfile = "install";
|
||||
} else if(strcmp(entryname, ".CHANGELOG") == 0) {
|
||||
/* the changelog goes inside the db */
|
||||
snprintf(filename, PATH_MAX, "%s%s-%s/changelog",
|
||||
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
dbfile = "changelog";
|
||||
} else if(strcmp(entryname, ".MTREE") == 0) {
|
||||
/* the mtree file goes inside the db */
|
||||
snprintf(filename, PATH_MAX, "%s%s-%s/mtree",
|
||||
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
dbfile = "mtree";
|
||||
} else if(*entryname == '.') {
|
||||
/* for now, ignore all files starting with '.' that haven't
|
||||
* already been handled (for future possibilities) */
|
||||
/* reserve all files starting with '.' for future possibilities */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);
|
||||
archive_read_data_skip(archive);
|
||||
return 0;
|
||||
} else {
|
||||
/* build the new entryname relative to handle->root */
|
||||
snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
|
||||
}
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
snprintf(filename, PATH_MAX, "%s%s-%s/%s",
|
||||
_alpm_db_path(handle->db_local), newpkg->name, newpkg->version, dbfile);
|
||||
return perform_extraction(handle, archive, entry, filename);
|
||||
}
|
||||
|
||||
static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
|
||||
struct archive_entry *entry, alpm_pkg_t *newpkg, alpm_pkg_t *oldpkg)
|
||||
{
|
||||
const char *entryname = archive_entry_pathname(entry);
|
||||
mode_t entrymode = archive_entry_mode(entry);
|
||||
alpm_backup_t *backup = _alpm_needbackup(entryname, newpkg);
|
||||
char filename[PATH_MAX]; /* the actual file we're extracting */
|
||||
int needbackup = 0, notouch = 0;
|
||||
const char *hash_orig = NULL;
|
||||
int isnewfile = 0, errors = 0;
|
||||
struct stat lsbuf;
|
||||
size_t filename_len;
|
||||
|
||||
if(*entryname == '.') {
|
||||
return extract_db_file(handle, archive, entry, newpkg, entryname);
|
||||
}
|
||||
|
||||
if (!alpm_filelist_contains(&newpkg->files, entryname)) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("file not found in file list for package %s. skipping extraction of %s\n"),
|
||||
newpkg->name, entryname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* build the new entryname relative to handle->root */
|
||||
filename_len = snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname);
|
||||
if(filename_len >= PATH_MAX) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("unable to extract %s%s: path too long"), handle->root, entryname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if a file is in NoExtract then we never extract it */
|
||||
if(alpm_list_find(handle->noextract, entryname, _alpm_fnmatch)) {
|
||||
if(_alpm_fnmatch_patterns(handle->noextract, entryname) == 0) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract,"
|
||||
" skipping extraction of %s\n",
|
||||
entryname, filename);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"note: %s is in NoExtract, skipping extraction\n", entryname);
|
||||
archive_read_data_skip(archive);
|
||||
return 0;
|
||||
}
|
||||
@@ -197,266 +228,182 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
|
||||
* to get 'right'. Here are the possibilities, with the filesystem
|
||||
* on the left and the package on the top:
|
||||
* (F=file, N=node, S=symlink, D=dir)
|
||||
* | F/N | S | D
|
||||
* non-existent | 1 | 2 | 3
|
||||
* F/N | 4 | 5 | 6
|
||||
* S | 7 | 8 | 9
|
||||
* D | 10 | 11 | 12
|
||||
* | F/N | D
|
||||
* non-existent | 1 | 2
|
||||
* F/N | 3 | 4
|
||||
* D | 5 | 6
|
||||
*
|
||||
* 1,2,3- extract, no magic necessary. lstat (_alpm_lstat) will fail here.
|
||||
* 4,5,6,7,8- conflict checks should have caught this. either overwrite
|
||||
* 1,2- extract, no magic necessary. lstat (llstat) will fail here.
|
||||
* 3,4- conflict checks should have caught this. either overwrite
|
||||
* or backup the file.
|
||||
* 9- follow the symlink, hopefully it is a directory, check it.
|
||||
* 10- file replacing directory- don't allow it.
|
||||
* 11- don't extract symlink- a dir exists here. we don't want links to
|
||||
* links, etc.
|
||||
* 12- skip extraction, dir already exists.
|
||||
* 5- file replacing directory- don't allow it.
|
||||
* 6- skip extraction, dir already exists.
|
||||
*/
|
||||
|
||||
/* do both a lstat and a stat, so we can see what symlinks point to */
|
||||
struct stat lsbuf, sbuf;
|
||||
if(_alpm_lstat(filename, &lsbuf) != 0 || stat(filename, &sbuf) != 0) {
|
||||
/* cases 1,2,3: couldn't stat an existing file, skip all backup checks */
|
||||
} else {
|
||||
if(S_ISDIR(lsbuf.st_mode)) {
|
||||
if(S_ISDIR(entrymode)) {
|
||||
/* case 12: existing dir, ignore it */
|
||||
if(lsbuf.st_mode != entrymode) {
|
||||
/* if filesystem perms are different than pkg perms, warn user */
|
||||
mode_t mask = 07777;
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("directory permissions differ on %s\n"
|
||||
"filesystem: %o package: %o\n"), filename, lsbuf.st_mode & mask,
|
||||
entrymode & mask);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: directory permissions differ on %s\n"
|
||||
"filesystem: %o package: %o\n", filename, lsbuf.st_mode & mask,
|
||||
entrymode & mask);
|
||||
}
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 0;
|
||||
} else {
|
||||
/* case 10/11: trying to overwrite dir with file/symlink, don't allow it */
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 1;
|
||||
}
|
||||
} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) {
|
||||
/* case 9: existing symlink, dir in package */
|
||||
if(S_ISDIR(sbuf.st_mode)) {
|
||||
/* the symlink on FS is to a directory, so we'll use it */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n",
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 0;
|
||||
} else {
|
||||
/* this is BAD. symlink was not to a directory */
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"),
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 1;
|
||||
}
|
||||
} else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) {
|
||||
/* case 6: trying to overwrite file with dir */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
|
||||
filename);
|
||||
} else if(S_ISREG(entrymode)) {
|
||||
/* case 4,7: */
|
||||
/* if file is in NoUpgrade, don't touch it */
|
||||
if(alpm_list_find(handle->noupgrade, entryname, _alpm_fnmatch)) {
|
||||
notouch = 1;
|
||||
} else {
|
||||
alpm_backup_t *backup;
|
||||
/* go to the backup array and see if our conflict is there */
|
||||
/* check newpkg first, so that adding backup files is retroactive */
|
||||
backup = _alpm_needbackup(entryname, newpkg);
|
||||
if(backup) {
|
||||
/* if we force hash_orig to be non-NULL retroactive backup works */
|
||||
hash_orig = "";
|
||||
needbackup = 1;
|
||||
}
|
||||
isnewfile = llstat(filename, &lsbuf) != 0;
|
||||
if(isnewfile) {
|
||||
/* cases 1,2: file doesn't exist, skip all backup checks */
|
||||
} else if(S_ISDIR(lsbuf.st_mode) && S_ISDIR(entrymode)) {
|
||||
#if 0
|
||||
uid_t entryuid = archive_entry_uid(entry);
|
||||
gid_t entrygid = archive_entry_gid(entry);
|
||||
#endif
|
||||
|
||||
/* check oldpkg for a backup entry, store the hash if available */
|
||||
if(oldpkg) {
|
||||
backup = _alpm_needbackup(entryname, oldpkg);
|
||||
if(backup) {
|
||||
hash_orig = backup->hash;
|
||||
needbackup = 1;
|
||||
}
|
||||
}
|
||||
/* case 6: existing dir, ignore it */
|
||||
if(lsbuf.st_mode != entrymode) {
|
||||
/* if filesystem perms are different than pkg perms, warn user */
|
||||
mode_t mask = 07777;
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("directory permissions differ on %s\n"
|
||||
"filesystem: %o package: %o\n"), filename, lsbuf.st_mode & mask,
|
||||
entrymode & mask);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: directory permissions differ on %s\n"
|
||||
"filesystem: %o package: %o\n", filename, lsbuf.st_mode & mask,
|
||||
entrymode & mask);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Disable this warning until our user management in packages has improved.
|
||||
Currently many packages have to create users in post_install and chown the
|
||||
directories. These all resulted in "false-positive" warnings. */
|
||||
|
||||
if((entryuid != lsbuf.st_uid) || (entrygid != lsbuf.st_gid)) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("directory ownership differs on %s\n"
|
||||
"filesystem: %u:%u package: %u:%u\n"), filename,
|
||||
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: directory ownership differs on %s\n"
|
||||
"filesystem: %u:%u package: %u:%u\n", filename,
|
||||
lsbuf.st_uid, lsbuf.st_gid, entryuid, entrygid);
|
||||
}
|
||||
#endif
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: skipping dir extraction of %s\n",
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 0;
|
||||
} else if(S_ISDIR(lsbuf.st_mode)) {
|
||||
/* case 5: trying to overwrite dir with file, don't allow it */
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"),
|
||||
filename);
|
||||
archive_read_data_skip(archive);
|
||||
return 1;
|
||||
} else if(S_ISDIR(entrymode)) {
|
||||
/* case 4: trying to overwrite file with dir */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extract: overwriting file with dir %s\n",
|
||||
filename);
|
||||
} else {
|
||||
/* case 3: trying to overwrite file with file */
|
||||
/* if file is in NoUpgrade, don't touch it */
|
||||
if(_alpm_fnmatch_patterns(handle->noupgrade, entryname) == 0) {
|
||||
notouch = 1;
|
||||
} else {
|
||||
alpm_backup_t *oldbackup;
|
||||
if(oldpkg && (oldbackup = _alpm_needbackup(entryname, oldpkg))) {
|
||||
hash_orig = oldbackup->hash;
|
||||
needbackup = 1;
|
||||
} else if(backup) {
|
||||
/* allow adding backup files retroactively */
|
||||
needbackup = 1;
|
||||
}
|
||||
}
|
||||
/* else if(S_ISLNK(entrymode)) */
|
||||
/* case 5,8: don't need to do anything special */
|
||||
}
|
||||
|
||||
/* we need access to the original entryname later after calls to
|
||||
* archive_entry_set_pathname(), so we need to dupe it and free() later */
|
||||
STRDUP(entryname_orig, entryname, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
if(notouch || needbackup) {
|
||||
if(filename_len + strlen(".pacnew") >= PATH_MAX) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("unable to extract %s.pacnew: path too long"), filename);
|
||||
return 1;
|
||||
}
|
||||
strcpy(filename + filename_len, ".pacnew");
|
||||
isnewfile = (llstat(filename, &lsbuf) != 0 && errno == ENOENT);
|
||||
}
|
||||
|
||||
if(needbackup) {
|
||||
char *checkfile;
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
|
||||
if(perform_extraction(handle, archive, entry, filename)) {
|
||||
errors++;
|
||||
return errors;
|
||||
}
|
||||
|
||||
if(backup) {
|
||||
FREE(backup->hash);
|
||||
backup->hash = alpm_compute_md5sum(filename);
|
||||
}
|
||||
|
||||
if(notouch) {
|
||||
alpm_event_pacnew_created_t event = {
|
||||
.type = ALPM_EVENT_PACNEW_CREATED,
|
||||
.from_noupgrade = 1,
|
||||
.oldpkg = oldpkg,
|
||||
.newpkg = newpkg,
|
||||
.file = filename
|
||||
};
|
||||
/* "remove" the .pacnew suffix */
|
||||
filename[filename_len] = '\0';
|
||||
EVENT(handle, &event);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: %s installed as %s.pacnew\n", filename, filename);
|
||||
} else if(needbackup) {
|
||||
char *hash_local = NULL, *hash_pkg = NULL;
|
||||
size_t len;
|
||||
char origfile[PATH_MAX] = "";
|
||||
|
||||
len = strlen(filename) + 10;
|
||||
MALLOC(checkfile, len,
|
||||
errors++; handle->pm_errno = ALPM_ERR_MEMORY; goto needbackup_cleanup);
|
||||
snprintf(checkfile, len, "%s.paccheck", filename);
|
||||
strncat(origfile, filename, filename_len);
|
||||
|
||||
if(perform_extraction(handle, archive, entry, checkfile, entryname_orig)) {
|
||||
errors++;
|
||||
goto needbackup_cleanup;
|
||||
}
|
||||
hash_local = alpm_compute_md5sum(origfile);
|
||||
hash_pkg = backup ? backup->hash : alpm_compute_md5sum(filename);
|
||||
|
||||
hash_local = alpm_compute_md5sum(filename);
|
||||
hash_pkg = alpm_compute_md5sum(checkfile);
|
||||
|
||||
/* update the md5 hash in newpkg's backup (it will be the new original) */
|
||||
alpm_list_t *i;
|
||||
for(i = alpm_pkg_get_backup(newpkg); i; i = i->next) {
|
||||
alpm_backup_t *backup = i->data;
|
||||
char *newhash;
|
||||
if(!backup->name || strcmp(backup->name, entryname_orig) != 0) {
|
||||
continue;
|
||||
}
|
||||
STRDUP(newhash, hash_pkg, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
FREE(backup->hash);
|
||||
backup->hash = newhash;
|
||||
}
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "checking hashes for %s\n", entryname_orig);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "checking hashes for %s\n", origfile);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "current: %s\n", hash_local);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "new: %s\n", hash_pkg);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "original: %s\n", hash_orig);
|
||||
|
||||
if(!oldpkg) {
|
||||
if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) != 0) {
|
||||
/* looks like we have a local file that has a different hash as the
|
||||
* file in the package, move it to a .pacorig */
|
||||
char *newpath;
|
||||
size_t newlen = strlen(filename) + 9;
|
||||
MALLOC(newpath, newlen,
|
||||
errors++; handle->pm_errno = ALPM_ERR_MEMORY; goto needbackup_cleanup);
|
||||
snprintf(newpath, newlen, "%s.pacorig", filename);
|
||||
|
||||
/* move the existing file to the "pacorig" */
|
||||
if(try_rename(handle, filename, newpath)) {
|
||||
errors++;
|
||||
errors++;
|
||||
} else {
|
||||
/* rename the file we extracted to the real name */
|
||||
if(try_rename(handle, checkfile, filename)) {
|
||||
errors++;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("%s saved as %s\n"), filename, newpath);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: %s saved as %s\n", filename, newpath);
|
||||
}
|
||||
}
|
||||
free(newpath);
|
||||
} else {
|
||||
/* local file is identical to pkg one, so just remove pkg one */
|
||||
unlink(checkfile);
|
||||
if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) == 0) {
|
||||
/* local and new files are the same, updating anyway to get
|
||||
* correct timestamps */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
|
||||
origfile);
|
||||
if(try_rename(handle, filename, origfile)) {
|
||||
errors++;
|
||||
}
|
||||
} else if(hash_orig) {
|
||||
/* the fun part */
|
||||
|
||||
if(hash_local && strcmp(hash_orig, hash_local) == 0) {
|
||||
/* installed file has NOT been changed by user */
|
||||
if(hash_pkg && strcmp(hash_orig, hash_pkg) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
|
||||
entryname_orig);
|
||||
|
||||
if(try_rename(handle, checkfile, filename)) {
|
||||
errors++;
|
||||
}
|
||||
} else {
|
||||
/* no sense in installing the same file twice, install
|
||||
* ONLY if the original and package hashes differ */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
|
||||
unlink(checkfile);
|
||||
}
|
||||
} else if(hash_pkg && strcmp(hash_orig, hash_pkg) == 0) {
|
||||
/* originally installed file and new file are the same - this
|
||||
* implies the case above failed - i.e. the file was changed by a
|
||||
* user */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
|
||||
unlink(checkfile);
|
||||
} else if(hash_local && hash_pkg && strcmp(hash_local, hash_pkg) == 0) {
|
||||
/* this would be magical. The above two cases failed, but the
|
||||
* user changes just so happened to make the new file exactly the
|
||||
* same as the one in the package... skip it */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: leaving existing file in place\n");
|
||||
unlink(checkfile);
|
||||
} else {
|
||||
char *newpath;
|
||||
size_t newlen = strlen(filename) + 8;
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: keeping current file and installing"
|
||||
" new one with .pacnew ending\n");
|
||||
MALLOC(newpath, newlen,
|
||||
errors++; handle->pm_errno = ALPM_ERR_MEMORY; goto needbackup_cleanup);
|
||||
snprintf(newpath, newlen, "%s.pacnew", filename);
|
||||
if(try_rename(handle, checkfile, newpath)) {
|
||||
errors++;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("%s installed as %s\n"),
|
||||
filename, newpath);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: %s installed as %s\n", filename, newpath);
|
||||
}
|
||||
free(newpath);
|
||||
} else if(hash_orig && hash_pkg && strcmp(hash_orig, hash_pkg) == 0) {
|
||||
/* original and new files are the same, leave the local version alone,
|
||||
* including any user changes */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"action: leaving existing file in place\n");
|
||||
if(isnewfile) {
|
||||
unlink(filename);
|
||||
}
|
||||
} else if(hash_orig && hash_local && strcmp(hash_orig, hash_local) == 0) {
|
||||
/* installed file has NOT been changed by user,
|
||||
* update to the new version */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "action: installing new file: %s\n",
|
||||
origfile);
|
||||
if(try_rename(handle, filename, origfile)) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
needbackup_cleanup:
|
||||
free(checkfile);
|
||||
free(hash_local);
|
||||
free(hash_pkg);
|
||||
} else {
|
||||
/* we didn't need a backup */
|
||||
if(notouch) {
|
||||
/* change the path to a .pacnew extension */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoUpgrade -- skipping\n", filename);
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("extracting %s as %s.pacnew\n"), filename, filename);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: extracting %s as %s.pacnew\n", filename, filename);
|
||||
strncat(filename, ".pacnew", PATH_MAX - strlen(filename));
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting %s\n", filename);
|
||||
/* none of the three files matched another, leave the unpacked
|
||||
* file alongside the local file */
|
||||
alpm_event_pacnew_created_t event = {
|
||||
.type = ALPM_EVENT_PACNEW_CREATED,
|
||||
.from_noupgrade = 0,
|
||||
.oldpkg = oldpkg,
|
||||
.newpkg = newpkg,
|
||||
.file = origfile
|
||||
};
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"action: keeping current file and installing"
|
||||
" new one with .pacnew ending\n");
|
||||
EVENT(handle, &event);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: %s installed as %s\n", origfile, filename);
|
||||
}
|
||||
|
||||
if(handle->trans->flags & ALPM_TRANS_FLAG_FORCE) {
|
||||
/* if FORCE was used, unlink() each file (whether it's there
|
||||
* or not) before extracting. This prevents the old "Text file busy"
|
||||
* error that crops up if forcing a glibc or pacman upgrade. */
|
||||
unlink(filename);
|
||||
}
|
||||
|
||||
if(perform_extraction(handle, archive, entry, filename, entryname_orig)) {
|
||||
/* error */
|
||||
free(entryname_orig);
|
||||
errors++;
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* calculate an hash if this is in newpkg's backup */
|
||||
alpm_list_t *i;
|
||||
for(i = alpm_pkg_get_backup(newpkg); i; i = i->next) {
|
||||
alpm_backup_t *backup = i->data;
|
||||
char *newhash;
|
||||
if(!backup->name || strcmp(backup->name, entryname_orig) != 0) {
|
||||
continue;
|
||||
}
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "appending backup entry for %s\n", entryname_orig);
|
||||
newhash = alpm_compute_md5sum(filename);
|
||||
FREE(backup->hash);
|
||||
backup->hash = newhash;
|
||||
free(hash_local);
|
||||
if(!backup) {
|
||||
free(hash_pkg);
|
||||
}
|
||||
}
|
||||
free(entryname_orig);
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -468,46 +415,45 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
alpm_pkg_t *oldpkg = NULL;
|
||||
alpm_db_t *db = handle->db_local;
|
||||
alpm_trans_t *trans = handle->trans;
|
||||
alpm_progress_t event = ALPM_PROGRESS_ADD_START;
|
||||
alpm_event_t done = ALPM_EVENT_ADD_DONE, start = ALPM_EVENT_ADD_START;
|
||||
alpm_progress_t progress = ALPM_PROGRESS_ADD_START;
|
||||
alpm_event_package_operation_t event;
|
||||
const char *log_msg = "adding";
|
||||
const char *pkgfile;
|
||||
struct archive *archive;
|
||||
struct archive_entry *entry;
|
||||
int fd, cwdfd;
|
||||
struct stat buf;
|
||||
|
||||
ASSERT(trans != NULL, return -1);
|
||||
|
||||
/* see if this is an upgrade. if so, remove the old package first */
|
||||
alpm_pkg_t *local = _alpm_db_get_pkgfromcache(db, newpkg->name);
|
||||
if(local) {
|
||||
int cmp = _alpm_pkg_compare_versions(newpkg, local);
|
||||
if((oldpkg = newpkg->oldpkg)) {
|
||||
int cmp = _alpm_pkg_compare_versions(newpkg, oldpkg);
|
||||
if(cmp < 0) {
|
||||
log_msg = "downgrading";
|
||||
event = ALPM_PROGRESS_DOWNGRADE_START;
|
||||
start = ALPM_EVENT_DOWNGRADE_START;
|
||||
done = ALPM_EVENT_DOWNGRADE_DONE;
|
||||
progress = ALPM_PROGRESS_DOWNGRADE_START;
|
||||
event.operation = ALPM_PACKAGE_DOWNGRADE;
|
||||
} else if(cmp == 0) {
|
||||
log_msg = "reinstalling";
|
||||
event = ALPM_PROGRESS_REINSTALL_START;
|
||||
start = ALPM_EVENT_REINSTALL_START;
|
||||
done = ALPM_EVENT_REINSTALL_DONE;
|
||||
progress = ALPM_PROGRESS_REINSTALL_START;
|
||||
event.operation = ALPM_PACKAGE_REINSTALL;
|
||||
} else {
|
||||
log_msg = "upgrading";
|
||||
event = ALPM_PROGRESS_UPGRADE_START;
|
||||
start = ALPM_EVENT_UPGRADE_START;
|
||||
done = ALPM_EVENT_UPGRADE_DONE;
|
||||
progress = ALPM_PROGRESS_UPGRADE_START;
|
||||
event.operation = ALPM_PACKAGE_UPGRADE;
|
||||
}
|
||||
is_upgrade = 1;
|
||||
|
||||
/* we'll need to save some record for backup checks later */
|
||||
if(_alpm_pkg_dup(local, &oldpkg) == -1) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* copy over the install reason */
|
||||
newpkg->reason = alpm_pkg_get_reason(local);
|
||||
newpkg->reason = alpm_pkg_get_reason(oldpkg);
|
||||
} else {
|
||||
event.operation = ALPM_PACKAGE_INSTALL;
|
||||
}
|
||||
|
||||
EVENT(handle, start, newpkg, local);
|
||||
event.type = ALPM_EVENT_PACKAGE_OPERATION_START;
|
||||
event.oldpkg = oldpkg;
|
||||
event.newpkg = newpkg;
|
||||
EVENT(handle, &event);
|
||||
|
||||
pkgfile = newpkg->origin_data.file;
|
||||
|
||||
@@ -538,8 +484,8 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare directory for database entries so permission are correct after
|
||||
changelog/install script installation (FS#12263) */
|
||||
/* prepare directory for database entries so permissions are correct after
|
||||
changelog/install script installation */
|
||||
if(_alpm_local_db_prepare(db, newpkg)) {
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: could not create database entry %s-%s\n",
|
||||
@@ -549,39 +495,47 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
|
||||
struct archive *archive;
|
||||
struct archive_entry *entry;
|
||||
struct stat buf;
|
||||
int fd, cwdfd;
|
||||
fd = _alpm_open_archive(db->handle, pkgfile, &buf,
|
||||
&archive, ALPM_ERR_PKG_OPEN);
|
||||
if(fd < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* save the cwd so we can restore it later */
|
||||
OPEN(cwdfd, ".", O_RDONLY | O_CLOEXEC);
|
||||
if(cwdfd < 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
|
||||
}
|
||||
|
||||
/* libarchive requires this for extracting hard links */
|
||||
if(chdir(handle->root) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
|
||||
handle->root, strerror(errno));
|
||||
_alpm_archive_read_free(archive);
|
||||
if(cwdfd >= 0) {
|
||||
close(cwdfd);
|
||||
}
|
||||
close(fd);
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(trans->flags & ALPM_TRANS_FLAG_DBONLY) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting db files\n");
|
||||
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
||||
const char *entryname = archive_entry_pathname(entry);
|
||||
if(entryname[0] == '.') {
|
||||
errors += extract_db_file(handle, archive, entry, newpkg, entryname);
|
||||
} else {
|
||||
archive_read_data_skip(archive);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "extracting files\n");
|
||||
|
||||
fd = _alpm_open_archive(db->handle, pkgfile, &buf,
|
||||
&archive, ALPM_ERR_PKG_OPEN);
|
||||
if(fd < 0) {
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* save the cwd so we can restore it later */
|
||||
OPEN(cwdfd, ".", O_RDONLY);
|
||||
if(cwdfd < 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
|
||||
}
|
||||
|
||||
/* libarchive requires this for extracting hard links */
|
||||
if(chdir(handle->root) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
|
||||
handle->root, strerror(errno));
|
||||
_alpm_archive_read_free(archive);
|
||||
CLOSE(fd);
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* call PROGRESS once with 0 percent, as we sort-of skip that here */
|
||||
PROGRESS(handle, event, newpkg->name, 0, pkg_count, pkg_current);
|
||||
PROGRESS(handle, progress, newpkg->name, 0, pkg_count, pkg_current);
|
||||
|
||||
for(i = 0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; i++) {
|
||||
int percent;
|
||||
@@ -599,38 +553,39 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
percent = 0;
|
||||
}
|
||||
|
||||
PROGRESS(handle, event, newpkg->name, percent, pkg_count, pkg_current);
|
||||
PROGRESS(handle, progress, newpkg->name, percent, pkg_count, pkg_current);
|
||||
|
||||
/* extract the next file from the archive */
|
||||
errors += extract_single_file(handle, archive, entry, newpkg, oldpkg);
|
||||
}
|
||||
_alpm_archive_read_free(archive);
|
||||
CLOSE(fd);
|
||||
}
|
||||
|
||||
/* restore the old cwd if we have it */
|
||||
if(cwdfd >= 0) {
|
||||
if(fchdir(cwdfd) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("could not restore working directory (%s)\n"), strerror(errno));
|
||||
}
|
||||
CLOSE(cwdfd);
|
||||
_alpm_archive_read_free(archive);
|
||||
close(fd);
|
||||
|
||||
/* restore the old cwd if we have it */
|
||||
if(cwdfd >= 0) {
|
||||
if(fchdir(cwdfd) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("could not restore working directory (%s)\n"), strerror(errno));
|
||||
}
|
||||
close(cwdfd);
|
||||
}
|
||||
|
||||
if(errors) {
|
||||
ret = -1;
|
||||
if(is_upgrade) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
|
||||
newpkg->name);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: problem occurred while upgrading %s\n",
|
||||
newpkg->name);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"),
|
||||
newpkg->name);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: problem occurred while installing %s\n",
|
||||
newpkg->name);
|
||||
}
|
||||
if(errors) {
|
||||
ret = -1;
|
||||
if(is_upgrade) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while upgrading %s\n"),
|
||||
newpkg->name);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: problem occurred while upgrading %s\n",
|
||||
newpkg->name);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("problem occurred while installing %s\n"),
|
||||
newpkg->name);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"error: problem occurred while installing %s\n",
|
||||
newpkg->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,9 +611,31 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
newpkg->name);
|
||||
}
|
||||
|
||||
PROGRESS(handle, event, newpkg->name, 100, pkg_count, pkg_current);
|
||||
PROGRESS(handle, progress, newpkg->name, 100, pkg_count, pkg_current);
|
||||
|
||||
/* run the post-install script if it exists */
|
||||
switch(event.operation) {
|
||||
case ALPM_PACKAGE_INSTALL:
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX, "installed %s (%s)\n",
|
||||
newpkg->name, newpkg->version);
|
||||
break;
|
||||
case ALPM_PACKAGE_DOWNGRADE:
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX, "downgraded %s (%s -> %s)\n",
|
||||
newpkg->name, oldpkg->version, newpkg->version);
|
||||
break;
|
||||
case ALPM_PACKAGE_REINSTALL:
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX, "reinstalled %s (%s)\n",
|
||||
newpkg->name, newpkg->version);
|
||||
break;
|
||||
case ALPM_PACKAGE_UPGRADE:
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX, "upgraded %s (%s -> %s)\n",
|
||||
newpkg->name, oldpkg->version, newpkg->version);
|
||||
break;
|
||||
default:
|
||||
/* we should never reach here */
|
||||
break;
|
||||
}
|
||||
|
||||
/* run the post-install script if it exists */
|
||||
if(alpm_pkg_has_scriptlet(newpkg)
|
||||
&& !(trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
|
||||
char *scriptlet = _alpm_local_db_pkgpath(db, newpkg, "install");
|
||||
@@ -669,10 +646,10 @@ static int commit_single_pkg(alpm_handle_t *handle, alpm_pkg_t *newpkg,
|
||||
free(scriptlet);
|
||||
}
|
||||
|
||||
EVENT(handle, done, newpkg, oldpkg);
|
||||
event.type = ALPM_EVENT_PACKAGE_OPERATION_DONE;
|
||||
EVENT(handle, &event);
|
||||
|
||||
cleanup:
|
||||
_alpm_pkg_free(oldpkg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -718,4 +695,4 @@ int _alpm_upgrade_packages(alpm_handle_t *handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* add.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_ADD_H
|
||||
#define _ALPM_ADD_H
|
||||
#ifndef ALPM_ADD_H
|
||||
#define ALPM_ADD_H
|
||||
|
||||
#include "db.h"
|
||||
#include "alpm_list.h"
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
int _alpm_upgrade_packages(alpm_handle_t *handle);
|
||||
|
||||
#endif /* _ALPM_ADD_H */
|
||||
#endif /* ALPM_ADD_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alpm.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
||||
@@ -50,12 +50,12 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
|
||||
{
|
||||
alpm_errno_t myerr;
|
||||
const char *lf = "db.lck";
|
||||
char *hookdir;
|
||||
size_t lockfilelen;
|
||||
alpm_handle_t *myhandle = _alpm_handle_new();
|
||||
|
||||
if(myhandle == NULL) {
|
||||
myerr = ALPM_ERR_MEMORY;
|
||||
goto cleanup;
|
||||
goto nomem;
|
||||
}
|
||||
if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) {
|
||||
goto cleanup;
|
||||
@@ -64,8 +64,18 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* to contatenate myhandle->root (ends with a slash) with SYSHOOKDIR (starts
|
||||
* with a slash) correctly, we skip SYSHOOKDIR[0]; the regular +1 therefore
|
||||
* disappears from the allocation */
|
||||
MALLOC(hookdir, strlen(myhandle->root) + strlen(SYSHOOKDIR), goto nomem);
|
||||
sprintf(hookdir, "%s%s", myhandle->root, SYSHOOKDIR + 1);
|
||||
myhandle->hookdirs = alpm_list_add(NULL, hookdir);
|
||||
|
||||
/* set default database extension */
|
||||
STRDUP(myhandle->dbext, ".db", goto nomem);
|
||||
|
||||
lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1;
|
||||
myhandle->lockfile = calloc(lockfilelen, sizeof(char));
|
||||
MALLOC(myhandle->lockfile, lockfilelen, goto nomem);
|
||||
snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf);
|
||||
|
||||
if(_alpm_db_register_local(myhandle) == NULL) {
|
||||
@@ -79,9 +89,11 @@ alpm_handle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath,
|
||||
|
||||
return myhandle;
|
||||
|
||||
nomem:
|
||||
myerr = ALPM_ERR_MEMORY;
|
||||
cleanup:
|
||||
_alpm_handle_free(myhandle);
|
||||
if(err && myerr) {
|
||||
if(err) {
|
||||
*err = myerr;
|
||||
}
|
||||
return NULL;
|
||||
@@ -155,4 +167,4 @@ enum alpm_caps SYMEXPORT alpm_capabilities(void)
|
||||
| 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alpm.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
||||
@@ -20,8 +20,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_H
|
||||
#define _ALPM_H
|
||||
#ifndef ALPM_H
|
||||
#define ALPM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -41,6 +41,94 @@ extern "C" {
|
||||
* Arch Linux Package Management library
|
||||
*/
|
||||
|
||||
/*
|
||||
* Opaque Structures
|
||||
*/
|
||||
typedef struct __alpm_handle_t alpm_handle_t;
|
||||
typedef struct __alpm_db_t alpm_db_t;
|
||||
typedef struct __alpm_pkg_t alpm_pkg_t;
|
||||
typedef struct __alpm_trans_t alpm_trans_t;
|
||||
|
||||
/** @addtogroup alpm_api_errors Error Codes
|
||||
* @{
|
||||
*/
|
||||
typedef enum _alpm_errno_t {
|
||||
ALPM_ERR_MEMORY = 1,
|
||||
ALPM_ERR_SYSTEM,
|
||||
ALPM_ERR_BADPERMS,
|
||||
ALPM_ERR_NOT_A_FILE,
|
||||
ALPM_ERR_NOT_A_DIR,
|
||||
ALPM_ERR_WRONG_ARGS,
|
||||
ALPM_ERR_DISK_SPACE,
|
||||
/* Interface */
|
||||
ALPM_ERR_HANDLE_NULL,
|
||||
ALPM_ERR_HANDLE_NOT_NULL,
|
||||
ALPM_ERR_HANDLE_LOCK,
|
||||
/* Databases */
|
||||
ALPM_ERR_DB_OPEN,
|
||||
ALPM_ERR_DB_CREATE,
|
||||
ALPM_ERR_DB_NULL,
|
||||
ALPM_ERR_DB_NOT_NULL,
|
||||
ALPM_ERR_DB_NOT_FOUND,
|
||||
ALPM_ERR_DB_INVALID,
|
||||
ALPM_ERR_DB_INVALID_SIG,
|
||||
ALPM_ERR_DB_VERSION,
|
||||
ALPM_ERR_DB_WRITE,
|
||||
ALPM_ERR_DB_REMOVE,
|
||||
/* Servers */
|
||||
ALPM_ERR_SERVER_BAD_URL,
|
||||
ALPM_ERR_SERVER_NONE,
|
||||
/* Transactions */
|
||||
ALPM_ERR_TRANS_NOT_NULL,
|
||||
ALPM_ERR_TRANS_NULL,
|
||||
ALPM_ERR_TRANS_DUP_TARGET,
|
||||
ALPM_ERR_TRANS_NOT_INITIALIZED,
|
||||
ALPM_ERR_TRANS_NOT_PREPARED,
|
||||
ALPM_ERR_TRANS_ABORT,
|
||||
ALPM_ERR_TRANS_TYPE,
|
||||
ALPM_ERR_TRANS_NOT_LOCKED,
|
||||
ALPM_ERR_TRANS_HOOK_FAILED,
|
||||
/* Packages */
|
||||
ALPM_ERR_PKG_NOT_FOUND,
|
||||
ALPM_ERR_PKG_IGNORED,
|
||||
ALPM_ERR_PKG_INVALID,
|
||||
ALPM_ERR_PKG_INVALID_CHECKSUM,
|
||||
ALPM_ERR_PKG_INVALID_SIG,
|
||||
ALPM_ERR_PKG_MISSING_SIG,
|
||||
ALPM_ERR_PKG_OPEN,
|
||||
ALPM_ERR_PKG_CANT_REMOVE,
|
||||
ALPM_ERR_PKG_INVALID_NAME,
|
||||
ALPM_ERR_PKG_INVALID_ARCH,
|
||||
ALPM_ERR_PKG_REPO_NOT_FOUND,
|
||||
/* Signatures */
|
||||
ALPM_ERR_SIG_MISSING,
|
||||
ALPM_ERR_SIG_INVALID,
|
||||
/* Deltas */
|
||||
ALPM_ERR_DLT_INVALID,
|
||||
ALPM_ERR_DLT_PATCHFAILED,
|
||||
/* Dependencies */
|
||||
ALPM_ERR_UNSATISFIED_DEPS,
|
||||
ALPM_ERR_CONFLICTING_DEPS,
|
||||
ALPM_ERR_FILE_CONFLICTS,
|
||||
/* Misc */
|
||||
ALPM_ERR_RETRIEVE,
|
||||
ALPM_ERR_INVALID_REGEX,
|
||||
/* External library errors */
|
||||
ALPM_ERR_LIBARCHIVE,
|
||||
ALPM_ERR_LIBCURL,
|
||||
ALPM_ERR_EXTERNAL_DOWNLOAD,
|
||||
ALPM_ERR_GPGME
|
||||
} alpm_errno_t;
|
||||
|
||||
/** Returns the current error code from the handle. */
|
||||
alpm_errno_t alpm_errno(alpm_handle_t *handle);
|
||||
|
||||
/** Returns the string corresponding to an error number. */
|
||||
const char *alpm_strerror(alpm_errno_t err);
|
||||
|
||||
/* End of alpm_api_errors */
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup alpm_api Public API
|
||||
* The libalpm Public API
|
||||
* @{
|
||||
@@ -79,17 +167,17 @@ typedef enum _alpm_pkgvalidation_t {
|
||||
|
||||
/** Types of version constraints in dependency specs. */
|
||||
typedef enum _alpm_depmod_t {
|
||||
/** No version constraint */
|
||||
/** No version constraint */
|
||||
ALPM_DEP_MOD_ANY = 1,
|
||||
/** Test version equality (package=x.y.z) */
|
||||
/** Test version equality (package=x.y.z) */
|
||||
ALPM_DEP_MOD_EQ,
|
||||
/** Test for at least a version (package>=x.y.z) */
|
||||
/** Test for at least a version (package>=x.y.z) */
|
||||
ALPM_DEP_MOD_GE,
|
||||
/** Test for at most a version (package<=x.y.z) */
|
||||
/** Test for at most a version (package<=x.y.z) */
|
||||
ALPM_DEP_MOD_LE,
|
||||
/** Test for greater than some version (package>x.y.z) */
|
||||
/** Test for greater than some version (package>x.y.z) */
|
||||
ALPM_DEP_MOD_GT,
|
||||
/** Test for less than some version (package<x.y.z) */
|
||||
/** Test for less than some version (package<x.y.z) */
|
||||
ALPM_DEP_MOD_LT
|
||||
} alpm_depmod_t;
|
||||
|
||||
@@ -115,10 +203,7 @@ typedef enum _alpm_siglevel_t {
|
||||
ALPM_SIG_DATABASE_MARGINAL_OK = (1 << 12),
|
||||
ALPM_SIG_DATABASE_UNKNOWN_OK = (1 << 13),
|
||||
|
||||
ALPM_SIG_PACKAGE_SET = (1 << 27),
|
||||
ALPM_SIG_PACKAGE_TRUST_SET = (1 << 28),
|
||||
|
||||
ALPM_SIG_USE_DEFAULT = (1 << 31)
|
||||
ALPM_SIG_USE_DEFAULT = (1 << 30)
|
||||
} alpm_siglevel_t;
|
||||
|
||||
/** PGP signature verification status return codes */
|
||||
@@ -143,11 +228,6 @@ typedef enum _alpm_sigvalidity_t {
|
||||
* Structures
|
||||
*/
|
||||
|
||||
typedef struct __alpm_handle_t alpm_handle_t;
|
||||
typedef struct __alpm_db_t alpm_db_t;
|
||||
typedef struct __alpm_pkg_t alpm_pkg_t;
|
||||
typedef struct __alpm_trans_t alpm_trans_t;
|
||||
|
||||
/** Dependency */
|
||||
typedef struct _alpm_depend_t {
|
||||
char *name;
|
||||
@@ -217,7 +297,6 @@ typedef struct _alpm_file_t {
|
||||
typedef struct _alpm_filelist_t {
|
||||
size_t count;
|
||||
alpm_file_t *files;
|
||||
char **resolved_path;
|
||||
} alpm_filelist_t;
|
||||
|
||||
/** Local package or package file backup entry */
|
||||
@@ -251,13 +330,23 @@ typedef struct _alpm_sigresult_t {
|
||||
|
||||
/**
|
||||
* Signature list. Contains the number of signatures found and a pointer to an
|
||||
* array of results. The array is of size count.
|
||||
* array of results. The array is of size count.
|
||||
*/
|
||||
typedef struct _alpm_siglist_t {
|
||||
size_t count;
|
||||
alpm_sigresult_t *results;
|
||||
} alpm_siglist_t;
|
||||
|
||||
|
||||
/*
|
||||
* Hooks
|
||||
*/
|
||||
|
||||
typedef enum _alpm_hook_when_t {
|
||||
ALPM_HOOK_PRE_TRANSACTION = 1,
|
||||
ALPM_HOOK_POST_TRANSACTION
|
||||
} alpm_hook_when_t;
|
||||
|
||||
/*
|
||||
* Logging facilities
|
||||
*/
|
||||
@@ -276,10 +365,9 @@ int alpm_logaction(alpm_handle_t *handle, const char *prefix,
|
||||
const char *fmt, ...) __attribute__((format(printf, 3, 4)));
|
||||
|
||||
/**
|
||||
* Events.
|
||||
* NULL parameters are passed to in all events unless specified otherwise.
|
||||
* Type of events.
|
||||
*/
|
||||
typedef enum _alpm_event_t {
|
||||
typedef enum _alpm_event_type_t {
|
||||
/** Dependencies will be computed for a package. */
|
||||
ALPM_EVENT_CHECKDEPS_START = 1,
|
||||
/** Dependencies were computed for a package. */
|
||||
@@ -296,49 +384,16 @@ typedef enum _alpm_event_t {
|
||||
ALPM_EVENT_INTERCONFLICTS_START,
|
||||
/** Inter-conflicts were checked for target package. */
|
||||
ALPM_EVENT_INTERCONFLICTS_DONE,
|
||||
/** Package will be installed.
|
||||
* A pointer to the target package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_ADD_START,
|
||||
/** Package was installed.
|
||||
* A pointer to the new package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_ADD_DONE,
|
||||
/** Package will be removed.
|
||||
* A pointer to the target package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_REMOVE_START,
|
||||
/** Package was removed.
|
||||
* A pointer to the removed package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_REMOVE_DONE,
|
||||
/** Package will be upgraded.
|
||||
* A pointer to the upgraded package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_UPGRADE_START,
|
||||
/** Package was upgraded.
|
||||
* A pointer to the new package, and a pointer to the old package is passed
|
||||
* to the callback, respectively.
|
||||
*/
|
||||
ALPM_EVENT_UPGRADE_DONE,
|
||||
/** Package will be downgraded.
|
||||
* A pointer to the downgraded package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_DOWNGRADE_START,
|
||||
/** Package was downgraded.
|
||||
* A pointer to the new package, and a pointer to the old package is passed
|
||||
* to the callback, respectively.
|
||||
*/
|
||||
ALPM_EVENT_DOWNGRADE_DONE,
|
||||
/** Package will be reinstalled.
|
||||
* A pointer to the reinstalled package is passed to the callback.
|
||||
*/
|
||||
ALPM_EVENT_REINSTALL_START,
|
||||
/** Package was reinstalled.
|
||||
* A pointer to the new package, and a pointer to the old package is passed
|
||||
* to the callback, respectively.
|
||||
*/
|
||||
ALPM_EVENT_REINSTALL_DONE,
|
||||
/** Processing the package transaction is starting. */
|
||||
ALPM_EVENT_TRANSACTION_START,
|
||||
/** Processing the package transaction is finished. */
|
||||
ALPM_EVENT_TRANSACTION_DONE,
|
||||
/** Package will be installed/upgraded/downgraded/re-installed/removed; See
|
||||
* alpm_event_package_operation_t for arguments. */
|
||||
ALPM_EVENT_PACKAGE_OPERATION_START,
|
||||
/** Package was installed/upgraded/downgraded/re-installed/removed; See
|
||||
* alpm_event_package_operation_t for arguments. */
|
||||
ALPM_EVENT_PACKAGE_OPERATION_DONE,
|
||||
/** Target package's integrity will be checked. */
|
||||
ALPM_EVENT_INTEGRITY_START,
|
||||
/** Target package's integrity was checked. */
|
||||
@@ -355,31 +410,40 @@ typedef enum _alpm_event_t {
|
||||
ALPM_EVENT_DELTA_PATCHES_START,
|
||||
/** Deltas were applied to packages. */
|
||||
ALPM_EVENT_DELTA_PATCHES_DONE,
|
||||
/** Delta patch will be applied to target package.
|
||||
* The filename of the package and the filename of the patch is passed to the
|
||||
* callback.
|
||||
*/
|
||||
/** Delta patch will be applied to target package; See
|
||||
* alpm_event_delta_patch_t for arguments.. */
|
||||
ALPM_EVENT_DELTA_PATCH_START,
|
||||
/** Delta patch was applied to target package. */
|
||||
ALPM_EVENT_DELTA_PATCH_DONE,
|
||||
/** Delta patch failed to apply to target package. */
|
||||
ALPM_EVENT_DELTA_PATCH_FAILED,
|
||||
/** Scriptlet has printed information.
|
||||
* A line of text is passed to the callback.
|
||||
*/
|
||||
/** Scriptlet has printed information; See alpm_event_scriptlet_info_t for
|
||||
* arguments. */
|
||||
ALPM_EVENT_SCRIPTLET_INFO,
|
||||
/** Files will be downloaded from a repository.
|
||||
* The repository's tree name is passed to the callback.
|
||||
*/
|
||||
/** Files will be downloaded from a repository. */
|
||||
ALPM_EVENT_RETRIEVE_START,
|
||||
/** Disk space usage will be computed for a package */
|
||||
/** Files were downloaded from a repository. */
|
||||
ALPM_EVENT_RETRIEVE_DONE,
|
||||
/** Not all files were successfully downloaded from a repository. */
|
||||
ALPM_EVENT_RETRIEVE_FAILED,
|
||||
/** A file will be downloaded from a repository; See alpm_event_pkgdownload_t
|
||||
* for arguments */
|
||||
ALPM_EVENT_PKGDOWNLOAD_START,
|
||||
/** A file was downloaded from a repository; See alpm_event_pkgdownload_t
|
||||
* for arguments */
|
||||
ALPM_EVENT_PKGDOWNLOAD_DONE,
|
||||
/** A file failed to be downloaded from a repository; See
|
||||
* alpm_event_pkgdownload_t for arguments */
|
||||
ALPM_EVENT_PKGDOWNLOAD_FAILED,
|
||||
/** Disk space usage will be computed for a package. */
|
||||
ALPM_EVENT_DISKSPACE_START,
|
||||
/** Disk space usage was computed for a package */
|
||||
/** Disk space usage was computed for a package. */
|
||||
ALPM_EVENT_DISKSPACE_DONE,
|
||||
/** An optdepend for another package is being removed
|
||||
* The requiring package and its dependency are passed to the callback */
|
||||
ALPM_EVENT_OPTDEP_REQUIRED,
|
||||
/** A configured repository database is missing */
|
||||
/** An optdepend for another package is being removed; See
|
||||
* alpm_event_optdep_removal_t for arguments. */
|
||||
ALPM_EVENT_OPTDEP_REMOVAL,
|
||||
/** A configured repository database is missing; See
|
||||
* alpm_event_database_missing_t for arguments. */
|
||||
ALPM_EVENT_DATABASE_MISSING,
|
||||
/** Checking keys used to create signatures are in keyring. */
|
||||
ALPM_EVENT_KEYRING_START,
|
||||
@@ -388,31 +452,267 @@ typedef enum _alpm_event_t {
|
||||
/** Downloading missing keys into keyring. */
|
||||
ALPM_EVENT_KEY_DOWNLOAD_START,
|
||||
/** Key downloading is finished. */
|
||||
ALPM_EVENT_KEY_DOWNLOAD_DONE
|
||||
ALPM_EVENT_KEY_DOWNLOAD_DONE,
|
||||
/** A .pacnew file was created; See alpm_event_pacnew_created_t for arguments. */
|
||||
ALPM_EVENT_PACNEW_CREATED,
|
||||
/** A .pacsave file was created; See alpm_event_pacsave_created_t for
|
||||
* arguments */
|
||||
ALPM_EVENT_PACSAVE_CREATED,
|
||||
/** Processing hooks will be started. */
|
||||
ALPM_EVENT_HOOK_START,
|
||||
/** Processing hooks is finished. */
|
||||
ALPM_EVENT_HOOK_DONE,
|
||||
/** A hook is starting */
|
||||
ALPM_EVENT_HOOK_RUN_START,
|
||||
/** A hook has finished running */
|
||||
ALPM_EVENT_HOOK_RUN_DONE
|
||||
} alpm_event_type_t;
|
||||
|
||||
typedef struct _alpm_event_any_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
} alpm_event_any_t;
|
||||
|
||||
typedef enum _alpm_package_operation_t {
|
||||
/** Package (to be) installed. (No oldpkg) */
|
||||
ALPM_PACKAGE_INSTALL = 1,
|
||||
/** Package (to be) upgraded */
|
||||
ALPM_PACKAGE_UPGRADE,
|
||||
/** Package (to be) re-installed. */
|
||||
ALPM_PACKAGE_REINSTALL,
|
||||
/** Package (to be) downgraded. */
|
||||
ALPM_PACKAGE_DOWNGRADE,
|
||||
/** Package (to be) removed. (No newpkg) */
|
||||
ALPM_PACKAGE_REMOVE
|
||||
} alpm_package_operation_t;
|
||||
|
||||
typedef struct _alpm_event_package_operation_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Type of operation. */
|
||||
alpm_package_operation_t operation;
|
||||
/** Old package. */
|
||||
alpm_pkg_t *oldpkg;
|
||||
/** New package. */
|
||||
alpm_pkg_t *newpkg;
|
||||
} alpm_event_package_operation_t;
|
||||
|
||||
typedef struct _alpm_event_optdep_removal_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Package with the optdep. */
|
||||
alpm_pkg_t *pkg;
|
||||
/** Optdep being removed. */
|
||||
alpm_depend_t *optdep;
|
||||
} alpm_event_optdep_removal_t;
|
||||
|
||||
typedef struct _alpm_event_delta_patch_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Delta info */
|
||||
alpm_delta_t *delta;
|
||||
} alpm_event_delta_patch_t;
|
||||
|
||||
typedef struct _alpm_event_scriptlet_info_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Line of scriptlet output. */
|
||||
const char *line;
|
||||
} alpm_event_scriptlet_info_t;
|
||||
|
||||
typedef struct _alpm_event_database_missing_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Name of the database. */
|
||||
const char *dbname;
|
||||
} alpm_event_database_missing_t;
|
||||
|
||||
typedef struct _alpm_event_pkgdownload_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Name of the file */
|
||||
const char *file;
|
||||
} alpm_event_pkgdownload_t;
|
||||
|
||||
typedef struct _alpm_event_pacnew_created_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Whether the creation was result of a NoUpgrade or not */
|
||||
int from_noupgrade;
|
||||
/** Old package. */
|
||||
alpm_pkg_t *oldpkg;
|
||||
/** New Package. */
|
||||
alpm_pkg_t *newpkg;
|
||||
/** Filename of the file without the .pacnew suffix */
|
||||
const char *file;
|
||||
} alpm_event_pacnew_created_t;
|
||||
|
||||
typedef struct _alpm_event_pacsave_created_t {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
/** Old package. */
|
||||
alpm_pkg_t *oldpkg;
|
||||
/** Filename of the file without the .pacsave suffix. */
|
||||
const char *file;
|
||||
} alpm_event_pacsave_created_t;
|
||||
|
||||
typedef struct _alpm_event_hook_t {
|
||||
/** Type of event.*/
|
||||
alpm_event_type_t type;
|
||||
/** Type of hooks. */
|
||||
alpm_hook_when_t when;
|
||||
} alpm_event_hook_t;
|
||||
|
||||
typedef struct _alpm_event_hook_run_t {
|
||||
/** Type of event.*/
|
||||
alpm_event_type_t type;
|
||||
/** Name of hook */
|
||||
const char *name;
|
||||
/** Description of hook to be outputted */
|
||||
const char *desc;
|
||||
/** position of hook being run */
|
||||
size_t position;
|
||||
/** total hooks being run */
|
||||
size_t total;
|
||||
} alpm_event_hook_run_t;
|
||||
|
||||
/** Events.
|
||||
* This is an union passed to the callback, that allows the frontend to know
|
||||
* which type of event was triggered (via type). It is then possible to
|
||||
* typecast the pointer to the right structure, or use the union field, in order
|
||||
* to access event-specific data. */
|
||||
typedef union _alpm_event_t {
|
||||
alpm_event_type_t type;
|
||||
alpm_event_any_t any;
|
||||
alpm_event_package_operation_t package_operation;
|
||||
alpm_event_optdep_removal_t optdep_removal;
|
||||
alpm_event_delta_patch_t delta_patch;
|
||||
alpm_event_scriptlet_info_t scriptlet_info;
|
||||
alpm_event_database_missing_t database_missing;
|
||||
alpm_event_pkgdownload_t pkgdownload;
|
||||
alpm_event_pacnew_created_t pacnew_created;
|
||||
alpm_event_pacsave_created_t pacsave_created;
|
||||
alpm_event_hook_t hook;
|
||||
alpm_event_hook_run_t hook_run;
|
||||
} alpm_event_t;
|
||||
|
||||
/** Event callback */
|
||||
typedef void (*alpm_cb_event)(alpm_event_t, void *, void *);
|
||||
/** Event callback. */
|
||||
typedef void (*alpm_cb_event)(alpm_event_t *);
|
||||
|
||||
/**
|
||||
* Questions.
|
||||
* Type of questions.
|
||||
* Unlike the events or progress enumerations, this enum has bitmask values
|
||||
* so a frontend can use a bitmask map to supply preselected answers to the
|
||||
* different types of questions.
|
||||
*/
|
||||
typedef enum _alpm_question_t {
|
||||
ALPM_QUESTION_INSTALL_IGNOREPKG = 1,
|
||||
typedef enum _alpm_question_type_t {
|
||||
ALPM_QUESTION_INSTALL_IGNOREPKG = (1 << 0),
|
||||
ALPM_QUESTION_REPLACE_PKG = (1 << 1),
|
||||
ALPM_QUESTION_CONFLICT_PKG = (1 << 2),
|
||||
ALPM_QUESTION_CORRUPTED_PKG = (1 << 3),
|
||||
ALPM_QUESTION_LOCAL_NEWER = (1 << 4),
|
||||
ALPM_QUESTION_REMOVE_PKGS = (1 << 5),
|
||||
ALPM_QUESTION_SELECT_PROVIDER = (1 << 6),
|
||||
ALPM_QUESTION_IMPORT_KEY = (1 << 7)
|
||||
ALPM_QUESTION_REMOVE_PKGS = (1 << 4),
|
||||
ALPM_QUESTION_SELECT_PROVIDER = (1 << 5),
|
||||
ALPM_QUESTION_IMPORT_KEY = (1 << 6)
|
||||
} alpm_question_type_t;
|
||||
|
||||
typedef struct _alpm_question_any_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer. */
|
||||
int answer;
|
||||
} alpm_question_any_t;
|
||||
|
||||
typedef struct _alpm_question_install_ignorepkg_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to install pkg anyway. */
|
||||
int install;
|
||||
/* Package in IgnorePkg/IgnoreGroup. */
|
||||
alpm_pkg_t *pkg;
|
||||
} alpm_question_install_ignorepkg_t;
|
||||
|
||||
typedef struct _alpm_question_replace_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to replace oldpkg with newpkg. */
|
||||
int replace;
|
||||
/* Package to be replaced. */
|
||||
alpm_pkg_t *oldpkg;
|
||||
/* Package to replace with. */
|
||||
alpm_pkg_t *newpkg;
|
||||
/* DB of newpkg */
|
||||
alpm_db_t *newdb;
|
||||
} alpm_question_replace_t;
|
||||
|
||||
typedef struct _alpm_question_conflict_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to remove conflict->package2. */
|
||||
int remove;
|
||||
/** Conflict info. */
|
||||
alpm_conflict_t *conflict;
|
||||
} alpm_question_conflict_t;
|
||||
|
||||
typedef struct _alpm_question_corrupted_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to remove filepath. */
|
||||
int remove;
|
||||
/** Filename to remove */
|
||||
const char *filepath;
|
||||
/** Error code indicating the reason for package invalidity */
|
||||
alpm_errno_t reason;
|
||||
} alpm_question_corrupted_t;
|
||||
|
||||
typedef struct _alpm_question_remove_pkgs_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to skip packages. */
|
||||
int skip;
|
||||
/** List of alpm_pkg_t* with unresolved dependencies. */
|
||||
alpm_list_t *packages;
|
||||
} alpm_question_remove_pkgs_t;
|
||||
|
||||
typedef struct _alpm_question_select_provider_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: which provider to use (index from providers). */
|
||||
int use_index;
|
||||
/** List of alpm_pkg_t* as possible providers. */
|
||||
alpm_list_t *providers;
|
||||
/** What providers provide for. */
|
||||
alpm_depend_t *depend;
|
||||
} alpm_question_select_provider_t;
|
||||
|
||||
typedef struct _alpm_question_import_key_t {
|
||||
/** Type of question. */
|
||||
alpm_question_type_t type;
|
||||
/** Answer: whether or not to import key. */
|
||||
int import;
|
||||
/** The key to import. */
|
||||
alpm_pgpkey_t *key;
|
||||
} alpm_question_import_key_t;
|
||||
|
||||
/**
|
||||
* Questions.
|
||||
* This is an union passed to the callback, that allows the frontend to know
|
||||
* which type of question was triggered (via type). It is then possible to
|
||||
* typecast the pointer to the right structure, or use the union field, in order
|
||||
* to access question-specific data. */
|
||||
typedef union _alpm_question_t {
|
||||
alpm_question_type_t type;
|
||||
alpm_question_any_t any;
|
||||
alpm_question_install_ignorepkg_t install_ignorepkg;
|
||||
alpm_question_replace_t replace;
|
||||
alpm_question_conflict_t conflict;
|
||||
alpm_question_corrupted_t corrupted;
|
||||
alpm_question_remove_pkgs_t remove_pkgs;
|
||||
alpm_question_select_provider_t select_provider;
|
||||
alpm_question_import_key_t import_key;
|
||||
} alpm_question_t;
|
||||
|
||||
/** Question callback */
|
||||
typedef void (*alpm_cb_question)(alpm_question_t, void *, void *, void *, int *);
|
||||
typedef void (*alpm_cb_question)(alpm_question_t *);
|
||||
|
||||
/** Progress */
|
||||
typedef enum _alpm_progress_t {
|
||||
@@ -520,6 +820,15 @@ int alpm_option_add_cachedir(alpm_handle_t *handle, const char *cachedir);
|
||||
int alpm_option_remove_cachedir(alpm_handle_t *handle, const char *cachedir);
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors to the list of package hook directories.
|
||||
* @{
|
||||
*/
|
||||
alpm_list_t *alpm_option_get_hookdirs(alpm_handle_t *handle);
|
||||
int alpm_option_set_hookdirs(alpm_handle_t *handle, alpm_list_t *hookdirs);
|
||||
int alpm_option_add_hookdir(alpm_handle_t *handle, const char *hookdir);
|
||||
int alpm_option_remove_hookdir(alpm_handle_t *handle, const char *hookdir);
|
||||
/** @} */
|
||||
|
||||
/** Returns the logfile name. */
|
||||
const char *alpm_option_get_logfile(alpm_handle_t *handle);
|
||||
/** Sets the logfile name. */
|
||||
@@ -541,9 +850,10 @@ int alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog);
|
||||
* @{
|
||||
*/
|
||||
alpm_list_t *alpm_option_get_noupgrades(alpm_handle_t *handle);
|
||||
int alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg);
|
||||
int alpm_option_add_noupgrade(alpm_handle_t *handle, const char *path);
|
||||
int alpm_option_set_noupgrades(alpm_handle_t *handle, alpm_list_t *noupgrade);
|
||||
int alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg);
|
||||
int alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *path);
|
||||
int alpm_option_match_noupgrade(alpm_handle_t *handle, const char *path);
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors to the list of no-extract files.
|
||||
@@ -553,9 +863,10 @@ int alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg);
|
||||
* @{
|
||||
*/
|
||||
alpm_list_t *alpm_option_get_noextracts(alpm_handle_t *handle);
|
||||
int alpm_option_add_noextract(alpm_handle_t *handle, const char *pkg);
|
||||
int alpm_option_add_noextract(alpm_handle_t *handle, const char *path);
|
||||
int alpm_option_set_noextracts(alpm_handle_t *handle, alpm_list_t *noextract);
|
||||
int alpm_option_remove_noextract(alpm_handle_t *handle, const char *pkg);
|
||||
int alpm_option_remove_noextract(alpm_handle_t *handle, const char *path);
|
||||
int alpm_option_match_noextract(alpm_handle_t *handle, const char *path);
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors to the list of ignored packages.
|
||||
@@ -580,6 +891,17 @@ int alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
|
||||
int alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp);
|
||||
/** @} */
|
||||
|
||||
/** @name Accessors to the list of ignored dependencies.
|
||||
* These functions modify the list of dependencies that
|
||||
* should be ignored by a sysupgrade.
|
||||
* @{
|
||||
*/
|
||||
alpm_list_t *alpm_option_get_assumeinstalled(alpm_handle_t *handle);
|
||||
int alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
|
||||
int alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps);
|
||||
int alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep);
|
||||
/** @} */
|
||||
|
||||
/** Returns the targeted architecture. */
|
||||
const char *alpm_option_get_arch(alpm_handle_t *handle);
|
||||
/** Sets the targeted architecture. */
|
||||
@@ -591,6 +913,9 @@ int alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio);
|
||||
int alpm_option_get_checkspace(alpm_handle_t *handle);
|
||||
int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
|
||||
|
||||
const char *alpm_option_get_dbext(alpm_handle_t *handle);
|
||||
int alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext);
|
||||
|
||||
alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle);
|
||||
int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
|
||||
|
||||
@@ -711,6 +1036,28 @@ alpm_list_t *alpm_db_get_groupcache(alpm_db_t *db);
|
||||
*/
|
||||
alpm_list_t *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles);
|
||||
|
||||
typedef enum _alpm_db_usage_ {
|
||||
ALPM_DB_USAGE_SYNC = 1,
|
||||
ALPM_DB_USAGE_SEARCH = (1 << 1),
|
||||
ALPM_DB_USAGE_INSTALL = (1 << 2),
|
||||
ALPM_DB_USAGE_UPGRADE = (1 << 3),
|
||||
ALPM_DB_USAGE_ALL = (1 << 4) - 1,
|
||||
} alpm_db_usage_t;
|
||||
|
||||
/** Sets the usage of a database.
|
||||
* @param db pointer to the package database to set the status for
|
||||
* @param usage a bitmask of alpm_db_usage_t values
|
||||
* @return 0 on success, or -1 on error
|
||||
*/
|
||||
int alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage);
|
||||
|
||||
/** Gets the usage of a database.
|
||||
* @param db pointer to the package database to get the status of
|
||||
* @param usage pointer to an alpm_db_usage_t to store db's status
|
||||
* @return 0 on success, or -1 on error
|
||||
*/
|
||||
int alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup alpm_api_packages Package Functions
|
||||
@@ -773,6 +1120,15 @@ alpm_list_t *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg);
|
||||
*/
|
||||
alpm_list_t *alpm_pkg_compute_optionalfor(alpm_pkg_t *pkg);
|
||||
|
||||
/** Test if a package should be ignored.
|
||||
* Checks if the package is ignored via IgnorePkg, or if the package is
|
||||
* in a group ignored via IgnoreGroup.
|
||||
* @param handle the context handle
|
||||
* @param pkg the package to test
|
||||
* @return 1 if the package should be ignored, 0 otherwise
|
||||
*/
|
||||
int alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg);
|
||||
|
||||
/** @name Package Property Accessors
|
||||
* Any pointer returned by these functions points to internal structures
|
||||
* allocated by libalpm. They should not be freed nor modified in any
|
||||
@@ -786,6 +1142,12 @@ alpm_list_t *alpm_pkg_compute_optionalfor(alpm_pkg_t *pkg);
|
||||
*/
|
||||
const char *alpm_pkg_get_filename(alpm_pkg_t *pkg);
|
||||
|
||||
/** Returns the package base name.
|
||||
* @param pkg a pointer to package
|
||||
* @return a reference to an internal string
|
||||
*/
|
||||
const char *alpm_pkg_get_base(alpm_pkg_t *pkg);
|
||||
|
||||
/** Returns the package name.
|
||||
* @param pkg a pointer to package
|
||||
* @return a reference to an internal string
|
||||
@@ -932,9 +1294,6 @@ alpm_list_t *alpm_pkg_get_replaces(alpm_pkg_t *pkg);
|
||||
alpm_filelist_t *alpm_pkg_get_files(alpm_pkg_t *pkg);
|
||||
|
||||
/** Returns the list of files backed up when installing pkg.
|
||||
* The elements of the returned list have the form
|
||||
* "<filename>\t<md5sum>", where the given md5sum is that of
|
||||
* the file as provided by the package.
|
||||
* @param pkg a pointer to package
|
||||
* @return a reference to a list of alpm_backup_t objects
|
||||
*/
|
||||
@@ -1043,7 +1402,7 @@ int alpm_pkg_set_reason(alpm_pkg_t *pkg, alpm_pkgreason_t reason);
|
||||
* @param path the path to search for in the package
|
||||
* @return a pointer to the matching file or NULL if not found
|
||||
*/
|
||||
char *alpm_filelist_contains(alpm_filelist_t *filelist, const char *path);
|
||||
alpm_file_t *alpm_filelist_contains(alpm_filelist_t *filelist, const char *path);
|
||||
|
||||
/*
|
||||
* Signatures
|
||||
@@ -1055,6 +1414,12 @@ int alpm_db_check_pgp_signature(alpm_db_t *db, alpm_siglist_t *siglist);
|
||||
|
||||
int alpm_siglist_cleanup(alpm_siglist_t *siglist);
|
||||
|
||||
int alpm_decode_signature(const char *base64_data,
|
||||
unsigned char **data, size_t *data_len);
|
||||
|
||||
int alpm_extract_keyid(alpm_handle_t *handle, const char *identifier,
|
||||
const unsigned char *sig, const size_t len, alpm_list_t **keys);
|
||||
|
||||
/*
|
||||
* Groups
|
||||
*/
|
||||
@@ -1212,6 +1577,17 @@ alpm_list_t *alpm_checkconflicts(alpm_handle_t *handle, alpm_list_t *pkglist);
|
||||
*/
|
||||
char *alpm_dep_compute_string(const alpm_depend_t *dep);
|
||||
|
||||
/** Return a newly allocated dependency information parsed from a string
|
||||
* @param depstring a formatted string, e.g. "glibc=2.12"
|
||||
* @return a dependency info structure
|
||||
*/
|
||||
alpm_depend_t *alpm_dep_from_string(const char *depstring);
|
||||
|
||||
/** Free a dependency info structure
|
||||
* @param dep struct to free
|
||||
*/
|
||||
void alpm_dep_free(alpm_depend_t *dep);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
@@ -1224,87 +1600,10 @@ char *alpm_dep_compute_string(const alpm_depend_t *dep);
|
||||
char *alpm_compute_md5sum(const char *filename);
|
||||
char *alpm_compute_sha256sum(const char *filename);
|
||||
|
||||
/** @addtogroup alpm_api_errors Error Codes
|
||||
* @{
|
||||
*/
|
||||
typedef enum _alpm_errno_t {
|
||||
ALPM_ERR_MEMORY = 1,
|
||||
ALPM_ERR_SYSTEM,
|
||||
ALPM_ERR_BADPERMS,
|
||||
ALPM_ERR_NOT_A_FILE,
|
||||
ALPM_ERR_NOT_A_DIR,
|
||||
ALPM_ERR_WRONG_ARGS,
|
||||
ALPM_ERR_DISK_SPACE,
|
||||
/* Interface */
|
||||
ALPM_ERR_HANDLE_NULL,
|
||||
ALPM_ERR_HANDLE_NOT_NULL,
|
||||
ALPM_ERR_HANDLE_LOCK,
|
||||
/* Databases */
|
||||
ALPM_ERR_DB_OPEN,
|
||||
ALPM_ERR_DB_CREATE,
|
||||
ALPM_ERR_DB_NULL,
|
||||
ALPM_ERR_DB_NOT_NULL,
|
||||
ALPM_ERR_DB_NOT_FOUND,
|
||||
ALPM_ERR_DB_INVALID,
|
||||
ALPM_ERR_DB_INVALID_SIG,
|
||||
ALPM_ERR_DB_VERSION,
|
||||
ALPM_ERR_DB_WRITE,
|
||||
ALPM_ERR_DB_REMOVE,
|
||||
/* Servers */
|
||||
ALPM_ERR_SERVER_BAD_URL,
|
||||
ALPM_ERR_SERVER_NONE,
|
||||
/* Transactions */
|
||||
ALPM_ERR_TRANS_NOT_NULL,
|
||||
ALPM_ERR_TRANS_NULL,
|
||||
ALPM_ERR_TRANS_DUP_TARGET,
|
||||
ALPM_ERR_TRANS_NOT_INITIALIZED,
|
||||
ALPM_ERR_TRANS_NOT_PREPARED,
|
||||
ALPM_ERR_TRANS_ABORT,
|
||||
ALPM_ERR_TRANS_TYPE,
|
||||
ALPM_ERR_TRANS_NOT_LOCKED,
|
||||
/* Packages */
|
||||
ALPM_ERR_PKG_NOT_FOUND,
|
||||
ALPM_ERR_PKG_IGNORED,
|
||||
ALPM_ERR_PKG_INVALID,
|
||||
ALPM_ERR_PKG_INVALID_CHECKSUM,
|
||||
ALPM_ERR_PKG_INVALID_SIG,
|
||||
ALPM_ERR_PKG_OPEN,
|
||||
ALPM_ERR_PKG_CANT_REMOVE,
|
||||
ALPM_ERR_PKG_INVALID_NAME,
|
||||
ALPM_ERR_PKG_INVALID_ARCH,
|
||||
ALPM_ERR_PKG_REPO_NOT_FOUND,
|
||||
/* Signatures */
|
||||
ALPM_ERR_SIG_MISSING,
|
||||
ALPM_ERR_SIG_INVALID,
|
||||
/* Deltas */
|
||||
ALPM_ERR_DLT_INVALID,
|
||||
ALPM_ERR_DLT_PATCHFAILED,
|
||||
/* Dependencies */
|
||||
ALPM_ERR_UNSATISFIED_DEPS,
|
||||
ALPM_ERR_CONFLICTING_DEPS,
|
||||
ALPM_ERR_FILE_CONFLICTS,
|
||||
/* Misc */
|
||||
ALPM_ERR_RETRIEVE,
|
||||
ALPM_ERR_INVALID_REGEX,
|
||||
/* External library errors */
|
||||
ALPM_ERR_LIBARCHIVE,
|
||||
ALPM_ERR_LIBCURL,
|
||||
ALPM_ERR_EXTERNAL_DOWNLOAD,
|
||||
ALPM_ERR_GPGME
|
||||
} alpm_errno_t;
|
||||
|
||||
/** Returns the current error code from the handle. */
|
||||
alpm_errno_t alpm_errno(alpm_handle_t *handle);
|
||||
|
||||
/** Returns the string corresponding to an error number. */
|
||||
const char *alpm_strerror(alpm_errno_t err);
|
||||
|
||||
/* End of alpm_api_errors */
|
||||
/** @} */
|
||||
|
||||
alpm_handle_t *alpm_initialize(const char *root, const char *dbpath,
|
||||
alpm_errno_t *err);
|
||||
int alpm_release(alpm_handle_t *handle);
|
||||
int alpm_unlock(alpm_handle_t *handle);
|
||||
|
||||
enum alpm_caps {
|
||||
ALPM_CAPABILITY_NLS = (1 << 0),
|
||||
@@ -1315,12 +1614,16 @@ enum alpm_caps {
|
||||
const char *alpm_version(void);
|
||||
enum alpm_caps alpm_capabilities(void);
|
||||
|
||||
void alpm_fileconflict_free(alpm_fileconflict_t *conflict);
|
||||
void alpm_depmissing_free(alpm_depmissing_t *miss);
|
||||
void alpm_conflict_free(alpm_conflict_t *conflict);
|
||||
|
||||
/* End of alpm_api */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _ALPM_H */
|
||||
#endif /* ALPM_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alpm_list.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Note: alpm_list.{c,h} are intended to be standalone files. Do not include
|
||||
* any other libalpm headers.
|
||||
*/
|
||||
|
||||
/* libalpm */
|
||||
#include "alpm_list.h"
|
||||
|
||||
@@ -66,11 +70,13 @@ void SYMEXPORT alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn)
|
||||
{
|
||||
alpm_list_t *it = list;
|
||||
|
||||
while(it) {
|
||||
if(fn && it->data) {
|
||||
fn(it->data);
|
||||
if(fn) {
|
||||
while(it) {
|
||||
if(it->data) {
|
||||
fn(it->data);
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,28 +93,42 @@ void SYMEXPORT alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn)
|
||||
*/
|
||||
alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
|
||||
{
|
||||
alpm_list_t *ptr, *lp;
|
||||
alpm_list_append(&list, data);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a new item to the end of the list.
|
||||
*
|
||||
* @param list the list to add to
|
||||
* @param data the new item to be added to the list
|
||||
*
|
||||
* @return the newly added item
|
||||
*/
|
||||
alpm_list_t SYMEXPORT *alpm_list_append(alpm_list_t **list, void *data)
|
||||
{
|
||||
alpm_list_t *ptr;
|
||||
|
||||
ptr = malloc(sizeof(alpm_list_t));
|
||||
if(ptr == NULL) {
|
||||
return list;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr->data = data;
|
||||
ptr->next = NULL;
|
||||
|
||||
/* Special case: the input list is empty */
|
||||
if(list == NULL) {
|
||||
if(*list == NULL) {
|
||||
*list = ptr;
|
||||
ptr->prev = ptr;
|
||||
return ptr;
|
||||
} else {
|
||||
alpm_list_t *lp = alpm_list_last(*list);
|
||||
lp->next = ptr;
|
||||
ptr->prev = lp;
|
||||
(*list)->prev = ptr;
|
||||
}
|
||||
|
||||
lp = alpm_list_last(list);
|
||||
lp->next = ptr;
|
||||
ptr->prev = lp;
|
||||
list->prev = ptr;
|
||||
|
||||
return list;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -784,4 +804,4 @@ void SYMEXPORT *alpm_list_to_array(const alpm_list_t *list, size_t n,
|
||||
|
||||
/** @} */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alpm_list.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,11 +17,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_LIST_H
|
||||
#define _ALPM_LIST_H
|
||||
#ifndef ALPM_LIST_H
|
||||
#define ALPM_LIST_H
|
||||
|
||||
#include <stdlib.h> /* size_t */
|
||||
|
||||
/* Note: alpm_list.{c,h} are intended to be standalone files. Do not include
|
||||
* any other libalpm headers.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -53,6 +57,7 @@ void alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn);
|
||||
|
||||
/* item mutators */
|
||||
alpm_list_t *alpm_list_add(alpm_list_t *list, void *data);
|
||||
alpm_list_t *alpm_list_append(alpm_list_t **list, void *data);
|
||||
alpm_list_t *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn);
|
||||
alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second);
|
||||
alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn);
|
||||
@@ -85,6 +90,6 @@ void *alpm_list_to_array(const alpm_list_t *list, size_t n, size_t size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _ALPM_LIST_H */
|
||||
#endif /* ALPM_LIST_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* backup.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2005 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
||||
@@ -47,8 +47,8 @@ int _alpm_split_backup(const char *string, alpm_backup_t **backup)
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
/* now str points to the filename and ptr points to the hash */
|
||||
STRDUP((*backup)->name, str, return -1);
|
||||
STRDUP((*backup)->hash, ptr, return -1);
|
||||
STRDUP((*backup)->name, str, FREE(str); return -1);
|
||||
STRDUP((*backup)->hash, ptr, FREE((*backup)->name); FREE(str); return -1);
|
||||
FREE(str);
|
||||
return 0;
|
||||
}
|
||||
@@ -77,9 +77,10 @@ alpm_backup_t *_alpm_needbackup(const char *file, alpm_pkg_t *pkg)
|
||||
|
||||
void _alpm_backup_free(alpm_backup_t *backup)
|
||||
{
|
||||
free(backup->name);
|
||||
free(backup->hash);
|
||||
free(backup);
|
||||
ASSERT(backup != NULL, return);
|
||||
FREE(backup->name);
|
||||
FREE(backup->hash);
|
||||
FREE(backup);
|
||||
}
|
||||
|
||||
alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup)
|
||||
@@ -87,10 +88,15 @@ alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup)
|
||||
alpm_backup_t *newbackup;
|
||||
CALLOC(newbackup, 1, sizeof(alpm_backup_t), return NULL);
|
||||
|
||||
STRDUP(newbackup->name, backup->name, return NULL);
|
||||
STRDUP(newbackup->hash, backup->hash, return NULL);
|
||||
STRDUP(newbackup->name, backup->name, goto error);
|
||||
STRDUP(newbackup->hash, backup->hash, goto error);
|
||||
|
||||
return newbackup;
|
||||
|
||||
error:
|
||||
free(newbackup->name);
|
||||
free(newbackup);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* backup.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_BACKUP_H
|
||||
#define _ALPM_BACKUP_H
|
||||
#ifndef ALPM_BACKUP_H
|
||||
#define ALPM_BACKUP_H
|
||||
|
||||
#include "alpm_list.h"
|
||||
#include "alpm.h"
|
||||
@@ -28,6 +28,6 @@ alpm_backup_t *_alpm_needbackup(const char *file, alpm_pkg_t *pkg);
|
||||
void _alpm_backup_free(alpm_backup_t *backup);
|
||||
alpm_backup_t *_alpm_backup_dup(const alpm_backup_t *backup);
|
||||
|
||||
#endif /* _ALPM_BACKUP_H */
|
||||
#endif /* ALPM_BACKUP_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#if 0
|
||||
static const unsigned char base64_enc_map[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
@@ -46,6 +47,7 @@ static const unsigned char base64_enc_map[64] =
|
||||
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '+', '/'
|
||||
};
|
||||
#endif
|
||||
|
||||
static const unsigned char base64_dec_map[128] =
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _BASE64_H
|
||||
#define _BASE64_H
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* be_local.c : backend for the local database
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -44,6 +44,9 @@
|
||||
#include "deps.h"
|
||||
#include "filelist.h"
|
||||
|
||||
/* local database format version */
|
||||
size_t ALPM_LOCAL_DB_VERSION = 9;
|
||||
|
||||
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq);
|
||||
|
||||
#define LAZY_LOAD(info, errret) \
|
||||
@@ -60,6 +63,12 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq);
|
||||
* initialized.
|
||||
*/
|
||||
|
||||
static const char *_cache_get_base(alpm_pkg_t *pkg)
|
||||
{
|
||||
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||
return pkg->base;
|
||||
}
|
||||
|
||||
static const char *_cache_get_desc(alpm_pkg_t *pkg)
|
||||
{
|
||||
LAZY_LOAD(INFRQ_DESC, NULL);
|
||||
@@ -294,6 +303,7 @@ static int _cache_force_load(alpm_pkg_t *pkg)
|
||||
* logic.
|
||||
*/
|
||||
static struct pkg_operations local_pkg_ops = {
|
||||
.get_base = _cache_get_base,
|
||||
.get_desc = _cache_get_desc,
|
||||
.get_url = _cache_get_url,
|
||||
.get_builddate = _cache_get_builddate,
|
||||
@@ -366,12 +376,48 @@ static int is_dir(const char *path, struct dirent *entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_db_add_version(alpm_db_t UNUSED *db, const char *dbpath)
|
||||
{
|
||||
char dbverpath[PATH_MAX];
|
||||
FILE *dbverfile;
|
||||
|
||||
snprintf(dbverpath, PATH_MAX, "%sALPM_DB_VERSION", dbpath);
|
||||
|
||||
dbverfile = fopen(dbverpath, "w");
|
||||
|
||||
if(dbverfile == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(dbverfile, "%zu\n", ALPM_LOCAL_DB_VERSION);
|
||||
fclose(dbverfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_db_create(alpm_db_t *db, const char *dbpath)
|
||||
{
|
||||
if(mkdir(dbpath, 0755) != 0) {
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not create directory %s: %s\n"),
|
||||
dbpath, strerror(errno));
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_CREATE, -1);
|
||||
}
|
||||
if(local_db_add_version(db, dbpath) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int local_db_validate(alpm_db_t *db)
|
||||
{
|
||||
struct dirent *ent = NULL;
|
||||
const char *dbpath;
|
||||
DIR *dbdir;
|
||||
int ret = -1;
|
||||
char dbverpath[PATH_MAX];
|
||||
FILE *dbverfile;
|
||||
int t;
|
||||
size_t version;
|
||||
|
||||
if(db->status & DB_STATUS_VALID) {
|
||||
return 0;
|
||||
@@ -384,15 +430,23 @@ static int local_db_validate(alpm_db_t *db)
|
||||
if(dbpath == NULL) {
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
|
||||
}
|
||||
|
||||
dbdir = opendir(dbpath);
|
||||
if(dbdir == NULL) {
|
||||
if(errno == ENOENT) {
|
||||
/* database dir doesn't exist yet */
|
||||
db->status |= DB_STATUS_VALID;
|
||||
db->status &= ~DB_STATUS_INVALID;
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status |= DB_STATUS_MISSING;
|
||||
return 0;
|
||||
/* local database dir doesn't exist yet - create it */
|
||||
if(local_db_create(db, dbpath) == 0) {
|
||||
db->status |= DB_STATUS_VALID;
|
||||
db->status &= ~DB_STATUS_INVALID;
|
||||
db->status |= DB_STATUS_EXISTS;
|
||||
db->status &= ~DB_STATUS_MISSING;
|
||||
return 0;
|
||||
} else {
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status |= DB_STATUS_MISSING;
|
||||
/* pm_errno is set by local_db_create */
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
|
||||
}
|
||||
@@ -400,43 +454,54 @@ static int local_db_validate(alpm_db_t *db)
|
||||
db->status |= DB_STATUS_EXISTS;
|
||||
db->status &= ~DB_STATUS_MISSING;
|
||||
|
||||
while((ent = readdir(dbdir)) != NULL) {
|
||||
const char *name = ent->d_name;
|
||||
char path[PATH_MAX];
|
||||
snprintf(dbverpath, PATH_MAX, "%sALPM_DB_VERSION", dbpath);
|
||||
|
||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
if(!is_dir(dbpath, ent)) {
|
||||
continue;
|
||||
if((dbverfile = fopen(dbverpath, "r")) == NULL) {
|
||||
/* create dbverfile if local database is empty - otherwise version error */
|
||||
while((ent = readdir(dbdir)) != NULL) {
|
||||
const char *name = ent->d_name;
|
||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
||||
continue;
|
||||
} else {
|
||||
goto version_error;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(path, PATH_MAX, "%s%s/depends", dbpath, name);
|
||||
if(access(path, F_OK) == 0) {
|
||||
/* we found a depends file- bail */
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status |= DB_STATUS_INVALID;
|
||||
db->handle->pm_errno = ALPM_ERR_DB_VERSION;
|
||||
goto done;
|
||||
if(local_db_add_version(db, dbpath) != 0) {
|
||||
goto version_error;
|
||||
}
|
||||
goto version_latest;
|
||||
}
|
||||
/* we found no depends file after full scan */
|
||||
|
||||
t = fscanf(dbverfile, "%zu", &version);
|
||||
fclose(dbverfile);
|
||||
|
||||
if(t != 1) {
|
||||
goto version_error;
|
||||
}
|
||||
|
||||
if(version != ALPM_LOCAL_DB_VERSION) {
|
||||
goto version_error;
|
||||
}
|
||||
|
||||
version_latest:
|
||||
closedir(dbdir);
|
||||
db->status |= DB_STATUS_VALID;
|
||||
db->status &= ~DB_STATUS_INVALID;
|
||||
ret = 0;
|
||||
return 0;
|
||||
|
||||
done:
|
||||
if(dbdir) {
|
||||
closedir(dbdir);
|
||||
}
|
||||
|
||||
return ret;
|
||||
version_error:
|
||||
closedir(dbdir);
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status |= DB_STATUS_INVALID;
|
||||
db->handle->pm_errno = ALPM_ERR_DB_VERSION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int local_db_populate(alpm_db_t *db)
|
||||
{
|
||||
size_t est_count;
|
||||
int count = 0;
|
||||
size_t count = 0;
|
||||
struct stat buf;
|
||||
struct dirent *ent = NULL;
|
||||
const char *dbpath;
|
||||
@@ -445,7 +510,9 @@ static int local_db_populate(alpm_db_t *db)
|
||||
if(db->status & DB_STATUS_INVALID) {
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1);
|
||||
}
|
||||
/* note: DB_STATUS_MISSING is not fatal for local database */
|
||||
if(db->status & DB_STATUS_MISSING) {
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1);
|
||||
}
|
||||
|
||||
dbpath = _alpm_db_path(db);
|
||||
if(dbpath == NULL) {
|
||||
@@ -455,12 +522,6 @@ static int local_db_populate(alpm_db_t *db)
|
||||
|
||||
dbdir = opendir(dbpath);
|
||||
if(dbdir == NULL) {
|
||||
if(errno == ENOENT) {
|
||||
/* no database existing yet is not an error */
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status |= DB_STATUS_MISSING;
|
||||
return 0;
|
||||
}
|
||||
RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
|
||||
}
|
||||
if(fstat(dirfd(dbdir), &buf) != 0) {
|
||||
@@ -546,12 +607,12 @@ static int local_db_populate(alpm_db_t *db)
|
||||
|
||||
closedir(dbdir);
|
||||
if(count > 0) {
|
||||
db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp);
|
||||
db->pkgcache->list = alpm_list_msort(db->pkgcache->list, count, _alpm_pkg_cmp);
|
||||
}
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n",
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "added %zu packages to package cache for db '%s'\n",
|
||||
count, db->treename);
|
||||
|
||||
return count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: the return value must be freed by the caller */
|
||||
@@ -572,7 +633,7 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
|
||||
}
|
||||
|
||||
#define READ_NEXT() do { \
|
||||
if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
|
||||
if(safe_fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
|
||||
_alpm_strip_newline(line, 0); \
|
||||
} while(0)
|
||||
|
||||
@@ -583,7 +644,7 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
|
||||
|
||||
#define READ_AND_STORE_ALL(f) do { \
|
||||
char *linedup; \
|
||||
if(fgets(line, sizeof(line), fp) == NULL) {\
|
||||
if(safe_fgets(line, sizeof(line), fp) == NULL) {\
|
||||
if(!feof(fp)) goto error; else break; \
|
||||
} \
|
||||
if(_alpm_strip_newline(line, 0) == 0) break; \
|
||||
@@ -592,11 +653,11 @@ char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
|
||||
} while(1) /* note the while(1) and not (0) */
|
||||
|
||||
#define READ_AND_SPLITDEP(f) do { \
|
||||
if(fgets(line, sizeof(line), fp) == NULL) {\
|
||||
if(safe_fgets(line, sizeof(line), fp) == NULL) {\
|
||||
if(!feof(fp)) goto error; else break; \
|
||||
} \
|
||||
if(_alpm_strip_newline(line, 0) == 0) break; \
|
||||
f = alpm_list_add(f, _alpm_splitdep(line)); \
|
||||
f = alpm_list_add(f, alpm_dep_from_string(line)); \
|
||||
} while(1) /* note the while(1) and not (0) */
|
||||
|
||||
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||
@@ -638,7 +699,7 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||
}
|
||||
free(path);
|
||||
while(!feof(fp)) {
|
||||
if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) {
|
||||
if(safe_fgets(line, sizeof(line), fp) == NULL && !feof(fp)) {
|
||||
goto error;
|
||||
}
|
||||
if(_alpm_strip_newline(line, 0) == 0) {
|
||||
@@ -657,6 +718,8 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version "
|
||||
"mismatch on package %s\n"), db->treename, info->name);
|
||||
}
|
||||
} else if(strcmp(line, "%BASE%") == 0) {
|
||||
READ_AND_STORE(info->base);
|
||||
} else if(strcmp(line, "%DESC%") == 0) {
|
||||
READ_AND_STORE(info->desc);
|
||||
} else if(strcmp(line, "%GROUPS%") == 0) {
|
||||
@@ -727,53 +790,54 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||
goto error;
|
||||
}
|
||||
free(path);
|
||||
while(fgets(line, sizeof(line), fp)) {
|
||||
while(safe_fgets(line, sizeof(line), fp)) {
|
||||
_alpm_strip_newline(line, 0);
|
||||
if(strcmp(line, "%FILES%") == 0) {
|
||||
size_t files_count = 0, files_size = 0, len;
|
||||
alpm_file_t *files = NULL;
|
||||
|
||||
while(fgets(line, sizeof(line), fp) &&
|
||||
while(safe_fgets(line, sizeof(line), fp) &&
|
||||
(len = _alpm_strip_newline(line, 0))) {
|
||||
if(files_count >= files_size) {
|
||||
size_t old_size = files_size;
|
||||
if(files_size == 0) {
|
||||
files_size = 8;
|
||||
} else {
|
||||
files_size *= 2;
|
||||
}
|
||||
files = realloc(files, sizeof(alpm_file_t) * files_size);
|
||||
if(!files) {
|
||||
_alpm_alloc_fail(sizeof(alpm_file_t) * files_size);
|
||||
goto error;
|
||||
}
|
||||
/* ensure all new memory is zeroed out, in both the initial
|
||||
* allocation and later reallocs */
|
||||
memset(files + old_size, 0,
|
||||
sizeof(alpm_file_t) * (files_size - old_size));
|
||||
if(!_alpm_greedy_grow((void **)&files, &files_size,
|
||||
(files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
|
||||
goto nomem;
|
||||
}
|
||||
/* since we know the length of the file string already,
|
||||
* we can do malloc + memcpy rather than strdup */
|
||||
len += 1;
|
||||
files[files_count].name = malloc(len);
|
||||
if(files[files_count].name == NULL) {
|
||||
_alpm_alloc_fail(len);
|
||||
goto error;
|
||||
}
|
||||
MALLOC(files[files_count].name, len, goto nomem);
|
||||
memcpy(files[files_count].name, line, len);
|
||||
files_count++;
|
||||
}
|
||||
/* attempt to hand back any memory we don't need */
|
||||
files = realloc(files, sizeof(alpm_file_t) * files_count);
|
||||
/* make sure the list is sorted */
|
||||
qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp);
|
||||
if(files_count > 0) {
|
||||
alpm_file_t *newfiles;
|
||||
|
||||
newfiles = realloc(files, sizeof(alpm_file_t) * files_count);
|
||||
if(newfiles != NULL) {
|
||||
files = newfiles;
|
||||
}
|
||||
|
||||
/* make sure the list is sorted */
|
||||
qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp);
|
||||
} else {
|
||||
FREE(files);
|
||||
}
|
||||
info->files.count = files_count;
|
||||
info->files.files = files;
|
||||
continue;
|
||||
nomem:
|
||||
while(files_count > 0) {
|
||||
FREE(files[--files_count].name);
|
||||
}
|
||||
FREE(files);
|
||||
goto error;
|
||||
} else if(strcmp(line, "%BACKUP%") == 0) {
|
||||
while(fgets(line, sizeof(line), fp) && _alpm_strip_newline(line, 0)) {
|
||||
while(safe_fgets(line, sizeof(line), fp) && _alpm_strip_newline(line, 0)) {
|
||||
alpm_backup_t *backup;
|
||||
CALLOC(backup, 1, sizeof(alpm_backup_t), goto error);
|
||||
if(_alpm_split_backup(line, &backup)) {
|
||||
FREE(backup);
|
||||
goto error;
|
||||
}
|
||||
info->backup = alpm_list_add(info->backup, backup);
|
||||
@@ -877,6 +941,10 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq
|
||||
free(path);
|
||||
fprintf(fp, "%%NAME%%\n%s\n\n"
|
||||
"%%VERSION%%\n%s\n\n", info->name, info->version);
|
||||
if(info->base) {
|
||||
fprintf(fp, "%%BASE%%\n"
|
||||
"%s\n\n", info->base);
|
||||
}
|
||||
if(info->desc) {
|
||||
fprintf(fp, "%%DESC%%\n"
|
||||
"%s\n\n", info->desc);
|
||||
@@ -990,16 +1058,11 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
/* INSTALL */
|
||||
/* nothing needed here (script is automatically extracted) */
|
||||
/* INSTALL and MTREE */
|
||||
/* nothing needed here (automatically extracted) */
|
||||
|
||||
cleanup:
|
||||
umask(oldmask);
|
||||
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1091,6 +1154,7 @@ alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle)
|
||||
}
|
||||
db->ops = &local_db_ops;
|
||||
db->handle = handle;
|
||||
db->usage = ALPM_DB_USAGE_ALL;
|
||||
|
||||
if(local_db_validate(db)) {
|
||||
/* pm_errno set in local_db_validate() */
|
||||
@@ -1102,4 +1166,4 @@ alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle)
|
||||
return db;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* be_package.c : backend for packages
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* libarchive */
|
||||
#include <archive.h>
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "package.h"
|
||||
#include "deps.h"
|
||||
#include "filelist.h"
|
||||
#include "util.h"
|
||||
|
||||
struct package_changelog {
|
||||
struct archive *archive;
|
||||
@@ -76,7 +78,7 @@ static void *_package_changelog_open(alpm_pkg_t *pkg)
|
||||
if(!changelog) {
|
||||
pkg->handle->pm_errno = ALPM_ERR_MEMORY;
|
||||
_alpm_archive_read_free(archive);
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
changelog->archive = archive;
|
||||
@@ -86,7 +88,7 @@ static void *_package_changelog_open(alpm_pkg_t *pkg)
|
||||
}
|
||||
/* we didn't find a changelog */
|
||||
_alpm_archive_read_free(archive);
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
errno = ENOENT;
|
||||
|
||||
return NULL;
|
||||
@@ -126,7 +128,7 @@ static int _package_changelog_close(const alpm_pkg_t UNUSED *pkg, void *fp)
|
||||
int ret;
|
||||
struct package_changelog *changelog = fp;
|
||||
ret = _alpm_archive_read_free(changelog->archive);
|
||||
CLOSE(changelog->fd);
|
||||
close(changelog->fd);
|
||||
free(changelog);
|
||||
return ret;
|
||||
}
|
||||
@@ -192,9 +194,11 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
|
||||
STRDUP(newpkg->name, ptr, return -1);
|
||||
newpkg->name_hash = _alpm_hash_sdbm(newpkg->name);
|
||||
} else if(strcmp(key, "pkgbase") == 0) {
|
||||
/* not used atm */
|
||||
STRDUP(newpkg->base, ptr, return -1);
|
||||
} else if(strcmp(key, "pkgver") == 0) {
|
||||
STRDUP(newpkg->version, ptr, return -1);
|
||||
} else if(strcmp(key, "basever") == 0) {
|
||||
/* not used atm */
|
||||
} else if(strcmp(key, "pkgdesc") == 0) {
|
||||
STRDUP(newpkg->desc, ptr, return -1);
|
||||
} else if(strcmp(key, "group") == 0) {
|
||||
@@ -213,24 +217,28 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
|
||||
/* size in the raw package is uncompressed (installed) size */
|
||||
newpkg->isize = _alpm_strtoofft(ptr);
|
||||
} else if(strcmp(key, "depend") == 0) {
|
||||
alpm_depend_t *dep = _alpm_splitdep(ptr);
|
||||
alpm_depend_t *dep = alpm_dep_from_string(ptr);
|
||||
newpkg->depends = alpm_list_add(newpkg->depends, dep);
|
||||
} else if(strcmp(key, "optdepend") == 0) {
|
||||
alpm_depend_t *optdep = _alpm_splitdep(ptr);
|
||||
alpm_depend_t *optdep = alpm_dep_from_string(ptr);
|
||||
newpkg->optdepends = alpm_list_add(newpkg->optdepends, optdep);
|
||||
} else if(strcmp(key, "makedepend") == 0) {
|
||||
/* not used atm */
|
||||
} else if(strcmp(key, "checkdepend") == 0) {
|
||||
/* not used atm */
|
||||
} else if(strcmp(key, "conflict") == 0) {
|
||||
alpm_depend_t *conflict = _alpm_splitdep(ptr);
|
||||
alpm_depend_t *conflict = alpm_dep_from_string(ptr);
|
||||
newpkg->conflicts = alpm_list_add(newpkg->conflicts, conflict);
|
||||
} else if(strcmp(key, "replaces") == 0) {
|
||||
alpm_depend_t *replace = _alpm_splitdep(ptr);
|
||||
alpm_depend_t *replace = alpm_dep_from_string(ptr);
|
||||
newpkg->replaces = alpm_list_add(newpkg->replaces, replace);
|
||||
} else if(strcmp(key, "provides") == 0) {
|
||||
alpm_depend_t *provide = _alpm_splitdep(ptr);
|
||||
alpm_depend_t *provide = alpm_dep_from_string(ptr);
|
||||
newpkg->provides = alpm_list_add(newpkg->provides, provide);
|
||||
} else if(strcmp(key, "backup") == 0) {
|
||||
alpm_backup_t *backup;
|
||||
CALLOC(backup, 1, sizeof(alpm_backup_t), return -1);
|
||||
STRDUP(backup->name, ptr, return -1);
|
||||
STRDUP(backup->name, ptr, FREE(backup); return -1);
|
||||
newpkg->backup = alpm_list_add(newpkg->backup, backup);
|
||||
} else if(strcmp(key, "force") == 0) {
|
||||
/* deprecated, skip it */
|
||||
@@ -323,9 +331,13 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle,
|
||||
}
|
||||
|
||||
/* even if we don't have a sig, run the check code if level tells us to */
|
||||
if(has_sig || level & ALPM_SIG_PACKAGE) {
|
||||
if(level & ALPM_SIG_PACKAGE) {
|
||||
const char *sig = syncpkg ? syncpkg->base64_sig : NULL;
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "sig data: %s\n", sig ? sig : "<from .sig>");
|
||||
if(!has_sig && !(level & ALPM_SIG_PACKAGE_OPTIONAL)) {
|
||||
handle->pm_errno = ALPM_ERR_PKG_MISSING_SIG;
|
||||
return -1;
|
||||
}
|
||||
if(_alpm_check_pgp_helper(handle, pkgfile, sig,
|
||||
level & ALPM_SIG_PACKAGE_OPTIONAL, level & ALPM_SIG_PACKAGE_MARGINAL_OK,
|
||||
level & ALPM_SIG_PACKAGE_UNKNOWN_OK, sigdata)) {
|
||||
@@ -344,6 +356,193 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the existence of simple paths for _alpm_load_pkg_internal()
|
||||
* @param pkg package to change
|
||||
* @param path path to examine
|
||||
* @return 0 if path doesn't match any rule, 1 if it has been handled
|
||||
*/
|
||||
static int handle_simple_path(alpm_pkg_t *pkg, const char *path)
|
||||
{
|
||||
if(strcmp(path, ".INSTALL") == 0) {
|
||||
pkg->scriptlet = 1;
|
||||
return 1;
|
||||
} else if(*path == '.') {
|
||||
/* for now, ignore all files starting with '.' that haven't
|
||||
* already been handled (for future possibilities) */
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the files list for pkg.
|
||||
*
|
||||
* @param pkg package to add the file to
|
||||
* @param files_size size of pkg->files.files
|
||||
* @param entry archive entry of the file to add to the list
|
||||
* @param path path of the file to be added
|
||||
* @return <0 on error, 0 on success
|
||||
*/
|
||||
static int add_entry_to_files_list(alpm_filelist_t *filelist,
|
||||
size_t *files_size, struct archive_entry *entry, const char *path)
|
||||
{
|
||||
const size_t files_count = filelist->count;
|
||||
alpm_file_t *current_file;
|
||||
mode_t type;
|
||||
size_t pathlen;
|
||||
|
||||
if(!_alpm_greedy_grow((void **)&filelist->files,
|
||||
files_size, (files_count + 1) * sizeof(alpm_file_t))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = archive_entry_filetype(entry);
|
||||
|
||||
pathlen = strlen(path);
|
||||
|
||||
current_file = filelist->files + files_count;
|
||||
|
||||
/* mtree paths don't contain a tailing slash, those we get from
|
||||
* the archive directly do (expensive way)
|
||||
* Other code relies on it to detect directories so add it here.*/
|
||||
if(type == AE_IFDIR && path[pathlen - 1] != '/') {
|
||||
/* 2 = 1 for / + 1 for \0 */
|
||||
char *newpath;
|
||||
MALLOC(newpath, pathlen + 2, return -1);
|
||||
strcpy(newpath, path);
|
||||
newpath[pathlen] = '/';
|
||||
newpath[pathlen + 1] = '\0';
|
||||
current_file->name = newpath;
|
||||
} else {
|
||||
STRDUP(current_file->name, path, return -1);
|
||||
}
|
||||
current_file->size = archive_entry_size(entry);
|
||||
current_file->mode = archive_entry_mode(entry);
|
||||
filelist->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new file list from an mtree file and add it to the package.
|
||||
* An existing file list will be free()d first.
|
||||
*
|
||||
* archive should point to an archive struct which is already at the
|
||||
* position of the mtree's header.
|
||||
*
|
||||
* @param handle
|
||||
* @param pkg package to add the file list to
|
||||
* @param archive archive containing the mtree
|
||||
* @return 0 on success, <0 on error
|
||||
*/
|
||||
static int build_filelist_from_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg, struct archive *archive)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
size_t mtree_maxsize = 0;
|
||||
size_t mtree_cursize = 0;
|
||||
size_t files_size = 0; /* we clean up the existing array so this is fine */
|
||||
char *mtree_data = NULL;
|
||||
struct archive *mtree;
|
||||
struct archive_entry *mtree_entry = NULL;
|
||||
alpm_filelist_t filelist;
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"found mtree for package %s, getting file list\n", pkg->filename);
|
||||
|
||||
memset(&filelist, 0, sizeof(alpm_filelist_t));
|
||||
|
||||
/* create a new archive to parse the mtree and load it from archive into memory */
|
||||
/* TODO: split this into a function */
|
||||
if((mtree = archive_read_new()) == NULL) {
|
||||
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
_alpm_archive_read_support_filter_all(mtree);
|
||||
archive_read_support_format_mtree(mtree);
|
||||
|
||||
/* TODO: split this into a function */
|
||||
while(1) {
|
||||
ssize_t size;
|
||||
|
||||
if(!_alpm_greedy_grow((void **)&mtree_data, &mtree_maxsize, mtree_cursize + ALPM_BUFFER_SIZE)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
size = archive_read_data(archive, mtree_data + mtree_cursize, ALPM_BUFFER_SIZE);
|
||||
|
||||
if(size < 0) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading package %s: %s\n"),
|
||||
pkg->filename, archive_error_string(archive));
|
||||
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
|
||||
goto error;
|
||||
}
|
||||
if(size == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
mtree_cursize += size;
|
||||
}
|
||||
|
||||
if(archive_read_open_memory(mtree, mtree_data, mtree_cursize)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
_("error while reading mtree of package %s: %s\n"),
|
||||
pkg->filename, archive_error_string(mtree));
|
||||
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
while((ret = archive_read_next_header(mtree, &mtree_entry)) == ARCHIVE_OK) {
|
||||
const char *path = archive_entry_pathname(mtree_entry);
|
||||
|
||||
/* strip leading "./" from path entries */
|
||||
if(path[0] == '.' && path[1] == '/') {
|
||||
path += 2;
|
||||
}
|
||||
|
||||
if(handle_simple_path(pkg, path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(add_entry_to_files_list(&filelist, &files_size, mtree_entry, path) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occurred */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, _("error while reading mtree of package %s: %s\n"),
|
||||
pkg->filename, archive_error_string(mtree));
|
||||
handle->pm_errno = ALPM_ERR_LIBARCHIVE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* throw away any files we loaded directly from the archive */
|
||||
for(i = 0; i < pkg->files.count; i++) {
|
||||
free(pkg->files.files[i].name);
|
||||
}
|
||||
free(pkg->files.files);
|
||||
|
||||
/* copy over new filelist */
|
||||
memcpy(&pkg->files, &filelist, sizeof(alpm_filelist_t));
|
||||
|
||||
free(mtree_data);
|
||||
_alpm_archive_read_free(mtree);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "finished mtree reading for %s\n", pkg->filename);
|
||||
return 0;
|
||||
error:
|
||||
/* throw away any files we loaded from the mtree */
|
||||
for(i = 0; i < filelist.count; i++) {
|
||||
free(filelist.files[i].name);
|
||||
}
|
||||
free(filelist.files);
|
||||
|
||||
free(mtree_data);
|
||||
_alpm_archive_read_free(mtree);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a package and create the corresponding alpm_pkg_t struct.
|
||||
* @param handle the context handle
|
||||
@@ -354,7 +553,9 @@ int _alpm_pkg_validate_internal(alpm_handle_t *handle,
|
||||
alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
const char *pkgfile, int full)
|
||||
{
|
||||
int ret, fd, config = 0;
|
||||
int ret, fd;
|
||||
int config = 0;
|
||||
int hit_mtree = 0;
|
||||
struct archive *archive;
|
||||
struct archive_entry *entry;
|
||||
alpm_pkg_t *newpkg;
|
||||
@@ -409,42 +610,25 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);
|
||||
goto pkg_invalid;
|
||||
}
|
||||
if(strchr(newpkg->version, '-') == NULL) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("invalid package version in %s\n"), pkgfile);
|
||||
goto pkg_invalid;
|
||||
}
|
||||
config = 1;
|
||||
continue;
|
||||
} else if(strcmp(entry_name, ".INSTALL") == 0) {
|
||||
newpkg->scriptlet = 1;
|
||||
} else if(*entry_name == '.') {
|
||||
/* for now, ignore all files starting with '.' that haven't
|
||||
* already been handled (for future possibilities) */
|
||||
} else if(full) {
|
||||
const size_t files_count = newpkg->files.count;
|
||||
alpm_file_t *current_file;
|
||||
/* Keep track of all files for filelist generation */
|
||||
if(files_count >= files_size) {
|
||||
size_t old_size = files_size;
|
||||
alpm_file_t *newfiles;
|
||||
if(files_size == 0) {
|
||||
files_size = 4;
|
||||
} else {
|
||||
files_size *= 2;
|
||||
}
|
||||
newfiles = realloc(newpkg->files.files,
|
||||
sizeof(alpm_file_t) * files_size);
|
||||
if(!newfiles) {
|
||||
_alpm_alloc_fail(sizeof(alpm_file_t) * files_size);
|
||||
goto error;
|
||||
}
|
||||
/* ensure all new memory is zeroed out, in both the initial
|
||||
* allocation and later reallocs */
|
||||
memset(newfiles + old_size, 0,
|
||||
sizeof(alpm_file_t) * (files_size - old_size));
|
||||
newpkg->files.files = newfiles;
|
||||
} else if(full && strcmp(entry_name, ".MTREE") == 0) {
|
||||
/* building the file list: cheap way
|
||||
* get the filelist from the mtree file rather than scanning
|
||||
* the whole archive */
|
||||
hit_mtree = build_filelist_from_mtree(handle, newpkg, archive) == 0;
|
||||
continue;
|
||||
} else if(handle_simple_path(newpkg, entry_name)) {
|
||||
continue;
|
||||
} else if(full && !hit_mtree) {
|
||||
/* building the file list: expensive way */
|
||||
if(add_entry_to_files_list(&newpkg->files, &files_size, entry, entry_name) < 0) {
|
||||
goto error;
|
||||
}
|
||||
current_file = newpkg->files.files + files_count;
|
||||
STRDUP(current_file->name, entry_name, goto error);
|
||||
current_file->size = archive_entry_size(entry);
|
||||
current_file->mode = archive_entry_mode(entry);
|
||||
newpkg->files.count++;
|
||||
}
|
||||
|
||||
if(archive_read_data_skip(archive)) {
|
||||
@@ -455,7 +639,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
}
|
||||
|
||||
/* if we are not doing a full read, see if we have all we need */
|
||||
if(!full && config) {
|
||||
if((!full || hit_mtree) && config) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -473,7 +657,7 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
}
|
||||
|
||||
_alpm_archive_read_free(archive);
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
|
||||
/* internal fields for package struct */
|
||||
newpkg->origin = ALPM_PKG_FROM_FILE;
|
||||
@@ -506,28 +690,31 @@ error:
|
||||
_alpm_pkg_free(newpkg);
|
||||
_alpm_archive_read_free(archive);
|
||||
if(fd >= 0) {
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* adopted limit from repo-add */
|
||||
#define MAX_SIGFILE_SIZE 16384
|
||||
|
||||
static int read_sigfile(const char *sigpath, unsigned char **sig)
|
||||
{
|
||||
struct stat st;
|
||||
FILE *fp;
|
||||
|
||||
if(stat(sigpath, &st) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
MALLOC(*sig, st.st_size, return -1);
|
||||
|
||||
if((fp = fopen(sigpath, "rb")) == NULL) {
|
||||
free(*sig);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(fstat(fileno(fp), &st) != 0 || st.st_size > MAX_SIGFILE_SIZE) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MALLOC(*sig, st.st_size, fclose(fp); return -1);
|
||||
|
||||
if(fread(*sig, st.st_size, 1, fp) != 1) {
|
||||
free(*sig);
|
||||
fclose(fp);
|
||||
@@ -562,7 +749,7 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(_alpm_extract_keyid(handle, filename, sig, len, &keys) == 0) {
|
||||
if(alpm_extract_keyid(handle, filename, sig, len, &keys) == 0) {
|
||||
alpm_list_t *k;
|
||||
for(k = keys; k; k = k->next) {
|
||||
char *key = k->data;
|
||||
@@ -579,6 +766,7 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
|
||||
|
||||
if(fail) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("required key missing from keyring\n"));
|
||||
free(sigpath);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -600,4 +788,4 @@ int SYMEXPORT alpm_pkg_load(alpm_handle_t *handle, const char *filename, int ful
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* be_sync.c : backend for sync databases
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* libarchive */
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "delta.h"
|
||||
#include "deps.h"
|
||||
#include "dload.h"
|
||||
#include "filelist.h"
|
||||
|
||||
static char *get_sync_dir(alpm_handle_t *handle)
|
||||
{
|
||||
@@ -88,9 +90,13 @@ static int sync_db_validate(alpm_db_t *db)
|
||||
|
||||
/* we can skip any validation if the database doesn't exist */
|
||||
if(_alpm_access(db->handle, NULL, dbpath, R_OK) != 0 && errno == ENOENT) {
|
||||
alpm_event_database_missing_t event = {
|
||||
.type = ALPM_EVENT_DATABASE_MISSING,
|
||||
.dbname = db->treename
|
||||
};
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status |= DB_STATUS_MISSING;
|
||||
EVENT(db->handle, ALPM_EVENT_DATABASE_MISSING, db->treename, NULL);
|
||||
EVENT(db->handle, &event);
|
||||
goto valid;
|
||||
}
|
||||
db->status |= DB_STATUS_EXISTS;
|
||||
@@ -169,7 +175,9 @@ valid:
|
||||
int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
{
|
||||
char *syncpath;
|
||||
const char *dbext;
|
||||
alpm_list_t *i;
|
||||
int updated = 0;
|
||||
int ret = -1;
|
||||
mode_t oldmask;
|
||||
alpm_handle_t *handle;
|
||||
@@ -182,11 +190,20 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
ASSERT(db != handle->db_local, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
ASSERT(db->servers != NULL, RET_ERR(handle, ALPM_ERR_SERVER_NONE, -1));
|
||||
|
||||
if(!(db->usage & ALPM_DB_USAGE_SYNC)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
syncpath = get_sync_dir(handle);
|
||||
if(!syncpath) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* force update of invalid databases to fix potential mismatched database/signature */
|
||||
if(db->status & DB_STATUS_INVALID) {
|
||||
force = 1;
|
||||
}
|
||||
|
||||
/* make sure we have a sane umask */
|
||||
oldmask = umask(0022);
|
||||
|
||||
@@ -199,8 +216,10 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1);
|
||||
}
|
||||
|
||||
dbext = db->handle->dbext;
|
||||
|
||||
for(i = db->servers; i; i = i->next) {
|
||||
const char *server = i->data;
|
||||
const char *server = i->data, *final_db_url = NULL;
|
||||
struct dload_payload payload;
|
||||
size_t len;
|
||||
int sig_ret = 0;
|
||||
@@ -211,18 +230,24 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
payload.max_size = 25 * 1024 * 1024;
|
||||
|
||||
/* print server + filename into a buffer */
|
||||
len = strlen(server) + strlen(db->treename) + 5;
|
||||
/* TODO fix leak syncpath and umask unset */
|
||||
MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
snprintf(payload.fileurl, len, "%s/%s.db", server, db->treename);
|
||||
len = strlen(server) + strlen(db->treename) + strlen(dbext) + 2;
|
||||
MALLOC(payload.fileurl, len,
|
||||
{
|
||||
free(syncpath);
|
||||
umask(oldmask);
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
|
||||
}
|
||||
);
|
||||
snprintf(payload.fileurl, len, "%s/%s%s", server, db->treename, dbext);
|
||||
payload.handle = handle;
|
||||
payload.force = force;
|
||||
payload.unlink_on_fail = 1;
|
||||
|
||||
ret = _alpm_download(&payload, syncpath, NULL, NULL);
|
||||
ret = _alpm_download(&payload, syncpath, NULL, &final_db_url);
|
||||
_alpm_dload_payload_reset(&payload);
|
||||
updated = (updated || ret == 0);
|
||||
|
||||
if(ret == 0 && (level & ALPM_SIG_DATABASE)) {
|
||||
if(ret != -1 && updated && (level & ALPM_SIG_DATABASE)) {
|
||||
/* an existing sig file is no good at this point */
|
||||
char *sigpath = _alpm_sigpath(handle, _alpm_db_path(db));
|
||||
if(!sigpath) {
|
||||
@@ -232,12 +257,39 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
unlink(sigpath);
|
||||
free(sigpath);
|
||||
|
||||
|
||||
/* check if the final URL from internal downloader looks reasonable */
|
||||
if(final_db_url != NULL) {
|
||||
if(strlen(final_db_url) < 3
|
||||
|| strcmp(final_db_url + strlen(final_db_url) - strlen(dbext),
|
||||
dbext) != 0) {
|
||||
final_db_url = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we downloaded a DB, we want the .sig from the same server */
|
||||
/* print server + filename into a buffer (leave space for .sig) */
|
||||
len = strlen(server) + strlen(db->treename) + 9;
|
||||
/* TODO fix leak syncpath and umask unset */
|
||||
MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
snprintf(payload.fileurl, len, "%s/%s.db.sig", server, db->treename);
|
||||
if(final_db_url != NULL) {
|
||||
/* print final_db_url into a buffer (leave space for .sig) */
|
||||
len = strlen(final_db_url) + 5;
|
||||
} else {
|
||||
/* print server + filename into a buffer (leave space for separator and .sig) */
|
||||
len = strlen(server) + strlen(db->treename) + strlen(dbext) + 6;
|
||||
}
|
||||
|
||||
MALLOC(payload.fileurl, len,
|
||||
{
|
||||
free(syncpath);
|
||||
umask(oldmask);
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
|
||||
}
|
||||
);
|
||||
|
||||
if(final_db_url != NULL) {
|
||||
snprintf(payload.fileurl, len, "%s.sig", final_db_url);
|
||||
} else {
|
||||
snprintf(payload.fileurl, len, "%s/%s%s.sig", server, db->treename, dbext);
|
||||
}
|
||||
|
||||
payload.handle = handle;
|
||||
payload.force = 1;
|
||||
payload.errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL);
|
||||
@@ -256,37 +308,32 @@ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db)
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 1) {
|
||||
/* files match, do nothing */
|
||||
handle->pm_errno = 0;
|
||||
goto cleanup;
|
||||
} else if(ret == -1) {
|
||||
if(updated) {
|
||||
/* Cache needs to be rebuilt */
|
||||
_alpm_db_free_pkgcache(db);
|
||||
|
||||
/* clear all status flags regarding validity/existence */
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status &= ~DB_STATUS_INVALID;
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status &= ~DB_STATUS_MISSING;
|
||||
|
||||
/* if the download failed skip validation to preserve the download error */
|
||||
if(ret != -1 && sync_db_validate(db) != 0) {
|
||||
/* pm_errno should be set */
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == -1) {
|
||||
/* pm_errno was set by the download code */
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n",
|
||||
alpm_strerror(handle->pm_errno));
|
||||
goto cleanup;
|
||||
} else {
|
||||
handle->pm_errno = 0;
|
||||
}
|
||||
|
||||
/* Cache needs to be rebuilt */
|
||||
_alpm_db_free_pkgcache(db);
|
||||
|
||||
/* clear all status flags regarding validity/existence */
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status &= ~DB_STATUS_INVALID;
|
||||
db->status &= ~DB_STATUS_EXISTS;
|
||||
db->status &= ~DB_STATUS_MISSING;
|
||||
|
||||
if(sync_db_validate(db)) {
|
||||
/* pm_errno should be set */
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if(_alpm_handle_unlock(handle)) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("could not remove lock file %s\n"),
|
||||
handle->lockfile);
|
||||
}
|
||||
_alpm_handle_unlock(handle);
|
||||
free(syncpath);
|
||||
umask(oldmask);
|
||||
return ret;
|
||||
@@ -408,14 +455,16 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive)
|
||||
/* assume it is at least somewhat compressed */
|
||||
per_package = 500;
|
||||
}
|
||||
|
||||
return (size_t)((st->st_size / per_package) + 1);
|
||||
}
|
||||
|
||||
static int sync_db_populate(alpm_db_t *db)
|
||||
{
|
||||
const char *dbpath;
|
||||
size_t est_count;
|
||||
int count, fd;
|
||||
size_t est_count, count;
|
||||
int fd;
|
||||
int ret = 0;
|
||||
struct stat buf;
|
||||
struct archive *archive;
|
||||
struct archive_entry *entry;
|
||||
@@ -440,10 +489,16 @@ static int sync_db_populate(alpm_db_t *db)
|
||||
}
|
||||
est_count = estimate_package_count(&buf, archive);
|
||||
|
||||
/* currently only .files dbs contain file lists - make flexible when required*/
|
||||
if(strcmp(db->handle->dbext, ".files") == 0) {
|
||||
/* files databases are about four times larger on average */
|
||||
est_count /= 4;
|
||||
}
|
||||
|
||||
db->pkgcache = _alpm_pkghash_create(est_count);
|
||||
if(db->pkgcache == NULL) {
|
||||
db->handle->pm_errno = ALPM_ERR_MEMORY;
|
||||
count = -1;
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -465,18 +520,18 @@ static int sync_db_populate(alpm_db_t *db)
|
||||
count = alpm_list_count(db->pkgcache->list);
|
||||
if(count > 0) {
|
||||
db->pkgcache->list = alpm_list_msort(db->pkgcache->list,
|
||||
(size_t)count, _alpm_pkg_cmp);
|
||||
count, _alpm_pkg_cmp);
|
||||
}
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG,
|
||||
"added %d packages to package cache for db '%s'\n",
|
||||
"added %zu packages to package cache for db '%s'\n",
|
||||
count, db->treename);
|
||||
|
||||
cleanup:
|
||||
_alpm_archive_read_free(archive);
|
||||
if(fd >= 0) {
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
}
|
||||
return count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function validates %FILENAME%. filename must be between 3 and
|
||||
@@ -528,7 +583,7 @@ static int _alpm_validate_filename(alpm_db_t *db, const char *pkgname,
|
||||
#define READ_AND_SPLITDEP(f) do { \
|
||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
|
||||
if(_alpm_strip_newline(buf.line, buf.real_line_size) == 0) break; \
|
||||
f = alpm_list_add(f, _alpm_splitdep(line)); \
|
||||
f = alpm_list_add(f, alpm_dep_from_string(line)); \
|
||||
} while(1) /* note the while(1) and not (0) */
|
||||
|
||||
static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
@@ -561,7 +616,16 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(filename == NULL) {
|
||||
/* A file exists outside of a subdirectory. This isn't a read error, so return
|
||||
* success and try to continue on. */
|
||||
_alpm_log(db->handle, ALPM_LOG_WARNING, _("unknown database file: %s\n"),
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|
||||
|| strcmp(filename, "files") == 0
|
||||
|| (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) {
|
||||
int ret;
|
||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||
@@ -588,6 +652,8 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
if(_alpm_validate_filename(db, pkg->name, pkg->filename) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if(strcmp(line, "%BASE%") == 0) {
|
||||
READ_AND_STORE(pkg->base);
|
||||
} else if(strcmp(line, "%DESC%") == 0) {
|
||||
READ_AND_STORE(pkg->desc);
|
||||
} else if(strcmp(line, "%GROUPS%") == 0) {
|
||||
@@ -645,6 +711,37 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
pkg->deltas = alpm_list_add(pkg->deltas,
|
||||
_alpm_delta_parse(db->handle, line));
|
||||
}
|
||||
} else if(strcmp(line, "%FILES%") == 0) {
|
||||
/* TODO: this could lazy load if there is future demand */
|
||||
size_t files_count = 0, files_size = 0;
|
||||
alpm_file_t *files = NULL;
|
||||
|
||||
while(1) {
|
||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) {
|
||||
goto error;
|
||||
}
|
||||
line = buf.line;
|
||||
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!_alpm_greedy_grow((void **)&files, &files_size,
|
||||
(files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
|
||||
goto error;
|
||||
}
|
||||
STRDUP(files[files_count].name, line, goto error);
|
||||
files_count++;
|
||||
}
|
||||
/* attempt to hand back any memory we don't need */
|
||||
if(files_count > 0) {
|
||||
files = realloc(files, sizeof(alpm_file_t) * files_count);
|
||||
/* make sure the list is sorted */
|
||||
qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp);
|
||||
} else {
|
||||
FREE(files);
|
||||
}
|
||||
pkg->files.count = files_count;
|
||||
pkg->files.files = files;
|
||||
}
|
||||
}
|
||||
if(ret != ARCHIVE_EOF) {
|
||||
@@ -653,8 +750,6 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
*likely_pkg = pkg;
|
||||
} else if(strcmp(filename, "deltas") == 0) {
|
||||
/* skip reading delta files if UseDelta is unset */
|
||||
} else if(strcmp(filename, "files") == 0) {
|
||||
/* currently do nothing with this file */
|
||||
} else {
|
||||
/* unknown database file */
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename);
|
||||
@@ -681,7 +776,7 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "registering sync database '%s'\n", treename);
|
||||
|
||||
#ifndef HAVE_LIBGPGME
|
||||
if((level &= ~ALPM_SIG_PACKAGE_SET) != 0 && level != ALPM_SIG_USE_DEFAULT) {
|
||||
if(level != ALPM_SIG_USE_DEFAULT) {
|
||||
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL);
|
||||
}
|
||||
#endif
|
||||
@@ -700,4 +795,4 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
|
||||
return db;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* conflict.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org>
|
||||
@@ -48,22 +48,27 @@ static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2,
|
||||
{
|
||||
alpm_conflict_t *conflict;
|
||||
|
||||
MALLOC(conflict, sizeof(alpm_conflict_t), return NULL);
|
||||
CALLOC(conflict, 1, sizeof(alpm_conflict_t), return NULL);
|
||||
|
||||
conflict->package1_hash = pkg1->name_hash;
|
||||
conflict->package2_hash = pkg2->name_hash;
|
||||
STRDUP(conflict->package1, pkg1->name, return NULL);
|
||||
STRDUP(conflict->package2, pkg2->name, return NULL);
|
||||
STRDUP(conflict->package1, pkg1->name, goto error);
|
||||
STRDUP(conflict->package2, pkg2->name, goto error);
|
||||
conflict->reason = reason;
|
||||
|
||||
return conflict;
|
||||
|
||||
error:
|
||||
alpm_conflict_free(conflict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free a conflict and its members.
|
||||
*/
|
||||
void _alpm_conflict_free(alpm_conflict_t *conflict)
|
||||
void SYMEXPORT alpm_conflict_free(alpm_conflict_t *conflict)
|
||||
{
|
||||
ASSERT(conflict != NULL, return);
|
||||
FREE(conflict->package2);
|
||||
FREE(conflict->package1);
|
||||
FREE(conflict);
|
||||
@@ -79,11 +84,15 @@ alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict)
|
||||
|
||||
newconflict->package1_hash = conflict->package1_hash;
|
||||
newconflict->package2_hash = conflict->package2_hash;
|
||||
STRDUP(newconflict->package1, conflict->package1, return NULL);
|
||||
STRDUP(newconflict->package2, conflict->package2, return NULL);
|
||||
STRDUP(newconflict->package1, conflict->package1, goto error);
|
||||
STRDUP(newconflict->package2, conflict->package2, goto error);
|
||||
newconflict->reason = conflict->reason;
|
||||
|
||||
return newconflict;
|
||||
|
||||
error:
|
||||
alpm_conflict_free(newconflict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +144,7 @@ static int add_conflict(alpm_handle_t *handle, alpm_list_t **baddeps,
|
||||
pkg1->name, pkg2->name, conflict_str);
|
||||
free(conflict_str);
|
||||
} else {
|
||||
_alpm_conflict_free(conflict);
|
||||
alpm_conflict_free(conflict);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -265,7 +274,7 @@ static alpm_list_t *add_fileconflict(alpm_handle_t *handle,
|
||||
alpm_pkg_t *pkg1, alpm_pkg_t *pkg2)
|
||||
{
|
||||
alpm_fileconflict_t *conflict;
|
||||
MALLOC(conflict, sizeof(alpm_fileconflict_t), goto error);
|
||||
CALLOC(conflict, 1, sizeof(alpm_fileconflict_t), goto error);
|
||||
|
||||
STRDUP(conflict->target, pkg1->name, goto error);
|
||||
STRDUP(conflict->file, filestr, goto error);
|
||||
@@ -284,14 +293,16 @@ static alpm_list_t *add_fileconflict(alpm_handle_t *handle,
|
||||
return conflicts;
|
||||
|
||||
error:
|
||||
alpm_fileconflict_free(conflict);
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, conflicts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees a conflict and its members.
|
||||
*/
|
||||
void _alpm_fileconflict_free(alpm_fileconflict_t *conflict)
|
||||
void SYMEXPORT alpm_fileconflict_free(alpm_fileconflict_t *conflict)
|
||||
{
|
||||
ASSERT(conflict != NULL, return);
|
||||
FREE(conflict->ctarget);
|
||||
FREE(conflict->file);
|
||||
FREE(conflict->target);
|
||||
@@ -299,97 +310,81 @@ void _alpm_fileconflict_free(alpm_fileconflict_t *conflict)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Recursively checks if a package owns all subdirectories and files in
|
||||
* a directory.
|
||||
* @brief Recursively checks if a set of packages own all subdirectories and
|
||||
* files in a directory.
|
||||
*
|
||||
* @param handle the context handle
|
||||
* @param dirpath path of the directory to check
|
||||
* @param pkg package being checked against
|
||||
* @param pkgs packages being checked against
|
||||
*
|
||||
* @return 1 if a package owns all subdirectories and files or a directory
|
||||
* cannot be opened, 0 otherwise
|
||||
* @return 1 if a package owns all subdirectories and files, 0 otherwise
|
||||
*/
|
||||
static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath,
|
||||
alpm_pkg_t *pkg)
|
||||
static int dir_belongsto_pkgs(alpm_handle_t *handle, const char *dirpath,
|
||||
alpm_list_t *pkgs)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
struct stat sbuf;
|
||||
char path[PATH_MAX];
|
||||
char abspath[PATH_MAX];
|
||||
char path[PATH_MAX], full_path[PATH_MAX];
|
||||
DIR *dir;
|
||||
struct dirent *ent = NULL;
|
||||
const char *root = handle->root;
|
||||
|
||||
/* check directory is actually in package - used for subdirectory checks */
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(pkg));
|
||||
if(!alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"directory %s not in package %s\n", dirpath, pkg->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: this is an overly strict check but currently pacman will not
|
||||
* overwrite a directory with a file (case 10/11 in add.c). Adjusting that
|
||||
* is not simple as even if the directory is being unowned by a conflicting
|
||||
* package, pacman does not sort this to ensure all required directory
|
||||
* "removals" happen before installation of file/symlink */
|
||||
|
||||
/* check that no other _installed_ package owns the directory */
|
||||
for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
|
||||
if(pkg == i->data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(i->data));
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"file %s also in package %s\n", dirpath,
|
||||
((alpm_pkg_t*)i->data)->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* check all files in directory are owned by the package */
|
||||
snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);
|
||||
dir = opendir(abspath);
|
||||
snprintf(full_path, PATH_MAX, "%s%s", handle->root, dirpath);
|
||||
dir = opendir(full_path);
|
||||
if(dir == NULL) {
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while((ent = readdir(dir)) != NULL) {
|
||||
const char *name = ent->d_name;
|
||||
int owned = 0, is_dir = 0;
|
||||
alpm_list_t *i;
|
||||
struct stat sbuf;
|
||||
|
||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
snprintf(path, PATH_MAX, "%s%s", dirpath, name);
|
||||
snprintf(abspath, PATH_MAX, "%s%s", root, path);
|
||||
if(stat(abspath, &sbuf) != 0) {
|
||||
continue;
|
||||
|
||||
snprintf(full_path, PATH_MAX, "%s%s%s", handle->root, dirpath, name);
|
||||
|
||||
if(lstat(full_path, &sbuf) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "could not stat %s\n", full_path);
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
if(S_ISDIR(sbuf.st_mode)) {
|
||||
if(dir_belongsto_pkg(handle, path, pkg)) {
|
||||
continue;
|
||||
} else {
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(pkg));
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) {
|
||||
continue;
|
||||
} else {
|
||||
closedir(dir);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"unowned file %s found in directory\n", path);
|
||||
return 0;
|
||||
is_dir = S_ISDIR(sbuf.st_mode);
|
||||
|
||||
snprintf(path, PATH_MAX, "%s%s%s", dirpath, name, is_dir ? "/" : "");
|
||||
|
||||
for(i = pkgs; i && !owned; i = i->next) {
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(i->data), path)) {
|
||||
owned = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(owned && is_dir) {
|
||||
owned = dir_belongsto_pkgs(handle, path, pkgs);
|
||||
}
|
||||
|
||||
if(!owned) {
|
||||
closedir(dir);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"unowned file %s found in directory\n", path);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static alpm_list_t *alpm_db_find_file_owners(alpm_db_t* db, const char *path)
|
||||
{
|
||||
alpm_list_t *i, *owners = NULL;
|
||||
for(i = alpm_db_get_pkgcache(db); i; i = i->next) {
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(i->data), path)) {
|
||||
owners = alpm_list_add(owners, i->data);
|
||||
}
|
||||
}
|
||||
return owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find file conflicts that may occur during the transaction.
|
||||
*
|
||||
@@ -417,11 +412,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
|
||||
rootlen = strlen(handle->root);
|
||||
|
||||
/* make sure all files to be installed have been resolved */
|
||||
for(i = upgrade; i; i = i->next) {
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(i->data));
|
||||
}
|
||||
|
||||
/* TODO this whole function needs a huge change, which hopefully will
|
||||
* be possible with real transactions. Right now we only do half as much
|
||||
* here as we do when we actually extract files in add.c with our 12
|
||||
@@ -470,7 +460,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
|
||||
conflicts = add_fileconflict(handle, conflicts, path, p1, p2);
|
||||
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
||||
FREELIST(conflicts);
|
||||
alpm_list_free_inner(conflicts,
|
||||
(alpm_list_fn_free) alpm_conflict_free);
|
||||
alpm_list_free(conflicts);
|
||||
alpm_list_free(common_files);
|
||||
return NULL;
|
||||
}
|
||||
@@ -491,7 +483,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
* be freed. */
|
||||
if(dbpkg) {
|
||||
/* older ver of package currently installed */
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(dbpkg));
|
||||
tmpfiles = _alpm_filelist_difference(alpm_pkg_get_files(p1),
|
||||
alpm_pkg_get_files(dbpkg));
|
||||
} else {
|
||||
@@ -499,7 +490,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
alpm_filelist_t *fl = alpm_pkg_get_files(p1);
|
||||
size_t filenum;
|
||||
for(filenum = 0; filenum < fl->count; filenum++) {
|
||||
tmpfiles = alpm_list_add(tmpfiles, fl->resolved_path[filenum]);
|
||||
tmpfiles = alpm_list_add(tmpfiles, fl->files[filenum].name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,38 +505,47 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
size_t pathlen;
|
||||
|
||||
pathlen = snprintf(path, PATH_MAX, "%s%s", handle->root, filestr);
|
||||
relative_path = path + rootlen;
|
||||
|
||||
/* stat the file - if it exists, do some checks */
|
||||
if(_alpm_lstat(path, &lsbuf) != 0) {
|
||||
if(llstat(path, &lsbuf) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "checking possible conflict: %s\n", path);
|
||||
|
||||
if(filestr[strlen(filestr) - 1] == '/') {
|
||||
struct stat sbuf;
|
||||
if(path[pathlen - 1] == '/') {
|
||||
if(S_ISDIR(lsbuf.st_mode)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "file is a directory, not a conflict\n");
|
||||
continue;
|
||||
}
|
||||
stat(path, &sbuf);
|
||||
if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"file is a symlink to a dir, hopefully not a conflict\n");
|
||||
continue;
|
||||
}
|
||||
/* if we made it to here, we want all subsequent path comparisons to
|
||||
* not include the trailing slash. This allows things like file ->
|
||||
* directory replacements. */
|
||||
path[pathlen - 1] = '\0';
|
||||
}
|
||||
|
||||
relative_path = path + rootlen;
|
||||
/* Check if the directory was a file in dbpkg */
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_path)) {
|
||||
size_t fslen = strlen(filestr);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"replacing package file with a directory, not a conflict\n");
|
||||
resolved_conflict = 1;
|
||||
|
||||
/* go ahead and skip any files inside filestr as they will
|
||||
* necessarily be resolved by replacing the file with a dir
|
||||
* NOTE: afterward, j will point to the last file inside filestr */
|
||||
for( ; j->next; j = j->next) {
|
||||
const char *filestr2 = j->next->data;
|
||||
if(strncmp(filestr, filestr2, fslen) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check remove list (will we remove the conflicting local file?) */
|
||||
for(k = rem; k && !resolved_conflict; k = k->next) {
|
||||
alpm_pkg_t *rempkg = k->data;
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(rempkg));
|
||||
if(rempkg && alpm_filelist_contains(alpm_pkg_get_files(rempkg),
|
||||
relative_path)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
@@ -556,62 +556,79 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
|
||||
/* Look at all the targets to see if file has changed hands */
|
||||
for(k = upgrade; k && !resolved_conflict; k = k->next) {
|
||||
alpm_pkg_t *p2 = k->data;
|
||||
if(!p2 || strcmp(p1->name, p2->name) == 0) {
|
||||
alpm_pkg_t *localp2, *p2 = k->data;
|
||||
if(!p2 || p1 == p2) {
|
||||
/* skip p1; both p1 and p2 come directly from the upgrade list
|
||||
* so they can be compared directly */
|
||||
continue;
|
||||
}
|
||||
alpm_pkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name);
|
||||
localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name);
|
||||
|
||||
/* localp2->files will be removed (target conflicts are handled by CHECK 1) */
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(localp2));
|
||||
if(localp2 && alpm_filelist_contains(alpm_pkg_get_files(localp2), filestr)) {
|
||||
if(localp2 && alpm_filelist_contains(alpm_pkg_get_files(localp2), relative_path)) {
|
||||
size_t fslen = strlen(filestr);
|
||||
|
||||
/* skip removal of file, but not add. this will prevent a second
|
||||
* package from removing the file when it was already installed
|
||||
* by its new owner (whether the file is in backup array or not */
|
||||
handle->trans->skip_remove =
|
||||
alpm_list_add(handle->trans->skip_remove, strdup(filestr));
|
||||
alpm_list_add(handle->trans->skip_remove, strdup(relative_path));
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"file changed packages, adding to remove skiplist\n");
|
||||
resolved_conflict = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if all files of the dir belong to the installed pkg */
|
||||
if(!resolved_conflict && S_ISDIR(lsbuf.st_mode) && dbpkg) {
|
||||
char *dir = malloc(strlen(filestr) + 2);
|
||||
sprintf(dir, "%s/", filestr);
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"checking if all files in %s belong to %s\n",
|
||||
dir, dbpkg->name);
|
||||
resolved_conflict = dir_belongsto_pkg(handle, dir, dbpkg);
|
||||
}
|
||||
free(dir);
|
||||
}
|
||||
|
||||
/* check if a component of the filepath was a link. canonicalize the path
|
||||
* and look for it in the old package. note that the actual file under
|
||||
* consideration cannot itself be a link, as it might be unowned- path
|
||||
* components can be safely checked as all directories are "unowned". */
|
||||
if(!resolved_conflict && dbpkg && !S_ISLNK(lsbuf.st_mode)) {
|
||||
char rpath[PATH_MAX];
|
||||
if(realpath(path, rpath)) {
|
||||
const char *relative_rpath = rpath + rootlen;
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"package contained the resolved realpath\n");
|
||||
resolved_conflict = 1;
|
||||
if(filestr[fslen - 1] == '/') {
|
||||
/* replacing a file with a directory:
|
||||
* go ahead and skip any files inside filestr as they will
|
||||
* necessarily be resolved by replacing the file with a dir
|
||||
* NOTE: afterward, j will point to the last file inside filestr */
|
||||
for( ; j->next; j = j->next) {
|
||||
const char *filestr2 = j->next->data;
|
||||
if(strncmp(filestr, filestr2, fslen) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if all files of the dir belong to the installed pkg */
|
||||
if(!resolved_conflict && S_ISDIR(lsbuf.st_mode)) {
|
||||
alpm_list_t *owners;
|
||||
char *dir = malloc(strlen(relative_path) + 2);
|
||||
sprintf(dir, "%s/", relative_path);
|
||||
|
||||
owners = alpm_db_find_file_owners(handle->db_local, dir);
|
||||
if(owners) {
|
||||
alpm_list_t *pkgs = NULL, *diff;
|
||||
|
||||
if(dbpkg) {
|
||||
pkgs = alpm_list_add(pkgs, dbpkg);
|
||||
}
|
||||
pkgs = alpm_list_join(pkgs, alpm_list_copy(rem));
|
||||
if((diff = alpm_list_diff(owners, pkgs, _alpm_pkg_cmp))) {
|
||||
/* dir is owned by files we aren't removing */
|
||||
/* TODO: with better commit ordering, we may be able to check
|
||||
* against upgrades as well */
|
||||
alpm_list_free(diff);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"checking if all files in %s belong to removed packages\n",
|
||||
dir);
|
||||
resolved_conflict = dir_belongsto_pkgs(handle, dir, owners);
|
||||
}
|
||||
alpm_list_free(pkgs);
|
||||
alpm_list_free(owners);
|
||||
}
|
||||
free(dir);
|
||||
}
|
||||
|
||||
/* is the file unowned and in the backup list of the new package? */
|
||||
if(!resolved_conflict && _alpm_needbackup(filestr, p1)) {
|
||||
if(!resolved_conflict && _alpm_needbackup(relative_path, p1)) {
|
||||
alpm_list_t *local_pkgs = _alpm_db_get_pkgcache(handle->db_local);
|
||||
int found = 0;
|
||||
for(k = local_pkgs; k && !found; k = k->next) {
|
||||
_alpm_filelist_resolve(handle, alpm_pkg_get_files(k->data));
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(k->data), filestr)) {
|
||||
if(alpm_filelist_contains(alpm_pkg_get_files(k->data), relative_path)) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
@@ -633,7 +650,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
if(!resolved_conflict) {
|
||||
conflicts = add_fileconflict(handle, conflicts, path, p1, NULL);
|
||||
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
||||
FREELIST(conflicts);
|
||||
alpm_list_free_inner(conflicts,
|
||||
(alpm_list_fn_free) alpm_conflict_free);
|
||||
alpm_list_free(conflicts);
|
||||
alpm_list_free(tmpfiles);
|
||||
return NULL;
|
||||
}
|
||||
@@ -647,4 +666,4 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* conflict.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,22 +17,19 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_CONFLICT_H
|
||||
#define _ALPM_CONFLICT_H
|
||||
#ifndef ALPM_CONFLICT_H
|
||||
#define ALPM_CONFLICT_H
|
||||
|
||||
#include "alpm.h"
|
||||
#include "db.h"
|
||||
#include "package.h"
|
||||
|
||||
alpm_conflict_t *_alpm_conflict_dup(const alpm_conflict_t *conflict);
|
||||
void _alpm_conflict_free(alpm_conflict_t *conflict);
|
||||
alpm_list_t *_alpm_innerconflicts(alpm_handle_t *handle, alpm_list_t *packages);
|
||||
alpm_list_t *_alpm_outerconflicts(alpm_db_t *db, alpm_list_t *packages);
|
||||
alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||
alpm_list_t *upgrade, alpm_list_t *remove);
|
||||
|
||||
void _alpm_fileconflict_free(alpm_fileconflict_t *conflict);
|
||||
#endif /* ALPM_CONFLICT_H */
|
||||
|
||||
#endif /* _ALPM_CONFLICT_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* db.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
|
||||
@@ -46,13 +46,27 @@
|
||||
alpm_db_t SYMEXPORT *alpm_register_syncdb(alpm_handle_t *handle,
|
||||
const char *treename, alpm_siglevel_t level)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
|
||||
/* Sanity checks */
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
ASSERT(treename != NULL && strlen(treename) != 0,
|
||||
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
|
||||
ASSERT(!strchr(treename, '/'), RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
|
||||
/* Do not register a database if a transaction is on-going */
|
||||
ASSERT(handle->trans == NULL, RET_ERR(handle, ALPM_ERR_TRANS_NOT_NULL, NULL));
|
||||
|
||||
/* ensure database name is unique */
|
||||
if(strcmp(treename, "local") == 0) {
|
||||
RET_ERR(handle, ALPM_ERR_DB_NOT_NULL, NULL);
|
||||
}
|
||||
for(i = handle->dbs_sync; i; i = i->next) {
|
||||
alpm_db_t *d = i->data;
|
||||
if(strcmp(treename, d->treename) == 0) {
|
||||
RET_ERR(handle, ALPM_ERR_DB_NOT_NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return _alpm_db_register_sync(handle, treename, level);
|
||||
}
|
||||
|
||||
@@ -292,6 +306,23 @@ alpm_list_t SYMEXPORT *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
|
||||
return _alpm_db_search(db, needles);
|
||||
}
|
||||
|
||||
/** Sets the usage bitmask for a repo */
|
||||
int SYMEXPORT alpm_db_set_usage(alpm_db_t *db, alpm_db_usage_t usage)
|
||||
{
|
||||
ASSERT(db != NULL, return -1);
|
||||
db->usage = usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Gets the usage bitmask for a repo */
|
||||
int SYMEXPORT alpm_db_get_usage(alpm_db_t *db, alpm_db_usage_t *usage)
|
||||
{
|
||||
ASSERT(db != NULL, return -1);
|
||||
ASSERT(usage != NULL, return -1);
|
||||
*usage = db->usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -300,18 +331,20 @@ alpm_db_t *_alpm_db_new(const char *treename, int is_local)
|
||||
alpm_db_t *db;
|
||||
|
||||
CALLOC(db, 1, sizeof(alpm_db_t), return NULL);
|
||||
STRDUP(db->treename, treename, return NULL);
|
||||
STRDUP(db->treename, treename, FREE(db); return NULL);
|
||||
if(is_local) {
|
||||
db->status |= DB_STATUS_LOCAL;
|
||||
} else {
|
||||
db->status &= ~DB_STATUS_LOCAL;
|
||||
}
|
||||
db->usage = ALPM_DB_USAGE_ALL;
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
void _alpm_db_free(alpm_db_t *db)
|
||||
{
|
||||
ASSERT(db != NULL, return);
|
||||
/* cleanup pkgcache */
|
||||
_alpm_db_free_pkgcache(db);
|
||||
/* cleanup server list */
|
||||
@@ -343,10 +376,12 @@ const char *_alpm_db_path(alpm_db_t *db)
|
||||
CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
|
||||
sprintf(db->_path, "%s%s/", dbpath, db->treename);
|
||||
} else {
|
||||
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + 4;
|
||||
const char *dbext = db->handle->dbext;
|
||||
|
||||
pathsize = strlen(dbpath) + 5 + strlen(db->treename) + strlen(dbext) + 1;
|
||||
CALLOC(db->_path, 1, pathsize, RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
|
||||
/* all sync DBs now reside in the sync/ subdir of the dbpath */
|
||||
sprintf(db->_path, "%ssync/%s.db", dbpath, db->treename);
|
||||
sprintf(db->_path, "%ssync/%s%s", dbpath, db->treename, dbext);
|
||||
}
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "database path for tree %s set to %s\n",
|
||||
db->treename, db->_path);
|
||||
@@ -365,6 +400,11 @@ alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
|
||||
{
|
||||
const alpm_list_t *i, *j, *k;
|
||||
alpm_list_t *ret = NULL;
|
||||
|
||||
if(!(db->usage & ALPM_DB_USAGE_SEARCH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy the pkgcache- we will free the list var after each needle */
|
||||
alpm_list_t *list = alpm_list_copy(_alpm_db_get_pkgcache(db));
|
||||
|
||||
@@ -421,7 +461,8 @@ alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles)
|
||||
|
||||
if(matched != NULL) {
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG,
|
||||
"search target '%s' matched '%s'\n", targ, matched);
|
||||
"search target '%s' matched '%s' on package '%s'\n",
|
||||
targ, matched, name);
|
||||
ret = alpm_list_add(ret, pkg);
|
||||
}
|
||||
}
|
||||
@@ -504,7 +545,10 @@ alpm_pkghash_t *_alpm_db_get_pkgcache_hash(alpm_db_t *db)
|
||||
}
|
||||
|
||||
if(!(db->status & DB_STATUS_PKGCACHE)) {
|
||||
load_pkgcache(db);
|
||||
if(load_pkgcache(db)) {
|
||||
/* handle->error set in local/sync-db-populate */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return db->pkgcache;
|
||||
@@ -524,18 +568,27 @@ alpm_list_t *_alpm_db_get_pkgcache(alpm_db_t *db)
|
||||
/* "duplicate" pkg then add it to pkgcache */
|
||||
int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg)
|
||||
{
|
||||
alpm_pkg_t *newpkg;
|
||||
alpm_pkg_t *newpkg = NULL;
|
||||
|
||||
if(db == NULL || pkg == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(_alpm_pkg_dup(pkg, &newpkg)) {
|
||||
/* we return memory on "non-fatal" error in _alpm_pkg_dup */
|
||||
_alpm_pkg_free(newpkg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
|
||||
newpkg->name, db->treename);
|
||||
if(newpkg->origin == ALPM_PKG_FROM_FILE) {
|
||||
free(newpkg->origin_data.file);
|
||||
}
|
||||
newpkg->origin = (db->status & DB_STATUS_LOCAL)
|
||||
? ALPM_PKG_FROM_LOCALDB
|
||||
: ALPM_PKG_FROM_SYNCDB;
|
||||
newpkg->origin_data.db = db;
|
||||
db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg);
|
||||
|
||||
free_groupcache(db);
|
||||
@@ -671,4 +724,4 @@ alpm_group_t *_alpm_db_get_groupfromcache(alpm_db_t *db, const char *target)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* db.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
||||
@@ -19,8 +19,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_DB_H
|
||||
#define _ALPM_DB_H
|
||||
#ifndef ALPM_DB_H
|
||||
#define ALPM_DB_H
|
||||
|
||||
/* libarchive */
|
||||
#include <archive.h>
|
||||
@@ -32,14 +32,15 @@
|
||||
|
||||
/* Database entries */
|
||||
typedef enum _alpm_dbinfrq_t {
|
||||
INFRQ_BASE = 1,
|
||||
INFRQ_BASE = (1 << 0),
|
||||
INFRQ_DESC = (1 << 1),
|
||||
INFRQ_FILES = (1 << 2),
|
||||
INFRQ_SCRIPTLET = (1 << 3),
|
||||
INFRQ_DSIZE = (1 << 4),
|
||||
/* ALL should be info stored in the package or database */
|
||||
INFRQ_ALL = 0x1F,
|
||||
INFRQ_ERROR = (1 << 31)
|
||||
INFRQ_ALL = INFRQ_BASE | INFRQ_DESC | INFRQ_FILES |
|
||||
INFRQ_SCRIPTLET | INFRQ_DSIZE,
|
||||
INFRQ_ERROR = (1 << 30)
|
||||
} alpm_dbinfrq_t;
|
||||
|
||||
/** Database status. Bitflags. */
|
||||
@@ -73,6 +74,7 @@ struct __alpm_db_t {
|
||||
/* flags determining validity, local, loaded caches, etc. */
|
||||
enum _alpm_dbstatus_t status;
|
||||
alpm_siglevel_t siglevel;
|
||||
alpm_db_usage_t usage;
|
||||
};
|
||||
|
||||
|
||||
@@ -105,6 +107,6 @@ alpm_pkg_t *_alpm_db_get_pkgfromcache(alpm_db_t *db, const char *target);
|
||||
alpm_list_t *_alpm_db_get_groupcache(alpm_db_t *db);
|
||||
alpm_group_t *_alpm_db_get_groupfromcache(alpm_db_t *db, const char *target);
|
||||
|
||||
#endif /* _ALPM_DB_H */
|
||||
#endif /* ALPM_DB_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* delta.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -306,10 +306,10 @@ alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line)
|
||||
|
||||
/* start at index 1 -- match 0 is the entire match */
|
||||
len = pmatch[1].rm_eo - pmatch[1].rm_so;
|
||||
STRNDUP(delta->delta, &line[pmatch[1].rm_so], len, return NULL);
|
||||
STRNDUP(delta->delta, &line[pmatch[1].rm_so], len, goto error);
|
||||
|
||||
len = pmatch[2].rm_eo - pmatch[2].rm_so;
|
||||
STRNDUP(delta->delta_md5, &line[pmatch[2].rm_so], len, return NULL);
|
||||
STRNDUP(delta->delta_md5, &line[pmatch[2].rm_so], len, goto error);
|
||||
|
||||
len = pmatch[3].rm_eo - pmatch[3].rm_so;
|
||||
if(len < sizeof(filesize)) {
|
||||
@@ -319,18 +319,23 @@ alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line)
|
||||
}
|
||||
|
||||
len = pmatch[4].rm_eo - pmatch[4].rm_so;
|
||||
STRNDUP(delta->from, &line[pmatch[4].rm_so], len, return NULL);
|
||||
STRNDUP(delta->from, &line[pmatch[4].rm_so], len, goto error);
|
||||
|
||||
len = pmatch[5].rm_eo - pmatch[5].rm_so;
|
||||
STRNDUP(delta->to, &line[pmatch[5].rm_so], len, return NULL);
|
||||
STRNDUP(delta->to, &line[pmatch[5].rm_so], len, goto error);
|
||||
|
||||
return delta;
|
||||
|
||||
error:
|
||||
_alpm_delta_free(delta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef NUM_MATCHES
|
||||
|
||||
void _alpm_delta_free(alpm_delta_t *delta)
|
||||
{
|
||||
ASSERT(delta != NULL, return);
|
||||
FREE(delta->delta);
|
||||
FREE(delta->delta_md5);
|
||||
FREE(delta->from);
|
||||
@@ -342,14 +347,18 @@ alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta)
|
||||
{
|
||||
alpm_delta_t *newdelta;
|
||||
CALLOC(newdelta, 1, sizeof(alpm_delta_t), return NULL);
|
||||
STRDUP(newdelta->delta, delta->delta, return NULL);
|
||||
STRDUP(newdelta->delta_md5, delta->delta_md5, return NULL);
|
||||
STRDUP(newdelta->from, delta->from, return NULL);
|
||||
STRDUP(newdelta->to, delta->to, return NULL);
|
||||
STRDUP(newdelta->delta, delta->delta, goto error);
|
||||
STRDUP(newdelta->delta_md5, delta->delta_md5, goto error);
|
||||
STRDUP(newdelta->from, delta->from, goto error);
|
||||
STRDUP(newdelta->to, delta->to, goto error);
|
||||
newdelta->delta_size = delta->delta_size;
|
||||
newdelta->download_size = delta->download_size;
|
||||
|
||||
return newdelta;
|
||||
|
||||
error:
|
||||
_alpm_delta_free(newdelta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* delta.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_DELTA_H
|
||||
#define _ALPM_DELTA_H
|
||||
#ifndef ALPM_DELTA_H
|
||||
#define ALPM_DELTA_H
|
||||
|
||||
#include <sys/types.h> /* off_t */
|
||||
|
||||
@@ -30,6 +30,6 @@ alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta);
|
||||
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
|
||||
const char *to, alpm_list_t **path);
|
||||
|
||||
#endif /* _ALPM_DELTA_H */
|
||||
#endif /* ALPM_DELTA_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* deps.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
||||
@@ -35,8 +35,9 @@
|
||||
#include "handle.h"
|
||||
#include "trans.h"
|
||||
|
||||
void _alpm_dep_free(alpm_depend_t *dep)
|
||||
void SYMEXPORT alpm_dep_free(alpm_depend_t *dep)
|
||||
{
|
||||
ASSERT(dep != NULL, return);
|
||||
FREE(dep->name);
|
||||
FREE(dep->version);
|
||||
FREE(dep->desc);
|
||||
@@ -48,25 +49,30 @@ static alpm_depmissing_t *depmiss_new(const char *target, alpm_depend_t *dep,
|
||||
{
|
||||
alpm_depmissing_t *miss;
|
||||
|
||||
MALLOC(miss, sizeof(alpm_depmissing_t), return NULL);
|
||||
CALLOC(miss, 1, sizeof(alpm_depmissing_t), return NULL);
|
||||
|
||||
STRDUP(miss->target, target, return NULL);
|
||||
STRDUP(miss->target, target, goto error);
|
||||
miss->depend = _alpm_dep_dup(dep);
|
||||
STRDUP(miss->causingpkg, causingpkg, return NULL);
|
||||
STRDUP(miss->causingpkg, causingpkg, goto error);
|
||||
|
||||
return miss;
|
||||
|
||||
error:
|
||||
alpm_depmissing_free(miss);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _alpm_depmiss_free(alpm_depmissing_t *miss)
|
||||
void SYMEXPORT alpm_depmissing_free(alpm_depmissing_t *miss)
|
||||
{
|
||||
_alpm_dep_free(miss->depend);
|
||||
ASSERT(miss != NULL, return);
|
||||
alpm_dep_free(miss->depend);
|
||||
FREE(miss->target);
|
||||
FREE(miss->causingpkg);
|
||||
FREE(miss);
|
||||
}
|
||||
|
||||
/* Does pkg1 depend on pkg2, ie. does pkg2 satisfy a dependency of pkg1? */
|
||||
static int _alpm_dep_edge(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2)
|
||||
/** Check if pkg2 satisfies a dependency of pkg1 */
|
||||
static int _alpm_pkg_depends_on(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) {
|
||||
@@ -77,15 +83,38 @@ static int _alpm_dep_edge(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static alpm_pkg_t *find_dep_satisfier(alpm_list_t *pkgs, alpm_depend_t *dep)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
|
||||
for(i = pkgs; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(_alpm_depcmp(pkg, dep)) {
|
||||
return pkg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert a list of alpm_pkg_t * to a graph structure,
|
||||
* with a edge for each dependency.
|
||||
* Returns a list of vertices (one vertex = one package)
|
||||
* (used by alpm_sortbydeps)
|
||||
*/
|
||||
static alpm_list_t *dep_graph_init(alpm_list_t *targets)
|
||||
static alpm_list_t *dep_graph_init(alpm_handle_t *handle,
|
||||
alpm_list_t *targets, alpm_list_t *ignore)
|
||||
{
|
||||
alpm_list_t *i, *j;
|
||||
alpm_list_t *vertices = NULL;
|
||||
alpm_list_t *localpkgs = alpm_list_diff(
|
||||
alpm_db_get_pkgcache(handle->db_local), targets, _alpm_pkg_cmp);
|
||||
|
||||
if(ignore) {
|
||||
alpm_list_t *oldlocal = localpkgs;
|
||||
localpkgs = alpm_list_diff(oldlocal, ignore, _alpm_pkg_cmp);
|
||||
alpm_list_free(oldlocal);
|
||||
}
|
||||
|
||||
/* We create the vertices */
|
||||
for(i = targets; i; i = i->next) {
|
||||
alpm_graph_t *vertex = _alpm_graph_new();
|
||||
@@ -101,13 +130,31 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)
|
||||
for(j = vertices; j; j = j->next) {
|
||||
alpm_graph_t *vertex_j = j->data;
|
||||
alpm_pkg_t *p_j = vertex_j->data;
|
||||
if(_alpm_dep_edge(p_i, p_j)) {
|
||||
if(_alpm_pkg_depends_on(p_i, p_j)) {
|
||||
vertex_i->children =
|
||||
alpm_list_add(vertex_i->children, vertex_j);
|
||||
}
|
||||
}
|
||||
|
||||
/* lazily add local packages to the dep graph so they don't
|
||||
* get resolved unnecessarily */
|
||||
j = localpkgs;
|
||||
while(j) {
|
||||
alpm_list_t *next = j->next;
|
||||
if(_alpm_pkg_depends_on(p_i, j->data)) {
|
||||
alpm_graph_t *vertex_j = _alpm_graph_new();
|
||||
vertex_j->data = (void *)j->data;
|
||||
vertices = alpm_list_add(vertices, vertex_j);
|
||||
vertex_i->children = alpm_list_add(vertex_i->children, vertex_j);
|
||||
localpkgs = alpm_list_remove_item(localpkgs, j);
|
||||
free(j);
|
||||
}
|
||||
j = next;
|
||||
}
|
||||
|
||||
vertex_i->childptr = vertex_i->children;
|
||||
}
|
||||
alpm_list_free(localpkgs);
|
||||
return vertices;
|
||||
}
|
||||
|
||||
@@ -120,13 +167,15 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets)
|
||||
*
|
||||
* Should be re-ordered to C,A,B,D
|
||||
*
|
||||
* packages listed in ignore will not be used to detect indirect dependencies
|
||||
*
|
||||
* if reverse is > 0, the dependency order will be reversed.
|
||||
*
|
||||
* This function returns the new alpm_list_t* target list.
|
||||
*
|
||||
*/
|
||||
alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
|
||||
alpm_list_t *targets, int reverse)
|
||||
alpm_list_t *targets, alpm_list_t *ignore, int reverse)
|
||||
{
|
||||
alpm_list_t *newtargs = NULL;
|
||||
alpm_list_t *vertices = NULL;
|
||||
@@ -139,7 +188,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "started sorting dependencies\n");
|
||||
|
||||
vertices = dep_graph_init(targets);
|
||||
vertices = dep_graph_init(handle, targets, ignore);
|
||||
|
||||
vptr = vertices;
|
||||
vertex = vertices->data;
|
||||
@@ -154,34 +203,56 @@ alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
|
||||
found = 1;
|
||||
nextchild->parent = vertex;
|
||||
vertex = nextchild;
|
||||
}
|
||||
else if(nextchild->state == -1) {
|
||||
alpm_pkg_t *vertexpkg = vertex->data;
|
||||
alpm_pkg_t *childpkg = nextchild->data;
|
||||
} else if(nextchild->state == -1) {
|
||||
/* child is an ancestor of vertex */
|
||||
alpm_graph_t *transvertex = vertex;
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n"));
|
||||
if(reverse) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("%s will be removed after its %s dependency\n"),
|
||||
vertexpkg->name, childpkg->name);
|
||||
if(!alpm_list_find_ptr(targets, nextchild->data)) {
|
||||
/* child is not part of the transaction, not a problem */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* find the nearest parent that's part of the transaction */
|
||||
while(transvertex) {
|
||||
if(alpm_list_find_ptr(targets, transvertex->data)) {
|
||||
break;
|
||||
}
|
||||
transvertex = transvertex->parent;
|
||||
}
|
||||
|
||||
if(!transvertex || transvertex == nextchild) {
|
||||
/* no transaction package in our ancestry or the package has
|
||||
* a circular dependency with itself, not a problem */
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("%s will be installed before its %s dependency\n"),
|
||||
vertexpkg->name, childpkg->name);
|
||||
alpm_pkg_t *transpkg = transvertex->data;
|
||||
alpm_pkg_t *childpkg = nextchild->data;
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("dependency cycle detected:\n"));
|
||||
if(reverse) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("%s will be removed after its %s dependency\n"),
|
||||
transpkg->name, childpkg->name);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("%s will be installed before its %s dependency\n"),
|
||||
transpkg->name, childpkg->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
newtargs = alpm_list_add(newtargs, vertex->data);
|
||||
if(alpm_list_find_ptr(targets, vertex->data)) {
|
||||
newtargs = alpm_list_add(newtargs, vertex->data);
|
||||
}
|
||||
/* mark that we've left this vertex */
|
||||
vertex->state = 1;
|
||||
vertex = vertex->parent;
|
||||
if(!vertex) {
|
||||
vptr = vptr->next;
|
||||
while(vptr) {
|
||||
/* top level vertex reached, move to the next unprocessed vertex */
|
||||
for( vptr = vptr->next; vptr; vptr = vptr->next) {
|
||||
vertex = vptr->data;
|
||||
if(vertex->state == 0) break;
|
||||
vptr = vptr->next;
|
||||
if(vertex->state == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,37 +282,6 @@ static int no_dep_version(alpm_handle_t *handle)
|
||||
return (handle->trans->flags & ALPM_TRANS_FLAG_NODEPVERSION);
|
||||
}
|
||||
|
||||
static alpm_depend_t *filtered_depend(alpm_depend_t *dep, int nodepversion)
|
||||
{
|
||||
if(nodepversion) {
|
||||
alpm_depend_t *newdep = _alpm_dep_dup(dep);
|
||||
ASSERT(newdep, return dep);
|
||||
newdep->mod = ALPM_DEP_MOD_ANY;
|
||||
dep = newdep;
|
||||
}
|
||||
return dep;
|
||||
}
|
||||
|
||||
static void release_filtered_depend(alpm_depend_t *dep, int nodepversion)
|
||||
{
|
||||
if(nodepversion) {
|
||||
free(dep);
|
||||
}
|
||||
}
|
||||
|
||||
static alpm_pkg_t *find_dep_satisfier(alpm_list_t *pkgs, alpm_depend_t *dep)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
|
||||
for(i = pkgs; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(_alpm_depcmp(pkg, dep)) {
|
||||
return pkg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Find a package satisfying a specified dependency.
|
||||
* The dependency can include versions with depmod operators.
|
||||
* @param pkgs an alpm_list_t* of alpm_pkg_t where the satisfier will be searched
|
||||
@@ -250,12 +290,12 @@ static alpm_pkg_t *find_dep_satisfier(alpm_list_t *pkgs, alpm_depend_t *dep)
|
||||
*/
|
||||
alpm_pkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring)
|
||||
{
|
||||
alpm_depend_t *dep = _alpm_splitdep(depstring);
|
||||
alpm_depend_t *dep = alpm_dep_from_string(depstring);
|
||||
if(!dep) {
|
||||
return NULL;
|
||||
}
|
||||
alpm_pkg_t *pkg = find_dep_satisfier(pkgs, dep);
|
||||
_alpm_dep_free(dep);
|
||||
alpm_dep_free(dep);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
@@ -298,11 +338,16 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
|
||||
|
||||
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
|
||||
alpm_depend_t *depend = j->data;
|
||||
depend = filtered_depend(depend, nodepversion);
|
||||
alpm_depmod_t orig_mod = depend->mod;
|
||||
if(nodepversion) {
|
||||
depend->mod = ALPM_DEP_MOD_ANY;
|
||||
}
|
||||
/* 1. we check the upgrade list */
|
||||
/* 2. we check database for untouched satisfying packages */
|
||||
/* 3. we check the dependency ignore list */
|
||||
if(!find_dep_satisfier(upgrade, depend) &&
|
||||
!find_dep_satisfier(dblist, depend)) {
|
||||
!find_dep_satisfier(dblist, depend) &&
|
||||
!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
|
||||
/* Unsatisfied dependency in the upgrade list */
|
||||
alpm_depmissing_t *miss;
|
||||
char *missdepstring = alpm_dep_compute_string(depend);
|
||||
@@ -312,7 +357,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
|
||||
miss = depmiss_new(tp->name, depend, NULL);
|
||||
baddeps = alpm_list_add(baddeps, miss);
|
||||
}
|
||||
release_filtered_depend(depend, nodepversion);
|
||||
depend->mod = orig_mod;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,14 +368,19 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
|
||||
alpm_pkg_t *lp = i->data;
|
||||
for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
|
||||
alpm_depend_t *depend = j->data;
|
||||
depend = filtered_depend(depend, nodepversion);
|
||||
alpm_depmod_t orig_mod = depend->mod;
|
||||
if(nodepversion) {
|
||||
depend->mod = ALPM_DEP_MOD_ANY;
|
||||
}
|
||||
alpm_pkg_t *causingpkg = find_dep_satisfier(modified, depend);
|
||||
/* we won't break this depend, if it is already broken, we ignore it */
|
||||
/* 1. check upgrade list for satisfiers */
|
||||
/* 2. check dblist for satisfiers */
|
||||
/* 3. we check the dependency ignore list */
|
||||
if(causingpkg &&
|
||||
!find_dep_satisfier(upgrade, depend) &&
|
||||
!find_dep_satisfier(dblist, depend)) {
|
||||
!find_dep_satisfier(upgrade, depend) &&
|
||||
!find_dep_satisfier(dblist, depend) &&
|
||||
!_alpm_depcmp_provides(depend, handle->assumeinstalled)) {
|
||||
alpm_depmissing_t *miss;
|
||||
char *missdepstring = alpm_dep_compute_string(depend);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
|
||||
@@ -339,7 +389,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle,
|
||||
miss = depmiss_new(lp->name, depend, causingpkg->name);
|
||||
baddeps = alpm_list_add(baddeps, miss);
|
||||
}
|
||||
release_filtered_depend(depend, nodepversion);
|
||||
depend->mod = orig_mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,17 +431,18 @@ int _alpm_depcmp_literal(alpm_pkg_t *pkg, alpm_depend_t *dep)
|
||||
return dep_vercmp(pkg->version, dep->mod, dep->version);
|
||||
}
|
||||
|
||||
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep)
|
||||
/**
|
||||
* @param dep dependency to check against the provision list
|
||||
* @param provisions provision list
|
||||
* @return 1 if provider is found, 0 otherwise
|
||||
*/
|
||||
int _alpm_depcmp_provides(alpm_depend_t *dep, alpm_list_t *provisions)
|
||||
{
|
||||
int satisfy = 0;
|
||||
alpm_list_t *i;
|
||||
int satisfy = _alpm_depcmp_literal(pkg, dep);
|
||||
|
||||
if(satisfy) {
|
||||
return satisfy;
|
||||
}
|
||||
|
||||
/* check provisions, name and version if available */
|
||||
for(i = alpm_pkg_get_provides(pkg); i && !satisfy; i = i->next) {
|
||||
for(i = provisions; i && !satisfy; i = i->next) {
|
||||
alpm_depend_t *provision = i->data;
|
||||
|
||||
if(dep->mod == ALPM_DEP_MOD_ANY) {
|
||||
@@ -409,7 +460,13 @@ int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep)
|
||||
return satisfy;
|
||||
}
|
||||
|
||||
alpm_depend_t *_alpm_splitdep(const char *depstring)
|
||||
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep)
|
||||
{
|
||||
return _alpm_depcmp_literal(pkg, dep)
|
||||
|| _alpm_depcmp_provides(dep, alpm_pkg_get_provides(pkg));
|
||||
}
|
||||
|
||||
alpm_depend_t SYMEXPORT *alpm_dep_from_string(const char *depstring)
|
||||
{
|
||||
alpm_depend_t *depend;
|
||||
const char *ptr, *version, *desc;
|
||||
@@ -419,11 +476,11 @@ alpm_depend_t *_alpm_splitdep(const char *depstring)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MALLOC(depend, sizeof(alpm_depend_t), return NULL);
|
||||
CALLOC(depend, 1, sizeof(alpm_depend_t), return NULL);
|
||||
|
||||
/* Note the extra space in ": " to avoid matching the epoch */
|
||||
if((desc = strstr(depstring, ": ")) != NULL) {
|
||||
STRDUP(depend->desc, desc + 2, return NULL);
|
||||
STRDUP(depend->desc, desc + 2, goto error);
|
||||
deplen = desc - depstring;
|
||||
} else {
|
||||
/* no description- point desc at NULL at end of string for later use */
|
||||
@@ -463,13 +520,17 @@ alpm_depend_t *_alpm_splitdep(const char *depstring)
|
||||
}
|
||||
|
||||
/* copy the right parts to the right places */
|
||||
STRNDUP(depend->name, depstring, ptr - depstring, return NULL);
|
||||
STRNDUP(depend->name, depstring, ptr - depstring, goto error);
|
||||
depend->name_hash = _alpm_hash_sdbm(depend->name);
|
||||
if(version) {
|
||||
STRNDUP(depend->version, version, desc - version, return NULL);
|
||||
STRNDUP(depend->version, version, desc - version, goto error);
|
||||
}
|
||||
|
||||
return depend;
|
||||
|
||||
error:
|
||||
alpm_dep_free(depend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep)
|
||||
@@ -477,53 +538,42 @@ alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep)
|
||||
alpm_depend_t *newdep;
|
||||
CALLOC(newdep, 1, sizeof(alpm_depend_t), return NULL);
|
||||
|
||||
STRDUP(newdep->name, dep->name, return NULL);
|
||||
STRDUP(newdep->version, dep->version, return NULL);
|
||||
STRDUP(newdep->desc, dep->desc, return NULL);
|
||||
STRDUP(newdep->name, dep->name, goto error);
|
||||
STRDUP(newdep->version, dep->version, goto error);
|
||||
STRDUP(newdep->desc, dep->desc, goto error);
|
||||
newdep->name_hash = dep->name_hash;
|
||||
newdep->mod = dep->mod;
|
||||
|
||||
return newdep;
|
||||
|
||||
error:
|
||||
alpm_dep_free(newdep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* These parameters are messy. We check if this package, given a list of
|
||||
* targets and a db is safe to remove. We do NOT remove it if it is in the
|
||||
* target list, or if the package was explicitly installed and
|
||||
* include_explicit == 0 */
|
||||
static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
|
||||
alpm_list_t *targets, int include_explicit)
|
||||
/** Move package dependencies from one list to another
|
||||
* @param from list to scan for dependencies
|
||||
* @param to list to add dependencies to
|
||||
* @param pkg package whose dependencies are moved
|
||||
* @param explicit if 0, explicitly installed packages are not moved
|
||||
*/
|
||||
static void _alpm_select_depends(alpm_list_t **from, alpm_list_t **to,
|
||||
alpm_pkg_t *pkg, int explicit)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
|
||||
if(alpm_pkg_find(targets, pkg->name)) {
|
||||
return 0;
|
||||
alpm_list_t *i, *next;
|
||||
if(!alpm_pkg_get_depends(pkg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!include_explicit) {
|
||||
/* see if it was explicitly installed */
|
||||
if(alpm_pkg_get_reason(pkg) == ALPM_PKG_REASON_EXPLICIT) {
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG,
|
||||
"excluding %s -- explicitly installed\n", pkg->name);
|
||||
return 0;
|
||||
for(i = *from; i; i = next) {
|
||||
alpm_pkg_t *deppkg = i->data;
|
||||
next = i->next;
|
||||
if((explicit || alpm_pkg_get_reason(deppkg) != ALPM_PKG_REASON_EXPLICIT)
|
||||
&& _alpm_pkg_depends_on(pkg, deppkg)) {
|
||||
*to = alpm_list_add(*to, deppkg);
|
||||
*from = alpm_list_remove_item(*from, i);
|
||||
free(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: checkdeps could be used here, it handles multiple providers
|
||||
* better, but that also makes it slower.
|
||||
* Also this would require to first add the package to the targets list,
|
||||
* then call checkdeps with it, then remove the package from the targets list
|
||||
* if checkdeps detected it would break something */
|
||||
|
||||
/* see if other packages need it */
|
||||
for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
|
||||
alpm_pkg_t *lpkg = i->data;
|
||||
if(_alpm_dep_edge(lpkg, pkg) && !alpm_pkg_find(targets, lpkg->name)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* it's ok to remove */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,31 +587,48 @@ static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
|
||||
* @param include_explicit if 0, explicitly installed packages are not included
|
||||
* @return 0 on success, -1 on errors
|
||||
*/
|
||||
int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit)
|
||||
int _alpm_recursedeps(alpm_db_t *db, alpm_list_t **targs, int include_explicit)
|
||||
{
|
||||
alpm_list_t *i, *j;
|
||||
alpm_list_t *i, *keep, *rem = NULL;
|
||||
|
||||
if(db == NULL || targs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = targs; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
|
||||
alpm_pkg_t *deppkg = j->data;
|
||||
if(_alpm_dep_edge(pkg, deppkg)
|
||||
&& can_remove_package(db, deppkg, targs, include_explicit)) {
|
||||
alpm_pkg_t *copy;
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding '%s' to the targets\n",
|
||||
deppkg->name);
|
||||
/* add it to the target list */
|
||||
if(_alpm_pkg_dup(deppkg, ©)) {
|
||||
return -1;
|
||||
}
|
||||
targs = alpm_list_add(targs, copy);
|
||||
}
|
||||
}
|
||||
keep = alpm_list_copy(_alpm_db_get_pkgcache(db));
|
||||
for(i = *targs; i; i = i->next) {
|
||||
keep = alpm_list_remove(keep, i->data, _alpm_pkg_cmp, NULL);
|
||||
}
|
||||
|
||||
/* recursively select all dependencies for removal */
|
||||
for(i = *targs; i; i = i->next) {
|
||||
_alpm_select_depends(&keep, &rem, i->data, include_explicit);
|
||||
}
|
||||
for(i = rem; i; i = i->next) {
|
||||
_alpm_select_depends(&keep, &rem, i->data, include_explicit);
|
||||
}
|
||||
|
||||
/* recursively select any still needed packages to keep */
|
||||
for(i = keep; i && rem; i = i->next) {
|
||||
_alpm_select_depends(&rem, &keep, i->data, 1);
|
||||
}
|
||||
alpm_list_free(keep);
|
||||
|
||||
/* copy selected packages into the target list */
|
||||
for(i = rem; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data, *copy = NULL;
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG,
|
||||
"adding '%s' to the targets\n", pkg->name);
|
||||
if(_alpm_pkg_dup(pkg, ©)) {
|
||||
/* we return memory on "non-fatal" error in _alpm_pkg_dup */
|
||||
_alpm_pkg_free(copy);
|
||||
alpm_list_free(rem);
|
||||
return -1;
|
||||
}
|
||||
*targs = alpm_list_add(*targs, copy);
|
||||
}
|
||||
alpm_list_free(rem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -589,19 +656,29 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
|
||||
|
||||
/* 1. literals */
|
||||
for(i = dbs; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
|
||||
alpm_pkg_t *pkg;
|
||||
alpm_db_t *db = i->data;
|
||||
|
||||
if(!(db->usage & (ALPM_DB_USAGE_INSTALL|ALPM_DB_USAGE_UPGRADE))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pkg = _alpm_db_get_pkgfromcache(db, dep->name);
|
||||
if(pkg && _alpm_depcmp_literal(pkg, dep)
|
||||
&& !alpm_pkg_find(excluding, pkg->name)) {
|
||||
if(_alpm_pkg_should_ignore(handle, pkg)) {
|
||||
int install = 0;
|
||||
if(alpm_pkg_should_ignore(handle, pkg)) {
|
||||
alpm_question_install_ignorepkg_t question = {
|
||||
.type = ALPM_QUESTION_INSTALL_IGNOREPKG,
|
||||
.install = 0,
|
||||
.pkg = pkg
|
||||
};
|
||||
if(prompt) {
|
||||
QUESTION(handle, ALPM_QUESTION_INSTALL_IGNOREPKG, pkg,
|
||||
NULL, NULL, &install);
|
||||
QUESTION(handle, &question);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"),
|
||||
pkg->name, pkg->version);
|
||||
}
|
||||
if(!install) {
|
||||
if(!question.install) {
|
||||
ignored = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -611,22 +688,29 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
|
||||
}
|
||||
/* 2. satisfiers (skip literals here) */
|
||||
for(i = dbs; i; i = i->next) {
|
||||
for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) {
|
||||
alpm_db_t *db = i->data;
|
||||
if(!(db->usage & (ALPM_DB_USAGE_INSTALL|ALPM_DB_USAGE_UPGRADE))) {
|
||||
continue;
|
||||
}
|
||||
for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
|
||||
alpm_pkg_t *pkg = j->data;
|
||||
/* with hash != hash, we can even skip the strcmp() as we know they can't
|
||||
* possibly be the same string */
|
||||
if(pkg->name_hash != dep->name_hash && _alpm_depcmp(pkg, dep)
|
||||
&& !alpm_pkg_find(excluding, pkg->name)) {
|
||||
if(_alpm_pkg_should_ignore(handle, pkg)) {
|
||||
int install = 0;
|
||||
if(alpm_pkg_should_ignore(handle, pkg)) {
|
||||
alpm_question_install_ignorepkg_t question = {
|
||||
.type = ALPM_QUESTION_INSTALL_IGNOREPKG,
|
||||
.install = 0,
|
||||
.pkg = pkg
|
||||
};
|
||||
if(prompt) {
|
||||
QUESTION(handle, ALPM_QUESTION_INSTALL_IGNOREPKG,
|
||||
pkg, NULL, NULL, &install);
|
||||
QUESTION(handle, &question);
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package %s-%s\n"),
|
||||
pkg->name, pkg->version);
|
||||
}
|
||||
if(!install) {
|
||||
if(!question.install) {
|
||||
ignored = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -649,15 +733,19 @@ static alpm_pkg_t *resolvedep(alpm_handle_t *handle, alpm_depend_t *dep,
|
||||
}
|
||||
count = alpm_list_count(providers);
|
||||
if(count >= 1) {
|
||||
/* default to first provider if there is no QUESTION callback */
|
||||
int idx = 0;
|
||||
alpm_question_select_provider_t question = {
|
||||
.type = ALPM_QUESTION_SELECT_PROVIDER,
|
||||
/* default to first provider if there is no QUESTION callback */
|
||||
.use_index = 0,
|
||||
.providers = providers,
|
||||
.depend = dep
|
||||
};
|
||||
if(count > 1) {
|
||||
/* if there is more than one provider, we ask the user */
|
||||
QUESTION(handle, ALPM_QUESTION_SELECT_PROVIDER,
|
||||
providers, dep, NULL, &idx);
|
||||
QUESTION(handle, &question);
|
||||
}
|
||||
if(idx >= 0 && idx < count) {
|
||||
alpm_list_t *nth = alpm_list_nth(providers, idx);
|
||||
if(question.use_index >= 0 && question.use_index < count) {
|
||||
alpm_list_t *nth = alpm_list_nth(providers, question.use_index);
|
||||
alpm_pkg_t *pkg = nth->data;
|
||||
alpm_list_free(providers);
|
||||
return pkg;
|
||||
@@ -692,10 +780,10 @@ alpm_pkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_handle_t *handle,
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
ASSERT(dbs, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
|
||||
|
||||
dep = _alpm_splitdep(depstring);
|
||||
dep = alpm_dep_from_string(depstring);
|
||||
ASSERT(dep, return NULL);
|
||||
pkg = resolvedep(handle, dep, dbs, NULL, 1);
|
||||
_alpm_dep_free(dep);
|
||||
alpm_dep_free(dep);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
@@ -753,7 +841,7 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
|
||||
/* check if one of the packages in the [*packages] list already satisfies
|
||||
* this dependency */
|
||||
if(find_dep_satisfier(*packages, missdep)) {
|
||||
_alpm_depmiss_free(miss);
|
||||
alpm_depmissing_free(miss);
|
||||
continue;
|
||||
}
|
||||
/* check if one of the packages in the [preferred] list already satisfies
|
||||
@@ -767,9 +855,9 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"pulling dependency %s (needed by %s)\n",
|
||||
spkg->name, pkg->name);
|
||||
_alpm_depmiss_free(miss);
|
||||
alpm_depmissing_free(miss);
|
||||
} else if(resolvedep(handle, missdep, (targ = alpm_list_add(NULL, handle->db_local)), rem, 0)) {
|
||||
_alpm_depmiss_free(miss);
|
||||
alpm_depmissing_free(miss);
|
||||
} else {
|
||||
handle->pm_errno = ALPM_ERR_UNSATISFIED_DEPS;
|
||||
char *missdepstring = alpm_dep_compute_string(missdep);
|
||||
@@ -782,8 +870,9 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
|
||||
}
|
||||
ret = -1;
|
||||
}
|
||||
alpm_list_free(targ);
|
||||
targ = NULL;
|
||||
}
|
||||
alpm_list_free(targ);
|
||||
alpm_list_free(deps);
|
||||
|
||||
if(ret != 0) {
|
||||
@@ -863,4 +952,4 @@ char SYMEXPORT *alpm_dep_compute_string(const alpm_depend_t *dep)
|
||||
|
||||
return str;
|
||||
}
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* deps.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
||||
@@ -19,26 +19,25 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_DEPS_H
|
||||
#define _ALPM_DEPS_H
|
||||
#ifndef ALPM_DEPS_H
|
||||
#define ALPM_DEPS_H
|
||||
|
||||
#include "db.h"
|
||||
#include "sync.h"
|
||||
#include "package.h"
|
||||
#include "alpm.h"
|
||||
|
||||
void _alpm_dep_free(alpm_depend_t *dep);
|
||||
alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep);
|
||||
void _alpm_depmiss_free(alpm_depmissing_t *miss);
|
||||
alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle, alpm_list_t *targets, int reverse);
|
||||
int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit);
|
||||
alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle,
|
||||
alpm_list_t *targets, alpm_list_t *ignore, int reverse);
|
||||
int _alpm_recursedeps(alpm_db_t *db, alpm_list_t **targs, int include_explicit);
|
||||
int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs, alpm_pkg_t *pkg,
|
||||
alpm_list_t *preferred, alpm_list_t **packages, alpm_list_t *remove,
|
||||
alpm_list_t **data);
|
||||
alpm_depend_t *_alpm_splitdep(const char *depstring);
|
||||
int _alpm_depcmp_literal(alpm_pkg_t *pkg, alpm_depend_t *dep);
|
||||
int _alpm_depcmp_provides(alpm_depend_t *dep, alpm_list_t *provisions);
|
||||
int _alpm_depcmp(alpm_pkg_t *pkg, alpm_depend_t *dep);
|
||||
|
||||
#endif /* _ALPM_DEPS_H */
|
||||
#endif /* ALPM_DEPS_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* diskspace.c
|
||||
*
|
||||
* Copyright (c) 2010-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -84,6 +84,9 @@ static int mount_point_load_fsinfo(alpm_handle_t *handle, alpm_mountpoint_t *mou
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "loading fsinfo for %s\n", mountpoint->mount_dir);
|
||||
mountpoint->read_only = mountpoint->fsp.f_flag & ST_RDONLY;
|
||||
mountpoint->fsinfo_loaded = MOUNT_FSINFO_LOADED;
|
||||
#else
|
||||
(void)handle;
|
||||
(void)mountpoint;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -109,7 +112,7 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
|
||||
|
||||
while((mnt = getmntent(fp))) {
|
||||
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir = strdup(mnt->mnt_dir);
|
||||
STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir_len = strlen(mp->mount_dir);
|
||||
|
||||
mount_points = alpm_list_add(mount_points, mp);
|
||||
@@ -132,7 +135,7 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
|
||||
|
||||
while((ret = getmntent(fp, &mnt)) == 0) {
|
||||
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir = strdup(mnt->mnt_mountp);
|
||||
STRDUP(mp->mount_dir, mnt->mnt_mountp, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir_len = strlen(mp->mount_dir);
|
||||
|
||||
mount_points = alpm_list_add(mount_points, mp);
|
||||
@@ -159,7 +162,7 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
|
||||
|
||||
for(; entries-- > 0; fsp++) {
|
||||
CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir = strdup(fsp->f_mntonname);
|
||||
STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
mp->mount_dir_len = strlen(mp->mount_dir);
|
||||
memcpy(&(mp->fsp), fsp, sizeof(FSSTATSTYPE));
|
||||
#if defined(HAVE_GETMNTINFO_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FLAG)
|
||||
@@ -232,7 +235,14 @@ static int calculate_removed_size(alpm_handle_t *handle,
|
||||
const char *filename = file->name;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
|
||||
_alpm_lstat(path, &st);
|
||||
|
||||
if(llstat(path, &st) == -1) {
|
||||
if(alpm_option_match_noextract(handle, filename)) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("could not get file information for %s\n"), filename);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip directories and symlinks to be consistent with libarchive that
|
||||
* reports them to be zero size */
|
||||
@@ -338,11 +348,11 @@ static int check_mountpoint(alpm_handle_t *handle, alpm_mountpoint_t *mp)
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"partition %s, needed %jd, cushion %ju, free %ju\n",
|
||||
mp->mount_dir, (intmax_t)mp->max_blocks_needed,
|
||||
(uintmax_t)cushion, (uintmax_t)mp->fsp.f_bfree);
|
||||
if(needed >= 0 && (fsblkcnt_t)needed > mp->fsp.f_bfree) {
|
||||
(uintmax_t)cushion, (uintmax_t)mp->fsp.f_bavail);
|
||||
if(needed >= 0 && (fsblkcnt_t)needed > mp->fsp.f_bavail) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Partition %s too full: %jd blocks needed, %jd blocks free\n"),
|
||||
mp->mount_dir, (intmax_t)needed, (uintmax_t)mp->fsp.f_bfree);
|
||||
_("Partition %s too full: %jd blocks needed, %ju blocks free\n"),
|
||||
mp->mount_dir, (intmax_t)needed, (uintmax_t)mp->fsp.f_bavail);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -357,7 +367,7 @@ int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
|
||||
size_t j;
|
||||
int error = 0;
|
||||
|
||||
/* resolve the cachedir path to ensure we check the right mountpoint. We
|
||||
/* resolve the cachedir path to ensure we check the right mountpoint. We
|
||||
* handle failures silently, and continue to use the possibly unresolved
|
||||
* path. */
|
||||
if(realpath(cachedir, resolved_cachedir) != NULL) {
|
||||
@@ -491,4 +501,4 @@ finish:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* diskspace.h
|
||||
*
|
||||
* Copyright (c) 2010-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2010-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,8 +17,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ALPM_DISKSPACE_H
|
||||
#define _ALPM_DISKSPACE_H
|
||||
#ifndef ALPM_DISKSPACE_H
|
||||
#define ALPM_DISKSPACE_H
|
||||
|
||||
#if defined(HAVE_SYS_MOUNT_H)
|
||||
#include <sys/mount.h>
|
||||
@@ -60,6 +60,6 @@ int _alpm_check_diskspace(alpm_handle_t *handle);
|
||||
int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
|
||||
size_t num_files, off_t *file_sizes);
|
||||
|
||||
#endif /* _ALPM_DISKSPACE_H */
|
||||
#endif /* ALPM_DISKSPACE_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* download.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -131,7 +131,9 @@ static int dload_progress_cb(void *file, double dltotal, double dlnow,
|
||||
payload->handle->dlcb(payload->remote_name, 0, (off_t)dltotal);
|
||||
}
|
||||
|
||||
payload->handle->dlcb(payload->remote_name, current_size, total_size);
|
||||
/* do NOT include initial_size since it wasn't part of the package's
|
||||
* download_size (nor included in the total download size callback) */
|
||||
payload->handle->dlcb(payload->remote_name, (off_t)dlnow, (off_t)dltotal);
|
||||
|
||||
payload->prevprogress = current_size;
|
||||
|
||||
@@ -286,7 +288,6 @@ static void curl_set_handle_opts(struct dload_payload *payload,
|
||||
* to reset the handle's parameters for each time it's used. */
|
||||
curl_easy_reset(curl);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, payload->fileurl);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
@@ -301,6 +302,7 @@ static void curl_set_handle_opts(struct dload_payload *payload,
|
||||
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, dload_sockopt_cb);
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, (void *)handle);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "url: %s\n", payload->fileurl);
|
||||
|
||||
@@ -321,7 +323,7 @@ static void curl_set_handle_opts(struct dload_payload *payload,
|
||||
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, (long)st.st_mtime);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG,
|
||||
"using time condition: %lu\n", (long)st.st_mtime);
|
||||
"using time condition: %ld\n", (long)st.st_mtime);
|
||||
} else if(stat(payload->tempfile_name, &st) == 0 && payload->allow_resume) {
|
||||
/* a previous partial download exists, resume from end of file. */
|
||||
payload->tempfile_openmode = "ab";
|
||||
@@ -366,7 +368,7 @@ static FILE *create_tempfile(struct dload_payload *payload, const char *localpat
|
||||
fchmod(fd, ~(_getumask()) & 0666) ||
|
||||
!(fp = fdopen(fd, payload->tempfile_openmode))) {
|
||||
unlink(randpath);
|
||||
CLOSE(fd);
|
||||
close(fd);
|
||||
_alpm_log(payload->handle, ALPM_LOG_ERROR,
|
||||
_("failed to create temporary file for download\n"));
|
||||
free(randpath);
|
||||
@@ -377,7 +379,7 @@ static FILE *create_tempfile(struct dload_payload *payload, const char *localpat
|
||||
payload->tempfile_name = randpath;
|
||||
free(payload->remote_name);
|
||||
STRDUP(payload->remote_name, strrchr(randpath, '/') + 1,
|
||||
RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
|
||||
fclose(fp); RET_ERR(payload->handle, ALPM_ERR_MEMORY, NULL));
|
||||
|
||||
return fp;
|
||||
}
|
||||
@@ -386,7 +388,7 @@ static FILE *create_tempfile(struct dload_payload *payload, const char *localpat
|
||||
#define HOSTNAME_SIZE 256
|
||||
|
||||
static int curl_download_internal(struct dload_payload *payload,
|
||||
const char *localpath, char **final_file, char **final_url)
|
||||
const char *localpath, char **final_file, const char **final_url)
|
||||
{
|
||||
int ret = -1;
|
||||
FILE *localf = NULL;
|
||||
@@ -465,8 +467,8 @@ static int curl_download_internal(struct dload_payload *payload,
|
||||
payload->curlerr);
|
||||
|
||||
/* disconnect relationships from the curl handle for things that might go out
|
||||
* of scope, but could still be touched on connection teardown. This really
|
||||
* only applies to FTP transfers. See FS#26327 for an example. */
|
||||
* of scope, but could still be touched on connection teardown. This really
|
||||
* only applies to FTP transfers. */
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, (char *)NULL);
|
||||
|
||||
@@ -477,12 +479,14 @@ static int curl_download_internal(struct dload_payload *payload,
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "response code: %ld\n", payload->respcode);
|
||||
if(payload->respcode >= 400) {
|
||||
payload->unlink_on_fail = 1;
|
||||
/* non-translated message is same as libcurl */
|
||||
snprintf(error_buffer, sizeof(error_buffer),
|
||||
"The requested URL returned error: %ld", payload->respcode);
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("failed retrieving file '%s' from %s : %s\n"),
|
||||
payload->remote_name, hostname, error_buffer);
|
||||
if(!payload->errors_ok) {
|
||||
/* non-translated message is same as libcurl */
|
||||
snprintf(error_buffer, sizeof(error_buffer),
|
||||
"The requested URL returned error: %ld", payload->respcode);
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("failed retrieving file '%s' from %s : %s\n"),
|
||||
payload->remote_name, hostname, error_buffer);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
@@ -490,12 +494,11 @@ static int curl_download_internal(struct dload_payload *payload,
|
||||
/* handle the interrupt accordingly */
|
||||
if(dload_interrupted == ABORT_OVER_MAXFILESIZE) {
|
||||
payload->curlerr = CURLE_FILESIZE_EXCEEDED;
|
||||
payload->unlink_on_fail = 1;
|
||||
handle->pm_errno = ALPM_ERR_LIBCURL;
|
||||
/* use the 'size exceeded' message from libcurl */
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("failed retrieving file '%s' from %s : %s\n"),
|
||||
payload->remote_name, hostname,
|
||||
curl_easy_strerror(CURLE_FILESIZE_EXCEEDED));
|
||||
_("failed retrieving file '%s' from %s : expected download size exceeded\n"),
|
||||
payload->remote_name, hostname);
|
||||
}
|
||||
goto cleanup;
|
||||
default:
|
||||
@@ -547,23 +550,25 @@ static int curl_download_internal(struct dload_payload *payload,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(payload->content_disp_name) {
|
||||
/* content-disposition header has a better name for our file */
|
||||
free(payload->destfile_name);
|
||||
payload->destfile_name = get_fullpath(localpath, payload->content_disp_name, "");
|
||||
} else {
|
||||
const char *effective_filename = strrchr(effective_url, '/');
|
||||
if(effective_filename && strlen(effective_filename) > 2) {
|
||||
effective_filename++;
|
||||
if(payload->trust_remote_name) {
|
||||
if(payload->content_disp_name) {
|
||||
/* content-disposition header has a better name for our file */
|
||||
free(payload->destfile_name);
|
||||
payload->destfile_name = get_fullpath(localpath, payload->content_disp_name, "");
|
||||
} else {
|
||||
const char *effective_filename = strrchr(effective_url, '/');
|
||||
if(effective_filename && strlen(effective_filename) > 2) {
|
||||
effective_filename++;
|
||||
|
||||
/* if destfile was never set, we wrote to a tempfile. even if destfile is
|
||||
* set, we may have followed some redirects and the effective url may
|
||||
* have a better suggestion as to what to name our file. in either case,
|
||||
* refactor destfile to this newly derived name. */
|
||||
if(!payload->destfile_name || strcmp(effective_filename,
|
||||
strrchr(payload->destfile_name, '/') + 1) != 0) {
|
||||
free(payload->destfile_name);
|
||||
payload->destfile_name = get_fullpath(localpath, effective_filename, "");
|
||||
/* if destfile was never set, we wrote to a tempfile. even if destfile is
|
||||
* set, we may have followed some redirects and the effective url may
|
||||
* have a better suggestion as to what to name our file. in either case,
|
||||
* refactor destfile to this newly derived name. */
|
||||
if(!payload->destfile_name || strcmp(effective_filename,
|
||||
strrchr(payload->destfile_name, '/') + 1) != 0) {
|
||||
free(payload->destfile_name);
|
||||
payload->destfile_name = get_fullpath(localpath, effective_filename, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -617,7 +622,7 @@ cleanup:
|
||||
* @return 0 on success, -1 on error (pm_errno is set accordingly if errors_ok == 0)
|
||||
*/
|
||||
int _alpm_download(struct dload_payload *payload, const char *localpath,
|
||||
char **final_file, char **final_url)
|
||||
char **final_file, const char **final_url)
|
||||
{
|
||||
alpm_handle_t *handle = payload->handle;
|
||||
|
||||
@@ -625,6 +630,9 @@ int _alpm_download(struct dload_payload *payload, const char *localpath,
|
||||
#ifdef HAVE_LIBCURL
|
||||
return curl_download_internal(payload, localpath, final_file, final_url);
|
||||
#else
|
||||
/* work around unused warnings when building without libcurl */
|
||||
(void)final_file;
|
||||
(void)final_url;
|
||||
RET_ERR(handle, ALPM_ERR_EXTERNAL_DOWNLOAD, -1);
|
||||
#endif
|
||||
} else {
|
||||
@@ -645,7 +653,7 @@ static char *filecache_find_url(alpm_handle_t *handle, const char *url)
|
||||
}
|
||||
|
||||
filebase++;
|
||||
if(filebase == '\0') {
|
||||
if(*filebase == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -656,8 +664,8 @@ static char *filecache_find_url(alpm_handle_t *handle, const char *url)
|
||||
char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
|
||||
{
|
||||
char *filepath;
|
||||
const char *cachedir;
|
||||
char *final_file = NULL, *final_pkg_url = NULL;
|
||||
const char *cachedir, *final_pkg_url = NULL;
|
||||
char *final_file = NULL;
|
||||
struct dload_payload payload;
|
||||
int ret = 0;
|
||||
|
||||
@@ -675,6 +683,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
|
||||
STRDUP(payload.fileurl, url, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
|
||||
payload.allow_resume = 1;
|
||||
payload.handle = handle;
|
||||
payload.trust_remote_name = 1;
|
||||
|
||||
/* download the file */
|
||||
ret = _alpm_download(&payload, cachedir, &final_file, &final_pkg_url);
|
||||
@@ -699,6 +708,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
|
||||
sig_filepath = filecache_find_url(handle, payload.fileurl);
|
||||
if(sig_filepath == NULL) {
|
||||
payload.handle = handle;
|
||||
payload.trust_remote_name = 1;
|
||||
payload.force = 1;
|
||||
payload.errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
|
||||
|
||||
@@ -742,4 +752,4 @@ void _alpm_dload_payload_reset(struct dload_payload *payload)
|
||||
memset(payload, '\0', sizeof(*payload));
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* dload.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_DLOAD_H
|
||||
#define _ALPM_DLOAD_H
|
||||
#ifndef ALPM_DLOAD_H
|
||||
#define ALPM_DLOAD_H
|
||||
|
||||
#include "alpm_list.h"
|
||||
#include "alpm.h"
|
||||
@@ -31,6 +31,8 @@ struct dload_payload {
|
||||
char *destfile_name;
|
||||
char *content_disp_name;
|
||||
char *fileurl;
|
||||
alpm_list_t *servers;
|
||||
long respcode;
|
||||
off_t initial_size;
|
||||
off_t max_size;
|
||||
off_t prevprogress;
|
||||
@@ -38,18 +40,17 @@ struct dload_payload {
|
||||
int allow_resume;
|
||||
int errors_ok;
|
||||
int unlink_on_fail;
|
||||
alpm_list_t *servers;
|
||||
int trust_remote_name;
|
||||
#ifdef HAVE_LIBCURL
|
||||
CURLcode curlerr; /* last error produced by curl */
|
||||
#endif
|
||||
long respcode;
|
||||
};
|
||||
|
||||
void _alpm_dload_payload_reset(struct dload_payload *payload);
|
||||
|
||||
int _alpm_download(struct dload_payload *payload, const char *localpath,
|
||||
char **final_file, char **final_url);
|
||||
char **final_file, const char **final_url);
|
||||
|
||||
#endif /* _ALPM_DLOAD_H */
|
||||
#endif /* ALPM_DLOAD_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* error.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -100,6 +100,8 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
|
||||
return _("operation not compatible with the transaction type");
|
||||
case ALPM_ERR_TRANS_NOT_LOCKED:
|
||||
return _("transaction commit attempt when database is not locked");
|
||||
case ALPM_ERR_TRANS_HOOK_FAILED:
|
||||
return _("failed to run transaction hooks");
|
||||
/* Packages */
|
||||
case ALPM_ERR_PKG_NOT_FOUND:
|
||||
return _("could not find or read package");
|
||||
@@ -111,6 +113,8 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
|
||||
return _("invalid or corrupted package (checksum)");
|
||||
case ALPM_ERR_PKG_INVALID_SIG:
|
||||
return _("invalid or corrupted package (PGP signature)");
|
||||
case ALPM_ERR_PKG_MISSING_SIG:
|
||||
return _("package missing required signature");
|
||||
case ALPM_ERR_PKG_OPEN:
|
||||
return _("cannot open package file");
|
||||
case ALPM_ERR_PKG_CANT_REMOVE:
|
||||
@@ -161,4 +165,4 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* filelist.c
|
||||
*
|
||||
* Copyright (c) 2012-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,199 +25,6 @@
|
||||
#include "filelist.h"
|
||||
#include "util.h"
|
||||
|
||||
/** Helper function for comparing strings when sorting */
|
||||
static int _alpm_filelist_strcmp(const void *s1, const void *s2)
|
||||
{
|
||||
return strcmp(*(char **)s1, *(char **)s2);
|
||||
}
|
||||
|
||||
/* TODO make sure callers check the return value so we can bail on errors.
|
||||
* For now we soldier on as best we can, skipping paths that are too long to
|
||||
* resolve and using the original filenames on memory errors. */
|
||||
/**
|
||||
* @brief Resolves a symlink and its children.
|
||||
*
|
||||
* @attention Pre-condition: files must be sorted!
|
||||
*
|
||||
* @param files filelist to resolve
|
||||
* @param i pointer to the index in files to start processing, will point to
|
||||
* the last file processed on return
|
||||
* @param path absolute path for the symlink being resolved
|
||||
* @param root_len length of the root portion of path
|
||||
* @param resolving is file \i in \files a symlink that needs to be resolved
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int _alpm_filelist_resolve_link(alpm_filelist_t *files, size_t *i,
|
||||
char *path, size_t root_len, int resolving)
|
||||
{
|
||||
char *causal_dir = NULL; /* symlink being resolved */
|
||||
char *filename_r = NULL; /* resolved filename */
|
||||
size_t causal_dir_len = 0, causal_dir_r_len = 0;
|
||||
|
||||
if(resolving) {
|
||||
/* deal with the symlink being resolved */
|
||||
MALLOC(filename_r, PATH_MAX, goto error);
|
||||
causal_dir = files->files[*i].name;
|
||||
causal_dir_len = strlen(causal_dir);
|
||||
if(realpath(path, filename_r) == NULL) {
|
||||
files->resolved_path[*i] = causal_dir;
|
||||
FREE(filename_r);
|
||||
return -1;
|
||||
}
|
||||
causal_dir_r_len = strlen(filename_r + root_len) + 1;
|
||||
if(causal_dir_r_len >= PATH_MAX) {
|
||||
files->resolved_path[*i] = causal_dir;
|
||||
FREE(filename_r);
|
||||
return -1;
|
||||
}
|
||||
/* remove root_r from filename_r */
|
||||
memmove(filename_r, filename_r + root_len, causal_dir_r_len);
|
||||
filename_r[causal_dir_r_len - 1] = '/';
|
||||
filename_r[causal_dir_r_len] = '\0';
|
||||
STRDUP(files->resolved_path[*i], filename_r, goto error);
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
for(; *i < files->count; (*i)++) {
|
||||
char *filename = files->files[*i].name;
|
||||
size_t filename_len = strlen(filename);
|
||||
size_t filename_r_len = filename_len;
|
||||
struct stat sbuf;
|
||||
int exists;
|
||||
|
||||
if(resolving) {
|
||||
if(filename_len < causal_dir_len || strncmp(filename, causal_dir, causal_dir_len) != 0) {
|
||||
/* not inside causal_dir anymore */
|
||||
break;
|
||||
}
|
||||
|
||||
filename_r_len = filename_len + causal_dir_r_len - causal_dir_len;
|
||||
if(filename_r_len >= PATH_MAX) {
|
||||
/* resolved path is too long */
|
||||
files->resolved_path[*i] = filename;
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy(filename_r + causal_dir_r_len, filename + causal_dir_len);
|
||||
}
|
||||
|
||||
/* deal with files and paths too long to resolve*/
|
||||
if(filename[filename_len - 1] != '/' || root_len + filename_r_len >= PATH_MAX) {
|
||||
if(resolving) {
|
||||
STRDUP(files->resolved_path[*i], filename_r, goto error);
|
||||
} else {
|
||||
files->resolved_path[*i] = filename;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* construct absolute path and stat() */
|
||||
strcpy(path + root_len, resolving ? filename_r : filename);
|
||||
exists = !_alpm_lstat(path, &sbuf);
|
||||
|
||||
/* deal with symlinks */
|
||||
if(exists && S_ISLNK(sbuf.st_mode)) {
|
||||
_alpm_filelist_resolve_link(files, i, path, root_len, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* deal with normal directories */
|
||||
if(resolving) {
|
||||
STRDUP(files->resolved_path[*i], filename_r, goto error);
|
||||
} else {
|
||||
files->resolved_path[*i] = filename;
|
||||
}
|
||||
|
||||
/* deal with children of non-existent directories to reduce lstat() calls */
|
||||
if(!exists) {
|
||||
for((*i)++; *i < files->count; (*i)++) {
|
||||
char *f = files->files[*i].name;
|
||||
size_t f_len = strlen(f);
|
||||
size_t f_r_len;
|
||||
|
||||
if(f_len < filename_len || strncmp(f, filename, filename_len) != 0) {
|
||||
/* not inside the non-existent dir anymore */
|
||||
break;
|
||||
}
|
||||
|
||||
f_r_len = f_len + causal_dir_r_len - causal_dir_len;
|
||||
if(resolving && f_r_len <= PATH_MAX) {
|
||||
strcpy(filename_r + causal_dir_r_len, f + causal_dir_len);
|
||||
STRDUP(files->resolved_path[*i], filename_r, goto error);
|
||||
} else {
|
||||
files->resolved_path[*i] = f;
|
||||
}
|
||||
}
|
||||
(*i)--;
|
||||
}
|
||||
}
|
||||
(*i)--;
|
||||
|
||||
FREE(filename_r);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
FREE(filename_r);
|
||||
/* out of memory, set remaining files to their original names */
|
||||
for(; *i < files->count; (*i)++) {
|
||||
files->resolved_path[*i] = files->files[*i].name;
|
||||
}
|
||||
(*i)--;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Takes a file list and resolves all directory paths according to the
|
||||
* filesystem
|
||||
*
|
||||
* @attention Pre-condition: files must be sorted!
|
||||
*
|
||||
* @note A symlink and directory at the same path in two difference packages
|
||||
* causes a conflict so the filepath can not change as packages get installed
|
||||
*
|
||||
* @param handle the context handle
|
||||
* @param files list of files to resolve
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int _alpm_filelist_resolve(alpm_handle_t *handle, alpm_filelist_t *files)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
size_t root_len, i = 0;
|
||||
int ret = 0;
|
||||
|
||||
if(!files || files->resolved_path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CALLOC(files->resolved_path, files->count, sizeof(char *), return -1);
|
||||
|
||||
/* not much point in going on if we can't even resolve root */
|
||||
if(realpath(handle->root, path) == NULL){
|
||||
return -1;
|
||||
}
|
||||
root_len = strlen(path);
|
||||
if(root_len + 1 >= PATH_MAX) {
|
||||
return -1;
|
||||
}
|
||||
/* append '/' if root is not "/" */
|
||||
if(path[root_len - 1] != '/') {
|
||||
path[root_len] = '/';
|
||||
root_len++;
|
||||
path[root_len] = '\0';
|
||||
}
|
||||
|
||||
ret = _alpm_filelist_resolve_link(files, &i, path, root_len, 0);
|
||||
|
||||
qsort(files->resolved_path, files->count, sizeof(char *),
|
||||
_alpm_filelist_strcmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the difference of the provided two lists of files.
|
||||
* Pre-condition: both lists are sorted!
|
||||
* When done, free the list but NOT the contained data.
|
||||
@@ -229,8 +36,8 @@ alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA,
|
||||
size_t ctrA = 0, ctrB = 0;
|
||||
|
||||
while(ctrA < filesA->count && ctrB < filesB->count) {
|
||||
char *strA = filesA->resolved_path[ctrA];
|
||||
char *strB = filesB->resolved_path[ctrB];
|
||||
char *strA = filesA->files[ctrA].name;
|
||||
char *strB = filesB->files[ctrB].name;
|
||||
|
||||
int cmp = strcmp(strA, strB);
|
||||
if(cmp < 0) {
|
||||
@@ -247,13 +54,30 @@ alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA,
|
||||
|
||||
/* ensure we have completely emptied pA */
|
||||
while(ctrA < filesA->count) {
|
||||
ret = alpm_list_add(ret, filesA->resolved_path[ctrA]);
|
||||
ret = alpm_list_add(ret, filesA->files[ctrA].name);
|
||||
ctrA++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _alpm_filelist_pathcmp(const char *p1, const char *p2)
|
||||
{
|
||||
while(*p1 && *p1 == *p2) {
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
|
||||
/* skip trailing '/' */
|
||||
if(*p1 == '\0' && *p2 == '/') {
|
||||
p2++;
|
||||
} else if(*p2 == '\0' && *p1 == '/') {
|
||||
p1++;
|
||||
}
|
||||
|
||||
return *p1 - *p2;
|
||||
}
|
||||
|
||||
/* Returns the intersection of the provided two lists of files.
|
||||
* Pre-condition: both lists are sorted!
|
||||
* When done, free the list but NOT the contained data.
|
||||
@@ -263,52 +87,23 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
|
||||
{
|
||||
alpm_list_t *ret = NULL;
|
||||
size_t ctrA = 0, ctrB = 0;
|
||||
alpm_file_t *arrA = filesA->files, *arrB = filesB->files;
|
||||
|
||||
while(ctrA < filesA->count && ctrB < filesB->count) {
|
||||
int cmp, isdirA, isdirB;
|
||||
char *strA, *strB;
|
||||
|
||||
isdirA = 0;
|
||||
strA = filesA->resolved_path[ctrA];
|
||||
if(strA[strlen(strA)-1] == '/') {
|
||||
isdirA = 1;
|
||||
strA = strndup(filesA->resolved_path[ctrA], strlen(strA)-1);
|
||||
}
|
||||
|
||||
isdirB = 0;
|
||||
strB = filesB->resolved_path[ctrB];
|
||||
if(strB[strlen(strB)-1] == '/') {
|
||||
isdirB = 1;
|
||||
strB = strndup(filesB->resolved_path[ctrB], strlen(strB)-1);
|
||||
}
|
||||
|
||||
cmp = strcmp(strA, strB);
|
||||
const char *strA = arrA[ctrA].name, *strB = arrB[ctrB].name;
|
||||
int cmp = _alpm_filelist_pathcmp(strA, strB);
|
||||
if(cmp < 0) {
|
||||
ctrA++;
|
||||
} else if(cmp > 0) {
|
||||
ctrB++;
|
||||
} else {
|
||||
/* TODO: this creates conflicts between a symlink to a directory in
|
||||
* one package and a real directory in the other. For example,
|
||||
* lib -> /usr/lib in pkg1 and /lib in pkg2. This would be allowed
|
||||
* when installing one package at a time _provided_ pkg1 is installed
|
||||
* first. This will need adjusted if the order of package install can
|
||||
* be guaranteed to install the symlink first */
|
||||
|
||||
/* when not directories, item in both qualifies as an intersect */
|
||||
if(! (isdirA && isdirB)) {
|
||||
ret = alpm_list_add(ret, filesA->resolved_path[ctrA]);
|
||||
if(strA[strlen(strA) - 1] != '/' || strB[strlen(strB) - 1] != '/') {
|
||||
ret = alpm_list_add(ret, arrA[ctrA].name);
|
||||
}
|
||||
ctrA++;
|
||||
ctrB++;
|
||||
}
|
||||
|
||||
if(isdirA) {
|
||||
free(strA);
|
||||
}
|
||||
if(isdirB) {
|
||||
free(strB);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -323,11 +118,10 @@ int _alpm_files_cmp(const void *f1, const void *f2)
|
||||
return strcmp(file1->name, file2->name);
|
||||
}
|
||||
|
||||
|
||||
char SYMEXPORT *alpm_filelist_contains(alpm_filelist_t *filelist,
|
||||
alpm_file_t SYMEXPORT *alpm_filelist_contains(alpm_filelist_t *filelist,
|
||||
const char *path)
|
||||
{
|
||||
alpm_file_t key, *match;
|
||||
alpm_file_t key;
|
||||
|
||||
if(!filelist) {
|
||||
return NULL;
|
||||
@@ -335,17 +129,8 @@ char SYMEXPORT *alpm_filelist_contains(alpm_filelist_t *filelist,
|
||||
|
||||
key.name = (char *)path;
|
||||
|
||||
match = bsearch(&key, filelist->files, filelist->count,
|
||||
return bsearch(&key, filelist->files, filelist->count,
|
||||
sizeof(alpm_file_t), _alpm_files_cmp);
|
||||
|
||||
if(match) {
|
||||
return match->name;
|
||||
} else if(filelist->resolved_path) {
|
||||
return bsearch(&path, filelist->resolved_path, filelist->count,
|
||||
sizeof(char *), _alpm_filelist_strcmp);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* filelist.h
|
||||
*
|
||||
* Copyright (c) 2012-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2012-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,15 +16,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_FILELIST_H
|
||||
#define _ALPM_FILELIST_H
|
||||
#ifndef ALPM_FILELIST_H
|
||||
#define ALPM_FILELIST_H
|
||||
|
||||
#include "alpm.h"
|
||||
|
||||
int _alpm_filelist_resolve_link(alpm_filelist_t *files, size_t *i,
|
||||
char *path, size_t root_len, int resolving);
|
||||
int _alpm_filelist_resolve(alpm_handle_t *handle, alpm_filelist_t *files);
|
||||
|
||||
alpm_list_t *_alpm_filelist_difference(alpm_filelist_t *filesA,
|
||||
alpm_filelist_t *filesB);
|
||||
|
||||
@@ -33,6 +29,6 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
|
||||
|
||||
int _alpm_files_cmp(const void *f1, const void *f2);
|
||||
|
||||
#endif /* _ALPM_FILELIST_H */
|
||||
#endif /* ALPM_FILELIST_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* graph.c - helpful graph structure and setup/teardown methods
|
||||
*
|
||||
* Copyright (c) 2007-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -31,9 +31,10 @@ alpm_graph_t *_alpm_graph_new(void)
|
||||
|
||||
void _alpm_graph_free(void *data)
|
||||
{
|
||||
ASSERT(data != NULL, return);
|
||||
alpm_graph_t *graph = data;
|
||||
alpm_list_free(graph->children);
|
||||
free(graph);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* graph.h - helpful graph structure and setup/teardown methods
|
||||
*
|
||||
* Copyright (c) 2007-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2007-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,25 +16,25 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_GRAPH_H
|
||||
#define _ALPM_GRAPH_H
|
||||
#ifndef ALPM_GRAPH_H
|
||||
#define ALPM_GRAPH_H
|
||||
|
||||
#include <sys/types.h> /* off_t */
|
||||
|
||||
#include "alpm_list.h"
|
||||
|
||||
typedef struct __alpm_graph_t {
|
||||
char state; /* 0: untouched, -1: entered, other: leaving time */
|
||||
off_t weight; /* weight of the node */
|
||||
void *data;
|
||||
struct __alpm_graph_t *parent; /* where did we come from? */
|
||||
alpm_list_t *children;
|
||||
alpm_list_t *childptr; /* points to a child in children list */
|
||||
off_t weight; /* weight of the node */
|
||||
signed char state; /* 0: untouched, -1: entered, other: leaving time */
|
||||
} alpm_graph_t;
|
||||
|
||||
alpm_graph_t *_alpm_graph_new(void);
|
||||
void _alpm_graph_free(void *data);
|
||||
|
||||
#endif /* _ALPM_GRAPH_H */
|
||||
#endif /* ALPM_GRAPH_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* group.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -50,4 +50,4 @@ void _alpm_group_free(alpm_group_t *grp)
|
||||
FREE(grp);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* group.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,14 +17,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_GROUP_H
|
||||
#define _ALPM_GROUP_H
|
||||
#ifndef ALPM_GROUP_H
|
||||
#define ALPM_GROUP_H
|
||||
|
||||
#include "alpm.h"
|
||||
|
||||
alpm_group_t *_alpm_group_new(const char *name);
|
||||
void _alpm_group_free(alpm_group_t *grp);
|
||||
|
||||
#endif /* _ALPM_GROUP_H */
|
||||
#endif /* ALPM_GROUP_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* handle.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
|
||||
* Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "delta.h"
|
||||
#include "trans.h"
|
||||
#include "alpm.h"
|
||||
#include "deps.h"
|
||||
|
||||
alpm_handle_t *_alpm_handle_new(void)
|
||||
{
|
||||
@@ -44,6 +45,7 @@ alpm_handle_t *_alpm_handle_new(void)
|
||||
|
||||
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
|
||||
handle->deltaratio = 0.0;
|
||||
handle->lockfd = -1;
|
||||
|
||||
return handle;
|
||||
}
|
||||
@@ -69,33 +71,41 @@ void _alpm_handle_free(alpm_handle_t *handle)
|
||||
curl_easy_cleanup(handle->curl);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBGPGME
|
||||
FREELIST(handle->known_keys);
|
||||
#endif
|
||||
|
||||
regfree(&handle->delta_regex);
|
||||
|
||||
/* free memory */
|
||||
_alpm_trans_free(handle->trans);
|
||||
FREE(handle->root);
|
||||
FREE(handle->dbpath);
|
||||
FREE(handle->dbext);
|
||||
FREELIST(handle->cachedirs);
|
||||
FREELIST(handle->hookdirs);
|
||||
FREE(handle->logfile);
|
||||
FREE(handle->lockfile);
|
||||
FREE(handle->arch);
|
||||
FREE(handle->gpgdir);
|
||||
FREELIST(handle->dbs_sync);
|
||||
FREELIST(handle->noupgrade);
|
||||
FREELIST(handle->noextract);
|
||||
FREELIST(handle->ignorepkg);
|
||||
FREELIST(handle->ignoregroup);
|
||||
|
||||
alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
|
||||
alpm_list_free(handle->assumeinstalled);
|
||||
|
||||
FREE(handle);
|
||||
}
|
||||
|
||||
/** Lock the database */
|
||||
int _alpm_handle_lock(alpm_handle_t *handle)
|
||||
{
|
||||
int fd;
|
||||
char *dir, *ptr;
|
||||
|
||||
ASSERT(handle->lockfile != NULL, return -1);
|
||||
ASSERT(handle->lckstream == NULL, return 0);
|
||||
ASSERT(handle->lockfd < 0, return 0);
|
||||
|
||||
/* create the dir of the lockfile first */
|
||||
dir = strdup(handle->lockfile);
|
||||
@@ -110,31 +120,51 @@ int _alpm_handle_lock(alpm_handle_t *handle)
|
||||
FREE(dir);
|
||||
|
||||
do {
|
||||
fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000);
|
||||
} while(fd == -1 && errno == EINTR);
|
||||
if(fd >= 0) {
|
||||
FILE *f = fdopen(fd, "w");
|
||||
fprintf(f, "%ld\n", (long)getpid());
|
||||
fflush(f);
|
||||
fsync(fd);
|
||||
handle->lckstream = f;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
handle->lockfd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0000);
|
||||
} while(handle->lockfd == -1 && errno == EINTR);
|
||||
|
||||
return (handle->lockfd >= 0 ? 0 : -1);
|
||||
}
|
||||
|
||||
/** Remove the database lock file
|
||||
* @param handle the context handle
|
||||
* @return 0 on success, -1 on error
|
||||
*
|
||||
* @note Safe to call from inside signal handlers.
|
||||
*/
|
||||
int SYMEXPORT alpm_unlock(alpm_handle_t *handle)
|
||||
{
|
||||
ASSERT(handle->lockfile != NULL, return 0);
|
||||
ASSERT(handle->lockfd >= 0, return 0);
|
||||
|
||||
close(handle->lockfd);
|
||||
handle->lockfd = -1;
|
||||
|
||||
if(unlink(handle->lockfile) != 0) {
|
||||
RET_ERR_ASYNC_SAFE(handle, ALPM_ERR_SYSTEM, -1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove a lock file */
|
||||
int _alpm_handle_unlock(alpm_handle_t *handle)
|
||||
{
|
||||
ASSERT(handle->lockfile != NULL, return -1);
|
||||
ASSERT(handle->lckstream != NULL, return 0);
|
||||
|
||||
fclose(handle->lckstream);
|
||||
handle->lckstream = NULL;
|
||||
|
||||
if(unlink(handle->lockfile) && errno != ENOENT) {
|
||||
return -1;
|
||||
if(alpm_unlock(handle) != 0) {
|
||||
if(errno == ENOENT) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("lock file missing %s\n"), handle->lockfile);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: lock file missing %s\n", handle->lockfile);
|
||||
return 0;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("could not remove lock file %s\n"), handle->lockfile);
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX,
|
||||
"warning: could not remove lock file %s\n", handle->lockfile);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -193,6 +223,12 @@ const char SYMEXPORT *alpm_option_get_dbpath(alpm_handle_t *handle)
|
||||
return handle->dbpath;
|
||||
}
|
||||
|
||||
alpm_list_t SYMEXPORT *alpm_option_get_hookdirs(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
return handle->hookdirs;
|
||||
}
|
||||
|
||||
alpm_list_t SYMEXPORT *alpm_option_get_cachedirs(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
@@ -247,6 +283,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
|
||||
return handle->ignoregroup;
|
||||
}
|
||||
|
||||
alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
return handle->assumeinstalled;
|
||||
}
|
||||
|
||||
const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
@@ -265,6 +307,12 @@ int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
|
||||
return handle->checkspace;
|
||||
}
|
||||
|
||||
const char SYMEXPORT *alpm_option_get_dbext(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
return handle->dbext;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
@@ -361,6 +409,58 @@ alpm_errno_t _alpm_set_directory_option(const char *value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_hookdir(alpm_handle_t *handle, const char *hookdir)
|
||||
{
|
||||
char *newhookdir;
|
||||
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
ASSERT(hookdir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
|
||||
newhookdir = canonicalize_path(hookdir);
|
||||
if(!newhookdir) {
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
|
||||
}
|
||||
handle->hookdirs = alpm_list_add(handle->hookdirs, newhookdir);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'hookdir' = %s\n", newhookdir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_hookdirs(alpm_handle_t *handle, alpm_list_t *hookdirs)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->hookdirs) {
|
||||
FREELIST(handle->hookdirs);
|
||||
}
|
||||
for(i = hookdirs; i; i = i->next) {
|
||||
int ret = alpm_option_add_hookdir(handle, i->data);
|
||||
if(ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_hookdir(alpm_handle_t *handle, const char *hookdir)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
char *newhookdir;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
ASSERT(hookdir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
|
||||
newhookdir = canonicalize_path(hookdir);
|
||||
if(!newhookdir) {
|
||||
RET_ERR(handle, ALPM_ERR_MEMORY, -1);
|
||||
}
|
||||
handle->hookdirs = alpm_list_remove_str(handle->hookdirs, newhookdir, &vdata);
|
||||
FREE(newhookdir);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_cachedir(alpm_handle_t *handle, const char *cachedir)
|
||||
{
|
||||
char *newcachedir;
|
||||
@@ -425,7 +525,7 @@ int SYMEXPORT alpm_option_set_logfile(alpm_handle_t *handle, const char *logfile
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->logfile = strdup(logfile);
|
||||
STRDUP(handle->logfile, logfile, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
|
||||
/* free the old logfile path string, and close the stream so logaction
|
||||
* will reopen a new stream on the new logfile */
|
||||
@@ -442,17 +542,11 @@ int SYMEXPORT alpm_option_set_logfile(alpm_handle_t *handle, const char *logfile
|
||||
|
||||
int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir)
|
||||
{
|
||||
int err;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(!gpgdir) {
|
||||
handle->pm_errno = ALPM_ERR_WRONG_ARGS;
|
||||
return -1;
|
||||
if((err = _alpm_set_directory_option(gpgdir, &(handle->gpgdir), 0))) {
|
||||
RET_ERR(handle, err, -1);
|
||||
}
|
||||
|
||||
if(handle->gpgdir) {
|
||||
FREE(handle->gpgdir);
|
||||
}
|
||||
handle->gpgdir = strdup(gpgdir);
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'gpgdir' = %s\n", handle->gpgdir);
|
||||
return 0;
|
||||
}
|
||||
@@ -464,111 +558,169 @@ int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg)
|
||||
static int _alpm_option_strlist_add(alpm_handle_t *handle, alpm_list_t **list, const char *str)
|
||||
{
|
||||
char *dup;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
STRDUP(dup, str, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
*list = alpm_list_add(*list, dup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _alpm_option_strlist_set(alpm_handle_t *handle, alpm_list_t **list, alpm_list_t *newlist)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
|
||||
FREELIST(*list);
|
||||
*list = alpm_list_strdup(newlist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _alpm_option_strlist_rem(alpm_handle_t *handle, alpm_list_t **list, const char *str)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
*list = alpm_list_remove_str(*list, str, &vdata);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg)
|
||||
{
|
||||
return _alpm_option_strlist_add(handle, &(handle->noupgrade), pkg);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_noupgrades(alpm_handle_t *handle, alpm_list_t *noupgrade)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->noupgrade) FREELIST(handle->noupgrade);
|
||||
handle->noupgrade = alpm_list_strdup(noupgrade);
|
||||
return 0;
|
||||
return _alpm_option_strlist_set(handle, &(handle->noupgrade), noupgrade);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return _alpm_option_strlist_rem(handle, &(handle->noupgrade), pkg);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_noextract(alpm_handle_t *handle, const char *pkg)
|
||||
int SYMEXPORT alpm_option_match_noupgrade(alpm_handle_t *handle, const char *path)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
|
||||
return 0;
|
||||
return _alpm_fnmatch_patterns(handle->noupgrade, path);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_noextract(alpm_handle_t *handle, const char *path)
|
||||
{
|
||||
return _alpm_option_strlist_add(handle, &(handle->noextract), path);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_noextracts(alpm_handle_t *handle, alpm_list_t *noextract)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->noextract) FREELIST(handle->noextract);
|
||||
handle->noextract = alpm_list_strdup(noextract);
|
||||
return 0;
|
||||
return _alpm_option_strlist_set(handle, &(handle->noextract), noextract);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_noextract(alpm_handle_t *handle, const char *pkg)
|
||||
int SYMEXPORT alpm_option_remove_noextract(alpm_handle_t *handle, const char *path)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return _alpm_option_strlist_rem(handle, &(handle->noextract), path);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_match_noextract(alpm_handle_t *handle, const char *path)
|
||||
{
|
||||
return _alpm_fnmatch_patterns(handle->noextract, path);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_ignorepkg(alpm_handle_t *handle, const char *pkg)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
|
||||
return 0;
|
||||
return _alpm_option_strlist_add(handle, &(handle->ignorepkg), pkg);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_ignorepkgs(alpm_handle_t *handle, alpm_list_t *ignorepkgs)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->ignorepkg) FREELIST(handle->ignorepkg);
|
||||
handle->ignorepkg = alpm_list_strdup(ignorepkgs);
|
||||
return 0;
|
||||
return _alpm_option_strlist_set(handle, &(handle->ignorepkg), ignorepkgs);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_ignorepkg(alpm_handle_t *handle, const char *pkg)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return _alpm_option_strlist_rem(handle, &(handle->ignorepkg), pkg);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_ignoregroup(alpm_handle_t *handle, const char *grp)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->ignoregroup = alpm_list_add(handle->ignoregroup, strdup(grp));
|
||||
return 0;
|
||||
return _alpm_option_strlist_add(handle, &(handle->ignoregroup), grp);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->ignoregroup) FREELIST(handle->ignoregroup);
|
||||
handle->ignoregroup = alpm_list_strdup(ignoregrps);
|
||||
return 0;
|
||||
return _alpm_option_strlist_set(handle, &(handle->ignoregroup), ignoregrps);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp)
|
||||
{
|
||||
char *vdata = NULL;
|
||||
return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp);
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
|
||||
{
|
||||
alpm_depend_t *depcpy;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
handle->ignoregroup = alpm_list_remove_str(handle->ignoregroup, grp, &vdata);
|
||||
ASSERT(dep->mod == ALPM_DEP_MOD_EQ || dep->mod == ALPM_DEP_MOD_ANY,
|
||||
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
ASSERT((depcpy = _alpm_dep_dup(dep)), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
|
||||
/* fill in name_hash in case dep was built by hand */
|
||||
depcpy->name_hash = _alpm_hash_sdbm(dep->name);
|
||||
handle->assumeinstalled = alpm_list_add(handle->assumeinstalled, depcpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->assumeinstalled) {
|
||||
alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
|
||||
alpm_list_free(handle->assumeinstalled);
|
||||
}
|
||||
while(deps) {
|
||||
if(alpm_option_add_assumeinstalled(handle, deps->data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
deps = deps->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int assumeinstalled_cmp(const void *d1, const void *d2)
|
||||
{
|
||||
const alpm_depend_t *dep1 = d1;
|
||||
const alpm_depend_t *dep2 = d2;
|
||||
|
||||
if(dep1->name_hash != dep2->name_hash
|
||||
|| strcmp(dep1->name, dep2->name) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(dep1->version && dep2->version
|
||||
&& strcmp(dep1->version, dep2->version) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(dep1->version == NULL && dep2->version == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
|
||||
{
|
||||
alpm_depend_t *vdata = NULL;
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
|
||||
handle->assumeinstalled = alpm_list_remove(handle->assumeinstalled, dep, &assumeinstalled_cmp, (void **)&vdata);
|
||||
if(vdata != NULL) {
|
||||
FREE(vdata);
|
||||
alpm_dep_free(vdata);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -576,11 +728,7 @@ int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
if(handle->arch) FREE(handle->arch);
|
||||
if(arch) {
|
||||
handle->arch = strdup(arch);
|
||||
} else {
|
||||
handle->arch = NULL;
|
||||
}
|
||||
STRDUP(handle->arch, arch, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -613,6 +761,21 @@ int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
ASSERT(dbext, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
|
||||
|
||||
if(handle->dbext) {
|
||||
FREE(handle->dbext);
|
||||
}
|
||||
|
||||
STRDUP(handle->dbext, dbext, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "option 'dbext' = %s\n", handle->dbext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
|
||||
alpm_siglevel_t level)
|
||||
{
|
||||
@@ -650,7 +813,11 @@ int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle,
|
||||
alpm_siglevel_t SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
return handle->localfilesiglevel;
|
||||
if(handle->localfilesiglevel & ALPM_SIG_USE_DEFAULT) {
|
||||
return handle->siglevel;
|
||||
} else {
|
||||
return handle->localfilesiglevel;
|
||||
}
|
||||
}
|
||||
|
||||
int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle,
|
||||
@@ -670,7 +837,11 @@ int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle,
|
||||
alpm_siglevel_t SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *handle)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
return handle->remotefilesiglevel;
|
||||
if(handle->remotefilesiglevel & ALPM_SIG_USE_DEFAULT) {
|
||||
return handle->siglevel;
|
||||
} else {
|
||||
return handle->remotefilesiglevel;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* handle.h
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _ALPM_HANDLE_H
|
||||
#define _ALPM_HANDLE_H
|
||||
#ifndef ALPM_HANDLE_H
|
||||
#define ALPM_HANDLE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
@@ -31,16 +31,16 @@
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#define EVENT(h, e, d1, d2) \
|
||||
#define EVENT(h, e) \
|
||||
do { \
|
||||
if((h)->eventcb) { \
|
||||
(h)->eventcb(e, d1, d2); \
|
||||
(h)->eventcb((alpm_event_t *) (e)); \
|
||||
} \
|
||||
} while(0)
|
||||
#define QUESTION(h, q, d1, d2, d3, r) \
|
||||
#define QUESTION(h, q) \
|
||||
do { \
|
||||
if((h)->questioncb) { \
|
||||
(h)->questioncb(q, d1, d2, d3, r); \
|
||||
(h)->questioncb((alpm_question_t *) (q)); \
|
||||
} \
|
||||
} while(0)
|
||||
#define PROGRESS(h, e, p, per, n, r) \
|
||||
@@ -52,10 +52,9 @@ do { \
|
||||
|
||||
struct __alpm_handle_t {
|
||||
/* internal usage */
|
||||
alpm_db_t *db_local; /* local db pointer */
|
||||
alpm_db_t *db_local; /* local db pointer */
|
||||
alpm_list_t *dbs_sync; /* List of (alpm_db_t *) */
|
||||
FILE *logstream; /* log file stream pointer */
|
||||
FILE *lckstream; /* lock file stream pointer if one exists */
|
||||
alpm_trans_t *trans;
|
||||
|
||||
#ifdef HAVE_LIBCURL
|
||||
@@ -63,11 +62,15 @@ struct __alpm_handle_t {
|
||||
CURL *curl; /* reusable curl_easy handle */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBGPGME
|
||||
alpm_list_t *known_keys; /* keys verified to be in our keychain */
|
||||
#endif
|
||||
|
||||
/* callback functions */
|
||||
alpm_cb_log logcb; /* Log callback function */
|
||||
alpm_cb_download dlcb; /* Download callback function */
|
||||
alpm_cb_log logcb; /* Log callback function */
|
||||
alpm_cb_download dlcb; /* Download callback function */
|
||||
alpm_cb_totaldl totaldlcb; /* Total download callback function */
|
||||
alpm_cb_fetch fetchcb; /* Download file callback function */
|
||||
alpm_cb_fetch fetchcb; /* Download file callback function */
|
||||
alpm_cb_event eventcb;
|
||||
alpm_cb_question questioncb;
|
||||
alpm_cb_progress progresscb;
|
||||
@@ -79,18 +82,21 @@ struct __alpm_handle_t {
|
||||
char *lockfile; /* Name of the lock file */
|
||||
char *gpgdir; /* Directory where GnuPG files are stored */
|
||||
alpm_list_t *cachedirs; /* Paths to pacman cache directories */
|
||||
alpm_list_t *hookdirs; /* Paths to hook directories */
|
||||
|
||||
/* package lists */
|
||||
alpm_list_t *noupgrade; /* List of packages NOT to be upgraded */
|
||||
alpm_list_t *noextract; /* List of files NOT to extract */
|
||||
alpm_list_t *ignorepkg; /* List of packages to ignore */
|
||||
alpm_list_t *ignoregroup; /* List of groups to ignore */
|
||||
alpm_list_t *assumeinstalled; /* List of virtual packages used to satisfy dependencies */
|
||||
|
||||
/* options */
|
||||
char *arch; /* Architecture of packages we should allow */
|
||||
double deltaratio; /* Download deltas if possible; a ratio value */
|
||||
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
|
||||
int checkspace; /* Check disk space before installing */
|
||||
char *dbext; /* Sync DB extension */
|
||||
alpm_siglevel_t siglevel; /* Default signature verification level */
|
||||
alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file
|
||||
upgrade operations */
|
||||
@@ -100,6 +106,9 @@ struct __alpm_handle_t {
|
||||
/* error code */
|
||||
alpm_errno_t pm_errno;
|
||||
|
||||
/* lock file descriptor */
|
||||
int lockfd;
|
||||
|
||||
/* for delta parsing efficiency */
|
||||
int delta_regex_compiled;
|
||||
regex_t delta_regex;
|
||||
@@ -114,6 +123,6 @@ int _alpm_handle_unlock(alpm_handle_t *handle);
|
||||
alpm_errno_t _alpm_set_directory_option(const char *value,
|
||||
char **storage, int must_exist);
|
||||
|
||||
#endif /* _ALPM_HANDLE_H */
|
||||
#endif /* ALPM_HANDLE_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
770
lib/libalpm/hook.c
Normal file
770
lib/libalpm/hook.c
Normal file
@@ -0,0 +1,770 @@
|
||||
/*
|
||||
* hook.c
|
||||
*
|
||||
* Copyright (c) 2015-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "handle.h"
|
||||
#include "hook.h"
|
||||
#include "ini.h"
|
||||
#include "log.h"
|
||||
#include "trans.h"
|
||||
#include "util.h"
|
||||
|
||||
enum _alpm_hook_op_t {
|
||||
ALPM_HOOK_OP_INSTALL = (1 << 0),
|
||||
ALPM_HOOK_OP_UPGRADE = (1 << 1),
|
||||
ALPM_HOOK_OP_REMOVE = (1 << 2),
|
||||
};
|
||||
|
||||
enum _alpm_trigger_type_t {
|
||||
ALPM_HOOK_TYPE_PACKAGE = 1,
|
||||
ALPM_HOOK_TYPE_FILE,
|
||||
};
|
||||
|
||||
struct _alpm_trigger_t {
|
||||
enum _alpm_hook_op_t op;
|
||||
enum _alpm_trigger_type_t type;
|
||||
alpm_list_t *targets;
|
||||
};
|
||||
|
||||
struct _alpm_hook_t {
|
||||
char *name;
|
||||
char *desc;
|
||||
alpm_list_t *triggers;
|
||||
alpm_list_t *depends;
|
||||
char **cmd;
|
||||
alpm_list_t *matches;
|
||||
alpm_hook_when_t when;
|
||||
int abort_on_fail, needs_targets;
|
||||
};
|
||||
|
||||
struct _alpm_hook_cb_ctx {
|
||||
alpm_handle_t *handle;
|
||||
struct _alpm_hook_t *hook;
|
||||
};
|
||||
|
||||
static void _alpm_trigger_free(struct _alpm_trigger_t *trigger)
|
||||
{
|
||||
if(trigger) {
|
||||
FREELIST(trigger->targets);
|
||||
free(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
static void _alpm_wordsplit_free(char **ws)
|
||||
{
|
||||
if(ws) {
|
||||
char **c;
|
||||
for(c = ws; *c; c++) {
|
||||
free(*c);
|
||||
}
|
||||
free(ws);
|
||||
}
|
||||
}
|
||||
|
||||
static void _alpm_hook_free(struct _alpm_hook_t *hook)
|
||||
{
|
||||
if(hook) {
|
||||
free(hook->name);
|
||||
free(hook->desc);
|
||||
_alpm_wordsplit_free(hook->cmd);
|
||||
alpm_list_free_inner(hook->triggers, (alpm_list_fn_free) _alpm_trigger_free);
|
||||
alpm_list_free(hook->triggers);
|
||||
alpm_list_free(hook->matches);
|
||||
FREELIST(hook->depends);
|
||||
free(hook);
|
||||
}
|
||||
}
|
||||
|
||||
static int _alpm_trigger_validate(alpm_handle_t *handle,
|
||||
struct _alpm_trigger_t *trigger, const char *file)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(trigger->targets == NULL) {
|
||||
ret = -1;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Missing trigger targets in hook: %s\n"), file);
|
||||
}
|
||||
|
||||
if(trigger->type == 0) {
|
||||
ret = -1;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Missing trigger type in hook: %s\n"), file);
|
||||
}
|
||||
|
||||
if(trigger->op == 0) {
|
||||
ret = -1;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Missing trigger operation in hook: %s\n"), file);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _alpm_hook_validate(alpm_handle_t *handle,
|
||||
struct _alpm_hook_t *hook, const char *file)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
int ret = 0;
|
||||
|
||||
if(hook->triggers == NULL) {
|
||||
/* special case: allow triggerless hooks as a way of creating dummy
|
||||
* hooks that can be used to mask lower priority hooks */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = hook->triggers; i; i = i->next) {
|
||||
if(_alpm_trigger_validate(handle, i->data, file) != 0) {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(hook->cmd == NULL) {
|
||||
ret = -1;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Missing Exec option in hook: %s\n"), file);
|
||||
}
|
||||
|
||||
if(hook->when == 0) {
|
||||
ret = -1;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("Missing When option in hook: %s\n"), file);
|
||||
} else if(hook->when != ALPM_HOOK_PRE_TRANSACTION && hook->abort_on_fail) {
|
||||
_alpm_log(handle, ALPM_LOG_WARNING,
|
||||
_("AbortOnFail set for PostTransaction hook: %s\n"), file);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char **_alpm_wordsplit(char *str)
|
||||
{
|
||||
char *c = str, *end;
|
||||
char **out = NULL, **outsave;
|
||||
size_t count = 0;
|
||||
|
||||
if(str == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(c = str; isspace(*c); c++);
|
||||
while(*c) {
|
||||
size_t wordlen = 0;
|
||||
|
||||
/* extend our array */
|
||||
outsave = out;
|
||||
if((out = realloc(out, (count + 1) * sizeof(char*))) == NULL) {
|
||||
out = outsave;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* calculate word length and check for unbalanced quotes */
|
||||
for(end = c; *end && !isspace(*end); end++) {
|
||||
if(*end == '\'' || *end == '"') {
|
||||
char quote = *end;
|
||||
while(*(++end) && *end != quote) {
|
||||
if(*end == '\\' && *(end + 1) == quote) {
|
||||
end++;
|
||||
}
|
||||
wordlen++;
|
||||
}
|
||||
if(*end != quote) {
|
||||
errno = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if(*end == '\\' && (end[1] == '\'' || end[1] == '"')) {
|
||||
end++; /* skip the '\\' */
|
||||
}
|
||||
wordlen++;
|
||||
}
|
||||
}
|
||||
|
||||
if(wordlen == (size_t) (end - c)) {
|
||||
/* no internal quotes or escapes, copy it the easy way */
|
||||
if((out[count++] = strndup(c, wordlen)) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* manually copy to remove quotes and escapes */
|
||||
char *dest = out[count++] = malloc(wordlen + 1);
|
||||
if(dest == NULL) { goto error; }
|
||||
while(c < end) {
|
||||
if(*c == '\'' || *c == '"') {
|
||||
char quote = *c;
|
||||
/* we know there must be a matching end quote,
|
||||
* no need to check for '\0' */
|
||||
for(c++; *c != quote; c++) {
|
||||
if(*c == '\\' && *(c + 1) == quote) {
|
||||
c++;
|
||||
}
|
||||
*(dest++) = *c;
|
||||
}
|
||||
c++;
|
||||
} else {
|
||||
if(*c == '\\' && (c[1] == '\'' || c[1] == '"')) {
|
||||
c++; /* skip the '\\' */
|
||||
}
|
||||
*(dest++) = *(c++);
|
||||
}
|
||||
}
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
if(*end == '\0') {
|
||||
break;
|
||||
} else {
|
||||
for(c = end + 1; isspace(*c); c++);
|
||||
}
|
||||
}
|
||||
|
||||
outsave = out;
|
||||
if((out = realloc(out, (count + 1) * sizeof(char*))) == NULL) {
|
||||
out = outsave;
|
||||
goto error;
|
||||
}
|
||||
|
||||
out[count++] = NULL;
|
||||
|
||||
return out;
|
||||
|
||||
error:
|
||||
/* can't use wordsplit_free here because NULL has not been appended */
|
||||
while(count) {
|
||||
free(out[--count]);
|
||||
}
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _alpm_hook_parse_cb(const char *file, int line,
|
||||
const char *section, char *key, char *value, void *data)
|
||||
{
|
||||
struct _alpm_hook_cb_ctx *ctx = data;
|
||||
alpm_handle_t *handle = ctx->handle;
|
||||
struct _alpm_hook_t *hook = ctx->hook;
|
||||
|
||||
#define error(...) _alpm_log(handle, ALPM_LOG_ERROR, __VA_ARGS__); return 1;
|
||||
|
||||
if(!section && !key) {
|
||||
error(_("error while reading hook %s: %s\n"), file, strerror(errno));
|
||||
} else if(!section) {
|
||||
error(_("hook %s line %d: invalid option %s\n"), file, line, key);
|
||||
} else if(!key) {
|
||||
/* beginning a new section */
|
||||
if(strcmp(section, "Trigger") == 0) {
|
||||
struct _alpm_trigger_t *t;
|
||||
CALLOC(t, sizeof(struct _alpm_trigger_t), 1, return 1);
|
||||
hook->triggers = alpm_list_add(hook->triggers, t);
|
||||
} else if(strcmp(section, "Action") == 0) {
|
||||
/* no special processing required */
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid section %s\n"), file, line, section);
|
||||
}
|
||||
} else if(strcmp(section, "Trigger") == 0) {
|
||||
struct _alpm_trigger_t *t = hook->triggers->prev->data;
|
||||
if(strcmp(key, "Operation") == 0) {
|
||||
if(strcmp(value, "Install") == 0) {
|
||||
t->op |= ALPM_HOOK_OP_INSTALL;
|
||||
} else if(strcmp(value, "Upgrade") == 0) {
|
||||
t->op |= ALPM_HOOK_OP_UPGRADE;
|
||||
} else if(strcmp(value, "Remove") == 0) {
|
||||
t->op |= ALPM_HOOK_OP_REMOVE;
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid value %s\n"), file, line, value);
|
||||
}
|
||||
} else if(strcmp(key, "Type") == 0) {
|
||||
if(strcmp(value, "Package") == 0) {
|
||||
t->type = ALPM_HOOK_TYPE_PACKAGE;
|
||||
} else if(strcmp(value, "File") == 0) {
|
||||
t->type = ALPM_HOOK_TYPE_FILE;
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid value %s\n"), file, line, value);
|
||||
}
|
||||
} else if(strcmp(key, "Target") == 0) {
|
||||
char *val;
|
||||
STRDUP(val, value, return 1);
|
||||
t->targets = alpm_list_add(t->targets, val);
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid option %s\n"), file, line, key);
|
||||
}
|
||||
} else if(strcmp(section, "Action") == 0) {
|
||||
if(strcmp(key, "When") == 0) {
|
||||
if(strcmp(value, "PreTransaction") == 0) {
|
||||
hook->when = ALPM_HOOK_PRE_TRANSACTION;
|
||||
} else if(strcmp(value, "PostTransaction") == 0) {
|
||||
hook->when = ALPM_HOOK_POST_TRANSACTION;
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid value %s\n"), file, line, value);
|
||||
}
|
||||
} else if(strcmp(key, "Description") == 0) {
|
||||
STRDUP(hook->desc, value, return 1);
|
||||
} else if(strcmp(key, "Depends") == 0) {
|
||||
char *val;
|
||||
STRDUP(val, value, return 1);
|
||||
hook->depends = alpm_list_add(hook->depends, val);
|
||||
} else if(strcmp(key, "AbortOnFail") == 0) {
|
||||
hook->abort_on_fail = 1;
|
||||
} else if(strcmp(key, "NeedsTargets") == 0) {
|
||||
hook->needs_targets = 1;
|
||||
} else if(strcmp(key, "Exec") == 0) {
|
||||
if((hook->cmd = _alpm_wordsplit(value)) == NULL) {
|
||||
if(errno == EINVAL) {
|
||||
error(_("hook %s line %d: invalid value %s\n"), file, line, value);
|
||||
} else {
|
||||
error(_("hook %s line %d: unable to set option (%s)\n"),
|
||||
file, line, strerror(errno));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error(_("hook %s line %d: invalid option %s\n"), file, line, key);
|
||||
}
|
||||
}
|
||||
|
||||
#undef error
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _alpm_hook_trigger_match_file(alpm_handle_t *handle,
|
||||
struct _alpm_hook_t *hook, struct _alpm_trigger_t *t)
|
||||
{
|
||||
alpm_list_t *i, *j, *install = NULL, *upgrade = NULL, *remove = NULL;
|
||||
size_t isize = 0, rsize = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* check if file will be installed */
|
||||
for(i = handle->trans->add; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
alpm_filelist_t filelist = pkg->files;
|
||||
size_t f;
|
||||
for(f = 0; f < filelist.count; f++) {
|
||||
if(alpm_option_match_noextract(handle, filelist.files[f].name) == 0) {
|
||||
continue;
|
||||
}
|
||||
if(_alpm_fnmatch_patterns(t->targets, filelist.files[f].name) == 0) {
|
||||
install = alpm_list_add(install, filelist.files[f].name);
|
||||
isize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if file will be removed due to package upgrade */
|
||||
for(i = handle->trans->add; i; i = i->next) {
|
||||
alpm_pkg_t *spkg = i->data;
|
||||
alpm_pkg_t *pkg = spkg->oldpkg;
|
||||
if(pkg) {
|
||||
alpm_filelist_t filelist = pkg->files;
|
||||
size_t f;
|
||||
for(f = 0; f < filelist.count; f++) {
|
||||
if(_alpm_fnmatch_patterns(t->targets, filelist.files[f].name) == 0) {
|
||||
remove = alpm_list_add(remove, filelist.files[f].name);
|
||||
rsize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if file will be removed due to package removal */
|
||||
for(i = handle->trans->remove; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
alpm_filelist_t filelist = pkg->files;
|
||||
size_t f;
|
||||
for(f = 0; f < filelist.count; f++) {
|
||||
if(_alpm_fnmatch_patterns(t->targets, filelist.files[f].name) == 0) {
|
||||
remove = alpm_list_add(remove, filelist.files[f].name);
|
||||
rsize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = install = alpm_list_msort(install, isize, (alpm_list_fn_cmp)strcmp);
|
||||
j = remove = alpm_list_msort(remove, rsize, (alpm_list_fn_cmp)strcmp);
|
||||
while(i) {
|
||||
while(j && strcmp(i->data, j->data) > 0) {
|
||||
j = j->next;
|
||||
}
|
||||
if(j == NULL) {
|
||||
break;
|
||||
}
|
||||
if(strcmp(i->data, j->data) == 0) {
|
||||
char *path = i->data;
|
||||
upgrade = alpm_list_add(upgrade, path);
|
||||
while(i && strcmp(i->data, path) == 0) {
|
||||
alpm_list_t *next = i->next;
|
||||
install = alpm_list_remove_item(install, i);
|
||||
free(i);
|
||||
i = next;
|
||||
}
|
||||
while(j && strcmp(j->data, path) == 0) {
|
||||
alpm_list_t *next = j->next;
|
||||
remove = alpm_list_remove_item(remove, j);
|
||||
free(j);
|
||||
j = next;
|
||||
}
|
||||
} else {
|
||||
i = i->next;
|
||||
}
|
||||
}
|
||||
|
||||
ret = (t->op & ALPM_HOOK_OP_INSTALL && install)
|
||||
|| (t->op & ALPM_HOOK_OP_UPGRADE && upgrade)
|
||||
|| (t->op & ALPM_HOOK_OP_REMOVE && remove);
|
||||
|
||||
if(hook->needs_targets) {
|
||||
#define _save_matches(_op, _matches) \
|
||||
if(t->op & _op && _matches) { \
|
||||
hook->matches = alpm_list_join(hook->matches, _matches); \
|
||||
} else { \
|
||||
alpm_list_free(_matches); \
|
||||
}
|
||||
_save_matches(ALPM_HOOK_OP_INSTALL, install);
|
||||
_save_matches(ALPM_HOOK_OP_UPGRADE, upgrade);
|
||||
_save_matches(ALPM_HOOK_OP_REMOVE, remove);
|
||||
#undef _save_matches
|
||||
} else {
|
||||
alpm_list_free(install);
|
||||
alpm_list_free(upgrade);
|
||||
alpm_list_free(remove);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _alpm_hook_trigger_match_pkg(alpm_handle_t *handle,
|
||||
struct _alpm_hook_t *hook, struct _alpm_trigger_t *t)
|
||||
{
|
||||
alpm_list_t *install = NULL, *upgrade = NULL, *remove = NULL;
|
||||
|
||||
if(t->op & ALPM_HOOK_OP_INSTALL || t->op & ALPM_HOOK_OP_UPGRADE) {
|
||||
alpm_list_t *i;
|
||||
for(i = handle->trans->add; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(_alpm_fnmatch_patterns(t->targets, pkg->name) == 0) {
|
||||
if(pkg->oldpkg) {
|
||||
if(t->op & ALPM_HOOK_OP_UPGRADE) {
|
||||
if(hook->needs_targets) {
|
||||
upgrade = alpm_list_add(upgrade, pkg->name);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(t->op & ALPM_HOOK_OP_INSTALL) {
|
||||
if(hook->needs_targets) {
|
||||
install = alpm_list_add(install, pkg->name);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(t->op & ALPM_HOOK_OP_REMOVE) {
|
||||
alpm_list_t *i;
|
||||
for(i = handle->trans->remove; i; i = i->next) {
|
||||
alpm_pkg_t *pkg = i->data;
|
||||
if(pkg && _alpm_fnmatch_patterns(t->targets, pkg->name) == 0) {
|
||||
if(!alpm_list_find(handle->trans->add, pkg, _alpm_pkg_cmp)) {
|
||||
if(hook->needs_targets) {
|
||||
remove = alpm_list_add(remove, pkg->name);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we reached this point we either need the target lists or we didn't
|
||||
* match anything and the following calls will all be no-ops */
|
||||
hook->matches = alpm_list_join(hook->matches, install);
|
||||
hook->matches = alpm_list_join(hook->matches, upgrade);
|
||||
hook->matches = alpm_list_join(hook->matches, remove);
|
||||
|
||||
return install || upgrade || remove;
|
||||
}
|
||||
|
||||
static int _alpm_hook_trigger_match(alpm_handle_t *handle,
|
||||
struct _alpm_hook_t *hook, struct _alpm_trigger_t *t)
|
||||
{
|
||||
return t->type == ALPM_HOOK_TYPE_PACKAGE
|
||||
? _alpm_hook_trigger_match_pkg(handle, hook, t)
|
||||
: _alpm_hook_trigger_match_file(handle, hook, t);
|
||||
}
|
||||
|
||||
static int _alpm_hook_triggered(alpm_handle_t *handle, struct _alpm_hook_t *hook)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
int ret = 0;
|
||||
for(i = hook->triggers; i; i = i->next) {
|
||||
if(_alpm_hook_trigger_match(handle, hook, i->data)) {
|
||||
if(!hook->needs_targets) {
|
||||
return 1;
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _alpm_hook_cmp(struct _alpm_hook_t *h1, struct _alpm_hook_t *h2)
|
||||
{
|
||||
return strcmp(h1->name, h2->name);
|
||||
}
|
||||
|
||||
static alpm_list_t *find_hook(alpm_list_t *haystack, const void *needle)
|
||||
{
|
||||
while(haystack) {
|
||||
struct _alpm_hook_t *h = haystack->data;
|
||||
if(h && strcmp(h->name, needle) == 0) {
|
||||
return haystack;
|
||||
}
|
||||
haystack = haystack->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t _alpm_hook_feed_targets(char *buf, ssize_t needed, alpm_list_t **pos)
|
||||
{
|
||||
size_t remaining = needed, written = 0;;
|
||||
size_t len;
|
||||
|
||||
while(*pos && (len = strlen((*pos)->data)) + 1 <= remaining) {
|
||||
memcpy(buf, (*pos)->data, len);
|
||||
buf[len++] = '\n';
|
||||
*pos = (*pos)->next;
|
||||
buf += len;
|
||||
remaining -= len;
|
||||
written += len;
|
||||
}
|
||||
|
||||
if(*pos && remaining) {
|
||||
memcpy(buf, (*pos)->data, remaining);
|
||||
(*pos)->data = (char*) (*pos)->data + remaining;
|
||||
written += remaining;
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static alpm_list_t *_alpm_strlist_dedup(alpm_list_t *list)
|
||||
{
|
||||
alpm_list_t *i = list;
|
||||
while(i) {
|
||||
alpm_list_t *next = i->next;
|
||||
while(next && strcmp(i->data, next->data) == 0) {
|
||||
list = alpm_list_remove_item(list, next);
|
||||
free(next);
|
||||
next = i->next;
|
||||
}
|
||||
i = next;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static int _alpm_hook_run_hook(alpm_handle_t *handle, struct _alpm_hook_t *hook)
|
||||
{
|
||||
alpm_list_t *i, *pkgs = _alpm_db_get_pkgcache(handle->db_local);
|
||||
|
||||
for(i = hook->depends; i; i = i->next) {
|
||||
if(!alpm_find_satisfier(pkgs, i->data)) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("unable to run hook %s: %s\n"),
|
||||
hook->name, _("could not satisfy dependencies"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(hook->needs_targets) {
|
||||
alpm_list_t *ctx;
|
||||
hook->matches = alpm_list_msort(hook->matches,
|
||||
alpm_list_count(hook->matches), (alpm_list_fn_cmp)strcmp);
|
||||
/* hooks with multiple triggers could have duplicate matches */
|
||||
ctx = hook->matches = _alpm_strlist_dedup(hook->matches);
|
||||
return _alpm_run_chroot(handle, hook->cmd[0], hook->cmd,
|
||||
(_alpm_cb_io) _alpm_hook_feed_targets, &ctx);
|
||||
} else {
|
||||
return _alpm_run_chroot(handle, hook->cmd[0], hook->cmd, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int _alpm_hook_run(alpm_handle_t *handle, alpm_hook_when_t when)
|
||||
{
|
||||
alpm_event_hook_t event = { .when = when };
|
||||
alpm_event_hook_run_t hook_event;
|
||||
alpm_list_t *i, *hooks = NULL, *hooks_triggered = NULL;
|
||||
const char *suffix = ".hook";
|
||||
size_t suflen = strlen(suffix), triggered = 0;
|
||||
int ret = 0;
|
||||
|
||||
for(i = alpm_list_last(handle->hookdirs); i; i = alpm_list_previous(i)) {
|
||||
char path[PATH_MAX];
|
||||
size_t dirlen;
|
||||
struct dirent *entry;
|
||||
DIR *d;
|
||||
|
||||
if((dirlen = strlen(i->data)) >= PATH_MAX) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not open directory: %s: %s\n"),
|
||||
(char *)i->data, strerror(ENAMETOOLONG));
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
memcpy(path, i->data, dirlen + 1);
|
||||
|
||||
if(!(d = opendir(path))) {
|
||||
if(errno == ENOENT) {
|
||||
continue;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("could not open directory: %s: %s\n"), path, strerror(errno));
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while((errno = 0, entry = readdir(d))) {
|
||||
struct _alpm_hook_cb_ctx ctx = { handle, NULL };
|
||||
struct stat buf;
|
||||
size_t name_len;
|
||||
|
||||
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if((name_len = strlen(entry->d_name)) >= PATH_MAX - dirlen) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not open file: %s%s: %s\n"),
|
||||
path, entry->d_name, strerror(ENAMETOOLONG));
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
memcpy(path + dirlen, entry->d_name, name_len + 1);
|
||||
|
||||
if(name_len < suflen
|
||||
|| strcmp(entry->d_name + name_len - suflen, suffix) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping non-hook file %s\n", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(find_hook(hooks, entry->d_name)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping overridden hook %s\n", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(stat(path, &buf) != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
_("could not stat file %s: %s\n"), path, strerror(errno));
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(S_ISDIR(buf.st_mode)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "skipping directory %s\n", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
CALLOC(ctx.hook, sizeof(struct _alpm_hook_t), 1,
|
||||
ret = -1; closedir(d); goto cleanup);
|
||||
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "parsing hook file %s\n", path);
|
||||
if(parse_ini(path, _alpm_hook_parse_cb, &ctx) != 0
|
||||
|| _alpm_hook_validate(handle, ctx.hook, path)) {
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "parsing hook file %s failed\n", path);
|
||||
_alpm_hook_free(ctx.hook);
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
STRDUP(ctx.hook->name, entry->d_name, ret = -1; closedir(d); goto cleanup);
|
||||
hooks = alpm_list_add(hooks, ctx.hook);
|
||||
}
|
||||
if(errno != 0) {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("could not read directory: %s: %s\n"),
|
||||
(char *) i->data, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
if(ret != 0 && when == ALPM_HOOK_PRE_TRANSACTION) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hooks = alpm_list_msort(hooks, alpm_list_count(hooks),
|
||||
(alpm_list_fn_cmp)_alpm_hook_cmp);
|
||||
|
||||
for(i = hooks; i; i = i->next) {
|
||||
struct _alpm_hook_t *hook = i->data;
|
||||
if(hook && hook->when == when && _alpm_hook_triggered(handle, hook)) {
|
||||
hooks_triggered = alpm_list_add(hooks_triggered, hook);
|
||||
triggered++;
|
||||
}
|
||||
}
|
||||
|
||||
if(hooks_triggered != NULL) {
|
||||
event.type = ALPM_EVENT_HOOK_START;
|
||||
EVENT(handle, (void *)&event);
|
||||
|
||||
hook_event.position = 1;
|
||||
hook_event.total = triggered;
|
||||
|
||||
for(i = hooks_triggered; i; i = i->next, hook_event.position++) {
|
||||
struct _alpm_hook_t *hook = i->data;
|
||||
alpm_logaction(handle, ALPM_CALLER_PREFIX, "running '%s'...\n", hook->name);
|
||||
|
||||
hook_event.type = ALPM_EVENT_HOOK_RUN_START;
|
||||
hook_event.name = hook->name;
|
||||
hook_event.desc = hook->desc;
|
||||
EVENT(handle, &hook_event);
|
||||
|
||||
if(_alpm_hook_run_hook(handle, hook) != 0 && hook->abort_on_fail) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
hook_event.type = ALPM_EVENT_HOOK_RUN_DONE;
|
||||
EVENT(handle, &hook_event);
|
||||
|
||||
if(ret != 0 && when == ALPM_HOOK_PRE_TRANSACTION) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
alpm_list_free(hooks_triggered);
|
||||
|
||||
event.type = ALPM_EVENT_HOOK_DONE;
|
||||
EVENT(handle, (void *)&event);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
alpm_list_free_inner(hooks, (alpm_list_fn_free) _alpm_hook_free);
|
||||
alpm_list_free(hooks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vim: set noet: */
|
||||
29
lib/libalpm/hook.h
Normal file
29
lib/libalpm/hook.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* hook.h
|
||||
*
|
||||
* Copyright (c) 2015-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ALPM_HOOK_H
|
||||
#define ALPM_HOOK_H
|
||||
|
||||
#include "alpm.h"
|
||||
|
||||
int _alpm_hook_run(alpm_handle_t *handle, alpm_hook_when_t when);
|
||||
|
||||
#endif /* ALPM_HOOK_H */
|
||||
|
||||
/* vim: set noet: */
|
||||
1
lib/libalpm/ini.c
Symbolic link
1
lib/libalpm/ini.c
Symbolic link
@@ -0,0 +1 @@
|
||||
../../src/common/ini.c
|
||||
1
lib/libalpm/ini.h
Symbolic link
1
lib/libalpm/ini.h
Symbolic link
@@ -0,0 +1 @@
|
||||
../../src/common/ini.h
|
||||
@@ -7,6 +7,6 @@ Name: libalpm
|
||||
Description: Arch Linux package management library
|
||||
URL: http://www.archlinux.org/pacman/
|
||||
Version: @LIB_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Cflags: -I${includedir} @LFS_CFLAGS@
|
||||
Libs: -L${libdir} -lalpm
|
||||
Libs.private: @LIBS@ @LIBARCHIVE_LIBS@ @LIBSSL_LIBS@ @LIBCURL_LIBS@ @GPGME_LIBS@
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef _LIBARCHIVE_COMPAT_H
|
||||
#define _LIBARCHIVE_COMPAT_H
|
||||
#ifndef LIBARCHIVE_COMPAT_H
|
||||
#define LIBARCHIVE_COMPAT_H
|
||||
|
||||
/*
|
||||
* libarchive-compat.h
|
||||
*
|
||||
* Copyright (c) 2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2013-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -68,6 +68,6 @@ static inline int _alpm_archive_read_support_filter_all(struct archive *archive)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _LIBARCHIVE_COMPAT_H */
|
||||
#endif /* LIBARCHIVE_COMPAT_H */
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* log.c
|
||||
*
|
||||
* Copyright (c) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2006-2016 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
/* libalpm */
|
||||
#include "log.h"
|
||||
@@ -33,6 +34,17 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int _alpm_log_leader(FILE *f, const char *prefix)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm = localtime(&t);
|
||||
|
||||
/* Use ISO-8601 date format */
|
||||
return fprintf(f, "[%04d-%02d-%02d %02d:%02d] [%s] ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, prefix);
|
||||
}
|
||||
|
||||
/** A printf-like function for logging.
|
||||
* @param handle the context handle
|
||||
* @param prefix caller-specific prefix for the log
|
||||
@@ -42,16 +54,24 @@
|
||||
int SYMEXPORT alpm_logaction(alpm_handle_t *handle, const char *prefix,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
va_list args;
|
||||
|
||||
ASSERT(handle != NULL, return -1);
|
||||
|
||||
if(!(prefix && *prefix)) {
|
||||
prefix = "UNKNOWN";
|
||||
}
|
||||
|
||||
/* check if the logstream is open already, opening it if needed */
|
||||
if(handle->logstream == NULL) {
|
||||
handle->logstream = fopen(handle->logfile, "a");
|
||||
if(handle->logstream == NULL && handle->logfile != NULL) {
|
||||
int fd;
|
||||
do {
|
||||
fd = open(handle->logfile, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC,
|
||||
0644);
|
||||
} while(fd == -1 && errno == EINTR);
|
||||
/* if we couldn't open it, we have an issue */
|
||||
if(handle->logstream == NULL) {
|
||||
if(fd < 0 || (handle->logstream = fdopen(fd, "a")) == NULL) {
|
||||
if(errno == EACCES) {
|
||||
handle->pm_errno = ALPM_ERR_BADPERMS;
|
||||
} else if(errno == ENOENT) {
|
||||
@@ -59,14 +79,31 @@ int SYMEXPORT alpm_logaction(alpm_handle_t *handle, const char *prefix,
|
||||
} else {
|
||||
handle->pm_errno = ALPM_ERR_SYSTEM;
|
||||
}
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
ret = _alpm_logaction(handle, prefix, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if(handle->usesyslog) {
|
||||
/* we can't use a va_list more than once, so we need to copy it
|
||||
* so we can use the original when calling vfprintf below. */
|
||||
va_list args_syslog;
|
||||
va_copy(args_syslog, args);
|
||||
vsyslog(LOG_WARNING, fmt, args_syslog);
|
||||
va_end(args_syslog);
|
||||
}
|
||||
|
||||
if(handle->logstream) {
|
||||
if(_alpm_log_leader(handle->logstream, prefix) < 0
|
||||
|| vfprintf(handle->logstream, fmt, args) < 0) {
|
||||
ret = -1;
|
||||
handle->pm_errno = ALPM_ERR_SYSTEM;
|
||||
}
|
||||
fflush(handle->logstream);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -85,4 +122,4 @@ void _alpm_log(alpm_handle_t *handle, alpm_loglevel_t flag, const char *fmt, ...
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* vim: set ts=2 sw=2 noet: */
|
||||
/* vim: set noet: */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user