Compare commits
1020 Commits
ZeroSevenZ
...
master
Author | SHA1 | Date | |
---|---|---|---|
6fb158b56d | |||
51f43127ac | |||
f84d038121 | |||
e5a8d91e4d | |||
f0d9795cd1 | |||
29bfd7e5e7 | |||
d48bbb4b66 | |||
17a020e9fc | |||
069b4edecd | |||
84e8efeb0a | |||
ddebbf1b60 | |||
ca29b77091 | |||
046f581baa | |||
c8ceb73b5f | |||
f4a09e9536 | |||
4628231cec | |||
f795db5d61 | |||
9acb8ad6da | |||
1172ef74c6 | |||
a904ae995a | |||
1954514210 | |||
629a4fa44d | |||
879cb991df | |||
d4d63213ab | |||
7765fbd1ab | |||
da44c706ea | |||
31591b8196 | |||
27e15689e5 | |||
0a1bbb1696 | |||
c76145f5e1 | |||
8d270b1fda | |||
892df643c9 | |||
31e8f5cf0e | |||
2a977cfc4b | |||
be039ff191 | |||
f1d5c670c5 | |||
d3bd97c05e | |||
d146886763 | |||
d95d5a2484 | |||
2a58d5ae5c | |||
3468a2ad38 | |||
6b2ae7d141 | |||
ab6b1039a4 | |||
8b9a8cfb4b | |||
0e1f5dc3da | |||
8d934ee7b8 | |||
e09acf3b8a | |||
799175019b | |||
b57c05c874 | |||
d4593f49ae | |||
91f7d4d34a | |||
ba9b69b1df | |||
1c235e807e | |||
95ad059aba | |||
0a37e8cbe5 | |||
3a940300e2 | |||
a6fdbc7a25 | |||
ce2ddab081 | |||
2298dfd08a | |||
354d45e640 | |||
6905bb447a | |||
0e73afd17c | |||
c5bc9f6de7 | |||
610e213f70 | |||
4d5486acf5 | |||
39f2712bb7 | |||
9ac8efa61e | |||
1c06669465 | |||
d72fb13225 | |||
7282eaab2c | |||
042fe178bf | |||
af65852dc8 | |||
f52507116b | |||
04f9a30787 | |||
c2bcf78c81 | |||
ef3609e021 | |||
9ee80eec9a | |||
255afdde45 | |||
c75ad3162c | |||
d32bb30e79 | |||
3fdf11817d | |||
2fe4b3ca2a | |||
ff039e8096 | |||
e35995b85e | |||
c84889bb81 | |||
84fad99eba | |||
95f5b1ce2b | |||
ef2fa1d99d | |||
b5b5cc1fb2 | |||
99e828c72f | |||
2886b82bf0 | |||
ef0d713b25 | |||
f1fc16bb8a | |||
260fc2983d | |||
ea486a109f | |||
516dc2ca76 | |||
113f5873cb | |||
2bb8bf470d | |||
a4b688ab52 | |||
d71d80d1a1 | |||
858e42d696 | |||
724d518dbc | |||
6f6bf688d9 | |||
6b020a3ab7 | |||
074f88fe98 | |||
19a1b8e768 | |||
80175e0054 | |||
d7b5090ff9 | |||
2a2d60d95d | |||
b5a84e7f01 | |||
261538cea7 | |||
607f339501 | |||
b9f67a86a1 | |||
e1d8d11c5f | |||
cd6b19a065 | |||
7cc62d99e9 | |||
ed6bf59026 | |||
0731eaa3e0 | |||
740e726ffe | |||
2e8dec42e5 | |||
ba7422b2b6 | |||
2e76a4dfdf | |||
078f75c2a7 | |||
6f072d870d | |||
f312d00a73 | |||
d5d802a226 | |||
daa9160df7 | |||
4189a000fe | |||
e631f2d977 | |||
6e5d3dc2d1 | |||
bdbcde351f | |||
37c53a22c8 | |||
34866215f7 | |||
f4ce749188 | |||
9e852c2b7c | |||
f61caa7feb | |||
94f02caddb | |||
69d12929e3 | |||
df1483c78d | |||
92e29de695 | |||
02d06cffbc | |||
2f4613fd26 | |||
541ea7aa09 | |||
224fe43539 | |||
80225c93a9 | |||
7f35793928 | |||
91c4ba0179 | |||
80ebe2923a | |||
f2c2e5e59c | |||
d428bae0fa | |||
cd94630dec | |||
774336bbe9 | |||
43e113ae54 | |||
be8834a564 | |||
71ee6246a6 | |||
e62426c705 | |||
d8cb782cfb | |||
ae9cd95cf1 | |||
1d15b0845f | |||
8d8d0b97a7 | |||
acfaa6e15a | |||
352a33d287 | |||
ef662655bb | |||
d32dbe37fe | |||
0f657077af | |||
bb0d0f9505 | |||
189a43bac9 | |||
232b49bc90 | |||
a3f86a1432 | |||
9917a1ddeb | |||
7993b719a7 | |||
98a6284402 | |||
6136eaf86f | |||
d31a72100b | |||
2b82095236 | |||
8ba554a60d | |||
d9206d7fdb | |||
ccefc2daa1 | |||
726351f211 | |||
20d01446d1 | |||
0f5b28ee64 | |||
142e138543 | |||
ead8735d2e | |||
cbc21aef76 | |||
955525c60c | |||
b212205b0b | |||
dfeefaa5fc | |||
53c279be18 | |||
caf04416ea | |||
8416310ba6 | |||
330fb2cd20 | |||
1602c51a26 | |||
d762c6b9dd | |||
6c7822b5bc | |||
22719b880e | |||
ab11ce2a0e | |||
793157c26b | |||
1a6fd3ad95 | |||
d06138d6b2 | |||
d26dc809d7 | |||
2d71ea303c | |||
60e2e7df28 | |||
d7e762b9be | |||
368b0590e2 | |||
29c0be903d | |||
0dd3ff606c | |||
df52e79df6 | |||
a46cbdcccd | |||
e1c12bbf57 | |||
300b9e7016 | |||
2d5bf266f7 | |||
6a927ae867 | |||
3dcee0dcc9 | |||
bbbb9a1eb3 | |||
3c6a36546a | |||
2326a36250 | |||
5a719c54c8 | |||
2f194084b8 | |||
decefbede5 | |||
cdf00267b0 | |||
e0167f9385 | |||
516df39cc7 | |||
406a0e7747 | |||
44f064fea0 | |||
5c154a478e | |||
4670984dec | |||
0b110821f6 | |||
ad688b85eb | |||
3877fc6bea | |||
77aeeba934 | |||
cfa6ee1498 | |||
a9affdc82a | |||
1286079d3d | |||
3b5906b30c | |||
0c9293f9c6 | |||
3c4dccc966 | |||
f3fd5fbc99 | |||
f4a49078c8 | |||
193c2b14d5 | |||
a3b8c3c659 | |||
73bd0547e2 | |||
da874ca4f8 | |||
69b282a5ba | |||
193c260285 | |||
ca532f7623 | |||
61e2176d03 | |||
91eca50221 | |||
e54f6ebd68 | |||
856081559c | |||
511d23f574 | |||
f17d5ee7d1 | |||
d08658833a | |||
a8a2d54c25 | |||
9accc668fa | |||
33e20f9e49 | |||
48db3adaf6 | |||
ac46978d63 | |||
2aba5b4dd7 | |||
6e5c50bde4 | |||
174c22aeb7 | |||
31abdedade | |||
b6afe92e47 | |||
1d616b5944 | |||
070ac64459 | |||
ad95f1ff2b | |||
3edde5dc9d | |||
cf5c7aa84f | |||
d40ab32360 | |||
43e1daab23 | |||
6e4d1cc53e | |||
cdbbcbb923 | |||
7f31c9e985 | |||
dd0ceb6720 | |||
5676a1953d | |||
78627934f3 | |||
217289f71a | |||
1c6f6c084f | |||
658851a497 | |||
2aa10d1099 | |||
ba8b1b5e17 | |||
ef17544eb9 | |||
7f99a8e70e | |||
5f6281261d | |||
04afd1c958 | |||
83eac67cf5 | |||
d09ecac4a8 | |||
404f239207 | |||
0cd21eed54 | |||
119c0cf76d | |||
edc90b880c | |||
ae4d296a60 | |||
4880ca3b93 | |||
429fed00c1 | |||
87ab352d6f | |||
6e372c9a6d | |||
1f7dfb84fc | |||
844dc958be | |||
f6132a97a0 | |||
642406b92e | |||
cc8ac3aefb | |||
2a8ae1be42 | |||
8d2e14a0b9 | |||
9e02c17004 | |||
669ccb9b43 | |||
05ae7e51e4 | |||
db2ec50deb | |||
6b93e66cfd | |||
9afa5379e5 | |||
b08075479e | |||
2b74f6fa63 | |||
8f60105c8d | |||
f8be7e46ab | |||
f9793c54c2 | |||
870b71377d | |||
8eed2e9558 | |||
abe560a6ec | |||
2a991bbab3 | |||
b46f7157de | |||
9aaca05499 | |||
bd381583de | |||
e2188fb9f7 | |||
fd8f4d48b8 | |||
0eb24d293f | |||
f1ef0a1995 | |||
0178c42c20 | |||
21511e3fdf | |||
744da88c3c | |||
3ab91cb93b | |||
19cbdde95f | |||
167d73e268 | |||
1887b0b938 | |||
0b932e5f7d | |||
ecd303149f | |||
8f500d90df | |||
644feceb5c | |||
eb03488f52 | |||
a252038113 | |||
ca3f994dcb | |||
7f8d8a04d0 | |||
2fd5af75eb | |||
cf363b27fa | |||
469ab7bf21 | |||
ac2bfec065 | |||
c566ea03cf | |||
3632e1be4e | |||
f18b832a82 | |||
1f92419cb4 | |||
d6e15a0139 | |||
e0db790103 | |||
9bc362f59b | |||
44d5f3ce4e | |||
0f43a39a45 | |||
0a1a085471 | |||
a1fdfe1519 | |||
bbb6315af0 | |||
40d83b2314 | |||
c82ac0a825 | |||
46b598abd2 | |||
c7784b79b7 | |||
f1b3184531 | |||
a18c862e84 | |||
c2903ab717 | |||
04ccaebff7 | |||
2e83dc554b | |||
3a17a8a014 | |||
ffca3e89dd | |||
676231c362 | |||
d76c715df7 | |||
9aa47792e0 | |||
f4cfe9b267 | |||
6f19122672 | |||
057f24d5b9 | |||
a843727bc7 | |||
bb409500ed | |||
1a74a05965 | |||
2df7f3d5d5 | |||
0728d855d5 | |||
100be5078c | |||
5139bf922a | |||
a2b4361d69 | |||
d216764867 | |||
4c74cbf7b3 | |||
7ed8619a9e | |||
fa2508bfd5 | |||
72ae8e3b5a | |||
fa95326bac | |||
eb86e5298a | |||
4cfa8170ee | |||
d885d9a408 | |||
6a23213113 | |||
89edfaf875 | |||
1297525889 | |||
5397f85d38 | |||
5ab84314c0 | |||
577d34e931 | |||
8ce54bcb28 | |||
6956a3b3d3 | |||
85820e9fc0 | |||
f34d3100be | |||
f81990c703 | |||
f77094073a | |||
31c4fe16e1 | |||
492e3d7895 | |||
529c4a2d2e | |||
31a4d2c1e1 | |||
564ccc36f5 | |||
7a7591aec5 | |||
b5d9b01909 | |||
0000bbc13a | |||
cda1817079 | |||
72c0e6236d | |||
2e4cf980c3 | |||
40db9f1d81 | |||
1b15b71905 | |||
cc95c408ec | |||
20229d9f49 | |||
7c158963c1 | |||
38fcbec963 | |||
fcad54ae01 | |||
b9c7cc4eeb | |||
a64773cd15 | |||
9664d1a315 | |||
bfb798b51b | |||
72645c8fba | |||
f338575f41 | |||
cc3ff147fe | |||
dcd1eab82d | |||
3ea4892040 | |||
e0d7eb4820 | |||
daf744276e | |||
8963905bbc | |||
88da4e9ead | |||
cc9ec8666c | |||
7ce13c6dd3 | |||
6549072dcd | |||
a88039e222 | |||
a75a838af9 | |||
024701c220 | |||
72c31e89b2 | |||
2f548e046d | |||
9f8e4fb36b | |||
645d41fdd2 | |||
853928815a | |||
38bbbf2496 | |||
6a13187e03 | |||
ce0f35831b | |||
0e9a79e352 | |||
0c01912143 | |||
66639c6e11 | |||
a0540651eb | |||
34195c3037 | |||
9623a04ce9 | |||
ef7999342b | |||
cb8c85579d | |||
ebf2fe5c28 | |||
66eba145d3 | |||
5cd7b09d5c | |||
ac7f4e90a4 | |||
2c10b444a1 | |||
ea1160f077 | |||
d4c4430a40 | |||
a2493b97e4 | |||
4d70043e78 | |||
c9a44d0128 | |||
a9b400833c | |||
0446226aa6 | |||
18efcd6299 | |||
775eb175b6 | |||
b8b6734cd1 | |||
688a6fccca | |||
792a5896e7 | |||
c1bd3ced61 | |||
dcb6f8344b | |||
83fa2ce51b | |||
b8eb8b35d9 | |||
c851520684 | |||
4c9783d7ae | |||
8ac3ee15f1 | |||
e5742f724a | |||
0c3fa9b341 | |||
a1f18ad44e | |||
3845e1af05 | |||
23d7867331 | |||
38aaa2f8aa | |||
ce29b4b38c | |||
f1ae493c57 | |||
4afaaf3fb6 | |||
8f725bab11 | |||
7b5040af17 | |||
47e5ce5da2 | |||
cdaa2971db | |||
67ae1413e3 | |||
6716f7041d | |||
94c50a0145 | |||
74fa33bc42 | |||
8cdba24ff9 | |||
c8debb85a3 | |||
eeef039aab | |||
1cc7c7f8b2 | |||
8f40e66fa4 | |||
a34596d7b7 | |||
e15e949a20 | |||
8e8ed3e682 | |||
52798b0b4a | |||
de6d193eec | |||
d774aa0b35 | |||
350971a34e | |||
64b90c1da6 | |||
398ee89348 | |||
c3a02f8631 | |||
89e5450fb8 | |||
e05285e246 | |||
9ab0edae71 | |||
|
8a9c6176c2 | ||
620871c91d | |||
2063dc2ca7 | |||
358ebaf458 | |||
38387c0cb0 | |||
f594e30f39 | |||
39bdf8c725 | |||
8a8a84b0f6 | |||
3b0f6b742f | |||
0e5149d716 | |||
c085581224 | |||
c84ba30220 | |||
7b0a23d553 | |||
7be652ac6b | |||
b385a3863e | |||
25d61ceba0 | |||
9aa23d6695 | |||
94a66f72d4 | |||
48e6a5975c | |||
1d5ee82c16 | |||
56c02fa394 | |||
7a5f1ab35c | |||
6b7e0f134a | |||
417a4cc0bf | |||
041f0e357e | |||
6629d05eea | |||
8d6c28b6c5 | |||
4814e8c13a | |||
2718016de6 | |||
dff3e97daa | |||
83e2d20322 | |||
303a2670be | |||
3b96910327 | |||
6c9b5a4419 | |||
cf181bdcd6 | |||
cc65aa9df6 | |||
b4ff95c2e7 | |||
a1158a118b | |||
afe242f920 | |||
854ebd647c | |||
42b6c22dca | |||
a247f7e7e9 | |||
cad8abef74 | |||
a504de4b58 | |||
126e73d19d | |||
ac4bfb128c | |||
8e97da0078 | |||
d6c8792a24 | |||
dcf6f74e5a | |||
39df1cdc4e | |||
3862b8d339 | |||
02255c89be | |||
3c7e723114 | |||
63c04b8c9b | |||
7d1c712c09 | |||
6b821fcd92 | |||
29f202a6fe | |||
2cae912040 | |||
3f7a92cc84 | |||
5faa1c25b0 | |||
f986fe83ff | |||
15192c2bfa | |||
9b042009fb | |||
15c6c539db | |||
824e610824 | |||
dbd2e28366 | |||
6cc3012284 | |||
ff1e0eb54e | |||
cbcae473ad | |||
fb841a7d08 | |||
207a702767 | |||
4c10e60dae | |||
7c1666cdce | |||
da3aba8ef5 | |||
822bdf8b7b | |||
880c95d9a4 | |||
d12589771b | |||
b7ecdb1014 | |||
fdb981db72 | |||
16724f3eef | |||
8cc1fc1ca7 | |||
421870ae51 | |||
006d1a32fb | |||
7ed9f978a8 | |||
b7c07ef18f | |||
1c66174a2e | |||
43b2f73217 | |||
2c282adafb | |||
1d64ff428e | |||
c813de47c2 | |||
d39843a974 | |||
8c25db0148 | |||
46719fbc5c | |||
93b65ac4e5 | |||
3e58712c36 | |||
f6fc14de13 | |||
4bba05f186 | |||
82697b2b8b | |||
ae91e331a7 | |||
df41e7b9ff | |||
49e91d491d | |||
a0a230e38b | |||
e05e813234 | |||
c5718b7a4c | |||
b81585e082 | |||
91e2256ffb | |||
38b30d5e5f | |||
44b0314449 | |||
3a993efb9f | |||
d9e6bde437 | |||
71c9dc9f28 | |||
35e553a808 | |||
fe812ffde2 | |||
a2965e9993 | |||
d073709328 | |||
7e6dadeb02 | |||
fe5efd7b37 | |||
7778536f45 | |||
60dde60ebd | |||
76c4c76722 | |||
2e20a4f888 | |||
62944e3b21 | |||
b0a4b7c15c | |||
ecc8bbc71f | |||
b47a0e6884 | |||
64f7f5d609 | |||
4e287dbfed | |||
13895a6518 | |||
f12ce229ae | |||
58d8f3b3c2 | |||
34c86e88d9 | |||
a2d2ec150b | |||
54325147ee | |||
7620840490 | |||
0894f7773e | |||
706f8b937d | |||
ec9bc5678b | |||
a751af6caa | |||
570346b3a5 | |||
f73698c0cb | |||
c11378f1a0 | |||
a734e868bd | |||
653586b97e | |||
3cec04dbe3 | |||
2d8047afcf | |||
781beb3a27 | |||
79e09728ac | |||
3f7210dfff | |||
c03149241d | |||
2433c1f68e | |||
9eb60cd8fc | |||
15e18501d9 | |||
ed8b303d62 | |||
9fbae8df29 | |||
04005adaf4 | |||
|
45da5c9934 | ||
|
64b1ab5b3d | ||
404717f305 | |||
e5ea8f75e6 | |||
eb01c9c6c5 | |||
c1ff7b9812 | |||
d6e90bb71f | |||
ae7f38c15a | |||
4abf2b75b1 | |||
f93babeea6 | |||
54723c9ee3 | |||
75f121d26e | |||
9ee4f65141 | |||
8d057e4ee4 | |||
47af302776 | |||
c96745af15 | |||
99af1501fc | |||
aeff7957f2 | |||
5f743b8030 | |||
27997067c9 | |||
cf8e46ec32 | |||
bad7a81d0d | |||
5e8e73d994 | |||
5ba8c03a98 | |||
096ed00f2e | |||
b4aeba18f7 | |||
0352486f97 | |||
edd131b1b9 | |||
30f3f70dfd | |||
806b9602e6 | |||
f116eeec64 | |||
7e50165d5c | |||
46357869fc | |||
f85cb8269f | |||
8fffc74a5b | |||
8fd81d4ec4 | |||
0c76daf2a9 | |||
86656a9d52 | |||
95e511b984 | |||
7af151169d | |||
7a9a7dfdd2 | |||
0ac6a64f12 | |||
8bd288e10c | |||
28078d059a | |||
ac665916a6 | |||
e9637067f8 | |||
a058e24375 | |||
f895077c3c | |||
73423b8819 | |||
5e9c7bac3f | |||
e32bd99801 | |||
e86a7f9880 | |||
9c9b82ae61 | |||
d5cc482015 | |||
1f14074d59 | |||
d0c6889603 | |||
a088a85374 | |||
a3ac6c63aa | |||
af41742516 | |||
998fcdbefa | |||
ed811f45e6 | |||
240e6abff4 | |||
402f4c0b04 | |||
1b166f484d | |||
b945974dc7 | |||
cf214650c6 | |||
69ec9334d1 | |||
238fde4ef1 | |||
69e95016fb | |||
a8e54b86d7 | |||
9f5e967bdf | |||
fcaf3e9d9a | |||
b59429c568 | |||
1f72fe107d | |||
043d9a82d8 | |||
952c9b0432 | |||
4f5075d7a9 | |||
2b07bd0632 | |||
0a714850d7 | |||
3caf176aeb | |||
43f7e7d063 | |||
447a68d691 | |||
0a3b34d9c1 | |||
0b25a4d258 | |||
3b5aeb0f81 | |||
5ec4a7419e | |||
bf7e4c8027 | |||
682078575f | |||
43f3d4b70f | |||
523b59984b | |||
dcf79a188a | |||
84d6cac5c1 | |||
261f05eb45 | |||
9334b3190d | |||
9b0772fe9c | |||
20c0ae24a8 | |||
0f622def33 | |||
707d6153f7 | |||
28ae78b4f1 | |||
7ceb67f0b0 | |||
e18bfe50c1 | |||
4083001548 | |||
45353dee67 | |||
f14b66a09b | |||
38c029d5e3 | |||
287b59cfd3 | |||
c49995b11a | |||
f2436351ef | |||
71844bf8b9 | |||
59e0824370 | |||
b7034abcbb | |||
df390ae7d3 | |||
c1f4063193 | |||
4cc524097b | |||
fb159b8dbd | |||
c693798571 | |||
34847fff80 | |||
54651df146 | |||
d4e4607a84 | |||
98b2e06c21 | |||
d5ecb382aa | |||
cdcda19384 | |||
b96aeece99 | |||
7bbf99384e | |||
9f61db5378 | |||
2a48b34bcd | |||
15266fb310 | |||
e2bdd521d8 | |||
7a3b871c4e | |||
713ec46f23 | |||
85eb091025 | |||
c866b6bc35 | |||
0250a2831d | |||
4c47b81a9c | |||
bb88ba5861 | |||
b30a2af7c7 | |||
b10cfb3d22 | |||
a2df41713d | |||
86ce32d170 | |||
7ba30596ce | |||
2f8ad976ea | |||
d0d37af096 | |||
81768cd4b0 | |||
e9828cddd0 | |||
7f0358892a | |||
bc40ce2876 | |||
6674667b7f | |||
cc4d72bf8b | |||
1eee6ab8a0 | |||
736d8b9019 | |||
8345eb8a71 | |||
cc7548f1c7 | |||
edca339338 | |||
9323cceff1 | |||
8b1b3f08c6 | |||
e332f4a438 | |||
960fe6d188 | |||
92c5f6f998 | |||
2069ffa863 | |||
e787d328c7 | |||
fafc190fd4 | |||
e6029ae238 | |||
6e17c59f6b | |||
0e777ec688 | |||
8dcdb5a87f | |||
4f372c00bc | |||
9f6d80d87d | |||
b33df8fbd5 | |||
b4bb522053 | |||
3289ffd1e6 | |||
196ef37108 | |||
cdad7fcd80 | |||
ed6e2df81b | |||
ae667ca2e8 | |||
873e3f5d78 | |||
72f9ff8b8c | |||
eb95f7fc16 | |||
3519b42c14 | |||
b4e5afd317 | |||
7446ed7daa | |||
2d40b098e5 | |||
ac64aef090 | |||
74a68adc6e | |||
937bc87bfc | |||
de482489c1 | |||
295fa1d526 | |||
99bba3e98e | |||
bd3016e085 | |||
dd74364ebb | |||
255e5362f9 | |||
471a0d0058 | |||
f5b556db47 | |||
c12bbff7d1 | |||
6db992e646 | |||
bd017a108e | |||
3a76f9245f | |||
580ca08cc5 | |||
a6bd4c24db | |||
54005cb60e | |||
15fbe0a7ea | |||
da1d260753 | |||
95865ee34d | |||
eb8b8faa3b | |||
39fd8b922d | |||
7ead54c8b9 | |||
2a85fc7d91 | |||
1e42a76415 | |||
734759190a | |||
16ffa10831 | |||
cdfc357064 | |||
df612390d3 | |||
77971f3680 | |||
5c75d583d7 | |||
2ff03841d7 | |||
a88745c82e | |||
96167b3d8e | |||
1ca38962d4 | |||
80bcabfd57 | |||
d9239aeafc | |||
758a197d06 | |||
ed972271ec | |||
0544ac8cd3 | |||
12a2be8d86 | |||
509db68d82 | |||
00ed59f34e | |||
2b8e8c2521 | |||
e3ff0bb0f6 | |||
8efb24ca6d | |||
d53c5db98e | |||
0320b7bf2a | |||
cee271f9cb | |||
c2a3e3677d | |||
fc3445215b | |||
4ce8bd45cf | |||
08169d63bc | |||
e13b6369ba | |||
d3988dd74b | |||
ef42052900 | |||
240afa7c3a | |||
5b72e5d06e | |||
4aa08e32ff | |||
eb34561262 | |||
dd85e37ac8 | |||
e566340261 | |||
7e86db207c | |||
a30ecd1abb | |||
45b28b6c31 | |||
afedcdd72b | |||
b8a98e0728 | |||
b238ad5a51 | |||
28f4454a9d | |||
cb8c23ed5a | |||
54bb1ab395 | |||
872068ba7c | |||
2bd800ed14 | |||
da0b3b3939 | |||
93aa6ccc6f | |||
d6edfc9961 | |||
2945ab61d7 | |||
d35f7d0de1 | |||
e335aa26b4 | |||
496d794bcd | |||
c88a428d5e | |||
dc8ecdd77e | |||
259d1cd2b7 | |||
7fddf9ffc5 | |||
6109a7bc08 | |||
9b28a9b272 | |||
f39ff2c2f6 | |||
c8e0472637 | |||
acb2f3b173 | |||
504677de4f | |||
ae8f65e956 | |||
c2c10e263e | |||
43761c55ef | |||
b28165f10b | |||
25489521bb | |||
79a33ca2ac | |||
738b83ac03 | |||
677b007100 | |||
0fc685fc85 | |||
ca2cae9b0a | |||
055876d6b7 | |||
9160b1dcbb | |||
0f37170759 | |||
ce3d4dbed3 | |||
f9acd4ee3d | |||
d118b82a13 | |||
76a4c0ac44 | |||
83f80364c5 | |||
9064b56c56 | |||
405e6b020e | |||
ffe80264c7 | |||
d158e7f456 | |||
4384b0c006 | |||
e78353b7dd | |||
3c2ad1be42 | |||
937a226543 | |||
cca24711b8 | |||
e646686145 | |||
f3070d2e71 | |||
e0c501a59a | |||
39a7d18266 | |||
de8ecab9b4 | |||
e9a6b9c36d | |||
e65ccb2b5e | |||
96a5a2a28a | |||
ca97df9798 | |||
22905f7349 | |||
a318da9463 | |||
3c69b684a8 | |||
4457061656 | |||
758f5a5c1e | |||
c8c4da8e8e | |||
4fdebcae9f | |||
82ee4c8788 | |||
ad4a286736 | |||
9017f0716f | |||
7973546a4c | |||
2e6f83b3b3 | |||
fdd190b65c | |||
97ac17512f | |||
28a1b4dcba | |||
b724ab2130 | |||
567beb1d9f | |||
eb62395e41 | |||
1d6c97c79f | |||
5e4c1cf967 | |||
719096b0a7 | |||
75dca6c6e9 | |||
1ef3a24885 | |||
790b4f31ee | |||
9362a0240b | |||
82e884c432 | |||
f6d6dcfad0 | |||
970ae46cfa | |||
693784cbf5 | |||
3a98bc52f9 | |||
6038928fe4 | |||
2e547b0bba | |||
e968e81409 | |||
557299d350 | |||
6642342274 | |||
40b3380d4d | |||
3b018684c7 | |||
96beb44455 | |||
9805ce7534 | |||
407471898c | |||
cf9a2031a4 | |||
d9fc6cc275 | |||
78713d8912 | |||
169963eced |
|
@ -1,12 +1,12 @@
|
||||||
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2017 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 as
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
|
527
ChangeLog
527
ChangeLog
|
@ -1 +1,526 @@
|
||||||
nothing here now
|
git clone git@dev.lovelyhq.com:libburnia/libburn.git
|
||||||
|
(to become libburn-1.5.8 or higher)
|
||||||
|
===============================================================================
|
||||||
|
- no novelties yet -
|
||||||
|
|
||||||
|
|
||||||
|
libburn-1.5.6.tar.gz Wed Jun 07 2023
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Overburning with cdrskin option -force ended by a libburn error
|
||||||
|
* New API call burn_write_opts_set_bdr_obs_exempt()
|
||||||
|
* New cdrskin option --bdr_obs_exempt
|
||||||
|
* Officially enabled overburning with burn_write_opts_set_force(,1)
|
||||||
|
|
||||||
|
libburn-1.5.4.tar.gz Sat Jan 30 2021
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Early SCSI commands from sg-linux.c were not logged
|
||||||
|
* New API call burn_drive_set_speed_exact()
|
||||||
|
* New API call burn_nominal_slowdown()
|
||||||
|
|
||||||
|
libburn-1.5.2.pl01.tar.gz Mon Nov 25 2019
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin multi-track burning was slow and stalled after track 1.
|
||||||
|
Regression introduced in version 1.5.0 by commit 84fad99, 2018.02.05
|
||||||
|
O_DIRECT is now disabled for track sources.
|
||||||
|
|
||||||
|
libburn-1.5.2.tar.gz Sat Oct 26 2019
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: No lock was obtained for setting up a fifo object
|
||||||
|
* Bug fix: Stream recording was applied regardless whether the drive offers it.
|
||||||
|
This caused Xfburn failures with some MATSHITA laptop drives.
|
||||||
|
* Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
|
||||||
|
* Made libburn ready for building out-of-source. Thanks Ross Burton.
|
||||||
|
* New API calls burn_drive_get_feature_codes(), burn_drive_get_feature()
|
||||||
|
* New cdrskin option --list_features
|
||||||
|
|
||||||
|
libburn-1.5.0.tar.gz Sat Sep 15 2018
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin threw errno 22 on data file input if libburn is
|
||||||
|
configured with --enable-track-src-odirect
|
||||||
|
* Bug fix: SIGSEGV could happen if a track ended by reaching its fixed size
|
||||||
|
while the track source still was willing to deliver bytes.
|
||||||
|
Thanks to user swordragon.
|
||||||
|
* Bug fix: Device file comparison parameters were recorded wrong with Linux sg
|
||||||
|
|
||||||
|
libburn-1.4.8.tar.gz Tue Sep 12 2017
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Option -dummy did not affect writing by direct_write_amount=
|
||||||
|
* New API call burn_drive_reset_simulate()
|
||||||
|
* New API call burn_drive_get_bd_r_pow()
|
||||||
|
* Refusing to write to BD-R if formatted to Pseudo Overwrite
|
||||||
|
|
||||||
|
libburn-1.4.6.tar.gz Fri Sep 16 2016
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: SAO CD could be perceived 2 blocks to short.
|
||||||
|
Regression in 1.4.4 by rev 5672.
|
||||||
|
* Now operating optical drives on OpenBSD. Thanks to SASANO Takayoshi.
|
||||||
|
* New API call burn_drive_set_immed()
|
||||||
|
* New cdrskin option use_immed_bit=
|
||||||
|
|
||||||
|
libburn-1.4.4.tar.gz Fri Jul 01 2016
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Option drive_scsi_dev_family=sg did not convert /dev/sr* to /dev/sg*
|
||||||
|
* Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding.
|
||||||
|
Affected cdrskin option: cdtext_to_v07t=
|
||||||
|
* Bug fix: Double free at end of run if burn_write_opts_set_leadin_text() is
|
||||||
|
used. Affected cdrskin option: textfile=
|
||||||
|
* Bug fix: DVD book type of DVD+RW DL and DVD+R DL was reported wrong.
|
||||||
|
Thanks to Etienne Bergeron.
|
||||||
|
|
||||||
|
libburn-1.4.2.pl01.tar.gz Fri Jan 29 2016
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin "failed to attach fifo" when burning from stdin.
|
||||||
|
Regression of 1.4.2, rev 5522.
|
||||||
|
|
||||||
|
libburn-1.4.2.tar.gz Sat Nov 28 2015
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long
|
||||||
|
* Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in
|
||||||
|
caps.start_range_high
|
||||||
|
* Bug fix: Media summary session count of blank and closed media was short by 1
|
||||||
|
* Bug fix: Endless loop if transport error occurs while waiting for drive ready
|
||||||
|
* New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno()
|
||||||
|
* Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs
|
||||||
|
|
||||||
|
libburn-1.4.0.tar.gz Sun May 17 2015
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Double free with cdrskin -vvv.
|
||||||
|
Introduced with rev 5065, version 1.3.1
|
||||||
|
* Bug fix: Wrong read access to memory. Reported by valgrind of lian jianfei.
|
||||||
|
|
||||||
|
libburn-1.3.8.tar.gz Sat Jun 28 2014
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2
|
||||||
|
* Bug fix: Minimum drive buffer fill was measured by cdrskin before the buffer
|
||||||
|
could get full
|
||||||
|
* Bug fix: A failed MMC BLANK command did not cause error indication by libburn
|
||||||
|
* Bug fix: A final fsync(2) was performed with stdio drives, even if not
|
||||||
|
desired
|
||||||
|
|
||||||
|
libburn-1.3.6.pl01.tar.gz Tue Mar 18 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: CD TAO with multiple tracks could cause a buffer overrun
|
||||||
|
* Bug fix: Compilation warning for unsupported systems mutated into an error
|
||||||
|
|
||||||
|
libburn-1.3.6.tar.gz Tue Mar 04 2013
|
||||||
|
===============================================================================
|
||||||
|
* New system adapter for NetBSD
|
||||||
|
|
||||||
|
libburn-1.3.4.tar.gz Thu Dec 12 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Drive error reports were ignored during blanking and formatting
|
||||||
|
* Bug fix: Drive LG BH16NS40 stalls on inspection of unformatted DVD+RW
|
||||||
|
* New API call burn_disc_pretend_full_uncond()
|
||||||
|
|
||||||
|
libburn-1.3.2.tar.gz Wed Aug 07 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin -msinfo on DVD and BD reported
|
||||||
|
old session start = next writable address.
|
||||||
|
Regression introduced by version 1.2.8 (rev 4956).
|
||||||
|
* Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU
|
||||||
|
* New API call burn_make_input_sheet_v07t()
|
||||||
|
* API call burn_session_input_sheet_v07t(): read multiple blocks from same file
|
||||||
|
* New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track()
|
||||||
|
* New cdrskin option textfile_to_v07t=
|
||||||
|
* New cdrskin options cdtext_to_textfile= and cdtext_to_v07t=
|
||||||
|
* New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= ,
|
||||||
|
--extract_dap
|
||||||
|
* New cdrskin option --pacifier_with_newline
|
||||||
|
* Improved granularity of SCSI log time measurement, now with timestamp
|
||||||
|
* Optional "make doc" now demands doxygen 1.8.4
|
||||||
|
|
||||||
|
libburn-1.3.0.pl01.tar.gz Fri May 31 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin -msinfo on DVD and BD reported
|
||||||
|
old session start = next writable address.
|
||||||
|
Regression introduced by version 1.2.8.
|
||||||
|
|
||||||
|
libburn-1.3.0.tar.gz Fri May 17 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Full formatting of BD-RE used certification regardless of drive
|
||||||
|
capabilities
|
||||||
|
* Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end
|
||||||
|
address
|
||||||
|
|
||||||
|
libburn-1.2.8.tar.gz Mon Mar 18 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: All CD tracks were reported with the sizes of the tracks in the
|
||||||
|
first session. Regression introduced with version 1.2.0 (rev 4552).
|
||||||
|
* Bug fix: On some drives the request for minimum speed yielded maximum speed
|
||||||
|
* New cdrskin option --list_speeds
|
||||||
|
* -toc and -minfo now report about tracks in the incomplete session
|
||||||
|
* New API call burn_disc_get_incomplete_sessions()
|
||||||
|
* New burn_toc_entry component .track_status_bits
|
||||||
|
|
||||||
|
libburn-1.2.6.tar.gz Tue Jan 08 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Speed setting had no effect on BD media
|
||||||
|
* New cdrskin option --no_load
|
||||||
|
* New API call burn_read_audio()
|
||||||
|
* New API call burn_list_sev_texts()
|
||||||
|
|
||||||
|
libburn-1.2.4.tar.gz Fri Jul 20 2012
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: CD SAO sessions with data tracks started by an audio pause
|
||||||
|
* Bug fix: CD tracks were perceived 2 sectors too short.
|
||||||
|
Nice with TAO, bad with SAO.
|
||||||
|
* Bug fix: cdrskin SIGSEGV if track source was added when no drive was available
|
||||||
|
* New API call burn_write_opts_set_obs_pad(), ./configure --enable-dvd-obs-pad
|
||||||
|
* New cdrskin option --obs_pad
|
||||||
|
|
||||||
|
libburn-1.2.2.tar.gz Mon Apr 02 2012
|
||||||
|
===============================================================================
|
||||||
|
* Small internal refinements
|
||||||
|
|
||||||
|
libburn-1.2.0.tar.gz Sat Jan 28 2012
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin produced a memory fault if interupted before writing began
|
||||||
|
* Bug fix: Solaris adapter mishandled write commands which failed on first try
|
||||||
|
* Bug fix: Interrupting libburn while drive tray is loading led to endless loop
|
||||||
|
* Bug fix: Progress report with blanking and formatting could be bogus
|
||||||
|
* New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text()
|
||||||
|
* New API calls for composing CD-TEXT, see doc/cdtext.txt
|
||||||
|
* New API call burn_session_by_cue_file() for reading CDRWIN .cue files
|
||||||
|
* New API call burn_track_set_isrc_string()
|
||||||
|
* New API calls burn_track_set_index(), burn_track_clear_indice()
|
||||||
|
* New API calls burn_session_set_start_tno(), burn_session_get_start_tno()
|
||||||
|
* New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size()
|
||||||
|
* Implemented cdrskin option textfile=
|
||||||
|
* Implemented cdrskin option combination -vv -toc for cdtext.dat production
|
||||||
|
* Implemented cdrskin options mcn= and isrc=
|
||||||
|
* Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp
|
||||||
|
* Implemented cdrskin option index=
|
||||||
|
* Partly implemented cdrskin options cuefile= and -text
|
||||||
|
* New cdrskin option input_sheet_v07t= for CD-TEXT definition
|
||||||
|
* New cdrskin options --cdtext_dummy and --cdtext_verbose
|
||||||
|
* New cdrskin options --four_channel --two_channel
|
||||||
|
* New cdrskin option cd_start_tno=
|
||||||
|
* New cdrskin options sao_pregap=, sao_postgap=
|
||||||
|
|
||||||
|
libburn-1.1.8.tar.gz Mon Nov 21 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Misinterpreted mode page 2A if block descriptors are present
|
||||||
|
* Enabled recognition of QEMU DVD-ROM 0.12
|
||||||
|
* Avoiding to intermediately close and open drive device file
|
||||||
|
* New API call burn_drive_re_assess()
|
||||||
|
|
||||||
|
libburn-1.1.6.tar.gz Tue Sep 27 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
|
||||||
|
* Worked around a collision with Linux udev which lets links vanish
|
||||||
|
|
||||||
|
libburn-1.1.4.tar.gz Sun Aug 07 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Some drives return -150 as NWA of blank CD, rather than 0.
|
||||||
|
libburn forwarded this misleading information to the application.
|
||||||
|
* Bug fix: Some drives returned wrong CD sizes after having burned DVD-R
|
||||||
|
* Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc
|
||||||
|
* Bug fix: Avoiding to load speed descriptor list twice
|
||||||
|
* New API call burn_lookup_device_link()
|
||||||
|
* New API call burn_disc_get_phys_format_info()
|
||||||
|
* New cdrskin option --device_links
|
||||||
|
|
||||||
|
Release 1.1.2 was skipped to get back in sync with libisoburn.
|
||||||
|
|
||||||
|
libburn-1.1.0.pl01.tar.gz Mon Jun 20 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris
|
||||||
|
|
||||||
|
libburn-1.1.0.tar.gz Sat Jun 18 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h
|
||||||
|
* New API call burn_disc_next_track_is_damaged()
|
||||||
|
* New API call burn_disc_close_damaged()
|
||||||
|
* Dropped suffix .plXY from tarball name
|
||||||
|
|
||||||
|
Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn.
|
||||||
|
|
||||||
|
libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011
|
||||||
|
===============================================================================
|
||||||
|
* Burning DVD-R DAO with 2 kB size granularity rather than 32 kB
|
||||||
|
* New API call burn_allow_drive_role_4()
|
||||||
|
|
||||||
|
libburn-1.0.4.pl00.tar.gz Thu Mar 3 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Read-only file descriptors were classified as write-only pseudo
|
||||||
|
drives
|
||||||
|
|
||||||
|
libburn-1.0.2.pl00.tar.gz Wed Feb 23 2011
|
||||||
|
===============================================================================
|
||||||
|
* Removed compilation obstacles on Solaris 9.
|
||||||
|
* Improved recognition of non-seekable stdio pseudo-drives.
|
||||||
|
|
||||||
|
libburn-1.0.0.pl00.tar.gz Sun Jan 16 2011
|
||||||
|
===============================================================================
|
||||||
|
* Allowed umask to create stdio-drive files with rw-permissions for all
|
||||||
|
* cdrskin now refuses to burn if the foreseeable size exceeds media capacity
|
||||||
|
|
||||||
|
libburn-0.9.0.pl00.tar.gz Wed Dec 08 2010
|
||||||
|
===============================================================================
|
||||||
|
* Regression fix: SCSI reply data logging was disabled in release 0.8.6
|
||||||
|
|
||||||
|
libburn-0.8.8.pl00.tar.gz Wed Oct 20 2010
|
||||||
|
===============================================================================
|
||||||
|
* New API call burn_offst_source_new()
|
||||||
|
* New API call burn_disc_get_bd_spare_info()
|
||||||
|
|
||||||
|
libburn-0.8.6.pl00.tar.gz Fri Sep 17 2010
|
||||||
|
===============================================================================
|
||||||
|
* Lifted test reservation on DVD-R DL media.
|
||||||
|
* Hiding all non-API symbols from the linker by use of --version-script
|
||||||
|
* Now with history of release notes in ./ChangeLog file.
|
||||||
|
|
||||||
|
libburn-0.8.4.pl00.tar.gz Wed Jun 30 2010
|
||||||
|
===============================================================================
|
||||||
|
* General POSIX system adapters ignore SIGWINCH and SIGURG if defined
|
||||||
|
* Allowed 64 kB max output buffer size on all OSes
|
||||||
|
|
||||||
|
libburn-0.8.2.pl00.tar.gz Fri Jun 11 2010
|
||||||
|
===============================================================================
|
||||||
|
* New system adapter for Solaris uscsi (tested on snv134, kernel 5.11)
|
||||||
|
* Bug fix: CD TOC was not read if the first track did not start at LBA 0
|
||||||
|
* Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses
|
||||||
|
* Bug fix: SIGSEGV of experimental libcdio system adapter if drive list is
|
||||||
|
empty
|
||||||
|
|
||||||
|
libburn-0.8.0.pl00.tar.gz Fri Apr 09 2010
|
||||||
|
===============================================================================
|
||||||
|
* libburn now works with ahci driver on FreeBSD 8-STABLE.
|
||||||
|
|
||||||
|
libburn-0.7.8.pl00.tar.gz Wed Mar 10 2010
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: On FreeBSD, piped input was falsely attributed a small fixed size.
|
||||||
|
* Built-in abort handling is more suitable for FreeBSD now.
|
||||||
|
cdrskin novelties:
|
||||||
|
* Bug fix: Option fs=0 led to SIGSEGV. Regression introduced by version 0.7.4
|
||||||
|
in december 2009.
|
||||||
|
* Abort handling is more suitable for FreeBSD now.
|
||||||
|
|
||||||
|
libburn-0.7.6.pl00.tar.gz Sat Jan 23 2010
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: System adapter for generic X/Open was missing in libburn release
|
||||||
|
tarball
|
||||||
|
* Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
|
||||||
|
* Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
|
||||||
|
* Enabled FreeBSD system adapter for Debian kfreebsd
|
||||||
|
* Experimental SCSI transport adapter via GNU libcdio 0.83git
|
||||||
|
cdrskin novelties:
|
||||||
|
* none
|
||||||
|
|
||||||
|
libburn-0.7.4.pl01.tar.gz Sat Dec 26 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Added missing system adapter for generic X/Open to libburn release
|
||||||
|
tarball
|
||||||
|
|
||||||
|
Libburn 0.7.4.pl00 Mon Dec 07 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG
|
||||||
|
GH22LS30
|
||||||
|
* Bug fix: DVD DAO track size was rounded up much too generously
|
||||||
|
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
|
||||||
|
(already fixed in 0.7.2.pl01)
|
||||||
|
* Workaround for Pioneer DVR-216D refusal to eject.
|
||||||
|
(already fixed in 0.7.2.pl01)
|
||||||
|
* Configure options --enable-dvd-obs-64k, --enable-track-src-odirect
|
||||||
|
* New API calls burn_write_opts_set_dvd_obs(),
|
||||||
|
burn_write_opts_set_stdio_fsync()
|
||||||
|
* New API call burn_set_scsi_logging()
|
||||||
|
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(),
|
||||||
|
burn_fifo_fill()
|
||||||
|
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
|
||||||
|
cdrskin novelties:
|
||||||
|
* cdrskin option -V for logging of SCSI commands
|
||||||
|
* New cdrskin options dvd_obs= and stdio_fsync=
|
||||||
|
* New compile_cdrskin.sh option -dvd_obs_64k
|
||||||
|
|
||||||
|
libburn-0.7.2.pl01.tar.gz Fri Nov 13 2009
|
||||||
|
===============================================================================
|
||||||
|
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
|
||||||
|
* Workaround for Pioneer DVR-216D refusal to eject.
|
||||||
|
|
||||||
|
Libburn 0.7.2.pl00 Mon Oct 12 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode
|
||||||
|
* New API calls burn_get_media_product_id() , burn_guess_manufacturer() ,
|
||||||
|
burn_guess_cd_manufacturer()
|
||||||
|
* New API call burn_disc_get_cd_info()
|
||||||
|
* New API call burn_track_set_cdxa_conv()
|
||||||
|
cdrskin novelties:
|
||||||
|
* Better interpretation of options -mode2, -xa, -xa1, -xa2
|
||||||
|
* New option --xa1-ignore
|
||||||
|
* New -atip report lines "Product Id:" and "Producer:"
|
||||||
|
|
||||||
|
libburn-0.7.0.pl00.tar.gz Thu Aug 27 2009
|
||||||
|
===============================================================================
|
||||||
|
* New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() allow
|
||||||
|
to inquire and process the list of supported media types. cdrskin lists all
|
||||||
|
supported profiles with option -atip -v
|
||||||
|
* New API call burn_drive_snooze() allows to calm down a drive when no i/o is
|
||||||
|
expected for a while.
|
||||||
|
* Bug fix: Some SCSI commands stalled on U3 memory sticks which appear as a hub
|
||||||
|
with a memory stick and a CD-ROM drive containing a small CD. These commands
|
||||||
|
make not much sense with a CD-ROM and are now avoided for this media
|
||||||
|
situation.
|
||||||
|
|
||||||
|
libburn-0.6.8.pl00.tar.gz Tue Jul 14 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length.
|
||||||
|
* cdrskin -scanbus now works with high SCSI bus numbers.
|
||||||
|
|
||||||
|
libburn-0.6.6.pl00.tar.gz Fri May 8 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Improper abort handling with broken pipe during outputto a stdio:
|
||||||
|
pseudo-drive.
|
||||||
|
* Bug fix: Device scan stalled on FreeBSD with non-burner USB device
|
||||||
|
|
||||||
|
libburn-0.6.4.pl00.tar.gz Fri Mar 13 2009
|
||||||
|
===============================================================================
|
||||||
|
* New operating system adapter "dummy" for stdio on general X/Open systems
|
||||||
|
* New API function burn_drive_set_stream_recording() allows to write the
|
||||||
|
crucial start blocks of a filesystem with slow BD-RE Defect Management and to
|
||||||
|
write the bulk of data with full nominal speed.
|
||||||
|
|
||||||
|
libburn-0.6.2.pl00.tar.gz Fri Feb 20 2009
|
||||||
|
===============================================================================
|
||||||
|
* Improvements with build system for FreeBSD
|
||||||
|
|
||||||
|
libburn-0.6.0.pl01.tar.gz Wed Jan 07 2009
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: BD-R were not correctly finalized
|
||||||
|
|
||||||
|
libburn-0.6.0.pl00.tar.gz Sun Jan 04 2009
|
||||||
|
===============================================================================
|
||||||
|
* Formatting and writing of BD-R media
|
||||||
|
* New API function burn_get_read_capacity()
|
||||||
|
|
||||||
|
libburn-0.5.8.pl00.tar.gz Mon Dec 08 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: A session without leadout entry on CD caused a SIGSEGV by NULL
|
||||||
|
* Improvements about BD-RE formatting
|
||||||
|
|
||||||
|
libburn-0.5.6.pl00.tar.gz Wed Nov 12 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: libburn fifo thread was not aborted when burn run was aborted which
|
||||||
|
could lead to use of freed memory.
|
||||||
|
|
||||||
|
libburn-0.5.4.pl00.tar.gz Mon Oct 6 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: On Linux 2.4 /dev/sr0 was accepted as enumerable address but then
|
||||||
|
failed to work.
|
||||||
|
|
||||||
|
libburn-0.5.2.pl00.tar.gz Wed Aug 20 2008
|
||||||
|
===============================================================================
|
||||||
|
* Larger set of possibly acceptable drive device file names
|
||||||
|
|
||||||
|
libburn-0.5.0.pl00.tar.gz Thu Jul 17 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: cdrskin option drive_scsi_dev_family=scd lead to buffer overflow
|
||||||
|
* Ability to use /dev/scd as fallback if /dev/sr does not exist
|
||||||
|
* New API call burn_fifo_peek_data()
|
||||||
|
|
||||||
|
libburn-0.4.8.pl00.tar.gz Sat May 17 2008
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Random access addressing for DVD-RAM and BD-RE did not work.
|
||||||
|
* cdrskin: Affected were options write_start_address= and
|
||||||
|
-- grow_overwriteable_iso on DVD-RAM or BD-RE.
|
||||||
|
* xorriso: Affected were sessions on DVD-RAM or BD-RE after the first one.
|
||||||
|
|
||||||
|
libburn-0.4.6.pl00.tar.gz Sun May 11 2008
|
||||||
|
===============================================================================
|
||||||
|
* Support for BD-RE media is now official
|
||||||
|
* New burn_write_opts_set_stream_recording() can speed up DVD-RAM and BD-RE
|
||||||
|
* New cdrskin option --list_formats
|
||||||
|
* New cdrskin blank types for expert formatting of DVD-RAM and BD-RE
|
||||||
|
* New cdrskin blank type blank=as_needed for automatic handling of media
|
||||||
|
|
||||||
|
libburn-0.4.4.tar.gz Thu April 10 2008
|
||||||
|
===============================================================================
|
||||||
|
* Support for DVD+R/DL media is now official
|
||||||
|
|
||||||
|
libburn-0.4.2.tar.gz Sun Feb 3 2008
|
||||||
|
===============================================================================
|
||||||
|
* Long term commitment to ABI libburn.so.4.
|
||||||
|
* ABI compatibility is guaranteed for any older feature set released since
|
||||||
|
libburn-0.3.2 about one year ago.
|
||||||
|
* libburn provides means for compile time and runtime checking of its version.
|
||||||
|
* Compile time check in cdrskin for proper version of libburn include file.
|
||||||
|
Required is at least 0.4.2.
|
||||||
|
* Runtime check in cdrskin prevents dynamic linking with outdated version of
|
||||||
|
libburn.so.4. Required is at least the version seen in the include file at
|
||||||
|
compile time.
|
||||||
|
|
||||||
|
libburn-0.4.0.tar.gz Mon Oct 29 2007
|
||||||
|
===============================================================================
|
||||||
|
* New option direct_write_amount=
|
||||||
|
* New option --grow_overwriteable_iso
|
||||||
|
* New option --allow_emulated_drives dev=stdio:<path>
|
||||||
|
* More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti
|
||||||
|
* New option fallback_program=
|
||||||
|
* A lot of libburn API additions.
|
||||||
|
|
||||||
|
libburn-0.3.8.tar.gz Tue Jul 31 2007
|
||||||
|
===============================================================================
|
||||||
|
* Now able to cope with the peculiarities of Linux 2.4 USB
|
||||||
|
* Refusal to perform -dummy runs on media which cannot simulate burning
|
||||||
|
* New option modesty_on_drive= may help with hda -> hdb burns
|
||||||
|
* New option minbuf= , cdrecord compatible frontend of modesty_on_drive=
|
||||||
|
* New option --adjust_speed_to_drive
|
||||||
|
* Precautions against using the burner drive as track source
|
||||||
|
* Note: ABI has not been broken.
|
||||||
|
|
||||||
|
libburn-0.3.6.tar.gz Thu Apr 26 2007
|
||||||
|
===============================================================================
|
||||||
|
* On Linux kernel 2.6, /dev/sr* gets used rather than /dev/sg*.
|
||||||
|
* DVD+R now get finalized (if not -multi is given)
|
||||||
|
|
||||||
|
libburn-0.3.4.tar.gz Mon Mar 12 2007
|
||||||
|
===============================================================================
|
||||||
|
* Multi-session recording on DVD+R, including -toc, -msinfo
|
||||||
|
* Options --tell_media_space , assert_write_lba=
|
||||||
|
* Bug fix of rare multi track fifo stall
|
||||||
|
|
||||||
|
libburn-0.3.2.tar.gz Feb 11 2007
|
||||||
|
===============================================================================
|
||||||
|
* Burnfree enabled by default
|
||||||
|
* Multi-session recording on sequential DVD-R[W], including -toc, -msinfo
|
||||||
|
* DVD-R[W] Disk-at-once recording
|
||||||
|
|
||||||
|
libburn-0.3.0.1.tar.gz Tue Jan 30 2007
|
||||||
|
===============================================================================
|
||||||
|
* Improved recognition of unsuitable media types
|
||||||
|
* Replaced ban of chmod u+s by loud warning
|
||||||
|
* detailed man page for cdrskin
|
||||||
|
* Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session
|
||||||
|
* Formatting and then burning to DVD-RW like to DVD+RW
|
||||||
|
* New option -msifile=path from cdrkit/wodim
|
||||||
|
* 0.3.0.1 release notes *
|
||||||
|
* Bug fix enabling tracks >= 1.3 GB from disk file
|
||||||
|
|
||||||
|
libburn-0.2.6.3.tar.gz Fri Dec 29 2006
|
||||||
|
===============================================================================
|
||||||
|
* 0.2.6 release notes (Wed Nov 22 2006)
|
||||||
|
* After a lot of time with dedication to this project, we proudly present you
|
||||||
|
libburn 0.2.6. It is the first version of cdrskin and libburn after they have
|
||||||
|
been split from genisofs and libisofs. Main new features are write mode TAO
|
||||||
|
and support for multi session.
|
||||||
|
* 0.2.6.1 release notes (Fri Nov 24 2006)
|
||||||
|
* Point release to fix misleading version numbers in messages and documentation
|
||||||
|
* 0.2.6.2 release notes (Sat Dec 16 2006)
|
||||||
|
* cdrskin man page backported from development version 0.2.7.
|
||||||
|
* 0.2.6.3 release notes (Fri Dec 29 2006)
|
||||||
|
* Point release to fix build system problems people have experienced with the
|
||||||
|
past release.
|
||||||
|
|
||||||
|
libburn-0.2.3.snapshot02.tar.gz Thu Nov 02 2006
|
||||||
|
===============================================================================
|
||||||
|
* Stabilized snapshot including release 0.2.4.pl01 of cdrskin
|
||||||
|
* cdrskin 0.2.4 release notes
|
||||||
|
* Compatibility with cdrecord has been improved in respect to drive addresses,
|
||||||
|
audio extraction from .wav, -scanbus, -toc, drive buffer fill indicator.
|
||||||
|
* Note: The previous snapshot01 with the same source base is handicapped by a
|
||||||
|
broken ./configure setup. It works well on Intel compatible CPUs but is
|
||||||
|
supposed to be unusable on big-endian architectures.
|
||||||
|
|
||||||
|
libburn-0.2.2.tar.gz Wed Sep 20 2006
|
||||||
|
===============================================================================
|
||||||
|
Initial release of libburnia's libburn combined with cdrskin.
|
||||||
|
|
58
Makefile.am
58
Makefile.am
|
@ -6,17 +6,22 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
||||||
libincludedir=$(includedir)/libburn
|
libincludedir=$(includedir)/libburn
|
||||||
|
|
||||||
lib_LTLIBRARIES = libburn/libburn.la
|
lib_LTLIBRARIES = libburn/libburn.la
|
||||||
|
ACLOCAL_AMFLAGS = -I ./
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
# Build libraries
|
# Build libraries
|
||||||
libburn_libburn_la_LDFLAGS = \
|
libburn_libburn_la_LDFLAGS = \
|
||||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
|
||||||
|
# This causes undesired .o names
|
||||||
|
# configure.ac appends -D options to variable CFLAG
|
||||||
|
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
|
||||||
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||||
libburn_libburn_la_SOURCES = \
|
libburn_libburn_la_SOURCES = \
|
||||||
libburn/async.c \
|
libburn/async.c \
|
||||||
libburn/async.h \
|
libburn/async.h \
|
||||||
libburn/back_hacks.h \
|
libburn/back_hacks.h \
|
||||||
|
libburn/cdtext.c \
|
||||||
libburn/cleanup.c \
|
libburn/cleanup.c \
|
||||||
libburn/cleanup.h \
|
libburn/cleanup.h \
|
||||||
libburn/crc.c \
|
libburn/crc.c \
|
||||||
|
@ -25,13 +30,13 @@ libburn_libburn_la_SOURCES = \
|
||||||
libburn/debug.h \
|
libburn/debug.h \
|
||||||
libburn/drive.c \
|
libburn/drive.c \
|
||||||
libburn/drive.h \
|
libburn/drive.h \
|
||||||
|
libburn/ecma130ab.c \
|
||||||
|
libburn/ecma130ab.h \
|
||||||
libburn/error.h \
|
libburn/error.h \
|
||||||
libburn/file.c \
|
libburn/file.c \
|
||||||
libburn/file.h \
|
libburn/file.h \
|
||||||
libburn/init.c \
|
libburn/init.c \
|
||||||
libburn/init.h \
|
libburn/init.h \
|
||||||
libburn/lec.c \
|
|
||||||
libburn/lec.h \
|
|
||||||
libburn/libburn.h \
|
libburn/libburn.h \
|
||||||
libburn/libdax_audioxtr.h \
|
libburn/libdax_audioxtr.h \
|
||||||
libburn/libdax_audioxtr.c \
|
libburn/libdax_audioxtr.c \
|
||||||
|
@ -64,24 +69,26 @@ libburn_libburn_la_SOURCES = \
|
||||||
libburn/util.c \
|
libburn/util.c \
|
||||||
libburn/util.h \
|
libburn/util.h \
|
||||||
libburn/write.c \
|
libburn/write.c \
|
||||||
libburn/write.h \
|
libburn/write.h
|
||||||
version.h
|
|
||||||
|
|
||||||
## libburn/sg-@ARCH@.c \
|
## libburn/sg-@ARCH@.c \
|
||||||
|
|
||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
libburn/libburn.h
|
libburn/libburn.h
|
||||||
|
|
||||||
|
install-exec-hook:
|
||||||
|
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
## Build test applications
|
## Build test applications
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
test/libburner \
|
test/libburner \
|
||||||
|
test/offst_source \
|
||||||
test/telltoc \
|
test/telltoc \
|
||||||
test/dewav \
|
test/dewav \
|
||||||
test/fake_au \
|
test/fake_au \
|
||||||
test/poll \
|
test/poll
|
||||||
test/structest
|
|
||||||
|
|
||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
cdrskin/cdrskin
|
cdrskin/cdrskin
|
||||||
|
@ -91,6 +98,9 @@ LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||||
test_libburner_CPPFLAGS = -Ilibburn
|
test_libburner_CPPFLAGS = -Ilibburn
|
||||||
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
test_libburner_SOURCES = test/libburner.c
|
test_libburner_SOURCES = test/libburner.c
|
||||||
|
test_offst_source_CPPFLAGS = -Ilibburn
|
||||||
|
test_offst_source_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
|
test_offst_source_SOURCES = test/offst_source.c
|
||||||
test_telltoc_CPPFLAGS = -Ilibburn
|
test_telltoc_CPPFLAGS = -Ilibburn
|
||||||
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
test_telltoc_SOURCES = test/telltoc.c
|
test_telltoc_SOURCES = test/telltoc.c
|
||||||
|
@ -103,13 +113,10 @@ test_fake_au_SOURCES = test/fake_au.c
|
||||||
test_poll_CPPFLAGS = -Ilibburn
|
test_poll_CPPFLAGS = -Ilibburn
|
||||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
test_poll_SOURCES = test/poll.c
|
test_poll_SOURCES = test/poll.c
|
||||||
test_structest_CPPFLAGS = -Ilibburn
|
|
||||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
|
||||||
test_structest_SOURCES = test/structest.c
|
|
||||||
|
|
||||||
## cdrskin construction site - ts A60816 - A90507
|
## cdrskin construction site - ts A60816 - C30607
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_6_9
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_5_7
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||||
|
@ -120,6 +127,11 @@ cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h
|
||||||
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
||||||
##
|
##
|
||||||
|
|
||||||
|
# "make clean" shall remove a few stubborn .libs directories
|
||||||
|
# which George Danchev reported Dec 03 2011.
|
||||||
|
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
|
||||||
|
clean-local:
|
||||||
|
-rm -rf cdrskin/.libs test/.libs
|
||||||
|
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
@ -140,7 +152,10 @@ doc/html: doc/doxygen.conf
|
||||||
doc-upload: doc/html
|
doc-upload: doc/html
|
||||||
scp -r $</* $(webhost):$(webpath)
|
scp -r $</* $(webhost):$(webpath)
|
||||||
|
|
||||||
all: doc
|
## ts B00729
|
||||||
|
## Not by default any more.
|
||||||
|
## It is unclear who is supposed to create file ./doc/doc.lock
|
||||||
|
# all: doc
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
if [ -f ./doc/doc.lock ]; then \
|
if [ -f ./doc/doc.lock ]; then \
|
||||||
|
@ -156,8 +171,7 @@ uninstall-local:
|
||||||
# Indent source files
|
# Indent source files
|
||||||
indent_files = \
|
indent_files = \
|
||||||
$(libburn_libburn_la_SOURCES) \
|
$(libburn_libburn_la_SOURCES) \
|
||||||
$(test_poll_SOURCES) \
|
$(test_poll_SOURCES)
|
||||||
$(test_structest_SOURCES)
|
|
||||||
|
|
||||||
|
|
||||||
indent: $(indent_files)
|
indent: $(indent_files)
|
||||||
|
@ -179,10 +193,15 @@ nodist_pkgconfig_DATA = \
|
||||||
man_MANS = cdrskin/cdrskin.1
|
man_MANS = cdrskin/cdrskin.1
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
bootstrap \
|
||||||
libburn-1.pc.in \
|
libburn-1.pc.in \
|
||||||
version.h.in \
|
version.h.in \
|
||||||
doc/comments \
|
doc/comments \
|
||||||
doc/doxygen.conf.in \
|
doc/doxygen.conf.in \
|
||||||
|
doc/cookbook.txt \
|
||||||
|
doc/mediainfo.txt \
|
||||||
|
doc/cdtext.txt \
|
||||||
|
doc/waveformat.txt \
|
||||||
README \
|
README \
|
||||||
AUTHORS \
|
AUTHORS \
|
||||||
CONTRIBUTORS \
|
CONTRIBUTORS \
|
||||||
|
@ -196,10 +215,19 @@ EXTRA_DIST = \
|
||||||
cdrskin/wiki_plain.txt \
|
cdrskin/wiki_plain.txt \
|
||||||
cdrskin/cleanup.h \
|
cdrskin/cleanup.h \
|
||||||
cdrskin/cleanup.c \
|
cdrskin/cleanup.c \
|
||||||
|
libburn/libburn.ver \
|
||||||
|
libburn/os-dummy.h \
|
||||||
libburn/os-freebsd.h \
|
libburn/os-freebsd.h \
|
||||||
libburn/os-linux.h \
|
libburn/os-linux.h \
|
||||||
|
libburn/os-libcdio.h \
|
||||||
|
libburn/os-solaris.h \
|
||||||
|
libburn/os-netbsd.h \
|
||||||
|
libburn/sg-dummy.c \
|
||||||
libburn/sg-freebsd.c \
|
libburn/sg-freebsd.c \
|
||||||
libburn/sg-linux.c \
|
libburn/sg-linux.c \
|
||||||
|
libburn/sg-libcdio.c \
|
||||||
|
libburn/sg-solaris.c \
|
||||||
|
libburn/sg-netbsd.c \
|
||||||
COPYING \
|
COPYING \
|
||||||
NEWS \
|
NEWS \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
|
|
516
README
516
README
|
@ -4,14 +4,14 @@
|
||||||
This all is under GPL.
|
This all is under GPL.
|
||||||
(See GPL reference, our clarification and commitment at the end of this text)
|
(See GPL reference, our clarification and commitment at the end of this text)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
libburn-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
||||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||||
and Ben Jansens <xor@orodu.net>
|
and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
http://files.libburnia-project.org/releases/libburn-0.6.8.pl00.tar.gz
|
http://files.libburnia-project.org/releases/libburn-1.5.6.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -19,14 +19,14 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
From tarball
|
From tarball
|
||||||
|
|
||||||
Obtain libburn-0.6.8.pl00.tar.gz, take it to a directory of your choice and do:
|
Obtain libburn-1.5.6.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf libburn-0.6.8.pl00.tar.gz
|
tar xzf libburn-1.5.6.tar.gz
|
||||||
cd libburn-0.6.8
|
cd libburn-1.5.6
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
To make libburn accessible for running resp. application development,
|
To make libburn accessible for running and application development,
|
||||||
and to install the cdrecord compatibility binary cdrskin, do
|
and to install the cdrecord compatibility binary cdrskin, do
|
||||||
(as Superuser):
|
(as Superuser):
|
||||||
|
|
||||||
|
@ -41,30 +41,83 @@ You may have to keep your hald away from the drive. See for example
|
||||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
http://www.freebsd.org/gnome/docs/halfaq.html
|
||||||
|
|
||||||
|
|
||||||
From SVN
|
From git
|
||||||
|
|
||||||
Our build system is based on autotools. For preparing the build of a SVN
|
Our build system is based on autotools. For preparing the build of a git
|
||||||
snapshot you will need autotools of at least version 1.7.
|
snapshot you will need autotools of at least version 1.7.
|
||||||
Do in a directory of your choice:
|
Do in a directory of your choice:
|
||||||
|
|
||||||
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
|
git clone https://dev.lovelyhq.com/libburnia/libburn.git libburn-git
|
||||||
cd libburn-svn
|
cd libburn-git
|
||||||
./bootstrap
|
./bootstrap
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|
||||||
Warning: The trunk might contain experimental features which might not
|
Warning: The master branch might contain experimental features which might
|
||||||
persist until next release.
|
not persist until next release.
|
||||||
|
|
||||||
|
|
||||||
|
Special ./configure options
|
||||||
|
|
||||||
|
make install on GNU/Linux will try to run program ldconfig with the library
|
||||||
|
installation directory as only argument. Failure to do so will not abort
|
||||||
|
installation. One may disable ldconfig by ./configure option:
|
||||||
|
--disable-ldconfig-at-install
|
||||||
|
|
||||||
|
In some situations Linux may deliver a better write performance to drives if
|
||||||
|
the track input is read with O_DIRECT (see man 2 open). The API call
|
||||||
|
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
||||||
|
can be told to use this peculiar read mode by:
|
||||||
|
--enable-track-src-odirect
|
||||||
|
|
||||||
|
But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield
|
||||||
|
even better performance in such a situation. 64k can be made default at
|
||||||
|
configure time by:
|
||||||
|
--enable-dvd-obs-64k
|
||||||
|
This may be combined with above --enable-track-src-odirect .
|
||||||
|
|
||||||
|
If it is desired that DVD DAO writing and stdio: writing get padded up to
|
||||||
|
a full write chunk of 32k or 64k, then use ./configure option:
|
||||||
|
--enable-dvd-obs-pad
|
||||||
|
|
||||||
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
|
You may install it and re-run libburn's ./configure with option
|
||||||
|
--enable-libcdio
|
||||||
|
|
||||||
|
By use of a version script, the libburn.so library exposes no other function
|
||||||
|
names but those of the API definition in libburn/libburn.h.
|
||||||
|
If -Wl,--version-script=... makes problems with the local compiler, then
|
||||||
|
disable this encapsulation feature by
|
||||||
|
--disable-versioned-libs
|
||||||
|
|
||||||
|
Make sure to re-compile all source files after running ./configure
|
||||||
|
make clean ; make
|
||||||
|
make install
|
||||||
|
|
||||||
|
|
||||||
|
Linux only:
|
||||||
|
|
||||||
|
libburn tries to avoid a collision with udev's drive examination by waiting
|
||||||
|
0.1 seconds before opening the device file for a longer time, after udev
|
||||||
|
might have been alarmed by drive scanning activities.
|
||||||
|
The waiting time can be set at ./configure time with microsecond granularity.
|
||||||
|
E.g. 2 seconds:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
|
||||||
|
./configure ...options...
|
||||||
|
Waiting can be disabled by zero waiting time:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
|
||||||
|
Alternatively, libburn can try to be nice by opening the device file,
|
||||||
|
closing it immediately, waiting, and only then opening it for real:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
The other parts of the the libburnia project are hosted as neighbors of
|
||||||
launchpad.net :
|
libburn:
|
||||||
bzr branch lp:libisofs
|
|
||||||
|
|
||||||
Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
git clone https://dev.lovelyhq.com/libburnia/libisofs.git
|
||||||
svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn
|
git clone https://dev.lovelyhq.com/libburnia/libisoburn.git
|
||||||
|
|
||||||
See README files there.
|
See README files there.
|
||||||
|
|
||||||
|
@ -75,19 +128,21 @@ See README files there.
|
||||||
|
|
||||||
libburnia-project.org is an open-source software project for reading, mastering
|
libburnia-project.org is an open-source software project for reading, mastering
|
||||||
and writing optical discs.
|
and writing optical discs.
|
||||||
For now this means CD media, all DVD media except DVD-R DL, all BD media.
|
For now this means CD media, all DVD media, all BD media.
|
||||||
|
|
||||||
The project comprises of several more or less interdependent parts which
|
The project comprises of several more or less interdependent parts which
|
||||||
together strive to be a usable foundation for application development.
|
together strive to be a usable foundation for application development.
|
||||||
These are libraries, language bindings, and middleware binaries which emulate
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
classical (and valuable) Linux tools.
|
classical (and valuable) Linux tools.
|
||||||
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
|
||||||
|
on OpenSolaris (tested with kernel 5.11),
|
||||||
|
on NetBSD (tested with 6.1.3).
|
||||||
On other X/Open compliant systems there will only be pseudo drives, but no
|
On other X/Open compliant systems there will only be pseudo drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
|
||||||
For full ports to other systems we would need : login on a development machine
|
For full ports to other systems we would need : login on a development machine
|
||||||
resp. a live OS on CD or DVD, advise from a system person about the equivalent
|
or a live OS on CD or DVD, advise from a system person about the equivalent
|
||||||
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
|
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
||||||
|
@ -114,12 +169,15 @@ The project components (list subject to growth, hopefully):
|
||||||
|
|
||||||
- libisofs is the library to pack up hard disk files and directories into a
|
- libisofs is the library to pack up hard disk files and directories into a
|
||||||
ISO 9660 disk image. This may then be brought to CD via libburn.
|
ISO 9660 disk image. This may then be brought to CD via libburn.
|
||||||
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
An own ISO 9660 extension stores ACLs, xattr, and MD5 of file
|
||||||
|
content.
|
||||||
|
|
||||||
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
||||||
also allows to grow ISO-9660 filesystem images on multi-session
|
also can grow ISO-9660 filesystem images on multi-session media
|
||||||
media as well as on overwriteable media via the same API.
|
as well as on overwriteable media via the same API.
|
||||||
All media peculiarities are handled automatically.
|
All media peculiarities are handled automatically.
|
||||||
|
It also contains the methods of command oriented application
|
||||||
|
xorriso and offers them via a C language API.
|
||||||
|
|
||||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
cdrecord is a powerful GPL'ed burn program included in Joerg
|
cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||||
|
@ -137,8 +195,12 @@ The project components (list subject to growth, hopefully):
|
||||||
Rock Ridge extensions. Manipulation is not only adding or
|
Rock Ridge extensions. Manipulation is not only adding or
|
||||||
overwriting of files but also deleting, renaming, attribute
|
overwriting of files but also deleting, renaming, attribute
|
||||||
changing, incremental backups, activating boot images, and
|
changing, incremental backups, activating boot images, and
|
||||||
extracting of files from ISO images to disk.
|
extracting of files from ISO images to disk. There is also a
|
||||||
See xorriso/README for more.
|
sparse emulation of cdrecord and a more laborate one of mkisofs.
|
||||||
|
All features of xorriso are also available via a C language API
|
||||||
|
of libisoburn.
|
||||||
|
A static compilation of xorriso and the libraries is dedicated
|
||||||
|
to the GNU Operating System. See xorriso/README_gnu_xorriso .
|
||||||
|
|
||||||
- "test" is a collection of application gestures and examples given by the
|
- "test" is a collection of application gestures and examples given by the
|
||||||
authors of the library features. The burn API example of libburn
|
authors of the library features. The burn API example of libburn
|
||||||
|
@ -164,8 +226,8 @@ Applications must use 64 bit off_t. E.g. by defining
|
||||||
#define _LARGEFILE_SOURCE
|
#define _LARGEFILE_SOURCE
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
or take special precautions to interface with the libraries by 64 bit integers
|
or take special precautions to interface with the libraries by 64 bit integers
|
||||||
where the .h files prescribe off_t. Not to use 64 bit file i/o will keep the
|
where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit
|
||||||
application from producing and processing ISO images of more than 2 GB size.
|
will keep it from processing tracks of more than 2 GB size.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -192,7 +254,7 @@ Project history as far as known to me:
|
||||||
which by about nearly everybody else was perceived as unfriendly fork.
|
which by about nearly everybody else was perceived as unfriendly fork.
|
||||||
Derek Foreman four days later posted a message which expressed his
|
Derek Foreman four days later posted a message which expressed his
|
||||||
discontent.
|
discontent.
|
||||||
The situation first caused me to publically regret it and then - after i
|
The situation first caused me to publicly regret it and then - after i
|
||||||
got the opportunity to move in with cdrskin - gave me true reason to
|
got the opportunity to move in with cdrskin - gave me true reason to
|
||||||
personally apologize to Derek Foreman, Ben Jansens and the contributors at
|
personally apologize to Derek Foreman, Ben Jansens and the contributors at
|
||||||
icculus.org/burn. Posted to both projects:
|
icculus.org/burn. Posted to both projects:
|
||||||
|
@ -266,7 +328,7 @@ Project history as far as known to me:
|
||||||
and write modes, and better protection against typical user mishaps.
|
and write modes, and better protection against typical user mishaps.
|
||||||
|
|
||||||
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
||||||
and an upcomming integrated application for manipulating and writing
|
and an upcoming integrated application for manipulating and writing
|
||||||
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
||||||
by these enhancements: growing of overwriteable media and disk files.
|
by these enhancements: growing of overwriteable media and disk files.
|
||||||
Taking again a bow towards Andy Polyakov.
|
Taking again a bow towards Andy Polyakov.
|
||||||
|
@ -292,7 +354,7 @@ Project history as far as known to me:
|
||||||
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
|
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
|
||||||
and can map pieces of disk files onto image files. Image directory iteration
|
and can map pieces of disk files onto image files. Image directory iteration
|
||||||
has been enhanced. Input data streams and extended information have been
|
has been enhanced. Input data streams and extended information have been
|
||||||
exposed in the API to allow future development.
|
exposed in the API to enable future development.
|
||||||
|
|
||||||
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
|
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
|
||||||
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
|
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
|
||||||
|
@ -306,7 +368,8 @@ Project history as far as known to me:
|
||||||
type with automatic media state recognition.
|
type with automatic media state recognition.
|
||||||
|
|
||||||
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
|
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
|
||||||
libburn-0.4.8 to allow libisoburn emulation of multisession on those media.
|
libburn-0.4.8. So libisoburn can now perform emulation of multisession
|
||||||
|
on those media.
|
||||||
|
|
||||||
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
|
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
|
||||||
on overwriteble media and disk files.
|
on overwriteble media and disk files.
|
||||||
|
@ -325,14 +388,14 @@ Project history as far as known to me:
|
||||||
and cdrecord style. xorriso now can serve underneath growisofs.
|
and cdrecord style. xorriso now can serve underneath growisofs.
|
||||||
|
|
||||||
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
|
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
|
||||||
enumerable in order to be adressable. Enumeration is enhanced by examining
|
enumerable in order to be addressable. Enumeration is enhanced by examining
|
||||||
/proc/sys/dev/cdrom/info.
|
/proc/sys/dev/cdrom/info.
|
||||||
|
|
||||||
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
|
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
|
||||||
with data retrieval option.
|
with data retrieval option.
|
||||||
|
|
||||||
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which allows very
|
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which can represent
|
||||||
large data files in the image.
|
very large data files in the image.
|
||||||
|
|
||||||
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
|
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
|
||||||
capabilities of libisofs.
|
capabilities of libisofs.
|
||||||
|
@ -350,19 +413,19 @@ Project history as far as known to me:
|
||||||
of an aborted burn run.
|
of an aborted burn run.
|
||||||
|
|
||||||
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
|
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
|
||||||
and allows to produce ISO images which resemble old mkisofs images.
|
and can produce ISO images which resemble old mkisofs images.
|
||||||
|
|
||||||
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
|
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
|
||||||
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
|
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
|
||||||
signature, and for producing ISO images with MBR which boot from hard disk
|
signature, and for producing ISO images with MBR which boot from hard disk
|
||||||
or USB stick. Three minor bugs were fixed.
|
or USB stick. Three minor bugs were fixed.
|
||||||
|
|
||||||
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
|
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with weird CD table-of-content
|
||||||
and improves BD-RE formatting.
|
and improves BD-RE formatting.
|
||||||
|
|
||||||
- 9th Dec 2008 Our project received a donation from Thomas Weber.
|
- 9th Dec 2008 Our project received a donation from Thomas Weber.
|
||||||
|
|
||||||
- 2nd Jan 2009 libburn-0.6.0 allows to format BD-R and to write to either
|
- 2nd Jan 2009 libburn-0.6.0 learned to format BD-R and write to either
|
||||||
formatted or unformatted BD-R.
|
formatted or unformatted BD-R.
|
||||||
|
|
||||||
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
||||||
|
@ -385,15 +448,16 @@ Project history as far as known to me:
|
||||||
|
|
||||||
- 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport.
|
- 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport.
|
||||||
It will show no drives and thus libburn will only be able to perform
|
It will show no drives and thus libburn will only be able to perform
|
||||||
operations on "stdio:" pseudo drives. Nevertheless this allowed to lift the
|
operations on "stdio:" pseudo drives. Nevertheless this was precondition
|
||||||
ban to build libburn on operating systems other than Linux and FreeBSD.
|
to lift the ban to build libburn on operating systems other than Linux
|
||||||
|
and FreeBSD.
|
||||||
|
|
||||||
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
|
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
|
||||||
in order to be mountable where mkisofs images are mountable.
|
in order to be mountable where mkisofs images are mountable.
|
||||||
|
|
||||||
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
||||||
Built-in filters allow compression to formats gzip and zisofs. External
|
Built-in filters implement compression to formats gzip and zisofs. External
|
||||||
filter processes allow arbitrary data conversions like encryption.
|
filter processes can perform arbitrary data conversions like encryption.
|
||||||
|
|
||||||
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
||||||
perform content filtering of data files.
|
perform content filtering of data files.
|
||||||
|
@ -413,12 +477,355 @@ Project history as far as known to me:
|
||||||
- 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives
|
- 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives
|
||||||
and with large SCSI bus numbers as handed out by Linux for USB drives.
|
and with large SCSI bus numbers as handed out by Linux for USB drives.
|
||||||
|
|
||||||
|
- 20 Jul 2009 libisoburn-0.4.0.pl01 fixes a regression in xorriso which caused
|
||||||
|
data loss in older sessions if xorriso was used underneath growisofs.
|
||||||
|
Affected are releases since libisoburn-0.3.2 in january 2009.
|
||||||
|
|
||||||
|
- 25 Aug 2009 libisofs-0.6.22 can record MD5 checksums for the whole session
|
||||||
|
and for each single data file. Checksum tags can be used to verify superblock
|
||||||
|
and directory tree before importing them.
|
||||||
|
|
||||||
|
- 27 Aug 2009 libburn-0.7.0 learned to calm down a drive and to inquire its
|
||||||
|
supported profiles. It works around some pitfalls with U3 enhanced memory
|
||||||
|
sticks which emulate a CD-ROM.
|
||||||
|
|
||||||
|
- 27 Aug 2009 libisoburn-0.4.0.pl00 can record MD5 checksums by which one may
|
||||||
|
verify the session or single data files in the image. When comparing image
|
||||||
|
files with files in the local filesystem, the MD5 sums avoid the need for
|
||||||
|
reading file content from the image.
|
||||||
|
|
||||||
|
- 22 Sep 2009 libisoburn-0.4.0.pl01 fixes a bug in xorriso option -cut_out.
|
||||||
|
|
||||||
|
- 08 Oct 2009 libisofs-0.6.24 fixes a bug which could cause the loss of blanks
|
||||||
|
in file names when a new session got added to an ISO image. With names
|
||||||
|
shorter than 251 characters this happened only to trailing blanks.
|
||||||
|
|
||||||
|
- 08 Oct 2009 libisoburn-0.4.0.pl02 fixes bugs with xorriso option -for_backup,
|
||||||
|
with xorrisofs -help, and with xorrecord -help.
|
||||||
|
|
||||||
|
- 12 Oct 2009 libburn-0.7.2 fixes a bug with CD TAO multi-track dummy sessions.
|
||||||
|
It can retrieve media product info and can process track input which was
|
||||||
|
prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo.
|
||||||
|
|
||||||
|
- 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and
|
||||||
|
introduces new information options about media type and ISO image id strings.
|
||||||
|
On Linux it helps with mounting two sessions of the same media
|
||||||
|
simultaneously.
|
||||||
|
|
||||||
|
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
|
||||||
|
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
|
||||||
|
|
||||||
|
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
|
||||||
|
provides throughput enhancements with hampered busses on Linux, and new
|
||||||
|
API calls to log SCSI commands and to control the libburn fifo.
|
||||||
|
|
||||||
|
- 09 Dec 2009 libisoburn-0.4.6 now offers performance tuning of output to DVD
|
||||||
|
drives or disk files.
|
||||||
|
|
||||||
|
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
|
||||||
|
the files of the generic system adapter for X/Open.
|
||||||
|
|
||||||
|
- 29 Dec 2009 Our project received a donation for purchasing a fine small
|
||||||
|
computer which shall serve as OS farm for development and support.
|
||||||
|
|
||||||
|
- 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance
|
||||||
|
portability.
|
||||||
|
|
||||||
|
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
|
||||||
|
fixes bugs about the generic X/Open system adapter, and can use
|
||||||
|
libcdio >= 0.83 as SCSI transport facility.
|
||||||
|
|
||||||
|
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
|
||||||
|
was introduced by version 0.6.22 in August 2009.
|
||||||
|
|
||||||
|
- 23 Feb 2010 libisoburn-0.5.0 marks the transition of the xorriso standalone
|
||||||
|
version to an official GNU project. The name changed to "GNU xorriso" and its
|
||||||
|
license is now GPLv3+.
|
||||||
|
The licenses of libburnia libraries and applications are not affected by
|
||||||
|
this change.
|
||||||
|
|
||||||
|
- 10 Mar 2010 libburn-0.7.8 fixes bugs and improves the built-in abort handler
|
||||||
|
on FreeBSD.
|
||||||
|
|
||||||
|
- 30 Mar 2010 Release 0.5.2 of libisoburn provides xorriso documentation in
|
||||||
|
GNU Texinfo format with embedded extra data to derive a full man page.
|
||||||
|
|
||||||
|
- 09 Apr 2010 libburn-0.8.0 now works with ahci driver on FreeBSD 8-STABLE.
|
||||||
|
|
||||||
|
- 03 May 2010 Version 0.6.32 of libisofs is able to create ISO images with
|
||||||
|
multiple boot images. All boot catalog parameters described in El-Torito
|
||||||
|
specs can be set and inquired. This was needed to use GRUB boot images
|
||||||
|
for EFI.
|
||||||
|
|
||||||
|
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
|
||||||
|
capabilities about boot images.
|
||||||
|
|
||||||
|
- 11 Jun 2010 libburn-0.8.2 now works on Solaris.
|
||||||
|
|
||||||
|
- 14 Jun 2010 By release 0.5.8.pl00 of libisoburn, xorriso becomes a public C
|
||||||
|
language API of libisoburn. The emulations of mkisofs and cdrecord have
|
||||||
|
been enhanced.
|
||||||
|
|
||||||
|
- Tue Jun 29 2010 Version 0.6.34 of libisofs provides new features about
|
||||||
|
hiding file names from directory trees.
|
||||||
|
|
||||||
|
- Wed Jun 30 2010 libburn-0.8.4 removes some restrictions on operating
|
||||||
|
systems other than Linux and FreeBSD.
|
||||||
|
|
||||||
|
- Fri Jul 02 2010 Release 0.6.0.pl00 of libisoburn adds more options to the
|
||||||
|
mkisofs emulation of xorriso. It also fixes minor bugs and shortcommings.
|
||||||
|
|
||||||
|
- Wed Sep 15 2010 Version 0.6.36 of libisofs can produce ISO images which
|
||||||
|
bear a partiton 1 with non-zero start address. They can be mounted from
|
||||||
|
USB stick via the main device file (e.g. /dev/sdb) as well as via the
|
||||||
|
partition device file (e.g. /dev/sdb1).
|
||||||
|
|
||||||
|
- Fri Sep 17 2010 libburn-0.8.6 lifts the test reservation on DVD-R DL media.
|
||||||
|
|
||||||
|
- Sat Sep 18 2010 Release 0.6.2.pl00 of libisoburn introduces a partition
|
||||||
|
with non-zero offset for ISO 9660 images on USB sticks, improves mkisofs
|
||||||
|
emulation, and fixes a regression which existed since version 0.4.2.
|
||||||
|
|
||||||
|
- Wed Oct 20 2010 libburn-0.8.8 can report the used amount of BD spare blocks.
|
||||||
|
|
||||||
|
- Sat Oct 23 2010 Version 0.6.38 of libisofs can use libjte to produce jigdo
|
||||||
|
files along with the ISO image. Further filesystem images may be appended
|
||||||
|
as MBR partitions 1 to 4. The capability was added to produce boot blocks
|
||||||
|
for computers with MIPS CPU.
|
||||||
|
|
||||||
|
- Tue Oct 26 2010 Release 0.6.4.pl00 of libisoburn and xorriso makes use of
|
||||||
|
the new libisofs capabilities.
|
||||||
|
|
||||||
|
- Wed Dec 08 2010 libburn-0.9.0 fixes a regression with SCSI command logging.
|
||||||
|
|
||||||
|
- Fri Dec 10 2010 Version 0.6.40 of libisofs makes the prediction of the
|
||||||
|
emerging image size less expensive and is able to make images bootable
|
||||||
|
for SUN SPARC systems.
|
||||||
|
|
||||||
|
- Sun Dec 12 2010 Release 0.6.6.pl00 of libisoburn and xorriso can read ISO
|
||||||
|
images which were copied to a different start address than they were prepared
|
||||||
|
for.
|
||||||
|
|
||||||
|
- Mon Jan 17 2011 we go for release 1.0.0. This does not indicate a
|
||||||
|
technological overhaul but shall emphasize the maturity of the software.
|
||||||
|
libisofs-1.0.0 fixes a bug about the length of ECMA-119 directory names and
|
||||||
|
is ready to store untranslated ECMA-119 names (violating the specs).
|
||||||
|
libburn-1.0.0.pl00 is now willing to create stdio-drive files with
|
||||||
|
rw-permissions for all, if umask really asks for it. cdrskin now refuses
|
||||||
|
to burn if the foreseeable size exceeds media capacity
|
||||||
|
libisoburn-1.0.0.pl00 can now create an ISO 9660:1999 directory tree,
|
||||||
|
improved the emulation fidelity of command -as mkisofs, lowered the default
|
||||||
|
abort threshold for xorriso batch mode, and increased that threshold for
|
||||||
|
xorriso dialog mode.
|
||||||
|
|
||||||
|
- Wed Feb 23 2011 release 1.0.2:
|
||||||
|
libisofs fixes several bugs and introduces the capability to copy files
|
||||||
|
inside the ISO filesystem.
|
||||||
|
libburn removed a compilation obstacle on Solaris 9 and improved recognition
|
||||||
|
of stdio pseudo-drives.
|
||||||
|
libisoburn and xorriso fix bugs and make use of the new libisofs capability.
|
||||||
|
xorriso improves its mkisofs emulation.
|
||||||
|
|
||||||
|
- Thu Mar 10 2011 release 1.0.4:
|
||||||
|
Several bugs were fixed in the libraries and in the mkisofs emulation of
|
||||||
|
xorriso. This emulation xorrisofs has now an own man page and info document.
|
||||||
|
|
||||||
|
- Sat Apr 09 2011 release 1.0.6:
|
||||||
|
libburn refined its representation of emulated drives. The size alignment
|
||||||
|
of DVD DAO is now 2 kB rather than 32 kB. libisofs produces Joliet names of
|
||||||
|
up to 103 characters. xorriso fixes two bugs and makes use of the library
|
||||||
|
improvements.
|
||||||
|
|
||||||
|
- Thu Apr 14 2011 release libisoburn-1.0.8:
|
||||||
|
A bug in the mkisofs emulation of xorriso could cause options to be ignored.
|
||||||
|
The problem was freshly introduced with libisoburn-1.0.6.
|
||||||
|
|
||||||
|
- Fri May 13 2011 release libisofs-1.0.8:
|
||||||
|
Fixes a few rarely occurring bugs that have been found during the last month.
|
||||||
|
|
||||||
|
- Sat Jun 18 2011 release 1.1.0:
|
||||||
|
The consumption of stack memory was reduced. Statical program analysis found
|
||||||
|
some rarely occurring memory leaks. Several small bugs were fixed.
|
||||||
|
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
|
||||||
|
|
||||||
|
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
|
||||||
|
libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris, but not on
|
||||||
|
other X/Open compliant systems.
|
||||||
|
|
||||||
|
- Fri Jul 08 2011 release libisofs-1.1.2 and libisoburn-1.1.2:
|
||||||
|
A severe regression was fixed in libisoburn and xorriso, which was introduced
|
||||||
|
with version 1.0.6. It caused ISO 9660 images to be unreadable if they were
|
||||||
|
written to a write-only random-access file. E.g. by: xorrisofs ... >image.iso
|
||||||
|
|
||||||
|
- Mon Aug 08 2011 release 1.1.4:
|
||||||
|
Several bugs were fixed in libburn. The most severe of them prevented xorriso
|
||||||
|
on some drives from burning mountable ISO 9660 images to CD media.
|
||||||
|
New means to list drives by their udev symbolic links help to deal with
|
||||||
|
the non-persistent drive addresses on modern GNU/Linux.
|
||||||
|
|
||||||
|
- Tue Sep 27 2011 release 1.1.6:
|
||||||
|
libisoburn now comes with a test suite. See releng/README. Bugs were fixed
|
||||||
|
in several rarely used features. Processing of ACL and extattr was enabled
|
||||||
|
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
|
||||||
|
|
||||||
|
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
|
||||||
|
libburn avoids to close and open drive device files while operating on them.
|
||||||
|
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
|
||||||
|
were prepared to operate on qemu virtio-blk-pci devices.
|
||||||
|
|
||||||
|
- Sat Jan 28 2012 release 1.2.0:
|
||||||
|
libburn has learned to read and write CD-TEXT with CD SAO audio sessions.
|
||||||
|
It can now read CDRWIN .cue files which define pure audio or pure data
|
||||||
|
sessions. libisofs and libisoburn improved timestamp handling. Several
|
||||||
|
minor bugs were fixed.
|
||||||
|
|
||||||
|
- Mon Apr 02 2012 release 1.2.2:
|
||||||
|
The handling of intentional deviations from ECMA-119 specifications has
|
||||||
|
been improved in libisofs. libisoburn and xorriso now make use of these
|
||||||
|
improvements. Some rarely occurring bugs have been fixed.
|
||||||
|
|
||||||
|
- Fri Jul 20 2012 release 1.2.4:
|
||||||
|
libburn and libisofs got some rarely occurring bugs fixed. libisofs learned
|
||||||
|
to produce HFS+ metadata and Apple Partition Map. The capabilities of
|
||||||
|
isohybrid options --efi and --mac have been implemented (GPT and APM).
|
||||||
|
|
||||||
|
- Tue Jan 08 2013 release 1.2.6:
|
||||||
|
Small improvements were made in libburn. Minor bugs were fixed in the
|
||||||
|
libraries. xorriso improved its capabilities to serve the needs of frontend
|
||||||
|
programs. A proof of concept for a GUI frontend has been implemented:
|
||||||
|
xorriso-tcltk
|
||||||
|
|
||||||
|
- Mon Mar 18 2013 release 1.2.8:
|
||||||
|
Some rarely occurring bugs were fixed in libisofs and libburn. libburn's
|
||||||
|
handling of incomplete sessions has been improved. xorriso's mkisofs
|
||||||
|
emulation learned to set El Torito section id strings.
|
||||||
|
|
||||||
|
- Fri May 17 2013 release 1.3.0:
|
||||||
|
Several bugs were fixed in the libraries and in xorriso. The recently
|
||||||
|
introduced new boot preparation capabilities have been tested. New
|
||||||
|
boot preparation options for GRUB2 were added.
|
||||||
|
|
||||||
|
- Fri May 31 2013 patch release libburn-1.3.0.pl01:
|
||||||
|
cdrskin -msinfo on DVD and BD reported as old session start the same
|
||||||
|
number as the next writable address.
|
||||||
|
Regression introduced by version 1.2.8.
|
||||||
|
|
||||||
|
- Fri Aug 07 2013 release 1.3.2:
|
||||||
|
cdrskin has acquired the capability to copy audio tracks to .wav files.
|
||||||
|
It can extract CD-TEXT in a form that is readable for humans and for
|
||||||
|
cdrskin itself. Several small bugs were fixed in xorriso. Its capabilities
|
||||||
|
to serve frontend programs in dialog mode have been improved.
|
||||||
|
|
||||||
|
- Thu Dec 12 2013 release 1.3.4:
|
||||||
|
A long standing hidden bug was fixed, which affected inspection of
|
||||||
|
unformatted DVD+RW.
|
||||||
|
xorriso now by default puts EL Torito boot images to low block addresses.
|
||||||
|
It can report and set read speeds. Several rarely occurring bugs were fixed.
|
||||||
|
|
||||||
|
- Tue Mar 04 2014 release 1.3.6:
|
||||||
|
libburn learned to operate optical drives and media on NetBSD. libisofs got
|
||||||
|
a bug fix about HFS+ and enhancements about character set conversion.
|
||||||
|
Minor bugs were fixed in libisoburn. xorriso can now find files with names
|
||||||
|
which cannot be represented unchanged in ECMA-119, Joliet, or HFS+.
|
||||||
|
|
||||||
|
- Sat Jun 28 2014 release 1.3.8:
|
||||||
|
libburn got several bugs fixed. libisofs offers new API calls for inspection
|
||||||
|
of boot sectors in ISO 9660 filesystems. xorriso improved its support for
|
||||||
|
NetBSD, offers new features with command -find, and a command to extract
|
||||||
|
ISO 9660 file content onto standard output or into filter processes.
|
||||||
|
|
||||||
|
- Sun May 17 2015 release 1.4.0:
|
||||||
|
This release is mainly about bug fixes and a new feature of xorriso to
|
||||||
|
propose commands or as_mkisofs options which can reproduce the boot
|
||||||
|
equipment of the loaded ISO filesystem.
|
||||||
|
|
||||||
|
- Sat Nov 28 2015 release 1.4.2:
|
||||||
|
libburn got some bugs fixed and learned to inquire the drive serial number.
|
||||||
|
libisofs now sorts data file content by ECMA-119 file names for better
|
||||||
|
reproducability of ISO content. Rock Ridge filenames may be restricted to
|
||||||
|
lengths between 64 and 255 bytes. If needed, a qualified truncation happens.
|
||||||
|
xorriso now can replay boot settings when modifying ISO filesystems.
|
||||||
|
In order to avoid clogging of concurrent Linux SG_IO, xorriso got command
|
||||||
|
-modesty_on_drive to enable an old workaround from IDE master/slave days.
|
||||||
|
The source code underwent a scan by Coverity. About 150 code changes
|
||||||
|
resulted, but no easy-to-trigger bugs were found.
|
||||||
|
|
||||||
|
- Fri Jan 29 2016 patch release libburn-1.4.2.pl01:
|
||||||
|
cdrskin did not work with "-" (stdin) as input.
|
||||||
|
Regression introduced by version 1.4.2.
|
||||||
|
|
||||||
|
- Fri Jul 01 2016 release 1.4.4:
|
||||||
|
The capability to use Linux /dev/sg was revived in order to circumvent the
|
||||||
|
sr_mutex lock which hampers concurrent use of optical drives via SG_IO.
|
||||||
|
libisofs now can use appended partitions by El Torito, avoiding the need
|
||||||
|
for duplicate EFI System Partition images.
|
||||||
|
Several bugs have been fixed.
|
||||||
|
|
||||||
|
- Fri Sep 16 2016 release 1.4.6:
|
||||||
|
libburn now operates optical drives on OpenBSD. libisofs makes pseudo-random
|
||||||
|
id generation reproducible by relating it to the volume date.
|
||||||
|
xorriso interprets environment variable SOURCE_DATE_EPOCH of
|
||||||
|
reproducible-builds.org to prepare a default setting which leads to identical
|
||||||
|
ISO images on identical input and identical constant options.
|
||||||
|
Several moderately embarrassing bugs have been fixed.
|
||||||
|
|
||||||
|
- Tue Sep 12 2017 release 1.4.8:
|
||||||
|
libburn now refuses to write to SRM+POW formatted BD-R, because it would
|
||||||
|
spoil them. libisofs got several bugs fixed and offers new API calls to
|
||||||
|
support new xorriso features. libisoburn and xorriso offer more detail
|
||||||
|
control with particular boot sector types. New bugs and a regression from
|
||||||
|
version 1.4.4 were fixed.
|
||||||
|
|
||||||
|
- Sat Sep 15 2018 release 1.5.0
|
||||||
|
libisofs now can record all xattr namespaces, user defined padding was moved
|
||||||
|
after appended partitions. libisoburn and xorriso make use of the new xattr
|
||||||
|
capability of libisofs.
|
||||||
|
All three libraries got some rarely triggered bugs fixed.
|
||||||
|
|
||||||
|
- Sat Oct 26 2019 release 1.5.2
|
||||||
|
The libraries are now ready for building out-of-source. libisofs got minor
|
||||||
|
API extensions. libburn got a bug fixed which spoiled burn runs on
|
||||||
|
some MATSHITA laptop drives. It is now able to list all features which
|
||||||
|
the drive announces. xorriso can now set GPT type GUIDs with appended
|
||||||
|
partitions and the ISO partition.
|
||||||
|
All three libraries got some rarely triggered bugs fixed.
|
||||||
|
|
||||||
|
- Mon Nov 25 2019 patch release 1.5.2.pl01
|
||||||
|
cdrskin did not properly burn multiple tracks. Track 1 was slow and burning
|
||||||
|
stalled before track 2. Regression introduced by 1.5.0.
|
||||||
|
|
||||||
|
- Sat Jan 30 2021 , 07 Feb 2021 release 1.5.4
|
||||||
|
libburn offers new opportunities to influence drive speed.
|
||||||
|
libisofs got a bug fixed which under medium rare circumstances spoiled
|
||||||
|
zisofs production. libisofs switched to usage of libjte-2.0.0. Further it
|
||||||
|
can now write and read zisofs2 format, which enables compression of files
|
||||||
|
>= 4 GiB. When reading Joliet file trees, the names get stripped of their
|
||||||
|
version numbers by default. After loading metadata, libisofs can now tell
|
||||||
|
which directory tree was loaded and whether Rock Ridge is used.
|
||||||
|
libisoburn and xorriso make use of these new features.
|
||||||
|
xorriso can put out the data stream of -check_media to standard output. It
|
||||||
|
can restore files with many zero bytes as sparse files and it is able to
|
||||||
|
extract recognized boot images into data files on hard disk.
|
||||||
|
A new script xorriso-dd-target helps to put an ISO image onto an USB stick
|
||||||
|
without endangering valuable hard disk content.
|
||||||
|
Several rarely triggered bugs were fixed.
|
||||||
|
|
||||||
|
- Wed Jun 07 2023 release 1.5.6
|
||||||
|
libburn can overburn CD media, i.e. write more data than the drive announced
|
||||||
|
as medium capacity.
|
||||||
|
libisofs can assess many of the features which were in effect when a
|
||||||
|
given ISO 9660 filesystem was created. A safety limit was introduced not
|
||||||
|
to exceed the limit of Linux which is imposed on the number of SUSP CE
|
||||||
|
entries which is good for about 60 KiB of AAIP data. Some rarely occuring
|
||||||
|
bugs were fixed in libisofs.
|
||||||
|
libisoburn and xorriso expose the new library features to the user and
|
||||||
|
got some minor improvements. Many minor bugs were fixed.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
the Free Software Foundation. To be exact: version 2 of that License.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
@ -436,16 +843,16 @@ other copyrighted code has been replaced by ours and by copyright-free
|
||||||
contributions of our friends:
|
contributions of our friends:
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
We, the copyright holders, agree on the interpretation that dynamical linking
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
of our libraries constitutes "use of" and not "derivation from" our work in
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
the sense of GPL, provided those libraries are compiled from our unaltered
|
||||||
those libraries are compiled from our unaltered code.
|
code or from altered code published under GPL.
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
So we will not raise legal protest if you link our libraries dynamically with
|
||||||
which are not under GPL. You may distribute our libraries and
|
applications which are not under GPL, or if you distribute our libraries
|
||||||
application tools in binary form, if you fulfill the usual
|
and application tools in binary form, as long as you fulfill the usual
|
||||||
condition of GPL to offer a copy of the source code -altered
|
condition of GPL to offer a copy of their source code -altered or unaltered-
|
||||||
or unaltered- under GPL.
|
under GPL.
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
We ask you politely to use our work in open source spirit
|
||||||
and with the due reference to the entire open source community.
|
and with the due reference to the entire open source community.
|
||||||
|
@ -462,4 +869,5 @@ means to qualify for GPL.
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
For now we are firmly committed to maintain one single license: GPL.
|
||||||
|
|
||||||
signed: Mario Danic, Thomas Schmitt
|
signed: Mario Danic, Thomas Schmitt
|
||||||
|
Agreement joined later by: Vreixo Formoso
|
||||||
|
|
||||||
|
|
164
acinclude.m4
164
acinclude.m4
|
@ -1,3 +1,14 @@
|
||||||
|
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||||
|
[
|
||||||
|
case $target_os in
|
||||||
|
freebsd* | netbsd*)
|
||||||
|
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||||
|
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
AC_DEFUN([TARGET_SHIZZLE],
|
AC_DEFUN([TARGET_SHIZZLE],
|
||||||
[
|
[
|
||||||
ARCH=""
|
ARCH=""
|
||||||
|
@ -5,28 +16,61 @@ AC_DEFUN([TARGET_SHIZZLE],
|
||||||
|
|
||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
|
libburn_check_libcam=
|
||||||
|
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||||
|
|
||||||
case $target in
|
case $target in
|
||||||
*-*-linux*)
|
*-*-linux*)
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
|
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
*-*-freebsd*)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
||||||
;;
|
;;
|
||||||
|
*-kfreebsd*-gnu*)
|
||||||
|
ARCH=freebsd
|
||||||
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
|
libburn_check_libcam=yes
|
||||||
|
;;
|
||||||
|
*-solaris*)
|
||||||
|
ARCH=solaris
|
||||||
|
LIBBURN_ARCH_LIBS=-lvolmgt
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
ARCH=
|
ARCH=
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_MSG_RESULT([$ARCH])
|
AC_MSG_RESULT([$ARCH])
|
||||||
|
|
||||||
|
if test x"$libburn_check_libcam" = xyes
|
||||||
|
then
|
||||||
|
LIBBURNIA_CHECK_LIBCAM
|
||||||
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl LIBBURN_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project
|
||||||
|
dnl It tests whether -Wl,--version-script=... works with the compiler
|
||||||
|
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
|
||||||
|
[
|
||||||
|
libburnia_save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/libburn/libburn.ver"
|
||||||
|
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||||
|
[vers_libs_test="yes"], [vers_libs_test="no"])
|
||||||
|
if test x$vers_libs_test = xyes
|
||||||
|
then
|
||||||
|
LIBLDFLAGS="-Wl,--version-script=$srcdir/libburn/libburn.ver"
|
||||||
|
fi
|
||||||
|
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||||
|
AC_SUBST(LIBLDFLAGS)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||||
dnl
|
dnl
|
||||||
|
@ -77,3 +121,121 @@ dnl For debugging only
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl LIBBURNIA_CHECK_ARCH_LIBS is by Thomas Schmitt, libburnia project
|
||||||
|
dnl It tests whether the OS dependent libraries are available.
|
||||||
|
dnl With libisoburn they are needed only for the case that indirect linking
|
||||||
|
dnl does not work. So it is worth a try to omit them.
|
||||||
|
dnl $1 = "mandatory" or "optional" define the action if test linking fails.
|
||||||
|
dnl "silent" is like "optional" but without message.
|
||||||
|
AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS],
|
||||||
|
[
|
||||||
|
libburnia_save_LIBS="$LIBS"
|
||||||
|
if test "x$LIBBURN_ARCH_LIBS" = x
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
LIBS="$LIBS $LIBBURN_ARCH_LIBS"
|
||||||
|
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||||
|
[archlibs_test="yes"], [archlibs_test="no"])
|
||||||
|
LIBS="$libburnia_save_LIBS"
|
||||||
|
if test x$archlibs_test = xno
|
||||||
|
then
|
||||||
|
if test x"$1" = xmandatory
|
||||||
|
then
|
||||||
|
echo >&2
|
||||||
|
echo "FATAL: Test linking with mandatory library options failed: $LIBBURN_ARCH_LIBS" >&2
|
||||||
|
echo >&2
|
||||||
|
(exit 1); exit 1;
|
||||||
|
else
|
||||||
|
if test x"$1" = xoptional
|
||||||
|
then
|
||||||
|
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
|
||||||
|
fi
|
||||||
|
LIBBURN_ARCH_LIBS=""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if test x"$1" = xsilent
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "enabled linking with $LIBBURN_ARCH_LIBS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl LIBBURNIA_CHECK_LINUX_SCSI is by Thomas Schmitt, libburnia project
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([LIBBURNIA_CHECK_LINUX_SCSI],
|
||||||
|
[
|
||||||
|
dnl Check whether it is a Linux without scsi/scsi.h
|
||||||
|
libburn_scsi_disabled=
|
||||||
|
if test x"$ARCH" = xlinux
|
||||||
|
then
|
||||||
|
AH_TEMPLATE([Libburn_use_sg_dummY],
|
||||||
|
[Define to compile without OS specific SCSI features])
|
||||||
|
AC_MSG_CHECKING([for missing scsi/scsi.h on Linux])
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#ifdef __linux
|
||||||
|
#include <scsi/scsi.h>
|
||||||
|
#endif
|
||||||
|
],
|
||||||
|
[;],
|
||||||
|
[AC_MSG_RESULT([no])],
|
||||||
|
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
||||||
|
libburn_scsi_disabled=yes
|
||||||
|
AC_MSG_RESULT([yes])]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if test x"$libburn_scsi_disabled" = xyes
|
||||||
|
then
|
||||||
|
echo "disabled operation of optical drives via SCSI"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl LIBBURNIA_CHECK_LIBCAM is by Thomas Schmitt, libburnia project
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([LIBBURNIA_CHECK_LIBCAM],
|
||||||
|
[
|
||||||
|
dnl Check whether libcam is requested for FreeBSD kernel but missing
|
||||||
|
libburn_scsi_disabled=
|
||||||
|
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
|
||||||
|
then
|
||||||
|
AH_TEMPLATE([Libburn_use_sg_dummY],
|
||||||
|
[Define to compile without OS specific SCSI features])
|
||||||
|
AC_MSG_CHECKING([for missing libcam for SCSI on FreeBSD kernel])
|
||||||
|
dnl If libcam is not available, LIBBURN_ARCH_LIBS will be made empty
|
||||||
|
LIBBURNIA_CHECK_ARCH_LIBS(silent)
|
||||||
|
if test x"$LIBBURN_ARCH_LIBS" = x
|
||||||
|
then
|
||||||
|
AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
||||||
|
libburn_scsi_disabled=yes
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
|
||||||
|
then
|
||||||
|
AC_MSG_CHECKING([for missing libcam headers])
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <camlib.h>
|
||||||
|
#include <cam/scsi/scsi_message.h>
|
||||||
|
#include <cam/scsi/scsi_pass.h>
|
||||||
|
],
|
||||||
|
[;],
|
||||||
|
[AC_MSG_RESULT([no])],
|
||||||
|
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
||||||
|
libburn_scsi_disabled=yes
|
||||||
|
AC_MSG_RESULT([yes])]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
if test x"$libburn_scsi_disabled" = xyes
|
||||||
|
then
|
||||||
|
echo "disabled operation of optical drives via SCSI"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -x
|
#!/bin/sh -x
|
||||||
|
|
||||||
aclocal
|
aclocal -I .
|
||||||
libtoolize --copy --force
|
libtoolize --copy --force
|
||||||
autoconf
|
autoconf
|
||||||
|
|
||||||
|
|
223
cdrskin/README
223
cdrskin/README
|
@ -4,17 +4,19 @@
|
||||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Integrated sub project of libburnia-project.org but also published via:
|
Integrated sub project of libburnia-project.org but also published via:
|
||||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
http://scdbackup.sourceforge.net/cdrskin-0.6.9.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-1.5.7.tar.gz
|
||||||
|
|
||||||
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
|
Copyright (C) 2006-2023 Thomas Schmitt, provided under GPL version 2 or later.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
||||||
most of the libburn features from the command line.
|
most of the libburn features from the command line.
|
||||||
|
|
||||||
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD,
|
||||||
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
on OpenSolaris, and on NetBSD.
|
||||||
|
IDE drives under Linux 2.4 need kernel module ide-scsi.
|
||||||
|
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
||||||
On other X/Open compliant systems there will only be emulated drives, but no
|
On other X/Open compliant systems there will only be emulated drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
|
||||||
|
@ -24,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
|
||||||
|
|
||||||
Compilation, First Glimpse, Installation
|
Compilation, First Glimpse, Installation
|
||||||
|
|
||||||
Obtain cdrskin-0.6.9.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-1.5.7.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-0.6.9.tar.gz
|
tar xzf cdrskin-1.5.7.tar.gz
|
||||||
cd cdrskin-0.6.9
|
cd cdrskin-1.5.7
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
|
@ -35,8 +37,7 @@ Within that directory execute:
|
||||||
make
|
make
|
||||||
|
|
||||||
This will already produce a cdrskin binary. But it will be necessary to
|
This will already produce a cdrskin binary. But it will be necessary to
|
||||||
install libburn in order to use this binary. Installation of libburn is
|
install libburn in order to use this binary.
|
||||||
beyond the scope of cdrskin. For this, see included libburn docs.
|
|
||||||
|
|
||||||
In order to surely get a standalone binary, execute
|
In order to surely get a standalone binary, execute
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ It is not necessary for the standalone cdrskin binary to have libburn
|
||||||
installed, since it incorporates the necessary libburn parts at compile time.
|
installed, since it incorporates the necessary libburn parts at compile time.
|
||||||
It will not collide with an installed version of libburn either.
|
It will not collide with an installed version of libburn either.
|
||||||
But libpthread must be installed on the system and glibc has to match. (See
|
But libpthread must be installed on the system and glibc has to match. (See
|
||||||
below for a way to create a statically linked binary.)
|
below for a way to create a totally static linked binary.)
|
||||||
|
|
||||||
To install the man page, you may do: echo $MANPATH and choose one of the
|
To install the man page, you may do: echo $MANPATH and choose one of the
|
||||||
listed directories to copy the man-page under its ./man1 directory. Like:
|
listed directories to copy the man-page under its ./man1 directory. Like:
|
||||||
|
@ -103,17 +104,26 @@ The output of cdrskin --devices might look like
|
||||||
0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
|
0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
|
||||||
1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
||||||
|
|
||||||
So full and insecure enabling of both for everybody would look like
|
On Linux, full and insecure enabling of both for everybody would look like
|
||||||
|
chmod a+rw /dev/sr0 /dev/hda
|
||||||
chmod a+rw /dev/sr0 /dev/sr1
|
|
||||||
|
|
||||||
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
||||||
|
|
||||||
|
On FreeBSD, device rw-permissions are to be set in /etc/devfs.rules.
|
||||||
|
On Solaris, pfexec privileges may be restricted to "basic,sys_devices".
|
||||||
|
On NetBSD, rw-permission may be granted by chmod a+rw /dev/rcd?d.
|
||||||
|
See below "System Dependend Drive Permission Examples".
|
||||||
|
|
||||||
I strongly discourage to run cdrskin with setuid root or via sudo !
|
I strongly discourage to run cdrskin with setuid root or via sudo !
|
||||||
It is not checked for the necessary degree of hacker safety.
|
It is not checked for the necessary degree of hacker safety.
|
||||||
|
Better consider to grant the necessary permissions to group "floppy"
|
||||||
|
and to add users to it.
|
||||||
|
|
||||||
|
|
||||||
|
A behavioral conflict is known between any burn software and demons like hald
|
||||||
|
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
|
||||||
|
You may have to keep your hald away from the drive. See for example
|
||||||
|
http://www.freebsd.org/gnome/docs/halfaq.html
|
||||||
|
|
||||||
Consider to put all authorized users into group "floppy", to chgrp the
|
|
||||||
device file to that group and to disallow w-access to others.
|
|
||||||
|
|
||||||
Helpful with Linux kernel 2.4 is a special SCSI feature:
|
Helpful with Linux kernel 2.4 is a special SCSI feature:
|
||||||
It is possible to address a scsi(-emulated) drive via associated device files
|
It is possible to address a scsi(-emulated) drive via associated device files
|
||||||
|
@ -122,11 +132,6 @@ as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is
|
||||||
compatible with generic read programs like dd and with write program growisofs.
|
compatible with generic read programs like dd and with write program growisofs.
|
||||||
For finding /dev/sg1 from /dev/sr0, the program needs rw-access to both files.
|
For finding /dev/sg1 from /dev/sr0, the program needs rw-access to both files.
|
||||||
|
|
||||||
A behavioral conflict is known between any burn software and demons like hald
|
|
||||||
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
|
|
||||||
You may have to keep your hald away from the drive. See for example
|
|
||||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
|
||||||
|
|
||||||
|
|
||||||
Usage examples
|
Usage examples
|
||||||
|
|
||||||
|
@ -146,7 +151,7 @@ Obtain some info about the drive
|
||||||
cdrskin dev=0,1,0 -checkdrive
|
cdrskin dev=0,1,0 -checkdrive
|
||||||
|
|
||||||
Obtain some info about the drive and the inserted media
|
Obtain some info about the drive and the inserted media
|
||||||
cdrskin dev=0,1,0 -atip -v
|
cdrskin dev=0,1,0 -atip -v -minfo
|
||||||
|
|
||||||
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
||||||
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||||
|
@ -187,6 +192,11 @@ See below "Audio CD" for specifications.
|
||||||
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
|
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
|
||||||
-audio -swab track0[1-5].cd /path/to/track6.wav
|
-audio -swab track0[1-5].cd /path/to/track6.wav
|
||||||
|
|
||||||
|
Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd:
|
||||||
|
mkdir /home/me/my_cd
|
||||||
|
cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \
|
||||||
|
cdtext_to_v07t=/home/me/my_cd/cdtext.v07t
|
||||||
|
|
||||||
|
|
||||||
Restrictions
|
Restrictions
|
||||||
|
|
||||||
|
@ -196,7 +206,7 @@ See output of command
|
||||||
If you have use cases for them, please report your wishes and expectations.
|
If you have use cases for them, please report your wishes and expectations.
|
||||||
|
|
||||||
On the other hand, the capability of multi-session and of writing streams
|
On the other hand, the capability of multi-session and of writing streams
|
||||||
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
|
of unpredicted length surpass the current DVD capabilities of cdrecord.
|
||||||
|
|
||||||
|
|
||||||
Inspiration and Standard
|
Inspiration and Standard
|
||||||
|
@ -306,10 +316,11 @@ Add-on session (equivalent to growisofs -M):
|
||||||
cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... -
|
cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... -
|
||||||
|
|
||||||
|
|
||||||
DVD-RW and DVD-R
|
DVD-RW , DVD-R , DVD-R DL
|
||||||
|
|
||||||
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
|
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
|
||||||
"Sequential Recording". DVD-R are always in sequential state.
|
"Sequential Recording". DVD-R are always in sequential state. DVD-R DL are
|
||||||
|
always sequential and incapable of multi-session.
|
||||||
|
|
||||||
"Sequential" is the state of unused media and of media previously blanked
|
"Sequential" is the state of unused media and of media previously blanked
|
||||||
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
|
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
|
||||||
|
@ -346,7 +357,7 @@ but leaves the media in "intermediate" state. In the first session of writing
|
||||||
one may only write sequentially to such a DVD. After that, it gets random
|
one may only write sequentially to such a DVD. After that, it gets random
|
||||||
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
|
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
|
||||||
|
|
||||||
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
|
blank=format_overwrite_full uses preferably "Full Format" (type 00h).
|
||||||
This formatting lasts as long as writing a full DVD. It includes writing of
|
This formatting lasts as long as writing a full DVD. It includes writing of
|
||||||
lead-out which is said to be good for DVD ROM compatibility.
|
lead-out which is said to be good for DVD ROM compatibility.
|
||||||
|
|
||||||
|
@ -398,6 +409,29 @@ drive. See man page section FILES for a way to lift that ban.
|
||||||
|
|
||||||
Special compilation variations
|
Special compilation variations
|
||||||
|
|
||||||
|
All following options of ./configure and cdrskin/compile_cdrskin.sh are
|
||||||
|
combinable. After runs of ./configure do as next:
|
||||||
|
make clean ; make
|
||||||
|
|
||||||
|
In some situations Linux may deliver a better write performance to drives if
|
||||||
|
the track input is read with O_DIRECT (see man 2 open). The API call
|
||||||
|
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
||||||
|
can be told to use this peculiar read mode by:
|
||||||
|
--enable-track-src-odirect
|
||||||
|
|
||||||
|
But often cdrskin option dvd_obs=64k will yield even better performance in
|
||||||
|
such a situation. 64k can be made default at compile time by
|
||||||
|
cdrskin/compile_cdrskin.sh -dvd_obs_64k
|
||||||
|
It can also be enabled at configure time by
|
||||||
|
./configure ... --enable-dvd-obs-64k ...
|
||||||
|
|
||||||
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
|
You may install it and re-run libburn's ./configure with option
|
||||||
|
--enable-libcdio
|
||||||
|
Add option
|
||||||
|
-use_libcdio
|
||||||
|
to your run of cdrskin/compile_cdrskin.sh .
|
||||||
|
|
||||||
You may get a (super fat) statically linked binary by :
|
You may get a (super fat) statically linked binary by :
|
||||||
cdrskin/compile_cdrskin.sh -static
|
cdrskin/compile_cdrskin.sh -static
|
||||||
if your system supports static linking, at all. This will not help with kernels
|
if your system supports static linking, at all. This will not help with kernels
|
||||||
|
@ -414,6 +448,106 @@ will not have a fifo buffer, and will not be able to put out help texts or
|
||||||
debugging messages.
|
debugging messages.
|
||||||
|
|
||||||
|
|
||||||
|
Linux only:
|
||||||
|
|
||||||
|
libburn tries to avoid a collision with udev's drive examination by waiting
|
||||||
|
0.1 seconds before opening the device file for a longer time, after udev
|
||||||
|
might have been alarmed by drive scanning activities.
|
||||||
|
The waiting time can be set at ./configure time with microsecond granularity.
|
||||||
|
E.g. 2 seconds:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
|
||||||
|
./configure ...options...
|
||||||
|
Waiting can be disabled by zero waiting time:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
|
||||||
|
Alternatively, libburn can try to be nice by opening the device file,
|
||||||
|
closing it immediately, waiting, and only then opening it for real:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
System Dependend Drive Permission Examples
|
||||||
|
|
||||||
|
Accessing the optical drives requires privileges which usually are granted
|
||||||
|
only to the superuser. Linux, FreeBSD, Solaris, NetBSD, offer quite different
|
||||||
|
approaches for avoiding the need for unrestricted privileges.
|
||||||
|
|
||||||
|
First check whether some friendly system setting already allows you to
|
||||||
|
access the drives as normal user:
|
||||||
|
cdrskin --devices
|
||||||
|
Those drives of which you see address and type strings are already usable.
|
||||||
|
|
||||||
|
If there remain drives invisible which the superuser can see by the same
|
||||||
|
command, then the following examples might help:
|
||||||
|
|
||||||
|
---------------
|
||||||
|
On all systems:
|
||||||
|
---------------
|
||||||
|
Add the authorized users of CD drives to group "floppy" in /etc/group.
|
||||||
|
If missing: create this group.
|
||||||
|
Changes to /etc/group often only affect new login sessions. So log out and in
|
||||||
|
before making the first tests.
|
||||||
|
|
||||||
|
---------
|
||||||
|
On Linux:
|
||||||
|
---------
|
||||||
|
Allow rw-access to the drives
|
||||||
|
chgrp floppy /dev/sr0 /dev/sr1
|
||||||
|
chmod g+rw /dev/sr0 /dev/sr1
|
||||||
|
It might be necessary to perform chgrp and chmod after each reboot or to
|
||||||
|
edit distro dependent device configuration files for permanent settings.
|
||||||
|
|
||||||
|
-----------
|
||||||
|
On FreeBSD:
|
||||||
|
-----------
|
||||||
|
Edit /etc/devfs.rules and make sure to have these lines
|
||||||
|
[localrules=10]
|
||||||
|
add path 'acd*' mode 0664 group floppy
|
||||||
|
add path 'cd*' mode 0664 group floppy
|
||||||
|
add path 'pass*' mode 0664 group floppy
|
||||||
|
add path 'xpt*' mode 0664 group floppy
|
||||||
|
[localrules=5]
|
||||||
|
add path 'pass*' mode 0664 group floppy
|
||||||
|
add path 'cd*' mode 0664 group floppy
|
||||||
|
add path 'xpt*' mode 0664 group floppy
|
||||||
|
add path 'acd*' mode 0664 group floppy
|
||||||
|
|
||||||
|
Edit /etc/rc.conf and add the following line if missing
|
||||||
|
devfs_system_ruleset="localrules"
|
||||||
|
|
||||||
|
This gets into effect by reboot or by command
|
||||||
|
/etc/rc.d/devfs start
|
||||||
|
|
||||||
|
-----------
|
||||||
|
On Solaris:
|
||||||
|
-----------
|
||||||
|
Run cdrskin by
|
||||||
|
pfexec cdrskin ...arguments...
|
||||||
|
|
||||||
|
The following settings will make pfexec keep original UID and EUID and prevent
|
||||||
|
most superuser powers. Be aware that you still can manipulate all device files
|
||||||
|
if you have the file permissions for that.
|
||||||
|
Full root privileges for cdrskin can then be acquired only by command su.
|
||||||
|
|
||||||
|
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
|
||||||
|
lines:
|
||||||
|
Media Backup:solaris:cmd:::/usr/local/bin/cdrskin:privs=basic,sys_devices
|
||||||
|
Edit /etc/user_attr and add profile "Media Backup" to the user's line:
|
||||||
|
thomas::::profiles=Media Backup,Primary Administrator;roles=root
|
||||||
|
See also man privileges, man exec_attr, man user_attr.
|
||||||
|
|
||||||
|
Then allow the group r-access to the drives
|
||||||
|
pfexec chgrp floppy /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
|
||||||
|
pfexec chmod g+r /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
|
||||||
|
The last two commands have to be executed after each boot. I do not know
|
||||||
|
the relevant device configuration files yet.
|
||||||
|
|
||||||
|
----------
|
||||||
|
On NetBSD:
|
||||||
|
----------
|
||||||
|
Allow rw-access to the drives
|
||||||
|
chgrp floppy /dev/rcd[01]d
|
||||||
|
chmod g+rw /dev/rcd[01]d
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Project aspects and legal stuff
|
Project aspects and legal stuff
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -429,7 +563,7 @@ are the cause. Any mistake of the burn program is supposed to be caught
|
||||||
by the drive's firmware and to lead to mere misburns.
|
by the drive's firmware and to lead to mere misburns.
|
||||||
The worst mishaps which hit the author imposed the need to reboot the
|
The worst mishaps which hit the author imposed the need to reboot the
|
||||||
system because of drives gnawing endlessly on ill media. Permanent hardware
|
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||||
damage did not occur in 3.5 years of development. But one never knows ...
|
damage did not occur in 13 years of development. But one never knows ...
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -441,7 +575,7 @@ contributions in a due way.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2
|
it under the terms of the GNU General Public License version 2 or later
|
||||||
as published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
|
@ -457,7 +591,7 @@ contributions in a due way.
|
||||||
Based on and sub project of:
|
Based on and sub project of:
|
||||||
libburnia-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libburnia-project.org is inspired by and in other components still containing
|
libburnia-project.org is inspired by and in other components still containing
|
||||||
parts of
|
parts of
|
||||||
|
@ -468,34 +602,3 @@ See toplevel README for an overview of the current copyright situation in
|
||||||
libburnia-project.org.
|
libburnia-project.org.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
cdrskin is currently copyright Thomas Schmitt only.
|
|
||||||
It adopts the following commitment by the toplevel copyright holders:
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
|
||||||
those libraries are compiled from our unaltered code.
|
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
|
||||||
which are not under GPL. You may distribute our libraries and
|
|
||||||
application tools in binary form, if you fulfill the usual
|
|
||||||
condition of GPL to offer a copy of the source code -altered
|
|
||||||
or unaltered- under GPL.
|
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
|
||||||
and with the due reference to the entire open source community.
|
|
||||||
|
|
||||||
If there should really arise the case where above clarification
|
|
||||||
does not suffice to fulfill a clear and neat request in open source
|
|
||||||
spirit that would otherwise be declined for mere formal reasons,
|
|
||||||
only in that case we will duely consider to issue a special license
|
|
||||||
covering only that special case.
|
|
||||||
It is the open source idea of responsible freedom which will be
|
|
||||||
decisive and you will have to prove that you exhausted all own
|
|
||||||
means to qualify for GPL.
|
|
||||||
|
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
|
||||||
|
|
||||||
signed for cdrskin: Thomas Schmitt
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ set -x
|
||||||
# Both binaries are static in respect to libburn.
|
# Both binaries are static in respect to libburn.
|
||||||
#
|
#
|
||||||
# The script is to be run in the directory above the toplevel
|
# The script is to be run in the directory above the toplevel
|
||||||
# directory of libburn resp. cdrskin development.
|
# directory of libburn (or cdrskin) development.
|
||||||
#
|
#
|
||||||
|
|
||||||
# The top level directory in the SVN snapshot is named
|
# The top level directory in the SVN snapshot is named
|
||||||
|
@ -38,8 +38,9 @@ original="./libburn_svn_release.tgz"
|
||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-release"
|
changes="./libburn-release"
|
||||||
|
|
||||||
skin_release="0.6.8"
|
skin_release="1.5.6"
|
||||||
patch_level=".pl00"
|
patch_level=""
|
||||||
|
# patch_level=".pl00"
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
# The result directory and the name of the result tarballs
|
# The result directory and the name of the result tarballs
|
||||||
|
@ -59,7 +60,8 @@ man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
||||||
man_page_html="cdrskin/man_1_cdrskin.html"
|
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||||
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||||
|
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
|
||||||
bintarget_static="$bintarget_dynamic"-static
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
if test -d "$changes"
|
if test -d "$changes"
|
||||||
|
@ -117,6 +119,7 @@ cp -a "$cdrskin_dir" "$cdrskin_target"
|
||||||
|
|
||||||
# Remove copied vim.swp and binaries
|
# Remove copied vim.swp and binaries
|
||||||
rm "$cdrskin_target"/.*.swp
|
rm "$cdrskin_target"/.*.swp
|
||||||
|
rm "$cdrskin_target"/.*.swo
|
||||||
rm "$cdrskin_target"/*.o
|
rm "$cdrskin_target"/*.o
|
||||||
rm "$cdrskin_target"/cdrfifo
|
rm "$cdrskin_target"/cdrfifo
|
||||||
rm "$cdrskin_target"/cdrskin
|
rm "$cdrskin_target"/cdrskin
|
||||||
|
@ -226,6 +229,7 @@ tar czf "$cdrskin_tarball" "$target"
|
||||||
"$compile_cmd" $compile_static_opts -O2 -do_strip
|
"$compile_cmd" $compile_static_opts -O2 -do_strip
|
||||||
cp "$compile_result" "../$bintarget_static"
|
cp "$compile_result" "../$bintarget_static"
|
||||||
fi
|
fi
|
||||||
|
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
|
||||||
"$man_to_html_cmd"
|
"$man_to_html_cmd"
|
||||||
mv "$man_page_html" ..
|
mv "$man_page_html" ..
|
||||||
)
|
)
|
|
@ -18,7 +18,7 @@ set -x
|
||||||
# Both binaries are static in respect to libburn.
|
# Both binaries are static in respect to libburn.
|
||||||
#
|
#
|
||||||
# The script is to be run in the directory above the toplevel
|
# The script is to be run in the directory above the toplevel
|
||||||
# directory of libburn resp. cdrskin development.
|
# directory of libburn (or cdrskin) development.
|
||||||
#
|
#
|
||||||
|
|
||||||
# The top level directory in the SVN snapshot is named
|
# The top level directory in the SVN snapshot is named
|
||||||
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-develop"
|
changes="./libburn-develop"
|
||||||
|
|
||||||
skin_release="0.6.9"
|
skin_release="1.5.7"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ compile_result="cdrskin/cdrskin"
|
||||||
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
||||||
man_page_html="cdrskin/man_1_cdrskin.html"
|
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||||
|
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
|
||||||
bintarget_static="$bintarget_dynamic"-static
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
if test -d "$changes"
|
if test -d "$changes"
|
||||||
|
@ -116,6 +117,7 @@ cp -a "$cdrskin_dir" "$cdrskin_target"
|
||||||
|
|
||||||
# Remove copied vim.swp and binaries
|
# Remove copied vim.swp and binaries
|
||||||
rm "$cdrskin_target"/.*.swp
|
rm "$cdrskin_target"/.*.swp
|
||||||
|
rm "$cdrskin_target"/.*.swo
|
||||||
rm "$cdrskin_target"/*.o
|
rm "$cdrskin_target"/*.o
|
||||||
rm "$cdrskin_target"/cdrfifo
|
rm "$cdrskin_target"/cdrfifo
|
||||||
rm "$cdrskin_target"/cdrskin
|
rm "$cdrskin_target"/cdrskin
|
||||||
|
@ -227,6 +229,8 @@ tar czf "$cdrskin_tarball" "$target"
|
||||||
fi
|
fi
|
||||||
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
|
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
|
||||||
# cp "$compile_result" "../$bintarget_dynamic"_diet
|
# cp "$compile_result" "../$bintarget_dynamic"_diet
|
||||||
|
|
||||||
|
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
|
||||||
"$man_to_html_cmd"
|
"$man_to_html_cmd"
|
||||||
mv "$man_page_html" ..
|
mv "$man_page_html" ..
|
||||||
)
|
)
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
||||||
By chaining of fifo objects, several fifos can be run simultaneously
|
By chaining of fifo objects, several fifos can be run simultaneously
|
||||||
|
@ -25,11 +25,30 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#ifndef Cdrfifo_standalonE
|
||||||
|
/* for burn_os_alloc_buffer() */
|
||||||
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
|
/* ts B91124:
|
||||||
|
DISABLED, because this spoils multi-track burning by slowing down first
|
||||||
|
track and stalling before the second track begins. Obviously a problem
|
||||||
|
with chained input and waiting for full O_DRIECT suitable read chunks.
|
||||||
|
DO NOT ENABLE before the wait code in this source file is fixed.
|
||||||
|
That long, ./configure option --enable-track-src-odirect must not
|
||||||
|
get into effect in libburn. NO -DLibburn_read_o_direcT either.
|
||||||
|
|
||||||
|
For extra safety, O_DIRECT has been banned in libburn/sg-linux.c too.
|
||||||
|
|
||||||
|
# def ine Libburn_has_open_trac_srC 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cdrfifo.h"
|
#include "cdrfifo.h"
|
||||||
|
|
||||||
|
|
||||||
/* Macro for creation of arrays of objects (or single objects) */
|
/* Macro for creation of arrays of objects (or single objects) */
|
||||||
#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
|
#define TSOB_FELD(typ,anz) (typ *) calloc(anz, sizeof(typ));
|
||||||
|
|
||||||
|
|
||||||
#define Cdrfifo_buffer_chunK 2048
|
#define Cdrfifo_buffer_chunK 2048
|
||||||
|
@ -102,6 +121,9 @@ struct CdrfifO {
|
||||||
/* index of currently active (i.e. reading) follow-up */
|
/* index of currently active (i.e. reading) follow-up */
|
||||||
int follow_up_fd_idx;
|
int follow_up_fd_idx;
|
||||||
|
|
||||||
|
/* short read encountered, take subsequent errno 22 with O_DIRECT as EOF */
|
||||||
|
int o_direct_was_short;
|
||||||
|
|
||||||
|
|
||||||
/* (simultaneous) peer chaining */
|
/* (simultaneous) peer chaining */
|
||||||
struct CdrfifO *next;
|
struct CdrfifO *next;
|
||||||
|
@ -120,7 +142,7 @@ struct CdrfifO {
|
||||||
struct burn_source object.
|
struct burn_source object.
|
||||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||||
@param buffer_size Size of fifo buffer
|
@param buffer_size Size of fifo buffer
|
||||||
@param flag Unused yet
|
@param flag bit0= Debugging verbosity
|
||||||
@return 1 on success, <=0 on failure
|
@return 1 on success, <=0 on failure
|
||||||
*/
|
*/
|
||||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
|
@ -172,9 +194,16 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
}
|
}
|
||||||
o->follow_up_fd_counter= 0;
|
o->follow_up_fd_counter= 0;
|
||||||
o->follow_up_fd_idx= -1;
|
o->follow_up_fd_idx= -1;
|
||||||
|
o->o_direct_was_short= 0;
|
||||||
o->next= o->prev= NULL;
|
o->next= o->prev= NULL;
|
||||||
o->chain_idx= 0;
|
o->chain_idx= 0;
|
||||||
|
|
||||||
|
#ifdef Libburn_has_open_trac_srC
|
||||||
|
o->buffer= burn_os_alloc_buffer((size_t) buffer_size, 0);
|
||||||
|
#else
|
||||||
o->buffer= TSOB_FELD(char,buffer_size);
|
o->buffer= TSOB_FELD(char,buffer_size);
|
||||||
|
#endif /* ! Libburn_has_open_trac_srC */
|
||||||
|
|
||||||
if(o->buffer==NULL)
|
if(o->buffer==NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -192,10 +221,11 @@ int Cdrfifo_close(struct CdrfifO *o, int flag)
|
||||||
if(o->dest_fd!=-1)
|
if(o->dest_fd!=-1)
|
||||||
close(o->dest_fd);
|
close(o->dest_fd);
|
||||||
o->dest_fd= -1;
|
o->dest_fd= -1;
|
||||||
for(i=0; i<o->follow_up_fd_counter; i++)
|
for(i=0; i<o->follow_up_fd_counter; i++) {
|
||||||
if(o->follow_up_fds[i][1]!=-1)
|
if(o->follow_up_fds[i][1]!=-1)
|
||||||
close(o->follow_up_fds[i][1]);
|
close(o->follow_up_fds[i][1]);
|
||||||
o->follow_up_fds[i][1]= -1;
|
o->follow_up_fds[i][1]= -1;
|
||||||
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,8 +256,14 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
|
||||||
|
|
||||||
if(o->iso_fs_descr!=NULL)
|
if(o->iso_fs_descr!=NULL)
|
||||||
free((char *) o->iso_fs_descr);
|
free((char *) o->iso_fs_descr);
|
||||||
|
|
||||||
if(o->buffer!=NULL)
|
if(o->buffer!=NULL)
|
||||||
|
#ifdef Libburn_has_open_trac_srC
|
||||||
|
burn_os_free_buffer(o->buffer, o->buffer_size, 0);
|
||||||
|
#else
|
||||||
free((char *) o->buffer);
|
free((char *) o->buffer);
|
||||||
|
#endif /* Libburn_has_open_trac_srC */
|
||||||
|
|
||||||
free((char *) o);
|
free((char *) o);
|
||||||
(*ff)= NULL;
|
(*ff)= NULL;
|
||||||
return(1);
|
return(1);
|
||||||
|
@ -616,7 +652,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
double buffer_space;
|
double buffer_space;
|
||||||
int can_read,can_write,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
int can_read,can_write= 0,ret,did_work= 0,idx,sod, eop_idx;
|
||||||
|
|
||||||
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
||||||
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
||||||
|
@ -626,7 +662,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
||||||
if(o->read_idx+can_write > o->buffer_size)
|
if(o->read_idx+can_write > o->buffer_size)
|
||||||
can_write= o->buffer_size - o->read_idx;
|
can_write= o->buffer_size - o->read_idx;
|
||||||
if(o->follow_up_fd_idx>=0) {
|
if(o->follow_up_fd_idx>=0) {
|
||||||
eop_is_near= Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0);
|
Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0);
|
||||||
if(can_write<=0)
|
if(can_write<=0)
|
||||||
goto after_write;
|
goto after_write;
|
||||||
}
|
}
|
||||||
|
@ -659,6 +695,55 @@ return: <0 = error , 0 = idle , 1 = did some work
|
||||||
after_write:;
|
after_write:;
|
||||||
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
||||||
can_read= o->buffer_size - o->write_idx;
|
can_read= o->buffer_size - o->write_idx;
|
||||||
|
|
||||||
|
#ifdef Libburn_has_open_trac_srC
|
||||||
|
|
||||||
|
/* ts A91115
|
||||||
|
This chunksize must be aligned to filesystem blocksize.
|
||||||
|
*/
|
||||||
|
#define Cdrfifo_o_direct_chunK 32768
|
||||||
|
|
||||||
|
if(o->write_idx < o->read_idx && o->write_idx + can_read > o->read_idx)
|
||||||
|
can_read= o->read_idx - o->write_idx;
|
||||||
|
if(o->fd_in_limit>=0.0)
|
||||||
|
if(can_read > o->fd_in_limit - o->fd_in_counter)
|
||||||
|
can_read= o->fd_in_limit - o->fd_in_counter;
|
||||||
|
/* Make sure to read with properly aligned size */
|
||||||
|
if(can_read > Cdrfifo_o_direct_chunK)
|
||||||
|
can_read= Cdrfifo_o_direct_chunK;
|
||||||
|
else if(can_read < Cdrfifo_o_direct_chunK)
|
||||||
|
can_read= -1;
|
||||||
|
ret= 0;
|
||||||
|
if(can_read>0) {
|
||||||
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
|
if(ret > 0) {
|
||||||
|
if(ret < can_read) {
|
||||||
|
/* Probably EOF. Prepare for errno = 22 in the next read. */
|
||||||
|
o->o_direct_was_short= 1;
|
||||||
|
} else {
|
||||||
|
o->o_direct_was_short= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(can_read < 0) {
|
||||||
|
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
||||||
|
if(can_write <= 0 && o->dest_fd >= 0) {
|
||||||
|
fd_set rds,wts,exs;
|
||||||
|
struct timeval wt;
|
||||||
|
|
||||||
|
FD_ZERO(&rds);
|
||||||
|
FD_ZERO(&wts);
|
||||||
|
FD_ZERO(&exs);
|
||||||
|
FD_SET((o->dest_fd),&wts);
|
||||||
|
wt.tv_sec= 0;
|
||||||
|
wt.tv_usec= 10000;
|
||||||
|
select(o->dest_fd + 1,&rds, &wts, &exs, &wt);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
|
||||||
|
#else /* Libburn_has_open_trac_srC */
|
||||||
|
|
||||||
if(can_read>o->chunk_size)
|
if(can_read>o->chunk_size)
|
||||||
can_read= o->chunk_size;
|
can_read= o->chunk_size;
|
||||||
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
||||||
|
@ -669,7 +754,12 @@ after_write:;
|
||||||
ret= 0;
|
ret= 0;
|
||||||
if(can_read>0)
|
if(can_read>0)
|
||||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_has_open_trac_srC */
|
||||||
|
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
|
if(o->o_direct_was_short && errno == 22)
|
||||||
|
goto have_eof;
|
||||||
|
|
||||||
/* >>> handle input error */;
|
/* >>> handle input error */;
|
||||||
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
|
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
|
||||||
|
@ -678,6 +768,7 @@ after_write:;
|
||||||
|
|
||||||
o->source_fd= -1;
|
o->source_fd= -1;
|
||||||
} else if(ret==0) { /* eof */
|
} else if(ret==0) { /* eof */
|
||||||
|
have_eof:;
|
||||||
/* activate eventual follow-up source fd */
|
/* activate eventual follow-up source fd */
|
||||||
if(Cdrfifo_debuG || (flag&1))
|
if(Cdrfifo_debuG || (flag&1))
|
||||||
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
|
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
|
||||||
|
@ -738,7 +829,7 @@ ex:;
|
||||||
/** Check for pending data at the fifo's source file descriptor and wether the
|
/** Check for pending data at the fifo's source file descriptor and wether the
|
||||||
fifo is ready to take them. Simultaneously check the buffer for existing
|
fifo is ready to take them. Simultaneously check the buffer for existing
|
||||||
data and the destination fd for readiness to accept some. If so, a small
|
data and the destination fd for readiness to accept some. If so, a small
|
||||||
chunk of data is transfered to and/or from the fifo.
|
chunk of data is transferred to and/or from the fifo.
|
||||||
This is done for the given fifo object and all members of its next-chain.
|
This is done for the given fifo object and all members of its next-chain.
|
||||||
The check and transactions are repeated until a given timespan has elapsed.
|
The check and transactions are repeated until a given timespan has elapsed.
|
||||||
libburn applications call this function in the burn loop instead of sleep().
|
libburn applications call this function in the burn loop instead of sleep().
|
||||||
|
@ -978,9 +1069,9 @@ int Test_mixed_bs(char **paths, int path_count,
|
||||||
bit0= debugging verbousity
|
bit0= debugging verbousity
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int fd_in[100],fd_out[100],ret,pipe_fds[100][2],real_out[100];
|
int fd_in[100],fd_out[100],ret,pipe_fds[100][2];
|
||||||
int i,iv,stall_counter= 0,cycle_counter= 0.0;
|
int i,iv,stall_counter= 0,cycle_counter= 0.0;
|
||||||
char buf[10240], target_path[80];
|
char target_path[80];
|
||||||
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
|
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
|
||||||
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
|
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
|
||||||
|
|
||||||
|
@ -1048,9 +1139,8 @@ int Test_multi(int fs_size, double speed_limit, double interval, int flag)
|
||||||
bit0= debugging verbousity
|
bit0= debugging verbousity
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int fd_in[4],fd_out[4],ret,pipe_fds[4][2],real_out[4],pipe_idx;
|
int fd_in[4],fd_out[4],ret,pipe_fds[4][2];
|
||||||
int i,iv;
|
int i,iv;
|
||||||
char buf[10240];
|
|
||||||
struct CdrfifO *ff1= NULL,*ff2= NULL;
|
struct CdrfifO *ff1= NULL,*ff2= NULL;
|
||||||
|
|
||||||
/* open four pairs of fds */
|
/* open four pairs of fds */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
||||||
By chaining of fifo objects, several fifos can be run simultaneously
|
By chaining of fifo objects, several fifos can be run simultaneously
|
||||||
|
@ -33,7 +33,7 @@ struct CdrfifO;
|
||||||
struct burn_source object.
|
struct burn_source object.
|
||||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||||
@param buffer_size Size of fifo buffer
|
@param buffer_size Size of fifo buffer
|
||||||
@param flag unused yet
|
@param flag bit0= Debugging verbosity
|
||||||
@return 1 on success, <=0 on failure
|
@return 1 on success, <=0 on failure
|
||||||
*/
|
*/
|
||||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
|
@ -118,7 +118,7 @@ int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
|
||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
/** Inquire the eventually detected size of an eventual ISO-9660 file system
|
/** Inquire the eventually detected size of an eventual ISO-9660 file system
|
||||||
@return 0=no ISO resp. size detected, 1=size_in_bytes is valid
|
@return 0=no ISO size detected, 1=size_in_bytes is valid
|
||||||
*/
|
*/
|
||||||
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);
|
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag);
|
||||||
/** Check for pending data at the fifo's source file descriptor and wether the
|
/** Check for pending data at the fifo's source file descriptor and wether the
|
||||||
fifo is ready to take them. Simultaneously check the buffer for existing
|
fifo is ready to take them. Simultaneously check the buffer for existing
|
||||||
data and the destination fd for readiness to accept some. If so, a small
|
data and the destination fd for readiness to accept some. If so, a small
|
||||||
chunk of data is transfered to and/or from the fifo.
|
chunk of data is transferred to and/or from the fifo.
|
||||||
This is done for the given fifo object and all members of its next-chain.
|
This is done for the given fifo object and all members of its next-chain.
|
||||||
The check and transactions are repeated until a given timespan has elapsed.
|
The check and transactions are repeated until a given timespan has elapsed.
|
||||||
libburn applications call this function in the burn loop instead of sleep().
|
libburn applications call this function in the burn loop instead of sleep().
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
4775
cdrskin/cdrskin.c
4775
cdrskin/cdrskin.c
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
||||||
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, DVD+R/DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
|
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, BD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-R DL, DVD-RW, DVD+RW, DVD+R, DVD+R DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
|
||||||
<META NAME="robots" CONTENT="follow">
|
<META NAME="robots" CONTENT="follow">
|
||||||
<TITLE>cdrskin homepage english</TITLE>
|
<TITLE>cdrskin homepage english</TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
@ -24,7 +24,8 @@
|
||||||
<P>
|
<P>
|
||||||
<H2>Purpose:</H2>
|
<H2>Purpose:</H2>
|
||||||
Burns preformatted data to CD, DVD, and BD media:<BR>
|
Burns preformatted data to CD, DVD, and BD media:<BR>
|
||||||
CD-R, DVD-R, DVD+R, DVD+R/DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
CD-R, DVD-R, DVD-R DL, DVD+R, DVD+R DL, BD-R, CD-RW,
|
||||||
|
DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||||
</P>
|
</P>
|
||||||
<P>
|
<P>
|
||||||
|
|
||||||
|
@ -34,10 +35,12 @@ CD-R, DVD-R, DVD+R, DVD+R/DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<H2>Hardware requirements:</H2>
|
<H2>Hardware requirements:</H2>
|
||||||
A CD/DVD/BD recorder suitable for
|
About any CD, DVD, or BD recorder produced in the recent ten years.
|
||||||
<A HREF="http://libburnia-project.org">http://libburnia-project.org</A> <BR>
|
<BR>
|
||||||
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
|
<A HREF="http://libburnia-project.org">libburn</A>
|
||||||
and to MMC-5 for DVD or BD).
|
supports recorders which are compliant to standards MMC-1 for CD and
|
||||||
|
MMC-5 for DVD or BD. Linux, FreeBSD, Solaris, and NetBSD can communicate
|
||||||
|
with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
|
@ -46,9 +49,14 @@ and to MMC-5 for DVD or BD).
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
||||||
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
||||||
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
|
<DD>With kernel 2.6 or higher the drive should not be under ide-scsi.</DD>
|
||||||
<DT>or FreeBSD (with libc, of course) :</DT>
|
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||||
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</DD>
|
<DD>ATA and SATA drives need atapicam running.</DD>
|
||||||
|
<DD>libcam has to be installed.</DD>
|
||||||
|
<DT>or Solaris (with libc, of course) :</DT>
|
||||||
|
<DD>Tested on kernel 5.11, hopefully suitable for older ones too.</DD>
|
||||||
|
<DT>or NetBSD (with libc, of course) :</DT>
|
||||||
|
<DD>Tested on 6.1.2 and 6.1.3</DD>
|
||||||
<DT>libpthread</DT>
|
<DT>libpthread</DT>
|
||||||
<DD>is supposed to be a standard system component.</DD>
|
<DD>is supposed to be a standard system component.</DD>
|
||||||
</DL>
|
</DL>
|
||||||
|
@ -59,7 +67,7 @@ and to MMC-5 for DVD or BD).
|
||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-0.6.8</DT>
|
<DT>libburn-1.5.6</DT>
|
||||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||||
developed and maintained since August 2006 by
|
developed and maintained since August 2006 by
|
||||||
Thomas Schmitt from team of libburnia-project.org)
|
Thomas Schmitt from team of libburnia-project.org)
|
||||||
|
@ -69,8 +77,8 @@ Thomas Schmitt from team of libburnia-project.org)
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
This program system has been tested on Intel/AMD Linux and FreeBSD systems
|
This program system has been tested on Intel/AMD with Linux, FreeBSD,
|
||||||
only.<BR>
|
OpenSolaris, and NetBSD based operating systems.<BR>
|
||||||
Ports to other usable systems are appreciated. Reports are welcome.
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
|
@ -90,26 +98,28 @@ Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
<DL>
|
<DL>
|
||||||
<DT>The most common options of cdrecord for data and audio on CD media
|
<DT>The most common options of cdrecord for data and audio on CD media
|
||||||
are provided in a compatible way.<BR>
|
are provided in a compatible way.<BR>
|
||||||
On all DVD media except DVD-R DL, cdrskin is able to perform any recording job
|
On all DVD media, cdrskin is able to perform any recording job
|
||||||
which is possible with cdrecord.
|
which is possible with cdrecord.
|
||||||
Other than with cdrecord, option -multi is supported with many DVD types and
|
Other than with cdrecord, option -multi is supported with many DVD types and
|
||||||
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW.
|
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW and
|
||||||
|
DVD-R DL, which both support no -multi.
|
||||||
</DT>
|
</DT>
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
<DT>Get an overview of drives and their addresses</DT>
|
<DT>Get an overview of drives and their addresses</DT>
|
||||||
<DD>#<KBD> cdrskin -scanbus</KBD></DD>
|
<DD>#<KBD> cdrskin -scanbus</KBD></DD>
|
||||||
<DD>#<KBD> cdrskin dev=ATA -scanbus</KBD></DD>
|
<DD>#<KBD> cdrskin dev=ATA -scanbus</KBD></DD>
|
||||||
<DD>#<KBD> cdrskin --devices</KBD></DD>
|
<DD>#<KBD> cdrskin --devices</KBD></DD>
|
||||||
<DT>Being superuser avoids permission problems with /dev/srN resp. /dev/hdX .
|
<DT>Being superuser avoids permission problems with /dev/srN and /dev/hdX .
|
||||||
</DT>
|
</DT>
|
||||||
<DT>Ordinary users should then get granted rw access to the /dev files
|
<DT>Ordinary users should then get granted access to the /dev files
|
||||||
as listed by option --devices.</DT>
|
as listed by option --devices. Linux, FreeBSD, and NetBSD demand rw-permission.
|
||||||
|
On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
|
||||||
<DT> </DT>
|
<DT> </DT>
|
||||||
|
|
||||||
<DT>Get info about a particular drive or loaded media:</DT>
|
<DT>Get info about a particular drive or loaded media:</DT>
|
||||||
<DD>$<KBD> cdrskin dev=0,1,0 -checkdrive</KBD></DD>
|
<DD>$<KBD> cdrskin dev=0,1,0 -checkdrive</KBD></DD>
|
||||||
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
||||||
<DD>$<KBD> cdrskin dev=/dev/hdc -toc</KBD></DD>
|
<DD>$<KBD> cdrskin dev=/dev/hdc -minfo</KBD></DD>
|
||||||
|
|
||||||
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
|
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
|
||||||
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
|
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
|
||||||
|
@ -125,7 +135,8 @@ as listed by option --devices.</DT>
|
||||||
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
||||||
<DD><KBD> blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
|
<DD><KBD> blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
|
||||||
|
|
||||||
<DT>Write compressed afio archive on-the-fly:</DT>
|
<DT>Write compressed afio archive on-the-fly
|
||||||
|
(not DVD-R DL or minimally blanked DVD-RW):</DT>
|
||||||
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
||||||
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
||||||
<DD><KBD> blank=as_needed padsize=300k -</KBD></DD>
|
<DD><KBD> blank=as_needed padsize=300k -</KBD></DD>
|
||||||
|
@ -191,8 +202,15 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Download as source code (see README):</DT>
|
<DT>Download as source code (see README):</DT>
|
||||||
<DD><A HREF="cdrskin-0.6.8.pl00.tar.gz">cdrskin-0.6.8.pl00.tar.gz</A>
|
<DD><A HREF="cdrskin-1.5.6.tar.gz">cdrskin-1.5.6.tar.gz</A>
|
||||||
(750 KB).
|
(1075 KB).
|
||||||
|
</DD>
|
||||||
|
<DD><A HREF="cdrskin-1.5.6.tar.gz.sig">cdrskin-1.5.6.tar.gz.sig</A></DD>
|
||||||
|
<DD>
|
||||||
|
(detached GPG signature for verification by
|
||||||
|
<KBD>gpg --verify cdrskin-1.5.6.tar.gz.sig cdrskin-1.5.6.tar.gz</KBD>
|
||||||
|
<BR>
|
||||||
|
after <KBD>gpg --keyserver keyserver.ubuntu.com --recv-keys ABC0A854</KBD>).
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
The cdrskin tarballs are source code identical with libburn releases
|
The cdrskin tarballs are source code identical with libburn releases
|
||||||
|
@ -229,8 +247,8 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
||||||
</DL>
|
</DL>
|
||||||
<DL><DT>Contact:</DT>
|
<DL><DT>Contact:</DT>
|
||||||
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
|
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
|
||||||
<DD>libburn development mailing list,
|
<DD>GNU xorriso mailing list, where cdrskin and libburn are on topic, too:
|
||||||
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
|
<A HREF="mailto:bug-xorriso@gnu.org">bug-xorriso@gnu.org</A></DD>
|
||||||
</DL>
|
</DL>
|
||||||
<DL><DT>License:</DT>
|
<DL><DT>License:</DT>
|
||||||
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
|
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
|
||||||
|
@ -241,53 +259,53 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
Enhancements towards previous stable version cdrskin-0.6.6.pl00:
|
Enhancements towards previous stable version cdrskin-1.5.4:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Made -scanbus work with high SCSI bus numbers</LI>
|
<LI>New cdrskin option --bdr_obs_exempt</LI>
|
||||||
|
<LI>Officially enabled overburning on CD media</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-0.6.6.pl00:
|
Bug fixes towards cdrskin-1.5.4:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Old MMC-1 drives were rejected</LI>
|
<LI>Overburning with cdrskin option -force ended by a libburn error</LI>
|
||||||
<!--
|
|
||||||
<LI>none</LI>
|
|
||||||
-->
|
|
||||||
</UL>
|
</UL>
|
||||||
|
<!--
|
||||||
|
-->
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 0.6.9 :</H3></DT>
|
<DT><H3>Development snapshot, version 1.5.7 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 0.6.8.pl00:
|
<DD>Enhancements towards current stable version 1.5.6:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
Bug fixes towards cdrskin-1.5.6:
|
||||||
|
|
||||||
<DD>Bug fixes towards cdrskin-0.6.8.pl00:
|
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 0.6.9</A>
|
<DD><A HREF="README_cdrskin_devel">README 1.5.7</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.6.9 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin-1.5.7 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.6.9 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin-1.5.7 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.6.9)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.5.7)</A></DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
<DT>Maintainers of cdrskin unstable packages please use git of
|
||||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||||
<DD>Download: <KBD><B>svn co http://svn.libburnia-project.org/libburn/trunk libburn</B>
|
<DD>Download: <KBD>
|
||||||
|
<B>git clone https://dev.lovelyhq.com/libburnia/libburn.git</B>
|
||||||
</KBD></DD>
|
</KBD></DD>
|
||||||
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
||||||
</KBD></DD>
|
</KBD></DD>
|
||||||
|
@ -298,13 +316,13 @@ vanilla tools like make and gcc are needed.</DD>
|
||||||
</DD>
|
</DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>The following download is intended for adventurous end users or
|
<DT>The following download is intended for adventurous end users or
|
||||||
admins with full system souvereignty.</DT>
|
admins with full system sovereignty.</DT>
|
||||||
<DD>Source (./bootstrap is already applied, build tested, for more see
|
<DD>Source (./bootstrap is already applied, build tested, for more see
|
||||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
<A HREF="cdrskin-0.6.9.tar.gz">cdrskin-0.6.9.tar.gz</A>
|
<A HREF="cdrskin-1.5.7.tar.gz">cdrskin-1.5.7.tar.gz</A>
|
||||||
(750 KB).
|
(1075 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<!-- This is not offered any more since spring 2008
|
<!-- This is not offered any more since spring 2008
|
||||||
|
@ -453,10 +471,11 @@ First of all: this relationship is single sided, as cdrskin has to be aware of
|
||||||
cdrecord but not vice versa.
|
cdrecord but not vice versa.
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
<BR>
|
||||||
I am a long time user of cdrecord and it works fine for me.
|
I was a long time user of cdrecord and it worked fine for me.
|
||||||
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
|
Especially i do appreciate its write mode -tao which can pipe arbitrary
|
||||||
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
||||||
maintained. So for me - there would be no problem with it.
|
maintained. So for me - there would be no problem with using it for
|
||||||
|
burning CDs.
|
||||||
<BR>
|
<BR>
|
||||||
But the author of cdrecord and the Linux kernel people foster a very hostile
|
But the author of cdrecord and the Linux kernel people foster a very hostile
|
||||||
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
||||||
|
@ -478,7 +497,7 @@ opportunity is the goal of a cdrecord compatibility wrapper.
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
<BR>
|
||||||
It is very important to me that this project is not perceived as hostile
|
It is very important to me that this project is not perceived as hostile
|
||||||
towards Joerg Schilling and his ongoing work.
|
towards Joerg Schilling and his work.
|
||||||
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
@ -499,11 +518,15 @@ and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
|
||||||
<A href="http://sourceforge.net">
|
<A href="http://sourceforge.net">
|
||||||
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
||||||
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
||||||
|
|
||||||
|
<!--
|
||||||
<P>
|
<P>
|
||||||
Enjoying a FreeBSD shell account with the opportunity to
|
Enjoying a FreeBSD shell account with the opportunity to
|
||||||
build and install cdrskin at<BR>
|
build and install cdrskin at<BR>
|
||||||
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
||||||
</P>
|
</P>
|
||||||
|
-->
|
||||||
|
|
||||||
</FONT></CENTER>
|
</FONT></CENTER>
|
||||||
<HR>
|
<HR>
|
||||||
<DL>
|
<DL>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define Cdrskin_timestamP "2009.08.24.202517"
|
#define Cdrskin_timestamP "2024.04.27.162735"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -200,9 +200,10 @@ main()
|
||||||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
if(1) { /* change to 0 in order to wait for external signals */
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
char *cpt= NULL,c;
|
char *cpt= NULL, c= ' ';
|
||||||
printf("Intentionally provoking SIGSEGV ...\n");
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
c= *cpt;
|
c= *cpt;
|
||||||
|
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
|
||||||
} else {
|
} else {
|
||||||
printf("killme: %d\n",getpid());
|
printf("killme: %d\n",getpid());
|
||||||
sleep(3600);
|
sleep(3600);
|
||||||
|
|
|
@ -1,24 +1,38 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# compile_cdrskin.sh
|
# compile_cdrskin.sh
|
||||||
# Copyright 2005 - 2009 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
|
# Copyright 2005 - 2023 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
|
||||||
# to be executed within ./libburn-* resp ./cdrskin-*
|
# to be executed within ./libburn-* or./cdrskin-*
|
||||||
|
|
||||||
debug_opts="-O2"
|
debug_opts="-O2"
|
||||||
def_opts=
|
def_opts=
|
||||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
libvers="-DCdrskin_libburn_0_6_9"
|
fifo_opts=""
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
libvers="-DCdrskin_libburn_1_5_6"
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||||
|
# burn="libburn/libburn_libburn_la-"
|
||||||
|
burn="libburn/"
|
||||||
|
|
||||||
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
do_strip=0
|
do_strip=0
|
||||||
static_opts=
|
static_opts=
|
||||||
warn_opts="-Wall"
|
warn_opts="-Wall -Wextra -Wno-unused-parameter"
|
||||||
|
libcdio=
|
||||||
fifo_source="cdrskin/cdrfifo.c"
|
fifo_source="cdrskin/cdrfifo.c"
|
||||||
compile_cdrskin=1
|
compile_cdrskin=1
|
||||||
compile_cdrfifo=0
|
compile_cdrfifo=0
|
||||||
compile_dewav=0
|
compile_dewav=0
|
||||||
|
|
||||||
|
libcam=
|
||||||
|
os=$(uname -s)
|
||||||
|
case $os in
|
||||||
|
*FreeBSD)
|
||||||
|
libcam="-lcam"
|
||||||
|
esac
|
||||||
|
|
||||||
for i in "$@"
|
for i in "$@"
|
||||||
do
|
do
|
||||||
if test "$i" = "-compile_cdrfifo"
|
if test "$i" = "-compile_cdrfifo"
|
||||||
|
@ -27,34 +41,27 @@ do
|
||||||
elif test "$i" = "-compile_dewav"
|
elif test "$i" = "-compile_dewav"
|
||||||
then
|
then
|
||||||
compile_dewav=1
|
compile_dewav=1
|
||||||
elif test "$i" = "-cvs_A60220"
|
elif test "$i" = "-libburn_1_5_6"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
libvers="-DCdrskin_libburn_1_5_6"
|
||||||
libdax_audioxtr_o=
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="libburn/message.o"
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-libburn_0_6_8"
|
|
||||||
then
|
|
||||||
libvers="-DCdrskin_libburn_0_6_8"
|
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_0_6_9"
|
libvers="-DCdrskin_libburn_1_5_7"
|
||||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="libburn/cleanup.o"
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||||
elif test "$i" = "-oldfashioned"
|
|
||||||
then
|
|
||||||
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
|
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
|
||||||
elif test "$i" = "-no_largefile"
|
elif test "$i" = "-no_largefile"
|
||||||
then
|
then
|
||||||
largefile_opts=
|
largefile_opts=
|
||||||
|
elif test "$i" = "-dvd_obs_64k"
|
||||||
|
then
|
||||||
|
def_opts="$def_opts -DCdrskin_dvd_obs_default_64K"
|
||||||
elif test "$i" = "-do_not_compile_cdrskin"
|
elif test "$i" = "-do_not_compile_cdrskin"
|
||||||
then
|
then
|
||||||
compile_cdrskin=0
|
compile_cdrskin=0
|
||||||
|
@ -66,6 +73,23 @@ do
|
||||||
elif test "$i" = "-do_strip"
|
elif test "$i" = "-do_strip"
|
||||||
then
|
then
|
||||||
do_strip=1
|
do_strip=1
|
||||||
|
elif test "$i" = "-use_libburn_fifo"
|
||||||
|
then
|
||||||
|
fifo_opts="-DCdrskin_use_libburn_fifO"
|
||||||
|
elif test "$i" = "-use_no_libburn_fifo"
|
||||||
|
then
|
||||||
|
fifo_opts=""
|
||||||
|
elif test "$i" = "-use_no_cdrfifo"
|
||||||
|
then
|
||||||
|
fifo_source=
|
||||||
|
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
||||||
|
elif test "$i" = "-use_libburn_cleanup"
|
||||||
|
then
|
||||||
|
fifo_source=
|
||||||
|
fifo_opts="-DCdrskin_use_libburn_cleanuP -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
||||||
|
elif test "$i" = "-use_libcdio"
|
||||||
|
then
|
||||||
|
libcdio="-lcdio"
|
||||||
elif test "$i" = "-g"
|
elif test "$i" = "-g"
|
||||||
then
|
then
|
||||||
debug_opts="-g"
|
debug_opts="-g"
|
||||||
|
@ -75,11 +99,14 @@ do
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||||
echo " -compile_dewav compile program test/dewav without libburn."
|
echo " -compile_dewav compile program test/dewav without libburn."
|
||||||
echo " -libburn_0_6_8 set macro to match libburn-0.6.8"
|
echo " -libburn_1_5_6 set macro to match libburn-1.5.6"
|
||||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
echo " -libburn_svn set macro to match current libburn git."
|
||||||
|
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||||
|
echo " -use_libcdio link with -lcdio because libburn uses it."
|
||||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
|
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
||||||
|
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
|
||||||
echo " -do_diet produce capability reduced lean version."
|
echo " -do_diet produce capability reduced lean version."
|
||||||
echo " -do_strip apply program strip to compiled programs."
|
echo " -do_strip apply program strip to compiled programs."
|
||||||
echo " -g produce debuggable programm."
|
echo " -g produce debuggable programm."
|
||||||
|
@ -98,13 +125,14 @@ echo "Build timestamp : $timestamp"
|
||||||
|
|
||||||
if test "$compile_cdrskin"
|
if test "$compile_cdrskin"
|
||||||
then
|
then
|
||||||
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj"
|
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio $libcam"
|
||||||
cc -I. \
|
cc -I. \
|
||||||
$warn_opts \
|
$warn_opts \
|
||||||
$static_opts \
|
$static_opts \
|
||||||
$debug_opts \
|
$debug_opts \
|
||||||
$libvers \
|
$libvers \
|
||||||
$largefile_opts \
|
$largefile_opts \
|
||||||
|
$fifo_opts \
|
||||||
$def_opts \
|
$def_opts \
|
||||||
\
|
\
|
||||||
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
||||||
|
@ -116,32 +144,35 @@ then
|
||||||
\
|
\
|
||||||
$cleanup_src_or_obj \
|
$cleanup_src_or_obj \
|
||||||
\
|
\
|
||||||
libburn/async.o \
|
"$burn"async.o \
|
||||||
libburn/debug.o \
|
"$burn"cdtext.o \
|
||||||
libburn/drive.o \
|
"$burn"debug.o \
|
||||||
libburn/file.o \
|
"$burn"drive.o \
|
||||||
libburn/init.o \
|
"$burn"file.o \
|
||||||
libburn/options.o \
|
"$burn"init.o \
|
||||||
libburn/source.o \
|
"$burn"options.o \
|
||||||
libburn/structure.o \
|
"$burn"source.o \
|
||||||
|
"$burn"structure.o \
|
||||||
\
|
\
|
||||||
libburn/sg.o \
|
"$burn"sg.o \
|
||||||
libburn/write.o \
|
"$burn"write.o \
|
||||||
libburn/read.o \
|
"$burn"read.o \
|
||||||
$libdax_audioxtr_o \
|
$libdax_audioxtr_o \
|
||||||
$libdax_msgs_o \
|
$libdax_msgs_o \
|
||||||
\
|
\
|
||||||
libburn/mmc.o \
|
"$burn"mmc.o \
|
||||||
libburn/sbc.o \
|
"$burn"sbc.o \
|
||||||
libburn/spc.o \
|
"$burn"spc.o \
|
||||||
libburn/util.o \
|
"$burn"util.o \
|
||||||
\
|
\
|
||||||
libburn/sector.o \
|
"$burn"sector.o \
|
||||||
libburn/toc.o \
|
"$burn"toc.o \
|
||||||
\
|
\
|
||||||
libburn/crc.o \
|
"$burn"crc.o \
|
||||||
libburn/lec.o \
|
"$burn"ecma130ab.o \
|
||||||
\
|
\
|
||||||
|
$libcdio \
|
||||||
|
$libcam \
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
ret=$?
|
ret=$?
|
||||||
|
@ -183,8 +214,8 @@ then
|
||||||
-DDewav_without_libburN \
|
-DDewav_without_libburN \
|
||||||
-o test/dewav \
|
-o test/dewav \
|
||||||
test/dewav.c \
|
test/dewav.c \
|
||||||
libburn/libdax_audioxtr.o \
|
"$burn"libdax_audioxtr.o \
|
||||||
libburn/libdax_msgs.o \
|
"$burn"libdax_msgs.o \
|
||||||
\
|
\
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# convert_man_to_html.sh - ts A61214
|
# convert_man_to_html.sh - ts A61214 , B50802
|
||||||
#
|
#
|
||||||
# Generates a HTML version of man page cdrskin.1
|
# Generates a HTML version of man page cdrskin.1
|
||||||
#
|
#
|
||||||
|
@ -38,27 +38,29 @@ then
|
||||||
|
|
||||||
sed \
|
sed \
|
||||||
-e 's/<meta name="generator" content="groff -Thtml, see www.gnu.org">/<meta name="generator" content="groff -Thtml, via man -H, via cdrskin\/convert_man_to_html.sh">/' \
|
-e 's/<meta name="generator" content="groff -Thtml, see www.gnu.org">/<meta name="generator" content="groff -Thtml, via man -H, via cdrskin\/convert_man_to_html.sh">/' \
|
||||||
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD, CD-RW, CD-R, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
|
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD-RW, CD-R, DVD-R, DVD-RW, DVD+R, DVD+RW, BD-R, BD-RE, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
|
||||||
-e 's/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
|
-e 's/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
|
||||||
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
|
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
|
||||||
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
|
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
|
||||||
-e 's/<b>Overview of features:<\/b>/\ <BR><b>Overview of features:<\/b>/' \
|
-e 's/<b>Overview of features:<\/b>/<b>Overview of features:<\/b><BR>/' \
|
||||||
-e 's/<b>General information paragraphs:<\/b>/\ <BR><b>General information paragraphs:<\/b>/' \
|
-e 's/<b>General information paragraphs:<\/b>/<b>General information paragraphs:<\/b><BR>/' \
|
||||||
-e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b>/' \
|
-e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b><BR>/' \
|
||||||
-e 's/^In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \
|
-e 's/^In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \
|
||||||
-e 's/^While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \
|
-e 's/^While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \
|
||||||
-e 's/<b>Write mode selection:<\/b>/\ <BR><b>Write mode selection:<\/b>/' \
|
-e 's/<b>Write mode selection:<\/b>/<b>Write mode selection:<\/b><BR>/' \
|
||||||
-e 's/<b>Recordable CD Media:<\/b>/\ <BR><b>Recordable CD Media:<\/b>/' \
|
-e 's/<b>Recordable CD Media:<\/b>/<b>Recordable CD Media:<\/b><BR>/' \
|
||||||
-e 's/<b>Overwriteable DVD Media:<\/b>/\ <BR><b>Overwriteable DVD Media:<\/b>/' \
|
-e 's/<b>Overwriteable DVD or BD Media:<\/b>/<b>Overwriteable DVD or BD Media:<\/b><BR>/' \
|
||||||
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\ <BR><b>Sequentially Recordable DVD Media:<\/b>/' \
|
-e 's/<b>Sequentially Recordable DVD or BD Media:<\/b>/<b>Sequentially Recordable DVD or BD Media:<\/b><BR>/' \
|
||||||
-e 's/^The write modes for DVD+R/\ <BR>The write modes for DVD+R/' \
|
-e 's/^The write modes for DVD+R/\ <BR>The write modes for DVD+R/' \
|
||||||
-e 's/<b>Drive preparation and addressing:<\/b>/\ <BR><b>Drive preparation and addressing:<\/b>/' \
|
-e 's/<b>Drive preparation and addressing:<\/b>/<b>Drive preparation and addressing:<\/b><BR>/' \
|
||||||
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||||
-e 's/<b>Emulated drives:<\/b>/\ <BR><b>Emulated drives:<\/b>/' \
|
-e 's/<b>Emulated drives:<\/b>/<b>Emulated drives:<\/b><BR>/' \
|
||||||
-e 's/^Alphabetical list of options/\ <BR>Alphabetical list of options/' \
|
-e 's/for normal use: <b><br>/for normal use: <b><br><BR>/' \
|
||||||
|
-e 's/original cdrecord by Joerg Schilling:<\/p>/original cdrecord by Joerg Schilling:<\/p><BR>/' \
|
||||||
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
||||||
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
||||||
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||||
|
-e 's/−/-/g' \
|
||||||
<"$2" >"$htmlpage"
|
<"$2" >"$htmlpage"
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
|
@ -69,8 +71,10 @@ then
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
export BROWSER='cp "%s" '"$raw_html"
|
# export BROWSER='cp "%s" '"$raw_html"
|
||||||
|
export BROWSER=$(pwd)/'cdrskin/unite_html_b_line "%s" '"$raw_html"
|
||||||
man -H "$manpage"
|
man -H "$manpage"
|
||||||
|
# cp "$raw_html" /tmp/x.html
|
||||||
"$0" -work_as_filter "$raw_html"
|
"$0" -work_as_filter "$raw_html"
|
||||||
rm "$raw_html"
|
rm "$raw_html"
|
||||||
rm "$man_dir"/man1
|
rm "$man_dir"/man1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Create version timestamp cdrskin/cdrskin_timestamp.h
|
# Create version timestamp cdrskin/cdrskin_timestamp.h
|
||||||
# to be executed within ./libburn-* resp ./cdrskin-*
|
# to be executed within ./libburn-* or ./cdrskin-*
|
||||||
|
|
||||||
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
echo "Version timestamp : $timestamp"
|
echo "Version timestamp : $timestamp"
|
||||||
|
|
124
cdrskin/unite_html_b_line.c
Normal file
124
cdrskin/unite_html_b_line.c
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Specialized converter for the output of man -H,
|
||||||
|
which unites lines where the line end is between <b> and </b>.
|
||||||
|
|
||||||
|
Copyright 2015 Thomas Schmitt, <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
int unite_lines(char *buffer, int *b_open, int *b_state, int flag)
|
||||||
|
{
|
||||||
|
char *cpt;
|
||||||
|
int last_was_nl= 0;
|
||||||
|
|
||||||
|
for(cpt= buffer; *cpt != 0; cpt++) {
|
||||||
|
if(*b_open) {
|
||||||
|
if(*b_state == 0 && *cpt == '<') {
|
||||||
|
*b_state= 1;
|
||||||
|
} else if(*b_state == 1) {
|
||||||
|
if(*cpt == '/')
|
||||||
|
*b_state= 2;
|
||||||
|
else
|
||||||
|
*b_state= 0;
|
||||||
|
} else if(*b_state == 2) {
|
||||||
|
if(*cpt == 'b' || *cpt == 'B')
|
||||||
|
*b_state= 3;
|
||||||
|
else
|
||||||
|
*b_state= 0;
|
||||||
|
} else if(*b_state == 3) {
|
||||||
|
if(*cpt == '>')
|
||||||
|
*b_open= 0;
|
||||||
|
*b_state= 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(*b_state == 0 && *cpt == '<') {
|
||||||
|
*b_state= 1;
|
||||||
|
} else if(*b_state == 1) {
|
||||||
|
if(*cpt == 'b' || *cpt == 'B')
|
||||||
|
*b_state= 2;
|
||||||
|
else
|
||||||
|
*b_state= 0;
|
||||||
|
} else if(*b_state == 2) {
|
||||||
|
if(*cpt == '>')
|
||||||
|
*b_open= 1;
|
||||||
|
*b_state= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_was_nl= (*cpt == '\n');
|
||||||
|
}
|
||||||
|
if(*b_open && last_was_nl) {
|
||||||
|
/* replace newline */
|
||||||
|
*(cpt - 1)= ' ';
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
FILE *fpin, *fpout;
|
||||||
|
char buffer[4096], *respt;
|
||||||
|
int ret, b_open= 0, b_state= 0;
|
||||||
|
|
||||||
|
if(argc != 3) {
|
||||||
|
fprintf(stderr, "usage: %s input_path output_path\n", argv[0]);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
if(strcmp(argv[1], "-") == 0) {
|
||||||
|
fpin= stdin;
|
||||||
|
} else {
|
||||||
|
fpin= fopen(argv[1], "rb");
|
||||||
|
if(fpin == 0) {
|
||||||
|
fprintf(stderr, "Error with input file '%s' : %s\n",
|
||||||
|
argv[1], strerror(errno));
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(strcmp(argv[2], "-") == 0) {
|
||||||
|
fpout= stdout;
|
||||||
|
} else {
|
||||||
|
fpout= fopen(argv[2], "wb");
|
||||||
|
if(fpout == 0) {
|
||||||
|
fprintf(stderr, "Error with output file '%s' : %s\n",
|
||||||
|
argv[2], strerror(errno));
|
||||||
|
return(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(1) {
|
||||||
|
respt= fgets(buffer, sizeof(buffer), fpin);
|
||||||
|
if(respt == NULL)
|
||||||
|
break;
|
||||||
|
ret= unite_lines(buffer, &b_open, &b_state, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
break;
|
||||||
|
ret= fputs(buffer, fpout);
|
||||||
|
if(ret < 0) {
|
||||||
|
fprintf(stderr, "Error writing to output file '%s' : %s\n",
|
||||||
|
argv[2], strerror(errno));
|
||||||
|
return(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fpin != stdin)
|
||||||
|
fclose(fpin);
|
||||||
|
if(fpout != stdout)
|
||||||
|
fclose(stdout);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
|
@ -19,12 +19,7 @@ Many bytes have been copied from the message output of cdrecord
|
||||||
runs, though. The most comprehensive technical overview of cdrskin
|
runs, though. The most comprehensive technical overview of cdrskin
|
||||||
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
|
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
|
||||||
|
|
||||||
About libburn API for burning CD and DVD: http://api.libburnia-project.org
|
About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
For yet unsupported media types see the advice to use dvd+rw-tools at
|
|
||||||
the end of this text.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -61,7 +56,7 @@ Some are of general user interest, though:
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
--devices allows the sysadmin to scan the system for possible drives
|
--devices can be used by the sysadmin to scan the system for possible drives
|
||||||
and displays their detected properties.
|
and displays their detected properties.
|
||||||
The drives are listed one per line, with fields:
|
The drives are listed one per line, with fields:
|
||||||
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
|
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
|
||||||
|
@ -90,7 +85,7 @@ Option blank= offers several specialized blanking and formatting types,
|
||||||
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
|
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
|
||||||
(See also below: blank=format_overwrite)
|
(See also below: blank=format_overwrite)
|
||||||
The drive offers a list of possible formats by cdrskin option --list_formats.
|
The drive offers a list of possible formats by cdrskin option --list_formats.
|
||||||
One should aquire MMC background information before making use of them.
|
One should acquire MMC background information before making use of them.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -172,7 +167,7 @@ media with a single session and track on it. blank= invalidates ISO images.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
assert_write_lba=<lba> allows to ensure that the start block address which
|
assert_write_lba=<lba> ensures that the start block address which
|
||||||
was used with the formatter program (e.g. mkisofs -C) matches the start block
|
was used with the formatter program (e.g. mkisofs -C) matches the start block
|
||||||
address which will be used by the upcoming burn.
|
address which will be used by the upcoming burn.
|
||||||
|
|
||||||
|
@ -220,7 +215,7 @@ With a very fat fs=# buffer (128 MB for 12x CD is not unrealistic) this
|
||||||
can cause a big delay until burning finally starts and takes its due time.
|
can cause a big delay until burning finally starts and takes its due time.
|
||||||
|
|
||||||
fifo_start_at=<num> makes cdrskin start burning after the given number of bytes
|
fifo_start_at=<num> makes cdrskin start burning after the given number of bytes
|
||||||
is read rather than waiting for the FIFO to be completely full resp. the data
|
is read rather than waiting for the FIFO to be completely full or the data
|
||||||
stream to end. It risks a few drive buffer underruns at the beginning of burn
|
stream to end. It risks a few drive buffer underruns at the beginning of burn
|
||||||
- but modern drives stand this.
|
- but modern drives stand this.
|
||||||
|
|
||||||
|
@ -268,7 +263,7 @@ would be the appropriate translation:
|
||||||
{{{
|
{{{
|
||||||
dev_translation=+0,0,0+/dev/hdc
|
dev_translation=+0,0,0+/dev/hdc
|
||||||
}}}
|
}}}
|
||||||
The "+" character is a separator to be choosen by you.
|
The "+" character is a separator to be chosen by you.
|
||||||
Currently i am not aware of the need to choose any other than "+"
|
Currently i am not aware of the need to choose any other than "+"
|
||||||
unless you get playful with custom translations like
|
unless you get playful with custom translations like
|
||||||
{{{
|
{{{
|
||||||
|
@ -279,23 +274,7 @@ for an illustrated example with K3b 0.10 .
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
DVD advise:
|
Advanced multi-session use cases as of dvd+rw-tools:
|
||||||
|
|
||||||
For burning of DVD/BD media other than DVD-RAM, DVD+RW, DVD+R, DVD+R DL,
|
|
||||||
DVD-RW, DVD-R, BD-RE, the cdrskin project currently advises to use
|
|
||||||
Andy Polyakov's dvd+rw-tools which despite their historic name are
|
|
||||||
capable of all the media above and more, including BD discs.
|
|
||||||
|
|
||||||
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
|
|
||||||
|
|
||||||
They are not compatible or related to cdrecord resp. cdrecord-ProDVD
|
|
||||||
(now obsoleted by original source cdrtools cdrecord with identical
|
|
||||||
capabilities besides the license key).
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Advanced multi-session use cases:
|
|
||||||
|
|
||||||
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
|
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
|
||||||
overwriteable media. This is not the same as multi-session writing of cdrskin
|
overwriteable media. This is not the same as multi-session writing of cdrskin
|
||||||
|
|
212
configure.ac
212
configure.ac
|
@ -1,13 +1,16 @@
|
||||||
AC_INIT([libburn], [0.6.9], [http://libburnia-project.org])
|
AC_INIT([libburn], [1.5.7], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
LIBBURNIA_SET_FLAGS
|
||||||
|
|
||||||
dnl Notes by ts A71207 - A90714 :
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
AC_CONFIG_MACRO_DIR([./])
|
||||||
|
|
||||||
|
dnl Notes about version numbers and .so numbers:
|
||||||
dnl
|
dnl
|
||||||
dnl Regrettably the meaning of the various version types was misunderstood
|
dnl Regrettably the meaning of the various version types was misunderstood
|
||||||
dnl before version 0.4.1.
|
dnl before version 0.4.1.
|
||||||
|
@ -73,6 +76,44 @@ dnl 0.6.2 = libburn.so.4.27.0
|
||||||
dnl 0.6.4 = libburn.so.4.29.0
|
dnl 0.6.4 = libburn.so.4.29.0
|
||||||
dnl 0.6.6 = libburn.so.4.31.0
|
dnl 0.6.6 = libburn.so.4.31.0
|
||||||
dnl 0.6.8 = libburn.so.4.33.0
|
dnl 0.6.8 = libburn.so.4.33.0
|
||||||
|
dnl 0.7.0 = libburn.so.4.35.0
|
||||||
|
dnl 0.7.2 = libburn.so.4.37.0
|
||||||
|
dnl 0.7.4 = libburn.so.4.39.0
|
||||||
|
dnl 0.7.6 = libburn.so.4.41.0
|
||||||
|
dnl 0.7.8 = libburn.so.4.43.0
|
||||||
|
dnl 0.8.0 = libburn.so.4.45.0
|
||||||
|
dnl 0.8.2 = libburn.so.4.47.0
|
||||||
|
dnl 0.8.4 = libburn.so.4.49.0
|
||||||
|
dnl 0.8.6 = libburn.so.4.51.0
|
||||||
|
dnl 0.8.8 = libburn.so.4.53.0
|
||||||
|
dnl 0.9.0 = libburn.so.4.55.0
|
||||||
|
dnl 1.0.0 = libburn.so.4.57.0
|
||||||
|
dnl 1.0.2 = libburn.so.4.59.0
|
||||||
|
dnl 1.0.4 = libburn.so.4.61.0
|
||||||
|
dnl 1.0.6 = libburn.so.4.63.0
|
||||||
|
dnl 1.1.0 = libburn.so.4.65.0
|
||||||
|
dnl 1.1.4 = libburn.so.4.67.0
|
||||||
|
dnl 1.1.6 = libburn.so.4.69.0
|
||||||
|
dnl 1.1.8 = libburn.so.4.71.0
|
||||||
|
dnl 1.2.0 = libburn.so.4.73.0
|
||||||
|
dnl 1.2.2 = libburn.so.4.75.0
|
||||||
|
dnl 1.2.4 = libburn.so.4.77.0
|
||||||
|
dnl 1.2.6 = libburn.so.4.79.0
|
||||||
|
dnl 1.2.8 = libburn.so.4.81.0
|
||||||
|
dnl 1.3.0 = libburn.so.4.83.0
|
||||||
|
dnl 1.3.2 = libburn.so.4.85.0
|
||||||
|
dnl 1.3.4 = libburn.so.4.87.0
|
||||||
|
dnl 1.3.6 = libburn.so.4.89.0
|
||||||
|
dnl 1.3.8 = libburn.so.4.91.0
|
||||||
|
dnl 1.4.0 = libburn.so.4.93.0
|
||||||
|
dnl 1.4.2 = libburn.so.4.95.0
|
||||||
|
dnl 1.4.4 = libburn.so.4.97.0
|
||||||
|
dnl 1.4.6 = libburn.so.4.99.0
|
||||||
|
dnl 1.4.8 = libburn.so.4.101.0
|
||||||
|
dnl 1.5.0 = libburn.so.4.103.0
|
||||||
|
dnl 1.5.2 = libburn.so.4.105.0
|
||||||
|
dnl 1.5.4 = libburn.so.4.107.0
|
||||||
|
dnl 1.5.6 = libburn.so.4.109.0
|
||||||
dnl
|
dnl
|
||||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||||
|
@ -96,9 +137,9 @@ dnl
|
||||||
dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||||
BURN_MAJOR_VERSION=0
|
BURN_MAJOR_VERSION=1
|
||||||
BURN_MINOR_VERSION=6
|
BURN_MINOR_VERSION=5
|
||||||
BURN_MICRO_VERSION=9
|
BURN_MICRO_VERSION=7
|
||||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(BURN_MAJOR_VERSION)
|
AC_SUBST(BURN_MAJOR_VERSION)
|
||||||
|
@ -109,15 +150,14 @@ AC_SUBST(BURN_VERSION)
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
dnl
|
dnl
|
||||||
dnl ts A90714
|
dnl ### This is the release version libburn-1.5.6
|
||||||
dnl ### This is the release version libburn-0.6.8 = libburn.so.4.33.0
|
|
||||||
dnl This is the development version after above release version
|
dnl This is the development version after above release version
|
||||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
dnl ### LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
dnl LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 37 - 33 = 4 . Linux library name = libburn.so.4.33.0
|
dnl SONAME = 114 - 110 = 4 . Linux library name = libburn.so.4.110.0
|
||||||
LT_CURRENT=37
|
LT_CURRENT=114
|
||||||
LT_AGE=33
|
LT_AGE=110
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
|
@ -136,12 +176,12 @@ AC_SUBST(BURN_BINARY_AGE)
|
||||||
AC_PREFIX_DEFAULT([/usr/local])
|
AC_PREFIX_DEFAULT([/usr/local])
|
||||||
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
||||||
|
|
||||||
AM_MAINTAINER_MODE
|
dnl ts B90405 : Disabled on advise of Ross Burton
|
||||||
|
dnl AM_MAINTAINER_MODE
|
||||||
|
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
AC_C_BIGENDIAN
|
|
||||||
|
|
||||||
dnl Large file support
|
dnl Large file support
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
@ -153,7 +193,7 @@ fi
|
||||||
|
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
AC_SUBST(LIBTOOL_DEPS)
|
AC_SUBST(LIBTOOL_DEPS)
|
||||||
LIBTOOL="$LIBTOOL --silent"
|
# LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
@ -175,7 +215,134 @@ AC_CHECK_HEADER(sys/statvfs.h, X=, STATVFS_DEF=)
|
||||||
AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=)
|
AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=)
|
||||||
dnl If this would be done more specifically in Makefile.am
|
dnl If this would be done more specifically in Makefile.am
|
||||||
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
|
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
|
||||||
CFLAGS="$CFLAGS $STATVFS_DEF"
|
CFLAGS="$STATVFS_DEF $CFLAGS"
|
||||||
|
|
||||||
|
dnl ts A91122
|
||||||
|
AC_ARG_ENABLE(track-src-odirect,
|
||||||
|
[ --enable-track-src-odirect Banned for now: (Enable use of O_DIRECT with track input, default=no)],
|
||||||
|
, enable_track_src_odirect=no)
|
||||||
|
if test x$enable_track_src_odirect = xyes; then
|
||||||
|
# LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
||||||
|
# echo "enabled use of O_DIRECT with track input"
|
||||||
|
echo "REFUSED to enable use of O_DIRECT with track input because of cdrskin multi-track bug"
|
||||||
|
else
|
||||||
|
LIBBURN_O_DIRECT_DEF=
|
||||||
|
echo "disabled use of O_DIRECT with track input"
|
||||||
|
fi
|
||||||
|
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
||||||
|
dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF)
|
||||||
|
CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS"
|
||||||
|
|
||||||
|
dnl ts A91116
|
||||||
|
AC_ARG_ENABLE(dvd-obs-64k,
|
||||||
|
[ --enable-dvd-obs-64k 64 KB default size for DVD writing, default=no],
|
||||||
|
, enable_dvd_obs_64k=no)
|
||||||
|
if test x$enable_dvd_obs_64k = xyes; then
|
||||||
|
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
||||||
|
echo "enabled write size default 64 KB on DVD"
|
||||||
|
else
|
||||||
|
LIBBURN_DVD_OBS_64K=
|
||||||
|
echo "disabled write size default 64 KB on DVD"
|
||||||
|
fi
|
||||||
|
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
|
||||||
|
|
||||||
|
dnl ts B20413
|
||||||
|
AC_ARG_ENABLE(dvd-obs-pad,
|
||||||
|
[ --enable-dvd-obs-pad pad DVD DAO sessions to 32 or 64 KB, default=no],
|
||||||
|
, enable_dvd_obs_pad=no)
|
||||||
|
if test x$enable_dvd_obs_pad = xyes; then
|
||||||
|
LIBBURN_DVD_OBS_PAD="-DLibburn_dvd_always_obs_paD"
|
||||||
|
echo "enabled padding of DVD DAO sessions to 32 or 64 KB"
|
||||||
|
else
|
||||||
|
LIBBURN_DVD_OBS_64K=
|
||||||
|
echo "disabled padding of DVD DAO sessions to 32 or 64 KB"
|
||||||
|
fi
|
||||||
|
CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS"
|
||||||
|
|
||||||
|
dnl ts A91218 - B21002
|
||||||
|
case $host_os in
|
||||||
|
cygwin*|mingw*)
|
||||||
|
default_libcdio=yes
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
default_libcdio=no
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Check for proper library versions if this is desired.
|
||||||
|
# (It fails too often on too many systems.)
|
||||||
|
AC_ARG_ENABLE(pkg-check-modules,
|
||||||
|
[ --enable-pkg-check-modules Enable pkg-config check for libcdio , default=no],
|
||||||
|
, enable_pkg_check_modules=no)
|
||||||
|
AC_ARG_ENABLE(libcdio,
|
||||||
|
[ --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows)],
|
||||||
|
, enable_libcdio=$default_libcdio)
|
||||||
|
PKG_PROG_PKG_CONFIG
|
||||||
|
if test x$enable_libcdio = xyes; then
|
||||||
|
dnl Check whether there is libcdio-devel and libcdio-runtime.
|
||||||
|
dnl If not, erase this macro
|
||||||
|
LIBCDIO_DEF="-DLibburn_use_libcdiO"
|
||||||
|
dnl The empty yes case obviously causes -lcdio to be linked
|
||||||
|
AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= )
|
||||||
|
else
|
||||||
|
LIBCDIO_DEF=
|
||||||
|
fi
|
||||||
|
if test x$LIBCDIO_DEF = x
|
||||||
|
then
|
||||||
|
if test x$enable_libcdio = xyes
|
||||||
|
then
|
||||||
|
echo "WARNING: could not enable use of libcdio as system adapter"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "enabled use of libcdio as system adapter"
|
||||||
|
CFLAGS="$LIBCDIO_DEF $CFLAGS"
|
||||||
|
|
||||||
|
if test x$enable_pkg_check_modules = xyes; then
|
||||||
|
LIBCDIO_REQUIRED=0.83
|
||||||
|
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
|
||||||
|
else
|
||||||
|
echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl ts B70127
|
||||||
|
# There are Linuxes with no public generic SCSI interface
|
||||||
|
LIBBURNIA_CHECK_LINUX_SCSI
|
||||||
|
|
||||||
|
dnl ts B00704
|
||||||
|
# Library versioning normally serves a complex purpose.
|
||||||
|
# Since libburn obeys strict ABI backward compatibility, it needs only the
|
||||||
|
# simple feature to declare function names "global:" or "local:". Only the
|
||||||
|
# global ones are visible to applications at library load time.
|
||||||
|
AC_ARG_ENABLE(versioned-libs,
|
||||||
|
[ --enable-versioned-libs Enable strict symbol encapsulation , default=yes],
|
||||||
|
, enable_versioned_libs=yes)
|
||||||
|
if test x$enable_versioned_libs = xyes; then
|
||||||
|
vers_libs_test=no
|
||||||
|
LIBBURN_ASSERT_VERS_LIBS
|
||||||
|
if test x$vers_libs_test = xno
|
||||||
|
then
|
||||||
|
echo "disabled strict symbol encapsulation (test failed)"
|
||||||
|
else
|
||||||
|
echo "enabled strict symbol encapsulation"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "disabled strict symbol encapsulation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for system dependent mandatory libraries (LIBBURN_ARCH_LIBS)
|
||||||
|
LIBBURNIA_CHECK_ARCH_LIBS(mandatory)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ldconfig-at-install,
|
||||||
|
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
|
||||||
|
, ldconfig_at_install=yes)
|
||||||
|
if test x$ldconfig_at_install = xyes; then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'"
|
||||||
|
echo "disabled run of ldconfig during installation on GNU/Linux"
|
||||||
|
fi
|
||||||
|
AC_SUBST(LIBBURNIA_LDCONFIG_CMD)
|
||||||
|
|
||||||
|
|
||||||
dnl Add compiler-specific flags
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
|
@ -185,18 +352,17 @@ AC_ARG_ENABLE(debug,
|
||||||
, enable_debug=yes)
|
, enable_debug=yes)
|
||||||
if test x$enable_debug != xyes; then
|
if test x$enable_debug != xyes; then
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="$CFLAGS -O3"
|
CFLAGS="-O3 $CFLAGS"
|
||||||
CFLAGS="$CFLAGS -fexpensive-optimizations"
|
CFLAGS="-fexpensive-optimizations $CFLAGS"
|
||||||
fi
|
fi
|
||||||
CFLAGS="$CFLAGS -DNDEBUG"
|
CFLAGS="-DNDEBUG $CFLAGS"
|
||||||
else
|
else
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="$CFLAGS -g -pedantic -Wall"
|
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
|
||||||
fi
|
fi
|
||||||
CFLAGS="$CFLAGS -DDEBUG"
|
CFLAGS="-DDEBUG $CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl Determine target directory for libburn-*.pc
|
dnl Determine target directory for libburn-*.pc
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||||
dnl
|
dnl
|
||||||
|
|
736
doc/cdtext.txt
Normal file
736
doc/cdtext.txt
Normal file
|
@ -0,0 +1,736 @@
|
||||||
|
|
||||||
|
Description of CD-TEXT
|
||||||
|
|
||||||
|
Guided by Leon Merten Lohse via libcdio-devel@gnu.org
|
||||||
|
by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/
|
||||||
|
by docs and results of cdtext.zip from http://www.sonydadc.com/file/
|
||||||
|
by reading http://digitalx.org/cue-sheet/syntax
|
||||||
|
by reading source of libcdio from http://www.gnu.org/s/libcdio
|
||||||
|
which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha
|
||||||
|
by reading cdrecord.1 from ftp://ftp.berlios.de/pub/cdrecord/alpha
|
||||||
|
|
||||||
|
Language codes were learned from http://tech.ebu.ch/docs/tech/tech3264.pdf
|
||||||
|
Genre codes were learned from libcdio and confirmed by
|
||||||
|
http://helpdesk.audiofile-engineering.com/index.php?pg=kb.page&id=123
|
||||||
|
|
||||||
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
Content:
|
||||||
|
- CD-TEXT from the view of the user
|
||||||
|
- Content specifications of particular pack types
|
||||||
|
- Format of a CD-TEXT packs array
|
||||||
|
- Overview of libburn API calls for CD-TEXT
|
||||||
|
- Sony Text File Format (Input Sheet Version 0.7T)
|
||||||
|
- CDRWIN cue sheet files
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
CD-TEXT from the view of the user:
|
||||||
|
|
||||||
|
CD-TEXT records attributes of disc and tracks on audio CD.
|
||||||
|
|
||||||
|
The attributes are grouped into blocks which represent particular languages.
|
||||||
|
Up to 8 blocks are possible.
|
||||||
|
|
||||||
|
There are 13 defined attribute categories, which are called Pack Types and are
|
||||||
|
identified by a single-byte code:
|
||||||
|
0x80 = Title
|
||||||
|
0x81 = Names of Performers
|
||||||
|
0x82 = Names of Songwriters
|
||||||
|
0x83 = Names of Composers
|
||||||
|
0x84 = Names of Arrangers
|
||||||
|
0x85 = Messages
|
||||||
|
0x86 = text-and-binary: Disc Identification
|
||||||
|
0x87 = text-and-binary: Genre Identification
|
||||||
|
0x88 = binary: Table of Content information
|
||||||
|
0x89 = binary: Second Table of Content information
|
||||||
|
(0x8a to 0x8c are reserved.)
|
||||||
|
0x8d = Closed Information
|
||||||
|
0x8e = UPC/EAN code of the album and ISRC code of each track
|
||||||
|
0x8f = binary: Size Information of the Block
|
||||||
|
|
||||||
|
Some of these categories apply to the whole disc only:
|
||||||
|
0x86, 0x87, 0x88, 0x89, 0x8d
|
||||||
|
Some have to be additionally attributed to each track, if they are present for
|
||||||
|
the whole disc:
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8e
|
||||||
|
One describes the overall content of a block and in part of all other blocks:
|
||||||
|
0x8f
|
||||||
|
|
||||||
|
The total size of a block's attribute set is restricted by the fact that it
|
||||||
|
has to be stored in at most 253 records with 12 bytes of payload. These records
|
||||||
|
are called Text Packs.
|
||||||
|
A shortcut for repeated identical track texts is provided, so that a text
|
||||||
|
that is identical to the one of the previous track occupies only 2 or 4 bytes.
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Content specification of particular pack types:
|
||||||
|
|
||||||
|
Pack types 0x80 to 0x85 and 0x8e contain 0-terminated cleartext. If double byte
|
||||||
|
characters are used, then two 0-bytes terminate the cleartext.
|
||||||
|
The meaning of 0x80 to 0x85 should be clear by above list. They are encoded
|
||||||
|
according to the Character Code of their block. Either as ISO-8859-1 single
|
||||||
|
byte characters, or as 7-bit ASCII single byte characters, or as MS-JIS double
|
||||||
|
byte characters.
|
||||||
|
More info to 0x8e is given below.
|
||||||
|
|
||||||
|
Pack type 0x86 (Disc Identification) is documented by Sony as "Catalog Number:
|
||||||
|
(use ASCII Code) Catalog Number of the album". So it is not really binary
|
||||||
|
but might be non-printable, and should contain only bytes with bit7 = 0.
|
||||||
|
|
||||||
|
Pack type 0x87 contains 2 binary bytes, followed by 0-terminated cleartext.
|
||||||
|
The two binary bytes form a big-endian index to the following list.
|
||||||
|
0x0000 = "Not Used" (Sony prescribes to use this if no genre applies)
|
||||||
|
0x0001 = "Not Defined"
|
||||||
|
0x0002 = "Adult Contemporary"
|
||||||
|
0x0003 = "Alternative Rock"
|
||||||
|
0x0004 = "Childrens Music"
|
||||||
|
0x0005 = "Classical"
|
||||||
|
0x0006 = "Contemporary Christian"
|
||||||
|
0x0007 = "Country"
|
||||||
|
0x0008 = "Dance"
|
||||||
|
0x0009 = "Easy Listening"
|
||||||
|
0x000a = "Erotic"
|
||||||
|
0x000b = "Folk"
|
||||||
|
0x000c = "Gospel"
|
||||||
|
0x000d = "Hip Hop"
|
||||||
|
0x000e = "Jazz"
|
||||||
|
0x000f = "Latin"
|
||||||
|
0x0010 = "Musical"
|
||||||
|
0x0011 = "New Age"
|
||||||
|
0x0012 = "Opera"
|
||||||
|
0x0013 = "Operetta"
|
||||||
|
0x0014 = "Pop Music"
|
||||||
|
0x0015 = "Rap"
|
||||||
|
0x0016 = "Reggae"
|
||||||
|
0x0017 = "Rock Music"
|
||||||
|
0x0018 = "Rhythm & Blues"
|
||||||
|
0x0019 = "Sound Effects"
|
||||||
|
0x001a = "Spoken Word"
|
||||||
|
0x001b = "World Music"
|
||||||
|
Sony documents the cleartext part as "Genre information that would supplement
|
||||||
|
the Genre Code, such as 'USA Rock music in the 60s'". Always ASCII encoded.
|
||||||
|
|
||||||
|
Pack type 0x88 records information from the CD's Table of Content, as of
|
||||||
|
READ PMA/TOC/ATIP Format 0010b (mmc3r10g.pdf, table 237 TOC Track Descriptor
|
||||||
|
Format, Q Sub-channel).
|
||||||
|
See below, Format of a CD-TEXT packs array, for more details about the content
|
||||||
|
of pack type 0x88.
|
||||||
|
|
||||||
|
Pack type 0x89 is yet quite unclear. It might be a representation of Playback
|
||||||
|
Skip Interval, Mode-5 Q sub-channel, POINT 01 to 40 (mmc3r10g.pdf 4.2.3.6.3).
|
||||||
|
If so, then this seems not to apply to write type SAO, because the CUE SHEET
|
||||||
|
format offers no way to express Mode-5 Q.
|
||||||
|
See below, Format of a CD-TEXT packs array, for an example of this pack type.
|
||||||
|
|
||||||
|
Pack type 0x8d is documented by Sony as "Closed Information: (use 8859-1 Code)
|
||||||
|
Any information can be recorded on disc as memorandum. Information in this
|
||||||
|
field will not be read by CD TEXT players available to the public."
|
||||||
|
Always ISO-8859-1 encoded.
|
||||||
|
|
||||||
|
Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album.
|
||||||
|
This field typically consists of 13 characters." Always ASCII encoded.
|
||||||
|
It applies to tracks as "ISRC code [which] typically consists of 12 characters"
|
||||||
|
and is always ISO-8859-1 encoded.
|
||||||
|
MMC calls these information entities Media Catalog Number and ISRC.
|
||||||
|
The catalog number consists of 13 decimal digits.
|
||||||
|
ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z],
|
||||||
|
2 year digits (00 to 99), 5 serial number digits (00000 to 99999).
|
||||||
|
|
||||||
|
Pack type 0x8f summarizes the whole list of text packs of a block.
|
||||||
|
See below, Format of a CD-TEXT packs array, for details.
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Format of a CD-TEXT packs array:
|
||||||
|
|
||||||
|
The attributes are represented on CD as Text Packs in the sub-channel of
|
||||||
|
the Lead-in of the disc. See doc/cookbook.txt for a description how to write
|
||||||
|
the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs
|
||||||
|
from CD.
|
||||||
|
|
||||||
|
The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by
|
||||||
|
the documentation in Sony's cdtext.zip :
|
||||||
|
|
||||||
|
Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC.
|
||||||
|
|
||||||
|
The first byte of each pack tells the pack type. See above for a list of types.
|
||||||
|
|
||||||
|
The second byte tells the track number to which the first text piece in
|
||||||
|
a pack is associated. Number 0 means the whole album. Higher numbers are
|
||||||
|
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
|
||||||
|
one text for the disc and one for each track.
|
||||||
|
With types 0x88 and 0x89, the second byte bears a track number, too.
|
||||||
|
With type 0x8f, the second byte counts the record parts from 0 to 2.
|
||||||
|
|
||||||
|
The third byte is a sequential counter.
|
||||||
|
|
||||||
|
The fourth byte is the Block Number and Character Position Indicator.
|
||||||
|
It consists of three bit fields:
|
||||||
|
bit7 = Double Bytes Character Code (0= single byte characters)
|
||||||
|
bit4-6 = Block Number (groups text packs in language blocks)
|
||||||
|
bit0-3 = Character position. Either the number of characters which
|
||||||
|
the current text inherited from the previous pack, or
|
||||||
|
15 if the current text started before the previous pack.
|
||||||
|
|
||||||
|
The 12 payload bytes contain pieces of 0-terminated texts or binary data.
|
||||||
|
A text may span over several packs. Unused characters in a pack are used for
|
||||||
|
the next text of the same pack type. If no text of the same type follows,
|
||||||
|
then the remaining text bytes are set to 0.
|
||||||
|
|
||||||
|
The CRC algorithm uses divisor 0x11021. The resulting 16-bit residue of the
|
||||||
|
polynomial division gets inverted and written as big-endian number to bytes
|
||||||
|
16 and 17 of the pack.
|
||||||
|
|
||||||
|
|
||||||
|
The text packs are grouped in up to 8 blocks of at most 256 packs. Each block
|
||||||
|
is in charge for one language. Sequence numbers of each block are counted
|
||||||
|
separately. All packs of block 0 come before the packs of block 1.
|
||||||
|
|
||||||
|
The limitation of block number and sequence numbers imply that there are at
|
||||||
|
most 2048 text packs possible. (READ TOC/PMA/ATIP could retrieve 3640 packs,
|
||||||
|
as it is limited to 64 kB - 2.)
|
||||||
|
|
||||||
|
|
||||||
|
If a text of a track (pack types 0x80 to 0x85 and 0x8e) repeats identically
|
||||||
|
for the next track, then it may be represented by a TAB character (ASCII 9)
|
||||||
|
for single byte texts, and two TAB characters for double byte texts.
|
||||||
|
(This should be used because 256 * 12 bytes is few space for 99 tracks.)
|
||||||
|
|
||||||
|
The two binary bytes of pack type 0x87 are written to the first 0x87 pack of
|
||||||
|
a block. They may or may not be repeated at the start of the follow-up packs
|
||||||
|
of type 0x87.
|
||||||
|
|
||||||
|
The first pack of type 0x88 in a block records in its payload bytes:
|
||||||
|
0 : PMIN of POINT A1 = First Track Number
|
||||||
|
1 : PMIN of POINT A2 = Last Track Number
|
||||||
|
2 : unknown, 0 in Sony example
|
||||||
|
3 : PMIN of POINT A2 = Start position of Lead-Out
|
||||||
|
4 : PSEC of POINT A2 = Start position of Lead-Out
|
||||||
|
5 : PFRAME of POINT A2 = Start position of Lead-Out
|
||||||
|
6 to 11 : unknown, 0 in Sony example
|
||||||
|
The following packs record PMIN, PSEC, PFRAME of the POINTs between the
|
||||||
|
lowest track number (min 01h) and the highest track number (max 63h).
|
||||||
|
The payload of the last pack is padded by 0s.
|
||||||
|
The Sony .TOC example:
|
||||||
|
A0 01
|
||||||
|
A1 14
|
||||||
|
A2 63:02:18
|
||||||
|
01 00:02:00
|
||||||
|
02 04:11:25
|
||||||
|
03 08:02:50
|
||||||
|
04 11:47:62
|
||||||
|
...
|
||||||
|
13 53:24:25
|
||||||
|
14 57:03:25
|
||||||
|
yields
|
||||||
|
88 00 23 00 01 0e 00 3f 02 12 00 00 00 00 00 00 12 00
|
||||||
|
88 01 24 00 00 02 00 04 0b 19 08 02 32 0b 2f 3e 67 2d
|
||||||
|
...
|
||||||
|
88 0d 27 00 35 18 19 39 03 19 00 00 00 00 00 00 ea af
|
||||||
|
|
||||||
|
Pack type 0x89 is yet quite unclear. Especially what the information shall
|
||||||
|
mean to the user of the CD. The time points in the Sony example are in the
|
||||||
|
time range of the tracks numbers that are given before the time points:
|
||||||
|
01 02:41:48 01 02:52:58
|
||||||
|
06 23:14:25 06 23:29:60
|
||||||
|
07 28:30:39 07 28:42:30
|
||||||
|
13 55:13:26 13 55:31:50
|
||||||
|
yields
|
||||||
|
89 01 28 00 01 04 00 00 00 00 02 29 30 02 34 3a f3 0c
|
||||||
|
89 06 29 00 02 04 00 00 00 00 17 0e 19 17 1d 3c 73 92
|
||||||
|
89 07 2a 00 03 04 00 00 00 00 1c 1e 27 1c 2a 1e 72 20
|
||||||
|
89 0d 2b 00 04 04 00 00 00 00 37 0d 1a 37 1f 32 0b 62
|
||||||
|
The track numbers are stored in the track number byte of the packs. The two
|
||||||
|
time points are stored in byte 6 to 11 of the payload. Byte 0 of the payload
|
||||||
|
seems to be a sequential counter. Byte 1 always 4 ? Byte 2 to 5 always 0 ?
|
||||||
|
|
||||||
|
Pack type 0x8f summarizes the whole list of text packs of a block.
|
||||||
|
So there is one group of three 0x8f packs per block.
|
||||||
|
Nevertheless each 0x8f group tells the highest sequence number and the
|
||||||
|
language code of all blocks.
|
||||||
|
The payload bytes of three 0x8f packs form a 36 byte record. The track number
|
||||||
|
bytes of the three packs have the values 0, 1, 2.
|
||||||
|
Byte :
|
||||||
|
0 : Character code for pack types 0x80 to 0x85:
|
||||||
|
0x00 = ISO-8859-1
|
||||||
|
0x01 = 7 bit ASCII
|
||||||
|
0x80 = MS-JIS (japanese Kanji, double byte characters)
|
||||||
|
1 : Number of first track
|
||||||
|
2 : Number of last track
|
||||||
|
3 : libcdio source states: "cd-text information copyright byte"
|
||||||
|
Probably 3 means "copyrighted", 0 means "not copyrighted".
|
||||||
|
4 - 19 : Pack count of the various types 0x80 to 0x8f.
|
||||||
|
Byte number N tells the count of packs of type 0x80 + (N - 4).
|
||||||
|
I.e. the first byte in this field of 16 counts packs of type 0x80.
|
||||||
|
20 - 27 : Highest sequence byte number of blocks 0 to 7.
|
||||||
|
28 - 36 : Language code for blocks 0 to 7 (tech3264.pdf appendix 3)
|
||||||
|
Not all of these Codes have ever been seen with CD-TEXT, though.
|
||||||
|
0x00 = Unknown
|
||||||
|
0x01 = Albanian
|
||||||
|
0x02 = Breton
|
||||||
|
0x03 = Catalan
|
||||||
|
0x04 = Croatian
|
||||||
|
0x05 = Welsh
|
||||||
|
0x06 = Czech
|
||||||
|
0x07 = Danish
|
||||||
|
0x08 = German
|
||||||
|
0x09 = English
|
||||||
|
0x0a = Spanish
|
||||||
|
0x0b = Esperanto
|
||||||
|
0x0c = Estonian
|
||||||
|
0x0d = Basque
|
||||||
|
0x0e = Faroese
|
||||||
|
0x0f = French
|
||||||
|
0x10 = Frisian
|
||||||
|
0x11 = Irish
|
||||||
|
0x12 = Gaelic
|
||||||
|
0x13 = Galician
|
||||||
|
0x14 = Icelandic
|
||||||
|
0x15 = Italian
|
||||||
|
0x16 = Lappish
|
||||||
|
0x17 = Latin
|
||||||
|
0x18 = Latvian
|
||||||
|
0x19 = Luxembourgian
|
||||||
|
0x1a = Lithuanian
|
||||||
|
0x1b = Hungarian
|
||||||
|
0x1c = Maltese
|
||||||
|
0x1d = Dutch
|
||||||
|
0x1e = Norwegian
|
||||||
|
0x1f = Occitan
|
||||||
|
0x20 = Polish
|
||||||
|
0x21 = Portuguese
|
||||||
|
0x22 = Romanian
|
||||||
|
0x23 = Romansh
|
||||||
|
0x24 = Serbian
|
||||||
|
0x25 = Slovak
|
||||||
|
0x26 = Slovenian
|
||||||
|
0x27 = Finnish
|
||||||
|
0x28 = Swedish
|
||||||
|
0x29 = Turkish
|
||||||
|
0x2a = Flemish
|
||||||
|
0x2b = Wallon
|
||||||
|
0x45 = Zulu
|
||||||
|
0x46 = Vietnamese
|
||||||
|
0x47 = Uzbek
|
||||||
|
0x48 = Urdu
|
||||||
|
0x49 = Ukrainian
|
||||||
|
0x4a = Thai
|
||||||
|
0x4b = Telugu
|
||||||
|
0x4c = Tatar
|
||||||
|
0x4d = Tamil
|
||||||
|
0x4e = Tadzhik
|
||||||
|
0x4f = Swahili
|
||||||
|
0x50 = Sranan Tongo
|
||||||
|
0x51 = Somali
|
||||||
|
0x52 = Sinhalese
|
||||||
|
0x53 = Shona
|
||||||
|
0x54 = Serbo-croat
|
||||||
|
0x55 = Ruthenian
|
||||||
|
0x56 = Russian
|
||||||
|
0x57 = Quechua
|
||||||
|
0x58 = Pushtu
|
||||||
|
0x59 = Punjabi
|
||||||
|
0x5a = Persian
|
||||||
|
0x5b = Papamiento
|
||||||
|
0x5c = Oriya
|
||||||
|
0x5d = Nepali
|
||||||
|
0x5e = Ndebele
|
||||||
|
0x5f = Marathi
|
||||||
|
0x60 = Moldavian
|
||||||
|
0x61 = Malaysian
|
||||||
|
0x62 = Malagasay
|
||||||
|
0x63 = Macedonian
|
||||||
|
0x64 = Laotian
|
||||||
|
0x65 = Korean
|
||||||
|
0x66 = Khmer
|
||||||
|
0x67 = Kazakh
|
||||||
|
0x68 = Kannada
|
||||||
|
0x69 = Japanese
|
||||||
|
0x6a = Indonesian
|
||||||
|
0x6b = Hindi
|
||||||
|
0x6c = Hebrew
|
||||||
|
0x6d = Hausa
|
||||||
|
0x6e = Gurani
|
||||||
|
0x6f = Gujurati
|
||||||
|
0x70 = Greek
|
||||||
|
0x71 = Georgian
|
||||||
|
0x72 = Fulani
|
||||||
|
0x73 = Dari
|
||||||
|
0x74 = Churash
|
||||||
|
0x75 = Chinese
|
||||||
|
0x76 = Burmese
|
||||||
|
0x77 = Bulgarian
|
||||||
|
0x78 = Bengali
|
||||||
|
0x79 = Bielorussian
|
||||||
|
0x7a = Bambora
|
||||||
|
0x7b = Azerbaijani
|
||||||
|
0x7c = Assamese
|
||||||
|
0x7d = Armenian
|
||||||
|
0x7e = Arabic
|
||||||
|
0x7f = Amharic
|
||||||
|
E.g. these three packs
|
||||||
|
42 : 8f 00 2a 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
|
||||||
|
43 : 8f 01 2b 00 00 00 00 00 00 00 06 03 2c 00 00 00 c0 20
|
||||||
|
44 : 8f 02 2c 00 00 00 00 00 09 00 00 00 00 00 00 00 11 45
|
||||||
|
decode to
|
||||||
|
Byte :Value Meaning
|
||||||
|
0 : 01 = ASCII 7-bit
|
||||||
|
1 : 01 = first track is 1
|
||||||
|
2 : 03 = last track is 3
|
||||||
|
3 : 00 = copyright (0 = public domain, 3 = copyrighted ?)
|
||||||
|
4 : 06 = 6 packs of type 0x80
|
||||||
|
5 : 05 = 5 packs of type 0x81
|
||||||
|
6 : 04 = 4 packs of type 0x82
|
||||||
|
7 : 05 = 5 packs of type 0x83
|
||||||
|
8 : 07 = 7 packs of type 0x84
|
||||||
|
9 : 06 = 6 packs of type 0x85
|
||||||
|
10 : 01 = 1 pack of type 0x86
|
||||||
|
11 : 02 = 2 packs of type 0x87
|
||||||
|
12 : 00 = 0 packs of type 0x88
|
||||||
|
13 : 00 = 0 packs of type 0x89
|
||||||
|
14 : 00 00 00 00 = 0 packs of types 0x8a to 0x8d
|
||||||
|
18 : 06 = 6 packs of type 0x8e
|
||||||
|
19 : 03 = 3 packs of type 0x8f
|
||||||
|
20 : 2c = last sequence for block 0
|
||||||
|
This matches the sequence number of the last text pack (0x2c = 44)
|
||||||
|
21 : 00 00 00 00 00 00 00 = last sequence numbers for block 1..7 (none)
|
||||||
|
28 : 09 = language code for block 0: English
|
||||||
|
29 : 00 00 00 00 00 00 00 = language codes for block 1..7 (none)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Overview of libburn API calls for CD-TEXT (see libburn/libburn.h for details):
|
||||||
|
|
||||||
|
libburn can retrieve the array of text packs from a CD:
|
||||||
|
|
||||||
|
int burn_disc_get_leadin_text(struct burn_drive *d,
|
||||||
|
unsigned char **text_packs, int *num_packs,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
It can write a text pack set with a CD SAO session.
|
||||||
|
|
||||||
|
This set may be attached as array of readily formatted text packs by:
|
||||||
|
|
||||||
|
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
||||||
|
unsigned char *text_packs,
|
||||||
|
int num_packs, int flag);
|
||||||
|
|
||||||
|
The array of text packs may be read from a file by
|
||||||
|
|
||||||
|
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
|
||||||
|
int *num_packs, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
Alternatively the pack set may be defined by attaching CD-TEXT attributes
|
||||||
|
to burn_session and burn_track:
|
||||||
|
|
||||||
|
int burn_session_set_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int languages[8], int flag);
|
||||||
|
|
||||||
|
int burn_session_set_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag);
|
||||||
|
|
||||||
|
int burn_track_set_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char *payload, int length, int flag);
|
||||||
|
|
||||||
|
Macros list the texts for genre and language codes:
|
||||||
|
|
||||||
|
BURN_CDTEXT_LANGUAGES_0X00
|
||||||
|
BURN_CDTEXT_FILLER
|
||||||
|
BURN_CDTEXT_LANGUAGES_0X45
|
||||||
|
|
||||||
|
BURN_CDTEXT_GENRE_LIST
|
||||||
|
BURN_CDTEXT_NUM_GENRES
|
||||||
|
|
||||||
|
There is a reader for Sony Input Sheet Version 0.7T:
|
||||||
|
|
||||||
|
int burn_session_input_sheet_v07t(struct burn_session *session,
|
||||||
|
char *path, int block, int flag);
|
||||||
|
|
||||||
|
and a writer which converts an array of text packs to such a Sony Input Sheet:
|
||||||
|
|
||||||
|
int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs,
|
||||||
|
int start_tno, int track_count,
|
||||||
|
char **result, int *char_code, int flag);
|
||||||
|
|
||||||
|
CD-TEXT can be read from a CDRWIN cue sheet file which defines the tracks
|
||||||
|
of a session
|
||||||
|
|
||||||
|
int burn_session_by_cue_file(struct burn_session *session,
|
||||||
|
char *path, int fifo_size, struct burn_source **fifo,
|
||||||
|
unsigned char **text_packs, int *num_packs, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
The session and track attributes can then be converted into an array of
|
||||||
|
text packs by:
|
||||||
|
|
||||||
|
int burn_cdtext_from_session(struct burn_session *s,
|
||||||
|
unsigned char **text_packs, int *num_packs,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
or they can be written as array of text packs to CD when burning begins and
|
||||||
|
no array of pre-formatted packs was attached to the write options by
|
||||||
|
burn_write_opts_set_leadin_text().
|
||||||
|
|
||||||
|
There are calls for inspecting the attached attributes:
|
||||||
|
|
||||||
|
int burn_session_get_cdtext_par(struct burn_session *s,
|
||||||
|
int char_codes[8], int copyrights[8],
|
||||||
|
int block_languages[8], int flag);
|
||||||
|
|
||||||
|
int burn_session_get_cdtext(struct burn_session *s, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag);
|
||||||
|
|
||||||
|
int burn_track_get_cdtext(struct burn_track *t, int block,
|
||||||
|
int pack_type, char *pack_type_name,
|
||||||
|
unsigned char **payload, int *length, int flag);
|
||||||
|
|
||||||
|
and for removing attached attributes:
|
||||||
|
|
||||||
|
int burn_session_dispose_cdtext(struct burn_session *s, int block);
|
||||||
|
|
||||||
|
int burn_track_dispose_cdtext(struct burn_track *t, int block);
|
||||||
|
|
||||||
|
|
||||||
|
UPC/EAN and ISRC not only affect CD-TEXT but also information that is written
|
||||||
|
along with the tracks in Q sub-channel. These can be influenced by
|
||||||
|
burn_session_input_sheet_v07t(), burn_session_by_cue_file() and by
|
||||||
|
|
||||||
|
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
||||||
|
unsigned char mediacatalog[13]);
|
||||||
|
|
||||||
|
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
|
||||||
|
int has_mediacatalog);
|
||||||
|
|
||||||
|
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
|
||||||
|
unsigned char year, unsigned int serial);
|
||||||
|
|
||||||
|
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13],
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Sony Text File Format (Input Sheet Version 0.7T):
|
||||||
|
|
||||||
|
This text file format provides comprehensive means to define the text
|
||||||
|
attributes of session and tracks for a single block. More than one
|
||||||
|
such file has to be read to form an attribute set with multiple blocks.
|
||||||
|
|
||||||
|
The information is given by text lines of the following form:
|
||||||
|
purpose specifier [whitespace] = [whitespace] content text
|
||||||
|
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
|
||||||
|
The purpose specifier tells the meaning of the content text.
|
||||||
|
Empty content text does not cause a CD-TEXT attribute to be attached.
|
||||||
|
|
||||||
|
The following purpose specifiers apply to the session as a whole:
|
||||||
|
Specifier = Meaning
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
Text Code = Character code for pack type 0x8f
|
||||||
|
"ASCII", "8859"
|
||||||
|
Language Code = One of the language names for pack type 0x8f
|
||||||
|
Album Title = Content of pack type 0x80
|
||||||
|
Artist Name = Content of pack type 0x81
|
||||||
|
Songwriter = Content of pack type 0x82
|
||||||
|
Composer = Content of pack type 0x83
|
||||||
|
Arranger = Content of pack type 0x84
|
||||||
|
Album Message = Content of pack type 0x85
|
||||||
|
Catalog Number = Content of pack type 0x86
|
||||||
|
Genre Code = One of the genre names for pack type 0x87
|
||||||
|
Genre Information = Cleartext part of pack type 0x87
|
||||||
|
Closed Information = Content of pack type 0x8d
|
||||||
|
UPC / EAN = Content of pack type 0x8e
|
||||||
|
Text Data Copy Protection = Copyright value for pack type 0x8f
|
||||||
|
"ON" = 0x03, "OFF" = 0x00
|
||||||
|
First Track Number = The lowest track number used in the file
|
||||||
|
Last Track Number = The highest track number used in the file
|
||||||
|
|
||||||
|
The following purpose specifiers apply to particular tracks:
|
||||||
|
Track NN Title = Content of pack type 0x80
|
||||||
|
Track NN Artist = Content of pack type 0x81
|
||||||
|
Track NN Songwriter = Content of pack type 0x82
|
||||||
|
Track NN Composer = Content of pack type 0x83
|
||||||
|
Track NN Arranger = Content of pack type 0x84
|
||||||
|
Track NN Message = Content of pack type 0x85
|
||||||
|
ISRC NN = Content of pack type 0x8e
|
||||||
|
|
||||||
|
The following purpose specifiers have no effect on CD-TEXT:
|
||||||
|
Remarks = Comments with no influence on CD-TEXT
|
||||||
|
Disc Information NN = Supplementary information for use by record companies.
|
||||||
|
ISO-8859-1 encoded. NN ranges from 01 to 04.
|
||||||
|
Input Sheet Version = "0.7T"
|
||||||
|
|
||||||
|
|
||||||
|
libburn peculiarties:
|
||||||
|
|
||||||
|
libburn may read files of the described format by
|
||||||
|
burn_session_input_sheet_v07t()
|
||||||
|
after the burn_session has been establiched and all burn_track objects have
|
||||||
|
been added. It can convert an array of CD-TEXT packs into this format by
|
||||||
|
burn_make_input_sheet_v07t()
|
||||||
|
|
||||||
|
The following purpose specifiers accept byte values of the form 0xXY.
|
||||||
|
Text Code , Language Code , Genre Code , Text Data Copy Protection
|
||||||
|
E.g. to indicate MS-JIS character code (of which the exact name is unknown):
|
||||||
|
Text Code = 0x80
|
||||||
|
Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT.
|
||||||
|
Genre Code = 0x001b
|
||||||
|
|
||||||
|
Purpose specifiers which have the meaning "Content of pack type 0xXY"
|
||||||
|
may be replaced by the pack type codes. E.g.:
|
||||||
|
0x80 = Session content of pack type 0x80
|
||||||
|
Track 02 0x80 = Track content of pack type 0x80 for track 2.
|
||||||
|
Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e.
|
||||||
|
|
||||||
|
Text Code may be specified only once. It gets speficied to "ISO-8850-1"
|
||||||
|
automatically as soon as content is defined which depends on the text
|
||||||
|
encoding of the block. I.e with pack types 0x80 to 0x85.
|
||||||
|
|
||||||
|
If a track attribute is set, but the corresponding session attribute is not
|
||||||
|
defined or defined with empty text, then the session attribute gets attached
|
||||||
|
as empty test. (Normally empty content is ignored.)
|
||||||
|
|
||||||
|
|
||||||
|
Example cdrskin run with three tracks:
|
||||||
|
|
||||||
|
$ cdrskin dev=/dev/sr0 -v input_sheet_v07t=NIGHTCATS.TXT \
|
||||||
|
-audio -swab track_source_1 track_source_2 track_source_3
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
Content of file NIGHTCATS.TXT :
|
||||||
|
----------------------------------------------------------
|
||||||
|
Input Sheet Version = 0.7T
|
||||||
|
Text Code = 8859
|
||||||
|
Language Code = English
|
||||||
|
Album Title = Joyful Nights
|
||||||
|
Artist Name = United Cat Orchestra
|
||||||
|
Songwriter = Various Songwriters
|
||||||
|
Composer = Various Composers
|
||||||
|
Arranger = Tom Cat
|
||||||
|
Album Message = For all our fans
|
||||||
|
Catalog Number = 1234567890
|
||||||
|
Genre Code = Classical
|
||||||
|
Genre Information = Feline classic music
|
||||||
|
Closed Information = This is not to be shown by CD players
|
||||||
|
UPC / EAN = 1234567890123
|
||||||
|
Text Data Copy Protection = OFF
|
||||||
|
First Track Number = 1
|
||||||
|
Last Track Number = 3
|
||||||
|
Track 01 Title = Song of Joy
|
||||||
|
Track 01 Artist = Felix and The Purrs
|
||||||
|
Track 01 Songwriter = Friedrich Schiller
|
||||||
|
Track 01 Composer = Ludwig van Beethoven
|
||||||
|
Track 01 Arranger = Tom Cat
|
||||||
|
Track 01 Message = Fritz and Louie once were punks
|
||||||
|
ISRC 01 = XYBLG1101234
|
||||||
|
Track 02 Title = Humpty Dumpty
|
||||||
|
Track 02 Artist = Catwalk Beauties
|
||||||
|
Track 02 Songwriter = Mother Goose
|
||||||
|
Track 02 Composer = unknown
|
||||||
|
Track 02 Arranger = Tom Cat
|
||||||
|
Track 02 Message = Pluck the goose
|
||||||
|
ISRC 02 = XYBLG1100005
|
||||||
|
Track 03 Title = Mee Owwww
|
||||||
|
Track 03 Artist = Mia Kitten
|
||||||
|
Track 03 Songwriter = Mia Kitten
|
||||||
|
Track 03 Composer = Mia Kitten
|
||||||
|
Track 03 Arranger = Mia Kitten
|
||||||
|
Track 03 Message =
|
||||||
|
ISRC 03 = XYBLG1100006
|
||||||
|
----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
CDRWIN cue sheet files:
|
||||||
|
|
||||||
|
A CDRWIN cue sheet file defines the track data source (FILE), various text
|
||||||
|
attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types
|
||||||
|
(TRACK), track start addresses (INDEX).
|
||||||
|
The rules for CDRWIN cue sheet files are described at
|
||||||
|
http://digitalx.org/cue-sheet/syntax/
|
||||||
|
There are three more text attributes mentioned in man cdrecord for defining
|
||||||
|
the corresponding CD-TEXT attributes: ARRANGER, COMPOSER, MESSAGE.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------
|
||||||
|
Example of a CDRWIN cue sheet file named NIGHTCATS.CUE :
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
CATALOG 1234567890123
|
||||||
|
FILE "audiodata.bin" BINARY
|
||||||
|
TITLE "Joyful Nights"
|
||||||
|
TRACK 01 AUDIO
|
||||||
|
FLAGS DCP
|
||||||
|
TITLE "Song of Joy"
|
||||||
|
PERFORMER "Felix and The Purrs"
|
||||||
|
SONGWRITER "Friedrich Schiller"
|
||||||
|
ISRC XYBLG1101234
|
||||||
|
INDEX 01 00:00:00
|
||||||
|
TRACK 02 AUDIO
|
||||||
|
FLAGS DCP
|
||||||
|
TITLE "Humpty Dumpty"
|
||||||
|
PERFORMER "Catwalk Beauties"
|
||||||
|
SONGWRITER "Mother Goose"
|
||||||
|
ISRC XYBLG1100005
|
||||||
|
INDEX 01 08:20:12
|
||||||
|
TRACK 03 AUDIO
|
||||||
|
FLAGS DCP
|
||||||
|
TITLE "Mee Owwww"
|
||||||
|
PERFORMER "Mia Kitten"
|
||||||
|
SONGWRITER "Mia Kitten"
|
||||||
|
ISRC XYBLG1100006
|
||||||
|
INDEX 01 13:20:33
|
||||||
|
|
||||||
|
By
|
||||||
|
|
||||||
|
$ cdrskin -v dev=/dev/sr0 -text cuefile=NIGHTCATS.CUE
|
||||||
|
|
||||||
|
this yields as text packs:
|
||||||
|
|
||||||
|
0 : 80 00 00 00 J o y f u l N i g h t f0 f7
|
||||||
|
1 : 80 00 01 0c s 00 S o n g o f J o 43 1c
|
||||||
|
2 : 80 01 02 0a y 00 H u m p t y D u m 43 f9
|
||||||
|
3 : 80 02 03 0a p t y 00 M e e O w w w 24 72
|
||||||
|
4 : 80 03 04 08 w 00 00 00 00 00 00 00 00 00 00 00 6e af
|
||||||
|
5 : 81 00 05 00 00 F e l i x a n d T 4d 51
|
||||||
|
6 : 81 01 06 0b h e P u r r s 00 C a t a7 40
|
||||||
|
7 : 81 02 07 03 w a l k B e a u t i e 59 80
|
||||||
|
8 : 81 02 08 0f s 00 M i a K i t t e n 30 c9
|
||||||
|
9 : 81 03 09 0a 00 00 00 00 00 00 00 00 00 00 00 00 ad 19
|
||||||
|
10 : 82 00 0a 00 00 F r i e d r i c h S 70 8f
|
||||||
|
11 : 82 01 0b 0b c h i l l e r 00 M o t h 33 43
|
||||||
|
12 : 82 02 0c 04 e r G o o s e 00 M i a d6 f5
|
||||||
|
13 : 82 03 0d 03 K i t t e n 00 00 00 00 00 f5 83
|
||||||
|
14 : 8e 00 0e 00 1 2 3 4 5 6 7 8 9 0 1 2 92 3e
|
||||||
|
15 : 8e 00 0f 0c 3 00 X Y B L G 1 1 0 1 2 c0 2b
|
||||||
|
16 : 8e 01 10 0a 3 4 00 X Y B L G 1 1 0 0 bb b3
|
||||||
|
17 : 8e 02 11 09 0 0 5 00 X Y B L G 1 1 0 f3 bf
|
||||||
|
18 : 8e 03 12 08 0 0 0 6 00 00 00 00 00 00 00 00 5b 5c
|
||||||
|
19 : 8f 00 13 00 00 01 03 00 05 05 04 00 00 00 00 00 9b fe
|
||||||
|
20 : 8f 01 14 00 00 00 00 00 00 00 05 03 15 00 00 00 11 0b
|
||||||
|
21 : 8f 02 15 00 00 00 00 00 09 00 00 00 00 00 00 00 da 77
|
||||||
|
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Some restrictions apply in the libburn call burn_session_by_cue_file():
|
||||||
|
|
||||||
|
Only FILE types BINARY, MOTOROLA, WAVE are allowed.
|
||||||
|
Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in
|
||||||
|
the same session.
|
||||||
|
|
||||||
|
On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally.
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
|
||||||
|
Permission is granted to copy, modify, and distribute it, as long as the
|
||||||
|
references to the original information sources are maintained.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
19
doc/comments
19
doc/comments
|
@ -8,14 +8,13 @@
|
||||||
Libburnia is an open-source project for reading, mastering and writing
|
Libburnia is an open-source project for reading, mastering and writing
|
||||||
optical discs. This page is about its capability to handle optical media.
|
optical discs. This page is about its capability to handle optical media.
|
||||||
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
||||||
DVD-R, BD-R, BD-RE.
|
DVD-R, DVD-R/DL, BD-R, BD-RE.
|
||||||
|
|
||||||
Not supported yet are DVD-R/DL. Testers wanted.
|
Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD.
|
||||||
|
For ports to other systems we would need : login on a development machine or
|
||||||
Our scope is currently Linux 2.4 and 2.6, or FreeBSD . For ports to other
|
an OS that is installable on an AMD 64-bit PC, advise from a system person
|
||||||
systems we would need : login on a development machine resp. a live OS on CD
|
about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of
|
||||||
or DVD, advise from a system person about the equivalent of Linux sg or FreeBSD
|
realistic use cases.
|
||||||
CAM, volunteers for testing of realistic use cases.
|
|
||||||
|
|
||||||
libburn is the library by which preformatted data get onto optical media.
|
libburn is the library by which preformatted data get onto optical media.
|
||||||
Its code is independent of cdrecord. Its DVD capabilities are learned from
|
Its code is independent of cdrecord. Its DVD capabilities are learned from
|
||||||
|
@ -53,7 +52,7 @@ and execute
|
||||||
|
|
||||||
- make
|
- make
|
||||||
|
|
||||||
To make the libraries accessible for running resp. developing applications
|
To make the libraries accessible for running and developing applications
|
||||||
|
|
||||||
- make install
|
- make install
|
||||||
|
|
||||||
|
@ -73,9 +72,9 @@ compatible for a good while.
|
||||||
@subsection libburner-help Libburner --help
|
@subsection libburner-help Libburner --help
|
||||||
<pre>
|
<pre>
|
||||||
Usage: test/libburner
|
Usage: test/libburner
|
||||||
[--drive <address>|<driveno>|"-"] [--audio]
|
[--drive address|driveno|"-"] [--audio]
|
||||||
[--blank_fast|--blank_full|--format] [--try_to_simulate]
|
[--blank_fast|--blank_full|--format] [--try_to_simulate]
|
||||||
[--multi] [<one or more imagefiles>|"-"]
|
[--multi] [one or more imagefiles|"-"]
|
||||||
Examples
|
Examples
|
||||||
A bus scan (needs rw-permissions to see a drive):
|
A bus scan (needs rw-permissions to see a drive):
|
||||||
test/libburner --drive -
|
test/libburner --drive -
|
||||||
|
|
242
doc/cookbook.txt
242
doc/cookbook.txt
|
@ -1,4 +1,10 @@
|
||||||
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Note: This is about how libburn operates optical drives. Not about how to
|
||||||
|
operate libburn. The libburn API is described in libburn/libburn.h
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
libburnia-project.org Optical Media Rotisserie Recipes as of December 2011
|
||||||
|
|
||||||
Content:
|
Content:
|
||||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||||
|
@ -86,12 +92,17 @@ parameters:
|
||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
|
Copy Whether to deny copying 1 = deny by SCMS , 0 = allow
|
||||||
Track Mode Describes frame type 4 for data , 0 for audio
|
Track Mode Describes frame type 4 for data , 0 for audio
|
||||||
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
||||||
0 for 2352 byte audio blocks
|
0 for 2352 byte audio blocks
|
||||||
Audio Pause Length 150 = 2 seconds
|
Audio Pause Length 150 = 2 seconds
|
||||||
|
Media Catalog Number A property of the disc 0x80 if valid
|
||||||
|
13 decimal digits as ASCII
|
||||||
|
ISRC A property of the track 0x80 if valid
|
||||||
|
12 letters and digits, ASCII
|
||||||
Any other parameters may be set to 0.
|
Any other parameters may be set to 0.
|
||||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||||
|
@ -119,19 +130,22 @@ A track must at least contain 300 payload blocks: 4 seconds of audio or
|
||||||
600 KiB of data.
|
600 KiB of data.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
|
|
||||||
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
|
Up to december 2009 the track was closed by 5Bh CLOSE TRACK SESSION Close
|
||||||
Older MMC specifies a valid Logical Track Number FFh to depict the open track.
|
Function 001b. Older MMC specifies a valid Logical Track Number FFh to depict
|
||||||
MMC-5 is quite silent about this. FFh works for my drives.
|
the open track. MMC-5 is quite silent about this. FFh worked for my drives.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
|
This is omitted since libburn-0.7.4, relying entirely on 35h SYNCHRONIZE CACHE.
|
||||||
|
First appeared a drive where CLOSE TRACK fails in simulation mode, later
|
||||||
|
another one produced error replies even with real burning.
|
||||||
|
|
||||||
After that, a new track may be written beginning with sending the mode page 05h
|
After that, a new track may be written beginning with sending the mode page 05h
|
||||||
again. It is not tested wether 05h can be omitted if Track Mode and Data Block
|
again. It is not tested whether 05h can be omitted if Track Mode and Data Block
|
||||||
Type are the same as with the previous track.
|
Type are the same as with the previous track.
|
||||||
The new track will be added to the session which was opened by the first track.
|
The new track will be added to the session which was opened by the first track.
|
||||||
|
|
||||||
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
||||||
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
||||||
value in mode page 05h wether the disc is finalized or stays appendable.
|
value in mode page 05h whether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.1.3)
|
(mmc5r03c.pdf 6.3.3.1.3)
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,7 +198,9 @@ If POINT is >= 1 and <= 99 (63h) then the descriptor is about the track of
|
||||||
which POINT tells the number.
|
which POINT tells the number.
|
||||||
The start address of this track can be read from PMIN, PSEC, PFRAME where
|
The start address of this track can be read from PMIN, PSEC, PFRAME where
|
||||||
it is encoded in MSF format:
|
it is encoded in MSF format:
|
||||||
blocks = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
If M is smaller than 90: LBA = (M * 60 + S) * 75 + F - 150
|
||||||
|
Else : LBA = (M * 60 + S) * 75 + F - 450150
|
||||||
|
|
||||||
The length of the track is given by MIN,SEC,FRAME in the same format.
|
The length of the track is given by MIN,SEC,FRAME in the same format.
|
||||||
|
|
||||||
If POINT = A0h then the descriptor tells in PMIN the first track number of its
|
If POINT = A0h then the descriptor tells in PMIN the first track number of its
|
||||||
|
@ -202,7 +218,7 @@ for finalized disc.
|
||||||
In libburn the address of the first track in the last session is obtained from
|
In libburn the address of the first track in the last session is obtained from
|
||||||
the last session's POINT = A0h and from the track descriptor with the POINT
|
the last session's POINT = A0h and from the track descriptor with the POINT
|
||||||
value matching the PMIN value of the A0h descriptor.
|
value matching the PMIN value of the A0h descriptor.
|
||||||
Untested is wether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
Untested is whether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
||||||
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,10 +227,12 @@ sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
SAO CD Cookbook
|
SAO CD Cookbook
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Guided by reading libburn/* from http://icculus.org/burn
|
Guided by reading libburn/* from http://icculus.org/burn
|
||||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||||
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S
|
backed by reading scms.html from
|
||||||
which used in part code from http://icculus.org/burn.
|
http://www.barrel-of-monkeys.com/graphics/prod/dvdplayers/
|
||||||
|
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S,
|
||||||
|
Optiarc BD RW BD-5300S, LG BDDVDRW GGC-H20L
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
@ -251,46 +269,96 @@ Each entry of the sheet is of 8 bytes size. Its fields are named
|
||||||
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
|
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
|
||||||
(mmc5r03c.pdf 6.33)
|
(mmc5r03c.pdf 6.33)
|
||||||
|
|
||||||
CTL is 40h for data and 00h for audio.
|
CTL is comprised of four bits:
|
||||||
|
bit4 = Pre-emphasis (audio only)
|
||||||
|
bit5 = Digital copy permission:
|
||||||
|
0 = prohibited (one-time copy is permitted if SCMS is 00h)
|
||||||
|
1 = permitted (unlimited)
|
||||||
|
bit6 = Data track indicator (bit4 and bit7 shall be 0)
|
||||||
|
bit7 = 4-channel audio
|
||||||
|
Usually CTL is 40h for data and 00h for audio.
|
||||||
(mmc5r03c.pdf 6.33.3.4)
|
(mmc5r03c.pdf 6.33.3.4)
|
||||||
ADR is always 01h.
|
ADR is 01h for entries which define time points. It is 02h for media catalog
|
||||||
TNO is the track number (1 to 99).
|
entries and it is 03h for track ISRC entries.
|
||||||
INDEX is a subaddress within tracks. This recipe uses only INDEX 01h within
|
The bits of CTL and ADR are combined in the CTL|ADR byte.
|
||||||
tracks.
|
|
||||||
|
TNO is the track number. The TNO of the first track may be chosen in the range
|
||||||
|
of 1 to 99. The TNO of following tracks must be the TNO of their predecessor
|
||||||
|
plus 1. The last track must not have a TNO larger than 99.
|
||||||
|
|
||||||
|
INDEX is a subaddress within tracks. INDEX 1 is mandatory and marks the start
|
||||||
|
of the payload area of a track. The range between INDEX 0 and 1 is called
|
||||||
|
pre-gap. It should contain zeros if it exists. Further cue sheet entries with
|
||||||
|
consecutive INDEX numbers mark ranges within the track. The range of the last
|
||||||
|
index may contain a post-gap with zeros.
|
||||||
(mmc5r03c.pdf 4.2.3.5.2)
|
(mmc5r03c.pdf 4.2.3.5.2)
|
||||||
DATA FORM is 00h for audio payload , 10h for data. (01h for audio pause is not
|
A pre-gap of 2 seconds is mandatory only for the first track. Pre-gap and
|
||||||
used in libburn).
|
post-gap may be needed with further tracks if they have neighbors with
|
||||||
|
different DATA FORM values. (Such mixing is not yet supported by libburn.)
|
||||||
|
|
||||||
|
DATA FORM is 00h for audio payload, 01h for audio pause (Lead-in and Lead-out),
|
||||||
|
10h for data, 14h for data pause (Lead-in and Lead-out).
|
||||||
|
This shall be ored with 40h for CD-TEXT in Lead-in.
|
||||||
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
|
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
|
||||||
SCMS is always 00h.
|
|
||||||
|
SCMS value 80h in conjunction with bit5 of CTL is an indicator for exhausted
|
||||||
|
one-time-copy permission. If this permission is still intact, then SCMS is 00h.
|
||||||
|
|
||||||
MIN, SEC, FRAME give the MSF address where the described data entity starts.
|
MIN, SEC, FRAME give the MSF address where the described data entity starts.
|
||||||
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
||||||
This address must increase from entry to entry (or at least stay equal).
|
This address must increase from entry to entry (or at least stay equal).
|
||||||
|
|
||||||
|
|
||||||
The first entry describes the Lead-in. Its content is
|
The first two entries in a Cue Sheet may describe the Media Catalog Number,
|
||||||
(CTL|ADR ,00h,00h,01h,00h,00h,00h,00h)
|
a string of 13 characters, also known with CD-TEXT as "UPC/EAN".
|
||||||
|
(02h, catalog characters 1 to 7)
|
||||||
|
(02h, catalog characters 8 to 13, 00h)
|
||||||
|
These two entries shall be omitted if no catalog number is given.
|
||||||
|
|
||||||
|
The next entry (eventually being the first one) describes the Lead-in.
|
||||||
|
Its content is
|
||||||
|
(CTL|ADR ,00h,00h, DATA FORM ,00h,00h,00h,00h)
|
||||||
With the CTL|ADR for the first track: 41h for data, 01h for audio.
|
With the CTL|ADR for the first track: 41h for data, 01h for audio.
|
||||||
|
DATA FORM is pause (audio=01h, data=14h). Ored with 40h if CD-TEXT shall
|
||||||
|
be stored in Lean-in.
|
||||||
|
|
||||||
The LBA for the first write is negative: -150. This corresponds to MSF address
|
The LBA for the first write is negative: -150. This corresponds to MSF address
|
||||||
00h:00h:00h. All addresses are to be given in MSF format.
|
00h:00h:00h. All addresses are to be given in MSF format.
|
||||||
The first information track on disc is preceded by a pause encoding of 2 sec:
|
|
||||||
|
Each track may be preceded by two entries describing an ISRC string of 12
|
||||||
|
characters.
|
||||||
|
(CTL | 03h, TNO, characters 1 to 6)
|
||||||
|
(CTL | 03h, TNO, characters 7 to 12)
|
||||||
|
These entries shall be omitted if no ISRC is given for the track.
|
||||||
|
CTL shall be the same as with the track.
|
||||||
|
|
||||||
|
The first information track on disc is preceded by a pause encoding or pre-gap
|
||||||
|
of at least 2 seconds:
|
||||||
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
|
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
|
||||||
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
|
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
|
||||||
address increases to 00h:02h:00h = LBA 0.
|
address increases to 00h:02h:00h = LBA 0. Optional further sectors may occupy
|
||||||
|
addresses larger than 0. This entry has to come after ISRC, if ISRC is given
|
||||||
|
for the track. INDEX has to be 0.
|
||||||
|
|
||||||
Each track is represented by an entry
|
Each track is represented by one or more entries, with increasing index number.
|
||||||
|
At least the entry for INDEX 1 has to exist:
|
||||||
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
||||||
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
|
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
|
||||||
the start address of the track. The MSF address is then increased by the size
|
the start address of the track. The MSF address is then increased by the size
|
||||||
of the track (to be used with next track or with lead-out).
|
of the track (to be used with next track or with lead-out).
|
||||||
|
There may be more entries with INDEX 2 to 99. Their MSF address tells the
|
||||||
|
sector where their range starts. This range ends at the MSF of the next entry
|
||||||
|
in the cue sheet. INDEX information is stored in the sub-channel of the sectors
|
||||||
|
but not in the Table-of-Content of the disc.
|
||||||
|
|
||||||
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
||||||
600 KiB of data.
|
600 KiB of data.
|
||||||
(mmc5r03c.pdf 6.33.3.6)
|
(mmc5r03c.pdf 6.33.3.6)
|
||||||
|
|
||||||
At the end of the session there is a lead-out entry
|
At the end of the session there is a lead-out entry
|
||||||
(CTL|ADR,AAh,01h,01h,00h,MIN,SEC,FRAME)
|
(CTL|ADR,AAh,01h,DATA FORM,00h,MIN,SEC,FRAME)
|
||||||
marking the end of the last track. (With libburn CTL is as of the last track.)
|
marking the end of the last track. (With libburn CTL is as of the last track.)
|
||||||
|
DATA FORM is 01h for audio, 14h for data.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -303,16 +371,26 @@ next lower possible value by the drive. So it is helpful to add a few
|
||||||
kbytes/sec just in case the drive has rounding problems.
|
kbytes/sec just in case the drive has rounding problems.
|
||||||
(mmc5r03c.pdf 6.37)
|
(mmc5r03c.pdf 6.37)
|
||||||
|
|
||||||
|
If CD-TEXT shall be written into Lead-in, then it is necessary to obtain the
|
||||||
|
Start Time of Lead-in by 43h READ TOC/PMA/ATIP Format 0100b. It is an MFS
|
||||||
|
address which varies from media manufacturer to media manufacturer.
|
||||||
|
Minute will be >= 90. Therefore this conversion applies:
|
||||||
|
LBA = (M * 60 + S) * 75 + F - 450150
|
||||||
|
|
||||||
A Write Parameters mode page 05h has to be composed and transmitted via
|
A Write Parameters mode page 05h has to be composed and transmitted via
|
||||||
55h MODE SELECT. This page describes the following parameters:
|
55h MODE SELECT. This page describes the following parameters:
|
||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 0 (is ignored)
|
Track Mode Describes frame type 0 (is ignored)
|
||||||
Data Block Type Layout of payload blocks 0 (is ignored)
|
Data Block Type Layout of payload blocks 0 (is ignored)
|
||||||
Audio Pause Length 150 = 2 seconds (ignored ?)
|
Audio Pause Length 150 = 2 seconds (ignored ?)
|
||||||
|
Media Catalog Number 0x80 if valid
|
||||||
|
See also Cue Sheet ADR 02h 13 decimal digits as ASCII
|
||||||
|
(With SAO, ISRC is transmitted only by the Cue Sheet.)
|
||||||
|
|
||||||
Any other parameters may be set to 0.
|
Any other parameters may be set to 0.
|
||||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||||
|
@ -329,15 +407,32 @@ blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be
|
||||||
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
||||||
can be written.
|
can be written.
|
||||||
(mmc5r03c.pdf, 6.44)
|
(mmc5r03c.pdf, 6.44)
|
||||||
Writing begins at LBA -150 which is to be transmitted as 4-byte, Big-endian,
|
Block addresses may be negative for areas before the normally readable
|
||||||
two's-complement. E.g: -150 = FFh FFh FFh 6Ah. This is the natural form found
|
data. Data representation of addresses is 4-byte, big-endian, two's-complement.
|
||||||
with about any 32-bit processor, so only the endianness has to be taken into
|
E.g: -150 = FFh FFh FFh 6Ah.
|
||||||
respect when converting a 32-bit integer into a LBA for command 2Ah WRITE.
|
This is the natural form found with about any 32-bit processor, so only
|
||||||
|
the endianness has to be taken into respect when converting a 32-bit
|
||||||
|
integer into a LBA for command 2Ah WRITE.
|
||||||
|
|
||||||
|
If CD-TEXT shall be written into Lead-in, then writing begins at the start
|
||||||
|
address of Lead-in, which was obtained above.
|
||||||
|
The 18 bytes of each text pack have to be split up to 24 bytes with only the
|
||||||
|
lowest six bits used in each byte. E.g. text pack
|
||||||
|
8F 00 2A 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
|
||||||
|
becomes
|
||||||
|
23 30 00 2A 00 00 04 01 00 30 00 06 01 10 10 05 01 30 18 01 00 24 21 25
|
||||||
|
4 of these 24 byte packs form a block of DATA FORM 41h. I.e. only 96 bytes
|
||||||
|
payload per block. The whole range from Lead-in start to LBA -150 has to be
|
||||||
|
filled with blocks of this form. Therefore it is necessary to write the
|
||||||
|
list of given packs in repeated cycles.
|
||||||
|
A typical Lead-in start address is -11635 = FFh FFh D2h 8Dh.
|
||||||
|
A description of the CD-TEXT pack format is given in file doc/cdtext.txt .
|
||||||
|
|
||||||
At first the mandatory pause preceding the first track has to be written as
|
Writing without CD-TEXT begins at LBA -150 = FFh FFh FFh 6Ah.
|
||||||
150 blocks of the matching sector size: 2048 for data, 2352 for audio.
|
|
||||||
By this, the LBA increases from -150 to 0.
|
In both cases, the mandatory pause preceding the first track has to be
|
||||||
|
written as 150 blocks of the matching sector size: 2048 for data,
|
||||||
|
2352 for audio. By this, the LBA increases from -150 to 0.
|
||||||
|
|
||||||
Next the tracks' payload is sent. For each track exactly the number of blocks
|
Next the tracks' payload is sent. For each track exactly the number of blocks
|
||||||
has to be transmitted as is announced in the Cue Sheet by the difference
|
has to be transmitted as is announced in the Cue Sheet by the difference
|
||||||
|
@ -349,7 +444,7 @@ There is no separator between the tracks of a pure mode SAO session.
|
||||||
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
||||||
between data mode tracks and audio mode tracks.)
|
between data mode tracks and audio mode tracks.)
|
||||||
(libburn sends its own buffer to the drive at the end of each track but does
|
(libburn sends its own buffer to the drive at the end of each track but does
|
||||||
not sync the drive's chache. It is unclear wether this separation of tracks
|
not sync the drive's chache. It is unclear whether this separation of tracks
|
||||||
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
||||||
harm in any case and would probably be unavoidable if audio and data tracks
|
harm in any case and would probably be unavoidable if audio and data tracks
|
||||||
were mixed.)
|
were mixed.)
|
||||||
|
@ -361,6 +456,21 @@ to media by 35h SYNCHRONIZE CACHE.
|
||||||
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Obtaining CD-TEXT from Lead-in :
|
||||||
|
|
||||||
|
Audio CDs may contain CD-TEXT information in their Lead-in. It is gained by
|
||||||
|
43h READ TOC/PMA/ATIP, Format 0101b. The reply consists of 4 bytes header,
|
||||||
|
of which the first two bytes give the number of following bytes as big-endian
|
||||||
|
16 bit number. The other two bytes are 0.
|
||||||
|
Following are text packs of 18 bytes each.
|
||||||
|
(mmc5r03c.pdf 6.26.3.7.1 table 495)
|
||||||
|
|
||||||
|
|
||||||
|
A description of CD-TEXT packs and of the applicable libburn API calls is
|
||||||
|
given in file doc/cdtext.txt .
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
What is known about mixed mode sessions :
|
What is known about mixed mode sessions :
|
||||||
|
|
||||||
|
@ -508,7 +618,7 @@ BG Format 3 indicates fully formatted media.
|
||||||
|
|
||||||
DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum
|
DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum
|
||||||
size given as Number Of Blocks, or by writing sequentially until the disc is
|
size given as Number Of Blocks, or by writing sequentially until the disc is
|
||||||
completely full into an intermediate session opened by format 15h resp. 13h.
|
completely full into an intermediate session opened by format 15h or 13h.
|
||||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.1, 6.5.4.2.10, 6.5.4.2.8)
|
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.1, 6.5.4.2.10, 6.5.4.2.8)
|
||||||
A fully formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
A fully formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
||||||
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
||||||
|
@ -537,7 +647,7 @@ In the reply, BG Format 0 indicates unformatted media (or unsuitable media).
|
||||||
(mmc5r03c.pdf 6.22.3.1.13)
|
(mmc5r03c.pdf 6.22.3.1.13)
|
||||||
|
|
||||||
Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h.
|
Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h.
|
||||||
Different from other format types, 26h allows to send a fantasy size of
|
Different from other format types, 26h is allowed to send a fantasy size of
|
||||||
0xffffffff blocks and does not require the caller to know the exact maximum
|
0xffffffff blocks and does not require the caller to know the exact maximum
|
||||||
size offered with that format.
|
size offered with that format.
|
||||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
||||||
|
@ -634,7 +744,7 @@ Elsewise the media is in Intermediate state. See below.
|
||||||
A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
||||||
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
||||||
Media") and the Number Of Blocks with formats 00h, 10h or 15h is larger than the
|
Media") and the Number Of Blocks with formats 00h, 10h or 15h is larger than the
|
||||||
currently formatted size, resp. more than 0 blocks are offered with Format
|
currently formatted size, or more than 0 blocks are offered with Format
|
||||||
Types 13h or 11h.
|
Types 13h or 11h.
|
||||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
||||||
|
|
||||||
|
@ -643,7 +753,7 @@ be unnecessary to do any further formatting.
|
||||||
But in order to make the DVD-RW surely accept its maximum number of bytes,
|
But in order to make the DVD-RW surely accept its maximum number of bytes,
|
||||||
partial formatting may be expanded by command 04h FORMAT UNIT, Format Type 13h,
|
partial formatting may be expanded by command 04h FORMAT UNIT, Format Type 13h,
|
||||||
which is supposed to be offered by the drive in this state. This brings the
|
which is supposed to be offered by the drive in this state. This brings the
|
||||||
session again into Intermediate state and thus allows expansion by sequential
|
session again into Intermediate state and thus enables expansion by sequential
|
||||||
writing. As with Format Type 15h it is ok to set Number Of Blocks to 0, so that
|
writing. As with Format Type 15h it is ok to set Number Of Blocks to 0, so that
|
||||||
no fixed size formatting work is done and writing can begin soon after.
|
no fixed size formatting work is done and writing can begin soon after.
|
||||||
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
|
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
|
||||||
|
@ -693,8 +803,8 @@ Two format types are relevant for DVD-RAM : 00h and 01h.
|
||||||
00h offers the default size format and usually a maximum payload size format.
|
00h offers the default size format and usually a maximum payload size format.
|
||||||
Even with that maximum size payload there is hardware defect management.
|
Even with that maximum size payload there is hardware defect management.
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.2)
|
(mmc5r03c.pdf 6.5.4.2.1.2)
|
||||||
01h allows to convert payload capacity into spare blocks for defect
|
01h can convert payload capacity into spare blocks for defect management.
|
||||||
managment. There is no way to increase payload capacity by format 01h.
|
There is no way to increase payload capacity by format 01h.
|
||||||
(mmc5r03c.pdf 6.5.4.2.2.1)
|
(mmc5r03c.pdf 6.5.4.2.2.1)
|
||||||
|
|
||||||
With BD-RE there are three format types : 00h, 30h and 31h.
|
With BD-RE there are three format types : 00h, 30h and 31h.
|
||||||
|
@ -755,7 +865,8 @@ The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
|
||||||
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
||||||
(mmc5r03c.pdf 6.45)
|
(mmc5r03c.pdf 6.45)
|
||||||
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
||||||
With the tested BD-RE one has to write full 64 kB buffers.
|
With the tested BD-RE one must write full 64 kB buffers, or else writing
|
||||||
|
might not get into effect at all.
|
||||||
|
|
||||||
Although it seems not optimal, this is specified not only to disable the
|
Although it seems not optimal, this is specified not only to disable the
|
||||||
cumbersome checkread but also to ignore known defects and to write data
|
cumbersome checkread but also to ignore known defects and to write data
|
||||||
|
@ -769,7 +880,8 @@ MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
||||||
None of the features of profiles 0012h and 0043h promises the existence of
|
None of the features of profiles 0012h and 0043h promises the existence of
|
||||||
AAh WRITE12.
|
AAh WRITE12.
|
||||||
(mmc5r03c.pdf 5.4.13, 6.45)
|
(mmc5r03c.pdf 5.4.13, 6.45)
|
||||||
Nevertheless it worked on all tested drives if proper alignment was observed.
|
Nevertheless it worked on all tested drives if proper alignment and block
|
||||||
|
size was observed.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -783,7 +895,8 @@ The term "superblock" shall depict the first 64 KiB after the sbsector address.
|
||||||
|
|
||||||
ISO 9660 multi-session depends on typical TOC information in two ways:
|
ISO 9660 multi-session depends on typical TOC information in two ways:
|
||||||
It needs the superblock address MSC1 of the most recently recorded session and
|
It needs the superblock address MSC1 of the most recently recorded session and
|
||||||
it needs the Next Writeable Address NWA for which to prepare the adress offset.
|
it needs the Next Writeable Address NWA for which to prepare the address
|
||||||
|
offset.
|
||||||
|
|
||||||
The following is learned from growisofs and from ECMA-119:
|
The following is learned from growisofs and from ECMA-119:
|
||||||
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
||||||
|
@ -801,7 +914,8 @@ To support CD, DVD and BD media alike, it is advisable to round the NWA
|
||||||
to the next multiple of 32 (= 64 KiB).
|
to the next multiple of 32 (= 64 KiB).
|
||||||
|
|
||||||
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
||||||
After writing the session it is necessary to patch the PVD at LBA 16.
|
After writing the session it is necessary to copy the PVD from session start
|
||||||
|
plus 16 to LBA 16 and to adjust it to its new location.
|
||||||
The minimal change would be to update the number of image sectors.
|
The minimal change would be to update the number of image sectors.
|
||||||
It is stored in both notations LSB and MSB:
|
It is stored in both notations LSB and MSB:
|
||||||
for(i= 0; i < 4; i++)
|
for(i= 0; i < 4; i++)
|
||||||
|
@ -841,6 +955,8 @@ This chain gives the start addresses of sessions. The sector count minus start
|
||||||
address gives the size of a particular session. ECMA-119 explains how to
|
address gives the size of a particular session. ECMA-119 explains how to
|
||||||
retrieve more info from the PVD (e.g. the volume id).
|
retrieve more info from the PVD (e.g. the volume id).
|
||||||
|
|
||||||
|
See also the multi-session example in libisofs/doc/checksums.txt.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -860,13 +976,13 @@ Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
|
||||||
DVD-R 0011h
|
DVD-R 0011h
|
||||||
DVD-RW Restricted Overwrite 0013h
|
DVD-RW Restricted Overwrite 0013h
|
||||||
DVD-RW Sequential Recording 0014h
|
DVD-RW Sequential Recording 0014h
|
||||||
(DVD-R/DL Sequential Recording 0015h untested, might be single-session only)
|
DVD-R/DL Sequential Recording 0015h (can only do single-session)
|
||||||
|
|
||||||
There are two approaches for writing to sequential DVD-R[W]: DAO and
|
There are two approaches for writing to sequential DVD-R[W]: DAO and
|
||||||
Incremental. Not all media and drives offer Incremental which allows
|
Incremental. Not all media and drives offer Incremental which can do
|
||||||
multi-session as with CD media and does not demand a predicted track size.
|
multi-session as with CD media and does not demand a predicted track size.
|
||||||
DAO seems to be the older method. It allows only one single session and
|
DAO seems to be the older method. It can only write one single session and
|
||||||
track and it demands an exactly predicted track size.
|
track, and it demands an exactly predicted track size.
|
||||||
|
|
||||||
- About overwriteable, blank, appendable and finalized DVD-R[W] media
|
- About overwriteable, blank, appendable and finalized DVD-R[W] media
|
||||||
- Incremental writing
|
- Incremental writing
|
||||||
|
@ -910,7 +1026,7 @@ brings back this feature.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Incremental writing :
|
Incremental writing :
|
||||||
|
|
||||||
Incremental writing allows to produce multi-session DVDs. It is indicated
|
Incremental writing can produce multi-session DVDs. It is indicated
|
||||||
by feature 0021h being marked current in the reply of 46h GET CONFIGURATION.
|
by feature 0021h being marked current in the reply of 46h GET CONFIGURATION.
|
||||||
growisofs inquires 0021h by setting Starting Feature Number to 0x21 and
|
growisofs inquires 0021h by setting Starting Feature Number to 0x21 and
|
||||||
Allocation Length to 16 in order to get only this one. The feature descriptor
|
Allocation Length to 16 in order to get only this one. The feature descriptor
|
||||||
|
@ -927,13 +1043,13 @@ which are returned by ACh.
|
||||||
|
|
||||||
growisofs fetches a mode page 05h template by MODE SENSE and inserts its own
|
growisofs fetches a mode page 05h template by MODE SENSE and inserts its own
|
||||||
parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero.
|
parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero.
|
||||||
libburn composes its mode page 05h from zero and allows control of
|
libburn composes its mode page 05h from zero and enables the application
|
||||||
Multi-Session by the application.
|
to control Multi-Session.
|
||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
LS_V Link size valid 1=true
|
LS_V Link size valid 1=true
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
|
@ -980,7 +1096,7 @@ from the reply of 51h READ DISC INFORMATION requesting Data Type 000b
|
||||||
Multiple tracks are permissible in a single session. After all of them have
|
Multiple tracks are permissible in a single session. After all of them have
|
||||||
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
||||||
Number 0 closes the session. It depends on the Multi-Session value in mode
|
Number 0 closes the session. It depends on the Multi-Session value in mode
|
||||||
page 05h wether the disc is finalized or stays appendable.
|
page 05h whether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.2.3)
|
(mmc5r03c.pdf 6.3.3.2.3)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1005,7 +1121,7 @@ The mode page 05h to be sent :
|
||||||
LS_V Link size valid 0=false [*3]
|
LS_V Link size valid 0=false [*3]
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
||||||
Multi-session Wether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
Link Size ??? 0 [*3]
|
Link Size ??? 0 [*3]
|
||||||
|
@ -1142,11 +1258,13 @@ track of the session.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Hearsay about DVD-R/DL (Dual Layer) :
|
Hearsay about DVD-R/DL (Dual Layer) :
|
||||||
|
|
||||||
|
Meanwhile confirmed by one user:
|
||||||
|
|
||||||
DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed
|
DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed
|
||||||
to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart
|
to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart
|
||||||
with DVD-R.
|
with DVD-R.
|
||||||
|
|
||||||
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 might indicate that closing a session
|
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 indicates that closing a session
|
||||||
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
|
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
|
||||||
in mode page 05h.
|
in mode page 05h.
|
||||||
growisofs applies this function in case of not DAO, though. A comment in
|
growisofs applies this function in case of not DAO, though. A comment in
|
||||||
|
@ -1222,7 +1340,7 @@ No mode page 05h is to be sent.
|
||||||
growisofs sends a page but the specs clearly state that one shall not do.
|
growisofs sends a page but the specs clearly state that one shall not do.
|
||||||
(mmc5r03c.pdf 7.5.3)
|
(mmc5r03c.pdf 7.5.3)
|
||||||
|
|
||||||
It is optional wether a track size is reserved in advance or not. Eventually
|
It is optional whether a track size is reserved in advance or not. Eventually
|
||||||
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
||||||
already be aligned to 32 KiB.
|
already be aligned to 32 KiB.
|
||||||
(mmc5r03c.pdf 6.31)
|
(mmc5r03c.pdf 6.31)
|
||||||
|
@ -1339,7 +1457,7 @@ eventually RRM) chosen by the format sub-type:
|
||||||
10b = (RRM)
|
10b = (RRM)
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.6)
|
(mmc5r03c.pdf 6.5.4.2.1.6)
|
||||||
|
|
||||||
Format type 32h uses the same sub-types but allows to allocate non-default
|
Format type 32h uses the same sub-types but can allocate non-default
|
||||||
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
|
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
|
||||||
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
||||||
The size may be chosen within that range.
|
The size may be chosen within that range.
|
||||||
|
@ -1392,5 +1510,11 @@ written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
|
||||||
at the NWA of a sufficiently sized track.
|
at the NWA of a sufficiently sized track.
|
||||||
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
|
||||||
|
Permission is granted to copy, modify, and distribute it, as long as the
|
||||||
|
references to the original information sources are maintained.
|
||||||
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ There are two classes of device specific suffixes:
|
||||||
If a lockfile does not exist and cannot be created then this shall not keep
|
If a lockfile does not exist and cannot be created then this shall not keep
|
||||||
a program from working on a device. But if a lockfile exists and if permissions
|
a program from working on a device. But if a lockfile exists and if permissions
|
||||||
or locking state do not allow to obtain a lock of the appropirate type, then
|
or locking state do not allow to obtain a lock of the appropirate type, then
|
||||||
this shall prevent any opening of device file in question resp. shall cause
|
this shall prevent any opening of device file in question and shall cause
|
||||||
immediate close(2) of an already opened device file.
|
immediate close(2) of an already opened device file.
|
||||||
|
|
||||||
The vulnerable programs shall not start their operation before they locked a
|
The vulnerable programs shall not start their operation before they locked a
|
||||||
|
@ -346,7 +346,7 @@ which keeps it from being the solution to all known legitimate use cases.
|
||||||
The attempt has failed to compose a waterproof locking mechanism from means of
|
The attempt has failed to compose a waterproof locking mechanism from means of
|
||||||
POSIX, FHS and from hardly documented Linux open(O_EXCL) on device files.
|
POSIX, FHS and from hardly documented Linux open(O_EXCL) on device files.
|
||||||
The resulting mechanisms would need about 1000 lines of code and still do
|
The resulting mechanisms would need about 1000 lines of code and still do
|
||||||
not close all gaps resp. cover the well motivated use cases.
|
not close all gaps and cover the well motivated use cases.
|
||||||
This attempt you see above: DDLP-A and DDLP-B.
|
This attempt you see above: DDLP-A and DDLP-B.
|
||||||
|
|
||||||
|
|
||||||
|
|
1790
doc/doxygen.conf.in
1790
doc/doxygen.conf.in
File diff suppressed because it is too large
Load Diff
1216
doc/mediainfo.txt
Normal file
1216
doc/mediainfo.txt
Normal file
File diff suppressed because it is too large
Load Diff
84
doc/waveformat.txt
Normal file
84
doc/waveformat.txt
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
|
||||||
|
Sound extraction for CD-DA burning from .WAV audio file format
|
||||||
|
|
||||||
|
Using information and text snippets
|
||||||
|
from https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
||||||
|
in may 2013. The link is now dead. An apparent copy of the page
|
||||||
|
is 2017 at: http://soundfile.sapp.org/doc/WaveFormat/
|
||||||
|
from https://en.wikipedia.org/wiki/WAV
|
||||||
|
|
||||||
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
December 2017
|
||||||
|
|
||||||
|
|
||||||
|
The WAVE file format is an application of the Microsoft RIFF container format
|
||||||
|
for multimedia files. A RIFF file consists of Chunks which contain Subchunks.
|
||||||
|
The Chunks form a linked list within the file, the Subchunks form a linked
|
||||||
|
list inside their Chunk.
|
||||||
|
All numbers are stored in little-endian byte order.
|
||||||
|
|
||||||
|
A .WAV file consists at least of one Chunk with id "RIFF", which contains
|
||||||
|
one Subchunk with id "fmt " and one with id "data":
|
||||||
|
|
||||||
|
Offset Size Name Description
|
||||||
|
|
||||||
|
0 4 ChunkID Contains the letters "RIFF"
|
||||||
|
4 4 ChunkSize The size of the rest of the chunk following
|
||||||
|
this field. I.e. the two fields ChunkID and
|
||||||
|
ChunkSize are not included in this count.
|
||||||
|
8 4 Format Contains the letters "WAVE"
|
||||||
|
|
||||||
|
|
||||||
|
The "fmt " subchunk describes the sound data's format:
|
||||||
|
|
||||||
|
Offset Size Name Description
|
||||||
|
|
||||||
|
0 4 Subchunk1ID Contains the letters "fmt "
|
||||||
|
|
||||||
|
4 4 Subchunk1Size The size of the rest of the Subchunk following
|
||||||
|
this field. I.e. Subchunk1ID and Subchunk1Size
|
||||||
|
are not included in this count.
|
||||||
|
8 2 AudioFormat PCM = 1 (i.e. Linear quantization)
|
||||||
|
Values other than 1 indicate some
|
||||||
|
form of compression.
|
||||||
|
10 2 NumChannels Mono = 1, Stereo = 2, etc.
|
||||||
|
12 4 SampleRate 8000, 44100, etc.
|
||||||
|
16 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
|
||||||
|
20 2 BlockAlign == NumChannels * BitsPerSample/8
|
||||||
|
The number of bytes for one sample including
|
||||||
|
all channels.
|
||||||
|
22 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
|
||||||
|
More data may follow in this Subchunk if AudioFormat is not PCM.
|
||||||
|
|
||||||
|
|
||||||
|
The "data" subchunk contains the size of the data and the actual sound:
|
||||||
|
|
||||||
|
Offset Size Name Description
|
||||||
|
|
||||||
|
0 4 Subchunk2ID Contains the letters "data"
|
||||||
|
|
||||||
|
4 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
|
||||||
|
The number of audio data bytes.
|
||||||
|
8 * Data The audio data bytes.
|
||||||
|
|
||||||
|
|
||||||
|
CD-DA prescribes these "fmt " parameters:
|
||||||
|
AudioFormat == 1
|
||||||
|
SampleRate == 44100
|
||||||
|
BitsPerSample == 16
|
||||||
|
NumChannels == 2 (stereo)
|
||||||
|
(little-endian byte order)
|
||||||
|
|
||||||
|
If matching parameters are given in the .WAV file, one can directly use the
|
||||||
|
data bytes of Subchunk "data" as payload for burning a CD-DA track.
|
||||||
|
|
||||||
|
|
||||||
|
Above simple form can be expanded by other Chunks or Subchunks of Chunk "RIFF".
|
||||||
|
A .wav file appeared which beared a Subchunk "LIST" inside Chunk "RIFF".
|
||||||
|
Wikipedia mentions Chunks "INFO", "CSET", "JUNK", "PAD ".
|
||||||
|
|
||||||
|
Therefore one should expect such Chunks before Chunk "RIFF" and Subchunks
|
||||||
|
other than "fmt " and "data" inside the "RIFF" Chunk.
|
||||||
|
Multiple Chunks "RIFF" and Subchunks "fmt " or "data" per file have not been
|
||||||
|
seen yet. They would make extraction more cumbersome.
|
||||||
|
|
365
libburn/async.c
365
libburn/async.c
|
@ -1,5 +1,9 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
/* ts A71019 */
|
/* ts A71019 */
|
||||||
|
|
||||||
|
@ -19,6 +23,9 @@
|
||||||
#define Libburn_detach_done_workeR 1
|
#define Libburn_detach_done_workeR 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
@ -36,6 +43,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <a ssert.h>
|
#include <a ssert.h>
|
||||||
|
@ -90,6 +98,14 @@ struct fifo_opts
|
||||||
int flag;
|
int flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union w_list_data
|
||||||
|
{
|
||||||
|
struct scan_opts scan;
|
||||||
|
struct erase_opts erase;
|
||||||
|
struct format_opts format;
|
||||||
|
struct write_opts write;
|
||||||
|
struct fifo_opts fifo;
|
||||||
|
};
|
||||||
|
|
||||||
struct w_list
|
struct w_list
|
||||||
{
|
{
|
||||||
|
@ -101,18 +117,49 @@ struct w_list
|
||||||
|
|
||||||
struct w_list *next;
|
struct w_list *next;
|
||||||
|
|
||||||
union w_list_data
|
union w_list_data u;
|
||||||
{
|
|
||||||
struct scan_opts scan;
|
|
||||||
struct erase_opts erase;
|
|
||||||
struct format_opts format;
|
|
||||||
struct write_opts write;
|
|
||||||
struct fifo_opts fifo;
|
|
||||||
} u;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct w_list *workers = NULL;
|
static struct w_list *workers = NULL;
|
||||||
|
|
||||||
|
static void *fifo_worker_func(struct w_list *w);
|
||||||
|
|
||||||
|
|
||||||
|
int burn_async_manage_lock(int mode)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
static pthread_mutex_t access_lock;
|
||||||
|
static int mutex_initialized = 0;
|
||||||
|
static int mutex_locked = 0;
|
||||||
|
|
||||||
|
if (mode == BURN_ASYNC_LOCK_INIT) {
|
||||||
|
if (mutex_initialized)
|
||||||
|
return 2;
|
||||||
|
ret = pthread_mutex_init(&access_lock, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return 0;
|
||||||
|
mutex_initialized = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!mutex_initialized)
|
||||||
|
return 0;
|
||||||
|
if (mode == BURN_ASYNC_LOCK_OBTAIN) {
|
||||||
|
ret = pthread_mutex_lock(&access_lock);
|
||||||
|
if (ret != 0)
|
||||||
|
return 0;
|
||||||
|
mutex_locked = 1;
|
||||||
|
} else if (mode == BURN_ASYNC_LOCK_RELEASE) {
|
||||||
|
if (!mutex_locked)
|
||||||
|
return 2;
|
||||||
|
ret = pthread_mutex_unlock(&access_lock);
|
||||||
|
if (ret != 0)
|
||||||
|
return 0;
|
||||||
|
mutex_locked = 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct w_list *find_worker(struct burn_drive *d)
|
static struct w_list *find_worker(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
@ -125,7 +172,7 @@ static struct w_list *find_worker(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_worker(int w_type, struct burn_drive *d,
|
static void add_worker(int w_type, struct burn_drive *d,
|
||||||
WorkerFunc f, void *data)
|
WorkerFunc f, union w_list_data *data)
|
||||||
{
|
{
|
||||||
struct w_list *a;
|
struct w_list *a;
|
||||||
struct w_list *tmp;
|
struct w_list *tmp;
|
||||||
|
@ -135,10 +182,13 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
a = malloc(sizeof(struct w_list));
|
a = calloc(1, sizeof(struct w_list));
|
||||||
a->w_type = w_type;
|
a->w_type = w_type;
|
||||||
a->drive = d;
|
a->drive = d;
|
||||||
a->u = *(union w_list_data *)data;
|
|
||||||
|
a->u = *data;
|
||||||
|
|
||||||
|
burn_async_manage_lock(BURN_ASYNC_LOCK_INIT);
|
||||||
|
|
||||||
/* insert at front of the list */
|
/* insert at front of the list */
|
||||||
a->next = workers;
|
a->next = workers;
|
||||||
|
@ -149,6 +199,7 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
d->busy = BURN_DRIVE_SPAWNING;
|
d->busy = BURN_DRIVE_SPAWNING;
|
||||||
|
|
||||||
#ifdef Libburn_create_detached_threadS
|
#ifdef Libburn_create_detached_threadS
|
||||||
|
|
||||||
/* ts A71019 :
|
/* ts A71019 :
|
||||||
Trying to start the threads detached to get rid of the zombies
|
Trying to start the threads detached to get rid of the zombies
|
||||||
which do neither react on pthread_join() nor on pthread_detach().
|
which do neither react on pthread_join() nor on pthread_detach().
|
||||||
|
@ -156,12 +207,12 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
attr_pt= &attr;
|
attr_pt= &attr;
|
||||||
/*
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
|
#endif /* Libburn_create_detached_threadS */
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
|
|
||||||
"add_worker(): Creating detached thread.", 0, 0);
|
/* Worker specific locks are to be released early by the worker */
|
||||||
*/
|
if (f == (WorkerFunc) fifo_worker_func)
|
||||||
#endif
|
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
||||||
|
|
||||||
if (pthread_create(&a->thread, attr_pt, f, a)) {
|
if (pthread_create(&a->thread, attr_pt, f, a)) {
|
||||||
free(a);
|
free(a);
|
||||||
|
@ -175,11 +226,6 @@ static void remove_worker(pthread_t th)
|
||||||
{
|
{
|
||||||
struct w_list *a, *l = NULL;
|
struct w_list *a, *l = NULL;
|
||||||
|
|
||||||
#ifdef Libburn_detach_done_workeR
|
|
||||||
int ret;
|
|
||||||
char msg[80];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (a = workers; a; l = a, a = a->next)
|
for (a = workers; a; l = a, a = a->next)
|
||||||
if (a->thread == th) {
|
if (a->thread == th) {
|
||||||
if (l)
|
if (l)
|
||||||
|
@ -192,8 +238,12 @@ static void remove_worker(pthread_t th)
|
||||||
/* Alternative : threads get detached and thus should
|
/* Alternative : threads get detached and thus should
|
||||||
dispose themselves.
|
dispose themselves.
|
||||||
*/
|
*/
|
||||||
ret = pthread_detach(th);
|
pthread_detach(th);
|
||||||
/*
|
/*
|
||||||
|
int ret;
|
||||||
|
char msg[80];
|
||||||
|
|
||||||
|
ret = pthread_detach(th);
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
|
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
|
||||||
(unsigned long) getpid(), (unsigned long) th, ret);
|
(unsigned long) getpid(), (unsigned long) th, ret);
|
||||||
|
@ -228,9 +278,25 @@ static void *scan_worker_func(struct w_list *w)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
||||||
|
int indices, off_t sectors, int flag)
|
||||||
|
{
|
||||||
|
/* reset the progress indicator */
|
||||||
|
d->progress.session = 0;
|
||||||
|
d->progress.sessions = sessions;
|
||||||
|
d->progress.track = 0;
|
||||||
|
d->progress.tracks = tracks;
|
||||||
|
d->progress.index = 0;
|
||||||
|
d->progress.indices = indices;
|
||||||
|
d->progress.start_sector = 0;
|
||||||
|
d->progress.sectors = sectors;
|
||||||
|
d->progress.sector = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
{
|
{
|
||||||
struct scan_opts o;
|
union w_list_data o;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
|
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
|
||||||
|
@ -243,7 +309,7 @@ int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cant be anything working! */
|
/* cannot be anything working! */
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(!(workers && workers->drive)); */
|
/* a ssert(!(workers && workers->drive)); */
|
||||||
|
@ -269,9 +335,9 @@ drive_is_active:;
|
||||||
*drives = NULL;
|
*drives = NULL;
|
||||||
*n_drives = 0;
|
*n_drives = 0;
|
||||||
|
|
||||||
o.drives = drives;
|
o.scan.drives = drives;
|
||||||
o.n_drives = n_drives;
|
o.scan.n_drives = n_drives;
|
||||||
o.done = 0;
|
o.scan.done = 0;
|
||||||
add_worker(Burnworker_type_scaN, NULL,
|
add_worker(Burnworker_type_scaN, NULL,
|
||||||
(WorkerFunc) scan_worker_func, &o);
|
(WorkerFunc) scan_worker_func, &o);
|
||||||
} else if (workers->u.scan.done) {
|
} else if (workers->u.scan.done) {
|
||||||
|
@ -297,21 +363,41 @@ drive_is_active:;
|
||||||
|
|
||||||
static void *erase_worker_func(struct w_list *w)
|
static void *erase_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define Libburn_protect_erase_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_erase_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect blank thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_erase_threaD */
|
||||||
|
|
||||||
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_erase_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_erase_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_disc_erase(struct burn_drive *drive, int fast)
|
void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
{
|
{
|
||||||
struct erase_opts o;
|
union w_list_data o;
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(drive); */
|
/* a ssert(drive); */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(drive)); */
|
/* a ssert(!find_worker(drive)); */
|
||||||
if((drive == NULL)) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
if(drive == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
0x00020104,
|
0x00020104,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"NULL pointer caught in burn_disc_erase", 0, 0);
|
"NULL pointer caught in burn_disc_erase", 0, 0);
|
||||||
|
@ -325,18 +411,23 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
0, 0);
|
0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
||||||
|
|
||||||
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
|
|
||||||
/* ts A70103 moved up from burn_disc_erase_sync() */
|
/* ts A70103 moved up from burn_disc_erase_sync() */
|
||||||
/* ts A60825 : allow on parole to blank appendable CDs */
|
/* ts A60825 : allow on parole to blank appendable CDs */
|
||||||
/* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */
|
/* ts A70131 : allow blanking of overwritable DVD-RW (profile 0x13) */
|
||||||
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
|
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
|
||||||
and of any kind of full media */
|
and of any kind of full media */
|
||||||
/* ts A70909 : the willingness to burn any BURN_DISC_FULL media is
|
/* ts A70909 : the willingness to burn any BURN_DISC_FULL media is
|
||||||
inappropriate. One would rather need a -force option
|
inappropriate. One would rather need a -force option
|
||||||
Note: keep this in sync with mmc_read_disc_info() */
|
Note: keep this in sync with mmc_read_disc_info() */
|
||||||
if ((drive->current_profile != 0x0a &&
|
/* ts B10321 : Allowed role 5 to be blanked */
|
||||||
|
if ((drive->drive_role == 1 &&
|
||||||
|
drive->current_profile != 0x0a &&
|
||||||
drive->current_profile != 0x13 &&
|
drive->current_profile != 0x13 &&
|
||||||
drive->current_profile != 0x14 &&
|
drive->current_profile != 0x14 &&
|
||||||
drive->status != BURN_DISC_FULL)
|
drive->status != BURN_DISC_FULL)
|
||||||
|
@ -345,18 +436,23 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
drive->status != BURN_DISC_APPENDABLE &&
|
drive->status != BURN_DISC_APPENDABLE &&
|
||||||
drive->status != BURN_DISC_BLANK)
|
drive->status != BURN_DISC_BLANK)
|
||||||
||
|
||
|
||||||
(drive->drive_role != 1)
|
(drive->drive_role != 1 && drive->drive_role != 5)
|
||||||
) {
|
) {
|
||||||
|
char msg[160];
|
||||||
|
|
||||||
|
sprintf(msg, "Drive and media state unsuitable for blanking. (role= %d , profile= 0x%x , status= %d)",
|
||||||
|
drive->drive_role,
|
||||||
|
(unsigned int) drive->current_profile,
|
||||||
|
drive->status);
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020130,
|
0x00020130,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive and media state unsuitable for blanking",
|
msg, 0, 0);
|
||||||
0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.drive = drive;
|
o.erase.drive = drive;
|
||||||
o.fast = fast;
|
o.erase.fast = fast;
|
||||||
add_worker(Burnworker_type_erasE, drive,
|
add_worker(Burnworker_type_erasE, drive,
|
||||||
(WorkerFunc) erase_worker_func, &o);
|
(WorkerFunc) erase_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
@ -365,9 +461,28 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
/* ts A61230 */
|
/* ts A61230 */
|
||||||
static void *format_worker_func(struct w_list *w)
|
static void *format_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define Libburn_protect_format_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_format_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect format thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_format_threaD */
|
||||||
|
|
||||||
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
||||||
w->u.format.flag);
|
w->u.format.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_format_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_format_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,9 +490,11 @@ static void *format_worker_func(struct w_list *w)
|
||||||
/* ts A61230 */
|
/* ts A61230 */
|
||||||
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
{
|
{
|
||||||
struct format_opts o;
|
union w_list_data o;
|
||||||
int ok = 0, ret;
|
int ok = 0, ret;
|
||||||
char msg[160];
|
char msg[40];
|
||||||
|
|
||||||
|
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
||||||
|
|
||||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
@ -449,42 +566,6 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
if ((flag & 6) != 6 || (flag & 128)) {
|
|
||||||
if ((flag & 64) && !(drive->current_feat23h_byte4 & 2)) {
|
|
||||||
if (drive->current_feat23h_byte4 & 1) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020165,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support fast formatting",
|
|
||||||
0, 0);
|
|
||||||
flag &= ~64;
|
|
||||||
} else {
|
|
||||||
no_non_default_bd_re:;
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020167,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support non-default formatting",
|
|
||||||
0, 0);
|
|
||||||
drive->cancel = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((!(flag & 64)) && !(drive->current_feat23h_byte4 & 1)){
|
|
||||||
if (drive->current_feat23h_byte4 & 2) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020166,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support full formatting",
|
|
||||||
0, 0);
|
|
||||||
flag |= 64;
|
|
||||||
} else
|
|
||||||
goto no_non_default_bd_re;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
@ -497,9 +578,9 @@ no_non_default_bd_re:;
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
o.drive = drive;
|
o.format.drive = drive;
|
||||||
o.size = size;
|
o.format.size = size;
|
||||||
o.flag = flag;
|
o.format.flag = flag;
|
||||||
add_worker(Burnworker_type_formaT, drive,
|
add_worker(Burnworker_type_formaT, drive,
|
||||||
(WorkerFunc) format_worker_func, &o);
|
(WorkerFunc) format_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
@ -508,8 +589,22 @@ no_non_default_bd_re:;
|
||||||
static void *write_disc_worker_func(struct w_list *w)
|
static void *write_disc_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = w->u.write.drive;
|
struct burn_drive *d = w->u.write.drive;
|
||||||
|
char msg[80];
|
||||||
|
|
||||||
|
#define Libburn_protect_write_threaD 1
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_write_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect write thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_write_threaD */
|
||||||
|
|
||||||
d->thread_pid = getpid();
|
d->thread_pid = getpid();
|
||||||
|
d->thread_tid = pthread_self();
|
||||||
d->thread_pid_valid= 1;
|
d->thread_pid_valid= 1;
|
||||||
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
||||||
d->thread_pid_valid= 0;
|
d->thread_pid_valid= 0;
|
||||||
|
@ -519,15 +614,28 @@ static void *write_disc_worker_func(struct w_list *w)
|
||||||
*/
|
*/
|
||||||
burn_write_opts_free(w->u.write.opts);
|
burn_write_opts_free(w->u.write.opts);
|
||||||
|
|
||||||
|
sprintf(msg, "Write thread on drive %d ended", d->global_index);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_write_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_write_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
{
|
{
|
||||||
struct write_opts o;
|
union w_list_data o;
|
||||||
char reasons[BURN_REASONS_LEN+80];
|
char *reasons= NULL;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
|
int mvalid;
|
||||||
|
|
||||||
d = opts->drive;
|
d = opts->drive;
|
||||||
|
|
||||||
|
@ -543,12 +651,20 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
||||||
|
disc->session[0]->track[0]->indices, (off_t) 0, 0);
|
||||||
|
|
||||||
/* For the next lines any return indicates failure */
|
/* For the next lines any return indicates failure */
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
|
|
||||||
/* ts A70203 : people have been warned in API specs */
|
/* ts A70203 : people have been warned in API specs */
|
||||||
if (opts->write_type == BURN_WRITE_NONE)
|
if (opts->write_type == BURN_WRITE_NONE) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x0002017c,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"No valid write type selected", 0, 0);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (d->drive_role == 0) {
|
if (d->drive_role == 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
@ -557,19 +673,34 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (d->drive_role == 4) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020181,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Pseudo-drive is a read-only file. Cannot write.",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
||||||
if (d->drive_role == 1 && d->mdata->valid <= 0) {
|
if (d->drive_role == 1) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
mvalid = 0;
|
||||||
|
if (d->mdata != NULL)
|
||||||
|
mvalid = 1;
|
||||||
|
if (!mvalid) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x00020113,
|
d->global_index, 0x00020113,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive capabilities not inquired yet", 0, 0);
|
"Drive capabilities not inquired yet", 0, 0);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A70219 : intended to replace all further tests here and many
|
/* ts A70219 : intended to replace all further tests here and many
|
||||||
tests in burn_*_write_sync()
|
tests in burn_*_write_sync()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM_VOID(reasons, char, BURN_REASONS_LEN + 80);
|
||||||
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
||||||
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
||||||
<= 0) {
|
<= 0) {
|
||||||
|
@ -577,8 +708,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
d->global_index, 0x00020139,
|
d->global_index, 0x00020139,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
reasons, 0, 0);
|
reasons, 0, 0);
|
||||||
return;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
BURN_FREE_MEM(reasons); reasons= NULL;
|
||||||
|
|
||||||
/* ts A90106 : early catching of unformatted BD-RE */
|
/* ts A90106 : early catching of unformatted BD-RE */
|
||||||
if (d->current_profile == 0x43)
|
if (d->current_profile == 0x43)
|
||||||
|
@ -594,50 +726,68 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
|
|
||||||
d->cancel = 0; /* End of the return = failure area */
|
d->cancel = 0; /* End of the return = failure area */
|
||||||
|
|
||||||
o.drive = d;
|
o.write.drive = d;
|
||||||
o.opts = opts;
|
o.write.opts = opts;
|
||||||
o.disc = disc;
|
o.write.disc = disc;
|
||||||
|
|
||||||
opts->refcount++;
|
opts->refcount++;
|
||||||
|
|
||||||
add_worker(Burnworker_type_writE, d,
|
add_worker(Burnworker_type_writE, d,
|
||||||
(WorkerFunc) write_disc_worker_func, &o);
|
(WorkerFunc) write_disc_worker_func, &o);
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(reasons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *fifo_worker_func(struct w_list *w)
|
static void *fifo_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
int old;
|
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
#define Libburn_protect_fifo_threaD 1
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
|
||||||
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
#ifdef Libburn_protect_fifo_threaD
|
||||||
|
sigset_t sigset, oldset;
|
||||||
|
|
||||||
|
/* Protect fifo thread from being interrupted by external signals */
|
||||||
|
sigfillset(&sigset);
|
||||||
|
sigdelset(&sigset, SIGSEGV);
|
||||||
|
sigdelset(&sigset, SIGILL);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
|
#endif /* Libburn_protect_fifo_threaD */
|
||||||
|
|
||||||
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
#ifdef Libburn_protect_fifo_threaD
|
||||||
|
/* (just in case it would not end with all signals blocked) */
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
#endif /* Libburn_protect_fifo_threaD */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_fifo_start(struct burn_source *source, int flag)
|
int burn_fifo_start(struct burn_source *source, int flag)
|
||||||
{
|
{
|
||||||
struct fifo_opts o;
|
union w_list_data o;
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
fs->is_started = -1;
|
fs->is_started = -1;
|
||||||
|
|
||||||
/* create and set up ring buffer */;
|
/* create and set up ring buffer */;
|
||||||
fs->buf = calloc(fs->chunksize, fs->chunks);
|
fs->buf = burn_os_alloc_buffer(
|
||||||
|
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||||
if (fs->buf == NULL) {
|
if (fs->buf == NULL) {
|
||||||
/* >>> could not start ring buffer */;
|
/* >>> could not start ring buffer */;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.source = source;
|
o.fifo.source = source;
|
||||||
o.flag = flag;
|
o.fifo.flag = flag;
|
||||||
add_worker(Burnworker_type_fifO, NULL,
|
add_worker(Burnworker_type_fifO, NULL,
|
||||||
(WorkerFunc) fifo_worker_func, &o);
|
(WorkerFunc) fifo_worker_func, &o);
|
||||||
fs->is_started = 1;
|
fs->is_started = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,18 +797,19 @@ int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
|
||||||
int ret;
|
int ret;
|
||||||
pthread_t pt;
|
pthread_t pt;
|
||||||
|
|
||||||
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL)
|
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
||||||
return(2);
|
|
||||||
|
|
||||||
#ifdef NIX
|
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
return 2;
|
||||||
"Aborting running burn_source_fifo thread", 0, 0);
|
}
|
||||||
#endif /* NIX */
|
pt = *((pthread_t *) fs->thread_handle);
|
||||||
|
|
||||||
|
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
||||||
|
|
||||||
|
fs->do_abort = 1;
|
||||||
|
ret = pthread_join(pt, NULL);
|
||||||
|
|
||||||
pt= *((pthread_t *) fs->thread_handle);
|
|
||||||
remove_worker(pt);
|
|
||||||
ret = pthread_cancel(pt);
|
|
||||||
return (ret == 0);
|
return (ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__ASYNC_H
|
#ifndef BURN__ASYNC_H
|
||||||
#define BURN__ASYNC_H
|
#define BURN__ASYNC_H
|
||||||
|
|
||||||
|
@ -14,5 +19,10 @@ int burn_fifo_start(struct burn_source *source, int flag);
|
||||||
/* To abort a running fifo thread before the fifo object gets deleted */
|
/* To abort a running fifo thread before the fifo object gets deleted */
|
||||||
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
|
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
|
||||||
|
|
||||||
|
/* ts B70126 */
|
||||||
|
#define BURN_ASYNC_LOCK_RELEASE 0
|
||||||
|
#define BURN_ASYNC_LOCK_OBTAIN 1
|
||||||
|
#define BURN_ASYNC_LOCK_INIT 2
|
||||||
|
int burn_async_manage_lock(int mode);
|
||||||
|
|
||||||
#endif /* BURN__ASYNC_H */
|
#endif /* BURN__ASYNC_H */
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
/**
|
/**
|
||||||
|
Copyright (c) 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
This file bundles variables which disable changes in libburn which are
|
This file bundles variables which disable changes in libburn which are
|
||||||
not yet completely accepted.
|
not yet completely accepted.
|
||||||
|
|
1737
libburn/cdtext.c
Executable file
1737
libburn/cdtext.c
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +1,19 @@
|
||||||
/*
|
/*
|
||||||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
Provided under GPLv2+ license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -40,7 +44,8 @@ static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
|
||||||
#else /* ! Cleanup_has_no_libburn_os_H */
|
#else /* ! Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
|
/* Outdated. GNU/Linux only.
|
||||||
|
For backward compatibility with pre-libburn-0.2.3 */
|
||||||
|
|
||||||
/* Signals to be caught */
|
/* Signals to be caught */
|
||||||
static int signal_list[]= {
|
static int signal_list[]= {
|
||||||
|
@ -128,15 +133,27 @@ static void Cleanup_handler_generic(int signum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *Cleanup_signo_to_name(int signo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i= 0; i < signal_list_count; i++)
|
||||||
|
if(signal_list[i] == signo)
|
||||||
|
return(signal_name_list[i]);
|
||||||
|
return("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||||
/*
|
/*
|
||||||
bit0= set to default handlers
|
bit0= set to default handlers
|
||||||
bit1= set to ignore
|
bit1= set to ignore
|
||||||
bit2= set cleanup_perform_app_handler_first
|
bit2= set cleanup_perform_app_handler_first
|
||||||
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
||||||
|
bit8= set SIGPIPE to SIGIGN
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
||||||
|
char *sig_name;
|
||||||
sighandler_t sig_handler;
|
sighandler_t sig_handler;
|
||||||
|
|
||||||
cleanup_msg[0]= 0;
|
cleanup_msg[0]= 0;
|
||||||
|
@ -167,8 +184,17 @@ int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||||
if(i==non_signal_list[j])
|
if(i==non_signal_list[j])
|
||||||
break;
|
break;
|
||||||
if(j>=non_signal_list_count) {
|
if(j>=non_signal_list_count) {
|
||||||
if(i==SIGABRT && (flag&8))
|
/* Avoid to use particular SIG macros which might not be defined.
|
||||||
|
If they are defined, then their names are in the name list.
|
||||||
|
*/
|
||||||
|
if(flag & (8 | 256))
|
||||||
|
sig_name= Cleanup_signo_to_name(i);
|
||||||
|
else
|
||||||
|
sig_name= "";
|
||||||
|
if((flag & 8) && strcmp(sig_name, "SIGABRT") == 0)
|
||||||
signal(i,Cleanup_handler_generic);
|
signal(i,Cleanup_handler_generic);
|
||||||
|
else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0)
|
||||||
|
signal(i, SIG_IGN);
|
||||||
else
|
else
|
||||||
signal(i,sig_handler);
|
signal(i,sig_handler);
|
||||||
}
|
}
|
||||||
|
@ -200,9 +226,10 @@ main()
|
||||||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
if(1) { /* change to 0 in order to wait for external signals */
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
char *cpt= NULL,c;
|
char *cpt= NULL, c= ' ';
|
||||||
printf("Intentionally provoking SIGSEGV ...\n");
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
c= *cpt;
|
c= *cpt;
|
||||||
|
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
|
||||||
} else {
|
} else {
|
||||||
printf("killme: %d\n",getpid());
|
printf("killme: %d\n",getpid());
|
||||||
sleep(3600);
|
sleep(3600);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPL license within GPL projects, BSD license elsewise.
|
Provided under GPLv2+ within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Cleanup_includeD
|
#ifndef Cleanup_includeD
|
||||||
|
|
614
libburn/crc.c
614
libburn/crc.c
|
@ -1,43 +1,568 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
|
Containing disabled code pieces from other GPL programs.
|
||||||
|
They are just quotes for reference.
|
||||||
|
|
||||||
|
The activated code uses plain polynomial division and other primitve
|
||||||
|
algorithms to build tables of pre-computed CRC values. It then computes
|
||||||
|
the CRCs by algorithms which are derived from mathematical considerations
|
||||||
|
and from analysing the mathematical meaning of the disabled code pieces.
|
||||||
|
|
||||||
|
The comments here are quite detailed in order to prove my own understanding
|
||||||
|
of the topic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
static unsigned short ccitt_table[256] = {
|
|
||||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
|
||||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
|
||||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
|
||||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
|
||||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
|
||||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
|
||||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
|
||||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
|
||||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
|
||||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
|
||||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
|
||||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
|
||||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
|
||||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
|
||||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
|
||||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
|
||||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
|
||||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
|
||||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
|
||||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
|
||||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
|
||||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
|
||||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
|
||||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
|
||||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
|
||||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
|
||||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
|
||||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
|
||||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
|
||||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
|
||||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
|
||||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned long crc32_table[256] = {
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 22.3.6 "CRC field"
|
||||||
|
"This field contains the inverted parity bits. The CRC code word must be
|
||||||
|
divisible by the check polynomial. [...]
|
||||||
|
The generating polynomial shall be
|
||||||
|
G(x) = x^16 + x^12 + x^5 + 1
|
||||||
|
"
|
||||||
|
Also known as CRC-16-CCITT, CRC-CCITT
|
||||||
|
|
||||||
|
Used in libburn for raw write modes in sector.c.
|
||||||
|
There is also disabled code in read.c which would use it.
|
||||||
|
|
||||||
|
ts B11222:
|
||||||
|
The same algorithm is prescribed for CD-TEXT in MMC-3 Annex J.
|
||||||
|
"CRC Field consists of 2 bytes. Initiator system may use these bytes
|
||||||
|
to check errors in the Pack. The polynomial is x^16 + x^12 + x^5 + 1.
|
||||||
|
All bits shall be inverted."
|
||||||
|
|
||||||
|
libburn/cdtext.c uses a simple bit shifting function : crc_11021()
|
||||||
|
|
||||||
|
|
||||||
|
ts B20211:
|
||||||
|
Discussion why both are equivalent in respect to their result:
|
||||||
|
|
||||||
|
Both map the bits of the given bytes to a polynomial over the finite field
|
||||||
|
of two elements "GF(2)". If bytes 0 .. M are given, then bit n of byte m
|
||||||
|
is mapped to the coefficient of x exponent (n + ((M - m) * 8) + 16).
|
||||||
|
I.e. they translate the bits into a polynomial with the highest bit
|
||||||
|
becoming the coefficient of the highest power of x. Then this polynomial
|
||||||
|
is multiplied by (x exp 16).
|
||||||
|
|
||||||
|
The set of all such polynomials forms a commutative ring. Its addition
|
||||||
|
corresponds to bitwise exclusive or. Addition and subtraction are identical.
|
||||||
|
Multiplication with polynomials of only one single non-zero coefficient
|
||||||
|
corresponds to leftward bit shifting by the exponent of that coefficient.
|
||||||
|
The same rules apply as with elementary school arithmetics on integer
|
||||||
|
numbers, but with surprising results due to the finite nature of the
|
||||||
|
coefficient number space.
|
||||||
|
Note that multiplication is _not_ an iteration of addition here.
|
||||||
|
|
||||||
|
Function crc_11021() performs a division with residue by the euclidian
|
||||||
|
algorithm. I.e. it splits polynomial d into quotient q(d) and residue r(d)
|
||||||
|
in respect to the polynomial p = x exp 16 + x exp 12 + x exp 5 + x exp 0
|
||||||
|
d = p * q(d) + r(d)
|
||||||
|
where r(d) is of a polynomial degree lower than p, i.e. only x exp 15
|
||||||
|
or lower have non-zero coefficients.
|
||||||
|
The checksum crc(D) is derived by reverse mapping (r(d) * (x exp 16)).
|
||||||
|
I.e. by mapping the coefficient of (x exp n) to bit n of the 16 bit word
|
||||||
|
crc(D).
|
||||||
|
The function result is the bit-wise complement of crc(D).
|
||||||
|
|
||||||
|
Function crc_ccitt uses a table ccitt_table of r(d) values for the
|
||||||
|
polynomials d which represent the single byte values 0x00 to 0xff.
|
||||||
|
It computes r(d) by computing the residues of an iteratively expanded
|
||||||
|
polynomial. The expansion of the processed byte string A by the next byte B
|
||||||
|
from the input byte string happens by shifting the string 8 bits to the
|
||||||
|
left, and by oring B onto bits 0 to 7.
|
||||||
|
In the space of polynomials, the already processed polynomial "a" (image of
|
||||||
|
byte string A) gets expanded by polynomial b (the image of byte B) like this
|
||||||
|
a * X + b
|
||||||
|
where X is (x exp 8), i.e. the single coefficient polynomial of degree 8.
|
||||||
|
|
||||||
|
The following argumentation uses algebra with commutative, associative
|
||||||
|
and distributive laws.
|
||||||
|
Valid especially with polynomials is this rule:
|
||||||
|
(1): r(a + b) = r(a) + r(b)
|
||||||
|
because r(a) and r(b) are of degree lower than degree(p) and
|
||||||
|
degree(a + b) <= max(degree(a), degree(b))
|
||||||
|
Further valid are:
|
||||||
|
(2): r(a) = r(r(a))
|
||||||
|
(3): r(p * a) = 0
|
||||||
|
|
||||||
|
The residue of this expanded polynomial can be expressed by means of the
|
||||||
|
residue r(a) which is known from the previous iteration step, and the
|
||||||
|
residue r(b) which may be looked up in ccitt_table.
|
||||||
|
r(a * X + b)
|
||||||
|
= r(p * q(a) * X + r(a) * X + p * q(b) + r(b))
|
||||||
|
|
||||||
|
Applying rule (1):
|
||||||
|
= r(p * q(a) * X) + r(r(a) * X) + r(p * q(b)) + r(r(b))
|
||||||
|
|
||||||
|
Rule (3) and rule (2):
|
||||||
|
= r(r(a) * X) + r(b)
|
||||||
|
|
||||||
|
Be h(a) and l(a) chosen so that: r(a) = h(a) * X + l(a),
|
||||||
|
and l(a) has zero coefficients above (x exp 7), and h(a) * X has zero
|
||||||
|
coefficients below (x exp 8). (They correspond to the high and low byte
|
||||||
|
of the 16 bit word crc(A).)
|
||||||
|
So the previous statement can be written as:
|
||||||
|
= r(h(a) * X * X) + r(l(a) * X) + r(b)
|
||||||
|
|
||||||
|
Since the degree of l(a) is lower than 8, the degree of l(a) * X is lower
|
||||||
|
than 16. Thus it cannot be divisible by p which has degree 16.
|
||||||
|
So: r(l(a) * X) = l(a) * X
|
||||||
|
This yields
|
||||||
|
= l(a) * X + r(h(a) * X * X + b)
|
||||||
|
|
||||||
|
h(a) * X * X is the polynomial representation of the high byte of 16 bit
|
||||||
|
word crc(A).
|
||||||
|
So in the world of bit patterns the iteration step is:
|
||||||
|
|
||||||
|
crc(byte string A expanded by byte B)
|
||||||
|
= (low_byte(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
|
||||||
|
|
||||||
|
And this is what function crc_ccitt() does, modulo swapping the exor
|
||||||
|
operants and the final bit inversion which is prescribed by ECMA-130
|
||||||
|
and MMC-3 Annex J.
|
||||||
|
|
||||||
|
The start value of the table driven byte shifting algorithm may be
|
||||||
|
different from the start value of an equivalent bit shifting algorithm.
|
||||||
|
This is because the final flushing by zero bits is already pre-computed
|
||||||
|
in the table. So the start value of the table driven algorithm must be
|
||||||
|
the CRC of the 0-polynomial under the start value of the bit shifting
|
||||||
|
algorithm.
|
||||||
|
This fact is not of much importance here, because the start value of
|
||||||
|
the bit shifter is 0x0000 which leads to CRC 0x0000 and thus to start
|
||||||
|
value 0x0000 with the table driven byte shifter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Plain implementation of polynomial division on a Galois field, where
|
||||||
|
addition and subtraction both are binary exor. Euclidian algorithm.
|
||||||
|
Divisor is x^16 + x^12 + x^5 + 1 = 0x11021.
|
||||||
|
|
||||||
|
This is about ten times slower than the table driven algorithm.
|
||||||
|
*/
|
||||||
|
static int crc_11021(unsigned char *data, int count, int flag)
|
||||||
|
{
|
||||||
|
int acc = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < count * 8 + 16; i++) {
|
||||||
|
acc = (acc << 1);
|
||||||
|
if (i < count * 8)
|
||||||
|
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
|
||||||
|
if (acc & 0x10000)
|
||||||
|
acc ^= 0x11021;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is my own table driven implementation for which i claim copyright.
|
||||||
|
|
||||||
|
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
*/
|
||||||
|
unsigned short crc_ccitt(unsigned char *data, int count)
|
||||||
|
{
|
||||||
|
static unsigned short crc_tab[256], tab_initialized = 0;
|
||||||
|
unsigned short acc = 0;
|
||||||
|
unsigned char b[1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!tab_initialized) {
|
||||||
|
/* Create table of byte residues */
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
b[0] = i;
|
||||||
|
crc_tab[i] = crc_11021(b, 1, 0);
|
||||||
|
}
|
||||||
|
tab_initialized = 1;
|
||||||
|
}
|
||||||
|
/* There seems to be a speed advantage on amd64 if (acc << 8) is the
|
||||||
|
second operant of exor, and *(data++) seems faster than data[i].
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
acc = crc_tab[(acc >> 8) ^ *(data++)] ^ (acc << 8);
|
||||||
|
|
||||||
|
/* ECMA-130 22.3.6 and MMC-3 Annex J (CD-TEXT) want the result with
|
||||||
|
inverted bits
|
||||||
|
*/
|
||||||
|
return ~acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This was the function inherited with libburn-0.2.
|
||||||
|
|
||||||
|
static unsigned short ccitt_table[256] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||||
|
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||||
|
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||||
|
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||||
|
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||||
|
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||||
|
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||||
|
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||||
|
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||||
|
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||||
|
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||||
|
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||||
|
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||||
|
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||||
|
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||||
|
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||||
|
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||||
|
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||||
|
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||||
|
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||||
|
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||||
|
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned short crc_ccitt(unsigned char *q, int len)
|
||||||
|
{
|
||||||
|
unsigned short crc = 0;
|
||||||
|
|
||||||
|
while (len-- > 0)
|
||||||
|
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 14.3 "EDC field"
|
||||||
|
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
|
||||||
|
The error detection code shall be a 32-bit CRC applied on bytes 0 to 2063.
|
||||||
|
The least significant bit of a data byte is used first. The EDC codeword
|
||||||
|
must be divisible by the check polynomial:
|
||||||
|
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
||||||
|
The least significant parity bit (x^0) is stored in the most significant
|
||||||
|
bit position of byte 2067.
|
||||||
|
"
|
||||||
|
|
||||||
|
Used for raw writing in sector.c
|
||||||
|
|
||||||
|
|
||||||
|
ts B20211:
|
||||||
|
Discussion why function crc_32() implements above prescription of ECMA-130.
|
||||||
|
See end of this file for the ofunction inherited with libburn-0.2.
|
||||||
|
|
||||||
|
The mentioned polynomial product
|
||||||
|
(x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
||||||
|
yields this sum of x exponents
|
||||||
|
32 31 18 16
|
||||||
|
18 17 4 2
|
||||||
|
17 16 3 1
|
||||||
|
16 15 2 0
|
||||||
|
======================================
|
||||||
|
32 31 16 15 4 3 1 0
|
||||||
|
(The number of x^18 and x^17 is divisible by two and thus 0 in GF(2).)
|
||||||
|
This yields as 33 bit number:
|
||||||
|
0x18001801b
|
||||||
|
|
||||||
|
If above prescription gets implemented straight forward by function
|
||||||
|
crc_18001801b(), then its results match the ones of crc_32() with all test
|
||||||
|
strings which i could invent.
|
||||||
|
|
||||||
|
The function consists of a conventional polynomial division with reverse
|
||||||
|
input order of bits per byte.
|
||||||
|
|
||||||
|
Further it swaps the bits in the resulting 32 bit word. That is because
|
||||||
|
sector.c:sector_headers writes the 4 bytes of crc_32() as little endian.
|
||||||
|
The ECMA-130 prescription rather demands big endianness and bit swapping
|
||||||
|
towards the normal bit order in bytes:
|
||||||
|
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
|
||||||
|
[...]
|
||||||
|
The least significant parity bit (x^0) is stored in the most
|
||||||
|
significant bit position of byte 2067."
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Overall bit mirroring of a 32 bit word */
|
||||||
|
unsigned int rfl32(unsigned int acc)
|
||||||
|
{
|
||||||
|
unsigned int inv_acc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
inv_acc = 0;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if (acc & (1 << i))
|
||||||
|
inv_acc |= 1 << (31 - i);
|
||||||
|
return inv_acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Plain implementation of polynomial division on a Galois field, where
|
||||||
|
addition and subtraction both are binary exor. Euclidian algorithm.
|
||||||
|
Divisor is (x^16 + x^15 + x^2 + 1) * (x^16 + x^2 + x + 1).
|
||||||
|
|
||||||
|
This is about ten times slower than the table driven algorithm.
|
||||||
|
|
||||||
|
@param flag bit0= do not mirror bits in input bytes and result word
|
||||||
|
(Useful for building the byte indexed CRC table)
|
||||||
|
*/
|
||||||
|
static unsigned int crc_18001801b(unsigned char *data, int count, int flag)
|
||||||
|
{
|
||||||
|
unsigned int acc = 0, top;
|
||||||
|
long int i;
|
||||||
|
unsigned int inv_acc;
|
||||||
|
|
||||||
|
for (i = 0; i < count * 8 + 32; i++) {
|
||||||
|
top = acc & 0x80000000;
|
||||||
|
acc = (acc << 1);
|
||||||
|
if (i < count * 8) {
|
||||||
|
if (flag & 1)
|
||||||
|
/* Normal bit sequence of input bytes */
|
||||||
|
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
|
||||||
|
else
|
||||||
|
/* Bit sequence of input bytes mirrored */
|
||||||
|
acc |= ((data[i / 8] >> (i % 8)) & 1);
|
||||||
|
}
|
||||||
|
if (top)
|
||||||
|
acc ^= 0x8001801b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & 1)
|
||||||
|
return (unsigned int) (acc & 0xffffffff);
|
||||||
|
|
||||||
|
/* The bits of the whole 32 bit result are mirrored for ECMA-130
|
||||||
|
output compliance and for sector.c habit to store CRC little endian
|
||||||
|
although ECMA-130 prescribes it big endian.
|
||||||
|
*/
|
||||||
|
inv_acc = rfl32((unsigned int) acc);
|
||||||
|
return inv_acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Above discussion why crc_ccitt() and crc_11021() yield identical results
|
||||||
|
can be changed from 16 bit to 32 bit by chosing h(a) and l(a) so that:
|
||||||
|
r(a) = h(a) * X * X * X + l(a)
|
||||||
|
h(a) corresponds to the highest byte of crc(A), whereas l(a) corresponds
|
||||||
|
to the lower three bytes of crc(A).
|
||||||
|
|
||||||
|
This yields
|
||||||
|
r(a * X + b)
|
||||||
|
= l(a) * X + r(h(a) * X * X * X * X + b)
|
||||||
|
|
||||||
|
h(a) * X * X * X * X is the polynomial representation of the high byte of
|
||||||
|
32 bit word crc(A).
|
||||||
|
So in the world of bit patterns we have:
|
||||||
|
|
||||||
|
crc(byte string A expanded by byte B)
|
||||||
|
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
|
||||||
|
|
||||||
|
|
||||||
|
Regrettably this does not yet account for the byte-internal mirroring of
|
||||||
|
bits during the conversion from bit pattern to polynomial, and during
|
||||||
|
conversion from polynomial residue to bit pattern.
|
||||||
|
|
||||||
|
Be rfl8(D) the result of byte-internal mirroring of bit pattern D,
|
||||||
|
and mirr8(d) its corresponding polynom.
|
||||||
|
|
||||||
|
Be now h(a) and l(a) chosen so that: r(mirr8(a)) = h(a) * X * X * X + l(a)
|
||||||
|
This corresponds to highest byte and lower three bytes of crc(A).
|
||||||
|
|
||||||
|
r(mirr8(a) * X + mirr8(b))
|
||||||
|
= r(h(a) * X * X * X * X) + r(l(a) * X) + r(mirr8(b))
|
||||||
|
= l(a)) * X + r(h(a) * X * X * X * X + mirr8(b))
|
||||||
|
|
||||||
|
The corresponding bit pattern operation is
|
||||||
|
|
||||||
|
crc(mirrored byte string A expanded by mirrored byte B)
|
||||||
|
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ rfl8(B))
|
||||||
|
|
||||||
|
This demands a final result mirroring to meet the ECMA-130 prescription.
|
||||||
|
|
||||||
|
rfl8() can be implemented as lookup table.
|
||||||
|
|
||||||
|
The start value of the bit shifting iteration is 0x00000000, which leads
|
||||||
|
to the same start value for the table driven byte shifting.
|
||||||
|
|
||||||
|
The following function crc32_by_tab() yields the same results as functions
|
||||||
|
crc_18001801b() and crc_32():
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Byte-internal bit mirroring function.
|
||||||
|
*/
|
||||||
|
unsigned int rfl8(unsigned int acc)
|
||||||
|
{
|
||||||
|
unsigned int inv_acc;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
inv_acc = 0;
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
if (acc & (1 << (i + 8 * j)))
|
||||||
|
inv_acc |= 1 << ((7 - i) + 8 * j);
|
||||||
|
return inv_acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_with_crc_illustratioN
|
||||||
|
/* Not needed for libburn. The new implementation of function crc_32() is the
|
||||||
|
one that is used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int crc32_by_tab(unsigned char *data, int count, int flag)
|
||||||
|
{
|
||||||
|
static unsigned int crc_tab[256], tab_initialized = 0;
|
||||||
|
static unsigned char mirr_tab[256];
|
||||||
|
unsigned int acc, inv_acc;
|
||||||
|
unsigned char b[1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!tab_initialized) {
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
b[0] = i;
|
||||||
|
/* Create table of non-mirrored 0x18001801b residues */
|
||||||
|
crc_tab[i] = crc_18001801b(b, 1, 1);
|
||||||
|
/* Create table of mirrored byte values */
|
||||||
|
mirr_tab[i] = rfl8(i);
|
||||||
|
}
|
||||||
|
tab_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc = 0;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
acc = (acc << 8) ^ crc_tab[(acc >> 24) ^ mirr_tab[data[i]]];
|
||||||
|
|
||||||
|
/* The bits of the whole 32 bit result are mirrored for ECMA-130
|
||||||
|
output compliance and for sector.c habit to store CRC little endian
|
||||||
|
although ECMA-130 prescribes it big endian.
|
||||||
|
*/
|
||||||
|
inv_acc = rfl32((unsigned int) acc);
|
||||||
|
return inv_acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_with_crc_illustratioN */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Above function yields sufficient performance, nevertheless the old function
|
||||||
|
crc_32() (see below) is faster by avoiding the additional mirror table
|
||||||
|
lookup.
|
||||||
|
A test with 10 times 650 MB on 3000 MHz amd64:
|
||||||
|
crc_18001801b : 187 s
|
||||||
|
crc32_by_tab : 27 s
|
||||||
|
crc_32 : 16 s
|
||||||
|
|
||||||
|
So how does crc_32() avoid the application of bit mirroring to B ?.
|
||||||
|
|
||||||
|
Inherited crc_32() performs
|
||||||
|
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
||||||
|
|
||||||
|
Above function crc32_by_tab() would be
|
||||||
|
crc = crc_tab[(crc >> 24) ^ mirr_tab[*data++]] ^ (crc << 8);
|
||||||
|
|
||||||
|
The shortcut does not change the polynomial representation of the algorithm
|
||||||
|
or the mapping from and to bit patterns. It only mirrors the bit direction
|
||||||
|
in the bytes and in the 32-bit words which are involved in the bit pattern
|
||||||
|
computation. This affects input (which is desired), intermediate state
|
||||||
|
(which is as good as unmirrored), and final output (which would be slightly
|
||||||
|
undesirable if libburn could not use the mirrored result anyway).
|
||||||
|
|
||||||
|
Instead of the high byte (crc >> 24), the abbreviated algorithm uses
|
||||||
|
the low byte of the mirrored intermediate checksum (crc & 0xffL).
|
||||||
|
Instead of shifting the other three intermediate bytes to the left
|
||||||
|
(crc << 8), the abbreviated algorithm shifts them to the right (crc >> 8).
|
||||||
|
In both cases they overwrite the single byte that was used for computing
|
||||||
|
the table index.
|
||||||
|
|
||||||
|
The byte indexed table of CRC values needs to hold mirrored 32 bit values.
|
||||||
|
The byte index [(crc ^ *data++) & 0xffL] would need to be mirrored, which
|
||||||
|
would eat up the gain of not mirroring the input bytes. But this mirroring
|
||||||
|
can be pre-computed into the table by exchanging each value with the value
|
||||||
|
of its mirrored index.
|
||||||
|
|
||||||
|
So this relation exists between the CRC table crc_tab[] of crc32_by_tab()
|
||||||
|
and the table crc32_table[] of the abbreviated algorithm crc_32():
|
||||||
|
|
||||||
|
crc_tab[i] == rfl32(crc32_table[rfl8(i)])
|
||||||
|
|
||||||
|
for i={0..255}.
|
||||||
|
|
||||||
|
I compared the generated table in crc32_by_tab() by this test
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
if (rfl32(crc_tab[rfl8(i)]) != crc32_table[i] ||
|
||||||
|
crc_tab[i] != rfl32(crc32_table[rfl8(i)])) {
|
||||||
|
printf("DEVIATION : i = %d\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
No screaming abort happened.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is my own mirrored table implementation for which i claim copyright.
|
||||||
|
With gcc -O2 it shows the same efficiency as the inherited implementation
|
||||||
|
below. With -O3, -O1, or -O0 it is only slightly slower.
|
||||||
|
|
||||||
|
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
*/
|
||||||
|
unsigned int crc_32(unsigned char *data, int count)
|
||||||
|
{
|
||||||
|
static unsigned int crc_tab[256], tab_initialized = 0;
|
||||||
|
unsigned int acc = 0;
|
||||||
|
unsigned char b[1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!tab_initialized) {
|
||||||
|
/* Create table of mirrored 0x18001801b residues in
|
||||||
|
bit-mirrored index positions.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
b[0] = i;
|
||||||
|
crc_tab[rfl8(i)] = rfl32(crc_18001801b(b, 1, 1));
|
||||||
|
}
|
||||||
|
tab_initialized = 1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
acc = (acc >> 8) ^ crc_tab[(acc & 0xff) ^ data[i]];
|
||||||
|
|
||||||
|
/* The bits of the whole 32 bit result stay mirrored for ECMA-130
|
||||||
|
output 8-bit mirroring and for sector.c habit to store the CRC
|
||||||
|
little endian although ECMA-130 prescribes it big endian.
|
||||||
|
*/
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
This was the function inherited with libburn-0.2 which implements the
|
||||||
|
abbreviated algorithm. Its obscure existence led me to above insights.
|
||||||
|
My compliments to the (unknown) people who invented this.
|
||||||
|
|
||||||
|
unsigned long crc32_table[256] = {
|
||||||
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
|
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
|
||||||
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
|
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
|
||||||
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
|
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
|
||||||
|
@ -102,21 +627,16 @@ unsigned long crc32_table[256] = {
|
||||||
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
|
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
|
||||||
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
|
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
|
||||||
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned short crc_ccitt(unsigned char *q, int len)
|
unsigned int crc_32(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
unsigned short crc = 0;
|
|
||||||
|
|
||||||
while (len-- > 0)
|
|
||||||
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
|
||||||
return ~crc;
|
|
||||||
}
|
|
||||||
unsigned int crc_32(unsigned char *data, int len)
|
|
||||||
{
|
|
||||||
unsigned int crc = 0;
|
unsigned int crc = 0;
|
||||||
|
|
||||||
while (len-- > 0)
|
while (len-- > 0)
|
||||||
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,33 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
#ifndef BURN__CRC_H
|
#ifndef BURN__CRC_H
|
||||||
#define BURN__CRC_H
|
#define BURN__CRC_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Xorriso_standalonE
|
||||||
|
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
|
||||||
|
/* ts B20219 : The functions have been re-implemented from scratch after
|
||||||
|
studying texts about CRC computation and understanding the
|
||||||
|
meaning of the underlying ECMA-130 specs.
|
||||||
|
Nevertheless, there is no need to include them into xorriso
|
||||||
|
because it does neither CD-TEXT nor raw CD writing.
|
||||||
|
*/
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
#define Libburn_no_crc_C 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
|
||||||
unsigned short crc_ccitt(unsigned char *, int len);
|
unsigned short crc_ccitt(unsigned char *, int len);
|
||||||
unsigned int crc_32(unsigned char *, int len);
|
unsigned int crc_32(unsigned char *, int len);
|
||||||
|
|
||||||
|
#endif /* Libburn_no_crc_C */
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__CRC_H */
|
#endif /* BURN__CRC_H */
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
|
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
|
||||||
|
|
||||||
The system macros enable 64-bit off_t and open(2) flag O_LARGEFILE, which
|
The system macros enable 64-bit off_t and open(2) flag O_LARGEFILE, which
|
||||||
are not absolutely necessary but explicitely take into respect that
|
are not absolutely necessary but explicitly take into respect that
|
||||||
our devices can offer more than 2 GB of addressable data.
|
our devices can offer more than 2 GB of addressable data.
|
||||||
|
|
||||||
Run test program:
|
Run test program:
|
||||||
|
@ -22,6 +22,10 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -46,7 +50,9 @@ static int ddlpa_debug_mode = 1;
|
||||||
#ifndef O_LARGEFILE
|
#ifndef O_LARGEFILE
|
||||||
#define O_LARGEFILE 0
|
#define O_LARGEFILE 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ----------------------- private -------------------- */
|
/* ----------------------- private -------------------- */
|
||||||
|
|
||||||
|
@ -169,7 +175,7 @@ static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
|
||||||
int ret, o_flags, o_rw, l_type;
|
int ret, o_flags, o_rw, l_type;
|
||||||
char *o_rwtext;
|
char *o_rwtext;
|
||||||
|
|
||||||
o_flags = o->o_flags | O_NDELAY;
|
o_flags = o->o_flags | O_NDELAY | O_BINARY;
|
||||||
if(!no_o_excl)
|
if(!no_o_excl)
|
||||||
o_flags |= O_EXCL;
|
o_flags |= O_EXCL;
|
||||||
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
|
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
|
||||||
|
@ -212,7 +218,7 @@ static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
|
||||||
static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
|
static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
|
||||||
int *bus, int *host, int *channel, int *id, int *lun)
|
int *bus, int *host, int *channel, int *id, int *lun)
|
||||||
{
|
{
|
||||||
int fd, ret, open_mode = O_RDONLY | O_NDELAY;
|
int fd, ret, open_mode = O_RDONLY | O_NDELAY | O_BINARY;
|
||||||
struct my_scsi_idlun {
|
struct my_scsi_idlun {
|
||||||
int x;
|
int x;
|
||||||
int host_unique_id;
|
int host_unique_id;
|
||||||
|
@ -546,7 +552,8 @@ usage:;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
This substitutes for:
|
This substitutes for:
|
||||||
fd = open(my_path, O_RDWR | O_EXCL | O_LARGEFILE);
|
fd = open(my_path,
|
||||||
|
O_RDWR | O_EXCL | O_LARGEFILE | O_BINARY);
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,20 +25,4 @@ void burn_set_verbosity(int v)
|
||||||
burn_verbosity = v;
|
burn_verbosity = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_print(int level, const char *a, ...)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
char debug_string_data[256];
|
|
||||||
#endif
|
|
||||||
va_list vl;
|
|
||||||
|
|
||||||
if (level <= burn_verbosity) {
|
|
||||||
va_start(vl, a);
|
|
||||||
#ifdef WIN32
|
|
||||||
vsprintf(debug_string_data, a, vl);
|
|
||||||
OutputDebugString(debug_string_data);
|
|
||||||
#else
|
|
||||||
vfprintf(stderr, a, vl);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
1900
libburn/drive.c
1900
libburn/drive.c
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,25 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __DRIVE
|
#ifndef __DRIVE
|
||||||
#define __DRIVE
|
#define __DRIVE
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "structure.h"
|
#include "structure.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
struct burn_drive;
|
struct burn_drive;
|
||||||
struct command;
|
struct command;
|
||||||
struct mempage;
|
struct mempage;
|
||||||
struct scsi_mode_data;
|
struct scsi_mode_data;
|
||||||
struct burn_speed_descriptor;
|
struct burn_speed_descriptor;
|
||||||
|
struct burn_feature_descr;
|
||||||
|
|
||||||
#define LEAD_IN 1
|
#define LEAD_IN 1
|
||||||
#define GAP 2
|
#define GAP 2
|
||||||
|
@ -78,7 +86,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
|
||||||
int burn_drive_inquire_media(struct burn_drive *d);
|
int burn_drive_inquire_media(struct burn_drive *d);
|
||||||
|
|
||||||
/* ts A61125 : model aspects of burn_drive_release */
|
/* ts A61125 : model aspects of burn_drive_release */
|
||||||
int burn_drive_mark_unready(struct burn_drive *d);
|
int burn_drive_mark_unready(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A61226 */
|
/* ts A61226 */
|
||||||
|
@ -121,8 +129,9 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
||||||
int burn_drive__fd_from_special_adr(char *adr);
|
int burn_drive__fd_from_special_adr(char *adr);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70929 : Find the drive which is being worked on by pid */
|
/* ts A70929 : Find the drive which is being worked on by pid , tid */
|
||||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid);
|
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
||||||
|
pthread_t tid);
|
||||||
|
|
||||||
|
|
||||||
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
||||||
|
@ -135,4 +144,38 @@ char *burn_drive_whitelist_item(int idx, int flag);
|
||||||
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00226 : Outsourced backend of burn_abort()
|
||||||
|
@param elapsed to be subtracted from start time
|
||||||
|
@param flag bit0= do not shutdown the library
|
||||||
|
*/
|
||||||
|
int burn_abort_5(int patience,
|
||||||
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
|
void *handle, int elapsed, int flag);
|
||||||
|
|
||||||
|
/* ts B10730 */
|
||||||
|
/* Send a default mode page 05 to CD and DVD-R-oids */
|
||||||
|
int burn_drive_send_default_page_05(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B40106 */
|
||||||
|
int burn_feature_descr_new(struct burn_feature_descr **new,
|
||||||
|
unsigned char *descr, int descr_len, int flag);
|
||||||
|
|
||||||
|
/* ts B40106 */
|
||||||
|
int burn_feature_descr_free(struct burn_feature_descr **new, int flag);
|
||||||
|
|
||||||
|
/* ts B40107 */
|
||||||
|
int burn_drive_has_feature(struct burn_drive *d, int feature_code,
|
||||||
|
struct burn_feature_descr **descr, int flag);
|
||||||
|
|
||||||
|
int burn_drive_grab_stdio(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
/* ts C10213 */
|
||||||
|
/* The size of limitless or oversized devices as pseudo drives */
|
||||||
|
/* Do not lightheartedly change this value because of its meaning to
|
||||||
|
burn_drive.media_read_capacity in libburn/transport.h
|
||||||
|
64 TiB = 2 exp 46 = 2 exp 35 blocks
|
||||||
|
*/
|
||||||
|
#define BURN_DRIVE_MAX_BYTES ((off_t) (0x800000000) * (off_t) 2048)
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
|
855
libburn/ecma130ab.c
Normal file
855
libburn/ecma130ab.c
Normal file
|
@ -0,0 +1,855 @@
|
||||||
|
|
||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
|
||||||
|
|
||||||
|
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
|
This code module implements the production of RSPC parity bytes (P- and Q-
|
||||||
|
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
|
||||||
|
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf
|
||||||
|
|
||||||
|
The following statements about Galois Fields have been learned mostly from
|
||||||
|
http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf
|
||||||
|
by James S. Plank after an e-mail exchange with Norbert Preining.
|
||||||
|
|
||||||
|
The output has been compared with the output of the old code of libburn
|
||||||
|
which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg
|
||||||
|
Schilling to stem from code by Heiko Eissfeldt.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
Note: In this text, "^" denotes exponentiation and not the binary exor
|
||||||
|
operation. Confusingly in the C code "^" is said exor.
|
||||||
|
Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and
|
||||||
|
always performed inside the drive.
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
RSPC , P- and Q-Parity
|
||||||
|
|
||||||
|
ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and
|
||||||
|
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
|
||||||
|
polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02).
|
||||||
|
Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words
|
||||||
|
as 24 rows and 43 columns. Then this matrix is split into a LSB matrix
|
||||||
|
and a MSB matrix of the same layout. Parity bytes are to be computed
|
||||||
|
from these 8-bit values.
|
||||||
|
2 P-bytes cover each column of 24 bytes. They get appended to the matrix
|
||||||
|
as rows 24 and 25.
|
||||||
|
2 Q-bytes cover each the 26 diagonals of the extended matrix.
|
||||||
|
|
||||||
|
Both parity byte pairs have to be computed so that extended rows or
|
||||||
|
diagonals match this linear equation:
|
||||||
|
H x V = (0,0)
|
||||||
|
H is a 2-row matrix of size n matching the length of the V ectors
|
||||||
|
[ 1 1 ... 1 1 ]
|
||||||
|
[ x^(n-1) x^(n-2) x^1 1 ]
|
||||||
|
Vp represents a P-row. It is a byte vector consisting of row bytes at
|
||||||
|
position 0 to 23 and the two parity bytes which shall be determined
|
||||||
|
at position 24 and 25. So Hp has 26 columns.
|
||||||
|
Vq represents a Q-diagonal. It is a byte vector consisting of diagonal
|
||||||
|
bytes at position 0 to 42 and the two parity bytes at position 43 and 44.
|
||||||
|
So Hq has 45 columns. The Q-diagonals cover P-parity bytes.
|
||||||
|
|
||||||
|
By applying some high school algebra one gets the parity bytes b0, b1 of
|
||||||
|
vector V = (n_payload_bytes, b0 , b1) as
|
||||||
|
|
||||||
|
b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes )
|
||||||
|
/ (H[n+1] - H[n])
|
||||||
|
b1 = - SUM(n_payload_bytes) - b0
|
||||||
|
|
||||||
|
H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1)
|
||||||
|
The result has to be computed by Galois field arithmetics. See below.
|
||||||
|
|
||||||
|
The P-parity bytes of each column get reunited as LSB and MSB of two words.
|
||||||
|
word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117.
|
||||||
|
The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118
|
||||||
|
to 1143, word0 to 1144 to 1169.
|
||||||
|
>>> I do not read this swap of word1 and word0 from ECMA-130 Annex A.
|
||||||
|
>>> But the new output matches the old output only if it is done that way.
|
||||||
|
>>> See correctness reservation below.
|
||||||
|
|
||||||
|
Algebra on Galois fields is the same as on Rational Numbers.
|
||||||
|
But arithmetics on its polynomials differ from usual integer arithmetics
|
||||||
|
on binary numbers.
|
||||||
|
Addition and subtraction are identical with the binary exor operator.
|
||||||
|
Multiplication and division would demand polynomial division, e.g. by the
|
||||||
|
euclidean algorithm. The computing path over logarithms and powers follows
|
||||||
|
algebra and reduces the arithmetic task to table lookups, additions
|
||||||
|
modulo 255, and exor operations. Note that the logarithms are natural
|
||||||
|
numbers, not polynomials. They get added or subtracted by the usual addition
|
||||||
|
(not by exor) and their polynomial power depends on their value modulo 255.
|
||||||
|
|
||||||
|
Needed are a logarithm table and a power table (or inverse logarithm table)
|
||||||
|
for Galois Field GF(2^8) which will serve to perform the peculiar
|
||||||
|
multiplication and division operation of Galois fields.
|
||||||
|
|
||||||
|
The power table is simply an enumeration of x^n accorting to
|
||||||
|
GF-multiplication. It also serves as second line of matrix H for the parity
|
||||||
|
equations:
|
||||||
|
Hp[i] = gfpow[25-i] , i out of {0,..,25}
|
||||||
|
Hq[i] = gfpow[44-i] , i out of {0,..,44}
|
||||||
|
|
||||||
|
The logarithm table is the inverse permutation of the power table.
|
||||||
|
|
||||||
|
Some simplifications apply to the implementation:
|
||||||
|
In the world of Galois fields there is no difference between - and +.
|
||||||
|
The term (H[n+1] - H[n]) is constant: 3.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Scrambling
|
||||||
|
|
||||||
|
ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector
|
||||||
|
with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and
|
||||||
|
a 15-bit register.
|
||||||
|
It shows a diagram of a Feedback Shift Register with 16 bit boxes, though.
|
||||||
|
|
||||||
|
Comparing this with explanations in
|
||||||
|
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
|
||||||
|
one can recognize the diagram as a Fibonacci Implementation. But there seems
|
||||||
|
really to be one bit box too many.
|
||||||
|
|
||||||
|
The difference of both lengths is expressed in function next_bit() by
|
||||||
|
the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits.
|
||||||
|
Comparing the output of both alternatives with the old scrambler output
|
||||||
|
lets 15 bit win for now.
|
||||||
|
|
||||||
|
So the prescription is to start with 15 bit value 1, to use the lowest bit
|
||||||
|
as output, to shift the bits down by one, to exor the output bit with the
|
||||||
|
next lowest bit, and to put that exor result into bit 14 of the register.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Correctness Reservation
|
||||||
|
|
||||||
|
In both cases, parity and scrambling, the goal for now is to replicate the
|
||||||
|
output of the dismissed old lec.c by output which is based on published
|
||||||
|
specs and own implementation code. Whether they comply to ECMA-130 is a
|
||||||
|
different question which can only be answered by real test cases for
|
||||||
|
raw CD recording.
|
||||||
|
|
||||||
|
Of course this implementation will be corrected so that it really complies
|
||||||
|
to ECMA-130 as soon as evidence emerges that it does not yet.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130.
|
||||||
|
Generated by burn_rspc_setup_tables() and burn_rspc_print_tables().
|
||||||
|
|
||||||
|
The highest possible sum of gflog[] values is is 508. So the table gfpow[]
|
||||||
|
with period 255 was manually unrolled to 509 elements to avoid one modulo
|
||||||
|
255 operation in burn_rspc_mult().
|
||||||
|
Proposed by D. Hugh Redelmeier.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char gfpow[509] = {
|
||||||
|
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
||||||
|
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
||||||
|
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
||||||
|
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
||||||
|
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
||||||
|
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
||||||
|
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
||||||
|
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
||||||
|
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
||||||
|
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
||||||
|
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
||||||
|
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
||||||
|
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
||||||
|
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
||||||
|
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
||||||
|
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
||||||
|
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
||||||
|
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
||||||
|
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
||||||
|
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
||||||
|
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
||||||
|
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
||||||
|
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
||||||
|
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
||||||
|
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
||||||
|
108, 216, 173, 71, 142,
|
||||||
|
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
||||||
|
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
||||||
|
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
||||||
|
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
||||||
|
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
||||||
|
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
||||||
|
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
||||||
|
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
||||||
|
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
||||||
|
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
||||||
|
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
||||||
|
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
||||||
|
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
||||||
|
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
||||||
|
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
||||||
|
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
||||||
|
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
||||||
|
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
||||||
|
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
||||||
|
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
||||||
|
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
||||||
|
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
||||||
|
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
||||||
|
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
||||||
|
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
||||||
|
108, 216, 173, 71,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char gflog[256] = {
|
||||||
|
0, 0, 1, 25, 2, 50, 26, 198, 3, 223,
|
||||||
|
51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
|
||||||
|
52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
|
||||||
|
76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
|
||||||
|
53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
|
||||||
|
194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
|
||||||
|
77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
|
||||||
|
48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
|
||||||
|
54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
|
||||||
|
19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
|
||||||
|
195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
|
||||||
|
186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
|
||||||
|
78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
|
||||||
|
192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
|
||||||
|
49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
|
||||||
|
180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
|
||||||
|
55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
|
||||||
|
151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
|
||||||
|
20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
|
||||||
|
65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
|
||||||
|
196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
|
||||||
|
59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
|
||||||
|
187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
|
||||||
|
160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
|
||||||
|
79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
|
||||||
|
244, 234, 168, 80, 88, 175
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define Libburn_use_h_matriceS 1
|
||||||
|
|
||||||
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
|
||||||
|
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
|
||||||
|
than using gfpow[25-i] and gfpow[44-1]. I blame this on the more
|
||||||
|
condensed data representation which slightly increases the rate of cache
|
||||||
|
hits.
|
||||||
|
Nevertheless this effect is very likely depending on the exact cache
|
||||||
|
size and architecture. In general, using h[] saves more than 8000
|
||||||
|
subtractions per sector.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Parity matrices H as prescribed by ECMA-130 Annex A.
|
||||||
|
Actually just reverted order start pieces of gfpow[].
|
||||||
|
*/
|
||||||
|
static unsigned char h26[26] = {
|
||||||
|
3, 143, 201, 234, 117, 180, 90, 45, 152, 76,
|
||||||
|
38, 19, 135, 205, 232, 116, 58, 29, 128, 64,
|
||||||
|
32, 16, 8, 4, 2, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char h45[45] = {
|
||||||
|
238, 119, 181, 212, 106, 53, 148, 74, 37, 156,
|
||||||
|
78, 39, 157, 192, 96, 48, 24, 12, 6, 3,
|
||||||
|
143, 201, 234, 117, 180, 90, 45, 152, 76, 38,
|
||||||
|
19, 135, 205, 232, 116, 58, 29, 128, 64, 32,
|
||||||
|
16, 8, 4, 2, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* Libburn_use_h_matriceS */
|
||||||
|
|
||||||
|
|
||||||
|
/* Pseudo-random bytes which of course are exactly the same as with the
|
||||||
|
previously used code.
|
||||||
|
Generated by function print_ecma_130_scrambler().
|
||||||
|
*/
|
||||||
|
static unsigned char ecma_130_annex_b[2340] = {
|
||||||
|
1, 128, 0, 96, 0, 40, 0, 30, 128, 8,
|
||||||
|
96, 6, 168, 2, 254, 129, 128, 96, 96, 40,
|
||||||
|
40, 30, 158, 136, 104, 102, 174, 170, 252, 127,
|
||||||
|
1, 224, 0, 72, 0, 54, 128, 22, 224, 14,
|
||||||
|
200, 4, 86, 131, 126, 225, 224, 72, 72, 54,
|
||||||
|
182, 150, 246, 238, 198, 204, 82, 213, 253, 159,
|
||||||
|
1, 168, 0, 126, 128, 32, 96, 24, 40, 10,
|
||||||
|
158, 135, 40, 98, 158, 169, 168, 126, 254, 160,
|
||||||
|
64, 120, 48, 34, 148, 25, 175, 74, 252, 55,
|
||||||
|
1, 214, 128, 94, 224, 56, 72, 18, 182, 141,
|
||||||
|
182, 229, 182, 203, 54, 215, 86, 222, 190, 216,
|
||||||
|
112, 90, 164, 59, 59, 83, 83, 125, 253, 225,
|
||||||
|
129, 136, 96, 102, 168, 42, 254, 159, 0, 104,
|
||||||
|
0, 46, 128, 28, 96, 9, 232, 6, 206, 130,
|
||||||
|
212, 97, 159, 104, 104, 46, 174, 156, 124, 105,
|
||||||
|
225, 238, 200, 76, 86, 181, 254, 247, 0, 70,
|
||||||
|
128, 50, 224, 21, 136, 15, 38, 132, 26, 227,
|
||||||
|
75, 9, 247, 70, 198, 178, 210, 245, 157, 135,
|
||||||
|
41, 162, 158, 249, 168, 66, 254, 177, 128, 116,
|
||||||
|
96, 39, 104, 26, 174, 139, 60, 103, 81, 234,
|
||||||
|
188, 79, 49, 244, 20, 71, 79, 114, 180, 37,
|
||||||
|
183, 91, 54, 187, 86, 243, 126, 197, 224, 83,
|
||||||
|
8, 61, 198, 145, 146, 236, 109, 141, 237, 165,
|
||||||
|
141, 187, 37, 179, 91, 53, 251, 87, 3, 126,
|
||||||
|
129, 224, 96, 72, 40, 54, 158, 150, 232, 110,
|
||||||
|
206, 172, 84, 125, 255, 97, 128, 40, 96, 30,
|
||||||
|
168, 8, 126, 134, 160, 98, 248, 41, 130, 158,
|
||||||
|
225, 168, 72, 126, 182, 160, 118, 248, 38, 194,
|
||||||
|
154, 209, 171, 28, 127, 73, 224, 54, 200, 22,
|
||||||
|
214, 142, 222, 228, 88, 75, 122, 183, 99, 54,
|
||||||
|
169, 214, 254, 222, 192, 88, 80, 58, 188, 19,
|
||||||
|
49, 205, 212, 85, 159, 127, 40, 32, 30, 152,
|
||||||
|
8, 106, 134, 175, 34, 252, 25, 129, 202, 224,
|
||||||
|
87, 8, 62, 134, 144, 98, 236, 41, 141, 222,
|
||||||
|
229, 152, 75, 42, 183, 95, 54, 184, 22, 242,
|
||||||
|
142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
|
||||||
|
105, 142, 174, 228, 124, 75, 97, 247, 104, 70,
|
||||||
|
174, 178, 252, 117, 129, 231, 32, 74, 152, 55,
|
||||||
|
42, 150, 159, 46, 232, 28, 78, 137, 244, 102,
|
||||||
|
199, 106, 210, 175, 29, 188, 9, 177, 198, 244,
|
||||||
|
82, 199, 125, 146, 161, 173, 184, 125, 178, 161,
|
||||||
|
181, 184, 119, 50, 166, 149, 186, 239, 51, 12,
|
||||||
|
21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
|
||||||
|
47, 85, 220, 63, 25, 208, 10, 220, 7, 25,
|
||||||
|
194, 138, 209, 167, 28, 122, 137, 227, 38, 201,
|
||||||
|
218, 214, 219, 30, 219, 72, 91, 118, 187, 102,
|
||||||
|
243, 106, 197, 239, 19, 12, 13, 197, 197, 147,
|
||||||
|
19, 45, 205, 221, 149, 153, 175, 42, 252, 31,
|
||||||
|
1, 200, 0, 86, 128, 62, 224, 16, 72, 12,
|
||||||
|
54, 133, 214, 227, 30, 201, 200, 86, 214, 190,
|
||||||
|
222, 240, 88, 68, 58, 179, 83, 53, 253, 215,
|
||||||
|
1, 158, 128, 104, 96, 46, 168, 28, 126, 137,
|
||||||
|
224, 102, 200, 42, 214, 159, 30, 232, 8, 78,
|
||||||
|
134, 180, 98, 247, 105, 134, 174, 226, 252, 73,
|
||||||
|
129, 246, 224, 70, 200, 50, 214, 149, 158, 239,
|
||||||
|
40, 76, 30, 181, 200, 119, 22, 166, 142, 250,
|
||||||
|
228, 67, 11, 113, 199, 100, 82, 171, 125, 191,
|
||||||
|
97, 176, 40, 116, 30, 167, 72, 122, 182, 163,
|
||||||
|
54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
|
||||||
|
239, 50, 204, 21, 149, 207, 47, 20, 28, 15,
|
||||||
|
73, 196, 54, 211, 86, 221, 254, 217, 128, 90,
|
||||||
|
224, 59, 8, 19, 70, 141, 242, 229, 133, 139,
|
||||||
|
35, 39, 89, 218, 186, 219, 51, 27, 85, 203,
|
||||||
|
127, 23, 96, 14, 168, 4, 126, 131, 96, 97,
|
||||||
|
232, 40, 78, 158, 180, 104, 119, 110, 166, 172,
|
||||||
|
122, 253, 227, 1, 137, 192, 102, 208, 42, 220,
|
||||||
|
31, 25, 200, 10, 214, 135, 30, 226, 136, 73,
|
||||||
|
166, 182, 250, 246, 195, 6, 209, 194, 220, 81,
|
||||||
|
153, 252, 106, 193, 239, 16, 76, 12, 53, 197,
|
||||||
|
215, 19, 30, 141, 200, 101, 150, 171, 46, 255,
|
||||||
|
92, 64, 57, 240, 18, 196, 13, 147, 69, 173,
|
||||||
|
243, 61, 133, 209, 163, 28, 121, 201, 226, 214,
|
||||||
|
201, 158, 214, 232, 94, 206, 184, 84, 114, 191,
|
||||||
|
101, 176, 43, 52, 31, 87, 72, 62, 182, 144,
|
||||||
|
118, 236, 38, 205, 218, 213, 155, 31, 43, 72,
|
||||||
|
31, 118, 136, 38, 230, 154, 202, 235, 23, 15,
|
||||||
|
78, 132, 52, 99, 87, 105, 254, 174, 192, 124,
|
||||||
|
80, 33, 252, 24, 65, 202, 176, 87, 52, 62,
|
||||||
|
151, 80, 110, 188, 44, 113, 221, 228, 89, 139,
|
||||||
|
122, 231, 99, 10, 169, 199, 62, 210, 144, 93,
|
||||||
|
172, 57, 189, 210, 241, 157, 132, 105, 163, 110,
|
||||||
|
249, 236, 66, 205, 241, 149, 132, 111, 35, 108,
|
||||||
|
25, 237, 202, 205, 151, 21, 174, 143, 60, 100,
|
||||||
|
17, 235, 76, 79, 117, 244, 39, 7, 90, 130,
|
||||||
|
187, 33, 179, 88, 117, 250, 167, 3, 58, 129,
|
||||||
|
211, 32, 93, 216, 57, 154, 146, 235, 45, 143,
|
||||||
|
93, 164, 57, 187, 82, 243, 125, 133, 225, 163,
|
||||||
|
8, 121, 198, 162, 210, 249, 157, 130, 233, 161,
|
||||||
|
142, 248, 100, 66, 171, 113, 191, 100, 112, 43,
|
||||||
|
100, 31, 107, 72, 47, 118, 156, 38, 233, 218,
|
||||||
|
206, 219, 20, 91, 79, 123, 116, 35, 103, 89,
|
||||||
|
234, 186, 207, 51, 20, 21, 207, 79, 20, 52,
|
||||||
|
15, 87, 68, 62, 179, 80, 117, 252, 39, 1,
|
||||||
|
218, 128, 91, 32, 59, 88, 19, 122, 141, 227,
|
||||||
|
37, 137, 219, 38, 219, 90, 219, 123, 27, 99,
|
||||||
|
75, 105, 247, 110, 198, 172, 82, 253, 253, 129,
|
||||||
|
129, 160, 96, 120, 40, 34, 158, 153, 168, 106,
|
||||||
|
254, 175, 0, 124, 0, 33, 192, 24, 80, 10,
|
||||||
|
188, 7, 49, 194, 148, 81, 175, 124, 124, 33,
|
||||||
|
225, 216, 72, 90, 182, 187, 54, 243, 86, 197,
|
||||||
|
254, 211, 0, 93, 192, 57, 144, 18, 236, 13,
|
||||||
|
141, 197, 165, 147, 59, 45, 211, 93, 157, 249,
|
||||||
|
169, 130, 254, 225, 128, 72, 96, 54, 168, 22,
|
||||||
|
254, 142, 192, 100, 80, 43, 124, 31, 97, 200,
|
||||||
|
40, 86, 158, 190, 232, 112, 78, 164, 52, 123,
|
||||||
|
87, 99, 126, 169, 224, 126, 200, 32, 86, 152,
|
||||||
|
62, 234, 144, 79, 44, 52, 29, 215, 73, 158,
|
||||||
|
182, 232, 118, 206, 166, 212, 122, 223, 99, 24,
|
||||||
|
41, 202, 158, 215, 40, 94, 158, 184, 104, 114,
|
||||||
|
174, 165, 188, 123, 49, 227, 84, 73, 255, 118,
|
||||||
|
192, 38, 208, 26, 220, 11, 25, 199, 74, 210,
|
||||||
|
183, 29, 182, 137, 182, 230, 246, 202, 198, 215,
|
||||||
|
18, 222, 141, 152, 101, 170, 171, 63, 63, 80,
|
||||||
|
16, 60, 12, 17, 197, 204, 83, 21, 253, 207,
|
||||||
|
1, 148, 0, 111, 64, 44, 48, 29, 212, 9,
|
||||||
|
159, 70, 232, 50, 206, 149, 148, 111, 47, 108,
|
||||||
|
28, 45, 201, 221, 150, 217, 174, 218, 252, 91,
|
||||||
|
1, 251, 64, 67, 112, 49, 228, 20, 75, 79,
|
||||||
|
119, 116, 38, 167, 90, 250, 187, 3, 51, 65,
|
||||||
|
213, 240, 95, 4, 56, 3, 82, 129, 253, 160,
|
||||||
|
65, 184, 48, 114, 148, 37, 175, 91, 60, 59,
|
||||||
|
81, 211, 124, 93, 225, 249, 136, 66, 230, 177,
|
||||||
|
138, 244, 103, 7, 106, 130, 175, 33, 188, 24,
|
||||||
|
113, 202, 164, 87, 59, 126, 147, 96, 109, 232,
|
||||||
|
45, 142, 157, 164, 105, 187, 110, 243, 108, 69,
|
||||||
|
237, 243, 13, 133, 197, 163, 19, 57, 205, 210,
|
||||||
|
213, 157, 159, 41, 168, 30, 254, 136, 64, 102,
|
||||||
|
176, 42, 244, 31, 7, 72, 2, 182, 129, 182,
|
||||||
|
224, 118, 200, 38, 214, 154, 222, 235, 24, 79,
|
||||||
|
74, 180, 55, 55, 86, 150, 190, 238, 240, 76,
|
||||||
|
68, 53, 243, 87, 5, 254, 131, 0, 97, 192,
|
||||||
|
40, 80, 30, 188, 8, 113, 198, 164, 82, 251,
|
||||||
|
125, 131, 97, 161, 232, 120, 78, 162, 180, 121,
|
||||||
|
183, 98, 246, 169, 134, 254, 226, 192, 73, 144,
|
||||||
|
54, 236, 22, 205, 206, 213, 148, 95, 47, 120,
|
||||||
|
28, 34, 137, 217, 166, 218, 250, 219, 3, 27,
|
||||||
|
65, 203, 112, 87, 100, 62, 171, 80, 127, 124,
|
||||||
|
32, 33, 216, 24, 90, 138, 187, 39, 51, 90,
|
||||||
|
149, 251, 47, 3, 92, 1, 249, 192, 66, 208,
|
||||||
|
49, 156, 20, 105, 207, 110, 212, 44, 95, 93,
|
||||||
|
248, 57, 130, 146, 225, 173, 136, 125, 166, 161,
|
||||||
|
186, 248, 115, 2, 165, 193, 187, 16, 115, 76,
|
||||||
|
37, 245, 219, 7, 27, 66, 139, 113, 167, 100,
|
||||||
|
122, 171, 99, 63, 105, 208, 46, 220, 28, 89,
|
||||||
|
201, 250, 214, 195, 30, 209, 200, 92, 86, 185,
|
||||||
|
254, 242, 192, 69, 144, 51, 44, 21, 221, 207,
|
||||||
|
25, 148, 10, 239, 71, 12, 50, 133, 213, 163,
|
||||||
|
31, 57, 200, 18, 214, 141, 158, 229, 168, 75,
|
||||||
|
62, 183, 80, 118, 188, 38, 241, 218, 196, 91,
|
||||||
|
19, 123, 77, 227, 117, 137, 231, 38, 202, 154,
|
||||||
|
215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
|
||||||
|
110, 193, 236, 80, 77, 252, 53, 129, 215, 32,
|
||||||
|
94, 152, 56, 106, 146, 175, 45, 188, 29, 177,
|
||||||
|
201, 180, 86, 247, 126, 198, 160, 82, 248, 61,
|
||||||
|
130, 145, 161, 172, 120, 125, 226, 161, 137, 184,
|
||||||
|
102, 242, 170, 197, 191, 19, 48, 13, 212, 5,
|
||||||
|
159, 67, 40, 49, 222, 148, 88, 111, 122, 172,
|
||||||
|
35, 61, 217, 209, 154, 220, 107, 25, 239, 74,
|
||||||
|
204, 55, 21, 214, 143, 30, 228, 8, 75, 70,
|
||||||
|
183, 114, 246, 165, 134, 251, 34, 195, 89, 145,
|
||||||
|
250, 236, 67, 13, 241, 197, 132, 83, 35, 125,
|
||||||
|
217, 225, 154, 200, 107, 22, 175, 78, 252, 52,
|
||||||
|
65, 215, 112, 94, 164, 56, 123, 82, 163, 125,
|
||||||
|
185, 225, 178, 200, 117, 150, 167, 46, 250, 156,
|
||||||
|
67, 41, 241, 222, 196, 88, 83, 122, 189, 227,
|
||||||
|
49, 137, 212, 102, 223, 106, 216, 47, 26, 156,
|
||||||
|
11, 41, 199, 94, 210, 184, 93, 178, 185, 181,
|
||||||
|
178, 247, 53, 134, 151, 34, 238, 153, 140, 106,
|
||||||
|
229, 239, 11, 12, 7, 69, 194, 179, 17, 181,
|
||||||
|
204, 119, 21, 230, 143, 10, 228, 7, 11, 66,
|
||||||
|
135, 113, 162, 164, 121, 187, 98, 243, 105, 133,
|
||||||
|
238, 227, 12, 73, 197, 246, 211, 6, 221, 194,
|
||||||
|
217, 145, 154, 236, 107, 13, 239, 69, 140, 51,
|
||||||
|
37, 213, 219, 31, 27, 72, 11, 118, 135, 102,
|
||||||
|
226, 170, 201, 191, 22, 240, 14, 196, 4, 83,
|
||||||
|
67, 125, 241, 225, 132, 72, 99, 118, 169, 230,
|
||||||
|
254, 202, 192, 87, 16, 62, 140, 16, 101, 204,
|
||||||
|
43, 21, 223, 79, 24, 52, 10, 151, 71, 46,
|
||||||
|
178, 156, 117, 169, 231, 62, 202, 144, 87, 44,
|
||||||
|
62, 157, 208, 105, 156, 46, 233, 220, 78, 217,
|
||||||
|
244, 90, 199, 123, 18, 163, 77, 185, 245, 178,
|
||||||
|
199, 53, 146, 151, 45, 174, 157, 188, 105, 177,
|
||||||
|
238, 244, 76, 71, 117, 242, 167, 5, 186, 131,
|
||||||
|
51, 33, 213, 216, 95, 26, 184, 11, 50, 135,
|
||||||
|
85, 162, 191, 57, 176, 18, 244, 13, 135, 69,
|
||||||
|
162, 179, 57, 181, 210, 247, 29, 134, 137, 162,
|
||||||
|
230, 249, 138, 194, 231, 17, 138, 140, 103, 37,
|
||||||
|
234, 155, 15, 43, 68, 31, 115, 72, 37, 246,
|
||||||
|
155, 6, 235, 66, 207, 113, 148, 36, 111, 91,
|
||||||
|
108, 59, 109, 211, 109, 157, 237, 169, 141, 190,
|
||||||
|
229, 176, 75, 52, 55, 87, 86, 190, 190, 240,
|
||||||
|
112, 68, 36, 51, 91, 85, 251, 127, 3, 96,
|
||||||
|
1, 232, 0, 78, 128, 52, 96, 23, 104, 14,
|
||||||
|
174, 132, 124, 99, 97, 233, 232, 78, 206, 180,
|
||||||
|
84, 119, 127, 102, 160, 42, 248, 31, 2, 136,
|
||||||
|
1, 166, 128, 122, 224, 35, 8, 25, 198, 138,
|
||||||
|
210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
|
||||||
|
43, 17, 223, 76, 88, 53, 250, 151, 3, 46,
|
||||||
|
129, 220, 96, 89, 232, 58, 206, 147, 20, 109,
|
||||||
|
207, 109, 148, 45, 175, 93, 188, 57, 177, 210,
|
||||||
|
244, 93, 135, 121, 162, 162, 249, 185, 130, 242,
|
||||||
|
225, 133, 136, 99, 38, 169, 218, 254, 219, 0,
|
||||||
|
91, 64, 59, 112, 19, 100, 13, 235, 69, 143,
|
||||||
|
115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
|
||||||
|
105, 230, 174, 202, 252, 87, 1, 254, 128, 64,
|
||||||
|
96, 48, 40, 20, 30, 143, 72, 100, 54, 171,
|
||||||
|
86, 255, 126, 192, 32, 80, 24, 60, 10, 145,
|
||||||
|
199, 44, 82, 157, 253, 169, 129, 190, 224, 112,
|
||||||
|
72, 36, 54, 155, 86, 235, 126, 207, 96, 84,
|
||||||
|
40, 63, 94, 144, 56, 108, 18, 173, 205, 189,
|
||||||
|
149, 177, 175, 52, 124, 23, 97, 206, 168, 84,
|
||||||
|
126, 191, 96, 112, 40, 36, 30, 155, 72, 107,
|
||||||
|
118, 175, 102, 252, 42, 193, 223, 16, 88, 12,
|
||||||
|
58, 133, 211, 35, 29, 217, 201, 154, 214, 235,
|
||||||
|
30, 207, 72, 84, 54, 191, 86, 240, 62, 196,
|
||||||
|
16, 83, 76, 61, 245, 209, 135, 28, 98, 137,
|
||||||
|
233, 166, 206, 250, 212, 67, 31, 113, 200, 36,
|
||||||
|
86, 155, 126, 235, 96, 79, 104, 52, 46, 151,
|
||||||
|
92, 110, 185, 236, 114, 205, 229, 149, 139, 47,
|
||||||
|
39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
|
||||||
|
40, 112, 30, 164, 8, 123, 70, 163, 114, 249,
|
||||||
|
229, 130, 203, 33, 151, 88, 110, 186, 172, 115,
|
||||||
|
61, 229, 209, 139, 28, 103, 73, 234, 182, 207,
|
||||||
|
54, 212, 22, 223, 78, 216, 52, 90, 151, 123,
|
||||||
|
46, 163, 92, 121, 249, 226, 194, 201, 145, 150,
|
||||||
|
236, 110, 205, 236, 85, 141, 255, 37, 128, 27,
|
||||||
|
32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
|
||||||
|
114, 218, 165, 155, 59, 43, 83, 95, 125, 248,
|
||||||
|
33, 130, 152, 97, 170, 168, 127, 62, 160, 16,
|
||||||
|
120, 12, 34, 133, 217, 163, 26, 249, 203, 2,
|
||||||
|
215, 65, 158, 176, 104, 116, 46, 167, 92, 122,
|
||||||
|
185, 227, 50, 201, 213, 150, 223, 46, 216, 28,
|
||||||
|
90, 137, 251, 38, 195, 90, 209, 251, 28, 67,
|
||||||
|
73, 241, 246, 196, 70, 211, 114, 221, 229, 153
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the new implementation of P- and Q-parity generation.
|
||||||
|
It needs about the same computing time as the old implementation (both
|
||||||
|
with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS
|
||||||
|
are needed for 48x CD speed (7.1 MB/s).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char burn_rspc_mult(unsigned char a, unsigned char b)
|
||||||
|
{
|
||||||
|
if (a == 0 || b == 0)
|
||||||
|
return 0;
|
||||||
|
/* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier
|
||||||
|
if((((int)a - 1) | ((int)b - 1)) < 0)
|
||||||
|
return 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
return gfpow[gflog[a] + gflog[b]];
|
||||||
|
/* % 255 not necessary because gfpow is unrolled up to index 510 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the
|
||||||
|
unrolled size of the gfpow[] array.
|
||||||
|
*/
|
||||||
|
static unsigned char burn_rspc_div_3(unsigned char a)
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
return 0;
|
||||||
|
return gfpow[230 + gflog[a]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void burn_rspc_p0p1(unsigned char *sector, int col,
|
||||||
|
unsigned char *p0_lsb, unsigned char *p0_msb,
|
||||||
|
unsigned char *p1_lsb, unsigned char *p1_msb)
|
||||||
|
{
|
||||||
|
unsigned char *start, b;
|
||||||
|
unsigned int i, sum_v_lsb = 0, sum_v_msb = 0;
|
||||||
|
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
||||||
|
|
||||||
|
start = sector + 12 + 2 * col;
|
||||||
|
for(i = 0; i < 24; i++) {
|
||||||
|
b = *start;
|
||||||
|
sum_v_lsb ^= b;
|
||||||
|
|
||||||
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
hxv_lsb ^= burn_rspc_mult(b, h26[i]);
|
||||||
|
#else
|
||||||
|
hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
b = *(start + 1);
|
||||||
|
sum_v_msb ^= b;
|
||||||
|
|
||||||
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
hxv_msb ^= burn_rspc_mult(b, h26[i]);
|
||||||
|
#else
|
||||||
|
hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
start += 86;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
||||||
|
*p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
||||||
|
*p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
||||||
|
*p1_lsb = sum_v_lsb ^ *p0_lsb;
|
||||||
|
*p1_msb = sum_v_msb ^ *p0_msb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void burn_rspc_parity_p(unsigned char *sector)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb;
|
||||||
|
|
||||||
|
/* Loop over P columns */
|
||||||
|
for(i = 0; i < 43; i++) {
|
||||||
|
burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb);
|
||||||
|
sector[2162 + 2 * i] = p0_lsb;
|
||||||
|
sector[2162 + 2 * i + 1] = p0_msb;
|
||||||
|
sector[2076 + 2 * i] = p1_lsb;
|
||||||
|
sector[2076 + 2 * i + 1] = p1_msb;
|
||||||
|
|
||||||
|
#ifdef Libburn_with_lec_generatoR
|
||||||
|
if(verbous) {
|
||||||
|
printf("p %2d : %2.2X %2.2X ", i,
|
||||||
|
(unsigned int) p0_lsb, (unsigned int) p0_msb);
|
||||||
|
printf("%2.2X %2.2X ",
|
||||||
|
(unsigned int) p1_lsb, (unsigned int) p1_msb);
|
||||||
|
printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i);
|
||||||
|
}
|
||||||
|
#endif /* Libburn_with_lec_generatoR */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void burn_rspc_q0q1(unsigned char *sector, int diag,
|
||||||
|
unsigned char *q0_lsb, unsigned char *q0_msb,
|
||||||
|
unsigned char *q1_lsb, unsigned char *q1_msb)
|
||||||
|
{
|
||||||
|
unsigned char *start, b;
|
||||||
|
unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0;
|
||||||
|
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
||||||
|
|
||||||
|
start = sector + 12;
|
||||||
|
idx = 2 * 43 * diag;
|
||||||
|
for(i = 0; i < 43; i++) {
|
||||||
|
if (idx >= 2236)
|
||||||
|
idx -= 2236;
|
||||||
|
b = start[idx];
|
||||||
|
sum_v_lsb ^= b;
|
||||||
|
|
||||||
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
hxv_lsb ^= burn_rspc_mult(b, h45[i]);
|
||||||
|
#else
|
||||||
|
hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
b = start[idx + 1];
|
||||||
|
sum_v_msb ^= b;
|
||||||
|
|
||||||
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
hxv_msb ^= burn_rspc_mult(b, h45[i]);
|
||||||
|
#else
|
||||||
|
hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
idx += 88;
|
||||||
|
}
|
||||||
|
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
||||||
|
*q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
||||||
|
*q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
||||||
|
*q1_lsb = sum_v_lsb ^ *q0_lsb;
|
||||||
|
*q1_msb = sum_v_msb ^ *q0_msb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void burn_rspc_parity_q(unsigned char *sector)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb;
|
||||||
|
|
||||||
|
/* Loop over Q diagonals */
|
||||||
|
for(i = 0; i < 26; i++) {
|
||||||
|
burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb);
|
||||||
|
sector[2300 + 2 * i] = q0_lsb;
|
||||||
|
sector[2300 + 2 * i + 1] = q0_msb;
|
||||||
|
sector[2248 + 2 * i] = q1_lsb;
|
||||||
|
sector[2248 + 2 * i + 1] = q1_msb;
|
||||||
|
|
||||||
|
#ifdef Libburn_with_lec_generatoR
|
||||||
|
if(verbous) {
|
||||||
|
printf("q %2d : %2.2X %2.2X ", i,
|
||||||
|
(unsigned int) q0_lsb, (unsigned int) q0_msb);
|
||||||
|
printf("%2.2X %2.2X ",
|
||||||
|
(unsigned int) q1_lsb, (unsigned int) q1_msb);
|
||||||
|
printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i);
|
||||||
|
}
|
||||||
|
#endif /* Libburn_with_lec_generatoR */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* The new implementation of the ECMA-130 Annex B scrambler.
|
||||||
|
It is totally unoptimized. One should make use of larger word operations.
|
||||||
|
Measurements indicate that about 50 MIPS are needed for 48x CD speed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void burn_ecma130_scramble(unsigned char *sector)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char *s;
|
||||||
|
|
||||||
|
s = sector + 12;
|
||||||
|
for (i = 0; i < 2340; i++)
|
||||||
|
s[i] ^= ecma_130_annex_b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* The following code is not needed for libburn but rather documents the
|
||||||
|
origin of the tables above. In libburn it will not be compiled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_with_lec_generatoR
|
||||||
|
|
||||||
|
|
||||||
|
/* This function produced the content of gflog[] and gfpow[]
|
||||||
|
*/
|
||||||
|
static int burn_rspc_setup_tables(void)
|
||||||
|
{
|
||||||
|
unsigned int b, l;
|
||||||
|
|
||||||
|
memset(gflog, 0, sizeof(gflog));
|
||||||
|
memset(gfpow, 0, sizeof(gfpow));
|
||||||
|
b = 1;
|
||||||
|
for (l = 0; l < 255; l++) {
|
||||||
|
gfpow[l] = (unsigned char) b;
|
||||||
|
gflog[b] = (unsigned char) l;
|
||||||
|
b = b << 1;
|
||||||
|
if (b & 256)
|
||||||
|
b = b ^ 0x11d;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function printed the content of gflog[] and gfpow[] as C code
|
||||||
|
and compared the content with the tables of the old implementation.
|
||||||
|
h26[] and h45[] are reverted order copies of gfpow[]
|
||||||
|
*/
|
||||||
|
static int burn_rspc_print_tables(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("static unsigned char gfpow[255] = {");
|
||||||
|
printf("\n\t");
|
||||||
|
for(i= 0; i < 255; i++) {
|
||||||
|
printf("%3u, ", gfpow[i]);
|
||||||
|
|
||||||
|
#ifdef Libburn_with_old_lec_comparisoN
|
||||||
|
if(gfpow[i] != gf8_ilog[i])
|
||||||
|
fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if((i % 10) == 9)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n};\n\n");
|
||||||
|
|
||||||
|
printf("static unsigned char gflog[256] = {");
|
||||||
|
printf("\n\t");
|
||||||
|
for(i= 0; i < 256; i++) {
|
||||||
|
printf(" %3u,", gflog[i]);
|
||||||
|
|
||||||
|
#ifdef Libburn_with_old_lec_comparisoN
|
||||||
|
if(gflog[i] != gf8_log[i])
|
||||||
|
fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if((i % 10) == 9)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n};\n\n");
|
||||||
|
|
||||||
|
printf("static unsigned char h26[26] = {");
|
||||||
|
printf("\n\t");
|
||||||
|
for(i= 0; i < 26; i++) {
|
||||||
|
printf(" %3u,", gfpow[25 - i]);
|
||||||
|
if((i % 10) == 9)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n};\n\n");
|
||||||
|
|
||||||
|
printf("static unsigned char h45[45] = {");
|
||||||
|
printf("\n\t");
|
||||||
|
for(i= 0; i < 45; i++) {
|
||||||
|
printf(" %3u,",gfpow[44 - i]);
|
||||||
|
if((i % 10) == 9)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n};\n\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This code was used to generate the content of array ecma_130_annex_b[].
|
||||||
|
*/
|
||||||
|
static unsigned short ecma_130_fsr = 1;
|
||||||
|
|
||||||
|
static int next_bit(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ecma_130_fsr & 1;
|
||||||
|
ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff;
|
||||||
|
if (ret ^ (ecma_130_fsr & 1))
|
||||||
|
ecma_130_fsr |= 0x4000;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int print_ecma_130_scrambler(void)
|
||||||
|
{
|
||||||
|
int i, j, b;
|
||||||
|
|
||||||
|
ecma_130_fsr = 1;
|
||||||
|
printf("static unsigned char ecma_130_annex_b[2340] = {");
|
||||||
|
printf("\n\t");
|
||||||
|
for (i = 0; i < 2340; i++) {
|
||||||
|
b = 0;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
b |= next_bit() << j;
|
||||||
|
|
||||||
|
printf("%3u, ", b);
|
||||||
|
if ((i % 10) == 9)
|
||||||
|
printf("\n\t");
|
||||||
|
}
|
||||||
|
printf("\n};\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_with_general_rspc_diV
|
||||||
|
|
||||||
|
/* This is a general polynomial division function.
|
||||||
|
burn_rspc_div_3() has been derived from this by setting b to constant 3.
|
||||||
|
*/
|
||||||
|
static unsigned char burn_rspc_div(unsigned char a, unsigned char b)
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
|
||||||
|
if (a == 0)
|
||||||
|
return 0;
|
||||||
|
if (b == 0)
|
||||||
|
return -1;
|
||||||
|
d = gflog[a] - gflog[b];
|
||||||
|
if (d < 0)
|
||||||
|
d += 255;
|
||||||
|
return gfpow[d];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_with_general_rspc_diV */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Libburn_with_lec_generatoR */
|
||||||
|
|
24
libburn/ecma130ab.h
Normal file
24
libburn/ecma130ab.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
|
||||||
|
|
||||||
|
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
|
This code module implements the computations prescribed in ECMA-130 Annex A
|
||||||
|
and B. For explanations of the underlying mathematics see ecma130ab.c .
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Libburn_ecma130ab_includeD
|
||||||
|
#define Libburn_ecma130ab_includeD 1
|
||||||
|
|
||||||
|
void burn_rspc_parity_p(unsigned char *sector);
|
||||||
|
|
||||||
|
void burn_rspc_parity_q(unsigned char *sector);
|
||||||
|
|
||||||
|
void burn_ecma130_scramble(unsigned char *sector);
|
||||||
|
|
||||||
|
#endif /* ! Libburn_ecma130ab_includeD */
|
||||||
|
|
606
libburn/file.c
606
libburn/file.c
|
@ -1,5 +1,16 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -11,10 +22,17 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "async.h"
|
#include "async.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -25,10 +43,8 @@ an unreadable disc */
|
||||||
|
|
||||||
|
|
||||||
/* This is a generic OS oriented function wrapper which compensates
|
/* This is a generic OS oriented function wrapper which compensates
|
||||||
shortcommings of read() in respect to a guaranteed amount of return data.
|
shortcomings of read() in respect to a guaranteed amount of return data.
|
||||||
See man 2 read , paragraph "RETURN VALUE".
|
See man 2 read , paragraph "RETURN VALUE".
|
||||||
Possibly libburn/file.c is not the right storage location for this.
|
|
||||||
To make it ready for a move, this function is not declared static.
|
|
||||||
*/
|
*/
|
||||||
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +100,9 @@ static off_t file_size(struct burn_source *source)
|
||||||
|
|
||||||
if (fs->fixed_size > 0)
|
if (fs->fixed_size > 0)
|
||||||
return fs->fixed_size;
|
return fs->fixed_size;
|
||||||
if (fstat(fs->datafd, &buf) == -1)
|
if (fstat(fs->datafd, &buf) != 0)
|
||||||
|
return (off_t) 0;
|
||||||
|
if ((buf.st_mode & S_IFMT) != S_IFREG)
|
||||||
return (off_t) 0;
|
return (off_t) 0;
|
||||||
return (off_t) buf.st_size;
|
return (off_t) buf.st_size;
|
||||||
}
|
}
|
||||||
|
@ -108,17 +126,17 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
fd1 = open(path, O_RDONLY);
|
fd1 = open(path, O_RDONLY | O_BINARY);
|
||||||
if (fd1 == -1)
|
if (fd1 == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (subpath != NULL) {
|
if (subpath != NULL) {
|
||||||
fd2 = open(subpath, O_RDONLY);
|
fd2 = open(subpath, O_RDONLY | O_BINARY);
|
||||||
if (fd2 == -1) {
|
if (fd2 == -1) {
|
||||||
close(fd1);
|
close(fd1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs = malloc(sizeof(struct burn_source_file));
|
fs = calloc(1, sizeof(struct burn_source_file));
|
||||||
|
|
||||||
/* ts A70825 */
|
/* ts A70825 */
|
||||||
if (fs == NULL) {
|
if (fs == NULL) {
|
||||||
|
@ -164,7 +182,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||||
|
|
||||||
if (datafd == -1)
|
if (datafd == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs = malloc(sizeof(struct burn_source_file));
|
fs = burn_alloc_mem(sizeof(struct burn_source_file), 1, 0);
|
||||||
if (fs == NULL) /* ts A70825 */
|
if (fs == NULL) /* ts A70825 */
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->datafd = datafd;
|
fs->datafd = datafd;
|
||||||
|
@ -200,9 +218,10 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||||
|
|
||||||
static int fifo_sleep(int flag)
|
static int fifo_sleep(int flag)
|
||||||
{
|
{
|
||||||
static struct timespec sleeptime = { 0, 50000000}; /* 50 ms */
|
static unsigned long sleeptime = 50000; /* 50 ms */
|
||||||
|
|
||||||
return nanosleep(&sleeptime, NULL);
|
usleep(sleeptime);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +230,7 @@ static int fifo_read(struct burn_source *source,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int ret, todo, rpos, bufsize, diff;
|
int ret, todo, rpos, bufsize, diff, counted = 0;
|
||||||
|
|
||||||
if (fs->end_of_consumption) {
|
if (fs->end_of_consumption) {
|
||||||
/* ??? msg: reading has been ended already */;
|
/* ??? msg: reading has been ended already */;
|
||||||
|
@ -256,6 +275,9 @@ static int fifo_read(struct burn_source *source,
|
||||||
"Forwarded input error ends output", 0, 0);
|
"Forwarded input error ends output", 0, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (!counted)
|
||||||
|
fs->empty_counter++;
|
||||||
|
counted = 1;
|
||||||
fifo_sleep(0);
|
fifo_sleep(0);
|
||||||
}
|
}
|
||||||
diff = fs->buf_writepos - rpos; /* read volatile only once */
|
diff = fs->buf_writepos - rpos; /* read volatile only once */
|
||||||
|
@ -285,6 +307,7 @@ static int fifo_read(struct burn_source *source,
|
||||||
(size - todo), fs->buf_readpos, (double) fs->out_counter);
|
(size - todo), fs->buf_readpos, (double) fs->out_counter);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
fs->get_counter++;
|
||||||
return (size - todo);
|
return (size - todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,12 +331,37 @@ static int fifo_set_size(struct burn_source *source, off_t size)
|
||||||
static void fifo_free(struct burn_source *source)
|
static void fifo_free(struct burn_source *source)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
int wait_count;
|
||||||
|
static int wait_max = 30, wait_usleep = 100000;
|
||||||
|
|
||||||
burn_fifo_abort(fs, 0);
|
burn_fifo_abort(fs, 0);
|
||||||
|
for (wait_count = 0; wait_count <= wait_max; wait_count++) {
|
||||||
|
if (fs->thread_is_valid <= 0)
|
||||||
|
break;
|
||||||
|
if (wait_count < wait_max)
|
||||||
|
usleep(wait_usleep);
|
||||||
|
}
|
||||||
|
if (wait_count > wait_max) {
|
||||||
|
/* The shoveler thread might still be active. If so, it would
|
||||||
|
use invalid or inappropriate memory if the fifo would be
|
||||||
|
disposed now. A memory and resource leak is the better
|
||||||
|
option here.
|
||||||
|
*/
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x000201ab,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Leaving burn_source_fifo object undisposed because it is possibly stuck but alive",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fs->inp != NULL)
|
if (fs->inp != NULL)
|
||||||
burn_source_free(fs->inp);
|
burn_source_free(fs->inp);
|
||||||
|
|
||||||
if (fs->buf != NULL)
|
if (fs->buf != NULL)
|
||||||
free(fs->buf);
|
burn_os_free_buffer(fs->buf,
|
||||||
|
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||||
free((char *) fs);
|
free((char *) fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +369,8 @@ static void fifo_free(struct burn_source *source)
|
||||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes, fill;
|
||||||
|
int counted;
|
||||||
char *bufpt;
|
char *bufpt;
|
||||||
pthread_t thread_handle_storage;
|
pthread_t thread_handle_storage;
|
||||||
|
|
||||||
|
@ -330,12 +379,20 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->thread_pid = getpid();
|
fs->thread_pid = getpid();
|
||||||
fs->thread_is_valid = 1;
|
fs->thread_is_valid = 1;
|
||||||
|
|
||||||
|
/* Lock was obtained by async.c:add_worker() */
|
||||||
|
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
||||||
|
|
||||||
bufsize = fs->chunksize * fs->chunks;
|
bufsize = fs->chunksize * fs->chunks;
|
||||||
while (!fs->end_of_consumption) {
|
while (!fs->end_of_consumption) {
|
||||||
|
if (fs->do_abort)
|
||||||
|
goto emergency_exit;
|
||||||
|
|
||||||
/* wait for enough buffer space available */
|
/* wait for enough buffer space available */
|
||||||
wpos = fs->buf_writepos;
|
wpos = fs->buf_writepos;
|
||||||
|
counted = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
if (fs->do_abort)
|
||||||
|
goto emergency_exit;
|
||||||
rpos = fs->buf_readpos;
|
rpos = fs->buf_readpos;
|
||||||
diff = rpos - wpos;
|
diff = rpos - wpos;
|
||||||
trans_end = 0;
|
trans_end = 0;
|
||||||
|
@ -345,18 +402,28 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
free_bytes = diff - 1;
|
free_bytes = diff - 1;
|
||||||
else {
|
else {
|
||||||
free_bytes = (bufsize - wpos) + rpos - 1;
|
free_bytes = (bufsize - wpos) + rpos - 1;
|
||||||
if (bufsize - wpos < fs->chunksize)
|
if (bufsize - wpos < fs->inp_read_size)
|
||||||
trans_end = 1;
|
trans_end = 1;
|
||||||
}
|
}
|
||||||
if (free_bytes >= fs->chunksize)
|
if (free_bytes >= fs->inp_read_size)
|
||||||
break;
|
break;
|
||||||
|
if (!counted)
|
||||||
|
fs->full_counter++;
|
||||||
|
counted = 1;
|
||||||
fifo_sleep(0);
|
fifo_sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fill = bufsize - free_bytes - 1;
|
||||||
|
if (fill < fs->total_min_fill)
|
||||||
|
fs->total_min_fill = fill;
|
||||||
|
if (fill < fs->interval_min_fill)
|
||||||
|
fs->interval_min_fill = fill;
|
||||||
|
|
||||||
/* prepare the receiving memory */
|
/* prepare the receiving memory */
|
||||||
bufpt = fs->buf + wpos;
|
bufpt = fs->buf + wpos;
|
||||||
if (trans_end) {
|
if (trans_end) {
|
||||||
bufpt = calloc(fs->chunksize, 1);
|
bufpt = burn_os_alloc_buffer(
|
||||||
|
(size_t) fs->inp_read_size, 0);
|
||||||
if (bufpt == NULL) {
|
if (bufpt == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
0x00000003,
|
0x00000003,
|
||||||
|
@ -368,17 +435,21 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain next chunk */
|
/* Obtain next chunk */
|
||||||
|
if (fs->do_abort)
|
||||||
|
goto emergency_exit;
|
||||||
if (fs->inp->read != NULL)
|
if (fs->inp->read != NULL)
|
||||||
ret = fs->inp->read(fs->inp,
|
ret = fs->inp->read(fs->inp,
|
||||||
(unsigned char *) bufpt, fs->chunksize);
|
(unsigned char *) bufpt, fs->inp_read_size);
|
||||||
else
|
else
|
||||||
ret = fs->inp->read_xt( fs->inp,
|
ret = fs->inp->read_xt( fs->inp,
|
||||||
(unsigned char *) bufpt, fs->chunksize);
|
(unsigned char *) bufpt, fs->inp_read_size);
|
||||||
if (ret > 0)
|
if (ret == 0) {
|
||||||
fs->in_counter += ret;
|
|
||||||
else if (ret == 0)
|
/* >>> ??? ts B00326 */
|
||||||
|
/* >>> report EOF of fifo input and fs->in_counter */;
|
||||||
|
|
||||||
break; /* EOF */
|
break; /* EOF */
|
||||||
else {
|
} else if (ret < 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Read error on fifo input", errno, 0);
|
"Read error on fifo input", errno, 0);
|
||||||
|
@ -387,17 +458,23 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->input_error = EIO;
|
fs->input_error = EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fs->in_counter += ret;
|
||||||
|
fs->put_counter++;
|
||||||
|
|
||||||
/* activate read chunk */
|
/* activate read chunk */
|
||||||
if (ret > fs->chunksize) /* beware of ill custom burn_source */
|
if (fs->do_abort)
|
||||||
ret = fs->chunksize;
|
goto emergency_exit;
|
||||||
|
if (ret > fs->inp_read_size)
|
||||||
|
/* beware of ill custom burn_source */
|
||||||
|
ret = fs->inp_read_size;
|
||||||
if (trans_end) {
|
if (trans_end) {
|
||||||
/* copy to end of buffer */
|
/* copy to end of buffer */
|
||||||
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
|
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
|
||||||
/* copy to start of buffer */
|
/* copy to start of buffer */
|
||||||
memcpy(fs->buf, bufpt + (bufsize - wpos),
|
memcpy(fs->buf, bufpt + (bufsize - wpos),
|
||||||
fs->chunksize - (bufsize - wpos));
|
fs->inp_read_size - (bufsize - wpos));
|
||||||
free(bufpt);
|
burn_os_free_buffer(bufpt, (size_t) fs->inp_read_size,
|
||||||
|
0);
|
||||||
if (ret >= bufsize - wpos)
|
if (ret >= bufsize - wpos)
|
||||||
fs->buf_writepos = ret - (bufsize - wpos);
|
fs->buf_writepos = ret - (bufsize - wpos);
|
||||||
else
|
else
|
||||||
|
@ -420,8 +497,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->end_of_input = 1;
|
fs->end_of_input = 1;
|
||||||
|
|
||||||
/* wait for end of reading by consumer */;
|
/* wait for end of reading by consumer */;
|
||||||
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption)
|
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) {
|
||||||
fifo_sleep(0);
|
if (fs->do_abort)
|
||||||
|
goto emergency_exit;
|
||||||
|
fifo_sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* destroy ring buffer */;
|
/* destroy ring buffer */;
|
||||||
if (!fs->end_of_consumption)
|
if (!fs->end_of_consumption)
|
||||||
|
@ -433,24 +513,32 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
So in both cases the consumer is aware that reading is futile
|
So in both cases the consumer is aware that reading is futile
|
||||||
or even fatal.
|
or even fatal.
|
||||||
*/
|
*/
|
||||||
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
if(fs->buf != NULL)
|
||||||
|
burn_os_free_buffer(fs->buf,
|
||||||
|
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
|
|
||||||
|
emergency_exit:;
|
||||||
|
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
||||||
fs->thread_handle= NULL;
|
fs->thread_handle= NULL;
|
||||||
fs->thread_is_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
|
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
||||||
return (fs->input_error == 0);
|
return (fs->input_error == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_fifo_cancel(struct burn_source *source)
|
int burn_fifo_cancel(struct burn_source *source)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
burn_source_cancel(fs->inp);
|
ret = burn_source_cancel(fs->inp);
|
||||||
return(1);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag bit0= allow larger read chunks
|
||||||
|
*/
|
||||||
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
int chunksize, int chunks, int flag)
|
int chunksize, int chunks, int flag)
|
||||||
{
|
{
|
||||||
|
@ -469,14 +557,19 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
"Desired fifo buffer too small", 0, 0);
|
"Desired fifo buffer too small", 0, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fs = malloc(sizeof(struct burn_source_fifo));
|
fs = burn_alloc_mem(sizeof(struct burn_source_fifo), 1, 0);
|
||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->is_started = 0;
|
fs->is_started = 0;
|
||||||
fs->thread_handle = NULL;
|
fs->thread_handle = NULL;
|
||||||
fs->thread_pid = 0;
|
fs->thread_pid = 0;
|
||||||
fs->thread_is_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
|
fs->do_abort = 0;
|
||||||
fs->inp = NULL; /* set later */
|
fs->inp = NULL; /* set later */
|
||||||
|
if (flag & 1)
|
||||||
|
fs->inp_read_size = 32 * 1024;
|
||||||
|
else
|
||||||
|
fs->inp_read_size = chunksize;
|
||||||
fs->chunksize = chunksize;
|
fs->chunksize = chunksize;
|
||||||
fs->chunks = chunks;
|
fs->chunks = chunks;
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
|
@ -485,6 +578,9 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
fs->input_error = 0;
|
fs->input_error = 0;
|
||||||
fs->end_of_consumption = 0;
|
fs->end_of_consumption = 0;
|
||||||
fs->in_counter = fs->out_counter = 0;
|
fs->in_counter = fs->out_counter = 0;
|
||||||
|
fs->total_min_fill = fs->interval_min_fill = 0;
|
||||||
|
fs->put_counter = fs->get_counter = 0;
|
||||||
|
fs->empty_counter = fs->full_counter = 0;
|
||||||
|
|
||||||
src = burn_source_new();
|
src = burn_source_new();
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
|
@ -550,34 +646,91 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
/* ts A91125 : API */
|
||||||
|
void burn_fifo_get_statistics(struct burn_source *source,
|
||||||
|
int *total_min_fill, int *interval_min_fill,
|
||||||
|
int *put_counter, int *get_counter,
|
||||||
|
int *empty_counter, int *full_counter)
|
||||||
|
{
|
||||||
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
|
*total_min_fill = fs->total_min_fill;
|
||||||
|
*interval_min_fill = fs->interval_min_fill;
|
||||||
|
*put_counter = fs->put_counter;
|
||||||
|
*get_counter = fs->get_counter;
|
||||||
|
*empty_counter = fs->empty_counter;
|
||||||
|
*full_counter = fs->full_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91125 : API */
|
||||||
|
void burn_fifo_next_interval(struct burn_source *source,
|
||||||
|
int *interval_min_fill)
|
||||||
|
{
|
||||||
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
int size, free_bytes, ret;
|
||||||
|
char *status_text;
|
||||||
|
|
||||||
|
*interval_min_fill = fs->interval_min_fill;
|
||||||
|
ret = burn_fifo_inquire_status(source,
|
||||||
|
&size, &free_bytes, &status_text);
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
fs->interval_min_fill = size - free_bytes - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= do not copy to buf but only wait until the fifo has read
|
||||||
|
bufsize or input ended.
|
||||||
|
The same happens if buf is NULL.
|
||||||
|
bit1= fill to max fifo size
|
||||||
|
*/
|
||||||
|
int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int size, free_bytes, ret, wait_count= 0;
|
int size, free_bytes, ret, wait_count= 0;
|
||||||
char *status_text;
|
char *status_text;
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
flag |= 1;
|
||||||
|
|
||||||
/* Eventually start fifo thread by reading 0 bytes */
|
/* Eventually start fifo thread by reading 0 bytes */
|
||||||
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
||||||
if (ret<0)
|
if (ret<0)
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
/* wait for at least bufsize bytes being ready */
|
/* wait for at least bufsize bytes being ready */
|
||||||
while (1) {
|
while (1) {
|
||||||
ret= burn_fifo_inquire_status(source,
|
ret= burn_fifo_inquire_status(source,
|
||||||
&size, &free_bytes, &status_text);
|
&size, &free_bytes, &status_text);
|
||||||
if (size < bufsize) {
|
if (flag & 2) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
|
bufsize = size - (size % fs->inp_read_size) -
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
fs->inp_read_size;
|
||||||
"Fifo size is smaller than desired peek buffer", 0, 0);
|
if (bufsize <= 0)
|
||||||
return -1;
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if (size - fs->inp_read_size < bufsize) {
|
||||||
|
if (flag & 1) {
|
||||||
|
bufsize = size - (size % fs->inp_read_size) -
|
||||||
|
fs->inp_read_size;
|
||||||
|
if (bufsize <= 0)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
} else {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x0002015c, LIBDAX_MSGS_SEV_FAILURE,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Fifo size too small for desired peek buffer",
|
||||||
|
0, 0);
|
||||||
|
{ret = -1; goto ex;}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Fifo is already under consumption when peeking is desired",
|
"Fifo is already under consumption when peeking is desired",
|
||||||
0, 0);
|
0, 0);
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
}
|
}
|
||||||
if(size - free_bytes >= bufsize) {
|
if(size - free_bytes >= bufsize) {
|
||||||
|
|
||||||
|
@ -586,17 +739,33 @@ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
||||||
wait_count, status_text, size - free_bytes);
|
wait_count, status_text, size - free_bytes);
|
||||||
*/
|
*/
|
||||||
|
if(!(flag & 1))
|
||||||
memcpy(buf, fs->buf, bufsize);
|
memcpy(buf, fs->buf, bufsize);
|
||||||
return 1;
|
{ret = 1; goto ex;}
|
||||||
}
|
}
|
||||||
if (ret&2) { /* input has ended, not enough data arrived */
|
|
||||||
|
if (ret & 2) {
|
||||||
|
/* input has ended, not enough data arrived */
|
||||||
|
if (flag & 1)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Fifo input ended short of desired peek buffer size",
|
"Fifo input ended short of desired peek buffer size",
|
||||||
0, 0);
|
0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (free_bytes < fs->inp_read_size) {
|
||||||
|
/* Usable fifo size filled, not enough data arrived */
|
||||||
|
if (flag & 1)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020174,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Fifo alignment does not allow desired read size",
|
||||||
|
0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
wait_count++;
|
wait_count++;
|
||||||
|
|
||||||
|
@ -608,5 +777,348 @@ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
return(0);
|
ret = 0;
|
||||||
|
ex:;
|
||||||
|
fs->total_min_fill = fs->interval_min_fill = fs->buf_writepos;
|
||||||
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80713 : API */
|
||||||
|
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
return burn_fifo_fill_data(source, buf, bufsize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91125 : API */
|
||||||
|
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
|
||||||
|
{
|
||||||
|
return burn_fifo_fill_data(source, NULL, bufsize,
|
||||||
|
1 | ((flag & 1) << 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------- Offset source ----------------------------- */
|
||||||
|
/* ts B00922 */
|
||||||
|
|
||||||
|
static void offst_free(struct burn_source *source);
|
||||||
|
|
||||||
|
/* @param flag bit0 = do not check for burn_source_offst, do not return NULL
|
||||||
|
*/
|
||||||
|
static struct burn_source_offst *offst_auth(struct burn_source *source,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
if (source->free_data != offst_free && !(flag & 1)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Expected offset source object as parameter",
|
||||||
|
0, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (struct burn_source_offst *) source->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t offst_get_size(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
|
if ((fs = offst_auth(source, 0)) == NULL)
|
||||||
|
return (off_t) 0;
|
||||||
|
return fs->nominal_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int offst_set_size(struct burn_source *source, off_t size)
|
||||||
|
{
|
||||||
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
|
if ((fs = offst_auth(source, 0)) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fs->nominal_size = size;
|
||||||
|
if (fs->size <= 0 || fs->size_adjustable)
|
||||||
|
fs->size = size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void offst_free(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
|
if ((fs = offst_auth(source, 0)) == NULL)
|
||||||
|
return;
|
||||||
|
if (fs->prev != NULL)
|
||||||
|
offst_auth(fs->prev, 1)->next = fs->next;
|
||||||
|
if (fs->next != NULL)
|
||||||
|
offst_auth(fs->next, 1)->prev = fs->prev;
|
||||||
|
if (fs->inp != NULL)
|
||||||
|
burn_source_free(fs->inp); /* i.e. decrement refcount */
|
||||||
|
free(source->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int offst_read(struct burn_source *source, unsigned char *buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
int ret, to_read, todo;
|
||||||
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
|
if ((fs = offst_auth(source, 0)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Eventually skip bytes up to start position */;
|
||||||
|
if (!fs->running) {
|
||||||
|
if (fs->prev != NULL)
|
||||||
|
fs->pos = offst_auth(fs->prev, 1)->pos;
|
||||||
|
fs->running= 1;
|
||||||
|
}
|
||||||
|
if(fs->pos < fs->start) {
|
||||||
|
todo = fs->start - fs->pos;
|
||||||
|
while (todo > 0) {
|
||||||
|
to_read = todo;
|
||||||
|
if (to_read > size)
|
||||||
|
to_read = size;
|
||||||
|
ret = burn_source_read(fs->inp, buffer, to_read);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
todo -= ret;
|
||||||
|
fs->pos += ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Produce EOF if source size is exhausted.
|
||||||
|
burn_source delivers no incomplete sector buffers.
|
||||||
|
*/
|
||||||
|
if (fs->pos + size > fs->start + fs->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Read payload */
|
||||||
|
ret = burn_source_read(fs->inp, buffer, size);
|
||||||
|
if (ret > 0)
|
||||||
|
fs->pos += ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int offst_cancel(struct burn_source *source)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
|
if ((fs = offst_auth(source, 0)) == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = burn_source_cancel(fs->inp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_source *burn_offst_source_new(
|
||||||
|
struct burn_source *inp, struct burn_source *prev,
|
||||||
|
off_t start, off_t size, int flag)
|
||||||
|
{
|
||||||
|
struct burn_source *src;
|
||||||
|
struct burn_source_offst *fs, *prev_fs = NULL;
|
||||||
|
|
||||||
|
if (prev != NULL)
|
||||||
|
if ((prev_fs = offst_auth(prev, 0)) == NULL)
|
||||||
|
return NULL; /* Not type burn_source_offst */
|
||||||
|
|
||||||
|
fs = calloc(1, sizeof(struct burn_source_offst));
|
||||||
|
if (fs == NULL)
|
||||||
|
return NULL;
|
||||||
|
src = burn_source_new();
|
||||||
|
if (src == NULL) {
|
||||||
|
free((char *) fs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
src->read = NULL;
|
||||||
|
src->read_sub = NULL;
|
||||||
|
src->get_size = offst_get_size;
|
||||||
|
src->set_size = offst_set_size;
|
||||||
|
src->free_data = offst_free;
|
||||||
|
src->data = fs;
|
||||||
|
src->version= 1;
|
||||||
|
src->read_xt = offst_read;
|
||||||
|
src->cancel= offst_cancel;
|
||||||
|
fs->inp = inp;
|
||||||
|
fs->prev = prev;
|
||||||
|
fs->next = NULL;
|
||||||
|
if (prev != NULL) {
|
||||||
|
if (prev_fs->next != NULL) {
|
||||||
|
offst_auth(prev_fs->next, 1)->prev = src;
|
||||||
|
fs->next = prev_fs->next;
|
||||||
|
}
|
||||||
|
prev_fs->next = src;
|
||||||
|
if (prev_fs->start + prev_fs->size > start) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020179,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Offset source start address is before end of previous source",
|
||||||
|
0, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs->start = start;
|
||||||
|
fs->size = size;
|
||||||
|
fs->size_adjustable = !(flag & 1);
|
||||||
|
fs->nominal_size = size;
|
||||||
|
fs->running = 0;
|
||||||
|
fs->pos = 0;
|
||||||
|
inp->refcount++; /* make sure inp lives longer than src */
|
||||||
|
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------- WAVE file extractor ------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B30522 */
|
||||||
|
/* API
|
||||||
|
@param flag Bitfield for control purposes:
|
||||||
|
bit0= Report about progress by UPDATE message
|
||||||
|
bit3= Enable DAP : "flaw obscuring mechanisms like
|
||||||
|
audio data mute and interpolate"
|
||||||
|
|
||||||
|
*/
|
||||||
|
int burn_drive_extract_audio(struct burn_drive *drive,
|
||||||
|
int start_sector, int sector_count,
|
||||||
|
char *target_path, int flag)
|
||||||
|
{
|
||||||
|
int fd = -1, ret, todo, sector_no, val, min, sec, fr;
|
||||||
|
int sectors_done= 0;
|
||||||
|
off_t data_size, data_count = 0;
|
||||||
|
time_t last_pacified = 0, now;
|
||||||
|
char *msg = NULL, *buf = NULL;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(msg, char, 4096);
|
||||||
|
BURN_ALLOC_MEM(buf, char, 24 * 2352);
|
||||||
|
|
||||||
|
fd = open(target_path, O_WRONLY | O_CREAT | O_BINARY,
|
||||||
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||||
|
if (fd == -1) {
|
||||||
|
sprintf(msg, "Cannot open disk file for writing: %.4000s",
|
||||||
|
target_path);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x000201a1,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, errno, 0);
|
||||||
|
ret = 0; goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WAV header */
|
||||||
|
strcpy(buf, "RIFF");
|
||||||
|
val = 4 + 8 + 16 + 8 + sector_count * 2352; /* ChunkSize */
|
||||||
|
burn_int_to_lsb(val, buf + 4);
|
||||||
|
strcpy(buf + 8, "WAVE");
|
||||||
|
strcpy(buf + 12, "fmt ");
|
||||||
|
burn_int_to_lsb(16, buf + 16); /* Subchunk1Size */
|
||||||
|
buf[20] = 1; /* AudioFormat */
|
||||||
|
buf[21] = 0;
|
||||||
|
buf[22] = 2; /* NumChannels */
|
||||||
|
buf[23] = 0;
|
||||||
|
burn_int_to_lsb(44100, buf + 24); /* SampleRate */
|
||||||
|
burn_int_to_lsb(176400, buf + 28); /* ByteRate */
|
||||||
|
buf[32] = 4; /* BlockAlign */
|
||||||
|
buf[33] = 0;
|
||||||
|
buf[34] = 16; /* BitsPerSample */
|
||||||
|
buf[35] = 0;
|
||||||
|
strcpy(buf + 36, "data");
|
||||||
|
burn_int_to_lsb(sector_count * 2352, buf + 40); /* Subchunk2Size */
|
||||||
|
|
||||||
|
ret = write(fd, buf, 44);
|
||||||
|
if (ret == -1)
|
||||||
|
goto write_error;
|
||||||
|
|
||||||
|
/* Audio data */
|
||||||
|
todo = sector_count;
|
||||||
|
sector_no = start_sector;
|
||||||
|
while (todo > 0) {
|
||||||
|
if (todo > 24)
|
||||||
|
data_size = 24 * 2352;
|
||||||
|
else
|
||||||
|
data_size = todo * 2352;
|
||||||
|
ret = burn_read_audio(drive, sector_no, buf, data_size,
|
||||||
|
&data_count, flag & 8);
|
||||||
|
if (ret <= 0) {
|
||||||
|
sprintf(msg, "Failure to read audio sectors");
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x000201a4,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = write(fd, buf, data_count);
|
||||||
|
if (ret == -1) {
|
||||||
|
write_error:;
|
||||||
|
sprintf(msg,
|
||||||
|
"Error while writing to disk file: %.4000s",
|
||||||
|
target_path);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x000201a2,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, errno, 0);
|
||||||
|
ret = 0; goto ex;
|
||||||
|
}
|
||||||
|
todo -= data_count / 2352;
|
||||||
|
sectors_done += data_count / 2352;
|
||||||
|
sector_no += data_count / 2352;
|
||||||
|
if ((flag & 1) && (now = time(NULL)) - last_pacified >= 1) {
|
||||||
|
last_pacified = now;
|
||||||
|
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
|
||||||
|
sprintf(msg,
|
||||||
|
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
|
||||||
|
min, sec,
|
||||||
|
((double) sectors_done) * 2352.0 / 1048576.0);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
|
||||||
|
LIBDAX_MSGS_SEV_UPDATE,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flag & 1)) {
|
||||||
|
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
|
||||||
|
sprintf(msg,
|
||||||
|
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
|
||||||
|
min, sec, ((double) sectors_done) * 2352.0 / 1048576.0);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
|
||||||
|
LIBDAX_MSGS_SEV_UPDATE,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(buf);
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B30522 */
|
||||||
|
/* API
|
||||||
|
@param flag Bitfield for control purposes:
|
||||||
|
bit0= Report about progress by UPDATE message
|
||||||
|
bit3= Enable DAP : "flaw obscuring mechanisms like
|
||||||
|
audio data mute and interpolate"
|
||||||
|
*/
|
||||||
|
int burn_drive_extract_audio_track(struct burn_drive *drive,
|
||||||
|
struct burn_track *track,
|
||||||
|
char *target_path, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct burn_toc_entry toc_entry;
|
||||||
|
|
||||||
|
burn_track_get_entry(track, &toc_entry);
|
||||||
|
if (!(toc_entry.extensions_valid & 1)) {
|
||||||
|
/* Can only happen if burn_disc_cd_toc_extensions() is skipped
|
||||||
|
in mmc_read_toc_al().
|
||||||
|
*/
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000004,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Internal libburn error: Outdated burn_toc_entry format encountered",
|
||||||
|
errno, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = burn_drive_extract_audio(drive, toc_entry.start_lba,
|
||||||
|
toc_entry.track_blocks,
|
||||||
|
target_path, flag & (1 | 8));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__FILE_H
|
#ifndef BURN__FILE_H
|
||||||
#define BURN__FILE_H
|
#define BURN__FILE_H
|
||||||
|
|
||||||
|
@ -22,8 +27,8 @@ struct burn_source_fifo {
|
||||||
/* The fifo stays inactive and unequipped with eventual resources
|
/* The fifo stays inactive and unequipped with eventual resources
|
||||||
until its read() method is called for the first time.
|
until its read() method is called for the first time.
|
||||||
Only then burn_fifo_start() gets called, allocates the complete
|
Only then burn_fifo_start() gets called, allocates the complete
|
||||||
resources, starts a thread with burn_fifo_source_shuffler()
|
resources, starts a thread with burn_fifo_source_shoveller()
|
||||||
which shuffles data and finally destroys the resources.
|
which shovels data and finally destroys the resources.
|
||||||
This late start is to stay modest in case of multiple tracks
|
This late start is to stay modest in case of multiple tracks
|
||||||
in one disc.
|
in one disc.
|
||||||
*/
|
*/
|
||||||
|
@ -33,8 +38,12 @@ struct burn_source_fifo {
|
||||||
int thread_pid;
|
int thread_pid;
|
||||||
int thread_is_valid;
|
int thread_is_valid;
|
||||||
|
|
||||||
|
/* The shoveller aborts if this is 1. Resource leaks are possible. */
|
||||||
|
volatile int do_abort;
|
||||||
|
|
||||||
/* the burn_source for which this fifo is acting as proxy */
|
/* the burn_source for which this fifo is acting as proxy */
|
||||||
struct burn_source *inp;
|
struct burn_source *inp;
|
||||||
|
int inp_read_size;
|
||||||
|
|
||||||
/* <<< up to now it was only a pipe. This is on its way out. */
|
/* <<< up to now it was only a pipe. This is on its way out. */
|
||||||
int outlet[2];
|
int outlet[2];
|
||||||
|
@ -51,6 +60,14 @@ struct burn_source_fifo {
|
||||||
|
|
||||||
off_t in_counter;
|
off_t in_counter;
|
||||||
off_t out_counter;
|
off_t out_counter;
|
||||||
|
|
||||||
|
int total_min_fill;
|
||||||
|
int interval_min_fill;
|
||||||
|
int put_counter;
|
||||||
|
int get_counter;
|
||||||
|
int empty_counter;
|
||||||
|
int full_counter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,4 +77,26 @@ struct burn_source_fifo {
|
||||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag);
|
int burn_fifo_source_shoveller(struct burn_source *source, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00922 */
|
||||||
|
struct burn_source_offst {
|
||||||
|
|
||||||
|
/* See burn_offst_source_new() */
|
||||||
|
struct burn_source *inp;
|
||||||
|
struct burn_source *prev;
|
||||||
|
off_t start;
|
||||||
|
off_t size;
|
||||||
|
int size_adjustable;
|
||||||
|
|
||||||
|
/* for set_size/get_size */
|
||||||
|
off_t nominal_size;
|
||||||
|
|
||||||
|
/* To help offst_free() */
|
||||||
|
struct burn_source *next;
|
||||||
|
|
||||||
|
/* The current reading position */
|
||||||
|
int running;
|
||||||
|
off_t pos;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* LIBBURN__FILE_H */
|
#endif /* LIBBURN__FILE_H */
|
||||||
|
|
290
libburn/init.c
290
libburn/init.c
|
@ -1,5 +1,15 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
|
@ -9,6 +19,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/* ts A70928 : init.h is for others, not for init .c
|
/* ts A70928 : init.h is for others, not for init .c
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
@ -20,6 +31,7 @@
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* ts A60825 : The storage location for back_hacks.h variables. */
|
/* ts A60825 : The storage location for back_hacks.h variables. */
|
||||||
#define BURN_BACK_HACKS_INIT 1
|
#define BURN_BACK_HACKS_INIT 1
|
||||||
|
@ -32,14 +44,19 @@ struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
int burn_running = 0;
|
int burn_running = 0;
|
||||||
|
|
||||||
/* ts A60813 : Linux: wether to use O_EXCL on open() of device files */
|
double lib_start_time;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
|
||||||
|
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
|
||||||
|
*/
|
||||||
int burn_sg_open_o_excl = 1;
|
int burn_sg_open_o_excl = 1;
|
||||||
|
|
||||||
/* ts A70403 : Linux: wether to use fcntl(,F_SETLK,)
|
/* ts A70403 : GNU/Linux: whether to use fcntl(,F_SETLK,)
|
||||||
after open() of device files */
|
after open() of device files */
|
||||||
int burn_sg_fcntl_f_setlk = 1;
|
int burn_sg_fcntl_f_setlk = 1;
|
||||||
|
|
||||||
/* ts A70314 : Linux: what device family to use :
|
/* ts A70314 : GNU/Linux: what device family to use :
|
||||||
0= default family
|
0= default family
|
||||||
1= sr
|
1= sr
|
||||||
2= scd
|
2= scd
|
||||||
|
@ -54,11 +71,17 @@ int burn_sg_use_family = 0;
|
||||||
has been thoroughly tested. */
|
has been thoroughly tested. */
|
||||||
int burn_sg_open_o_nonblock = 1;
|
int burn_sg_open_o_nonblock = 1;
|
||||||
|
|
||||||
/* wether to take a busy drive as an error */
|
/* whether to take a busy drive as an error */
|
||||||
/* Caution: this is implemented by a rough hack and eventually leads
|
/* Caution: this is implemented by a rough hack and eventually leads
|
||||||
to unconditional abort of the process */
|
to unconditional abort of the process */
|
||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* The message returned from sg_id_string() and/or sg_initialize()
|
||||||
|
*/
|
||||||
|
static char sg_initialize_msg[1024] = {""};
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
|
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
|
@ -66,15 +89,33 @@ int burn_sg_open_abort_busy = 0;
|
||||||
/* Parameters for builtin abort handler */
|
/* Parameters for builtin abort handler */
|
||||||
static char abort_message_prefix[81] = {"libburn : "};
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
static pid_t abort_control_pid= 0;
|
static pid_t abort_control_pid= 0;
|
||||||
|
static pthread_t abort_control_thread;
|
||||||
volatile int burn_global_abort_level= 0;
|
volatile int burn_global_abort_level= 0;
|
||||||
int burn_global_abort_signum= 0;
|
int burn_global_abort_signum= 0;
|
||||||
void *burn_global_signal_handle = NULL;
|
void *burn_global_signal_handle = NULL;
|
||||||
burn_abort_handler_t burn_global_signal_handler = NULL;
|
burn_abort_handler_t burn_global_signal_handler = NULL;
|
||||||
|
int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
|
||||||
|
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : wether implemented untested profiles are supported */
|
/* ts A70223 : whether implemented untested profiles are supported */
|
||||||
int burn_support_untested_profiles = 0;
|
int burn_support_untested_profiles = 0;
|
||||||
|
|
||||||
|
/* ts A91111 :
|
||||||
|
whether to log SCSI commands (to be implemented in sg-*.c)
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
int burn_sg_log_scsi = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B10312 :
|
||||||
|
Whether to map random-access readonly files to drive role 4.
|
||||||
|
Else it is role 2 overwritable drive
|
||||||
|
*/
|
||||||
|
int burn_drive_role_4_allowed = 0;
|
||||||
|
|
||||||
|
|
||||||
/* ts A60925 : ticket 74 */
|
/* ts A60925 : ticket 74 */
|
||||||
/** Create the messenger object for libburn. */
|
/** Create the messenger object for libburn. */
|
||||||
|
@ -99,10 +140,20 @@ int burn_initialize(void)
|
||||||
|
|
||||||
if (burn_running)
|
if (burn_running)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
lib_start_time = burn_get_time(0);
|
||||||
burn_support_untested_profiles = 0;
|
burn_support_untested_profiles = 0;
|
||||||
ret = burn_msgs_initialize();
|
ret = burn_msgs_initialize();
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
ret = sg_initialize(sg_initialize_msg, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x00020175,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
sg_initialize_msg, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
burn_running = 1;
|
burn_running = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -130,10 +181,24 @@ void burn_finish(void)
|
||||||
/* ts A60924 : ticket 74 */
|
/* ts A60924 : ticket 74 */
|
||||||
libdax_msgs_destroy(&libdax_messenger,0);
|
libdax_msgs_destroy(&libdax_messenger,0);
|
||||||
|
|
||||||
|
sg_shutdown(0);
|
||||||
|
|
||||||
|
burn_drive_clear_whitelist();
|
||||||
|
|
||||||
burn_running = 0;
|
burn_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91226 */
|
||||||
|
/** API function. See libburn.h */
|
||||||
|
char *burn_scsi_transport_id(int flag)
|
||||||
|
{
|
||||||
|
if (!burn_running)
|
||||||
|
sg_id_string(sg_initialize_msg, 0);
|
||||||
|
return sg_initialize_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A60813 */
|
/* ts A60813 */
|
||||||
/** API function. See libburn.h */
|
/** API function. See libburn.h */
|
||||||
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
|
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
|
||||||
|
@ -289,6 +354,48 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B21214 API */
|
||||||
|
char *burn_list_sev_texts(int flag)
|
||||||
|
{
|
||||||
|
char *sev_list;
|
||||||
|
|
||||||
|
libdax_msgs__sev_to_text(0, &sev_list, 1);
|
||||||
|
return sev_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00224 */
|
||||||
|
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
||||||
|
{
|
||||||
|
int i, l;
|
||||||
|
|
||||||
|
sprintf(text, "[%lu,", (unsigned long int) getpid());
|
||||||
|
l= strlen(text);
|
||||||
|
for(i= 0; i < ((int) sizeof(pthread_t)) && 2 * i < 80 - l - 3; i++)
|
||||||
|
sprintf(text + l + 2 * i,
|
||||||
|
"%2.2X", ((unsigned char *) &tid)[i]);
|
||||||
|
|
||||||
|
sprintf(text + l + 2 * i, "]");
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B20122 */
|
||||||
|
/* @param value 0=return rather than exit(value)
|
||||||
|
*/
|
||||||
|
int burn_abort_exit(int value)
|
||||||
|
{
|
||||||
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
if (value)
|
||||||
|
exit(value);
|
||||||
|
burn_global_abort_level = -2;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -296,15 +403,53 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
/*
|
/*
|
||||||
#define Libburn_signal_handler_verbouS 1
|
#define Libburn_signal_handler_verbouS 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
|
|
||||||
#ifdef Libburn_signal_handler_verbouS
|
#ifdef Libburn_signal_handler_verbouS
|
||||||
fprintf(stderr,
|
char text[80];
|
||||||
"libburn_ABORT: pid = %d , abort_control_pid = %d , sig= %d\n",
|
|
||||||
getpid(), abort_control_pid, signum);
|
fprintf(stderr, "libburn_ABORT: in = %s\n",
|
||||||
|
burn_util_thread_id(getpid(), pthread_self(), text));
|
||||||
|
fprintf(stderr, "libburn_ABORT: ctrl = %s\n",
|
||||||
|
burn_util_thread_id(abort_control_pid, abort_control_thread,
|
||||||
|
text));
|
||||||
|
if (burn_global_signal_handler == burn_builtin_abort_handler)
|
||||||
|
fprintf(stderr, "libburn_ABORT: signal action = %d\n",
|
||||||
|
burn_builtin_signal_action);
|
||||||
|
|
||||||
|
/* >>> find writing drives and report their tid
|
||||||
|
fprintf(stderr, "libburn_ABORT: wrt = %s\n",
|
||||||
|
burn_util_thread_id(0, burn_write_thread_id, text));
|
||||||
|
fprintf(stderr, "libburn_ABORT: sig= %d\n", signum);
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
burn_builtin_triggered_action = burn_builtin_signal_action;
|
||||||
|
burn_global_abort_level = -1;
|
||||||
|
|
||||||
|
if (burn_builtin_signal_action > 1) {
|
||||||
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
if (burn_builtin_signal_action == 4)
|
||||||
|
return -2;
|
||||||
|
fprintf(stderr,"%sABORT : Trying to shut down busy drives\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
burn_abort_5(0, burn_abort_pacifier, abort_message_prefix,
|
||||||
|
0, 1);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020177,
|
||||||
|
LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Urged drive worker threads to do emergency halt",
|
||||||
|
0, 0);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- old deprecated stuck-in-abort-handler loop ---- */
|
||||||
|
|
||||||
/* ts A70928:
|
/* ts A70928:
|
||||||
Must be quick. Allowed to coincide with other thread and to share
|
Must be quick. Allowed to coincide with other thread and to share
|
||||||
the increment with that one. It must not decrease, though, and
|
the increment with that one. It must not decrease, though, and
|
||||||
|
@ -317,7 +462,8 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
|
|
||||||
#ifdef Libburn_new_thread_signal_handleR
|
#ifdef Libburn_new_thread_signal_handleR
|
||||||
|
|
||||||
ret = burn_drive_find_by_thread_pid(&d, getpid());
|
ret = burn_drive_find_by_thread_pid(&d, getpid(),
|
||||||
|
pthread_self());
|
||||||
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
||||||
/* This is an active writer thread */
|
/* This is an active writer thread */
|
||||||
|
|
||||||
|
@ -357,6 +503,7 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
}
|
}
|
||||||
burn_global_abort_level = -1;
|
burn_global_abort_level = -1;
|
||||||
Cleanup_set_handlers(NULL, NULL, 2);
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
|
||||||
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -364,37 +511,110 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
burn_abort_exit(0);
|
||||||
|
return (1);
|
||||||
fprintf(stderr,
|
|
||||||
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
|
||||||
abort_message_prefix);
|
|
||||||
burn_global_abort_level = -2;
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 : API */
|
||||||
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
if(handler == NULL && mode == 0) {
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_experimental: burn_set_signal_handling, handler==%lx mode=%d\n", (unsigned long) handler, mode);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(handler == NULL) {
|
||||||
handler = burn_builtin_abort_handler;
|
handler = burn_builtin_abort_handler;
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
if ((mode & ~4) == 0)
|
||||||
|
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
strcpy(abort_message_prefix, "libburn : ");
|
strcpy(abort_message_prefix, "libburn : ");
|
||||||
if(handle != NULL)
|
abort_message_prefix[0] = 0;
|
||||||
|
if(handle != NULL && handler == burn_builtin_abort_handler)
|
||||||
strncpy(abort_message_prefix, (char *) handle,
|
strncpy(abort_message_prefix, (char *) handle,
|
||||||
sizeof(abort_message_prefix)-1);
|
sizeof(abort_message_prefix)-1);
|
||||||
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
abort_control_pid = getpid();
|
abort_control_pid = getpid();
|
||||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
abort_control_thread = pthread_self();
|
||||||
|
burn_builtin_signal_action = (mode >> 4) & 15;
|
||||||
|
if((mode & 11) != 0)
|
||||||
|
burn_builtin_signal_action = 0;
|
||||||
|
if(burn_builtin_signal_action > 1)
|
||||||
|
burn_builtin_triggered_action = 0;
|
||||||
|
if(burn_builtin_signal_action == 0)
|
||||||
|
burn_builtin_signal_action = 1;
|
||||||
|
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
|
||||||
|
(mode & 15) | 4 | (mode & 256));
|
||||||
burn_global_signal_handle = handle;
|
burn_global_signal_handle = handle;
|
||||||
burn_global_signal_handler = handler;
|
burn_global_signal_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00304 : API */
|
||||||
|
int burn_is_aborting(int flag)
|
||||||
|
{
|
||||||
|
return burn_builtin_triggered_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00225 */
|
||||||
|
/* @return 0= no abort action 2 pending , 1= not control thread
|
||||||
|
*/
|
||||||
|
int burn_init_catch_on_abort(int flag)
|
||||||
|
{
|
||||||
|
if (burn_builtin_triggered_action != 2)
|
||||||
|
return 0;
|
||||||
|
if (abort_control_pid != getpid() ||
|
||||||
|
abort_control_thread != pthread_self())
|
||||||
|
return 1;
|
||||||
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* B20122 */
|
||||||
|
/* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort()
|
||||||
|
waits for its own thread to end grabbing.
|
||||||
|
*/
|
||||||
|
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag)
|
||||||
|
{
|
||||||
|
*signal_action_mem = -1;
|
||||||
|
if (burn_global_signal_handler == burn_builtin_abort_handler &&
|
||||||
|
burn_builtin_signal_action >= 0 &&
|
||||||
|
burn_builtin_signal_action <= 2) {
|
||||||
|
*signal_action_mem = burn_builtin_signal_action;
|
||||||
|
burn_builtin_signal_action = 3;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* B20122 */
|
||||||
|
/* Re-enable builtin actions 0,1,2 and perform delayed signal reactions
|
||||||
|
*/
|
||||||
|
int burn_grab_restore_sig_action(int signal_action_mem, int flag)
|
||||||
|
{
|
||||||
|
if (signal_action_mem >= 0)
|
||||||
|
burn_builtin_signal_action = signal_action_mem;
|
||||||
|
if (burn_is_aborting(0) && signal_action_mem >= 0) {
|
||||||
|
if (signal_action_mem == 0 || signal_action_mem == 1) {
|
||||||
|
burn_abort_exit(1); /* Never comes back */
|
||||||
|
} else if (signal_action_mem == 2) {
|
||||||
|
burn_builtin_triggered_action = signal_action_mem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : API */
|
/* ts A70223 : API */
|
||||||
void burn_allow_untested_profiles(int yes)
|
void burn_allow_untested_profiles(int yes)
|
||||||
{
|
{
|
||||||
|
@ -414,3 +634,31 @@ int burn_set_messenger(void *messenger)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91111 API */
|
||||||
|
void burn_set_scsi_logging(int flag)
|
||||||
|
{
|
||||||
|
burn_sg_log_scsi = flag & 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B10312 API */
|
||||||
|
void burn_allow_drive_role_4(int allowed)
|
||||||
|
{
|
||||||
|
burn_drive_role_4_allowed = (allowed & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B10606 */
|
||||||
|
void *burn_alloc_mem(size_t size, size_t count, int flag)
|
||||||
|
{
|
||||||
|
void *pt;
|
||||||
|
|
||||||
|
pt = calloc(count, size);
|
||||||
|
if(pt == NULL)
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Out of virtual memory", 0, 0);
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__INIT_H
|
#ifndef BURN__INIT_H
|
||||||
#define BURN__INIT_H
|
#define BURN__INIT_H
|
||||||
|
|
||||||
extern int burn_running;
|
extern int burn_running;
|
||||||
|
|
||||||
/** Indicator for burn_drive_get_status() wether a signal hit parts of the
|
extern double lib_start_time;
|
||||||
|
|
||||||
|
/** Indicator for burn_drive_get_status() whether a signal hit parts of the
|
||||||
thread team.
|
thread team.
|
||||||
0= all works well ,
|
0= all works well ,
|
||||||
1 to 5 = waiting for eventual signal on control thread
|
1 to 5 = waiting for eventual signal on control thread
|
||||||
|
@ -17,5 +24,40 @@ extern int burn_global_abort_signum;
|
||||||
extern void *burn_global_signal_handle;
|
extern void *burn_global_signal_handle;
|
||||||
extern burn_abort_handler_t burn_global_signal_handler;
|
extern burn_abort_handler_t burn_global_signal_handler;
|
||||||
|
|
||||||
|
extern int burn_builtin_signal_action; /* burn_set_signal_handling() */
|
||||||
|
extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00225 */
|
||||||
|
/* @return 0= no abort pending , 1= not control thread ,
|
||||||
|
-1= surprisingly burn_abort returned
|
||||||
|
*/
|
||||||
|
int burn_init_catch_on_abort(int flag);
|
||||||
|
|
||||||
|
/* ts B10606 */
|
||||||
|
void *burn_alloc_mem(size_t size, size_t count, int flag);
|
||||||
|
|
||||||
|
#define BURN_ALLOC_MEM(pt, typ, count) { \
|
||||||
|
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||||
|
if(pt == NULL) { \
|
||||||
|
ret= -1; goto ex; \
|
||||||
|
} }
|
||||||
|
|
||||||
|
#define BURN_ALLOC_MEM_VOID(pt, typ, count) { \
|
||||||
|
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||||
|
if(pt == NULL) { \
|
||||||
|
goto ex; \
|
||||||
|
} }
|
||||||
|
|
||||||
|
#define BURN_FREE_MEM(pt) { \
|
||||||
|
if(pt != NULL) \
|
||||||
|
free((char *) pt); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* B20122 */
|
||||||
|
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag);
|
||||||
|
int burn_grab_restore_sig_action(int signal_action_mem, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__INIT_H */
|
#endif /* BURN__INIT_H */
|
||||||
|
|
451
libburn/lec.c
451
libburn/lec.c
|
@ -1,451 +0,0 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
||||||
|
|
||||||
/* borrowed HEAVILY from cdrdao */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "lec.h"
|
|
||||||
|
|
||||||
#define LEC_HEADER_OFFSET 12
|
|
||||||
#define LEC_MODE1_P_PARITY_OFFSET 2076
|
|
||||||
#define LEC_MODE1_Q_PARITY_OFFSET 2248
|
|
||||||
|
|
||||||
static unsigned char gf8_ilog[255] = {
|
|
||||||
1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76,
|
|
||||||
152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96,
|
|
||||||
192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119,
|
|
||||||
238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186,
|
|
||||||
105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94,
|
|
||||||
188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187,
|
|
||||||
107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217,
|
|
||||||
175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103,
|
|
||||||
206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197,
|
|
||||||
151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79,
|
|
||||||
158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85,
|
|
||||||
170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99,
|
|
||||||
198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227,
|
|
||||||
219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
|
||||||
174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224,
|
|
||||||
221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195,
|
|
||||||
155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244,
|
|
||||||
245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125,
|
|
||||||
250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142,
|
|
||||||
};
|
|
||||||
static unsigned char gf8_log[256] = {
|
|
||||||
0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100,
|
|
||||||
224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113,
|
|
||||||
5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18,
|
|
||||||
130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9,
|
|
||||||
120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253,
|
|
||||||
226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143,
|
|
||||||
150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182,
|
|
||||||
163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61,
|
|
||||||
202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115,
|
|
||||||
243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222,
|
|
||||||
237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124,
|
|
||||||
17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188,
|
|
||||||
207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211,
|
|
||||||
171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31,
|
|
||||||
45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12,
|
|
||||||
111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134,
|
|
||||||
177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11,
|
|
||||||
245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231,
|
|
||||||
173, 232, 116, 214, 244, 234, 168, 80, 88, 175,
|
|
||||||
};
|
|
||||||
static unsigned char gf8_q_coeffs[2][45] = {
|
|
||||||
{97, 251, 133, 60, 82, 160, 155, 201, 8, 112, 246, 11, 21, 42, 157,
|
|
||||||
169, 80, 174, 232, 230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200,
|
|
||||||
75, 103, 221, 252, 96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0},
|
|
||||||
{190, 96, 250, 132, 59, 81, 159, 154, 200, 7, 111, 245, 10, 20, 41,
|
|
||||||
156, 168, 79, 173, 231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8,
|
|
||||||
199, 74, 102, 220, 251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0}
|
|
||||||
};
|
|
||||||
static unsigned char gf8_p_coeffs[2][26] = {
|
|
||||||
{230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200, 75, 103, 221, 252,
|
|
||||||
96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0},
|
|
||||||
{231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8, 199, 74, 102, 220,
|
|
||||||
251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned char yellowbook_scrambler[2340] = {
|
|
||||||
1, 128, 0, 96, 0, 40, 0, 30, 128, 8, 96, 6, 168, 2, 254, 129, 128, 96,
|
|
||||||
96, 40, 40, 30, 158,
|
|
||||||
136, 104, 102, 174, 170, 252, 127, 1, 224, 0, 72, 0, 54, 128, 22, 224,
|
|
||||||
14, 200, 4, 86, 131, 126, 225,
|
|
||||||
224, 72, 72, 54, 182, 150, 246, 238, 198, 204, 82, 213, 253, 159, 1,
|
|
||||||
168, 0, 126, 128, 32, 96, 24, 40,
|
|
||||||
10, 158, 135, 40, 98, 158, 169, 168, 126, 254, 160, 64, 120, 48, 34,
|
|
||||||
148, 25, 175, 74, 252, 55, 1, 214,
|
|
||||||
128, 94, 224, 56, 72, 18, 182, 141, 182, 229, 182, 203, 54, 215, 86,
|
|
||||||
222, 190, 216, 112, 90, 164, 59, 59,
|
|
||||||
83, 83, 125, 253, 225, 129, 136, 96, 102, 168, 42, 254, 159, 0, 104, 0,
|
|
||||||
46, 128, 28, 96, 9, 232, 6,
|
|
||||||
206, 130, 212, 97, 159, 104, 104, 46, 174, 156, 124, 105, 225, 238,
|
|
||||||
200, 76, 86, 181, 254, 247, 0, 70, 128,
|
|
||||||
50, 224, 21, 136, 15, 38, 132, 26, 227, 75, 9, 247, 70, 198, 178, 210,
|
|
||||||
245, 157, 135, 41, 162, 158, 249,
|
|
||||||
168, 66, 254, 177, 128, 116, 96, 39, 104, 26, 174, 139, 60, 103, 81,
|
|
||||||
234, 188, 79, 49, 244, 20, 71, 79,
|
|
||||||
114, 180, 37, 183, 91, 54, 187, 86, 243, 126, 197, 224, 83, 8, 61, 198,
|
|
||||||
145, 146, 236, 109, 141, 237, 165,
|
|
||||||
141, 187, 37, 179, 91, 53, 251, 87, 3, 126, 129, 224, 96, 72, 40, 54,
|
|
||||||
158, 150, 232, 110, 206, 172, 84,
|
|
||||||
125, 255, 97, 128, 40, 96, 30, 168, 8, 126, 134, 160, 98, 248, 41, 130,
|
|
||||||
158, 225, 168, 72, 126, 182, 160,
|
|
||||||
118, 248, 38, 194, 154, 209, 171, 28, 127, 73, 224, 54, 200, 22, 214,
|
|
||||||
142, 222, 228, 88, 75, 122, 183, 99,
|
|
||||||
54, 169, 214, 254, 222, 192, 88, 80, 58, 188, 19, 49, 205, 212, 85,
|
|
||||||
159, 127, 40, 32, 30, 152, 8, 106,
|
|
||||||
134, 175, 34, 252, 25, 129, 202, 224, 87, 8, 62, 134, 144, 98, 236, 41,
|
|
||||||
141, 222, 229, 152, 75, 42, 183,
|
|
||||||
95, 54, 184, 22, 242, 142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
|
|
||||||
105, 142, 174, 228, 124, 75, 97, 247,
|
|
||||||
104, 70, 174, 178, 252, 117, 129, 231, 32, 74, 152, 55, 42, 150, 159,
|
|
||||||
46, 232, 28, 78, 137, 244, 102, 199,
|
|
||||||
106, 210, 175, 29, 188, 9, 177, 198, 244, 82, 199, 125, 146, 161, 173,
|
|
||||||
184, 125, 178, 161, 181, 184, 119, 50,
|
|
||||||
166, 149, 186, 239, 51, 12, 21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
|
|
||||||
47, 85, 220, 63, 25, 208, 10,
|
|
||||||
220, 7, 25, 194, 138, 209, 167, 28, 122, 137, 227, 38, 201, 218, 214,
|
|
||||||
219, 30, 219, 72, 91, 118, 187, 102,
|
|
||||||
243, 106, 197, 239, 19, 12, 13, 197, 197, 147, 19, 45, 205, 221, 149,
|
|
||||||
153, 175, 42, 252, 31, 1, 200, 0,
|
|
||||||
86, 128, 62, 224, 16, 72, 12, 54, 133, 214, 227, 30, 201, 200, 86, 214,
|
|
||||||
190, 222, 240, 88, 68, 58, 179,
|
|
||||||
83, 53, 253, 215, 1, 158, 128, 104, 96, 46, 168, 28, 126, 137, 224,
|
|
||||||
102, 200, 42, 214, 159, 30, 232, 8,
|
|
||||||
78, 134, 180, 98, 247, 105, 134, 174, 226, 252, 73, 129, 246, 224, 70,
|
|
||||||
200, 50, 214, 149, 158, 239, 40, 76,
|
|
||||||
30, 181, 200, 119, 22, 166, 142, 250, 228, 67, 11, 113, 199, 100, 82,
|
|
||||||
171, 125, 191, 97, 176, 40, 116, 30,
|
|
||||||
167, 72, 122, 182, 163, 54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
|
|
||||||
239, 50, 204, 21, 149, 207, 47, 20,
|
|
||||||
28, 15, 73, 196, 54, 211, 86, 221, 254, 217, 128, 90, 224, 59, 8, 19,
|
|
||||||
70, 141, 242, 229, 133, 139, 35,
|
|
||||||
39, 89, 218, 186, 219, 51, 27, 85, 203, 127, 23, 96, 14, 168, 4, 126,
|
|
||||||
131, 96, 97, 232, 40, 78, 158,
|
|
||||||
180, 104, 119, 110, 166, 172, 122, 253, 227, 1, 137, 192, 102, 208, 42,
|
|
||||||
220, 31, 25, 200, 10, 214, 135, 30,
|
|
||||||
226, 136, 73, 166, 182, 250, 246, 195, 6, 209, 194, 220, 81, 153, 252,
|
|
||||||
106, 193, 239, 16, 76, 12, 53, 197,
|
|
||||||
215, 19, 30, 141, 200, 101, 150, 171, 46, 255, 92, 64, 57, 240, 18,
|
|
||||||
196, 13, 147, 69, 173, 243, 61, 133,
|
|
||||||
209, 163, 28, 121, 201, 226, 214, 201, 158, 214, 232, 94, 206, 184, 84,
|
|
||||||
114, 191, 101, 176, 43, 52, 31, 87,
|
|
||||||
72, 62, 182, 144, 118, 236, 38, 205, 218, 213, 155, 31, 43, 72, 31,
|
|
||||||
118, 136, 38, 230, 154, 202, 235, 23,
|
|
||||||
15, 78, 132, 52, 99, 87, 105, 254, 174, 192, 124, 80, 33, 252, 24, 65,
|
|
||||||
202, 176, 87, 52, 62, 151, 80,
|
|
||||||
110, 188, 44, 113, 221, 228, 89, 139, 122, 231, 99, 10, 169, 199, 62,
|
|
||||||
210, 144, 93, 172, 57, 189, 210, 241,
|
|
||||||
157, 132, 105, 163, 110, 249, 236, 66, 205, 241, 149, 132, 111, 35,
|
|
||||||
108, 25, 237, 202, 205, 151, 21, 174, 143,
|
|
||||||
60, 100, 17, 235, 76, 79, 117, 244, 39, 7, 90, 130, 187, 33, 179, 88,
|
|
||||||
117, 250, 167, 3, 58, 129, 211,
|
|
||||||
32, 93, 216, 57, 154, 146, 235, 45, 143, 93, 164, 57, 187, 82, 243,
|
|
||||||
125, 133, 225, 163, 8, 121, 198, 162,
|
|
||||||
210, 249, 157, 130, 233, 161, 142, 248, 100, 66, 171, 113, 191, 100,
|
|
||||||
112, 43, 100, 31, 107, 72, 47, 118, 156,
|
|
||||||
38, 233, 218, 206, 219, 20, 91, 79, 123, 116, 35, 103, 89, 234, 186,
|
|
||||||
207, 51, 20, 21, 207, 79, 20, 52,
|
|
||||||
15, 87, 68, 62, 179, 80, 117, 252, 39, 1, 218, 128, 91, 32, 59, 88, 19,
|
|
||||||
122, 141, 227, 37, 137, 219,
|
|
||||||
38, 219, 90, 219, 123, 27, 99, 75, 105, 247, 110, 198, 172, 82, 253,
|
|
||||||
253, 129, 129, 160, 96, 120, 40, 34,
|
|
||||||
158, 153, 168, 106, 254, 175, 0, 124, 0, 33, 192, 24, 80, 10, 188, 7,
|
|
||||||
49, 194, 148, 81, 175, 124, 124,
|
|
||||||
33, 225, 216, 72, 90, 182, 187, 54, 243, 86, 197, 254, 211, 0, 93, 192,
|
|
||||||
57, 144, 18, 236, 13, 141, 197,
|
|
||||||
165, 147, 59, 45, 211, 93, 157, 249, 169, 130, 254, 225, 128, 72, 96,
|
|
||||||
54, 168, 22, 254, 142, 192, 100, 80,
|
|
||||||
43, 124, 31, 97, 200, 40, 86, 158, 190, 232, 112, 78, 164, 52, 123, 87,
|
|
||||||
99, 126, 169, 224, 126, 200, 32,
|
|
||||||
86, 152, 62, 234, 144, 79, 44, 52, 29, 215, 73, 158, 182, 232, 118,
|
|
||||||
206, 166, 212, 122, 223, 99, 24, 41,
|
|
||||||
202, 158, 215, 40, 94, 158, 184, 104, 114, 174, 165, 188, 123, 49, 227,
|
|
||||||
84, 73, 255, 118, 192, 38, 208, 26,
|
|
||||||
220, 11, 25, 199, 74, 210, 183, 29, 182, 137, 182, 230, 246, 202, 198,
|
|
||||||
215, 18, 222, 141, 152, 101, 170, 171,
|
|
||||||
63, 63, 80, 16, 60, 12, 17, 197, 204, 83, 21, 253, 207, 1, 148, 0, 111,
|
|
||||||
64, 44, 48, 29, 212, 9,
|
|
||||||
159, 70, 232, 50, 206, 149, 148, 111, 47, 108, 28, 45, 201, 221, 150,
|
|
||||||
217, 174, 218, 252, 91, 1, 251, 64,
|
|
||||||
67, 112, 49, 228, 20, 75, 79, 119, 116, 38, 167, 90, 250, 187, 3, 51,
|
|
||||||
65, 213, 240, 95, 4, 56, 3,
|
|
||||||
82, 129, 253, 160, 65, 184, 48, 114, 148, 37, 175, 91, 60, 59, 81, 211,
|
|
||||||
124, 93, 225, 249, 136, 66, 230,
|
|
||||||
177, 138, 244, 103, 7, 106, 130, 175, 33, 188, 24, 113, 202, 164, 87,
|
|
||||||
59, 126, 147, 96, 109, 232, 45, 142,
|
|
||||||
157, 164, 105, 187, 110, 243, 108, 69, 237, 243, 13, 133, 197, 163, 19,
|
|
||||||
57, 205, 210, 213, 157, 159, 41, 168,
|
|
||||||
30, 254, 136, 64, 102, 176, 42, 244, 31, 7, 72, 2, 182, 129, 182, 224,
|
|
||||||
118, 200, 38, 214, 154, 222, 235,
|
|
||||||
24, 79, 74, 180, 55, 55, 86, 150, 190, 238, 240, 76, 68, 53, 243, 87,
|
|
||||||
5, 254, 131, 0, 97, 192, 40,
|
|
||||||
80, 30, 188, 8, 113, 198, 164, 82, 251, 125, 131, 97, 161, 232, 120,
|
|
||||||
78, 162, 180, 121, 183, 98, 246, 169,
|
|
||||||
134, 254, 226, 192, 73, 144, 54, 236, 22, 205, 206, 213, 148, 95, 47,
|
|
||||||
120, 28, 34, 137, 217, 166, 218, 250,
|
|
||||||
219, 3, 27, 65, 203, 112, 87, 100, 62, 171, 80, 127, 124, 32, 33, 216,
|
|
||||||
24, 90, 138, 187, 39, 51, 90,
|
|
||||||
149, 251, 47, 3, 92, 1, 249, 192, 66, 208, 49, 156, 20, 105, 207, 110,
|
|
||||||
212, 44, 95, 93, 248, 57, 130,
|
|
||||||
146, 225, 173, 136, 125, 166, 161, 186, 248, 115, 2, 165, 193, 187, 16,
|
|
||||||
115, 76, 37, 245, 219, 7, 27, 66,
|
|
||||||
139, 113, 167, 100, 122, 171, 99, 63, 105, 208, 46, 220, 28, 89, 201,
|
|
||||||
250, 214, 195, 30, 209, 200, 92, 86,
|
|
||||||
185, 254, 242, 192, 69, 144, 51, 44, 21, 221, 207, 25, 148, 10, 239,
|
|
||||||
71, 12, 50, 133, 213, 163, 31, 57,
|
|
||||||
200, 18, 214, 141, 158, 229, 168, 75, 62, 183, 80, 118, 188, 38, 241,
|
|
||||||
218, 196, 91, 19, 123, 77, 227, 117,
|
|
||||||
137, 231, 38, 202, 154, 215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
|
|
||||||
110, 193, 236, 80, 77, 252, 53, 129,
|
|
||||||
215, 32, 94, 152, 56, 106, 146, 175, 45, 188, 29, 177, 201, 180, 86,
|
|
||||||
247, 126, 198, 160, 82, 248, 61, 130,
|
|
||||||
145, 161, 172, 120, 125, 226, 161, 137, 184, 102, 242, 170, 197, 191,
|
|
||||||
19, 48, 13, 212, 5, 159, 67, 40, 49,
|
|
||||||
222, 148, 88, 111, 122, 172, 35, 61, 217, 209, 154, 220, 107, 25, 239,
|
|
||||||
74, 204, 55, 21, 214, 143, 30, 228,
|
|
||||||
8, 75, 70, 183, 114, 246, 165, 134, 251, 34, 195, 89, 145, 250, 236,
|
|
||||||
67, 13, 241, 197, 132, 83, 35, 125,
|
|
||||||
217, 225, 154, 200, 107, 22, 175, 78, 252, 52, 65, 215, 112, 94, 164,
|
|
||||||
56, 123, 82, 163, 125, 185, 225, 178,
|
|
||||||
200, 117, 150, 167, 46, 250, 156, 67, 41, 241, 222, 196, 88, 83, 122,
|
|
||||||
189, 227, 49, 137, 212, 102, 223, 106,
|
|
||||||
216, 47, 26, 156, 11, 41, 199, 94, 210, 184, 93, 178, 185, 181, 178,
|
|
||||||
247, 53, 134, 151, 34, 238, 153, 140,
|
|
||||||
106, 229, 239, 11, 12, 7, 69, 194, 179, 17, 181, 204, 119, 21, 230,
|
|
||||||
143, 10, 228, 7, 11, 66, 135, 113,
|
|
||||||
162, 164, 121, 187, 98, 243, 105, 133, 238, 227, 12, 73, 197, 246, 211,
|
|
||||||
6, 221, 194, 217, 145, 154, 236, 107,
|
|
||||||
13, 239, 69, 140, 51, 37, 213, 219, 31, 27, 72, 11, 118, 135, 102, 226,
|
|
||||||
170, 201, 191, 22, 240, 14, 196,
|
|
||||||
4, 83, 67, 125, 241, 225, 132, 72, 99, 118, 169, 230, 254, 202, 192,
|
|
||||||
87, 16, 62, 140, 16, 101, 204, 43,
|
|
||||||
21, 223, 79, 24, 52, 10, 151, 71, 46, 178, 156, 117, 169, 231, 62, 202,
|
|
||||||
144, 87, 44, 62, 157, 208, 105,
|
|
||||||
156, 46, 233, 220, 78, 217, 244, 90, 199, 123, 18, 163, 77, 185, 245,
|
|
||||||
178, 199, 53, 146, 151, 45, 174, 157,
|
|
||||||
188, 105, 177, 238, 244, 76, 71, 117, 242, 167, 5, 186, 131, 51, 33,
|
|
||||||
213, 216, 95, 26, 184, 11, 50, 135,
|
|
||||||
85, 162, 191, 57, 176, 18, 244, 13, 135, 69, 162, 179, 57, 181, 210,
|
|
||||||
247, 29, 134, 137, 162, 230, 249, 138,
|
|
||||||
194, 231, 17, 138, 140, 103, 37, 234, 155, 15, 43, 68, 31, 115, 72, 37,
|
|
||||||
246, 155, 6, 235, 66, 207, 113,
|
|
||||||
148, 36, 111, 91, 108, 59, 109, 211, 109, 157, 237, 169, 141, 190, 229,
|
|
||||||
176, 75, 52, 55, 87, 86, 190, 190,
|
|
||||||
240, 112, 68, 36, 51, 91, 85, 251, 127, 3, 96, 1, 232, 0, 78, 128, 52,
|
|
||||||
96, 23, 104, 14, 174, 132,
|
|
||||||
124, 99, 97, 233, 232, 78, 206, 180, 84, 119, 127, 102, 160, 42, 248,
|
|
||||||
31, 2, 136, 1, 166, 128, 122, 224,
|
|
||||||
35, 8, 25, 198, 138, 210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
|
|
||||||
43, 17, 223, 76, 88, 53, 250, 151,
|
|
||||||
3, 46, 129, 220, 96, 89, 232, 58, 206, 147, 20, 109, 207, 109, 148, 45,
|
|
||||||
175, 93, 188, 57, 177, 210, 244,
|
|
||||||
93, 135, 121, 162, 162, 249, 185, 130, 242, 225, 133, 136, 99, 38, 169,
|
|
||||||
218, 254, 219, 0, 91, 64, 59, 112,
|
|
||||||
19, 100, 13, 235, 69, 143, 115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
|
|
||||||
105, 230, 174, 202, 252, 87, 1,
|
|
||||||
254, 128, 64, 96, 48, 40, 20, 30, 143, 72, 100, 54, 171, 86, 255, 126,
|
|
||||||
192, 32, 80, 24, 60, 10, 145,
|
|
||||||
199, 44, 82, 157, 253, 169, 129, 190, 224, 112, 72, 36, 54, 155, 86,
|
|
||||||
235, 126, 207, 96, 84, 40, 63, 94,
|
|
||||||
144, 56, 108, 18, 173, 205, 189, 149, 177, 175, 52, 124, 23, 97, 206,
|
|
||||||
168, 84, 126, 191, 96, 112, 40, 36,
|
|
||||||
30, 155, 72, 107, 118, 175, 102, 252, 42, 193, 223, 16, 88, 12, 58,
|
|
||||||
133, 211, 35, 29, 217, 201, 154, 214,
|
|
||||||
235, 30, 207, 72, 84, 54, 191, 86, 240, 62, 196, 16, 83, 76, 61, 245,
|
|
||||||
209, 135, 28, 98, 137, 233, 166,
|
|
||||||
206, 250, 212, 67, 31, 113, 200, 36, 86, 155, 126, 235, 96, 79, 104,
|
|
||||||
52, 46, 151, 92, 110, 185, 236, 114,
|
|
||||||
205, 229, 149, 139, 47, 39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
|
|
||||||
40, 112, 30, 164, 8, 123, 70, 163,
|
|
||||||
114, 249, 229, 130, 203, 33, 151, 88, 110, 186, 172, 115, 61, 229, 209,
|
|
||||||
139, 28, 103, 73, 234, 182, 207, 54,
|
|
||||||
212, 22, 223, 78, 216, 52, 90, 151, 123, 46, 163, 92, 121, 249, 226,
|
|
||||||
194, 201, 145, 150, 236, 110, 205, 236,
|
|
||||||
85, 141, 255, 37, 128, 27, 32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
|
|
||||||
114, 218, 165, 155, 59, 43, 83,
|
|
||||||
95, 125, 248, 33, 130, 152, 97, 170, 168, 127, 62, 160, 16, 120, 12,
|
|
||||||
34, 133, 217, 163, 26, 249, 203, 2,
|
|
||||||
215, 65, 158, 176, 104, 116, 46, 167, 92, 122, 185, 227, 50, 201, 213,
|
|
||||||
150, 223, 46, 216, 28, 90, 137, 251,
|
|
||||||
38, 195, 90, 209, 251, 28, 67, 73, 241, 246, 196, 70, 211, 114, 221,
|
|
||||||
229, 153,
|
|
||||||
};
|
|
||||||
|
|
||||||
void scramble(unsigned char *inout)
|
|
||||||
{
|
|
||||||
unsigned char *r = inout + 12;
|
|
||||||
unsigned char *s = yellowbook_scrambler;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 2340; i; i--) {
|
|
||||||
*r++ ^= *s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the P parities for the sector.
|
|
||||||
* The 43 P vectors of length 24 are combined with the GF8_P_COEFFS.
|
|
||||||
*/
|
|
||||||
void parity_p(unsigned char *sector)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
unsigned char p0_msb, p1_msb;
|
|
||||||
unsigned char p0_lsb, p1_lsb;
|
|
||||||
unsigned char *p_msb_start, *p_lsb_start;
|
|
||||||
unsigned char *p_msb, *p_lsb;
|
|
||||||
unsigned char *coeffs0, *coeffs1;
|
|
||||||
unsigned char *p0, *p1;
|
|
||||||
unsigned char d;
|
|
||||||
unsigned short c;
|
|
||||||
|
|
||||||
p_lsb_start = sector + LEC_HEADER_OFFSET;
|
|
||||||
p_msb_start = sector + LEC_HEADER_OFFSET + 1;
|
|
||||||
|
|
||||||
p1 = sector + LEC_MODE1_P_PARITY_OFFSET;
|
|
||||||
p0 = sector + LEC_MODE1_P_PARITY_OFFSET + 2 * 43;
|
|
||||||
|
|
||||||
for (i = 0; i <= 42; i++) {
|
|
||||||
p_lsb = p_lsb_start;
|
|
||||||
p_msb = p_msb_start;
|
|
||||||
|
|
||||||
coeffs0 = gf8_p_coeffs[0];
|
|
||||||
coeffs1 = gf8_p_coeffs[1];
|
|
||||||
|
|
||||||
p0_lsb = p1_lsb = p0_msb = p1_msb = 0;
|
|
||||||
|
|
||||||
for (j = 0; j <= 23; j++) {
|
|
||||||
d = *p_lsb;
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
c = gf8_log[d] + *coeffs0;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
p0_lsb ^= gf8_ilog[c];
|
|
||||||
|
|
||||||
c = gf8_log[d] + *coeffs1;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
p1_lsb ^= gf8_ilog[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
d = *p_msb;
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
c = gf8_log[d] + *coeffs0;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
p0_msb ^= gf8_ilog[c];
|
|
||||||
|
|
||||||
c = gf8_log[d] + *coeffs1;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
p1_msb ^= gf8_ilog[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
coeffs0++;
|
|
||||||
coeffs1++;
|
|
||||||
|
|
||||||
p_lsb += 2 * 43;
|
|
||||||
p_msb += 2 * 43;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p0 = p0_lsb;
|
|
||||||
*(p0 + 1) = p0_msb;
|
|
||||||
|
|
||||||
*p1 = p1_lsb;
|
|
||||||
*(p1 + 1) = p1_msb;
|
|
||||||
|
|
||||||
p0 += 2;
|
|
||||||
p1 += 2;
|
|
||||||
|
|
||||||
p_lsb_start += 2;
|
|
||||||
p_msb_start += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the Q parities for the sector.
|
|
||||||
* The 26 Q vectors of length 43 are combined with the GF8_Q_COEFFS.
|
|
||||||
*/
|
|
||||||
void parity_q(unsigned char *sector)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
unsigned char q0_msb, q1_msb;
|
|
||||||
unsigned char q0_lsb, q1_lsb;
|
|
||||||
unsigned char *q_msb_start, *q_lsb_start;
|
|
||||||
unsigned char *q_msb, *q_lsb;
|
|
||||||
unsigned char *coeffs0, *coeffs1;
|
|
||||||
unsigned char *q0, *q1, *q_start;
|
|
||||||
unsigned char d;
|
|
||||||
unsigned short c;
|
|
||||||
|
|
||||||
q_lsb_start = sector + LEC_HEADER_OFFSET;
|
|
||||||
q_msb_start = sector + LEC_HEADER_OFFSET + 1;
|
|
||||||
|
|
||||||
q_start = sector + LEC_MODE1_Q_PARITY_OFFSET;
|
|
||||||
q1 = sector + LEC_MODE1_Q_PARITY_OFFSET;
|
|
||||||
q0 = sector + LEC_MODE1_Q_PARITY_OFFSET + 2 * 26;
|
|
||||||
|
|
||||||
for (i = 0; i <= 25; i++) {
|
|
||||||
q_lsb = q_lsb_start;
|
|
||||||
q_msb = q_msb_start;
|
|
||||||
|
|
||||||
coeffs0 = gf8_q_coeffs[0];
|
|
||||||
coeffs1 = gf8_q_coeffs[1];
|
|
||||||
|
|
||||||
q0_lsb = q1_lsb = q0_msb = q1_msb = 0;
|
|
||||||
|
|
||||||
for (j = 0; j <= 42; j++) {
|
|
||||||
d = *q_lsb;
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
c = gf8_log[d] + *coeffs0;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
q0_lsb ^= gf8_ilog[c];
|
|
||||||
|
|
||||||
c = gf8_log[d] + *coeffs1;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
q1_lsb ^= gf8_ilog[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
d = *q_msb;
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
c = gf8_log[d] + *coeffs0;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
q0_msb ^= gf8_ilog[c];
|
|
||||||
|
|
||||||
c = gf8_log[d] + *coeffs1;
|
|
||||||
if (c >= 255)
|
|
||||||
c -= 255;
|
|
||||||
q1_msb ^= gf8_ilog[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
coeffs0++;
|
|
||||||
coeffs1++;
|
|
||||||
|
|
||||||
q_lsb += 2 * 44;
|
|
||||||
q_msb += 2 * 44;
|
|
||||||
|
|
||||||
if (q_lsb >= q_start) {
|
|
||||||
q_msb -= 2 * 1118;
|
|
||||||
q_lsb -= 2 * 1118;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*q0 = q0_lsb;
|
|
||||||
*(q0 + 1) = q0_msb;
|
|
||||||
|
|
||||||
*q1 = q1_lsb;
|
|
||||||
*(q1 + 1) = q1_msb;
|
|
||||||
|
|
||||||
q0 += 2;
|
|
||||||
q1 += 2;
|
|
||||||
|
|
||||||
q_lsb_start += 2 * 43;
|
|
||||||
q_msb_start += 2 * 43;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
||||||
|
|
||||||
#ifndef __LEC
|
|
||||||
#define __LEC
|
|
||||||
|
|
||||||
#define RS_L12_BITS 8
|
|
||||||
|
|
||||||
void scramble(unsigned char *);
|
|
||||||
void parity_p(unsigned char *in);
|
|
||||||
void parity_q(unsigned char *in);
|
|
||||||
|
|
||||||
#endif /* __LEC */
|
|
2358
libburn/libburn.h
2358
libburn/libburn.h
File diff suppressed because it is too large
Load Diff
225
libburn/libburn.ver
Normal file
225
libburn/libburn.ver
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
LIBBURN4 {
|
||||||
|
global:
|
||||||
|
burn_abort;
|
||||||
|
burn_abort_pacifier;
|
||||||
|
burn_allow_drive_role_4;
|
||||||
|
burn_allow_untested_profiles;
|
||||||
|
burn_cdtext_from_session;
|
||||||
|
burn_cdtext_from_packfile;
|
||||||
|
burn_disc_add_session;
|
||||||
|
burn_disc_available_space;
|
||||||
|
burn_disc_close_damaged;
|
||||||
|
burn_disc_create;
|
||||||
|
burn_disc_erasable;
|
||||||
|
burn_disc_erase;
|
||||||
|
burn_disc_format;
|
||||||
|
burn_disc_free;
|
||||||
|
burn_disc_free_multi_caps;
|
||||||
|
burn_disc_get_bd_spare_info;
|
||||||
|
burn_disc_get_cd_info;
|
||||||
|
burn_disc_get_format_descr;
|
||||||
|
burn_disc_get_formats;
|
||||||
|
burn_disc_get_incomplete_sessions;
|
||||||
|
burn_disc_get_leadin_text;
|
||||||
|
burn_disc_get_media_id;
|
||||||
|
burn_disc_get_msc1;
|
||||||
|
burn_disc_get_multi_caps;
|
||||||
|
burn_disc_get_phys_format_info;
|
||||||
|
burn_disc_get_profile;
|
||||||
|
burn_disc_get_sectors;
|
||||||
|
burn_disc_get_sessions;
|
||||||
|
burn_disc_get_status;
|
||||||
|
burn_disc_next_track_is_damaged;
|
||||||
|
burn_disc_pretend_blank;
|
||||||
|
burn_disc_pretend_full;
|
||||||
|
burn_disc_pretend_full_uncond;
|
||||||
|
burn_disc_read;
|
||||||
|
burn_disc_read_atip;
|
||||||
|
burn_disc_remove_session;
|
||||||
|
burn_disc_track_lba_nwa;
|
||||||
|
burn_disc_write;
|
||||||
|
burn_drive_add_whitelist;
|
||||||
|
burn_drive_cancel;
|
||||||
|
burn_drive_clear_whitelist;
|
||||||
|
burn_drive_convert_fs_adr;
|
||||||
|
burn_drive_convert_scsi_adr;
|
||||||
|
burn_drive_d_get_adr;
|
||||||
|
burn_drive_equals_adr;
|
||||||
|
burn_drive_extract_audio;
|
||||||
|
burn_drive_extract_audio_track;
|
||||||
|
burn_drive_free_speedlist;
|
||||||
|
burn_drive_get_adr;
|
||||||
|
burn_drive_get_all_profiles;
|
||||||
|
burn_drive_get_bd_r_pow;
|
||||||
|
burn_drive_get_best_speed;
|
||||||
|
burn_drive_get_disc;
|
||||||
|
burn_drive_get_drive_role;
|
||||||
|
burn_drive_get_feature;
|
||||||
|
burn_drive_get_feature_codes;
|
||||||
|
burn_drive_get_immed;
|
||||||
|
burn_drive_get_media_sno;
|
||||||
|
burn_drive_get_min_write_speed;
|
||||||
|
burn_drive_get_read_speed;
|
||||||
|
burn_drive_get_serial_no;
|
||||||
|
burn_drive_get_speedlist;
|
||||||
|
burn_drive_get_start_end_lba;
|
||||||
|
burn_drive_get_status;
|
||||||
|
burn_drive_get_write_speed;
|
||||||
|
burn_drive_grab;
|
||||||
|
burn_drive_info_forget;
|
||||||
|
burn_drive_info_free;
|
||||||
|
burn_drive_is_enumerable_adr;
|
||||||
|
burn_drive_leave_locked;
|
||||||
|
burn_drive_obtain_scsi_adr;
|
||||||
|
burn_drive_probe_cd_write_modes;
|
||||||
|
burn_drive_re_assess;
|
||||||
|
burn_drive_release;
|
||||||
|
burn_drive_reset_simulate;
|
||||||
|
burn_drive_scan;
|
||||||
|
burn_drive_scan_and_grab;
|
||||||
|
burn_drive_set_buffer_waiting;
|
||||||
|
burn_drive_set_immed;
|
||||||
|
burn_drive_set_speed;
|
||||||
|
burn_drive_set_speed_exact;
|
||||||
|
burn_drive_set_stream_recording;
|
||||||
|
burn_drive_snooze;
|
||||||
|
burn_drive_was_feat21_failure;
|
||||||
|
burn_drive_wrote_well;
|
||||||
|
burn_fd_source_new;
|
||||||
|
burn_fifo_fill;
|
||||||
|
burn_fifo_get_statistics;
|
||||||
|
burn_fifo_inquire_status;
|
||||||
|
burn_fifo_next_interval;
|
||||||
|
burn_fifo_peek_data;
|
||||||
|
burn_fifo_source_new;
|
||||||
|
burn_file_source_new;
|
||||||
|
burn_finish;
|
||||||
|
burn_get_read_capacity;
|
||||||
|
burn_guess_cd_manufacturer;
|
||||||
|
burn_guess_manufacturer;
|
||||||
|
burn_initialize;
|
||||||
|
burn_is_aborting;
|
||||||
|
burn_lba_to_msf;
|
||||||
|
burn_list_sev_texts;
|
||||||
|
burn_lookup_device_link;
|
||||||
|
burn_make_input_sheet_v07t;
|
||||||
|
burn_msf_to_lba;
|
||||||
|
burn_msf_to_sectors;
|
||||||
|
burn_msgs_obtain;
|
||||||
|
burn_msgs_set_severities;
|
||||||
|
burn_msgs_submit;
|
||||||
|
burn_nominal_slowdown;
|
||||||
|
burn_obtain_profile_name;
|
||||||
|
burn_offst_source_new;
|
||||||
|
burn_os_alloc_buffer;
|
||||||
|
burn_os_free_buffer;
|
||||||
|
burn_os_open_track_src;
|
||||||
|
burn_precheck_write;
|
||||||
|
burn_preset_device_open;
|
||||||
|
burn_random_access_write;
|
||||||
|
burn_read_audio;
|
||||||
|
burn_read_data;
|
||||||
|
burn_read_opts_free;
|
||||||
|
burn_read_opts_new;
|
||||||
|
burn_read_opts_read_subcodes_audio;
|
||||||
|
burn_read_opts_read_subcodes_data;
|
||||||
|
burn_read_opts_report_recovered_errors;
|
||||||
|
burn_read_opts_set_c2errors;
|
||||||
|
burn_read_opts_set_hardware_error_recovery;
|
||||||
|
burn_read_opts_set_hardware_error_retries;
|
||||||
|
burn_read_opts_set_raw;
|
||||||
|
burn_read_opts_transfer_damaged_blocks;
|
||||||
|
burn_scsi_transport_id;
|
||||||
|
burn_sectors_to_msf;
|
||||||
|
burn_session_add_track;
|
||||||
|
burn_session_by_cue_file;
|
||||||
|
burn_session_create;
|
||||||
|
burn_session_dispose_cdtext;
|
||||||
|
burn_session_free;
|
||||||
|
burn_session_get_cdtext;
|
||||||
|
burn_session_get_cdtext_par;
|
||||||
|
burn_session_get_hidefirst;
|
||||||
|
burn_session_get_leadout_entry;
|
||||||
|
burn_session_get_sectors;
|
||||||
|
burn_session_get_start_tno;
|
||||||
|
burn_session_get_tracks;
|
||||||
|
burn_session_hide_first_track;
|
||||||
|
burn_session_input_sheet_v07t;
|
||||||
|
burn_session_remove_track;
|
||||||
|
burn_session_set_cdtext;
|
||||||
|
burn_session_set_cdtext_par;
|
||||||
|
burn_session_set_start_tno;
|
||||||
|
burn_set_messenger;
|
||||||
|
burn_set_scsi_logging;
|
||||||
|
burn_set_signal_handling;
|
||||||
|
burn_set_verbosity;
|
||||||
|
burn_sev_to_text;
|
||||||
|
burn_source_free;
|
||||||
|
burn_structure_print_disc;
|
||||||
|
burn_structure_print_session;
|
||||||
|
burn_structure_print_track;
|
||||||
|
burn_text_to_sev;
|
||||||
|
burn_track_clear_indice;
|
||||||
|
burn_track_clear_isrc;
|
||||||
|
burn_track_create;
|
||||||
|
burn_track_define_data;
|
||||||
|
burn_track_dispose_cdtext;
|
||||||
|
burn_track_free;
|
||||||
|
burn_track_get_cdtext;
|
||||||
|
burn_track_get_counters;
|
||||||
|
burn_track_get_entry;
|
||||||
|
burn_track_get_mode;
|
||||||
|
burn_track_get_sectors;
|
||||||
|
burn_track_set_byte_swap;
|
||||||
|
burn_track_set_cdxa_conv;
|
||||||
|
burn_track_set_cdtext;
|
||||||
|
burn_track_set_default_size;
|
||||||
|
burn_track_set_index;
|
||||||
|
burn_track_set_isrc;
|
||||||
|
burn_track_set_isrc_string;
|
||||||
|
burn_track_set_postgap_size;
|
||||||
|
burn_track_set_pregap_size;
|
||||||
|
burn_track_set_size;
|
||||||
|
burn_track_set_source;
|
||||||
|
burn_version;
|
||||||
|
burn_write_opts_auto_write_type;
|
||||||
|
burn_write_opts_free;
|
||||||
|
burn_write_opts_get_drive;
|
||||||
|
burn_write_opts_new;
|
||||||
|
burn_write_opts_set_bdr_obs_exempt;
|
||||||
|
burn_write_opts_set_dvd_obs;
|
||||||
|
burn_write_opts_set_fail21h_sev;
|
||||||
|
burn_write_opts_set_fillup;
|
||||||
|
burn_write_opts_set_force;
|
||||||
|
burn_write_opts_set_format;
|
||||||
|
burn_write_opts_set_has_mediacatalog;
|
||||||
|
burn_write_opts_set_leadin_text;
|
||||||
|
burn_write_opts_set_mediacatalog;
|
||||||
|
burn_write_opts_set_multi;
|
||||||
|
burn_write_opts_set_obs_pad;
|
||||||
|
burn_write_opts_set_perform_opc;
|
||||||
|
burn_write_opts_set_simulate;
|
||||||
|
burn_write_opts_set_start_byte;
|
||||||
|
burn_write_opts_set_stdio_fsync;
|
||||||
|
burn_write_opts_set_stream_recording;
|
||||||
|
burn_write_opts_set_toc_entries;
|
||||||
|
burn_write_opts_set_underrun_proof;
|
||||||
|
burn_write_opts_set_write_type;
|
||||||
|
libdax_audioxtr_destroy;
|
||||||
|
libdax_audioxtr_detach_fd;
|
||||||
|
libdax_audioxtr_get_id;
|
||||||
|
libdax_audioxtr_get_size;
|
||||||
|
libdax_audioxtr_new;
|
||||||
|
libdax_audioxtr_read;
|
||||||
|
local: *;
|
||||||
|
};
|
||||||
|
|
||||||
|
LIBBURN4_1.5.8 {
|
||||||
|
burn_disc_get_sectors_v2;
|
||||||
|
burn_disc_track_lba_nwa_v2;
|
||||||
|
burn_drive_get_status_v2;
|
||||||
|
burn_get_read_capacity_v2;
|
||||||
|
burn_session_get_sectors_v2;
|
||||||
|
burn_track_get_sectors_v2;
|
||||||
|
} LIBBURN4;
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -13,6 +17,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -21,7 +29,8 @@ extern struct libdax_msgs *libdax_messenger;
|
||||||
/* Only this single source module is entitled to do this */
|
/* Only this single source module is entitled to do this */
|
||||||
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
||||||
|
|
||||||
/* All clients of the extraction facility must do this */
|
/* All clients of the extraction facility must do this or include libburn.h */
|
||||||
|
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
|
||||||
#include "libdax_audioxtr.h"
|
#include "libdax_audioxtr.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +39,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||||
int ret= -1;
|
int ret= -1;
|
||||||
struct libdax_audioxtr *o;
|
struct libdax_audioxtr *o;
|
||||||
|
|
||||||
o= *xtr= (struct libdax_audioxtr *) malloc(sizeof(struct libdax_audioxtr));
|
o= *xtr= (struct libdax_audioxtr *) calloc(1, sizeof(struct libdax_audioxtr));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
||||||
|
@ -46,6 +55,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||||
o->bits_per_sample= 0;
|
o->bits_per_sample= 0;
|
||||||
o->msb_first= 0;
|
o->msb_first= 0;
|
||||||
|
|
||||||
|
o->wav_data_location= 44;
|
||||||
o->wav_subchunk2_size= 0;
|
o->wav_subchunk2_size= 0;
|
||||||
|
|
||||||
o->au_data_location= 0;
|
o->au_data_location= 0;
|
||||||
|
@ -85,7 +95,7 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||||
if(strcmp(o->path,"-")==0)
|
if(strcmp(o->path,"-")==0)
|
||||||
o->fd= 0;
|
o->fd= 0;
|
||||||
else
|
else
|
||||||
o->fd= open(o->path, O_RDONLY);
|
o->fd= open(o->path, O_RDONLY | O_BINARY);
|
||||||
if(o->fd<0) {
|
if(o->fd<0) {
|
||||||
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
||||||
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
||||||
|
@ -112,47 +122,123 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @param flag: bit0= sequential file, skip by reading data
|
||||||
|
*/
|
||||||
|
static int libdax_audioxtr_skip(struct libdax_audioxtr *o,
|
||||||
|
off_t *old_pos,
|
||||||
|
off_t pos, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t to_read;
|
||||||
|
static char buf[256]; /* Thread safe because the content does not matter */
|
||||||
|
|
||||||
|
if((flag & 1) || o->fd == 0) { /* stdin */
|
||||||
|
while(pos - *old_pos > 0) {
|
||||||
|
to_read= pos - *old_pos;
|
||||||
|
if(to_read > sizeof(buf))
|
||||||
|
to_read= sizeof(buf);
|
||||||
|
ret= read(o->fd, buf, to_read);
|
||||||
|
if(ret < (int) to_read)
|
||||||
|
return(0);
|
||||||
|
*old_pos+= to_read;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret= lseek(o->fd, pos, SEEK_SET);
|
||||||
|
if(ret == -1)
|
||||||
|
return(0);
|
||||||
|
*old_pos= pos;
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, fmt_seen= 0, data_seen= 0;
|
||||||
char buf[45];
|
off_t pos= 0, old_pos= 0, riff_end= 0;
|
||||||
|
char buf[16];
|
||||||
|
unsigned char *ubuf;
|
||||||
|
|
||||||
/* check wether this is a MS WAVE file .wav */
|
/* check whether this is a MS WAVE file .wav */
|
||||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
||||||
|
https://en.wikipedia.org/wiki/WAV
|
||||||
|
see summary in: doc/waveformat.txt
|
||||||
|
*/
|
||||||
|
ubuf= (unsigned char *) buf;
|
||||||
|
|
||||||
if(o->fd!=0) {
|
/* Look for ChunkID "RIFF" , tolerate other known chunks */
|
||||||
ret= lseek(o->fd,0,SEEK_SET);
|
while(1) {
|
||||||
if(ret==-1)
|
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
|
||||||
|
if(ret <= 0)
|
||||||
return(0);
|
return(0);
|
||||||
|
ret= read(o->fd, buf, 8);
|
||||||
|
if(ret < 8)
|
||||||
|
return(0);
|
||||||
|
old_pos+= 8;
|
||||||
|
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
|
||||||
|
if(pos > 0xffffffff || pos - old_pos < 4) /* Too large or no Format word */
|
||||||
|
return(0);
|
||||||
|
if(strncmp(buf, "RIFF", 4) == 0)
|
||||||
|
break;
|
||||||
|
/* Wikipedia mentions these known ChunkId values */
|
||||||
|
if(strncmp(buf, "INFO", 4) == 0 ||
|
||||||
|
strncmp(buf, "CSET", 4) == 0 ||
|
||||||
|
strncmp(buf, "JUNK", 4) == 0 ||
|
||||||
|
strncmp(buf, "PAD ", 4) == 0)
|
||||||
|
continue;
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
ret= read(o->fd, buf, 44);
|
|
||||||
if(ret<44)
|
|
||||||
return(0);
|
|
||||||
buf[44]= 0; /* as stopper for any string operations */
|
|
||||||
|
|
||||||
if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */
|
/* Read RIFF Format header */
|
||||||
|
ret= read(o->fd, buf, 4);
|
||||||
|
if(ret < 4)
|
||||||
return(0);
|
return(0);
|
||||||
if(strncmp(buf+8,"WAVE",4)!=0) /* Format */
|
old_pos+= 4;
|
||||||
return(0);
|
if(strncmp(buf, "WAVE", 4) != 0) /* Format */
|
||||||
if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */
|
|
||||||
return(0);
|
|
||||||
if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */
|
|
||||||
return(0);
|
|
||||||
if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */
|
|
||||||
return(0);
|
return(0);
|
||||||
|
riff_end= pos;
|
||||||
|
|
||||||
strcpy(o->fmt,".wav");
|
/* Look for SubchunkID "fmt " and "data" */
|
||||||
o->msb_first= 0;
|
pos= old_pos;
|
||||||
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0);
|
while(old_pos < riff_end) {
|
||||||
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0);
|
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
|
||||||
o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0);
|
if(ret <= 0)
|
||||||
sprintf(o->fmt_info,
|
return(0);
|
||||||
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
ret= read(o->fd, buf, 8);
|
||||||
o->num_channels,o->sample_rate,o->bits_per_sample);
|
if(ret < 8)
|
||||||
o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0);
|
return(0);
|
||||||
o->data_size= o->wav_subchunk2_size;
|
old_pos= pos + 8;
|
||||||
return(1);
|
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0); /* SubchunkSize */
|
||||||
|
|
||||||
|
if(strncmp(buf,"fmt ", 4) == 0) {
|
||||||
|
if(pos - old_pos < 16)
|
||||||
|
return(0);
|
||||||
|
ret= read(o->fd, buf, 16);
|
||||||
|
if(ret < 16)
|
||||||
|
return(0);
|
||||||
|
old_pos+= 16;
|
||||||
|
if(buf[0]!=1 || buf[1]!=0) /* AudioFormat (1 = Linear quantization) */
|
||||||
|
return(0);
|
||||||
|
o->msb_first= 0;
|
||||||
|
o->num_channels= libdax_audioxtr_to_int(o, ubuf + 2 , 2, 0);
|
||||||
|
o->sample_rate= libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
|
||||||
|
o->bits_per_sample= libdax_audioxtr_to_int(o, ubuf + 14, 2, 0);
|
||||||
|
sprintf(o->fmt_info,
|
||||||
|
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||||
|
o->num_channels, o->sample_rate, o->bits_per_sample);
|
||||||
|
fmt_seen= 1;
|
||||||
|
|
||||||
|
} else if(strncmp(buf,"data", 4) == 0) {
|
||||||
|
o->wav_data_location= old_pos;
|
||||||
|
o->wav_subchunk2_size= pos - old_pos;
|
||||||
|
o->data_size= o->wav_subchunk2_size;
|
||||||
|
data_seen= 1;
|
||||||
|
}
|
||||||
|
if(fmt_seen && data_seen) {
|
||||||
|
strcpy(o->fmt,".wav");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,7 +247,7 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
||||||
int ret,encoding;
|
int ret,encoding;
|
||||||
char buf[24];
|
char buf[24];
|
||||||
|
|
||||||
/* Check wether this is a Sun Audio, .au file */
|
/* Check whether this is a Sun Audio, .au file */
|
||||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
if(o->fd!=0) {
|
if(o->fd!=0) {
|
||||||
|
@ -199,10 +285,6 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
||||||
sprintf(o->fmt_info,
|
sprintf(o->fmt_info,
|
||||||
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||||
o->num_channels,o->sample_rate,o->bits_per_sample);
|
o->num_channels,o->sample_rate,o->bits_per_sample);
|
||||||
|
|
||||||
/* <<< for testing only */;
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
return(o->bits_per_sample>0); /* Audio format must be linear PCM */
|
return(o->bits_per_sample>0); /* Audio format must be linear PCM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +333,7 @@ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
|
||||||
|
|
||||||
o->extract_count= 0;
|
o->extract_count= 0;
|
||||||
if(strcmp(o->fmt,".wav")==0)
|
if(strcmp(o->fmt,".wav")==0)
|
||||||
ret= lseek(o->fd,44,SEEK_SET);
|
ret= lseek(o->fd, o->wav_data_location, SEEK_SET);
|
||||||
else if(strcmp(o->fmt,".au")==0)
|
else if(strcmp(o->fmt,".au")==0)
|
||||||
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
|
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
||||||
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Normally this public API is defined in <libburn/libburn.h>
|
||||||
|
Macro LIBDAX_AUDIOXTR_H_PUBLIC enables the definition for programs
|
||||||
|
which only include this file.
|
||||||
|
*/
|
||||||
|
#ifdef LIBDAX_AUDIOXTR_H_PUBLIC
|
||||||
|
|
||||||
/* Public Macros */
|
/* Public Macros */
|
||||||
|
|
||||||
/* Maximum size for address paths and fmt_info strings */
|
/* Maximum size for address paths and fmt_info strings */
|
||||||
|
@ -31,7 +38,7 @@ struct libdax_audioxtr;
|
||||||
/* Calls from applications (to be forwarded by libdax/libburn) */
|
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||||
|
|
||||||
|
|
||||||
/** Open an audio file, check wether suitable, create extractor object.
|
/** Open an audio file, check whether suitable, create extractor object.
|
||||||
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||||
@param path Address of the audio file to extract. "-" is stdin (but might
|
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||||
be not suitable for all futurely supported formats).
|
be not suitable for all futurely supported formats).
|
||||||
|
@ -110,15 +117,16 @@ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
|
||||||
*/
|
*/
|
||||||
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
||||||
|
|
||||||
|
#endif /* LIBDAX_AUDIOXTR_H_PUBLIC */
|
||||||
|
|
||||||
|
|
||||||
#ifdef LIDBAX_AUDIOXTR________________
|
#ifdef LIBDAX_AUDIOXTR________________
|
||||||
|
|
||||||
|
|
||||||
-- place documentation text here ---
|
-- place documentation text here ---
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIDBAX_AUDIOXTR_________________ */
|
#endif /* LIBDAX_AUDIOXTR_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,7 +176,10 @@ struct libdax_audioxtr {
|
||||||
/* Format dependent parameters */
|
/* Format dependent parameters */
|
||||||
|
|
||||||
/* MS WAVE Format */
|
/* MS WAVE Format */
|
||||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
/* see description in: doc/waveformat.txt */
|
||||||
|
|
||||||
|
/* Offset to "data" subchunk */
|
||||||
|
unsigned int wav_data_location;
|
||||||
|
|
||||||
/* == NumSamples * NumChannels * BitsPerSample/8
|
/* == NumSamples * NumChannels * BitsPerSample/8
|
||||||
This is the number of bytes in the data. */
|
This is the number of bytes in the data. */
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -12,6 +16,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
/* Only this single source module is entitled to do this */
|
/* Only this single source module is entitled to do this */
|
||||||
#define LIBDAX_MSGS_H_INTERNAL 1
|
#define LIBDAX_MSGS_H_INTERNAL 1
|
||||||
|
@ -29,14 +34,13 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
||||||
int ret;
|
int ret;
|
||||||
struct libdax_msgs_item *o;
|
struct libdax_msgs_item *o;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
|
||||||
|
|
||||||
(*item)= o=
|
(*item)= o=
|
||||||
(struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item));
|
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->timestamp= 0.0;
|
o->timestamp= 0.0;
|
||||||
ret= gettimeofday(&tv,&tz);
|
ret= gettimeofday(&tv, NULL);
|
||||||
if(ret==0)
|
if(ret==0)
|
||||||
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
||||||
o->process_id= getpid();
|
o->process_id= getpid();
|
||||||
|
@ -135,7 +139,7 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag)
|
||||||
{
|
{
|
||||||
struct libdax_msgs *o;
|
struct libdax_msgs *o;
|
||||||
|
|
||||||
(*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs));
|
(*m)= o= (struct libdax_msgs *) calloc(1, sizeof(struct libdax_msgs));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->refcount= 1;
|
o->refcount= 1;
|
||||||
|
@ -284,7 +288,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
if(flag&1) {
|
if(flag&1) {
|
||||||
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
|
*severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
*severity_name= "";
|
*severity_name= "";
|
||||||
|
@ -322,6 +326,11 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= If direct output to stderr:
|
||||||
|
CarriageReturn rather than LineFeed
|
||||||
|
*/
|
||||||
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
int severity, int priority, char *msg_text,
|
int severity, int priority, char *msg_text,
|
||||||
int os_errno, int flag)
|
int os_errno, int flag)
|
||||||
|
@ -340,7 +349,8 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
if(ret>0)
|
if(ret>0)
|
||||||
sprintf(sev_text,"%s : ",sev_name);
|
sprintf(sev_text,"%s : ",sev_name);
|
||||||
|
|
||||||
fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt);
|
fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt,
|
||||||
|
(flag & 1) ? '\r' : '\n');
|
||||||
if(os_errno!=0) {
|
if(os_errno!=0) {
|
||||||
ret= libdax_msgs_lock(m,0);
|
ret= libdax_msgs_lock(m,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
|
@ -365,7 +375,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
item->severity= severity;
|
item->severity= severity;
|
||||||
item->priority= priority;
|
item->priority= priority;
|
||||||
if(msg_text!=NULL) {
|
if(msg_text!=NULL) {
|
||||||
item->msg_text= malloc(strlen(msg_text)+1);
|
item->msg_text= calloc(1, strlen(msg_text)+1);
|
||||||
if(item->msg_text==NULL)
|
if(item->msg_text==NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
strcpy(item->msg_text,msg_text);
|
strcpy(item->msg_text,msg_text);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libburn and libisofs.
|
||||||
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2021 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,8 +266,9 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag);
|
||||||
|
|
||||||
/** Destroy a message handling facility and all its eventual messages.
|
/** Destroy a message handling facility and all its eventual messages.
|
||||||
The submitted pointer gets set to NULL.
|
The submitted pointer gets set to NULL.
|
||||||
Actually only the last destroy call of all offical references to the object
|
Actually only the last destroy call of all official references to the
|
||||||
will really dispose it. All others just decrement the reference counter.
|
object will really dispose it. All others just decrement the reference
|
||||||
|
counter.
|
||||||
Call this function only with official reference pointers obtained by
|
Call this function only with official reference pointers obtained by
|
||||||
libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer.
|
libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer.
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@ -302,7 +303,9 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
|
||||||
@param priority The LIBDAX_MSGS_PRIO_* number of the event.
|
@param priority The LIBDAX_MSGS_PRIO_* number of the event.
|
||||||
@param msg_text Printable and human readable message text.
|
@param msg_text Printable and human readable message text.
|
||||||
@param os_errno Eventual error code from operating system (0 if none)
|
@param os_errno Eventual error code from operating system (0 if none)
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= If direct output to stderr:
|
||||||
|
CarriageReturn rather than LineFeed
|
||||||
@return 1 on success, 0 on rejection, <0 for severe errors
|
@return 1 on success, 0 on rejection, <0 for severe errors
|
||||||
*/
|
*/
|
||||||
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
|
@ -316,7 +319,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
|
|
||||||
/** Convert a registered severity number into a severity name
|
/** Convert a registered severity number into a severity name
|
||||||
@param flag Bitfield for control purposes:
|
@param flag Bitfield for control purposes:
|
||||||
bit0= list all severity names in a newline separated string
|
bit0= list all severity names in a blank separated string
|
||||||
@return >0 success, <=0 failure
|
@return >0 success, <=0 failure
|
||||||
*/
|
*/
|
||||||
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
|
@ -395,7 +398,7 @@ int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
|
||||||
int *severity, int *priority, int flag);
|
int *severity, int *priority, int flag);
|
||||||
|
|
||||||
|
|
||||||
#ifdef LIDBAX_MSGS_________________
|
#ifdef LIBDAX_MSGS_________________
|
||||||
|
|
||||||
|
|
||||||
/* Registered Error Codes */
|
/* Registered Error Codes */
|
||||||
|
@ -411,6 +414,7 @@ Range "libdax_msgs" : 0x00000000 to 0x0000ffff
|
||||||
0x00000001 (DEBUG,ZERO) = Test error message
|
0x00000001 (DEBUG,ZERO) = Test error message
|
||||||
0x00000002 (DEBUG,ZERO) = Debugging message
|
0x00000002 (DEBUG,ZERO) = Debugging message
|
||||||
0x00000003 (FATAL,HIGH) = Out of virtual memory
|
0x00000003 (FATAL,HIGH) = Out of virtual memory
|
||||||
|
0x00000004 (FATAL,HIGH) = Generic fatal error
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -421,7 +425,7 @@ Range "elmom" : 0x00010000 to 0x0001ffff
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
|
|
||||||
Acessing and defending drives:
|
Accessing and defending drives:
|
||||||
|
|
||||||
0x00020001 (SORRY,LOW) = Cannot open busy device
|
0x00020001 (SORRY,LOW) = Cannot open busy device
|
||||||
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
||||||
|
@ -434,6 +438,9 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
||||||
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
|
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
|
||||||
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
||||||
|
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
|
||||||
|
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
|
||||||
|
0x0002000e (NOTE,HIGH) = Failed to open device during
|
||||||
|
|
||||||
General library operations:
|
General library operations:
|
||||||
|
|
||||||
|
@ -471,7 +478,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
|
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
|
||||||
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
||||||
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
||||||
0x00020122 (FATAL,HIGH) = SCSI error on format_unit
|
0x00020122 (FAILURE,HIGH) = SCSI error on format_unit
|
||||||
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
|
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
|
||||||
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
|
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
|
||||||
0x00020125 (SORRY,HIGH) = Write start address not supported
|
0x00020125 (SORRY,HIGH) = Write start address not supported
|
||||||
|
@ -514,10 +521,10 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
||||||
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
||||||
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
|
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
|
||||||
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
|
0x0002014d (SORRY,HIGH) = Asynchronous SCSI error
|
||||||
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
|
0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command
|
||||||
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
|
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
|
||||||
0x00020151 (FATAL,HIGH) = Read attempt on write-only drive
|
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
|
||||||
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
|
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
|
||||||
0x00020153 (SORRY,HIGH) = Read error on fifo input
|
0x00020153 (SORRY,HIGH) = Read error on fifo input
|
||||||
0x00020154 (NOTE,HIGH) = Forwarded input error ends output
|
0x00020154 (NOTE,HIGH) = Forwarded input error ends output
|
||||||
|
@ -528,7 +535,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
||||||
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
||||||
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
||||||
0x0002015c (FAILURE,HIGH) = Fifo size is smaller than desired peek buffer
|
0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer
|
||||||
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
||||||
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
||||||
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
||||||
|
@ -548,8 +555,69 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
||||||
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
||||||
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
||||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
0x00020171 (NOTE,HIGH) = Closing BD-R with accidentally open session
|
||||||
|
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
||||||
|
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
||||||
|
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
||||||
|
0x00020175 (FATAL,HIGH) = Supporting library is too old
|
||||||
|
0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer
|
||||||
|
0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt
|
||||||
|
0x00020178 (DEBUG,HIGH) = Write thread ended
|
||||||
|
0x00020179 (FAILURE,HIGH) = Offset source start address is before end of previous source
|
||||||
|
0x0002017a (FAILURE,HIGH) = Expected offset source object as parameter
|
||||||
|
0x0002017b (WARNING,HIGH) = Sequential BD-R media likely to soon fail writing
|
||||||
|
0x0002017c (FAILURE,HIGH) = No valid write type selected
|
||||||
|
0x0002017d (FATAL,HIGH) = Invalid file descriptor with stdio pseudo-drive
|
||||||
|
0x0002017e (FAILURE,HIGH) = Failed to close track, session, or disc
|
||||||
|
0x0002017f (FAILURE,HIGH) = Failed to synchronize drive cache
|
||||||
|
0x00020180 (FAILURE,HIGH) = Premature end of input encountered
|
||||||
|
0x00020181 (FAILURE,HIGH) = Pseudo-drive is a read-only file. Cannot write.
|
||||||
|
0x00020182 (FAILURE,HIGH) = Cannot truncate disk file for pseudo blanking
|
||||||
|
0x00020183 (WARNING,HIGH) = Failed to open device (a pseudo-drive) for reading
|
||||||
|
0x00020184 (WARNING,HIGH) = No Next-Writable-Address
|
||||||
|
0x00020185 (WARNING,HIGH) = Track damaged, not closed and not writable
|
||||||
|
0x00020186 (WARNING,HIGH) = Track damaged and not closed
|
||||||
|
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
||||||
|
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
|
||||||
|
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
|
||||||
|
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry canceled.
|
||||||
|
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
|
||||||
|
0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range
|
||||||
|
0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range
|
||||||
|
0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block
|
||||||
|
0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch
|
||||||
|
0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected
|
||||||
|
0x00020191 (FAILURE,HIGH) = Unknown parameter in text input file
|
||||||
|
0x00020192 (FAILURE,HIGH) = Text input file sequence error
|
||||||
|
0x00020193 (FAILURE,HIGH) = Text input file readability problem
|
||||||
|
0x00020194 (FAILURE,HIGH) = Text input file syntax error or specs violation
|
||||||
|
0x00020195 (WARNING,HIGH) = Text input file warning
|
||||||
|
0x00020196 (FAILURE,HIGH) = Session has already defined tracks
|
||||||
|
0x00020197 (FAILURE,HIGH) = Unsupported text input file feature
|
||||||
|
0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem
|
||||||
|
0x00020199 (SORRY,HIGH) = Text input file reading aborted
|
||||||
|
0x0002019a (SORRY,HIGH) = Bad track index number
|
||||||
|
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
|
||||||
|
0x0002019c (SORRY,HIGH) = Session has no defined tracks
|
||||||
|
0x0002019d (SORRY,HIGH) = Audio read size not properly aligned
|
||||||
|
0x0002019e (NOTE,HIGH) = Drive does not support media certification
|
||||||
|
0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty
|
||||||
|
0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded
|
||||||
|
0x000201a1 (FAILURE,HIGH) = Cannot open disk file for writing
|
||||||
|
0x000201a2 (FAILURE,HIGH) = Error while writing to disk file
|
||||||
|
0x000201a3 (UPDATE,HIGH) = Progress message of burn_drive_extract_audio()
|
||||||
|
0x000201a4 (FAILURE,HIGH) = Failure to read audio sectors
|
||||||
|
0x000201a5 (FAILURE,HIGH) = Asynchronous SCSI error
|
||||||
|
0x000201a6 (FATAL,HIGH) = Lost connection to drive
|
||||||
|
0x000201a7 (FAILURE,HIGH) = SCSI command yielded host problem
|
||||||
|
0x000201a8 (FAILURE,HIGH) = SCSI command yielded driver problem
|
||||||
|
0x000201a9 (FAILURE,HIGH) = Implausible length from GET CONFIGURATION
|
||||||
|
0x000201aa (FAILURE,HIGH) = No CD-TEXT packs in file
|
||||||
|
0x000201ab (WARN,HIGH) = Leaving burn_source_fifo object undisposed
|
||||||
|
0x000201ac (NOTE,HIGH) = Drive currently does not offer Stream Recording
|
||||||
|
0x000201ad (NOTE,HIGH) = WRITE commands have been repeated
|
||||||
|
0x000201ae (FAILURE,HIGH) = Track size exceeds 4 TiB - 32 KiB
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
@ -579,11 +647,11 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
|
||||||
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
||||||
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
||||||
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
||||||
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
|
0x0003ff7f (FAILURE,HIGH) = Trying to open an already opened file
|
||||||
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
||||||
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
||||||
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
||||||
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
|
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not opened
|
||||||
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
||||||
0x0003ff79 (FAILURE,HIGH) = File read error
|
0x0003ff79 (FAILURE,HIGH) = File read error
|
||||||
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
||||||
|
@ -634,7 +702,7 @@ X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
|
||||||
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
||||||
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
||||||
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
||||||
X enought info about it
|
X enough info about it
|
||||||
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
||||||
|
|
||||||
|
|
||||||
|
@ -670,7 +738,7 @@ Range "libisoburn" : 0x00060000 to 0x00006ffff
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif /* LIDBAX_MSGS_________________ */
|
#endif /* LIBDAX_MSGS_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
4091
libburn/mmc.c
4091
libburn/mmc.c
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __MMC
|
#ifndef __MMC
|
||||||
#define __MMC
|
#define __MMC
|
||||||
|
|
||||||
|
@ -21,7 +27,7 @@ void mmc_close_disc(struct burn_write_opts *o);
|
||||||
|
|
||||||
void mmc_close(struct burn_drive *, int session, int track);
|
void mmc_close(struct burn_drive *, int session, int track);
|
||||||
void mmc_get_event(struct burn_drive *);
|
void mmc_get_event(struct burn_drive *);
|
||||||
int mmc_write(struct burn_drive *, int start, struct buffer *buf);
|
int mmc_write(struct burn_drive *, off_t start, struct buffer *buf);
|
||||||
void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf);
|
void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf);
|
||||||
void mmc_sync_cache(struct burn_drive *);
|
void mmc_sync_cache(struct burn_drive *);
|
||||||
void mmc_load(struct burn_drive *);
|
void mmc_load(struct burn_drive *);
|
||||||
|
@ -30,9 +36,9 @@ void mmc_erase(struct burn_drive *, int);
|
||||||
void mmc_read_toc(struct burn_drive *);
|
void mmc_read_toc(struct burn_drive *);
|
||||||
void mmc_read_disc_info(struct burn_drive *);
|
void mmc_read_disc_info(struct burn_drive *);
|
||||||
void mmc_read_atip(struct burn_drive *);
|
void mmc_read_atip(struct burn_drive *);
|
||||||
void mmc_read_sectors(struct burn_drive *,
|
int mmc_read_cd(struct burn_drive *d, int start, int len,
|
||||||
int,
|
int sec_type, int main_ch,
|
||||||
int, const struct burn_read_opts *, struct buffer *);
|
const struct burn_read_opts *o, struct buffer *buf, int flag);
|
||||||
void mmc_set_speed(struct burn_drive *, int, int);
|
void mmc_set_speed(struct burn_drive *, int, int);
|
||||||
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
||||||
void mmc_perform_opc(struct burn_drive *);
|
void mmc_perform_opc(struct burn_drive *);
|
||||||
|
@ -42,7 +48,8 @@ void mmc_get_configuration(struct burn_drive *);
|
||||||
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
||||||
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
|
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
|
||||||
|
|
||||||
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
/* ts B11228 : changed from void to int */
|
||||||
|
int mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
||||||
|
|
||||||
/* ts A61023 : get size and free space of drive buffer */
|
/* ts A61023 : get size and free space of drive buffer */
|
||||||
int mmc_read_buffer_capacity(struct burn_drive *d);
|
int mmc_read_buffer_capacity(struct burn_drive *d);
|
||||||
|
@ -65,10 +72,22 @@ int mmc_get_write_performance(struct burn_drive *d);
|
||||||
is the eventual duty of the caller.
|
is the eventual duty of the caller.
|
||||||
*/
|
*/
|
||||||
int mmc_compose_mode_page_5(struct burn_drive *d,
|
int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||||
|
struct burn_session *s, int tno,
|
||||||
const struct burn_write_opts *o,
|
const struct burn_write_opts *o,
|
||||||
unsigned char *pd);
|
unsigned char *pd);
|
||||||
|
|
||||||
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
/* ts A70201 */
|
||||||
|
int mmc_four_char_to_int(unsigned char *data);
|
||||||
|
/* ts C40226 */
|
||||||
|
unsigned int mmc_four_char_to_uint(unsigned char *data);
|
||||||
|
|
||||||
|
/* ts A70201 :
|
||||||
|
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
|
||||||
|
*/
|
||||||
|
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
|
||||||
|
int alloc_len);
|
||||||
|
|
||||||
|
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occurred */
|
||||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||||
struct buffer *buf);
|
struct buffer *buf);
|
||||||
|
|
||||||
|
@ -82,4 +101,49 @@ char *mmc_obtain_profile_name(int profile_number);
|
||||||
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
||||||
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90903 */
|
||||||
|
/* MMC backend of API call burn_get_media_product_id()
|
||||||
|
*/
|
||||||
|
int mmc_get_media_product_id(struct burn_drive *d,
|
||||||
|
char **product_id, char **media_code1, char **media_code2,
|
||||||
|
char **book_type, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60910 (estimated) */
|
||||||
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
/* ts A91118 */
|
||||||
|
int mmc_start_if_needed(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
/* ts B00924 */
|
||||||
|
int mmc_get_bd_spare_info(struct burn_drive *d,
|
||||||
|
int *alloc_blocks, int *free_blocks, int flag);
|
||||||
|
|
||||||
|
/* ts B10801 */
|
||||||
|
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
|
char **book_name, int *part_version, int *num_layers,
|
||||||
|
int *num_blocks, int flag);
|
||||||
|
|
||||||
|
/* ts B11201 */
|
||||||
|
int mmc_get_leadin_text(struct burn_drive *d,
|
||||||
|
unsigned char **text_packs, int *num_packs, int flag);
|
||||||
|
|
||||||
|
/* ts B40107 */
|
||||||
|
int mmc_get_performance(struct burn_drive *d, int descr_type, int flag);
|
||||||
|
|
||||||
|
/* ts B90414 */
|
||||||
|
int burn_make_feature_text(struct burn_drive *d, unsigned int feature_code,
|
||||||
|
unsigned char flags,
|
||||||
|
unsigned char additional_length,
|
||||||
|
unsigned char *feature_data,
|
||||||
|
char **text, int flag);
|
||||||
|
|
||||||
|
#ifdef Libburn_develop_quality_scaN
|
||||||
|
/* B21108 ts */
|
||||||
|
int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op,
|
||||||
|
int start_lba, int rate_period,
|
||||||
|
int *eba, int *error_rate1, int *error_rate2);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /*__MMC*/
|
#endif /*__MMC*/
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "null.h"
|
#include "null.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -15,7 +24,7 @@ struct burn_source *burn_null_source_new(void)
|
||||||
{
|
{
|
||||||
struct burn_source *src;
|
struct burn_source *src;
|
||||||
|
|
||||||
src = malloc(sizeof(struct burn_source));
|
src = calloc(1, sizeof(struct burn_source));
|
||||||
src->refcount = 1;
|
src->refcount = 1;
|
||||||
src->read = null_read;
|
src->read = null_read;
|
||||||
src->read_sub = NULL;
|
src->read_sub = NULL;
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "write.h"
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -17,7 +30,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
struct burn_write_opts *opts;
|
struct burn_write_opts *opts;
|
||||||
|
|
||||||
opts = malloc(sizeof(struct burn_write_opts));
|
opts = calloc(1, sizeof(struct burn_write_opts));
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
@ -31,14 +44,27 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
opts->toc_entry = NULL;
|
opts->toc_entry = NULL;
|
||||||
opts->toc_entries = 0;
|
opts->toc_entries = 0;
|
||||||
opts->simulate = 0;
|
opts->simulate = 0;
|
||||||
opts->underrun_proof = drive->mdata->underrun_proof;
|
opts->underrun_proof = drive->mdata->p2a_valid > 0 &&
|
||||||
|
drive->mdata->underrun_proof;
|
||||||
opts->perform_opc = 1;
|
opts->perform_opc = 1;
|
||||||
opts->obs = -1;
|
opts->obs = -1;
|
||||||
|
|
||||||
|
#ifdef Libburn_dvd_always_obs_paD
|
||||||
|
opts->obs_pad = 1;
|
||||||
|
#else
|
||||||
opts->obs_pad = 0;
|
opts->obs_pad = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
opts->bdr_obs_exempt = 0;
|
||||||
opts->start_byte = -1;
|
opts->start_byte = -1;
|
||||||
opts->fill_up_media = 0;
|
opts->fill_up_media = 0;
|
||||||
opts->force_is_set = 0;
|
opts->force_is_set = 0;
|
||||||
opts->do_stream_recording = 0;
|
opts->do_stream_recording = 0;
|
||||||
|
opts->dvd_obs_override = 0;
|
||||||
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
|
opts->text_packs = NULL;
|
||||||
|
opts->num_text_packs = 0;
|
||||||
|
opts->no_text_pack_crc_check = 0;
|
||||||
opts->has_mediacatalog = 0;
|
opts->has_mediacatalog = 0;
|
||||||
opts->format = BURN_CDROM;
|
opts->format = BURN_CDROM;
|
||||||
opts->multi = 0;
|
opts->multi = 0;
|
||||||
|
@ -48,15 +74,47 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
|
|
||||||
void burn_write_opts_free(struct burn_write_opts *opts)
|
void burn_write_opts_free(struct burn_write_opts *opts)
|
||||||
{
|
{
|
||||||
if (--opts->refcount <= 0)
|
if (--opts->refcount > 0)
|
||||||
free(opts);
|
return;
|
||||||
|
if (opts->text_packs != NULL)
|
||||||
|
free(opts->text_packs);
|
||||||
|
free(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_write_opts_clone(struct burn_write_opts *from,
|
||||||
|
struct burn_write_opts **to, int flag)
|
||||||
|
{
|
||||||
|
if (*to != NULL)
|
||||||
|
burn_write_opts_free(*to);
|
||||||
|
if (from == NULL)
|
||||||
|
return 1;
|
||||||
|
*to = calloc(1, sizeof(struct burn_write_opts));
|
||||||
|
if (*to == NULL) {
|
||||||
|
out_of_mem:;
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Out of virtual memory", 0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(*to, from, sizeof(struct burn_write_opts));
|
||||||
|
(*to)->text_packs = NULL;
|
||||||
|
(*to)->num_text_packs = 0;
|
||||||
|
if (from->text_packs != NULL && from->num_text_packs > 0) {
|
||||||
|
(*to)->text_packs = calloc(1, from->num_text_packs * 18);
|
||||||
|
if ((*to)->text_packs == NULL)
|
||||||
|
goto out_of_mem;
|
||||||
|
memcpy((*to)->text_packs, from->text_packs,
|
||||||
|
from->num_text_packs * 18);
|
||||||
|
}
|
||||||
|
(*to)->refcount= 1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
struct burn_read_opts *opts;
|
struct burn_read_opts *opts;
|
||||||
|
|
||||||
opts = malloc(sizeof(struct burn_read_opts));
|
opts = calloc(1, sizeof(struct burn_read_opts));
|
||||||
opts->drive = drive;
|
opts->drive = drive;
|
||||||
opts->refcount = 1;
|
opts->refcount = 1;
|
||||||
opts->raw = 0;
|
opts->raw = 0;
|
||||||
|
@ -67,6 +125,7 @@ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
||||||
opts->report_recovered_errors = 0;
|
opts->report_recovered_errors = 0;
|
||||||
opts->transfer_damaged_blocks = 0;
|
opts->transfer_damaged_blocks = 0;
|
||||||
opts->hardware_error_retries = 3;
|
opts->hardware_error_retries = 3;
|
||||||
|
opts->dap_bit = 0;
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +172,7 @@ void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count,
|
||||||
struct burn_toc_entry *toc_entries)
|
struct burn_toc_entry *toc_entries)
|
||||||
{
|
{
|
||||||
opts->toc_entries = count;
|
opts->toc_entries = count;
|
||||||
opts->toc_entry = malloc(count * sizeof(struct burn_toc_entry));
|
opts->toc_entry = calloc(count, sizeof(struct burn_toc_entry));
|
||||||
memcpy(opts->toc_entry, &toc_entries,
|
memcpy(opts->toc_entry, &toc_entries,
|
||||||
sizeof(struct burn_toc_entry) * count);
|
sizeof(struct burn_toc_entry) * count);
|
||||||
}
|
}
|
||||||
|
@ -125,17 +184,6 @@ void burn_write_opts_set_format(struct burn_write_opts *opts, int format)
|
||||||
|
|
||||||
int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
||||||
{
|
{
|
||||||
/* <<< ts A70529 :
|
|
||||||
One cannot predict the ability to simulate from page 05h
|
|
||||||
information alone. This check is now done later in
|
|
||||||
function burn_write_opts_auto_write_type().
|
|
||||||
|
|
||||||
if (opts->drive->mdata->simulate) {
|
|
||||||
opts->simulate = sim;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
*/
|
|
||||||
opts->simulate = !!sim;
|
opts->simulate = !!sim;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -143,9 +191,8 @@ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
||||||
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
||||||
int underrun_proof)
|
int underrun_proof)
|
||||||
{
|
{
|
||||||
if (opts->drive->mdata->valid <= 0)
|
if (opts->drive->mdata->p2a_valid <= 0 ||
|
||||||
return 0;
|
opts->drive->mdata->underrun_proof) {
|
||||||
if (opts->drive->mdata->underrun_proof) {
|
|
||||||
opts->underrun_proof = underrun_proof;
|
opts->underrun_proof = underrun_proof;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +213,7 @@ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
|
||||||
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
||||||
unsigned char mediacatalog[13])
|
unsigned char mediacatalog[13])
|
||||||
{
|
{
|
||||||
memcpy(opts->mediacatalog, &mediacatalog, 13);
|
memcpy(opts->mediacatalog, mediacatalog, 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,6 +224,81 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B31024 */
|
||||||
|
/* API */
|
||||||
|
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
|
||||||
|
char *severity)
|
||||||
|
{
|
||||||
|
int ret, sevno;
|
||||||
|
|
||||||
|
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
opts->feat21h_fail_sev = 0;
|
||||||
|
else
|
||||||
|
opts->feat21h_fail_sev = sevno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11204 */
|
||||||
|
/* @param flag bit0=do not verify checksums
|
||||||
|
bit1= repair mismatching checksums
|
||||||
|
bit2= repair checksums if they are 00 00 with each pack
|
||||||
|
*/
|
||||||
|
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
||||||
|
unsigned char *text_packs,
|
||||||
|
int num_packs, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char *pack_buffer = NULL;
|
||||||
|
|
||||||
|
if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||||
|
0x0002018b,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Too many CD-TEXT packs", 0, 0);
|
||||||
|
ret= 0; goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_packs > 0)
|
||||||
|
BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
|
||||||
|
|
||||||
|
if (opts->text_packs != NULL) {
|
||||||
|
free(opts->text_packs);
|
||||||
|
opts->text_packs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & 1) {
|
||||||
|
opts->no_text_pack_crc_check = 1;
|
||||||
|
} else {
|
||||||
|
opts->no_text_pack_crc_check = 0;
|
||||||
|
ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
|
||||||
|
(flag >> 1) & 3);
|
||||||
|
if (ret > 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack CRC mismatch", 0, 0);
|
||||||
|
ret = 0; goto ex;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"CD-TEXT pack CRC mismatch had to be corrected",
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_packs > 0) {
|
||||||
|
memcpy(pack_buffer, text_packs, num_packs * 18);
|
||||||
|
opts->text_packs = pack_buffer;
|
||||||
|
pack_buffer = NULL;
|
||||||
|
}
|
||||||
|
opts->num_text_packs = num_packs;
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(pack_buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61222 */
|
/* ts A61222 */
|
||||||
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
||||||
{
|
{
|
||||||
|
@ -202,6 +324,11 @@ enum burn_write_types burn_write_opts_auto_write_type(
|
||||||
|
|
||||||
reasons[0] = 0;
|
reasons[0] = 0;
|
||||||
|
|
||||||
|
if (burn_drive_get_bd_r_pow(d)) {
|
||||||
|
strcat(reasons,
|
||||||
|
"MEDIA: unsuitable BD-R Pseudo Overwrite formatting, ");
|
||||||
|
return BURN_WRITE_NONE;
|
||||||
|
}
|
||||||
if (d->status != BURN_DISC_BLANK &&
|
if (d->status != BURN_DISC_BLANK &&
|
||||||
d->status != BURN_DISC_APPENDABLE){
|
d->status != BURN_DISC_APPENDABLE){
|
||||||
if (d->status == BURN_DISC_FULL)
|
if (d->status == BURN_DISC_FULL)
|
||||||
|
@ -284,6 +411,10 @@ do_sao:;
|
||||||
{wt = BURN_WRITE_SAO; goto ex;}
|
{wt = BURN_WRITE_SAO; goto ex;}
|
||||||
no_sao:;
|
no_sao:;
|
||||||
try_tao:;
|
try_tao:;
|
||||||
|
if (opts->num_text_packs > 0) {
|
||||||
|
strcat(reasons, "CD-TEXT: write type SAO required, ");
|
||||||
|
{wt = BURN_WRITE_NONE; goto ex;}
|
||||||
|
}
|
||||||
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
|
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
|
||||||
goto try_raw;
|
goto try_raw;
|
||||||
reason_pt = reasons + strlen(reasons);
|
reason_pt = reasons + strlen(reasons);
|
||||||
|
@ -389,6 +520,42 @@ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91115: API */
|
||||||
|
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
|
||||||
|
{
|
||||||
|
if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
|
||||||
|
return;
|
||||||
|
opts->dvd_obs_override = obs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B20406: API */
|
||||||
|
void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
|
||||||
|
{
|
||||||
|
opts->obs_pad = 2 * !!pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts C10909: API */
|
||||||
|
void burn_write_opts_set_bdr_obs_exempt(struct burn_write_opts *opts,
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
opts->bdr_obs_exempt = !!value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91115: API */
|
||||||
|
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rhythm)
|
||||||
|
{
|
||||||
|
if (rhythm == -1)
|
||||||
|
opts->stdio_fsync_size = -1; /* never */
|
||||||
|
else if (rhythm == 0)
|
||||||
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
|
else if (rhythm == 1)
|
||||||
|
opts->stdio_fsync_size = 0; /* only at end of writing */
|
||||||
|
else if (rhythm >= 32)
|
||||||
|
opts->stdio_fsync_size = rhythm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70901: API */
|
/* ts A70901: API */
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__OPTIONS_H
|
#ifndef BURN__OPTIONS_H
|
||||||
#define BURN__OPTIONS_H
|
#define BURN__OPTIONS_H
|
||||||
|
|
||||||
|
@ -36,34 +42,75 @@ struct burn_write_opts
|
||||||
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
||||||
-1 with CD, 32 kB with DVD */
|
-1 with CD, 32 kB with DVD */
|
||||||
int obs;
|
int obs;
|
||||||
int obs_pad; /* 1=pad up last block to obs */
|
int obs_pad; /* >0 pad up last block to obs, 0 do not
|
||||||
|
2 indicates burn_write_opts_set_obs_pad(,1)
|
||||||
|
*/
|
||||||
|
|
||||||
/* ts A61222 : Start address for media which allow a choice */
|
/* 1= do not apply obs_pad=1 to BD-R if not stream recording. */
|
||||||
|
int bdr_obs_exempt;
|
||||||
|
|
||||||
|
/* ts A61222 : Start address for media which offer a choice */
|
||||||
off_t start_byte;
|
off_t start_byte;
|
||||||
|
|
||||||
/* ts A70213 : Wether to fill up the available space on media */
|
/* ts A70213 : Whether to fill up the available space on media */
|
||||||
int fill_up_media;
|
int fill_up_media;
|
||||||
|
|
||||||
/* ts A70303 : Wether to override conformance checks:
|
/* ts A70303 : Whether to override conformance checks:
|
||||||
- the check wether CD write+block type is supported by the drive
|
- the check whether CD write+block type is supported by the drive
|
||||||
*/
|
*/
|
||||||
int force_is_set;
|
int force_is_set;
|
||||||
|
|
||||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||||
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
||||||
This gets transferred to burn_drive.do_stream_recording */
|
This gets transferred to burn_drive.do_stream_recording
|
||||||
|
*/
|
||||||
int do_stream_recording;
|
int do_stream_recording;
|
||||||
|
|
||||||
|
/* ts A91115 : override value for .obs on DVD media.
|
||||||
|
Only values 0, 32K and 64K are allowed for now. */
|
||||||
|
int dvd_obs_override;
|
||||||
|
|
||||||
|
/* ts A91115 : size of the fsync() interval for stdio writing.
|
||||||
|
Values 0 or >= 32 counted in 2 KB blocks. */
|
||||||
|
int stdio_fsync_size;
|
||||||
|
|
||||||
|
/* ts B11203 : CD-TEXT */
|
||||||
|
unsigned char *text_packs;
|
||||||
|
int num_text_packs;
|
||||||
|
int no_text_pack_crc_check;
|
||||||
|
|
||||||
/** A disc can have a media catalog number */
|
/** A disc can have a media catalog number */
|
||||||
int has_mediacatalog;
|
int has_mediacatalog;
|
||||||
unsigned char mediacatalog[13];
|
unsigned char mediacatalog[13];
|
||||||
/** Session format */
|
/** Session format */
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
/* internal use only */
|
/* internal use only */
|
||||||
unsigned char control;
|
unsigned char control;
|
||||||
|
|
||||||
|
/* Whether to keep medium appendable */
|
||||||
unsigned char multi;
|
unsigned char multi;
|
||||||
|
|
||||||
|
/* ts B31024 */
|
||||||
|
/* The severity to be attributed to error messages about failed
|
||||||
|
write attempt with blank DVD-RW, possibly due to falsely reported
|
||||||
|
feature 21h Incremental Streaming Writable
|
||||||
|
*/
|
||||||
|
int feat21h_fail_sev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Default value for burn_write_opts.stdio_flush_size
|
||||||
|
*/
|
||||||
|
#define Libburn_stdio_fsync_limiT 8192
|
||||||
|
|
||||||
|
/* Maximum number of Lead-in text packs.
|
||||||
|
READ TOC/PMA/ATIP can at most return 3640.7 packs.
|
||||||
|
The sequence counters of the packs have 8 bits. There are 8 blocks at most.
|
||||||
|
Thus max 2048 packs.
|
||||||
|
*/
|
||||||
|
#define Libburn_leadin_cdtext_packs_maX 2048
|
||||||
|
|
||||||
|
|
||||||
/** Options for disc reading operations. This should be created with
|
/** Options for disc reading operations. This should be created with
|
||||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
struct burn_read_opts
|
struct burn_read_opts
|
||||||
|
@ -95,6 +142,19 @@ struct burn_read_opts
|
||||||
/** The number of retries the hardware should make to correct
|
/** The number of retries the hardware should make to correct
|
||||||
errors. */
|
errors. */
|
||||||
unsigned char hardware_error_retries;
|
unsigned char hardware_error_retries;
|
||||||
|
|
||||||
|
/* ts B21119 */
|
||||||
|
/* >>> Needs API access */
|
||||||
|
/** Whether to set DAP bit which allows the drive to apply
|
||||||
|
"flaw obscuring mechanisms like audio data mute and interpolate"
|
||||||
|
*/
|
||||||
|
unsigned int dap_bit;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int burn_write_opts_clone(struct burn_write_opts *from,
|
||||||
|
struct burn_write_opts **to, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__OPTIONS_H */
|
#endif /* BURN__OPTIONS_H */
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
Unknown POSIX like systems
|
Unknown POSIX like systems
|
||||||
with the dummy MMC transport adapter sg-dummy.c
|
with the dummy MMC transport adapter sg-dummy.c
|
||||||
|
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,25 +17,49 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
SIGUSR1, SIGUSR2, SIGXCPU
|
||||||
SIGTTOU
|
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
||||||
"SIGTTOU"
|
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_SIGNAL_COUNT 16
|
#define BURN_OS_SIGNAL_COUNT 13
|
||||||
|
|
||||||
/** To list all signals which shall surely not be caught */
|
/** The list of all signals which shall surely not be caught.
|
||||||
|
It depends on the particular signal whether it can be ignored or whether
|
||||||
|
it will lead to sudden death of the process.
|
||||||
|
Some signals are not POSIX,
|
||||||
|
but nevertheless ought to be ignored if they are defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH ,SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_WINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIGURG
|
||||||
|
#define BURN_OS_SIG_URG ,SIGURG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_URG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The combined list of all signals which shall not be caught.
|
||||||
|
*/
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP
|
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
|
||||||
|
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 3
|
#define BURN_OS_NON_SIGNAL_COUNT \
|
||||||
|
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
|
||||||
|
|
||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
FreeBSD with CAM
|
FreeBSD with CAM
|
||||||
|
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
|
Provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** List of all signals which shall be caught by signal handlers and trigger
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
@ -14,34 +15,34 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPROF, \
|
||||||
SIGTTOU, \
|
SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ
|
||||||
SIGBUS, SIGPROF, SIGSYS, SIGTRAP, \
|
|
||||||
SIGVTALRM, SIGXCPU, SIGXFSZ
|
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPROF", \
|
||||||
"SIGTTOU", \
|
"SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
||||||
"SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
|
||||||
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_SIGNAL_COUNT 23
|
#define BURN_OS_SIGNAL_COUNT 20
|
||||||
|
|
||||||
/** To list all signals which shall surely not be caught */
|
/** To list all signals which shall surely not be caught */
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 5
|
#define BURN_OS_NON_SIGNAL_COUNT 9
|
||||||
|
|
||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
/* Important : MUST be at least 32768 ! */
|
/* Important : MUST be at least 32768 ! */
|
||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
/* Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
|
||||||
|
on 8-STABLE. It is by default only used with BD in streaming mode.
|
||||||
|
So older systems should still be quite safe with this buffer max size.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
/** To hold all state information of BSD device enumeration
|
/** To hold all state information of BSD device enumeration
|
||||||
|
@ -57,5 +58,8 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
|
||||||
To be initialized and used within sg-*.c .
|
To be initialized and used within sg-*.c .
|
||||||
*/
|
*/
|
||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
struct cam_device* cam;
|
struct cam_device* cam; \
|
||||||
|
int lock_fd; \
|
||||||
|
int is_ahci; \
|
||||||
|
|
||||||
|
|
||||||
|
|
95
libburn/os-libcdio.h
Normal file
95
libburn/os-libcdio.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
|
||||||
|
/* os-libcdio.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
Unknown X/Open-like systems
|
||||||
|
with GNU libcdio MMC transport adapter sg-libcdio.c
|
||||||
|
|
||||||
|
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
a graceful abort of libburn. (See man 7 signal.)
|
||||||
|
*/
|
||||||
|
/* Once as system defined macros */
|
||||||
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
|
SIGUSR1, SIGUSR2, SIGXCPU
|
||||||
|
|
||||||
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
|
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_SIGNAL_COUNT 13
|
||||||
|
|
||||||
|
|
||||||
|
/** The list of all signals which shall surely not be caught.
|
||||||
|
It depends on the particular signal whether it can be ignored or whether
|
||||||
|
it will lead to sudden death of the process.
|
||||||
|
Some signals are not POSIX,
|
||||||
|
but nevertheless ought to be ignored if they are defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH ,SIGWINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_WINCH
|
||||||
|
#define BURN_OS_SIG_WINCH_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIGURG
|
||||||
|
#define BURN_OS_SIG_URG ,SIGURG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 1
|
||||||
|
#else
|
||||||
|
#define BURN_OS_SIG_URG
|
||||||
|
#define BURN_OS_SIG_URG_CNT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The combined list of all signals which shall not be caught.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
|
||||||
|
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT \
|
||||||
|
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
|
||||||
|
with buffer size 32 kB. So stream recording is allowed only with size 64k.
|
||||||
|
Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
|
||||||
|
on 8-STABLE. It is by default only used with BD in streaming mode.
|
||||||
|
So older systems should still be quite safe with this buffer max size.
|
||||||
|
*/
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
|
/* To hold the position of the most recently delivered address from
|
||||||
|
device enumeration.
|
||||||
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
char **ppsz_cd_drives;
|
||||||
|
char **pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
|
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* The list of operating system dependent elements in struct burn_drive.
|
||||||
|
Usually they are initialized in sg-*.c:enumerate_common().
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
|
void *p_cdio; /* actually a pointer to CdIo_t */ \
|
||||||
|
char libcdio_name[4096]; /* The drive path as used by libcdio */ \
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
/* os-linux.h
|
/* os-linux.h
|
||||||
Operating system specific libburn definitions and declarations. Included
|
Operating system specific libburn definitions and declarations. Included
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg)
|
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
|
||||||
|
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,29 +16,27 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPOLL, \
|
||||||
SIGTTOU, \
|
SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, \
|
||||||
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, \
|
SIGXFSZ
|
||||||
SIGVTALRM, SIGXCPU, SIGXFSZ
|
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPOLL", \
|
||||||
"SIGTTOU", \
|
"SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", \
|
||||||
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
"SIGXFSZ"
|
||||||
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_SIGNAL_COUNT 24
|
#define BURN_OS_SIGNAL_COUNT 21
|
||||||
|
|
||||||
/** To list all signals which shall surely not be caught */
|
/** To list all signals which shall surely not be caught */
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGURG, SIGWINCH, SIGTTIN, SIGTTOU
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 5
|
#define BURN_OS_NON_SIGNAL_COUNT 9
|
||||||
|
|
||||||
|
|
||||||
/* The maximum size for a (SCSI) i/o transaction */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
99
libburn/os-netbsd.h
Normal file
99
libburn/os-netbsd.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
|
||||||
|
/* os-netbsd.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
NetBSD 6 or OpenBSD 5.9
|
||||||
|
with MMC transport adapter sg-netbsd.c
|
||||||
|
|
||||||
|
Copyright (C) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
provided under GPLv2+
|
||||||
|
|
||||||
|
Derived 2014 from libburn/os-solaris.c
|
||||||
|
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
a graceful abort of libburn. (See man signal.h)
|
||||||
|
*/
|
||||||
|
/* Once as system defined macros */
|
||||||
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, \
|
||||||
|
SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, \
|
||||||
|
SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGXCPU, \
|
||||||
|
SIGXFSZ, SIGVTALRM, SIGPROF, SIGUSR1, SIGUSR2
|
||||||
|
|
||||||
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", \
|
||||||
|
"SIGABRT", "SIGEMT", "SIGFPE", "SIGBUS", "SIGSEGV", \
|
||||||
|
"SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGXCPU", \
|
||||||
|
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGUSR1", "SIGUSR2"
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_SIGNAL_COUNT 20
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
|
||||||
|
/** To list all signals which shall surely not be caught */
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
|
||||||
|
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
|
||||||
|
SIGINFO
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 11
|
||||||
|
|
||||||
|
/* ts B60730 */
|
||||||
|
/* Either OpenBSD or SASANO Takayoshi's LG BH14NS48 throw 2,0,0
|
||||||
|
on Immed bit with BLANK and SYNCHRONIZE CACHE.
|
||||||
|
Until it is clear that the drive is to blame, the OpenBSD default is
|
||||||
|
not to use Immed.
|
||||||
|
|
||||||
|
This may be overridden at ./configure time by
|
||||||
|
export CFLAGS
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_do_no_immed_defaulT=0"
|
||||||
|
*/
|
||||||
|
#ifndef Libburn_do_no_immed_defaulT
|
||||||
|
#define Libburn_do_no_immed_defaulT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* __OpenBSD__ */
|
||||||
|
|
||||||
|
/** To list all signals which shall surely not be caught */
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
|
||||||
|
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
|
||||||
|
SIGINFO, SIGPWR
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 12
|
||||||
|
|
||||||
|
#endif /* ! __OpenBSD__ */
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
|
||||||
|
with buffer size 32 kB. So stream recording is allowed only with size 64k.
|
||||||
|
*/
|
||||||
|
/* >>> ??? Does it do 64 kB ? */
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
|
/* To hold the position of the most recently delivered address from
|
||||||
|
device enumeration.
|
||||||
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
int cdno;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
|
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* The list of operating system dependent elements in struct burn_drive.
|
||||||
|
Usually they are initialized in sg-*.c:enumerate_common().
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
|
int fd;
|
||||||
|
|
65
libburn/os-solaris.h
Normal file
65
libburn/os-solaris.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
/* os-solaris.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
Solaris based systems, e.g. SunOS 5.11
|
||||||
|
with Solaris uscsi MMC transport adapter sg-solaris.c
|
||||||
|
|
||||||
|
Copyright (C) 2010 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
a graceful abort of libburn. (See man signal.h)
|
||||||
|
*/
|
||||||
|
/* Once as system defined macros */
|
||||||
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
|
SIGUSR1, SIGUSR2, SIGXCPU
|
||||||
|
|
||||||
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
|
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_SIGNAL_COUNT 13
|
||||||
|
|
||||||
|
/** To list all signals which shall surely not be caught */
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 9
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
|
||||||
|
with buffer size 32 kB. So stream recording is allowed only with size 64k.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> */
|
||||||
|
|
||||||
|
/* To hold the position of the most recently delivered address from
|
||||||
|
device enumeration.
|
||||||
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
void *dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
|
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* The list of operating system dependent elements in struct burn_drive.
|
||||||
|
Usually they are initialized in sg-*.c:enumerate_common().
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
|
int fd;
|
||||||
|
|
59
libburn/os.h
59
libburn/os.h
|
@ -3,7 +3,8 @@
|
||||||
Operating system specific libburn definitions and declarations.
|
Operating system specific libburn definitions and declarations.
|
||||||
The macros defined here are used by libburn modules in order to
|
The macros defined here are used by libburn modules in order to
|
||||||
avoid own system dependent case distinctions.
|
avoid own system dependent case distinctions.
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
|
provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BURN_OS_H_INCLUDED
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
|
@ -13,6 +14,38 @@
|
||||||
Operating system case distinction
|
Operating system case distinction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
|
||||||
|
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
||||||
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------- X/Open with GNU libcdio ---------------------- */
|
||||||
|
#include "os-libcdio.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------- NetBSD with SCIOCCOMMAND --------------------- */
|
||||||
|
#include "os-netbsd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------- OpenBSD with SCIOCCOMMAND -------------------- */
|
||||||
|
#include "os-netbsd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,14 +53,30 @@
|
||||||
#include "os-freebsd.h"
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------- FreeBSD with CAM under Debian ------------------- */
|
||||||
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
|
|
||||||
|
|
||||||
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
/* ------- Linux kernels 2.4 and 2.6 with GNU/Linux SCSI Generic (sg) ------ */
|
||||||
#include "os-linux.h"
|
#include "os-linux.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __sun
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Solaris (e.g. SunOS 5.11) with uscsi ------ */
|
||||||
|
#include "os-solaris.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,8 +84,14 @@
|
||||||
#include "os-dummy.h"
|
#include "os-dummy.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! __sun*/
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
|
#endif /* ! __FreeBSD__kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
|
#endif /* ! __OpenBSD__ */
|
||||||
|
#endif /* ! __NetBSD__ */
|
||||||
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! BURN_OS_H_INCLUDED */
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
|
471
libburn/read.c
471
libburn/read.c
|
@ -1,6 +1,13 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -15,6 +22,11 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sector.h"
|
#include "sector.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
|
@ -27,9 +39,9 @@
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "lec.h"
|
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "mmc.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
#include "read.h"
|
#include "read.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
@ -48,7 +60,7 @@ void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o)
|
||||||
int drive_lba;
|
int drive_lba;
|
||||||
unsigned short crc;
|
unsigned short crc;
|
||||||
unsigned char fakesub[96];
|
unsigned char fakesub[96];
|
||||||
struct buffer page;
|
struct buffer page; <- needs to become dynamic memory
|
||||||
int speed;
|
int speed;
|
||||||
|
|
||||||
/* ts A61007 : if this function gets revived, then these
|
/* ts A61007 : if this function gets revived, then these
|
||||||
|
@ -95,7 +107,13 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
fakesub[20] = 2;
|
fakesub[20] = 2;
|
||||||
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
||||||
d->toc->toc_entry[0].adr;
|
d->toc->toc_entry[0].adr;
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(fakesub + 12, 10);
|
crc = crc_ccitt(fakesub + 12, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
fakesub[22] = crc >> 8;
|
fakesub[22] = crc >> 8;
|
||||||
fakesub[23] = crc & 0xFF;
|
fakesub[23] = crc & 0xFF;
|
||||||
write(o->subfd, fakesub, 96);
|
write(o->subfd, fakesub, 96);
|
||||||
|
@ -103,7 +121,6 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
while (1) {
|
while (1) {
|
||||||
seclen = burn_sector_length_read(d, o);
|
seclen = burn_sector_length_read(d, o);
|
||||||
|
|
||||||
burn_print(12, "received %d blocks\n", page.sectors);
|
|
||||||
for (i = 0; i < page.sectors; i++) {
|
for (i = 0; i < page.sectors; i++) {
|
||||||
burn_packet_process(d, page.data + seclen * i, o);
|
burn_packet_process(d, page.data + seclen * i, o);
|
||||||
d->track_end--;
|
d->track_end--;
|
||||||
|
@ -111,7 +128,6 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
||||||
burn_print(1, "finished or cancelled\n");
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
if (!d->cancel)
|
if (!d->cancel)
|
||||||
d->toc->complete = 1;
|
d->toc->complete = 1;
|
||||||
|
@ -125,16 +141,14 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
if (d->currtrack >
|
if (d->currtrack >
|
||||||
d->toc->session[d->currsession].lasttrack) {
|
d->toc->session[d->currsession].lasttrack) {
|
||||||
d->currsession++;
|
d->currsession++;
|
||||||
burn_print(12, "session switch to %d\n",
|
/* session switch to d->currsession */
|
||||||
d->currsession);
|
/* skipping a lead out */
|
||||||
burn_print(12, "skipping a lead out\n");
|
|
||||||
drive_lba = CURRENT_SESSION_START(d);
|
drive_lba = CURRENT_SESSION_START(d);
|
||||||
burn_print(12, "new lba %d\n", drive_lba);
|
|
||||||
/* XXX more of the same
|
/* XXX more of the same
|
||||||
end = burn_track_end(d, d->currsession,
|
end = burn_track_end(d, d->currsession,
|
||||||
d->currtrack);
|
d->currtrack);
|
||||||
*/ }
|
*/
|
||||||
burn_print(12, "track switch to %d\n", d->currtrack);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
page.sectors = 0;
|
page.sectors = 0;
|
||||||
|
@ -150,6 +164,8 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
drive_lba);
|
drive_lba);
|
||||||
|
|
||||||
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
||||||
|
/* >>> ts B21123 : Would now be d->read_cd() with
|
||||||
|
with sectype = 0 , mainch = 0xf8 */
|
||||||
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
||||||
|
|
||||||
printf("Read %d\n", page.sectors);
|
printf("Read %d\n", page.sectors);
|
||||||
|
@ -189,23 +205,21 @@ static int bitcount(unsigned char *data, int n)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
const struct burn_read_opts *o)
|
const struct burn_read_opts *o)
|
||||||
{
|
{
|
||||||
unsigned char sub[96];
|
unsigned char sub[96];
|
||||||
unsigned short crc;
|
|
||||||
int ptr = 2352, i, j, code, fb;
|
int ptr = 2352, i, j, code, fb;
|
||||||
int audio = 1;
|
int audio = 1;
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
unsigned short crc;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (o->c2errors) {
|
if (o->c2errors) {
|
||||||
fb = bitcount(data + ptr, 294);
|
fb = bitcount(data + ptr, 294);
|
||||||
if (fb) {
|
if (fb) {
|
||||||
burn_print(1, "%d damaged bits\n",
|
/* bitcount(data + ptr, 294) damaged bits */;
|
||||||
bitcount(data + ptr, 294));
|
|
||||||
burn_print(1, "sending error on %s %s\n",
|
|
||||||
d->idata->vendor, d->idata->product);
|
|
||||||
/* XXX send a burn_message! burn_message_error(d,
|
|
||||||
something); */
|
|
||||||
}
|
}
|
||||||
ptr += 294;
|
ptr += 294;
|
||||||
}
|
}
|
||||||
|
@ -241,15 +255,20 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
crc = (*(sub + 22) << 8) + *(sub + 23);
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
if (crc != crc_ccitt(sub + 12, 10)) {
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
|
/*
|
||||||
burn_print(1, "sending error on %s %s\n",
|
burn_print(1, "sending error on %s %s\n",
|
||||||
d->idata->vendor, d->idata->product);
|
d->idata->vendor, d->idata->product);
|
||||||
/* e = burn_error();
|
e = burn_error();
|
||||||
e->drive = d;
|
e->drive = d;
|
||||||
*/
|
|
||||||
burn_print(1, "crc mismatch in Q\n");
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
|
*/;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* else process_q(d, sub + 12); */
|
/* else process_q(d, sub + 12); */
|
||||||
/*
|
/*
|
||||||
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
||||||
|
@ -267,11 +286,15 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
*//* write(o->datafd, data, 2352); */
|
*//* write(o->datafd, data, 2352); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* so yeah, when you uncomment these, make them write zeros insted of crap
|
/* so yeah, when you uncomment these, make them write zeros instead of crap
|
||||||
static void write_empty_sector(int fd)
|
static void write_empty_sector(int fd)
|
||||||
{
|
{
|
||||||
char sec[2352];
|
static char sec[2352], initialized = 0;
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
memset(sec, 0, 2352);
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
burn_print(1, "writing an 'empty' sector\n");
|
burn_print(1, "writing an 'empty' sector\n");
|
||||||
write(fd, sec, 2352);
|
write(fd, sec, 2352);
|
||||||
}
|
}
|
||||||
|
@ -291,8 +314,33 @@ static void flipq(unsigned char *sub)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @param flag bit1= be silent on failure
|
||||||
|
bit5= report failure with severity DEBUG
|
||||||
|
*/
|
||||||
|
static int burn_stdio_seek(int fd, off_t byte_address, struct burn_drive *d,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
char msg[80];
|
||||||
|
|
||||||
|
if (lseek(fd, byte_address, SEEK_SET) != -1)
|
||||||
|
return 1;
|
||||||
|
if (!(flag & 2)) {
|
||||||
|
sprintf(msg, "Cannot address start byte %.f",
|
||||||
|
(double) byte_address);
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x00020147,
|
||||||
|
(flag & 32) ?
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70904 */
|
/* ts A70904 */
|
||||||
/** @param flag bit0=be silent on data shortage */
|
/** @param flag bit0= be silent on data shortage
|
||||||
|
bit5= report data shortage with severity DEBUG
|
||||||
|
*/
|
||||||
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
|
@ -307,7 +355,9 @@ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||||
if(todo > 0 && !(flag & 1)) {
|
if(todo > 0 && !(flag & 1)) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002014a,
|
0x0002014a,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
(flag & 32) ?
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Cannot read desired amount of data", errno, 0);
|
"Cannot read desired amount of data", errno, 0);
|
||||||
}
|
}
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
|
@ -316,14 +366,85 @@ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* With DVD and BD media, the minimum ECC entity is read instead of single
|
||||||
|
blocks.
|
||||||
|
@param flag see burn_read_data() in libburn.h
|
||||||
|
*/
|
||||||
|
static int retry_mmc_read(struct burn_drive *d, int chunksize, int sose_mem,
|
||||||
|
int start, char **wpt, off_t *data_count,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int i, err, todo;
|
||||||
|
int retry_at, retry_size;
|
||||||
|
|
||||||
|
retry_at = start;
|
||||||
|
retry_size = chunksize;
|
||||||
|
todo = chunksize;
|
||||||
|
retry_size = 16; /* DVD ECC block size */
|
||||||
|
if (d->current_is_cd_profile) {
|
||||||
|
retry_size = 1; /* CD block size */
|
||||||
|
} else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) {
|
||||||
|
retry_size = 32; /* BD cluster size */
|
||||||
|
}
|
||||||
|
for (i = 0; todo > 0; i++) {
|
||||||
|
if (flag & 2)
|
||||||
|
d->silent_on_scsi_error = 1;
|
||||||
|
else if (flag & 32)
|
||||||
|
d->silent_on_scsi_error = 3;
|
||||||
|
retry_at = start + i * retry_size;
|
||||||
|
if (retry_size > todo)
|
||||||
|
retry_size = todo;
|
||||||
|
err = d->read_10(d, retry_at, retry_size, d->buffer);
|
||||||
|
if (flag & (2 | 32))
|
||||||
|
d->silent_on_scsi_error = sose_mem;
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
|
return 0;
|
||||||
|
memcpy(*wpt, d->buffer->data, retry_size * 2048);
|
||||||
|
*wpt += retry_size * 2048;
|
||||||
|
*data_count += retry_size * 2048;
|
||||||
|
todo -= retry_size;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag see burn_read_data() in libburn.h
|
||||||
|
*/
|
||||||
|
static int retry_stdio_read(struct burn_drive *d, int fd, int chunksize,
|
||||||
|
int start, char **wpt, off_t *data_count,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int i, ret, to_read, todo;
|
||||||
|
|
||||||
|
ret = burn_stdio_seek(fd, ((off_t) start) * 2048, d, flag & 2);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
todo = chunksize * 2048;
|
||||||
|
for (i = 0; todo > 0; i += 2048) {
|
||||||
|
to_read = todo;
|
||||||
|
if (to_read > 2048)
|
||||||
|
to_read = 2048;
|
||||||
|
ret = burn_stdio_read(fd, (char *) d->buffer->data, to_read,
|
||||||
|
d, 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
memcpy(*wpt, d->buffer->data, to_read);
|
||||||
|
*wpt += to_read;
|
||||||
|
*data_count += to_read;
|
||||||
|
todo -= to_read;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70812 : API function */
|
/* ts A70812 : API function */
|
||||||
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
char data[], off_t data_size, off_t *data_count, int flag)
|
char data[], off_t data_size, off_t *data_count, int flag)
|
||||||
{
|
{
|
||||||
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
|
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size;
|
||||||
int sose_mem = 0, fd = -1, ret;
|
int sose_mem = 0, fd = -1, ret;
|
||||||
char msg[81], *wpt;
|
char msg[81], *wpt;
|
||||||
struct buffer buf, *buffer_mem = d->buffer;
|
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Libburn_read_data_adr_logginG 1
|
#define Libburn_read_data_adr_logginG 1
|
||||||
|
@ -337,7 +458,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
fprintf(log_fp, "%d\n", (int) (byte_address / 2048));
|
fprintf(log_fp, "%d\n", (int) (byte_address / 2048));
|
||||||
#endif /* Libburn_read_data_logginG */
|
#endif /* Libburn_read_data_logginG */
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||||
*data_count = 0;
|
*data_count = 0;
|
||||||
sose_mem = d->silent_on_scsi_error;
|
sose_mem = d->silent_on_scsi_error;
|
||||||
|
|
||||||
|
@ -346,20 +467,20 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
d->global_index, 0x00020142,
|
d->global_index, 0x00020142,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive is not grabbed on random access read", 0, 0);
|
"Drive is not grabbed on random access read", 0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
if (d->drive_role == 0) {
|
if (d->drive_role == 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020146,
|
0x00020146,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
} else if (d->drive_role == 3) {
|
} else if (d->drive_role == 3) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020151,
|
0x00020151,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Read attempt on write-only drive", 0, 0);
|
"Read attempt on write-only drive", 0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
if ((byte_address % alignment) != 0) {
|
if ((byte_address % alignment) != 0) {
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
|
@ -369,7 +490,21 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
0x00020143,
|
0x00020143,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if (d->media_read_capacity != 0x7fffffffffffffff &&
|
||||||
|
byte_address >= (d->media_read_capacity + 1) * (off_t) 2048) {
|
||||||
|
if (!(flag & 2)) {
|
||||||
|
sprintf(msg,
|
||||||
|
"Read start address %.fs larger than number of readable blocks %.f",
|
||||||
|
(double) (byte_address / 2048 + !!(byte_address % 2048)),
|
||||||
|
(double) (d->media_read_capacity + 1));
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020172, (flag & 32) ?
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
||||||
|
}
|
||||||
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->busy != BURN_DRIVE_IDLE) {
|
if (d->busy != BURN_DRIVE_IDLE) {
|
||||||
|
@ -377,7 +512,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
d->global_index, 0x00020145,
|
d->global_index, 0x00020145,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive is busy on attempt to read data", 0, 0);
|
"Drive is busy on attempt to read data", 0, 0);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->drive_role != 1) {
|
if (d->drive_role != 1) {
|
||||||
|
@ -391,30 +526,38 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
fd = d->stdio_fd;
|
fd = d->stdio_fd;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
d->stdio_fd = fd =
|
d->stdio_fd = fd =
|
||||||
open(d->devname, O_RDONLY | O_LARGEFILE);
|
open(d->devname,
|
||||||
|
O_RDONLY | O_LARGEFILE | O_BINARY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno != ENOENT || !(flag & 2))
|
if (errno == EACCES && (flag & 2)) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
if (!(flag & 8))
|
||||||
d->global_index,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
0x00020005,
|
d->global_index, 0x00020183,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_WARNING,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Failed to open device (a pseudo-drive) for reading",
|
"Failed to open device (a pseudo-drive) for reading",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
ret = 0; goto ex;
|
} else if (errno != ENOENT || !(flag & 2))
|
||||||
}
|
|
||||||
if (lseek(fd, byte_address, SEEK_SET) == -1) {
|
|
||||||
if (!(flag & 2))
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index,
|
d->global_index, 0x00020005,
|
||||||
0x00020147,
|
(flag & 32) && errno == ENOENT ?
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG :
|
||||||
"Cannot address start byte", errno, 0);
|
LIBDAX_MSGS_SEV_SORRY,
|
||||||
ret = 0; goto ex;
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Failed to open device (a pseudo-drive) for reading",
|
||||||
|
errno, 0);
|
||||||
|
ret = 0;
|
||||||
|
if (errno == EACCES && (flag & 8))
|
||||||
|
ret= -2;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
ret = burn_stdio_seek(fd, byte_address, d, flag & (2 | 32));
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_READING_SYNC;
|
d->busy = BURN_DRIVE_READING_SYNC;
|
||||||
d->buffer = &buf;
|
d->buffer = buf;
|
||||||
|
|
||||||
start = byte_address / 2048;
|
start = byte_address / 2048;
|
||||||
upto = start + data_size / 2048;
|
upto = start + data_size / 2048;
|
||||||
|
@ -423,69 +566,213 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
wpt = data;
|
wpt = data;
|
||||||
for (; start < upto; start += chunksize) {
|
for (; start < upto; start += chunksize) {
|
||||||
chunksize = upto - start;
|
chunksize = upto - start;
|
||||||
if (chunksize > 16) {
|
if (chunksize > (BUFFER_SIZE / 2048)) {
|
||||||
chunksize = 16;
|
chunksize = (BUFFER_SIZE / 2048);
|
||||||
cpy_size = 16 * 2048;
|
cpy_size = BUFFER_SIZE;
|
||||||
} else
|
} else
|
||||||
cpy_size = data_size - *data_count;
|
cpy_size = data_size - *data_count;
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
d->silent_on_scsi_error = 1;
|
d->silent_on_scsi_error = 1;
|
||||||
|
else if (flag & 32)
|
||||||
|
d->silent_on_scsi_error = 3;
|
||||||
|
if (flag & 16) {
|
||||||
|
d->had_particular_error &= ~1;
|
||||||
|
if (!d->silent_on_scsi_error)
|
||||||
|
d->silent_on_scsi_error = 2;
|
||||||
|
}
|
||||||
if (d->drive_role == 1) {
|
if (d->drive_role == 1) {
|
||||||
err = d->read_10(d, start, chunksize, d->buffer);
|
err = d->read_10(d, start, chunksize, d->buffer);
|
||||||
} else {
|
} else {
|
||||||
ret = burn_stdio_read(fd, (char *) d->buffer->data,
|
ret = burn_stdio_read(fd, (char *) d->buffer->data,
|
||||||
cpy_size, d, !!(flag & 2));
|
cpy_size, d,
|
||||||
|
(flag & 32) | !!(flag & 2));
|
||||||
err = 0;
|
err = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
err = BE_CANCELLED;
|
err = BE_CANCELLED;
|
||||||
}
|
}
|
||||||
if (flag & 2)
|
if (flag & (2 | 16 | 32))
|
||||||
d->silent_on_scsi_error = sose_mem;
|
d->silent_on_scsi_error = sose_mem;
|
||||||
if (err == BE_CANCELLED) {
|
if (err == BE_CANCELLED) {
|
||||||
/* Try to read a smaller part of the chunk */
|
if ((flag & 16) && (d->had_particular_error & 1))
|
||||||
if(!(flag & 4))
|
{ret = -3; goto ex;}
|
||||||
for (i = 0; i < chunksize - 1; i++) {
|
/* Retry: with CD read by single blocks
|
||||||
if (flag & 2)
|
with other media: retry in full chunks
|
||||||
d->silent_on_scsi_error = 1;
|
*/
|
||||||
if (d->drive_role == 1) {
|
if(flag & 4)
|
||||||
err = d->read_10(d, start + i, 1,
|
goto bad_read;
|
||||||
d->buffer);
|
if (d->drive_role == 1) {
|
||||||
} else {
|
ret = retry_mmc_read(d, chunksize, sose_mem,
|
||||||
ret = burn_stdio_read(fd,
|
start, &wpt, data_count, flag);
|
||||||
(char *) d->buffer->data,
|
} else {
|
||||||
2048, d, 1);
|
ret = retry_stdio_read(d, fd, chunksize,
|
||||||
if (ret <= 0)
|
start, &wpt, data_count, flag);
|
||||||
err = BE_CANCELLED;
|
|
||||||
}
|
|
||||||
if (flag & 2)
|
|
||||||
d->silent_on_scsi_error = sose_mem;
|
|
||||||
if (err == BE_CANCELLED)
|
|
||||||
break;
|
|
||||||
memcpy(wpt, d->buffer->data, 2048);
|
|
||||||
wpt += 2048;
|
|
||||||
*data_count += 2048;
|
|
||||||
}
|
}
|
||||||
if (!(flag & 2))
|
if (ret <= 0)
|
||||||
libdax_msgs_submit(libdax_messenger,
|
goto bad_read;
|
||||||
d->global_index,
|
} else {
|
||||||
0x00020000,
|
memcpy(wpt, d->buffer->data, cpy_size);
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
wpt += cpy_size;
|
||||||
"burn_read_data() returns 0",
|
*data_count += cpy_size;
|
||||||
0, 0);
|
|
||||||
ret = 0; goto ex;
|
|
||||||
}
|
}
|
||||||
memcpy(wpt, d->buffer->data, cpy_size);
|
|
||||||
wpt += cpy_size;
|
|
||||||
*data_count += cpy_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
/* <<< let it open until drive is given up or writing shall happen
|
BURN_FREE_MEM(buf);
|
||||||
if (fd != -1)
|
d->buffer = buffer_mem;
|
||||||
close(fd);
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
*/
|
return ret;
|
||||||
|
|
||||||
|
bad_read:;
|
||||||
|
if (!(flag & 2))
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020000,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"burn_read_data() returns 0", 0, 0);
|
||||||
|
ret = 0; goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B21119 : API function*/
|
||||||
|
int burn_read_audio(struct burn_drive *d, int sector_no,
|
||||||
|
char data[], off_t data_size, off_t *data_count, int flag)
|
||||||
|
{
|
||||||
|
int alignment = 2352, start, upto, chunksize = 1, err, cpy_size, i;
|
||||||
|
int sose_mem = 0, ret;
|
||||||
|
char msg[81], *wpt;
|
||||||
|
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||||
|
*data_count = 0;
|
||||||
|
sose_mem = d->silent_on_scsi_error;
|
||||||
|
|
||||||
|
if (d->released) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x00020142,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is not grabbed on random access read", 0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if (d->drive_role != 1) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020146,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is a virtual placeholder (stdio-drive or null-drive)",
|
||||||
|
0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if ((data_size % alignment) != 0) {
|
||||||
|
sprintf(msg,
|
||||||
|
"Audio read size not properly aligned (%d bytes)",
|
||||||
|
alignment);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x0002019d,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if (d->busy != BURN_DRIVE_IDLE) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x00020145,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is busy on attempt to read audio", 0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->busy = BURN_DRIVE_READING_SYNC;
|
||||||
|
d->buffer = buf;
|
||||||
|
|
||||||
|
start = sector_no;
|
||||||
|
upto = start + data_size / alignment;
|
||||||
|
wpt = data;
|
||||||
|
for (; start < upto; start += chunksize) {
|
||||||
|
chunksize = upto - start;
|
||||||
|
if (chunksize > (BUFFER_SIZE / alignment))
|
||||||
|
chunksize = (BUFFER_SIZE / alignment);
|
||||||
|
cpy_size = chunksize * alignment;
|
||||||
|
if (flag & 2)
|
||||||
|
d->silent_on_scsi_error = 1;
|
||||||
|
else if (flag & 32)
|
||||||
|
d->silent_on_scsi_error = 3;
|
||||||
|
if (flag & 16) {
|
||||||
|
d->had_particular_error &= ~1;
|
||||||
|
if (!d->silent_on_scsi_error)
|
||||||
|
d->silent_on_scsi_error = 2;
|
||||||
|
}
|
||||||
|
err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer,
|
||||||
|
(flag & 8) >> 3);
|
||||||
|
if (flag & (2 | 16 | 32))
|
||||||
|
d->silent_on_scsi_error = sose_mem;
|
||||||
|
if (err == BE_CANCELLED) {
|
||||||
|
if ((flag & 16) && (d->had_particular_error & 1))
|
||||||
|
{ret = -3; goto ex;}
|
||||||
|
if(!(flag & 4))
|
||||||
|
for (i = 0; i < chunksize - 1; i++) {
|
||||||
|
if (flag & 2)
|
||||||
|
d->silent_on_scsi_error = 1;
|
||||||
|
else if (flag & 32)
|
||||||
|
d->silent_on_scsi_error = 3;
|
||||||
|
err = d->read_cd(d, start + i, 1, 1, 0x10,
|
||||||
|
NULL, d->buffer, (flag & 8) >> 3);
|
||||||
|
if (flag & (2 | 32))
|
||||||
|
d->silent_on_scsi_error = sose_mem;
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
|
break;
|
||||||
|
memcpy(wpt, d->buffer->data, alignment);
|
||||||
|
wpt += alignment;
|
||||||
|
*data_count += alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0; goto ex;
|
||||||
|
}
|
||||||
|
memcpy(wpt, d->buffer->data, cpy_size);
|
||||||
|
wpt += cpy_size;
|
||||||
|
*data_count += cpy_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:
|
||||||
|
BURN_FREE_MEM(buf);
|
||||||
d->buffer = buffer_mem;
|
d->buffer = buffer_mem;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_develop_quality_scaN
|
||||||
|
|
||||||
|
/* B21108 ts */
|
||||||
|
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
||||||
|
int start_lba, int rate_period, int flag)
|
||||||
|
{
|
||||||
|
int ret, lba = 0, error_rate1 = 0, error_rate2 = 0, enabled = 0, dret;
|
||||||
|
|
||||||
|
/* Sub Operation Code 1 : Enable Error Rate reporting function */
|
||||||
|
ret = mmc_nec_optiarc_f3(d, 1, start_lba, rate_period,
|
||||||
|
&lba, &error_rate1, &error_rate2);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
enabled = 1;
|
||||||
|
|
||||||
|
/* >>> Sub Operation Code 2 : Seek to starting address
|
||||||
|
start_lba , rate_period
|
||||||
|
*/;
|
||||||
|
|
||||||
|
/* >>> Loop with Sub Operation Code 3 : Send Error Rate information
|
||||||
|
reply: 4-byte LBA , 2-byte C1/PIE , 2-byte C2/PIF
|
||||||
|
*/;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (enabled) {
|
||||||
|
/* Code F : Disable Error Rate reporting function */
|
||||||
|
dret = mmc_nec_optiarc_f3(d, 0xf, 0, 0,
|
||||||
|
&lba, &error_rate1, &error_rate2);
|
||||||
|
if (dret < ret)
|
||||||
|
ret = dret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_develop_quality_scaN */
|
||||||
|
|
||||||
|
|
143
libburn/sbc.c
143
libburn/sbc.c
|
@ -2,6 +2,15 @@
|
||||||
|
|
||||||
/* scsi block commands */
|
/* scsi block commands */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -17,7 +26,27 @@
|
||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
|
||||||
/* spc command set */
|
/* START STOP UNIT as of SBC-1 and SBC-2
|
||||||
|
0: Opcode 0x1B
|
||||||
|
1: bit0= Immed
|
||||||
|
bit1-7= reserved
|
||||||
|
2: reserved
|
||||||
|
3: reserved
|
||||||
|
4: bit0= Start (else Stop unit)
|
||||||
|
bit1= Load/Eject (according to Start resp. Stop)
|
||||||
|
bit2-3= reserved
|
||||||
|
bit4-7= Power Condition
|
||||||
|
0= Start Valid: process Start and Load/Eject bits
|
||||||
|
1= assume Active state
|
||||||
|
2= assume Idle state
|
||||||
|
3= assume Stanby state
|
||||||
|
(5= SBC-1 only: assume Sleep state)
|
||||||
|
7= transfer control of power conditions to logical unit
|
||||||
|
10= force idle condition timer to 0
|
||||||
|
11= force standby condition timer to 0
|
||||||
|
All others are reserved.
|
||||||
|
5: Control (set to 0)
|
||||||
|
*/
|
||||||
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
||||||
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
||||||
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
||||||
|
@ -25,25 +54,22 @@ static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
void sbc_load(struct burn_drive *d)
|
void sbc_load(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command *c;
|
||||||
|
|
||||||
|
c = &(d->casual_command);
|
||||||
if (mmc_function_spy(d, "load") <= 0)
|
if (mmc_function_spy(d, "load") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
|
scsi_init_command(c, SBC_LOAD, sizeof(SBC_LOAD));
|
||||||
/*
|
c->retry = 1;
|
||||||
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
|
|
||||||
c.oplen = sizeof(SBC_LOAD);
|
|
||||||
c.page = NULL;
|
|
||||||
*/
|
|
||||||
c.retry = 1;
|
|
||||||
|
|
||||||
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
|
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
|
||||||
/* c.opcode[1] |= 1; / * ts A70918 : Immed */
|
/* c->opcode[1] |= 1; / * ts A70918 : Immed */
|
||||||
|
|
||||||
c.dir = NO_TRANSFER;
|
c->dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
c->timeout = Libburn_mmc_load_timeouT;
|
||||||
if (c.error)
|
d->issue_command(d, c);
|
||||||
|
if (c->error)
|
||||||
return;
|
return;
|
||||||
/* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now
|
/* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now
|
||||||
5 minutes for loading. If this does not suffice then other commands
|
5 minutes for loading. If this does not suffice then other commands
|
||||||
|
@ -53,66 +79,91 @@ void sbc_load(struct burn_drive *d)
|
||||||
|
|
||||||
void sbc_eject(struct burn_drive *d)
|
void sbc_eject(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command *c;
|
||||||
|
|
||||||
|
c = &(d->casual_command);
|
||||||
if (mmc_function_spy(d, "eject") <= 0)
|
if (mmc_function_spy(d, "eject") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
scsi_init_command(c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||||
/*
|
/* c->opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
|
||||||
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
c->page = NULL;
|
||||||
c.oplen = sizeof(SBC_UNLOAD);
|
c->dir = NO_TRANSFER;
|
||||||
c.page = NULL;
|
d->issue_command(d, c);
|
||||||
*/
|
/* ts A70918 : Wait long. A late eject could surprise or hurt user.
|
||||||
|
ts B00109 : Asynchronous eject revoked, as one cannot reliably
|
||||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
distinguish out from unready.
|
||||||
|
if (c->error)
|
||||||
c.page = NULL;
|
|
||||||
c.dir = NO_TRANSFER;
|
|
||||||
d->issue_command(d, &c);
|
|
||||||
if (c.error)
|
|
||||||
return;
|
return;
|
||||||
/* ts A70918 : Wait long. A late eject could surprise or hurt user. */
|
|
||||||
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
|
|
||||||
int sbc_start_unit(struct burn_drive *d)
|
/* ts A91112 : Now with flag */
|
||||||
|
/* @param flag bit0= asynchronous waiting
|
||||||
|
*/
|
||||||
|
int sbc_start_unit_flag(struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command *c;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
c = &(d->casual_command);
|
||||||
if (mmc_function_spy(d, "start_unit") <= 0)
|
if (mmc_function_spy(d, "start_unit") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||||
c.retry = 1;
|
c->retry = 1;
|
||||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
if (d->do_no_immed && (flag & 1))
|
||||||
c.dir = NO_TRANSFER;
|
c->timeout = 1800 * 1000;
|
||||||
d->issue_command(d, &c);
|
else
|
||||||
if (c.error)
|
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
|
||||||
|
c->dir = NO_TRANSFER;
|
||||||
|
d->issue_command(d, c);
|
||||||
|
if (c->error)
|
||||||
return 0;
|
return 0;
|
||||||
/* ts A70918 : now asynchronous */
|
if (d->do_no_immed || !(flag & 1))
|
||||||
d->is_stopped = 0;
|
return 1;
|
||||||
|
/* ts A70918 : asynchronous */
|
||||||
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sbc_start_unit(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
d->is_stopped = 0; /* no endless starting attempts */
|
||||||
|
|
||||||
|
/* Asynchronous, not to block controller by waiting */
|
||||||
|
ret = sbc_start_unit_flag(d, 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
/* Synchronous to catch Pioneer DVR-216D which is ready too early.
|
||||||
|
A pending START UNIT can prevent ejecting of the tray.
|
||||||
|
*/
|
||||||
|
ret = sbc_start_unit_flag(d, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A90824 : Trying to reduce drive noise */
|
/* ts A90824 : Trying to reduce drive noise */
|
||||||
int sbc_stop_unit(struct burn_drive *d)
|
int sbc_stop_unit(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command *c;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
c = &(d->casual_command);
|
||||||
if (mmc_function_spy(d, "stop_unit") <= 0)
|
if (mmc_function_spy(d, "stop_unit") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
|
scsi_init_command(c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
|
||||||
c.retry = 1;
|
c->retry = 0;
|
||||||
c.opcode[1] |= 1; /* Immed */
|
c->opcode[1] |= 1; /* Immed */
|
||||||
c.dir = NO_TRANSFER;
|
c->dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, c);
|
||||||
if (c.error)
|
if (c->error)
|
||||||
return 0;
|
return 0;
|
||||||
ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
|
ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
|
||||||
d->is_stopped = 1;
|
d->is_stopped = 1;
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SBC
|
#ifndef __SBC
|
||||||
#define __SBC
|
#define __SBC
|
||||||
|
|
||||||
|
|
239
libburn/sector.c
239
libburn/sector.c
|
@ -1,5 +1,14 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2021 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
|
@ -15,18 +24,26 @@
|
||||||
#include "sector.h"
|
#include "sector.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "lec.h"
|
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "write.h"
|
#include "write.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
#include "ecma130ab.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
|
/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
|
||||||
|
|
||||||
|
@ -92,11 +109,12 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||||
int valid, shortage, curr, i, tr;
|
int valid, shortage, curr, i, tr;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
static int tee_fd= -1;
|
static int tee_fd= -1;
|
||||||
if(tee_fd==-1)
|
if(tee_fd==-1)
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
||||||
|
S_IRUSR | S_IWUSR);
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +156,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||||
track->sourcecount += valid;
|
track->sourcecount += valid;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* <<< ts A61031 */
|
/* ts A61031 */
|
||||||
if(tee_fd!=-1 && valid>0) {
|
if(tee_fd!=-1 && valid>0) {
|
||||||
write(tee_fd, data + curr, valid);
|
write(tee_fd, data + curr, valid);
|
||||||
}
|
}
|
||||||
|
@ -166,10 +184,29 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||||
if (!shortage)
|
if (!shortage)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
/* ts A61031 */
|
/* ts A61031 - B10103 */
|
||||||
if (shortage >= count)
|
if (shortage >= count)
|
||||||
track->track_data_done = 1;
|
track->track_data_done = 1;
|
||||||
if (track->open_ended)
|
if (track->end_on_premature_eoi && shortage >= count &&
|
||||||
|
!track->open_ended) {
|
||||||
|
char msg[80];
|
||||||
|
off_t missing, inp_block_size, track_blocks;
|
||||||
|
|
||||||
|
inp_block_size = burn_sector_length(track->mode);
|
||||||
|
track_blocks = burn_track_get_sectors_2_v2(track, 1);
|
||||||
|
if (track_blocks < 0)
|
||||||
|
track_blocks = 0;
|
||||||
|
missing = track_blocks * inp_block_size - track->sourcecount;
|
||||||
|
sprintf(msg,
|
||||||
|
"Premature end of input encountered. Missing: %.f bytes",
|
||||||
|
(double) missing);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0,0);
|
||||||
|
/* Memorize that premature end of input happened */
|
||||||
|
track->end_on_premature_eoi = 2;
|
||||||
|
}
|
||||||
|
if (track->open_ended || track->end_on_premature_eoi)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
/* If we're still short, and there's a "next" pointer, we pull from that.
|
/* If we're still short, and there's a "next" pointer, we pull from that.
|
||||||
|
@ -198,6 +235,43 @@ ex:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B20113 : outsourced from get_sector() */
|
||||||
|
int sector_write_buffer(struct burn_drive *d,
|
||||||
|
struct burn_track *track, int flag)
|
||||||
|
{
|
||||||
|
int err, i;
|
||||||
|
struct buffer *out;
|
||||||
|
|
||||||
|
out = d->buffer;
|
||||||
|
if (out->sectors <= 0)
|
||||||
|
return 2;
|
||||||
|
err = d->write(d, d->nwa, out);
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* ts A61101 */
|
||||||
|
if(track != NULL) {
|
||||||
|
track->writecount += out->bytes;
|
||||||
|
track->written_sectors += out->sectors;
|
||||||
|
|
||||||
|
/* Determine current index */
|
||||||
|
for (i = d->progress.index; i + 1 < track->indices; i++) {
|
||||||
|
if (track->index[i + 1] > d->nwa + out->sectors)
|
||||||
|
break;
|
||||||
|
d->progress.index = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ts A61119 */
|
||||||
|
d->progress.buffered_bytes += out->bytes;
|
||||||
|
|
||||||
|
d->nwa += out->sectors;
|
||||||
|
out->bytes = 0;
|
||||||
|
out->sectors = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
|
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
|
||||||
and to count hand outs as well as reserved bytes */
|
and to count hand outs as well as reserved bytes */
|
||||||
/* ts A61101 : added parameter track for counting written bytes */
|
/* ts A61101 : added parameter track for counting written bytes */
|
||||||
|
@ -206,8 +280,7 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||||
{
|
{
|
||||||
struct burn_drive *d = opts->drive;
|
struct burn_drive *d = opts->drive;
|
||||||
struct buffer *out = d->buffer;
|
struct buffer *out = d->buffer;
|
||||||
int outmode;
|
int outmode, seclen, write_ret;
|
||||||
int seclen;
|
|
||||||
unsigned char *ret;
|
unsigned char *ret;
|
||||||
|
|
||||||
outmode = get_outmode(opts);
|
outmode = get_outmode(opts);
|
||||||
|
@ -223,26 +296,13 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||||
seclen += burn_subcode_length(outmode);
|
seclen += burn_subcode_length(outmode);
|
||||||
|
|
||||||
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
||||||
|
/* (there is enough buffer size reserve for track->cdxa_conversion) */
|
||||||
if (out->bytes + seclen > BUFFER_SIZE ||
|
if (out->bytes + seclen > BUFFER_SIZE ||
|
||||||
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
||||||
int err;
|
write_ret = sector_write_buffer(d, track, 0);
|
||||||
err = d->write(d, d->nwa, out);
|
if (write_ret <= 0)
|
||||||
if (err == BE_CANCELLED)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* ts A61101 */
|
|
||||||
if(track != NULL) {
|
|
||||||
track->writecount += out->bytes;
|
|
||||||
track->written_sectors += out->sectors;
|
|
||||||
}
|
|
||||||
/* ts A61119 */
|
|
||||||
d->progress.buffered_bytes += out->bytes;
|
|
||||||
|
|
||||||
d->nwa += out->sectors;
|
|
||||||
out->bytes = 0;
|
|
||||||
out->sectors = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = out->data + out->bytes;
|
ret = out->data + out->bytes;
|
||||||
out->bytes += seclen;
|
out->bytes += seclen;
|
||||||
out->sectors++;
|
out->sectors++;
|
||||||
|
@ -295,11 +355,21 @@ static int convert_data(struct burn_write_opts *o, struct burn_track *track,
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
/* a ssert(outlen >= inlen); */
|
/* a ssert(outlen >= inlen); */
|
||||||
if (outlen < inlen)
|
if (outlen < inlen || outlen < 0 || inlen < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
||||||
|
/* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
|
||||||
|
Table 24 Mode 2 Formed Sector Sub-header Format */
|
||||||
|
if (track != NULL)
|
||||||
|
if (track->cdxa_conversion == 1)
|
||||||
|
inlen += 8;
|
||||||
|
|
||||||
get_bytes(track, inlen, data);
|
get_bytes(track, inlen, data);
|
||||||
|
|
||||||
|
if (track != NULL)
|
||||||
|
if (track->cdxa_conversion == 1)
|
||||||
|
memmove(data, data + 8, inlen - 8);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +462,13 @@ a2 - lout ctrl
|
||||||
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
||||||
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
||||||
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
d->toc_temp++;
|
d->toc_temp++;
|
||||||
|
@ -413,7 +489,8 @@ int sector_toc(struct burn_write_opts *o, int mode)
|
||||||
return 0;
|
return 0;
|
||||||
subcode_toc(d, mode, subs);
|
subcode_toc(d, mode, subs);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
sector_headers(o, data, mode, 1);
|
if (sector_headers(o, data, mode, 1) <= 0)
|
||||||
|
return 0;
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -433,7 +510,8 @@ int sector_pregap(struct burn_write_opts *o,
|
||||||
return 0;
|
return 0;
|
||||||
subcode_user(o, subs, tno, control, 0, NULL, 1);
|
subcode_user(o, subs, tno, control, 0, NULL, 1);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
sector_headers(o, data, mode, 0);
|
if (sector_headers(o, data, mode, 0) <= 0)
|
||||||
|
return 0;
|
||||||
sector_common(--)
|
sector_common(--)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -450,11 +528,12 @@ int sector_postgap(struct burn_write_opts *o,
|
||||||
return 0;
|
return 0;
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
if (convert_data(o, NULL, mode, data) <= 0)
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
return 0;;
|
return 0;
|
||||||
/* use last index in track */
|
/* use last index in track */
|
||||||
subcode_user(o, subs, tno, control, 1, NULL, 1);
|
subcode_user(o, subs, tno, control, 1, NULL, 1);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
sector_headers(o, data, mode, 0);
|
if (sector_headers(o, data, mode, 0) <= 0)
|
||||||
|
return 0;
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -486,7 +565,13 @@ static void subcode_lout(struct burn_write_opts *o, unsigned char control,
|
||||||
q[7] = dec_to_bcd(min);
|
q[7] = dec_to_bcd(min);
|
||||||
q[8] = dec_to_bcd(sec);
|
q[8] = dec_to_bcd(sec);
|
||||||
q[9] = dec_to_bcd(frame);
|
q[9] = dec_to_bcd(frame);
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +691,13 @@ void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
|
||||||
}
|
}
|
||||||
q[0] = (control << 4) + qmode;
|
q[0] = (control << 4) + qmode;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xff;
|
q[11] = crc & 0xff;
|
||||||
}
|
}
|
||||||
|
@ -625,7 +716,8 @@ int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
|
||||||
return 0;
|
return 0;
|
||||||
subcode_lout(o, control, subs);
|
subcode_lout(o, control, subs);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
sector_headers(o, data, mode, 0);
|
if (sector_headers(o, data, mode, 0) <= 0)
|
||||||
|
return 0;
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -637,14 +729,14 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = get_sector(o, t, t->mode);
|
data = get_sector(o, t, t->mode);
|
||||||
if (!data)
|
if (data == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
if (convert_data(o, t, t->mode, data) <= 0)
|
if (convert_data(o, t, t->mode, data) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* ts A61031 */
|
/* ts A61031 */
|
||||||
if (t->open_ended && t->track_data_done) {
|
if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
|
||||||
unget_sector(o, t->mode);
|
unget_sector(o, t->mode);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +752,8 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
||||||
t->entry->control, 1, &t->isrc, psub);
|
t->entry->control, 1, &t->isrc, psub);
|
||||||
convert_subs(o, t->mode, subs, data);
|
convert_subs(o, t->mode, subs, data);
|
||||||
|
|
||||||
sector_headers(o, data, t->mode, 0);
|
if (sector_headers(o, data, t->mode, 0) <= 0)
|
||||||
|
return 0;
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -711,42 +804,27 @@ int sector_headers_is_ok(struct burn_write_opts *o, int mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sector_headers(struct burn_write_opts *o, unsigned char *out,
|
/* ts A90830 : changed return type to int
|
||||||
|
@return 0= failure
|
||||||
|
1= success
|
||||||
|
*/
|
||||||
|
int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||||
int mode, int leadin)
|
int mode, int leadin)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef Libburn_ecma130ab_includeD
|
||||||
|
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
int min, sec, frame;
|
int min, sec, frame;
|
||||||
int modebyte = -1;
|
int modebyte = -1;
|
||||||
|
|
||||||
/* ts A61009 */
|
|
||||||
#if 1
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sector_headers_is_ok(o, mode);
|
ret = sector_headers_is_ok(o, mode);
|
||||||
if (ret != 2)
|
if (ret != 2)
|
||||||
return;
|
return !!ret;
|
||||||
modebyte = 1;
|
modebyte = 1;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (mode & BURN_AUDIO) /* no headers for "audio" */
|
|
||||||
return;
|
|
||||||
if (o->write_type == BURN_WRITE_SAO)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* ts A61031 */
|
|
||||||
if (o->write_type == BURN_WRITE_TAO)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mode & BURN_MODE1)
|
|
||||||
modebyte = 1;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ts A61009 : now ensured by burn_disc_write_is_ok() */
|
|
||||||
/* a ssert(modebyte == 1); */
|
|
||||||
|
|
||||||
out[0] = 0;
|
out[0] = 0;
|
||||||
memset(out + 1, 0xFF, 10); /* sync */
|
memset(out + 1, 0xFF, 10); /* sync */
|
||||||
out[11] = 0;
|
out[11] = 0;
|
||||||
|
@ -765,7 +843,13 @@ void sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||||
out[15] = modebyte;
|
out[15] = modebyte;
|
||||||
}
|
}
|
||||||
if (mode & BURN_MODE1) {
|
if (mode & BURN_MODE1) {
|
||||||
|
|
||||||
|
#ifdef Libburn_no_crc_C
|
||||||
|
crc = 0; /* dummy */
|
||||||
|
#else
|
||||||
crc = crc_32(out, 2064);
|
crc = crc_32(out, 2064);
|
||||||
|
#endif
|
||||||
|
|
||||||
out[2064] = crc & 0xFF;
|
out[2064] = crc & 0xFF;
|
||||||
crc >>= 8;
|
crc >>= 8;
|
||||||
out[2065] = crc & 0xFF;
|
out[2065] = crc & 0xFF;
|
||||||
|
@ -776,10 +860,33 @@ void sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||||
}
|
}
|
||||||
if (mode & BURN_MODE1) {
|
if (mode & BURN_MODE1) {
|
||||||
memset(out + 2068, 0, 8);
|
memset(out + 2068, 0, 8);
|
||||||
parity_p(out);
|
burn_rspc_parity_p(out);
|
||||||
parity_q(out);
|
burn_rspc_parity_q(out);
|
||||||
}
|
}
|
||||||
scramble(out);
|
burn_ecma130_scramble(out);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#else /* Libburn_ecma130ab_includeD */
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sector_headers_is_ok(o, mode);
|
||||||
|
if (ret != 2)
|
||||||
|
return (!! ret);
|
||||||
|
|
||||||
|
/* ts A90830 : lec.c is copied from cdrdao.
|
||||||
|
I have no idea yet how lec.c implements the Reed-Solomon encoding
|
||||||
|
which is described in ECMA-130 for CD-ROM.
|
||||||
|
So this got removed for now.
|
||||||
|
*/
|
||||||
|
libdax_msgs_submit(libdax_messenger, o->drive->global_index,
|
||||||
|
0x0002010a,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Raw CD write modes are not supported", 0, 0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_ecma130ab_includeD */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -807,7 +914,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* XXX dont ignore these */
|
/* XXX do not ignore these */
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
||||||
|
@ -818,7 +925,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/* ts A61009 : if reactivated then witout Assert */
|
/* ts A61009 : if reactivated then without Assert */
|
||||||
a ssert(0);
|
a ssert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -826,7 +933,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
|
|
||||||
/* this needs more info. subs in the data? control/adr? */
|
/* this needs more info. subs in the data? control/adr? */
|
||||||
|
|
||||||
/* ts A61119 : One should not use inofficial compiler extensions.
|
/* ts A61119 : One should not use unofficial compiler extensions.
|
||||||
>>> Some day this function needs to be implemented. At least for now
|
>>> Some day this function needs to be implemented. At least for now
|
||||||
the result does not match the "mode" of cdrecord -toc.
|
the result does not match the "mode" of cdrecord -toc.
|
||||||
*/
|
*/
|
||||||
|
@ -835,12 +942,14 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
*/
|
*/
|
||||||
int sector_identify(unsigned char *data)
|
int sector_identify(unsigned char *data)
|
||||||
{
|
{
|
||||||
scramble(data);
|
|
||||||
/*
|
/*
|
||||||
|
burn_ecma130_scramble(data);
|
||||||
check mode byte for 1 or 2
|
check mode byte for 1 or 2
|
||||||
test parity to see if it's a valid sector
|
test parity to see if it's a valid sector
|
||||||
if invalid, return BURN_MODE_AUDIO;
|
if invalid, return BURN_MODE_AUDIO;
|
||||||
else return mode byte (what about mode 2 formless? heh)
|
else return mode byte (what about mode 2 formless? heh)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return BURN_MODE1;
|
return BURN_MODE1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SECTOR
|
#ifndef __SECTOR
|
||||||
#define __SECTOR
|
#define __SECTOR
|
||||||
|
|
||||||
|
@ -19,10 +24,14 @@ int sector_postgap(struct burn_write_opts *, unsigned char tno,
|
||||||
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
|
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
|
||||||
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
|
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
|
||||||
|
|
||||||
|
/* ts B20113 */
|
||||||
|
int sector_write_buffer(struct burn_drive *d,
|
||||||
|
struct burn_track *track, int flag);
|
||||||
|
|
||||||
/* ts A61009 */
|
/* ts A61009 */
|
||||||
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
||||||
|
|
||||||
void sector_headers(struct burn_write_opts *, unsigned char *,
|
int sector_headers(struct burn_write_opts *, unsigned char *,
|
||||||
int mode, int leadin);
|
int mode, int leadin);
|
||||||
void subcode_user(struct burn_write_opts *, unsigned char *s,
|
void subcode_user(struct burn_write_opts *, unsigned char *s,
|
||||||
unsigned char tno, unsigned char control,
|
unsigned char tno, unsigned char control,
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
|
@ -7,8 +17,8 @@ the transport level aspects of SCSI control and command i/o.
|
||||||
|
|
||||||
Present implementation: default dummy which enables libburn only to work
|
Present implementation: default dummy which enables libburn only to work
|
||||||
with stdio: pseudo drive addresses.
|
with stdio: pseudo drive addresses.
|
||||||
For real implementations see sg-linux.c or sg-freebsd.c
|
For real implementations see sg-linux.c, sg-freebsd.c,
|
||||||
|
sg-libcdio.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,11 +29,17 @@ Present implementation: default dummy which enables libburn only to work
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
#ifdef Libburn_os_has_statvfS
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif /* Libburn_os_has_stavtfS */
|
#endif /* Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
|
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
|
@ -33,11 +49,65 @@ Present implementation: default dummy which enables libburn only to work
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal X/Open adapter sg-dummy");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally acquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
allowed to return addresses of drives which are not available but under
|
allowed to return addresses of drives which are not available but under
|
||||||
|
@ -74,9 +144,9 @@ int scsi_enumerate_drives(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether libburn has the given drive in use or exclusively reserved.
|
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
||||||
If it is "open" then libburn will eventually call sg_release() on it when
|
If it is "open" then libburn will eventually call sg_release() on it when
|
||||||
it is time to give up usage resp. reservation.
|
it is time to give up usage and reservation.
|
||||||
*/
|
*/
|
||||||
/** Published as burn_drive.drive_is_open() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
@ -110,7 +180,7 @@ int sg_release(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -143,7 +213,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
int sg_is_enumerable_adr(char *adr)
|
int sg_is_enumerable_adr(char *adr)
|
||||||
|
@ -152,6 +222,23 @@ int sg_is_enumerable_adr(char *adr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
fseeked, read, and possibly written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (S_ISBLK(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
exist yet, then the directory will be inquired.
|
exist yet, then the directory will be inquired.
|
||||||
|
@ -162,7 +249,7 @@ int sg_is_enumerable_adr(char *adr)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
1 = estimation has been made, bytes was set
|
||||||
*/
|
*/
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes)
|
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
{
|
{
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
|
@ -170,12 +257,13 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char testpath[4096], *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
|
@ -186,44 +274,86 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||||
else
|
else
|
||||||
*cpt = 0;
|
*cpt = 0;
|
||||||
if (stat(testpath, &stbuf) == -1)
|
if (stat(testpath, &stbuf) == -1)
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
|
|
||||||
#ifdef Libburn_if_this_was_linuX
|
#ifdef Libburn_if_this_was_linuX
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
fd = open(path, open_mode);
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
|
fd = open(path, open_mode | O_BINARY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
*bytes = ((off_t) blocks) * (off_t) 512;
|
||||||
|
|
||||||
#endif /* Libburn_if_this_was_linuX */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
add_size = burn_sparse_file_addsize(write_start, &stbuf);
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
#ifdef Libburn_os_has_statvfS
|
||||||
|
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
|
|
||||||
#else /* Libburn_os_has_statvfS */
|
#else /* Libburn_os_has_statvfS */
|
||||||
|
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
#endif /* ! Libburn_os_has_stavtfS */
|
#endif /* ! Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(testpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
|
#ifdef Libburn_read_o_direcT
|
||||||
|
|
||||||
|
/* No special O_DIRECT-like precautions are implemented here */
|
||||||
|
|
||||||
|
#endif /* Libburn_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, open_flags | O_BINARY);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
buf = calloc(1, amount);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return 0;
|
||||||
|
free(buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* THIS CODE IS NOT FUNCTIONAL YET !!! */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
|
@ -29,13 +38,29 @@ and of deriving the following system specific files from existing examples:
|
||||||
Said sg-*.c operations are defined by a public function interface, which has
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
to be implemented in a way that provides libburn with the desired services:
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
|
sg_id_string() returns an id string of the SCSI transport adapter.
|
||||||
|
It may be called before initialization but then may
|
||||||
|
return only a preliminary id.
|
||||||
|
|
||||||
|
sg_initialize() performs global initialization of the SCSI transport
|
||||||
|
adapter and eventually needed operating system
|
||||||
|
facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
|
||||||
|
sg_shutdown() performs global finalizations and releases globally
|
||||||
|
acquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
|
||||||
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
|
on destruction. Releases resources which were acquired
|
||||||
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
|
sg_drive_is_open() tells whether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
undisturbed access.
|
undisturbed access.
|
||||||
|
@ -43,19 +68,40 @@ sg_grab() opens the drive for SCSI commands and ensures
|
||||||
sg_release() closes a drive opened by sg_grab()
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
and evaluates wether the command succeeded or shall
|
and evaluates whether the command succeeded or shall
|
||||||
be retried or finally failed.
|
be retried or finally failed.
|
||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
||||||
|
that can be used in 2 kB granularity by lseek(2),
|
||||||
|
read(2), and possibly write(2) if not read-only.
|
||||||
|
E.g. a USB stick or a hard disk.
|
||||||
|
|
||||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
|
burn_os_open_track_src() opens a disk file in a way that offers best
|
||||||
|
throughput with file reading and/or SCSI write command
|
||||||
|
transmission.
|
||||||
|
|
||||||
|
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||||
|
descriptors issued by burn_os_open_track_src().
|
||||||
|
The buffer size may be rounded up for alignment
|
||||||
|
reasons.
|
||||||
|
|
||||||
|
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
||||||
|
|
||||||
|
|
||||||
Porting hints are marked by the text "PORTING:".
|
Porting hints are marked by the text "PORTING:".
|
||||||
Send feedback to libburn-hackers@pykix.org .
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
|
@ -117,7 +163,7 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(&(idx->ccb), sizeof(union ccb));
|
memset(&(idx->ccb), 0, sizeof(union ccb));
|
||||||
|
|
||||||
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
@ -126,9 +172,10 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||||
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
idx->ccb.cdm.matches = (struct dev_match_result *)
|
||||||
|
calloc(1, idx->bufsize);
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("can't malloc memory for matches");
|
warnx("cannot allocate memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +277,61 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd-port");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally acquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
allowed to return addresses of drives which are not available but under
|
allowed to return addresses of drives which are not available but under
|
||||||
|
@ -299,7 +401,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||||
break;
|
break;
|
||||||
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(adr_size <= strlen(buf)
|
if(adr_size <= strlen(buf))
|
||||||
return -1;
|
return -1;
|
||||||
strcpy(adr, buf);
|
strcpy(adr, buf);
|
||||||
|
|
||||||
|
@ -323,7 +425,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||||
int scsi_enumerate_drives(void)
|
int scsi_enumerate_drives(void)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -338,12 +440,13 @@ int scsi_enumerate_drives(void)
|
||||||
idx.result->target_lun);
|
idx.result->target_lun);
|
||||||
}
|
}
|
||||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether libburn has the given drive in use or exclusively reserved.
|
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
||||||
If it is "open" then libburn will eventually call sg_release() on it when
|
If it is "open" then libburn will eventually call sg_release() on it when
|
||||||
it is time to give up usage resp. reservation.
|
it is time to give up usage and reservation.
|
||||||
*/
|
*/
|
||||||
/** Published as burn_drive.drive_is_open() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
@ -360,11 +463,12 @@ int sg_drive_is_open(struct burn_drive * d)
|
||||||
*/
|
*/
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
|
|
||||||
if(d->cam != NULL)
|
if(d->cam != NULL) {
|
||||||
return 0;
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
|
@ -381,7 +485,7 @@ int sg_grab(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** PORTING: Is mainly about the call to sg_close_drive() and wether it
|
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
|
||||||
implements the demanded functionality.
|
implements the demanded functionality.
|
||||||
*/
|
*/
|
||||||
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
||||||
|
@ -389,16 +493,14 @@ int sg_grab(struct burn_drive *d)
|
||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->cam == NULL) {
|
if (d->cam == NULL)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -446,8 +548,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.cdb_len = c->oplen;
|
ccb->csio.cdb_len = c->oplen;
|
||||||
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
||||||
|
|
||||||
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
|
|
||||||
|
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
ccb->csio.data_ptr = c->page->data;
|
ccb->csio.data_ptr = c->page->data;
|
||||||
if (c->dir == FROM_DRIVE) {
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
@ -467,7 +567,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts B90523 : Record effective transfer length request for debugging*/
|
||||||
|
c->dxfer_len = ccb->csio.dxfer_len;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
if (err == -1) {
|
if (err == -1) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
@ -484,6 +588,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
||||||
|
c->sense_len = ccb->csio.sense_len;
|
||||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
if (!c->retry) {
|
if (!c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
|
@ -502,6 +607,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
if (!done)
|
||||||
|
spc_register_retry(c);
|
||||||
} while (!done);
|
} while (!done);
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -515,7 +622,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
int *target_no, int *lun_no)
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
|
@ -524,7 +631,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
initialize = 0;
|
initialize = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
if (strcmp(adr, buf) != 0)
|
if (strcmp(path, buf) != 0)
|
||||||
continue;
|
continue;
|
||||||
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
*bus_no = result->path_id;
|
*bus_no = result->path_id;
|
||||||
|
@ -540,13 +647,13 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
int sg_is_enumerable_adr(char* adr)
|
int sg_is_enumerable_adr(char* adr)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1;
|
int initialize = 1, ret;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -564,6 +671,47 @@ int sg_is_enumerable_adr(char* adr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00115 */
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
seeked, written, and read with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
char *spt;
|
||||||
|
int i, e;
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
|
return 0;
|
||||||
|
spt = strrchr(path, '/');
|
||||||
|
if (spt == NULL)
|
||||||
|
spt = path;
|
||||||
|
else
|
||||||
|
spt++;
|
||||||
|
e = strlen(spt);
|
||||||
|
for (i = strlen(spt) - 1; i > 0; i--)
|
||||||
|
if (spt[i] >= '0' && spt[i] <= '9')
|
||||||
|
e = i;
|
||||||
|
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
|
@ -574,17 +722,16 @@ int sg_is_enumerable_adr(char* adr)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
1 = estimation has been made, bytes was set
|
||||||
*/
|
*/
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes)
|
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
{
|
{
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
char testpath[4096], *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
int open_mode = O_RDWR, fd, ret;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
int fd, ret;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
|
@ -595,37 +742,89 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||||
else
|
else
|
||||||
*cpt = 0;
|
*cpt = 0;
|
||||||
if (stat(testpath, &stbuf) == -1)
|
if (stat(testpath, &stbuf) == -1)
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
|
|
||||||
#ifdef Libburn_if_this_was_linuX
|
#ifdef Libburn_if_this_was_linuX
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
|
int open_mode = O_RDWR, fd, ret;
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
if(burn_sg_open_o_excl)
|
if(burn_sg_open_o_excl)
|
||||||
open_mode |= O_EXCL;
|
open_mode |= O_EXCL;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
*bytes = ((off_t) blocks) * (off_t) 512;
|
||||||
|
|
||||||
#endif /* Libburn_if_this_was_linuX */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
|
|
||||||
|
} else if(S_ISCHR(stbuf.st_mode)) {
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
close(fd);
|
||||||
|
if (ret == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
*bytes = add_size;
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
add_size = burn_sparse_file_addsize(write_start, &stbuf);
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:
|
||||||
|
BURN_FREE_MEM(testpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
|
#ifdef Libburn_read_o_direcT
|
||||||
|
|
||||||
|
/* No special O_DIRECT-like precautions are implemented here */
|
||||||
|
|
||||||
|
#endif /* Libburn_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, open_flags);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
buf = calloc(1, amount);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return 0;
|
||||||
|
free(buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later
|
||||||
|
and under FreeBSD license revised, i.e. without advertising clause.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -7,6 +17,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
@ -16,10 +27,24 @@
|
||||||
|
|
||||||
#include <err.h> /* XXX */
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
/* ts B00121 */
|
||||||
|
#include <sys/disk.h> /* DIOCGMEDIASIZE */
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00326 : For use of CAM_PASS_ERR_RECOVER with ahci */
|
||||||
|
#define Libburn_for_freebsd_ahcI yes
|
||||||
|
|
||||||
|
/* ts B00327 : for debugging of cam_send_cdb() failures
|
||||||
|
# define Libburn_ahci_verbouS yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ts B00327 : Apply CAM_PASS_ERR_RECOVER to drives even if not ahci
|
||||||
|
# define libburn_ahci_style_for_alL yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
|
@ -30,6 +55,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -54,6 +80,79 @@ int burn_drive_is_banned(char *device_address);
|
||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00113
|
||||||
|
Whether to log SCSI commands:
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
extern int burn_sg_log_scsi;
|
||||||
|
|
||||||
|
/* ts B00114 */
|
||||||
|
/* Storage object is in libburn/init.c
|
||||||
|
whether to strive for exclusive access to the drive
|
||||||
|
*/
|
||||||
|
extern int burn_sg_open_o_excl;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally acquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
||||||
sg_give_next_adr() */
|
sg_give_next_adr() */
|
||||||
/* Some helper functions for scsi_give_next_adr() */
|
/* Some helper functions for scsi_give_next_adr() */
|
||||||
|
@ -63,19 +162,21 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
||||||
struct burn_drive_enumeration_state *idx;
|
struct burn_drive_enumeration_state *idx;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
|
|
||||||
idx = malloc(sizeof(*idx));
|
idx = calloc(1, sizeof(*idx));
|
||||||
if (idx == NULL) {
|
if (idx == NULL) {
|
||||||
warnx("can't malloc memory for enumerator");
|
warnx("cannot allocate memory for enumerator");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
idx->skip_device = 0;
|
idx->skip_device = 0;
|
||||||
|
|
||||||
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
warn("couldn't open %s", XPT_DEVICE);
|
warn("could not open %s", XPT_DEVICE);
|
||||||
|
free(idx);
|
||||||
|
idx = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(&(idx->ccb), sizeof(union ccb));
|
memset(&(idx->ccb), 0, sizeof(union ccb));
|
||||||
|
|
||||||
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
@ -84,9 +185,9 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
||||||
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
bufsize = sizeof(struct dev_match_result) * 100;
|
bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
idx->ccb.cdm.match_buf_len = bufsize;
|
idx->ccb.cdm.match_buf_len = bufsize;
|
||||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
idx->ccb.cdm.matches = (struct dev_match_result *) calloc(1, bufsize);
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("can't malloc memory for matches");
|
warnx("cannot allocate memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
free(idx);
|
free(idx);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -143,7 +244,7 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index object state and the next enumerated drive address.
|
||||||
@param idx An opaque handle. Make no own theories about it.
|
@param idx An opaque handle. Make no own theories about it.
|
||||||
@param adr Takes the reply
|
@param adr Takes the reply
|
||||||
@param adr_size Gives maximum size of reply including final 0
|
@param adr_size Gives maximum size of reply including final 0
|
||||||
|
@ -197,9 +298,15 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
||||||
|
/* ts B00112 : we really want only "cd" devices.
|
||||||
|
|
||||||
if (idx->skip_device ||
|
if (idx->skip_device ||
|
||||||
strcmp(result->periph_name, "pass") == 0)
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
|
if (idx->skip_device ||
|
||||||
|
strcmp(result->periph_name, "cd") != 0)
|
||||||
|
break;
|
||||||
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(ret >= adr_size)
|
if(ret >= adr_size)
|
||||||
|
@ -210,7 +317,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
||||||
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* printf(stderr, "unknown match type\n"); */
|
/* fprintf(stderr, "unknown match type\n"); */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
(idx->i)++;
|
(idx->i)++;
|
||||||
|
@ -285,6 +392,10 @@ int sg_close_drive(struct burn_drive * d)
|
||||||
cam_close_device(d->cam);
|
cam_close_device(d->cam);
|
||||||
d->cam = NULL;
|
d->cam = NULL;
|
||||||
}
|
}
|
||||||
|
if (d->lock_fd > 0) {
|
||||||
|
close(d->lock_fd);
|
||||||
|
d->lock_fd = -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +441,11 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
struct burn_drive *t;
|
struct burn_drive *t;
|
||||||
struct burn_drive out;
|
struct burn_drive out;
|
||||||
|
|
||||||
|
/* Initialize pointers to managed memory */
|
||||||
|
out.devname = NULL;
|
||||||
|
out.idata = NULL;
|
||||||
|
out.mdata = NULL;
|
||||||
|
|
||||||
/* ts A60923 */
|
/* ts A60923 */
|
||||||
out.bus_no = bus_no;
|
out.bus_no = bus_no;
|
||||||
out.host = host_no;
|
out.host = host_no;
|
||||||
|
@ -337,8 +453,13 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
out.channel = channel_no;
|
out.channel = channel_no;
|
||||||
out.lun = lun_no;
|
out.lun = lun_no;
|
||||||
|
|
||||||
out.devname = burn_strdup(fname);
|
out.devname = strdup(fname);
|
||||||
|
if (out.devname == NULL)
|
||||||
|
goto could_not_allocate;
|
||||||
|
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
out.start_lba= -2000000000;
|
out.start_lba= -2000000000;
|
||||||
out.end_lba= -2000000000;
|
out.end_lba= -2000000000;
|
||||||
|
@ -363,7 +484,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
out.read_toc = mmc_read_toc;
|
out.read_toc = mmc_read_toc;
|
||||||
out.write = mmc_write;
|
out.write = mmc_write;
|
||||||
out.erase = mmc_erase;
|
out.erase = mmc_erase;
|
||||||
out.read_sectors = mmc_read_sectors;
|
out.read_cd = mmc_read_cd;
|
||||||
out.perform_opc = mmc_perform_opc;
|
out.perform_opc = mmc_perform_opc;
|
||||||
out.set_speed = mmc_set_speed;
|
out.set_speed = mmc_set_speed;
|
||||||
out.send_parameters = spc_select_error_params;
|
out.send_parameters = spc_select_error_params;
|
||||||
|
@ -375,16 +496,26 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
out.close_session = mmc_close_session;
|
out.close_session = mmc_close_session;
|
||||||
out.close_track_session = mmc_close;
|
out.close_track_session = mmc_close;
|
||||||
out.read_buffer_capacity = mmc_read_buffer_capacity;
|
out.read_buffer_capacity = mmc_read_buffer_capacity;
|
||||||
out.idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
out.idata = calloc(1, sizeof(struct burn_scsi_inquiry_data));
|
||||||
out.idata->valid = 0;
|
out.idata->valid = 0;
|
||||||
out.mdata = malloc(sizeof(struct scsi_mode_data));
|
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
|
||||||
out.mdata->valid = 0;
|
|
||||||
if (out.idata == NULL || out.mdata == NULL) {
|
if (out.idata == NULL || out.mdata == NULL) {
|
||||||
|
could_not_allocate:;
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not allocate new drive object", 0, 0);
|
"Could not allocate new drive object", 0, 0);
|
||||||
|
if (out.devname != NULL)
|
||||||
|
free(out.devname);
|
||||||
|
out.devname = NULL;
|
||||||
|
if (out.idata != NULL)
|
||||||
|
free(out.idata);
|
||||||
|
out.idata = NULL;
|
||||||
|
if (out.mdata != NULL)
|
||||||
|
free(out.mdata);
|
||||||
|
out.mdata = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
out.mdata->p2a_valid = 0;
|
||||||
memset(&out.params, 0, sizeof(struct params));
|
memset(&out.params, 0, sizeof(struct params));
|
||||||
t = burn_drive_register(&out);
|
t = burn_drive_register(&out);
|
||||||
|
|
||||||
|
@ -394,12 +525,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
|
|
||||||
/* try to get the drive info */
|
/* try to get the drive info */
|
||||||
if (t->grab(t)) {
|
if (t->grab(t)) {
|
||||||
burn_print(2, "getting drive info\n");
|
|
||||||
t->getcaps(t);
|
t->getcaps(t);
|
||||||
t->unlock(t);
|
t->unlock(t);
|
||||||
t->released = 1;
|
t->released = 1;
|
||||||
} else {
|
|
||||||
burn_print(2, "unable to grab new located drive\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
|
@ -430,6 +558,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
/* Operating system adapter is CAM */
|
/* Operating system adapter is CAM */
|
||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
|
out.lock_fd = -1;
|
||||||
|
out.is_ahci = 0;
|
||||||
|
|
||||||
/* Adapter specific functions */
|
/* Adapter specific functions */
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
|
@ -442,15 +573,149 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
|
|
||||||
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
/* ts A61021: do not believe this:
|
|
||||||
we use the sg reference count to decide whether we can use the
|
/* Lock the inode associated to dev_fd and the inode associated to devname.
|
||||||
drive or not.
|
Return OS errno, number of pass device of dev_fd, locked fd to devname,
|
||||||
if refcount is not one, drive is open somewhere else.
|
error message.
|
||||||
|
A return value of > 0 means success, <= 0 means failure.
|
||||||
*/
|
*/
|
||||||
|
static int freebsd_dev_lock(int dev_fd, char *devname,
|
||||||
|
int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096],
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100;
|
||||||
|
int max_retry = 3, tries = 0;
|
||||||
|
struct stat fd_stbuf, name_stbuf;
|
||||||
|
char pass_name[16], *lock_name;
|
||||||
|
|
||||||
|
*os_errno = 0;
|
||||||
|
*pass_dev_no = -1;
|
||||||
|
*lock_fd = -1;
|
||||||
|
msg[0] = 0;
|
||||||
|
|
||||||
|
fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf);
|
||||||
|
|
||||||
|
/* Try to find name of pass device by inode number */
|
||||||
|
lock_name = (char *) "effective device";
|
||||||
|
if(fd_stbuf_valid) {
|
||||||
|
for (i = 0; i < pass_l; i++) {
|
||||||
|
sprintf(pass_name, "/dev/pass%d", i);
|
||||||
|
if (stat(pass_name, &name_stbuf) != -1)
|
||||||
|
if(fd_stbuf.st_ino == name_stbuf.st_ino &&
|
||||||
|
fd_stbuf.st_dev == name_stbuf.st_dev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < pass_l) {
|
||||||
|
lock_name = pass_name;
|
||||||
|
*pass_dev_no = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name_stbuf_valid = !stat(devname, &name_stbuf);
|
||||||
|
for (tries= 0; tries <= max_retry; tries++) {
|
||||||
|
lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB);
|
||||||
|
*os_errno = errno;
|
||||||
|
if (lock_denied) {
|
||||||
|
if (errno == EAGAIN && tries < max_retry) {
|
||||||
|
/* <<< debugging
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n",
|
||||||
|
tries);
|
||||||
|
*/
|
||||||
|
usleep(2000000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sprintf(msg,
|
||||||
|
"Device busy. flock(LOCK_EX) failed on %s of %s",
|
||||||
|
strlen(lock_name) > 2000 || *pass_dev_no < 0 ?
|
||||||
|
"pass device" : lock_name,
|
||||||
|
strlen(devname) > 2000 ? "drive" : devname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n",
|
||||||
|
lock_name, devname);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Eventually lock the official device node too */
|
||||||
|
if (fd_stbuf_valid && name_stbuf_valid &&
|
||||||
|
(fd_stbuf.st_ino != name_stbuf.st_ino ||
|
||||||
|
fd_stbuf.st_dev != name_stbuf.st_dev)) {
|
||||||
|
|
||||||
|
*lock_fd = open(devname, O_RDONLY);
|
||||||
|
if (*lock_fd == 0) {
|
||||||
|
close(*lock_fd);
|
||||||
|
*lock_fd = -1;
|
||||||
|
} if (*lock_fd > 0) {
|
||||||
|
for (tries = 0; tries <= max_retry; tries++) {
|
||||||
|
lock_denied =
|
||||||
|
flock(*lock_fd, LOCK_EX | LOCK_NB);
|
||||||
|
if (lock_denied) {
|
||||||
|
if (errno == EAGAIN &&
|
||||||
|
tries < max_retry) {
|
||||||
|
/* <<< debugging
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n",
|
||||||
|
tries);
|
||||||
|
*/
|
||||||
|
|
||||||
|
usleep(2000000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
close(*lock_fd);
|
||||||
|
*lock_fd = -1;
|
||||||
|
sprintf(msg,
|
||||||
|
"Device busy. flock(LOCK_EX) failed on %s",
|
||||||
|
strlen(devname) > 4000 ? "drive" : devname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n",
|
||||||
|
devname);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_lock(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
int ret, os_errno, pass_dev_no = -1, flock_fd = -1;
|
||||||
|
char *msg = NULL;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(msg, char, 4096);
|
||||||
|
ret = freebsd_dev_lock(d->cam->fd, d->devname,
|
||||||
|
&os_errno, &pass_dev_no, &flock_fd, msg, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020008,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, os_errno, 0);
|
||||||
|
sg_close_drive(d);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
if (d->lock_fd > 0)
|
||||||
|
close(d->lock_fd);
|
||||||
|
d->lock_fd = flock_fd;
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int count;
|
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
|
char path_string[80];
|
||||||
|
|
||||||
if (mmc_function_spy(d, "sg_grab") <= 0)
|
if (mmc_function_spy(d, "sg_grab") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -462,22 +727,31 @@ int sg_grab(struct burn_drive *d)
|
||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
0x00020003,
|
||||||
"Could not grab drive", 0/*os_errno*/, 0);
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not grab drive", errno, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/
|
d->cam = cam;
|
||||||
count = 1;
|
if (burn_sg_open_o_excl & 63)
|
||||||
if (1 == count) {
|
if (sg_lock(d, 0) <= 0)
|
||||||
d->cam = cam;
|
return 0;
|
||||||
fcntl(cam->fd, F_SETOWN, getpid());
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
d->released = 0;
|
|
||||||
return 1;
|
cam_path_string(d->cam, path_string, sizeof(path_string));
|
||||||
}
|
|
||||||
burn_print(1, "could not acquire drive - already open\n");
|
#ifdef Libburn_ahci_verbouS
|
||||||
sg_close_drive(d);
|
fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string);
|
||||||
return 0;
|
#endif
|
||||||
|
|
||||||
|
if (strstr(path_string, ":ahcich") != NULL)
|
||||||
|
d->is_ahci = 1;
|
||||||
|
else
|
||||||
|
d->is_ahci = -1;
|
||||||
|
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -491,10 +765,8 @@ int sg_release(struct burn_drive *d)
|
||||||
if (mmc_function_spy(d, "sg_release") <= 0)
|
if (mmc_function_spy(d, "sg_release") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (d->cam == NULL) {
|
if (d->cam == NULL)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
||||||
|
|
||||||
|
@ -505,21 +777,34 @@ int sg_release(struct burn_drive *d)
|
||||||
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0, err, sense_len = 0, ret, ignore_error, i;
|
||||||
int err;
|
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
time_t start_time;
|
||||||
|
|
||||||
char buf[161];
|
mmc_function_spy(NULL, "sg_issue_command");
|
||||||
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
|
||||||
(void*)d->cam, d->released);
|
|
||||||
mmc_function_spy(NULL, buf);
|
|
||||||
|
|
||||||
if (d->cam == NULL) {
|
|
||||||
c->error = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
|
|
||||||
|
if (d->cam == NULL)
|
||||||
|
return 0;
|
||||||
|
if (burn_sg_log_scsi & 1) {
|
||||||
|
if (fp == NULL) {
|
||||||
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
fprintf(fp,
|
||||||
|
"\n-----------------------------------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
|
c->error = 0;
|
||||||
|
if (c->timeout > 0)
|
||||||
|
timeout_ms = c->timeout;
|
||||||
|
else
|
||||||
|
timeout_ms = 200000;
|
||||||
|
|
||||||
ccb = cam_getccb(d->cam);
|
ccb = cam_getccb(d->cam);
|
||||||
cam_fill_csio(&ccb->csio,
|
cam_fill_csio(&ccb->csio,
|
||||||
|
@ -531,7 +816,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
0, /* dxfer_len */
|
0, /* dxfer_len */
|
||||||
sizeof (ccb->csio.sense_data), /* sense_len */
|
sizeof (ccb->csio.sense_data), /* sense_len */
|
||||||
0, /* cdb_len */
|
0, /* cdb_len */
|
||||||
30*1000); /* timeout */
|
timeout_ms); /* timeout */
|
||||||
switch (c->dir) {
|
switch (c->dir) {
|
||||||
case TO_DRIVE:
|
case TO_DRIVE:
|
||||||
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
||||||
|
@ -544,11 +829,26 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_for_freebsd_ahcI
|
||||||
|
/* ts B00325 : Advise by Alexander Motin */
|
||||||
|
/* Runs well on 8-STABLE (23 Mar 2003)
|
||||||
|
But on 8-RELEASE cam_send_ccb() returns non-zero with errno 6
|
||||||
|
on eject. Long lasting TEST UNIT READY cycles break with
|
||||||
|
errno 16.
|
||||||
|
*/
|
||||||
|
#ifdef Libburn_ahci_style_for_alL
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
if (d->is_ahci > 0) {
|
||||||
|
#endif
|
||||||
|
ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
|
||||||
|
cam_pass_err_recover = 1;
|
||||||
|
}
|
||||||
|
#endif /* Libburn_for_freebsd_ahcI */
|
||||||
|
|
||||||
ccb->csio.cdb_len = c->oplen;
|
ccb->csio.cdb_len = c->oplen;
|
||||||
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
||||||
|
|
||||||
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
|
|
||||||
|
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
ccb->csio.data_ptr = c->page->data;
|
ccb->csio.data_ptr = c->page->data;
|
||||||
if (c->dir == FROM_DRIVE) {
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
@ -566,12 +866,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
/* touch page so we can use valgrind */
|
/* touch page so we can use valgrind */
|
||||||
memset(c->page->data, 0, BUFFER_SIZE);
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
} else {
|
} else {
|
||||||
/* ts A90430 */
|
|
||||||
/* a ssert(c->page->bytes > 0); */
|
|
||||||
if (c->page->bytes <= 0) {
|
|
||||||
c->error = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ccb->csio.dxfer_len = c->page->bytes;
|
ccb->csio.dxfer_len = c->page->bytes;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -579,44 +873,193 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
/* ts B90523 : Record effective transfer length request for debugging*/
|
||||||
|
c->dxfer_len = ccb->csio.dxfer_len;
|
||||||
|
|
||||||
|
start_time = time(NULL);
|
||||||
|
for (i = 0; !done; i++) {
|
||||||
|
|
||||||
|
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
|
||||||
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
|
c->start_time = burn_get_time(0);
|
||||||
|
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
if (err == -1) {
|
|
||||||
|
c->end_time = burn_get_time(0);
|
||||||
|
ignore_error = sense_len = 0;
|
||||||
|
/* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
|
||||||
|
if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
|
||||||
|
/* ts B00110 */
|
||||||
|
/* Better curb sense_len */
|
||||||
|
sense_len = ccb->csio.sense_len;
|
||||||
|
if (sense_len > (int) sizeof(c->sense))
|
||||||
|
sense_len = sizeof(c->sense);
|
||||||
|
memcpy(c->sense, &ccb->csio.sense_data, sense_len);
|
||||||
|
spc_decode_sense(c->sense, sense_len,
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
if (sense_len >= 14 && cam_pass_err_recover && key)
|
||||||
|
ignore_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == -1 && cam_pass_err_recover && ! ignore_error) {
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (errno == ENXIO && c->opcode[0] != 0) {
|
||||||
|
/* Operations on empty or ejected tray */
|
||||||
|
/* MEDIUM NOT PRESENT */
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,3A,00] MEDIUM NOT PRESENT\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x3A;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
} else if (c->opcode[0] == 0 &&
|
||||||
|
(errno == EBUSY || errno == ENXIO)) {
|
||||||
|
/* Timeout of TEST UNIT READY loop */
|
||||||
|
/* Inquiries while tray is being loaded */
|
||||||
|
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
c->sense[2] = 0x02;
|
||||||
|
c->sense[12] = 0x04;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
} else if (errno == EINVAL) {
|
||||||
|
/* Inappropriate MODE SENSE */
|
||||||
|
/* INVALID FIELD IN CDB */
|
||||||
|
|
||||||
|
#ifdef Libburn_ahci_verbouS
|
||||||
|
fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [5,24,00] INVALID FIELD IN CDB\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
|
c->sense[2] = 0x05;
|
||||||
|
c->sense[12] = 0x24;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
|
sense_len = 14;
|
||||||
|
ignore_error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == -1 && !ignore_error) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x0002010c,
|
d->global_index, 0x0002010c,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Failed to transfer command to drive",
|
"Failed to transfer command to drive",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
cam_freeccb(ccb);
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
d->released = 1;
|
d->released = 1;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
|
||||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
if (!c->retry) {
|
if (sense_len < 14) {
|
||||||
c->error = 1;
|
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
||||||
cam_freeccb(ccb);
|
|
||||||
return 1;
|
#ifdef Libburn_ahci_verbouS
|
||||||
}
|
fprintf(stderr, "libburn_EXPERIMENTAL: CAM_STATUS= %d .Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n", (ccb->ccb_h.status & CAM_STATUS_MASK));
|
||||||
switch (scsi_error(d, c->sense, 0)) {
|
#endif
|
||||||
case RETRY:
|
|
||||||
done = 0;
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
break;
|
c->sense[2] = 0x02;
|
||||||
case FAIL:
|
c->sense[12] = 0x04;
|
||||||
|
c->sense[13] = 0x00;
|
||||||
done = 1;
|
done = 1;
|
||||||
c->error = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
done = 1;
|
|
||||||
}
|
}
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
||||||
|
sense_len, start_time,
|
||||||
|
timeout_ms, i, !!ignore_error);
|
||||||
|
if (d->cancel)
|
||||||
|
done = 1;
|
||||||
|
if (!done)
|
||||||
|
spc_register_retry(c);
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return 1;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00115 */
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
fseeked, read and eventually written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
||||||
|
int fd, ret;
|
||||||
|
off_t add_size;
|
||||||
|
#else
|
||||||
|
char *spt;
|
||||||
|
int i, e;
|
||||||
|
#endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
||||||
|
|
||||||
|
/* If it throws no error with DIOCGMEDIASIZE then it is a
|
||||||
|
'block device'
|
||||||
|
*/
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return 0;
|
||||||
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return (ret != -1);
|
||||||
|
|
||||||
|
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
|
spt = strrchr(path, '/');
|
||||||
|
if (spt == NULL)
|
||||||
|
spt = path;
|
||||||
|
else
|
||||||
|
spt++;
|
||||||
|
e = strlen(spt);
|
||||||
|
for (i = strlen(spt) - 1; i > 0; i--)
|
||||||
|
if (spt[i] >= '0' && spt[i] <= '9')
|
||||||
|
e = i;
|
||||||
|
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
||||||
|
return 1;
|
||||||
|
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -630,16 +1073,16 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
1 = estimation has been made, bytes was set
|
||||||
*/
|
*/
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes)
|
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
{
|
{
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
char testpath[4096], *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
int fd, ret;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
|
@ -650,39 +1093,89 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||||
else
|
else
|
||||||
*cpt = 0;
|
*cpt = 0;
|
||||||
if (stat(testpath, &stbuf) == -1)
|
if (stat(testpath, &stbuf) == -1)
|
||||||
return -1;
|
{ret = -1; goto ex;}
|
||||||
|
|
||||||
#ifdef Libburn_if_this_was_linuX
|
#ifdef Libburn_if_this_was_linuX
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
int open_mode = O_RDWR, fd, ret;
|
int open_mode = O_RDWR, fd, ret;
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
if(burn_sg_open_o_excl)
|
if(burn_sg_open_o_excl)
|
||||||
open_mode |= O_EXCL;
|
open_mode |= O_EXCL;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
*bytes = ((off_t) blocks) * (off_t) 512;
|
||||||
|
|
||||||
#endif /* Libburn_if_this_was_linuX */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
|
|
||||||
|
} else if(S_ISCHR(stbuf.st_mode)) {
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
close(fd);
|
||||||
|
if (ret == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
*bytes = add_size;
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
add_size = burn_sparse_file_addsize(write_start, &stbuf);
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
{ret = -2; goto ex;}
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:
|
||||||
|
BURN_FREE_MEM(testpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
|
#ifdef Libburn_read_o_direcT
|
||||||
|
|
||||||
|
/* No special O_DIRECT-like precautions are implemented here */
|
||||||
|
|
||||||
|
#endif /* Libburn_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, open_flags);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
buf = calloc(1, amount);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return 0;
|
||||||
|
free(buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1019
libburn/sg-libcdio.c
Normal file
1019
libburn/sg-libcdio.c
Normal file
File diff suppressed because it is too large
Load Diff
1640
libburn/sg-linux.c
1640
libburn/sg-linux.c
File diff suppressed because it is too large
Load Diff
916
libburn/sg-netbsd.c
Normal file
916
libburn/sg-netbsd.c
Normal file
|
@ -0,0 +1,916 @@
|
||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
|
Derived 2014 from libburn/sg-solaris.c with information learned from
|
||||||
|
dvd+rw-tools, http://fxr.watson.org/fxr/source/sys/scsiio.h?v=NETBSD,
|
||||||
|
http://netbsd.gw.com/cgi-bin/man-cgi?scsi+4+NetBSD-current,
|
||||||
|
and experiments made by Freddy Fisker.
|
||||||
|
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
|
the transport level aspects of SCSI control and command i/o.
|
||||||
|
|
||||||
|
Present implementation: NetBSD 6, ioctl SCIOCCOMMAND
|
||||||
|
OpenBSD 5.9, ioctl SCIOCCOMMAND
|
||||||
|
|
||||||
|
PORTING:
|
||||||
|
|
||||||
|
Porting libburn typically will consist of adding a new operating system case
|
||||||
|
to the following switcher files:
|
||||||
|
os.h Operating system specific libburn definitions and declarations.
|
||||||
|
sg.c Operating system dependent transport level modules.
|
||||||
|
and of deriving the following system specific files from existing examples:
|
||||||
|
os-*.h Included by os.h. You will need some general system knowledge
|
||||||
|
about signals and knowledge about the storage object needs of your
|
||||||
|
transport level module sg-*.c.
|
||||||
|
|
||||||
|
sg-*.c This source module. You will need special system knowledge about
|
||||||
|
how to detect all potentially available drives, how to open them,
|
||||||
|
eventually how to exclusively reserve them, how to perform
|
||||||
|
SCSI transactions, how to inquire the (pseudo-)SCSI driver.
|
||||||
|
You will not need to care about CD burning, MMC or other high-level
|
||||||
|
SCSI aspects.
|
||||||
|
|
||||||
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
|
sg_id_string() returns an id string of the SCSI transport adapter.
|
||||||
|
It may be called before initialization but then may
|
||||||
|
return only a preliminary id.
|
||||||
|
|
||||||
|
sg_initialize() performs global initialization of the SCSI transport
|
||||||
|
adapter and eventually needed operating system
|
||||||
|
facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
|
||||||
|
sg_shutdown() performs global finalizations and releases globally
|
||||||
|
acquired resources.
|
||||||
|
|
||||||
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
|
address strings.
|
||||||
|
|
||||||
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
|
on destruction. Releases resources which were acquired
|
||||||
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
|
sg_drive_is_open() tells whether libburn has the given drive in use.
|
||||||
|
|
||||||
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
|
undisturbed access.
|
||||||
|
|
||||||
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
|
and evaluates whether the command succeeded or shall
|
||||||
|
be retried or finally failed.
|
||||||
|
|
||||||
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
||||||
|
that can be used in 2 kB granularity by lseek(2),
|
||||||
|
read(2), and possibly write(2) if not read-only..
|
||||||
|
E.g. a USB stick or a hard disk.
|
||||||
|
|
||||||
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
|
burn_os_open_track_src() opens a disk file in a way that offers best
|
||||||
|
throughput with file reading and/or SCSI write command
|
||||||
|
transmission.
|
||||||
|
|
||||||
|
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||||
|
descriptors issued by burn_os_open_track_src().
|
||||||
|
The buffer size may be rounded up for alignment
|
||||||
|
reasons.
|
||||||
|
|
||||||
|
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
||||||
|
|
||||||
|
Porting hints are marked by the text "PORTING:".
|
||||||
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef Libburn_os_has_statvfS
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif /* Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/scsiio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "spc.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/* is in portable part of libburn */
|
||||||
|
int burn_drive_is_banned(char *device_address);
|
||||||
|
int burn_drive_resolve_link(char *path, char adr[],
|
||||||
|
int *recursion_count, int flag); /* drive.c */
|
||||||
|
|
||||||
|
/* Whether to log SCSI commands:
|
||||||
|
bit0= log in /tmp/libburn_sg_command_log
|
||||||
|
bit1= log to stderr
|
||||||
|
bit2= flush every line
|
||||||
|
*/
|
||||||
|
extern int burn_sg_log_scsi;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Private definitions. Port only if needed by public functions. */
|
||||||
|
/* (Public functions are listed below) */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/* Storage object is in libburn/init.c
|
||||||
|
whether to strive for exclusive access to the drive
|
||||||
|
*/
|
||||||
|
extern int burn_sg_open_o_excl;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Private functions. Port only if needed by public functions */
|
||||||
|
/* (Public functions are listed below) */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
static int sg_close_drive(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
if (d->fd != -1) {
|
||||||
|
close(d->fd);
|
||||||
|
d->fd = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
/* PORTING: Private functions which contain publicly needed functionality. */
|
||||||
|
/* Their portable part must be performed. So it is probably best */
|
||||||
|
/* to replace the non-portable part and to call these functions */
|
||||||
|
/* in your port, too. */
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/** Wraps a detected drive into libburn structures and hands it over to
|
||||||
|
libburn drive list.
|
||||||
|
*/
|
||||||
|
static void enumerate_common(char *fname,
|
||||||
|
int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct burn_drive out;
|
||||||
|
|
||||||
|
/* General libburn drive setup */
|
||||||
|
burn_setup_drive(&out, fname);
|
||||||
|
|
||||||
|
/* This transport adapter uses SCSI-family commands and models
|
||||||
|
(seems the adapter would know better than its boss, if ever) */
|
||||||
|
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
|
||||||
|
target_no, lun_no, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* PORTING: ------------------- non portable part --------------- */
|
||||||
|
|
||||||
|
/* Transport adapter is NetBSD/OpenBSD ioctl SCIOCCOMMAND */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
|
|
||||||
|
out.fd = -1;
|
||||||
|
|
||||||
|
/* PORTING: ---------------- end of non portable part ------------ */
|
||||||
|
|
||||||
|
/* Adapter specific functions with standardized names */
|
||||||
|
out.grab = sg_grab;
|
||||||
|
out.release = sg_release;
|
||||||
|
out.drive_is_open = sg_drive_is_open;
|
||||||
|
out.issue_command = sg_issue_command;
|
||||||
|
/* Finally register drive and inquire drive information */
|
||||||
|
burn_drive_finish_enum(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int start_enum_rcdNx(burn_drive_enumerator_t *idx, int flag)
|
||||||
|
{
|
||||||
|
idx->cdno = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Trying /dev/rcd[0..63][dc] */
|
||||||
|
#define Libburn_netbsd_max_cdnuM 63
|
||||||
|
|
||||||
|
static int next_enum_rcdNx(burn_drive_enumerator_t *idx,
|
||||||
|
char adr[], int adr_size, int flag)
|
||||||
|
{
|
||||||
|
static char suffix[2] = {'d', 'c'};
|
||||||
|
struct stat stbuf;
|
||||||
|
int i, stat_ret;
|
||||||
|
char path[16];
|
||||||
|
|
||||||
|
while (idx->cdno < Libburn_netbsd_max_cdnuM) {
|
||||||
|
idx->cdno++;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
sprintf(path, "/dev/rcd%d%c", idx->cdno, suffix[i]);
|
||||||
|
stat_ret = stat(path, &stbuf);
|
||||||
|
if (stat_ret == -1)
|
||||||
|
continue;
|
||||||
|
if (!S_ISCHR(stbuf.st_mode))
|
||||||
|
continue;
|
||||||
|
if ((int) strlen(path) >= adr_size)
|
||||||
|
continue;
|
||||||
|
strcpy(adr, path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Searching the first byte address that cannot be lseeked and read
|
||||||
|
*/
|
||||||
|
static int guess_size_by_seek_set(int fd, off_t *bytes, int flag)
|
||||||
|
{
|
||||||
|
static off_t abs_limit = ((off_t) 1024) * 1024 * 1024 * 1024 * 1024;
|
||||||
|
off_t i, step = ((off_t) 1024) * 1024 * 1024 * 1024, ret;
|
||||||
|
char buf[1];
|
||||||
|
|
||||||
|
*bytes = 0;
|
||||||
|
for (i = step; i < abs_limit; i += step) {
|
||||||
|
ret = lseek(fd, i, SEEK_SET);
|
||||||
|
if (ret == -1) {
|
||||||
|
i -= step;
|
||||||
|
step = step >> 1;
|
||||||
|
if (step > 0)
|
||||||
|
continue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ret = read(fd, buf, 1);
|
||||||
|
if (ret == -1) {
|
||||||
|
i -= step;
|
||||||
|
step = step >> 1;
|
||||||
|
if (step > 0)
|
||||||
|
continue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*bytes = i + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Public functions. These MUST be ported. */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
sprintf(msg, "internal OpenBSD SCIOCCOMMAND adapter sg-netbsd");
|
||||||
|
#else
|
||||||
|
sprintf(msg, "internal NetBSD SCIOCCOMMAND adapter sg-netbsd");
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility of supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag)
|
||||||
|
{
|
||||||
|
return sg_id_string(msg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally acquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
|
allowed to return addresses of drives which are not available but under
|
||||||
|
some (even exotic) circumstances could be available. It is on the other
|
||||||
|
hand allowed, only to hand out addresses which can really be used right
|
||||||
|
in the moment of this call. (This implementation chooses the former.)
|
||||||
|
@param idx An opaque handle. Make no own theories about it.
|
||||||
|
@param adr Takes the reply
|
||||||
|
@param adr_size Gives maximum size of reply including final 0
|
||||||
|
@param initialize 1 = start new,
|
||||||
|
0 = continue, use no other values for now
|
||||||
|
-1 = finish
|
||||||
|
@return 1 = reply is a valid address , 0 = no further address available
|
||||||
|
-1 = severe error (e.g. adr_size too small)
|
||||||
|
*/
|
||||||
|
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
|
char adr[], int adr_size, int initialize)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (initialize == 1) {
|
||||||
|
ret = start_enum_rcdNx(idx, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
} else if (initialize == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ret = next_enum_rcdNx(idx, adr, adr_size, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Brings all available, not-whitelist-banned, and accessible drives into
|
||||||
|
libburn's list of drives.
|
||||||
|
*/
|
||||||
|
int scsi_enumerate_drives(void)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1, ret, i_bus_no = -1, buf_size = 4096;
|
||||||
|
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(buf, char, buf_size);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, buf_size, initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
continue;
|
||||||
|
sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
|
||||||
|
&i_channel_no, &i_target_no, &i_lun_no);
|
||||||
|
enumerate_common(buf,
|
||||||
|
i_bus_no, i_host_no, i_channel_no,
|
||||||
|
i_target_no, i_lun_no);
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, buf_size, -1);
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
||||||
|
If it is "open" then libburn will eventually call sg_release() on it when
|
||||||
|
it is time to give up usage and reservation.
|
||||||
|
*/
|
||||||
|
/** Published as burn_drive.drive_is_open() */
|
||||||
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
return (d->fd != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Opens the drive for SCSI commands and - if burn activities are prone
|
||||||
|
to external interference on your system - obtains an exclusive access lock
|
||||||
|
on the drive. (Note: this is not physical tray locking.)
|
||||||
|
A drive that has been opened with sg_grab() will eventually be handed
|
||||||
|
over to sg_release() for closing and unreserving.
|
||||||
|
*/
|
||||||
|
int sg_grab(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
char *msg = NULL;
|
||||||
|
int os_errno, ret;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(msg, char, 4096);
|
||||||
|
|
||||||
|
if (d->fd != -1) {
|
||||||
|
d->released = 0;
|
||||||
|
{ret = 1; goto ex;}
|
||||||
|
}
|
||||||
|
d->fd = open(d->devname, O_RDWR | O_NDELAY);
|
||||||
|
if (d->fd == -1) {
|
||||||
|
os_errno = errno;
|
||||||
|
sprintf(msg, "Could not grab drive '%s'", d->devname);
|
||||||
|
/* (errno == ENXIO is a device file with no drive attached) */
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020003,
|
||||||
|
errno == ENXIO ? LIBDAX_MSGS_SEV_DEBUG :
|
||||||
|
LIBDAX_MSGS_SEV_SORRY,
|
||||||
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, os_errno, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->released = 0;
|
||||||
|
|
||||||
|
/* Make sure by INQUIRY that this is really a MMC drive */
|
||||||
|
ret = spc_confirm_cd_drive(d, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto revoke;
|
||||||
|
|
||||||
|
/* # define Libburn_sg_netbsd_scsi_debuG */
|
||||||
|
#ifdef Libburn_sg_netbsd_scsi_debuG
|
||||||
|
{
|
||||||
|
static int sc_db = SC_DB_CMDS | SC_DB_FLOW;
|
||||||
|
|
||||||
|
ret = ioctl(d->fd, SCIOCDEBUG, &sc_db);
|
||||||
|
if (ret == -1)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libburn_DEBUG: ioctl(%d, SCIOCDEBUG, &(0x%X)) returns %d, errno = %d\n",
|
||||||
|
d->fd, (unsigned int) sc_db, ret, errno);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
{ret = 1; goto ex;}
|
||||||
|
|
||||||
|
revoke:;
|
||||||
|
sprintf(msg, "Could not grab drive '%s'.", d->devname);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020003,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
if (d->fd >= 0) {
|
||||||
|
close(d->fd);
|
||||||
|
d->fd = -1;
|
||||||
|
d->released = 1;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
|
||||||
|
implements the demanded functionality.
|
||||||
|
*/
|
||||||
|
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
||||||
|
(Note: this is not physical tray locking.)
|
||||||
|
*/
|
||||||
|
int sg_release(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
if (d->fd < 0)
|
||||||
|
return 0;
|
||||||
|
sg_close_drive(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
||||||
|
the command succeeded or shall be retried or finally failed.
|
||||||
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
a retry shall be notified via scsi_notify_error().
|
||||||
|
The Libburn_log_sg_commandS facility might be of help when problems with
|
||||||
|
a drive have to be examined. It shall stay disabled for normal use.
|
||||||
|
@return: 1 success , <=0 failure
|
||||||
|
*/
|
||||||
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
|
{
|
||||||
|
int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len, max_sl;
|
||||||
|
time_t start_time;
|
||||||
|
scsireq_t req;
|
||||||
|
char msg[160];
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
|
c->error = 0;
|
||||||
|
|
||||||
|
if (d->fd == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (burn_sg_log_scsi & 1) {
|
||||||
|
if (fp == NULL) {
|
||||||
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
fprintf(fp,
|
||||||
|
"\n-----------------------------------------\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
|
if (c->timeout > 0)
|
||||||
|
timeout_ms = c->timeout;
|
||||||
|
else
|
||||||
|
timeout_ms = 200000;
|
||||||
|
|
||||||
|
memset (&req, 0, sizeof(req));
|
||||||
|
memcpy(req.cmd, c->opcode, c->oplen);
|
||||||
|
req.cmdlen = c->oplen;
|
||||||
|
req.databuf = (caddr_t) c->page->data;
|
||||||
|
req.flags = SCCMD_ESCAPE; /* probably to make req.cmdlen significant */
|
||||||
|
req.timeout = timeout_ms;
|
||||||
|
max_sl = sizeof(c->sense) > SENSEBUFLEN ?
|
||||||
|
SENSEBUFLEN : sizeof(c->sense);
|
||||||
|
req.senselen = max_sl;
|
||||||
|
if (c->dir == TO_DRIVE) {
|
||||||
|
req.datalen = c->page->bytes;
|
||||||
|
req.flags |= SCCMD_WRITE;
|
||||||
|
} else if (c->dir == FROM_DRIVE) {
|
||||||
|
req.flags |= SCCMD_READ;
|
||||||
|
if (c->dxfer_len >= 0)
|
||||||
|
req.datalen = c->dxfer_len;
|
||||||
|
else
|
||||||
|
req.datalen = BUFFER_SIZE;
|
||||||
|
/* touch page so we can use valgrind */
|
||||||
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
req.flags |= SCCMD_READ;
|
||||||
|
req.datalen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts B90523 : Record effective transfer length request for debugging*/
|
||||||
|
c->dxfer_len = req.datalen;
|
||||||
|
|
||||||
|
/* retry-loop */
|
||||||
|
start_time = time(NULL);
|
||||||
|
for(i = 0; !done; i++) {
|
||||||
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
|
c->start_time = burn_get_time(0);
|
||||||
|
|
||||||
|
ret = ioctl(d->fd, SCIOCCOMMAND, &req);
|
||||||
|
|
||||||
|
/* <<< Fault mock-up
|
||||||
|
if (c->opcode[0] == 0x28) {
|
||||||
|
ret = -1;
|
||||||
|
errno = 9;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
c->end_time = burn_get_time(0);
|
||||||
|
|
||||||
|
/* #define Libburn_debug_sg_netbsD */
|
||||||
|
#ifdef Libburn_debug_sg_netbsD
|
||||||
|
fprintf(stderr, "libburn_DEBUG: ret= %d, retsts = 0x%X, senselen_used = %d, status = 0x%X, error= 0x%X\n", ret, (unsigned int) req.retsts, (int) req.senselen_used, (unsigned int) req.status, req.error);
|
||||||
|
fprintf(stderr, "libburn_DEBUG: datalen_used = %u\n",
|
||||||
|
(unsigned int) req.datalen_used);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret != 0 ||
|
||||||
|
(req.retsts != SCCMD_SENSE && req.retsts != SCCMD_OK)) {
|
||||||
|
sprintf(msg, "Failed to transfer command to drive. (ioctl(%d, SCIOCCOMMAND) = %d, scsireq_t.retsts = 0x%X, errno= %d)",
|
||||||
|
d->fd, ret, (unsigned int) req.retsts, errno);
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_message(d, fp, msg, 0);
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002010c,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, errno, 0);
|
||||||
|
sg_close_drive(d);
|
||||||
|
d->released = 1;
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
c->error = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sense_len = 0;
|
||||||
|
if (req.retsts == SCCMD_SENSE) {
|
||||||
|
memcpy(c->sense, req.sense, max_sl);
|
||||||
|
sense_len = req.senselen > max_sl ?
|
||||||
|
max_sl : req.senselen;
|
||||||
|
}
|
||||||
|
spc_decode_sense(c->sense, sense_len, &key, &asc, &ascq);
|
||||||
|
if (key || asc || ascq)
|
||||||
|
sense_len = req.senselen;
|
||||||
|
else
|
||||||
|
sense_len = 0;
|
||||||
|
|
||||||
|
/* <<< Fault mock-up
|
||||||
|
if (c->opcode[0] == 0x5a) {
|
||||||
|
req.datalen_used = 0;
|
||||||
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (c->dir == FROM_DRIVE && sense_len == 0 &&
|
||||||
|
req.datalen > 0 && req.datalen_used < req.datalen) {
|
||||||
|
sprintf(msg, "Short reply from SCSI command %2.2X: expected: %d, got: %d, req.retsts: 0x%X",
|
||||||
|
(unsigned int) c->opcode[0],
|
||||||
|
(int) req.datalen, (int) req.datalen_used,
|
||||||
|
(unsigned int) req.retsts);
|
||||||
|
if (burn_sg_log_scsi & 3)
|
||||||
|
scsi_log_message(d, fp, msg, 0);
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
if (req.datalen_used == 0)
|
||||||
|
c->error = 1;
|
||||||
|
c->dxfer_len = req.datalen_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
|
||||||
|
start_time, timeout_ms, i, 0);
|
||||||
|
if (d->cancel)
|
||||||
|
done = 1;
|
||||||
|
if (!done)
|
||||||
|
spc_register_retry(c);
|
||||||
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tries to obtain SCSI address parameters.
|
||||||
|
@return 1 is success , 0 is failure
|
||||||
|
*/
|
||||||
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no)
|
||||||
|
{
|
||||||
|
int ret, fd = -1;
|
||||||
|
struct scsi_addr addr;
|
||||||
|
|
||||||
|
fd = open(path, O_RDWR | O_NDELAY);
|
||||||
|
if (fd == -1)
|
||||||
|
return 0;
|
||||||
|
*bus_no = *host_no = *channel_no = *target_no = *lun_no = 0;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
ret = ioctl(fd, SCIOCIDENTIFY, &addr);
|
||||||
|
if (ret != 0)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
if (addr.type != TYPE_SCSI)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
|
||||||
|
*bus_no = *host_no = addr.scbus;
|
||||||
|
*target_no = addr.target;
|
||||||
|
*lun_no = addr.lun;
|
||||||
|
|
||||||
|
#else /* __OpenBSD__ */
|
||||||
|
|
||||||
|
*bus_no = *host_no = addr.addr.scsi.scbus;
|
||||||
|
*target_no = addr.addr.scsi.target;
|
||||||
|
*lun_no = addr.addr.scsi.lun;
|
||||||
|
|
||||||
|
#endif /* ! __OpenBSD__ */
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||||
|
functions.
|
||||||
|
*/
|
||||||
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1, ret;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) == 0) {
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
|
fseeked, read, and possibly written with 2 kB granularity.
|
||||||
|
*/
|
||||||
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
int l, i, dev, tl;
|
||||||
|
char try[16];
|
||||||
|
|
||||||
|
/* >>> ??? Is this a comprehensive list of lseek()-capable devices ? */
|
||||||
|
/* http://www.netbsd.org/docs/guide/en/chap-rmmedia.html */
|
||||||
|
static char dev_names[][4] = {
|
||||||
|
"fd", "rfd", "sd" , "cd", "rcd", "wd", ""};
|
||||||
|
|
||||||
|
if (path[0] == 0)
|
||||||
|
return 0;
|
||||||
|
if (stat(path, &stbuf) == -1)
|
||||||
|
return 0;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
if (S_ISBLK(stbuf.st_mode))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Look for known device names which promise the desired capabilities */
|
||||||
|
if (strncmp(path, "/dev/", 5) != 0)
|
||||||
|
return 0;
|
||||||
|
l = strlen(path);
|
||||||
|
for (dev = 0; dev_names[dev][0] != 0; dev++) {
|
||||||
|
sprintf(try, "/dev/%s", dev_names[dev]);
|
||||||
|
tl = strlen(try);
|
||||||
|
if (strncmp(path, try, tl) != 0)
|
||||||
|
continue;
|
||||||
|
l -= tl;
|
||||||
|
for (i = 0; i < Libburn_netbsd_max_cdnuM; i++) {
|
||||||
|
sprintf(try + tl, "%d", i);
|
||||||
|
if (strncmp(path, try, strlen(try)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= Libburn_netbsd_max_cdnuM)
|
||||||
|
continue;
|
||||||
|
tl += strlen(try + tl);
|
||||||
|
if (l == tl)
|
||||||
|
return 1;
|
||||||
|
if (l > tl + 1)
|
||||||
|
continue;
|
||||||
|
if (path[l - 1] >= 'a' && path[l - 1] <= 'z')
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Estimate the potential payload capacity of a file address.
|
||||||
|
@param path The address of the file to be examined. If it does not
|
||||||
|
exist yet, then the directory will be inquired.
|
||||||
|
@param bytes The pointed value gets modified, but only if an estimation is
|
||||||
|
possible.
|
||||||
|
@return -2 = cannot perform necessary operations on file object
|
||||||
|
-1 = neither path nor dirname of path exist
|
||||||
|
0 = could not estimate size capacity of file object
|
||||||
|
1 = estimation has been made, bytes was set
|
||||||
|
*/
|
||||||
|
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef Libburn_os_has_statvfS
|
||||||
|
struct statvfs vfsbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *testpath = NULL, *cpt;
|
||||||
|
off_t add_size = 0;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
|
|
||||||
|
testpath[0] = 0;
|
||||||
|
if (stat(path, &stbuf) == -1) {
|
||||||
|
strcpy(testpath, path);
|
||||||
|
cpt = strrchr(testpath, '/');
|
||||||
|
if(cpt == NULL)
|
||||||
|
strcpy(testpath, ".");
|
||||||
|
else if(cpt == testpath)
|
||||||
|
testpath[1] = 0;
|
||||||
|
else
|
||||||
|
*cpt = 0;
|
||||||
|
if (stat(testpath, &stbuf) == -1)
|
||||||
|
{ret = -1; goto ex;}
|
||||||
|
|
||||||
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
|
int open_mode = O_RDONLY, fd;
|
||||||
|
|
||||||
|
fd = open(path, open_mode);
|
||||||
|
if (fd == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
*bytes = lseek(fd, 0, SEEK_END);
|
||||||
|
if (*bytes <= 0)
|
||||||
|
guess_size_by_seek_set(fd, bytes, 0);
|
||||||
|
close(fd);
|
||||||
|
if (*bytes == -1) {
|
||||||
|
*bytes = 0;
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
|
add_size = burn_sparse_file_addsize(write_start, &stbuf);
|
||||||
|
strcpy(testpath, path);
|
||||||
|
} else
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
|
if (testpath[0]) {
|
||||||
|
|
||||||
|
#ifdef Libburn_os_has_statvfS
|
||||||
|
|
||||||
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
|
{ret = -2; goto ex;}
|
||||||
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
|
(off_t) vfsbuf.f_bavail;
|
||||||
|
|
||||||
|
#else /* Libburn_os_has_statvfS */
|
||||||
|
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
|
#endif /* ! Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(testpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||||
|
|
||||||
|
#ifdef Libburn_read_o_direcT
|
||||||
|
|
||||||
|
/* No special O_DIRECT-like precautions are implemented here */
|
||||||
|
|
||||||
|
#endif /* Libburn_read_o_direcT */
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, open_flags);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||||
|
{
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
buf = calloc(1, amount);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return 0;
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
1018
libburn/sg-solaris.c
Normal file
1018
libburn/sg-solaris.c
Normal file
File diff suppressed because it is too large
Load Diff
58
libburn/sg.c
58
libburn/sg.c
|
@ -1,19 +1,63 @@
|
||||||
|
|
||||||
/* sg.c
|
/* sg.c
|
||||||
Switcher for operating system dependent transport level modules of libburn.
|
Switcher for operating system dependent transport level modules of libburn.
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
|
provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#undef HAVE_CONFIG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
#include "sg-dummy.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef Libburn_use_libcdiO
|
||||||
|
|
||||||
|
#include "sg-libcdio.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
|
||||||
|
#include "sg-netbsd.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
|
||||||
|
#include "sg-netbsd.c"
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_freebsd_porT
|
||||||
|
#include "sg-freebsd-port.c"
|
||||||
|
#else
|
||||||
#include "sg-freebsd.c"
|
#include "sg-freebsd.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_freebsd_porT
|
||||||
|
#include "sg-freebsd-port.c"
|
||||||
|
#else
|
||||||
|
#include "sg-freebsd.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
|
|
||||||
#include "sg-linux.c"
|
#include "sg-linux.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __sun
|
||||||
|
|
||||||
|
#include "sg-solaris.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* The dummy adapter formally fulfills the expectations of libburn towards
|
/* The dummy adapter formally fulfills the expectations of libburn towards
|
||||||
|
@ -24,11 +68,13 @@
|
||||||
static int intentional_compiler_warning(void)
|
static int intentional_compiler_warning(void)
|
||||||
{
|
{
|
||||||
int INTENTIONAL_COMPILER_WARNING_;
|
int INTENTIONAL_COMPILER_WARNING_;
|
||||||
int Cannot_recognize_Linux_nor_FreeBSD_;
|
int Cannot_recognize_supported_operating_system_;
|
||||||
|
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD_;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
int Have_to_use_dummy_MMC_transport_adapter_;
|
||||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter;
|
int Have_to_use_dummy_MMC_transport_adapter;
|
||||||
int Cannot_recognize_Linux_nor_FreeBSD;
|
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD;
|
||||||
|
int Cannot_recognize_supported_operating_system;
|
||||||
int INTENTIONAL_COMPILER_WARNING;
|
int INTENTIONAL_COMPILER_WARNING;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -36,6 +82,12 @@ static int intentional_compiler_warning(void)
|
||||||
|
|
||||||
#include "sg-dummy.c"
|
#include "sg-dummy.c"
|
||||||
|
|
||||||
|
#endif /* ! __sun */
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
|
#endif /* ! __FreeBSD_kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
|
#endif /* ! __OpenBSD__ */
|
||||||
|
#endif /* ! __NetBSD__ */
|
||||||
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
50
libburn/sg.h
50
libburn/sg.h
|
@ -1,5 +1,8 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __SG
|
#ifndef __SG
|
||||||
#define __SG
|
#define __SG
|
||||||
|
|
||||||
|
@ -31,6 +34,51 @@ int scsi_enumerate_drives(void);
|
||||||
|
|
||||||
int sg_drive_is_open(struct burn_drive * d);
|
int sg_drive_is_open(struct burn_drive * d);
|
||||||
|
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes);
|
int burn_os_is_2k_seekrw(char *path, int flag);
|
||||||
|
|
||||||
|
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities.
|
||||||
|
This call is usable even if sg_initialize() was not called yet. In that
|
||||||
|
case a preliminary constant message might be issued if detailed info is
|
||||||
|
not available yet.
|
||||||
|
@param msg returns id string
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_id_string(char msg[1024], int flag);
|
||||||
|
|
||||||
|
/* ts A91225 */
|
||||||
|
/** Performs global initialization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Checks for compatibility supporting
|
||||||
|
software components.
|
||||||
|
@param msg returns ids and/or error messages of eventual helpers
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_initialize(char msg[1024], int flag);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
|
needed operating system facilities. Releases globally acquired resources.
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_shutdown(int flag);
|
||||||
|
|
||||||
|
/* ts A91227 */
|
||||||
|
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
||||||
|
struct burn_drive which are defined in os-*.h.
|
||||||
|
The eventual initialization of those components was made underneath
|
||||||
|
scsi_enumerate_drives().
|
||||||
|
This will be called when a burn_drive gets disposed.
|
||||||
|
@param d the drive to be finalized
|
||||||
|
@param flag unused yet, submit 0
|
||||||
|
@return 1 = success, <=0 = failure
|
||||||
|
*/
|
||||||
|
int sg_dispose_drive(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __SG */
|
#endif /* __SG */
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "structure.h"
|
#include "structure.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
void burn_source_free(struct burn_source *src)
|
void burn_source_free(struct burn_source *src)
|
||||||
{
|
{
|
||||||
|
@ -31,12 +42,10 @@ struct burn_source *burn_source_new(void)
|
||||||
{
|
{
|
||||||
struct burn_source *out;
|
struct burn_source *out;
|
||||||
|
|
||||||
out = calloc(1, sizeof(struct burn_source));
|
/* ts A70825 , B11219 */
|
||||||
|
out = burn_alloc_mem(sizeof(struct burn_source), 1, 0);
|
||||||
/* ts A70825 */
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
memset((char *) out, 0, sizeof(struct burn_source));
|
|
||||||
|
|
||||||
out->refcount = 1;
|
out->refcount = 1;
|
||||||
return out;
|
return out;
|
||||||
|
@ -53,3 +62,15 @@ int burn_source_cancel(struct burn_source *src)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B00922 */
|
||||||
|
int burn_source_read(struct burn_source *src, unsigned char *buffer, int size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (src->read != NULL)
|
||||||
|
ret = src->read(src, buffer, size);
|
||||||
|
else
|
||||||
|
ret = src->read_xt(src, buffer, size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -7,4 +7,6 @@ struct burn_source *burn_source_new(void);
|
||||||
|
|
||||||
int burn_source_cancel(struct burn_source *src);
|
int burn_source_cancel(struct burn_source *src);
|
||||||
|
|
||||||
|
int burn_source_read(struct burn_source *src, unsigned char *buffer, int size);
|
||||||
|
|
||||||
#endif /*__SOURCE*/
|
#endif /*__SOURCE*/
|
||||||
|
|
1844
libburn/spc.c
1844
libburn/spc.c
File diff suppressed because it is too large
Load Diff
132
libburn/spc.h
132
libburn/spc.h
|
@ -1,5 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SPC
|
#ifndef __SPC
|
||||||
#define __SPC
|
#define __SPC
|
||||||
|
|
||||||
|
@ -15,14 +21,21 @@ void spc_select_error_params(struct burn_drive *,
|
||||||
void spc_getcaps(struct burn_drive *d);
|
void spc_getcaps(struct burn_drive *d);
|
||||||
void spc_sense_write_params(struct burn_drive *);
|
void spc_sense_write_params(struct burn_drive *);
|
||||||
void spc_select_write_params(struct burn_drive *,
|
void spc_select_write_params(struct burn_drive *,
|
||||||
|
struct burn_session *, int,
|
||||||
const struct burn_write_opts *);
|
const struct burn_write_opts *);
|
||||||
|
|
||||||
|
#ifdef Libburn_enable_scsi_cmd_ABh
|
||||||
|
int spc_read_media_serial_number(struct burn_drive *d);
|
||||||
|
#endif
|
||||||
|
|
||||||
void spc_probe_write_modes(struct burn_drive *);
|
void spc_probe_write_modes(struct burn_drive *);
|
||||||
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
|
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
|
||||||
int spc_block_type(enum burn_block_types b);
|
int spc_block_type(enum burn_block_types b);
|
||||||
int spc_get_erase_progress(struct burn_drive *d);
|
int spc_get_erase_progress(struct burn_drive *d);
|
||||||
|
|
||||||
/* ts A70315 : test_unit_ready with result parameters */
|
/* ts A70315 : test_unit_ready with result parameters */
|
||||||
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq);
|
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
|
||||||
|
int *progress);
|
||||||
|
|
||||||
int spc_test_unit_ready(struct burn_drive *d);
|
int spc_test_unit_ready(struct burn_drive *d);
|
||||||
|
|
||||||
|
@ -43,7 +56,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||||
int channel_no, int target_no, int lun_no, int flag);
|
int channel_no, int target_no, int lun_no, int flag);
|
||||||
|
|
||||||
/* ts A61115 moved from sg-*.h */
|
/* ts A61115 moved from sg-*.h */
|
||||||
enum response { RETRY, FAIL };
|
enum response { RETRY, FAIL, GO_ON };
|
||||||
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
||||||
|
|
||||||
/* ts A61122 */
|
/* ts A61122 */
|
||||||
|
@ -59,4 +72,119 @@ int scsi_notify_error(struct burn_drive *, struct command *c,
|
||||||
/* ts A70519 */
|
/* ts A70519 */
|
||||||
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
||||||
|
|
||||||
|
/* ts A91106 */
|
||||||
|
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
/** Logs command (before execution). */
|
||||||
|
int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
|
||||||
|
unsigned char *data, int bytes,
|
||||||
|
void *fp_in, int flag);
|
||||||
|
|
||||||
|
/* ts B40731 */
|
||||||
|
/* Arbitrary SCSI log message */
|
||||||
|
int scsi_log_text(char *text, void *fp_in, int flag);
|
||||||
|
|
||||||
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
|
/** Legacy frontend to scsi_log_command() */
|
||||||
|
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
/** Logs outcome of a sg command.
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
|
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
|
||||||
|
int dxfer_len, void *fp_in, unsigned char sense[18],
|
||||||
|
int sense_len, double duration, int flag);
|
||||||
|
|
||||||
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
|
/** Legacy frontend to scsi_log_reply().
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
|
int scsi_log_err(struct burn_drive *d, struct command *c,
|
||||||
|
void *fp, unsigned char sense[18],
|
||||||
|
int sense_len, int flag);
|
||||||
|
|
||||||
|
/* ts B31112 */
|
||||||
|
int scsi_log_message(struct burn_drive *d, void *fp, char * msg, int flag);
|
||||||
|
|
||||||
|
/* ts B00728 */
|
||||||
|
int spc_decode_sense(unsigned char *sense, int senselen,
|
||||||
|
int *key, int *asc, int *ascq);
|
||||||
|
|
||||||
|
/* ts B90206 */
|
||||||
|
char *spc_command_name(unsigned int c, int flag);
|
||||||
|
|
||||||
|
/* ts B90511 */
|
||||||
|
int spc_human_readable_cmd(struct command *c, char *msg, int msg_max,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
/* ts B90616 */
|
||||||
|
void spc_register_retry(struct command *c);
|
||||||
|
|
||||||
|
/* ts B00808 */
|
||||||
|
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
|
||||||
|
and issues DEBUG error message in case the command is evaluated as done.
|
||||||
|
@param flag bit1 = do not print duration
|
||||||
|
@return 0 = not yet done , 1 = done , -1 = error
|
||||||
|
*/
|
||||||
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
|
||||||
|
unsigned char *sense, int sense_len,
|
||||||
|
time_t start_time, int timeout_ms,
|
||||||
|
int loop_count, int flag);
|
||||||
|
|
||||||
|
/* ts B40204 */
|
||||||
|
/* Verify by INQUIRY that the drive is indeed a MMC device.
|
||||||
|
*/
|
||||||
|
int spc_confirm_cd_drive(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
|
Before each retry wait Libburn_scsi_retry_incR longer than with
|
||||||
|
the previous one. At most wait for Libburn_scsi_retry_umaX microseconds.
|
||||||
|
*/
|
||||||
|
#define Libburn_scsi_retry_usleeP 100000
|
||||||
|
#define Libburn_scsi_retry_incR 100000
|
||||||
|
#define Libburn_scsi_retry_umaX 500000
|
||||||
|
|
||||||
|
/* The retry waiting time for commands WRITE(10) and WRITE(12).
|
||||||
|
*/
|
||||||
|
#define Libburn_scsi_write_retry_usleeP 0
|
||||||
|
#define Libburn_scsi_write_retry_incR 2000
|
||||||
|
#define Libburn_scsi_write_retry_umaX 25000
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11124 */
|
||||||
|
/* Millisecond timeout for quickly responding SPC, SBC, and MMC commands */
|
||||||
|
#define Libburn_scsi_default_timeouT 30000
|
||||||
|
|
||||||
|
/* WRITE(10) and WRITE(12) */
|
||||||
|
#define Libburn_scsi_write_timeouT 200000
|
||||||
|
|
||||||
|
/* RESERVE TRACK */
|
||||||
|
#define Libburn_mmc_reserve_timeouT 200000
|
||||||
|
|
||||||
|
/* CLOSE TRACK/SESSION with Immed bit */
|
||||||
|
#define Libburn_mmc_close_timeouT 200000
|
||||||
|
/* CLOSE TRACK/SESSION without Immed bit */
|
||||||
|
#define Libburn_mmc_close_noim_timeouT 3600000
|
||||||
|
|
||||||
|
/* BLANK , FORMAT UNIT with Immed bit */
|
||||||
|
#define Libburn_mmc_blank_timeouT 200000
|
||||||
|
/* BLANK , FORMAT UNIT without Immed bit */
|
||||||
|
#define Libburn_mmc_blank_noim_timeouT 18000000
|
||||||
|
|
||||||
|
/* SEND OPC INFORMATION */
|
||||||
|
#define Libburn_mmc_opc_timeouT 200000
|
||||||
|
|
||||||
|
/* MMC_SYNC_CACHE with Immed bit */
|
||||||
|
#define Libburn_mmc_sync_timeouT 200000
|
||||||
|
/* MMC_SYNC_CACHE without Immed bit */
|
||||||
|
#define Libburn_mmc_sync_noim_timeouT 3600000
|
||||||
|
|
||||||
|
/* START STOP UNIT with Start bit and Load bit set */
|
||||||
|
#define Libburn_mmc_load_timeouT 300000
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
|
1691
libburn/structure.c
1691
libburn/structure.c
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,9 @@
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef BURN__STRUCTURE_H
|
#ifndef BURN__STRUCTURE_H
|
||||||
#define BURN__STRUCTURE_H
|
#define BURN__STRUCTURE_H
|
||||||
|
|
||||||
|
@ -10,13 +16,32 @@ struct isrc
|
||||||
unsigned int serial; /* must be 0-99999 */
|
unsigned int serial; /* must be 0-99999 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
#define Libburn_pack_type_basE 0x80
|
||||||
|
#define Libburn_pack_num_typeS 0x10
|
||||||
|
#define Libburn_pack_type_nameS \
|
||||||
|
"TITLE", "PERFORMER", "SONGWRITER", "COMPOSER", \
|
||||||
|
"ARRANGER", "MESSAGE", "DISCID", "GENRE", \
|
||||||
|
"TOC", "TOC2", "", "", \
|
||||||
|
"", "CLOSED", "UPC_ISRC", "BLOCKSIZE"
|
||||||
|
|
||||||
|
struct burn_cdtext
|
||||||
|
{
|
||||||
|
unsigned char *(payload[Libburn_pack_num_typeS]);
|
||||||
|
int length[Libburn_pack_num_typeS];
|
||||||
|
int flags; /* bit0 - bit15= double byte characters */
|
||||||
|
};
|
||||||
|
|
||||||
struct burn_track
|
struct burn_track
|
||||||
{
|
{
|
||||||
int refcnt;
|
int refcnt;
|
||||||
struct burn_toc_entry *entry;
|
struct burn_toc_entry *entry;
|
||||||
unsigned char indices;
|
unsigned char indices;
|
||||||
/* lba address of the index */
|
/* lba address of the index. CD only. 0x7fffffff means undefined index.
|
||||||
unsigned int index[99];
|
To be programmed relative to track source start before burning,
|
||||||
|
but to hold absolute addresses after burning or reading.
|
||||||
|
*/
|
||||||
|
int index[100];
|
||||||
/** number of 0 bytes to write before data */
|
/** number of 0 bytes to write before data */
|
||||||
int offset;
|
int offset;
|
||||||
/** how much offset has been used */
|
/** how much offset has been used */
|
||||||
|
@ -28,7 +53,7 @@ struct burn_track
|
||||||
/** 1 means Pad with zeros, 0 means start reading the next track */
|
/** 1 means Pad with zeros, 0 means start reading the next track */
|
||||||
int pad;
|
int pad;
|
||||||
|
|
||||||
/* ts A70213 : wether to expand this track to full available media */
|
/* ts A70213 : whether to expand this track to full available media */
|
||||||
int fill_up_media;
|
int fill_up_media;
|
||||||
|
|
||||||
/* ts A70218 : a track size to use if it is mandarory to have some */
|
/* ts A70218 : a track size to use if it is mandarory to have some */
|
||||||
|
@ -49,6 +74,14 @@ struct burn_track
|
||||||
int open_ended;
|
int open_ended;
|
||||||
/** End of open ended track flag : offset+payload+tail are delivered */
|
/** End of open ended track flag : offset+payload+tail are delivered */
|
||||||
int track_data_done;
|
int track_data_done;
|
||||||
|
/* ts B10103 */
|
||||||
|
/** End track writing on premature End-of-input if source is of
|
||||||
|
defined length.
|
||||||
|
0= normal operation in case of eoi
|
||||||
|
1= be ready to end track writing on eoi
|
||||||
|
2= eoi was encountered with previously set value of 1
|
||||||
|
*/
|
||||||
|
int end_on_premature_eoi;
|
||||||
|
|
||||||
/** The audio/data mode for the entry. Derived from control and
|
/** The audio/data mode for the entry. Derived from control and
|
||||||
possibly from reading the track's first sector. */
|
possibly from reading the track's first sector. */
|
||||||
|
@ -57,13 +90,30 @@ struct burn_track
|
||||||
int pregap1;
|
int pregap1;
|
||||||
/** The track contains interval two of a pregap */
|
/** The track contains interval two of a pregap */
|
||||||
int pregap2;
|
int pregap2;
|
||||||
|
|
||||||
|
/* ts B20110 */
|
||||||
|
/** The number of sectors in pre-gap 2, if .pregap2 is set */
|
||||||
|
int pregap2_size;
|
||||||
|
|
||||||
/** The track contains a postgap */
|
/** The track contains a postgap */
|
||||||
int postgap;
|
int postgap;
|
||||||
|
|
||||||
|
/* ts B20111 */
|
||||||
|
/** The number of sectors in post-gap, if .postgap is set */
|
||||||
|
int postgap_size;
|
||||||
|
|
||||||
struct isrc isrc;
|
struct isrc isrc;
|
||||||
|
|
||||||
/* ts A61024 */
|
/* ts A61024 */
|
||||||
/** Byte swapping on source data stream : 0=none , 1=pairwise */
|
/** Byte swapping on source data stream : 0=none , 1=pairwise */
|
||||||
int swap_source_bytes;
|
int swap_source_bytes;
|
||||||
|
|
||||||
|
/* ts A90910 : conversions from CD XA prepared input */
|
||||||
|
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *cdtext[8];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_session
|
struct burn_session
|
||||||
|
@ -79,12 +129,26 @@ struct burn_session
|
||||||
int tracks;
|
int tracks;
|
||||||
struct burn_track **track;
|
struct burn_track **track;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *cdtext[8];
|
||||||
|
unsigned char cdtext_char_code[8];
|
||||||
|
unsigned char cdtext_copyright[8];
|
||||||
|
unsigned char cdtext_language[8];
|
||||||
|
|
||||||
|
/* ts B11226 */
|
||||||
|
unsigned char mediacatalog[14]; /* overridable by burn_write_opts */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_disc
|
struct burn_disc
|
||||||
{
|
{
|
||||||
int sessions;
|
int sessions;
|
||||||
struct burn_session **session;
|
struct burn_session **session;
|
||||||
|
|
||||||
|
#ifdef Libburn_disc_with_incomplete_sessioN
|
||||||
|
int incomplete_sessions;
|
||||||
|
#endif
|
||||||
|
|
||||||
int refcnt;
|
int refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,7 +160,7 @@ int burn_track_is_open_ended(struct burn_track *t);
|
||||||
int burn_track_is_data_done(struct burn_track *t);
|
int burn_track_is_data_done(struct burn_track *t);
|
||||||
|
|
||||||
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
|
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
|
||||||
int burn_track_set_sectors(struct burn_track *t, int sectors);
|
int burn_track_set_sectors(struct burn_track *t, off_t sectors);
|
||||||
|
|
||||||
/* ts A70218 : sets the payload size alone */
|
/* ts A70218 : sets the payload size alone */
|
||||||
int burn_track_set_size(struct burn_track *t, off_t size);
|
int burn_track_set_size(struct burn_track *t, off_t size);
|
||||||
|
@ -110,7 +174,18 @@ off_t burn_track_get_default_size(struct burn_track *t);
|
||||||
|
|
||||||
|
|
||||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||||
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
|
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11206 */
|
||||||
|
struct burn_cdtext *burn_cdtext_create(void);
|
||||||
|
void burn_cdtext_free(struct burn_cdtext **cdtext);
|
||||||
|
|
||||||
|
/* ts B20119 */
|
||||||
|
/* @param flag bit0= do not add post-gap
|
||||||
|
*/
|
||||||
|
int burn_track_get_sectors_2(struct burn_track *t, int flag);
|
||||||
|
off_t burn_track_get_sectors_2_v2(struct burn_track *t, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__STRUCTURE_H */
|
#endif /* BURN__STRUCTURE_H */
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2011 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
@ -11,6 +21,7 @@
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "sector.h"
|
#include "sector.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void write_clonecd2(volatile struct toc *toc, int f);
|
static void write_clonecd2(volatile struct toc *toc, int f);
|
||||||
|
@ -94,17 +105,14 @@ static void write_clonecd2(volatile struct toc *toc, int f)
|
||||||
|
|
||||||
void toc_find_modes(struct burn_drive *d)
|
void toc_find_modes(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct burn_read_opts o;
|
|
||||||
int lba;
|
|
||||||
int i, j;
|
int i, j;
|
||||||
struct buffer mem;
|
struct buffer *mem = NULL;
|
||||||
struct burn_toc_entry *e;
|
struct burn_toc_entry *e;
|
||||||
|
|
||||||
/* ts A61008 : to be prevented on the higher levels */
|
/* ts A70519 : the code which needs this does not work with GNU/Linux 2.4 USB
|
||||||
/* a ssert(d->busy); */
|
int lba;
|
||||||
|
struct burn_read_opts o;
|
||||||
|
|
||||||
mem.bytes = 0;
|
|
||||||
mem.sectors = 1;
|
|
||||||
o.raw = 1;
|
o.raw = 1;
|
||||||
o.c2errors = 0;
|
o.c2errors = 0;
|
||||||
o.subcodes_audio = 1;
|
o.subcodes_audio = 1;
|
||||||
|
@ -113,29 +121,42 @@ void toc_find_modes(struct burn_drive *d)
|
||||||
o.report_recovered_errors = 0;
|
o.report_recovered_errors = 0;
|
||||||
o.transfer_damaged_blocks = 1;
|
o.transfer_damaged_blocks = 1;
|
||||||
o.hardware_error_retries = 1;
|
o.hardware_error_retries = 1;
|
||||||
|
*/
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM_VOID(mem, struct buffer, 1);
|
||||||
|
|
||||||
|
mem->bytes = 0;
|
||||||
|
mem->sectors = 1;
|
||||||
|
|
||||||
for (i = 0; i < d->disc->sessions; i++)
|
for (i = 0; i < d->disc->sessions; i++)
|
||||||
for (j = 0; j < d->disc->session[i]->tracks; j++) {
|
for (j = 0; j < d->disc->session[i]->tracks; j++) {
|
||||||
struct burn_track *t = d->disc->session[i]->track[j];
|
struct burn_track *t = d->disc->session[i]->track[j];
|
||||||
|
|
||||||
e = t->entry;
|
e = t->entry;
|
||||||
if (!e)
|
|
||||||
lba = 0;
|
|
||||||
else
|
|
||||||
lba = burn_msf_to_lba(e->pmin, e->psec,
|
|
||||||
e->pframe);
|
|
||||||
/* XXX | in the subcodes if appropriate! */
|
/* XXX | in the subcodes if appropriate! */
|
||||||
if (e && !(e->control & 4)) {
|
if (e && !(e->control & 4)) {
|
||||||
t->mode = BURN_AUDIO;
|
t->mode = BURN_AUDIO;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
t->mode = BURN_MODE1;
|
t->mode = BURN_MODE1;
|
||||||
/* ts A70519 : this does not work with Linux 2.4 USB because one cannot
|
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
|
||||||
predict the exact dxfer_size without knowing the sector type.
|
predict the exact dxfer_size without knowing the sector type.
|
||||||
mem.sectors = 1;
|
if (!e)
|
||||||
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
lba = 0;
|
||||||
t->mode = sector_identify(mem.data);
|
else
|
||||||
|
lba = burn_msf_to_lba(e->pmin, e->psec,
|
||||||
|
e->pframe);
|
||||||
|
mem->sectors = 1;
|
||||||
|
|
||||||
|
ts B21119 : Would now be d->read_cd() with
|
||||||
|
with sectype = 0 , mainch = 0xf8
|
||||||
|
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
||||||
|
|
||||||
|
t->mode = sector_identify(mem->data);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ex:
|
||||||
|
BURN_FREE_MEM(mem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TOC_H
|
#ifndef __TOC_H
|
||||||
#define __TOC_H
|
#define __TOC_H
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TRANSPORT
|
#ifndef __TRANSPORT
|
||||||
#define __TRANSPORT
|
#define __TRANSPORT
|
||||||
|
|
||||||
|
@ -40,7 +46,9 @@ struct buffer
|
||||||
Added 4096 bytes reserve against possible buffer overflows.
|
Added 4096 bytes reserve against possible buffer overflows.
|
||||||
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
||||||
This can at most cause a 1 sector overlap. Sometimes an offset
|
This can at most cause a 1 sector overlap. Sometimes an offset
|
||||||
of 16 byte is applied to the output data (in some RAW mode). ) */
|
of 16 byte is applied to the output data (in some RAW mode). )
|
||||||
|
burn_write_opts.cdxa_conversion can imply an offset of 8 bytes.
|
||||||
|
*/
|
||||||
unsigned char data[BUFFER_SIZE + 4096];
|
unsigned char data[BUFFER_SIZE + 4096];
|
||||||
int sectors;
|
int sectors;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
@ -53,22 +61,40 @@ struct command
|
||||||
int dir;
|
int dir;
|
||||||
int dxfer_len;
|
int dxfer_len;
|
||||||
unsigned char sense[128];
|
unsigned char sense[128];
|
||||||
|
int sense_len;
|
||||||
int error;
|
int error;
|
||||||
int retry;
|
int retry;
|
||||||
struct buffer *page;
|
struct buffer *page;
|
||||||
|
int timeout; /* milliseconds */
|
||||||
|
|
||||||
|
double start_time;
|
||||||
|
double end_time;
|
||||||
|
|
||||||
|
int retry_count;
|
||||||
|
int last_retry_key;
|
||||||
|
int last_retry_asc;
|
||||||
|
int last_retry_ascq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_scsi_inquiry_data
|
struct burn_scsi_inquiry_data
|
||||||
{
|
{
|
||||||
|
char peripheral; /* bit0-4: device type should be 5
|
||||||
|
bit5-7: qualifier must be 0 */
|
||||||
|
|
||||||
|
char version; /* should be 3 (SPC-1) to 5 (SPC-3) (or higher ?)
|
||||||
|
but is often 0. */
|
||||||
|
|
||||||
char vendor[9];
|
char vendor[9];
|
||||||
char product[17];
|
char product[17];
|
||||||
char revision[5];
|
char revision[5];
|
||||||
|
|
||||||
int valid;
|
int valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct scsi_mode_data
|
struct scsi_mode_data
|
||||||
{
|
{
|
||||||
|
int p2a_valid;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
int dvdram_read;
|
int dvdram_read;
|
||||||
int dvdram_write;
|
int dvdram_write;
|
||||||
|
@ -80,8 +106,13 @@ struct scsi_mode_data
|
||||||
int cdr_read;
|
int cdr_read;
|
||||||
int cdr_write;
|
int cdr_write;
|
||||||
int simulate;
|
int simulate;
|
||||||
|
int c2_pointers;
|
||||||
|
int underrun_proof;
|
||||||
|
|
||||||
int max_read_speed;
|
int max_read_speed;
|
||||||
|
int cur_read_speed;
|
||||||
int max_write_speed;
|
int max_write_speed;
|
||||||
|
int cur_write_speed;
|
||||||
|
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
int min_write_speed;
|
int min_write_speed;
|
||||||
|
@ -92,15 +123,10 @@ struct scsi_mode_data
|
||||||
int max_end_lba;
|
int max_end_lba;
|
||||||
struct burn_speed_descriptor *speed_descriptors;
|
struct burn_speed_descriptor *speed_descriptors;
|
||||||
|
|
||||||
int cur_read_speed;
|
|
||||||
int cur_write_speed;
|
|
||||||
int retry_page_length;
|
int retry_page_length;
|
||||||
int retry_page_valid;
|
int retry_page_valid;
|
||||||
int write_page_length;
|
int write_page_length;
|
||||||
int write_page_valid;
|
int write_page_valid;
|
||||||
int c2_pointers;
|
|
||||||
int valid;
|
|
||||||
int underrun_proof;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,6 +144,26 @@ struct burn_format_descr {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B40106 : represents a Feature Descriptor as of mmc5r03c.pdf 5.2.2
|
||||||
|
There can be many of them. Thus a linked list.
|
||||||
|
*/
|
||||||
|
struct burn_feature_descr {
|
||||||
|
unsigned short feature_code;
|
||||||
|
|
||||||
|
unsigned char flags; /* bit0= current
|
||||||
|
bit1= persistent
|
||||||
|
bit2-5= version
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char data_lenght;
|
||||||
|
|
||||||
|
/* Additional bytes after the first 4 bytes of the descriptor */
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
struct burn_feature_descr *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Gets initialized in enumerate_common() and burn_drive_register() */
|
/** Gets initialized in enumerate_common() and burn_drive_register() */
|
||||||
struct burn_drive
|
struct burn_drive
|
||||||
{
|
{
|
||||||
|
@ -126,6 +172,8 @@ struct burn_drive
|
||||||
1=MMC drive ,
|
1=MMC drive ,
|
||||||
2=stdio random read-write
|
2=stdio random read-write
|
||||||
3=stdio sequential write-only
|
3=stdio sequential write-only
|
||||||
|
4=stdio random read-only
|
||||||
|
5=stdio random write-only
|
||||||
*/
|
*/
|
||||||
int drive_role;
|
int drive_role;
|
||||||
|
|
||||||
|
@ -167,12 +215,24 @@ struct burn_drive
|
||||||
unsigned char all_profiles[256];
|
unsigned char all_profiles[256];
|
||||||
int num_profiles;
|
int num_profiles;
|
||||||
|
|
||||||
|
/* ts B40106 : All feature descriptors as read from drive */
|
||||||
|
struct burn_feature_descr *features;
|
||||||
|
|
||||||
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
||||||
Quite internal. Regard as opaque :)
|
Quite internal. Regard as opaque :)
|
||||||
*/
|
*/
|
||||||
/* 1 = incremental recording available, 0 = not available */
|
/* 1 = incremental recording available, 0 = not available */
|
||||||
int current_has_feat21h;
|
int current_has_feat21h;
|
||||||
|
|
||||||
|
/* Some drives announce feature 21h on fast-blanked DVD-RW
|
||||||
|
although they cannot write them in Incremental mode.
|
||||||
|
0= does not look like the recent write run failed due to
|
||||||
|
Incremental on fast blanked DVD-RW
|
||||||
|
1= it seems to have happened
|
||||||
|
2= it seems to have happened with write address 0
|
||||||
|
*/
|
||||||
|
int was_feat21h_failure;
|
||||||
|
|
||||||
/* Link Size item number 0 from feature 0021h descriptor */
|
/* Link Size item number 0 from feature 0021h descriptor */
|
||||||
int current_feat21h_link_size;
|
int current_feat21h_link_size;
|
||||||
|
|
||||||
|
@ -198,11 +258,26 @@ struct burn_drive
|
||||||
*/
|
*/
|
||||||
int current_feat2fh_byte4;
|
int current_feat2fh_byte4;
|
||||||
|
|
||||||
|
/* ts B51016 : Result from feature 108h : Drive Serial Number
|
||||||
|
*/
|
||||||
|
char *drive_serial_number;
|
||||||
|
int drive_serial_number_len;
|
||||||
|
|
||||||
|
/* ts B51016 : Result from command AB READ MEDIA SERIAL NUMBER
|
||||||
|
*/
|
||||||
|
char *media_serial_number;
|
||||||
|
int media_serial_number_len;
|
||||||
|
|
||||||
|
/* ts B10524 : whether the damage bit was set for the future track.
|
||||||
|
bit0= damage bit , bit1= nwa valid bit
|
||||||
|
*/
|
||||||
|
int next_track_damaged;
|
||||||
|
|
||||||
/* ts A70114 : whether a DVD-RW media holds an incomplete session
|
/* ts A70114 : whether a DVD-RW media holds an incomplete session
|
||||||
(which could need closing after write) */
|
(which could need closing after write) */
|
||||||
int needs_close_session;
|
int needs_close_session;
|
||||||
/* ts A71003 : whether a random write operation was done and no
|
/* ts A71003 : whether a random write operation was done and no
|
||||||
synchronize chache has happened yet */
|
synchronize cache has happened yet */
|
||||||
int needs_sync_cache;
|
int needs_sync_cache;
|
||||||
|
|
||||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||||
|
@ -216,7 +291,19 @@ struct burn_drive
|
||||||
int stream_recording_start;
|
int stream_recording_start;
|
||||||
|
|
||||||
/* ts A61218 from 51h READ DISC INFORMATION */
|
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||||
|
int last_lead_in;
|
||||||
|
int last_lead_out;
|
||||||
|
int num_opc_tables; /* ts A91104: -1= not yet known */
|
||||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||||
|
int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */
|
||||||
|
unsigned int disc_id; /* a "32 bit binary integer" */
|
||||||
|
char disc_bar_code[9];
|
||||||
|
int disc_app_code;
|
||||||
|
int disc_info_valid; /* bit0= disc_type , bit1= disc_id ,
|
||||||
|
bit2= disc_bar_code , bit3= disc_app_code
|
||||||
|
bit4= URU bit is set (= unrestricted use)
|
||||||
|
bit5= Erasable bit was set in reply
|
||||||
|
*/
|
||||||
|
|
||||||
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
||||||
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
|
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
|
||||||
|
@ -233,25 +320,48 @@ struct burn_drive
|
||||||
volatile int released;
|
volatile int released;
|
||||||
|
|
||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
|
/* 0= report errors
|
||||||
|
1= do not report errors
|
||||||
|
2= do not report errors which the libburn function indicates in
|
||||||
|
member .had_particular_error
|
||||||
|
3= report errors with severity DEBUG
|
||||||
|
*/
|
||||||
int silent_on_scsi_error;
|
int silent_on_scsi_error;
|
||||||
|
|
||||||
|
/* ts B21023 */
|
||||||
|
/* bit0= 5 64 00 occurred with READ10 in mmc_read_10()
|
||||||
|
*/
|
||||||
|
int had_particular_error;
|
||||||
|
|
||||||
int stdio_fd;
|
int stdio_fd;
|
||||||
|
|
||||||
int nwa; /* next writeable address */
|
off_t nwa; /* next writeable address */
|
||||||
int alba; /* absolute lba */
|
int alba; /* absolute lba */
|
||||||
int rlba; /* relative lba in section */
|
int rlba; /* relative lba in section */
|
||||||
int start_lba;
|
int start_lba;
|
||||||
int end_lba;
|
int end_lba;
|
||||||
|
|
||||||
|
/* ts B61116 */
|
||||||
|
int do_simulate;
|
||||||
|
|
||||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||||
int complete_sessions;
|
int complete_sessions;
|
||||||
/* ts A90107 */
|
/* ts A90107 */
|
||||||
int state_of_last_session;
|
int state_of_last_session;
|
||||||
|
|
||||||
|
#ifdef Libburn_disc_with_incomplete_sessioN
|
||||||
|
/* ts B30112 */
|
||||||
|
int incomplete_sessions;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ts A70129 :
|
/* ts A70129 :
|
||||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||||
int last_track_no;
|
int last_track_no;
|
||||||
|
|
||||||
|
/* ts B10730 : whether a default mode page 05 was already sent.
|
||||||
|
*/
|
||||||
|
int sent_default_page_05;
|
||||||
/* ts A70212 : from various sources : free space on media (in bytes)
|
/* ts A70212 : from various sources : free space on media (in bytes)
|
||||||
With CD this might change after particular write
|
With CD this might change after particular write
|
||||||
parameters have been set and nwa has been inquired.
|
parameters have been set and nwa has been inquired.
|
||||||
|
@ -261,15 +371,40 @@ struct burn_drive
|
||||||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
/* ts A81210 : Upper limit of readable data size,
|
/* ts A81210 / C40303 : Upper limit of readable data size,
|
||||||
0x7fffffff = unknown */
|
0x7fffffffffffffff = unknown
|
||||||
int media_read_capacity;
|
BURN_DRIVE_MAX_BYTES / 2048 = possibly truncated
|
||||||
|
or unknown stdio size
|
||||||
|
*/
|
||||||
|
off_t media_read_capacity;
|
||||||
|
|
||||||
|
/* ts B60305 : Whether READ CAPACITY of CD is credible:
|
||||||
|
-1= no READ CAPACITY yet , 0= untrusted READ CAPACITY
|
||||||
|
1= READ CAPACITY confirmed or corrected by other commands
|
||||||
|
*/
|
||||||
|
int mr_capacity_trusted;
|
||||||
|
|
||||||
|
/* ts B10314 / C40302 : Next Writeable Address for drive_role == 5 */
|
||||||
|
off_t role_5_nwa;
|
||||||
|
|
||||||
|
/* ts B60730 */
|
||||||
|
int do_no_immed;
|
||||||
|
|
||||||
int toc_temp;
|
int toc_temp;
|
||||||
struct burn_disc *disc; /* disc structure */
|
struct burn_disc *disc; /* disc structure */
|
||||||
int block_types[4];
|
int block_types[4];
|
||||||
struct buffer *buffer;
|
struct buffer *buffer;
|
||||||
struct burn_progress progress;
|
struct burn_progress_v2 progress;
|
||||||
|
|
||||||
|
/* To be used by mmc.c, sbc.c, spc.c for SCSI commands where the struct
|
||||||
|
content surely does not have to persist while another command gets
|
||||||
|
composed and executed.
|
||||||
|
(Inherently, sending SCSI commands to the same drive cannot be
|
||||||
|
thread-safe. But there are functions which send SCSI commands
|
||||||
|
and also call other such functions. These shall use own allocated
|
||||||
|
command structs and not this struct here.)
|
||||||
|
*/
|
||||||
|
struct command casual_command;
|
||||||
|
|
||||||
/* ts A70711 : keeping an eye on the drive buffer */
|
/* ts A70711 : keeping an eye on the drive buffer */
|
||||||
off_t pessimistic_buffer_free;
|
off_t pessimistic_buffer_free;
|
||||||
|
@ -289,10 +424,32 @@ struct burn_drive
|
||||||
volatile int cancel;
|
volatile int cancel;
|
||||||
volatile enum burn_drive_status busy;
|
volatile enum burn_drive_status busy;
|
||||||
|
|
||||||
|
/* During write runs, this points to a copy of the applied
|
||||||
|
struct burn_write_opts. Only read this underneath
|
||||||
|
burn_disc_write_sync() which removes the copy when done.
|
||||||
|
Especially do not read it from outside the write thread.
|
||||||
|
*/
|
||||||
|
struct burn_write_opts *write_opts;
|
||||||
|
|
||||||
/* ts A70929 */
|
/* ts A70929 */
|
||||||
pid_t thread_pid;
|
pid_t thread_pid;
|
||||||
int thread_pid_valid;
|
int thread_pid_valid;
|
||||||
|
/* ts B00225 */
|
||||||
|
pthread_t thread_tid;
|
||||||
|
|
||||||
|
/* ts B90513 */
|
||||||
|
unsigned int write_retry_count;
|
||||||
|
|
||||||
|
/* ts C00806 */
|
||||||
|
/* 0=no change, 1=change, -1=already urged OS to revalidate medium */
|
||||||
|
int medium_state_changed;
|
||||||
|
|
||||||
|
/* ts C00822 */
|
||||||
|
/* If set, use Exact bit with SET STREAMING and use SET STREAMING
|
||||||
|
even if the medium is a CD.
|
||||||
|
*/
|
||||||
|
int set_streaming_exact_bit;
|
||||||
|
int set_streaming_err;
|
||||||
|
|
||||||
/* transport functions */
|
/* transport functions */
|
||||||
int (*grab) (struct burn_drive *);
|
int (*grab) (struct burn_drive *);
|
||||||
|
@ -310,7 +467,7 @@ struct burn_drive
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
void (*read_atip) (struct burn_drive *);
|
void (*read_atip) (struct burn_drive *);
|
||||||
|
|
||||||
int (*write) (struct burn_drive *, int, struct buffer *);
|
int (*write) (struct burn_drive *, off_t, struct buffer *);
|
||||||
void (*read_toc) (struct burn_drive *);
|
void (*read_toc) (struct burn_drive *);
|
||||||
void (*lock) (struct burn_drive *);
|
void (*lock) (struct burn_drive *);
|
||||||
void (*unlock) (struct burn_drive *);
|
void (*unlock) (struct burn_drive *);
|
||||||
|
@ -323,17 +480,18 @@ struct burn_drive
|
||||||
int is_stopped;
|
int is_stopped;
|
||||||
|
|
||||||
void (*read_disc_info) (struct burn_drive *);
|
void (*read_disc_info) (struct burn_drive *);
|
||||||
void (*read_sectors) (struct burn_drive *,
|
int (*read_cd) (struct burn_drive *, int start, int len,
|
||||||
int start,
|
int sec_type, int main_ch,
|
||||||
int len,
|
const struct burn_read_opts *, struct buffer *,
|
||||||
const struct burn_read_opts *, struct buffer *);
|
int flag);
|
||||||
void (*perform_opc) (struct burn_drive *);
|
void (*perform_opc) (struct burn_drive *);
|
||||||
void (*set_speed) (struct burn_drive *, int, int);
|
void (*set_speed) (struct burn_drive *, int, int);
|
||||||
void (*send_parameters) (struct burn_drive *,
|
void (*send_parameters) (struct burn_drive *,
|
||||||
const struct burn_read_opts *);
|
const struct burn_read_opts *);
|
||||||
void (*send_write_parameters) (struct burn_drive *,
|
void (*send_write_parameters) (struct burn_drive *,
|
||||||
|
struct burn_session *, int tno,
|
||||||
const struct burn_write_opts *);
|
const struct burn_write_opts *);
|
||||||
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
int (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
||||||
|
|
||||||
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
|
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
|
||||||
int (*reserve_track) (struct burn_drive *d, off_t size);
|
int (*reserve_track) (struct burn_drive *d, off_t size);
|
||||||
|
|
417
libburn/util.c
417
libburn/util.c
|
@ -1,9 +1,26 @@
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
||||||
#include "v ersion.h"
|
#include "v ersion.h"
|
||||||
|
@ -12,42 +29,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
|
|
||||||
char *burn_strdup(char *s)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
/* ts A61008 */
|
|
||||||
/* a ssert(s); */
|
|
||||||
if (s == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
l = strlen(s) + 1;
|
|
||||||
ret = malloc(l);
|
|
||||||
memcpy(ret, s, l);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *burn_strndup(char *s, int n)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
/* ts A61008 */
|
|
||||||
/* a ssert(s); */
|
|
||||||
/* a ssert(n > 0); */
|
|
||||||
if (s == NULL || n <= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
l = strlen(s);
|
|
||||||
ret = malloc(l < n ? l : n);
|
|
||||||
|
|
||||||
memcpy(ret, s, l < n - 1 ? l : n - 1);
|
|
||||||
ret[n - 1] = '\0';
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void burn_version(int *major, int *minor, int *micro)
|
void burn_version(int *major, int *minor, int *micro)
|
||||||
{
|
{
|
||||||
|
@ -56,3 +37,367 @@ void burn_version(int *major, int *minor, int *micro)
|
||||||
*minor = burn_header_version_minor;
|
*minor = burn_header_version_minor;
|
||||||
*micro = burn_header_version_micro;
|
*micro = burn_header_version_micro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct cd_mid_record {
|
||||||
|
char *manufacturer;
|
||||||
|
int m_li;
|
||||||
|
int s_li;
|
||||||
|
int f_li;
|
||||||
|
char *other_brands;
|
||||||
|
};
|
||||||
|
typedef struct cd_mid_record cd_mid_record_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90902 */
|
||||||
|
/** API
|
||||||
|
@param flag Bitfield for control purposes,
|
||||||
|
bit0= append "(aka %s)",other_brands to reply
|
||||||
|
*/
|
||||||
|
char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
||||||
|
int m_lo, int s_lo, int f_lo, int flag)
|
||||||
|
{
|
||||||
|
static cd_mid_record_t mid_list[]= {
|
||||||
|
{"SKC", 96, 40, 0, ""},
|
||||||
|
{"Ritek Corp" , 96, 43, 30, ""},
|
||||||
|
{"TDK / Ritek" , 97, 10, 0, "TRAXDATA"},
|
||||||
|
{"TDK Corporation" , 97, 15, 0, ""},
|
||||||
|
{"Ritek Corp" , 97, 15, 10, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"},
|
||||||
|
{"Mitsubishi Chemical Corporation" , 97, 15, 20, ""},
|
||||||
|
{"Nan-Ya Plastics Corporation" , 97, 15, 30, "Hatron, MMore, Acer, LITEON"},
|
||||||
|
{"Delphi" , 97, 15, 50, ""},
|
||||||
|
{"Shenzhen SG&SAST" , 97, 16, 20, ""},
|
||||||
|
{"Moser Baer India Limited" , 97, 17, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"},
|
||||||
|
{"SKY media Manufacturing SA" , 97, 17, 10, ""},
|
||||||
|
{"Wing" , 97, 18, 10, ""},
|
||||||
|
{"DDT" , 97, 18, 20, ""},
|
||||||
|
{"Daxon Technology Inc. / Acer" , 97, 22, 60, "Maxmax, Diamond Data, BenQ, gold, SONY"},
|
||||||
|
{"Taiyo Yuden Company Limited" , 97, 24, 0, "Maxell, FUJIFILM, SONY"},
|
||||||
|
{"Sony Corporation" , 97, 24, 10, "LeadData, Imation"},
|
||||||
|
{"Computer Support Italcard s.r.l" , 97, 24, 20, ""},
|
||||||
|
{"Unitech Japan Inc." , 97, 24, 30, ""},
|
||||||
|
{"MPO, France" , 97, 25, 0, "TDK"},
|
||||||
|
{"Hitachi Maxell Ltd." , 97, 25, 20, ""},
|
||||||
|
{"Infodisc Technology Co,Ltd." , 97, 25, 30, "MEMOREX, SPEEDA, Lead data"},
|
||||||
|
{"Xcitec" , 97, 25, 60, ""},
|
||||||
|
{"Fornet International Pte Ltd" , 97, 26, 0, "COMPUSA, Cdhouse"},
|
||||||
|
{"Postech Corporation" , 97, 26, 10, "Mr.Platinum"},
|
||||||
|
{"SKC Co Ltd." , 97, 26, 20, "Infinite"},
|
||||||
|
{"Fuji Photo Film Co,Ltd." , 97, 26, 40, ""},
|
||||||
|
{"Lead Data Inc." , 97, 26, 50, "SONY, Gigastorage, MIRAGE"},
|
||||||
|
{"CMC Magnetics Corporation" , 97, 26, 60, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"},
|
||||||
|
{"Ricoh Company Limited" , 97, 27, 0, "Sony, Digital Storage, Csita"},
|
||||||
|
{"Plasmon Data Systems Ltd" , 97, 27, 10, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"},
|
||||||
|
{"Princo Corporation" , 97, 27, 20, ""},
|
||||||
|
{"Pioneer" , 97, 27, 30, ""},
|
||||||
|
{"Eastman Kodak Company" , 97, 27, 40, ""},
|
||||||
|
{"Mitsui Chemicals Inc." , 97, 27, 50, "MAM-A, TDK"},
|
||||||
|
{"Ricoh Company Limited" , 97, 27, 60, "Ritek"},
|
||||||
|
{"Gigastorage Corporation" , 97, 28, 10, "MaxMax, Nan-Ya"},
|
||||||
|
{"Multi Media Masters&Machinary SA" , 97, 28, 20, "King, Mmirex"},
|
||||||
|
{"Ritek Corp" , 97, 31, 0, "TDK"},
|
||||||
|
{"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, ""},
|
||||||
|
{"TDK Corporation" , 97, 32, 00, ""},
|
||||||
|
{"Prodisc Technology Inc." , 97, 32, 10, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"},
|
||||||
|
{"Mitsubishi Chemical Corporation" , 97, 34, 20, "YAMAHA, Verbatim"},
|
||||||
|
{"Mitsui Chemicals Inc." , 97, 48, 50, ""},
|
||||||
|
{"TDK Corporation" , 97, 49, 0, ""},
|
||||||
|
{"", 0, 0, 0, ""}
|
||||||
|
};
|
||||||
|
|
||||||
|
int i, f_li_0;
|
||||||
|
char buf[1024];
|
||||||
|
char *result = NULL;
|
||||||
|
|
||||||
|
if (m_li == 0 && s_li == 2 && f_li == 0) {
|
||||||
|
result = strdup("(no manufacturer code)");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
f_li_0 = f_li - (f_li % 10);
|
||||||
|
for (i = 0; mid_list[i].manufacturer[0]; i++) {
|
||||||
|
if (m_li == mid_list[i].m_li &&
|
||||||
|
s_li == mid_list[i].s_li &&
|
||||||
|
(f_li_0 == mid_list[i].f_li || f_li == mid_list[i].f_li))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mid_list[i].manufacturer[0] == 0) {
|
||||||
|
sprintf(buf, "Unknown CD manufacturer. Please report code '%2.2dm%2.2ds%2.2df/%2.2dm%2.2ds%2.2df', the human readable brand, size, and speed to scdbackup@gmx.net.", m_li, s_li, f_li, m_lo, s_lo, f_lo);
|
||||||
|
result = strdup(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compose, allocate and copy result */
|
||||||
|
if ((flag & 1) && mid_list[i].other_brands[0]) {
|
||||||
|
sprintf(buf, "%s (aka %s)",
|
||||||
|
mid_list[i].manufacturer, mid_list[i].other_brands);
|
||||||
|
result = strdup(buf);
|
||||||
|
} else
|
||||||
|
result = strdup(mid_list[i].manufacturer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90904 */
|
||||||
|
struct dvd_mid_record {
|
||||||
|
char *mc1;
|
||||||
|
int mc1_sig_len;
|
||||||
|
char *manufacturer;
|
||||||
|
};
|
||||||
|
typedef struct dvd_mid_record dvd_mid_record_t;
|
||||||
|
|
||||||
|
/* ts A90904 */
|
||||||
|
char *burn_guess_manufacturer(int prf,
|
||||||
|
char *media_code1, char *media_code2, int flag)
|
||||||
|
{
|
||||||
|
int i, l = 0, m_li, s_li, f_li, m_lo, s_lo, f_lo;
|
||||||
|
char buf[1024];
|
||||||
|
char *result = NULL, *cpt;
|
||||||
|
|
||||||
|
/* Important Note: media_code1 and media_code2 are supposed to be
|
||||||
|
encoded by burn_util_make_printable_word().
|
||||||
|
Especially: ' ' -> '_' , {"_%/" unprintables -> %XY)
|
||||||
|
*/
|
||||||
|
static dvd_mid_record_t mid_list[]= {
|
||||||
|
{"AML", 8, "UML"},
|
||||||
|
{"BeAll", 5, "BeAll Developers, Inc."},
|
||||||
|
{"CMC", 3, "CMC Magnetics Corporation"},
|
||||||
|
{"DAXON", 5, "Daxon Technology Inc. / Acer"},
|
||||||
|
{"Daxon", 5, "Daxon Technology Inc. / Acer"},
|
||||||
|
{"FUJI", 4, "Fujifilm Holdings Corporation"},
|
||||||
|
{"INFODISC", 8, "New Star Digital Co., Ltd."},
|
||||||
|
{"INFOME", 6, "InfoMedia Inc."},
|
||||||
|
{"ISMMBD", 6, "Info Source Multi Media Ltd."},
|
||||||
|
{"JVC", 3, "JVC Limited"},
|
||||||
|
{"KIC01RG", 7, "AMC"},
|
||||||
|
{"LD", 8, "Lead Data Inc."},
|
||||||
|
{"LGE", 3, "LG Electronics"},
|
||||||
|
{"MAM", 8, "Mitsui Advanced Media, Inc. Europe"},
|
||||||
|
{"MAXELL", 6, "Hitachi Maxell Ltd."},
|
||||||
|
{"MBI", 3, "Moser Baer India Limited"},
|
||||||
|
{"MCC", 8, "Mitsubishi Chemical Corporation"},
|
||||||
|
{"MCI", 8, "Mitsui Chemicals Inc."},
|
||||||
|
{"MEI", 3, "Panasonic Corporation"},
|
||||||
|
{"MILLEN", 8, "Millenniata Inc."},
|
||||||
|
{"MKM", 3, "Mitsubishi Kagaku Media Co."},
|
||||||
|
{"MMC", 8, "Mitsubishi Kagaku Media Co."},
|
||||||
|
{"MXL", 8, "Hitachi Maxell Ltd."},
|
||||||
|
{"NANYA", 5, "Nan-Ya Plastics Corporation"},
|
||||||
|
{"NSD", 8, "NESA International Inc."},
|
||||||
|
{"OPTODISC", 8, "Optodisc Technology Corporation"},
|
||||||
|
{"OTCBDR", 8, "Optodisc Technology Corporation"},
|
||||||
|
{"PHILIP", 8, "Moser Baer India Limited"},
|
||||||
|
{"PHILIPS", 8, "Philips"},
|
||||||
|
{"PRINCO", 6, "Princo Corporation"},
|
||||||
|
{"PRODISC", 7, "Prodisc Technology Inc."},
|
||||||
|
{"Prodisc", 7, "Prodisc Technology Inc."},
|
||||||
|
{"PVC", 3, "Pioneer"},
|
||||||
|
{"RICOHJPN", 8, "Ricoh Company Limited"},
|
||||||
|
{"RITEK", 5, "Ritek Corp"},
|
||||||
|
{"SONY", 4, "Sony Corporation"},
|
||||||
|
{"TDK", 3, "TDK Corporation"},
|
||||||
|
{"TTG", 3, "TDK Corporation"},
|
||||||
|
{"TTH", 3, "TDK Corporation"},
|
||||||
|
{"TY", 8, "Taiyo Yuden Company Limited"},
|
||||||
|
{"TYG", 3, "Taiyo Yuden Company Limited"},
|
||||||
|
{"UME", 3, "UmeDisc Limited"},
|
||||||
|
{"UTJR001", 7, "Unifino Inc."},
|
||||||
|
{"VERBAT", 5, "Mitsubishi Kagaku Media Co."},
|
||||||
|
{"YUDEN", 5, "Taiyo Yuden Company Limited"},
|
||||||
|
{"", 0, ""}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (media_code2 != NULL &&
|
||||||
|
(prf == -1 || prf == 0x09 || prf == 0x0A)) {
|
||||||
|
if (strlen(media_code2) == 9 && media_code1[0] == '9' &&
|
||||||
|
media_code1[2] == 'm' && media_code1[5] == 's' &&
|
||||||
|
media_code1[8] == 'f' &&
|
||||||
|
strchr(media_code1, '%') == NULL) {
|
||||||
|
sscanf(media_code1, "%dm%ds%df", &m_li, &s_li, &f_li);
|
||||||
|
sscanf(media_code2, "%dm%ds%df", &m_lo, &s_lo, &f_lo);
|
||||||
|
if (m_li >= 96 && m_li <= 97 && m_lo > 0) {
|
||||||
|
result = burn_guess_cd_manufacturer(
|
||||||
|
m_li, s_li, f_li, m_lo, s_lo, f_lo, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DVD-R do not keep manufacturer id apart from media id.
|
||||||
|
Some manufacturers use a blank as separator which would now be '_'.
|
||||||
|
*/
|
||||||
|
cpt = strchr(media_code1, '_');
|
||||||
|
if (cpt != NULL && (prf == -1 || prf == 0x11 || prf == 0x13 ||
|
||||||
|
prf == 0x14 || prf == 0x15))
|
||||||
|
l = cpt - media_code1;
|
||||||
|
|
||||||
|
for (i = 0; mid_list[i].mc1[0]; i++) {
|
||||||
|
if (strncmp(mid_list[i].mc1, media_code1,
|
||||||
|
mid_list[i].mc1_sig_len) == 0)
|
||||||
|
break;
|
||||||
|
if (l > 0)
|
||||||
|
if (strncmp(mid_list[i].mc1, media_code1, l) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mid_list[i].mc1[0] == 0) {
|
||||||
|
sprintf(buf, "Unknown DVD/BD manufacturer. Please report code '%s/%s', the human readable brand, size, and speed to scdbackup@gmx.net.",
|
||||||
|
media_code1, media_code2);
|
||||||
|
result = strdup(buf);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = strdup(mid_list[i].manufacturer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A90905 */
|
||||||
|
/* Make *text a single printable word */
|
||||||
|
/* IMPORTANT: text must be freeable memory !
|
||||||
|
@param flag bit0=escape '/' too
|
||||||
|
bit1=(overrides bit0) do not escape " _/"
|
||||||
|
*/
|
||||||
|
int burn_util_make_printable_word(char **text, int flag)
|
||||||
|
{
|
||||||
|
int i, esc_add = 0, ret;
|
||||||
|
char *wpt, *rpt, *new_text = NULL;
|
||||||
|
|
||||||
|
if (flag & 2)
|
||||||
|
flag &= ~1;
|
||||||
|
|
||||||
|
for (i = 0; (*text)[i]; i++) {
|
||||||
|
rpt = (*text) + i;
|
||||||
|
if (*rpt < 32 || *rpt > 126 || *rpt == 96 ||
|
||||||
|
((*rpt == '_' || *rpt == '%') && (!(flag & 2))) ||
|
||||||
|
(*rpt == '/' && (flag & 1)))
|
||||||
|
esc_add += 2;
|
||||||
|
}
|
||||||
|
if (esc_add) {
|
||||||
|
new_text = calloc(strlen(*text) + esc_add + 1, 1);
|
||||||
|
if (new_text == NULL) {
|
||||||
|
ret = -1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
wpt = new_text;
|
||||||
|
for (i = 0; (*text)[i]; i++) {
|
||||||
|
rpt = (*text) + i;
|
||||||
|
if (*rpt < 32 || *rpt > 126 || *rpt == 96 ||
|
||||||
|
((*rpt == '_' || *rpt == '%') && (!(flag & 2))) ||
|
||||||
|
(*rpt == '/' && (flag & 1))) {
|
||||||
|
sprintf(wpt, "%%%2.2X",
|
||||||
|
(unsigned int) *((unsigned char *) rpt));
|
||||||
|
wpt+= 3;
|
||||||
|
} else
|
||||||
|
*(wpt++) = *rpt;
|
||||||
|
}
|
||||||
|
*wpt = 0;
|
||||||
|
free(*text);
|
||||||
|
*text = new_text;
|
||||||
|
}
|
||||||
|
if (!(flag & 2))
|
||||||
|
for (i = 0; (*text)[i]; i++)
|
||||||
|
if ((*text)[i] == ' ')
|
||||||
|
(*text)[i] = '_';
|
||||||
|
ret = 1;
|
||||||
|
ex:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11216 */
|
||||||
|
/** Read a line from fp and strip LF or CRLF */
|
||||||
|
char *burn_sfile_fgets(char *line, int maxl, FILE *fp)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
ret = fgets(line, maxl, fp);
|
||||||
|
if (ret == NULL)
|
||||||
|
return NULL;
|
||||||
|
l = strlen(line);
|
||||||
|
if (l > 0)
|
||||||
|
if (line[l - 1] == '\r')
|
||||||
|
line[--l] = 0;
|
||||||
|
if (l > 0)
|
||||||
|
if (line[l - 1] == '\n')
|
||||||
|
line[--l] = 0;
|
||||||
|
if(l > 0)
|
||||||
|
if(line[l - 1] == '\r')
|
||||||
|
line[--l] = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *burn_printify(char *msg)
|
||||||
|
{
|
||||||
|
char *cpt;
|
||||||
|
|
||||||
|
for (cpt = msg; *cpt != 0; cpt++)
|
||||||
|
if (*cpt < 32 || *cpt > 126)
|
||||||
|
*cpt = '#';
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B30521 */
|
||||||
|
void burn_int_to_lsb(int val, char *target)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
|
||||||
|
buf = (unsigned char *) target;
|
||||||
|
buf[0] = val & 0xff;
|
||||||
|
buf[1] = (val >> 8) & 0xff;
|
||||||
|
buf[2] = (val >> 16) & 0xff;
|
||||||
|
buf[3] = (val >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B30609 */
|
||||||
|
double burn_get_time(int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
#ifdef Libburn_use_clock_gettime_monotoniC
|
||||||
|
#ifdef _POSIX_TIMERS
|
||||||
|
#ifdef _POSIX_MONOTONIC_CLOCK
|
||||||
|
|
||||||
|
/* Enable by
|
||||||
|
export CFLAGS=-DLibburn_use_clock_gettime_monotoniC
|
||||||
|
export LIBS=-lrt
|
||||||
|
./configure ... && make clean && make
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct timespec tp;
|
||||||
|
ret = clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||||
|
if (ret == 0)
|
||||||
|
return ((double) tp.tv_sec) + ((double) tp.tv_nsec) * 1.0e-9;
|
||||||
|
|
||||||
|
#endif /* _POSIX_MONOTONIC_CLOCK */
|
||||||
|
#endif /* _POSIX_TIMERS */
|
||||||
|
#endif /* Xorriso_use_clock_gettime_monotoniC */
|
||||||
|
|
||||||
|
ret = gettimeofday(&tv, NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
return ((double) tv.tv_sec) + ((double) tv.tv_usec) * 1.0e-6;
|
||||||
|
return (double) time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts B40609 */
|
||||||
|
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf)
|
||||||
|
{
|
||||||
|
off_t add_size;
|
||||||
|
|
||||||
|
add_size = stbuf->st_blocks * (off_t) 512;
|
||||||
|
if (add_size < stbuf->st_size) {
|
||||||
|
/* Sparse file */
|
||||||
|
if (write_start < stbuf->st_size) {
|
||||||
|
/* Might write into sparse gaps */
|
||||||
|
if (write_start > add_size)
|
||||||
|
add_size = write_start;
|
||||||
|
} else {
|
||||||
|
/* Will not write into sparse area */
|
||||||
|
add_size = stbuf->st_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return add_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,25 @@
|
||||||
#ifndef __UTIL
|
#ifndef __UTIL
|
||||||
#define __UTIL
|
#define __UTIL
|
||||||
|
|
||||||
char *burn_strdup(char *s);
|
/* for struct stat */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
char *burn_strndup(char *s, int n);
|
/* ts A90905 */
|
||||||
|
int burn_util_make_printable_word(char **text, int flag);
|
||||||
|
|
||||||
|
/* ts B11216 */
|
||||||
|
char *burn_sfile_fgets(char *line, int maxl, FILE *fp);
|
||||||
|
char *burn_printify(char *msg);
|
||||||
|
|
||||||
|
/* ts B30521 */
|
||||||
|
void burn_int_to_lsb(int val, char *target);
|
||||||
|
|
||||||
|
/* ts B30609 */
|
||||||
|
double burn_get_time(int flag);
|
||||||
|
|
||||||
|
/* ts B40609 */
|
||||||
|
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1698
libburn/write.c
1698
libburn/write.c
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BURN__WRITE_H
|
#ifndef BURN__WRITE_H
|
||||||
#define BURN__WRITE_H
|
#define BURN__WRITE_H
|
||||||
|
|
||||||
|
@ -31,7 +37,14 @@ int burn_write_flush(struct burn_write_opts *o, struct burn_track *track);
|
||||||
/* ts A61030 : necessary for TAO */
|
/* ts A61030 : necessary for TAO */
|
||||||
int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
int tnum);
|
int tnum);
|
||||||
int burn_write_close_session(struct burn_write_opts *o,struct burn_session *s);
|
int burn_write_close_session(struct burn_write_opts *o);
|
||||||
|
|
||||||
|
/* @param flag bit0= repair checksum
|
||||||
|
bit1= repair checksum if all pack CRCs are 0
|
||||||
|
@return 0= no mismatch , >0 number of unrepaired mismatches
|
||||||
|
<0 number of repaired mismatches
|
||||||
|
*/
|
||||||
|
int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,18 +25,19 @@
|
||||||
#include "../libburn/libdax_msgs.h"
|
#include "../libburn/libdax_msgs.h"
|
||||||
struct libdax_msgs *libdax_messenger= NULL;
|
struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
|
/* The API for .wav extraction */
|
||||||
|
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
|
||||||
|
#include "../libburn/libdax_audioxtr.h"
|
||||||
|
|
||||||
#else /* Dewav_without_libburN */
|
#else /* Dewav_without_libburN */
|
||||||
|
|
||||||
/* This build environment uses libdax_msgs via libburn */
|
/* This build environment uses libdax_msgs and libdax_audioxtr via libburn */
|
||||||
/* Thus the API header of libburn */
|
/* Thus the API header of libburn */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
#endif /* ! Dewav_without_libburN */
|
#endif /* ! Dewav_without_libburN */
|
||||||
|
|
||||||
|
|
||||||
/* The API for .wav extraction */
|
|
||||||
#include "../libburn/libdax_audioxtr.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
Fakes a file in SUN .au format from a raw little-endian PCM audio file
|
Fakes a file in SUN .au format from a raw little-endian PCM audio file
|
||||||
(e.g. a file extracted from .wav by test/dewav). The input data are assumed
|
(e.g. a file extracted from .wav by test/dewav). The input data are assumed
|
||||||
to be 16 bit, stereo, 44100 Hz.
|
to be 16 bit, stereo, 44100 Hz.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
Copyright (C) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Provided under GPL version 2 or later.
|
||||||
|
|
||||||
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
|
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
|
||||||
*/
|
*/
|
||||||
|
@ -47,6 +48,13 @@ int main(int argc, char **argv)
|
||||||
exit_value= 1;
|
exit_value= 1;
|
||||||
goto help;
|
goto help;
|
||||||
}
|
}
|
||||||
|
for(i= 1; i<argc; i++) {
|
||||||
|
if(strlen(argv[i]) >= 4096) {
|
||||||
|
fprintf(stderr,"%s: argument at position %d is much too long.\n",
|
||||||
|
argv[0], i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
for(i= 1; i<argc; i++) {
|
for(i= 1; i<argc; i++) {
|
||||||
if(strcmp(argv[i],"-o")==0) {
|
if(strcmp(argv[i],"-o")==0) {
|
||||||
if(i>=argc-1) {
|
if(i>=argc-1) {
|
||||||
|
|
184
test/libburner.c
184
test/libburner.c
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
||||||
/* Copyright (C) 2005 - 2009 Thomas Schmitt <scdbackup@gmx.net> */
|
/* Copyright (C) 2005 - 2016 Thomas Schmitt <scdbackup@gmx.net> */
|
||||||
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
|
/* Provided under GPL, see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
|
@ -16,35 +16,59 @@
|
||||||
to serve the libburnia team as reference application. libburner.c does indeed
|
to serve the libburnia team as reference application. libburner.c does indeed
|
||||||
define the standard way how above three gestures can be implemented and
|
define the standard way how above three gestures can be implemented and
|
||||||
stay upward compatible for a good while.
|
stay upward compatible for a good while.
|
||||||
|
There is another demo program, test/telltoc.c, which inspects drive, media
|
||||||
|
state, and media contents.
|
||||||
|
|
||||||
Before you can do anything, you have to initialize libburn by
|
Before you can do anything, you have to initialize libburn by
|
||||||
burn_initialize()
|
burn_initialize()
|
||||||
and provide some signal and abort handling, e.g. by the builtin handler, by
|
and provide some signal and abort handling, e.g. by the builtin handler, by
|
||||||
burn_set_signal_handling()
|
burn_set_signal_handling("libburner : ", NULL, 0x0)
|
||||||
as it is done in main() at the end of this file. Then you aquire a
|
as it is done in main() at the end of this file.
|
||||||
drive in an appropriate way conforming to the API. The two main
|
Then you acquire a drive in an appropriate way conforming to the API. The two
|
||||||
approaches are shown here in application functions:
|
main approaches are shown here in application functions:
|
||||||
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
With that aquired drive you can blank a CD-RW
|
|
||||||
|
With that acquired drive you can blank a CD-RW or DVD-RW as shown in
|
||||||
libburner_blank_disc()
|
libburner_blank_disc()
|
||||||
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
||||||
or an unused BD to default size with spare blocks
|
or an unused BD to default size with spare blocks
|
||||||
libburner_format()
|
libburner_format()
|
||||||
With the aquired drive you can burn to CD, DVD, BD
|
With the acquired drive you can burn to CD, DVD, BD. See
|
||||||
libburner_payload()
|
libburner_payload()
|
||||||
|
|
||||||
|
These three functions switch temporarily to a non-fatal signal handler
|
||||||
|
while they are waiting for the drive to become idle again:
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30)
|
||||||
|
After the waiting loop ended, they check for eventual abort events by
|
||||||
|
burn_is_aborting(0)
|
||||||
|
The 0x30 handler will eventually execute
|
||||||
|
burn_abort()
|
||||||
|
but not wait for the drive to become idle and not call exit().
|
||||||
|
This is needed because the worker threads might block as long as the signal
|
||||||
|
handler has not returned. The 0x0 handler would wait for them to finish.
|
||||||
|
Take this into respect when implementing own signal handlers.
|
||||||
|
|
||||||
When everything is done, main() releases the drive and shuts down libburn:
|
When everything is done, main() releases the drive and shuts down libburn:
|
||||||
burn_drive_release();
|
burn_drive_release();
|
||||||
burn_finish()
|
burn_finish()
|
||||||
|
|
||||||
|
Applications must use 64 bit off_t. E.g. by defining
|
||||||
|
#define _LARGEFILE_SOURCE
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
or take special precautions to interface with the library by 64 bit integers
|
||||||
|
where libburn/libburn.h prescribes off_t.
|
||||||
|
This program gets fed with appropriate settings externally by libburn's
|
||||||
|
autotools generated build system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** See this for the decisive API specs . libburn.h is The Original */
|
/** See this for the decisive API specs . libburn.h is The Original */
|
||||||
/* For using the installed header file : #include <libburn/libburn.h> */
|
/* For using the installed header file : #include <libburn/libburn.h> */
|
||||||
/* This program insists in the own headerfile. */
|
/* This program insists in the own headerfile. */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
/* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */
|
/* libburn works on Linux systems with kernel 2.4 or 2.6, FreeBSD, Solaris */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -74,12 +98,12 @@ static unsigned int drive_count;
|
||||||
finally released */
|
finally released */
|
||||||
static int drive_is_grabbed = 0;
|
static int drive_is_grabbed = 0;
|
||||||
|
|
||||||
/** A number and a text describing the type of media in aquired drive */
|
/** A number and a text describing the type of media in acquired drive */
|
||||||
static int current_profile= -1;
|
static int current_profile= -1;
|
||||||
static char current_profile_name[80]= {""};
|
static char current_profile_name[80]= {""};
|
||||||
|
|
||||||
|
|
||||||
/* Some in-advance definitions to allow a more comprehensive ordering
|
/* Some in-advance definitions make possible a more comprehensive ordering
|
||||||
of the functions and their explanations in here */
|
of the functions and their explanations in here */
|
||||||
int libburner_aquire_by_adr(char *drive_adr);
|
int libburner_aquire_by_adr(char *drive_adr);
|
||||||
int libburner_aquire_by_driveno(int *drive_no);
|
int libburner_aquire_by_driveno(int *drive_no);
|
||||||
|
@ -87,7 +111,7 @@ int libburner_aquire_by_driveno(int *drive_no);
|
||||||
|
|
||||||
/* ------------------------------- API gestures ---------------------------- */
|
/* ------------------------------- API gestures ---------------------------- */
|
||||||
|
|
||||||
/** You need to aquire a drive before burning. The API offers this as one
|
/** You need to acquire a drive before burning. The API offers this as one
|
||||||
compact call and alternatively as application controllable gestures of
|
compact call and alternatively as application controllable gestures of
|
||||||
whitelisting, scanning for drives and finally grabbing one of them.
|
whitelisting, scanning for drives and finally grabbing one of them.
|
||||||
|
|
||||||
|
@ -196,7 +220,7 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||||
printf("\nOverview of accessible drives (%d found) :\n",
|
printf("\nOverview of accessible drives (%d found) :\n",
|
||||||
drive_count);
|
drive_count);
|
||||||
printf("-----------------------------------------------------------------------------\n");
|
printf("-----------------------------------------------------------------------------\n");
|
||||||
for (i = 0; i < drive_count; i++) {
|
for (i = 0; i < (int) drive_count; i++) {
|
||||||
if (burn_drive_get_adr(&(drive_list[i]), adr) <=0)
|
if (burn_drive_get_adr(&(drive_list[i]), adr) <=0)
|
||||||
strcpy(adr, "-get_adr_failed-");
|
strcpy(adr, "-get_adr_failed-");
|
||||||
printf("%d --drive '%s' : '%s' '%s'\n",
|
printf("%d --drive '%s' : '%s' '%s'\n",
|
||||||
|
@ -215,14 +239,14 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||||
and to restart when the choice has been made. The list of selectable
|
and to restart when the choice has been made. The list of selectable
|
||||||
drives should also hold persistent drive addresses as obtained
|
drives should also hold persistent drive addresses as obtained
|
||||||
above by burn_drive_get_adr(). By such an address one may use
|
above by burn_drive_get_adr(). By such an address one may use
|
||||||
burn_drive_scan_and_grab() to finally aquire exactly one drive.
|
burn_drive_scan_and_grab() to finally acquire exactly one drive.
|
||||||
|
|
||||||
A not yet tested shortcut should be to call burn_drive_info_free()
|
A not yet tested shortcut should be to call burn_drive_info_free()
|
||||||
and to call either burn_drive_scan() or burn_drive_scan_and_grab()
|
and to call either burn_drive_scan() or burn_drive_scan_and_grab()
|
||||||
before accessing any drives again.
|
before accessing any drives again.
|
||||||
|
|
||||||
In both cases you have to be aware that the desired drive might get
|
In both cases you have to be aware that the desired drive might get
|
||||||
aquired in the meantime by another user resp. libburn process.
|
acquired in the meantime by another user or libburn process.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* We already made our choice via command line. (default is 0)
|
/* We already made our choice via command line. (default is 0)
|
||||||
|
@ -233,7 +257,7 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||||
printf("Pseudo-drive \"-\" given : bus scanning done.\n");
|
printf("Pseudo-drive \"-\" given : bus scanning done.\n");
|
||||||
return 2; /* the program will end after this */
|
return 2; /* the program will end after this */
|
||||||
}
|
}
|
||||||
if (drive_count <= *driveno) {
|
if ((int) drive_count <= *driveno) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Found only %d drives. Number %d not available.\n",
|
"Found only %d drives. Number %d not available.\n",
|
||||||
drive_count, *driveno);
|
drive_count, *driveno);
|
||||||
|
@ -241,7 +265,7 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop all drives which we do not want to use */
|
/* Drop all drives which we do not want to use */
|
||||||
for (i = 0; i < drive_count; i++) {
|
for (i = 0; i < (int) drive_count; i++) {
|
||||||
if (i == *driveno) /* the one drive we want to keep */
|
if (i == *driveno) /* the one drive we want to keep */
|
||||||
continue;
|
continue;
|
||||||
ret = burn_drive_info_forget(&(drive_list[i]),0);
|
ret = burn_drive_info_forget(&(drive_list[i]),0);
|
||||||
|
@ -300,9 +324,12 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||||
"FATAL : Media is not of erasable type\n");
|
"FATAL : Media is not of erasable type\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf(
|
/* Switch to asynchronous signal handling for the time of waiting */
|
||||||
"Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
|
printf("Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
||||||
burn_disc_erase(drive, blank_fast);
|
burn_disc_erase(drive, blank_fast);
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||||
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||||
|
@ -311,6 +338,10 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||||
printf("Blanking ( %.1f%% done )\n", percent);
|
printf("Blanking ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
if (burn_is_aborting(0) > 0)
|
||||||
|
return -1;
|
||||||
|
/* Back to synchronous handling */
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -363,6 +394,7 @@ int libburner_format(struct burn_drive *drive)
|
||||||
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
printf("Beginning to format media.\n");
|
printf("Beginning to format media.\n");
|
||||||
burn_disc_format(drive, size, format_flag);
|
burn_disc_format(drive, size, format_flag);
|
||||||
|
@ -375,6 +407,9 @@ int libburner_format(struct burn_drive *drive)
|
||||||
printf("Formatting ( %.1f%% done )\n", percent);
|
printf("Formatting ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
if (burn_is_aborting(0) > 0)
|
||||||
|
return -1;
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
||||||
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||||
current_profile_name);
|
current_profile_name);
|
||||||
if (current_profile == 0x14 || current_profile == 0x13)
|
if (current_profile == 0x14 || current_profile == 0x13)
|
||||||
|
@ -400,28 +435,31 @@ int libburner_format(struct burn_drive *drive)
|
||||||
|
|
||||||
In case of external signals expect abort handling of an ongoing burn to
|
In case of external signals expect abort handling of an ongoing burn to
|
||||||
last up to a minute. Wait the normal burning timespan before any kill -9.
|
last up to a minute. Wait the normal burning timespan before any kill -9.
|
||||||
|
|
||||||
For simplicity, this function allows memory leaks in case of failure.
|
|
||||||
In apps which do not abort immediately, one should clean up better.
|
|
||||||
*/
|
*/
|
||||||
int libburner_payload(struct burn_drive *drive,
|
int libburner_payload(struct burn_drive *drive,
|
||||||
char source_adr[][4096], int source_adr_count,
|
char source_adr[][4096], int source_adr_count,
|
||||||
int multi, int simulate_burn, int all_tracks_type)
|
int multi, int simulate_burn, int all_tracks_type)
|
||||||
{
|
{
|
||||||
struct burn_source *data_src, *fifo_src[99];
|
struct burn_source *data_src = NULL, *fifo_src[99];
|
||||||
struct burn_disc *target_disc;
|
struct burn_disc *target_disc = NULL;
|
||||||
struct burn_session *session;
|
struct burn_session *session = NULL;
|
||||||
struct burn_write_opts *burn_options;
|
struct burn_write_opts *burn_options = NULL;
|
||||||
enum burn_disc_status disc_state;
|
enum burn_disc_status disc_state;
|
||||||
struct burn_track *track, *tracklist[99];
|
struct burn_track *track, *tracklist[99];
|
||||||
struct burn_progress progress;
|
struct burn_progress progress;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
|
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
|
||||||
int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
|
int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
|
||||||
|
int ret;
|
||||||
off_t fixed_size;
|
off_t fixed_size;
|
||||||
char *adr, reasons[BURN_REASONS_LEN];
|
char *adr, reasons[BURN_REASONS_LEN];
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
|
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
|
||||||
|
fifo_src[trackno] = NULL;
|
||||||
|
tracklist[trackno] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (all_tracks_type != BURN_AUDIO) {
|
if (all_tracks_type != BURN_AUDIO) {
|
||||||
all_tracks_type = BURN_MODE1;
|
all_tracks_type = BURN_MODE1;
|
||||||
/* a padding of 300 kiB helps to avoid the read-ahead bug */
|
/* a padding of 300 kiB helps to avoid the read-ahead bug */
|
||||||
|
@ -455,7 +493,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
|
|
||||||
/* Convert this filedescriptor into a burn_source object */
|
/* Convert this filedescriptor into a burn_source object */
|
||||||
data_src = NULL;
|
data_src = NULL;
|
||||||
if (fd>=0)
|
if (fd >= 0)
|
||||||
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
||||||
if (data_src == NULL) {
|
if (data_src == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -463,7 +501,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
if(errno!=0)
|
if(errno!=0)
|
||||||
fprintf(stderr,"(Most recent system error: %s )\n",
|
fprintf(stderr,"(Most recent system error: %s )\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
/* Install a fifo object on top of that data source object */
|
/* Install a fifo object on top of that data source object */
|
||||||
fifo_src[trackno] = burn_fifo_source_new(data_src,
|
fifo_src[trackno] = burn_fifo_source_new(data_src,
|
||||||
|
@ -471,7 +509,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
if (fifo_src[trackno] == NULL) {
|
if (fifo_src[trackno] == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Could not create fifo object of 4 MB\n");
|
"FATAL: Could not create fifo object of 4 MB\n");
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the fifo object as data source for the track */
|
/* Use the fifo object as data source for the track */
|
||||||
|
@ -479,7 +517,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
!= BURN_SOURCE_OK) {
|
!= BURN_SOURCE_OK) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Cannot attach source object to track object\n");
|
"FATAL: Cannot attach source object to track object\n");
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
burn_session_add_track(session, track, BURN_POS_END);
|
burn_session_add_track(session, track, BURN_POS_END);
|
||||||
|
@ -487,6 +525,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
|
|
||||||
/* Give up local reference to the data burn_source object */
|
/* Give up local reference to the data burn_source object */
|
||||||
burn_source_free(data_src);
|
burn_source_free(data_src);
|
||||||
|
data_src = NULL;
|
||||||
|
|
||||||
} /* trackno loop end */
|
} /* trackno loop end */
|
||||||
|
|
||||||
|
@ -503,7 +542,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
else
|
else
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Cannot recognize state of drive and media\n");
|
"FATAL: Cannot recognize state of drive and media\n");
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
burn_options = burn_write_opts_new(drive);
|
burn_options = burn_write_opts_new(drive);
|
||||||
|
@ -518,14 +557,14 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
reasons, 0) == BURN_WRITE_NONE) {
|
reasons, 0) == BURN_WRITE_NONE) {
|
||||||
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
|
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
|
||||||
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
||||||
return 0;
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
||||||
start_time = time(0);
|
start_time = time(0);
|
||||||
burn_disc_write(burn_options, target_disc);
|
burn_disc_write(burn_options, target_disc);
|
||||||
|
|
||||||
burn_write_opts_free(burn_options);
|
|
||||||
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
|
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
|
||||||
usleep(100002);
|
usleep(100002);
|
||||||
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
|
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
|
||||||
|
@ -561,19 +600,32 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
|
if (burn_is_aborting(0) > 0)
|
||||||
burn_source_free(fifo_src[trackno]);
|
{ret = -1; goto ex;}
|
||||||
burn_track_free(tracklist[trackno]);
|
|
||||||
}
|
|
||||||
burn_session_free(session);
|
|
||||||
burn_disc_free(target_disc);
|
|
||||||
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
||||||
current_profile != 0x12 && current_profile != 0x43)
|
current_profile != 0x12 && current_profile != 0x43)
|
||||||
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
||||||
printf("NOTE: Media left appendable.\n");
|
printf("NOTE: Media left appendable.\n");
|
||||||
if (simulate_burn)
|
if (simulate_burn)
|
||||||
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
||||||
return 1;
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
/* Dispose objects */
|
||||||
|
if (burn_options != NULL)
|
||||||
|
burn_write_opts_free(burn_options);
|
||||||
|
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
|
||||||
|
if (fifo_src[trackno] != NULL)
|
||||||
|
burn_source_free(fifo_src[trackno]);
|
||||||
|
if (tracklist[trackno])
|
||||||
|
burn_track_free(tracklist[trackno]);
|
||||||
|
}
|
||||||
|
if (data_src != NULL)
|
||||||
|
burn_source_free(data_src);
|
||||||
|
if (session != NULL)
|
||||||
|
burn_session_free(session);
|
||||||
|
if (target_disc != NULL)
|
||||||
|
burn_disc_free(target_disc);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -702,6 +754,13 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* A warning to programmers who start their own projekt from here. */
|
||||||
|
if (sizeof(off_t) != 8) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nFATAL: Compile time misconfiguration. off_t is not 64 bit.\n\n");
|
||||||
|
exit(39);
|
||||||
|
}
|
||||||
|
|
||||||
ret = libburner_setup(argc, argv);
|
ret = libburner_setup(argc, argv);
|
||||||
if (ret)
|
if (ret)
|
||||||
exit(ret);
|
exit(ret);
|
||||||
|
@ -718,14 +777,14 @@ int main(int argc, char **argv)
|
||||||
/* Print messages of severity SORRY or more directly to stderr */
|
/* Print messages of severity SORRY or more directly to stderr */
|
||||||
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
||||||
|
|
||||||
/* Activate the default signal handler which eventually will try to
|
/* Activate the synchronous signal handler which eventually will try to
|
||||||
properly shutdown drive and library on aborting events. */
|
properly shutdown drive and library on aborting events. */
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0);
|
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
||||||
|
|
||||||
/** Note: driveno might change its value in this call */
|
/** Note: driveno might change its value in this call */
|
||||||
ret = libburner_aquire_drive(drive_adr, &driveno);
|
ret = libburner_aquire_drive(drive_adr, &driveno);
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
fprintf(stderr,"\nFATAL: Failed to aquire drive.\n");
|
fprintf(stderr,"\nFATAL: Failed to acquire drive.\n");
|
||||||
{ ret = 34; goto finish_libburn; }
|
{ ret = 34; goto finish_libburn; }
|
||||||
}
|
}
|
||||||
if (ret == 2)
|
if (ret == 2)
|
||||||
|
@ -752,10 +811,14 @@ release_drive:;
|
||||||
burn_drive_release(drive_list[driveno].drive, 0);
|
burn_drive_release(drive_list[driveno].drive, 0);
|
||||||
|
|
||||||
finish_libburn:;
|
finish_libburn:;
|
||||||
|
if (burn_is_aborting(0) > 0) {
|
||||||
|
burn_abort(4400, burn_abort_pacifier, "libburner : ");
|
||||||
|
fprintf(stderr,"\nlibburner run aborted\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
/* This app does not bother to know about exact scan state.
|
/* This app does not bother to know about exact scan state.
|
||||||
Better to accept a memory leak here. We are done anyway. */
|
Better to accept a memory leak here. We are done anyway. */
|
||||||
/* burn_drive_info_free(drive_list); */
|
/* burn_drive_info_free(drive_list); */
|
||||||
|
|
||||||
burn_finish();
|
burn_finish();
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
@ -768,37 +831,6 @@ Read. Try. Think. Play. Write yourself some code. Be free of my copyright.
|
||||||
|
|
||||||
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
||||||
|
|
||||||
|
|
||||||
Clarification in my name and in the name of Mario Danic, copyright holder
|
|
||||||
on toplevel of libburnia. To be fully in effect after the remaining other
|
|
||||||
copyrighted code has been replaced by ours and by copyright-free contributions
|
|
||||||
of our friends:
|
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that
|
|
||||||
dynamical linking of our libraries constitutes "use of" and
|
|
||||||
not "derivation from" our work in the sense of GPL, provided
|
|
||||||
those libraries are compiled from our unaltered code.
|
|
||||||
|
|
||||||
Thus you may link our libraries dynamically with applications
|
|
||||||
which are not under GPL. You may distribute our libraries and
|
|
||||||
application tools in binary form, if you fulfill the usual
|
|
||||||
condition of GPL to offer a copy of the source code -altered
|
|
||||||
or unaltered- under GPL.
|
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
|
||||||
and with the due reference to the entire open source community.
|
|
||||||
|
|
||||||
If there should really arise the case where above clarification
|
|
||||||
does not suffice to fulfill a clear and neat request in open source
|
|
||||||
spirit that would otherwise be declined for mere formal reasons,
|
|
||||||
only in that case we will duely consider to issue a special license
|
|
||||||
covering only that special case.
|
|
||||||
It is the open source idea of responsible freedom which will be
|
|
||||||
decisive and you will have to prove that you exhausted all own
|
|
||||||
means to qualify for GPL.
|
|
||||||
|
|
||||||
For now we are firmly committed to maintain one single license: GPL.
|
|
||||||
|
|
||||||
History:
|
History:
|
||||||
libburner is a compilation of my own contributions to test/burniso.c and
|
libburner is a compilation of my own contributions to test/burniso.c and
|
||||||
fresh code which replaced the remaining parts under copyright of
|
fresh code which replaced the remaining parts under copyright of
|
||||||
|
|
134
test/offst_source.c
Normal file
134
test/offst_source.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
cc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS -g -o test/offst_source test/offst_source.c -lburn
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
|
/* Just everything from test/libburner.c */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int create_original(struct burn_source **original, char *path, int flag)
|
||||||
|
{
|
||||||
|
printf("create_original: path='%s'\n", path);
|
||||||
|
*original = burn_file_source_new(path, NULL);
|
||||||
|
if (*original == NULL)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int set_up_offst_sources(struct burn_source *original,
|
||||||
|
struct burn_source *offsetters[],
|
||||||
|
int count, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
off_t start = 3, size = 10, gap = 7;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
offsetters[i] = burn_offst_source_new(original,
|
||||||
|
i > 0 ? offsetters[i - 1] : NULL,
|
||||||
|
start, size, 0);
|
||||||
|
if (offsetters[i] == NULL)
|
||||||
|
return 0;
|
||||||
|
printf("set_up_offst_sources: idx=%d, start=%d\n",
|
||||||
|
i, (int) start);
|
||||||
|
start += size + gap;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int consume_source(struct burn_source *src, int flag)
|
||||||
|
{
|
||||||
|
int ret, count = 0;
|
||||||
|
unsigned char buf[1];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ret = src->read_xt(src, buf, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("\n");
|
||||||
|
fprintf(stderr, "consume_source: count=%d, ret=%d\n",
|
||||||
|
count, ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
printf("%u ", buf[0]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
printf(" count=%d\n", count);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int consume_all_sources(struct burn_source *offsetters[],
|
||||||
|
int count, int flag)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
printf("consume_source: idx=%d\n", i);
|
||||||
|
ret = consume_source(offsetters[i], 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int free_all_sources(struct burn_source *original,
|
||||||
|
struct burn_source *offsetters[],
|
||||||
|
int count, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
burn_source_free(offsetters[i]);
|
||||||
|
burn_source_free(original);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *path = "./COPYRIGHT";
|
||||||
|
struct burn_source *original = NULL, *offsetters[4];
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
path = argv[1];
|
||||||
|
|
||||||
|
if (burn_initialize() == 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
ret = create_original(&original, path, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
exit(2);
|
||||||
|
|
||||||
|
ret = set_up_offst_sources(original, offsetters, 4, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
exit(3);
|
||||||
|
|
||||||
|
ret = consume_all_sources(offsetters, 4, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
exit(4);
|
||||||
|
|
||||||
|
ret = free_all_sources(original, offsetters, 4, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
exit(5);
|
||||||
|
|
||||||
|
burn_finish();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static struct burn_drive_info *drives;
|
static struct burn_drive_info *drives;
|
||||||
|
@ -20,8 +21,6 @@ static void catch_int ()
|
||||||
|
|
||||||
static void poll_drive(int d)
|
static void poll_drive(int d)
|
||||||
{
|
{
|
||||||
enum burn_disc_status s;
|
|
||||||
|
|
||||||
fprintf(stderr, "polling disc in %s - %s:\n",
|
fprintf(stderr, "polling disc in %s - %s:\n",
|
||||||
drives[d].vendor, drives[d].product);
|
drives[d].vendor, drives[d].product);
|
||||||
|
|
||||||
|
@ -33,8 +32,7 @@ static void poll_drive(int d)
|
||||||
while (burn_drive_get_status(drives[d].drive, NULL))
|
while (burn_drive_get_status(drives[d].drive, NULL))
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
while ((s = burn_disc_get_status(drives[d].drive))
|
while (burn_disc_get_status(drives[d].drive) == BURN_DISC_UNREADY)
|
||||||
== BURN_DISC_UNREADY)
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
while (NEXT == 0) {
|
while (NEXT == 0) {
|
||||||
|
@ -65,9 +63,10 @@ int main()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&newact, 0, sizeof(newact));
|
||||||
newact.sa_handler = catch_int;
|
newact.sa_handler = catch_int;
|
||||||
sigaction(SIGINT, &newact, &oldact);
|
sigaction(SIGINT, &newact, &oldact);
|
||||||
for (i = 0; i < n_drives; i++) {
|
for (i = 0; i < (int) n_drives; i++) {
|
||||||
NEXT=0;
|
NEXT=0;
|
||||||
poll_drive(i);
|
poll_drive(i);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user