Tagged 0.3.0 libburn/cdrskin release
This commit is contained in:
parent
67598916f5
commit
f87a54f8df
5
libburn/tags/ZeroThreeZero/AUTHORS
Normal file
5
libburn/tags/ZeroThreeZero/AUTHORS
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Developers:
|
||||||
|
|
||||||
|
Mario Danic
|
||||||
|
Thomas Schmitt
|
||||||
|
Lorenzo Taylor
|
5
libburn/tags/ZeroThreeZero/CONTRIBUTORS
Normal file
5
libburn/tags/ZeroThreeZero/CONTRIBUTORS
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Joe Neeman
|
||||||
|
Philippe Rouquier
|
||||||
|
Gabriel Craciunescu
|
||||||
|
George Danchev
|
||||||
|
Jean-Francois Wauthy
|
280
libburn/tags/ZeroThreeZero/COPYING
Normal file
280
libburn/tags/ZeroThreeZero/COPYING
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
19
libburn/tags/ZeroThreeZero/COPYRIGHT
Normal file
19
libburn/tags/ZeroThreeZero/COPYRIGHT
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||||
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
1
libburn/tags/ZeroThreeZero/ChangeLog
Normal file
1
libburn/tags/ZeroThreeZero/ChangeLog
Normal file
@ -0,0 +1 @@
|
|||||||
|
nothing here now
|
234
libburn/tags/ZeroThreeZero/INSTALL
Normal file
234
libburn/tags/ZeroThreeZero/INSTALL
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
Installation Instructions
|
||||||
|
*************************
|
||||||
|
|
||||||
|
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||||
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free documentation; the Free Software Foundation gives
|
||||||
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
Briefly, the shell commands `./configure; make; make install' should
|
||||||
|
configure, build, and install this package. The following
|
||||||
|
more-detailed instructions are generic; see the `README' file for
|
||||||
|
instructions specific to this package.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, and a
|
||||||
|
file `config.log' containing compiler output (useful mainly for
|
||||||
|
debugging `configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called `config.cache'
|
||||||
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
|
the results of its tests to speed up reconfiguring. Caching is
|
||||||
|
disabled by default to prevent problems with accidental use of stale
|
||||||
|
cache files.
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point `config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
|
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||||
|
you want to change it or regenerate `configure' using a newer version
|
||||||
|
of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system.
|
||||||
|
|
||||||
|
Running `configure' might take a while. While running, it prints
|
||||||
|
some messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
5. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that the
|
||||||
|
`configure' script does not know about. Run `./configure --help' for
|
||||||
|
details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give `configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
With a non-GNU `make', it is safer to compile the package for one
|
||||||
|
architecture at a time in the source code directory. After you have
|
||||||
|
installed the package for one architecture, use `make distclean' before
|
||||||
|
reconfiguring for another architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' installs the package's commands under
|
||||||
|
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||||
|
can specify an installation prefix other than `/usr/local' by giving
|
||||||
|
`configure' the option `--prefix=PREFIX'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||||
|
PREFIX as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=DIR' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' cannot figure out automatically,
|
||||||
|
but needs to determine by the type of machine the package will run on.
|
||||||
|
Usually, assuming the package is built to be run on the _same_
|
||||||
|
architectures, `configure' can figure that out, but if it prints a
|
||||||
|
message saying it cannot guess the machine type, give it the
|
||||||
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS KERNEL-OS
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the option `--target=TYPE' to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with `--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share, you
|
||||||
|
can create a site shell script called `config.site' that gives default
|
||||||
|
values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to `configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||||
|
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||||
|
|
||||||
|
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||||
|
|
||||||
|
`configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it operates.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
`-h'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
`-V'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
`--config-cache'
|
||||||
|
`-C'
|
||||||
|
Alias for `--cache-file=config.cache'.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options. Run
|
||||||
|
`configure --help' for more details.
|
||||||
|
|
198
libburn/tags/ZeroThreeZero/Makefile.am
Normal file
198
libburn/tags/ZeroThreeZero/Makefile.am
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
pkgconfigdir=$(libdir)/pkgconfig
|
||||||
|
libincludedir=$(includedir)/libburn
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libburn/libburn.la
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
# Build libraries
|
||||||
|
libburn_libburn_la_LDFLAGS = \
|
||||||
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||||
|
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||||
|
libburn_libburn_la_SOURCES = \
|
||||||
|
libburn/async.c \
|
||||||
|
libburn/async.h \
|
||||||
|
libburn/back_hacks.h \
|
||||||
|
libburn/cleanup.c \
|
||||||
|
libburn/cleanup.h \
|
||||||
|
libburn/crc.c \
|
||||||
|
libburn/crc.h \
|
||||||
|
libburn/debug.c \
|
||||||
|
libburn/debug.h \
|
||||||
|
libburn/drive.c \
|
||||||
|
libburn/drive.h \
|
||||||
|
libburn/error.h \
|
||||||
|
libburn/file.c \
|
||||||
|
libburn/file.h \
|
||||||
|
libburn/init.c \
|
||||||
|
libburn/init.h \
|
||||||
|
libburn/lec.c \
|
||||||
|
libburn/lec.h \
|
||||||
|
libburn/libburn.h \
|
||||||
|
libburn/libdax_audioxtr.h \
|
||||||
|
libburn/libdax_audioxtr.c \
|
||||||
|
libburn/libdax_msgs.h \
|
||||||
|
libburn/libdax_msgs.c \
|
||||||
|
libburn/mmc.c \
|
||||||
|
libburn/mmc.h \
|
||||||
|
libburn/null.c \
|
||||||
|
libburn/null.h \
|
||||||
|
libburn/options.c \
|
||||||
|
libburn/options.h \
|
||||||
|
libburn/os.h \
|
||||||
|
libburn/read.c \
|
||||||
|
libburn/read.h \
|
||||||
|
libburn/sbc.c \
|
||||||
|
libburn/sbc.h \
|
||||||
|
libburn/sector.c \
|
||||||
|
libburn/sector.h \
|
||||||
|
libburn/sg.c \
|
||||||
|
libburn/sg.h \
|
||||||
|
libburn/source.h \
|
||||||
|
libburn/source.c \
|
||||||
|
libburn/spc.c \
|
||||||
|
libburn/spc.h \
|
||||||
|
libburn/structure.c \
|
||||||
|
libburn/structure.h \
|
||||||
|
libburn/toc.c \
|
||||||
|
libburn/toc.h \
|
||||||
|
libburn/transport.h \
|
||||||
|
libburn/util.c \
|
||||||
|
libburn/util.h \
|
||||||
|
libburn/write.c \
|
||||||
|
libburn/write.h \
|
||||||
|
version.h
|
||||||
|
|
||||||
|
## libburn/sg-@ARCH@.c \
|
||||||
|
|
||||||
|
libinclude_HEADERS = \
|
||||||
|
libburn/libburn.h
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
## Build test applications
|
||||||
|
noinst_PROGRAMS = \
|
||||||
|
test/libburner \
|
||||||
|
test/telltoc \
|
||||||
|
test/dewav \
|
||||||
|
test/fake_au \
|
||||||
|
test/poll \
|
||||||
|
test/structest
|
||||||
|
|
||||||
|
bin_PROGRAMS = \
|
||||||
|
cdrskin/cdrskin
|
||||||
|
|
||||||
|
test_libburner_CPPFLAGS = -Ilibburn
|
||||||
|
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
test_libburner_SOURCES = test/libburner.c
|
||||||
|
test_telltoc_CPPFLAGS = -Ilibburn
|
||||||
|
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
test_telltoc_SOURCES = test/telltoc.c
|
||||||
|
test_dewav_CPPFLAGS = -Ilibburn
|
||||||
|
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
test_dewav_SOURCES = test/dewav.c
|
||||||
|
test_fake_au_CPPFLAGS =
|
||||||
|
test_fake_au_LDADD =
|
||||||
|
test_fake_au_SOURCES = test/fake_au.c
|
||||||
|
test_poll_CPPFLAGS = -Ilibburn
|
||||||
|
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
test_poll_SOURCES = test/poll.c
|
||||||
|
test_structest_CPPFLAGS = -Ilibburn
|
||||||
|
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
test_structest_SOURCES = test/structest.c
|
||||||
|
|
||||||
|
## cdrskin construction site - ts A60816
|
||||||
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_2_7
|
||||||
|
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
|
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
||||||
|
##
|
||||||
|
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
||||||
|
##
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
## Build documentation (You need Doxygen for this to work)
|
||||||
|
webhost = http://libburn-api.pykix.org
|
||||||
|
webpath = /
|
||||||
|
docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
doc: doc/html
|
||||||
|
|
||||||
|
doc/html: doc/doxygen.conf
|
||||||
|
if [ -f ./doc/doc.lock ]; then \
|
||||||
|
$(RM) -r doc/html; \
|
||||||
|
doxygen doc/doxygen.conf; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
doc-upload: doc/html
|
||||||
|
scp -r $</* $(webhost):$(webpath)
|
||||||
|
|
||||||
|
all: doc
|
||||||
|
|
||||||
|
install-data-local:
|
||||||
|
if [ -f ./doc/doc.lock ]; then \
|
||||||
|
$(mkinstalldirs) $(docdir)/html; \
|
||||||
|
$(INSTALL_DATA) doc/html/* $(docdir)/html; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
uninstall-local:
|
||||||
|
rm -rf $(docdir)
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
# Indent source files
|
||||||
|
indent_files = \
|
||||||
|
$(libburn_libburn_la_SOURCES) \
|
||||||
|
$(test_poll_SOURCES) \
|
||||||
|
$(test_structest_SOURCES)
|
||||||
|
|
||||||
|
|
||||||
|
indent: $(indent_files)
|
||||||
|
indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \
|
||||||
|
-cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \
|
||||||
|
-lp -saf -sai -nprs -npsl -saw -sob -ss -ut \
|
||||||
|
-sbi0 -nsc -ts8 -npcs -ncdb -fca \
|
||||||
|
$^
|
||||||
|
|
||||||
|
.PHONY: indent
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
# Extra things
|
||||||
|
nodist_pkgconfig_DATA = \
|
||||||
|
libburn-1.pc
|
||||||
|
|
||||||
|
# http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages
|
||||||
|
man_MANS = cdrskin/cdrskin.1
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
libburn-1.pc.in \
|
||||||
|
version.h.in \
|
||||||
|
doc/comments \
|
||||||
|
doc/doxygen.conf.in \
|
||||||
|
README \
|
||||||
|
AUTHORS \
|
||||||
|
CONTRIBUTORS \
|
||||||
|
COPYRIGHT \
|
||||||
|
cdrskin/README \
|
||||||
|
cdrskin/cdrecord_spy.sh \
|
||||||
|
cdrskin/compile_cdrskin.sh \
|
||||||
|
cdrskin/convert_man_to_html.sh \
|
||||||
|
cdrskin/changelog.txt \
|
||||||
|
cdrskin/cdrskin_eng.html \
|
||||||
|
cdrskin/wiki_plain.txt \
|
||||||
|
cdrskin/cleanup.h \
|
||||||
|
cdrskin/cleanup.c \
|
||||||
|
libburn/os-freebsd.h \
|
||||||
|
libburn/os-linux.h \
|
||||||
|
libburn/sg-freebsd.c \
|
||||||
|
libburn/sg-linux.c \
|
||||||
|
COPYING \
|
||||||
|
NEWS \
|
||||||
|
ChangeLog \
|
||||||
|
INSTALL \
|
||||||
|
$(man_MANS)
|
||||||
|
|
1
libburn/tags/ZeroThreeZero/NEWS
Normal file
1
libburn/tags/ZeroThreeZero/NEWS
Normal file
@ -0,0 +1 @@
|
|||||||
|
nothing here now
|
231
libburn/tags/ZeroThreeZero/README
Normal file
231
libburn/tags/ZeroThreeZero/README
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
libburnia.pykix.org
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This all is under GPL.
|
||||||
|
(See GPL reference, our clarification and commitment at the end of this text)
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
libburnia.pykix.org
|
||||||
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
Still containing parts of
|
||||||
|
Libburn. By Derek Foreman <derek@signalmarketing.com> and
|
||||||
|
Ben Jansens <xor@orodu.net>
|
||||||
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
These parts are to be replaced by own code of above libburnia.pykix.org
|
||||||
|
copyright holders and then libburnia.pykix.org is to be their sole copyright.
|
||||||
|
This is done to achieve the right to issue the clarification and the
|
||||||
|
commitment as written at the end of this text.
|
||||||
|
The rights and merits of the Libburn-copyright holders Derek Foreman and
|
||||||
|
Ben Jansens will be duely respected.
|
||||||
|
|
||||||
|
This libburnia.pykix.org toplevel README (C) 2006-2007 Thomas Schmitt
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Build and Installation
|
||||||
|
|
||||||
|
Our build system is based on autotools. For preparing the build of a SVN
|
||||||
|
snapshot you will need autotools of at least version 1.7.
|
||||||
|
Check out from SVN by
|
||||||
|
svn co http://libburnia-svn.pykix.org/libburn/trunk libburn_pykix
|
||||||
|
go into directory libburn_pykix and apply autotools by
|
||||||
|
./bootstrap
|
||||||
|
|
||||||
|
Alternatively you may unpack a release tarball for which you do not need
|
||||||
|
autotools installed.
|
||||||
|
|
||||||
|
To build a libburnia.pykix.org subproject it should be sufficient to go
|
||||||
|
into its toplevel directory (here: "libburn_pykix") and execute
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
|
||||||
|
To make the libraries accessible for running resp. developing applications
|
||||||
|
make install
|
||||||
|
|
||||||
|
|
||||||
|
The other half of the project, libisofs, is hosted in the libburnia SVN, too:
|
||||||
|
svn co http://libburnia-svn.pykix.org/libisofs/trunk libisofs_pykix
|
||||||
|
See README file there.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Overview of libburnia.pykix.org
|
||||||
|
|
||||||
|
libburnia.pykix.org is an open-source software project for reading, mastering
|
||||||
|
and writing optical discs. For now this means only CD-R and CD-RW.
|
||||||
|
|
||||||
|
The project comprises of several more or less interdependent parts which
|
||||||
|
together strive to be a usable foundation for application development.
|
||||||
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
|
classical (and valuable) Linux tools.
|
||||||
|
|
||||||
|
Our scope is currently Linux 2.4 and 2.6 only. For 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 of Linux sg or FreeBSD CAM,
|
||||||
|
volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
|
We do have a workable code base for burning data CDs, though. The burn API is
|
||||||
|
quite comprehensively documented and can be used to build a presentable
|
||||||
|
application.
|
||||||
|
We do have a functional binary which emulates parts of cdrecord in order to
|
||||||
|
prove that usability, and in order to allow you to explore libburnia's scope
|
||||||
|
by help of existing cdrecord frontends.
|
||||||
|
|
||||||
|
The project components (list subject to growth, hopefully):
|
||||||
|
|
||||||
|
- libburn is the library by which preformatted data get onto optical media.
|
||||||
|
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
||||||
|
/dev/hdX (e.g. on kernel 2.6).
|
||||||
|
libburn is the foundation of our cdrecord emulation.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
||||||
|
|
||||||
|
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
|
Cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||||
|
Schilling's cdrtools. cdrskin strives to be a second source for
|
||||||
|
the services traditionally provided by cdrecord.
|
||||||
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
Many bytes have been copied from the message output of cdrecord
|
||||||
|
runs, though.
|
||||||
|
See cdrskin/README for more.
|
||||||
|
|
||||||
|
- test is a collection of application gestures and examples given by the
|
||||||
|
authors of the library features. The main API example for libburn
|
||||||
|
is test/libburner.c .
|
||||||
|
Explore these examples if you look for inspiration.
|
||||||
|
|
||||||
|
We plan to be a responsive upstream. Bear with us. We are still practicing.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Project history as far as known to me:
|
||||||
|
|
||||||
|
- Founded in 2002 as it seems. See mailing list archives
|
||||||
|
http://lists.freedesktop.org/archives/libburn/
|
||||||
|
The site of this founder team is reachable and offers download of a
|
||||||
|
(somewhat outdated) tarball and from CVS :
|
||||||
|
http://icculus.org/burn/
|
||||||
|
Copyright holders and most probably founders:
|
||||||
|
Derek Foreman and Ben Jansens.
|
||||||
|
|
||||||
|
- I came to using libburn in 2005. Founded the cdrskin project and submitted
|
||||||
|
necessary patches which were accepted or implemented better. Except one
|
||||||
|
remaining patch which prevented cdrskin from using vanilla libburn from CVS.
|
||||||
|
The cdrskin project site is reachable and offers download of the heavily
|
||||||
|
patched (elsewise outdated) tarball under the name cdrskin-0.1.2 :
|
||||||
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
|
It has meanwhile moved to use vanilla libburn.pykix.org , though.
|
||||||
|
Version 0.1.4 constitutes the first release of this kind.
|
||||||
|
|
||||||
|
- In Juli 2006 our team mate Mario Danic announced a revival of libburn
|
||||||
|
which by about nearly everybody else was perceived as unfriendly fork.
|
||||||
|
Derek Foreman four days later posted a message which expressed his
|
||||||
|
discontent.
|
||||||
|
The situation first caused me to publically regret it and then - after i
|
||||||
|
got the opportunity to move in with cdrskin - gave me true reason to
|
||||||
|
personally apologize to Derek Foreman, Ben Jansens and the contibutors at
|
||||||
|
icculus.org/burn. Posted to both projects:
|
||||||
|
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
|
||||||
|
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
|
||||||
|
|
||||||
|
- Mid August 2006 project cdrskin established a branch office in
|
||||||
|
libburn.pykix.org so that all maintainers of our tools have one single place
|
||||||
|
to get the current (at least slightely) usable coordinated versions of
|
||||||
|
everything.
|
||||||
|
Project cdrskin will live forth independendly for a while but it is committed
|
||||||
|
to stay in sync with libburn.pykix.org (or some successor, if ever).
|
||||||
|
cdrskin is also committed to support icculus.org/burn if the pending fork
|
||||||
|
is made reality by content changes in that project. It will cease to maintain
|
||||||
|
a patched version of icculus.org/burn though. Precondition for a new
|
||||||
|
release of cdrskin on base of icculus.org/burn would be the pending
|
||||||
|
"whitelist patch" therefore.
|
||||||
|
I would rather prefer if both projects find consense and merge, or at least
|
||||||
|
cooperate. I have not given up hope totally, yet.
|
||||||
|
I, personally, will honor any approach.
|
||||||
|
|
||||||
|
- 2nd September 2006 the decision is made to strive for a consolidation of
|
||||||
|
copyright and a commitment to GPL in a reasonable and open minded way.
|
||||||
|
This is to avoid long term problems with code of unknown origin and
|
||||||
|
with finding consense among the not so clearly defined group of copyright
|
||||||
|
claimers and -holders.
|
||||||
|
libisofs is already claimed sole copyright Mario Danic.
|
||||||
|
cdrskin and libburner are already claimed sole copyright Thomas Schmitt.
|
||||||
|
Rewrites of other components will follow and concluded by claiming full
|
||||||
|
copyright within the group of libburn.pykix.org-copyright holders.
|
||||||
|
|
||||||
|
- 16th September 2006 feature freeze for release of libburn-0.2.2 .
|
||||||
|
|
||||||
|
- 20th September 2006 release of libburn-0.2.2 .
|
||||||
|
|
||||||
|
- 26th October 2006 feature freeze for cdrskin-0.2.4 based on libburn-0.2.3 .
|
||||||
|
This version of cdrskin is much more cdrecord compatible in repect
|
||||||
|
to drive addressing and audio features.
|
||||||
|
|
||||||
|
- 30th October 2006 release of cdrskin-0.2.4 .
|
||||||
|
|
||||||
|
- 13th November 2006 splitting releases of libburn+cdrskin from libisofs.
|
||||||
|
|
||||||
|
- 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has
|
||||||
|
become suitable for unaware frontends as long as they perform only the core
|
||||||
|
of cdrecord use cases (including open-ended input streams, audio, and
|
||||||
|
multi-session).
|
||||||
|
|
||||||
|
- 28th November 2006 the umbrella project which encloses both, libisofs and
|
||||||
|
libburn, is now called libburnia. For the origin of this name, see
|
||||||
|
http://en.wikipedia.org/wiki/Liburnians .
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Clarification in my name and in the name of Mario Danic, upcoming copyright
|
||||||
|
holders 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.
|
||||||
|
|
||||||
|
signed: Mario Danic, Thomas Schmitt
|
||||||
|
|
22
libburn/tags/ZeroThreeZero/acinclude.m4
Normal file
22
libburn/tags/ZeroThreeZero/acinclude.m4
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
AC_DEFUN([TARGET_SHIZZLE],
|
||||||
|
[
|
||||||
|
ARCH=""
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
|
case $target in
|
||||||
|
*-*-linux*)
|
||||||
|
ARCH=linux
|
||||||
|
LIBBURN_ARCH_LIBS=
|
||||||
|
;;
|
||||||
|
*-*-freebsd*)
|
||||||
|
ARCH=freebsd
|
||||||
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$ARCH])
|
||||||
|
])
|
10
libburn/tags/ZeroThreeZero/bootstrap
Executable file
10
libburn/tags/ZeroThreeZero/bootstrap
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
|
||||||
|
aclocal
|
||||||
|
libtoolize --copy --force
|
||||||
|
autoconf
|
||||||
|
|
||||||
|
# ts A61101 : libburn is not prepared for config.h
|
||||||
|
# autoheader
|
||||||
|
|
||||||
|
automake --foreign --add-missing --copy --include-deps
|
496
libburn/tags/ZeroThreeZero/cdrskin/README
Normal file
496
libburn/tags/ZeroThreeZero/cdrskin/README
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
libburnia.pykix.org scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Installation instructions at about line 60. First the legal stuff:
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This all is under GPL.
|
||||||
|
(See GPL reference, our clarification and commitment at the end of this text)
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Based on and sub project of:
|
||||||
|
libburnia.pykix.org
|
||||||
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
libburnia.pykix.org is inspired by and in other components still containing
|
||||||
|
parts of
|
||||||
|
Libburn. By Derek Foreman <derek@signalmarketing.com> and
|
||||||
|
Ben Jansens <xor@orodu.net>
|
||||||
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
See toplevel README for an overview of the current copyright situation in
|
||||||
|
libburnia.pykix.org.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
My thanks to the above authors (except myself, of course) for making the
|
||||||
|
following possible.
|
||||||
|
|
||||||
|
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
Integrated sub project of libburnia.pykix.org but also published via:
|
||||||
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
|
http://scdbackup.sourceforge.net/cdrskin-0.2.7.tar.gz
|
||||||
|
Copyright (C) 2006-2007 Thomas Schmitt
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
On top of libburn there is implemented cdrskin 0.2.7, a limited cdrecord
|
||||||
|
compatibility wrapper which allows to use some libburn features from
|
||||||
|
the command line.
|
||||||
|
Interested users of cdrecord are invited to participate in the development
|
||||||
|
of cdrskin. Contact: scdbackup@gmx.net or libburn-hackers@pykix.org .
|
||||||
|
We will keep copyright narrow but will of course acknowledge valuable
|
||||||
|
contributions in a due way.
|
||||||
|
|
||||||
|
|
||||||
|
Important :
|
||||||
|
This software is provided as is. There is no warranty implied and no
|
||||||
|
protection against possible damages. You use this on your own risk.
|
||||||
|
Don't blame me or other authors of libburn if anything goes wrong.
|
||||||
|
|
||||||
|
I used it on my own risk with :
|
||||||
|
SuSE 7.2, kernel 2.4.4, ide-scsi emulation, LITE-ON LTR48125S CD burner, 2002
|
||||||
|
SuSE 9.0, kernel 2.4.21, ide-scsi emulation, LG GSA-4082B CD/DVD burner, 2004
|
||||||
|
NEC ND-4570A CD/DVD burner, 2006
|
||||||
|
RIP-14.4, kernel 2.6.14, no ide-scsi, with all above burners
|
||||||
|
|
||||||
|
It fails to compile or run on SuSE 6.4 (kernel 2.2.14).
|
||||||
|
It does not find the IDE CD burner on SuSE 7.2 without ide-scsi.
|
||||||
|
Other people sucessfully tested cdrskin on several kernel 2.6 based x86 Linux
|
||||||
|
systems, including 64 bit systems. (Further reports are welcome.)
|
||||||
|
|
||||||
|
|
||||||
|
Compilation, First Glimpse, Installation
|
||||||
|
|
||||||
|
Obtain cdrskin-0.2.7.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
|
tar xzf cdrskin-0.2.7.tar.gz
|
||||||
|
cd cdrskin-0.2.7
|
||||||
|
|
||||||
|
Or obtain a libburnia.pykix.org SVN snapshot,
|
||||||
|
go into the toplevel directory of the snapshot (e.g. cd libburn_pykix ),
|
||||||
|
and execute the autotools script ./bootstrap . Use autools version >= 1.7 .
|
||||||
|
|
||||||
|
Within that toplevel directory of either cdrskin-0.2.7 or libburn then execute:
|
||||||
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
|
||||||
|
(Note: there are next-level directories "libburn" and "cdrskin". Those
|
||||||
|
would be the wrong ones. Meant is the highest directory of tarball resp.
|
||||||
|
SVN download. Among others containing files "AUTHORS", "configure",
|
||||||
|
"Makefile.am", as well as directories "libburn" and "cdrskin".)
|
||||||
|
|
||||||
|
This will already produce a cdrskin binary. But it might be necessary to
|
||||||
|
install libburn in order to use this binary. Installation of libburn is
|
||||||
|
beyond the scope of cdrskin. For this, see included libburn docs.
|
||||||
|
|
||||||
|
In order to surely get a standalone binary, execute
|
||||||
|
|
||||||
|
cdrskin/compile_cdrskin.sh
|
||||||
|
|
||||||
|
Version identification and help texts available afterwards:
|
||||||
|
cdrskin/cdrskin -version
|
||||||
|
cdrskin/cdrskin --help
|
||||||
|
cdrskin/cdrskin -help
|
||||||
|
man cdrskin/cdrskin.1
|
||||||
|
|
||||||
|
Install (eventually as superuser) cdrskin to a directory where it can be found:
|
||||||
|
If cdrskin was already installed by a previous version, or by "make install"
|
||||||
|
in the course of this installation, then find out where:
|
||||||
|
which cdrskin
|
||||||
|
Copy your standalone binary to exactly the address which you get as reply
|
||||||
|
|
||||||
|
cp cdrskin/cdrskin /usr/bin/cdrskin
|
||||||
|
|
||||||
|
Check the version timestamps of the globally installed binary
|
||||||
|
cdrskin -version
|
||||||
|
|
||||||
|
It is not necessary for the standalone cdrskin binary to have libburn
|
||||||
|
installed, since it incorporates the necessary libburn parts at compile time.
|
||||||
|
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
|
||||||
|
below for a way to create a statically linked binary.)
|
||||||
|
|
||||||
|
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:
|
||||||
|
cp cdrskin/cdrskin.1 /usr/share/man/man1/cdrskin.1
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
|
||||||
|
The user of cdrskin needs rw-permission for the CD burner device.
|
||||||
|
A list of rw-accessible drives can be obtained by
|
||||||
|
|
||||||
|
cdrskin --devices
|
||||||
|
|
||||||
|
CD devices which offer no rw-permission are invisible to normal users.
|
||||||
|
The superuser should be able to see any usable drive and then set the
|
||||||
|
permissions as needed. If this hangs then there is a drive with
|
||||||
|
unexpected problems (locked, busy, broken, whatever). You might have to
|
||||||
|
guess the address of your (non-broken) burner by other means, then.
|
||||||
|
On Linux 2.4 this would be some /dev/sgN and on 2.6. some /dev/hdX.
|
||||||
|
|
||||||
|
The output of cdrskin --devices might look like
|
||||||
|
|
||||||
|
0 dev='/dev/sg0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
|
||||||
|
1 dev='/dev/sg1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
||||||
|
|
||||||
|
So full and insecure enabling of both for everybody would look like
|
||||||
|
|
||||||
|
chmod a+rw /dev/sg0 /dev/sg1
|
||||||
|
|
||||||
|
I strongly discourage to run cdrskin with setuid root or via sudo !
|
||||||
|
It is not checked for the necessary degree of hacker safety.
|
||||||
|
|
||||||
|
|
||||||
|
Usage examples
|
||||||
|
|
||||||
|
Get an overview of cdrecord style addresses of available devices
|
||||||
|
cdrskin -scanbus
|
||||||
|
cdrskin dev=ATA -scanbus
|
||||||
|
cdrskin --devices
|
||||||
|
|
||||||
|
Adresses reported with dev=ATA need prefix "ATA:". Address examples:
|
||||||
|
dev=0,1,0 dev=ATA:1,0,0 dev=/dev/sg1 dev=/dev/hdc
|
||||||
|
See also "Drive Addressing" below.
|
||||||
|
|
||||||
|
Obtain some info about the drive
|
||||||
|
cdrskin dev=0,1,0 -checkdrive
|
||||||
|
|
||||||
|
Obtain some info about the drive and the inserted media
|
||||||
|
cdrskin dev=0,1,0 -atip -v
|
||||||
|
|
||||||
|
Thoroughly blank a CD-RW
|
||||||
|
cdrskin -v dev=0,1,0 blank=all -eject
|
||||||
|
|
||||||
|
Blank CD-RW sufficiently for making it ready for overwrite
|
||||||
|
cdrskin -v dev=0,1,0 blank=fast -eject
|
||||||
|
|
||||||
|
Burn image file my_image.iso to CD or DVD+-RW
|
||||||
|
cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \
|
||||||
|
-eject my_image.iso
|
||||||
|
|
||||||
|
Burn a compressed afio archive to CD or DVD+-RW on-the-fly
|
||||||
|
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 -tao \
|
||||||
|
driveropts=burnfree padsize=300k -
|
||||||
|
|
||||||
|
Burn 6 audio tracks from files with different formats to CD.
|
||||||
|
Anything except .wav or .au files has to be converted into raw format first.
|
||||||
|
See below "Audio CD" for specifications.
|
||||||
|
ogg123 -d raw -f track01.cd /path/to/track1.ogg
|
||||||
|
oggdec -R -o track02.cd /path/to/track2.ogg
|
||||||
|
lame --decode -t /path/to/track3.mp3 track03.cd
|
||||||
|
madplay -o raw:track04.cd /path/to/track4.mp3
|
||||||
|
mppdec --raw-le /path/to/track5.mpc track05.cd
|
||||||
|
|
||||||
|
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
|
||||||
|
-audio -swab track0[1-5].cd /path/to/track6.wav
|
||||||
|
|
||||||
|
|
||||||
|
Usage example with http://scdbackup.sourceforge.net
|
||||||
|
|
||||||
|
Address may be a cdrecord-style "scsibus,target,lun" as listed with
|
||||||
|
cdrskin -scanbus (and hopefully as listed with cdrecord -scanbus) :
|
||||||
|
|
||||||
|
export SCDBACKUP_SCSI_ADR="0,1,0"
|
||||||
|
|
||||||
|
or a device file address as listed by --devices with an accessible drive :
|
||||||
|
|
||||||
|
export SCDBACKUP_SCSI_ADR="/dev/sg1"
|
||||||
|
|
||||||
|
Set usage of cdrskin with appropriate options rather than cdrecord :
|
||||||
|
|
||||||
|
export SCDBACKUP_CDRECORD="cdrskin -v -v"
|
||||||
|
|
||||||
|
Run a backup :
|
||||||
|
|
||||||
|
scdbackup_home
|
||||||
|
|
||||||
|
|
||||||
|
Restrictions
|
||||||
|
|
||||||
|
The major restrictions are lifted now: audio, TAO, multi-session do work.
|
||||||
|
Many cdrecord options are still unsupported, though.
|
||||||
|
|
||||||
|
If you have use cases for them, please report your wishes and expectations.
|
||||||
|
|
||||||
|
DVD support is still immature and restricted to DVD+-RW for now.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Inspiration and Standard
|
||||||
|
|
||||||
|
For the original meaning of cdrecord options see :
|
||||||
|
man cdrecord
|
||||||
|
(http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html)
|
||||||
|
Do not bother Joerg Schilling with any cdrskin problems.
|
||||||
|
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
|
||||||
|
this "don't bother Joerg" demand.)
|
||||||
|
cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes
|
||||||
|
have been copied from the message output of cdrecord runs, though. I am
|
||||||
|
thankful to Joerg Schilling for every single one of them.
|
||||||
|
|
||||||
|
Actually i, Thomas Schmitt, am a devoted user of cdrecord via my project
|
||||||
|
scdbackup which still runs a bit better with cdrecord than with cdrskin. TAO.
|
||||||
|
I have the hope that Joerg feels more flattered than annoyed by cdrskin.
|
||||||
|
|
||||||
|
|
||||||
|
Drive Addressing
|
||||||
|
|
||||||
|
Drives get addressed either via their cdrecord-style addresses as listed
|
||||||
|
with option -scanbus (see below "Pseudo-SCSI Adresses") or via the paths
|
||||||
|
of device files.
|
||||||
|
Not only device files listed by --devices may be used but also device files
|
||||||
|
which via their major,minor numbers point to the same device driver as
|
||||||
|
a listed device file.
|
||||||
|
|
||||||
|
Helpful with Linux kernel 2.4 is a special SCSI feature:
|
||||||
|
It is possible to address a scsi(-emulated) drive via associated device files
|
||||||
|
which are not listed by option --devices but point to the same SCSI addresses
|
||||||
|
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.
|
||||||
|
|
||||||
|
Pseudo-SCSI Adresses
|
||||||
|
|
||||||
|
cdrecord and cdrskin share the syntax of SCSI addresses but not necessarily
|
||||||
|
the meaning of the components. A cdrecord-style address for cdrskin
|
||||||
|
[prefix:]scsibus,target,lun
|
||||||
|
can be interpreted in two different modes.
|
||||||
|
|
||||||
|
Standard mode tries to be compatible to original cdrecord. This should be true
|
||||||
|
with (emulated) SCSI where the /dev/sgN with is looked up with matching
|
||||||
|
scsibus,target,lun as given by the operating system.
|
||||||
|
With dev=ATA: or dev=ATAPI: the translation to /dev/hdX is purely literal
|
||||||
|
but matches the cdrecord addresses on all systems tested so far:
|
||||||
|
X = 'a' + 2 * scsibus + target
|
||||||
|
where target only may have the values 0 or 1.
|
||||||
|
|
||||||
|
In this mode, option -scanbus will list only SCSI devices unless option
|
||||||
|
dev=ATA or dev=ATAPI are given, which will suppress SCSI devices and only
|
||||||
|
show IDE drives (i.e. /dev/hdX without ide-scsi emulation).
|
||||||
|
|
||||||
|
|
||||||
|
In mode --old_pseudo_scsi_adr there is a scsibus,target,lun representation
|
||||||
|
which has nothing to do with SCSI and thus is not compatible to cdrecord.
|
||||||
|
Each number triple corresponds either to a device file address or to a
|
||||||
|
libburn drive number.
|
||||||
|
Component "scsibus" indicates the translation method. Defined busses are:
|
||||||
|
0 target is the libburn drivenumber as listed with --devices
|
||||||
|
1 associated to device file /dev/sgN , target chooses N
|
||||||
|
2 associated to device file /dev/hdX , target 0='a', 1='b' ..., 25='z'
|
||||||
|
|
||||||
|
So "1,1,0" is /dev/sg1, "2,3,0" is /dev/hdd, "0,2,0" is libburn drive #2 at
|
||||||
|
some unspecified device file.
|
||||||
|
This scheme shall help to keep cdrecord-style addresses stable and exchangeable
|
||||||
|
between users without excluding drives with unexpected device addresses.
|
||||||
|
The numbering on bus 0 is prone to arbitrary changes caused by changes in
|
||||||
|
drive accessability.
|
||||||
|
Further busses may emerge as libburn evolves. "prefix" and "lun" may get
|
||||||
|
a meaning. To stay upward compatible, use addresses as printed by -scanbus.
|
||||||
|
|
||||||
|
User Defined Device Address Translation
|
||||||
|
|
||||||
|
Some programs or users have their own ideas about the address of their burner.
|
||||||
|
K3b 0.10 for example derives cdrecord addresses by own examination of the
|
||||||
|
devices and not by calling cdrecord -scanbus.
|
||||||
|
Standard mode will hopefully be fully compatible with their ideas.
|
||||||
|
|
||||||
|
Old frontends which do not know dev=ATA or dev=ATAPI and which do ask their
|
||||||
|
"cdrecord" via -scanbus may be well served with option --old_pseudo_scsi_adr .
|
||||||
|
|
||||||
|
To direct any remaining stubborn callers to the appropriate drives, cdrskin
|
||||||
|
allows to define device address aliases. Like
|
||||||
|
cdrskin dev_translation=+1,0,0+/dev/sg1 \
|
||||||
|
dev_translation=+ATA:1,0,0+/dev/sg1 \
|
||||||
|
dev_translation=-"cd+dvd"-0,1,0 \
|
||||||
|
...
|
||||||
|
Any of the addresses dev=1,0,0, dev=ATA:1,0,0, dev=cd+dvd will be mapped to
|
||||||
|
/dev/sg1 resp. to 0,1,0.
|
||||||
|
The first character after "dev_translation=" defines the character which
|
||||||
|
separates the two parts of the translation pair. (Above: "+" and "-".)
|
||||||
|
|
||||||
|
In K3b 0.10 it is possible to employ alternative writer programs by setting
|
||||||
|
their full path (e.g. /usr/bin/cdrskin) in menu
|
||||||
|
Settings:Configure K3b...:Programs:Search Path
|
||||||
|
and to make them default in menu
|
||||||
|
Settings:Configure K3b...:Programs:Programs:
|
||||||
|
A suitable setting for "cdrecord" in menu
|
||||||
|
Settings:Configure K3b...:Programs:User Parameters
|
||||||
|
would then probably be
|
||||||
|
-v dev_translation=+1,0,0+/dev/sg1
|
||||||
|
You will learn from button "Show Debugging Output" after a failed burn run
|
||||||
|
what cdrecord command was used with what address "dev=...". This address "..."
|
||||||
|
will be the right one to replace "1,0,0" in above example.
|
||||||
|
|
||||||
|
|
||||||
|
Startup Files
|
||||||
|
|
||||||
|
If not --no_rc is the first argument then cdrskin attempts on startup to read
|
||||||
|
arguments from the following three files:
|
||||||
|
/etc/default/cdrskin
|
||||||
|
/etc/opt/cdrskin/rc
|
||||||
|
/etc/cdrskin/cdrskin.conf
|
||||||
|
$HOME/.cdrskinrc
|
||||||
|
The files are read in the sequence given above.
|
||||||
|
Each readable line is treated as one single argument. No extra blanks.
|
||||||
|
A first character '#' marks a comment, empty lines are ignored.
|
||||||
|
|
||||||
|
Example content of a startup file:
|
||||||
|
# This is the default device
|
||||||
|
dev=0,1,0
|
||||||
|
# To accomodate to eventual remnant cdrskin-0.2.2 addresses
|
||||||
|
dev_translation=+1,0,0+0,1,0
|
||||||
|
|
||||||
|
# Some more options
|
||||||
|
fifo_start_at=0
|
||||||
|
fs=16m
|
||||||
|
|
||||||
|
|
||||||
|
Audio CD
|
||||||
|
|
||||||
|
Lorenzo Taylor enabled option -audio in cdrskin (thanks !) and reports neat
|
||||||
|
results with audio data files which are :
|
||||||
|
headerless PCM (i.e. uncompressed)
|
||||||
|
44100 Hz sampling rate
|
||||||
|
16 bits per sample
|
||||||
|
stereo (2 channels)
|
||||||
|
little-endian byte order with option -swab, or big-endian without -swab
|
||||||
|
|
||||||
|
Files with name extension .wav get examined wether they are in Microsoft WAVE
|
||||||
|
format with above parameters and eventually get extracted by cdrskin itself.
|
||||||
|
In the same way files with name extension .au get examined wether they are
|
||||||
|
in SUN's audio format. For both formats, track format -audio and eventual
|
||||||
|
endianness option -swab are enabled automatically.
|
||||||
|
|
||||||
|
Any other formats are to be converted to format .wav with above parameters
|
||||||
|
or to be extracted as raw CD track data by commands like those given above
|
||||||
|
under "Usage examples". Those raw files need option -audio and in most cases
|
||||||
|
option -swab to mark them as little-endian/Intel/LSB-first 16-bit data.
|
||||||
|
Incorrect endianness setting results in random noise on CD.
|
||||||
|
|
||||||
|
I myself am not into audio. So libburn-hackers@pykix.org might be the
|
||||||
|
best address for suggestions, requests and bug reports.
|
||||||
|
|
||||||
|
|
||||||
|
DVD+RW and DVD-RAM
|
||||||
|
|
||||||
|
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
|
||||||
|
hold data or not. Options -audio and -multi are not allowed. Only one track
|
||||||
|
is allowed. -toc does not return information about the media content.
|
||||||
|
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second). Currently
|
||||||
|
there is no difference between -sao and -tao. If ever, then -tao will be the
|
||||||
|
mode which preserves the current behavior.
|
||||||
|
|
||||||
|
For these media, -msinfo alone would not be enough to perform appending of an
|
||||||
|
ISO filesystem. The filesystem driver will need a hint to find the start of the
|
||||||
|
most recent session. For example put an ISO filesystem at address 1 GB:
|
||||||
|
mkisofs -C 0,524288 ... | \
|
||||||
|
cdrskin dev=/dev/sr0 -v fs=32m -eject speed=4 write_start_address=524288s -
|
||||||
|
The superuser may then do:
|
||||||
|
mount -t iso9660 -o ro,sbsector=524288 /dev/sr0 /mnt
|
||||||
|
Note: On my linux-2.4.21-215 mount works only with sbsector <= 337920 (660 MB).
|
||||||
|
To extend a filesystem already existing at address 0
|
||||||
|
mkisofs -C 0,524288 -M /dev/sr0 ... | cdrskin dev=/dev/sr0 ...
|
||||||
|
Record the number 524288 for usage as first number with -C at the next
|
||||||
|
extension:
|
||||||
|
mkisofs -C 524288,1000000 ... | cdrskin write_start_address=1000000s ...
|
||||||
|
|
||||||
|
Program growisofs can append to an ISO filesystem on DVD+RW by additionally
|
||||||
|
manipulating the first session. cdrskin does not want to get involved so deep
|
||||||
|
into the format of the burned data. Be advised to use growisofs for the
|
||||||
|
task of maintaining extendable ISO-Filesystems on DVD+RW.
|
||||||
|
|
||||||
|
|
||||||
|
DVD-RW
|
||||||
|
|
||||||
|
DVD-RW are usable if formatted to state "Restricted Overwrite". They then
|
||||||
|
behave much like DVD+RW. See above.
|
||||||
|
DVD-RW in state "Sequential" have first to be formatted by
|
||||||
|
cdrskin dev=... -v blank=format_overwrite
|
||||||
|
"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.
|
||||||
|
(Command dvd+rw-format -force can achieve "Restricted Overwrite".)
|
||||||
|
|
||||||
|
Formatting or first use of freshly formatted DVD-RW can produce unusual noises
|
||||||
|
from the drive and last several minutes. Depending on mutual compatibility of
|
||||||
|
drive and media, formatting can yield unusable media. It seems that those die
|
||||||
|
too on blanking by cdrecord or dvd+rw-format. Perils of DVD-RW, i fear.
|
||||||
|
|
||||||
|
There are three formatting variants with cdrskin currently:
|
||||||
|
|
||||||
|
blank=format_overwrite uses "DVD-RW Quick" formatting (MMC-type 15h)
|
||||||
|
and writes a first session of 128 MB. This leads to media which are expandable
|
||||||
|
and random addressable by cdrskin.
|
||||||
|
|
||||||
|
blank=format_overwrite_quickest uses "DVD-RW Quick" formatting (type 15h) too,
|
||||||
|
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
|
||||||
|
addressable by cdrskin.
|
||||||
|
|
||||||
|
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
Special compilation variations
|
||||||
|
|
||||||
|
You may get a (super fat) statically linked binary by :
|
||||||
|
cdrskin/compile_cdrskin.sh -static
|
||||||
|
if your system supports static linking, at all. This will not help with kernels
|
||||||
|
which do not properly support the necessary low-level interfaces chosen by
|
||||||
|
your compile-time libraries.
|
||||||
|
|
||||||
|
A size reduced but fully functional binary may be produced by
|
||||||
|
cdrskin/compile_cdrskin.sh -do_strip
|
||||||
|
|
||||||
|
An extra lean binary with reduced capabilities is created by
|
||||||
|
cdrskin/compile_cdrskin.sh -do_diet -do_strip
|
||||||
|
It will not read startup files, will abort on option dev_translation= ,
|
||||||
|
will not have a fifo buffer, and will not be able to put out help texts or
|
||||||
|
debugging messages.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
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
|
206
libburn/tags/ZeroThreeZero/cdrskin/add_ts_changes_to_libburn_0_2_6
Executable file
206
libburn/tags/ZeroThreeZero/cdrskin/add_ts_changes_to_libburn_0_2_6
Executable file
@ -0,0 +1,206 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# This script documents how this cdrskin version was derived from
|
||||||
|
# a vanilla libburn version. It is not intended nor needed for any
|
||||||
|
# use of cdrskin but included here only to show the technical
|
||||||
|
# relationship between both projects - which are close friends
|
||||||
|
# and issue roughly the same software.
|
||||||
|
#
|
||||||
|
# Package maintainers are advised to cover rather libburn than
|
||||||
|
# cdrskin unless they put only emphasis on the cdrecord emulation
|
||||||
|
# provided by cdrskin. libburn contains cdrskin - cdrskin is an
|
||||||
|
# oscillating, friendly and coordinated fork of libburn.
|
||||||
|
#
|
||||||
|
# Script results are a source tarball and two binaries
|
||||||
|
# one dynamic and one static in respect to system libs.
|
||||||
|
# Both binaries are static in respect to libburn.
|
||||||
|
#
|
||||||
|
# The script is to be run in the directory above the toplevel
|
||||||
|
# directory of libburn resp. cdrskin development.
|
||||||
|
#
|
||||||
|
# libburn version used: http://libburn.pykix.org
|
||||||
|
# Downloaded by:
|
||||||
|
# $ svn co http://libburn-svn.pykix.org/trunk libburn_pykix
|
||||||
|
# packed up in a tarball just to save it from inadverted changes by
|
||||||
|
# $ tar czf libburn_svn.tgz libburn_pykix
|
||||||
|
original="./libburn_svn.tgz"
|
||||||
|
# Historic moments:
|
||||||
|
# original="./libburn_svn_A60815.tgz"
|
||||||
|
# original="./libburn_cdrskin_A60819.tgz"
|
||||||
|
|
||||||
|
# The top level directory in that snapshot is named
|
||||||
|
intermediate="./libburn_pykix"
|
||||||
|
|
||||||
|
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
|
||||||
|
|
||||||
|
changes="./libburn-0.2.3.ts.develop"
|
||||||
|
skin_release="0.2.6"
|
||||||
|
patch_level=".pl01"
|
||||||
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
|
|
||||||
|
# The result directory and the name of the result tarballs
|
||||||
|
target="./cdrskin-${skin_release}"
|
||||||
|
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
|
||||||
|
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
|
||||||
|
|
||||||
|
# (This once earned me an embarrassingly blooping source tarball)
|
||||||
|
# compile_dir="$changes"
|
||||||
|
|
||||||
|
compile_dir="$target"
|
||||||
|
compile_cmd="./cdrskin/compile_cdrskin.sh"
|
||||||
|
compile_static_opts="-static"
|
||||||
|
compile_result="cdrskin/cdrskin"
|
||||||
|
|
||||||
|
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||||
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
|
if test -d "$changes"
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "$0 : FATAL : no directory $changes" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in "$target" "$intermediate"
|
||||||
|
do
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
echo "$0 : FATAL : already existing $i" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -f "$original"
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "$0 : FATAL : no file $original" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Unpack SVN snapshot.
|
||||||
|
tar xzf "$original"
|
||||||
|
|
||||||
|
|
||||||
|
# Rename the directory to the cdrskin name
|
||||||
|
mv "$intermediate" "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Copy the changes from the development tree
|
||||||
|
#
|
||||||
|
cdrskin_dir="$changes"/cdrskin
|
||||||
|
libburn_dir="$changes"/libburn
|
||||||
|
cdrskin_target="$target"/cdrskin
|
||||||
|
libburn_target="$target"/libburn
|
||||||
|
|
||||||
|
# Create version timestamp
|
||||||
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
|
echo "$timestamp"
|
||||||
|
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
|
||||||
|
|
||||||
|
# Add the cdrskin files
|
||||||
|
if test -e "$cdrskin_target"
|
||||||
|
then
|
||||||
|
rm -rf "$cdrskin_target"
|
||||||
|
fi
|
||||||
|
cp -a "$cdrskin_dir" "$cdrskin_target"
|
||||||
|
|
||||||
|
# Remove copied binaries
|
||||||
|
rm "$cdrskin_target"/*.o
|
||||||
|
rm "$cdrskin_target"/cdrfifo
|
||||||
|
rm "$cdrskin_target"/cdrskin
|
||||||
|
rm "$cdrskin_target"/cleanup
|
||||||
|
for i in std new make old
|
||||||
|
do
|
||||||
|
if test -e "$cdrskin_target"/cdrskin_"$i"
|
||||||
|
then
|
||||||
|
rm "$cdrskin_target"/cdrskin_"$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
for i in .deps .dirstamp .libs
|
||||||
|
do
|
||||||
|
if test -e "$cdrskin_target"/"$i"
|
||||||
|
then
|
||||||
|
rm -rf "$cdrskin_target"/"$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove unwanted SVN stuff (TODO: avoid downloading it)
|
||||||
|
for i in "$target"/.svn "$target"/*/.svn
|
||||||
|
do
|
||||||
|
if test "$i" = "$target"'/*/.svn'
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
rm -rf "$i"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
## No more : Add own libburn-README in toplevel
|
||||||
|
# cp -a "$changes"/README "$target"
|
||||||
|
|
||||||
|
## No more : Add modified Makefile.am
|
||||||
|
# cp -a "$changes"/Makefile.am "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Make SVN state tarball for the libburn team
|
||||||
|
tar czf "$cdrskin_tarball_svn" "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Get over dependecy on autotools. Rely only on cc, make et. al.
|
||||||
|
# This is not the same as "make dist" but i can do it without
|
||||||
|
# having to evaluate the quality of said "make dist"
|
||||||
|
#
|
||||||
|
( cd "$target" ; ./bootstrap )
|
||||||
|
|
||||||
|
# Remove unwanted stuff after bootstrap
|
||||||
|
for i in "$target"/autom4te.cache
|
||||||
|
do
|
||||||
|
if echo "$i" | grep '\*' >/dev/null
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
rm -rf "$i"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Pack it up to the new libburn+cdrskin-tarball
|
||||||
|
tar czf "$cdrskin_tarball" "$target"
|
||||||
|
|
||||||
|
# Produce a static and a dynamic binary
|
||||||
|
(
|
||||||
|
cd "$compile_dir" || exit 1
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
$compile_cmd -do_strip
|
||||||
|
cp "$compile_result" "../$bintarget_dynamic"
|
||||||
|
if test -n "$compile_static_opts"
|
||||||
|
then
|
||||||
|
$compile_cmd $compile_static_opts -do_strip
|
||||||
|
cp "$compile_result" "../$bintarget_static"
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove the build area
|
||||||
|
# Disable this for debugging the merge process
|
||||||
|
rm -rf "$target"
|
||||||
|
|
||||||
|
# Show the result
|
||||||
|
./"$bintarget_dynamic" -version
|
||||||
|
./"$bintarget_static" -version
|
||||||
|
ls -l "$cdrskin_tarball"
|
||||||
|
ls -l "$bintarget_dynamic"
|
||||||
|
ls -l "$bintarget_static"
|
||||||
|
|
217
libburn/tags/ZeroThreeZero/cdrskin/add_ts_changes_to_libburn_0_2_7
Executable file
217
libburn/tags/ZeroThreeZero/cdrskin/add_ts_changes_to_libburn_0_2_7
Executable file
@ -0,0 +1,217 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# This script documents how this cdrskin version was derived from
|
||||||
|
# a vanilla libburn version. It is not intended nor needed for any
|
||||||
|
# use of cdrskin but included here only to show the technical
|
||||||
|
# relationship between both projects - which are close friends
|
||||||
|
# and issue roughly the same software.
|
||||||
|
#
|
||||||
|
# Package maintainers are advised to cover rather libburn than
|
||||||
|
# cdrskin unless they put only emphasis on the cdrecord emulation
|
||||||
|
# provided by cdrskin. libburn contains cdrskin - cdrskin is an
|
||||||
|
# oscillating, friendly and coordinated fork of libburn.
|
||||||
|
#
|
||||||
|
# Script results are a source tarball and two binaries
|
||||||
|
# one dynamic and one static in respect to system libs.
|
||||||
|
# Both binaries are static in respect to libburn.
|
||||||
|
#
|
||||||
|
# The script is to be run in the directory above the toplevel
|
||||||
|
# directory of libburn resp. cdrskin development.
|
||||||
|
#
|
||||||
|
# libburn version used: http://libburn.pykix.org
|
||||||
|
# Downloaded by:
|
||||||
|
# $ svn co http://libburn-svn.pykix.org/libburn/trunk libburn_pykix
|
||||||
|
# packed up in a tarball just to save it from inadverted changes by
|
||||||
|
# $ tar czf libburn_svn.tgz libburn_pykix
|
||||||
|
original="./libburn_svn.tgz"
|
||||||
|
# Historic moments:
|
||||||
|
# original="./libburn_svn_A60815.tgz"
|
||||||
|
# original="./libburn_cdrskin_A60819.tgz"
|
||||||
|
|
||||||
|
# The top level directory in that snapshot is named
|
||||||
|
intermediate="./libburn_pykix"
|
||||||
|
|
||||||
|
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
|
||||||
|
|
||||||
|
changes="./libburn-0.2.3.ts.develop"
|
||||||
|
skin_rev="0.2.7"
|
||||||
|
|
||||||
|
# The result directory and the name of the result tarballs
|
||||||
|
target="./cdrskin-${skin_rev}"
|
||||||
|
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
|
||||||
|
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
|
||||||
|
|
||||||
|
# (This once earned me an embarrassingly blooping source tarball)
|
||||||
|
# compile_dir="$changes"
|
||||||
|
|
||||||
|
compile_dir="$target"
|
||||||
|
compile_cmd="./cdrskin/compile_cdrskin.sh"
|
||||||
|
compile_static_opts="-static"
|
||||||
|
compile_result="cdrskin/cdrskin"
|
||||||
|
|
||||||
|
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
||||||
|
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
|
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||||
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
|
if test -d "$changes"
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "$0 : FATAL : no directory $changes" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in "$target" "$intermediate"
|
||||||
|
do
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
echo "$0 : FATAL : already existing $i" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -f "$original"
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "$0 : FATAL : no file $original" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Unpack SVN snapshot.
|
||||||
|
tar xzf "$original"
|
||||||
|
|
||||||
|
|
||||||
|
# Rename the directory to the cdrskin name
|
||||||
|
mv "$intermediate" "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Copy the changes from the development tree
|
||||||
|
#
|
||||||
|
cdrskin_dir="$changes"/cdrskin
|
||||||
|
libburn_dir="$changes"/libburn
|
||||||
|
cdrskin_target="$target"/cdrskin
|
||||||
|
libburn_target="$target"/libburn
|
||||||
|
|
||||||
|
# Create version timestamp
|
||||||
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
|
echo "$timestamp"
|
||||||
|
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
|
||||||
|
|
||||||
|
# Add the cdrskin files
|
||||||
|
if test -e "$cdrskin_target"
|
||||||
|
then
|
||||||
|
rm -rf "$cdrskin_target"
|
||||||
|
fi
|
||||||
|
cp -a "$cdrskin_dir" "$cdrskin_target"
|
||||||
|
|
||||||
|
# Remove copied binaries
|
||||||
|
rm "$cdrskin_target"/*.o
|
||||||
|
rm "$cdrskin_target"/cdrfifo
|
||||||
|
rm "$cdrskin_target"/cdrskin
|
||||||
|
rm "$cdrskin_target"/cleanup
|
||||||
|
for i in std new make old
|
||||||
|
do
|
||||||
|
if test -e "$cdrskin_target"/cdrskin_"$i"
|
||||||
|
then
|
||||||
|
rm "$cdrskin_target"/cdrskin_"$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove automatically generated HTML man page
|
||||||
|
rm "$cdrskin_target"/man_1_cdrskin.html
|
||||||
|
|
||||||
|
# Remove eventual SVN stuff from cdrskin driectory
|
||||||
|
for i in .deps .dirstamp .libs
|
||||||
|
do
|
||||||
|
if test -e "$cdrskin_target"/"$i"
|
||||||
|
then
|
||||||
|
rm -rf "$cdrskin_target"/"$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove GIFs of cdrskin_eng.html
|
||||||
|
rm "$cdrskin_target"/doener_*.gif
|
||||||
|
|
||||||
|
# Remove unwanted SVN stuff (TODO: avoid downloading it)
|
||||||
|
for i in "$target"/.svn "$target"/*/.svn
|
||||||
|
do
|
||||||
|
if test "$i" = "$target"'/*/.svn'
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
rm -rf "$i"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
## No more : Add own libburn-README in toplevel
|
||||||
|
# cp -a "$changes"/README "$target"
|
||||||
|
|
||||||
|
## No more : Add modified Makefile.am
|
||||||
|
# cp -a "$changes"/Makefile.am "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Make SVN state tarball for the libburn team
|
||||||
|
tar czf "$cdrskin_tarball_svn" "$target"
|
||||||
|
|
||||||
|
|
||||||
|
# Get over dependecy on autotools. Rely only on cc, make et. al.
|
||||||
|
# This is not the same as "make dist" but i can do it without
|
||||||
|
# having to evaluate the quality of said "make dist"
|
||||||
|
#
|
||||||
|
( cd "$target" ; ./bootstrap )
|
||||||
|
|
||||||
|
# Remove unwanted stuff after bootstrap
|
||||||
|
for i in "$target"/autom4te.cache
|
||||||
|
do
|
||||||
|
if echo "$i" | grep '\*' >/dev/null
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
if test -e "$i"
|
||||||
|
then
|
||||||
|
rm -rf "$i"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Pack it up to the new libburn+cdrskin-tarball
|
||||||
|
tar czf "$cdrskin_tarball" "$target"
|
||||||
|
|
||||||
|
# Produce a static and a dynamic binary, and a HTML man page
|
||||||
|
(
|
||||||
|
cd "$compile_dir" || exit 1
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
"$compile_cmd" -do_strip
|
||||||
|
cp "$compile_result" "../$bintarget_dynamic"
|
||||||
|
if test -n "$compile_static_opts"
|
||||||
|
then
|
||||||
|
"$compile_cmd" $compile_static_opts -do_strip
|
||||||
|
cp "$compile_result" "../$bintarget_static"
|
||||||
|
fi
|
||||||
|
"$man_to_html_cmd"
|
||||||
|
mv "$man_page_html" ..
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove the build area
|
||||||
|
# Disable this for debugging the merge process
|
||||||
|
rm -rf "$target"
|
||||||
|
|
||||||
|
# Show the result
|
||||||
|
./"$bintarget_dynamic" -version
|
||||||
|
./"$bintarget_static" -version
|
||||||
|
ls -l "$cdrskin_tarball"
|
||||||
|
ls -l "$bintarget_dynamic"
|
||||||
|
ls -l "$bintarget_static"
|
||||||
|
ls -l $(basename "$man_page_html")
|
||||||
|
|
37
libburn/tags/ZeroThreeZero/cdrskin/cdrecord_spy.sh
Executable file
37
libburn/tags/ZeroThreeZero/cdrskin/cdrecord_spy.sh
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Spying on the call to cdrecord.
|
||||||
|
#
|
||||||
|
# Move $(which cdrecord) to $(dirname $(which cdrecord))/real_cdrecord .
|
||||||
|
# Install this sript instead. (Do not forget to revoke this after the test.)
|
||||||
|
#
|
||||||
|
|
||||||
|
# The report target is set in variable rt.
|
||||||
|
# The default is this file :
|
||||||
|
rt=/tmp/cdrecord_spy_log
|
||||||
|
|
||||||
|
# To use a bystanding xterm as target i find out the pty address by
|
||||||
|
# executing in that terminal
|
||||||
|
# sleep 12345
|
||||||
|
# and then running in another terminal
|
||||||
|
# ps -ef | grep 'sleep 12345'
|
||||||
|
# which answers something like
|
||||||
|
# thomas 21303 30518 0 14:02 pts/23 00:00:00 sleep 12345
|
||||||
|
# thomas 21421 30523 0 14:02 pts/24 00:00:00 grep sleep 12345
|
||||||
|
# from which i learn that pts/23 is sleeping 12345. Now sleep can be aborted.
|
||||||
|
#
|
||||||
|
# rt=/dev/pts/23
|
||||||
|
|
||||||
|
echo '------------------------------------- cdrecord_spy 0.1.0 -------' >>"$rt"
|
||||||
|
date >>"$rt"
|
||||||
|
echo '----------------------------------------------------------------' >>"$rt"
|
||||||
|
echo "$0" >>"$rt"
|
||||||
|
for i in "$@"
|
||||||
|
do
|
||||||
|
echo "$i" >>"$rt"
|
||||||
|
done
|
||||||
|
echo '------------------------------------- cdrecord_spy 0.1.0 - end -' >>"$rt"
|
||||||
|
|
||||||
|
real_cdrecord "$@"
|
||||||
|
|
||||||
|
|
1083
libburn/tags/ZeroThreeZero/cdrskin/cdrfifo.c
Normal file
1083
libburn/tags/ZeroThreeZero/cdrskin/cdrfifo.c
Normal file
File diff suppressed because it is too large
Load Diff
156
libburn/tags/ZeroThreeZero/cdrskin/cdrfifo.h
Normal file
156
libburn/tags/ZeroThreeZero/cdrskin/cdrfifo.h
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
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
|
||||||
|
in fd-to-fd mode. Modes are controlled by parameter flag of
|
||||||
|
Cdrfifo_try_to_work().
|
||||||
|
|
||||||
|
Provided under GPL license within cdrskin and under BSD license elsewise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Cdrfifo_headerfile_includeD
|
||||||
|
#define Cdrfifo_headerfile_includeD
|
||||||
|
|
||||||
|
|
||||||
|
/** The fifo buffer which will smoothen the data stream from data provider
|
||||||
|
to data consumer. Although this is not a mandatory lifesaver for modern
|
||||||
|
burners any more, a fifo can speed up burning of data which is delivered
|
||||||
|
with varying bandwidths (e.g. compressed archives created on the fly
|
||||||
|
or mkisofs running at its speed limit.).
|
||||||
|
This structure is opaque to applications and may only be used via
|
||||||
|
the Cdrfifo*() methods described in cdrfifo.h .
|
||||||
|
*/
|
||||||
|
struct CdrfifO;
|
||||||
|
|
||||||
|
|
||||||
|
/** Create a fifo object.
|
||||||
|
@param ff Returns the address of the new object.
|
||||||
|
@param source_fd Filedescriptor opened to a readable data stream.
|
||||||
|
@param dest_fd Filedescriptor opened to a writable data stream.
|
||||||
|
To work with libburn, it needs to be attached to a
|
||||||
|
struct burn_source object.
|
||||||
|
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||||
|
@param buffer_size Size of fifo buffer
|
||||||
|
@param flag unused yet
|
||||||
|
@return 1 on success, <=0 on failure
|
||||||
|
*/
|
||||||
|
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
|
int chunk_size, int buffer_size, int flag);
|
||||||
|
|
||||||
|
/** Release from memory a fifo object previously created by Cdrfifo_new().
|
||||||
|
@param ff The victim (gets returned as NULL, call can stand *ff==NULL)
|
||||||
|
@param flag Bitfield for control purposes:
|
||||||
|
bit0= do not close destination fd
|
||||||
|
*/
|
||||||
|
int Cdrfifo_destroy(struct CdrfifO **ff, int flag);
|
||||||
|
|
||||||
|
/** Close any output fds */
|
||||||
|
int Cdrfifo_close(struct CdrfifO *o, int flag);
|
||||||
|
|
||||||
|
/** Close any output fds of o and its chain peers */
|
||||||
|
int Cdrfifo_close_all(struct CdrfifO *o, int flag);
|
||||||
|
|
||||||
|
int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
/** Set a speed limit for buffer output.
|
||||||
|
@param o The fifo object
|
||||||
|
@param bytes_per_second >0 catch up slowdowns over the whole run time
|
||||||
|
<0 catch up slowdowns only over one interval
|
||||||
|
=0 disable speed limit
|
||||||
|
*/
|
||||||
|
int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
/** Set a fixed size for input in order to cut off any unwanted tail
|
||||||
|
@param o The fifo object
|
||||||
|
@param idx index for fds attached via Cdrfifo_attach_follow_up_fds(),
|
||||||
|
first attached is 0, <0 directs limit to active fd limit
|
||||||
|
(i.e. first track is -1, second track is 0, third is 1, ...)
|
||||||
|
*/
|
||||||
|
int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag);
|
||||||
|
int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Attach a further pair of input and output fd which will use the same
|
||||||
|
fifo buffer when its predecessors are exhausted. Reading will start as
|
||||||
|
soon as reading of the predecessor encounters EOF. Writing will start
|
||||||
|
as soon as all pending predecessor data are written.
|
||||||
|
@return index number of new item + 1, <=0 indicates error
|
||||||
|
*/
|
||||||
|
int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
/** Attach a further fifo which shall be processed simultaneously with this
|
||||||
|
one by Cdrfifo_try_to_work() in fd-to-fd mode.
|
||||||
|
*/
|
||||||
|
int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain buffer state.
|
||||||
|
@param o The buffer object
|
||||||
|
@param fill Returns the number of pending payload bytes in the buffer
|
||||||
|
@param space Returns the number of unused buffer bytes
|
||||||
|
@param flag unused yet
|
||||||
|
@return -1=error , 0=inactive , 1=reading and writing ,
|
||||||
|
2=reading ended (but still writing)
|
||||||
|
*/
|
||||||
|
int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag);
|
||||||
|
|
||||||
|
int Cdrfifo_get_counters(struct CdrfifO *o,
|
||||||
|
double *in_counter, double *out_counter, int flag);
|
||||||
|
|
||||||
|
/** reads min_fill and begins measurement interval for next min_fill */
|
||||||
|
int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag);
|
||||||
|
|
||||||
|
int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill,
|
||||||
|
int *interval_min_fill, int flag);
|
||||||
|
|
||||||
|
int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
|
||||||
|
double *put_counter, double *get_counter,
|
||||||
|
double *empty_counter, double *full_counter,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
libburn applications call this function in the burn loop instead of sleep().
|
||||||
|
It may also be used instead of read(). Then it returns as soon as an output
|
||||||
|
transaction would be performed. See flag:bit2.
|
||||||
|
@param o The fifo object
|
||||||
|
@param wait_usec The time in microseconds after which the function shall
|
||||||
|
return.
|
||||||
|
@param reply_buffer with bit2: Returns write-ready buffer chunk and must
|
||||||
|
be able to take at least chunk_size bytes
|
||||||
|
@param reply_count with bit2: Returns number of writeable bytes in reply_pt
|
||||||
|
@param flag Bitfield for control purposes:
|
||||||
|
bit0= Enable debug pacifier (same with Cdrfifo_debuG)
|
||||||
|
bit1= Do not write, just fill buffer
|
||||||
|
bit2= fd-to-memory mode (else fd-to-fd mode):
|
||||||
|
Rather than writing a chunk return it and its size.
|
||||||
|
No simultaneous processing of chained fifos.
|
||||||
|
bit3= With bit2: do not check destination fd for readiness
|
||||||
|
@return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done
|
||||||
|
*/
|
||||||
|
int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec,
|
||||||
|
char *reply_buffer, int *reply_count, int flag);
|
||||||
|
|
||||||
|
/** Fill the fifo as far as possible without writing to destination fd.
|
||||||
|
@param size if >=0 : end filling after the given number of bytes
|
||||||
|
@return 1 on success, <=0 on failure
|
||||||
|
*/
|
||||||
|
int Cdrfifo_fill(struct CdrfifO *o, int size, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Cdrfifo_headerfile_includeD */
|
||||||
|
|
703
libburn/tags/ZeroThreeZero/cdrskin/cdrskin.1
Normal file
703
libburn/tags/ZeroThreeZero/cdrskin/cdrskin.1
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
|
.\" First parameter, NAME, should be all caps
|
||||||
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
|
.TH CDRSKIN 1 "January 12, 2007"
|
||||||
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
|
.\"
|
||||||
|
.\" Some roff macros, for reference:
|
||||||
|
.\" .nh disable hyphenation
|
||||||
|
.\" .hy enable hyphenation
|
||||||
|
.\" .ad l left justify
|
||||||
|
.\" .ad b justify to both left and right margins
|
||||||
|
.\" .nf disable filling
|
||||||
|
.\" .fi enable filling
|
||||||
|
.\" .br insert line break
|
||||||
|
.\" .sp <n> insert n+1 empty lines
|
||||||
|
.\" for manpage-specific macros, see man(7)
|
||||||
|
.SH NAME
|
||||||
|
cdrskin \- burns preformatted data to CD-R, CD-RW, DVD+/-RW, DVD-RAM
|
||||||
|
via libburn.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B cdrskin
|
||||||
|
.RI [ options | track_source_addresses ]
|
||||||
|
.br
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||||
|
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||||
|
.\" respectively.
|
||||||
|
.PP
|
||||||
|
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
||||||
|
in a compatible way for CD media. With DVD it has its own ways for now.
|
||||||
|
You do not need to be superuser for its daily usage.
|
||||||
|
.PP
|
||||||
|
.B Overview of features:
|
||||||
|
.br
|
||||||
|
Blanking of CD-RW.
|
||||||
|
.br
|
||||||
|
Burning of data or audio tracks to CD,
|
||||||
|
.br
|
||||||
|
either in versatile Track at Once mode (TAO)
|
||||||
|
.br
|
||||||
|
or in Session at Once mode for seamless tracks.
|
||||||
|
.br
|
||||||
|
Multi session on CD (follow-up sessions in TAO only).
|
||||||
|
.br
|
||||||
|
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
|
||||||
|
.br
|
||||||
|
Burning of a single data track to DVD+RW, DVD-RW or DVD-RAM.
|
||||||
|
.br
|
||||||
|
See section EXAMPLES at the end of this text.
|
||||||
|
.PP
|
||||||
|
.B Track recording model:
|
||||||
|
.br
|
||||||
|
The input-output entities which get processed are called tracks.
|
||||||
|
A \fBtrack\fP stores a stream of bytes.
|
||||||
|
.br
|
||||||
|
Each track is initiated by one track source address argument, which may either
|
||||||
|
be "-" for standard input or the address of a readable file. If no write mode
|
||||||
|
is given explicitely then one will be chosen which matches the peculiarities
|
||||||
|
of track sources and the state of the output media.
|
||||||
|
.PP
|
||||||
|
More than one track can be burned by a single run of cdrskin.
|
||||||
|
In the terms of the MMC standard all tracks written by the same run constitute
|
||||||
|
a \fBsession\fP.
|
||||||
|
.br
|
||||||
|
CDs can be kept appendable so that further tracks can
|
||||||
|
be written to them in subsequent runs of cdrskin (see option -multi).
|
||||||
|
Info about the addresses of burned tracks is kept in a table of
|
||||||
|
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
||||||
|
These informations are also used by the operating systems' CD-ROM read drivers.
|
||||||
|
.PP
|
||||||
|
In general there are two types of tracks: data and audio. They differ in
|
||||||
|
sector size, throughput and readability via the systems' CD-ROM drivers
|
||||||
|
resp. by music CD players.
|
||||||
|
.br
|
||||||
|
If not explicitely option -audio is given, then any track is burned as type
|
||||||
|
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
||||||
|
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
|
||||||
|
parameters. Such files are burned as audio tracks by default.
|
||||||
|
.PP
|
||||||
|
While audio tracks just contain a given time span of acoustic vibrations,
|
||||||
|
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
|
||||||
|
are established as a format which can represent a tree of directories and
|
||||||
|
files on all major operating systems. Such filesystem images can be
|
||||||
|
produced by programs mkisofs or genisoimage. They can also be extended by
|
||||||
|
follow-up tracks if prepared properly. See the man pages of said programs.
|
||||||
|
cdrskin is able to fulfill the needs about their option -C.
|
||||||
|
.br
|
||||||
|
Another type of data track content are archive formats which originally
|
||||||
|
have been developed for magnetic tapes. Only formats which mark a detectable
|
||||||
|
end-of-archive in their data are suitable, though. Well tested are
|
||||||
|
the archivers afio and star. Not suitable seems GNU tar.
|
||||||
|
.PP
|
||||||
|
.B Recordable CD Media:
|
||||||
|
.br
|
||||||
|
CD-R can be initially written only once and eventually extended until they
|
||||||
|
get closed (or are spoiled because they are overly full). After that they are
|
||||||
|
read-only.
|
||||||
|
.br
|
||||||
|
CD-RW media can be blanked to make them re-usable for another
|
||||||
|
round of overwriting. Usually
|
||||||
|
.B blank=fast
|
||||||
|
is the appropriate option.
|
||||||
|
Blanking damages the previous content but does not
|
||||||
|
make it completely unreadable. It is no effective privacy precaution.
|
||||||
|
Multiple cycles of blanking and overwriting with random numbers might be.
|
||||||
|
.PP
|
||||||
|
.B Recordable DVD Media:
|
||||||
|
.br
|
||||||
|
Currently only types DVD+RW, DVD-RW and DVD-RAM can be burned via cdrskin.
|
||||||
|
.br
|
||||||
|
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
|
||||||
|
hold data or not. They need no special initial formatting.
|
||||||
|
Options -audio and -multi are not allowed. Only one track is allowed.
|
||||||
|
-toc does not return information about the media content.
|
||||||
|
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second). Currently
|
||||||
|
there is no difference between -sao and -tao. If ever, then -tao will be the
|
||||||
|
mode which preserves the current behavior.
|
||||||
|
.br
|
||||||
|
DVD-RW need to be formatted to state "Restricted Overwrite". Then they behave
|
||||||
|
much like DVD+RW. This formatting can be done by option
|
||||||
|
.B blank=format_overwrite
|
||||||
|
It is necessary for unused media, for media written or blanked by cdrecord,
|
||||||
|
for media which have been written unformatted by growisofs or blanked by
|
||||||
|
dvd+rw-format -blank. If in doubt, just give it a try.
|
||||||
|
.PP
|
||||||
|
.B Drive preparation and addressing:
|
||||||
|
.br
|
||||||
|
The drives, either CD burners or DVD burners, are accessed via addresses which
|
||||||
|
are specific to libburn and the operating system. Those addresses get listed
|
||||||
|
by a run of \fBcdrskin --devices\fP.
|
||||||
|
.br
|
||||||
|
On Linux, they are device files which traditionally do not offer
|
||||||
|
w-permissions for normal users. Because libburn needs rw-permission,
|
||||||
|
it might be only the superuser who is able to get this list without further
|
||||||
|
precautions.
|
||||||
|
.br
|
||||||
|
It is consensus that \fBchmod a+rw /dev/sg0\fP or \fBchmod a+rw /dev/hdc\fP
|
||||||
|
is less security sensitive than chmod u+s /usr/bin/cdrskin. The risk for the
|
||||||
|
drive is somewhat higher but the overall system is much less at stake.
|
||||||
|
.br
|
||||||
|
.PP
|
||||||
|
If you only got one CD capable drive then you may leave out cdrskin option
|
||||||
|
\fBdev=\fP. Else you should use this option to address the drive you want.
|
||||||
|
.br
|
||||||
|
cdrskin option dev= not only accepts the listed addresses but also
|
||||||
|
traditional cdrecord SCSI addresses which on Linux consist of three
|
||||||
|
numbers: Bus,Target,Lun. There is also a related address family "ATA" which
|
||||||
|
accesses IDE drives not under control of Linux SCSI drivers:
|
||||||
|
ATA:Bus,Target,Lun.
|
||||||
|
.br
|
||||||
|
See option -scanbus for getting a list of cdrecord style addresses.
|
||||||
|
.br
|
||||||
|
Further are accepted on Linux: links to libburn-suitable device files,
|
||||||
|
device files which have the same major and minor device number,
|
||||||
|
and device files which have the same SCSI address parameters (e.g. /dev/sr0).
|
||||||
|
.br
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.BI \-\-help
|
||||||
|
Show non-cdrecord compatible options.
|
||||||
|
.TP
|
||||||
|
.BI \-help
|
||||||
|
Show cdrecord compatible options.
|
||||||
|
.TP
|
||||||
|
.BI \-version
|
||||||
|
Print cdrskin id line, compatibility lure line, libburn version, cdrskin
|
||||||
|
version, version timestamp, build timestamp (if available), and then exit.
|
||||||
|
.PP
|
||||||
|
Alphabetical list of options which are intended to be compatible with
|
||||||
|
original cdrecord by Joerg Schilling:
|
||||||
|
.TP
|
||||||
|
.BI \-atip
|
||||||
|
Retrieve some info about media state. With CD-RW print "Is erasable".
|
||||||
|
With DVD media print "book type:" and a media type text.
|
||||||
|
.TP
|
||||||
|
.BI \-audio
|
||||||
|
Announces that the subsequent tracks are to be burned as audio.
|
||||||
|
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
||||||
|
stereo. For little-endian byte order (which is usual on PCs) use option
|
||||||
|
-swab. Unless marked explicitely by option -data, input files with suffix
|
||||||
|
.wav are examined wether they have a header in MS-WAVE format confirming
|
||||||
|
those parameters and eventually raw audio data get extracted and burned as
|
||||||
|
audio track. Same is done for suffix .au and SUN Audio.
|
||||||
|
.TP
|
||||||
|
.BI blank= type
|
||||||
|
Blank a CD-RW or format a DVD+/-RW.
|
||||||
|
This is combinable with burning in the same run of cdrskin.
|
||||||
|
The type given with blank= selects the particular behavior:
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
help
|
||||||
|
Print this list of blanking types.
|
||||||
|
.TP
|
||||||
|
all
|
||||||
|
Blank an entire CD.
|
||||||
|
.TP
|
||||||
|
fast
|
||||||
|
Minimally blank an entire CD.
|
||||||
|
.TP
|
||||||
|
format_overwrite
|
||||||
|
Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
|
||||||
|
(Note: format_overwrite* are not original cdrecord options.)
|
||||||
|
.TP
|
||||||
|
format_overwrite_quickest
|
||||||
|
Like format_overwrite without creating a 128 MB trailblazer session.
|
||||||
|
Leads to "intermediate" state which only allows sequential write
|
||||||
|
beginning from address 0.
|
||||||
|
The "intermediate" state ends after the first session of writing data.
|
||||||
|
.TP
|
||||||
|
format_overwrite_full
|
||||||
|
For DVD-RW this is like format_overwrite but claims full media size
|
||||||
|
rather than just 128 MB.
|
||||||
|
Most traditional formatting is attempted. No data get written.
|
||||||
|
Much patience is required.
|
||||||
|
.br
|
||||||
|
For DVD+RW this is the only supported explicit formatting type. It provides
|
||||||
|
complete "de-icing" so no reader slips on unwritten data areas.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI \-checkdrive
|
||||||
|
Retrieve some info about the addressed drive.
|
||||||
|
Exits with non-zero value if the drive cannot be found and opened.
|
||||||
|
.TP
|
||||||
|
.BI \-dao
|
||||||
|
Alias for option -sao. Write disk in Session at Once mode.
|
||||||
|
.TP
|
||||||
|
.BI \-data
|
||||||
|
Subsequent tracks are data tracks. This option is default and only needed
|
||||||
|
to mark the end of the range of an eventual option -audio.
|
||||||
|
.TP
|
||||||
|
.BI dev= target
|
||||||
|
Set the address of the drive to use. Valid are at least the
|
||||||
|
addresses listed with option --devices,
|
||||||
|
X,Y,Z addresses listed with option -scanbus,
|
||||||
|
ATA:X,Y,Z addresses listed with options dev=ATA -scanbus,
|
||||||
|
and volatile libburn drive numbers (numbering starts at "0").
|
||||||
|
Other device file addresses which lead to the same drive might work too.
|
||||||
|
.br
|
||||||
|
If no dev= is given, volatile address "dev=0" is assumed. That is the first
|
||||||
|
drive found being available. Better avoid this ambiguity on systems with more
|
||||||
|
than one drive.
|
||||||
|
.br
|
||||||
|
The special target "help" lists hints about available addressing formats.
|
||||||
|
Be aware that deprecated option --old_pseudo_scsi_adr may change the meaning
|
||||||
|
of Bus,Target,Lun addresses.
|
||||||
|
.TP
|
||||||
|
.BI driveropts= opt
|
||||||
|
Set "driveropts=burnfree" to enable the drive's eventual protection mechanism
|
||||||
|
against temporary lack of source data (i.e. buffer underrun).
|
||||||
|
It is not an error to do this with a drive that has no such capabilities.
|
||||||
|
.TP
|
||||||
|
.BI \-dummy
|
||||||
|
Try to perform the drive operations without actually affecting the inserted
|
||||||
|
media. There is no guarantee that this will work with a particular drive
|
||||||
|
in a particular write mode. Blanking is prevented reliably, though.
|
||||||
|
.TP
|
||||||
|
.BI \-eject
|
||||||
|
Eject the disk after work is done.
|
||||||
|
.TP
|
||||||
|
.BI \-force
|
||||||
|
Assume that the user knows better in situations when cdrskin or libburn are
|
||||||
|
insecure about drive or media state. This includes the attempt to blank
|
||||||
|
media which are classified as unknown or unsuitable, and the attempt to use
|
||||||
|
write modes which libburn believes they are not supported by the drive.
|
||||||
|
.br
|
||||||
|
Another application is with blank=format_* to enforce re-formatting of media
|
||||||
|
which appear to be sufficiently formatted already.
|
||||||
|
.br
|
||||||
|
Use this only when in urgent need.
|
||||||
|
.TP
|
||||||
|
.BI fs= size
|
||||||
|
Set the fifo size to the given value. The value may have appended letters which
|
||||||
|
multiply the preceding number:
|
||||||
|
.br
|
||||||
|
"k" or "K" = 1024 , "m" or "M" = 1024k , "g" or "G" = 1024m , "s" or "S" = 2048
|
||||||
|
.br
|
||||||
|
Set size to 0 in order to disable the fifo (default is "4m").
|
||||||
|
.br
|
||||||
|
The fifo buffers an eventual temporary surplus of track source data in order to
|
||||||
|
provide the drive with a steady stream during times of temporary lack of track
|
||||||
|
source supply.
|
||||||
|
The larger the fifo, the longer periods of poor source supply can be
|
||||||
|
compensated.
|
||||||
|
But a large fifo needs substantial time to fill up if not curbed via
|
||||||
|
option fifo_start_at=size.
|
||||||
|
.TP
|
||||||
|
.BI gracetime= seconds
|
||||||
|
Set the grace time before starting to write. (Default is 0)
|
||||||
|
.TP
|
||||||
|
.BI msifile= path
|
||||||
|
Run option -msinfo and copy the result line into the file given by path.
|
||||||
|
Unlike -msinfo this option does not redirect all normal output away from
|
||||||
|
standard output. But it may be combined with -msinfo to achieve this.
|
||||||
|
.br
|
||||||
|
Note: msifile=path is actually an option of wodim and not of cdrecord.
|
||||||
|
.TP
|
||||||
|
.BI \-msinfo
|
||||||
|
Retrieve multi-session info for preparing a follow-up session by option -C
|
||||||
|
of programs mkisofs or genisoimage. Print result to standard output.
|
||||||
|
This option redirects to stderr all
|
||||||
|
message output besides its own result string, which consists of two numbers.
|
||||||
|
The result string shall be used as argument of option -C with said programs.
|
||||||
|
It gives the start address of the most recent session and the predicted
|
||||||
|
start address of the next session to be appended. The string is empty if
|
||||||
|
the most recent session was not written with option -multi.
|
||||||
|
.TP
|
||||||
|
.BI \-multi
|
||||||
|
This option keeps the CD appendable after the current session has been written.
|
||||||
|
Without it the disk gets closed and may not be written any more - unless it
|
||||||
|
is a CD-RW and gets blanked which causes loss of its content.
|
||||||
|
.br
|
||||||
|
The following sessions can only be written in -tao mode.
|
||||||
|
.br
|
||||||
|
In order to have all filesystem content accessible, the eventual ISO-9660
|
||||||
|
filesystem of a follow-up
|
||||||
|
session needs to be prepared in a special way by the filesystem formatter
|
||||||
|
program. mkisofs and genisoimage expect particular info about the situation
|
||||||
|
which can be retrieved by cdrskin option -msinfo.
|
||||||
|
.br
|
||||||
|
To retrieve an archive file which was written as follow-up session,
|
||||||
|
you may use option -toc to learn about the "lba" of the desired track number.
|
||||||
|
.TP
|
||||||
|
.BI \-nopad
|
||||||
|
Do not add trailing zeros to the data stream. Nevertheless, since there seems
|
||||||
|
to be no use for audio tracks with incomplete last sector, this option applies
|
||||||
|
only to data tracks. There it is default.
|
||||||
|
.TP
|
||||||
|
.BI \-pad
|
||||||
|
Add 30 kB of trailing zeros to each data track. (This is not sufficient to
|
||||||
|
avoid problems with various CD-ROM read drivers.)
|
||||||
|
.TP
|
||||||
|
.BI padsize= size
|
||||||
|
Add the given amount of trailing zeros to the next data track. This option
|
||||||
|
gets reset to padsize=0 after that next track is written. It may be set
|
||||||
|
again before the next track argument. About size specifiers, see option fs=.
|
||||||
|
.TP
|
||||||
|
.BI \-raw96r
|
||||||
|
Write disk in RAW/RAW96R mode. This mode allows to put more payload bytes
|
||||||
|
into a CD sector but obviously at the cost of error correction. It can only
|
||||||
|
be used for tracks of fixely predicted size. Some drives allow this mode but
|
||||||
|
then behave strange or even go bad for the next few attempts to burn a CD.
|
||||||
|
One should use it only if inavoidable.
|
||||||
|
.TP
|
||||||
|
.BI \-sao
|
||||||
|
Write disk in Session At Once mode. This mode is able to put several audio
|
||||||
|
tracks on CD without producing audible gaps between them. It can only
|
||||||
|
be used for tracks of fixely predicted size. This implies that track arguments
|
||||||
|
which depict stdin or named pipes need to be preceeded by option tsize= or
|
||||||
|
by option tao_to_sao_tsize=.
|
||||||
|
.TP
|
||||||
|
.BI \-scanbus
|
||||||
|
Scan the system for drives. On Linux the drives at /dev/s* and at /dev/hd*
|
||||||
|
are to be scanned by two separate runs. One without dev= for /dev/s* and
|
||||||
|
one with dev=ATA for /dev/hd* devices. (Option --drives lists all available
|
||||||
|
drives in a single run.)
|
||||||
|
.br
|
||||||
|
Drives which are busy or which offer no rw-permission to the user of cdrskin
|
||||||
|
are not listed. Busy drives get reported in form of warning messages.
|
||||||
|
.br
|
||||||
|
The useful fields in a result line are:
|
||||||
|
.br
|
||||||
|
Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
|
||||||
|
.TP
|
||||||
|
.BI speed= number
|
||||||
|
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
|
||||||
|
150 kB/s. It is not an error to set a speed higher than is suitable for drive
|
||||||
|
and media. One should stay within a realistic speed range, though.
|
||||||
|
.TP
|
||||||
|
.BI \-swab
|
||||||
|
Announce that the raw audio data source of subsequent tracks is byte swapped
|
||||||
|
versus the expectations of cdrecord. This option is suitable for audio where
|
||||||
|
the least significant byte of a 16 bit word is first (little-endian, Intel).
|
||||||
|
Most raw audio data on PC systems are available in this byte order.
|
||||||
|
Less guesswork is needed if track sources are in format MS-WAVE in a file with
|
||||||
|
suffix ".wav".
|
||||||
|
.TP
|
||||||
|
.BI \-tao
|
||||||
|
Write disk in Track At Once (TAO) mode. This mode can be used with track
|
||||||
|
sources of unpredictable size, like standard input or named pipes. It is
|
||||||
|
also the only mode that can be used for writing to appendable CD which
|
||||||
|
already hold data.
|
||||||
|
.TP
|
||||||
|
.BI \-toc
|
||||||
|
Print the table of content (TOC) which describes the tracks recorded on CD.
|
||||||
|
The output contains all info from option -atip plus lines which begin with
|
||||||
|
"track:", the track number, the word "lba:" and a number which gives the
|
||||||
|
start address of the track. Addresses are counted in CD sectors which with
|
||||||
|
SAO or TAO data tracks hold 2048 bytes each.
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
Example. Retrieve an afio archive from track number 2:
|
||||||
|
.br
|
||||||
|
tracknumber=2
|
||||||
|
.br
|
||||||
|
lba=$(cdrskin dev=/dev/cdrom -toc 2>&1 | \\
|
||||||
|
.br
|
||||||
|
grep '^track:[ ]*[ 0-9][0-9]' | \\
|
||||||
|
.br
|
||||||
|
tail +"$tracknumber" | head -1 | \\
|
||||||
|
.br
|
||||||
|
awk '{ print $4}' )
|
||||||
|
.br
|
||||||
|
dd if=/dev/cdrom bs=2048 skip="$lba" | \\
|
||||||
|
.br
|
||||||
|
afio -t - | less
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.BI tsize= size
|
||||||
|
Announces the exact size of the next track source. This is necessary with any
|
||||||
|
write mode other than -tao if the track source is not a regular disk file, but
|
||||||
|
e.g. "-" (standard input) or a named pipe.
|
||||||
|
About size specifiers, see option fs=.
|
||||||
|
.br
|
||||||
|
If the track source does not deliver the predicted amount of bytes, the
|
||||||
|
remainder of the track is padded with zeros. This is not considered an error.
|
||||||
|
If on the other hand the track source delivers more than the announced bytes
|
||||||
|
then the track on CD gets truncated to the predicted size and cdrskin exits
|
||||||
|
with non-zero value.
|
||||||
|
.TP
|
||||||
|
.BI \-v
|
||||||
|
Increment verbose level by one. Startlevel is 0 with only few messages.
|
||||||
|
Level 1 prints progress report with long running operations and also causes
|
||||||
|
some extra lines to be put out with info retrieval options.
|
||||||
|
Level 2 additionally reports about option settings derived from arguments or
|
||||||
|
startup files. Level 3 is for debugging and useful mainly in conjunction with
|
||||||
|
somebody who had a look into the program sourcecode.
|
||||||
|
.PP
|
||||||
|
Alphabetical list of options which are genuine to cdrskin and intended for
|
||||||
|
normal use:
|
||||||
|
.TP
|
||||||
|
.BI \--allow_setuid
|
||||||
|
Disable the loud warning about insecure discrepance between login user and
|
||||||
|
effective user which indicates application of chmod u+s to the program binary.
|
||||||
|
One should not do this chmod u+s , but it is an old cdrecord tradition.
|
||||||
|
.TP
|
||||||
|
.BI \--any_track
|
||||||
|
Allow source_addresses to begin with "-" (plus further characters) or to
|
||||||
|
contain a "=" character.
|
||||||
|
By default such arguments are seen as misspelled options. It is nevertheless
|
||||||
|
not possible to use one of the options listed with --list_ignored_options.
|
||||||
|
.TP
|
||||||
|
.BI \--demand_a_drive
|
||||||
|
Exit with a nonzero value if no drive can be found during a bus scan.
|
||||||
|
.TP
|
||||||
|
.BI \--devices
|
||||||
|
List the device file addresses of all accessible CD drives. In order to get
|
||||||
|
listed, a drive has to offer rw-permission for the cdrskin user and it may
|
||||||
|
not be busy. The superuser should be able to see all idle drives listed and
|
||||||
|
busy drives reported as "SORRY" messages.
|
||||||
|
.br
|
||||||
|
Each available drive gets listed by a line containing the following fields:
|
||||||
|
.br
|
||||||
|
Number dev='Devicefile' rw-Permissions : 'Vendor' 'Model'
|
||||||
|
.br
|
||||||
|
Number and Devicefile can both be used with option dev=, but number is
|
||||||
|
volatile (numbering changes if drives become busy).
|
||||||
|
.TP
|
||||||
|
.BI fifo_start_at= size
|
||||||
|
Do not wait for full fifo but start burning as soon as the given number
|
||||||
|
of bytes is read. This option may be helpful to bring the average throughput
|
||||||
|
near to the maximum throughput of a drive. A large fs= and a small
|
||||||
|
fifo_start_at= combine a quick burn start and a large savings buffer to
|
||||||
|
compensate for temporary lack of source data. At the beginning of burning,
|
||||||
|
the software protection against buffer underun is as weak as the size of
|
||||||
|
fifo_start_at= . So it is best if the drive offers hardware protection which
|
||||||
|
has to be enabled by driveropts=burnfree.
|
||||||
|
.TP
|
||||||
|
.BI \--list_ignored_options
|
||||||
|
List all ignored cdrecord options. The --options cannot be used as addresses
|
||||||
|
of track sources. No track source address may begin with a text equal to an
|
||||||
|
option which ends by "=". The list is ended by an empty line.
|
||||||
|
.TP
|
||||||
|
.BI \--no_rc
|
||||||
|
Only if used as first command line argument this option prevents reading and
|
||||||
|
interpretation of eventual startup files. See section FILES below.
|
||||||
|
.TP
|
||||||
|
.BI \--single_track
|
||||||
|
Accept only the last argument of the command line as track source address.
|
||||||
|
.TP
|
||||||
|
.BI write_start_address= byte_offset
|
||||||
|
Set the address on media where to start writing the track. With DVD+RW or
|
||||||
|
DVD-RAM byte_offset must be aligned to 2 KB blocks, but better is 32 kB.
|
||||||
|
With DVD-RW 32 kB alignment is mandatory.
|
||||||
|
.br
|
||||||
|
Other media are not suitable for this option yet.
|
||||||
|
.PP
|
||||||
|
Alphabetical list of options which are only intended for very special
|
||||||
|
situations and not for normal use:
|
||||||
|
.TP
|
||||||
|
.BI \--abort_handler
|
||||||
|
Establish default signal handling not to leave a drive in busy state
|
||||||
|
but rather to shut it down and to wait until it has ended the final operations.
|
||||||
|
This option is only needed for revoking eventual --ignore_signals or
|
||||||
|
--no_abort_handler.
|
||||||
|
.TP
|
||||||
|
.BI dev_translation= <sep><from><sep><to>
|
||||||
|
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
|
||||||
|
translate cdrecord addresses into cdrskin addresses.
|
||||||
|
.br
|
||||||
|
<sep> is a single character which may not occur in the address string
|
||||||
|
<from>. <from> is an address as expected to be given by the user via option
|
||||||
|
dev=. <to> is the address to be used instead whenever <from> is given.
|
||||||
|
More than one translation instruction can be given in one cdrskin run.
|
||||||
|
.br
|
||||||
|
E.g.: dev_translation=+ATA:1,0,0+/dev/sg1 dev_translation=+ATA:1,1,0+/dev/sg2
|
||||||
|
.TP
|
||||||
|
.BI \--drive_abort_on_busy
|
||||||
|
Linux specific: Abort process if a busy drive is encountered.
|
||||||
|
.TP
|
||||||
|
.BI \--drive_blocking
|
||||||
|
Linux specific: Try to wait for a busy drive to become free.
|
||||||
|
This is not guaranteed to work with all drivers. Some need nonblocking i/o.
|
||||||
|
.TP
|
||||||
|
.BI \--drive_not_exclusive
|
||||||
|
Linux specific: Do not ask the operating system to prevent opening busy drives.
|
||||||
|
Wether this leads to senseful behavior depends on operating system and kernel.
|
||||||
|
.TP
|
||||||
|
.BI \--drive_scsi_exclusive
|
||||||
|
Linux specific:
|
||||||
|
Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/stK of drive.
|
||||||
|
this would be helpful to protect against collisions with program growisofs.
|
||||||
|
Regrettably on Linux kernel 2.4 with ide-scsi emulation this seems not to
|
||||||
|
work. Wether it becomes helpful with new Linux systems has to be evaluated.
|
||||||
|
.TP
|
||||||
|
.BI \--fifo_disable
|
||||||
|
Disable fifo despite any fs=.
|
||||||
|
.TP
|
||||||
|
.BI \--fifo_per_track
|
||||||
|
Use a separate fifo for each track.
|
||||||
|
.TP
|
||||||
|
.BI grab_drive_and_wait= seconds
|
||||||
|
Open the addressed drive, wait the given number of seconds, release the drive,
|
||||||
|
and do normal work as indicated by the other options used. This option helps
|
||||||
|
to explore the program behavior when faced with busy drives. Just start a
|
||||||
|
second cdrskin with option --devices while grab_drive_and_wait= is still
|
||||||
|
active.
|
||||||
|
.TP
|
||||||
|
.BI \--ignore_signals
|
||||||
|
Try to ignore any signals rather than to abort the program. This is not a
|
||||||
|
very good idea. You might end up waiting a very long time for cdrskin
|
||||||
|
to finish.
|
||||||
|
.TP
|
||||||
|
.BI \--no_abort_handler
|
||||||
|
On signals exit even if the drive is in busy state. This is not a very good
|
||||||
|
idea. You might end up with a stuck drive that refuses to hand out the media.
|
||||||
|
.TP
|
||||||
|
.BI \--no_blank_appendable
|
||||||
|
Refuse to blank appendable CD-RW. This is a feature that was once builtin with
|
||||||
|
libburn. No information available for what use case it was needed.
|
||||||
|
.TP
|
||||||
|
.BI \--no_convert_fs_adr
|
||||||
|
Do only literal translations of dev=. This prevents cdrskin from test-opening
|
||||||
|
device files in order to find one that matches the given dev= specifier.
|
||||||
|
.br
|
||||||
|
Partly Linux specific:
|
||||||
|
Such opening is needed for Bus,Target,Lun addresses unless option
|
||||||
|
--old_pseudo_scsi_adr is given. It is also needed to resolve device file
|
||||||
|
addresses which are not listed with cdrskin --devices but nevertheless point
|
||||||
|
to a usable drive. (Like /dev/sr0 using the same SCSI address as /dev/sg0.)
|
||||||
|
.TP
|
||||||
|
.BI \--old_pseudo_scsi_adr
|
||||||
|
Linux specific:
|
||||||
|
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||||
|
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||||
|
original cdrecord.
|
||||||
|
.TP
|
||||||
|
.BI tao_to_sao_tsize= size
|
||||||
|
Set an exact fixed size for the next track to be in effect only if the track
|
||||||
|
source cannot deliver a size prediction and no tsize= was specified.
|
||||||
|
This is the fallback from bad old times when cdrskin was unable to burn
|
||||||
|
in mode -tao.
|
||||||
|
.br
|
||||||
|
.SH EXAMPLES
|
||||||
|
.SS
|
||||||
|
.B Get an overview of drives:
|
||||||
|
.br
|
||||||
|
cdrskin -scanbus
|
||||||
|
.br
|
||||||
|
cdrskin dev=ATA -scanbus
|
||||||
|
.br
|
||||||
|
cdrskin --devices
|
||||||
|
.SS
|
||||||
|
.B Get info about a particular drive or loaded media:
|
||||||
|
.br
|
||||||
|
cdrskin dev=0,1,0 -checkdrive
|
||||||
|
.br
|
||||||
|
cdrskin dev=ATA:1,0,0 -atip
|
||||||
|
.br
|
||||||
|
cdrskin dev=/dev/hdc -toc
|
||||||
|
.SS
|
||||||
|
.B Make used CD-RW writable again:
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=/dev/sg1 blank=all -eject
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=/dev/dvd blank=fast -eject
|
||||||
|
.SS
|
||||||
|
.B Format DVD-RW before first use with cdrskin:
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=/dev/sr0 blank=format_overwrite
|
||||||
|
.SS
|
||||||
|
.B Write ISO-9660 filesystem image:
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
||||||
|
.br
|
||||||
|
driveropts=burnfree -sao -eject \\
|
||||||
|
.br
|
||||||
|
padsize=300k my_image.iso
|
||||||
|
.SS
|
||||||
|
.B Write compressed afio archive on-the-fly:
|
||||||
|
.br
|
||||||
|
find . | afio -oZ - | \\
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree \\
|
||||||
|
.br
|
||||||
|
padsize=300k -tao -
|
||||||
|
.SS
|
||||||
|
.B Write several sessions to the same CD:
|
||||||
|
.br
|
||||||
|
cdrskin dev=/dev/hdc padsize=300k -multi 1.iso
|
||||||
|
.br
|
||||||
|
cdrskin dev=/dev/hdc padsize=300k -multi -tao 2.afio
|
||||||
|
.br
|
||||||
|
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.afio
|
||||||
|
.br
|
||||||
|
cdrskin dev=/dev/hdc padsize=300k -tao 4.afio
|
||||||
|
.SS
|
||||||
|
.B Get CD multi-session info for option -C of program mkisofs:
|
||||||
|
.br
|
||||||
|
c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)
|
||||||
|
.br
|
||||||
|
mkisofs ... -C "$c_values" ...
|
||||||
|
.SS
|
||||||
|
.B Write audio tracks to CD:
|
||||||
|
.br
|
||||||
|
cdrskin -v dev=ATA:1,0,0 speed=48 \\
|
||||||
|
.br
|
||||||
|
driveropts=burnfree -sao \\
|
||||||
|
.br
|
||||||
|
track1.wav track2.au -audio -swab track3.raw
|
||||||
|
.br
|
||||||
|
.SH FILES
|
||||||
|
If not --no_rc is given as the first argument then cdrskin attempts on
|
||||||
|
startup to read the arguments from the following files:
|
||||||
|
.PP
|
||||||
|
.br
|
||||||
|
.B /etc/default/cdrskin
|
||||||
|
.br
|
||||||
|
.B /etc/opt/cdrskin/rc
|
||||||
|
.br
|
||||||
|
.B /etc/cdrskin/cdrskin.conf
|
||||||
|
.br
|
||||||
|
.B $HOME/.cdrskinrc
|
||||||
|
.br
|
||||||
|
.PP
|
||||||
|
The files are read in the sequence given above, but none of them is
|
||||||
|
required for cdrskin to function properly. Each readable line is treated
|
||||||
|
as one single argument. No extra blanks.
|
||||||
|
A first character '#' marks a comment, empty lines are ignored.
|
||||||
|
.SS
|
||||||
|
.B Example content of a startup file:
|
||||||
|
.br
|
||||||
|
# This is the default device
|
||||||
|
.br
|
||||||
|
dev=0,1,0
|
||||||
|
.br
|
||||||
|
# To accomodate to remnant cdrskin-0.2.2 addresses
|
||||||
|
.br
|
||||||
|
dev_translation=+1,0,0+0,1,0
|
||||||
|
.br
|
||||||
|
# Some more options
|
||||||
|
.br
|
||||||
|
fifo_start_at=0
|
||||||
|
.br
|
||||||
|
fs=16m
|
||||||
|
.br
|
||||||
|
.SH SEE ALSO
|
||||||
|
.TP
|
||||||
|
Formatting track sources for cdrskin:
|
||||||
|
.br
|
||||||
|
.BR mkisofs (8),
|
||||||
|
.BR genisoimage (8),
|
||||||
|
.BR afio (1),
|
||||||
|
.BR star (1)
|
||||||
|
.br
|
||||||
|
.TP
|
||||||
|
Other CD/DVD burn programs:
|
||||||
|
.br
|
||||||
|
.BR cdrecord (1),
|
||||||
|
.BR wodim (1)
|
||||||
|
.br
|
||||||
|
.TP
|
||||||
|
For DVD burning:
|
||||||
|
.br
|
||||||
|
.BR growisofs (1)
|
||||||
|
.br
|
||||||
|
.SH AUTHOR
|
||||||
|
cdrskin was written by Thomas Schmitt <scdbackup@gmx.net>.
|
||||||
|
.PP
|
||||||
|
This manual page was written by George Danchev <danchev@spnet.net> and
|
||||||
|
Thomas Schmitt, for the Debian project and for all others.
|
||||||
|
|
5967
libburn/tags/ZeroThreeZero/cdrskin/cdrskin.c
Normal file
5967
libburn/tags/ZeroThreeZero/cdrskin/cdrskin.c
Normal file
File diff suppressed because it is too large
Load Diff
441
libburn/tags/ZeroThreeZero/cdrskin/cdrskin_eng.html
Normal file
441
libburn/tags/ZeroThreeZero/cdrskin/cdrskin_eng.html
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
<HTML>
|
||||||
|
|
||||||
|
<HEAD>
|
||||||
|
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
|
||||||
|
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, linux, CDR, CD-R, CDRW, CD-RW, cdrecord, compatible, scdbackup, burning">
|
||||||
|
<META NAME="robots" CONTENT="follow">
|
||||||
|
<TITLE>cdrskin homepage english</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
|
||||||
|
<BODY BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>
|
||||||
|
<FONT SIZE=+1>
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
|
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
|
||||||
|
<IMG SRC="doener_150x200_tr_octx.gif" BORDER=0
|
||||||
|
ALT="cdrskin logo: Doener mit Scharf">
|
||||||
|
</A>
|
||||||
|
<P><H2> Homepage of </H2>
|
||||||
|
<H1> cdrskin </H1>
|
||||||
|
<!-- <FONT SIZE=+0><A HREF="cdrskin_ger.html">deutsch (german)</A></FONT> -->
|
||||||
|
|
||||||
|
<H2>Limited cdrecord compatibility wrapper for libburn</H2>
|
||||||
|
</CENTER>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Purpose:</H2>
|
||||||
|
<UL>
|
||||||
|
<LI>Burns preformatted data to CD-R or CD-RW</LI>
|
||||||
|
</UL>
|
||||||
|
</P>
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Hardware requirements:</H2>
|
||||||
|
A CD recorder suitable for
|
||||||
|
<A HREF="http://libburnia.pykix.org">libburnia.pykix.org</A>
|
||||||
|
(SCSI or IDE/ATAPI writers compliant to mmc-3 standard).
|
||||||
|
<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Software requirements :</H2>
|
||||||
|
<DL>
|
||||||
|
<DT>Linux kernel 2.4 or higher</DT>
|
||||||
|
<DD>With kernel 2.4 the drive has to be under ide-scsi emulation.</DD>
|
||||||
|
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
|
||||||
|
<DT>libpthread</DT>
|
||||||
|
<DD>is supposed to be a standard system component.</DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>
|
||||||
|
GPL software included:<BR>
|
||||||
|
</H2>
|
||||||
|
<DL>
|
||||||
|
<DT>libburn-0.2.6</DT>
|
||||||
|
<DD>(by Derek Foreman, Ben Jansens, and team of libburnia.pykix.org)</DD>
|
||||||
|
<DD>transfers data to CD</DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
This program system has been tested on Intel/AMD Linux systems only.<BR>
|
||||||
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Special features:</H2>
|
||||||
|
<UL>
|
||||||
|
<LI>Source code is independent of
|
||||||
|
<A HREF="http://cdrecord.berlios.de/old/private/cdrecord.html">cdrecord</A>
|
||||||
|
</LI>
|
||||||
|
</UL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Commands:</H2>
|
||||||
|
<DL>
|
||||||
|
<DT>The goal is to provide some of cdrecord's options in a compatible way.
|
||||||
|
This has been achieved quite sufficiently for the needs of backup tool
|
||||||
|
<A HREF="http://scdbackup.sourceforge.net/main_eng.html">scdbackup</A>
|
||||||
|
and for data CD projects of <A HREF="http://www.k3b.org">K3b</A>
|
||||||
|
(see <A HREF="#examples">examples</A>).
|
||||||
|
Suitability for audio CD frontends has been improved much and is now being
|
||||||
|
evaluated.<BR>
|
||||||
|
Further enhancements depend on people who can describe and discuss their
|
||||||
|
wishes as well as on the development of libburn.</DT>
|
||||||
|
<BR><BR>
|
||||||
|
<DT>Get an overview of drives:</DT>
|
||||||
|
<DD>$ cdrskin -scanbus</DD>
|
||||||
|
<DD>$ cdrskin dev=ATA -scanbus</DD>
|
||||||
|
<DD>$ cdrskin --devices</DD>
|
||||||
|
<DT>Get info about a particular drive or loaded media:</DT>
|
||||||
|
<DD>$ cdrskin dev=0,1,0 -checkdrive</DD>
|
||||||
|
<DD>$ cdrskin dev=ATA:1,0,0 -atip</DD>
|
||||||
|
<DD>$ cdrskin dev=/dev/hdc -toc</DD>
|
||||||
|
<DT>Make used CD-RW writable again:</DT>
|
||||||
|
<DD>$ cdrskin -v dev=/dev/sg1 blank=all -eject</DD>
|
||||||
|
<DD>$ cdrskin -v dev=/dev/dvd blank=fast -eject</DD>
|
||||||
|
<DT>Write ISO-9660 filesystem image:</DT>
|
||||||
|
<DD>$ cdrskin -v dev=/dev/hdc speed=12 fs=8m driveropts=burnfree -sao -eject padsize=300k my_image.iso</DD>
|
||||||
|
<DT>Write compressed afio archive on-the-fly :</DT>
|
||||||
|
<DD>$ find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree padsize=300k -tao -</DD>
|
||||||
|
<DT>Write audio tracks:</DT>
|
||||||
|
<DD>$ cdrskin -v dev=ATA:1,0,0 speed=48 driveropts=burnfree -sao track1.wav track2.au -audio -swab track3.raw
|
||||||
|
<DD>
|
||||||
|
<BR>
|
||||||
|
<DT>Get overview of the cdrecord compatible options:</DT>
|
||||||
|
<DD><A HREF="cdrskin_help">$ cdrskin -help</A></DD>
|
||||||
|
<DT>Get overview of the non-cdrecord options:</DT>
|
||||||
|
<DD><A HREF="cdrskin__help">$ cdrskin --help</A></DD>
|
||||||
|
<DT>Read the detailed manual page:</DT>
|
||||||
|
<DD><A HREF="man_1_cdrskin.html">$ man cdrskin</A></DD>
|
||||||
|
<DT>Read about the standard for which cdrskin is striving:</DT>
|
||||||
|
<DD><A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">
|
||||||
|
$ man cdrecord</A></DD>
|
||||||
|
<DD><B>Do not bother Joerg Schilling with any cdrskin problems.</B>
|
||||||
|
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
|
||||||
|
this "don't bother Joerg" demand.)
|
||||||
|
</DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H2>Known deficiencies:</H2>
|
||||||
|
<UL>
|
||||||
|
<DT></DT>
|
||||||
|
<LI>
|
||||||
|
Appending sessions to unclosed media is restricted to write mode TAO.
|
||||||
|
</LI>
|
||||||
|
<LI>
|
||||||
|
cdrskin -scanbus or --devices hangs for quite a while if there is
|
||||||
|
a CD drive which does not work properly (e.g. because it has individual
|
||||||
|
problems with DMA).
|
||||||
|
So if the superuser gets no result with cdrskin --devices then one should
|
||||||
|
disable DMA with the problematic CD drives
|
||||||
|
(like: <KBD>hdparm -d0 /dev/hdd</KBD> )
|
||||||
|
and try again.<BR>
|
||||||
|
In severe cases it might be necessary to guess the device name /dev/sgN resp.
|
||||||
|
/dev/hdX of the non-ill burner if it cannot be found otherwise among its
|
||||||
|
ill peers. Alternatively one can guess the address of the ill device, remove
|
||||||
|
rw-permissions and retry the bus scan as non-superuser.
|
||||||
|
</UL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT>Download as source code (see README):</DT>
|
||||||
|
<DD><A HREF="cdrskin-0.2.6.pl02.tar.gz">cdrskin-0.2.6.pl02.tar.gz</A>
|
||||||
|
(510 KB).
|
||||||
|
</DD>
|
||||||
|
<DD>(Most recent patch: backported man page from cdrskin-0.2.7)</DD>
|
||||||
|
<DD>
|
||||||
|
The "stable" cdrskin tarballs are source code identical with "stable"
|
||||||
|
libburn releases or with "stabilized" libburn SVN snapshots. They get
|
||||||
|
produced via a different procedure, though.<BR>
|
||||||
|
cdrskin is part of libburn - full libburn is provided with cdrskin releases.
|
||||||
|
</DD>
|
||||||
|
<DD> </DD>
|
||||||
|
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
|
||||||
|
<DD><A HREF="cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz">
|
||||||
|
cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz</A>, (60 KB),
|
||||||
|
<DL>
|
||||||
|
<DD>runs on SuSE 9.0 (2.4.21) , RIP-14.4 (2.6.14) ,
|
||||||
|
Gentoo (2.6.15 x86_64 Athlon).</DD>
|
||||||
|
</DL>
|
||||||
|
<DD><A HREF="cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz">
|
||||||
|
cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz</A>, (260 KB), -static compiled,
|
||||||
|
<DL>
|
||||||
|
<DD>runs on SuSE 7.2 (2.4.4), and on the systems above.</DD>
|
||||||
|
</DL>
|
||||||
|
</DD>
|
||||||
|
</DL>
|
||||||
|
<DL><DT>Documentation:</DT>
|
||||||
|
<DD><A HREF="README_cdrskin">README</A> a short introduction</DD>
|
||||||
|
<DD><A HREF="cdrskin__help">cdrskin --help</A> non-cdrecord options</DD>
|
||||||
|
<DD><A HREF="cdrskin_help">cdrskin -help</A> cdrecord compatible options</DD>
|
||||||
|
<DD><A HREF="man_1_cdrskin.html">man cdrskin</A> the manual page</DD>
|
||||||
|
<DD> </DD>
|
||||||
|
</DL>
|
||||||
|
<DL><DT>Contact:</DT>
|
||||||
|
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
|
||||||
|
<DD>libburn development mailing list,
|
||||||
|
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
|
||||||
|
</DL>
|
||||||
|
<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> </DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Enhancements towards previous stable version cdrskin-0.2.4:
|
||||||
|
<UL>
|
||||||
|
<LI>Option <KBD><B>-tao</B></KBD> is fully enabled.<BR>
|
||||||
|
SAO is still the preferred default but TAO is default if a track of
|
||||||
|
unpredicted size is present (stdin, named pipe, ...) or if a follow-up
|
||||||
|
session is written to an appendable CD.
|
||||||
|
(This is an intentional deviation from cdrecord defaults which themselves
|
||||||
|
have changed with the newest cdrecord versions.)
|
||||||
|
</LI>
|
||||||
|
<LI>Status report during blank, preparation and finalization improved.</LI>
|
||||||
|
<LI>Bug fixed: Trailing trash appended to .wav files caused error message
|
||||||
|
and, if exceeding fifo size, could even stall a burn.
|
||||||
|
(Workaround: disable fifo by <KBD><B>fs=0</B></KBD>)</LI>
|
||||||
|
<LI>Bug fixed: False speed with first pacifier cycle. Potential program
|
||||||
|
abort by floating point exception (NaN).</LI>
|
||||||
|
<LI>multi-session CDs: <KBD><B>-multi</B></KBD>, <KBD><B>-msinfo</B></KBD>,
|
||||||
|
writing to appendable CDs (for now restricted to write mode TAO).</LI>
|
||||||
|
</UL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT><H3>Development snapshot, version 0.2.7 :</H3></DT>
|
||||||
|
<DD>Enhancements towards stable version 0.2.6:
|
||||||
|
<UL>
|
||||||
|
<LI>Improved recognition of unsuitable media types</LI>
|
||||||
|
<LI>Ban of chmod u+s is replaced by a loud warning</LI>
|
||||||
|
<LI>Detailed man page (already backported to cdrskin-0.2.6.pl02)</LI>
|
||||||
|
<LI>Burning to DVD+RW and DVD-RAM as non-multi, non-appending,
|
||||||
|
single-track session</LI>
|
||||||
|
<LI>Formatting and then burning to DVD-RW like to DVD+RW</LI>
|
||||||
|
<LI>Emulation of new wodim option msifile=path</LI>
|
||||||
|
</UL>
|
||||||
|
</DD>
|
||||||
|
<DD> </DD>
|
||||||
|
<DD><A HREF="README_cdrskin_devel">README 0.2.7</A>
|
||||||
|
<DD><A HREF="cdrskin__help_devel">cdrskin_0.2.7 --help</A></DD>
|
||||||
|
<DD><A HREF="cdrskin_help_devel">cdrskin_0.2.7 -help</A></DD>
|
||||||
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.2.7)</A></DD>
|
||||||
|
<DD> </DD>
|
||||||
|
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||||
|
<A HREF="http://libburnia.pykix.org"> libburnia.pykix.org</A></DT>
|
||||||
|
<DD>Download: <KBD><B>svn co http://libburnia-svn.pykix.org/libburn/trunk libburn_pykix</B>
|
||||||
|
</KBD></DD>
|
||||||
|
<DD>Build: <KBD><B>cd libburn_pykix ; ./bootstrap ; ./configure ; make</B>
|
||||||
|
</KBD></DD>
|
||||||
|
<DD>Build of SVN versions needs <A HREF="http://sources.redhat.com/autobook/">
|
||||||
|
autotools</A> of at least version 1.7 installed.
|
||||||
|
But after the run of <KBD>./bootstrap</KBD>, only
|
||||||
|
vanilla tools like make and gcc are needed.</DD>
|
||||||
|
</DD>
|
||||||
|
<DD> </DD>
|
||||||
|
<DT>The following downloads are intended for adventurous end users or
|
||||||
|
admins with full system souvereignty.</DT>
|
||||||
|
<DD>Source (./bootstrap is already applied, build tested, for more see
|
||||||
|
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||||
|
</DD>
|
||||||
|
<DD>
|
||||||
|
<A HREF="cdrskin-0.2.7.tar.gz">cdrskin-0.2.7.tar.gz</A>
|
||||||
|
(550 KB).
|
||||||
|
</DD>
|
||||||
|
<DD>Binary (untar and move to /usr/bin/cdrskin):</DD>
|
||||||
|
<DD><A HREF="cdrskin_0.2.7-x86-suse9_0.tar.gz">
|
||||||
|
cdrskin_0.2.7-x86-suse9_0.tar.gz</A>, (75 KB).
|
||||||
|
</DD>
|
||||||
|
<DD><A HREF="cdrskin_0.2.7-x86-suse9_0-static.tar.gz">
|
||||||
|
cdrskin_0.2.7-x86-suse9_0-static.tar.gz</A>, (275 KB)
|
||||||
|
</DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Many thanks to Joerg Schilling for cdrecord,
|
||||||
|
<BR>
|
||||||
|
and to Derek Foreman and Ben Jansens for creating libburn.
|
||||||
|
<BR>
|
||||||
|
Historic versions based on Derek's and Ben's
|
||||||
|
<A HREF="http://icculus.org/burn">icculus.org/burn</A> :<BR>
|
||||||
|
<A HREF="cdrskin-0.1.2.0.2.ts.tar.gz">cdrskin-0.1.2.0.2.ts.tar.gz</A><BR>
|
||||||
|
<A HREF="cdrskin-0.1.3.0.2.ts.tar.gz">cdrskin-0.1.3.0.2.ts.tar.gz</A>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<A NAME="examples">
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT>Example for a setup of device permissions. To be done by the superuser:</DT>
|
||||||
|
<DT>(CD devices which offer no r-permission are invisible to normal users.)</DT>
|
||||||
|
<DT>(CD devices which offer no w-permission are not useable.)</DT>
|
||||||
|
<DD># <KBD><B>cdrskin --devices</B></KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD>0 dev='/dev/sg0' rwrwr- : 'TEAC' 'CD-ROM CD-532S'</KBD></DD>
|
||||||
|
<DD><KBD>1 dev='/dev/hdc' rwrw-- : 'LITE-ON' 'LTR-48125S'</KBD></DD>
|
||||||
|
<DD># <KBD><B>chmod a+rw /dev/sg0 /dev/hdc</B></KBD></DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<A NAME="k3b">
|
||||||
|
<P>
|
||||||
|
<A HREF="k3b_on_cdrskin.html">
|
||||||
|
Example how to setup K3b to use cdrskin for burning data CD projects.
|
||||||
|
<A><BR>
|
||||||
|
(<A HREF="http://www.k3b.org">K3b</A>
|
||||||
|
is a GUI frontend which uses cdrecord for CD burning.)
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<A NAME="scdbackup">
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT>Example for a test session with a cdrecord based scdbackup installation:</DT>
|
||||||
|
<DD>$ <KBD><B>cdrskin -scanbus</B></KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD> 2,0,0 0) 'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM</KBD></DD>
|
||||||
|
<DD>$ <KBD><B>cdrskin -scanbus dev=ATA</B></KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD> 1,0,0 1) 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
|
||||||
|
<DD>$ <KBD><B>export SCDBACKUP_SCSI_ADR="ATA:1,0,0"</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v tao_to_sao_tsize=650m"</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>scdbackup_home</B></KBD></DD>
|
||||||
|
</DL>
|
||||||
|
<DL>
|
||||||
|
<DT>Example for a permanent configuration of cdrskin based scdbackup</DT>
|
||||||
|
<DD>$ <KBD><B>cd scdbackup-0.8.6/inst</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=1</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD>cdrskin 0.2.6 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
|
||||||
|
</DL>
|
||||||
|
If your system is stricken with some ill CD device then this can stall
|
||||||
|
and you will have to press <KBD>Ctrl+C</KBD> to abort.
|
||||||
|
In this case, you may execute
|
||||||
|
<KBD>export SCDBACKUP_NO_SCANBUS=1</KBD>
|
||||||
|
and try again.
|
||||||
|
<DL>
|
||||||
|
<DT></DT>
|
||||||
|
<DD><KBD> ------------------- SCSI devices. To be used like 0,0,0</KBD></DD>
|
||||||
|
<DD><KBD> 2,0,0 0) 'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM</KBD></DD>
|
||||||
|
<DD><KBD> ------------------- end of SCSI device list</KBD></DD>
|
||||||
|
<DD><KBD> ------------------- ATA devices. To be used like ATA:0,0,0
|
||||||
|
<DD><KBD> 1,0,0 1) 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD> * Your cdrecord offers -driveropts=burnfree with your recorder.</KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD>scdbackup for CD 0.8.6 : First stage of installation done.</KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD><KBD>Now give it a try. Run : scdbackup_home</KBD></DD>
|
||||||
|
<DD>$ <KBD><B>unset SCDBACKUP_USE_CDRSKIN</B></KBD></DD>
|
||||||
|
</DL>
|
||||||
|
<DL>
|
||||||
|
<DT>To get back to using cdrecord :</DT>
|
||||||
|
<DD>$ <KBD><B>cd scdbackup-0.8.6/inst</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=0</B></KBD></DD>
|
||||||
|
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
|
||||||
|
<DD><KBD>...</KBD></DD>
|
||||||
|
<DD>$ <KBD><B>unset SCDBACKUP_USE_CDRSKIN</B></KBD></DD>
|
||||||
|
</DL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<A NAME="cdrecord">
|
||||||
|
<P>
|
||||||
|
<CENTER><H3>About the relationship of cdrecord and cdrskin</H3></CENTER>
|
||||||
|
First of all: this relationship is single sided, as cdrskin has to be aware of
|
||||||
|
cdrecord but not vice versa.
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
I am a long time user of cdrecord and it works fine for me.
|
||||||
|
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
|
||||||
|
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
||||||
|
maintained. So for me - there would be not problem with it.
|
||||||
|
<BR>
|
||||||
|
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).
|
||||||
|
One has to be aware, though, that this relationship might lead to a situation
|
||||||
|
where cdrecord is no longer available for certain Linux kernels.
|
||||||
|
<BR>
|
||||||
|
To have my own project prepared for such a time, i began to implement its
|
||||||
|
cdrecord gestures on top of libburn.
|
||||||
|
From now on i invite other interested users of cdrecord to teach cdrskin
|
||||||
|
the gestures necessary for their cdrecord applications.
|
||||||
|
Contact me. Let's see what we can achieve.
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
libburn and cdrskin are now mature enough to substitute cdrecord in its
|
||||||
|
major use cases of CD burning. It is possible to foist cdrskin on various
|
||||||
|
software packages if it gets falsely named "cdrecord".
|
||||||
|
I do not encourage this approach, but of course such a replacement
|
||||||
|
opportunity is the goal of a cdrecord compatibility wrapper.
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
It is very important to me that this project is not perceived as hostile
|
||||||
|
towards Joerg Schilling and his ongoing work.
|
||||||
|
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
||||||
|
<BR>
|
||||||
|
</P>
|
||||||
|
<HR>
|
||||||
|
|
||||||
|
<CENTER><FONT SIZE=+0>
|
||||||
|
<!-- <A NAME="bottom" HREF="main_ger.html#bottom">deutsch (german)</A>
|
||||||
|
<BR><BR>
|
||||||
|
-->
|
||||||
|
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
|
||||||
|
<IMG SRC="doener_150x200_tr.gif" BORDER=0
|
||||||
|
ALT="cdrskin logo: Doener mit Scharf"></A>
|
||||||
|
<BR><BR>
|
||||||
|
<FONT SIZE=+0>Enjoying free Open Source hosting by <A HREF="http://www.webframe.org">www.webframe.org</A><BR>
|
||||||
|
<A HREF="http://www.webframe.org">
|
||||||
|
<IMG SRC="msfree.gif" ALT="100 % Microsoft free" BORDER=0></A><BR>
|
||||||
|
and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
|
||||||
|
<A href="http://sourceforge.net">
|
||||||
|
<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> -->
|
||||||
|
</FONT></CENTER>
|
||||||
|
<HR>
|
||||||
|
<DL>
|
||||||
|
<DT>Links to my other published software projects :
|
||||||
|
<DD><A HREF=http://scdbackup.webframe.org/main_eng.html>
|
||||||
|
scdbackup, multi volume CD backup</A>
|
||||||
|
<DL><DD><A HREF=http://scdbackup.sourceforge.net/main_eng.html>
|
||||||
|
(a second source of above)</A></DL>
|
||||||
|
<DD><A HREF=http://stic.webframe.org>Some Tools for Image Collectors</A>
|
||||||
|
<DL><DD><A HREF=http://stic.sourceforge.net>(a second source of above)</A></DL>
|
||||||
|
<DD><A HREF=http://scdbackup.webframe.org/pppoem>
|
||||||
|
pppoem, a DSL throughput monitor (mainly for Linux kernel 2.4)</A>
|
||||||
|
</DL>
|
||||||
|
<BR><BR>
|
||||||
|
Legal statement: This website does not serve any commercial purpose.<BR>
|
||||||
|
</FONT>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
1
libburn/tags/ZeroThreeZero/cdrskin/cdrskin_timestamp.h
Normal file
1
libburn/tags/ZeroThreeZero/cdrskin/cdrskin_timestamp.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#define Cdrskin_timestamP "2007.01.14.133951"
|
2519
libburn/tags/ZeroThreeZero/cdrskin/changelog.txt
Normal file
2519
libburn/tags/ZeroThreeZero/cdrskin/changelog.txt
Normal file
File diff suppressed because it is too large
Load Diff
215
libburn/tags/ZeroThreeZero/cdrskin/cleanup.c
Normal file
215
libburn/tags/ZeroThreeZero/cdrskin/cleanup.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
typedef void (*sighandler_t)(int);
|
||||||
|
|
||||||
|
|
||||||
|
#include "cleanup.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Cleanup_has_no_libburn_os_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "../libburn/os.h"
|
||||||
|
|
||||||
|
/* see os.h for name of particular os-*.h where this is defined */
|
||||||
|
static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1};
|
||||||
|
static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"};
|
||||||
|
static int signal_list_count= BURN_OS_SIGNAL_COUNT;
|
||||||
|
static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1};
|
||||||
|
static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* ! Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
|
||||||
|
|
||||||
|
/* Signals to be caught */
|
||||||
|
static int signal_list[]= {
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
|
||||||
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
|
||||||
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
|
||||||
|
SIGTTOU,
|
||||||
|
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ, -1
|
||||||
|
};
|
||||||
|
static char *signal_name_list[]= {
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
|
||||||
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
|
||||||
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
|
||||||
|
"SIGTTOU",
|
||||||
|
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
|
||||||
|
};
|
||||||
|
static int signal_list_count= 24;
|
||||||
|
|
||||||
|
/* Signals not to be caught */
|
||||||
|
static int non_signal_list[]= {
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
|
||||||
|
};
|
||||||
|
static int non_signal_list_count= 5;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* run time dynamic part */
|
||||||
|
static char cleanup_msg[4096]= {""};
|
||||||
|
static int cleanup_exiting= 0;
|
||||||
|
static int cleanup_has_reported= -1234567890;
|
||||||
|
|
||||||
|
static void *cleanup_app_handle= NULL;
|
||||||
|
static Cleanup_app_handler_T cleanup_app_handler= NULL;
|
||||||
|
static int cleanup_perform_app_handler_first= 0;
|
||||||
|
|
||||||
|
|
||||||
|
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
|
||||||
|
fprintf(stderr,"\n%s\n",cleanup_msg);
|
||||||
|
cleanup_has_reported= signum;
|
||||||
|
}
|
||||||
|
if(cleanup_perform_app_handler_first)
|
||||||
|
if(cleanup_app_handler!=NULL) {
|
||||||
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
|
if(ret==2 || ret==-2)
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
if(cleanup_exiting) {
|
||||||
|
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
||||||
|
getpid(),signum);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
cleanup_exiting= 1;
|
||||||
|
alarm(0);
|
||||||
|
if(!cleanup_perform_app_handler_first)
|
||||||
|
if(cleanup_app_handler!=NULL) {
|
||||||
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
|
if(ret==2 || ret==-2)
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
exit(exit_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Cleanup_handler_generic(int signum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
|
||||||
|
for(i= 0; i<signal_list_count; i++)
|
||||||
|
if(signum==signal_list[i]) {
|
||||||
|
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
|
||||||
|
signal_name_list[i],errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Cleanup_handler_exit(1,signum,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||||
|
/*
|
||||||
|
bit0= set to default handlers
|
||||||
|
bit1= set to ignore
|
||||||
|
bit2= set cleanup_perform_app_handler_first
|
||||||
|
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
||||||
|
sighandler_t sig_handler;
|
||||||
|
|
||||||
|
cleanup_msg[0]= 0;
|
||||||
|
cleanup_app_handle= handle;
|
||||||
|
cleanup_app_handler= handler;
|
||||||
|
|
||||||
|
/* <<< make cleanup_exiting thread safe to get rid of this */
|
||||||
|
if(flag&4)
|
||||||
|
cleanup_perform_app_handler_first= 1;
|
||||||
|
|
||||||
|
|
||||||
|
if(flag&1)
|
||||||
|
sig_handler= SIG_DFL;
|
||||||
|
else if(flag&2)
|
||||||
|
sig_handler= SIG_IGN;
|
||||||
|
else
|
||||||
|
sig_handler= Cleanup_handler_generic;
|
||||||
|
/* set all signal numbers between the lowest and highest in the list
|
||||||
|
except those in the non-signal list */
|
||||||
|
for(i= 0; i<signal_list_count; i++) {
|
||||||
|
if(signal_list[i]>max_sig)
|
||||||
|
max_sig= signal_list[i];
|
||||||
|
if(signal_list[i]<min_sig)
|
||||||
|
min_sig= signal_list[i];
|
||||||
|
}
|
||||||
|
for(i= min_sig; i<=max_sig; i++) {
|
||||||
|
for(j= 0; j<non_signal_list_count; j++)
|
||||||
|
if(i==non_signal_list[j])
|
||||||
|
break;
|
||||||
|
if(j>=non_signal_list_count) {
|
||||||
|
if(i==SIGABRT && (flag&8))
|
||||||
|
signal(i,Cleanup_handler_generic);
|
||||||
|
else
|
||||||
|
signal(i,sig_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Cleanup_standalonE
|
||||||
|
|
||||||
|
struct Demo_apP {
|
||||||
|
char *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
|
||||||
|
{
|
||||||
|
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
|
||||||
|
signum,demoapp->msg);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
struct Demo_apP demoapp;
|
||||||
|
|
||||||
|
demoapp.msg= "Good Bye";
|
||||||
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
|
char *cpt= NULL,c;
|
||||||
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
|
c= *cpt;
|
||||||
|
} else {
|
||||||
|
printf("killme: %d\n",getpid());
|
||||||
|
sleep(3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup_set_handlers(NULL,NULL,1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Cleanup_standalonE */
|
34
libburn/tags/ZeroThreeZero/cdrskin/cleanup.h
Normal file
34
libburn/tags/ZeroThreeZero/cdrskin/cleanup.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Cleanup_includeD
|
||||||
|
#define Cleanup_includeD 1
|
||||||
|
|
||||||
|
|
||||||
|
/** Layout of an application provided cleanup function using an application
|
||||||
|
provided handle as first argument and the signal number as second
|
||||||
|
argument. The third argument is a flag bit field with no defined bits yet.
|
||||||
|
If the handler returns 2 or -2 then it has delegated exit() to some other
|
||||||
|
instance and the Cleanup handler shall return rather than exit.
|
||||||
|
*/
|
||||||
|
typedef int (*Cleanup_app_handler_T)(void *, int, int);
|
||||||
|
|
||||||
|
|
||||||
|
/** Establish exiting signal handlers on (hopefully) all signals that are
|
||||||
|
not ignored by default or non-catchable.
|
||||||
|
@param handle Opaque object which knows how to cleanup application
|
||||||
|
@param handler Function which uses handle to perform application cleanup
|
||||||
|
@param flag Control Bitfield
|
||||||
|
bit0= reset to default signal handling
|
||||||
|
*/
|
||||||
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! Cleanup_includeD */
|
||||||
|
|
219
libburn/tags/ZeroThreeZero/cdrskin/compile_cdrskin.sh
Executable file
219
libburn/tags/ZeroThreeZero/cdrskin/compile_cdrskin.sh
Executable file
@ -0,0 +1,219 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# compile_cdrskin.sh
|
||||||
|
# Copyright 2005 - 2006 Thomas Schmitt, scdbackup@gmx.net, GPL
|
||||||
|
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||||
|
|
||||||
|
debug_opts=
|
||||||
|
def_opts=
|
||||||
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
|
libvers="-DCdrskin_libburn_0_2_7"
|
||||||
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
|
do_strip=0
|
||||||
|
static_opts=
|
||||||
|
warn_opts="-Wall"
|
||||||
|
fifo_source="cdrskin/cdrfifo.c"
|
||||||
|
compile_cdrskin=1
|
||||||
|
compile_cdrfifo=0
|
||||||
|
compile_dewav=0
|
||||||
|
|
||||||
|
for i in "$@"
|
||||||
|
do
|
||||||
|
if test "$i" = "-compile_cdrfifo"
|
||||||
|
then
|
||||||
|
compile_cdrfifo=1
|
||||||
|
elif test "$i" = "-compile_dewav"
|
||||||
|
then
|
||||||
|
compile_dewav=1
|
||||||
|
elif test "$i" = "-cvs_A60220"
|
||||||
|
then
|
||||||
|
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
||||||
|
libdax_audioxtr_o=
|
||||||
|
libdax_msgs_o="libburn/message.o"
|
||||||
|
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||||
|
elif test "$i" = "-libburn_0_2_6"
|
||||||
|
then
|
||||||
|
libvers="-DCdrskin_libburn_0_2_6"
|
||||||
|
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"
|
||||||
|
then
|
||||||
|
libvers="-DCdrskin_libburn_0_2_7"
|
||||||
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
|
then
|
||||||
|
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"
|
||||||
|
then
|
||||||
|
largefile_opts=
|
||||||
|
elif test "$i" = "-do_not_compile_cdrskin"
|
||||||
|
then
|
||||||
|
compile_cdrskin=0
|
||||||
|
elif test "$i" = "-do_diet"
|
||||||
|
then
|
||||||
|
fifo_source=
|
||||||
|
def_opts="$def_opts -DCdrskin_extra_leaN"
|
||||||
|
warn_opts=
|
||||||
|
elif test "$i" = "-do_strip"
|
||||||
|
then
|
||||||
|
do_strip=1
|
||||||
|
elif test "$i" = "-g"
|
||||||
|
then
|
||||||
|
debug_opts="$debug_opts -g"
|
||||||
|
elif test "$i" = "-O2"
|
||||||
|
then
|
||||||
|
debug_opts="$debug_opts -O2"
|
||||||
|
elif test "$i" = "-help" -o "$i" = "--help" -o "$i" = "-h"
|
||||||
|
then
|
||||||
|
echo "cdrskin/compile_cdrskin.sh : to be executed within top level directory"
|
||||||
|
echo "Options:"
|
||||||
|
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||||
|
echo " -compile_dewav compile program test/dewav without libburn."
|
||||||
|
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
|
||||||
|
echo " -libburn_0_2_6 set macro to match libburn-0.2.6."
|
||||||
|
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||||
|
echo " -no_largefile do not use 64 bit off_t (must match libburn)."
|
||||||
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
|
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_strip apply program strip to compiled programs."
|
||||||
|
echo " -g compile with cc option -g."
|
||||||
|
echo " -O2 compile with cc option -O2."
|
||||||
|
echo " -static compile with cc option -static."
|
||||||
|
exit 0
|
||||||
|
elif test "$i" = "-static"
|
||||||
|
then
|
||||||
|
static_opts="-static"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
|
echo "Version timestamp : $(sed -e 's/#define Cdrskin_timestamP "//' -e 's/"$//' cdrskin/cdrskin_timestamp.h)"
|
||||||
|
echo "Build timestamp : $timestamp"
|
||||||
|
|
||||||
|
if test "$compile_cdrskin"
|
||||||
|
then
|
||||||
|
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj"
|
||||||
|
cc -I. \
|
||||||
|
$warn_opts \
|
||||||
|
$static_opts \
|
||||||
|
$debug_opts \
|
||||||
|
$libvers \
|
||||||
|
$largefile_opts \
|
||||||
|
$def_opts \
|
||||||
|
\
|
||||||
|
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
||||||
|
\
|
||||||
|
-o cdrskin/cdrskin \
|
||||||
|
\
|
||||||
|
cdrskin/cdrskin.c \
|
||||||
|
$fifo_source \
|
||||||
|
\
|
||||||
|
$cleanup_src_or_obj \
|
||||||
|
\
|
||||||
|
libburn/async.o \
|
||||||
|
libburn/debug.o \
|
||||||
|
libburn/drive.o \
|
||||||
|
libburn/file.o \
|
||||||
|
libburn/init.o \
|
||||||
|
libburn/options.o \
|
||||||
|
libburn/source.o \
|
||||||
|
libburn/structure.o \
|
||||||
|
\
|
||||||
|
libburn/sg.o \
|
||||||
|
libburn/write.o \
|
||||||
|
$libdax_audioxtr_o \
|
||||||
|
$libdax_msgs_o \
|
||||||
|
\
|
||||||
|
libburn/mmc.o \
|
||||||
|
libburn/sbc.o \
|
||||||
|
libburn/spc.o \
|
||||||
|
libburn/util.o \
|
||||||
|
\
|
||||||
|
libburn/sector.o \
|
||||||
|
libburn/toc.o \
|
||||||
|
\
|
||||||
|
libburn/crc.o \
|
||||||
|
libburn/lec.o \
|
||||||
|
\
|
||||||
|
-lpthread
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if test "$ret" = 0
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo >&2
|
||||||
|
echo "+++ FATAL : Compilation of cdrskin failed" >&2
|
||||||
|
echo >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$compile_cdrfifo" = 1
|
||||||
|
then
|
||||||
|
echo "compiling program cdrskin/cdrfifo.c $static_opts $debug_opts"
|
||||||
|
cc $static_opts $debug_opts \
|
||||||
|
-DCdrfifo_standalonE \
|
||||||
|
-o cdrskin/cdrfifo \
|
||||||
|
cdrskin/cdrfifo.c
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if test "$ret" = 0
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo >&2
|
||||||
|
echo "+++ FATAL : Compilation of cdrfifo failed" >&2
|
||||||
|
echo >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$compile_dewav" = 1
|
||||||
|
then
|
||||||
|
echo "compiling program test/dewav.c -DDewav_without_libburN $static_opts $debug_opts"
|
||||||
|
cc $static_opts $debug_opts \
|
||||||
|
-DDewav_without_libburN \
|
||||||
|
-o test/dewav \
|
||||||
|
test/dewav.c \
|
||||||
|
libburn/libdax_audioxtr.o \
|
||||||
|
libburn/libdax_msgs.o \
|
||||||
|
\
|
||||||
|
-lpthread
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if test "$ret" = 0
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo >&2
|
||||||
|
echo "+++ FATAL : Compilation of test/dewav failed" >&2
|
||||||
|
echo >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$do_strip" = 1
|
||||||
|
then
|
||||||
|
echo "stripping result cdrskin/cdrskin"
|
||||||
|
strip cdrskin/cdrskin
|
||||||
|
if test "$compile_cdrfifo" = 1
|
||||||
|
then
|
||||||
|
echo "stripping result cdrskin/cdrfifo"
|
||||||
|
strip cdrskin/cdrfifo
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'done.'
|
72
libburn/tags/ZeroThreeZero/cdrskin/convert_man_to_html.sh
Executable file
72
libburn/tags/ZeroThreeZero/cdrskin/convert_man_to_html.sh
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# convert_man_to_html.sh - ts A61214
|
||||||
|
#
|
||||||
|
# Generates a HTML version of man page cdrskin.1
|
||||||
|
#
|
||||||
|
# To be executed within the libburn toplevel directory (like ./libburn-0.2.7)
|
||||||
|
#
|
||||||
|
|
||||||
|
# set -x
|
||||||
|
|
||||||
|
man_dir=$(pwd)"/cdrskin"
|
||||||
|
export MANPATH="$man_dir"
|
||||||
|
manpage="cdrskin"
|
||||||
|
raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html"
|
||||||
|
htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
|
if test -r "$manpage"
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
echo "Cannot find readable man page source $1" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -e "$man_dir"/man1
|
||||||
|
then
|
||||||
|
dummy=dummy
|
||||||
|
else
|
||||||
|
ln -s . "$man_dir"/man1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$1" = "-work_as_filter"
|
||||||
|
then
|
||||||
|
|
||||||
|
# set -x
|
||||||
|
|
||||||
|
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="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/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
|
||||||
|
-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/<b>Overview of features:<\/b>/\ <BR><b>Overview of features:<\/b>/' \
|
||||||
|
-e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b>/' \
|
||||||
|
-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/<b>Recordable CD Media:<\/b>/\ <BR><b>Recordable CD Media:<\/b>/' \
|
||||||
|
-e 's/<b>Recordable DVD Media:<\/b>/\ <BR><b>Recordable DVD Media:<\/b>/' \
|
||||||
|
-e 's/<b>Drive preparation and addressing:<\/b>/\ <BR><b>Drive preparation and addressing:<\/b>/' \
|
||||||
|
-e 's/If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||||
|
-e 's/^Alphabetical list of options/\ <BR>Alphabetical list of options/' \
|
||||||
|
-e 's/and for all others\.<\/td><\/table>/and for all others.<\/td><\/table> <BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT>/' \
|
||||||
|
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||||
|
<"$2" >"$htmlpage"
|
||||||
|
|
||||||
|
set +x
|
||||||
|
|
||||||
|
chmod u+rw,go+r,go-w "$htmlpage"
|
||||||
|
echo "Emerged file:"
|
||||||
|
ls -l "$htmlpage"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
export BROWSER='cp "%s" '"$raw_html"
|
||||||
|
man -H "$manpage"
|
||||||
|
"$0" -work_as_filter "$raw_html"
|
||||||
|
rm "$raw_html"
|
||||||
|
rm "$man_dir"/man1
|
||||||
|
|
||||||
|
fi
|
BIN
libburn/tags/ZeroThreeZero/cdrskin/doener_150x200_tr.gif
Normal file
BIN
libburn/tags/ZeroThreeZero/cdrskin/doener_150x200_tr.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
libburn/tags/ZeroThreeZero/cdrskin/doener_150x200_tr_octx.gif
Normal file
BIN
libburn/tags/ZeroThreeZero/cdrskin/doener_150x200_tr_octx.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
9
libburn/tags/ZeroThreeZero/cdrskin/make_timestamp.sh
Executable file
9
libburn/tags/ZeroThreeZero/cdrskin/make_timestamp.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Create version timestamp cdrskin/cdrskin_timestamp.h
|
||||||
|
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||||
|
|
||||||
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
|
echo "Version timestamp : $timestamp"
|
||||||
|
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >cdrskin/cdrskin_timestamp.h
|
||||||
|
|
230
libburn/tags/ZeroThreeZero/cdrskin/wiki_plain.txt
Normal file
230
libburn/tags/ZeroThreeZero/cdrskin/wiki_plain.txt
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
cdrskin Wiki - plain text copy
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
[[Image(source:/libburn/trunk/cdrskin/doener_150x200_tr.gif)]] [http://en.wikipedia.org/wiki/D%C3%B6ner_kebab Doener]
|
||||||
|
|
||||||
|
'''cdrskin is the cdrecord compatibility middleware of libburn.'''
|
||||||
|
|
||||||
|
Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg
|
||||||
|
Schilling's cdrtools. cdrskin strives to be a second source for the services
|
||||||
|
traditionally provided by cdrecord. Currently it does CD-R and CD-RW.
|
||||||
|
Its future ability to burn DVD media depends on the development of libburn.
|
||||||
|
|
||||||
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
Many bytes have been copied from the message output of cdrecord
|
||||||
|
runs, though. The most comprehensive technical overview of cdrskin
|
||||||
|
can be found in [http://libburnia.pykix.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
|
||||||
|
|
||||||
|
About libburn API for burning CD: http://libburnia-api.pykix.org
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Appending sessions to an unclosed CD is restricted to write mode TAO.
|
||||||
|
(Users who have a burner which succeeds with a follow-up session via
|
||||||
|
cdrecord -sao : please contact us.)
|
||||||
|
|
||||||
|
The development version of cdrskin is able to burn a single track to DVD+RW
|
||||||
|
or DVD-RW media.
|
||||||
|
For other DVD types and for appending sessions to ISO filesystems see the
|
||||||
|
advise to use dvd+rw-tools at the end of this text.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
About the command line options of cdrskin:
|
||||||
|
|
||||||
|
They are described in detail in [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#OPTIONS section OPTIONS] of
|
||||||
|
[http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html man cdrskin]
|
||||||
|
|
||||||
|
There are two families of options: cdrecord-compatible ones and options
|
||||||
|
which are specific to cdrskin. The latter are mostly used to configure
|
||||||
|
cdrskin for its task to emulate cdrecord. There are some, nevertheless,
|
||||||
|
which provide rather exotic unique features of cdrskin.
|
||||||
|
|
||||||
|
The cdrecord-compatible options are listed in the output of
|
||||||
|
{{{
|
||||||
|
cdrskin -help
|
||||||
|
}}}
|
||||||
|
where the option "help" has *one* dash. Online: [http://scdbackup.sourceforge.net/cdrskin_help_devel cdrskin -help]
|
||||||
|
|
||||||
|
For these options you may expect program behavior that is roughly the
|
||||||
|
same as described in original man cdrecord .
|
||||||
|
|
||||||
|
Online: http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html
|
||||||
|
|
||||||
|
The cdrskin-specific options are listed by
|
||||||
|
{{{
|
||||||
|
cdrskin --help
|
||||||
|
}}}
|
||||||
|
where the option "help" has *two* dashes. Online: [http://scdbackup.sourceforge.net/cdrskin__help_devel cdrskin --help]
|
||||||
|
|
||||||
|
Some are very experimental and should only be
|
||||||
|
used in coordination with the libburnia developer team.
|
||||||
|
Some are of general user interest, though:
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--devices allows the sysadmin to scan the system for possible drives
|
||||||
|
and displays their detected properties.
|
||||||
|
The drives are listed one per line, with fields:
|
||||||
|
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
|
||||||
|
{{{
|
||||||
|
0 dev='/dev/sg0' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
|
||||||
|
}}}
|
||||||
|
This feature is valuable since cdrskin -scanbus will not give you
|
||||||
|
the device file name and its current permissions.
|
||||||
|
cdrskin will accept of course the proposed dev= option as address
|
||||||
|
for any usage of the drive.
|
||||||
|
|
||||||
|
Different from cdrecord, cdrskin is intended to be run without special
|
||||||
|
privileges, i.e. no superuser setuid. It is intended that the sysadmin
|
||||||
|
controls drive accessability by rw-permissions of the drive rather than
|
||||||
|
by x-permission of the burn binary. To be usable with cdrskin, the drive
|
||||||
|
has to offer both, r- and w-permission.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Non-cdrecord blank mode blank=format_overwrite is needed to bring a DVD-RW
|
||||||
|
disc from its initial profile "Sequential Recording" into profile state
|
||||||
|
"Restricted Overwrite". The latter is usable with cdrskin.
|
||||||
|
{{{
|
||||||
|
cdrskin dev=/dev/sr0 -v blank=format_overwrite
|
||||||
|
}}}
|
||||||
|
|
||||||
|
DVD-RW "Restricted Overwrite" and DVD+RW appear to cdrskin as blank media
|
||||||
|
which are capable of taking only a single track. This track may be positioned
|
||||||
|
on a 32KiB aligned address, though.
|
||||||
|
{{{
|
||||||
|
cdrskin ... write_start_address=2412m ...
|
||||||
|
}}}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fifo_start_at=<num> is a throughput enhancer for unsteady data streams
|
||||||
|
like they are produced by a compressing archiver program when piping to
|
||||||
|
CD on-the-fly. It makes better use of the general property of a FIFO
|
||||||
|
buffer to transport surplus bandwidth into the future. Yep. A time machine.
|
||||||
|
One-way, i fear.
|
||||||
|
|
||||||
|
FIFO originally was introduced by cdrecord's author Joerg Schilling in order
|
||||||
|
to protect mediocre burner hardware from suffering buffer underruns
|
||||||
|
and thus producing misburns (at 1x speed on CD-R media at the price of a
|
||||||
|
DVD-RAM nowadays). This purpose would not justify a fifo any more -
|
||||||
|
given the limited life time of burners and the seamless underrun protection
|
||||||
|
of contemporary consumer drives.
|
||||||
|
|
||||||
|
With an unsteady data stream the task of the buffer is to soak up peak
|
||||||
|
performance and to release it steadily at the drive's maximum speed.
|
||||||
|
The larger the buffer the more reserves can be built up and the longer
|
||||||
|
input drought can be compensated.
|
||||||
|
|
||||||
|
Original cdrecord has the historical property, though, to first wait until
|
||||||
|
the buffer is completely filled. Best practice for fighting drive
|
||||||
|
underruns, of course.
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
stream to end. It risks a few drive buffer underruns at the beginning of burn
|
||||||
|
- but modern drives stand this.
|
||||||
|
|
||||||
|
Usage examples:
|
||||||
|
{{{
|
||||||
|
cdrskin ... fs=128m fifo_start_at=20m ...
|
||||||
|
cdrskin ... fifo_start_at=0 ...
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Note: no FIFO can give you better average throughput than the average
|
||||||
|
throughput of the data source and the throughput of the burner.
|
||||||
|
It can be used, though, to bring the effective throughput very close
|
||||||
|
to the theoretical limit. Especially with high speed media.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--no_rc allows you to surely ban influence from systemwide or user specific
|
||||||
|
default settings of cdrskin. Possible locations for such settings:
|
||||||
|
|
||||||
|
/etc/default/cdrskin
|
||||||
|
|
||||||
|
/etc/opt/cdrskin/rc
|
||||||
|
|
||||||
|
/etc/cdrskin/cdrskin.conf
|
||||||
|
|
||||||
|
$HOME/.cdrskinrc
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
tao_to_sao_tsize=<num> allows the - actually unsupported - cdrecord option
|
||||||
|
-tao and defines a default track size to be used if - as custom with -tao -
|
||||||
|
no option tsize=# is given.
|
||||||
|
|
||||||
|
Since -tao is supported in cdrskin-0.2.6 the TAO-to-SAO workaround has become
|
||||||
|
quite obsolete. Nevertheless, tao_to_sao_tsize= allows to preset a default
|
||||||
|
size for SAO mode which is in effect only if no track size is available.
|
||||||
|
|
||||||
|
As in general with cdrskin tsize=# the data source does not have to provide
|
||||||
|
the full annouced amount of data. Missing data will be padded up by 0-bytes.
|
||||||
|
Surplus data is supposed to cause an error, though. The burn will then
|
||||||
|
be a failure in any way.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
dev_translation=<sep><from><sep><to> may be needed to foist cdrskin to
|
||||||
|
frontend programs of cdrecord which do *not* ask cdrecord -scanbus but
|
||||||
|
which make own assumptions and guesses about cdrecord's device addresses.
|
||||||
|
|
||||||
|
Normally, cdrskin understands all addresses which are suitable for cdrecord
|
||||||
|
under Linux. See cdrskin/README, "Pseudo-SCSI Adresses".
|
||||||
|
This option is mainly for (yet unknown) exotic configurations or very
|
||||||
|
stubborn frontend programs.
|
||||||
|
|
||||||
|
If a frontend refuses to work with cdrskin, look into the error protocol
|
||||||
|
of that frontend, look at the output of a run of cdrskin --devices and give
|
||||||
|
cdrskin the necessary hint.
|
||||||
|
Example: Your frontend insists in using "0,0,0" and --devices reported
|
||||||
|
dev='/dev/hdc' resp. cdrskin dev=ATA -scanbus reported "1,0,0" then this
|
||||||
|
would be the appropriate translation:
|
||||||
|
{{{
|
||||||
|
dev_translation=+0,0,0+/dev/hdc
|
||||||
|
}}}
|
||||||
|
The "+" character is a separator to be choosen by you.
|
||||||
|
Currently i am not aware of the need to choose any other than "+"
|
||||||
|
unless you get playful with custom translations like
|
||||||
|
{{{
|
||||||
|
dev_translation=-"cd+dvd"-1,0,0
|
||||||
|
}}}
|
||||||
|
See http://scdbackup.sourceforge.net/k3b_on_cdrskin.html
|
||||||
|
for an illustrated example with K3b 0.10 .
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DVD advise:
|
||||||
|
|
||||||
|
For burning of DVD media the cdrskin project currently advises to use
|
||||||
|
Andy Polyakov's dvd+rw-tools which despite their historic name burn
|
||||||
|
for me on above burner: DVD+RW, DVD+R, DVD-RW, DVD-R .
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
libburn and thus the cdrskin project are currently aquiring own capabilities
|
||||||
|
to burn to DVD media. For now restricted to DVD+RW and DVD-RW and to single
|
||||||
|
tracks.
|
||||||
|
|
||||||
|
To my knowledge, Linux kernels 2.6 do write to DVD+RW via block devices as
|
||||||
|
they would write to a traditional tape device. Try old tape archiver
|
||||||
|
commands with addresses like /dev/sr0 or /dev/hdc rather than /dev/mt0 .
|
||||||
|
I have heard rumors that DVD-RW in mode "restricted overwrite" would be
|
||||||
|
block device ready, too. My burner is not a real friend of DVD-RW and
|
||||||
|
in an experiment the burn worked fine - but the result was not identical
|
||||||
|
to the stream sent to the device. I had similar failure with DVD-RAM, too.
|
||||||
|
|
||||||
|
Beware of the impact of a slow block device on overall system i/o buffering.
|
||||||
|
It is wise to curb its input to a speed which it is able to deliver to media.
|
||||||
|
Else your i/o dedicated RAM might buffer a big amount of stream data.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
117
libburn/tags/ZeroThreeZero/configure.ac
Normal file
117
libburn/tags/ZeroThreeZero/configure.ac
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
AC_INIT([libburn], [0.2.7], [http://libburnia.pykix.org])
|
||||||
|
AC_PREREQ([2.50])
|
||||||
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
|
dnl A61101 This breaks Linux build (makes 32 bit off_t)
|
||||||
|
dnl http://sourceware.org/autobook/autobook/autobook_96.html says
|
||||||
|
dnl one must include some config.h and this was a pitfall.
|
||||||
|
dnl So why dig the pit at all ?
|
||||||
|
dnl AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
dnl Making releases:
|
||||||
|
dnl BURN_MICRO_VERSION += 1;
|
||||||
|
dnl BURN_INTERFACE_AGE += 1;
|
||||||
|
dnl BURN_BINARY_AGE += 1;
|
||||||
|
dnl if any functions have been added, set BURN_INTERFACE_AGE to 0.
|
||||||
|
dnl if backwards compatibility has been broken,
|
||||||
|
dnl set BURN_BINARY_AGE and BURN_INTERFACE_AGE to 0.
|
||||||
|
dnl
|
||||||
|
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||||
|
dnl
|
||||||
|
BURN_MAJOR_VERSION=0
|
||||||
|
BURN_MINOR_VERSION=2
|
||||||
|
BURN_MICRO_VERSION=7
|
||||||
|
BURN_INTERFACE_AGE=0
|
||||||
|
BURN_BINARY_AGE=0
|
||||||
|
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
|
|
||||||
|
AC_SUBST(BURN_MAJOR_VERSION)
|
||||||
|
AC_SUBST(BURN_MINOR_VERSION)
|
||||||
|
AC_SUBST(BURN_MICRO_VERSION)
|
||||||
|
AC_SUBST(BURN_INTERFACE_AGE)
|
||||||
|
AC_SUBST(BURN_BINARY_AGE)
|
||||||
|
AC_SUBST(BURN_VERSION)
|
||||||
|
|
||||||
|
dnl Libtool versioning
|
||||||
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION
|
||||||
|
LT_CURRENT=`expr $BURN_MICRO_VERSION - $BURN_INTERFACE_AGE`
|
||||||
|
LT_REVISION=$BURN_INTERFACE_AGE
|
||||||
|
LT_AGE=`expr $BURN_BINARY_AGE - $BURN_INTERFACE_AGE`
|
||||||
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
|
AC_SUBST(LT_RELEASE)
|
||||||
|
AC_SUBST(LT_CURRENT)
|
||||||
|
AC_SUBST(LT_REVISION)
|
||||||
|
AC_SUBST(LT_AGE)
|
||||||
|
AC_SUBST(LT_CURRENT_MINUS_AGE)
|
||||||
|
|
||||||
|
AC_PREFIX_DEFAULT([/usr/local])
|
||||||
|
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
||||||
|
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
|
dnl Large file support
|
||||||
|
AC_SYS_LARGEFILE
|
||||||
|
AC_FUNC_FSEEKO
|
||||||
|
AC_CHECK_FUNC([fseeko])
|
||||||
|
if test ! $ac_cv_func_fseeko; then
|
||||||
|
AC_ERROR([Libburn requires largefile support.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AC_SUBST(LIBTOOL_DEPS)
|
||||||
|
LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS()
|
||||||
|
|
||||||
|
AC_CHECK_MEMBER([struct tm.tm_gmtoff],
|
||||||
|
[AC_DEFINE(HAVE_TM_GMTOFF, 1,
|
||||||
|
[Define this if tm structure includes a tm_gmtoff entry.])],
|
||||||
|
,
|
||||||
|
[#include <time.h>])
|
||||||
|
|
||||||
|
THREAD_LIBS=-lpthread
|
||||||
|
AC_SUBST(THREAD_LIBS)
|
||||||
|
|
||||||
|
TARGET_SHIZZLE
|
||||||
|
AC_SUBST(ARCH)
|
||||||
|
AC_SUBST(LIBBURN_ARCH_LIBS)
|
||||||
|
|
||||||
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
|
dnl See if the user wants aggressive optimizations of the code
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
[ --enable-debug Disable aggressive optimizations [default=yes]],
|
||||||
|
, enable_debug=yes)
|
||||||
|
if test x$enable_debug != xyes; then
|
||||||
|
if test x$GCC = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -O3"
|
||||||
|
CFLAGS="$CFLAGS -fexpensive-optimizations"
|
||||||
|
fi
|
||||||
|
CFLAGS="$CFLAGS -DNDEBUG"
|
||||||
|
else
|
||||||
|
if test x$GCC = xyes; then
|
||||||
|
CFLAGS="$CFLAGS -g -pedantic -Wall"
|
||||||
|
fi
|
||||||
|
CFLAGS="$CFLAGS -DDEBUG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
doc/doxygen.conf
|
||||||
|
version.h
|
||||||
|
libburn-1.pc
|
||||||
|
])
|
||||||
|
AC_OUTPUT
|
4
libburn/tags/ZeroThreeZero/doc/Makefile
Normal file
4
libburn/tags/ZeroThreeZero/doc/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
all clean:
|
||||||
|
$(MAKE) -C .. -$(MAKEFLAGS) $@
|
||||||
|
|
||||||
|
.PHONY: all clean
|
136
libburn/tags/ZeroThreeZero/doc/comments
Normal file
136
libburn/tags/ZeroThreeZero/doc/comments
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
@author Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
@mainpage Libburnia Documentation Index
|
||||||
|
|
||||||
|
@section intro Introduction
|
||||||
|
|
||||||
|
Libburnia is an open-source project for reading, mastering and writing
|
||||||
|
optical discs. For now this means only CD-R and CD-RW.
|
||||||
|
Support for DVD+RW and DVD-RW is emerging.
|
||||||
|
|
||||||
|
|
||||||
|
The project comprises of several more or less interdependent parts which
|
||||||
|
together strive to be a usable foundation for application development.
|
||||||
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
|
classical (and valuable) Linux tools.
|
||||||
|
|
||||||
|
Our scope is currently Linux 2.4 and 2.6 only. For 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 of Linux sg or FreeBSD CAM,
|
||||||
|
volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
|
We have a workable code base for burning data and audio CDs. The burn API is
|
||||||
|
quite comprehensively documented and can be used to build a presentable
|
||||||
|
application.
|
||||||
|
We have a functional binary which emulates the core use cases of cdrecord in
|
||||||
|
order to prove that usability, and in order to allow you to explore libburn's
|
||||||
|
scope by help of existing cdrecord frontends.
|
||||||
|
|
||||||
|
@subsection components The project components (list subject to growth, hopefully):
|
||||||
|
|
||||||
|
- libburn is the library by which preformatted data get onto optical media.
|
||||||
|
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
||||||
|
/dev/hdX (e.g. on kernel 2.6).
|
||||||
|
libburn is the foundation of our cdrecord emulation.
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
||||||
|
|
||||||
|
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
|
cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||||
|
Schilling's cdrtools. cdrskin strives to be a second source for
|
||||||
|
the services traditionally provided by cdrecord.
|
||||||
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
Many bytes have been copied from the message output of cdrecord
|
||||||
|
runs, though.
|
||||||
|
See cdrskin/README for more.
|
||||||
|
|
||||||
|
- "test" is a collection of application gestures and examples given by the
|
||||||
|
authors of the library features. The main API example of libburn
|
||||||
|
is named test/libburner.c .
|
||||||
|
Explore these examples if you look for inspiration.
|
||||||
|
|
||||||
|
We plan to be a responsive upstream. Bear with us.
|
||||||
|
|
||||||
|
|
||||||
|
@section using Using the libraries
|
||||||
|
|
||||||
|
Our build system is based on autotools.
|
||||||
|
User experience tells us that you will need at least autotools version 1.7.
|
||||||
|
|
||||||
|
To build libburn and its subprojects it should be sufficient to go into
|
||||||
|
its toplevel directory and execute
|
||||||
|
|
||||||
|
- ./bootstrap (needed if you downloaded from SVN)
|
||||||
|
|
||||||
|
- ./configure
|
||||||
|
|
||||||
|
- make
|
||||||
|
|
||||||
|
To make the libraries accessible for running resp. developing applications
|
||||||
|
|
||||||
|
- make install
|
||||||
|
|
||||||
|
Both libraries are written in C language and get built by autotools.
|
||||||
|
Thus we expect them to be useable by a wide range of Linux-implemented
|
||||||
|
languages and development tools.
|
||||||
|
|
||||||
|
|
||||||
|
@section libburner Libburner
|
||||||
|
|
||||||
|
libburner is a minimal demo application for the library libburn
|
||||||
|
(see: libburn/libburn.h) as provided on http://libburn.pykix.org .
|
||||||
|
It can list the available devices, can blank a CD-RW and
|
||||||
|
can burn to CD-R or CD-RW.
|
||||||
|
New: burning to DVD+/-RW (single data track, single session only).
|
||||||
|
|
||||||
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
|
to serve the libburnia team as reference application. libburner does indeed
|
||||||
|
define the standard way how above three gestures can be implemented and
|
||||||
|
stay upward compatible for a good while.
|
||||||
|
|
||||||
|
@subsection libburner-help Libburner --help
|
||||||
|
<pre>
|
||||||
|
Usage: test/libburner
|
||||||
|
[--drive <address>|<driveno>|"-"] [--audio]
|
||||||
|
[--blank_fast|--blank_full] [--try_to_simulate]
|
||||||
|
[--multi] [one or more imagefiles|"-"]
|
||||||
|
Examples
|
||||||
|
A bus scan (needs rw-permissions to see a drive):
|
||||||
|
test/libburner --drive -
|
||||||
|
Burn a file to drive chosen by number, leave appendable:
|
||||||
|
test/libburner --drive 0 --multi my_image_file
|
||||||
|
Burn a file to drive chosen by persistent address, close:
|
||||||
|
test/libburner --drive /dev/hdc my_image_file
|
||||||
|
Blank a used CD-RW (is combinable with burning in one run):
|
||||||
|
test/libburner --drive /dev/hdc --blank_fast
|
||||||
|
Burn two audio tracks
|
||||||
|
lame --decode -t /path/to/track1.mp3 track1.cd
|
||||||
|
test/dewav /path/to/track2.wav -o track2.cd
|
||||||
|
test/libburner --drive /dev/hdc --audio track1.cd track2.cd
|
||||||
|
Burn a compressed afio archive on-the-fly:
|
||||||
|
( cd my_directory ; find . -print | afio -oZ - ) | \
|
||||||
|
test/libburner --drive /dev/hdc -
|
||||||
|
To be read from *not mounted* CD via: afio -tvZ /dev/hdc
|
||||||
|
Program tar would need a clean EOF which our padded CD cannot deliver.
|
||||||
|
</pre>
|
||||||
|
libburner has two companions, telltoc and dewav, which help to perform some
|
||||||
|
peripheral tasks of burning.
|
||||||
|
|
||||||
|
telltoc prints a table of content (sessions, tracks and leadouts), it tells
|
||||||
|
about type and state of CD media, and also is able to provide the necessary
|
||||||
|
multi-session information for program mkisofs option -C.
|
||||||
|
See: test/telltoc --help.
|
||||||
|
|
||||||
|
dewav extracts raw byte-swapped audio data from files of format .wav (MS WAVE)
|
||||||
|
or .au (SUN Audio). See example in libburner --help.
|
||||||
|
|
||||||
|
@subsection libburner-source Sourceode of libburner
|
||||||
|
|
||||||
|
Click on blue names of functions, structures, variables, etc in oder to
|
||||||
|
get to the according specs of libburn API or libburner sourcecode.
|
||||||
|
|
||||||
|
@include libburner.c
|
||||||
|
*/
|
186
libburn/tags/ZeroThreeZero/doc/doxygen.conf.in
Normal file
186
libburn/tags/ZeroThreeZero/doc/doxygen.conf.in
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
# Doxyfile 1.2.18
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# General configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
PROJECT_NAME = @PACKAGE_NAME@
|
||||||
|
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||||
|
OUTPUT_DIRECTORY =
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
EXTRACT_ALL = YES
|
||||||
|
EXTRACT_PRIVATE = YES
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
FULL_PATH_NAMES = YES
|
||||||
|
STRIP_FROM_PATH = @top_srcdir@
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
STRIP_CODE_COMMENTS = NO
|
||||||
|
CASE_SENSE_NAMES = NO
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
VERBATIM_HEADERS = YES
|
||||||
|
SHOW_INCLUDE_FILES = YES
|
||||||
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
MULTILINE_CPP_IS_BRIEF = YES
|
||||||
|
DETAILS_AT_TOP = YES
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
INLINE_INFO = YES
|
||||||
|
SORT_MEMBER_DOCS = YES
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
TAB_SIZE = 4
|
||||||
|
GENERATE_TODOLIST = YES
|
||||||
|
GENERATE_TESTLIST = YES
|
||||||
|
GENERATE_BUGLIST = YES
|
||||||
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
ALIASES =
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
SHOW_USED_FILES = YES
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to warning and progress messages
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
QUIET = YES
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE =
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the input files
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
INPUT = libburn doc test
|
||||||
|
FILE_PATTERNS = libburn.h comments libburner.c
|
||||||
|
RECURSIVE = NO
|
||||||
|
EXCLUDE =
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
EXAMPLE_PATH = test
|
||||||
|
EXAMPLE_PATTERNS =
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
IMAGE_PATH =
|
||||||
|
INPUT_FILTER =
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to source browsing
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
INLINE_SOURCES = YES
|
||||||
|
REFERENCED_BY_RELATION = YES
|
||||||
|
REFERENCES_RELATION = YES
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the alphabetical class index
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ALPHABETICAL_INDEX = NO
|
||||||
|
COLS_IN_ALPHA_INDEX = 5
|
||||||
|
IGNORE_PREFIX = OB OTK _
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the HTML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
HTML_OUTPUT = doc/html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_HEADER =
|
||||||
|
HTML_FOOTER =
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
HTML_ALIGN_MEMBERS = YES
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
CHM_FILE =
|
||||||
|
HHC_LOCATION =
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
BINARY_TOC = NO
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
GENERATE_TREEVIEW = NO
|
||||||
|
TREEVIEW_WIDTH = 200
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the LaTeX output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
LATEX_CMD_NAME = latex
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
PAPER_TYPE = letter
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
LATEX_HEADER =
|
||||||
|
PDF_HYPERLINKS = YES
|
||||||
|
USE_PDFLATEX = NO
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the RTF output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the man page output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_LINKS = NO
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options related to the XML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_XML = NO
|
||||||
|
XML_SCHEMA =
|
||||||
|
XML_DTD =
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# configuration options for the AutoGen Definitions output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the preprocessor
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = NO
|
||||||
|
EXPAND_ONLY_PREDEF = NO
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
INCLUDE_PATH =
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
PREDEFINED = DOXYGEN
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration::addtions related to external references
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
TAGFILES =
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
PERL_PATH = /usr/bin/perl
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the dot tool
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
CLASS_DIAGRAMS = YES
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
HAVE_DOT = YES
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
COLLABORATION_GRAPH = YES
|
||||||
|
TEMPLATE_RELATIONS = YES
|
||||||
|
INCLUDE_GRAPH = YES
|
||||||
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
GRAPHICAL_HIERARCHY = NO
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
DOT_PATH =
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
MAX_DOT_GRAPH_WIDTH = 1024
|
||||||
|
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
DOT_CLEANUP = YES
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration::addtions related to the search engine
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
SEARCHENGINE = NO
|
12
libburn/tags/ZeroThreeZero/libburn-1.pc.in
Normal file
12
libburn/tags/ZeroThreeZero/libburn-1.pc.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libburn
|
||||||
|
Description: Disc reading/writing library
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires:
|
||||||
|
Libs: -L${libdir} -lburn
|
||||||
|
Libs.private: @THREAD_LIBS@ @LIBBURN_ARCH_LIBS@
|
||||||
|
Cflags: -I${includedir}/libburn
|
4
libburn/tags/ZeroThreeZero/libburn/Makefile
Normal file
4
libburn/tags/ZeroThreeZero/libburn/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
all clean:
|
||||||
|
$(MAKE) -C .. -$(MAKEFLAGS) $@
|
||||||
|
|
||||||
|
.PHONY: all clean
|
65
libburn/tags/ZeroThreeZero/libburn/Makefile.am
Normal file
65
libburn/tags/ZeroThreeZero/libburn/Makefile.am
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
pkgconfigdir=$(libdir)/pkgconfig
|
||||||
|
libincludedir=$(includedir)/libburn
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libburn.la
|
||||||
|
|
||||||
|
libburn_la_SOURCES = \
|
||||||
|
async.c \
|
||||||
|
async.h \
|
||||||
|
crc.c \
|
||||||
|
crc.h \
|
||||||
|
debug.c \
|
||||||
|
debug.h \
|
||||||
|
drive.c \
|
||||||
|
drive.h \
|
||||||
|
file.c \
|
||||||
|
file.h \
|
||||||
|
init.c \
|
||||||
|
init.h \
|
||||||
|
lec.c \
|
||||||
|
lec.h \
|
||||||
|
message.c \
|
||||||
|
message.h \
|
||||||
|
mmc.c \
|
||||||
|
mmc.h \
|
||||||
|
null.c \
|
||||||
|
null.h \
|
||||||
|
options.c \
|
||||||
|
options.h \
|
||||||
|
read.c \
|
||||||
|
read.h \
|
||||||
|
sbc.c \
|
||||||
|
sbc.h \
|
||||||
|
sector.c \
|
||||||
|
sector.h \
|
||||||
|
sg.c \
|
||||||
|
sg.h \
|
||||||
|
spc.c \
|
||||||
|
spc.h \
|
||||||
|
source.h \
|
||||||
|
source.c \
|
||||||
|
structure.c \
|
||||||
|
structure.h \
|
||||||
|
toc.c \
|
||||||
|
toc.h \
|
||||||
|
transport.h \
|
||||||
|
util.c \
|
||||||
|
util.h \
|
||||||
|
write.c \
|
||||||
|
write.h
|
||||||
|
|
||||||
|
libinclude_HEADERS = libburn.h
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
||||||
|
indent_files = $(libburn_la_SOURCES)
|
||||||
|
|
||||||
|
indent: $(indent_files)
|
||||||
|
indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \
|
||||||
|
-cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \
|
||||||
|
-lp -saf -sai -nprs -npsl -saw -sob -ss -ut \
|
||||||
|
-sbi0 -nsc -ts8 -npcs -ncdb -fca \
|
||||||
|
$^
|
||||||
|
|
||||||
|
.PHONY: indent
|
||||||
|
|
||||||
|
## ========================================================================= ##
|
792
libburn/tags/ZeroThreeZero/libburn/asserts.txt
Normal file
792
libburn/tags/ZeroThreeZero/libburn/asserts.txt
Normal file
@ -0,0 +1,792 @@
|
|||||||
|
List of assert() calls in libburn. 6 Oct 2006.
|
||||||
|
|
||||||
|
Format:
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Number) grep'ed line
|
||||||
|
(++ before number means: is fully done, + means is done so far )
|
||||||
|
function():
|
||||||
|
Description of abort condition.
|
||||||
|
|
||||||
|
Possible callers and their relation to the abort condition.
|
||||||
|
|
||||||
|
: Error Evaluation
|
||||||
|
=> Consequences
|
||||||
|
|
||||||
|
Eventual implementation timestamp
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 1) libburn/async.c: assert(a != NULL); /* wasn't found.. this should not be possible */
|
||||||
|
static remove_worker():
|
||||||
|
A thread describing structure (struct w_list) could not be found in
|
||||||
|
order to be released.
|
||||||
|
|
||||||
|
Called by API burn_drive_scan()
|
||||||
|
Called by static erase_worker_func() , thread under API burn_disc_erase()
|
||||||
|
Called by static write_disc_worker_func(), thread under API burn_disc_write()
|
||||||
|
All three want to clean up after they are done.
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> issue LIBDAX_MSGS_SEV_WARNING
|
||||||
|
|
||||||
|
ts A61006
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 2) libburn/async.c: assert(!(workers && workers->drive));
|
||||||
|
API burn_drive_scan():
|
||||||
|
Before spawning a thread, the function refuses work because another
|
||||||
|
drive activity is going on.
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
|
||||||
|
ts A61006
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
+ 3) libburn/async.c: assert(workers == NULL);
|
||||||
|
API burn_drive_scan():
|
||||||
|
After thread is done and remover_worker() succeeded, there is still a
|
||||||
|
worker registered. Shall probably detect roguely appeared burn or
|
||||||
|
erase runs. (I consider to install a mutex shielded function for that.)
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> Same as 1)
|
||||||
|
|
||||||
|
ts A61006
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 4) libburn/async.c: assert(drive);
|
||||||
|
libburn/async.c: assert(!SCAN_GOING());
|
||||||
|
libburn/async.c: assert(!find_worker(drive));
|
||||||
|
API burn_disc_erase():
|
||||||
|
Wants to see a drive (assumes NULL == 0), wants to see no scan and
|
||||||
|
wants to see no other worker on that drive. I.e. this would tolerate
|
||||||
|
a parallel activity on another drive.
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> (no return value), issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
|
||||||
|
ts A61006
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 5) libburn/async.c: assert(!SCAN_GOING());
|
||||||
|
libburn/async.c: assert(!find_worker(opts->drive));
|
||||||
|
API burn_disc_write():
|
||||||
|
Same as 4)
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> Same as 4)
|
||||||
|
|
||||||
|
ts A61006
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 6) libburn/drive.c: assert(d->busy == BURN_DRIVE_IDLE);
|
||||||
|
API burn_drive_release():
|
||||||
|
A drive is not idle on release.
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> Same as 4)
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 7) libburn/drive.c: assert(d->released);
|
||||||
|
burn_wait_all()
|
||||||
|
A drive is found grabbed.
|
||||||
|
|
||||||
|
Called by burn_drive_scan_sync(), thread under API burn_drive_scan()
|
||||||
|
Called by API burn_finish
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> rename and redefine burn_wait_all() : now burn_drives_are_clear()
|
||||||
|
=> change all use of burn_wait_all()
|
||||||
|
=> Move tests up to burn_drive_scan()
|
||||||
|
=> There: return -1; issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 8) libburn/drive.c: assert(!d->released);
|
||||||
|
API burn_disc_get_status()
|
||||||
|
Attempt to read status of non-grabbed drive.
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> extend enum burn_disc_status by BURN_DISC_UNGRABBED
|
||||||
|
=> return BURN_DISC_UNGRABBED, issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 9) libburn/drive.c: assert( /* (write_type >= BURN_WRITE_PACKET) && */
|
||||||
|
burn_drive_get_block_types():
|
||||||
|
Will not work on BURN_WRITE below BURN_WRITE_RAW.
|
||||||
|
|
||||||
|
Called by -nobody- ?
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> inactivate unused function
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 10) libburn/drive.c: assert(d->idata);
|
||||||
|
libburn/drive.c: assert(d->mdata);
|
||||||
|
static drive_getcaps():
|
||||||
|
sg.c:enumerate_common() did not succeed in creating a proper struct burn_drive
|
||||||
|
Called by burn_drive_scan_sync()
|
||||||
|
|
||||||
|
: Severe System Error
|
||||||
|
=> This could possibly really stay an abort() because the reason is
|
||||||
|
a plain failure of the system's memory management.
|
||||||
|
=> Detect this failure already in enumerate_common(),
|
||||||
|
issue LIBDAX_MSGS_SEV_FATAL, return
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 11) libburn/drive.c: assert(burn_running);
|
||||||
|
burn_drive_scan_sync():
|
||||||
|
The library was not initialized.
|
||||||
|
|
||||||
|
Called as thread by API burn_drive_scan()
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> Move this test up to burn_drive_scan()
|
||||||
|
=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_FATAL
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 12) libburn/drive.c: assert(d->released == 1);
|
||||||
|
burn_drive_scan_sync():
|
||||||
|
Inactivated
|
||||||
|
|
||||||
|
: (Severe Application Error)
|
||||||
|
=> throw out inactivated code
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 13) libburn/drive.c: assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN);
|
||||||
|
burn_drive_raw_get_adr():
|
||||||
|
An enumerated device address is longer than the API's maximum length
|
||||||
|
|
||||||
|
Called by API burn_drive_get_adr()
|
||||||
|
Called by API burn_drive_obtain_scsi_adr()
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> return -1; in all three functions, enhance burn_drive_get_adr @return docs
|
||||||
|
=> issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 14) libburn/drive.c: assert(drive_info->drive!=NULL);
|
||||||
|
API burn_drive_get_adr():
|
||||||
|
Drive info has no drive attached.
|
||||||
|
|
||||||
|
: Severe Libburn Error (unlikely, will eventually SIGSEGV on NULL)
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 15) libburn/init.c: assert(burn_running);
|
||||||
|
API burn_finish():
|
||||||
|
The library is not initialized
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> return (assume no msg system)
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 16) libburn/init.c: assert(burn_running);
|
||||||
|
API burn_preset_device_open():
|
||||||
|
The library is not initialized
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> return (assume no msg system)
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 17) libburn/mmc.c: assert(o->drive == d);
|
||||||
|
mmc_close_disc():
|
||||||
|
alias: struct burn_drive.close_disc()
|
||||||
|
Parameters struct burn_drive and struct burn_write_opts do not match
|
||||||
|
|
||||||
|
Called by -nobody- ?
|
||||||
|
|
||||||
|
( => Disable unused function ? )
|
||||||
|
=> removed redundant parameter struct burn_drive
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 18) libburn/mmc.c: assert(o->drive == d);
|
||||||
|
mmc_close_session():
|
||||||
|
Same as 17)
|
||||||
|
alias: struct burn_drive.close_session()
|
||||||
|
|
||||||
|
Called by -nobody- ?
|
||||||
|
|
||||||
|
( => Disable unused function ? )
|
||||||
|
=> removed redundant parameter struct burn_drive
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 19) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */
|
||||||
|
mmc_write_12():
|
||||||
|
- Unclear what .bytes and .sectors mean in struct buffer -
|
||||||
|
|
||||||
|
Called by -nobody- ?
|
||||||
|
|
||||||
|
=> problems with filling the write buffer have to be handled by callers
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 20) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */
|
||||||
|
mmc_write():
|
||||||
|
- Unclear what .bytes and .sectors mean in struct buffer -
|
||||||
|
|
||||||
|
libburn/mmc.c: c.page->sectors = errorblock - start + 1;
|
||||||
|
mmc_read_sectors() by toc_find_modes() by mmc_read_toc() alias drive.read_toc()
|
||||||
|
by burn_drive_grab()
|
||||||
|
This seems to be unrelated to mmc_write().
|
||||||
|
|
||||||
|
libburn/sector.c: out->sectors++;
|
||||||
|
get_sector()
|
||||||
|
Seems to hand out sector start pointer in opts->drive->buffer
|
||||||
|
and to count reservation transactions as well as reserved bytes.
|
||||||
|
Ensures out->bytes >= out->sectors
|
||||||
|
|
||||||
|
|
||||||
|
libburn/mmc.c: c.page->bytes = s->count * 8;
|
||||||
|
mmc_send_cue_sheet()
|
||||||
|
Does not use mmc_write() but directly (sg_)issue_command()
|
||||||
|
|
||||||
|
libburn/sector.c: out->bytes += seclen;
|
||||||
|
get_sector()
|
||||||
|
See above
|
||||||
|
Ensures out->bytes >= out->sectors
|
||||||
|
|
||||||
|
libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->retry_page_length;
|
||||||
|
spc_select_error_params()
|
||||||
|
Does not use mmc_write() but directly (sg_)issue_command()
|
||||||
|
|
||||||
|
libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->write_page_length;
|
||||||
|
spc_select_error_params()
|
||||||
|
Does not use mmc_write() but directly (sg_)issue_command()
|
||||||
|
|
||||||
|
libburn/spc.c: c.page->bytes = 8 + 2 + 0x32;
|
||||||
|
spc_probe_write_modes()
|
||||||
|
Does not use mmc_write() but directly (sg_)issue_command()
|
||||||
|
|
||||||
|
alias struct burn_drive.write()
|
||||||
|
Called by static get_sector, by many
|
||||||
|
Called by burn_write_flush
|
||||||
|
Called by burn_write_track
|
||||||
|
|
||||||
|
=> problems with filling the write buffer have to be handled by callers
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 21) libburn/mmc.c: assert(((dlen - 2) % 11) == 0);
|
||||||
|
mmc_read_toc():
|
||||||
|
- Is defunct -
|
||||||
|
|
||||||
|
=> :)
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 22) libburn/mmc.c: assert(len >= 0);
|
||||||
|
mmc_read_sectors():
|
||||||
|
Catches a bad parameter
|
||||||
|
|
||||||
|
alias: struct burn_drive.read_sectors()
|
||||||
|
Called by API burn_disc_read() , - is defunct -, one could catch the problem
|
||||||
|
Called by toc_find_modes(), problem cannot occur: mem.sectors = 1;
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
(=> in burn_disc_read() check page.sectors before d->read_sectors() )
|
||||||
|
=> :)
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 23) libburn/mmc.c: assert(d->busy);
|
||||||
|
mmc_read_sectors():
|
||||||
|
Catches use of a drive that is not marked as busy
|
||||||
|
|
||||||
|
alias: struct burn_drive.read_sectors()
|
||||||
|
Called by API burn_disc_read() , - is defunct -, busy = BURN_DRIVE_READING;
|
||||||
|
Called by toc_find_modes(), does the same assert. To be solved there.
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> :)
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 24) libburn/options.c: assert(0);
|
||||||
|
API burn_write_opts_set_write_type():
|
||||||
|
Detects unsuitable enum burn_write_types write_type and int block_type.
|
||||||
|
API promises return 0 on failure
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> issue LIBDAX_MSGS_SEV_SORRY
|
||||||
|
=> should also detect problem of 26) : wrong write_type,block_type combination
|
||||||
|
by calling sector_get_outmode() and checking for -1
|
||||||
|
=> should also detect problem of 41) : unknown block_type
|
||||||
|
by spc_block_type() and checking for -1
|
||||||
|
=> delete assert(0)
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 25) libburn/read.c: assert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000));
|
||||||
|
libburn/read.c: assert(!d->busy);
|
||||||
|
libburn/read.c: assert(d->toc->valid);
|
||||||
|
libburn/read.c: assert(o->datafd != -1);
|
||||||
|
API burn_disc_read():
|
||||||
|
- ? -
|
||||||
|
|
||||||
|
burn_disc_read() is defunct
|
||||||
|
OPTIONS_VERSION does not occur outside this line
|
||||||
|
|
||||||
|
( => one would return )
|
||||||
|
( 22) => catch page.sectors<0 before d->read_sectors() )
|
||||||
|
( 37) => catch ! d->mdata->valid )
|
||||||
|
=> :)
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 26) libburn/sector.c: assert(0); /* return BURN_MODE_UNIMPLEMENTED :) */
|
||||||
|
static get_outmode():
|
||||||
|
burn_write_opts is wrongly programmed with .write_type and .block_type
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> This gets handled by burn_write_opts_set_write_type()
|
||||||
|
ts A61007 by new semi-public sector_get_outmode()
|
||||||
|
=> delete assert()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 27) libburn/sector.c: assert(outlen >= inlen);
|
||||||
|
libburn/sector.c: assert(outmode & BURN_MODE_RAW);
|
||||||
|
libburn/sector.c: assert(offset != -1);
|
||||||
|
static convert_data():
|
||||||
|
Several unacceptable settings within struct burn_write_opts
|
||||||
|
|
||||||
|
Called by sector_toc() sector_pregap() sector_postgap() sector_lout()
|
||||||
|
sector_data()
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> change return type of convert_data()
|
||||||
|
=> all callers interpret return value and eventually return failure
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 28) libburn/sector.c: assert(0);
|
||||||
|
static char_to_isrc():
|
||||||
|
Called by subcode_user() with data set by API burn_track_set_isrc()
|
||||||
|
Some character conversion fails on wrong input
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> burn_track_set_isrc() has to make sure that only good data are set
|
||||||
|
=> char_to_isrc() returns 0 as default
|
||||||
|
=> delete assert()
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 29) libburn/sector.c: assert(qmode == 1 || qmode == 2 || qmode == 3);
|
||||||
|
subcode_user():
|
||||||
|
- can not happen -
|
||||||
|
|
||||||
|
: Unknown reason of assert()
|
||||||
|
=> remove assert()
|
||||||
|
|
||||||
|
ts A61010
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 30) libburn/sector.c: assert(modebyte == 1);
|
||||||
|
sector_headers():
|
||||||
|
Does only accept modes BURN_AUDIO, BURN_MODE1 or write_type BURN_WRITE_SAO
|
||||||
|
|
||||||
|
Called by sector_toc() sector_pregap() sector_postgap() sector_lout()
|
||||||
|
sector_data()
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> new functions sector_headers_is_ok(), burn_disc_write_is_ok()
|
||||||
|
help to catch problem in API burn_disc_write()
|
||||||
|
=> issue LIBDAX_MSGS_SEV_FATAL
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 31) libburn/sector.c: assert(0);
|
||||||
|
process_q()
|
||||||
|
- defunct -
|
||||||
|
|
||||||
|
=> :)
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 32) libburn/sg.c: assert("drive busy" == "non fatal");
|
||||||
|
sg_handle_busy_device():
|
||||||
|
Intentional abort preset by the app
|
||||||
|
|
||||||
|
=> change to abort()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 33) libburn/sg.c: assert(fd != -1337);
|
||||||
|
sg_grab():
|
||||||
|
The drive device file could not be opened
|
||||||
|
|
||||||
|
:Severe External Problem
|
||||||
|
=> obsolete by normal drive open failure handling
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 34) libburn/sg.c: assert(!c->page);
|
||||||
|
sg_issue_command():
|
||||||
|
An SCSI command of direction NO_TRANSFER may not have a .page != NULL.
|
||||||
|
|
||||||
|
Since it is about exposing a libburn detail towards the sg driver, i believe
|
||||||
|
it is sufficient to just not use it.
|
||||||
|
|
||||||
|
: Libburn Error
|
||||||
|
=> enhance internal logics of sg_issue_command()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 35) libburn/sg.c: assert(c->page->bytes > 0);
|
||||||
|
sg_issue_command():
|
||||||
|
An SCSI command of direction TO_DRIVE wants to transfer 0 bytes.
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> set command.error = 1 and return 0
|
||||||
|
|
||||||
|
ts A61010
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 36) libburn/sg.c: assert(err != -1);
|
||||||
|
sg_issue_command():
|
||||||
|
The transfer of the command via ioctl() failed
|
||||||
|
|
||||||
|
: Severe Transport Level Problem
|
||||||
|
=> close drive fd, set idle and released
|
||||||
|
=> set command.error = 1 and return -1
|
||||||
|
|
||||||
|
ts A61010
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 37) libburn/spc.c: assert(d->mdata->valid);
|
||||||
|
spc_select_error_params():
|
||||||
|
Drive was not properly programmed
|
||||||
|
|
||||||
|
alias struct burn_drive.send_parameters()
|
||||||
|
Called by burn_disc_read, - defunct -
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> moved up as mangled assert to burn_disc_read()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 38) libburn/spc.c: assert(d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||||
|
spc_sense_write_params():
|
||||||
|
Drive does not offer write of any known media type
|
||||||
|
|
||||||
|
alias struct burn_drive.read_disc_info()
|
||||||
|
Called by API burn_drive_grab (assert test made there in soft)
|
||||||
|
|
||||||
|
: Severe Command Level Problem
|
||||||
|
=> remove assert()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 39) libburn/spc.c: assert(o->drive == d);
|
||||||
|
spc_select_write_params():
|
||||||
|
Drive does not match struct burn_write_opts
|
||||||
|
|
||||||
|
alias struct burn_drive.send_write_parameters()
|
||||||
|
Called by mmc_close_disc() (-defunct- ?), mmc_close_session() (-defunct- ?),
|
||||||
|
burn_write_track() (d = o->drive;),
|
||||||
|
burn_disc_write_sync() d = (o->drive;)
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> remove assert()
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 40) libburn/spc.c: assert(d->mdata->valid);
|
||||||
|
spc_select_write_params():
|
||||||
|
Drive was not properly programmed
|
||||||
|
|
||||||
|
Called by (see 39)
|
||||||
|
burn_write_track() by burn_write_session() by burn_disc_write_sync()
|
||||||
|
burn_disc_write_sync() indirectly by API burn_disc_write()
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> caught in burn_disc_write() now
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 41) libburn/spc.c: assert(0);
|
||||||
|
spc_block_type():
|
||||||
|
Unknown value with enum burn_block_types
|
||||||
|
|
||||||
|
Called by spc_select_write_params, uses burn_write_opts.block_type,
|
||||||
|
set by API burn_write_opts_set_write_type()
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> catch in API burn_write_opts_set_write_type
|
||||||
|
by calling spc_block_type()
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61007
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 42) libburn/structure.c: assert(!(pos > BURN_POS_END));\
|
||||||
|
macro RESIZE
|
||||||
|
An illegal list index is given by the app.
|
||||||
|
|
||||||
|
( TO->NEW##s obviusly means to append "s" to cpp result of TO->NEW )
|
||||||
|
Used by API burn_session_add_track() and API burn_disc_add_session()
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> replace assert by if-and-return-0
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 43) libburn/structure.c: assert(s->track != NULL);
|
||||||
|
API burn_session_remove_track()
|
||||||
|
An application supplied pointer is NULL
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> replace by if-and-return-0
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 44) libburn/structure.c: assert((country[i] >= '0' || country[i] < '9') &&
|
||||||
|
libburn/structure.c: assert((owner[i] >= '0' || owner[i] < '9') &&
|
||||||
|
libburn/structure.c: assert(year <= 99);
|
||||||
|
libburn/structure.c: assert(serial <= 99999);
|
||||||
|
API burn_track_set_isrc():
|
||||||
|
Illegal texts supplied by application.
|
||||||
|
The logical expression is always true !
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> issue LIBDAX_MSGS_SEV_SORRY and return
|
||||||
|
=> delete assert
|
||||||
|
=> delete assert 28) in char_to_isrc()
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 45) libburn/toc.c: assert(0); /* unhandled! find out ccd's
|
||||||
|
static write_clonecd2():
|
||||||
|
|
||||||
|
- defunct -, - unused -
|
||||||
|
|
||||||
|
=> mangle assert
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 46) libburn/toc.c: assert(d->busy);
|
||||||
|
toc_find_modes():
|
||||||
|
The drive to work on is not marked busy
|
||||||
|
|
||||||
|
Called by mmc_read_toc() alias read_toc() by ... burn_drive_grab()
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> to be prevented on the higher levels
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 47) libburn/util.c: assert(s);
|
||||||
|
burn_strdup()
|
||||||
|
Abort on NULL string which would elsewise cause a SIGSEGV
|
||||||
|
|
||||||
|
Used once in enumerate_common() with a string that worked with open(2) before
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 48) libburn/util.c: assert(s);
|
||||||
|
burn_strndup(): - unused -
|
||||||
|
Same as 47
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> return NULL
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 49) libburn/util.c: assert(n > 0);
|
||||||
|
burn_strndup(): - unused -
|
||||||
|
Prevent problems by negative copy length
|
||||||
|
|
||||||
|
: Severe Libburn Error
|
||||||
|
=> return NULL
|
||||||
|
=> delete assert
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 50) libburn/write.c: assert(0);
|
||||||
|
static type_to_ctrl():
|
||||||
|
Unsuitable mode to be converted into "ctrl"
|
||||||
|
Called by static type_to_form() finally burn_create_toc_entries()
|
||||||
|
|
||||||
|
: Severe Application Error
|
||||||
|
=> to be caught in burn_track_define_data by calling for test type_to_form()
|
||||||
|
=> return -1;
|
||||||
|
|
||||||
|
ts A61008
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 51) libburn/write.c: assert(0);
|
||||||
|
libburn/write.c: assert(0); /* XXX someone's gonna want this sometime */
|
||||||
|
static type_to_form():
|
||||||
|
Does not like BURN_MODE0 or BURN_MODE2 but tolerates unknown modes
|
||||||
|
|
||||||
|
Called by static burn_create_toc_entries() by burn_disc_write_sync()
|
||||||
|
|
||||||
|
: Undocumented Libburn Restriction
|
||||||
|
=> set *form = -1 , *ctladr = 0xff , return
|
||||||
|
=> make function non-static
|
||||||
|
=> call for test in API burn_track_define_data()
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 52) libburn/write.c: assert(ptr);
|
||||||
|
static add_cue():
|
||||||
|
realloc() failed
|
||||||
|
|
||||||
|
Called by burn_create_toc_entries() by burn_disc_write_sync()
|
||||||
|
(burn_create_toc_entries is ignorant towards own potential memory problems)
|
||||||
|
(This could possibly really stay an abort() because the reason is
|
||||||
|
a plain failure of the system's memory management.)
|
||||||
|
|
||||||
|
: Severe System Error
|
||||||
|
=> change return type of add_cue to int
|
||||||
|
=> react on return -1 in burn_create_toc_entries, return NULL on failure
|
||||||
|
=> abort burn_disc_write_sync() on NULL return
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 53) libburn/write.c: assert(d->toc_entry == NULL);
|
||||||
|
burn_create_toc_entries():
|
||||||
|
Multiple usage of struct burn_drive.toc_entry
|
||||||
|
|
||||||
|
Called by burn_disc_write_sync()
|
||||||
|
This will probably trigger an abort with disc->sessions > 1
|
||||||
|
(disc->sessions is incremented in macro RESIZE() as "NEW##s")
|
||||||
|
|
||||||
|
: Design Problem
|
||||||
|
( => ? disallow multiple sessions ? )
|
||||||
|
=> replace assert by soft means and wait what happens
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
++ 54) libburn/write.c: assert(0);
|
||||||
|
burn_sector_length():
|
||||||
|
Only BURN_AUDIO, BURN_MODE_RAW, BURN_MODE1 are allowed
|
||||||
|
|
||||||
|
Called by get_sector(), convert_data(), ...
|
||||||
|
|
||||||
|
=> call burn_sector_length() for test in API burn_track_define_data()
|
||||||
|
=> replace assert by -1
|
||||||
|
|
||||||
|
ts A61009
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
365
libburn/tags/ZeroThreeZero/libburn/async.c
Normal file
365
libburn/tags/ZeroThreeZero/libburn/async.c
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "transport.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "write.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "async.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "back_hacks.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <a ssert.h>
|
||||||
|
*/
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
#define SCAN_GOING() (workers && !workers->drive)
|
||||||
|
|
||||||
|
typedef void *(*WorkerFunc) (void *);
|
||||||
|
|
||||||
|
struct scan_opts
|
||||||
|
{
|
||||||
|
struct burn_drive_info **drives;
|
||||||
|
unsigned int *n_drives;
|
||||||
|
|
||||||
|
int done;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct erase_opts
|
||||||
|
{
|
||||||
|
struct burn_drive *drive;
|
||||||
|
int fast;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ts A61230 */
|
||||||
|
struct format_opts
|
||||||
|
{
|
||||||
|
struct burn_drive *drive;
|
||||||
|
off_t size;
|
||||||
|
int flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct write_opts
|
||||||
|
{
|
||||||
|
struct burn_drive *drive;
|
||||||
|
struct burn_write_opts *opts;
|
||||||
|
struct burn_disc *disc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct w_list
|
||||||
|
{
|
||||||
|
struct burn_drive *drive;
|
||||||
|
pthread_t thread;
|
||||||
|
|
||||||
|
struct w_list *next;
|
||||||
|
|
||||||
|
union w_list_data
|
||||||
|
{
|
||||||
|
struct scan_opts scan;
|
||||||
|
struct erase_opts erase;
|
||||||
|
struct format_opts format;
|
||||||
|
struct write_opts write;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct w_list *workers;
|
||||||
|
|
||||||
|
static struct w_list *find_worker(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct w_list *a;
|
||||||
|
|
||||||
|
for (a = workers; a; a = a->next)
|
||||||
|
if (a->drive == d)
|
||||||
|
return a;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
|
||||||
|
{
|
||||||
|
struct w_list *a;
|
||||||
|
struct w_list *tmp;
|
||||||
|
|
||||||
|
a = malloc(sizeof(struct w_list));
|
||||||
|
a->drive = d;
|
||||||
|
a->u = *(union w_list_data *)data;
|
||||||
|
|
||||||
|
/* insert at front of the list */
|
||||||
|
a->next = workers;
|
||||||
|
tmp = workers;
|
||||||
|
workers = a;
|
||||||
|
|
||||||
|
if (d)
|
||||||
|
d->busy = BURN_DRIVE_SPAWNING;
|
||||||
|
|
||||||
|
if (pthread_create(&a->thread, NULL, f, a)) {
|
||||||
|
free(a);
|
||||||
|
workers = tmp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_worker(pthread_t th)
|
||||||
|
{
|
||||||
|
struct w_list *a, *l = NULL;
|
||||||
|
|
||||||
|
for (a = workers; a; l = a, a = a->next)
|
||||||
|
if (a->thread == th) {
|
||||||
|
if (l)
|
||||||
|
l->next = a->next;
|
||||||
|
else
|
||||||
|
workers = a->next;
|
||||||
|
free(a);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61006 */
|
||||||
|
/* a ssert(a != NULL);/ * wasn't found.. this should not be possible */
|
||||||
|
if (a == NULL)
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020101,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"remove_worker() cannot find given worker item", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *scan_worker_func(struct w_list *w)
|
||||||
|
{
|
||||||
|
burn_drive_scan_sync(w->u.scan.drives, w->u.scan.n_drives);
|
||||||
|
w->u.scan.done = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
|
{
|
||||||
|
struct scan_opts o;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
|
||||||
|
if (!burn_running) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020109,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Library not running (on attempt to scan)", 0, 0);
|
||||||
|
*drives = NULL;
|
||||||
|
*n_drives = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cant be anything working! */
|
||||||
|
|
||||||
|
/* ts A61006 */
|
||||||
|
/* a ssert(!(workers && workers->drive)); */
|
||||||
|
if (workers != NULL && workers->drive != NULL) {
|
||||||
|
drive_is_active:;
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020102,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"A drive operation is still going on (want to scan)",
|
||||||
|
0, 0);
|
||||||
|
*drives = NULL;
|
||||||
|
*n_drives = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workers) {
|
||||||
|
/* start it */
|
||||||
|
|
||||||
|
/* ts A61007 : test moved up from burn_drive_scan_sync()
|
||||||
|
was burn_wait_all() */
|
||||||
|
if (!burn_drives_are_clear())
|
||||||
|
goto drive_is_active;
|
||||||
|
*drives = NULL;
|
||||||
|
*n_drives = 0;
|
||||||
|
|
||||||
|
o.drives = drives;
|
||||||
|
o.n_drives = n_drives;
|
||||||
|
o.done = 0;
|
||||||
|
add_worker(NULL, (WorkerFunc) scan_worker_func, &o);
|
||||||
|
} else if (workers->u.scan.done) {
|
||||||
|
/* its done */
|
||||||
|
ret = workers->u.scan.done;
|
||||||
|
remove_worker(workers->thread);
|
||||||
|
|
||||||
|
/* ts A61006 */
|
||||||
|
/* a ssert(workers == NULL); */
|
||||||
|
if (workers != NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020101,
|
||||||
|
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"After scan a drive operation is still going on",
|
||||||
|
0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* still going */
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *erase_worker_func(struct w_list *w)
|
||||||
|
{
|
||||||
|
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
||||||
|
remove_worker(pthread_self());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
|
{
|
||||||
|
struct erase_opts o;
|
||||||
|
|
||||||
|
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||||
|
drive->cancel = 1;
|
||||||
|
|
||||||
|
/* ts A61006 */
|
||||||
|
/* a ssert(drive); */
|
||||||
|
/* a ssert(!SCAN_GOING()); */
|
||||||
|
/* a ssert(!find_worker(drive)); */
|
||||||
|
if((drive == NULL)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
0x00020104,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"NULL pointer caught in burn_disc_erase", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((SCAN_GOING()) || find_worker(drive)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
0x00020102,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"A drive operation is still going on (want to erase)",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A70103 moved up from burn_disc_erase_sync() */
|
||||||
|
/* ts A60825 : allow on parole to blank appendable CDs */
|
||||||
|
if ( ! (drive->status == BURN_DISC_FULL ||
|
||||||
|
(drive->status == BURN_DISC_APPENDABLE &&
|
||||||
|
! libburn_back_hack_42) ) ) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
0x00020130,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive and media state unsuitable for blanking",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
o.drive = drive;
|
||||||
|
o.fast = fast;
|
||||||
|
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61230 */
|
||||||
|
static void *format_worker_func(struct w_list *w)
|
||||||
|
{
|
||||||
|
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
||||||
|
w->u.format.flag);
|
||||||
|
remove_worker(pthread_self());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61230 */
|
||||||
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
|
{
|
||||||
|
struct format_opts o;
|
||||||
|
int ok = 0;
|
||||||
|
char msg[160];
|
||||||
|
|
||||||
|
if ((SCAN_GOING()) || find_worker(drive)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
0x00020102,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"A drive operation is still going on (want to format)",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (flag & 128) /* application prescribed format type */
|
||||||
|
flag |= 16; /* enforce re-format */
|
||||||
|
|
||||||
|
if (drive->current_profile == 0x14)
|
||||||
|
ok = 1; /* DVD-RW sequential */
|
||||||
|
else if (drive->current_profile == 0x13 && (flag & 16))
|
||||||
|
ok = 1; /* DVD-RW Restricted Overwrite with force bit */
|
||||||
|
else if (drive->current_profile == 0x1a) {
|
||||||
|
ok = 1; /* DVD+RW */
|
||||||
|
size = 0;
|
||||||
|
flag &= ~(2|8); /* no insisting in size 0, no expansion */
|
||||||
|
flag |= 4; /* format up to maximum size */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
sprintf(msg,"Will not format media type %4.4Xh",
|
||||||
|
drive->current_profile);
|
||||||
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
0x00020129,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
drive->cancel = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
o.drive = drive;
|
||||||
|
o.size = size;
|
||||||
|
o.flag = flag;
|
||||||
|
add_worker(drive, (WorkerFunc) format_worker_func, &o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *write_disc_worker_func(struct w_list *w)
|
||||||
|
{
|
||||||
|
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
||||||
|
|
||||||
|
/* the options are refcounted, free out ref count which we added below
|
||||||
|
*/
|
||||||
|
burn_write_opts_free(w->u.write.opts);
|
||||||
|
|
||||||
|
remove_worker(pthread_self());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
|
{
|
||||||
|
struct write_opts o;
|
||||||
|
|
||||||
|
/* ts A61006 */
|
||||||
|
/* a ssert(!SCAN_GOING()); */
|
||||||
|
/* a ssert(!find_worker(opts->drive)); */
|
||||||
|
if ((SCAN_GOING()) || find_worker(opts->drive)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||||
|
0x00020102,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"A drive operation is still going on (want to write)",
|
||||||
|
0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
||||||
|
if (!opts->drive->mdata->valid) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
opts->drive->global_index, 0x00020113,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive capabilities not inquired yet", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* ts A61009 : obsolete Assert in sector_headers() */
|
||||||
|
if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */
|
||||||
|
return;
|
||||||
|
|
||||||
|
o.drive = opts->drive;
|
||||||
|
o.opts = opts;
|
||||||
|
o.disc = disc;
|
||||||
|
|
||||||
|
opts->refcount++;
|
||||||
|
|
||||||
|
add_worker(opts->drive, (WorkerFunc) write_disc_worker_func, &o);
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_async_join_all(void)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
while (workers)
|
||||||
|
pthread_join(workers->thread, &ret);
|
||||||
|
}
|
8
libburn/tags/ZeroThreeZero/libburn/async.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/async.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__ASYNC_H
|
||||||
|
#define BURN__ASYNC_H
|
||||||
|
|
||||||
|
void burn_async_join_all(void);
|
||||||
|
struct burn_write_opts;
|
||||||
|
#endif /* BURN__ASYNC_H */
|
54
libburn/tags/ZeroThreeZero/libburn/back_hacks.h
Normal file
54
libburn/tags/ZeroThreeZero/libburn/back_hacks.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
This file bundles variables which disable changes in libburn which are
|
||||||
|
not yet completely accepted.
|
||||||
|
|
||||||
|
The use of these variables is *strongly discouraged* unless you have sincere
|
||||||
|
reason and are willing to share your gained knowledge with the libburn
|
||||||
|
developers.
|
||||||
|
|
||||||
|
Do *not silently rely* on these variables with your application. Tell us
|
||||||
|
that you needed one or more of them. They are subject to removal as soon
|
||||||
|
as consense has been found about correctness of the change they revoke.
|
||||||
|
|
||||||
|
Value 0 means that the new behavior is enabled. Any other value enables
|
||||||
|
the described old time behavior.
|
||||||
|
|
||||||
|
If you doubt one of the changes here broke your application, then do
|
||||||
|
*in your application*, *not here* :
|
||||||
|
|
||||||
|
- #include "libburn/back_hacks.h" like you include "libburn/libburn.h"
|
||||||
|
|
||||||
|
- Set the libburn_back_hack_* variable of your choice to 1.
|
||||||
|
In your app. Not here.
|
||||||
|
|
||||||
|
- Then start and use libburn as usual. Watch out for results.
|
||||||
|
|
||||||
|
- If you believe to have detected a flaw in our change, come forward
|
||||||
|
and report it to the libburn developers. Thanks in advance. :)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Do not define this macro in your application. Only libburn/init.c is
|
||||||
|
entitled to set it.
|
||||||
|
*/
|
||||||
|
#ifdef BURN_BACK_HACKS_INIT
|
||||||
|
|
||||||
|
|
||||||
|
/** Corresponds to http://libburn.pykix.org/ticket/42
|
||||||
|
Reinstates the old ban not to blank appendable CD-RW. We see no reason
|
||||||
|
for this ban yet. It appears unusual. But maybe it patches a bug.
|
||||||
|
*/
|
||||||
|
int libburn_back_hack_42= 0;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* BURN_BACK_HACKS_INIT */
|
||||||
|
|
||||||
|
/* Note: no application programmer info beyond this point */
|
||||||
|
|
||||||
|
|
||||||
|
extern int libburn_back_hack_42;
|
||||||
|
|
||||||
|
#endif /* ! BURN_BACK_HACKS_INIT */
|
||||||
|
|
||||||
|
|
215
libburn/tags/ZeroThreeZero/libburn/cleanup.c
Normal file
215
libburn/tags/ZeroThreeZero/libburn/cleanup.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
typedef void (*sighandler_t)(int);
|
||||||
|
|
||||||
|
|
||||||
|
#include "cleanup.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Cleanup_has_no_libburn_os_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "../libburn/os.h"
|
||||||
|
|
||||||
|
/* see os.h for name of particular os-*.h where this is defined */
|
||||||
|
static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1};
|
||||||
|
static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"};
|
||||||
|
static int signal_list_count= BURN_OS_SIGNAL_COUNT;
|
||||||
|
static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1};
|
||||||
|
static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
|
||||||
|
|
||||||
|
|
||||||
|
#else /* ! Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
|
||||||
|
|
||||||
|
/* Signals to be caught */
|
||||||
|
static int signal_list[]= {
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
|
||||||
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
|
||||||
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
|
||||||
|
SIGTTOU,
|
||||||
|
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ, -1
|
||||||
|
};
|
||||||
|
static char *signal_name_list[]= {
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
|
||||||
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
|
||||||
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
|
||||||
|
"SIGTTOU",
|
||||||
|
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
|
||||||
|
};
|
||||||
|
static int signal_list_count= 24;
|
||||||
|
|
||||||
|
/* Signals not to be caught */
|
||||||
|
static int non_signal_list[]= {
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
|
||||||
|
};
|
||||||
|
static int non_signal_list_count= 5;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* run time dynamic part */
|
||||||
|
static char cleanup_msg[4096]= {""};
|
||||||
|
static int cleanup_exiting= 0;
|
||||||
|
static int cleanup_has_reported= -1234567890;
|
||||||
|
|
||||||
|
static void *cleanup_app_handle= NULL;
|
||||||
|
static Cleanup_app_handler_T cleanup_app_handler= NULL;
|
||||||
|
static int cleanup_perform_app_handler_first= 0;
|
||||||
|
|
||||||
|
|
||||||
|
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
|
||||||
|
fprintf(stderr,"\n%s\n",cleanup_msg);
|
||||||
|
cleanup_has_reported= signum;
|
||||||
|
}
|
||||||
|
if(cleanup_perform_app_handler_first)
|
||||||
|
if(cleanup_app_handler!=NULL) {
|
||||||
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
|
if(ret==2 || ret==-2)
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
if(cleanup_exiting) {
|
||||||
|
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
||||||
|
getpid(),signum);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
cleanup_exiting= 1;
|
||||||
|
alarm(0);
|
||||||
|
if(!cleanup_perform_app_handler_first)
|
||||||
|
if(cleanup_app_handler!=NULL) {
|
||||||
|
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
|
||||||
|
if(ret==2 || ret==-2)
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
exit(exit_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Cleanup_handler_generic(int signum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
|
||||||
|
for(i= 0; i<signal_list_count; i++)
|
||||||
|
if(signum==signal_list[i]) {
|
||||||
|
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
|
||||||
|
signal_name_list[i],errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Cleanup_handler_exit(1,signum,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||||
|
/*
|
||||||
|
bit0= set to default handlers
|
||||||
|
bit1= set to ignore
|
||||||
|
bit2= set cleanup_perform_app_handler_first
|
||||||
|
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
||||||
|
sighandler_t sig_handler;
|
||||||
|
|
||||||
|
cleanup_msg[0]= 0;
|
||||||
|
cleanup_app_handle= handle;
|
||||||
|
cleanup_app_handler= handler;
|
||||||
|
|
||||||
|
/* <<< make cleanup_exiting thread safe to get rid of this */
|
||||||
|
if(flag&4)
|
||||||
|
cleanup_perform_app_handler_first= 1;
|
||||||
|
|
||||||
|
|
||||||
|
if(flag&1)
|
||||||
|
sig_handler= SIG_DFL;
|
||||||
|
else if(flag&2)
|
||||||
|
sig_handler= SIG_IGN;
|
||||||
|
else
|
||||||
|
sig_handler= Cleanup_handler_generic;
|
||||||
|
/* set all signal numbers between the lowest and highest in the list
|
||||||
|
except those in the non-signal list */
|
||||||
|
for(i= 0; i<signal_list_count; i++) {
|
||||||
|
if(signal_list[i]>max_sig)
|
||||||
|
max_sig= signal_list[i];
|
||||||
|
if(signal_list[i]<min_sig)
|
||||||
|
min_sig= signal_list[i];
|
||||||
|
}
|
||||||
|
for(i= min_sig; i<=max_sig; i++) {
|
||||||
|
for(j= 0; j<non_signal_list_count; j++)
|
||||||
|
if(i==non_signal_list[j])
|
||||||
|
break;
|
||||||
|
if(j>=non_signal_list_count) {
|
||||||
|
if(i==SIGABRT && (flag&8))
|
||||||
|
signal(i,Cleanup_handler_generic);
|
||||||
|
else
|
||||||
|
signal(i,sig_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Cleanup_standalonE
|
||||||
|
|
||||||
|
struct Demo_apP {
|
||||||
|
char *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
|
||||||
|
{
|
||||||
|
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
|
||||||
|
signum,demoapp->msg);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
struct Demo_apP demoapp;
|
||||||
|
|
||||||
|
demoapp.msg= "Good Bye";
|
||||||
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
|
char *cpt= NULL,c;
|
||||||
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
|
c= *cpt;
|
||||||
|
} else {
|
||||||
|
printf("killme: %d\n",getpid());
|
||||||
|
sleep(3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup_set_handlers(NULL,NULL,1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Cleanup_standalonE */
|
34
libburn/tags/ZeroThreeZero/libburn/cleanup.h
Normal file
34
libburn/tags/ZeroThreeZero/libburn/cleanup.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Cleanup_includeD
|
||||||
|
#define Cleanup_includeD 1
|
||||||
|
|
||||||
|
|
||||||
|
/** Layout of an application provided cleanup function using an application
|
||||||
|
provided handle as first argument and the signal number as second
|
||||||
|
argument. The third argument is a flag bit field with no defined bits yet.
|
||||||
|
If the handler returns 2 or -2 then it has delegated exit() to some other
|
||||||
|
instance and the Cleanup handler shall return rather than exit.
|
||||||
|
*/
|
||||||
|
typedef int (*Cleanup_app_handler_T)(void *, int, int);
|
||||||
|
|
||||||
|
|
||||||
|
/** Establish exiting signal handlers on (hopefully) all signals that are
|
||||||
|
not ignored by default or non-catchable.
|
||||||
|
@param handle Opaque object which knows how to cleanup application
|
||||||
|
@param handler Function which uses handle to perform application cleanup
|
||||||
|
@param flag Control Bitfield
|
||||||
|
bit0= reset to default signal handling
|
||||||
|
*/
|
||||||
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! Cleanup_includeD */
|
||||||
|
|
122
libburn/tags/ZeroThreeZero/libburn/crc.c
Normal file
122
libburn/tags/ZeroThreeZero/libburn/crc.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#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] = {
|
||||||
|
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
|
||||||
|
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
|
||||||
|
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
|
||||||
|
0x06C00C00L, 0x96510D01L, 0x97E10E01L, 0x07700F00L,
|
||||||
|
0x99011001L, 0x09901100L, 0x08201200L, 0x98B11301L,
|
||||||
|
0x0B401400L, 0x9BD11501L, 0x9A611601L, 0x0AF01700L,
|
||||||
|
0x0D801800L, 0x9D111901L, 0x9CA11A01L, 0x0C301B00L,
|
||||||
|
0x9FC11C01L, 0x0F501D00L, 0x0EE01E00L, 0x9E711F01L,
|
||||||
|
0x82012001L, 0x12902100L, 0x13202200L, 0x83B12301L,
|
||||||
|
0x10402400L, 0x80D12501L, 0x81612601L, 0x11F02700L,
|
||||||
|
0x16802800L, 0x86112901L, 0x87A12A01L, 0x17302B00L,
|
||||||
|
0x84C12C01L, 0x14502D00L, 0x15E02E00L, 0x85712F01L,
|
||||||
|
0x1B003000L, 0x8B913101L, 0x8A213201L, 0x1AB03300L,
|
||||||
|
0x89413401L, 0x19D03500L, 0x18603600L, 0x88F13701L,
|
||||||
|
0x8F813801L, 0x1F103900L, 0x1EA03A00L, 0x8E313B01L,
|
||||||
|
0x1DC03C00L, 0x8D513D01L, 0x8CE13E01L, 0x1C703F00L,
|
||||||
|
0xB4014001L, 0x24904100L, 0x25204200L, 0xB5B14301L,
|
||||||
|
0x26404400L, 0xB6D14501L, 0xB7614601L, 0x27F04700L,
|
||||||
|
0x20804800L, 0xB0114901L, 0xB1A14A01L, 0x21304B00L,
|
||||||
|
0xB2C14C01L, 0x22504D00L, 0x23E04E00L, 0xB3714F01L,
|
||||||
|
0x2D005000L, 0xBD915101L, 0xBC215201L, 0x2CB05300L,
|
||||||
|
0xBF415401L, 0x2FD05500L, 0x2E605600L, 0xBEF15701L,
|
||||||
|
0xB9815801L, 0x29105900L, 0x28A05A00L, 0xB8315B01L,
|
||||||
|
0x2BC05C00L, 0xBB515D01L, 0xBAE15E01L, 0x2A705F00L,
|
||||||
|
0x36006000L, 0xA6916101L, 0xA7216201L, 0x37B06300L,
|
||||||
|
0xA4416401L, 0x34D06500L, 0x35606600L, 0xA5F16701L,
|
||||||
|
0xA2816801L, 0x32106900L, 0x33A06A00L, 0xA3316B01L,
|
||||||
|
0x30C06C00L, 0xA0516D01L, 0xA1E16E01L, 0x31706F00L,
|
||||||
|
0xAF017001L, 0x3F907100L, 0x3E207200L, 0xAEB17301L,
|
||||||
|
0x3D407400L, 0xADD17501L, 0xAC617601L, 0x3CF07700L,
|
||||||
|
0x3B807800L, 0xAB117901L, 0xAAA17A01L, 0x3A307B00L,
|
||||||
|
0xA9C17C01L, 0x39507D00L, 0x38E07E00L, 0xA8717F01L,
|
||||||
|
0xD8018001L, 0x48908100L, 0x49208200L, 0xD9B18301L,
|
||||||
|
0x4A408400L, 0xDAD18501L, 0xDB618601L, 0x4BF08700L,
|
||||||
|
0x4C808800L, 0xDC118901L, 0xDDA18A01L, 0x4D308B00L,
|
||||||
|
0xDEC18C01L, 0x4E508D00L, 0x4FE08E00L, 0xDF718F01L,
|
||||||
|
0x41009000L, 0xD1919101L, 0xD0219201L, 0x40B09300L,
|
||||||
|
0xD3419401L, 0x43D09500L, 0x42609600L, 0xD2F19701L,
|
||||||
|
0xD5819801L, 0x45109900L, 0x44A09A00L, 0xD4319B01L,
|
||||||
|
0x47C09C00L, 0xD7519D01L, 0xD6E19E01L, 0x46709F00L,
|
||||||
|
0x5A00A000L, 0xCA91A101L, 0xCB21A201L, 0x5BB0A300L,
|
||||||
|
0xC841A401L, 0x58D0A500L, 0x5960A600L, 0xC9F1A701L,
|
||||||
|
0xCE81A801L, 0x5E10A900L, 0x5FA0AA00L, 0xCF31AB01L,
|
||||||
|
0x5CC0AC00L, 0xCC51AD01L, 0xCDE1AE01L, 0x5D70AF00L,
|
||||||
|
0xC301B001L, 0x5390B100L, 0x5220B200L, 0xC2B1B301L,
|
||||||
|
0x5140B400L, 0xC1D1B501L, 0xC061B601L, 0x50F0B700L,
|
||||||
|
0x5780B800L, 0xC711B901L, 0xC6A1BA01L, 0x5630BB00L,
|
||||||
|
0xC5C1BC01L, 0x5550BD00L, 0x54E0BE00L, 0xC471BF01L,
|
||||||
|
0x6C00C000L, 0xFC91C101L, 0xFD21C201L, 0x6DB0C300L,
|
||||||
|
0xFE41C401L, 0x6ED0C500L, 0x6F60C600L, 0xFFF1C701L,
|
||||||
|
0xF881C801L, 0x6810C900L, 0x69A0CA00L, 0xF931CB01L,
|
||||||
|
0x6AC0CC00L, 0xFA51CD01L, 0xFBE1CE01L, 0x6B70CF00L,
|
||||||
|
0xF501D001L, 0x6590D100L, 0x6420D200L, 0xF4B1D301L,
|
||||||
|
0x6740D400L, 0xF7D1D501L, 0xF661D601L, 0x66F0D700L,
|
||||||
|
0x6180D800L, 0xF111D901L, 0xF0A1DA01L, 0x6030DB00L,
|
||||||
|
0xF3C1DC01L, 0x6350DD00L, 0x62E0DE00L, 0xF271DF01L,
|
||||||
|
0xEE01E001L, 0x7E90E100L, 0x7F20E200L, 0xEFB1E301L,
|
||||||
|
0x7C40E400L, 0xECD1E501L, 0xED61E601L, 0x7DF0E700L,
|
||||||
|
0x7A80E800L, 0xEA11E901L, 0xEBA1EA01L, 0x7B30EB00L,
|
||||||
|
0xE8C1EC01L, 0x7850ED00L, 0x79E0EE00L, 0xE971EF01L,
|
||||||
|
0x7700F000L, 0xE791F101L, 0xE621F201L, 0x76B0F300L,
|
||||||
|
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
|
||||||
|
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
|
||||||
|
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
unsigned int crc_32(unsigned char *data, int len)
|
||||||
|
{
|
||||||
|
unsigned int crc = 0;
|
||||||
|
|
||||||
|
while (len-- > 0)
|
||||||
|
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
||||||
|
return crc;
|
||||||
|
}
|
9
libburn/tags/ZeroThreeZero/libburn/crc.h
Normal file
9
libburn/tags/ZeroThreeZero/libburn/crc.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__CRC_H
|
||||||
|
#define BURN__CRC_H
|
||||||
|
|
||||||
|
unsigned short crc_ccitt(unsigned char *, int len);
|
||||||
|
unsigned int crc_32(unsigned char *, int len);
|
||||||
|
|
||||||
|
#endif /* BURN__CRC_H */
|
35
libburn/tags/ZeroThreeZero/libburn/debug.c
Normal file
35
libburn/tags/ZeroThreeZero/libburn/debug.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int burn_verbosity = 0;
|
||||||
|
|
||||||
|
void burn_set_verbosity(int 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
|
||||||
|
}
|
||||||
|
}
|
8
libburn/tags/ZeroThreeZero/libburn/debug.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/debug.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__DEBUG_H
|
||||||
|
#define BURN__DEBUG_H
|
||||||
|
|
||||||
|
void burn_print(int level, const char *a, ...);
|
||||||
|
|
||||||
|
#endif /* BURN__DEBUG_H */
|
1531
libburn/tags/ZeroThreeZero/libburn/drive.c
Normal file
1531
libburn/tags/ZeroThreeZero/libburn/drive.c
Normal file
File diff suppressed because it is too large
Load Diff
98
libburn/tags/ZeroThreeZero/libburn/drive.h
Normal file
98
libburn/tags/ZeroThreeZero/libburn/drive.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __DRIVE
|
||||||
|
#define __DRIVE
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "structure.h"
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
struct command;
|
||||||
|
struct mempage;
|
||||||
|
struct scsi_mode_data;
|
||||||
|
struct burn_speed_descriptor;
|
||||||
|
|
||||||
|
#define LEAD_IN 1
|
||||||
|
#define GAP 2
|
||||||
|
#define USER_DATA 3
|
||||||
|
#define LEAD_OUT 4
|
||||||
|
#define SYNC 5
|
||||||
|
|
||||||
|
#define SESSION_LEADOUT_ENTRY(d,s) (d)->toc->session[(s)].leadout_entry
|
||||||
|
|
||||||
|
#define CURRENT_SESSION_START(d) \
|
||||||
|
burn_msf_to_lba(d->toc->session[d->currsession].start_m, \
|
||||||
|
d->toc->session[d->currsession].start_s, \
|
||||||
|
d->toc->session[d->currsession].start_f)
|
||||||
|
|
||||||
|
#define SESSION_END(d,s) \
|
||||||
|
TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (s)))
|
||||||
|
|
||||||
|
#define PREVIOUS_SESSION_END(d) \
|
||||||
|
TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (d)->currsession-1))
|
||||||
|
|
||||||
|
#define LAST_SESSION_END(d) \
|
||||||
|
TOC_ENTRY_PLBA((d)->toc, \
|
||||||
|
SESSION_LEADOUT_ENTRY((d), (d)->toc->sessions-1))
|
||||||
|
|
||||||
|
struct burn_drive *burn_drive_register(struct burn_drive *);
|
||||||
|
int burn_drive_unregister(struct burn_drive *d);
|
||||||
|
|
||||||
|
unsigned int burn_drive_count(void);
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
/* void burn_wait_all(void); */
|
||||||
|
int burn_drives_are_clear(void);
|
||||||
|
|
||||||
|
int burn_sector_length_write(struct burn_drive *d);
|
||||||
|
int burn_track_control(struct burn_drive *d, int);
|
||||||
|
void burn_write_empty_sector(int fd);
|
||||||
|
void burn_write_empty_subcode(int fd);
|
||||||
|
void burn_drive_free(struct burn_drive *d);
|
||||||
|
void burn_drive_free_all(void);
|
||||||
|
|
||||||
|
int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||||
|
unsigned int *n_drives);
|
||||||
|
void burn_disc_erase_sync(struct burn_drive *d, int fast);
|
||||||
|
int burn_drive_get_block_types(struct burn_drive *d,
|
||||||
|
enum burn_write_types write_type);
|
||||||
|
|
||||||
|
int burn_drive_is_open(struct burn_drive *d);
|
||||||
|
int burn_drive_is_occupied(struct burn_drive *d);
|
||||||
|
int burn_drive_forget(struct burn_drive *d, int force);
|
||||||
|
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
|
||||||
|
|
||||||
|
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int burn_setup_drive(struct burn_drive *d, char *fname);
|
||||||
|
|
||||||
|
/* ts A61021 : after-setup activities from sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61125 : media status aspects of burn_drive_grab() */
|
||||||
|
int burn_drive_inquire_media(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61125 : model aspects of burn_drive_release */
|
||||||
|
int burn_drive_mark_unready(struct burn_drive *d);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61226 */
|
||||||
|
int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
|
||||||
|
struct burn_speed_descriptor *prev,
|
||||||
|
struct burn_speed_descriptor *next, int flag);
|
||||||
|
|
||||||
|
/* ts A61226 */
|
||||||
|
/* @param flag bit0= destroy whole next-chain of descriptors */
|
||||||
|
int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
|
||||||
|
int burn_mdata_free_subs(struct scsi_mode_data *m);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61230 */
|
||||||
|
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
|
||||||
|
|
||||||
|
#endif /* __DRIVE */
|
8
libburn/tags/ZeroThreeZero/libburn/error.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/error.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* -*- indent-tabs-mode; t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __ERROR_H
|
||||||
|
#define __ERROR_H
|
||||||
|
|
||||||
|
#define BE_CANCELLED 1
|
||||||
|
|
||||||
|
#endif /* __ERROR_H */
|
187
libburn/tags/ZeroThreeZero/libburn/file.c
Normal file
187
libburn/tags/ZeroThreeZero/libburn/file.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "source.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
/* main channel data can be padded on read, but 0 padding the subs will make
|
||||||
|
an unreadable disc */
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a generic OS oriented function wrapper which compensates
|
||||||
|
shortcommings of read() in respect to a guaranteed amount of return data.
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int ret,summed_ret = 0;
|
||||||
|
|
||||||
|
/* make safe against partial buffer returns */
|
||||||
|
while (1) {
|
||||||
|
ret = read(fd, buffer + summed_ret, size - summed_ret);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
summed_ret += ret;
|
||||||
|
if (summed_ret >= size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret < 0) /* error encountered. abort immediately */
|
||||||
|
return ret;
|
||||||
|
return summed_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int file_read(struct burn_source *source,
|
||||||
|
unsigned char *buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct burn_source_fd *fs = source->data;
|
||||||
|
|
||||||
|
return read_full_buffer(fs->datafd, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_read_sub(struct burn_source *source,
|
||||||
|
unsigned char *buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct burn_source_file *fs = source->data;
|
||||||
|
|
||||||
|
return read_full_buffer(fs->subfd, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void file_free(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct burn_source_file *fs = source->data;
|
||||||
|
|
||||||
|
close(fs->datafd);
|
||||||
|
if (source->read_sub)
|
||||||
|
close(fs->subfd);
|
||||||
|
free(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t file_size(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
struct burn_source_file *fs = source->data;
|
||||||
|
|
||||||
|
if (fstat(fs->datafd, &buf) == -1)
|
||||||
|
return (off_t) 0;
|
||||||
|
/* for now we keep it compatible to the old (int) return value */
|
||||||
|
if(buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
|
||||||
|
return (off_t) 1308622848;
|
||||||
|
return (off_t) buf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
||||||
|
{
|
||||||
|
struct burn_source_file *fs;
|
||||||
|
struct burn_source *src;
|
||||||
|
int fd1, fd2 = 0;
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
return NULL;
|
||||||
|
fd1 = open(path, O_RDONLY);
|
||||||
|
if (fd1 == -1)
|
||||||
|
return NULL;
|
||||||
|
if (subpath) {
|
||||||
|
fd2 = open(subpath, O_RDONLY);
|
||||||
|
if (fd2 == -1) {
|
||||||
|
close(fd1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs = malloc(sizeof(struct burn_source_file));
|
||||||
|
fs->datafd = fd1;
|
||||||
|
|
||||||
|
if (subpath)
|
||||||
|
fs->subfd = fd2;
|
||||||
|
|
||||||
|
src = burn_source_new();
|
||||||
|
src->read = file_read;
|
||||||
|
if (subpath)
|
||||||
|
src->read_sub = file_read_sub;
|
||||||
|
|
||||||
|
src->get_size = file_size;
|
||||||
|
src->free_data = file_free;
|
||||||
|
src->data = fs;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------ provisory location for the new source subclass fd --------- */
|
||||||
|
|
||||||
|
static off_t fd_get_size(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
struct burn_source_fd *fs = source->data;
|
||||||
|
|
||||||
|
if (fs->fixed_size > 0)
|
||||||
|
return fs->fixed_size;
|
||||||
|
if (fstat(fs->datafd, &buf) == -1)
|
||||||
|
return (off_t) 0;
|
||||||
|
/* for now we keep it compatible to the old (int) return value */
|
||||||
|
if (buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
|
||||||
|
return (off_t) 1308622848;
|
||||||
|
return buf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fd_read(struct burn_source *source,
|
||||||
|
unsigned char *buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct burn_source_fd *fs = source->data;
|
||||||
|
|
||||||
|
return read_full_buffer(fs->datafd, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int fd_read_sub(struct burn_source *source,
|
||||||
|
unsigned char *buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct burn_source_fd *fs = source->data;
|
||||||
|
|
||||||
|
return read_full_buffer(fs->subfd, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fd_free_data(struct burn_source *source)
|
||||||
|
{
|
||||||
|
struct burn_source_fd *fs = source->data;
|
||||||
|
|
||||||
|
close(fs->datafd);
|
||||||
|
if (source->read_sub)
|
||||||
|
close(fs->subfd);
|
||||||
|
free(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||||
|
{
|
||||||
|
struct burn_source_fd *fs;
|
||||||
|
struct burn_source *src;
|
||||||
|
|
||||||
|
if (datafd == -1)
|
||||||
|
return NULL;
|
||||||
|
fs = malloc(sizeof(struct burn_source_fd));
|
||||||
|
fs->datafd = datafd;
|
||||||
|
fs->subfd = subfd;
|
||||||
|
fs->fixed_size = size;
|
||||||
|
|
||||||
|
src = burn_source_new();
|
||||||
|
src->read = fd_read;
|
||||||
|
if(subfd != -1)
|
||||||
|
src->read = fd_read_sub;
|
||||||
|
src->get_size = fd_get_size;
|
||||||
|
src->free_data = fd_free_data;
|
||||||
|
src->data = fs;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
22
libburn/tags/ZeroThreeZero/libburn/file.h
Normal file
22
libburn/tags/ZeroThreeZero/libburn/file.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__FILE_H
|
||||||
|
#define BURN__FILE_H
|
||||||
|
|
||||||
|
struct burn_source_file
|
||||||
|
{
|
||||||
|
int datafd;
|
||||||
|
int subfd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ------ provisory location for the new source subclass fd --------- */
|
||||||
|
|
||||||
|
struct burn_source_fd
|
||||||
|
{
|
||||||
|
int datafd;
|
||||||
|
int subfd;
|
||||||
|
off_t fixed_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIBBURN__FILE_H */
|
276
libburn/tags/ZeroThreeZero/libburn/init.c
Normal file
276
libburn/tags/ZeroThreeZero/libburn/init.c
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "init.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "drive.h"
|
||||||
|
|
||||||
|
/* ts A60825 : The storage location for back_hacks.h variables. */
|
||||||
|
#define BURN_BACK_HACKS_INIT 1
|
||||||
|
#include "back_hacks.h"
|
||||||
|
|
||||||
|
/* ts A60924 : a new message handling facility */
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
|
|
||||||
|
int burn_running = 0;
|
||||||
|
|
||||||
|
/* ts A60813 : wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */
|
||||||
|
int burn_sg_open_o_excl = 1;
|
||||||
|
|
||||||
|
/* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use.
|
||||||
|
For enumerate_sg() it seems ok.
|
||||||
|
So it should stay default mode until enumerate_ata() without O_NONBLOCK
|
||||||
|
has been thoroughly tested. */
|
||||||
|
int burn_sg_open_o_nonblock = 1;
|
||||||
|
|
||||||
|
/* wether to take a busy drive as an error */
|
||||||
|
/* Caution: this is implemented by a rough hack and eventually leads
|
||||||
|
to unconditional abort of the process */
|
||||||
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61002 */
|
||||||
|
|
||||||
|
#include "cleanup.h"
|
||||||
|
|
||||||
|
/* Parameters for builtin abort handler */
|
||||||
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
|
static pid_t abort_control_pid= 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60925 : ticket 74 */
|
||||||
|
/** Create the messenger object for libburn. */
|
||||||
|
int burn_msgs_initialize(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(libdax_messenger == NULL) {
|
||||||
|
ret = libdax_msgs_new(&libdax_messenger,0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, "libburn: ", 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A60924 : ticket 74 : Added use of global libdax_messenger */
|
||||||
|
int burn_initialize(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_running)
|
||||||
|
return 1;
|
||||||
|
ret = burn_msgs_initialize();
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
burn_running = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_finish(void)
|
||||||
|
{
|
||||||
|
/* ts A61007 : assume no messageing system */
|
||||||
|
/* a ssert(burn_running); */
|
||||||
|
if (!burn_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
/* burn_wait_all(); */
|
||||||
|
if (!burn_drives_are_clear()) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020107,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is busy on attempt to shut down library", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */
|
||||||
|
burn_drive_free_all();
|
||||||
|
|
||||||
|
/* ts A60924 : ticket 74 */
|
||||||
|
libdax_msgs_destroy(&libdax_messenger,0);
|
||||||
|
|
||||||
|
burn_running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60813 */
|
||||||
|
/** API function. See libburn.h */
|
||||||
|
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
|
||||||
|
{
|
||||||
|
/* ts A61007 */
|
||||||
|
/* a ssert(burn_running); */
|
||||||
|
if (!burn_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
burn_sg_open_o_excl= exclusive;
|
||||||
|
burn_sg_open_o_nonblock= !blocking;
|
||||||
|
burn_sg_open_abort_busy= !!abort_on_busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60924 : ticket 74 */
|
||||||
|
/** Control queueing and stderr printing of messages from libburn.
|
||||||
|
Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT",
|
||||||
|
"NOTE", "UPDATE", "DEBUG", "ALL".
|
||||||
|
@param queue_severity Gives the minimum limit for messages to be queued.
|
||||||
|
Default: "NEVER". If you queue messages then you
|
||||||
|
must consume them by burn_msgs_obtain().
|
||||||
|
@param print_severity Does the same for messages to be printed directly
|
||||||
|
to stderr.
|
||||||
|
@param print_id A text prefix to be printed before the message.
|
||||||
|
@return >0 for success, <=0 for error
|
||||||
|
|
||||||
|
*/
|
||||||
|
int burn_msgs_set_severities(char *queue_severity,
|
||||||
|
char *print_severity, char *print_id)
|
||||||
|
{
|
||||||
|
int ret, queue_sevno, print_sevno;
|
||||||
|
|
||||||
|
ret = libdax_msgs__text_to_sev(queue_severity, &queue_sevno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = libdax_msgs__text_to_sev(print_severity, &print_sevno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = libdax_msgs_set_severities(libdax_messenger, queue_sevno,
|
||||||
|
print_sevno, print_id, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60924 : ticket 74 */
|
||||||
|
#define BURM_MSGS_MESSAGE_LEN 4096
|
||||||
|
|
||||||
|
/** Obtain the oldest pending libburn message from the queue which has at
|
||||||
|
least the given minimum_severity. This message and any older message of
|
||||||
|
lower severity will get discarded from the queue and is then lost forever.
|
||||||
|
Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT",
|
||||||
|
"NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER"
|
||||||
|
will discard the whole queue.
|
||||||
|
@param error_code Will become a unique error code as liste in
|
||||||
|
libburn/libdax_msgs.h
|
||||||
|
@param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes.
|
||||||
|
@param os_errno Will become the eventual errno related to the message
|
||||||
|
@param severity Will become the severity related to the message and
|
||||||
|
should provide at least 80 bytes.
|
||||||
|
@return 1 if a matching item was found, 0 if not, <0 for severe errors
|
||||||
|
*/
|
||||||
|
int burn_msgs_obtain(char *minimum_severity,
|
||||||
|
int *error_code, char msg_text[], int *os_errno,
|
||||||
|
char severity[])
|
||||||
|
{
|
||||||
|
int ret, minimum_sevno, sevno, priority;
|
||||||
|
char *textpt, *sev_name;
|
||||||
|
struct libdax_msgs_item *item = NULL;
|
||||||
|
|
||||||
|
ret = libdax_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
ret = libdax_msgs_obtain(libdax_messenger, &item, minimum_sevno,
|
||||||
|
LIBDAX_MSGS_PRIO_ZERO, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
ret = libdax_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
strncpy(msg_text, textpt, BURM_MSGS_MESSAGE_LEN-1);
|
||||||
|
if(strlen(textpt) >= BURM_MSGS_MESSAGE_LEN)
|
||||||
|
msg_text[BURM_MSGS_MESSAGE_LEN-1] = 0;
|
||||||
|
|
||||||
|
severity[0]= 0;
|
||||||
|
ret = libdax_msgs_item_get_rank(item, &sevno, &priority, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
ret = libdax_msgs__sev_to_text(sevno, &sev_name, 0);
|
||||||
|
if(ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
strcpy(severity,sev_name);
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:
|
||||||
|
libdax_msgs_destroy_item(libdax_messenger, &item, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
|
{
|
||||||
|
if(getpid() != abort_control_pid) {
|
||||||
|
|
||||||
|
#ifdef Not_yeT
|
||||||
|
pthread_t thread_id;
|
||||||
|
|
||||||
|
/* >>> need better handling of self-induced SIGs
|
||||||
|
like SIGSEGV or SIGFPE.
|
||||||
|
Like bonking the control thread if it did not show up
|
||||||
|
after a short while.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* >>> if this is a non-fatal signal : return -2 */
|
||||||
|
|
||||||
|
thread_id = pthread_self();
|
||||||
|
/* >>> find thread_id in worker list of async.c */
|
||||||
|
/* >>> if owning a drive : mark idle and canceled
|
||||||
|
(can't do anything more) */
|
||||||
|
|
||||||
|
usleep(1000000); /* calm down */
|
||||||
|
|
||||||
|
/* forward signal to control thread */
|
||||||
|
if (abort_control_pid>1)
|
||||||
|
kill(abort_control_pid, signum);
|
||||||
|
|
||||||
|
/* >>> ??? end thread */;
|
||||||
|
|
||||||
|
#else
|
||||||
|
usleep(1000000); /* calm down */
|
||||||
|
return -2;
|
||||||
|
#endif /* ! Not_yeT */
|
||||||
|
|
||||||
|
}
|
||||||
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
fprintf(stderr,
|
||||||
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
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);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
|
int mode)
|
||||||
|
{
|
||||||
|
if(handler == NULL && mode == 0) {
|
||||||
|
handler = burn_builtin_abort_handler;
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
strcpy(abort_message_prefix, "libburn : ");
|
||||||
|
if(handle != NULL)
|
||||||
|
strncpy(abort_message_prefix, (char *) handle,
|
||||||
|
sizeof(abort_message_prefix)-1);
|
||||||
|
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
|
abort_control_pid= getpid();
|
||||||
|
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
||||||
|
}
|
||||||
|
|
8
libburn/tags/ZeroThreeZero/libburn/init.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/init.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__INIT_H
|
||||||
|
#define BURN__INIT_H
|
||||||
|
|
||||||
|
extern int burn_running;
|
||||||
|
|
||||||
|
#endif /* BURN__INIT_H */
|
451
libburn/tags/ZeroThreeZero/libburn/lec.c
Normal file
451
libburn/tags/ZeroThreeZero/libburn/lec.c
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
/* -*- 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;
|
||||||
|
}
|
||||||
|
}
|
12
libburn/tags/ZeroThreeZero/libburn/lec.h
Normal file
12
libburn/tags/ZeroThreeZero/libburn/lec.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* -*- 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 */
|
1450
libburn/tags/ZeroThreeZero/libburn/libburn.h
Normal file
1450
libburn/tags/ZeroThreeZero/libburn/libburn.h
Normal file
File diff suppressed because it is too large
Load Diff
326
libburn/tags/ZeroThreeZero/libburn/libdax_audioxtr.c
Normal file
326
libburn/tags/ZeroThreeZero/libburn/libdax_audioxtr.c
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
|
||||||
|
/* libdax_audioxtr
|
||||||
|
Audio track data extraction facility of libdax and libburn.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/* Only this single source module is entitled to do this */
|
||||||
|
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
|
||||||
|
|
||||||
|
/* All clients of the extraction facility must do this */
|
||||||
|
#include "libdax_audioxtr.h"
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||||
|
{
|
||||||
|
int ret= -1;
|
||||||
|
struct libdax_audioxtr *o;
|
||||||
|
|
||||||
|
o= *xtr= (struct libdax_audioxtr *) malloc(sizeof(struct libdax_audioxtr));
|
||||||
|
if(o==NULL)
|
||||||
|
return(-1);
|
||||||
|
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
|
||||||
|
o->path[LIBDAX_AUDIOXTR_STRLEN]= 0;
|
||||||
|
o->fd= -1;
|
||||||
|
strcpy(o->fmt,"unidentified");
|
||||||
|
o->fmt_info[0]= 0;
|
||||||
|
o->data_size= 0;
|
||||||
|
o->extract_count= 0;
|
||||||
|
|
||||||
|
o->num_channels= 0;
|
||||||
|
o->sample_rate= 0;
|
||||||
|
o->bits_per_sample= 0;
|
||||||
|
o->msb_first= 0;
|
||||||
|
|
||||||
|
o->wav_subchunk2_size= 0;
|
||||||
|
|
||||||
|
o->au_data_location= 0;
|
||||||
|
o->au_data_size= 0xffffffff;
|
||||||
|
|
||||||
|
ret= libdax_audioxtr_open(o,0);
|
||||||
|
if(ret<=0)
|
||||||
|
{ret= -2*(ret<0); goto failure;}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
failure:
|
||||||
|
libdax_audioxtr_destroy(xtr,0);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag)
|
||||||
|
{
|
||||||
|
struct libdax_audioxtr *o;
|
||||||
|
|
||||||
|
o= *xtr;
|
||||||
|
if(o==NULL)
|
||||||
|
return(0);
|
||||||
|
if(o->fd>=0 && strcmp(o->path,"-")!=0)
|
||||||
|
close(o->fd);
|
||||||
|
free((char *) o);
|
||||||
|
*xtr= NULL;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char msg[LIBDAX_AUDIOXTR_STRLEN+80];
|
||||||
|
|
||||||
|
if(strcmp(o->path,"-")==0)
|
||||||
|
o->fd= 0;
|
||||||
|
else
|
||||||
|
o->fd= open(o->path, O_RDONLY);
|
||||||
|
if(o->fd<0) {
|
||||||
|
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
||||||
|
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, errno, 0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
ret= libdax_audioxtr_identify(o,0);
|
||||||
|
if(ret<=0) {
|
||||||
|
sprintf(msg,"Audio source file has unsuitable format : %s",o->path);
|
||||||
|
libdax_msgs_submit(libdax_messenger,-1,0x00020201,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
ret= libdax_audioxtr_init_reading(o,0);
|
||||||
|
if(ret<=0) {
|
||||||
|
sprintf(msg,"Failed to prepare reading of audio data : %s",o->path);
|
||||||
|
libdax_msgs_submit(libdax_messenger,-1,0x00020202,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char buf[45];
|
||||||
|
|
||||||
|
/* check wether this is a MS WAVE file .wav */
|
||||||
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
|
if(o->fd!=0) {
|
||||||
|
ret= lseek(o->fd,0,SEEK_SET);
|
||||||
|
if(ret==-1)
|
||||||
|
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 */
|
||||||
|
return(0);
|
||||||
|
if(strncmp(buf+8,"WAVE",4)!=0) /* Format */
|
||||||
|
return(0);
|
||||||
|
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);
|
||||||
|
|
||||||
|
strcpy(o->fmt,".wav");
|
||||||
|
o->msb_first= 0;
|
||||||
|
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0);
|
||||||
|
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0);
|
||||||
|
o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,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);
|
||||||
|
o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0);
|
||||||
|
o->data_size= o->wav_subchunk2_size;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
||||||
|
{
|
||||||
|
int ret,encoding;
|
||||||
|
char buf[24];
|
||||||
|
|
||||||
|
/* Check wether this is a Sun Audio, .au file */
|
||||||
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
|
if(o->fd!=0) {
|
||||||
|
ret= lseek(o->fd,0,SEEK_SET);
|
||||||
|
if(ret==-1)
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
ret= read(o->fd, buf, 24);
|
||||||
|
if(ret<24)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(strncmp(buf,".snd",4)!=0)
|
||||||
|
return(0);
|
||||||
|
strcpy(o->fmt,".au");
|
||||||
|
o->msb_first= 1;
|
||||||
|
o->au_data_location= libdax_audioxtr_to_int(o,(unsigned char *)buf+4,4,1);
|
||||||
|
o->au_data_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+8,4,1);
|
||||||
|
encoding= libdax_audioxtr_to_int(o,(unsigned char *)buf+12,4,1);
|
||||||
|
if(encoding==2)
|
||||||
|
o->bits_per_sample= 8;
|
||||||
|
else if(encoding==3)
|
||||||
|
o->bits_per_sample= 16;
|
||||||
|
else if(encoding==4)
|
||||||
|
o->bits_per_sample= 24;
|
||||||
|
else if(encoding==5)
|
||||||
|
o->bits_per_sample= 32;
|
||||||
|
else
|
||||||
|
o->bits_per_sample= -encoding;
|
||||||
|
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *)buf+16,4,1);
|
||||||
|
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *)buf+20,4,1);
|
||||||
|
if(o->au_data_size!=0xffffffff)
|
||||||
|
o->data_size= o->au_data_size;
|
||||||
|
else
|
||||||
|
o->data_size= 0;
|
||||||
|
sprintf(o->fmt_info,
|
||||||
|
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||||
|
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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret= libdax_audioxtr_identify_wav(o, 0);
|
||||||
|
if(ret!=0)
|
||||||
|
return(ret);
|
||||||
|
if(o->fd==0) /* cannot rewind stdin */
|
||||||
|
return(0);
|
||||||
|
ret= libdax_audioxtr_identify_au(o, 0);
|
||||||
|
if(ret!=0)
|
||||||
|
return(ret);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0=msb_first */
|
||||||
|
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
|
||||||
|
unsigned char *bytes, int len, int flag)
|
||||||
|
{
|
||||||
|
unsigned int ret= 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(flag&1)
|
||||||
|
for(i= 0; i<len; i++)
|
||||||
|
ret= ret*256+bytes[i];
|
||||||
|
else
|
||||||
|
for(i= len-1; i>=0; i--)
|
||||||
|
ret= ret*256+bytes[i];
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
/* currently this only works for MS WAVE files .wav and Sun .au*/;
|
||||||
|
if(o->fd==0) /* stdin: hope no read came after libdax_audioxtr_identify() */
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
o->extract_count= 0;
|
||||||
|
if(strcmp(o->fmt,".wav")==0)
|
||||||
|
ret= lseek(o->fd,44,SEEK_SET);
|
||||||
|
else if(strcmp(o->fmt,".au")==0)
|
||||||
|
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
|
||||||
|
else
|
||||||
|
ret= -1;
|
||||||
|
if(ret==-1)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_get_id(struct libdax_audioxtr *o,
|
||||||
|
char **fmt, char **fmt_info,
|
||||||
|
int *num_channels, int *sample_rate, int *bits_per_sample,
|
||||||
|
int *msb_first, int flag)
|
||||||
|
{
|
||||||
|
*fmt= o->fmt;
|
||||||
|
*fmt_info= o->fmt_info;
|
||||||
|
*num_channels= o->num_channels;
|
||||||
|
*sample_rate= o->sample_rate;
|
||||||
|
*bits_per_sample= o->bits_per_sample;
|
||||||
|
*msb_first= o->msb_first;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag)
|
||||||
|
{
|
||||||
|
*size= o->data_size;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_read(struct libdax_audioxtr *o,
|
||||||
|
char buffer[], int buffer_size, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(buffer_size<=0 || o->fd<0)
|
||||||
|
return(-2);
|
||||||
|
if(o->data_size>0 && !(flag&1))
|
||||||
|
if(buffer_size > o->data_size - o->extract_count)
|
||||||
|
buffer_size= o->data_size - o->extract_count;
|
||||||
|
if(buffer_size<=0)
|
||||||
|
return(0);
|
||||||
|
ret= read(o->fd,buffer,buffer_size);
|
||||||
|
if(ret>0)
|
||||||
|
o->extract_count+= ret;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag)
|
||||||
|
{
|
||||||
|
if(o->fd<0)
|
||||||
|
return(-1);
|
||||||
|
if(strcmp(o->fmt,".wav")!=0 && strcmp(o->fmt,".au")!=0)
|
||||||
|
return(0);
|
||||||
|
if(flag&1) {
|
||||||
|
*fd= o->fd;
|
||||||
|
} else {
|
||||||
|
*fd= dup(o->fd);
|
||||||
|
if(*fd>=0 && strcmp(o->path,"-")!=0)
|
||||||
|
close(o->fd);
|
||||||
|
}
|
||||||
|
if(*fd>=0) {
|
||||||
|
o->fd= -1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
229
libburn/tags/ZeroThreeZero/libburn/libdax_audioxtr.h
Normal file
229
libburn/tags/ZeroThreeZero/libburn/libdax_audioxtr.h
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
|
||||||
|
/* libdax_audioxtr
|
||||||
|
Audio track data extraction facility of libdax and libburn.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
|
||||||
|
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
|
||||||
|
|
||||||
|
/* Public Macros */
|
||||||
|
|
||||||
|
/* Maximum size for address paths and fmt_info strings */
|
||||||
|
#define LIBDAX_AUDIOXTR_STRLEN 4096
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Opaque Handles */
|
||||||
|
|
||||||
|
/** Extractor object encapsulating intermediate states of extraction.
|
||||||
|
The clients of libdax_audioxtr shall only allocate pointers to this
|
||||||
|
struct and get a storage object via libdax_audioxtr_new().
|
||||||
|
Appropriate initial value for the pointer is NULL.
|
||||||
|
*/
|
||||||
|
struct libdax_audioxtr;
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Functions */
|
||||||
|
|
||||||
|
/* Calls initiated from inside libdax/libburn */
|
||||||
|
|
||||||
|
|
||||||
|
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||||
|
|
||||||
|
|
||||||
|
/** Open an audio file, check wether suitable, create 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
|
||||||
|
be not suitable for all futurely supported formats).
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success
|
||||||
|
0 unsuitable format
|
||||||
|
-1 severe error
|
||||||
|
-2 path not found
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain identification parameters of opened audio source.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param fmt Gets pointed to the audio file format id text: ".wav" , ".au"
|
||||||
|
@param fmt_info Gets pointed to a format info text telling parameters
|
||||||
|
@param num_channels e.g. 1=mono, 2=stereo, etc
|
||||||
|
@param sample_rate e.g. 11025, 44100
|
||||||
|
@param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ...
|
||||||
|
@param msb_first Byte order of samples: 0=Intel 1=Motorola
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr,
|
||||||
|
char **fmt, char **fmt_info,
|
||||||
|
int *num_channels, int *sample_rate,
|
||||||
|
int *bits_per_sample, int *msb_first, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain a prediction about the extracted size based on internal information
|
||||||
|
of the formatted file.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param size Gets filled with the predicted size
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 prediction was possible , 0 no prediction could be made
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain next buffer full of extracted data in desired format (only raw audio
|
||||||
|
for now).
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param buffer Gets filled with extracted data
|
||||||
|
@param buffer_size Maximum number of bytes to be filled into buffer
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not stop at predicted end of data
|
||||||
|
@return >0 number of valid buffer bytes,
|
||||||
|
0 End of file
|
||||||
|
-1 operating system reports error
|
||||||
|
-2 usage error by application
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
|
||||||
|
char buffer[], int buffer_size, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Try to obtain a file descriptor which will deliver extracted data
|
||||||
|
to normal calls of read(2). This may fail because the format is
|
||||||
|
unsuitable for that, but ".wav" is ok. If this call succeeds the xtr
|
||||||
|
object will have forgotten its file descriptor and libdax_audioxtr_read()
|
||||||
|
will return a usage error. One may use *fd after libdax_audioxtr_destroy()
|
||||||
|
and will have to close it via close(2) when done with it.
|
||||||
|
@param xtr Opaque handle to extractor
|
||||||
|
@param fd Eventually returns the file descriptor number
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not dup(2) and close(2) but hand out original fd
|
||||||
|
@return 1 success, 0 cannot hand out fd , -1 severe error
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Clean up after extraction and destroy extractor object.
|
||||||
|
@param xtr Opaque handle to extractor, *xtr is allowed to be NULL,
|
||||||
|
*xtr is set to NULL by this function
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 = destroyed object, 0 = was already destroyed
|
||||||
|
*/
|
||||||
|
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LIDBAX_AUDIOXTR________________
|
||||||
|
|
||||||
|
|
||||||
|
-- place documentation text here ---
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* LIDBAX_AUDIOXTR_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Never* set this macro outside libdax_audioxtr.c !
|
||||||
|
The entrails of this facility are not to be seen by
|
||||||
|
the other library components or the applications.
|
||||||
|
*/
|
||||||
|
#ifdef LIBDAX_AUDIOXTR_H_INTERNAL
|
||||||
|
|
||||||
|
/* Internal Structures */
|
||||||
|
|
||||||
|
/** Extractor object encapsulating intermediate states of extraction */
|
||||||
|
struct libdax_audioxtr {
|
||||||
|
|
||||||
|
/* Source of the encoded audio data */
|
||||||
|
char path[LIBDAX_AUDIOXTR_STRLEN];
|
||||||
|
|
||||||
|
/* File descriptor to path. Anything else than 0 must be lseek-able */
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* Format identifier. E.g. ".wav" */
|
||||||
|
char fmt[80];
|
||||||
|
|
||||||
|
/* Format parameter info text */
|
||||||
|
char fmt_info[LIBDAX_AUDIOXTR_STRLEN];
|
||||||
|
|
||||||
|
/* 1= mono, 2= stereo, etc. */
|
||||||
|
int num_channels;
|
||||||
|
|
||||||
|
/* 8000, 44100, etc. */
|
||||||
|
int sample_rate;
|
||||||
|
|
||||||
|
/* 8 bits = 8, 16 bits = 16, etc. */
|
||||||
|
int bits_per_sample;
|
||||||
|
|
||||||
|
/* Byte order of samples: 0=Intel 1=Motorola */
|
||||||
|
int msb_first;
|
||||||
|
|
||||||
|
/* Number of bytes to extract (0= unknown/unlimited) */
|
||||||
|
off_t data_size;
|
||||||
|
|
||||||
|
/* Number of extracted data bytes */
|
||||||
|
off_t extract_count;
|
||||||
|
|
||||||
|
|
||||||
|
/* Format dependent parameters */
|
||||||
|
|
||||||
|
/* MS WAVE Format */
|
||||||
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
|
/* == NumSamples * NumChannels * BitsPerSample/8
|
||||||
|
This is the number of bytes in the data. */
|
||||||
|
unsigned wav_subchunk2_size;
|
||||||
|
|
||||||
|
|
||||||
|
/* Sun Audio, .au */
|
||||||
|
/* info used: http://www.opengroup.org/public/pubs/external/auformat.html */
|
||||||
|
|
||||||
|
/* Number of bytes in non-payload header part */
|
||||||
|
unsigned au_data_location;
|
||||||
|
|
||||||
|
/* Number of payload bytes or 0xffffffff */
|
||||||
|
unsigned au_data_size;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal Functions */
|
||||||
|
|
||||||
|
/** Open the audio source pointed to by .path and evaluate suitability.
|
||||||
|
@return -1 failure to open, 0 unsuitable format, 1 success
|
||||||
|
*/
|
||||||
|
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Identify format and evaluate suitability.
|
||||||
|
@return 0 unsuitable format, 1 format is suitable
|
||||||
|
*/
|
||||||
|
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag);
|
||||||
|
|
||||||
|
/** Specialized identifier for .wav */
|
||||||
|
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag);
|
||||||
|
/** Specialized identifier for .au */
|
||||||
|
static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert a byte string into a number (currently only little endian)
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0=msb_first
|
||||||
|
@return The resulting number
|
||||||
|
*/
|
||||||
|
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
|
||||||
|
unsigned char *bytes, int len, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Prepare for reading of first buffer.
|
||||||
|
@return 0 error, 1 success
|
||||||
|
*/
|
||||||
|
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* LIBDAX_AUDIOXTR_H_INTERNAL */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! LIBDAX_AUDIOXTR_H_INCLUDED */
|
||||||
|
|
404
libburn/tags/ZeroThreeZero/libburn/libdax_msgs.c
Normal file
404
libburn/tags/ZeroThreeZero/libburn/libdax_msgs.c
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
|
||||||
|
/* libdax_msgs
|
||||||
|
Message handling facility of libdax.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
/* Only this single source module is entitled to do this */
|
||||||
|
#define LIBDAX_MSGS_H_INTERNAL 1
|
||||||
|
|
||||||
|
/* All participants in the messaging system must do this */
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------- libdax_msgs_item ------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
||||||
|
struct libdax_msgs_item *link, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct libdax_msgs_item *o;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
|
||||||
|
(*item)= o=
|
||||||
|
(struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item));
|
||||||
|
if(o==NULL)
|
||||||
|
return(-1);
|
||||||
|
o->timestamp= 0.0;
|
||||||
|
ret= gettimeofday(&tv,&tz);
|
||||||
|
if(ret==0)
|
||||||
|
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
||||||
|
o->process_id= getpid();
|
||||||
|
o->driveno= -1;
|
||||||
|
o->severity= LIBDAX_MSGS_SEV_ALL;
|
||||||
|
o->priority= LIBDAX_MSGS_PRIO_ZERO;
|
||||||
|
o->error_code= 0;
|
||||||
|
o->msg_text= NULL;
|
||||||
|
o->os_errno= 0;
|
||||||
|
o->prev= link;
|
||||||
|
o->next= NULL;
|
||||||
|
if(link!=NULL) {
|
||||||
|
if(link->next!=NULL) {
|
||||||
|
link->next->prev= o;
|
||||||
|
o->next= link->next;
|
||||||
|
}
|
||||||
|
link->next= o;
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Detaches item from its queue and eventually readjusts start, end pointers
|
||||||
|
of the queue */
|
||||||
|
int libdax_msgs_item_unlink(struct libdax_msgs_item *o,
|
||||||
|
struct libdax_msgs_item **chain_start,
|
||||||
|
struct libdax_msgs_item **chain_end, int flag)
|
||||||
|
{
|
||||||
|
if(o->prev!=NULL)
|
||||||
|
o->prev->next= o->next;
|
||||||
|
if(o->next!=NULL)
|
||||||
|
o->next->prev= o->prev;
|
||||||
|
if(chain_start!=NULL)
|
||||||
|
if(*chain_start == o)
|
||||||
|
*chain_start= o->next;
|
||||||
|
if(chain_end!=NULL)
|
||||||
|
if(*chain_end == o)
|
||||||
|
*chain_end= o->prev;
|
||||||
|
o->next= o->prev= NULL;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_item_destroy(struct libdax_msgs_item **item,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
struct libdax_msgs_item *o;
|
||||||
|
|
||||||
|
o= *item;
|
||||||
|
if(o==NULL)
|
||||||
|
return(0);
|
||||||
|
libdax_msgs_item_unlink(o,NULL,NULL,0);
|
||||||
|
if(o->msg_text!=NULL)
|
||||||
|
free((char *) o->msg_text);
|
||||||
|
free((char *) o);
|
||||||
|
*item= NULL;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
|
||||||
|
int *error_code, char **msg_text, int *os_errno,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
*error_code= item->error_code;
|
||||||
|
*msg_text= item->msg_text;
|
||||||
|
*os_errno= item->os_errno;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
|
||||||
|
double *timestamp, pid_t *process_id, int *driveno,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
*timestamp= item->timestamp;
|
||||||
|
*process_id= item->process_id;
|
||||||
|
*driveno= item->driveno;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
|
||||||
|
int *severity, int *priority, int flag)
|
||||||
|
{
|
||||||
|
*severity= item->severity;
|
||||||
|
*priority= item->priority;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------- libdax_msgs ---------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_new(struct libdax_msgs **m, int flag)
|
||||||
|
{
|
||||||
|
struct libdax_msgs *o;
|
||||||
|
|
||||||
|
(*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs));
|
||||||
|
if(o==NULL)
|
||||||
|
return(-1);
|
||||||
|
o->oldest= NULL;
|
||||||
|
o->youngest= NULL;
|
||||||
|
o->count= 0;
|
||||||
|
o->queue_severity= LIBDAX_MSGS_SEV_ALL;
|
||||||
|
o->print_severity= LIBDAX_MSGS_SEV_NEVER;
|
||||||
|
strcpy(o->print_id,"libdax: ");
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
pthread_mutex_init(&(o->lock_mutex),NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_destroy(struct libdax_msgs **m, int flag)
|
||||||
|
{
|
||||||
|
struct libdax_msgs *o;
|
||||||
|
struct libdax_msgs_item *item, *next_item;
|
||||||
|
|
||||||
|
o= *m;
|
||||||
|
if(o==NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
if(pthread_mutex_destroy(&(o->lock_mutex))!=0) {
|
||||||
|
pthread_mutex_unlock(&(o->lock_mutex));
|
||||||
|
pthread_mutex_destroy(&(o->lock_mutex));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(item= o->oldest; item!=NULL; item= next_item) {
|
||||||
|
next_item= item->next;
|
||||||
|
libdax_msgs_item_destroy(&item,0);
|
||||||
|
}
|
||||||
|
free((char *) o);
|
||||||
|
*m= NULL;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity,
|
||||||
|
int print_severity, char *print_id, int flag)
|
||||||
|
{
|
||||||
|
m->queue_severity= queue_severity;
|
||||||
|
m->print_severity= print_severity;
|
||||||
|
strncpy(m->print_id,print_id,80);
|
||||||
|
m->print_id[80]= 0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_msgs_lock(struct libdax_msgs *m, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret= pthread_mutex_lock(&(m->lock_mutex));
|
||||||
|
if(ret!=0)
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int libdax_msgs_unlock(struct libdax_msgs *m, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret= pthread_mutex_unlock(&(m->lock_mutex));
|
||||||
|
if(ret!=0)
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs__text_to_sev(char *severity_name, int *severity,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
if(strncmp(severity_name,"NEVER",5)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_NEVER;
|
||||||
|
else if(strncmp(severity_name,"ABORT",5)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_ABORT;
|
||||||
|
else if(strncmp(severity_name,"FATAL",5)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_FATAL;
|
||||||
|
else if(strncmp(severity_name,"SORRY",5)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_SORRY;
|
||||||
|
else if(strncmp(severity_name,"WARNING",7)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_WARNING;
|
||||||
|
else if(strncmp(severity_name,"HINT",4)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_HINT;
|
||||||
|
else if(strncmp(severity_name,"NOTE",4)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_NOTE;
|
||||||
|
else if(strncmp(severity_name,"UPDATE",6)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_UPDATE;
|
||||||
|
else if(strncmp(severity_name,"DEBUG",5)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_DEBUG;
|
||||||
|
else if(strncmp(severity_name,"ALL",3)==0)
|
||||||
|
*severity= LIBDAX_MSGS_SEV_ALL;
|
||||||
|
else {
|
||||||
|
*severity= LIBDAX_MSGS_SEV_NEVER;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
if(flag&1) {
|
||||||
|
*severity_name=
|
||||||
|
"NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL";
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
*severity_name= "";
|
||||||
|
if(severity>=LIBDAX_MSGS_SEV_NEVER)
|
||||||
|
*severity_name= "NEVER";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_ABORT)
|
||||||
|
*severity_name= "ABORT";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_FATAL)
|
||||||
|
*severity_name= "FATAL";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_SORRY)
|
||||||
|
*severity_name= "SORRY";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_WARNING)
|
||||||
|
*severity_name= "WARNING";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_HINT)
|
||||||
|
*severity_name= "HINT";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_NOTE)
|
||||||
|
*severity_name= "NOTE";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_UPDATE)
|
||||||
|
*severity_name= "UPDATE";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_DEBUG)
|
||||||
|
*severity_name= "DEBUG";
|
||||||
|
else if(severity>=LIBDAX_MSGS_SEV_ALL)
|
||||||
|
*severity_name= "ALL";
|
||||||
|
else {
|
||||||
|
*severity_name= "";
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
|
||||||
|
int severity, int priority, char *msg_text,
|
||||||
|
int os_errno, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *textpt,*sev_name,sev_text[81];
|
||||||
|
struct libdax_msgs_item *item= NULL;
|
||||||
|
|
||||||
|
if(severity >= m->print_severity) {
|
||||||
|
if(msg_text==NULL)
|
||||||
|
textpt= "";
|
||||||
|
else
|
||||||
|
textpt= msg_text;
|
||||||
|
sev_text[0]= 0;
|
||||||
|
ret= libdax_msgs__sev_to_text(severity,&sev_name,0);
|
||||||
|
if(ret>0)
|
||||||
|
sprintf(sev_text,"%s : ",sev_name);
|
||||||
|
|
||||||
|
fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt);
|
||||||
|
if(os_errno!=0) {
|
||||||
|
ret= libdax_msgs_lock(m,0);
|
||||||
|
if(ret<=0)
|
||||||
|
return(-1);
|
||||||
|
fprintf(stderr,"%s( Most recent system error: %d '%s' )\n",
|
||||||
|
m->print_id,os_errno,strerror(os_errno));
|
||||||
|
libdax_msgs_unlock(m,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(severity < m->queue_severity)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
ret= libdax_msgs_lock(m,0);
|
||||||
|
if(ret<=0)
|
||||||
|
return(-1);
|
||||||
|
ret= libdax_msgs_item_new(&item,m->youngest,0);
|
||||||
|
if(ret<=0)
|
||||||
|
goto failed;
|
||||||
|
item->driveno= driveno;
|
||||||
|
item->error_code= error_code;
|
||||||
|
item->severity= severity;
|
||||||
|
item->priority= priority;
|
||||||
|
if(msg_text!=NULL) {
|
||||||
|
item->msg_text= malloc(strlen(msg_text)+1);
|
||||||
|
if(item->msg_text==NULL)
|
||||||
|
goto failed;
|
||||||
|
strcpy(item->msg_text,msg_text);
|
||||||
|
}
|
||||||
|
item->os_errno= os_errno;
|
||||||
|
if(m->oldest==NULL)
|
||||||
|
m->oldest= item;
|
||||||
|
m->youngest= item;
|
||||||
|
m->count++;
|
||||||
|
libdax_msgs_unlock(m,0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr,"libdax_experimental: message submitted to queue (now %d)\n",
|
||||||
|
m->count);
|
||||||
|
*/
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
failed:;
|
||||||
|
libdax_msgs_item_destroy(&item,0);
|
||||||
|
libdax_msgs_unlock(m,0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item,
|
||||||
|
int severity, int priority, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct libdax_msgs_item *im, *next_im= NULL;
|
||||||
|
|
||||||
|
*item= NULL;
|
||||||
|
ret= libdax_msgs_lock(m,0);
|
||||||
|
if(ret<=0)
|
||||||
|
return(-1);
|
||||||
|
for(im= m->oldest; im!=NULL; im= next_im) {
|
||||||
|
for(; im!=NULL; im= next_im) {
|
||||||
|
next_im= im->next;
|
||||||
|
if(im->severity>=severity)
|
||||||
|
break;
|
||||||
|
libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
|
||||||
|
libdax_msgs_item_destroy(&im,0); /* severity too low: delete */
|
||||||
|
}
|
||||||
|
if(im==NULL)
|
||||||
|
break;
|
||||||
|
if(im->priority>=priority)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(im==NULL)
|
||||||
|
{ret= 0; goto ex;}
|
||||||
|
libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
|
||||||
|
*item= im;
|
||||||
|
ret= 1;
|
||||||
|
ex:;
|
||||||
|
libdax_msgs_unlock(m,0);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int libdax_msgs_destroy_item(struct libdax_msgs *m,
|
||||||
|
struct libdax_msgs_item **item, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret= libdax_msgs_lock(m,0);
|
||||||
|
if(ret<=0)
|
||||||
|
return(-1);
|
||||||
|
ret= libdax_msgs_item_destroy(item,0);
|
||||||
|
libdax_msgs_unlock(m,0);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
397
libburn/tags/ZeroThreeZero/libburn/libdax_msgs.h
Normal file
397
libburn/tags/ZeroThreeZero/libburn/libdax_msgs.h
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
|
||||||
|
/* libdax_msgs
|
||||||
|
Message handling facility of libdax.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*Never* set this macro outside libdax_msgs.c !
|
||||||
|
The entrails of the message handling facility are not to be seen by
|
||||||
|
the other library components or the applications.
|
||||||
|
*/
|
||||||
|
#ifdef LIBDAX_MSGS_H_INTERNAL
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct libdax_msgs_item {
|
||||||
|
|
||||||
|
double timestamp;
|
||||||
|
pid_t process_id;
|
||||||
|
int driveno;
|
||||||
|
|
||||||
|
int severity;
|
||||||
|
int priority;
|
||||||
|
|
||||||
|
/* Apply for your developer's error code range at
|
||||||
|
libburn-hackers@pykix.org
|
||||||
|
Report introduced codes in the list below. */
|
||||||
|
int error_code;
|
||||||
|
|
||||||
|
char *msg_text;
|
||||||
|
int os_errno;
|
||||||
|
|
||||||
|
struct libdax_msgs_item *prev,*next;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct libdax_msgs {
|
||||||
|
|
||||||
|
struct libdax_msgs_item *oldest;
|
||||||
|
struct libdax_msgs_item *youngest;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
int queue_severity;
|
||||||
|
int print_severity;
|
||||||
|
char print_id[81];
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_SINGLE_THREADED
|
||||||
|
pthread_mutex_t lock_mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIBDAX_MSGS_H_INTERNAL */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_H_INCLUDED
|
||||||
|
#define LIBDAX_MSGS_H_INCLUDED 1
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIBDAX_MSGS_H_INTERNAL
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Opaque Handles */
|
||||||
|
|
||||||
|
/** A pointer to this is a opaque handle to a message handling facility */
|
||||||
|
struct libdax_msgs;
|
||||||
|
|
||||||
|
/** A pointer to this is a opaque handle to a single message item */
|
||||||
|
struct libdax_msgs_item;
|
||||||
|
|
||||||
|
#endif /* ! LIBDAX_MSGS_H_INTERNAL */
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Macros */
|
||||||
|
|
||||||
|
|
||||||
|
/* Registered Severities */
|
||||||
|
|
||||||
|
/* It is well advisable to let applications select severities via strings and
|
||||||
|
forwarded functions libdax_msgs__text_to_sev(), libdax_msgs__sev_to_text().
|
||||||
|
These macros are for use by libdax/libburn only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Use this to get messages of any severity. Do not use for submitting.
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_ALL 0x00000000
|
||||||
|
|
||||||
|
/** Debugging messages not to be visible to normal users by default
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_DEBUG 0x10000000
|
||||||
|
|
||||||
|
/** Update of a progress report about long running actions
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_UPDATE 0x20000000
|
||||||
|
|
||||||
|
/** Not so usual events which were gracefully handled
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_NOTE 0x30000000
|
||||||
|
|
||||||
|
/** Possibilities to achieve a better result
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_HINT 0x40000000
|
||||||
|
|
||||||
|
/** Warnings about problems which could not be handled optimally
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_WARNING 0x50000000
|
||||||
|
|
||||||
|
/** Non-fatal error messages indicating that parts of the action failed
|
||||||
|
but processing will/should go on
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_SORRY 0x60000000
|
||||||
|
|
||||||
|
/** An error message which puts the whole operation of libdax in question
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_FATAL 0x70000000
|
||||||
|
|
||||||
|
/** A message from an abort handler which will finally finish libburn
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_ABORT 0x71000000
|
||||||
|
|
||||||
|
/** A severity to exclude resp. discard any possible message.
|
||||||
|
Do not use this severity for submitting.
|
||||||
|
*/
|
||||||
|
#define LIBDAX_MSGS_SEV_NEVER 0x7fffffff
|
||||||
|
|
||||||
|
|
||||||
|
/* Registered Priorities */
|
||||||
|
|
||||||
|
/* Priorities are to be used by libburn/libdax only. */
|
||||||
|
|
||||||
|
#define LIBDAX_MSGS_PRIO_ZERO 0x00000000
|
||||||
|
#define LIBDAX_MSGS_PRIO_LOW 0x10000000
|
||||||
|
#define LIBDAX_MSGS_PRIO_MEDIUM 0x20000000
|
||||||
|
#define LIBDAX_MSGS_PRIO_HIGH 0x30000000
|
||||||
|
#define LIBDAX_MSGS_PRIO_TOP 0x7ffffffe
|
||||||
|
|
||||||
|
/* Do not use this priority for submitting */
|
||||||
|
#define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Functions */
|
||||||
|
|
||||||
|
/* Calls initiated from inside libdax/libburn */
|
||||||
|
|
||||||
|
|
||||||
|
/** Create new empty message handling facility with queue.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
*/
|
||||||
|
int libdax_msgs_new(struct libdax_msgs **m, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Destroy a message handling facility and all its eventual messages.
|
||||||
|
The submitted pointer gets set to NULL.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 for success, 0 for pointer to NULL
|
||||||
|
*/
|
||||||
|
int libdax_msgs_destroy(struct libdax_msgs **m, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Submit a message to a message handling facility.
|
||||||
|
@param driveno libdax drive number. Use -1 if no number is known.
|
||||||
|
@param error_code Unique error code. Use only registered codes. See below.
|
||||||
|
The same unique error_code may be issued at different
|
||||||
|
occasions but those should be equivalent out of the view
|
||||||
|
of a libdax application. (E.g. "cannot open ATA drive"
|
||||||
|
versus "cannot open SCSI drive" would be equivalent.)
|
||||||
|
@param severity The LIBDAX_MSGS_SEV_* of the event.
|
||||||
|
@param priority The LIBDAX_MSGS_PRIO_* number of the event.
|
||||||
|
@param msg_text Printable and human readable message text.
|
||||||
|
@param os_errno Eventual error code from operating system (0 if none)
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 on success, 0 on rejection, <0 for severe errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
|
||||||
|
int severity, int priority, char *msg_text,
|
||||||
|
int os_errno, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert a registered severity number into a severity name
|
||||||
|
@param flag Bitfield for control purposes:
|
||||||
|
bit0= list all severity names in a newline separated string
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
*/
|
||||||
|
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Convert a severity name into a severity number,
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
*/
|
||||||
|
int libdax_msgs__text_to_sev(char *severity_name, int *severity,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Set minimum severity for messages to be queued (default
|
||||||
|
LIBDAX_MSGS_SEV_ALL) and for messages to be printed directly to stderr
|
||||||
|
(default LIBDAX_MSGS_SEV_NEVER).
|
||||||
|
@param print_id A text of at most 80 characters to be printed before
|
||||||
|
any eventually printed message (default is "libdax: ").
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return always 1 for now
|
||||||
|
*/
|
||||||
|
int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity,
|
||||||
|
int print_severity, char *print_id, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain a message item that has at least the given severity and priority.
|
||||||
|
Usually all older messages of lower severity are discarded then. If no
|
||||||
|
item of sufficient severity was found, all others are discarded from the
|
||||||
|
queue.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 if a matching item was found, 0 if not, <0 for severe errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item,
|
||||||
|
int severity, int priority, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted
|
||||||
|
pointer gets set to NULL.
|
||||||
|
Caution: Copy eventually obtained msg_text before destroying the item,
|
||||||
|
if you want to use it further.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 for success, 0 for pointer to NULL, <0 for severe errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_destroy_item(struct libdax_msgs *m,
|
||||||
|
struct libdax_msgs_item **item, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain from a message item the three application oriented components as
|
||||||
|
submitted with the originating call of libdax_msgs_submit().
|
||||||
|
Caution: msg_text becomes a pointer into item, not a copy.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 on success, 0 on invalid item, <0 for servere errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
|
||||||
|
int *error_code, char **msg_text, int *os_errno,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain from a message item the submitter identification submitted
|
||||||
|
with the originating call of libdax_msgs_submit().
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 on success, 0 on invalid item, <0 for servere errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
|
||||||
|
double *timestamp, pid_t *process_id, int *driveno,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Obtain from a message item severity and priority as submitted
|
||||||
|
with the originating call of libdax_msgs_submit().
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 on success, 0 on invalid item, <0 for servere errors
|
||||||
|
*/
|
||||||
|
int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
|
||||||
|
int *severity, int *priority, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LIDBAX_MSGS_________________
|
||||||
|
|
||||||
|
|
||||||
|
/* Registered Error Codes */
|
||||||
|
|
||||||
|
|
||||||
|
Format: error_code (LIBDAX_MSGS_SEV_*,LIBDAX_MSGS_PRIO_*) = explanation
|
||||||
|
If no severity or priority are fixely associates, use "(,)".
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Range "libdax_msgs" : 0x00000000 to 0x0000ffff
|
||||||
|
|
||||||
|
0x00000000 (ALL,ZERO) = Initial setting in new libdax_msgs_item
|
||||||
|
0x00000001 (DEBUG,ZERO) = Test error message
|
||||||
|
0x00000002 (DEBUG,ZERO) = Debugging message
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Range "elmom" : 0x00010000 to 0x0001ffff
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
|
|
||||||
|
Acessing and defending drives:
|
||||||
|
|
||||||
|
0x00020001 (SORRY,LOW) = Cannot open busy device
|
||||||
|
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
||||||
|
0x00020003 (SORRY,HIGH) = Could not grab drive
|
||||||
|
0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling
|
||||||
|
0x00020005 (FATAL,HIGH) = Failed to open device
|
||||||
|
0x00020006 (FATAL,HIGH) = Too many scsi siblings
|
||||||
|
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
||||||
|
|
||||||
|
General library operations:
|
||||||
|
|
||||||
|
0x00020101 (WARNING,HIGH) = Cannot find given worker item
|
||||||
|
0x00020102 (SORRY,HIGH) = A drive operation is still going on
|
||||||
|
0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on
|
||||||
|
0x00020104 (SORRY,HIGH) = NULL pointer caught
|
||||||
|
0x00020105 (SORRY,HIGH) = Drive is already released
|
||||||
|
0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close
|
||||||
|
0x00020107 (SORRY,HIGH) = Drive is busy on attempt to shut down library
|
||||||
|
0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry
|
||||||
|
0x00020108 (FATAL,HIGH) = Could not allocate new drive object
|
||||||
|
0x00020109 (FATAL,HIGH) = Library not running
|
||||||
|
0x0002010a (FATAL,HIGH) = Unsuitable track mode
|
||||||
|
0x0002010b (FATAL,HIGH) = Burn run failed
|
||||||
|
0x0002010c (FATAL,HIGH) = Failed to transfer command to drive
|
||||||
|
0x0002010d (DEBUG,HIGH) = Could not inquire TOC
|
||||||
|
0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive
|
||||||
|
0x0002010f (DEBUG,HIGH) = SCSI error condition on command
|
||||||
|
0x00020110 (FATAL,HIGH) = Persistent drive address too long
|
||||||
|
0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object
|
||||||
|
0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type
|
||||||
|
0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet
|
||||||
|
0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data
|
||||||
|
0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value
|
||||||
|
0x00020116 (FATAL,HIGH) = Track mode has unusable value
|
||||||
|
0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use
|
||||||
|
0x00020118 (DEBUG,HIGH) = Closing track
|
||||||
|
0x00020119 (DEBUG,HIGH) = Closing session
|
||||||
|
0x0002011a (NOTE,HIGH) = Padding up track to minimum size
|
||||||
|
0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive
|
||||||
|
0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive
|
||||||
|
0x0002011d (FATAL,HIGH) = SCSI error on write
|
||||||
|
0x0002011e (SORRY,HIGH) = Unsuitable media detected
|
||||||
|
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
|
||||||
|
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
||||||
|
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
||||||
|
0x00020122 (FATAL,HIGH) = SCSI error on format_unit
|
||||||
|
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
|
||||||
|
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
|
||||||
|
0x00020125 (SORRY,HIGH) = Write start address not supported
|
||||||
|
0x00020126 (SORRY,HIGH) = Write start address not properly aligned
|
||||||
|
0x00020127 (NOTE,HIGH) = Write start address is ...
|
||||||
|
0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance
|
||||||
|
0x00020129 (SORRY,HIGH) = Will not format media type
|
||||||
|
0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking
|
||||||
|
0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive
|
||||||
|
|
||||||
|
|
||||||
|
libdax_audioxtr:
|
||||||
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format
|
||||||
|
0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif /* LIDBAX_MSGS_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LIBDAX_MSGS_H_INTERNAL
|
||||||
|
|
||||||
|
/* Internal Functions */
|
||||||
|
|
||||||
|
|
||||||
|
/** Lock before doing side effect operations on m */
|
||||||
|
static int libdax_msgs_lock(struct libdax_msgs *m, int flag);
|
||||||
|
|
||||||
|
/** Unlock after effect operations on m are done */
|
||||||
|
static int libdax_msgs_unlock(struct libdax_msgs *m, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Create new empty message item.
|
||||||
|
@param link Previous item in queue
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return >0 success, <=0 failure
|
||||||
|
*/
|
||||||
|
static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
||||||
|
struct libdax_msgs_item *link, int flag);
|
||||||
|
|
||||||
|
/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted
|
||||||
|
pointer gets set to NULL.
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 for success, 0 for pointer to NULL
|
||||||
|
*/
|
||||||
|
static int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* LIBDAX_MSGS_H_INTERNAL */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! LIBDAX_MSGS_H_INCLUDED */
|
1731
libburn/tags/ZeroThreeZero/libburn/mmc.c
Normal file
1731
libburn/tags/ZeroThreeZero/libburn/mmc.c
Normal file
File diff suppressed because it is too large
Load Diff
72
libburn/tags/ZeroThreeZero/libburn/mmc.h
Normal file
72
libburn/tags/ZeroThreeZero/libburn/mmc.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __MMC
|
||||||
|
#define __MMC
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
struct burn_write_opts;
|
||||||
|
struct command;
|
||||||
|
struct buffer;
|
||||||
|
struct cue_sheet;
|
||||||
|
|
||||||
|
/* MMC commands */
|
||||||
|
|
||||||
|
void mmc_read(struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61009 : removed redundant parameter d in favor of o->drive */
|
||||||
|
/* void mmc_close_session(struct burn_drive *, struct burn_write_opts *); */
|
||||||
|
/* void mmc_close_disc(struct burn_drive *, struct burn_write_opts *); */
|
||||||
|
void mmc_close_session(struct burn_write_opts *o);
|
||||||
|
void mmc_close_disc(struct burn_write_opts *o);
|
||||||
|
|
||||||
|
void mmc_close(struct burn_drive *, int session, int track);
|
||||||
|
void mmc_get_event(struct burn_drive *);
|
||||||
|
int mmc_write(struct burn_drive *, 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_load(struct burn_drive *);
|
||||||
|
void mmc_eject(struct burn_drive *);
|
||||||
|
void mmc_erase(struct burn_drive *, int);
|
||||||
|
void mmc_read_toc(struct burn_drive *);
|
||||||
|
void mmc_read_disc_info(struct burn_drive *);
|
||||||
|
void mmc_read_atip(struct burn_drive *);
|
||||||
|
void mmc_read_sectors(struct burn_drive *,
|
||||||
|
int,
|
||||||
|
int, const struct burn_read_opts *, struct buffer *);
|
||||||
|
void mmc_set_speed(struct burn_drive *, int, int);
|
||||||
|
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
||||||
|
void mmc_perform_opc(struct burn_drive *);
|
||||||
|
void mmc_get_configuration(struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value.
|
||||||
|
@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);
|
||||||
|
|
||||||
|
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
||||||
|
|
||||||
|
/* ts A61023 : get size and free space of drive buffer */
|
||||||
|
int mmc_read_buffer_capacity(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int mmc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
|
||||||
|
and mmc5r03c.pdf, 6.5 FORMAT UNIT */
|
||||||
|
int mmc_format_unit(struct burn_drive *d, off_t size, int flag);
|
||||||
|
|
||||||
|
/* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */
|
||||||
|
int mmc_get_write_performance(struct burn_drive *d);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61229 : outsourced from spc_select_write_params() */
|
||||||
|
/* Note: Page data is not zeroed here to allow preset defaults. Thus
|
||||||
|
memset(pd, 0, 2 + d->mdata->write_page_length);
|
||||||
|
is the eventual duty of the caller.
|
||||||
|
*/
|
||||||
|
int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||||
|
const struct burn_write_opts *o,
|
||||||
|
unsigned char *pd);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*__MMC*/
|
27
libburn/tags/ZeroThreeZero/libburn/null.c
Normal file
27
libburn/tags/ZeroThreeZero/libburn/null.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include "null.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
int null_read(struct burn_source *source, unsigned char *buffer, int size)
|
||||||
|
{
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_source *burn_null_source_new(void)
|
||||||
|
{
|
||||||
|
struct burn_source *src;
|
||||||
|
|
||||||
|
src = malloc(sizeof(struct burn_source));
|
||||||
|
src->refcount = 1;
|
||||||
|
src->read = null_read;
|
||||||
|
src->read_sub = NULL;
|
||||||
|
|
||||||
|
src->get_size = 0;
|
||||||
|
src->free_data = NULL;
|
||||||
|
src->data = NULL;
|
||||||
|
return src;
|
||||||
|
}
|
10
libburn/tags/ZeroThreeZero/libburn/null.h
Normal file
10
libburn/tags/ZeroThreeZero/libburn/null.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__NULL_H
|
||||||
|
#define BURN__NULL_H
|
||||||
|
|
||||||
|
struct burn_source;
|
||||||
|
int null_read(struct burn_source *source, unsigned char *buffer, int size);
|
||||||
|
struct burn_source *burn_null_source_new(void);
|
||||||
|
|
||||||
|
#endif /* LIBBURN__NULL_H */
|
219
libburn/tags/ZeroThreeZero/libburn/options.c
Normal file
219
libburn/tags/ZeroThreeZero/libburn/options.c
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#include "libburn.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
|
{
|
||||||
|
struct burn_write_opts *opts;
|
||||||
|
|
||||||
|
opts = malloc(sizeof(struct burn_write_opts));
|
||||||
|
if (opts == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not allocate new auxiliary object", 0, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
opts->drive = drive;
|
||||||
|
opts->refcount = 1;
|
||||||
|
opts->write_type = BURN_WRITE_TAO;
|
||||||
|
opts->block_type = BURN_BLOCK_MODE1;
|
||||||
|
opts->toc_entry = NULL;
|
||||||
|
opts->toc_entries = 0;
|
||||||
|
opts->simulate = 0;
|
||||||
|
opts->underrun_proof = drive->mdata->underrun_proof;
|
||||||
|
opts->perform_opc = 1;
|
||||||
|
opts->obs = -1;
|
||||||
|
opts->obs_pad = 0;
|
||||||
|
opts->start_byte = -1;
|
||||||
|
opts->has_mediacatalog = 0;
|
||||||
|
opts->format = BURN_CDROM;
|
||||||
|
opts->multi = 0;
|
||||||
|
opts->control = 0;
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_free(struct burn_write_opts *opts)
|
||||||
|
{
|
||||||
|
if (--opts->refcount <= 0)
|
||||||
|
free(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
||||||
|
{
|
||||||
|
struct burn_read_opts *opts;
|
||||||
|
|
||||||
|
opts = malloc(sizeof(struct burn_read_opts));
|
||||||
|
opts->drive = drive;
|
||||||
|
opts->refcount = 1;
|
||||||
|
opts->raw = 0;
|
||||||
|
opts->c2errors = 0;
|
||||||
|
opts->subcodes_audio = 0;
|
||||||
|
opts->subcodes_data = 0;
|
||||||
|
opts->hardware_error_recovery = 0;
|
||||||
|
opts->report_recovered_errors = 0;
|
||||||
|
opts->transfer_damaged_blocks = 0;
|
||||||
|
opts->hardware_error_retries = 3;
|
||||||
|
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_free(struct burn_read_opts *opts)
|
||||||
|
{
|
||||||
|
if (--opts->refcount <= 0)
|
||||||
|
free(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_write_opts_set_write_type(struct burn_write_opts *opts,
|
||||||
|
enum burn_write_types write_type,
|
||||||
|
int block_type)
|
||||||
|
{
|
||||||
|
int sector_get_outmode(enum burn_write_types write_type,
|
||||||
|
enum burn_block_types block_type);
|
||||||
|
int spc_block_type(enum burn_block_types b);
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
if (! ( (write_type == BURN_WRITE_SAO && block_type == BURN_BLOCK_SAO)
|
||||||
|
|| (opts->drive->block_types[write_type] & block_type) ) ) {
|
||||||
|
bad_combination:;
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020112,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Bad combination of write_type and block_type", 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* ts A61007 : obsoleting Assert in sector.c:get_outmode() */
|
||||||
|
if (sector_get_outmode(write_type, (enum burn_block_types) block_type)
|
||||||
|
== -1)
|
||||||
|
goto bad_combination;
|
||||||
|
/* ts A61007 : obsoleting Assert in spc.c:spc_block_type() */
|
||||||
|
if (spc_block_type((enum burn_block_types) block_type) == -1)
|
||||||
|
goto bad_combination;
|
||||||
|
|
||||||
|
opts->write_type = write_type;
|
||||||
|
opts->block_type = block_type;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* a ssert(0); */
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count,
|
||||||
|
struct burn_toc_entry *toc_entries)
|
||||||
|
{
|
||||||
|
opts->toc_entries = count;
|
||||||
|
opts->toc_entry = malloc(count * sizeof(struct burn_toc_entry));
|
||||||
|
memcpy(opts->toc_entry, &toc_entries,
|
||||||
|
sizeof(struct burn_toc_entry) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_set_format(struct burn_write_opts *opts, int format)
|
||||||
|
{
|
||||||
|
opts->format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
||||||
|
{
|
||||||
|
if (opts->drive->mdata->simulate) {
|
||||||
|
opts->simulate = sim;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
||||||
|
int underrun_proof)
|
||||||
|
{
|
||||||
|
if (opts->drive->mdata->underrun_proof) {
|
||||||
|
opts->underrun_proof = underrun_proof;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc)
|
||||||
|
{
|
||||||
|
opts->perform_opc = opc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
|
||||||
|
int has_mediacatalog)
|
||||||
|
{
|
||||||
|
opts->has_mediacatalog = has_mediacatalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
||||||
|
unsigned char mediacatalog[13])
|
||||||
|
{
|
||||||
|
memcpy(opts->mediacatalog, &mediacatalog, 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61106 */
|
||||||
|
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
|
||||||
|
{
|
||||||
|
opts->multi = !!multi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61222 */
|
||||||
|
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
||||||
|
{
|
||||||
|
opts->start_byte = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw)
|
||||||
|
{
|
||||||
|
opts->raw = raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors)
|
||||||
|
{
|
||||||
|
opts->c2errors = c2errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts,
|
||||||
|
int subcodes_audio)
|
||||||
|
{
|
||||||
|
opts->subcodes_audio = subcodes_audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts,
|
||||||
|
int subcodes_data)
|
||||||
|
{
|
||||||
|
opts->subcodes_data = subcodes_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts,
|
||||||
|
int hardware_error_recovery)
|
||||||
|
{
|
||||||
|
opts->hardware_error_recovery = hardware_error_recovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts,
|
||||||
|
int report_recovered_errors)
|
||||||
|
{
|
||||||
|
opts->report_recovered_errors = report_recovered_errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts,
|
||||||
|
int transfer_damaged_blocks)
|
||||||
|
{
|
||||||
|
opts->transfer_damaged_blocks = transfer_damaged_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts,
|
||||||
|
unsigned char
|
||||||
|
hardware_error_retries)
|
||||||
|
{
|
||||||
|
opts->hardware_error_retries = hardware_error_retries;
|
||||||
|
}
|
||||||
|
|
87
libburn/tags/ZeroThreeZero/libburn/options.h
Normal file
87
libburn/tags/ZeroThreeZero/libburn/options.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef BURN__OPTIONS_H
|
||||||
|
#define BURN__OPTIONS_H
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
|
||||||
|
/** Options for disc writing operations. This should be created with
|
||||||
|
burn_write_opts_new() and freed with burn_write_opts_free(). */
|
||||||
|
struct burn_write_opts
|
||||||
|
{
|
||||||
|
/** Drive the write opts are good for */
|
||||||
|
struct burn_drive *drive;
|
||||||
|
|
||||||
|
/** For internal use. */
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
/** The method/style of writing to use. */
|
||||||
|
enum burn_write_types write_type;
|
||||||
|
/** format of the data to send to the drive */
|
||||||
|
enum burn_block_types block_type;
|
||||||
|
|
||||||
|
/** Number of toc entries. if this is 0, they will be auto generated*/
|
||||||
|
int toc_entries;
|
||||||
|
/** Toc entries for the disc */
|
||||||
|
struct burn_toc_entry *toc_entry;
|
||||||
|
|
||||||
|
/** Simulate the write so that the disc is not actually written */
|
||||||
|
unsigned int simulate:1;
|
||||||
|
/** If available, enable a drive feature which prevents buffer
|
||||||
|
underruns if not enough data is available to keep up with the
|
||||||
|
drive. */
|
||||||
|
unsigned int underrun_proof:1;
|
||||||
|
/** Perform calibration of the drive's laser before beginning the
|
||||||
|
write. */
|
||||||
|
unsigned int perform_opc:1;
|
||||||
|
|
||||||
|
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
||||||
|
-1 with CD, 32 kB with DVD */
|
||||||
|
int obs;
|
||||||
|
int obs_pad; /* 1=pad up last block to obs */
|
||||||
|
|
||||||
|
/* ts A61222 : Start address for media which allow a choice */
|
||||||
|
off_t start_byte;
|
||||||
|
|
||||||
|
/** A disc can have a media catalog number */
|
||||||
|
int has_mediacatalog;
|
||||||
|
unsigned char mediacatalog[13];
|
||||||
|
/** Session format */
|
||||||
|
int format;
|
||||||
|
/* internal use only */
|
||||||
|
unsigned char control;
|
||||||
|
unsigned char multi;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Options for disc reading operations. This should be created with
|
||||||
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
|
struct burn_read_opts
|
||||||
|
{
|
||||||
|
/** Drive the read opts are good for */
|
||||||
|
struct burn_drive *drive;
|
||||||
|
|
||||||
|
/** For internal use. */
|
||||||
|
int refcount;
|
||||||
|
|
||||||
|
/** Read in raw mode, so that everything in the data tracks on the
|
||||||
|
disc is read, including headers. Not needed if just reading a
|
||||||
|
filesystem off a disc, but it should usually be used when making a
|
||||||
|
disc image or copying a disc. */
|
||||||
|
unsigned int raw:1;
|
||||||
|
/** Report c2 errors. Useful for statistics reporting */
|
||||||
|
unsigned int c2errors:1;
|
||||||
|
/** Read subcodes from audio tracks on the disc */
|
||||||
|
unsigned int subcodes_audio:1;
|
||||||
|
/** Read subcodes from data tracks on the disc */
|
||||||
|
unsigned int subcodes_data:1;
|
||||||
|
/** Have the drive recover errors if possible */
|
||||||
|
unsigned int hardware_error_recovery:1;
|
||||||
|
/** Report errors even when they were recovered from */
|
||||||
|
unsigned int report_recovered_errors:1;
|
||||||
|
/** Read blocks even when there are unrecoverable errors in them */
|
||||||
|
unsigned int transfer_damaged_blocks:1;
|
||||||
|
|
||||||
|
/** The number of retries the hardware should make to correct
|
||||||
|
errors. */
|
||||||
|
unsigned char hardware_error_retries;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* BURN__OPTIONS_H */
|
73
libburn/tags/ZeroThreeZero/libburn/os-freebsd.h
Normal file
73
libburn/tags/ZeroThreeZero/libburn/os-freebsd.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
/* os-freebsd.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
FreeBSD with CAM
|
||||||
|
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
|
#define BURN_OS_H_INCLUDED 1
|
||||||
|
|
||||||
|
|
||||||
|
/** 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, SIGTSTP, SIGTTIN, \
|
||||||
|
SIGTTOU, \
|
||||||
|
SIGBUS, SIGPROF, SIGSYS, SIGTRAP, \
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ
|
||||||
|
|
||||||
|
/* 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", "SIGTSTP", "SIGTTIN", \
|
||||||
|
"SIGTTOU", \
|
||||||
|
"SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_SIGNAL_COUNT 23
|
||||||
|
|
||||||
|
/** To list all signals which shall surely not be caught */
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 5
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
||||||
|
|
||||||
|
|
||||||
|
/** To hold all state information of BSD device enumeration
|
||||||
|
which are now local in sg_enumerate() . So that sg_give_next_adr()
|
||||||
|
can work in BSD and sg_enumerate() can use it.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
|
struct burn_drive_enumeration_state { \
|
||||||
|
union ccb ccb; \
|
||||||
|
int bufsize, fd; \
|
||||||
|
unsigned int i; \
|
||||||
|
int skip_device; \
|
||||||
|
}; \
|
||||||
|
typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* The list of operating system dependent elements in struct burn_drive.
|
||||||
|
To be initialized and used within sg-*.c .
|
||||||
|
*/
|
||||||
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
|
struct cam_device* cam;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
|
64
libburn/tags/ZeroThreeZero/libburn/os-linux.h
Normal file
64
libburn/tags/ZeroThreeZero/libburn/os-linux.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
/* os-linux.h
|
||||||
|
Operating system specific libburn definitions and declarations. Included
|
||||||
|
by os.h in case of compilation for
|
||||||
|
Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg)
|
||||||
|
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** 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, SIGTSTP, SIGTTIN, \
|
||||||
|
SIGTTOU, \
|
||||||
|
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, \
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ
|
||||||
|
|
||||||
|
/* 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", "SIGTSTP", "SIGTTIN", \
|
||||||
|
"SIGTTOU", \
|
||||||
|
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_SIGNAL_COUNT 24
|
||||||
|
|
||||||
|
/** To list all signals which shall surely not be caught */
|
||||||
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
|
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
||||||
|
|
||||||
|
/* The number of above list items */
|
||||||
|
#define BURN_OS_NON_SIGNAL_COUNT 5
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
/* Important : MUST be at least 32768 ! */
|
||||||
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
|
/* To hold the index number of the most recently delivered address from
|
||||||
|
device enumeration.
|
||||||
|
*/
|
||||||
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
|
typedef int 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; \
|
||||||
|
\
|
||||||
|
/* ts A60926 : trying to lock against growisofs /dev/srN, /dev/scdN */ \
|
||||||
|
int sibling_count; \
|
||||||
|
int sibling_fds[LIBBURN_SG_MAX_SIBLINGS];
|
||||||
|
|
34
libburn/tags/ZeroThreeZero/libburn/os.h
Normal file
34
libburn/tags/ZeroThreeZero/libburn/os.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
/* os.h
|
||||||
|
Operating system specific libburn definitions and declarations.
|
||||||
|
The macros defined here are used by libburn modules in order to
|
||||||
|
avoid own system dependent case distinctions.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
|
#define BURN_OS_H_INCLUDED 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
Operating system case distinction
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------- FreeBSD with CAM -------------------------- */
|
||||||
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#else /* operating system case distinction */
|
||||||
|
|
||||||
|
|
||||||
|
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
||||||
|
#include "os-linux.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* End of operating system case distinction */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
|
282
libburn/tags/ZeroThreeZero/libburn/read.c
Normal file
282
libburn/tags/ZeroThreeZero/libburn/read.c
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* ts A61007 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "sector.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
/* ts A60925 : obsoleted by libdax_msgs.h
|
||||||
|
#include "message.h"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "crc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "lec.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "read.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int i, end, maxsects, finish;
|
||||||
|
int seclen;
|
||||||
|
int drive_lba;
|
||||||
|
unsigned short crc;
|
||||||
|
unsigned char fakesub[96];
|
||||||
|
struct buffer page;
|
||||||
|
int speed;
|
||||||
|
|
||||||
|
/* ts A61007 : if this function gets revived, then these
|
||||||
|
tests have to be done more graceful */
|
||||||
|
a ssert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000));
|
||||||
|
a ssert(!d->busy);
|
||||||
|
a ssert(d->toc->valid);
|
||||||
|
a ssert(o->datafd != -1);
|
||||||
|
|
||||||
|
/* moved up from spc_select_error_params alias d->send_parameters() */
|
||||||
|
a ssert(d->mdata->valid);
|
||||||
|
|
||||||
|
/* XXX not sure this is a good idea. copy it? */
|
||||||
|
/* XXX also, we have duplicated data now, do we remove the fds from struct
|
||||||
|
drive, or only store a subset of the _opts structs in drives */
|
||||||
|
|
||||||
|
/* set the speed on the drive */
|
||||||
|
speed = o->speed > 0 ? o->speed : d->mdata->max_read_speed;
|
||||||
|
d->set_speed(d, speed, 0);
|
||||||
|
|
||||||
|
d->params.retries = o->hardware_error_retries;
|
||||||
|
|
||||||
|
d->send_parameters(d, o);
|
||||||
|
|
||||||
|
d->cancel = 0;
|
||||||
|
d->busy = BURN_DRIVE_READING;
|
||||||
|
d->currsession = 0;
|
||||||
|
/* drive_lba = 232000;
|
||||||
|
d->currtrack = 18;
|
||||||
|
*/
|
||||||
|
d->currtrack = 0;
|
||||||
|
drive_lba = 0;
|
||||||
|
/* XXX removal of this line obviously breaks *
|
||||||
|
d->track_end = burn_track_end(d, d->currsession, d->currtrack);*/
|
||||||
|
printf("track ends at %d\n", d->track_end);
|
||||||
|
page.sectors = 0;
|
||||||
|
page.bytes = 0;
|
||||||
|
|
||||||
|
if (o->subfd != -1) {
|
||||||
|
memset(fakesub, 0xFF, 12);
|
||||||
|
memset(fakesub + 12, 0, 84);
|
||||||
|
fakesub[13] = 1;
|
||||||
|
fakesub[14] = 1;
|
||||||
|
fakesub[20] = 2;
|
||||||
|
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
||||||
|
d->toc->toc_entry[0].adr;
|
||||||
|
crc = crc_ccitt(fakesub + 12, 10);
|
||||||
|
fakesub[22] = crc >> 8;
|
||||||
|
fakesub[23] = crc & 0xFF;
|
||||||
|
write(o->subfd, fakesub, 96);
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
seclen = burn_sector_length_read(d, o);
|
||||||
|
|
||||||
|
burn_print(12, "received %d blocks\n", page.sectors);
|
||||||
|
for (i = 0; i < page.sectors; i++) {
|
||||||
|
burn_packet_process(d, page.data + seclen * i, o);
|
||||||
|
d->track_end--;
|
||||||
|
drive_lba++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
||||||
|
burn_print(1, "finished or cancelled\n");
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
if (!d->cancel)
|
||||||
|
d->toc->complete = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* XXX: removal of this line obviously breaks *
|
||||||
|
end = burn_track_end(d, d->currsession, d->currtrack); */
|
||||||
|
|
||||||
|
if (drive_lba == end) {
|
||||||
|
d->currtrack++;
|
||||||
|
if (d->currtrack >
|
||||||
|
d->toc->session[d->currsession].lasttrack) {
|
||||||
|
d->currsession++;
|
||||||
|
burn_print(12, "session switch to %d\n",
|
||||||
|
d->currsession);
|
||||||
|
burn_print(12, "skipping a lead out\n");
|
||||||
|
drive_lba = CURRENT_SESSION_START(d);
|
||||||
|
burn_print(12, "new lba %d\n", drive_lba);
|
||||||
|
/* XXX more of the same
|
||||||
|
end = burn_track_end(d, d->currsession,
|
||||||
|
d->currtrack);
|
||||||
|
*/ }
|
||||||
|
burn_print(12, "track switch to %d\n", d->currtrack);
|
||||||
|
}
|
||||||
|
|
||||||
|
page.sectors = 0;
|
||||||
|
page.bytes = 0;
|
||||||
|
|
||||||
|
maxsects = BUFFER_SIZE / seclen;
|
||||||
|
finish = end - drive_lba;
|
||||||
|
|
||||||
|
d->track_end = finish;
|
||||||
|
|
||||||
|
page.sectors = (finish < maxsects) ? finish : maxsects;
|
||||||
|
printf("reading %d sectors from %d\n", page.sectors,
|
||||||
|
drive_lba);
|
||||||
|
|
||||||
|
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
||||||
|
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
||||||
|
|
||||||
|
printf("Read %d\n", page.sectors);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
int burn_sector_length_read(struct burn_drive *d,
|
||||||
|
const struct burn_read_opts *o)
|
||||||
|
{
|
||||||
|
int dlen = 2352;
|
||||||
|
int data;
|
||||||
|
|
||||||
|
/*XXX how do we handle this crap now?*/
|
||||||
|
/* data = d->toc->track[d->currtrack].toc_entry->control & 4;*/
|
||||||
|
data = 1;
|
||||||
|
if (o->report_recovered_errors)
|
||||||
|
dlen += 294;
|
||||||
|
if ((o->subcodes_data) && data)
|
||||||
|
dlen += 96;
|
||||||
|
if ((o->subcodes_audio) && !data)
|
||||||
|
dlen += 96;
|
||||||
|
return dlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bitcount(unsigned char *data, int n)
|
||||||
|
{
|
||||||
|
int i, j, count = 0;
|
||||||
|
unsigned char tem;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
tem = data[i];
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
count += tem & 1;
|
||||||
|
tem >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
|
const struct burn_read_opts *o)
|
||||||
|
{
|
||||||
|
unsigned char sub[96];
|
||||||
|
unsigned short crc;
|
||||||
|
int ptr = 2352, i, j, code, fb;
|
||||||
|
int audio = 1;
|
||||||
|
|
||||||
|
if (o->c2errors) {
|
||||||
|
fb = bitcount(data + ptr, 294);
|
||||||
|
if (fb) {
|
||||||
|
burn_print(1, "%d damaged bits\n",
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (d->toc->track[d->currtrack].mode == BURN_MODE_UNINITIALIZED) {
|
||||||
|
if ((d->toc->track[d->currtrack].toc_entry->control & 4) == 0)
|
||||||
|
d->toc->track[d->currtrack].mode = BURN_MODE_AUDIO;
|
||||||
|
else
|
||||||
|
switch (data[15]) {
|
||||||
|
case 0:
|
||||||
|
d->toc->track[d->currtrack].mode = BURN_MODE0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
d->toc->track[d->currtrack].mode = BURN_MODE1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
d->toc->track[d->currtrack].mode =
|
||||||
|
BURN_MODE2_FORMLESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if ((audio && o->subcodes_audio)
|
||||||
|
|| (!audio && o->subcodes_data)) {
|
||||||
|
memset(sub, 0, sizeof(sub));
|
||||||
|
for (i = 0; i < 12; i++) {
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
for (code = 0; code < 8; code++) {
|
||||||
|
sub[code * 12 + i] <<= 1;
|
||||||
|
if (data[ptr + j + i * 8] &
|
||||||
|
(1 << (7 - code)))
|
||||||
|
sub[code * 12 + i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
|
burn_print(1, "sending error on %s %s\n",
|
||||||
|
d->idata->vendor, d->idata->product);
|
||||||
|
/* e = burn_error();
|
||||||
|
e->drive = d;
|
||||||
|
*/
|
||||||
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
|
}
|
||||||
|
/* else process_q(d, sub + 12); */
|
||||||
|
/*
|
||||||
|
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if ((d->track_end <= 150)
|
||||||
|
&& (drive_lba + 150 < CURRENT_SESSION_END(d))
|
||||||
|
&& (TOC_ENTRY(d->toc, d->currtrack).control == 4)
|
||||||
|
&& (TOC_ENTRY(d->toc, d->currtrack + 1).control == 0)) {
|
||||||
|
burn_print(12, "pregap : %d\n", d->track_end);
|
||||||
|
write(o->binfd, zeros, 2352);
|
||||||
|
|
||||||
|
#warning XXX WHERE ARE MY SUBCODES
|
||||||
|
} else
|
||||||
|
*//* write(o->datafd, data, 2352); */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* so yeah, when you uncomment these, make them write zeros insted of crap
|
||||||
|
static void write_empty_sector(int fd)
|
||||||
|
{
|
||||||
|
char sec[2352];
|
||||||
|
|
||||||
|
burn_print(1, "writing an 'empty' sector\n");
|
||||||
|
write(fd, sec, 2352);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_empty_subcode(int fd)
|
||||||
|
{
|
||||||
|
char sub[96];
|
||||||
|
|
||||||
|
write(fd, sub, 96);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flipq(unsigned char *sub)
|
||||||
|
{
|
||||||
|
*(sub + 12 + 10) = ~*(sub + 12 + 10);
|
||||||
|
*(sub + 12 + 11) = ~*(sub + 12 + 11);
|
||||||
|
}
|
||||||
|
*/
|
14
libburn/tags/ZeroThreeZero/libburn/read.h
Normal file
14
libburn/tags/ZeroThreeZero/libburn/read.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __LIBBURN_READ
|
||||||
|
#define __LIBBURN_READ
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
struct burn_read_opts;
|
||||||
|
|
||||||
|
int burn_sector_length_read(struct burn_drive *d,
|
||||||
|
const struct burn_read_opts *o);
|
||||||
|
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
|
const struct burn_read_opts *o);
|
||||||
|
|
||||||
|
#endif /* __LIBBURN_READ */
|
65
libburn/tags/ZeroThreeZero/libburn/sbc.c
Normal file
65
libburn/tags/ZeroThreeZero/libburn/sbc.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* scsi block commands */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
/* spc command set */
|
||||||
|
static char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
||||||
|
static char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
||||||
|
static char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
||||||
|
|
||||||
|
void sbc_load(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SBC_LOAD);
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
c.page = NULL;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sbc_eject(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
c.page = NULL;
|
||||||
|
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||||
|
c.oplen = 1;
|
||||||
|
c.oplen = sizeof(SBC_UNLOAD);
|
||||||
|
c.page = NULL;
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
|
||||||
|
int sbc_start_unit(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SBC_START_UNIT);
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
c.page = NULL;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
return (c.error==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int sbc_setup_drive(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
d->eject = sbc_eject;
|
||||||
|
d->load = sbc_load;
|
||||||
|
d->start_unit = sbc_start_unit;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
18
libburn/tags/ZeroThreeZero/libburn/sbc.h
Normal file
18
libburn/tags/ZeroThreeZero/libburn/sbc.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __SBC
|
||||||
|
#define __SBC
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
|
||||||
|
void sbc_load(struct burn_drive *);
|
||||||
|
void sbc_eject(struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61118 */
|
||||||
|
int sbc_start_unit(struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int sbc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
|
#endif /* __SBC */
|
840
libburn/tags/ZeroThreeZero/libburn/sector.c
Normal file
840
libburn/tags/ZeroThreeZero/libburn/sector.c
Normal file
@ -0,0 +1,840 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* ts A61010 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "error.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "transport.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "sector.h"
|
||||||
|
#include "crc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "lec.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "write.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
/* <<< ts A61031 */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
|
||||||
|
/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
|
||||||
|
|
||||||
|
#define sector_common(X) d->alba++; d->rlba X;
|
||||||
|
|
||||||
|
static void uncook_subs(unsigned char *dest, unsigned char *source)
|
||||||
|
{
|
||||||
|
int i, j, code;
|
||||||
|
|
||||||
|
memset(dest, 0, 96);
|
||||||
|
|
||||||
|
for (i = 0; i < 12; i++) {
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
for (code = 0; code < 8; code++) {
|
||||||
|
if (source[code * 12 + i] & 0x80)
|
||||||
|
dest[j + i * 8] |= (1 << (7 - code));
|
||||||
|
source[code * 12 + i] <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @return >=0 : valid , <0 invalid */
|
||||||
|
int sector_get_outmode(enum burn_write_types write_type,
|
||||||
|
enum burn_block_types block_type)
|
||||||
|
{
|
||||||
|
/* ts A61103 : extended SAO condition to TAO */
|
||||||
|
if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
switch (block_type) {
|
||||||
|
case BURN_BLOCK_RAW0:
|
||||||
|
return BURN_MODE_RAW;
|
||||||
|
case BURN_BLOCK_RAW16:
|
||||||
|
return BURN_MODE_RAW | BURN_SUBCODE_P16;
|
||||||
|
case BURN_BLOCK_RAW96P:
|
||||||
|
return BURN_MODE_RAW | BURN_SUBCODE_P96;
|
||||||
|
case BURN_BLOCK_RAW96R:
|
||||||
|
return BURN_MODE_RAW | BURN_SUBCODE_R96;
|
||||||
|
case BURN_BLOCK_MODE1:
|
||||||
|
return BURN_MODE1;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61007 : now handled in burn_write_opts_set_write_type() */
|
||||||
|
/* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 0 means "same as inmode" */
|
||||||
|
static int get_outmode(struct burn_write_opts *o)
|
||||||
|
{
|
||||||
|
/* ts A61007 */
|
||||||
|
return sector_get_outmode(o->write_type, o->block_type);
|
||||||
|
|
||||||
|
/* -1 is prevented by check in burn_write_opts_set_write_type() */
|
||||||
|
/* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||||
|
{
|
||||||
|
int valid, shortage, curr, i, tr;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
/* <<< ts A61031 */
|
||||||
|
static int tee_fd= -1;
|
||||||
|
if(tee_fd==-1)
|
||||||
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
|
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
|
||||||
|
/* no track pointer means we're just generating 0s */
|
||||||
|
if (!track) {
|
||||||
|
memset(data, 0, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first we use up any offset */
|
||||||
|
valid = track->offset - track->offsetcount;
|
||||||
|
if (valid > count)
|
||||||
|
valid = count;
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
track->offsetcount += valid;
|
||||||
|
memset(data, 0, valid);
|
||||||
|
}
|
||||||
|
shortage = count - valid;
|
||||||
|
|
||||||
|
if (!shortage)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
/* Next we use source data */
|
||||||
|
curr = valid;
|
||||||
|
if (!track->eos) {
|
||||||
|
valid = track->source->read(track->source, data + curr, count - curr);
|
||||||
|
} else valid = 0;
|
||||||
|
|
||||||
|
if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
|
||||||
|
track->eos = 1;
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
track->sourcecount += valid;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
/* <<< ts A61031 */
|
||||||
|
if(tee_fd!=-1 && valid>0) {
|
||||||
|
write(tee_fd, data + curr, valid);
|
||||||
|
}
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
curr += valid;
|
||||||
|
shortage = count - curr;
|
||||||
|
|
||||||
|
if (!shortage)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
/* Before going to the next track, we run through any tail */
|
||||||
|
|
||||||
|
valid = track->tail - track->tailcount;
|
||||||
|
if (valid > count - curr)
|
||||||
|
valid = count - curr;
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
track->tailcount += valid;
|
||||||
|
memset(data + curr, 0, valid);
|
||||||
|
}
|
||||||
|
curr += valid;
|
||||||
|
shortage -= valid;
|
||||||
|
|
||||||
|
if (!shortage)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
if (shortage >= count)
|
||||||
|
track->track_data_done = 1;
|
||||||
|
if (track->open_ended)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
/* If we're still short, and there's a "next" pointer, we pull from that.
|
||||||
|
if that depletes, we'll just fill with 0s.
|
||||||
|
*/
|
||||||
|
if (track->source->next) {
|
||||||
|
struct burn_source *src;
|
||||||
|
printf("pulling from next track\n");
|
||||||
|
src = track->source->next;
|
||||||
|
valid = src->read(src, data + curr, shortage);
|
||||||
|
if (valid > 0) {
|
||||||
|
shortage -= valid;
|
||||||
|
curr += valid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ex:;
|
||||||
|
/* ts A61024 : general finalizing processing */
|
||||||
|
if(shortage)
|
||||||
|
memset(data + curr, 0, shortage); /* this is old icculus.org */
|
||||||
|
if (track->swap_source_bytes == 1) {
|
||||||
|
for (i = 1; i < count; i += 2) {
|
||||||
|
tr = data[i];
|
||||||
|
data[i] = data[i-1];
|
||||||
|
data[i-1] = tr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
|
||||||
|
and to count hand outs as well as reserved bytes */
|
||||||
|
/* ts A61101 : added parameter track for counting written bytes */
|
||||||
|
static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||||
|
struct burn_track *track, int inmode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = opts->drive;
|
||||||
|
struct buffer *out = d->buffer;
|
||||||
|
int outmode;
|
||||||
|
int seclen;
|
||||||
|
unsigned char *ret;
|
||||||
|
|
||||||
|
outmode = get_outmode(opts);
|
||||||
|
if (outmode == 0)
|
||||||
|
outmode = inmode;
|
||||||
|
|
||||||
|
/* ts A61009 : react on eventual failure of burn_sector_length()
|
||||||
|
(should not happen if API tested properly).
|
||||||
|
Ensures out->bytes >= out->sectors */
|
||||||
|
seclen = burn_sector_length(outmode);
|
||||||
|
if (seclen <= 0)
|
||||||
|
return NULL;
|
||||||
|
seclen += burn_subcode_length(outmode);
|
||||||
|
|
||||||
|
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
||||||
|
if (out->bytes + (seclen) > BUFFER_SIZE || out->bytes == opts->obs) {
|
||||||
|
int err;
|
||||||
|
err = d->write(d, d->nwa, out);
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
|
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;
|
||||||
|
out->bytes += seclen;
|
||||||
|
out->sectors++;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
/* Revoke the counting of the most recent sector handed out by get_sector() */
|
||||||
|
static void unget_sector(struct burn_write_opts *opts, int inmode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = opts->drive;
|
||||||
|
struct buffer *out = d->buffer;
|
||||||
|
int outmode;
|
||||||
|
int seclen;
|
||||||
|
|
||||||
|
outmode = get_outmode(opts);
|
||||||
|
if (outmode == 0)
|
||||||
|
outmode = inmode;
|
||||||
|
|
||||||
|
/* ts A61009 : react on eventual failure of burn_sector_length()
|
||||||
|
(should not happen if API tested properly).
|
||||||
|
Ensures out->bytes >= out->sectors */
|
||||||
|
seclen = burn_sector_length(outmode);
|
||||||
|
if (seclen <= 0)
|
||||||
|
return;
|
||||||
|
seclen += burn_subcode_length(outmode);
|
||||||
|
|
||||||
|
out->bytes -= seclen;
|
||||||
|
out->sectors--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* either inmode == outmode, or outmode == raw. anything else is bad news */
|
||||||
|
/* ts A61010 : changed type to int in order to propagate said bad news */
|
||||||
|
/** @return 1 is ok, <= 0 is failure */
|
||||||
|
static int convert_data(struct burn_write_opts *o, struct burn_track *track,
|
||||||
|
int inmode, unsigned char *data)
|
||||||
|
{
|
||||||
|
int outlen, inlen;
|
||||||
|
int offset = -1;
|
||||||
|
int outmode;
|
||||||
|
|
||||||
|
outmode = get_outmode(o);
|
||||||
|
if (outmode == 0)
|
||||||
|
outmode = inmode;
|
||||||
|
|
||||||
|
outlen = burn_sector_length(outmode);
|
||||||
|
inlen = burn_sector_length(inmode);
|
||||||
|
|
||||||
|
/* ts A61010 */
|
||||||
|
/* a ssert(outlen >= inlen); */
|
||||||
|
if (outlen < inlen)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
||||||
|
get_bytes(track, inlen, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61010 */
|
||||||
|
/* a ssert(outmode & BURN_MODE_RAW); */
|
||||||
|
if (!(outmode & BURN_MODE_RAW))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (inmode & BURN_MODE1)
|
||||||
|
offset = 16;
|
||||||
|
if (inmode & BURN_MODE_RAW)
|
||||||
|
offset = 0;
|
||||||
|
if (inmode & BURN_AUDIO)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
/* ts A61010 */
|
||||||
|
/* a ssert(offset != -1); */
|
||||||
|
if (offset == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
get_bytes(track, inlen, data + offset);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_subs(struct burn_write_opts *o, int inmode,
|
||||||
|
unsigned char *subs, unsigned char *sector)
|
||||||
|
{
|
||||||
|
unsigned char *out;
|
||||||
|
int outmode;
|
||||||
|
|
||||||
|
outmode = get_outmode(o);
|
||||||
|
if (outmode == 0)
|
||||||
|
outmode = inmode;
|
||||||
|
sector += burn_sector_length(outmode);
|
||||||
|
/* XXX for sao with subs, we'd need something else... */
|
||||||
|
|
||||||
|
switch (o->block_type) {
|
||||||
|
case BURN_BLOCK_RAW96R:
|
||||||
|
uncook_subs(sector, subs);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BURN_BLOCK_RAW16:
|
||||||
|
memcpy(sector, subs + 12, 12);
|
||||||
|
out = sector + 12;
|
||||||
|
out[0] = 0;
|
||||||
|
out[1] = 0;
|
||||||
|
out[2] = 0;
|
||||||
|
/*XXX find a better way to deal with partially damaged P channels*/
|
||||||
|
if (subs[2] != 0)
|
||||||
|
out[3] = 0x80;
|
||||||
|
else
|
||||||
|
out[3] = 0;
|
||||||
|
out = sector + 10;
|
||||||
|
|
||||||
|
out[0] = ~out[0];
|
||||||
|
out[1] = ~out[1];
|
||||||
|
break;
|
||||||
|
/* ts A61119 : to silence compiler warnings */
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
|
||||||
|
{
|
||||||
|
unsigned char *q;
|
||||||
|
int track;
|
||||||
|
int crc;
|
||||||
|
int min, sec, frame;
|
||||||
|
|
||||||
|
track = d->toc_temp / 3;
|
||||||
|
memset(data, 0, 96);
|
||||||
|
q = data + 12;
|
||||||
|
|
||||||
|
burn_lba_to_msf(d->rlba, &min, &sec, &frame);
|
||||||
|
/*XXX track numbers are BCD
|
||||||
|
a0 - 1st track ctrl
|
||||||
|
a1 - last track ctrl
|
||||||
|
a2 - lout ctrl
|
||||||
|
*/
|
||||||
|
q[0] = (d->toc_entry[track].control << 4) + 1;
|
||||||
|
q[1] = 0;
|
||||||
|
if (d->toc_entry[track].point < 100)
|
||||||
|
q[2] = dec_to_bcd(d->toc_entry[track].point);
|
||||||
|
else
|
||||||
|
q[2] = d->toc_entry[track].point;
|
||||||
|
q[3] = dec_to_bcd(min);
|
||||||
|
q[4] = dec_to_bcd(sec);
|
||||||
|
q[5] = dec_to_bcd(frame);
|
||||||
|
q[6] = 0;
|
||||||
|
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
||||||
|
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
||||||
|
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
||||||
|
crc = crc_ccitt(q, 10);
|
||||||
|
q[10] = crc >> 8;
|
||||||
|
q[11] = crc & 0xFF;
|
||||||
|
d->toc_temp++;
|
||||||
|
d->toc_temp %= (d->toc_entries * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_toc(struct burn_write_opts *o, int mode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned char subs[96];
|
||||||
|
|
||||||
|
data = get_sector(o, NULL, mode);
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
/* ts A61010 */
|
||||||
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
|
return 0;
|
||||||
|
subcode_toc(d, mode, subs);
|
||||||
|
convert_subs(o, mode, subs, data);
|
||||||
|
sector_headers(o, data, mode, 1);
|
||||||
|
sector_common(++)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_pregap(struct burn_write_opts *o,
|
||||||
|
unsigned char tno, unsigned char control, int mode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned char subs[96];
|
||||||
|
|
||||||
|
data = get_sector(o, NULL, mode);
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
/* ts A61010 */
|
||||||
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
|
return 0;
|
||||||
|
subcode_user(o, subs, tno, control, 0, NULL, 1);
|
||||||
|
convert_subs(o, mode, subs, data);
|
||||||
|
sector_headers(o, data, mode, 0);
|
||||||
|
sector_common(--)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_postgap(struct burn_write_opts *o,
|
||||||
|
unsigned char tno, unsigned char control, int mode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char subs[96];
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
data = get_sector(o, NULL, mode);
|
||||||
|
if (data == NULL)
|
||||||
|
return 0;
|
||||||
|
/* ts A61010 */
|
||||||
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
|
return 0;;
|
||||||
|
/* use last index in track */
|
||||||
|
subcode_user(o, subs, tno, control, 1, NULL, 1);
|
||||||
|
convert_subs(o, mode, subs, data);
|
||||||
|
sector_headers(o, data, mode, 0);
|
||||||
|
sector_common(++)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcode_lout(struct burn_write_opts *o, unsigned char control,
|
||||||
|
unsigned char *data)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char *q;
|
||||||
|
int crc;
|
||||||
|
int rmin, min, rsec, sec, rframe, frame;
|
||||||
|
|
||||||
|
memset(data, 0, 96);
|
||||||
|
q = data + 12;
|
||||||
|
|
||||||
|
burn_lba_to_msf(d->alba, &min, &sec, &frame);
|
||||||
|
burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe);
|
||||||
|
|
||||||
|
if (((rmin == 0) && (rsec == 0) && (rframe == 0)) ||
|
||||||
|
((rsec >= 2) && !((rframe / 19) % 2)))
|
||||||
|
memset(data, 0xFF, 12);
|
||||||
|
q[0] = (control << 4) + 1;
|
||||||
|
q[1] = 0xAA;
|
||||||
|
q[2] = 0x01;
|
||||||
|
q[3] = dec_to_bcd(rmin);
|
||||||
|
q[4] = dec_to_bcd(rsec);
|
||||||
|
q[5] = dec_to_bcd(rframe);
|
||||||
|
q[6] = 0;
|
||||||
|
q[7] = dec_to_bcd(min);
|
||||||
|
q[8] = dec_to_bcd(sec);
|
||||||
|
q[9] = dec_to_bcd(frame);
|
||||||
|
crc = crc_ccitt(q, 10);
|
||||||
|
q[10] = crc >> 8;
|
||||||
|
q[11] = crc & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char char_to_isrc(char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
return 0x11 + (c - 'A');
|
||||||
|
if (c >= 'a' && c <= 'z')
|
||||||
|
return 0x11 + (c - 'a');
|
||||||
|
|
||||||
|
/* ts A61008 : obsoleted by test in burn_track_set_isrc() */
|
||||||
|
/* a ssert(0); */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
|
||||||
|
unsigned char tno, unsigned char control,
|
||||||
|
unsigned char indx, struct isrc *isrc, int psub)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char *p, *q;
|
||||||
|
int crc;
|
||||||
|
int m, s, f, c, qmode; /* 1, 2 or 3 */
|
||||||
|
|
||||||
|
memset(subcodes, 0, 96);
|
||||||
|
|
||||||
|
p = subcodes;
|
||||||
|
if ((tno == 1) && (d->rlba == -150))
|
||||||
|
memset(p, 0xFF, 12);
|
||||||
|
|
||||||
|
if (psub)
|
||||||
|
memset(p, 0xFF, 12);
|
||||||
|
q = subcodes + 12;
|
||||||
|
|
||||||
|
qmode = 1;
|
||||||
|
/* every 1 in 10 we can do something different */
|
||||||
|
if (d->rlba % 10 == 0) {
|
||||||
|
/* each of these can occur 1 in 100 */
|
||||||
|
if ((d->rlba / 10) % 10 == 0) {
|
||||||
|
if (o->has_mediacatalog)
|
||||||
|
qmode = 2;
|
||||||
|
} else if ((d->rlba / 10) % 10 == 1) {
|
||||||
|
if (isrc && isrc->has_isrc)
|
||||||
|
qmode = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61010 : this cannot happen. Assert for fun ? */
|
||||||
|
/* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */
|
||||||
|
|
||||||
|
switch (qmode) {
|
||||||
|
case 1:
|
||||||
|
q[1] = dec_to_bcd(tno); /* track number */
|
||||||
|
q[2] = dec_to_bcd(indx); /* index XXX read this shit
|
||||||
|
from the track array */
|
||||||
|
burn_lba_to_msf(d->rlba, &m, &s, &f);
|
||||||
|
q[3] = dec_to_bcd(m); /* rel min */
|
||||||
|
q[4] = dec_to_bcd(s); /* rel sec */
|
||||||
|
q[5] = dec_to_bcd(f); /* rel frame */
|
||||||
|
q[6] = 0; /* zero */
|
||||||
|
burn_lba_to_msf(d->alba, &m, &s, &f);
|
||||||
|
q[7] = dec_to_bcd(m); /* abs min */
|
||||||
|
q[8] = dec_to_bcd(s); /* abs sec */
|
||||||
|
q[9] = dec_to_bcd(f); /* abs frame */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* media catalog number */
|
||||||
|
q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1];
|
||||||
|
q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3];
|
||||||
|
q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5];
|
||||||
|
q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7];
|
||||||
|
q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9];
|
||||||
|
q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11];
|
||||||
|
q[7] = o->mediacatalog[12] << 4;
|
||||||
|
|
||||||
|
q[8] = 0;
|
||||||
|
burn_lba_to_msf(d->alba, &m, &s, &f);
|
||||||
|
q[9] = dec_to_bcd(f); /* abs frame */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
c = char_to_isrc(isrc->country[0]);
|
||||||
|
/* top 6 bits of [1] is the first country code */
|
||||||
|
q[1] = c << 2;
|
||||||
|
c = char_to_isrc(isrc->country[1]);
|
||||||
|
/* bottom 2 bits of [1] is part of the second country code */
|
||||||
|
q[1] += (c >> 4);
|
||||||
|
/* top 4 bits if [2] is the rest of the second country code */
|
||||||
|
q[2] = c << 4;
|
||||||
|
|
||||||
|
c = char_to_isrc(isrc->owner[0]);
|
||||||
|
/* bottom 4 bits of [2] is part of the first owner code */
|
||||||
|
q[2] += (c >> 2);
|
||||||
|
/* top 2 bits of [3] is the rest of the first owner code */
|
||||||
|
q[3] = c << 6;
|
||||||
|
c = char_to_isrc(isrc->owner[1]);
|
||||||
|
/* bottom 6 bits of [3] is the entire second owner code */
|
||||||
|
q[3] += c;
|
||||||
|
c = char_to_isrc(isrc->owner[2]);
|
||||||
|
/* top 6 bits of [4] are the third owner code */
|
||||||
|
q[4] = c << 2;
|
||||||
|
|
||||||
|
/* [5] is the year in 2 BCD numbers */
|
||||||
|
q[5] = dec_to_bcd(isrc->year % 100);
|
||||||
|
/* [6] is the first 2 digits in the serial */
|
||||||
|
q[6] = dec_to_bcd(isrc->serial % 100);
|
||||||
|
/* [7] is the next 2 digits in the serial */
|
||||||
|
q[7] = dec_to_bcd((isrc->serial / 100) % 100);
|
||||||
|
/* the top 4 bits of [8] is the last serial digit, the rest is
|
||||||
|
zeros */
|
||||||
|
q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4;
|
||||||
|
burn_lba_to_msf(d->alba, &m, &s, &f);
|
||||||
|
q[9] = dec_to_bcd(f); /* abs frame */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
q[0] = (control << 4) + qmode;
|
||||||
|
|
||||||
|
crc = crc_ccitt(q, 10);
|
||||||
|
q[10] = crc >> 8;
|
||||||
|
q[11] = crc & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char subs[96];
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
data = get_sector(o, NULL, mode);
|
||||||
|
if (!data)
|
||||||
|
return 0;
|
||||||
|
/* ts A61010 */
|
||||||
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
|
return 0;
|
||||||
|
subcode_lout(o, control, subs);
|
||||||
|
convert_subs(o, mode, subs, data);
|
||||||
|
sector_headers(o, data, mode, 0);
|
||||||
|
sector_common(++)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned char subs[96];
|
||||||
|
unsigned char *data;
|
||||||
|
|
||||||
|
data = get_sector(o, t, t->mode);
|
||||||
|
if (!data)
|
||||||
|
return 0;
|
||||||
|
/* ts A61010 */
|
||||||
|
if (convert_data(o, t, t->mode, data) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
if (t->open_ended && t->track_data_done) {
|
||||||
|
unget_sector(o, t->mode);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61219 : allow track without .entry */
|
||||||
|
if (t->entry == NULL)
|
||||||
|
;
|
||||||
|
else if (!t->source->read_sub)
|
||||||
|
subcode_user(o, subs, t->entry->point,
|
||||||
|
t->entry->control, 1, &t->isrc, psub);
|
||||||
|
else if (!t->source->read_sub(t->source, subs, 96))
|
||||||
|
subcode_user(o, subs, t->entry->point,
|
||||||
|
t->entry->control, 1, &t->isrc, psub);
|
||||||
|
convert_subs(o, t->mode, subs, data);
|
||||||
|
|
||||||
|
sector_headers(o, data, t->mode, 0);
|
||||||
|
sector_common(++)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_msf_to_lba(int m, int s, int f)
|
||||||
|
{
|
||||||
|
if (m < 90)
|
||||||
|
return (m * 60 + s) * 75 + f - 150;
|
||||||
|
else
|
||||||
|
return (m * 60 + s) * 75 + f - 450150;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_lba_to_msf(int lba, int *m, int *s, int *f)
|
||||||
|
{
|
||||||
|
if (lba >= -150) {
|
||||||
|
*m = (lba + 150) / (60 * 75);
|
||||||
|
*s = (lba + 150 - *m * 60 * 75) / 75;
|
||||||
|
*f = lba + 150 - *m * 60 * 75 - *s * 75;
|
||||||
|
} else {
|
||||||
|
*m = (lba + 450150) / (60 * 75);
|
||||||
|
*s = (lba + 450150 - *m * 60 * 75) / 75;
|
||||||
|
*f = lba + 450150 - *m * 60 * 75 - *s * 75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dec_to_bcd(int d)
|
||||||
|
{
|
||||||
|
int top, bottom;
|
||||||
|
|
||||||
|
top = d / 10;
|
||||||
|
bottom = d - (top * 10);
|
||||||
|
return (top << 4) + bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sector_headers_is_ok(struct burn_write_opts *o, int mode)
|
||||||
|
{
|
||||||
|
if (mode & BURN_AUDIO) /* no headers for "audio" */
|
||||||
|
return 1;
|
||||||
|
if (o->write_type == BURN_WRITE_SAO)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
if (o->write_type == BURN_WRITE_TAO)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (mode & BURN_MODE1)
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||||
|
int mode, int leadin)
|
||||||
|
{
|
||||||
|
struct burn_drive *d = o->drive;
|
||||||
|
unsigned int crc;
|
||||||
|
int min, sec, frame;
|
||||||
|
int modebyte = -1;
|
||||||
|
|
||||||
|
/* ts A61009 */
|
||||||
|
#if 1
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sector_headers_is_ok(o, mode);
|
||||||
|
if (ret != 2)
|
||||||
|
return;
|
||||||
|
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;
|
||||||
|
memset(out + 1, 0xFF, 10); /* sync */
|
||||||
|
out[11] = 0;
|
||||||
|
|
||||||
|
if (leadin) {
|
||||||
|
burn_lba_to_msf(d->rlba, &min, &sec, &frame);
|
||||||
|
out[12] = dec_to_bcd(min) + 0xA0;
|
||||||
|
out[13] = dec_to_bcd(sec);
|
||||||
|
out[14] = dec_to_bcd(frame);
|
||||||
|
out[15] = modebyte;
|
||||||
|
} else {
|
||||||
|
burn_lba_to_msf(d->alba, &min, &sec, &frame);
|
||||||
|
out[12] = dec_to_bcd(min);
|
||||||
|
out[13] = dec_to_bcd(sec);
|
||||||
|
out[14] = dec_to_bcd(frame);
|
||||||
|
out[15] = modebyte;
|
||||||
|
}
|
||||||
|
if (mode & BURN_MODE1) {
|
||||||
|
crc = crc_32(out, 2064);
|
||||||
|
out[2064] = crc & 0xFF;
|
||||||
|
crc >>= 8;
|
||||||
|
out[2065] = crc & 0xFF;
|
||||||
|
crc >>= 8;
|
||||||
|
out[2066] = crc & 0xFF;
|
||||||
|
crc >>= 8;
|
||||||
|
out[2067] = crc & 0xFF;
|
||||||
|
}
|
||||||
|
if (mode & BURN_MODE1) {
|
||||||
|
memset(out + 2068, 0, 8);
|
||||||
|
parity_p(out);
|
||||||
|
parity_q(out);
|
||||||
|
}
|
||||||
|
scramble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
|
{
|
||||||
|
unsigned char i[5];
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
mode = q[0] & 0xF;
|
||||||
|
/* burn_print(12, "mode: %d : ", mode);*/
|
||||||
|
switch (mode) {
|
||||||
|
case 1:
|
||||||
|
/* burn_print(12, "tno = %d : ", q[1]);
|
||||||
|
burn_print(12, "index = %d\n", q[2]);
|
||||||
|
*/
|
||||||
|
/* q[1] is the track number (starting at 1) q[2] is the index
|
||||||
|
number (starting at 0) */
|
||||||
|
#warning this is totally bogus
|
||||||
|
if (q[1] - 1 > 99)
|
||||||
|
break;
|
||||||
|
if (q[2] > d->toc->track[q[1] - 1].indices) {
|
||||||
|
burn_print(12, "new index at %d\n", d->alba);
|
||||||
|
d->toc->track[q[1] - 1].index[q[2]] = d->alba;
|
||||||
|
d->toc->track[q[1] - 1].indices++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* XXX dont ignore these */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
||||||
|
i[0] = isrc[(q[1] << 2) >> 2];
|
||||||
|
/* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
|
||||||
|
burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
/* ts A61009 : if reactivated then witout Assert */
|
||||||
|
a ssert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this needs more info. subs in the data? control/adr? */
|
||||||
|
|
||||||
|
/* ts A61119 : One should not use inofficial compiler extensions.
|
||||||
|
>>> Some day this function needs to be implemented. At least for now
|
||||||
|
the result does not match the "mode" of cdrecord -toc.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#warning sector_identify needs to be written
|
||||||
|
*/
|
||||||
|
int sector_identify(unsigned char *data)
|
||||||
|
{
|
||||||
|
scramble(data);
|
||||||
|
/*
|
||||||
|
check mode byte for 1 or 2
|
||||||
|
test parity to see if it's a valid sector
|
||||||
|
if invalid, return BURN_MODE_AUDIO;
|
||||||
|
else return mode byte (what about mode 2 formless? heh)
|
||||||
|
*/
|
||||||
|
return BURN_MODE1;
|
||||||
|
}
|
35
libburn/tags/ZeroThreeZero/libburn/sector.h
Normal file
35
libburn/tags/ZeroThreeZero/libburn/sector.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __SECTOR
|
||||||
|
#define __SECTOR
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
struct isrc;
|
||||||
|
|
||||||
|
int dec_to_bcd(int);
|
||||||
|
|
||||||
|
int sector_toc(struct burn_write_opts *, int mode);
|
||||||
|
int sector_pregap(struct burn_write_opts *, unsigned char tno,
|
||||||
|
unsigned char control, int mode);
|
||||||
|
int sector_postgap(struct burn_write_opts *, unsigned char tno,
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* ts A61009 */
|
||||||
|
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
||||||
|
|
||||||
|
void sector_headers(struct burn_write_opts *, unsigned char *,
|
||||||
|
int mode, int leadin);
|
||||||
|
void subcode_user(struct burn_write_opts *, unsigned char *s,
|
||||||
|
unsigned char tno, unsigned char control,
|
||||||
|
unsigned char index, struct isrc *isrc, int psub);
|
||||||
|
|
||||||
|
int sector_identify(unsigned char *);
|
||||||
|
|
||||||
|
void process_q(struct burn_drive *d, unsigned char *q);
|
||||||
|
|
||||||
|
#endif /* __SECTOR */
|
559
libburn/tags/ZeroThreeZero/libburn/sg-freebsd-port.c
Normal file
559
libburn/tags/ZeroThreeZero/libburn/sg-freebsd-port.c
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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: FreeBSD CAM (untested)
|
||||||
|
|
||||||
|
|
||||||
|
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_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_drive_is_open() tells wether 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 wether the command succeeded or shall
|
||||||
|
be retried or finally failed.
|
||||||
|
|
||||||
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
|
Porting hints are marked by the text "PORTING:".
|
||||||
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <camlib.h>
|
||||||
|
#include <cam/scsi/scsi_message.h>
|
||||||
|
#include <cam/scsi/scsi_pass.h>
|
||||||
|
|
||||||
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "spc.h"
|
||||||
|
#include "mmc.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "util.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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* ts A61115: Private functions. Port only if needed by public functions */
|
||||||
|
/* (Public functions are listed below) */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function for scsi_give_next_adr() */
|
||||||
|
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
idx->skip_device = 0;
|
||||||
|
|
||||||
|
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
|
warn("couldn't open %s", XPT_DEVICE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&(idx->ccb), sizeof(union ccb));
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
|
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
|
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
|
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||||
|
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
||||||
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
|
warnx("can't malloc memory for matches");
|
||||||
|
close(idx->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
idx->ccb.cdm.num_matches = 0;
|
||||||
|
idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fetch all nodes, since we display most of them in the default
|
||||||
|
* case, and all in the verbose case.
|
||||||
|
*/
|
||||||
|
idx->ccb.cdm.num_patterns = 0;
|
||||||
|
idx->ccb.cdm.pattern_buf_len = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function for scsi_give_next_adr() */
|
||||||
|
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We do the ioctl multiple times if necessary, in case there are
|
||||||
|
* more than 100 nodes in the EDT.
|
||||||
|
*/
|
||||||
|
if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) {
|
||||||
|
warn("error sending CAMIOCOMMAND ioctl");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((idx->ccb.ccb_h.status != CAM_REQ_CMP)
|
||||||
|
|| ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST)
|
||||||
|
&& (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
|
||||||
|
warnx("got CAM error %#x, CDM error %d\n",
|
||||||
|
idx->ccb.ccb_h.status, idx->ccb.cdm.status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_close_drive(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
if (d->cam != NULL) {
|
||||||
|
cam_close_device(d->cam);
|
||||||
|
d->cam = NULL;
|
||||||
|
}
|
||||||
|
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 --------------- */
|
||||||
|
|
||||||
|
/* Operating system adapter is CAM */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
|
out.cam = NULL;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61115 */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* PORTING: Public functions. These MUST be ported. */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/** 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 latter.)
|
||||||
|
@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 = sg_init_enumerator(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
} else if (initialize == -1) {
|
||||||
|
if(idx->fd != -1)
|
||||||
|
close(idx->fd);
|
||||||
|
idx->fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||||
|
|
||||||
|
/* Loop content from old scsi_enumerate_drives() */
|
||||||
|
|
||||||
|
while (idx->i >= idx->ccb.cdm.num_matches) {
|
||||||
|
ret = sg_next_enumeration_buffer(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return -1;
|
||||||
|
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
|
||||||
|
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
|
||||||
|
return 0;
|
||||||
|
idx->i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (idx->ccb.cdm.matches[idx->i].type) {
|
||||||
|
case DEV_MATCH_BUS:
|
||||||
|
break;
|
||||||
|
case DEV_MATCH_DEVICE: {
|
||||||
|
struct device_match_result* result;
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.device_result);
|
||||||
|
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||||
|
idx->skip_device = 1;
|
||||||
|
else
|
||||||
|
idx->skip_device = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEV_MATCH_PERIPH: {
|
||||||
|
struct periph_match_result* result;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
if (idx->skip_device ||
|
||||||
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
|
break;
|
||||||
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
|
result->periph_name, result->unit_number);
|
||||||
|
if(adr_size <= strlen(buf)
|
||||||
|
return -1;
|
||||||
|
strcpy(adr, buf);
|
||||||
|
|
||||||
|
/* Found next enumerable address */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* printf(stderr, "unknown match type\n"); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(idx->i)++;
|
||||||
|
goto try_item; /* Regular function exit is return 1 above */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
continue;
|
||||||
|
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
|
||||||
|
0, idx.result->target_id,
|
||||||
|
idx.result->target_lun);
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells wether 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 resp. reservation.
|
||||||
|
*/
|
||||||
|
/** Published as burn_drive.drive_is_open() */
|
||||||
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
return (d->cam != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
struct cam_device *cam;
|
||||||
|
|
||||||
|
if(d->cam != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
|
if (cam == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020003,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not grab drive", 0/*os_errno*/, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
d->cam = cam;
|
||||||
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** PORTING: Is mainly about the call to sg_close_drive() and wether 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->cam == NULL) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sg_close_drive(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
|
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 done = 0;
|
||||||
|
int err;
|
||||||
|
union ccb *ccb;
|
||||||
|
|
||||||
|
if (d->cam == NULL) {
|
||||||
|
c->error = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->error = 0;
|
||||||
|
|
||||||
|
ccb = cam_getccb(d->cam);
|
||||||
|
cam_fill_csio(&ccb->csio,
|
||||||
|
1, /* retries */
|
||||||
|
NULL, /* cbfncp */
|
||||||
|
CAM_DEV_QFRZDIS, /* flags */
|
||||||
|
MSG_SIMPLE_Q_TAG, /* tag_action */
|
||||||
|
NULL, /* data_ptr */
|
||||||
|
0, /* dxfer_len */
|
||||||
|
sizeof (ccb->csio.sense_data), /* sense_len */
|
||||||
|
0, /* cdb_len */
|
||||||
|
30*1000); /* timeout */
|
||||||
|
switch (c->dir) {
|
||||||
|
case TO_DRIVE:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
||||||
|
break;
|
||||||
|
case FROM_DRIVE:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_IN;
|
||||||
|
break;
|
||||||
|
case NO_TRANSFER:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccb->csio.cdb_len = 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) {
|
||||||
|
ccb->csio.data_ptr = c->page->data;
|
||||||
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
ccb->csio.dxfer_len = BUFFER_SIZE;
|
||||||
|
/* touch page so we can use valgrind */
|
||||||
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* ts A61115: removed a ssert() */
|
||||||
|
if(c->page->bytes <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ccb->csio.dxfer_len = c->page->bytes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ccb->csio.data_ptr = NULL;
|
||||||
|
ccb->csio.dxfer_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
|
if (err == -1) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002010c,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Failed to transfer command to drive",
|
||||||
|
errno, 0);
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
sg_close_drive(d);
|
||||||
|
d->released = 1;
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
c->error = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* XXX */
|
||||||
|
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
||||||
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
|
if (!c->retry) {
|
||||||
|
c->error = 1;
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
switch (scsi_error(d, c->sense, 0)) {
|
||||||
|
case RETRY:
|
||||||
|
done = 0;
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
done = 1;
|
||||||
|
c->error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
struct periph_match_result* result;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) != 0)
|
||||||
|
continue;
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
*bus_no = result->path_id;
|
||||||
|
*host_no = result->path_id;
|
||||||
|
*channel_no = 0;
|
||||||
|
*target_no = result->target_id
|
||||||
|
*lun_no = result->target_lun;
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tells wether 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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
697
libburn/tags/ZeroThreeZero/libburn/sg-freebsd.c
Normal file
697
libburn/tags/ZeroThreeZero/libburn/sg-freebsd.c
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Revives old enumerate_common(). New version delegates much work
|
||||||
|
to methods in drive, mmc, spc, and sbc .
|
||||||
|
*/
|
||||||
|
#define Scsi_freebsd_make_own_enumeratE 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Revives old scsi_enumerate_drives(). New version delegates most work to
|
||||||
|
sg_give_next_adr().
|
||||||
|
*/
|
||||||
|
#define Scsi_freebsd_old_scsi_enumeratE 1
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <camlib.h>
|
||||||
|
#include <cam/scsi/scsi_message.h>
|
||||||
|
#include <cam/scsi/scsi_pass.h>
|
||||||
|
|
||||||
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "sg.h"
|
||||||
|
#include "spc.h"
|
||||||
|
#include "mmc.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "toc.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no);
|
||||||
|
|
||||||
|
/* ts A51221 */
|
||||||
|
int burn_drive_is_banned(char *device_address);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60821
|
||||||
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
|
int mmc_function_spy(char * text);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_old_scsi_enumeratE
|
||||||
|
|
||||||
|
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
|
char adr[], int adr_size, int initialize)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Scsi_freebsd_old_scsi_enumeratE */
|
||||||
|
|
||||||
|
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
||||||
|
sg_give_next_adr() */
|
||||||
|
/* Some helper functions for scsi_give_next_adr() */
|
||||||
|
|
||||||
|
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
idx->skip_device = 0;
|
||||||
|
|
||||||
|
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
|
warn("couldn't open %s", XPT_DEVICE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&(idx->ccb), sizeof(union ccb));
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
|
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
|
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
|
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||||
|
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
||||||
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
|
warnx("can't malloc memory for matches");
|
||||||
|
close(idx->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
idx->ccb.cdm.num_matches = 0;
|
||||||
|
idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fetch all nodes, since we display most of them in the default
|
||||||
|
* case, and all in the verbose case.
|
||||||
|
*/
|
||||||
|
idx->ccb.cdm.num_patterns = 0;
|
||||||
|
idx->ccb.cdm.pattern_buf_len = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We do the ioctl multiple times if necessary, in case there are
|
||||||
|
* more than 100 nodes in the EDT.
|
||||||
|
*/
|
||||||
|
if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) {
|
||||||
|
warn("error sending CAMIOCOMMAND ioctl");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((idx->ccb.ccb_h.status != CAM_REQ_CMP)
|
||||||
|
|| ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST)
|
||||||
|
&& (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
|
||||||
|
warnx("got CAM error %#x, CDM error %d\n",
|
||||||
|
idx->ccb.ccb_h.status, idx->ccb.cdm.status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
|
@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 = sg_init_enumerator(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
} else if (initialize == -1) {
|
||||||
|
if(idx->fd != -1)
|
||||||
|
close(idx->fd);
|
||||||
|
idx->fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||||
|
|
||||||
|
/* Loop content from old scsi_enumerate_drives() */
|
||||||
|
|
||||||
|
while (idx->i >= idx->ccb.cdm.num_matches) {
|
||||||
|
ret = sg_next_enumeration_buffer(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return -1;
|
||||||
|
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
|
||||||
|
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
|
||||||
|
return 0;
|
||||||
|
idx->i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (idx->ccb.cdm.matches[idx->i].type) {
|
||||||
|
case DEV_MATCH_BUS:
|
||||||
|
break;
|
||||||
|
case DEV_MATCH_DEVICE: {
|
||||||
|
struct device_match_result* result;
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.device_result);
|
||||||
|
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||||
|
idx->skip_device = 1;
|
||||||
|
else
|
||||||
|
idx->skip_device = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEV_MATCH_PERIPH: {
|
||||||
|
struct periph_match_result* result;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
if (idx->skip_device ||
|
||||||
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
|
break;
|
||||||
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
|
result->periph_name, result->unit_number);
|
||||||
|
if(adr_size <= strlen(buf)
|
||||||
|
return -1;
|
||||||
|
strcpy(adr, buf);
|
||||||
|
|
||||||
|
/* Found next enumerable address */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* printf(stderr, "unknown match type\n"); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(idx->i)++;
|
||||||
|
goto try_item; /* Regular function exit is return 1 above */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Try 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)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
struct periph_match_result* result;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) != 0)
|
||||||
|
continue;
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
*bus_no = result->path_id;
|
||||||
|
*host_no = result->path_id;
|
||||||
|
*channel_no = 0;
|
||||||
|
*target_no = result->target_id
|
||||||
|
*lun_no = result->target_lun;
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
|
||||||
|
|
||||||
|
|
||||||
|
int sg_close_drive(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
if (d->cam != NULL) {
|
||||||
|
cam_close_device(d->cam);
|
||||||
|
d->cam = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
return (d->cam != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int scsi_enumerate_drives(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_old_scsi_enumeratE
|
||||||
|
|
||||||
|
union ccb ccb;
|
||||||
|
int bufsize, fd;
|
||||||
|
unsigned int i;
|
||||||
|
int skip_device = 0;
|
||||||
|
|
||||||
|
if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
|
warn("couldn't open %s", XPT_DEVICE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&ccb, sizeof(union ccb));
|
||||||
|
|
||||||
|
ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
|
ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||||
|
|
||||||
|
ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
|
bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
|
ccb.cdm.match_buf_len = bufsize;
|
||||||
|
ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
||||||
|
if (ccb.cdm.matches == NULL) {
|
||||||
|
warnx("can't malloc memory for matches");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ccb.cdm.num_matches = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fetch all nodes, since we display most of them in the default
|
||||||
|
* case, and all in the verbose case.
|
||||||
|
*/
|
||||||
|
ccb.cdm.num_patterns = 0;
|
||||||
|
ccb.cdm.pattern_buf_len = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do the ioctl multiple times if necessary, in case there are
|
||||||
|
* more than 100 nodes in the EDT.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
|
||||||
|
warn("error sending CAMIOCOMMAND ioctl");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ccb.ccb_h.status != CAM_REQ_CMP)
|
||||||
|
|| ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
|
||||||
|
&& (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
|
||||||
|
warnx("got CAM error %#x, CDM error %d\n",
|
||||||
|
ccb.ccb_h.status, ccb.cdm.status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ccb.cdm.num_matches; i++) {
|
||||||
|
switch (ccb.cdm.matches[i].type) {
|
||||||
|
case DEV_MATCH_BUS:
|
||||||
|
break;
|
||||||
|
case DEV_MATCH_DEVICE: {
|
||||||
|
struct device_match_result* result;
|
||||||
|
|
||||||
|
result = &ccb.cdm.matches[i].result.device_result;
|
||||||
|
|
||||||
|
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||||
|
skip_device = 1;
|
||||||
|
else
|
||||||
|
skip_device = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEV_MATCH_PERIPH: {
|
||||||
|
struct periph_match_result* result;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
result = &ccb.cdm.matches[i].result.periph_result;
|
||||||
|
if (skip_device || strcmp(result->periph_name, "pass") == 0)
|
||||||
|
break;
|
||||||
|
snprintf(buf, sizeof (buf), "/dev/%s%d", result->periph_name, result->unit_number);
|
||||||
|
/* ts A51221 */
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
break;
|
||||||
|
|
||||||
|
enumerate_common(buf, result->path_id, result->path_id, 0,
|
||||||
|
result->target_id, result->target_lun);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fprintf(stdout, "unknown match type\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ((ccb.ccb_h.status == CAM_REQ_CMP)
|
||||||
|
&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
#else /* Scsi_freebsd_old_scsi_enumeratE */
|
||||||
|
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
continue;
|
||||||
|
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
|
||||||
|
0, idx.result->target_id,
|
||||||
|
idx.result->target_lun);
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
|
||||||
|
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_make_own_enumeratE
|
||||||
|
|
||||||
|
/* ts A61021: The old version which mixes SCSI and operating system adapter
|
||||||
|
*/
|
||||||
|
static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no)
|
||||||
|
{
|
||||||
|
struct burn_drive *t;
|
||||||
|
struct burn_drive out;
|
||||||
|
|
||||||
|
/* ts A60923 */
|
||||||
|
out.bus_no = bus_no;
|
||||||
|
out.host = host_no;
|
||||||
|
out.id = target_no;
|
||||||
|
out.channel = channel_no;
|
||||||
|
out.lun = lun_no;
|
||||||
|
|
||||||
|
out.devname = burn_strdup(fname);
|
||||||
|
out.cam = NULL;
|
||||||
|
|
||||||
|
out.start_lba= -2000000000;
|
||||||
|
out.end_lba= -2000000000;
|
||||||
|
out.read_atip = mmc_read_atip;
|
||||||
|
|
||||||
|
out.grab = sg_grab;
|
||||||
|
out.release = sg_release;
|
||||||
|
out.drive_is_open= sg_drive_is_open;
|
||||||
|
out.issue_command = sg_issue_command;
|
||||||
|
out.getcaps = spc_getcaps;
|
||||||
|
out.released = 1;
|
||||||
|
out.status = BURN_DISC_UNREADY;
|
||||||
|
|
||||||
|
out.eject = sbc_eject;
|
||||||
|
out.load = sbc_load;
|
||||||
|
out.lock = spc_prevent;
|
||||||
|
out.unlock = spc_allow;
|
||||||
|
out.read_disc_info = spc_sense_write_params;
|
||||||
|
out.get_erase_progress = spc_get_erase_progress;
|
||||||
|
out.test_unit_ready = spc_test_unit_ready;
|
||||||
|
out.probe_write_modes = spc_probe_write_modes;
|
||||||
|
out.read_toc = mmc_read_toc;
|
||||||
|
out.write = mmc_write;
|
||||||
|
out.erase = mmc_erase;
|
||||||
|
out.read_sectors = mmc_read_sectors;
|
||||||
|
out.perform_opc = mmc_perform_opc;
|
||||||
|
out.set_speed = mmc_set_speed;
|
||||||
|
out.send_parameters = spc_select_error_params;
|
||||||
|
out.send_write_parameters = spc_select_write_params;
|
||||||
|
out.send_cue_sheet = mmc_send_cue_sheet;
|
||||||
|
out.sync_cache = mmc_sync_cache;
|
||||||
|
out.get_nwa = mmc_get_nwa;
|
||||||
|
out.close_disc = mmc_close_disc;
|
||||||
|
out.close_session = mmc_close_session;
|
||||||
|
out.close_track_session = mmc_close;
|
||||||
|
out.read_buffer_capacity = mmc_read_buffer_capacity;
|
||||||
|
out.idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
||||||
|
out.idata->valid = 0;
|
||||||
|
out.mdata = malloc(sizeof(struct scsi_mode_data));
|
||||||
|
out.mdata->valid = 0;
|
||||||
|
if (out.idata == NULL || out.mdata == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not allocate new drive object", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(&out.params, 0, sizeof(struct params));
|
||||||
|
t = burn_drive_register(&out);
|
||||||
|
|
||||||
|
/* ts A60821
|
||||||
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
|
mmc_function_spy("enumerate_common : -------- doing grab");
|
||||||
|
|
||||||
|
/* try to get the drive info */
|
||||||
|
if (t->grab(t)) {
|
||||||
|
burn_print(2, "getting drive info\n");
|
||||||
|
t->getcaps(t);
|
||||||
|
t->unlock(t);
|
||||||
|
t->released = 1;
|
||||||
|
} else {
|
||||||
|
burn_print(2, "unable to grab new located drive\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A60821
|
||||||
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
|
mmc_function_spy("enumerate_common : ----- would release ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
|
/* The new, more concise version of enumerate_common */
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Operating system adapter is CAM */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
|
out.cam = NULL;
|
||||||
|
/* Adapter specific functions */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
|
drive or not.
|
||||||
|
if refcount is not one, drive is open somewhere else.
|
||||||
|
*/
|
||||||
|
int sg_grab(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
struct cam_device *cam;
|
||||||
|
|
||||||
|
mmc_function_spy("sg_grab");
|
||||||
|
|
||||||
|
assert(d->cam == NULL);
|
||||||
|
|
||||||
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
|
if (cam == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not grab drive", 0/*os_errno*/, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/
|
||||||
|
count = 1;
|
||||||
|
if (1 == count) {
|
||||||
|
d->cam = cam;
|
||||||
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
|
d->released = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
burn_print(1, "could not acquire drive - already open\n");
|
||||||
|
sg_close_drive(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
non zero return means you still have the drive and it's not
|
||||||
|
in a state to be released? (is that even possible?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int sg_release(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
mmc_function_spy("sg_release");
|
||||||
|
|
||||||
|
if (d->cam == NULL) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mmc_function_spy("sg_release ----------- closing.");
|
||||||
|
|
||||||
|
sg_close_drive(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
|
{
|
||||||
|
int done = 0;
|
||||||
|
int err;
|
||||||
|
union ccb *ccb;
|
||||||
|
|
||||||
|
char buf[161];
|
||||||
|
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
||||||
|
(void*)d->cam, d->released);
|
||||||
|
mmc_function_spy(buf);
|
||||||
|
|
||||||
|
if (d->cam == NULL) {
|
||||||
|
c->error = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->error = 0;
|
||||||
|
|
||||||
|
ccb = cam_getccb(d->cam);
|
||||||
|
cam_fill_csio(&ccb->csio,
|
||||||
|
1, /* retries */
|
||||||
|
NULL, /* cbfncp */
|
||||||
|
CAM_DEV_QFRZDIS, /* flags */
|
||||||
|
MSG_SIMPLE_Q_TAG, /* tag_action */
|
||||||
|
NULL, /* data_ptr */
|
||||||
|
0, /* dxfer_len */
|
||||||
|
sizeof (ccb->csio.sense_data), /* sense_len */
|
||||||
|
0, /* cdb_len */
|
||||||
|
30*1000); /* timeout */
|
||||||
|
switch (c->dir) {
|
||||||
|
case TO_DRIVE:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
||||||
|
break;
|
||||||
|
case FROM_DRIVE:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_IN;
|
||||||
|
break;
|
||||||
|
case NO_TRANSFER:
|
||||||
|
ccb->csio.ccb_h.flags |= CAM_DIR_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccb->csio.cdb_len = 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) {
|
||||||
|
ccb->csio.data_ptr = c->page->data;
|
||||||
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
ccb->csio.dxfer_len = BUFFER_SIZE;
|
||||||
|
/* touch page so we can use valgrind */
|
||||||
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
assert(c->page->bytes > 0);
|
||||||
|
ccb->csio.dxfer_len = c->page->bytes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ccb->csio.data_ptr = NULL;
|
||||||
|
ccb->csio.dxfer_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
|
if (err == -1) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002010c,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Failed to transfer command to drive",
|
||||||
|
errno, 0);
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
sg_close_drive(d);
|
||||||
|
d->released = 1;
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
c->error = 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* XXX */
|
||||||
|
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
||||||
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
|
if (!c->retry) {
|
||||||
|
c->error = 1;
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
switch (scsi_error(d, c->sense, 0)) {
|
||||||
|
case RETRY:
|
||||||
|
done = 0;
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
done = 1;
|
||||||
|
c->error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
cam_freeccb(ccb);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
1104
libburn/tags/ZeroThreeZero/libburn/sg-linux.c
Normal file
1104
libburn/tags/ZeroThreeZero/libburn/sg-linux.c
Normal file
File diff suppressed because it is too large
Load Diff
17
libburn/tags/ZeroThreeZero/libburn/sg.c
Normal file
17
libburn/tags/ZeroThreeZero/libburn/sg.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
/* sg.c
|
||||||
|
Switcher for operating system dependent transport level modules of libburn.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
#include "sg-freebsd.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "sg-linux.c"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
34
libburn/tags/ZeroThreeZero/libburn/sg.h
Normal file
34
libburn/tags/ZeroThreeZero/libburn/sg.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __SG
|
||||||
|
#define __SG
|
||||||
|
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* see os.h for name of particular os-*.h where this is defined */
|
||||||
|
BURN_OS_DEFINE_DRIVE_ENUMERATOR_T
|
||||||
|
|
||||||
|
|
||||||
|
struct burn_drive;
|
||||||
|
struct command;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60922 ticket 33 */
|
||||||
|
int sg_give_next_adr(burn_drive_enumerator_t *enm_context,
|
||||||
|
char adr[], int adr_size, int initialize);
|
||||||
|
int sg_is_enumerable_adr(char *adr);
|
||||||
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no);
|
||||||
|
|
||||||
|
int sg_grab(struct burn_drive *);
|
||||||
|
int sg_release(struct burn_drive *);
|
||||||
|
int sg_issue_command(struct burn_drive *, struct command *);
|
||||||
|
|
||||||
|
/* ts A61115 : formerly sg_enumerate();ata_enumerate() */
|
||||||
|
int scsi_enumerate_drives(void);
|
||||||
|
|
||||||
|
int sg_drive_is_open(struct burn_drive * d);
|
||||||
|
|
||||||
|
#endif /* __SG */
|
39
libburn/tags/ZeroThreeZero/libburn/source.c
Normal file
39
libburn/tags/ZeroThreeZero/libburn/source.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "source.h"
|
||||||
|
#include "structure.h"
|
||||||
|
|
||||||
|
void burn_source_free(struct burn_source *src)
|
||||||
|
{
|
||||||
|
if (--src->refcount < 1) {
|
||||||
|
if (src->free_data)
|
||||||
|
src->free_data(src);
|
||||||
|
free(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum burn_source_status burn_track_set_source(struct burn_track *t,
|
||||||
|
struct burn_source *s)
|
||||||
|
{
|
||||||
|
if (!s->read)
|
||||||
|
return BURN_SOURCE_FAILED;
|
||||||
|
s->refcount++;
|
||||||
|
t->source = s;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
t->open_ended = (s->get_size(s) <= 0);
|
||||||
|
|
||||||
|
return BURN_SOURCE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_source *burn_source_new(void)
|
||||||
|
{
|
||||||
|
struct burn_source *out;
|
||||||
|
|
||||||
|
out = calloc(1, sizeof(struct burn_source));
|
||||||
|
out->refcount = 1;
|
||||||
|
return out;
|
||||||
|
}
|
8
libburn/tags/ZeroThreeZero/libburn/source.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/source.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __SOURCE
|
||||||
|
#define __SOURCE
|
||||||
|
|
||||||
|
struct burn_source *burn_source_new(void);
|
||||||
|
|
||||||
|
#endif /*__SOURCE*/
|
752
libburn/tags/ZeroThreeZero/libburn/spc.c
Normal file
752
libburn/tags/ZeroThreeZero/libburn/spc.c
Normal file
@ -0,0 +1,752 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* scsi primary commands */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "transport.h"
|
||||||
|
#include "spc.h"
|
||||||
|
#include "mmc.h"
|
||||||
|
#include "sbc.h"
|
||||||
|
#include "drive.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/* spc command set */
|
||||||
|
static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 255, 0 };
|
||||||
|
|
||||||
|
/*static char SPC_TEST[]={0,0,0,0,0,0};*/
|
||||||
|
static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
|
||||||
|
static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
|
||||||
|
static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
|
static unsigned char SPC_MODE_SELECT[] =
|
||||||
|
{ 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
|
||||||
|
static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
int spc_test_unit_ready(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
c.retry = 0;
|
||||||
|
c.oplen = sizeof(SPC_TEST_UNIT_READY);
|
||||||
|
memcpy(c.opcode, SPC_TEST_UNIT_READY, sizeof(SPC_TEST_UNIT_READY));
|
||||||
|
c.page = NULL;
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
if (c.error)
|
||||||
|
return (c.sense[2] & 0xF) == 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_request_sense(struct burn_drive *d, struct buffer *buf)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
c.retry = 0;
|
||||||
|
c.oplen = sizeof(SPC_REQUEST_SENSE);
|
||||||
|
memcpy(c.opcode, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE));
|
||||||
|
c.page = buf;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spc_get_erase_progress(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer b;
|
||||||
|
|
||||||
|
spc_request_sense(d, &b);
|
||||||
|
return (b.data[16] << 8) | b.data[17];
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_inquiry(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct burn_scsi_inquiry_data *id;
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_INQUIRY);
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
|
id = (struct burn_scsi_inquiry_data *)d->idata;
|
||||||
|
id->vendor[8] = 0;
|
||||||
|
id->product[16] = 0;
|
||||||
|
id->revision[4] = 0;
|
||||||
|
|
||||||
|
memcpy(id->vendor, c.page->data + 8, 8);
|
||||||
|
memcpy(id->product, c.page->data + 16, 16);
|
||||||
|
memcpy(id->revision, c.page->data + 32, 4);
|
||||||
|
|
||||||
|
id->valid = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_prevent(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_PREVENT);
|
||||||
|
c.page = NULL;
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_allow(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_ALLOW, sizeof(SPC_ALLOW));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_ALLOW);
|
||||||
|
c.page = NULL;
|
||||||
|
c.dir = NO_TRANSFER;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_sense_caps(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct scsi_mode_data *m;
|
||||||
|
int size, page_length, num_write_speeds = 0, i, speed, ret;
|
||||||
|
unsigned char *page;
|
||||||
|
struct command c;
|
||||||
|
struct burn_speed_descriptor *sd;
|
||||||
|
|
||||||
|
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
|
||||||
|
static int speed_debug = 0;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SENSE);
|
||||||
|
c.opcode[2] = 0x2A;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
|
m = d->mdata;
|
||||||
|
page = c.page->data + 8;
|
||||||
|
|
||||||
|
/* ts A61225 :
|
||||||
|
Although MODE SENSE indeed belongs to SPC, the returned code page
|
||||||
|
2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
|
||||||
|
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
|
||||||
|
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
|
||||||
|
*/
|
||||||
|
page_length = page[1];
|
||||||
|
|
||||||
|
m->valid = 0;
|
||||||
|
burn_mdata_free_subs(m);
|
||||||
|
|
||||||
|
m->buffer_size = page[12] * 256 + page[13];
|
||||||
|
m->dvdram_read = page[2] & 32;
|
||||||
|
m->dvdram_write = page[3] & 32;
|
||||||
|
m->dvdr_read = page[2] & 16;
|
||||||
|
m->dvdr_write = page[3] & 16;
|
||||||
|
m->dvdrom_read = page[2] & 8;
|
||||||
|
m->simulate = page[3] & 4;
|
||||||
|
m->cdrw_read = page[2] & 2;
|
||||||
|
m->cdrw_write = page[3] & 2;
|
||||||
|
m->cdr_read = page[2] & 1;
|
||||||
|
m->cdr_write = page[3] & 1;
|
||||||
|
|
||||||
|
m->c2_pointers = page[5] & 16;
|
||||||
|
m->underrun_proof = page[4] & 128;
|
||||||
|
|
||||||
|
/* ts A61021 : these fields are marked obsolete in MMC 3 */
|
||||||
|
m->max_read_speed = page[8] * 256 + page[9];
|
||||||
|
m->cur_read_speed = page[14] * 256 + page[15];
|
||||||
|
|
||||||
|
m->max_write_speed = page[18] * 256 + page[19];
|
||||||
|
m->cur_write_speed = page[20] * 256 + page[21];
|
||||||
|
|
||||||
|
/* ts A61021 : New field to be set by atip (or following MMC-3 info) */
|
||||||
|
m->min_write_speed = m->max_write_speed;
|
||||||
|
|
||||||
|
/* ts A61225 : for ACh GET PERFORMANCE, Type 03h */
|
||||||
|
m->min_end_lba = 0x7fffffff;
|
||||||
|
m->max_end_lba = 0;
|
||||||
|
|
||||||
|
m->valid = 1;
|
||||||
|
|
||||||
|
mmc_get_configuration(d);
|
||||||
|
|
||||||
|
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
|
||||||
|
if (page_length < 32) /* no write speed descriptors ? */
|
||||||
|
goto try_mmc_get_performance;
|
||||||
|
|
||||||
|
m->cur_write_speed = page[28] * 256 + page[29];
|
||||||
|
|
||||||
|
if (speed_debug)
|
||||||
|
fprintf(stderr, "LIBBURN_DEBUG: cur_write_speed = %d\n",
|
||||||
|
m->cur_write_speed);
|
||||||
|
|
||||||
|
num_write_speeds = page[30] * 256 + page[31];
|
||||||
|
m->max_write_speed = m->min_write_speed = m->cur_write_speed;
|
||||||
|
for (i = 0; i < num_write_speeds; i++) {
|
||||||
|
speed = page[32 + 4*i + 2] * 256 + page[32 + 4*i + 3];
|
||||||
|
|
||||||
|
if (speed_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
|
||||||
|
i, speed, page[32 + 4*i +1] & 7);
|
||||||
|
|
||||||
|
/* ts A61226 */
|
||||||
|
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
|
||||||
|
NULL, d->mdata->speed_descriptors, 0);
|
||||||
|
if (ret > 0) {
|
||||||
|
sd = d->mdata->speed_descriptors;
|
||||||
|
sd->source = 1;
|
||||||
|
if (d->current_profile > 0) {
|
||||||
|
sd->profile_loaded = d->current_profile;
|
||||||
|
strcpy(sd->profile_name,
|
||||||
|
d->current_profile_text);
|
||||||
|
}
|
||||||
|
sd->wrc = (( page[32 + 4*i +1] & 7 ) == 1 );
|
||||||
|
sd->write_speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (speed > m->max_write_speed)
|
||||||
|
m->max_write_speed = speed;
|
||||||
|
if (speed < m->min_write_speed)
|
||||||
|
m->min_write_speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (speed_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"LIBBURN_DEBUG: 5Ah,2Ah min_write_speed = %d , max_write_speed = %d\n",
|
||||||
|
m->min_write_speed, m->max_write_speed);
|
||||||
|
|
||||||
|
try_mmc_get_performance:;
|
||||||
|
ret = mmc_get_write_performance(d);
|
||||||
|
|
||||||
|
if (ret > 0 && speed_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
|
||||||
|
m->min_write_speed, m->max_write_speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void spc_sense_error_params(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct scsi_mode_data *m;
|
||||||
|
int size;
|
||||||
|
unsigned char *page;
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SENSE);
|
||||||
|
c.opcode[2] = 0x01;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
|
m = d->mdata;
|
||||||
|
page = c.page->data + 8;
|
||||||
|
d->params.retries = page[3];
|
||||||
|
m->retry_page_length = page[1];
|
||||||
|
m->retry_page_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_select_error_params(struct burn_drive *d,
|
||||||
|
const struct burn_read_opts *o)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||||
|
c.opcode[8] = 8 + 2 + d->mdata->retry_page_length;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
|
||||||
|
/* ts A61007 : moved up to only caller burn_disc_read() */
|
||||||
|
/* a ssert(d->mdata->valid); */
|
||||||
|
|
||||||
|
memset(c.page->data, 0, 8 + 2 + d->mdata->retry_page_length);
|
||||||
|
c.page->bytes = 8 + 2 + d->mdata->retry_page_length;
|
||||||
|
c.page->data[8] = 1;
|
||||||
|
c.page->data[9] = d->mdata->retry_page_length;
|
||||||
|
if (o->transfer_damaged_blocks)
|
||||||
|
c.page->data[10] |= 32;
|
||||||
|
if (o->report_recovered_errors)
|
||||||
|
c.page->data[10] |= 4;
|
||||||
|
if (!o->hardware_error_recovery)
|
||||||
|
c.page->data[10] |= 1;
|
||||||
|
/*burn_print(1, "error parameter 0x%x\n", c->page->data[10]);*/
|
||||||
|
c.page->data[11] = d->params.retries;
|
||||||
|
c.dir = TO_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_sense_write_params(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct scsi_mode_data *m;
|
||||||
|
int size;
|
||||||
|
unsigned char *page;
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
/* ts A61007 : Done in soft at only caller burn_drive_grab() */
|
||||||
|
/* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||||
|
d->mdata->dvdr_write || d->mdata->dvdram_write); */
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SENSE);
|
||||||
|
c.opcode[2] = 0x05;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
|
m = d->mdata;
|
||||||
|
page = c.page->data + 8;
|
||||||
|
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||||
|
m->write_page_length = page[1];
|
||||||
|
m->write_page_valid = 1;
|
||||||
|
mmc_read_disc_info(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61229 */
|
||||||
|
#define Libburn_mmc_compose_mode_page_5 1
|
||||||
|
|
||||||
|
|
||||||
|
/* remark ts A61104 :
|
||||||
|
Although command MODE SELECT is SPC, the content of the
|
||||||
|
Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
|
||||||
|
Thus the filling of the mode page should be done by a mmc_ function.
|
||||||
|
*/
|
||||||
|
void spc_select_write_params(struct burn_drive *d,
|
||||||
|
const struct burn_write_opts *o)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct command c;
|
||||||
|
#ifndef Libburn_mmc_compose_mode_page_5
|
||||||
|
int bufe, sim;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A61007 : All current callers are safe. */
|
||||||
|
/* a ssert(o->drive == d); */
|
||||||
|
|
||||||
|
/* <<< A61030
|
||||||
|
fprintf(stderr,"libburn_debug: write_type=%d multi=%d control=%d\n",
|
||||||
|
o->write_type,o->multi,o->control);
|
||||||
|
fprintf(stderr,"libburn_debug: block_type=%d spc_block_type=%d\n",
|
||||||
|
o->block_type,spc_block_type(o->block_type));
|
||||||
|
*/
|
||||||
|
|
||||||
|
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||||
|
c.opcode[8] = 8 + 2 + d->mdata->write_page_length;
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
|
||||||
|
/* ts A61007 : moved up to burn_disc_write() */
|
||||||
|
/* a ssert(d->mdata->valid); */
|
||||||
|
|
||||||
|
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
|
||||||
|
c.page->bytes = 8 + 2 + d->mdata->write_page_length;
|
||||||
|
|
||||||
|
burn_print(12, "using write page length %d (valid %d)\n",
|
||||||
|
d->mdata->write_page_length, d->mdata->write_page_valid);
|
||||||
|
|
||||||
|
#ifdef Libburn_mmc_compose_mode_page_5
|
||||||
|
|
||||||
|
/* ts A61229 */
|
||||||
|
if (mmc_compose_mode_page_5(d, o, c.page->data + 8) <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
c.page->data[8] = 5;
|
||||||
|
c.page->data[9] = d->mdata->write_page_length;
|
||||||
|
|
||||||
|
bufe = o->underrun_proof;
|
||||||
|
sim = o->simulate;
|
||||||
|
c.page->data[10] = (bufe << 6)
|
||||||
|
+ (sim << 4)
|
||||||
|
+ o->write_type;
|
||||||
|
|
||||||
|
/* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */
|
||||||
|
c.page->data[11] = ((3 * !!o->multi) << 6) | o->control;
|
||||||
|
|
||||||
|
c.page->data[12] = spc_block_type(o->block_type);
|
||||||
|
|
||||||
|
/* ts A61104 */
|
||||||
|
if(!(o->control&4)) /* audio (MMC-1 table 61) */
|
||||||
|
if(o->write_type == BURN_WRITE_TAO) /* ??? for others too ? */
|
||||||
|
c.page->data[12] = 0; /* Data Block Type: Raw Data */
|
||||||
|
|
||||||
|
c.page->data[22] = 0;
|
||||||
|
c.page->data[23] = 150; /* audio pause length */
|
||||||
|
|
||||||
|
/*XXX need session format! */
|
||||||
|
|
||||||
|
#endif /* ! Libburn_mmc_compose_mode_page_5 */
|
||||||
|
|
||||||
|
c.dir = TO_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spc_getcaps(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
spc_inquiry(d);
|
||||||
|
spc_sense_caps(d);
|
||||||
|
spc_sense_error_params(d);
|
||||||
|
|
||||||
|
/* <<< for debugging. >>> ??? to be fixely included here ?
|
||||||
|
mmc_read_format_capacities(d, -1);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
only called when a blank is present, so we set type to blank
|
||||||
|
(on the last pass)
|
||||||
|
|
||||||
|
don't check totally stupid modes (raw/raw0)
|
||||||
|
some drives say they're ok, and they're not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void spc_probe_write_modes(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
int try_write_type = 1;
|
||||||
|
int try_block_type = 0;
|
||||||
|
int key, asc, ascq;
|
||||||
|
struct command c;
|
||||||
|
|
||||||
|
while (try_write_type != 4) {
|
||||||
|
burn_print(9, "trying %d, %d\n", try_write_type,
|
||||||
|
try_block_type);
|
||||||
|
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||||
|
c.opcode[8] = 8 + 2 + 0x32;
|
||||||
|
c.page = &buf;
|
||||||
|
|
||||||
|
memset(c.page->data, 0, 8 + 2 + 0x32);
|
||||||
|
c.page->bytes = 8 + 2 + 0x32;
|
||||||
|
|
||||||
|
c.page->data[8] = 5;
|
||||||
|
c.page->data[9] = 0x32;
|
||||||
|
c.page->data[10] = try_write_type;
|
||||||
|
if (try_block_type > 4)
|
||||||
|
c.page->data[11] = 4;
|
||||||
|
else
|
||||||
|
c.page->data[11] = 0;
|
||||||
|
c.page->data[12] = try_block_type;
|
||||||
|
c.page->data[23] = 150;
|
||||||
|
c.dir = TO_DRIVE;
|
||||||
|
|
||||||
|
d->silent_on_scsi_error = 1;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
d->silent_on_scsi_error = 0;
|
||||||
|
|
||||||
|
key = c.sense[2];
|
||||||
|
asc = c.sense[12];
|
||||||
|
ascq = c.sense[13];
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
burn_print(7, "%d not supported\n", try_block_type);
|
||||||
|
else {
|
||||||
|
burn_print(7, "%d:%d SUPPORTED MODE!\n",
|
||||||
|
try_write_type, try_block_type);
|
||||||
|
if (try_write_type == 2) /* sao */
|
||||||
|
d->block_types[try_write_type] =
|
||||||
|
BURN_BLOCK_SAO;
|
||||||
|
else
|
||||||
|
d->block_types[try_write_type] |=
|
||||||
|
1 << try_block_type;
|
||||||
|
}
|
||||||
|
switch (try_block_type) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
try_block_type++;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
try_block_type = 8;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
try_block_type++;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
try_block_type = 0;
|
||||||
|
try_write_type++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
|
||||||
|
|
||||||
|
/** @return -1 = error */
|
||||||
|
int spc_block_type(enum burn_block_types b)
|
||||||
|
{
|
||||||
|
switch (b) {
|
||||||
|
case BURN_BLOCK_SAO:
|
||||||
|
return 0; /* ignored bitz */
|
||||||
|
case BURN_BLOCK_RAW0:
|
||||||
|
return 0;
|
||||||
|
case BURN_BLOCK_RAW16:
|
||||||
|
return 1;
|
||||||
|
case BURN_BLOCK_RAW96P:
|
||||||
|
return 2;
|
||||||
|
case BURN_BLOCK_RAW96R:
|
||||||
|
return 3;
|
||||||
|
case BURN_BLOCK_MODE1:
|
||||||
|
return 8;
|
||||||
|
case BURN_BLOCK_MODE2R:
|
||||||
|
return 9;
|
||||||
|
case BURN_BLOCK_MODE2_PATHETIC:
|
||||||
|
return 10;
|
||||||
|
case BURN_BLOCK_MODE2_LAME:
|
||||||
|
return 11;
|
||||||
|
case BURN_BLOCK_MODE2_OBSCURE:
|
||||||
|
return 12;
|
||||||
|
case BURN_BLOCK_MODE2_OK:
|
||||||
|
return 13;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* ts A61007 : already prevented in burn_write_opts_set_write_type() */
|
||||||
|
/* a ssert(0); */;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the spc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int spc_setup_drive(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
d->getcaps = spc_getcaps;
|
||||||
|
d->lock = spc_prevent;
|
||||||
|
d->unlock = spc_allow;
|
||||||
|
d->read_disc_info = spc_sense_write_params;
|
||||||
|
d->get_erase_progress = spc_get_erase_progress;
|
||||||
|
d->test_unit_ready = spc_test_unit_ready;
|
||||||
|
d->probe_write_modes = spc_probe_write_modes;
|
||||||
|
d->send_parameters = spc_select_error_params;
|
||||||
|
d->send_write_parameters = spc_select_write_params;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common()
|
||||||
|
@param flag Bitfiled for control purposes
|
||||||
|
bit0= do not setup spc/sbc/mmc
|
||||||
|
*/
|
||||||
|
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 ret;
|
||||||
|
|
||||||
|
/* ts A60923 */
|
||||||
|
d->bus_no = bus_no;
|
||||||
|
d->host = host_no;
|
||||||
|
d->id = target_no;
|
||||||
|
d->channel = channel_no;
|
||||||
|
d->lun = lun_no;
|
||||||
|
|
||||||
|
/* ts A61106 */
|
||||||
|
d->silent_on_scsi_error = 0;
|
||||||
|
|
||||||
|
|
||||||
|
d->idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
||||||
|
d->idata->valid = 0;
|
||||||
|
d->mdata = malloc(sizeof(struct scsi_mode_data));
|
||||||
|
d->mdata->valid = 0;
|
||||||
|
d->mdata->speed_descriptors = NULL;
|
||||||
|
|
||||||
|
/* ts A61007 : obsolete Assert in drive_getcaps() */
|
||||||
|
if(d->idata == NULL || d->mdata == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not allocate new drive object", 0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(!(flag & 1)) {
|
||||||
|
ret = spc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
ret = sbc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
ret = mmc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61122 */
|
||||||
|
enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
||||||
|
int senselen, char msg[161],
|
||||||
|
int *key, int *asc, int *ascq)
|
||||||
|
{
|
||||||
|
*key= *asc= *ascq= -1;
|
||||||
|
|
||||||
|
if (senselen<=0 || senselen>2)
|
||||||
|
*key = sense[2];
|
||||||
|
if (senselen<=0 || senselen>12)
|
||||||
|
*asc = sense[12];
|
||||||
|
if (senselen<=0 || senselen>13)
|
||||||
|
*ascq = sense[13];
|
||||||
|
|
||||||
|
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
||||||
|
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
|
||||||
|
|
||||||
|
switch (*asc) {
|
||||||
|
case 0:
|
||||||
|
sprintf(msg, "(no error reported by SCSI transaction)");
|
||||||
|
return RETRY;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
sprintf(msg, "not ready");
|
||||||
|
return RETRY;
|
||||||
|
case 4:
|
||||||
|
sprintf(msg,
|
||||||
|
"logical unit is in the process of becoming ready");
|
||||||
|
return RETRY;
|
||||||
|
case 0x20:
|
||||||
|
if (*key == 5)
|
||||||
|
sprintf(msg, "bad opcode");
|
||||||
|
return FAIL;
|
||||||
|
case 0x21:
|
||||||
|
sprintf(msg, "invalid address");
|
||||||
|
return FAIL;
|
||||||
|
case 0x24:
|
||||||
|
if (*key == 5)
|
||||||
|
sprintf(msg, "invalid field in cdb");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
return FAIL;
|
||||||
|
case 0x26:
|
||||||
|
if (*key == 5 )
|
||||||
|
sprintf(msg, "invalid field in parameter list" );
|
||||||
|
return FAIL;
|
||||||
|
case 0x28:
|
||||||
|
if (*key == 6)
|
||||||
|
sprintf(msg, "Medium may have changed");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
return RETRY;
|
||||||
|
case 0x3A:
|
||||||
|
sprintf(msg, "Medium not present");
|
||||||
|
d->status = BURN_DISC_EMPTY;
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
sprintf(msg,
|
||||||
|
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
|
||||||
|
*key, *asc, *ascq);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61115 moved from sg-*.c */
|
||||||
|
/* ts A61122 made it frontend to scsi_error_msg() */
|
||||||
|
enum response scsi_error(struct burn_drive *d, unsigned char *sense,
|
||||||
|
int senselen)
|
||||||
|
{
|
||||||
|
int key, asc, ascq;
|
||||||
|
char msg[160];
|
||||||
|
enum response resp;
|
||||||
|
|
||||||
|
resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq);
|
||||||
|
if (asc == 0 || asc == 0x3A)
|
||||||
|
burn_print(12, "%s\n", msg);
|
||||||
|
else
|
||||||
|
burn_print(1, "%s\n", msg);
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61030 - A61115 */
|
||||||
|
/* @param flag bit0=do report conditions which are considered not an error */
|
||||||
|
int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||||
|
unsigned char *sense, int senselen, int flag)
|
||||||
|
{
|
||||||
|
int key= -1, asc= -1, ascq= -1, ret;
|
||||||
|
char msg[320],scsi_msg[160];
|
||||||
|
|
||||||
|
if (d->silent_on_scsi_error)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
strcpy(scsi_msg, " \"");
|
||||||
|
scsi_error_msg(d, sense, senselen, scsi_msg + strlen(scsi_msg),
|
||||||
|
&key, &asc, &ascq);
|
||||||
|
strcat(scsi_msg, "\"");
|
||||||
|
|
||||||
|
if(!(flag & 1)) {
|
||||||
|
/* SPC : TEST UNIT READY command */
|
||||||
|
if (c->opcode[0] == 0)
|
||||||
|
return 1;
|
||||||
|
/* MMC : READ DISC INFORMATION command */
|
||||||
|
if (c->opcode[0] == 0x51)
|
||||||
|
if (key == 0x2 && asc == 0x3A &&
|
||||||
|
ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(msg,"SCSI error condition on command %2.2Xh :", c->opcode[0]);
|
||||||
|
if (key>=0)
|
||||||
|
sprintf(msg+strlen(msg), " key=%Xh", key);
|
||||||
|
if (asc>=0)
|
||||||
|
sprintf(msg+strlen(msg), " asc=%2.2Xh", asc);
|
||||||
|
if (ascq>=0)
|
||||||
|
sprintf(msg+strlen(msg), " ascq=%2.2Xh", ascq);
|
||||||
|
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
scsi_msg,0,0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
50
libburn/tags/ZeroThreeZero/libburn/spc.h
Normal file
50
libburn/tags/ZeroThreeZero/libburn/spc.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __SPC
|
||||||
|
#define __SPC
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
|
||||||
|
void spc_inquiry(struct burn_drive *);
|
||||||
|
void spc_prevent(struct burn_drive *);
|
||||||
|
void spc_allow(struct burn_drive *);
|
||||||
|
void spc_sense_caps(struct burn_drive *);
|
||||||
|
void spc_sense_error_params(struct burn_drive *);
|
||||||
|
void spc_select_error_params(struct burn_drive *,
|
||||||
|
const struct burn_read_opts *);
|
||||||
|
void spc_getcaps(struct burn_drive *d);
|
||||||
|
void spc_sense_write_params(struct burn_drive *);
|
||||||
|
void spc_select_write_params(struct burn_drive *,
|
||||||
|
const struct burn_write_opts *);
|
||||||
|
void spc_probe_write_modes(struct burn_drive *);
|
||||||
|
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
|
||||||
|
int spc_block_type(enum burn_block_types b);
|
||||||
|
int spc_get_erase_progress(struct burn_drive *d);
|
||||||
|
int spc_test_unit_ready(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61021 : the spc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int spc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common()
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not setup spc/sbc/mmc
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* ts A61115 moved from sg-*.h */
|
||||||
|
enum response { RETRY, FAIL };
|
||||||
|
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
||||||
|
|
||||||
|
/* ts A61122 */
|
||||||
|
enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
||||||
|
int senselen, char msg[161],
|
||||||
|
int *key, int *asc, int *ascq);
|
||||||
|
|
||||||
|
/* ts A61030 */
|
||||||
|
/* @param flag bit0=do report conditions which are considered not an error */
|
||||||
|
int scsi_notify_error(struct burn_drive *, struct command *c,
|
||||||
|
unsigned char *sense, int senselen, int flag);
|
||||||
|
|
||||||
|
#endif /*__SPC*/
|
424
libburn/tags/ZeroThreeZero/libburn/structure.c
Normal file
424
libburn/tags/ZeroThreeZero/libburn/structure.c
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "structure.h"
|
||||||
|
#include "write.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61008 : replaced Assert by if and return 0 */
|
||||||
|
/* a ssert(!(pos > BURN_POS_END)); */
|
||||||
|
|
||||||
|
#define RESIZE(TO, NEW, pos) {\
|
||||||
|
void *tmp;\
|
||||||
|
\
|
||||||
|
if (pos > BURN_POS_END)\
|
||||||
|
return 0;\
|
||||||
|
if (pos == BURN_POS_END)\
|
||||||
|
pos = TO->NEW##s;\
|
||||||
|
if (pos > TO->NEW##s)\
|
||||||
|
return 0;\
|
||||||
|
\
|
||||||
|
tmp = realloc(TO->NEW, sizeof(struct NEW *) * (TO->NEW##s + 1));\
|
||||||
|
if (!tmp)\
|
||||||
|
return 0;\
|
||||||
|
TO->NEW = tmp;\
|
||||||
|
memmove(TO->NEW + pos + 1, TO->NEW + pos,\
|
||||||
|
sizeof(struct NEW *) * (TO->NEW##s - pos));\
|
||||||
|
TO->NEW##s++;\
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_disc *burn_disc_create(void)
|
||||||
|
{
|
||||||
|
struct burn_disc *d;
|
||||||
|
d = calloc(1, sizeof(struct burn_disc));
|
||||||
|
d->refcnt = 1;
|
||||||
|
d->sessions = 0;
|
||||||
|
d->session = NULL;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_disc_free(struct burn_disc *d)
|
||||||
|
{
|
||||||
|
d->refcnt--;
|
||||||
|
if (d->refcnt == 0) {
|
||||||
|
/* dec refs on all elements */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < d->sessions; i++)
|
||||||
|
burn_session_free(d->session[i]);
|
||||||
|
free(d->session);
|
||||||
|
free(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_session *burn_session_create(void)
|
||||||
|
{
|
||||||
|
struct burn_session *s;
|
||||||
|
s = calloc(1, sizeof(struct burn_session));
|
||||||
|
s->refcnt = 1;
|
||||||
|
s->tracks = 0;
|
||||||
|
s->track = NULL;
|
||||||
|
s->hidefirst = 0;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_session_hide_first_track(struct burn_session *s, int onoff)
|
||||||
|
{
|
||||||
|
s->hidefirst = onoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_session_free(struct burn_session *s)
|
||||||
|
{
|
||||||
|
s->refcnt--;
|
||||||
|
if (s->refcnt == 0) {
|
||||||
|
/* dec refs on all elements */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->tracks; i++)
|
||||||
|
burn_track_free(s->track[i]);
|
||||||
|
free(s->track);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_disc_add_session(struct burn_disc *d, struct burn_session *s,
|
||||||
|
unsigned int pos)
|
||||||
|
{
|
||||||
|
RESIZE(d, session, pos);
|
||||||
|
d->session[pos] = s;
|
||||||
|
s->refcnt++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_track *burn_track_create(void)
|
||||||
|
{
|
||||||
|
struct burn_track *t;
|
||||||
|
t = calloc(1, sizeof(struct burn_track));
|
||||||
|
t->refcnt = 1;
|
||||||
|
t->indices = 0;
|
||||||
|
t->offset = 0;
|
||||||
|
t->offsetcount = 0;
|
||||||
|
t->tail = 0;
|
||||||
|
t->tailcount = 0;
|
||||||
|
t->mode = BURN_MODE1;
|
||||||
|
t->isrc.has_isrc = 0;
|
||||||
|
t->pad = 1;
|
||||||
|
t->entry = NULL;
|
||||||
|
t->source = NULL;
|
||||||
|
t->eos = 0;
|
||||||
|
|
||||||
|
/* ts A61101 */
|
||||||
|
t->sourcecount = 0;
|
||||||
|
t->writecount = 0;
|
||||||
|
t->written_sectors = 0;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
t->open_ended = 0;
|
||||||
|
t->track_data_done = 0;
|
||||||
|
|
||||||
|
t->postgap = 0;
|
||||||
|
t->pregap1 = 0;
|
||||||
|
t->pregap2 = 0;
|
||||||
|
|
||||||
|
/* ts A61024 */
|
||||||
|
t->swap_source_bytes = 0;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_track_free(struct burn_track *t)
|
||||||
|
{
|
||||||
|
t->refcnt--;
|
||||||
|
if (t->refcnt == 0) {
|
||||||
|
/* dec refs on all elements */
|
||||||
|
if (t->source)
|
||||||
|
burn_source_free(t->source);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_session_add_track(struct burn_session *s, struct burn_track *t,
|
||||||
|
unsigned int pos)
|
||||||
|
{
|
||||||
|
RESIZE(s, track, pos);
|
||||||
|
s->track[pos] = t;
|
||||||
|
t->refcnt++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_session_remove_track(struct burn_session *s, struct burn_track *t)
|
||||||
|
{
|
||||||
|
struct burn_track **tmp;
|
||||||
|
int i, pos = -1;
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* a ssert(s->track != NULL); */
|
||||||
|
if (s->track == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
burn_track_free(t);
|
||||||
|
|
||||||
|
/* Find the position */
|
||||||
|
for (i = 0; i < s->tracks; i++) {
|
||||||
|
if (t == s->track[i]) {
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Is it the last track? */
|
||||||
|
if (pos != s->tracks - 1) {
|
||||||
|
memmove(&s->track[pos], &s->track[pos + 1],
|
||||||
|
sizeof(struct burn_track *) * (s->tracks - (pos + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
s->tracks--;
|
||||||
|
tmp = realloc(s->track, sizeof(struct burn_track *) * s->tracks);
|
||||||
|
if (tmp)
|
||||||
|
s->track = tmp;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_structure_print_disc(struct burn_disc *d)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
burn_print(12, "This disc has %d sessions\n", d->sessions);
|
||||||
|
for (i = 0; i < d->sessions; i++) {
|
||||||
|
burn_structure_print_session(d->session[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void burn_structure_print_session(struct burn_session *s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
burn_print(12, " Session has %d tracks\n", s->tracks);
|
||||||
|
for (i = 0; i < s->tracks; i++) {
|
||||||
|
burn_structure_print_track(s->track[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void burn_structure_print_track(struct burn_track *t)
|
||||||
|
{
|
||||||
|
burn_print(12, "(%p) track size %d sectors\n", t,
|
||||||
|
burn_track_get_sectors(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
||||||
|
int pad, int mode)
|
||||||
|
{
|
||||||
|
int type_to_form(int mode, unsigned char *ctladr, int *form);
|
||||||
|
int burn_sector_length(int tracktype);
|
||||||
|
unsigned char ctladr;
|
||||||
|
int form = -1; /* unchanged form will be considered an error too */
|
||||||
|
|
||||||
|
type_to_form(mode, &ctladr, &form);
|
||||||
|
if (form == -1 || burn_sector_length(mode) <= 0) {
|
||||||
|
char msg[160];
|
||||||
|
|
||||||
|
sprintf(msg, "Attempt to set track mode to unusable value %d",
|
||||||
|
mode);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020115,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->offset = offset;
|
||||||
|
t->pad = pad;
|
||||||
|
t->mode = mode;
|
||||||
|
t->tail = tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61024 */
|
||||||
|
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes)
|
||||||
|
{
|
||||||
|
if(swap_source_bytes!=0 && swap_source_bytes!=1)
|
||||||
|
return 0;
|
||||||
|
t->swap_source_bytes = swap_source_bytes;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
|
||||||
|
unsigned char year, unsigned int serial)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
|
||||||
|
/* ts A61008 : This is always true */
|
||||||
|
/* a ssert((country[i] >= '0' || country[i] < '9') &&
|
||||||
|
(country[i] >= 'a' || country[i] < 'z') &&
|
||||||
|
(country[i] >= 'A' || country[i] < 'Z')); */
|
||||||
|
/* ts A61008 : now coordinated with sector.c: char_to_isrc() */
|
||||||
|
if (! ((country[i] >= '0' && country[i] <= '9') ||
|
||||||
|
(country[i] >= 'a' && country[i] <= 'z') ||
|
||||||
|
(country[i] >= 'A' && country[i] <= 'Z') ) )
|
||||||
|
goto is_not_allowed;
|
||||||
|
|
||||||
|
t->isrc.country[i] = country[i];
|
||||||
|
}
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
|
||||||
|
/* ts A61008 : This is always true */
|
||||||
|
/* a ssert((owner[i] >= '0' || owner[i] < '9') &&
|
||||||
|
(owner[i] >= 'a' || owner[i] < 'z') &&
|
||||||
|
(owner[i] >= 'A' || owner[i] < 'Z')); */
|
||||||
|
/* ts A61008 : now coordinated with sector.c: char_to_isrc() */
|
||||||
|
if (! ((owner[i] >= '0' && owner[i] <= '9') ||
|
||||||
|
(owner[i] >= 'a' && owner[i] <= 'z') ||
|
||||||
|
(owner[i] >= 'A' && owner[i] <= 'Z') ) )
|
||||||
|
goto is_not_allowed;
|
||||||
|
|
||||||
|
t->isrc.owner[i] = owner[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* a ssert(year <= 99); */
|
||||||
|
if (year > 99)
|
||||||
|
goto is_not_allowed;
|
||||||
|
|
||||||
|
t->isrc.year = year;
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* a ssert(serial <= 99999); */
|
||||||
|
if (serial > 99999)
|
||||||
|
goto is_not_allowed;
|
||||||
|
|
||||||
|
t->isrc.serial = serial;
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
t->isrc.has_isrc = 1;
|
||||||
|
return;
|
||||||
|
is_not_allowed:;
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020114,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Attempt to set ISRC with bad data", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_track_clear_isrc(struct burn_track *t)
|
||||||
|
{
|
||||||
|
t->isrc.has_isrc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_track_get_sectors(struct burn_track *t)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int sectors, seclen;
|
||||||
|
|
||||||
|
seclen = burn_sector_length(t->mode);
|
||||||
|
size = t->offset + t->source->get_size(t->source) + t->tail;
|
||||||
|
sectors = size / seclen;
|
||||||
|
if (size % seclen)
|
||||||
|
sectors++;
|
||||||
|
burn_print(1, "%d sectors of %d length\n", sectors, seclen);
|
||||||
|
return sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
int burn_track_is_open_ended(struct burn_track *t)
|
||||||
|
{
|
||||||
|
return !!t->open_ended;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61101 : API function */
|
||||||
|
int burn_track_get_counters(struct burn_track *t,
|
||||||
|
off_t *read_bytes, off_t *written_bytes)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "libburn_experimental: sizeof(off_t)=%d\n",
|
||||||
|
sizeof(off_t));
|
||||||
|
*/
|
||||||
|
*read_bytes = t->sourcecount;
|
||||||
|
*written_bytes = t->writecount;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
int burn_track_is_data_done(struct burn_track *t)
|
||||||
|
{
|
||||||
|
return !!t->track_data_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_track_get_shortage(struct burn_track *t)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int seclen;
|
||||||
|
|
||||||
|
seclen = burn_sector_length(t->mode);
|
||||||
|
size = t->offset + t->source->get_size(t->source) + t->tail;
|
||||||
|
if (size % seclen)
|
||||||
|
return seclen - size % seclen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_session_get_sectors(struct burn_session *s)
|
||||||
|
{
|
||||||
|
int sectors = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->tracks; i++)
|
||||||
|
sectors += burn_track_get_sectors(s->track[i]);
|
||||||
|
return sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_disc_get_sectors(struct burn_disc *d)
|
||||||
|
{
|
||||||
|
int sectors = 0, i;
|
||||||
|
|
||||||
|
for (i = 0; i < d->sessions; i++)
|
||||||
|
sectors += burn_session_get_sectors(d->session[i]);
|
||||||
|
return sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry)
|
||||||
|
{
|
||||||
|
if (t->entry == NULL)
|
||||||
|
memset(entry, 0, sizeof(struct burn_toc_entry));
|
||||||
|
else
|
||||||
|
memcpy(entry, t->entry, sizeof(struct burn_toc_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
void burn_session_get_leadout_entry(struct burn_session *s,
|
||||||
|
struct burn_toc_entry *entry)
|
||||||
|
{
|
||||||
|
if (s->leadout_entry == NULL)
|
||||||
|
memset(entry, 0, sizeof(struct burn_toc_entry));
|
||||||
|
else
|
||||||
|
memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num)
|
||||||
|
{
|
||||||
|
*num = d->sessions;
|
||||||
|
return d->session;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num)
|
||||||
|
{
|
||||||
|
*num = s->tracks;
|
||||||
|
return s->track;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_track_get_mode(struct burn_track *track)
|
||||||
|
{
|
||||||
|
return track->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int burn_session_get_hidefirst(struct burn_session *session)
|
||||||
|
{
|
||||||
|
return session->hidefirst;
|
||||||
|
}
|
92
libburn/tags/ZeroThreeZero/libburn/structure.h
Normal file
92
libburn/tags/ZeroThreeZero/libburn/structure.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#ifndef BURN__STRUCTURE_H
|
||||||
|
#define BURN__STRUCTURE_H
|
||||||
|
|
||||||
|
struct isrc
|
||||||
|
{
|
||||||
|
int has_isrc;
|
||||||
|
char country[2]; /* each must be 0-9, A-Z */
|
||||||
|
char owner[3]; /* each must be 0-9, A-Z */
|
||||||
|
unsigned char year; /* must be 0-99 */
|
||||||
|
unsigned int serial; /* must be 0-99999 */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct burn_track
|
||||||
|
{
|
||||||
|
int refcnt;
|
||||||
|
struct burn_toc_entry *entry;
|
||||||
|
unsigned char indices;
|
||||||
|
/* lba address of the index */
|
||||||
|
unsigned int index[99];
|
||||||
|
/** number of 0 bytes to write before data */
|
||||||
|
int offset;
|
||||||
|
/** how much offset has been used */
|
||||||
|
int offsetcount;
|
||||||
|
/** Number of zeros to write after data */
|
||||||
|
int tail;
|
||||||
|
/** how much tail has been used */
|
||||||
|
int tailcount;
|
||||||
|
/** 1 means Pad with zeros, 0 means start reading the next track */
|
||||||
|
int pad;
|
||||||
|
/** Data source */
|
||||||
|
struct burn_source *source;
|
||||||
|
/** End of Source flag */
|
||||||
|
int eos;
|
||||||
|
|
||||||
|
/* ts A61101 */
|
||||||
|
off_t sourcecount;
|
||||||
|
off_t writecount;
|
||||||
|
off_t written_sectors;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
/** Source is of undefined length */
|
||||||
|
int open_ended;
|
||||||
|
/** End of open ended track flag : offset+payload+tail are delivered */
|
||||||
|
int track_data_done;
|
||||||
|
|
||||||
|
/** The audio/data mode for the entry. Derived from control and
|
||||||
|
possibly from reading the track's first sector. */
|
||||||
|
int mode;
|
||||||
|
/** The track contains interval one of a pregap */
|
||||||
|
int pregap1;
|
||||||
|
/** The track contains interval two of a pregap */
|
||||||
|
int pregap2;
|
||||||
|
/** The track contains a postgap */
|
||||||
|
int postgap;
|
||||||
|
struct isrc isrc;
|
||||||
|
|
||||||
|
/* ts A61024 */
|
||||||
|
/** Byte swapping on source data stream : 0=none , 1=pairwise */
|
||||||
|
int swap_source_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct burn_session
|
||||||
|
{
|
||||||
|
unsigned char firsttrack;
|
||||||
|
unsigned char lasttrack;
|
||||||
|
int hidefirst;
|
||||||
|
unsigned char start_m;
|
||||||
|
unsigned char start_s;
|
||||||
|
unsigned char start_f;
|
||||||
|
struct burn_toc_entry *leadout_entry;
|
||||||
|
|
||||||
|
int tracks;
|
||||||
|
struct burn_track **track;
|
||||||
|
int refcnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct burn_disc
|
||||||
|
{
|
||||||
|
int sessions;
|
||||||
|
struct burn_session **session;
|
||||||
|
int refcnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
int burn_track_get_shortage(struct burn_track *t);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61031 : might go to libburn.h */
|
||||||
|
int burn_track_is_open_ended(struct burn_track *t);
|
||||||
|
int burn_track_is_data_done(struct burn_track *t);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BURN__STRUCTURE_H */
|
136
libburn/tags/ZeroThreeZero/libburn/toc.c
Normal file
136
libburn/tags/ZeroThreeZero/libburn/toc.c
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "toc.h"
|
||||||
|
#include "transport.h"
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "sector.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void write_clonecd2(volatile struct toc *toc, int f);
|
||||||
|
|
||||||
|
static void write_clonecd2(volatile struct toc *toc, int f)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* header */
|
||||||
|
dprintf(f, "[CloneCD]\r\n");
|
||||||
|
dprintf(f, "Version=2\r\n");
|
||||||
|
dprintf(f, "\r\n");
|
||||||
|
|
||||||
|
/* disc data */
|
||||||
|
dprintf(f, "[Disc]\r\n");
|
||||||
|
|
||||||
|
dprintf(f, "TocEntries=%d\r\n", toc->toc_entries);
|
||||||
|
dprintf(f, "Sessions=%d\r\n", toc->sessions);
|
||||||
|
dprintf(f, "DataTracksScrambled=%d\r\n", toc->datatracksscrambled);
|
||||||
|
dprintf(f, "CDTextLength=%d\r\n", toc->cdtextlength);
|
||||||
|
dprintf(f, "\r\n");
|
||||||
|
|
||||||
|
/* session data */
|
||||||
|
for (i = 0; i < toc->sessions; ++i) {
|
||||||
|
dprintf(f, "[Session %d]\r\n", i + 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
|
||||||
|
switch (toc->session[i].track[0]->mode) {
|
||||||
|
case BURN_MODE_RAW_DATA:
|
||||||
|
case BURN_MODE_AUDIO:
|
||||||
|
m = 0;
|
||||||
|
break;
|
||||||
|
case BURN_MODE0:
|
||||||
|
m = 1;
|
||||||
|
break;
|
||||||
|
case BURN_MODE1:
|
||||||
|
case BURN_MODE2_FORMLESS:
|
||||||
|
case BURN_MODE2_FORM1:
|
||||||
|
case BURN_MODE2_FORM2:
|
||||||
|
case BURN_MODE_UNINITIALIZED:
|
||||||
|
|
||||||
|
/* ts A61008 : do this softly without Assert */
|
||||||
|
|
||||||
|
a ssert(0); /* unhandled! find out ccd's
|
||||||
|
value for these modes! */
|
||||||
|
}
|
||||||
|
dprintf(f, "PreGapMode=%d\r\n", m);
|
||||||
|
}
|
||||||
|
dprintf(f, "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < toc->toc_entries; ++i) {
|
||||||
|
dprintf(f, "[Entry %d]\r\n", i);
|
||||||
|
|
||||||
|
dprintf(f, "Session=%d\r\n", toc->toc_entry[i].session);
|
||||||
|
dprintf(f, "Point=0x%02x\r\n", toc->toc_entry[i].point);
|
||||||
|
dprintf(f, "ADR=0x%02x\r\n", toc->toc_entry[i].adr);
|
||||||
|
dprintf(f, "Control=0x%02x\r\n", toc->toc_entry[i].control);
|
||||||
|
dprintf(f, "TrackNo=%d\r\n", toc->toc_entry[i].tno);
|
||||||
|
dprintf(f, "AMin=%d\r\n", toc->toc_entry[i].min);
|
||||||
|
dprintf(f, "ASec=%d\r\n", toc->toc_entry[i].sec);
|
||||||
|
dprintf(f, "AFrame=%d\r\n", toc->toc_entry[i].frame);
|
||||||
|
dprintf(f, "ALBA=%d\r\n",
|
||||||
|
burn_msf_to_lba(toc->toc_entry[i].min,
|
||||||
|
toc->toc_entry[i].sec,
|
||||||
|
toc->toc_entry[i].frame));
|
||||||
|
dprintf(f, "Zero=%d\r\n", toc->toc_entry[i].zero);
|
||||||
|
dprintf(f, "PMin=%d\r\n", toc->toc_entry[i].pmin);
|
||||||
|
dprintf(f, "PSec=%d\r\n", toc->toc_entry[i].psec);
|
||||||
|
dprintf(f, "PFrame=%d\r\n", toc->toc_entry[i].pframe);
|
||||||
|
dprintf(f, "PLBA=%d\r\n",
|
||||||
|
burn_msf_to_lba(toc->toc_entry[i].pmin,
|
||||||
|
toc->toc_entry[i].psec,
|
||||||
|
toc->toc_entry[i].pframe));
|
||||||
|
dprintf(f, "\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void toc_find_modes(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct burn_read_opts o;
|
||||||
|
int lba;
|
||||||
|
int i, j;
|
||||||
|
struct buffer mem;
|
||||||
|
struct burn_toc_entry *e;
|
||||||
|
|
||||||
|
/* ts A61008 : to be prevented on the higher levels */
|
||||||
|
/* a ssert(d->busy); */
|
||||||
|
|
||||||
|
mem.bytes = 0;
|
||||||
|
mem.sectors = 1;
|
||||||
|
o.raw = 1;
|
||||||
|
o.c2errors = 0;
|
||||||
|
o.subcodes_audio = 1;
|
||||||
|
o.subcodes_data = 1;
|
||||||
|
o.hardware_error_recovery = 1;
|
||||||
|
o.report_recovered_errors = 0;
|
||||||
|
o.transfer_damaged_blocks = 1;
|
||||||
|
o.hardware_error_retries = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < d->disc->sessions; i++)
|
||||||
|
for (j = 0; j < d->disc->session[i]->tracks; j++) {
|
||||||
|
struct burn_track *t = d->disc->session[i]->track[j];
|
||||||
|
|
||||||
|
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! */
|
||||||
|
if (e && !(e->control & 4)) {
|
||||||
|
t->mode = BURN_AUDIO;
|
||||||
|
} else {
|
||||||
|
mem.sectors = 1;
|
||||||
|
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
||||||
|
t->mode = sector_identify(mem.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
libburn/tags/ZeroThreeZero/libburn/toc.h
Normal file
48
libburn/tags/ZeroThreeZero/libburn/toc.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __TOC_H
|
||||||
|
#define __TOC_H
|
||||||
|
|
||||||
|
struct command;
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "structure.h"
|
||||||
|
|
||||||
|
/* return if a given entry refers to a track position */
|
||||||
|
#define TOC_ENTRY_IS_TRACK(drive, entrynum) \
|
||||||
|
((drive)->toc_entry[entrynum].point < 100)
|
||||||
|
|
||||||
|
/* return if a given entry is in audio or data format */
|
||||||
|
#define TOC_ENTRY_IS_AUDIO(drive, entrynum) \
|
||||||
|
(~(drive)->toc_entry[entrynum].control & 4)
|
||||||
|
|
||||||
|
/* return the point value for a given entry number */
|
||||||
|
#define TOC_POINT(drive, entrynum) ((drive)->toc_entry[entrynum].point)
|
||||||
|
|
||||||
|
/* return the track struct for a given entry number */
|
||||||
|
#define TOC_TRACK(drive, entrynum) \
|
||||||
|
((drive)->track[TOC_POINT(drive, entrynum) - 1])
|
||||||
|
|
||||||
|
/* return the lba of a toc entry */
|
||||||
|
#define TOC_ENTRY_PLBA(drive, entrynum) \
|
||||||
|
burn_msf_to_lba((drive)->toc_entry[(entrynum)].pmin, \
|
||||||
|
(drive)->toc_entry[(entrynum)].psec, \
|
||||||
|
(drive)->toc_entry[(entrynum)].pframe)
|
||||||
|
|
||||||
|
/* flags for the q subchannel control field */
|
||||||
|
#define TOC_CONTROL_AUDIO (0)
|
||||||
|
#define TOC_CONTROL_DATA (1 << 2)
|
||||||
|
#define TOC_CONTROL_AUDIO_TWO_CHANNELS (0)
|
||||||
|
#define TOC_CONTROL_AUDIO_FOUR_CHANNELS (1 << 3)
|
||||||
|
#define TOC_CONTROL_AUDIO_PRE_EMPHASIS (1 << 0)
|
||||||
|
#define TOC_CONTROL_DATA_RECORDED_UNINTERRUPTED (0)
|
||||||
|
#define TOC_CONTROL_DATA_RECORDED_INCREMENT (1 << 0)
|
||||||
|
#define TOC_CONTROL_COPY_PROHIBITED (0)
|
||||||
|
#define TOC_CONTROL_COPY_PERMITTED (1 << 1)
|
||||||
|
|
||||||
|
/** read a sector from each track on disc to determine modes
|
||||||
|
@param d The drive.
|
||||||
|
*/
|
||||||
|
void toc_find_modes(struct burn_drive *d);
|
||||||
|
|
||||||
|
#endif /*__TOC_H*/
|
266
libburn/tags/ZeroThreeZero/libburn/transport.h
Normal file
266
libburn/tags/ZeroThreeZero/libburn/transport.h
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __TRANSPORT
|
||||||
|
#define __TRANSPORT
|
||||||
|
|
||||||
|
#include "libburn.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
/* sg data structures */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* see os.h for name of particular os-*.h where this is defined */
|
||||||
|
#define BUFFER_SIZE BURN_OS_TRANSPORT_BUFFER_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
enum transfer_direction
|
||||||
|
{ TO_DRIVE, FROM_DRIVE, NO_TRANSFER };
|
||||||
|
|
||||||
|
/* end of sg data structures */
|
||||||
|
|
||||||
|
/* generic 'drive' data structures */
|
||||||
|
|
||||||
|
struct cue_sheet
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
unsigned char *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct params
|
||||||
|
{
|
||||||
|
int speed;
|
||||||
|
int retries;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct buffer
|
||||||
|
{
|
||||||
|
/* ts A61219:
|
||||||
|
Added 4096 bytes reserve against possible buffer overflows.
|
||||||
|
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
||||||
|
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). ) */
|
||||||
|
unsigned char data[BUFFER_SIZE + 4096];
|
||||||
|
int sectors;
|
||||||
|
int bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct command
|
||||||
|
{
|
||||||
|
unsigned char opcode[16];
|
||||||
|
int oplen;
|
||||||
|
int dir;
|
||||||
|
unsigned char sense[128];
|
||||||
|
int error;
|
||||||
|
int retry;
|
||||||
|
struct buffer *page;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct burn_scsi_inquiry_data
|
||||||
|
{
|
||||||
|
char vendor[9];
|
||||||
|
char product[17];
|
||||||
|
char revision[5];
|
||||||
|
int valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct scsi_mode_data
|
||||||
|
{
|
||||||
|
int buffer_size;
|
||||||
|
int dvdram_read;
|
||||||
|
int dvdram_write;
|
||||||
|
int dvdr_read;
|
||||||
|
int dvdr_write;
|
||||||
|
int dvdrom_read;
|
||||||
|
int cdrw_read;
|
||||||
|
int cdrw_write;
|
||||||
|
int cdr_read;
|
||||||
|
int cdr_write;
|
||||||
|
int simulate;
|
||||||
|
int max_read_speed;
|
||||||
|
int max_write_speed;
|
||||||
|
|
||||||
|
/* ts A61021 */
|
||||||
|
int min_write_speed;
|
||||||
|
|
||||||
|
/* ts A61225 : Results from ACh GET PERFORMANCE, Type 03h
|
||||||
|
Speed values go into *_*_speed */
|
||||||
|
int min_end_lba;
|
||||||
|
int max_end_lba;
|
||||||
|
struct burn_speed_descriptor *speed_descriptors;
|
||||||
|
|
||||||
|
int cur_read_speed;
|
||||||
|
int cur_write_speed;
|
||||||
|
int retry_page_length;
|
||||||
|
int retry_page_valid;
|
||||||
|
int write_page_length;
|
||||||
|
int write_page_valid;
|
||||||
|
int c2_pointers;
|
||||||
|
int valid;
|
||||||
|
int underrun_proof;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70112 : represents a single Formattable Capacity Descriptor as of
|
||||||
|
mmc5r03c.pdf 6.24.3.3 . There can at most be 32 of them. */
|
||||||
|
struct burn_format_descr {
|
||||||
|
/* format type: e.g 0x00 is "Full", 0x15 is "Quick" */
|
||||||
|
int type;
|
||||||
|
|
||||||
|
/* the size in bytes derived from Number of Blocks */
|
||||||
|
off_t size;
|
||||||
|
|
||||||
|
/* the Type Dependent Parameter (usually the write alignment size) */
|
||||||
|
unsigned tdp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define LIBBURN_SG_MAX_SIBLINGS 16
|
||||||
|
|
||||||
|
/** Gets initialized in enumerate_common() and burn_drive_register() */
|
||||||
|
struct burn_drive
|
||||||
|
{
|
||||||
|
int bus_no;
|
||||||
|
int host;
|
||||||
|
int id;
|
||||||
|
int channel;
|
||||||
|
int lun;
|
||||||
|
char *devname;
|
||||||
|
|
||||||
|
|
||||||
|
/* see os.h for name of particular os-*.h where this is defined */
|
||||||
|
BURN_OS_TRANSPORT_DRIVE_ELEMENTS
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60904 : ticket 62, contribution by elmom */
|
||||||
|
/**
|
||||||
|
Tells the index in scanned burn_drive_info array.
|
||||||
|
-1 if fallen victim to burn_drive_info_forget()
|
||||||
|
*/
|
||||||
|
int global_index;
|
||||||
|
|
||||||
|
pthread_mutex_t access_lock;
|
||||||
|
|
||||||
|
enum burn_disc_status status;
|
||||||
|
int erasable;
|
||||||
|
|
||||||
|
/* ts A61201 from 46h GET CONFIGURATION */
|
||||||
|
int current_profile;
|
||||||
|
char current_profile_text[80];
|
||||||
|
int current_is_cd_profile;
|
||||||
|
int current_is_supported_profile;
|
||||||
|
|
||||||
|
/* ts A70114 : wether a DVD-RW media holds an incomplete session
|
||||||
|
(which could need closing after write) */
|
||||||
|
int dvd_minus_rw_incomplete;
|
||||||
|
|
||||||
|
/* ts A61218 from 46h GET CONFIGURATION */
|
||||||
|
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||||
|
|
||||||
|
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
||||||
|
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
|
||||||
|
off_t format_curr_max_size; /* meaning depends on format_descr_type */
|
||||||
|
unsigned format_curr_blsas; /* meaning depends on format_descr_type */
|
||||||
|
int best_format_type;
|
||||||
|
off_t best_format_size;
|
||||||
|
|
||||||
|
/* The complete list of format descriptors as read with 23h */
|
||||||
|
int num_format_descr;
|
||||||
|
struct burn_format_descr format_descriptors[32];
|
||||||
|
|
||||||
|
|
||||||
|
volatile int released;
|
||||||
|
|
||||||
|
/* ts A61106 */
|
||||||
|
int silent_on_scsi_error;
|
||||||
|
|
||||||
|
int nwa; /* next writeable address */
|
||||||
|
int alba; /* absolute lba */
|
||||||
|
int rlba; /* relative lba in section */
|
||||||
|
int start_lba;
|
||||||
|
int end_lba;
|
||||||
|
int toc_temp;
|
||||||
|
struct burn_disc *disc; /* disc structure */
|
||||||
|
int block_types[4];
|
||||||
|
struct buffer *buffer;
|
||||||
|
struct burn_progress progress;
|
||||||
|
|
||||||
|
volatile int cancel;
|
||||||
|
volatile enum burn_drive_status busy;
|
||||||
|
/* transport functions */
|
||||||
|
int (*grab) (struct burn_drive *);
|
||||||
|
int (*release) (struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61021 */
|
||||||
|
int (*drive_is_open) (struct burn_drive *);
|
||||||
|
|
||||||
|
int (*issue_command) (struct burn_drive *, struct command *);
|
||||||
|
|
||||||
|
/* lower level functions */
|
||||||
|
void (*erase) (struct burn_drive *, int);
|
||||||
|
void (*getcaps) (struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61021 */
|
||||||
|
void (*read_atip) (struct burn_drive *);
|
||||||
|
|
||||||
|
int (*write) (struct burn_drive *, int, struct buffer *);
|
||||||
|
void (*read_toc) (struct burn_drive *);
|
||||||
|
void (*lock) (struct burn_drive *);
|
||||||
|
void (*unlock) (struct burn_drive *);
|
||||||
|
void (*eject) (struct burn_drive *);
|
||||||
|
void (*load) (struct burn_drive *);
|
||||||
|
int (*start_unit) (struct burn_drive *);
|
||||||
|
void (*read_disc_info) (struct burn_drive *);
|
||||||
|
void (*read_sectors) (struct burn_drive *,
|
||||||
|
int start,
|
||||||
|
int len,
|
||||||
|
const struct burn_read_opts *, struct buffer *);
|
||||||
|
void (*perform_opc) (struct burn_drive *);
|
||||||
|
void (*set_speed) (struct burn_drive *, int, int);
|
||||||
|
void (*send_parameters) (struct burn_drive *,
|
||||||
|
const struct burn_read_opts *);
|
||||||
|
void (*send_write_parameters) (struct burn_drive *,
|
||||||
|
const struct burn_write_opts *);
|
||||||
|
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
||||||
|
void (*sync_cache) (struct burn_drive *);
|
||||||
|
int (*get_erase_progress) (struct burn_drive *);
|
||||||
|
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
|
||||||
|
|
||||||
|
/* ts A61009 : removed d in favor of o->drive */
|
||||||
|
/* void (*close_disc) (struct burn_drive * d,
|
||||||
|
struct burn_write_opts * o);
|
||||||
|
void (*close_session) (struct burn_drive * d,
|
||||||
|
struct burn_write_opts * o);
|
||||||
|
*/
|
||||||
|
void (*close_disc) (struct burn_write_opts * o);
|
||||||
|
void (*close_session) ( struct burn_write_opts * o);
|
||||||
|
|
||||||
|
/* ts A61029 */
|
||||||
|
void (*close_track_session) ( struct burn_drive *d,
|
||||||
|
int session, int track);
|
||||||
|
|
||||||
|
int (*test_unit_ready) (struct burn_drive * d);
|
||||||
|
void (*probe_write_modes) (struct burn_drive * d);
|
||||||
|
struct params params;
|
||||||
|
struct burn_scsi_inquiry_data *idata;
|
||||||
|
struct scsi_mode_data *mdata;
|
||||||
|
int toc_entries;
|
||||||
|
struct burn_toc_entry *toc_entry;
|
||||||
|
|
||||||
|
/* ts A61023 : get size and free space of drive buffer */
|
||||||
|
int (*read_buffer_capacity) (struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61220 : format media (e.g. DVD+RW) */
|
||||||
|
int (*format_unit) (struct burn_drive *d, off_t size, int flag);
|
||||||
|
|
||||||
|
/* ts A70108 */
|
||||||
|
/* mmc5r03c.pdf 6.24 : get list of available formats */
|
||||||
|
int (*read_format_capacities) (struct burn_drive *d, int top_wanted);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* end of generic 'drive' data structures */
|
||||||
|
|
||||||
|
#endif /* __TRANSPORT */
|
53
libburn/tags/ZeroThreeZero/libburn/util.c
Normal file
53
libburn/tags/ZeroThreeZero/libburn/util.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../version.h"
|
||||||
|
#include "util.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)
|
||||||
|
{
|
||||||
|
*major = BURN_MAJOR_VERSION;
|
||||||
|
*minor = BURN_MINOR_VERSION;
|
||||||
|
*micro = BURN_MICRO_VERSION;
|
||||||
|
}
|
8
libburn/tags/ZeroThreeZero/libburn/util.h
Normal file
8
libburn/tags/ZeroThreeZero/libburn/util.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef __UTIL
|
||||||
|
#define __UTIL
|
||||||
|
|
||||||
|
char *burn_strdup(char *s);
|
||||||
|
|
||||||
|
char *burn_strndup(char *s, int n);
|
||||||
|
|
||||||
|
#endif
|
1350
libburn/tags/ZeroThreeZero/libburn/write.c
Normal file
1350
libburn/tags/ZeroThreeZero/libburn/write.c
Normal file
File diff suppressed because it is too large
Load Diff
35
libburn/tags/ZeroThreeZero/libburn/write.h
Normal file
35
libburn/tags/ZeroThreeZero/libburn/write.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef BURN__WRITE_H
|
||||||
|
#define BURN__WRITE_H
|
||||||
|
|
||||||
|
struct cue_sheet;
|
||||||
|
struct burn_session;
|
||||||
|
struct burn_write_opts;
|
||||||
|
struct burn_disc;
|
||||||
|
|
||||||
|
struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
||||||
|
struct burn_session *session,
|
||||||
|
int nwa);
|
||||||
|
int burn_sector_length(int trackmode);
|
||||||
|
int burn_subcode_length(int trackmode);
|
||||||
|
|
||||||
|
/* ts A61009 */
|
||||||
|
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc);
|
||||||
|
|
||||||
|
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc);
|
||||||
|
int burn_write_leadin(struct burn_write_opts *o,
|
||||||
|
struct burn_session *s, int first);
|
||||||
|
int burn_write_leadout(struct burn_write_opts *o,
|
||||||
|
int first, unsigned char control, int mode);
|
||||||
|
int burn_write_session(struct burn_write_opts *o, struct burn_session *s);
|
||||||
|
int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
|
int tnum);
|
||||||
|
int burn_write_flush(struct burn_write_opts *o, struct burn_track *track);
|
||||||
|
|
||||||
|
/* ts A61030 : necessary for TAO */
|
||||||
|
int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
|
int tnum);
|
||||||
|
int burn_write_close_session(struct burn_write_opts *o,struct burn_session *s);
|
||||||
|
|
||||||
|
#endif /* BURN__WRITE_H */
|
4
libburn/tags/ZeroThreeZero/test/Makefile
Normal file
4
libburn/tags/ZeroThreeZero/test/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
all clean:
|
||||||
|
$(MAKE) -C .. -$(MAKEFLAGS) $@
|
||||||
|
|
||||||
|
.PHONY: all clean
|
215
libburn/tags/ZeroThreeZero/test/dewav.c
Normal file
215
libburn/tags/ZeroThreeZero/test/dewav.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
|
||||||
|
/* dewav
|
||||||
|
Demo of libburn extension libdax_audioxtr
|
||||||
|
Audio track data extraction facility of libdax and libburn.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* libdax_audioxtr is quite independent of libburn. It only needs
|
||||||
|
the messaging facility libdax_msgs. So we got two build variations:
|
||||||
|
*/
|
||||||
|
#ifdef Dewav_without_libburN
|
||||||
|
|
||||||
|
/* This build environment is standalone relying only on libdax components */
|
||||||
|
#include "../libburn/libdax_msgs.h"
|
||||||
|
struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
|
#else /* Dewav_without_libburN */
|
||||||
|
|
||||||
|
/* This build environment uses libdax_msgs via libburn */
|
||||||
|
/* Thus the API header of libburn */
|
||||||
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
|
#endif /* ! Dewav_without_libburN */
|
||||||
|
|
||||||
|
|
||||||
|
/* The API for .wav extraction */
|
||||||
|
#include "../libburn/libdax_audioxtr.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* This program acts as filter from in_path to out_path */
|
||||||
|
char *in_path= "", *out_path= "-";
|
||||||
|
|
||||||
|
/* The read-and-extract object for use with in_path */
|
||||||
|
struct libdax_audioxtr *xtr= NULL;
|
||||||
|
/* The file descriptor eventually detached from xtr */
|
||||||
|
int xtr_fd= -2;
|
||||||
|
|
||||||
|
/* Default output is stdout */
|
||||||
|
int out_fd= 1;
|
||||||
|
|
||||||
|
/* Inquired source parameters */
|
||||||
|
char *fmt, *fmt_info;
|
||||||
|
int num_channels, sample_rate, bits_per_sample, msb_first;
|
||||||
|
off_t data_size;
|
||||||
|
|
||||||
|
/* Auxiliary variables */
|
||||||
|
int ret, i, be_strict= 1, buf_count, detach_fd= 0, extract_all= 0;
|
||||||
|
char buf[2048];
|
||||||
|
|
||||||
|
if(argc < 2)
|
||||||
|
goto help;
|
||||||
|
for(i= 1; i<argc; i++) {
|
||||||
|
if(strcmp(argv[i],"-o")==0) {
|
||||||
|
if(i>=argc-1) {
|
||||||
|
fprintf(stderr,"%s: option -o needs a file address as argument.\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
out_path= argv[i];
|
||||||
|
} else if(strcmp(argv[i],"--lax")==0) {
|
||||||
|
be_strict= 0;
|
||||||
|
} else if(strcmp(argv[i],"--strict")==0) {
|
||||||
|
be_strict= 1;
|
||||||
|
} else if(strcmp(argv[i],"--detach_fd")==0) {
|
||||||
|
/* Test the dirty detach method. Always --extract_all */
|
||||||
|
detach_fd= 1;
|
||||||
|
} else if(strcmp(argv[i],"--extract_all")==0) {
|
||||||
|
/* Dirty : read all available bytes regardless of data_size */
|
||||||
|
extract_all= 1;
|
||||||
|
} else if(strcmp(argv[i],"--help")==0) {
|
||||||
|
help:;
|
||||||
|
fprintf(stderr,
|
||||||
|
"usage: %s [-o output_path|\"-\"] [--lax|--strict] [source_path|\"-\"]\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
if(in_path[0]!=0) {
|
||||||
|
fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
in_path= argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(in_path[0] == 0)
|
||||||
|
in_path= "-";
|
||||||
|
|
||||||
|
|
||||||
|
/* Depending on wether this was built standalone or with full libburn :
|
||||||
|
*/
|
||||||
|
#ifdef Dewav_without_libburN
|
||||||
|
|
||||||
|
/* Initialize and set up libdax messaging system */
|
||||||
|
ret= libdax_msgs_new(&libdax_messenger,0);
|
||||||
|
if(ret<=0) {
|
||||||
|
fprintf(stderr,"Failed to create libdax_messenger object.\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER,
|
||||||
|
LIBDAX_MSGS_SEV_NOTE, "", 0);
|
||||||
|
fprintf(stderr, "dewav on libdax\n");
|
||||||
|
|
||||||
|
#else /* Dewav_without_libburN */
|
||||||
|
|
||||||
|
/* Initialize libburn and set up its messaging system */
|
||||||
|
if(burn_initialize() == 0) {
|
||||||
|
fprintf(stderr,"Failed to initialize libburn.\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
/* Print messages of severity NOTE or more directly to stderr */
|
||||||
|
burn_msgs_set_severities("NEVER", "NOTE", "");
|
||||||
|
fprintf(stderr, "dewav on libburn\n");
|
||||||
|
|
||||||
|
#endif /* ! Dewav_without_libburN */
|
||||||
|
|
||||||
|
|
||||||
|
/* Open audio source and create extractor object */
|
||||||
|
ret= libdax_audioxtr_new(&xtr, in_path, 0);
|
||||||
|
if(ret<=0)
|
||||||
|
exit(4);
|
||||||
|
if(strcmp(out_path,"-")!=0) {
|
||||||
|
out_fd= open(out_path, O_WRONLY | O_CREAT | O_TRUNC,
|
||||||
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||||
|
if(out_fd == -1) {
|
||||||
|
fprintf(stderr, "Cannot open file: %s\n", out_path);
|
||||||
|
fprintf(stderr, "Error reported: '%s' (%d)\n",strerror(errno), errno);
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Obtain and print parameters of audio source */
|
||||||
|
libdax_audioxtr_get_id(xtr, &fmt, &fmt_info,
|
||||||
|
&num_channels, &sample_rate, &bits_per_sample, &msb_first, 0);
|
||||||
|
fprintf(stderr, "Detected format: %s\n", fmt_info);
|
||||||
|
libdax_audioxtr_get_size(xtr, &data_size, 0);
|
||||||
|
fprintf(stderr, "Data size : %.f bytes\n", (double) data_size);
|
||||||
|
if((strcmp(fmt,".wav")!=0 && strcmp(fmt,".au")!=0) ||
|
||||||
|
num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%sAudio source parameters do not comply to cdrskin/README specs\n",
|
||||||
|
(be_strict ? "" : "WARNING: "));
|
||||||
|
if(be_strict)
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
if(msb_first==0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"NOTE: Extracted data to be written with cdrskin option -swab\n");
|
||||||
|
|
||||||
|
if(detach_fd) {
|
||||||
|
/* Take over fd from xtr */;
|
||||||
|
ret= libdax_audioxtr_detach_fd(xtr, &xtr_fd, 0);
|
||||||
|
if(ret<=0) {
|
||||||
|
fprintf(stderr, "Cannot detach file descriptor from extractor\n");
|
||||||
|
exit(8);
|
||||||
|
}
|
||||||
|
/* not needed any more */
|
||||||
|
libdax_audioxtr_destroy(&xtr, 0);
|
||||||
|
fprintf(stderr, "Note: detached fd and freed extractor object.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract and put out raw audio data */;
|
||||||
|
while(1) {
|
||||||
|
if(detach_fd) {
|
||||||
|
buf_count= read(xtr_fd, buf, sizeof(buf));
|
||||||
|
if(buf_count==-1)
|
||||||
|
fprintf(stderr,"Error while reading from detached fd\n(%d) '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
} else {
|
||||||
|
buf_count= libdax_audioxtr_read(xtr, buf, sizeof(buf), !!extract_all);
|
||||||
|
}
|
||||||
|
if(buf_count < 0)
|
||||||
|
exit(7);
|
||||||
|
if(buf_count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret= write(out_fd, buf, buf_count);
|
||||||
|
if(ret == -1) {
|
||||||
|
fprintf(stderr, "Failed to write buffer of %d bytes to: %s\n",
|
||||||
|
buf_count, out_path);
|
||||||
|
fprintf(stderr, "Error reported: '%s' (%d)\n", strerror(errno), errno);
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shutdown */
|
||||||
|
if(out_fd>2)
|
||||||
|
close(out_fd);
|
||||||
|
/* ( It is permissible to do this with xtr==NULL ) */
|
||||||
|
libdax_audioxtr_destroy(&xtr, 0);
|
||||||
|
|
||||||
|
#ifdef Dewav_without_libburN
|
||||||
|
|
||||||
|
libdax_msgs_destroy(&libdax_messenger,0);
|
||||||
|
|
||||||
|
#else /* Dewav_without_libburN */
|
||||||
|
|
||||||
|
burn_finish();
|
||||||
|
|
||||||
|
#endif /* ! Dewav_without_libburN */
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
164
libburn/tags/ZeroThreeZero/test/fake_au.c
Normal file
164
libburn/tags/ZeroThreeZero/test/fake_au.c
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
|
||||||
|
/* fake_au
|
||||||
|
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
|
||||||
|
to be 16 bit, stereo, 44100 Hz.
|
||||||
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
|
|
||||||
|
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
int fake_write(unsigned char *buf, size_t size, FILE *fp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret= fwrite(buf,size,1,fp);
|
||||||
|
if(ret==1)
|
||||||
|
return(1);
|
||||||
|
fprintf(stderr,"Error %d while writing: '%s'\n",errno,strerror(errno));
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
unsigned data_size= 0,byte_count,exit_value= 0;
|
||||||
|
FILE *fp_out= stdout,*fp_in= stdin;
|
||||||
|
unsigned char buf[4];
|
||||||
|
char out_path[4096],in_path[4096];
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
strcpy(out_path,"-");
|
||||||
|
strcpy(in_path,"");
|
||||||
|
if(argc < 2) {
|
||||||
|
exit_value= 1;
|
||||||
|
goto help;
|
||||||
|
}
|
||||||
|
for(i= 1; i<argc; i++) {
|
||||||
|
if(strcmp(argv[i],"-o")==0) {
|
||||||
|
if(i>=argc-1) {
|
||||||
|
fprintf(stderr,"%s: option -o needs a file address as argument.\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
strcpy(out_path, argv[i]);
|
||||||
|
} else if(strcmp(argv[i],"--stdin_size")==0) {
|
||||||
|
if(i>=argc-1) {
|
||||||
|
fprintf(stderr,"%s: option --stdin_size needs a number as argument.\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
sscanf(argv[i],"%u",&data_size);
|
||||||
|
} else if(strcmp(argv[i],"--help")==0) {
|
||||||
|
exit_value= 0;
|
||||||
|
help:;
|
||||||
|
fprintf(stderr,"usage: %s \\\n", argv[0]);
|
||||||
|
fprintf(stderr," [-o output_path|\"-\"] [source_path | --stdin_size size]\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"Disguises an extracted .wav stream as .au stereo, 16bit, 44100Hz\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"stdin gets byte-swapped and appended up to the announced data_size.\n");
|
||||||
|
exit(exit_value);
|
||||||
|
} else {
|
||||||
|
if(in_path[0]!=0) {
|
||||||
|
fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
strcpy(in_path, argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(in_path,"-")==0 || in_path[0]==0) {
|
||||||
|
if(data_size==0) {
|
||||||
|
fprintf(stderr,"%s: input from stdin needs option --stdin_size.\n",
|
||||||
|
argv[0]);
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
fp_in= stdin;
|
||||||
|
} else {
|
||||||
|
fp_in= fopen(in_path,"r");
|
||||||
|
if(stat(in_path,&stbuf)!=-1)
|
||||||
|
data_size= stbuf.st_size;
|
||||||
|
}
|
||||||
|
if(fp_in==NULL) {
|
||||||
|
fprintf(stderr,"Error %d while fopen(\"%s\",\"r\") : '%s'\n",
|
||||||
|
errno,in_path,strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(out_path,"-")==0) {
|
||||||
|
fp_out= stdout;
|
||||||
|
} else {
|
||||||
|
if(stat(out_path,&stbuf)!=-1) {
|
||||||
|
fprintf(stderr,"%s: file '%s' already existing\n",argv[0],out_path);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
fp_out= fopen(out_path,"w");
|
||||||
|
}
|
||||||
|
if(fp_out==NULL) {
|
||||||
|
fprintf(stderr,"Error %d while fopen(\"%s\",\"w\") : '%s'\n",
|
||||||
|
errno,out_path,strerror(errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_write((unsigned char *) ".snd",4,fp_out); /* magic number */
|
||||||
|
buf[0]= buf[1]= buf[2]= 0;
|
||||||
|
buf[3]= 32;
|
||||||
|
fake_write(buf,4,fp_out); /* data_location */
|
||||||
|
buf[0]= (data_size>>24)&0xff;
|
||||||
|
buf[1]= (data_size>>16)&0xff;
|
||||||
|
buf[2]= (data_size>>8)&0xff;
|
||||||
|
buf[3]= (data_size)&0xff;
|
||||||
|
fake_write(buf,4,fp_out); /* data_size */
|
||||||
|
buf[0]= buf[1]= buf[2]= 0;
|
||||||
|
buf[3]= 3;
|
||||||
|
fake_write(buf,4,fp_out); /* encoding 16 Bit PCM */
|
||||||
|
buf[0]= buf[1]= 0;
|
||||||
|
buf[2]= 172;
|
||||||
|
buf[3]= 68;
|
||||||
|
fake_write(buf,4,fp_out); /* sample rate 44100 Hz */
|
||||||
|
buf[0]= buf[1]= buf[2]= 0;
|
||||||
|
buf[3]= 2;
|
||||||
|
fake_write(buf,4,fp_out); /* number of channels */
|
||||||
|
buf[0]= buf[1]= buf[2]= buf[3]= 0;
|
||||||
|
fake_write(buf,4,fp_out); /* padding */
|
||||||
|
fake_write(buf,4,fp_out); /* padding */
|
||||||
|
|
||||||
|
for(byte_count= 0; byte_count<data_size; byte_count+=2) {
|
||||||
|
ret= fread(buf,2,1,fp_in);
|
||||||
|
if(ret<=0) {
|
||||||
|
fprintf(stderr,"Premature end end of input\n");
|
||||||
|
exit_value= 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[3]= buf[0];
|
||||||
|
buf[2]= buf[1];
|
||||||
|
ret= fake_write(buf+2,2,fp_out);
|
||||||
|
if(ret<=0) {
|
||||||
|
exit_value= 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fp_out!=stdout)
|
||||||
|
fclose(fp_out);
|
||||||
|
if(fp_in!=stdin)
|
||||||
|
fclose(fp_in);
|
||||||
|
fprintf(stderr, "Swapped and appended: %u stdin bytes\n",byte_count);
|
||||||
|
exit(exit_value);
|
||||||
|
}
|
||||||
|
|
718
libburn/tags/ZeroThreeZero/test/libburner.c
Normal file
718
libburn/tags/ZeroThreeZero/test/libburner.c
Normal file
@ -0,0 +1,718 @@
|
|||||||
|
|
||||||
|
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
||||||
|
/* Copyright (C) 2005 - 2006 Thomas Schmitt <scdbackup@gmx.net> */
|
||||||
|
/* Provided under GPL, see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
|
/** Overview
|
||||||
|
|
||||||
|
libburner is a minimal demo application for the library libburn as provided
|
||||||
|
on http://libburnia.pykix.org . It can list the available devices, can
|
||||||
|
blank a CD-RW, can format a DVD-RW, and can burn to CD-R, CD-RW, DVD+RW,
|
||||||
|
DVD-RAM or DVD-RW.
|
||||||
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
|
to serve the libburnia team as reference application. libburner.c does indeed
|
||||||
|
define the standard way how above three gestures can be implemented and
|
||||||
|
stay upward compatible for a good while.
|
||||||
|
|
||||||
|
Before you can do anything, you have to initialize libburn by
|
||||||
|
burn_initialize()
|
||||||
|
and provide some signal and abort handling, e.g. by the builtin handler, by
|
||||||
|
burn_set_signal_handling()
|
||||||
|
as it is done in main() at the end of this file. Then you aquire a
|
||||||
|
drive in an appropriate way conforming to the API. The two main
|
||||||
|
approaches are shown here in application functions:
|
||||||
|
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
|
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
|
With that aquired drive you can blank a CD-RW
|
||||||
|
libburner_blank_disc()
|
||||||
|
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
||||||
|
libburner_format_row()
|
||||||
|
With the aquired drive you can burn to CD-R, CD-RW, DVD+RW, DVD-RAM, DVD-RW
|
||||||
|
libburner_payload()
|
||||||
|
When everything is done, main() releases the drive and shuts down libburn:
|
||||||
|
burn_drive_release();
|
||||||
|
burn_finish()
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** See this for the decisive API specs . libburn.h is The Original */
|
||||||
|
/* For using the installed header file : #include <libburn/libburn.h> */
|
||||||
|
/* This program insists in the own headerfile. */
|
||||||
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
|
/* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */
|
||||||
|
#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>
|
||||||
|
|
||||||
|
|
||||||
|
/** For simplicity i use global variables to represent the drives.
|
||||||
|
Drives are systemwide global, so we do not give away much of good style.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** This list will hold the drives known to libburn. This might be all CD
|
||||||
|
drives of the system and thus might impose severe impact on the system.
|
||||||
|
*/
|
||||||
|
static struct burn_drive_info *drive_list;
|
||||||
|
|
||||||
|
/** If you start a long lasting operation with drive_count > 1 then you are
|
||||||
|
not friendly to the users of other drives on those systems. Beware. */
|
||||||
|
static unsigned int drive_count;
|
||||||
|
|
||||||
|
/** This variable indicates wether the drive is grabbed and must be
|
||||||
|
finally released */
|
||||||
|
static int drive_is_grabbed = 0;
|
||||||
|
|
||||||
|
/** A number and a text describing the type of media in aquired drive */
|
||||||
|
static int current_profile= -1;
|
||||||
|
static char current_profile_name[80]= {""};
|
||||||
|
|
||||||
|
|
||||||
|
/* Some in-advance definitions to allow a more comprehensive ordering
|
||||||
|
of the functions and their explanations in here */
|
||||||
|
int libburner_aquire_by_adr(char *drive_adr);
|
||||||
|
int libburner_aquire_by_driveno(int *drive_no);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------- API gestures ---------------------------- */
|
||||||
|
|
||||||
|
/** You need to aquire a drive before burning. The API offers this as one
|
||||||
|
compact call and alternatively as application controllable gestures of
|
||||||
|
whitelisting, scanning for drives and finally grabbing one of them.
|
||||||
|
|
||||||
|
If you have a persistent address of the drive, then the compact call is
|
||||||
|
to prefer because it only touches one drive. On modern Linux kernels,
|
||||||
|
there should be no fatal disturbance of ongoing burns of other libburn
|
||||||
|
instances with any of our approaches. We use open(O_EXCL) by default.
|
||||||
|
On /dev/hdX it should cooperate with growisofs and some cdrecord variants.
|
||||||
|
On /dev/sgN versus /dev/scdM expect it not to respect other programs.
|
||||||
|
*/
|
||||||
|
int libburner_aquire_drive(char *drive_adr, int *driveno)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(drive_adr != NULL && drive_adr[0] != 0)
|
||||||
|
ret = libburner_aquire_by_adr(drive_adr);
|
||||||
|
else
|
||||||
|
ret = libburner_aquire_by_driveno(driveno);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||||
|
current_profile_name);
|
||||||
|
if (current_profile_name[0])
|
||||||
|
printf("Detected media type: %s\n", current_profile_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** If the persistent drive address is known, then this approach is much
|
||||||
|
more un-obtrusive to the systemwide livestock of drives. Only the
|
||||||
|
given drive device will be opened during this procedure.
|
||||||
|
*/
|
||||||
|
int libburner_aquire_by_adr(char *drive_adr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
|
||||||
|
|
||||||
|
/* This tries to resolve links or alternative device files */
|
||||||
|
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
|
||||||
|
if (ret<=0) {
|
||||||
|
fprintf(stderr,"Address does not lead to a CD burner: '%s'\n",
|
||||||
|
drive_adr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Aquiring drive '%s' ...\n",libburn_drive_adr);
|
||||||
|
ret = burn_drive_scan_and_grab(&drive_list,libburn_drive_adr,1);
|
||||||
|
if (ret <= 0) {
|
||||||
|
fprintf(stderr,"FAILURE with persistent drive address '%s'\n",
|
||||||
|
libburn_drive_adr);
|
||||||
|
} else {
|
||||||
|
printf("Done\n");
|
||||||
|
drive_is_grabbed = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** This method demonstrates how to use libburn without knowing a persistent
|
||||||
|
drive address in advance. It has to make sure that after assessing the list
|
||||||
|
of available drives, all unwanted drives get closed again. As long as they
|
||||||
|
are open, no other libburn instance can see them. This is an intended
|
||||||
|
locking feature. The application is responsible for giving up the locks
|
||||||
|
by either burn_drive_release() (only after burn_drive_grab() !),
|
||||||
|
burn_drive_info_forget(), burn_drive_info_free(), or burn_finish().
|
||||||
|
@param driveno the index number in libburn's drive list. This will get
|
||||||
|
set to 0 on success and will then be the drive index to
|
||||||
|
use in the further dourse of processing.
|
||||||
|
@return 1 success , <= 0 failure
|
||||||
|
*/
|
||||||
|
int libburner_aquire_by_driveno(int *driveno)
|
||||||
|
{
|
||||||
|
char adr[BURN_DRIVE_ADR_LEN];
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
printf("Beginning to scan for devices ...\n");
|
||||||
|
while (!burn_drive_scan(&drive_list, &drive_count))
|
||||||
|
usleep(1002);
|
||||||
|
if (drive_count <= 0 && *driveno >= 0) {
|
||||||
|
printf("FAILED (no drives found)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf("Done\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Interactive programs may choose the drive number at this moment.
|
||||||
|
|
||||||
|
drive[0] to drive[drive_count-1] are struct burn_drive_info
|
||||||
|
as defined in libburn/libburn.h . This structure is part of API
|
||||||
|
and thus will strive for future compatibility on source level.
|
||||||
|
Have a look at the info offered.
|
||||||
|
Caution: do not take .location for drive address. Always use
|
||||||
|
burn_drive_get_adr() or you might become incompatible
|
||||||
|
in future.
|
||||||
|
Note: bugs with struct burn_drive_info - if any - will not be
|
||||||
|
easy to fix. Please report them but also strive for
|
||||||
|
workarounds on application level.
|
||||||
|
*/
|
||||||
|
printf("\nOverview of accessible drives (%d found) :\n",
|
||||||
|
drive_count);
|
||||||
|
printf("-----------------------------------------------------------------------------\n");
|
||||||
|
for (i = 0; i < drive_count; i++) {
|
||||||
|
if (burn_drive_get_adr(&(drive_list[i]), adr) <=0)
|
||||||
|
strcpy(adr, "-get_adr_failed-");
|
||||||
|
printf("%d --drive '%s' : '%s' '%s'\n",
|
||||||
|
i,adr,drive_list[i].vendor,drive_list[i].product);
|
||||||
|
}
|
||||||
|
printf("-----------------------------------------------------------------------------\n\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
On multi-drive systems save yourself from sysadmins' revenge.
|
||||||
|
|
||||||
|
Be aware that you hold reserved all available drives at this point.
|
||||||
|
So either make your choice quick enough not to annoy other system
|
||||||
|
users, or set free the drives for a while.
|
||||||
|
|
||||||
|
The tested way of setting free all drives is to shutdown the library
|
||||||
|
and to restart when the choice has been made. The list of selectable
|
||||||
|
drives should also hold persistent drive addresses as obtained
|
||||||
|
above by burn_drive_get_adr(). By such an address one may use
|
||||||
|
burn_drive_scan_and_grab() to finally aquire exactly one drive.
|
||||||
|
|
||||||
|
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()
|
||||||
|
before accessing any drives again.
|
||||||
|
|
||||||
|
In both cases you have to be aware that the desired drive might get
|
||||||
|
aquired in the meantime by another user resp. libburn process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* We already made our choice via command line. (default is 0)
|
||||||
|
So we just have to keep our desired drive and drop all others.
|
||||||
|
No other libburn instance will have a chance to steal our drive.
|
||||||
|
*/
|
||||||
|
if (*driveno < 0) {
|
||||||
|
printf("Pseudo-drive \"-\" given : bus scanning done.\n");
|
||||||
|
return 2; /* the program will end after this */
|
||||||
|
}
|
||||||
|
if (drive_count <= *driveno) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Found only %d drives. Number %d not available.\n",
|
||||||
|
drive_count, *driveno);
|
||||||
|
return 0; /* the program will end after this */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drop all drives which we do not want to use */
|
||||||
|
for (i = 0; i < drive_count; i++) {
|
||||||
|
if (i == *driveno) /* the one drive we want to keep */
|
||||||
|
continue;
|
||||||
|
ret = burn_drive_info_forget(&(drive_list[i]),0);
|
||||||
|
if (ret != 1)
|
||||||
|
fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n",
|
||||||
|
i, ret);
|
||||||
|
else
|
||||||
|
printf("Dropped unwanted drive %d\n",i);
|
||||||
|
}
|
||||||
|
/* Make the one we want ready for blanking or burning */
|
||||||
|
ret= burn_drive_grab(drive_list[*driveno].drive, 1);
|
||||||
|
if (ret != 1)
|
||||||
|
return 0;
|
||||||
|
drive_is_grabbed = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Makes a previously used CD-RW ready for thorough re-usal.
|
||||||
|
|
||||||
|
To our knowledge it is hardly possible to abort an ongoing blank operation
|
||||||
|
because after start it is entirely handled by the drive.
|
||||||
|
So expect signal handling to wait the normal blanking timespan until it
|
||||||
|
can allow the process to end. External kill -9 will not help the drive.
|
||||||
|
*/
|
||||||
|
int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||||
|
{
|
||||||
|
enum burn_disc_status disc_state;
|
||||||
|
struct burn_progress p;
|
||||||
|
int percent = 1;
|
||||||
|
|
||||||
|
disc_state = burn_disc_get_status(drive);
|
||||||
|
printf(
|
||||||
|
"Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n",
|
||||||
|
disc_state);
|
||||||
|
if (disc_state == BURN_DISC_BLANK) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"IDLE: Blank media detected. Will leave it untouched\n");
|
||||||
|
return 2;
|
||||||
|
} else if (disc_state == BURN_DISC_FULL ||
|
||||||
|
disc_state == BURN_DISC_APPENDABLE) {
|
||||||
|
; /* this is what libburn is willing to blank */
|
||||||
|
} else if (disc_state == BURN_DISC_EMPTY) {
|
||||||
|
fprintf(stderr,"FATAL: No media detected in drive\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: Unsuitable drive and media state\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!burn_disc_erasable(drive)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL : Media is not of erasable type\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf(
|
||||||
|
"Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
||||||
|
burn_disc_erase(drive, blank_fast);
|
||||||
|
sleep(1);
|
||||||
|
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||||
|
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||||
|
percent = 1.0 + ((double) p.sector+1.0)
|
||||||
|
/ ((double) p.sectors) * 98.0;
|
||||||
|
printf("Blanking ( %d%% done )\n", percent);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
printf("Done\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Persistently changes DVD-RW profile 0014h "Sequential Recording"
|
||||||
|
to profile 0013h "Restricted Overwrite" which is usable with libburner.
|
||||||
|
|
||||||
|
Expect a behavior similar to blanking with unusual noises from the drive.
|
||||||
|
*/
|
||||||
|
int libburner_format_row(struct burn_drive *drive)
|
||||||
|
{
|
||||||
|
struct burn_progress p;
|
||||||
|
int percent = 1;
|
||||||
|
|
||||||
|
if (current_profile == 0x13) {
|
||||||
|
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
||||||
|
return 2;
|
||||||
|
} else if (current_profile != 0x14) {
|
||||||
|
fprintf(stderr, "FATAL: Can only format DVD-RW\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf("Beginning to format media.\n");
|
||||||
|
burn_disc_format(drive, (off_t) 0, 0);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||||
|
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||||
|
percent = 1.0 + ((double) p.sector+1.0)
|
||||||
|
/ ((double) p.sectors) * 98.0;
|
||||||
|
printf("Formatting ( %d%% done )\n", percent);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||||
|
current_profile_name);
|
||||||
|
printf("Media type now: %4.4xh \"%s\"\n",
|
||||||
|
current_profile, current_profile_name);
|
||||||
|
if (current_profile != 0x13) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: Failed to change media profile to desired value\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Brings preformatted track images (ISO 9660, audio, ...) onto media.
|
||||||
|
To make sure a data image is fully readable on any Linux machine, this
|
||||||
|
function adds 300 kB of padding to the (usualy single) track.
|
||||||
|
Audio tracks get padded to complete their last sector.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
int libburner_payload(struct burn_drive *drive,
|
||||||
|
char source_adr[][4096], int source_adr_count,
|
||||||
|
int multi, int simulate_burn, int all_tracks_type)
|
||||||
|
{
|
||||||
|
struct burn_source *data_src;
|
||||||
|
struct burn_disc *target_disc;
|
||||||
|
struct burn_session *session;
|
||||||
|
struct burn_write_opts *burn_options;
|
||||||
|
enum burn_disc_status disc_state;
|
||||||
|
struct burn_track *track, *tracklist[99];
|
||||||
|
struct burn_progress progress;
|
||||||
|
time_t start_time;
|
||||||
|
int last_sector = 0, padding = 0, trackno, write_mode_tao = 0, fd;
|
||||||
|
off_t fixed_size;
|
||||||
|
char *adr;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (all_tracks_type != BURN_AUDIO) {
|
||||||
|
all_tracks_type = BURN_MODE1;
|
||||||
|
/* a padding of 300 kB helps to avoid the read-ahead bug */
|
||||||
|
padding = 300*1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_disc = burn_disc_create();
|
||||||
|
session = burn_session_create();
|
||||||
|
burn_disc_add_session(target_disc, session, BURN_POS_END);
|
||||||
|
|
||||||
|
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
|
||||||
|
tracklist[trackno] = track = burn_track_create();
|
||||||
|
burn_track_define_data(track, 0, padding, 1, all_tracks_type);
|
||||||
|
|
||||||
|
adr = source_adr[trackno];
|
||||||
|
fixed_size = 0;
|
||||||
|
if (adr[0] == '-' && adr[1] == 0) {
|
||||||
|
fd = 0;
|
||||||
|
} else {
|
||||||
|
fd = open(adr, O_RDONLY);
|
||||||
|
if (fd>=0)
|
||||||
|
if (fstat(fd,&stbuf)!=-1)
|
||||||
|
if((stbuf.st_mode&S_IFMT)==S_IFREG)
|
||||||
|
fixed_size = stbuf.st_size;
|
||||||
|
}
|
||||||
|
if (fixed_size==0)
|
||||||
|
write_mode_tao = 1;
|
||||||
|
data_src = NULL;
|
||||||
|
if (fd>=0)
|
||||||
|
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
||||||
|
if (data_src == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: Could not open data source '%s'.\n",adr);
|
||||||
|
if(errno!=0)
|
||||||
|
fprintf(stderr,"(Most recent system error: %s )\n",
|
||||||
|
strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (burn_track_set_source(track, data_src) != BURN_SOURCE_OK) {
|
||||||
|
printf("FATAL: Cannot attach source object to track object\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
burn_session_add_track(session, track, BURN_POS_END);
|
||||||
|
printf("Track %d : source is '%s'\n", trackno+1, adr);
|
||||||
|
burn_source_free(data_src);
|
||||||
|
} /* trackno loop end */
|
||||||
|
|
||||||
|
/* Evaluate drive and media */
|
||||||
|
disc_state = burn_disc_get_status(drive);
|
||||||
|
if (disc_state == BURN_DISC_APPENDABLE) {
|
||||||
|
write_mode_tao = 1;
|
||||||
|
} else if (disc_state != BURN_DISC_BLANK) {
|
||||||
|
if (disc_state == BURN_DISC_FULL) {
|
||||||
|
fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n");
|
||||||
|
if (burn_disc_erasable(drive))
|
||||||
|
fprintf(stderr, "HINT: Try --blank_fast\n\n");
|
||||||
|
} else if (disc_state == BURN_DISC_EMPTY)
|
||||||
|
fprintf(stderr,"FATAL: No media detected in drive\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: Cannot recognize state of drive and media\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
burn_options = burn_write_opts_new(drive);
|
||||||
|
burn_write_opts_set_perform_opc(burn_options, 0);
|
||||||
|
burn_write_opts_set_multi(burn_options, !!multi);
|
||||||
|
if (write_mode_tao)
|
||||||
|
burn_write_opts_set_write_type(burn_options,
|
||||||
|
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
|
||||||
|
else
|
||||||
|
burn_write_opts_set_write_type(burn_options,
|
||||||
|
BURN_WRITE_SAO, BURN_BLOCK_SAO);
|
||||||
|
if(simulate_burn)
|
||||||
|
printf("\n*** Will TRY to SIMULATE burning ***\n\n");
|
||||||
|
burn_write_opts_set_simulate(burn_options, simulate_burn);
|
||||||
|
burn_structure_print_disc(target_disc);
|
||||||
|
burn_drive_set_speed(drive, 0, 0);
|
||||||
|
burn_write_opts_set_underrun_proof(burn_options, 1);
|
||||||
|
|
||||||
|
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
||||||
|
start_time = time(0);
|
||||||
|
burn_disc_write(burn_options, target_disc);
|
||||||
|
|
||||||
|
burn_write_opts_free(burn_options);
|
||||||
|
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
|
||||||
|
usleep(1002);
|
||||||
|
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
|
||||||
|
if( progress.sectors <= 0 || progress.sector == last_sector)
|
||||||
|
printf(
|
||||||
|
"Thank you for being patient since %d seconds.\n",
|
||||||
|
(int) (time(0) - start_time));
|
||||||
|
else if(write_mode_tao)
|
||||||
|
printf("Track %d : sector %d\n", progress.track+1,
|
||||||
|
progress.sector);
|
||||||
|
else
|
||||||
|
printf("Track %d : sector %d of %d\n",progress.track+1,
|
||||||
|
progress.sector, progress.sectors);
|
||||||
|
last_sector = progress.sector;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
for (trackno = 0 ; trackno < source_adr_count; trackno++)
|
||||||
|
burn_track_free(tracklist[trackno]);
|
||||||
|
burn_session_free(session);
|
||||||
|
burn_disc_free(target_disc);
|
||||||
|
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
||||||
|
current_profile != 0x12) /* not with DVD+RW, DVD-RW, DVD-RAM */
|
||||||
|
printf("NOTE: Media left appendable.\n");
|
||||||
|
if (simulate_burn)
|
||||||
|
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** The setup parameters of libburner */
|
||||||
|
static char drive_adr[BURN_DRIVE_ADR_LEN] = {""};
|
||||||
|
static int driveno = 0;
|
||||||
|
static int do_blank = 0;
|
||||||
|
static char source_adr[99][4096];
|
||||||
|
static int source_adr_count = 0;
|
||||||
|
static int do_multi = 0;
|
||||||
|
static int simulate_burn = 0;
|
||||||
|
static int all_tracks_type = BURN_MODE1;
|
||||||
|
|
||||||
|
|
||||||
|
/** Converts command line arguments into above setup parameters.
|
||||||
|
drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes.
|
||||||
|
source_adr[] must provide at least 4096 bytes.
|
||||||
|
*/
|
||||||
|
int libburner_setup(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, insuffient_parameters = 0, print_help = 0;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
if (!strcmp(argv[i], "--audio")) {
|
||||||
|
all_tracks_type = BURN_AUDIO;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--blank_fast")) {
|
||||||
|
do_blank = 1;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--blank_full")) {
|
||||||
|
do_blank = 2;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--burn_for_real")) {
|
||||||
|
simulate_burn = 0;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--drive")) {
|
||||||
|
++i;
|
||||||
|
if (i >= argc) {
|
||||||
|
fprintf(stderr,"--drive requires an argument\n");
|
||||||
|
return 1;
|
||||||
|
} else if (strcmp(argv[i], "-") == 0) {
|
||||||
|
drive_adr[0] = 0;
|
||||||
|
driveno = -1;
|
||||||
|
} else if (isdigit(argv[i][0])) {
|
||||||
|
drive_adr[0] = 0;
|
||||||
|
driveno = atoi(argv[i]);
|
||||||
|
} else {
|
||||||
|
if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) {
|
||||||
|
fprintf(stderr,"--drive address too long (max. %d)\n",
|
||||||
|
BURN_DRIVE_ADR_LEN-1);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
strcpy(drive_adr, argv[i]);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--format_overwrite")) {
|
||||||
|
do_blank = 101;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--multi")) {
|
||||||
|
do_multi = 1;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--stdin_size")) { /* obsoleted */
|
||||||
|
i++;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--try_to_simulate")) {
|
||||||
|
simulate_burn = 1;
|
||||||
|
|
||||||
|
} else if (!strcmp(argv[i], "--help")) {
|
||||||
|
print_help = 1;
|
||||||
|
|
||||||
|
} else if (!strncmp(argv[i], "--",2)) {
|
||||||
|
fprintf(stderr, "Unidentified option: %s\n", argv[i]);
|
||||||
|
return 7;
|
||||||
|
} else {
|
||||||
|
if(strlen(argv[i]) >= 4096) {
|
||||||
|
fprintf(stderr, "Source address too long (max. %d)\n", 4096-1);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
if(source_adr_count >= 99) {
|
||||||
|
fprintf(stderr, "Too many tracks (max. 99)\n");
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
strcpy(source_adr[source_adr_count], argv[i]);
|
||||||
|
source_adr_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insuffient_parameters = 1;
|
||||||
|
if (driveno < 0)
|
||||||
|
insuffient_parameters = 0;
|
||||||
|
if (source_adr_count > 0)
|
||||||
|
insuffient_parameters = 0;
|
||||||
|
if (do_blank)
|
||||||
|
insuffient_parameters = 0;
|
||||||
|
if (print_help || insuffient_parameters ) {
|
||||||
|
printf("Usage: %s\n", argv[0]);
|
||||||
|
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
|
||||||
|
printf(" [--blank_fast|--blank_full|--format_overwrite]\n");
|
||||||
|
printf(" [--try_to_simulate]\n");
|
||||||
|
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
|
||||||
|
printf("Examples\n");
|
||||||
|
printf("A bus scan (needs rw-permissions to see a drive):\n");
|
||||||
|
printf(" %s --drive -\n",argv[0]);
|
||||||
|
printf("Burn a file to drive chosen by number, leave appendable:\n");
|
||||||
|
printf(" %s --drive 0 --multi my_image_file\n", argv[0]);
|
||||||
|
printf("Burn a file to drive chosen by persistent address, close:\n");
|
||||||
|
printf(" %s --drive /dev/hdc my_image_file\n", argv[0]);
|
||||||
|
printf("Blank a used CD-RW (is combinable with burning in one run):\n");
|
||||||
|
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
|
||||||
|
printf("Format a DVD-RW once before first use with libburner:\n");
|
||||||
|
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
|
||||||
|
printf("Burn two audio tracks:\n");
|
||||||
|
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
||||||
|
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
||||||
|
printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]);
|
||||||
|
printf("Burn a compressed afio archive on-the-fly:\n");
|
||||||
|
printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n");
|
||||||
|
printf(" %s --drive /dev/hdc -\n", argv[0]);
|
||||||
|
printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n");
|
||||||
|
if (insuffient_parameters)
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = libburner_setup(argc, argv);
|
||||||
|
if (ret)
|
||||||
|
exit(ret);
|
||||||
|
|
||||||
|
printf("Initializing libburnia.pykix.org ...\n");
|
||||||
|
if (burn_initialize())
|
||||||
|
printf("Done\n");
|
||||||
|
else {
|
||||||
|
printf("FAILED\n");
|
||||||
|
fprintf(stderr,"\nFATAL: Failed to initialize.\n");
|
||||||
|
exit(33);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print messages of severity SORRY or more directly to stderr */
|
||||||
|
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
||||||
|
|
||||||
|
/* Activate the default signal handler which eventually will try to
|
||||||
|
properly shutdown drive and library on aborting events. */
|
||||||
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
|
|
||||||
|
/** Note: driveno might change its value in this call */
|
||||||
|
ret = libburner_aquire_drive(drive_adr, &driveno);
|
||||||
|
if (ret<=0) {
|
||||||
|
fprintf(stderr,"\nFATAL: Failed to aquire drive.\n");
|
||||||
|
{ ret = 34; goto finish_libburn; }
|
||||||
|
}
|
||||||
|
if (ret == 2)
|
||||||
|
{ ret = 0; goto release_drive; }
|
||||||
|
if (do_blank) {
|
||||||
|
if (do_blank > 100)
|
||||||
|
ret = libburner_format_row(drive_list[driveno].drive);
|
||||||
|
else
|
||||||
|
ret = libburner_blank_disc(drive_list[driveno].drive,
|
||||||
|
do_blank == 1);
|
||||||
|
if (ret<=0)
|
||||||
|
{ ret = 36; goto release_drive; }
|
||||||
|
}
|
||||||
|
if (source_adr_count > 0) {
|
||||||
|
ret = libburner_payload(drive_list[driveno].drive,
|
||||||
|
source_adr, source_adr_count,
|
||||||
|
do_multi, simulate_burn, all_tracks_type);
|
||||||
|
if (ret<=0)
|
||||||
|
{ ret = 38; goto release_drive; }
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
release_drive:;
|
||||||
|
if (drive_is_grabbed)
|
||||||
|
burn_drive_release(drive_list[driveno].drive, 0);
|
||||||
|
|
||||||
|
finish_libburn:;
|
||||||
|
/* This app does not bother to know about exact scan state.
|
||||||
|
Better to accept a memory leak here. We are done anyway. */
|
||||||
|
/* burn_drive_info_free(drive_list); */
|
||||||
|
|
||||||
|
burn_finish();
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* License and copyright aspects:
|
||||||
|
|
||||||
|
This all is provided under GPL.
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
libburner is a compilation of my own contributions to test/burniso.c and
|
||||||
|
fresh code which replaced the remaining parts under copyright of
|
||||||
|
Derek Foreman.
|
||||||
|
My respect and my thanks to Derek for providing me a start back in 2005.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
78
libburn/tags/ZeroThreeZero/test/poll.c
Normal file
78
libburn/tags/ZeroThreeZero/test/poll.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#include "libburn/libburn.h"
|
||||||
|
#include "libburn/toc.h"
|
||||||
|
#include "libburn/mmc.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
static struct burn_drive_info *drives;
|
||||||
|
static unsigned int n_drives;
|
||||||
|
int NEXT;
|
||||||
|
|
||||||
|
static void catch_int ()
|
||||||
|
{
|
||||||
|
NEXT = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void poll_drive(int d)
|
||||||
|
{
|
||||||
|
enum burn_disc_status s;
|
||||||
|
|
||||||
|
fprintf(stderr, "polling disc in %s - %s:\n",
|
||||||
|
drives[d].vendor, drives[d].product);
|
||||||
|
|
||||||
|
if (!burn_drive_grab(drives[d].drive, 1)) {
|
||||||
|
fprintf(stderr, "Unable to open the drive!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (burn_drive_get_status(drives[d].drive, NULL))
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
while ((s = burn_disc_get_status(drives[d].drive))
|
||||||
|
== BURN_DISC_UNREADY)
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
while (NEXT == 0) {
|
||||||
|
sleep(2);
|
||||||
|
mmc_get_event(drives[d].drive);
|
||||||
|
}
|
||||||
|
burn_drive_release(drives[d].drive, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct sigaction newact;
|
||||||
|
struct sigaction oldact;
|
||||||
|
fprintf(stderr, "Initializing library...");
|
||||||
|
if (burn_initialize())
|
||||||
|
fprintf(stderr, "Success\n");
|
||||||
|
else {
|
||||||
|
printf("Failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Scanning for devices...");
|
||||||
|
while (!burn_drive_scan(&drives, &n_drives)) ;
|
||||||
|
fprintf(stderr, "Done\n");
|
||||||
|
if (!drives) {
|
||||||
|
printf("No burner found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
newact.sa_handler = catch_int;
|
||||||
|
sigaction(SIGINT, &newact, &oldact);
|
||||||
|
for (i = 0; i < n_drives; i++) {
|
||||||
|
NEXT=0;
|
||||||
|
poll_drive(i);
|
||||||
|
}
|
||||||
|
sigaction(SIGINT, &oldact, NULL);
|
||||||
|
burn_drive_info_free(drives);
|
||||||
|
burn_finish();
|
||||||
|
return 0;
|
||||||
|
}
|
48
libburn/tags/ZeroThreeZero/test/structest.c
Normal file
48
libburn/tags/ZeroThreeZero/test/structest.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libburn/libburn.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *path;
|
||||||
|
struct burn_track *track;
|
||||||
|
struct burn_disc *disc;
|
||||||
|
struct burn_session *session;
|
||||||
|
struct burn_source *src;
|
||||||
|
|
||||||
|
disc = burn_disc_create();
|
||||||
|
session = burn_session_create();
|
||||||
|
burn_disc_add_session(disc, session, BURN_POS_END);
|
||||||
|
|
||||||
|
/* Define a source for all of the tracks */
|
||||||
|
path = strdup("/etc/hosts");
|
||||||
|
src = burn_file_source_new(path, NULL);
|
||||||
|
|
||||||
|
/* Add ten tracks to a session */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
track = burn_track_create();
|
||||||
|
burn_session_add_track(session, track, 0);
|
||||||
|
if (burn_track_set_source(track, src) != BURN_SOURCE_OK) {
|
||||||
|
printf("problem with the source\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add ten tracks to a session */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
track = burn_track_create();
|
||||||
|
burn_session_add_track(session, track, 0);
|
||||||
|
if (burn_track_set_source(track, src) != BURN_SOURCE_OK) {
|
||||||
|
printf("problem with the source\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a session */
|
||||||
|
burn_session_remove_track(session, track);
|
||||||
|
|
||||||
|
burn_structure_print_disc(disc);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user