Adding upstream version 1.22.20.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
4edf0f5987
commit
1879661313
2130 changed files with 1371224 additions and 0 deletions
1
.dist-vcs-id
Normal file
1
.dist-vcs-id
Normal file
|
@ -0,0 +1 @@
|
|||
8243233fc5173110798cbc22711fb4675a356d02
|
1
.dist-vcs-url
Normal file
1
.dist-vcs-url
Normal file
|
@ -0,0 +1 @@
|
|||
https://git.dpkg.org/git/dpkg/dpkg.git
|
1
.dist-version
Normal file
1
.dist-version
Normal file
|
@ -0,0 +1 @@
|
|||
1.22.20
|
1
ABOUT-NLS
Normal file
1
ABOUT-NLS
Normal file
|
@ -0,0 +1 @@
|
|||
<https://www.gnu.org/software/gettext/manual/html_node/Users.html>
|
35
AUTHORS
Normal file
35
AUTHORS
Normal file
|
@ -0,0 +1,35 @@
|
|||
It is currently maintained by:
|
||||
|
||||
Guillem Jover <guillem@debian.org> (2006-)
|
||||
|
||||
and has previously been maintained by:
|
||||
|
||||
Raphaël Hertzog <hertzog@debian.org> (2008-2015)
|
||||
Christian Perrier <bubulle@debian.org> (2006-2008)
|
||||
Frank Lichtenheld <djpig@debian.org> (2006-2009)
|
||||
Brendan O'Dea <bod@debian.org> (2006-2007)
|
||||
Scott James Remnant <scott@netsplit.com> (2004-2005)
|
||||
Adam Heath <doogie@brainfood.com> (2001-2003)
|
||||
Wichert Akkerman <wakkerma@debian.org> (1999-2003)
|
||||
Ben Collins <bcollins@debian.org> (1999-2001)
|
||||
Daniel Jacobowitz <dan@debian.org> (1998)
|
||||
J.H.M. Dassen (Ray) <jdassen@wi.LeidenUniv.nl> (1998)
|
||||
James Troup <jjtroup@comp.brad.ac.uk> (1998)
|
||||
Nils Rennebarth <nils@debian.org> (1998)
|
||||
Klee Dienes <klee@debian.org> (1997)
|
||||
Guy Maor <maor@ece.utexas.edu> (1997)
|
||||
Heiko Schlittermann <hs@schlittermann.de> (1996)
|
||||
|
||||
the C implementation of dpkg was originally written and maintained by:
|
||||
|
||||
Ian Jackson <ijackson@chiark.greenend.org.uk> (1994-1998)
|
||||
|
||||
based on the Perl implementation written and/or maintained by:
|
||||
|
||||
Matt Welsh <mdw@sunsite.unc.edu> (1994)
|
||||
Carl Streeter <streeter@cae.wisc.edu> (1994)
|
||||
Ian Murdock <imurdock@debian.org> (1994)
|
||||
|
||||
Countless other people have contributed to dpkg (see THANKS) and provided
|
||||
code for which they claim copyright (see debian/copyright). Many thanks
|
||||
to them all.
|
339
COPYING
Normal file
339
COPYING
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
16925
ChangeLog.old
Normal file
16925
ChangeLog.old
Normal file
File diff suppressed because it is too large
Load diff
264
Makefile.am
Normal file
264
Makefile.am
Normal file
|
@ -0,0 +1,264 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
if BUILD_DSELECT
|
||||
MAYBE_DSELECT = dselect
|
||||
endif
|
||||
|
||||
SUBDIRS = \
|
||||
lib \
|
||||
src \
|
||||
utils \
|
||||
$(MAYBE_DSELECT) \
|
||||
scripts \
|
||||
po \
|
||||
man \
|
||||
# EOL
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
dist_aclocal_DATA = \
|
||||
m4/dpkg-arch.m4 \
|
||||
m4/dpkg-build.m4 \
|
||||
m4/dpkg-compiler.m4 \
|
||||
m4/dpkg-coverage.m4 \
|
||||
m4/dpkg-funcs.m4 \
|
||||
m4/dpkg-headers.m4 \
|
||||
m4/dpkg-libs.m4 \
|
||||
m4/dpkg-linker.m4 \
|
||||
m4/dpkg-progs.m4 \
|
||||
m4/dpkg-types.m4 \
|
||||
m4/dpkg-unicode.m4 \
|
||||
# EOL
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
data/pie-compile.specs \
|
||||
data/pie-link.specs \
|
||||
data/no-pie-compile.specs \
|
||||
data/no-pie-link.specs \
|
||||
data/cputable \
|
||||
data/ostable \
|
||||
data/abitable \
|
||||
data/tupletable \
|
||||
# EOL
|
||||
|
||||
dist_doc_DATA = \
|
||||
doc/README.api \
|
||||
doc/README.feature-removal-schedule \
|
||||
# EOL
|
||||
|
||||
dist_docspec_DATA = \
|
||||
doc/spec/build-driver.txt \
|
||||
doc/spec/frontend-api.txt \
|
||||
doc/spec/protected-field.txt \
|
||||
doc/spec/rootless-builds.txt \
|
||||
doc/spec/triggers.txt \
|
||||
# EOL
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog.old \
|
||||
README.l10n \
|
||||
autogen \
|
||||
build-aux/gen-changelog \
|
||||
build-aux/gen-release \
|
||||
build-aux/get-vcs-id \
|
||||
build-aux/get-version \
|
||||
build-aux/lcov-inject \
|
||||
build-aux/run-script \
|
||||
build-aux/test-runner \
|
||||
doc/coding-style.txt \
|
||||
debian/README.bug-usertags \
|
||||
debian/changelog \
|
||||
debian/control \
|
||||
debian/copyright \
|
||||
debian/dpkg-dev.NEWS \
|
||||
debian/dpkg-dev.docs \
|
||||
debian/dpkg-dev.install \
|
||||
debian/dpkg-dev.manpages \
|
||||
debian/dpkg.alternatives.logrotate \
|
||||
debian/dpkg.cfg \
|
||||
debian/dpkg.cron.daily \
|
||||
debian/dpkg.docs \
|
||||
debian/dpkg.dpkg-db-backup.service \
|
||||
debian/dpkg.dpkg-db-backup.timer \
|
||||
debian/dpkg.install \
|
||||
debian/dpkg.manpages \
|
||||
debian/dpkg.postinst \
|
||||
debian/dpkg.postrm \
|
||||
debian/dpkg.logrotate \
|
||||
debian/dpkg.lintian-overrides \
|
||||
debian/dpkg.lintian-profile \
|
||||
debian/dselect.cfg \
|
||||
debian/dselect.docs \
|
||||
debian/dselect.install \
|
||||
debian/dselect.lintian-overrides \
|
||||
debian/dselect.manpages \
|
||||
debian/dselect.postrm \
|
||||
debian/libdpkg-dev.install \
|
||||
debian/libdpkg-dev.manpages \
|
||||
debian/libdpkg-perl.install \
|
||||
debian/source/format \
|
||||
debian/source/lintian-overrides \
|
||||
debian/not-installed \
|
||||
debian/rules \
|
||||
debian/shlibs.default \
|
||||
debian/shlibs.override \
|
||||
debian/tests/control \
|
||||
debian/tests/test-func \
|
||||
debian/tests/test-func-root \
|
||||
debian/tests/test-not-root \
|
||||
debian/tests/test-root \
|
||||
po/its/polkit.its \
|
||||
po/its/polkit.loc \
|
||||
# EOL
|
||||
|
||||
.PHONY: doc
|
||||
|
||||
doc: doc/Doxyfile
|
||||
$(DOXYGEN) doc/Doxyfile
|
||||
|
||||
doc-clean:
|
||||
rm -rf doc/html/
|
||||
|
||||
# Code coverage support
|
||||
|
||||
.PHONY: coverage coverage-clean
|
||||
|
||||
if COVERAGE_ENABLED
|
||||
LCOV_OPTS = --quiet --rc checksum=1 --rc branch_coverage=1
|
||||
LCOV_CAPTURE_OPTS = $(LCOV_OPTS) --no-recursion \
|
||||
--directory $(top_builddir)/lib/dpkg \
|
||||
--directory $(top_builddir)/src/common \
|
||||
--directory $(top_builddir)/src/deb \
|
||||
--directory $(top_builddir)/src/split \
|
||||
--directory $(top_builddir)/src/divert \
|
||||
--directory $(top_builddir)/src/query \
|
||||
--directory $(top_builddir)/src/trigger \
|
||||
--directory $(top_builddir)/src/statoverride \
|
||||
--directory $(top_builddir)/src/main \
|
||||
--directory $(top_builddir)/utils \
|
||||
# EOL
|
||||
LCOV_INJECT = $(PERL) -i $(top_srcdir)/build-aux/lcov-inject
|
||||
|
||||
coverage: all
|
||||
: # Remove coverage data from any previous run
|
||||
rm -f *.lcov
|
||||
find -name '*.gcda' -o -name '*.gcov' | xargs rm -f
|
||||
|
||||
: # Initialize data
|
||||
$(LCOV) $(LCOV_CAPTURE_OPTS) --capture --initial \
|
||||
--output-file dpkg_base.lcov
|
||||
: # Run test cases
|
||||
$(MAKE) -C lib/dpkg check
|
||||
$(MAKE) -C src check
|
||||
$(MAKE) -C utils check
|
||||
: # Merge test coverage data
|
||||
$(LCOV) $(LCOV_CAPTURE_OPTS) --capture \
|
||||
--output-file dpkg_test.lcov
|
||||
$(LCOV) $(LCOV_OPTS) \
|
||||
--add-tracefile dpkg_base.lcov \
|
||||
--add-tracefile dpkg_test.lcov \
|
||||
--output-file dpkg.lcov
|
||||
: # Generate reports
|
||||
$(LCOV) $(LCOV_OPTS) --list dpkg.lcov
|
||||
$(LCOV_GENHTML) $(LCOV_OPTS) \
|
||||
--legend --title "dpkg $(VERSION) C code coverage" \
|
||||
--output-directory doc/coverage dpkg.lcov
|
||||
|
||||
$(MAKE) -C scripts $@
|
||||
|
||||
: # XXX: Inject perl coverage into lcov index files. This is a fragile
|
||||
: # hack which might break depending on the html output generated.
|
||||
$(LCOV_INJECT) doc/coverage/index-sort-b.html
|
||||
$(LCOV_INJECT) doc/coverage/index-sort-f.html
|
||||
$(LCOV_INJECT) doc/coverage/index-sort-l.html
|
||||
$(LCOV_INJECT) doc/coverage/index.html
|
||||
|
||||
coverage-clean:
|
||||
rm -rf doc/coverage/
|
||||
find -name '*.gcno' -o -name '*.gcda' -o \
|
||||
-name '*.gcov' -o -name '*.lcov' | xargs rm -f
|
||||
$(MAKE) -C scripts $@
|
||||
else
|
||||
coverage:
|
||||
@echo "Need to reconfigure with --enable-coverage"
|
||||
|
||||
coverage-clean:
|
||||
endif
|
||||
|
||||
test_scripts = \
|
||||
t/po.t \
|
||||
t/pod.t \
|
||||
t/pod-spell.t \
|
||||
t/pod-coverage.t \
|
||||
t/synopsis.t \
|
||||
t/minimum-version.t \
|
||||
t/module-version.t \
|
||||
t/syntax.t \
|
||||
t/strict.t \
|
||||
t/critic.t \
|
||||
t/codespell.t \
|
||||
t/shellcheck.t \
|
||||
t/cppcheck.t \
|
||||
# EOL
|
||||
|
||||
test_data = \
|
||||
t/codespell/stopwords \
|
||||
t/cppcheck/cppcheck.supp \
|
||||
t/critic/perlcriticrc \
|
||||
# EOL
|
||||
|
||||
EXTRA_DIST += \
|
||||
tests \
|
||||
$(test_scripts) \
|
||||
$(test_data) \
|
||||
# EOL
|
||||
|
||||
# We need to use absolute paths here due to strict.t invoking a sub-perl,
|
||||
# while changing dir to source dir on out-of-tree builds.
|
||||
TEST_ENV_VARS = \
|
||||
DPKG_DATADIR=$(abs_top_srcdir)/data \
|
||||
# EOL
|
||||
|
||||
include $(top_srcdir)/build-aux/tap.am
|
||||
|
||||
check-local: tap-check
|
||||
|
||||
.PHONY: update-po
|
||||
|
||||
update-po:
|
||||
$(MAKE) -C po update-po
|
||||
$(MAKE) -C scripts/po update-po
|
||||
$(MAKE) -C dselect/po update-po
|
||||
$(MAKE) -C man update-po
|
||||
|
||||
include $(top_srcdir)/build-aux/cpan.am
|
||||
|
||||
# If we create the dist tarball from the git repository, make sure
|
||||
# that we're not forgetting some files, and we are not storing any symlink
|
||||
# in the repository (except for the origins/default one) as those degrade
|
||||
# to regular files due to automake telling tar to dereference them.
|
||||
#
|
||||
# XXX: As long as we have the Makefile based functional test suite, we need
|
||||
# to remove .gitignore files from it, because we are including the entire
|
||||
# hierarchy in EXTRA_DIST.
|
||||
dist-hook:
|
||||
echo $(VERSION) >$(distdir)/.dist-version
|
||||
echo $(PACKAGE_VCS_URL) >$(distdir)/.dist-vcs-url
|
||||
echo $(PACKAGE_VCS_ID) >$(distdir)/.dist-vcs-id
|
||||
find "$(distdir)/tests" -type f -name '.git*' | xargs rm -f
|
||||
if [ -e .git ]; then \
|
||||
for file in `git ls-tree -r HEAD | grep ^12 | grep -v t/origins/default`; do \
|
||||
echo "$$file is a symlink packed as a file on the dist tar" >&2 ; \
|
||||
exit 1 ; \
|
||||
done ; \
|
||||
for file in `git ls-files | grep -vE '\.(git|mailmap)'`; do \
|
||||
if [ ! -e "$(distdir)/$$file" ]; then \
|
||||
echo "$$file is missing in $(distdir)" >&2 ; \
|
||||
exit 1 ; \
|
||||
fi ; \
|
||||
done ; \
|
||||
XDG_CONFIG_HOME= HOME= \
|
||||
git log -C --stat 1.15.0.. >$(distdir)/ChangeLog; \
|
||||
fi
|
||||
|
||||
clean-local: doc-clean coverage-clean tap-clean
|
1374
Makefile.in
Normal file
1374
Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
1
NEWS
Normal file
1
NEWS
Normal file
|
@ -0,0 +1 @@
|
|||
See debian/changelog for major changes between dpkg releases.
|
142
README
Normal file
142
README
Normal file
|
@ -0,0 +1,142 @@
|
|||
dpkg - Debian's package maintenance system
|
||||
|
||||
This is the dpkg suite of programs that form the foundation of the Debian's
|
||||
package management system; on the lower layer there are ‘dpkg-deb’ and
|
||||
‘dpkg-split’ programs handling the binary formats, and ‘dpkg-source’ program
|
||||
handling the source formats; there is a collection of tools to handle building
|
||||
source packages into binary packages; there is the medium-level and less
|
||||
user-friendly command-line interface (CLI) in the form of the ‘dpkg’ command;
|
||||
and then there is the terminal user interface (TUI) ‘dselect’ program (which
|
||||
has gone out of preference in favor of the apt (CLI) and aptitude (TUI)
|
||||
programs).
|
||||
|
||||
The dpkg suite also includes some other programs currently maintained
|
||||
on external repositories, namely ‘dpkg-repack’, ‘dpkg-www’, ‘dupload’
|
||||
and ‘debsig-verify’.
|
||||
|
||||
|
||||
Releases
|
||||
--------
|
||||
|
||||
The current legacy, stable and development releases can be found at:
|
||||
|
||||
<https://deb.debian.org/debian/pool/main/d/dpkg/>
|
||||
|
||||
For older releases check:
|
||||
|
||||
<https://snapshot.debian.org/package/dpkg/>
|
||||
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
The subscription interface and web archives can be found at:
|
||||
|
||||
<https://lists.debian.org/debian-dpkg/>
|
||||
|
||||
The mailing list address is (no subscription required to post):
|
||||
|
||||
debian-dpkg@lists.debian.org
|
||||
|
||||
|
||||
Source Repository
|
||||
-----------------
|
||||
|
||||
The primary repository can be browsed and cloned from:
|
||||
|
||||
<https://git.dpkg.org/git/dpkg/dpkg.git>
|
||||
|
||||
|
||||
Building from git source
|
||||
------------------------
|
||||
|
||||
To prepare the dpkg source tree from git before starting the build process
|
||||
some required software needs to be installed:
|
||||
|
||||
GNU autoconf >= 2.60
|
||||
GNU automake >= 1.11
|
||||
GNU libtool >= 2.0
|
||||
GNU autopoint >= 0.19.7 (from GNU gettext)
|
||||
GNU gettext >= 0.19.7 (only with --enable-nls)
|
||||
|
||||
After installing the needed software, and running the following command on
|
||||
the git tree:
|
||||
|
||||
$ ./autogen
|
||||
|
||||
the source should be roughly equivalent to the distributed tar source.
|
||||
|
||||
To enable translated documentation this software will be needed:
|
||||
|
||||
po4a >= 0.59
|
||||
|
||||
|
||||
Building from tar source
|
||||
------------------------
|
||||
|
||||
The minimum software required to configure and build dpkg from a tarball is:
|
||||
|
||||
C99 compiler (see doc/coding-style.txt)
|
||||
perl (see doc/coding-style.txt)
|
||||
pkgconf
|
||||
GNU make
|
||||
|
||||
To enable optional functionality or programs, this software might be needed:
|
||||
|
||||
libmd (used by libdpkg, required if libc is missing digest functions)
|
||||
libz (from zlib, used instead of gzip command-line tool)
|
||||
liblzma (from xz utils, used instead of xz command-line tool)
|
||||
libzstd (from libzstd, used instead of zstd command-line tool)
|
||||
libbz2 (from bzip2, used instead of bzip2 command-line tool)
|
||||
libselinux
|
||||
curses compatible library (needed on --enable-dselect)
|
||||
|
||||
To run the test suite («make check» or «make authorcheck» for author tests,
|
||||
those that might not be pertinent during release builds) the following
|
||||
software might be needed:
|
||||
|
||||
Test::MinimumVersion perl module (optional, author)
|
||||
Test::Pod perl module (optional)
|
||||
Test::Pod::Coverage perl module (optional, author)
|
||||
Test::Spelling perl module (optional, author)
|
||||
Test::Strict perl module (optional)
|
||||
Test::Synopsis perl module (optional, author)
|
||||
Test::Perl::Critic perl module (optional, author)
|
||||
aspell (optional, author)
|
||||
aspell-en (optional, author)
|
||||
codespell (optional, author)
|
||||
cppcheck (optional, author)
|
||||
fakeroot (optional)
|
||||
sop [sqop (from Sequoia-PGP), pgpainless-cli] (optional)
|
||||
sq (from Sequoia-PGP, optional)
|
||||
gpg-sq (from Sequoia-PGP, optional), gpg (optional)
|
||||
i18nspector (optional, author)
|
||||
shellcheck (optional, author)
|
||||
|
||||
To enable additional developer's documentation («make doc») this software
|
||||
will be needed:
|
||||
|
||||
pod2man
|
||||
doxygen
|
||||
dot
|
||||
|
||||
To enable code coverage («./configure --enable-coverage; make coverage»)
|
||||
this software is needed:
|
||||
|
||||
lcov (from the Linux Test Project)
|
||||
Devel-Cover perl module
|
||||
|
||||
The build process is done by running the usual «./configure; make». To
|
||||
see all available configuration options please run «./configure --help».
|
||||
The following configure options might be of interest to disable specific
|
||||
programs:
|
||||
|
||||
--disable-dselect
|
||||
--disable-start-stop-daemon
|
||||
--disable-update-alternatives
|
||||
|
||||
And the following to disable modifications to the build flags:
|
||||
|
||||
--disable-compiler-warnings
|
||||
--disable-compiler-optimizations
|
||||
--disable-linker-optimizations
|
61
README.l10n
Normal file
61
README.l10n
Normal file
|
@ -0,0 +1,61 @@
|
|||
Translators, when adding/updating your translation files, please follow
|
||||
the following rules:
|
||||
|
||||
* Do not update debian/changelog:
|
||||
|
||||
- The file will get generated out of the commit messages at release time.
|
||||
- Beware that you should NOT update any of the legacy ChangeLog.old
|
||||
files for translation updates.
|
||||
|
||||
* Format of commit message
|
||||
|
||||
Following guidelines in <https://wiki.debian.org/Teams/Dpkg/GitUsage>
|
||||
you should start the commit message with a summary line, followed by an
|
||||
empty line and optional pseudo-headers.
|
||||
|
||||
The summary line should use the following format:
|
||||
|
||||
«po: <Action> <Language> [<part> ]translation»
|
||||
|
||||
Where:
|
||||
|
||||
- <Action> is one of “Update” or “Add”,
|
||||
- <Language> should be capitalized (such as “English”),
|
||||
- <part> should be one of «programs» (for lib/, src/ and utils/), «dselect»,
|
||||
«scripts» and «man pages» (man/), or not be set if the commit includes
|
||||
changes to various parts.
|
||||
|
||||
For example:
|
||||
|
||||
==========================================================
|
||||
po: Update German programs translation
|
||||
|
||||
Closes: #123456
|
||||
Reviewed-by: Full Name <email@example.org>
|
||||
==========================================================
|
||||
|
||||
* Use of po/LINGUAS, dselect/po/LINGUAS or scripts/po/LINGUAS:
|
||||
|
||||
When ADDING a new translation, don't forget adding the language to
|
||||
the LINGUAS file, otherwise it will not be used.
|
||||
|
||||
* Always CHECK your translations:
|
||||
|
||||
You MUST check your PO files for validity.
|
||||
|
||||
The correct syntax for doing so is:
|
||||
|
||||
$ msgmerge --update <file> dpkg.pot
|
||||
$ msgfmt --check --output-file /dev/null --statistics <file>
|
||||
$ msgcat <file> >/dev/null
|
||||
|
||||
- msgmerge updates your file with the current POT file.
|
||||
- msgfmt checks it for validity.
|
||||
- msgcat may detect encoding problems.
|
||||
|
||||
In addition to the above, the easiest way to check that the po4a
|
||||
translations have valid POD markup, is to try to build them (please
|
||||
see the Building sections in the README file for further details
|
||||
regarding the setup of the source tree):
|
||||
|
||||
$ make -C man
|
243
THANKS
Normal file
243
THANKS
Normal file
|
@ -0,0 +1,243 @@
|
|||
A Costa <agcosta@gis.net>
|
||||
Aaron M. Ucko <ucko@debian.org>
|
||||
Adam Conrad <adconrad@0c3.net>
|
||||
Adam Heath <doogie@debian.org>
|
||||
Adeodato Simó <adeodato@debian.org>
|
||||
Alberto Garcia <berto@gpul.org>
|
||||
Américo Monteiro <a_monteiro@gmx.com>
|
||||
Anand Kumria <wildfire@progsoc.org>
|
||||
Andreas Barth <aba@not.so.argh.org>
|
||||
Andreas Metzler <ametzler@debian.org>
|
||||
Andreas Påhlsson <andreas.pahlsson@xcerion.com>
|
||||
Andrew Ferrier <andrew@new-destiny.co.uk>
|
||||
Andrew Hobson <ahobson@eng.mindspring.net>
|
||||
Andrew Suffield <asuffield@debian.org>
|
||||
Anthony Towns <aj@azure.humbug.org.au>
|
||||
Aurelien Jarno <aurel32@debian.org>
|
||||
Bart Cornelis <cobaco@skolelinux.no>
|
||||
Bart Martens <bart.martens@advalvas.be>
|
||||
Bastian Kleineidam <calvin@debian.org>
|
||||
Bastien ROUCARIÈS <roucaries.bastien@gmail.com>
|
||||
Ben Collins <bcollins@debian.org>
|
||||
Ben Hutchings <ben@decadent.org.uk>
|
||||
Ben Pfaff <blp@cs.stanford.edu>
|
||||
Bill Allombert <ballombe@debian.org>
|
||||
Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
|
||||
Boyuan Yang <byang@debian.org>
|
||||
Branden Robinson <branden@debian.org>
|
||||
Branko Lankester
|
||||
Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
|
||||
Bruce Perens <bruce@pixar.com>
|
||||
Bruce Sass <bmsass@shaw.ca>
|
||||
Carl Streeter <streeter@cae.wisc.edu>
|
||||
Carlos Laviola <claviola@brfree.com.br>
|
||||
Carlos Z.F. Liu <carlosliu@users.sourceforge.net>
|
||||
Carsten Hey <carsten@debian.org>
|
||||
Carsten Leonhardt <leo@debian.org>
|
||||
Changwoo Ryu <cwryu@debian.org>
|
||||
Charles Briscoe-Smith <cpbs@debian.org>
|
||||
Chris Lamb <lamby@debian.org>
|
||||
Christian Haggstrom <chm@c00.info>
|
||||
Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
|
||||
Christoph Maser <cm@financial.com>
|
||||
Christophe Le Bars <clebars@teaser.fr>
|
||||
Claus Hindsgaul <claus.hindsgaul@gmail.com>
|
||||
Clytie Siddall <clytie@riverland.net.au>
|
||||
Colin Plumb <colin@nyx.net>
|
||||
Colin Watson <cjwatson@debian.org>
|
||||
Dafydd Harries <daf@muse.19inch.net>
|
||||
Dan Gohman <gohmandj@mrs.umn.edu>
|
||||
Dan Streetman <ddstreet@canonical.com>
|
||||
Daniel Hahler <debian-bugs@thequod.de>
|
||||
Daniel Jacobowitz <dan@debian.org>
|
||||
Daniel Kahn Gillmor <dkg@fifthhorseman.net>
|
||||
Daniel Leidert <daniel.leidert@wgdd.de>
|
||||
Daniel Nylander <yeager@lidkoping.net>
|
||||
Daniel Shahaf <danielsh@apache.org>
|
||||
Darren Stalder <torin@daft.com>
|
||||
David Huggins-Daines <dhd@debian.org>
|
||||
David Kalnischkies <david@kalnischkies.de>
|
||||
David Lopez Moreno <david.lopez.moreno@hispalinux.es>
|
||||
David Rabel <david.rabel@noresoft.com>
|
||||
Denis Barbier <barbier@debian.org>
|
||||
Didier Vidal <didier-devel@melix.net>
|
||||
Dmitry Shachnev <mitya57@debian.org>
|
||||
Don Armstrong <don@debian.org>
|
||||
Eddy Petrișor <eddy.petrisor@gmail.com>
|
||||
Erast Benson <erast@gnusolaris.org>
|
||||
Erick Branderhorst <branderhorst@heel.fgg.eur.nl>
|
||||
Flavio Stanchina <flavio@stanchina.net>
|
||||
Frank S. Thomas <frank@thomas-alfeld.de>
|
||||
Frans Spiesschaert <Frans.Spiesschaert@yucom.be>
|
||||
Frédéric Bothamy <frederic.bothamy@free.fr>
|
||||
Galen Hazelwood <galenh@debian.org>
|
||||
Goswin Brederlow <brederlo@informatik.uni-tuebingen.de>
|
||||
Guy Maor <maor@debian.org>
|
||||
Hanno Böck <hanno@hboeck.de>
|
||||
Hans Fredrik Nordhaug <hans@nordhaug.priv.no>
|
||||
Hartmut Koptein <koptein@naffel.de>
|
||||
Heiko Schlittermann <hs@schlittermann.de>
|
||||
Helge Kreutzmann <debian@helgefjell.de>
|
||||
Helmut Grohne <helmut@subdivi.de>
|
||||
Hiroshi KISE <fuyuneko@ryukyu.ne.jp>
|
||||
Holger Wansing <linux@wansing-online.de>
|
||||
Ian Eure <ieure@debian.org>
|
||||
Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
Ian Murdock <imurdock@debian.org>
|
||||
Ian Zimmerman <itz@buug.org>
|
||||
Ingo Saitz <ingo@debian.org>
|
||||
Ivar Smolin <okul@linux.ee>
|
||||
Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
J.H.M. Dassen <jdassen@cistron.nl>
|
||||
Jack Bates <wdz7eo@nottheoilrig.com>
|
||||
Jacobo Tarrio <jtarrio@debian.org>
|
||||
Jakub Wilk <jwilk@debian.org>
|
||||
James R. Van Zandt <jrvz@comcast.net>
|
||||
James Troup <troup@debian.org>
|
||||
James Vega <jamessan@debian.org>
|
||||
Jared Spiegel <jrrs@frontiernet.net>
|
||||
Jari Aalto <jari.aalto@cante.net>
|
||||
Javier Fernández-Sanguino Peña <jfs@debian.org>
|
||||
Javier Serrano Polo <javier@jasp.net>
|
||||
Jean-Pierre Giraud <jenapierregiraud75@free.fr>
|
||||
Jeffrey W. Baker <jwbaker@acm.org>
|
||||
Jeroen van Wolffelaar <jeroen@wolffelaar.nl>
|
||||
Jessica Clarke <jrtc27@debian.org>
|
||||
Jim Pick <jim@jimpick.com>
|
||||
Jim Van Zandt <jrv@vanzandt.mv.com>
|
||||
Jiří Paleček <jpalecek@web.de>
|
||||
Joachim Breitner <mail@joachim-breitner.de>
|
||||
Joel Klecker <jk@espy.org>
|
||||
Joey Hess <joeyh@debian.org>
|
||||
Johannes Schauer <josch@debian.org>
|
||||
Johannes Veser <veser@gmx.de>
|
||||
John Wright <jsw@debian.org>
|
||||
John Zaitseff <J.Zaitseff@zap.org.au>
|
||||
Jonathan Nieder <jrnieder@gmail.com>
|
||||
Jordi Mallach <jordi@debian.org>
|
||||
Josh Soref <jsoref@gmail.com>
|
||||
Josh Triplett <josh@joshtriplett.org>
|
||||
Josip Rodin <jrodin@jagor.srce.hr>
|
||||
Juan Cespedes <cespedes@debian.org>
|
||||
Juergen Menden <menden@morgana.camelot.de>
|
||||
Juho Vuori <javuori@cc.helsinki.fi>
|
||||
Julian Andres Klode <jak@debian.org>
|
||||
Julian Gilbey <jdg@debian.org>
|
||||
Julian R <debian@styxxx.de>
|
||||
Julien Cristau <jcristau@debian.org>
|
||||
Junichi Uekawa <dancer@debian.org>
|
||||
Justin Pryzby <justinpryzby@users.sourceforge.net>
|
||||
Jörg Sonnenberger <joerg@netbsd.org>
|
||||
Ken Bloom <kbloom@gmail.com>
|
||||
Kenshi Muto <kmuto@debian.org>
|
||||
Kevin Ryde <user42@zip.com.au>
|
||||
Kim-Minh Kaplan <kkaplan@cdfhp3.in2p3.fr>
|
||||
Klee Dienes <klee@debian.org>
|
||||
Koblinger Egmont <egmont@uhulinux.hu>
|
||||
Kurt B. Kaiser <kbk@shore.net>
|
||||
Kylan Robinson <Kylan_Robinson@selinc.com>
|
||||
Lele Gaifax <lele@seldati.it>
|
||||
Lennert Buytenhek <buytenh+debian@wantstofly.org>
|
||||
Ludovic Rousseau <rousseau@debian.org>
|
||||
Manoj Srivastava <srivasta@debian.org>
|
||||
Manuel A. Fernandez Montecelo <mafm@debian.org>
|
||||
Marc Dequènes <duck@duckcorp.org>
|
||||
Marc Haber <mh+debian-packages@zugschlus.de>
|
||||
Marcel Toele <mtoele@kern.nl>
|
||||
Marcin Owsiany <marcin@owsiany.pl>
|
||||
Marco d'Itri <md@linux.it>
|
||||
Marcus Brinkmann <brinkmd@debian.org>
|
||||
Marek Vasut <marex@denx.de>
|
||||
Mark Rosenstand <mark@borkware.net>
|
||||
Martin Bagge <martin.bagge@glesys.se>
|
||||
Martin Koeppe <mkoeppe@gmx.de>
|
||||
Martin Pitt <martin.pitt@ubuntu.com>
|
||||
Masato Taruishi <taru@debian.or.jp>
|
||||
Mathias Weidner <mathias@weidner.in-bad-schmiedeberg.de>
|
||||
Matt Kraai <kraai@ftbfs.org>
|
||||
Matt Welsh <mdw@sunsite.unc.edu>
|
||||
Matt Zimmerman <mdz@debian.org>
|
||||
Mattia Rizzolo <mattia@debian.org>
|
||||
Maximilian Attems <debian@sternwelten.at>
|
||||
Mert Dirik <mertdirik@gmail.com>
|
||||
Michael Alan Dorman <mdorman@calder.med.miami.edu>
|
||||
Michael Shields <shields@crosslink.net>
|
||||
Michael Sobolev <mss@transas.com>
|
||||
Michael Vogt <mvo@ubuntu.com>
|
||||
Michel Lespinasse <walken@zoy.org>
|
||||
Miguel Figueiredo <elmig@debianpt.org>
|
||||
Miguel Figueiredo <elmig@debianpt.org>
|
||||
Milo Casagrande <milo@milo.name>
|
||||
Miquel van Smoorenburg <miquels@cistron.nl>
|
||||
Miroslav Kure <kurem@debian.cz>
|
||||
Mo Zhou <lumin@debian.org>
|
||||
Modestas Vainius <modax@debian.org>
|
||||
Moritz Muehlenhoff <jmm@inutil.org>
|
||||
NIIBE Yutaka <gniibe@fsij.org>
|
||||
Niall Walsh <niallwalsh@celtux.org>
|
||||
Nicolas Bonifas
|
||||
Nicolas Boulenguez <nicolas@debian.org>
|
||||
Nicolas François <nicolas.francois@centraliens.net>
|
||||
Nicolás Lichtmaier <nick@debian.org>
|
||||
Niels Thykier <niels@thykier.net>
|
||||
Nils Rennebarth <nils@debian.org>
|
||||
Nishanth Aravamudan <nish.aravamudan@canonical.com>
|
||||
Ondřej Surý <ondrej@sury.org>
|
||||
Paul Wise <pabs@debian.org>
|
||||
Peter Krefting <peter@softwolves.pp.se>
|
||||
Peter Mann <Peter.Mann@tuke.sk>
|
||||
Peter van Dijk <peter@dataloss.nl>
|
||||
Petr Cech <cech@atrey.karlin.mff.cuni.cz>
|
||||
Philippe Batailler <pbatailler@teaser.fr>
|
||||
Pierre Habouzit <madcoder@debian.org>
|
||||
Pietro Battiston <me@pietrobattiston.it>
|
||||
Piotr Engelking <inkerman42@gmail.com>
|
||||
Piotr Roszatycki <dexter@fnet.pl>
|
||||
Quentin PAGÈS <quentinantonin@free.fr>
|
||||
Rakesh 'arky' Ambati <rakesh_ambati@yahoo.com>
|
||||
Ralf Treinen <treinen@free.fr>
|
||||
Raphaël Hertzog <hertzog@debian.org>
|
||||
Reiner Herrmann <reiner@reiner-h.de>
|
||||
Richard Kettlewell <rjk@sfere.greenend.org.uk>
|
||||
Riku Voipio <riku.voipio@iki.fi>
|
||||
Robert Luberda <robert@debian.org>
|
||||
Robert Millan <rmh@debian.org>
|
||||
Roderich Schupp <roderich.schupp@gmail.com>
|
||||
Roderick Schertler <roderick@argon.org>
|
||||
Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
||||
Russell Coker <russell@coker.com.au>
|
||||
SZERVÁC Attila <sas@321.hu>
|
||||
Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Scott Barker <scott@mostlylinux.ab.ca>
|
||||
Scott James Remnant <scott@netsplit.com>
|
||||
Sean Finney <seanius@seanius.net>
|
||||
Sergio Gelato <Sergio.Gelato@astro.su.se>
|
||||
Stefano Canepa <sc@linux.it>
|
||||
Stepan Golosunov <stepan@golosunov.pp.ru>
|
||||
Stephane Bortzmeyer <stephane@sources.org>
|
||||
Steve Langasek <vorlon@debian.org>
|
||||
Steven Chamberlain <steven@pyro.eu.org>
|
||||
Sven Joachim <svenjoac@gmx.de>
|
||||
Sven Rudolph <sr1@loom.sax.de>
|
||||
Takuma Yamada <tyamada@takumayamada.com>
|
||||
Taowa Munene-Tardif <taowa@debian.org>
|
||||
Thomas Klausner <wiz@NetBSD.org>
|
||||
Thomas Morin <thomas.morin@enst-bretagne.fr>
|
||||
Timothy G Abbott <tabbott@MIT.EDU>
|
||||
Tom Goulet <tomg@sentex.ca>
|
||||
Tom Lees <tom@lpsg.demon.co.uk>
|
||||
Tomas Pospisek <tpo_deb@sourcepole.ch>
|
||||
Topi Miettinen <Topi.Miettinen@nic.fi>
|
||||
Trek <trek00@inbox.ru>
|
||||
Trần Ngọc Quân <vnwildman@gmail.com>
|
||||
Vagrant Cascadian <vagrant@reproducible-builds.org>
|
||||
Vasilis Vasaitis <v.vasaitis@sms.ed.ac.uk>
|
||||
Wayne Davison <wayned@users.sourceforge.net>
|
||||
Wichert Akkerman <wakkerma@debian.org>
|
||||
YunQiang Su <wzssyqa@gmail.com>
|
||||
Yuri Gribov <tetra2005@gmail.com>
|
||||
Yuri Kozlov <kozlov.y@gmail.com>
|
||||
Zefram <zefram@fysh.org>
|
||||
Zhou Mo <cdluminate@gmail.com>
|
||||
Łukasz Dulny <bartekchom@poczta.onet.pl>
|
||||
林博仁(Buo-ren Lin) <Buo.Ren.Lin@gmail.com>
|
151
TODO
Normal file
151
TODO
Normal file
|
@ -0,0 +1,151 @@
|
|||
RoadMap
|
||||
=======
|
||||
|
||||
<https://wiki.debian.org/Teams/Dpkg/RoadMap>
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
|
||||
Recurring
|
||||
---------
|
||||
|
||||
* Review this file and remove or update the old entries.
|
||||
|
||||
* Look for FIXME and XXX items in the source.
|
||||
|
||||
* Triage as much bugs as possible to get the bug count below 300 ;)
|
||||
and merge as much patches as possible.
|
||||
|
||||
|
||||
Projects
|
||||
--------
|
||||
|
||||
* Merge functionality from debsigs-verify, debsigs:
|
||||
- Redesign OpenPGP signatures support within .deb archive and its policy.
|
||||
|
||||
* Add UTF-8 support to all programs.
|
||||
|
||||
* Discuss and implement:
|
||||
<https://www.hadrons.org/~guillem/debian/docs/origin.proposal>.
|
||||
|
||||
|
||||
Tasks
|
||||
-----
|
||||
|
||||
* C/C++ code cleanup / bug fixes:
|
||||
- Get rid of static variables inside functions.
|
||||
- Coalesce hash and checksum functions.
|
||||
- Split modstatdb_rw into mode and flags.
|
||||
- Move fd function out of mustlib.
|
||||
- Cleanup status chars -> strings hardcoded mappings all over the place.
|
||||
(Fix tied field enum with its dselect description (pkgdisplay.cc))
|
||||
- Refactor src/unpack.c.
|
||||
- Split dpkg.h into independent headers.
|
||||
- Do more unused header include removal.
|
||||
- Add needed includes to all header files.
|
||||
- Get rid of useless "unsigned" modifiers.
|
||||
- Use enums for currently hardcoded literals (replacingfilesandsaid,
|
||||
filetriggers_edited, etc).
|
||||
- Do not use nfmalloc (and friends) for non in-core db memory.
|
||||
- Call nffreeall on exit (need to detangle nfmalloc from non-db first).
|
||||
- Add a size parameter to the buffer API to avoid some useless
|
||||
pipe+fork+copy.
|
||||
- Handle instdir '/' separator consistently.
|
||||
- Check if caching selinux context for second call is possible.
|
||||
- Add missing newlines in --version output.
|
||||
- Handle symlinks in statcmd.c statdb_node_apply().
|
||||
- Fix dpkg termination on SIGPIPE from status-fd.
|
||||
|
||||
* libcompat cleanup:
|
||||
- Add fnmatch, IRIX5 doesn't have it.
|
||||
|
||||
* Man pages:
|
||||
- Add example to dpkg-scanfoo manual pages?
|
||||
- Merge synopsis lines in dpkg-triggers.
|
||||
- Check all command vs action.
|
||||
- Check usage of '|' instead of ', '.
|
||||
- Check position of short option before long option.
|
||||
- Fix dpkg man page, refs to dpkg-deb and dpkg-split, etc.
|
||||
- Fix «. ».
|
||||
|
||||
* L10n:
|
||||
- Check dpkg-divert strings for new and fixable ones.
|
||||
- Standardize translated error messages in the perl code to avoid useless
|
||||
work for translators.
|
||||
|
||||
* s-s-d: Add POSIX capabilities support.
|
||||
|
||||
* dpkg: Deprecate --force-not-root (remove modstatdb_rw rootneeded flags).
|
||||
|
||||
* dpkg: Test and re-enable --command-fd.
|
||||
|
||||
* dpkg: Check --no-act for log_action().
|
||||
|
||||
* test: Add non-regression tests for Dpkg::Source::*.
|
||||
|
||||
* dpkg: Allow packages to register additional files, declare ownership of
|
||||
files for dpkg -S and -L without having dpkg act on this (.psuedolist?).
|
||||
|
||||
* dpkg-checkbuilddeps: Make it easier to use by other programs such as
|
||||
pbuilder or sbuild, so that they can start using the new architecture
|
||||
wildcards automatically.
|
||||
- Support for output format. (#214566)
|
||||
|
||||
* libdpkg: Fix conflicting action -%c, when short is 0.
|
||||
|
||||
* libdpkg: We should set our own obstack_alloc_failed_handler.
|
||||
|
||||
* dpkg: Declarative diversions, as a control archive entry.
|
||||
|
||||
* dpkg: --status for virtual packages.
|
||||
|
||||
? dpkg: --query, -Q.
|
||||
|
||||
* dpkg: Filename field generated by --record-avail.
|
||||
|
||||
? dpkg: Allow external program to specify how to handle conffiles.
|
||||
|
||||
? dpkg: Add --call-maint-script=<script> --maint-script-arg=<arg>
|
||||
--maint-script-arg=<arg> <pkg> <pkg>
|
||||
Where dpkg would not allow <script> to be one of {pre,post}{inst,rm}.
|
||||
Only unknown scripts can be called this way. dpkg would also not keep
|
||||
track of any state for these scripts.
|
||||
|
||||
? dpkg: _Always_ show section in --yet-to-unpack.
|
||||
|
||||
* dpkg: Fix:
|
||||
<joeyh_> package a conflicted with old versions of package b. package b
|
||||
conflicted with old versions of package a. I had the old versions
|
||||
of both installed, and told dpkg to install the new versions of
|
||||
a and b simultaneously. It refused.
|
||||
|
||||
* dselect: Automatically do --yet-to-unpack in installation methods.
|
||||
|
||||
* dselect: Make it understand Replaces.
|
||||
|
||||
* dselect: Per-half focus and keybindings improvements.
|
||||
!missing bug report #1555!
|
||||
|
||||
|
||||
Inadequacies (ponder, some might be fine)
|
||||
------------
|
||||
|
||||
* Conflicts << installation ordering.
|
||||
|
||||
* Search for all pre-depends things at once, bomb out if any not found.
|
||||
|
||||
* Check depending packages when installing new version.
|
||||
|
||||
* Several things ought to be configurable but are not.
|
||||
|
||||
* Filenames containing newlines.
|
||||
|
||||
* Conffile names containing spaces.
|
||||
|
||||
* Handling of case in package names.
|
||||
|
||||
* 'fake' or 'null' packages (useful for equivs or fink system packages).
|
||||
|
||||
* Local conffiles, as well as local files that dpkg should check before
|
||||
overwriting.
|
1740
aclocal.m4
vendored
Normal file
1740
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
9
autogen
Executable file
9
autogen
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ -e .git ] && command -v git >/dev/null 2>&1; then
|
||||
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
fi
|
||||
|
||||
autoreconf --force --install
|
279
build-aux/ar-lib
Executable file
279
build-aux/ar-lib
Executable file
|
@ -0,0 +1,279 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for Microsoft lib.exe
|
||||
|
||||
me=ar-lib
|
||||
scriptversion=2024-06-19.01; # UTC
|
||||
|
||||
# Copyright (C) 2010-2024 Free Software Foundation, Inc.
|
||||
# Written by Peter Rosin <peda@lysator.liu.se>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
|
||||
# func_error message
|
||||
func_error ()
|
||||
{
|
||||
echo "$me: $1" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN* | MSYS*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv in
|
||||
mingw)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin | msys)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_at_file at_file operation archive
|
||||
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
|
||||
# for each of them.
|
||||
# When interpreting the content of the @FILE, do NOT use func_file_conv,
|
||||
# since the user would need to supply preconverted file names to
|
||||
# binutils ar, at least for MinGW.
|
||||
func_at_file ()
|
||||
{
|
||||
operation=$2
|
||||
archive=$3
|
||||
at_file_contents=`cat "$1"`
|
||||
eval set x "$at_file_contents"
|
||||
shift
|
||||
|
||||
for member
|
||||
do
|
||||
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
|
||||
done
|
||||
}
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
func_error "no command. Try '$0 --help' for more information."
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<EOF
|
||||
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
|
||||
|
||||
Members may be specified in a file named with @FILE.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "$me (GNU Automake) $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test $# -lt 3; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
|
||||
AR=$1
|
||||
shift
|
||||
while :
|
||||
do
|
||||
if test $# -lt 2; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
case $1 in
|
||||
-lib | -LIB \
|
||||
| -ltcg | -LTCG \
|
||||
| -machine* | -MACHINE* \
|
||||
| -subsystem* | -SUBSYSTEM* \
|
||||
| -verbose | -VERBOSE \
|
||||
| -wx* | -WX* )
|
||||
AR="$AR $1"
|
||||
shift
|
||||
;;
|
||||
-nologo | -NOLOGO)
|
||||
# We always invoke AR with -nologo, so don't need to add it again.
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
action=$1
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
orig_archive=$1
|
||||
shift
|
||||
func_file_conv "$orig_archive"
|
||||
archive=$file
|
||||
|
||||
# strip leading dash in $action
|
||||
action=${action#-}
|
||||
|
||||
delete=
|
||||
extract=
|
||||
list=
|
||||
quick=
|
||||
replace=
|
||||
index=
|
||||
create=
|
||||
|
||||
while test -n "$action"
|
||||
do
|
||||
case $action in
|
||||
d*) delete=yes ;;
|
||||
x*) extract=yes ;;
|
||||
t*) list=yes ;;
|
||||
q*) quick=yes ;;
|
||||
r*) replace=yes ;;
|
||||
s*) index=yes ;;
|
||||
S*) ;; # the index is always updated implicitly
|
||||
c*) create=yes ;;
|
||||
u*) ;; # TODO: don't ignore the update modifier
|
||||
v*) ;; # TODO: don't ignore the verbose modifier
|
||||
*)
|
||||
func_error "unknown action specified"
|
||||
;;
|
||||
esac
|
||||
action=${action#?}
|
||||
done
|
||||
|
||||
case $delete$extract$list$quick$replace,$index in
|
||||
yes,* | ,yes)
|
||||
;;
|
||||
yesyes*)
|
||||
func_error "more than one action specified"
|
||||
;;
|
||||
*)
|
||||
func_error "no action specified"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$delete"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -REMOVE "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
elif test -n "$extract"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
if test $# -gt 0; then
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -EXTRACT "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
$AR -NOLOGO -LIST "$archive" | tr -d '\r' | sed -e 's/\\/\\\\/g' \
|
||||
| while read member
|
||||
do
|
||||
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
|
||||
done
|
||||
fi
|
||||
|
||||
elif test -n "$quick$replace"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
if test -z "$create"; then
|
||||
echo "$me: creating $orig_archive"
|
||||
fi
|
||||
orig_archive=
|
||||
else
|
||||
orig_archive=$archive
|
||||
fi
|
||||
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_file_conv "${1#@}"
|
||||
set x "$@" "@$file"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
set x "$@" "$file"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
done
|
||||
|
||||
if test -n "$orig_archive"; then
|
||||
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
|
||||
else
|
||||
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
|
||||
fi
|
||||
|
||||
elif test -n "$list"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
$AR -NOLOGO -LIST "$archive" || exit $?
|
||||
fi
|
40
build-aux/autotest.am
Normal file
40
build-aux/autotest.am
Normal file
|
@ -0,0 +1,40 @@
|
|||
EXTRA_DIST += $(srcdir)/at/package.m4
|
||||
|
||||
DISTCLEANFILES += at/atconfig
|
||||
|
||||
AUTOTEST_DEPS = at/atconfig at/atlocal $(TESTSUITE)
|
||||
|
||||
TEST_VERBOSE ?= 0
|
||||
TEST_PARALLEL ?= 1
|
||||
|
||||
TEST_VERBOSE_OPT = $(TEST_VERBOSE:0=)
|
||||
|
||||
TESTSUITEFLAGS =
|
||||
TESTSUITEFLAGS += -j$(TEST_PARALLEL)
|
||||
TESTSUITEFLAGS += $(TEST_VERBOSE_OPT:1=--verbose)
|
||||
|
||||
# The ":;" works around a Bash 3.2 bug when the output is not writable.
|
||||
$(srcdir)/at/package.m4: $(top_srcdir)/configure.ac
|
||||
:;{ \
|
||||
echo '# Signature of the current package.' && \
|
||||
echo 'm4_define([AT_PACKAGE_NAME], [$(PACKAGE_NAME)])' && \
|
||||
echo 'm4_define([AT_PACKAGE_TARNAME], [$(PACKAGE_TARNAME)])' && \
|
||||
echo 'm4_define([AT_PACKAGE_VERSION], [$(PACKAGE_VERSION)])' && \
|
||||
echo 'm4_define([AT_PACKAGE_STRING], [$(PACKAGE_STRING)])' && \
|
||||
echo 'm4_define([AT_PACKAGE_URL], [$(PACKAGE_URL)])' && \
|
||||
echo 'm4_define([AT_PACKAGE_BUGREPORT], [$(PACKAGE_BUGREPORT)])'; \
|
||||
} >'$(srcdir)/at/package.m4'
|
||||
|
||||
autotest-check: $(AUTOTEST_DEPS)
|
||||
$(SHELL) '$(TESTSUITE)' -C at $(TESTSUITEFLAGS)
|
||||
|
||||
autotest-installcheck: $(AUTOTEST_DEPS)
|
||||
$(SHELL) '$(TESTSUITE)' -C at AUTOTEST_PATH='$(bindir)' $(TESTSUITEFLAGS)
|
||||
|
||||
autotest-clean:
|
||||
test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' -C at --clean
|
||||
|
||||
AUTOTEST = $(AUTOM4TE) --language=autotest
|
||||
$(TESTSUITE): $(srcdir)/at/package.m4 $(TESTSUITE_AT)
|
||||
$(AUTOTEST) -I '$(srcdir)/at' -o $@.tmp $@.at
|
||||
mv $@.tmp $@
|
351
build-aux/compile
Executable file
351
build-aux/compile
Executable file
|
@ -0,0 +1,351 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2024-06-19.01; # UTC
|
||||
|
||||
# Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN* | MSYS*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/* | msys/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.lo | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile (GNU Automake) $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
||||
clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \
|
||||
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1815
build-aux/config.guess
vendored
Executable file
1815
build-aux/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
751
build-aux/config.rpath
Executable file
751
build-aux/config.rpath
Executable file
|
@ -0,0 +1,751 @@
|
|||
#! /bin/sh
|
||||
# Output a system dependent set of variables, describing how to set the
|
||||
# run time search path of shared libraries in a binary (executable or
|
||||
# shared library).
|
||||
#
|
||||
# Copyright 1996-2024 Free Software Foundation, Inc.
|
||||
# Taken from GNU libtool, 2001
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# Known limitations:
|
||||
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
|
||||
# than 256 bytes, otherwise the compiler driver will dump core. The only
|
||||
# known workaround is to choose shorter directory names for the build
|
||||
# directory and/or the installation directory.
|
||||
|
||||
# func_usage
|
||||
# outputs to stdout the --help usage message.
|
||||
func_usage ()
|
||||
{
|
||||
echo "\
|
||||
Usage: config.rpath [OPTION] HOST
|
||||
|
||||
Prints shell variable assignments that describe how to hardcode a directory
|
||||
for the lookup of shared libraries into a binary (executable or shared library).
|
||||
|
||||
The first argument passed to this file is the canonical host specification,
|
||||
CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
or
|
||||
CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
|
||||
The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
|
||||
should be set by the caller.
|
||||
|
||||
The set of defined variables is at the end of this script.
|
||||
|
||||
Options:
|
||||
--help print this help and exit
|
||||
--version print version information and exit
|
||||
|
||||
Send patches and bug reports to <bug-gnulib@gnu.org>."
|
||||
}
|
||||
|
||||
# func_version
|
||||
# outputs to stdout the --version message.
|
||||
func_version ()
|
||||
{
|
||||
echo "config.rpath (GNU gnulib, module havelib)"
|
||||
echo "Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
License: All-Permissive.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law."
|
||||
echo
|
||||
printf 'Written by %s.\n' "Bruno Haible"
|
||||
}
|
||||
|
||||
# func_fatal_error message
|
||||
# outputs to stderr a fatal error message, and terminates the program.
|
||||
func_fatal_error ()
|
||||
{
|
||||
echo "config.rpath: *** $1" 1>&2
|
||||
echo "config.rpath: *** Stop." 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Command-line option processing.
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
--help | --hel | --he | --h )
|
||||
func_usage
|
||||
exit 0 ;;
|
||||
--version | --versio | --versi | --vers | --ver | --ve | --v )
|
||||
func_version
|
||||
exit 0 ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
-* )
|
||||
func_fatal_error "unrecognized option: $1"
|
||||
;;
|
||||
* )
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test $# -gt 1; then
|
||||
func_fatal_error "too many arguments"
|
||||
fi
|
||||
if test $# -lt 1; then
|
||||
func_fatal_error "too few arguments"
|
||||
fi
|
||||
|
||||
# All known linkers require a '.a' archive for static linking (except MSVC,
|
||||
# which needs '.lib').
|
||||
libext=a
|
||||
shrext=.so
|
||||
|
||||
host="$1"
|
||||
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
|
||||
# Code taken from libtool.m4's _LT_CC_BASENAME.
|
||||
|
||||
for cc_temp in $CC""; do
|
||||
case $cc_temp in
|
||||
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
|
||||
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
|
||||
\-*) ;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
|
||||
|
||||
# Code taken from libtool.m4's _LT_COMPILER_PIC.
|
||||
|
||||
wl=
|
||||
if test "$GCC" = yes; then
|
||||
wl='-Wl,'
|
||||
else
|
||||
case "$host_os" in
|
||||
aix*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
mingw* | cygwin* | pw32* | os2* | cegcc*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
linux* | k*bsd*-gnu | kopensolaris*-gnu)
|
||||
case $cc_basename in
|
||||
ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
icc* | ifort*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
lf95*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
nagfor*)
|
||||
wl='-Wl,-Wl,,'
|
||||
;;
|
||||
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
ccc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
xl* | bgxl* | bgf* | mpixl*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
como)
|
||||
wl='-lopt='
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ F* | *Sun*Fortran*)
|
||||
wl=
|
||||
;;
|
||||
*Sun\ C*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
newsos6)
|
||||
;;
|
||||
*nto* | *qnx*)
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
rdos*)
|
||||
;;
|
||||
solaris*)
|
||||
case $cc_basename in
|
||||
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
|
||||
wl='-Qoption ld '
|
||||
;;
|
||||
*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sunos4*)
|
||||
wl='-Qoption ld '
|
||||
;;
|
||||
sysv4 | sysv4.2uw2* | sysv4.3*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
unicos*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
uts4*)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
|
||||
|
||||
hardcode_libdir_flag_spec=
|
||||
hardcode_libdir_separator=
|
||||
hardcode_direct=no
|
||||
hardcode_minus_L=no
|
||||
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
if test "$GCC" != yes; then
|
||||
with_gnu_ld=no
|
||||
fi
|
||||
;;
|
||||
interix*)
|
||||
# we just hope/assume this is gcc and not c89 (= MSVC++)
|
||||
with_gnu_ld=yes
|
||||
;;
|
||||
openbsd*)
|
||||
with_gnu_ld=no
|
||||
;;
|
||||
esac
|
||||
|
||||
ld_shlibs=yes
|
||||
if test "$with_gnu_ld" = yes; then
|
||||
# Set some defaults for GNU ld with shared library support. These
|
||||
# are reset later if shared libraries are not supported. Putting them
|
||||
# here allows them to be overridden if necessary.
|
||||
# Unlike libtool, we use -rpath here, not --rpath, since the documented
|
||||
# option of GNU ld is called -rpath, not --rpath.
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
case "$host_os" in
|
||||
aix[3-9]*)
|
||||
# On AIX/PPC, the GNU linker is very broken
|
||||
if test "$host_cpu" != ia64; then
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
case "$host_cpu" in
|
||||
powerpc)
|
||||
;;
|
||||
m68k)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
beos*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
haiku*)
|
||||
;;
|
||||
interix[3-9]*)
|
||||
hardcode_direct=no
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
netbsd*)
|
||||
;;
|
||||
solaris*)
|
||||
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
|
||||
ld_shlibs=no
|
||||
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
|
||||
case `$LD -v 2>&1` in
|
||||
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test "$ld_shlibs" = no; then
|
||||
hardcode_libdir_flag_spec=
|
||||
fi
|
||||
else
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
# Note: this linker hardcodes the directories in LIBPATH if there
|
||||
# are no directories specified by -L.
|
||||
hardcode_minus_L=yes
|
||||
if test "$GCC" = yes; then
|
||||
# Neither direct hardcoding nor static linking is supported with a
|
||||
# broken collect2.
|
||||
hardcode_direct=unsupported
|
||||
fi
|
||||
;;
|
||||
aix[4-9]*)
|
||||
if test "$host_cpu" = ia64; then
|
||||
# On IA64, the linker does run time linking by default, so we don't
|
||||
# have to do anything special.
|
||||
aix_use_runtimelinking=no
|
||||
else
|
||||
aix_use_runtimelinking=no
|
||||
# Test if we are trying to use run time linking or normal
|
||||
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
|
||||
# need to do runtime linking.
|
||||
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
|
||||
for ld_flag in $LDFLAGS; do
|
||||
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
|
||||
aix_use_runtimelinking=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_separator=':'
|
||||
if test "$GCC" = yes; then
|
||||
case $host_os in aix4.[012]|aix4.[012].*)
|
||||
collect2name=`${CC} -print-prog-name=collect2`
|
||||
if test -f "$collect2name" && \
|
||||
strings "$collect2name" | grep resolve_lib_name >/dev/null
|
||||
then
|
||||
# We have reworked collect2
|
||||
:
|
||||
else
|
||||
# We have old collect2
|
||||
hardcode_direct=unsupported
|
||||
hardcode_minus_L=yes
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_libdir_separator=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Begin _LT_AC_SYS_LIBPATH_AIX.
|
||||
echo 'int main () { return 0; }' > conftest.c
|
||||
${CC} ${LDFLAGS} conftest.c -o conftest
|
||||
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
fi
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath="/usr/lib:/lib"
|
||||
fi
|
||||
rm -f conftest.c conftest
|
||||
# End _LT_AC_SYS_LIBPATH_AIX.
|
||||
if test "$aix_use_runtimelinking" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
else
|
||||
if test "$host_cpu" = ia64; then
|
||||
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
|
||||
else
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
case "$host_cpu" in
|
||||
powerpc)
|
||||
;;
|
||||
m68k)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec=' '
|
||||
libext=lib
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
hardcode_direct=no
|
||||
if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
dgux*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
freebsd2.[01]*)
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
hpux9*)
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
hpux10*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
fi
|
||||
;;
|
||||
hpux11*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
case $host_cpu in
|
||||
hppa*64*|ia64*)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
*)
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
netbsd*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
newsos6)
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
*nto* | *qnx*)
|
||||
;;
|
||||
openbsd*)
|
||||
if test -f /usr/libexec/ld.so; then
|
||||
hardcode_direct=yes
|
||||
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
else
|
||||
case "$host_os" in
|
||||
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
os2*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
osf3*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
osf4* | osf5*)
|
||||
if test "$GCC" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
else
|
||||
# Both cc and cxx compiler support -rpath directly
|
||||
hardcode_libdir_flag_spec='-rpath $libdir'
|
||||
fi
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
solaris*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
sysv4)
|
||||
case $host_vendor in
|
||||
sni)
|
||||
hardcode_direct=yes # is this really true???
|
||||
;;
|
||||
siemens)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
motorola)
|
||||
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sysv4.3*)
|
||||
;;
|
||||
sysv4*MP*)
|
||||
if test -d /usr/nec; then
|
||||
ld_shlibs=yes
|
||||
fi
|
||||
;;
|
||||
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6*)
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
|
||||
hardcode_libdir_separator=':'
|
||||
;;
|
||||
uts4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Check dynamic linker characteristics
|
||||
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
|
||||
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
|
||||
# only about the one the linker finds when passed -lNAME. This is the last
|
||||
# element of library_names_spec in libtool.m4, or possibly two of them if the
|
||||
# linker has special search rules.
|
||||
library_names_spec= # the last element of library_names_spec in libtool.m4
|
||||
libname_spec='lib$name'
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
library_names_spec='$libname.a'
|
||||
;;
|
||||
aix[4-9]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
amigaos*)
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
library_names_spec='$libname$shrext' ;;
|
||||
m68k)
|
||||
library_names_spec='$libname.a' ;;
|
||||
esac
|
||||
;;
|
||||
beos*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
bsdi[45]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
shrext=.dll
|
||||
library_names_spec='$libname.dll.a $libname.lib'
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
shrext=.dylib
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
dgux*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
freebsd[23].*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
gnu*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
haiku*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
case $host_cpu in
|
||||
ia64*)
|
||||
shrext=.so
|
||||
;;
|
||||
hppa*64*)
|
||||
shrext=.sl
|
||||
;;
|
||||
*)
|
||||
shrext=.sl
|
||||
;;
|
||||
esac
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
interix[3-9]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
library_names_spec='$libname$shrext'
|
||||
case "$host_os" in
|
||||
irix5* | nonstopux*)
|
||||
libsuff= shlibsuff=
|
||||
;;
|
||||
*)
|
||||
case $LD in
|
||||
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
|
||||
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
|
||||
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
|
||||
*) libsuff= shlibsuff= ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
linux*oldld* | linux*aout* | linux*coff*)
|
||||
;;
|
||||
linux* | k*bsd*-gnu | kopensolaris*-gnu)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
knetbsd*-gnu)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
netbsd*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
newsos6)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
*nto* | *qnx*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
openbsd*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
os2*)
|
||||
libname_spec='$name'
|
||||
shrext=.dll
|
||||
library_names_spec='$libname.a'
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
rdos*)
|
||||
;;
|
||||
solaris*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sunos4*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
sysv4 | sysv4.3*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
tpf*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
uts4*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
esac
|
||||
|
||||
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
|
||||
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
|
||||
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
|
||||
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
|
||||
|
||||
# How to pass a linker flag through the compiler.
|
||||
wl="$escaped_wl"
|
||||
|
||||
# Static library suffix (normally "a").
|
||||
libext="$libext"
|
||||
|
||||
# Shared library suffix (normally "so").
|
||||
shlibext="$shlibext"
|
||||
|
||||
# Format of library name prefix.
|
||||
libname_spec="$escaped_libname_spec"
|
||||
|
||||
# Library names that the linker finds when passed -lNAME.
|
||||
library_names_spec="$escaped_library_names_spec"
|
||||
|
||||
# Flag to hardcode \$libdir into a binary during linking.
|
||||
# This must work even if \$libdir does not exist.
|
||||
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
|
||||
|
||||
# Whether we need a single -rpath flag with a separated argument.
|
||||
hardcode_libdir_separator="$hardcode_libdir_separator"
|
||||
|
||||
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_direct="$hardcode_direct"
|
||||
|
||||
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_minus_L="$hardcode_minus_L"
|
||||
|
||||
EOF
|
2354
build-aux/config.sub
vendored
Executable file
2354
build-aux/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
46
build-aux/cpan.am
Normal file
46
build-aux/cpan.am
Normal file
|
@ -0,0 +1,46 @@
|
|||
CPAN_DIST_NAME = $(PACKAGE_CPAN_NAME)
|
||||
CPAN_DIST_VERSION = $(PACKAGE_VERSION)
|
||||
if !PACKAGE_DIST_IS_RELEASE
|
||||
CPAN_DIST_SUFFIX = -TRIAL
|
||||
endif
|
||||
CPAN_DIST = $(CPAN_DIST_NAME)-$(CPAN_DIST_VERSION)$(CPAN_DIST_SUFFIX)
|
||||
CPAN_DIST_ARCHIVE = $(CPAN_DIST).tar.gz
|
||||
|
||||
dist-cpan:
|
||||
: # Create the CPAN source tree.
|
||||
mkdir -p $(CPAN_DIST)
|
||||
mkdir -p $(CPAN_DIST)/lib
|
||||
mkdir -p $(CPAN_DIST)/t
|
||||
cp -fpR $(top_srcdir)/COPYING $(CPAN_DIST)/LICENSE
|
||||
cp -fpR $(top_srcdir)/debian/changelog $(CPAN_DIST)/Changes
|
||||
cp -fpR $(top_srcdir)/data $(CPAN_DIST)
|
||||
cp -fpR $(top_srcdir)/t/* \
|
||||
$(top_srcdir)/scripts/t/Dpkg* \
|
||||
$(top_srcdir)/scripts/t/origins \
|
||||
$(CPAN_DIST)/t
|
||||
cp -fpR $(top_srcdir)/scripts/Dpkg.pm $(CPAN_DIST)/lib/
|
||||
cp -fpR $(top_srcdir)/scripts/Dpkg $(CPAN_DIST)/lib/
|
||||
cp -fpR $(top_srcdir)/scripts/Test $(CPAN_DIST)/lib/
|
||||
cp -fpR $(top_builddir)/scripts/README.cpan $(CPAN_DIST)/README
|
||||
cp -fpR $(top_builddir)/scripts/Build.PL $(CPAN_DIST)
|
||||
|
||||
: # Fix permissions of the distributed files.
|
||||
find $(CPAN_DIST) \
|
||||
-type d ! -perm 755 -exec chmod u+rwx,go+rx {} ';' -o \
|
||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; || \
|
||||
chmod -R a+r $(CPAN_DIST)
|
||||
|
||||
: # Prepare the CPAN distribution.
|
||||
cd $(CPAN_DIST) && $(PERL) Build.PL
|
||||
cd $(CPAN_DIST) && ./Build manifest
|
||||
cd $(CPAN_DIST) && ./Build distdir
|
||||
|
||||
: # Pack the CPAN distribution.
|
||||
$(TAR) -caf $(CPAN_DIST_ARCHIVE) -C $(CPAN_DIST) -Hustar \
|
||||
--sort=name --owner=root:0 --group=root:0 $(CPAN_DIST)
|
||||
|
||||
: # Cleanup the CPAN source tree.
|
||||
find $(CPAN_DIST) -type d ! -perm -200 -exec chmod u+w {} ';'
|
||||
rm -rf $(CPAN_DIST)
|
792
build-aux/depcomp
Executable file
792
build-aux/depcomp
Executable file
|
@ -0,0 +1,792 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2024-06-19.01; # UTC
|
||||
|
||||
# Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
||||
General help using GNU software: <https://www.gnu.org/gethelp/>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp (GNU Automake) $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interference from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
if test "$depmode" = msvc7msys; then
|
||||
# This is just like msvc7 but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u='sed s,\\\\,/,g'
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsolete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IBM xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The second -e expression handles DOS-style file names with drive
|
||||
# letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||
| tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
showIncludes=-Wc,-showIncludes
|
||||
else
|
||||
showIncludes=-showIncludes
|
||||
fi
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
# The first sed program below extracts the file names and escapes
|
||||
# backslashes for cygpath. The second sed program outputs the file
|
||||
# name when reading, but also accumulates all include files in the
|
||||
# hold buffer in order to output them again at the end. This only
|
||||
# works with sed implementations that can handle large buffers.
|
||||
sed < "$tmpdepfile" -n '
|
||||
/^Note: including file: *\(.*\)/ {
|
||||
s//\1/
|
||||
s/\\/\\\\/g
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvc7msys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E \
|
||||
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
303
build-aux/gen-changelog
Executable file
303
build-aux/gen-changelog
Executable file
|
@ -0,0 +1,303 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# gen-changelog
|
||||
#
|
||||
# Copyright © 2020-2022 Guillem Jover <guillem@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use lib qw(scripts);
|
||||
|
||||
use List::Util qw(uniq);
|
||||
use Text::Wrap;
|
||||
use Dpkg::IPC;
|
||||
use Dpkg::Index;
|
||||
|
||||
my @sections = qw(
|
||||
main
|
||||
arch
|
||||
port
|
||||
perl-mod
|
||||
make-mod
|
||||
shell-mod
|
||||
doc
|
||||
code-int
|
||||
build-sys
|
||||
pkg
|
||||
test
|
||||
l10n
|
||||
);
|
||||
|
||||
my %sections = (
|
||||
arch => {
|
||||
title => 'Architecture support',
|
||||
match => qr/^arch: /,
|
||||
},
|
||||
port => {
|
||||
title => 'Portability',
|
||||
type => 'porting',
|
||||
},
|
||||
'perl-mod' => {
|
||||
title => 'Perl modules',
|
||||
match => qr/^(?:Test|Dpkg|Dselect).*[,:] /,
|
||||
keep => 1,
|
||||
},
|
||||
'make-mod' => {
|
||||
title => 'Make fragments',
|
||||
match => qr{^scripts/mk: },
|
||||
},
|
||||
'shell-mod' => {
|
||||
title => 'Shell library',
|
||||
match => qr{^src/sh: },
|
||||
},
|
||||
doc => {
|
||||
title => 'Documentation',
|
||||
match => qr/^(?:doc|man)[,:] /,
|
||||
keep => 1,
|
||||
},
|
||||
'code-int' => {
|
||||
title => 'Code internals',
|
||||
type => 'internal',
|
||||
match => qr/^(?:lib(?:compat|dpkg)?|src|scripts|perl|utils): /,
|
||||
keep => 1,
|
||||
},
|
||||
'build-sys' => {
|
||||
title => 'Build system',
|
||||
match => qr/^build: /,
|
||||
},
|
||||
pkg => {
|
||||
title => 'Packaging',
|
||||
match => qr/^debian: /,
|
||||
},
|
||||
test => {
|
||||
title => 'Test suite',
|
||||
match => qr/^(?:test|t): /,
|
||||
},
|
||||
l10n => {
|
||||
title => 'Localization',
|
||||
match => qr/^po: /,
|
||||
sort => 1,
|
||||
},
|
||||
);
|
||||
|
||||
my @metafields = qw(
|
||||
Thanks-to
|
||||
Co-Author
|
||||
Based-on-patch-by
|
||||
Improved-by
|
||||
Prompted-by
|
||||
Reported-by
|
||||
Required-by
|
||||
Analysis-by
|
||||
Requested-by
|
||||
Suggested-by
|
||||
Spotted-by
|
||||
Naming-by
|
||||
Ref
|
||||
);
|
||||
|
||||
my %metafield = (
|
||||
'Co-Author' => 'Co-authored by',
|
||||
'Based-on-patch-by' => 'Based on a patch by',
|
||||
'Improved-by' => 'Improved by',
|
||||
'Prompted-by' => 'Prompted by',
|
||||
'Reported-by' => 'Reported by',
|
||||
'Required-by' => 'Required by',
|
||||
'Analysis-by' => 'Analysis by',
|
||||
'Requested-by' => 'Requested by',
|
||||
'Suggested-by' => 'Suggested by',
|
||||
'Spotted-by' => 'Spotted by',
|
||||
'Naming-by' => 'Naming by',
|
||||
'Thanks-to' => 'Thanks to',
|
||||
'Ref' => 'See',
|
||||
);
|
||||
|
||||
my %mappings = (
|
||||
'u-a' => 'update-alternatives',
|
||||
's-s-d' => 'start-stop-daemon',
|
||||
'dpkg-m-h' => 'dpkg-maintscript-helper',
|
||||
);
|
||||
|
||||
my $log_format =
|
||||
'Commit: %H%n' .
|
||||
'Author: %aN%n' .
|
||||
'AuthorEmail: %aE%n' .
|
||||
'Committer: %cN%n' .
|
||||
'CommitterEmail: %cE%n' .
|
||||
'Title: %s%n' .
|
||||
'%(trailers:only,unfold)%N';
|
||||
|
||||
my $tag_prev = $ARGV[0];
|
||||
my $tag_next = $ARGV[1] // "";
|
||||
|
||||
$tag_prev //= qx(git describe --abbrev=0);
|
||||
chomp $tag_prev;
|
||||
|
||||
my $fh_gitlog;
|
||||
|
||||
spawn(
|
||||
exec => [
|
||||
qw(git log --first-parent), "--format=tformat:$log_format",
|
||||
"$tag_prev..$tag_next"
|
||||
],
|
||||
to_pipe => \$fh_gitlog,
|
||||
);
|
||||
|
||||
my $log = Dpkg::Index->new(
|
||||
get_key_func => sub { return $_[0]->{Commit} },
|
||||
item_opts => {
|
||||
keep_duplicate => 1,
|
||||
allow_duplicate => 1,
|
||||
},
|
||||
);
|
||||
$log->parse($fh_gitlog, 'git log');
|
||||
|
||||
my %entries;
|
||||
my %groups;
|
||||
my @groups;
|
||||
|
||||
# Analyze the commits and select which group and section to place them in.
|
||||
foreach my $id (reverse $log->get_keys()) {
|
||||
my $commit = $log->get_by_key($id);
|
||||
my $title = $commit->{Title};
|
||||
my $group = $commit->{Committer};
|
||||
my $changelog = $commit->{'Changelog'};
|
||||
my $sectmatch = 'main';
|
||||
|
||||
# Skip irrelevant commits.
|
||||
if ($title =~ m/^(?:Bump version to|Release) /) {
|
||||
next;
|
||||
}
|
||||
if ($title =~ m/^po: Regenerate/) {
|
||||
next;
|
||||
}
|
||||
|
||||
if (defined $changelog) {
|
||||
# Skip silent commits.
|
||||
next if $changelog =~ m/(?:silent|skip|ignore)/;
|
||||
|
||||
# Include the entire commit body for verbose commits.
|
||||
if ($changelog =~ m/(?:verbose|full)/) {
|
||||
my $body = qx(git show -s --pretty=tformat:%b $id);
|
||||
$commit->{Title} .= "\n$body";
|
||||
}
|
||||
|
||||
if ($changelog =~ m{s/([^/]+)/([^/]+)/}) {
|
||||
$commit->{Fixup} = {
|
||||
old => $1,
|
||||
new => $2,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
# Decide into what section the commit should go.
|
||||
foreach my $sectname (keys %sections) {
|
||||
my $section = $sections{$sectname};
|
||||
|
||||
if ((exists $section->{match} and $title =~ m/$section->{match}/) or
|
||||
(exists $section->{type} and defined $changelog and
|
||||
$changelog =~ m/$section->{type}/)) {
|
||||
$sectmatch = $sectname;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Add the group entries in order, with l10n ones at the end.
|
||||
if (not exists $entries{$group}) {
|
||||
push @groups, $group;
|
||||
}
|
||||
|
||||
push @{$entries{$group}{$sectmatch}}, $commit;
|
||||
}
|
||||
|
||||
# Go over the groups and their sections and format them.
|
||||
foreach my $groupname (@groups) {
|
||||
print "\n";
|
||||
print " [ $groupname ]\n";
|
||||
|
||||
foreach my $sectname (@sections) {
|
||||
my $section = $sections{$sectname};
|
||||
|
||||
next unless exists $entries{$groupname}{$sectname};
|
||||
next if @{$entries{$groupname}{$sectname}} == 0;
|
||||
|
||||
if (exists $sections{$sectname}->{title}) {
|
||||
print " * $sections{$sectname}->{title}:\n";
|
||||
}
|
||||
my @entries;
|
||||
foreach my $commit (@{$entries{$groupname}{$sectname}}) {
|
||||
my $title = $commit->{Title} =~ s/\.$//r . '.';
|
||||
|
||||
# Remove the title prefix if needed.
|
||||
if (exists $section->{match} and not exists $section->{keep}) {
|
||||
$title =~ s/$section->{match}//;
|
||||
}
|
||||
|
||||
# Metafields.
|
||||
if ($commit->{Author} ne $commit->{Committer}) {
|
||||
$commit->{'Thanks-to'} = "$commit->{Author} <$commit->{AuthorEmail}>";
|
||||
}
|
||||
foreach my $metafield (@metafields) {
|
||||
next unless exists $commit->{$metafield};
|
||||
|
||||
my $values = $commit->{$metafield};
|
||||
$values = [ $values ] if ref $values ne 'ARRAY';
|
||||
|
||||
foreach my $value (@{$values}) {
|
||||
$title .= "\n$metafield{$metafield} $value.";
|
||||
}
|
||||
}
|
||||
# Handle the Closes metafield last.
|
||||
if (exists $commit->{Closes}) {
|
||||
$title .= " Closes: $commit->{Closes}";
|
||||
}
|
||||
|
||||
# Handle fixups from git notes.
|
||||
if (exists $commit->{Fixup}) {
|
||||
$title =~ s/\Q$commit->{Fixup}{old}\E/$commit->{Fixup}{new}/m;
|
||||
}
|
||||
|
||||
# Handle mappings.
|
||||
foreach my $mapping (keys %mappings) {
|
||||
$title =~ s/$mapping/$mappings{$mapping}/g;
|
||||
}
|
||||
|
||||
# Select prefix formatting.
|
||||
my ($entry_tab, $body_tab);
|
||||
if (not exists $sections{$sectname}->{title}) {
|
||||
$entry_tab = ' * ';
|
||||
$body_tab = ' ';
|
||||
} else {
|
||||
$entry_tab = ' - ';
|
||||
$body_tab = ' ';
|
||||
}
|
||||
|
||||
local $Text::Wrap::columns = 80;
|
||||
local $Text::Wrap::unexpand = 0;
|
||||
local $Text::Wrap::huge = 'overflow';
|
||||
local $Text::Wrap::break = qr/(?<!Closes:)\s/;
|
||||
push @entries, wrap($entry_tab, $body_tab, $title) . "\n";
|
||||
}
|
||||
|
||||
if ($sections{$sectname}->{sort}) {
|
||||
@entries = uniq(sort @entries);
|
||||
}
|
||||
|
||||
print @entries;
|
||||
}
|
||||
}
|
166
build-aux/gen-release
Executable file
166
build-aux/gen-release
Executable file
|
@ -0,0 +1,166 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# gen-release
|
||||
#
|
||||
# Copyright © 2017-2024 Guillem Jover <guillem@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
set -x
|
||||
set -e
|
||||
set -u
|
||||
|
||||
# Pre-checks.
|
||||
|
||||
# Currently requires packages: dpkg-dev, git, schroot and devscripts
|
||||
# (the latter should eventually be replaced by dpkg tools).
|
||||
for req in dpkg-parsechangelog git schroot dch debsign dscverify; do
|
||||
if ! command -v $req >/dev/null 2>&1; then
|
||||
echo "error: missing required command $req" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$(dpkg-parsechangelog -SSource)" != 'dpkg' ] || ! [ -e .git ]; then
|
||||
echo "error: not inside the dpkg git tree" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Setup.
|
||||
dist="${1:-unstable}"
|
||||
relver="${2:-$(dpkg-parsechangelog -SVersion)}"
|
||||
|
||||
numjobs="$(nproc)"
|
||||
checkflags="-j$numjobs AUTHOR_TESTING=1 TEST_PARALLEL=$numjobs"
|
||||
|
||||
dircode="$(pwd)"
|
||||
dirtests="$dircode/tests"
|
||||
dirbuild="$(mktemp --tmpdir --directory release-dpkg.XXXXXXXX)"
|
||||
|
||||
# Update the source chroot.
|
||||
schroot -c "source:$dist" -- sudo eatmydata apt-get --yes update
|
||||
schroot -c "source:$dist" -- sudo eatmydata apt-get --yes upgrade
|
||||
|
||||
# Setup a clean chroot session.
|
||||
chroot="$(schroot -c "$dist" -b)"
|
||||
|
||||
echo "Release start: $(date -Iseconds)"
|
||||
|
||||
cd "$dircode"
|
||||
|
||||
schroot -c "$chroot" -r -- sudo eatmydata apt-get --yes build-dep \
|
||||
-P pkg.dpkg.author-testing,pkg.dpkg.author-release .
|
||||
|
||||
if ! git log --format=tformat:%s -s HEAD~2.. | grep 'po: Regenerate'; then
|
||||
# Clean slate.
|
||||
git clean -Xdf
|
||||
|
||||
# Update the .pot and .po files.
|
||||
echo "$relver" >.dist-version
|
||||
schroot -c "$chroot" -r -- ./autogen
|
||||
schroot -c "$chroot" -r -- ./configure
|
||||
schroot -c "$chroot" -r -- make update-po
|
||||
rm -f .dist-version
|
||||
git commit -a -m 'po: Regenerate .pot files and merge .po files with them'
|
||||
fi
|
||||
|
||||
if [ -z "$(git tag --list "$relver")" ]; then
|
||||
# Finalize the actual release.
|
||||
genchangelog='build-aux/gen-changelog'
|
||||
sed -i -e "2e$genchangelog" -e '2,3d' debian/changelog
|
||||
dch -r -D"$dist"
|
||||
git commit -a -m "Release $relver"
|
||||
git tag -s "$relver" -m "Release $relver"
|
||||
elif [ "$(git describe)" != "$relver" ]; then
|
||||
echo "error: mismatched tag for $relver not on git HEAD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean slate.
|
||||
git clean -Xdf
|
||||
|
||||
# Prepare the tarball for distribution.
|
||||
schroot -c "$chroot" -r -- ./autogen
|
||||
schroot -c "$chroot" -r -- ./configure
|
||||
if [ "$dist" = unstable ]; then
|
||||
# Generate the CPAN distribution only from main.
|
||||
make dist-cpan
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
schroot -c "$chroot" -r -- make $checkflags distcheck
|
||||
|
||||
# Prepare for packaged release.
|
||||
mkdir -p "$dirbuild"
|
||||
cp "dpkg-$relver.tar.xz" "$dirbuild/"
|
||||
|
||||
# Teardown pre-release chroot.
|
||||
schroot -c "$chroot" -e
|
||||
|
||||
cd "$dirbuild"
|
||||
|
||||
# Setup a clean chroot session for the dist tarballs.
|
||||
chroot="$(schroot -c "$dist" -b)"
|
||||
|
||||
# Build twice, to make sure we can build ourselves with the new dpkg,
|
||||
# and to verify that we are building reproducibly.
|
||||
|
||||
# Build A and B in a chroot.
|
||||
for iter in a b; do (
|
||||
mkdir -p "build-$iter"
|
||||
cd "build-$iter"
|
||||
tar xaf "../dpkg-$relver.tar.xz"
|
||||
cd "dpkg-$relver"
|
||||
|
||||
schroot -c "$chroot" -r -- sudo eatmydata apt-get --yes build-dep .
|
||||
schroot -c "$chroot" -r -- dpkg-buildpackage -us -uc --changes-option=-S
|
||||
|
||||
# Install resulting .debs.
|
||||
schroot -c "$chroot" -r -- sudo eatmydata dpkg -iO ../*.deb
|
||||
) done
|
||||
|
||||
# Run functional test-suite.
|
||||
(
|
||||
set -x
|
||||
set -e
|
||||
set -u
|
||||
|
||||
cd "$dirtests"
|
||||
schroot -c "$chroot" -r -- sudo eatmydata apt-get --yes purge pkg-config
|
||||
schroot -c "$chroot" -r -- eatmydata make test-clean clean
|
||||
schroot -c "$chroot" -r -- eatmydata make test 2>&1 | tee test.log
|
||||
)
|
||||
|
||||
schroot -c "$chroot" -r -- sudo eatmydata apt-get --yes install lintian
|
||||
|
||||
# Verify the result.
|
||||
diff -u build-a/dpkg_*.changes build-b/dpkg_*.changes || true
|
||||
# Prompt to continue? (.buildinfo will differ)
|
||||
diff -u build-a/dpkg_*.buildinfo build-b/dpkg_*.buildinfo || true
|
||||
# Prompt to continue? (Build-Date, Environment will differ).
|
||||
schroot -c "$chroot" -r -- lintian build-b/*.changes build-b/*.deb
|
||||
|
||||
# Teardown chroot.
|
||||
schroot -c "$chroot" -e
|
||||
|
||||
# Sign and verify.
|
||||
cd "$dirbuild/build-b"
|
||||
debsign dpkg_"${relver}"_*.changes
|
||||
dscverify dpkg_"${relver}"_*.changes
|
||||
|
||||
ls -l "$(pwd)"
|
||||
|
||||
echo "Release process finished (dpkg ${relver}): $(date -Iseconds)"
|
||||
echo " Hint: upload to CPAN"
|
||||
echo " Hint: update https://www.wikidata.org/wiki/Q305892"
|
49
build-aux/get-vcs-id
Executable file
49
build-aux/get-vcs-id
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# get-vcs-id
|
||||
#
|
||||
# Copyright © 2009-2024 Guillem Jover <guillem@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
error()
|
||||
{
|
||||
echo "get-vcs-id: error: $*" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -f .dist-vcs-id ]; then
|
||||
# Get the VCS id from the file distributed in the tarball.
|
||||
id="$(cat .dist-vcs-id)"
|
||||
elif [ -d .git ] || [ -f .git ]; then
|
||||
if ! command -v git >/dev/null; then
|
||||
error "cannot get project VCS id, git checkout but git program not found"
|
||||
fi
|
||||
|
||||
# Get the VCS id from the git repository.
|
||||
id="$(git rev-list -1 HEAD 2>/dev/null)"
|
||||
|
||||
# Check if we are on a dirty checkout.
|
||||
git update-index --refresh -q >/dev/null
|
||||
dirty=$(git diff-index --name-only HEAD 2>/dev/null)
|
||||
if [ -n "$dirty" ]; then
|
||||
id="$id-dirty"
|
||||
fi
|
||||
else
|
||||
error "cannot get project VCS id, not a git checkout nor a distribution tarball."
|
||||
fi
|
||||
|
||||
# Use printf to avoid the trailing new line that m4_esyscmd would not handle.
|
||||
printf "%s" "$id"
|
50
build-aux/get-version
Executable file
50
build-aux/get-version
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# get-version
|
||||
#
|
||||
# Copyright © 2009, 2013-2015, 2018, 2020 Guillem Jover <guillem@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
error()
|
||||
{
|
||||
echo "get-version: error: $*" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -f .dist-version ]; then
|
||||
# Get the version from the file distributed in the tarball.
|
||||
version=$(cat .dist-version)
|
||||
elif [ -d .git ] || [ -f .git ]; then
|
||||
if ! command -v git >/dev/null; then
|
||||
error "cannot get project version, git checkout but git program not found"
|
||||
fi
|
||||
|
||||
# Get the version from the git repository. Since tags cannot contain colons
|
||||
# or tildes, we use percent and underscore instead. Reverse that switch here.
|
||||
version=$(git describe --abbrev=4 HEAD 2>/dev/null | tr %_ :~)
|
||||
|
||||
# Check if we are on a dirty checkout.
|
||||
git update-index --refresh -q >/dev/null
|
||||
dirty=$(git diff-index --name-only HEAD 2>/dev/null)
|
||||
if [ -n "$dirty" ]; then
|
||||
version="$version-dirty"
|
||||
fi
|
||||
else
|
||||
error "cannot get project version, not a git checkout nor a distribution tarball."
|
||||
fi
|
||||
|
||||
# Use printf to avoid the trailing new line that m4_esyscmd would not handle.
|
||||
printf "%s" "$version"
|
541
build-aux/install-sh
Executable file
541
build-aux/install-sh
Executable file
|
@ -0,0 +1,541 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2024-06-19.01; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
# Create dirs (including intermediate dirs) using mode 755.
|
||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
||||
mkdir_umask=22
|
||||
|
||||
backupsuffix=
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-p pass -p to $cpprog.
|
||||
-s $stripprog installed files.
|
||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
|
||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
||||
it's up to you to specify -f if you want it.
|
||||
|
||||
If -S is not specified, no backups are attempted.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
||||
General help using GNU software: <https://www.gnu.org/gethelp/>."
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-p) cpprog="$cpprog -p";;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-S) backupsuffix="$2"
|
||||
shift;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
# Don't chown directories that already exist.
|
||||
if test $dstdir_status = 0; then
|
||||
chowncmd=""
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dstbase=`basename "$src"`
|
||||
case $dst in
|
||||
*/) dst=$dst$dstbase;;
|
||||
*) dst=$dst/$dstbase;;
|
||||
esac
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
case $dstdir in
|
||||
*/) dstdirslash=$dstdir;;
|
||||
*) dstdirslash=$dstdir/;;
|
||||
esac
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
# The $RANDOM variable is not portable (e.g., dash). Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap '
|
||||
ret=$?
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
|
||||
exit $ret
|
||||
' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p'.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibility with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=${dstdirslash}_inst.$$_
|
||||
rmtmp=${dstdirslash}_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask &&
|
||||
{ test -z "$stripcmd" || {
|
||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
||||
# which would cause strip to fail.
|
||||
if test -z "$doit"; then
|
||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
||||
else
|
||||
$doit touch "$dsttmp"
|
||||
fi
|
||||
}
|
||||
} &&
|
||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# If $backupsuffix is set, and the file being installed
|
||||
# already exists, attempt a backup. Don't worry if it fails,
|
||||
# e.g., if mv doesn't support -f.
|
||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
98
build-aux/lcov-inject
Executable file
98
build-aux/lcov-inject
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# lcov-inject
|
||||
#
|
||||
# Copyright © 2014-2024 Guillem Jover <guillem@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cwd;
|
||||
use Devel::Cover::DB;
|
||||
|
||||
my $dir = 'scripts';
|
||||
my $cwd = getcwd();
|
||||
|
||||
chdir $dir or die "cannot switch to $dir\n";
|
||||
|
||||
my $db = Devel::Cover::DB->new(db => 'cover_db');
|
||||
$db = $db->merge_runs();
|
||||
$db->calculate_summary(map { $_ => 1 } $db->collected());
|
||||
|
||||
chdir $cwd or die "cannot switch to $cwd\n";
|
||||
|
||||
my $s = $db->{summary}{Total};
|
||||
|
||||
my $tmpl = sprintf '
|
||||
<td class="coverDirectory"><a href="%s">%s</a></td>
|
||||
<td class="coverBar" align="center">
|
||||
<table border=0 cellspacing=0 cellpadding=1>
|
||||
<tr><td class="coverBarOutline">%s</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
</tr>
|
||||
<tr>
|
||||
', "$dir/coverage.html", $dir, bar_html($s->{total}{percentage}),
|
||||
box_html($s->{total}), box_html($s->{branch}), box_html($s->{subroutine});
|
||||
|
||||
while (<>) {
|
||||
s/^(.*<td .*href="utils\/index\.html".*<\/td>.*)$/$tmpl$1/;
|
||||
print;
|
||||
}
|
||||
|
||||
sub bar_image {
|
||||
my ($num) = @_;
|
||||
|
||||
return 'emerald.png' if $num >= 90;
|
||||
return 'ruby.png' if $num < 75;
|
||||
return 'amber.png';
|
||||
}
|
||||
|
||||
sub bar_html {
|
||||
my ($num) = @_;
|
||||
|
||||
my $html = sprintf '<img src="%s" width=%.0f height=10 alt="%.1f">',
|
||||
bar_image($num), $num, $num;
|
||||
|
||||
if ($num < 100) {
|
||||
$html .= sprintf '<img src="snow.png" width=%.0f height=10 alt="%.1f">',
|
||||
100 - $num, $num;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
sub box_rating {
|
||||
my ($num) = @_;
|
||||
|
||||
return 'Hi' if $num >= 90;
|
||||
return 'Lo' if $num < 75;
|
||||
return 'Med';
|
||||
}
|
||||
|
||||
sub box_html {
|
||||
my ($stats) = @_;
|
||||
|
||||
return sprintf '<td class="coverPer%s">%.1f %%</td>' . "\n" .
|
||||
'<td class="coverNum%s">%d</td>' . "\n" .
|
||||
'<td class="coverNum%s">%d</td>',
|
||||
box_rating($stats->{percentage}), $stats->{percentage},
|
||||
'Dflt', $stats->{total}, 'Dflt', $stats->{covered};
|
||||
}
|
11523
build-aux/ltmain.sh
Executable file
11523
build-aux/ltmain.sh
Executable file
File diff suppressed because it is too large
Load diff
236
build-aux/missing
Executable file
236
build-aux/missing
Executable file
|
@ -0,0 +1,236 @@
|
|||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU and other programs.
|
||||
|
||||
scriptversion=2024-06-07.14; # UTC
|
||||
|
||||
# shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells
|
||||
|
||||
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autogen autoheader autom4te automake autoreconf
|
||||
bison flex help2man lex makeinfo perl yacc
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
GNU Automake home page: <https://www.gnu.org/software/automake/>.
|
||||
General help using GNU software: <https://www.gnu.org/gethelp/>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing (GNU Automake) $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=https://www.perl.org/
|
||||
flex_URL=https://github.com/westes/flex
|
||||
gnu_software_URL=https://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake|autoreconf)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
*)
|
||||
:
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
autoheader_deps="'acconfig.h'"
|
||||
automake_deps="'Makefile.am'"
|
||||
aclocal_deps="'acinclude.m4'"
|
||||
case $normalized_program in
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified $aclocal_deps or"
|
||||
echo "$configure_deps."
|
||||
;;
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified $configure_deps."
|
||||
;;
|
||||
autogen*)
|
||||
echo "You should only need it if you modified a '.def' or '.tpl' file."
|
||||
echo "You may want to install the GNU AutoGen package:"
|
||||
echo "<$gnu_software_URL/autogen/>"
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified $autoheader_deps or"
|
||||
echo "$configure_deps."
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified $automake_deps or"
|
||||
echo "$configure_deps."
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
;;
|
||||
autoreconf*)
|
||||
echo "You should only need it if you modified $aclocal_deps or"
|
||||
echo "$automake_deps or $autoheader_deps or $automake_deps or"
|
||||
echo "$configure_deps."
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
perl*)
|
||||
echo "You should only need it to run GNU Autoconf, GNU Automake, "
|
||||
echo " assorted other tools, or if you modified a Perl source file."
|
||||
echo "You may want to install the Perl 5 language interpreter:"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
program_details "$normalized_program"
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
21
build-aux/run-script
Executable file
21
build-aux/run-script
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
top_srcdir="$(dirname "$0")/.."
|
||||
|
||||
# To avoid using «readlink -f» or «realpath» we just change into the
|
||||
# desired directory and work from there.
|
||||
cd "$top_srcdir"
|
||||
cwd="$(pwd)"
|
||||
cd "$OLDPWD"
|
||||
|
||||
# Set up the environment, to use local perl modules and data files.
|
||||
export PERL="${PERL:-perl}"
|
||||
export PERL5LIB="$cwd/scripts:$cwd/dselect/methods"
|
||||
export DPKG_DATADIR="$cwd/data"
|
||||
|
||||
script="$1"
|
||||
shift 1
|
||||
|
||||
exec "$PERL" "$cwd/$script" "$@"
|
48
build-aux/subst.am
Normal file
48
build-aux/subst.am
Normal file
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# Build time variable substitution for generated files.
|
||||
#
|
||||
|
||||
# Shell support.
|
||||
|
||||
subst_shell_rules = "\
|
||||
s{^ADMINDIR=.*$$}{ADMINDIR='$(admindir)'}; \
|
||||
s{^BACKUPSDIR=.*$$}{BACKUPSDIR='$(backupsdir)'}; \
|
||||
s{^PKGDATADIR_DEFAULT=.*$$}{PKGDATADIR_DEFAULT='$(pkgdatadir)'}; \
|
||||
s{^version=['\"][^'\"]*[\"']}{version=\"$(PACKAGE_VERSION)\"}; \
|
||||
s{^TAR=.*$$}{TAR='$(TAR)'}; \
|
||||
"
|
||||
|
||||
subst_shell_filter = $(PERL) -p -e $(subst_shell_rules)
|
||||
subst_shell_file = $(PERL) -i -p -e $(shell_subst_rules)
|
||||
|
||||
SUFFIXES += .sh
|
||||
|
||||
.sh: Makefile
|
||||
@test -d `dirname $@` || $(MKDIR_P) `dirname $@`
|
||||
$(AM_V_GEN) $(subst_shell_filter) <$< >$@
|
||||
$(AM_V_at) chmod +x $@
|
||||
|
||||
# Perl support.
|
||||
|
||||
# Note: We need to hex-escape '#' (0x23) to avoid portability issues with make.
|
||||
subst_perl_rules = "\
|
||||
s{^\x23!\s*/usr/bin/perl}{\x23!$(PERL)}; \
|
||||
s{our \\\$$CONFDIR = .*;}{our \\\$$CONFDIR = '$(pkgconfdir)';}; \
|
||||
s{our \\\$$ADMINDIR = .*;}{our \\\$$ADMINDIR = '$(admindir)';}; \
|
||||
s{our \\\$$LIBDIR = .*;}{our \\\$$LIBDIR = '$(pkglibexecdir)';}; \
|
||||
s{our \\\$$DATADIR = .*;}{our \\\$$DATADIR = '$(pkgdatadir)';}; \
|
||||
s{our \\\$$PROGMAKE = .*;}{our \\\$$PROGMAKE = '$(MAKE)';}; \
|
||||
s{our \\\$$PROGTAR = .*;}{our \\\$$PROGTAR = '$(TAR)';}; \
|
||||
s{our \\\$$PROGPATCH = .*;}{our \\\$$PROGPATCH = '$(PATCH)';}; \
|
||||
s{our \\\$$PROGVERSION = .*;}{our \\\$$PROGVERSION = '$(PACKAGE_VERSION)';}; \
|
||||
"
|
||||
|
||||
subst_perl_filter = $(PERL) -p -e $(subst_perl_rules)
|
||||
subst_perl_file = $(PERL) -i -p -e $(subst_perl_rules)
|
||||
|
||||
SUFFIXES += .pl
|
||||
|
||||
.pl: Makefile
|
||||
@test -d `dirname $@` || $(MKDIR_P) `dirname $@`
|
||||
$(AM_V_GEN) $(subst_perl_filter) <$< >$@
|
||||
$(AM_V_at) chmod +x $@
|
38
build-aux/tap.am
Normal file
38
build-aux/tap.am
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Variables to be defined:
|
||||
#
|
||||
# TEST_VERBOSE - set to 0 (default) or 1 to control test suite verbosity
|
||||
# TEST_PARALLEL - set to 1 (default) or N to control the parallel jobs
|
||||
# TEST_ENV_VARS - environment variables to be set for the test suite
|
||||
# TEST_COVERAGE - set to the perl module in charge of getting test coverage
|
||||
# test_tmpdir - test suite temporary directory
|
||||
# test_scripts - list of test case scripts
|
||||
# test_programs - list of test case programs
|
||||
# test_data - list of test data files
|
||||
|
||||
TEST_VERBOSE ?= 0
|
||||
TEST_PARALLEL ?= 1
|
||||
|
||||
tap-clean:
|
||||
[ -z "$(test_tmpdir)" ] || rm -fr $(test_tmpdir)
|
||||
|
||||
tap-check: $(test_data) $(test_programs) $(test_scripts)
|
||||
[ -z "$(test_tmpdir)" ] || $(MKDIR_P) $(test_tmpdir)
|
||||
$(TEST_ENV_VARS) \
|
||||
TEST_PARALLEL=$(TEST_PARALLEL) \
|
||||
TEST_VERBOSE=$(TEST_VERBOSE) \
|
||||
abs_srcdir=$(abs_srcdir) \
|
||||
abs_builddir=$(abs_builddir) \
|
||||
abs_top_srcdir=$(abs_top_srcdir) \
|
||||
abs_top_builddir=$(abs_top_builddir) \
|
||||
srcdir=$(srcdir) builddir=$(builddir) \
|
||||
CC=$(CC) \
|
||||
SHELL=$(SHELL) \
|
||||
PERL=$(PERL) \
|
||||
PERL_DL_NONLAZY=1 \
|
||||
PERL5OPT=$(TEST_COVERAGE) \
|
||||
$(PERL) $(top_srcdir)/build-aux/test-runner \
|
||||
$(addprefix $(builddir)/,$(test_programs)) \
|
||||
$(addprefix $(srcdir)/,$(test_scripts))
|
||||
|
||||
authorcheck:
|
||||
AUTHOR_TESTING=1 $(MAKE) check
|
42
build-aux/test-runner
Executable file
42
build-aux/test-runner
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use TAP::Harness;
|
||||
|
||||
my $srcroot = $ENV{abs_top_srcdir};
|
||||
my $binroot = $ENV{abs_top_builddir};
|
||||
|
||||
# Setup the environment
|
||||
$ENV{LC_ALL} = 'C';
|
||||
$ENV{DPKG_COLORS} = 'never';
|
||||
$ENV{PATH} = "$binroot/src:$binroot/scripts:$binroot/utils:$ENV{PATH}";
|
||||
|
||||
my %options;
|
||||
# XXX: We need force the file formatter to workaround verbose + parallel
|
||||
# not working correctly, as the console formatter eats the test output,
|
||||
# see <https://github.com/Perl-Toolchain-Gang/Test-Harness/issues/105>.
|
||||
if ($ENV{TEST_VERBOSE} && $ENV{TEST_PARALLEL} > 1) {
|
||||
$options{formatter_class} = 'TAP::Formatter::File';
|
||||
}
|
||||
|
||||
my $harness = TAP::Harness->new({
|
||||
exec => sub {
|
||||
my (undef, $test) = @_;
|
||||
return [ $test ] if $test !~ m/\.t$/ and -x $test;
|
||||
return
|
||||
},
|
||||
lib => [
|
||||
"$srcroot/scripts",
|
||||
"$srcroot/dselect/methods"
|
||||
],
|
||||
color => 1,
|
||||
verbosity => $ENV{TEST_VERBOSE},
|
||||
jobs => $ENV{TEST_PARALLEL},
|
||||
failures => 1,
|
||||
%options,
|
||||
});
|
||||
|
||||
my $aggregate = $harness->runtests(@ARGV);
|
||||
die "FAIL: test suite has errors\n" if $aggregate->has_errors;
|
580
config.h.in
Normal file
580
config.h.in
Normal file
|
@ -0,0 +1,580 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* The normal alignment of 'max_align_t', in bytes. */
|
||||
#undef ALIGNOF_MAX_ALIGN_T
|
||||
|
||||
/* Set this to the canonical dpkg architecture name. */
|
||||
#undef ARCHITECTURE
|
||||
|
||||
/* Set this to the canonical dpkg CPU name. */
|
||||
#undef ARCHITECTURE_CPU
|
||||
|
||||
/* Set this to the canonical dpkg system name. */
|
||||
#undef ARCHITECTURE_OS
|
||||
|
||||
/* Define to 1 if dselect is compiled. */
|
||||
#undef BUILD_DSELECT
|
||||
|
||||
/* Define to 1 if start-stop-daemon is compiled. */
|
||||
#undef BUILD_START_STOP_DAEMON
|
||||
|
||||
/* Define to 1 if update-alternatives is compiled. */
|
||||
#undef BUILD_UPDATE_ALTERNATIVES
|
||||
|
||||
/* default dpkg-deb build compressor */
|
||||
#undef DEB_DEFAULT_COMPRESSOR
|
||||
|
||||
/* pager program used by dpkg */
|
||||
#undef DPKG_DEFAULT_PAGER
|
||||
|
||||
/* POSIX shell interpreter used by dpkg */
|
||||
#undef DPKG_DEFAULT_SHELL
|
||||
|
||||
/* Whether structured procfs supports LFS */
|
||||
#undef DPKG_STRUCTURED_PROCFS_SUPPORTS_LFS
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define to 1 if you have the 'alphasort' function. */
|
||||
#undef HAVE_ALPHASORT
|
||||
|
||||
/* Define to 1 if you have the 'asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Define to 1 if the 'snprintf' family is C99 conformant */
|
||||
#undef HAVE_C99_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function
|
||||
CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */
|
||||
#undef HAVE_CFLOCALECOPYPREFERREDLANGUAGES
|
||||
|
||||
/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
|
||||
|
||||
/* Define to 1 if you have the 'closefrom' function. */
|
||||
#undef HAVE_CLOSEFROM
|
||||
|
||||
/* Define to 1 if you have the 'close_range' function. */
|
||||
#undef HAVE_CLOSE_RANGE
|
||||
|
||||
/* Define to 1 if you have the <curses.h> header file. */
|
||||
#undef HAVE_CURSES_H
|
||||
|
||||
/* Define to 1 if you have the <cxxabi.h> header file. */
|
||||
#undef HAVE_CXXABI_H
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
#undef HAVE_DCGETTEXT
|
||||
|
||||
/* Define to 1 if you have the declaration of 'sys_errlist', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SYS_ERRLIST
|
||||
|
||||
/* Define to 1 if you have the declaration of 'sys_nerr', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SYS_NERR
|
||||
|
||||
/* Define to 1 if you have the declaration of 'sys_siglist', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SYS_SIGLIST
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* POSIX shell interpreter used by dpkg supports -- after -c */
|
||||
#undef HAVE_DPKG_SHELL_WITH_DASH_DASH
|
||||
|
||||
/* Define to 1 if you have the <error.h> header file. */
|
||||
#undef HAVE_ERROR_H
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#undef HAVE_ERR_H
|
||||
|
||||
/* Define to 1 if you have the 'fallocate' function. */
|
||||
#undef HAVE_FALLOCATE
|
||||
|
||||
/* Define to 1 if you have the 'fgetgrent' function. */
|
||||
#undef HAVE_FGETGRENT
|
||||
|
||||
/* Define to 1 if you have the 'fgetpwent' function. */
|
||||
#undef HAVE_FGETPWENT
|
||||
|
||||
/* Define to 1 if the 'fsync' function works on directories */
|
||||
#undef HAVE_FSYNC_DIR
|
||||
|
||||
/* Define to 1 if 'F_ALLOCSP64' is declared in <fcntl.h> */
|
||||
#undef HAVE_F_ALLOCSP64
|
||||
|
||||
/* Define to 1 if 'F_PREALLOCATE' is declared in <fcntl.h> */
|
||||
#undef HAVE_F_PREALLOCATE
|
||||
|
||||
/* Define to 1 if you have the 'getdtablesize' function. */
|
||||
#undef HAVE_GETDTABLESIZE
|
||||
|
||||
/* Define to 1 if you have the 'getexecname' function. */
|
||||
#undef HAVE_GETEXECNAME
|
||||
|
||||
/* Define to 1 if you have the 'getopt' function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define to 1 if you have the 'getopt_long' function. */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Define to 1 if you have the 'getprocs64' function. */
|
||||
#undef HAVE_GETPROCS64
|
||||
|
||||
/* Define to 1 if you have the 'getprogname' function. */
|
||||
#undef HAVE_GETPROGNAME
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
#undef HAVE_ICONV
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <kvm.h> header file. */
|
||||
#undef HAVE_KVM_H
|
||||
|
||||
/* Define to 1 if you have the 'lchown' function. */
|
||||
#undef HAVE_LCHOWN
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fiemap.h> header file. */
|
||||
#undef HAVE_LINUX_FIEMAP_H
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if you have the 'lutimes' function. */
|
||||
#undef HAVE_LUTIMES
|
||||
|
||||
/* xz multi-threaded decompression support */
|
||||
#undef HAVE_LZMA_MT_DECODER
|
||||
|
||||
/* xz multi-threaded compression support */
|
||||
#undef HAVE_LZMA_MT_ENCODER
|
||||
|
||||
/* Define to 1 if 'makedev' is declared in <sys/types.h> */
|
||||
#undef HAVE_MAKEDEV
|
||||
|
||||
/* Define to 1 if you have the <md5.h> header file. */
|
||||
#undef HAVE_MD5_H
|
||||
|
||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
||||
#undef HAVE_MINIX_CONFIG_H
|
||||
|
||||
/* Define to 1 if you have the 'mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */
|
||||
#undef HAVE_NCURSESW_NCURSES_H
|
||||
|
||||
/* Define to 1 if you have the <ncursesw/term.h> header file. */
|
||||
#undef HAVE_NCURSESW_TERM_H
|
||||
|
||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||
#undef HAVE_NCURSES_H
|
||||
|
||||
/* Define to 1 if you have the <ncurses/ncurses.h> header file. */
|
||||
#undef HAVE_NCURSES_NCURSES_H
|
||||
|
||||
/* Define to 1 if you have the <ncurses/term.h> header file. */
|
||||
#undef HAVE_NCURSES_TERM_H
|
||||
|
||||
/* Define to 1 if you have the 'obstack_free' function. */
|
||||
#undef HAVE_OBSTACK_FREE
|
||||
|
||||
/* Define to 1 if 'offsetof' is declared in <stddef.h> */
|
||||
#undef HAVE_OFFSETOF
|
||||
|
||||
/* Define to 1 if 'O_NOFOLLOW' is declared in <fcntl.h> */
|
||||
#undef HAVE_O_NOFOLLOW
|
||||
|
||||
/* Define to 1 if you have the 'posix_fadvise' function. */
|
||||
#undef HAVE_POSIX_FADVISE
|
||||
|
||||
/* Define to 1 if you have the 'posix_fallocate' function. */
|
||||
#undef HAVE_POSIX_FALLOCATE
|
||||
|
||||
/* Define to 1 if you have program_invocation_short_name */
|
||||
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME
|
||||
|
||||
/* Define to 1 if 'P_tmpdir' is declared in <stdio.h> */
|
||||
#undef HAVE_P_TMPDIR
|
||||
|
||||
/* Define to 1 if you have the 'scandir' function. */
|
||||
#undef HAVE_SCANDIR
|
||||
|
||||
/* Define to 1 if you have the 'setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#undef HAVE_STDIO_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the 'strchrnul' function. */
|
||||
#undef HAVE_STRCHRNUL
|
||||
|
||||
/* Define to 1 if you have the 'strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the 'strndup' function. */
|
||||
#undef HAVE_STRNDUP
|
||||
|
||||
/* Define to 1 if you have the 'strnlen' function. */
|
||||
#undef HAVE_STRNLEN
|
||||
|
||||
/* Define to 1 if you have the 'strsignal' function. */
|
||||
#undef HAVE_STRSIGNAL
|
||||
|
||||
/* Define to 1 if the system has the type 'struct psinfo'. */
|
||||
#undef HAVE_STRUCT_PSINFO
|
||||
|
||||
/* Define to 1 if you have the <sys/mkdev.h> header file. */
|
||||
#undef HAVE_SYS_MKDEV_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/procfs.h> header file. */
|
||||
#undef HAVE_SYS_PROCFS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/proc.h> header file. */
|
||||
#undef HAVE_SYS_PROC_H
|
||||
|
||||
/* Define to 1 if you have the <sys/pstat.h> header file. */
|
||||
#undef HAVE_SYS_PSTAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/syscall.h> header file. */
|
||||
#undef HAVE_SYS_SYSCALL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#undef HAVE_SYS_SYSCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
|
||||
#undef HAVE_SYS_SYSMACROS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/user.h> header file. */
|
||||
#undef HAVE_SYS_USER_H
|
||||
|
||||
/* Define to 1 if you have the <term.h> header file. */
|
||||
#undef HAVE_TERM_H
|
||||
|
||||
/* Define to 1 if 'TIOCNOTTY' is declared in <sys/ioctl.h> */
|
||||
#undef HAVE_TIOCNOTTY
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the 'unsetenv' function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define to 1 if you have the 'uselocale' function. */
|
||||
#undef HAVE_USELOCALE
|
||||
|
||||
/* Define to 1 if the 'va_copy' macro exists */
|
||||
#undef HAVE_VA_COPY
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Define to 1 if 'WCOREDUMP' is declared in <sys/wait.h> */
|
||||
#undef HAVE_WCOREDUMP
|
||||
|
||||
/* Define to 1 if you have the <xlocale.h> header file. */
|
||||
#undef HAVE_XLOCALE_H
|
||||
|
||||
/* Define to 1 if you have the '__cxa_pure_virtual' function. */
|
||||
#undef HAVE___CXA_PURE_VIRTUAL
|
||||
|
||||
/* Define to 1 if you have __progname */
|
||||
#undef HAVE___PROGNAME
|
||||
|
||||
/* Acknowledge the volatility of the API. */
|
||||
#undef LIBDPKG_VOLATILE_API
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define the project release information, version and architecture */
|
||||
#undef PACKAGE_RELEASE
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* GNU patch program */
|
||||
#undef PATCH
|
||||
|
||||
/* The size of 'double', as computed by sizeof. */
|
||||
#undef SIZEOF_DOUBLE
|
||||
|
||||
/* The size of 'float', as computed by sizeof. */
|
||||
#undef SIZEOF_FLOAT
|
||||
|
||||
/* The size of 'int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of 'long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG
|
||||
|
||||
/* The size of 'long double', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_DOUBLE
|
||||
|
||||
/* The size of 'long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of 'off_t', as computed by sizeof. */
|
||||
#undef SIZEOF_OFF_T
|
||||
|
||||
/* The size of 'short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
/* The size of 'time_t', as computed by sizeof. */
|
||||
#undef SIZEOF_TIME_T
|
||||
|
||||
/* The size of 'void *', as computed by sizeof. */
|
||||
#undef SIZEOF_VOID_P
|
||||
|
||||
/* Define to 1 if all of the C89 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* GNU tar program */
|
||||
#undef TAR
|
||||
|
||||
/* Use disk size pre-allocation */
|
||||
#undef USE_DISK_PREALLOCATE
|
||||
|
||||
/* Define to the zlib implementation to use */
|
||||
#undef USE_LIBZ_IMPL
|
||||
|
||||
/* Define none as 0 for the zlib implementation enum */
|
||||
#undef USE_LIBZ_IMPL_NONE
|
||||
|
||||
/* Define zlib as 1 for the zlib implementation enum */
|
||||
#undef USE_LIBZ_IMPL_ZLIB
|
||||
|
||||
/* Define zlib-ng as 2 for the zlib implementation enum */
|
||||
#undef USE_LIBZ_IMPL_ZLIB_NG
|
||||
|
||||
/* Use unreliable mmap support */
|
||||
#undef USE_MMAP
|
||||
|
||||
/* Enable extensions on AIX, Interix, z/OS. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on macOS. */
|
||||
#ifndef _DARWIN_C_SOURCE
|
||||
# undef _DARWIN_C_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable X/Open compliant socket functions that do not require linking
|
||||
with -lxnet on HP-UX 11.11. */
|
||||
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
|
||||
# undef _HPUX_ALT_XOPEN_SOCKET_API
|
||||
#endif
|
||||
/* Identify the host operating system as Minix.
|
||||
This macro does not affect the system headers' behavior.
|
||||
A future release of Autoconf may stop defining this macro. */
|
||||
#ifndef _MINIX
|
||||
# undef _MINIX
|
||||
#endif
|
||||
/* Enable general extensions on NetBSD.
|
||||
Enable NetBSD compatibility extensions on Minix. */
|
||||
#ifndef _NETBSD_SOURCE
|
||||
# undef _NETBSD_SOURCE
|
||||
#endif
|
||||
/* Enable OpenBSD compatibility extensions on NetBSD.
|
||||
Oddly enough, this does nothing on OpenBSD. */
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
# undef _OPENBSD_SOURCE
|
||||
#endif
|
||||
/* Define to 1 if needed for POSIX-compatible behavior. */
|
||||
#ifndef _POSIX_SOURCE
|
||||
# undef _POSIX_SOURCE
|
||||
#endif
|
||||
/* Define to 2 if needed for POSIX-compatible behavior. */
|
||||
#ifndef _POSIX_1_SOURCE
|
||||
# undef _POSIX_1_SOURCE
|
||||
#endif
|
||||
/* Enable POSIX-compatible threading on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
|
||||
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
|
||||
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_BFP_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_DFP_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by C23 Annex F. */
|
||||
#ifndef __STDC_WANT_IEC_60559_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
|
||||
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
|
||||
#ifndef __STDC_WANT_LIB_EXT2__
|
||||
# undef __STDC_WANT_LIB_EXT2__
|
||||
#endif
|
||||
/* Enable extensions specified by ISO/IEC 24747:2009. */
|
||||
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
|
||||
# undef __STDC_WANT_MATH_SPEC_FUNCS__
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable X/Open extensions. Define to 500 only if necessary
|
||||
to make mbstate_t available. */
|
||||
#ifndef _XOPEN_SOURCE
|
||||
# undef _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to yes to use zlib-ng gzFile IO support */
|
||||
#undef WITH_GZFILEOP
|
||||
|
||||
/* Define to 1 to use bz2 library rather than console tool */
|
||||
#undef WITH_LIBBZ2
|
||||
|
||||
/* Define to 1 to use lzma library rather than console tool */
|
||||
#undef WITH_LIBLZMA
|
||||
|
||||
/* Define to 1 to compile in SELinux support */
|
||||
#undef WITH_LIBSELINUX
|
||||
|
||||
/* Define to 1 to use z library rather than console tool */
|
||||
#undef WITH_LIBZ
|
||||
|
||||
/* Define to 1 to use zstd library rather than console tool */
|
||||
#undef WITH_LIBZSTD
|
||||
|
||||
/* Define to 1 to use z-ng library rather than console tool */
|
||||
#undef WITH_LIBZ_NG
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define to 1 on platforms where this makes off_t a 64-bit type. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Number of bits in time_t, on hosts where this is settable. */
|
||||
#undef _TIME_BITS
|
||||
|
||||
/* Define to 1 if type 'char' is unsigned and your compiler does not
|
||||
predefine this macro. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
# undef __CHAR_UNSIGNED__
|
||||
#endif
|
||||
|
||||
/* Define to 1 on platforms where this makes time_t a 64-bit type. */
|
||||
#undef __MINGW_USE_VC2005_COMPAT
|
||||
|
||||
/* Define to empty if 'const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to '__inline__' or '__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to 'int' if <sys/types.h> does not define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define as a signed integer type capable of holding a process identifier. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to 'int' if <malloc.h> does not define. */
|
||||
#undef ptrdiff_t
|
||||
|
||||
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to empty if the keyword 'volatile' does not work. Warning: valid
|
||||
code using 'volatile' can become incorrect without. Disable with care. */
|
||||
#undef volatile
|
352
configure.ac
Normal file
352
configure.ac
Normal file
|
@ -0,0 +1,352 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
m4_pattern_forbid([^_?DPKG_])
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT([dpkg], m4_esyscmd([build-aux/get-version]),
|
||||
[debian-dpkg@lists.debian.org], [dpkg],
|
||||
[https://wiki.debian.org/Teams/Dpkg])
|
||||
DPKG_DIST_IS_RELEASE
|
||||
AC_SUBST([PACKAGE_COPYRIGHT_HOLDER], ['Dpkg Developers'])
|
||||
AC_SUBST([PACKAGE_VCS_ID], m4_esyscmd([build-aux/get-vcs-id]))
|
||||
AC_SUBST([PACKAGE_VCS_TYPE], [git])
|
||||
AC_SUBST([PACKAGE_VCS_URL], [https://git.dpkg.org/git/dpkg/dpkg.git])
|
||||
AC_SUBST([PACKAGE_VCS_WEB], [https://git.dpkg.org/cgit/dpkg/dpkg.git])
|
||||
AC_SUBST([PACKAGE_BUG_WEB], [https://bugs.debian.org/src:dpkg])
|
||||
AC_SUBST([PACKAGE_CPAN_NAME], [Dpkg])
|
||||
AC_CONFIG_SRCDIR([lib/dpkg/dpkg.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
AM_INIT_AUTOMAKE(
|
||||
[1.11]
|
||||
[-Wall]
|
||||
[foreign]
|
||||
[nostdinc]
|
||||
[subdir-objects]
|
||||
[tar-ustar no-dist-gzip dist-xz]
|
||||
)
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
# Require at least this gettext version, but will take any later version too.
|
||||
AM_GNU_GETTEXT_REQUIRE_VERSION([0.19.8])
|
||||
# XXX: We cannot remove the following macro due to backwards compatibility
|
||||
# reasons. The above macro is set unconditionally to the minimal version
|
||||
# required, and the below is set to 0.19.6, the first version introducing
|
||||
# the AM_GNU_GETTEXT_REQUIRE_VERSION macro.
|
||||
AM_GNU_GETTEXT_VERSION([0.19.6])
|
||||
AM_GNU_GETTEXT([external])
|
||||
DPKG_DIST_CHECK([test "$GMSGFMT" = ":" && test "$USE_NLS" = "yes"],
|
||||
[gettext required when NLS support enabled])
|
||||
|
||||
# Shared libraries are disabled on purpose, currently there is no ABI stability
|
||||
# guarantee, and it will be broken at will. The infrastructure is in place just
|
||||
# to be able to test that its future activation will work.
|
||||
AM_PROG_AR
|
||||
LT_INIT([disable-shared])
|
||||
DPKG_BUILD_SHARED_LIBS
|
||||
DPKG_LINKER_AS_NEEDED
|
||||
DPKG_LINKER_VERSION_SCRIPT
|
||||
|
||||
# Allow compilation without optional programs
|
||||
DPKG_BUILD_PROG([dselect])
|
||||
DPKG_BUILD_PROG([start-stop-daemon])
|
||||
DPKG_BUILD_PROG([update-alternatives])
|
||||
|
||||
DPKG_BUILD_RELEASE_DATE
|
||||
DPKG_BUILD_DEVEL_DOCS
|
||||
|
||||
# Allow alternate directories
|
||||
DPKG_WITH_DIR([devlibdir], [${libdir}],
|
||||
[dpkg development library directory [LIBDIR]])
|
||||
DPKG_WITH_DIR([pkgconfdir], [${sysconfdir}/${PACKAGE_TARNAME}],
|
||||
[dpkg configuration directory [SYSCONFDIR/dpkg]])
|
||||
DPKG_WITH_DIR([docspecdir], [${docdir}/spec],
|
||||
[dpkg specifications directory [DOCDIR/spec]])
|
||||
DPKG_WITH_DIR([methodsdir], [${libexecdir}/${PACKAGE_TARNAME}/methods],
|
||||
[dpkg download methods directory [LIBEXECDIR/dpkg/methods]])
|
||||
DPKG_WITH_DIR([admindir], [${localstatedir}/lib/${PACKAGE_TARNAME}],
|
||||
[dpkg database directory [LOCALSTATEDIR/lib/dpkg]])
|
||||
DPKG_WITH_DIR([backupsdir], [${localstatedir}/backups],
|
||||
[dpkg database backups directory [LOCALSTATEDIR/backups]])
|
||||
DPKG_WITH_DIR([logdir], [${localstatedir}/log],
|
||||
[system logging directory [LOCALSTATEDIR/log]])
|
||||
DPKG_WITH_DIR([pkgconfigdir], [${devlibdir}/pkgconfig],
|
||||
[pkg-config .pc fragments directory [DEVLIBDIR/pkgconfig]])
|
||||
DPKG_WITH_DIR([aclocaldir], [${datadir}/aclocal],
|
||||
[aclocal m4 fragments files directory [DATADIR/aclocal]])
|
||||
DPKG_WITH_DIR([polkitactionsdir], [${datadir}/polkit-1/actions],
|
||||
[polkit .policy actions directory [DATADIR/polkit-1/actions]])
|
||||
DPKG_WITH_DIR([bashcompletionsdir], [${datadir}/bash-completion/completions],
|
||||
[bash completions directory [DATADIR/bash-completion/completions]])
|
||||
DPKG_WITH_DIR([zshcompletionsdir], [${datadir}/zsh/vendor-completions],
|
||||
[zsh vendor completions directory [DATADIR/zsh/vendor-completions]])
|
||||
|
||||
# Set default dpkg-deb values
|
||||
DPKG_DEB_COMPRESSOR([xz])
|
||||
|
||||
# Checks for programs.
|
||||
DPKG_PROG_SHELL
|
||||
DPKG_PROG_PAGER
|
||||
AC_PROG_SED
|
||||
AC_PROG_GREP
|
||||
AC_PROG_EGREP
|
||||
AC_PROG_CC
|
||||
DPKG_C_STD([99])
|
||||
AC_PROG_CXX
|
||||
DPKG_CXX_STD([14])
|
||||
DPKG_PROG_PATCH
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
AC_CHECK_PROG([HAVE_DOT], [dot], [YES], [NO])
|
||||
DPKG_PROG_TAR
|
||||
DPKG_PROG_PO4A
|
||||
DPKG_PROG_PERL
|
||||
DPKG_PROG_POD2MAN
|
||||
DPKG_CODE_COVERAGE
|
||||
|
||||
# Checks for operating system services and capabilities.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Checks for libraries.
|
||||
DPKG_LIB_RT
|
||||
DPKG_LIB_MD
|
||||
DPKG_LIB_Z
|
||||
DPKG_LIB_BZ2
|
||||
DPKG_LIB_LZMA
|
||||
DPKG_LIB_ZSTD
|
||||
DPKG_LIB_SELINUX
|
||||
AS_IF([test "$build_dselect" = "yes"], [
|
||||
DPKG_LIB_CURSES
|
||||
])
|
||||
AS_IF([test "$build_start_stop_daemon" = "yes"], [
|
||||
DPKG_LIB_SOCKET
|
||||
DPKG_LIB_PS
|
||||
DPKG_LIB_KVM
|
||||
])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([\
|
||||
error.h \
|
||||
err.h \
|
||||
locale.h \
|
||||
xlocale.h \
|
||||
libintl.h \
|
||||
kvm.h \
|
||||
sys/sysmacros.h \
|
||||
sys/param.h \
|
||||
sys/syscall.h \
|
||||
sys/user.h \
|
||||
sys/mkdev.h \
|
||||
sys/pstat.h \
|
||||
linux/fiemap.h \
|
||||
])
|
||||
AS_CASE([$host_os],
|
||||
[linux-gnu*], [
|
||||
# The glibc project has deprecated the <sys/sysctl.h> header and emits
|
||||
# warnings on its usage, and removed it in 2.32. The Linux kernel removed
|
||||
# support for it in 5.5.
|
||||
], [
|
||||
# On other systems, we need to check whether to use it.
|
||||
AC_CHECK_HEADERS([\
|
||||
sys/sysctl.h \
|
||||
])
|
||||
]
|
||||
)
|
||||
DPKG_CHECK_HEADER_SYS_PROCFS
|
||||
AC_CHECK_HEADERS([sys/proc.h], [], [], [
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AS_IF([test "$build_dselect" = "yes"], [
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_CHECK_HEADERS([cxxabi.h])
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
DPKG_ARCH_ABI
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_VOLATILE
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
DPKG_TYPE_PTRDIFF_T
|
||||
DPKG_TYPE_STRUCT_PSINFO
|
||||
DPKG_DECL_SYS_SIGLIST
|
||||
DPKG_DECL_SYS_ERRLIST
|
||||
|
||||
# Checks for library functions.
|
||||
DPKG_FUNC_VA_COPY
|
||||
DPKG_FUNC_C99_SNPRINTF
|
||||
DPKG_FUNC_FSYNC_DIR
|
||||
DPKG_CHECK_DECL([offsetof], [stddef.h])
|
||||
DPKG_CHECK_DECL([makedev], [sys/types.h])
|
||||
DPKG_CHECK_DECL([WCOREDUMP], [sys/wait.h])
|
||||
DPKG_CHECK_DECL([TIOCNOTTY], [sys/ioctl.h])
|
||||
DPKG_CHECK_DECL([O_NOFOLLOW], [fcntl.h])
|
||||
DPKG_CHECK_DECL([F_ALLOCSP64], [fcntl.h])
|
||||
DPKG_CHECK_DECL([F_PREALLOCATE], [fcntl.h])
|
||||
DPKG_CHECK_DECL([P_tmpdir], [stdio.h])
|
||||
DPKG_CHECK_PROGNAME
|
||||
DPKG_CHECK_COMPAT_FUNCS([\
|
||||
getopt \
|
||||
getopt_long \
|
||||
obstack_free \
|
||||
strchrnul \
|
||||
strnlen \
|
||||
strndup \
|
||||
strerror \
|
||||
strsignal \
|
||||
asprintf \
|
||||
fgetpwent \
|
||||
fgetgrent \
|
||||
scandir \
|
||||
alphasort \
|
||||
unsetenv \
|
||||
])
|
||||
AC_CHECK_FUNCS([\
|
||||
lchown \
|
||||
], [], [AC_MSG_ERROR([missing required function])])
|
||||
AC_CHECK_FUNCS([\
|
||||
setsid \
|
||||
getdtablesize \
|
||||
closefrom \
|
||||
close_range \
|
||||
getprocs64 \
|
||||
getprogname \
|
||||
getexecname \
|
||||
lutimes \
|
||||
fallocate \
|
||||
posix_fallocate \
|
||||
posix_fadvise \
|
||||
uselocale \
|
||||
])
|
||||
|
||||
AS_IF([test "$build_dselect" = "yes"], [
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_CHECK_FUNCS([__cxa_pure_virtual])
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
|
||||
DPKG_USE_MMAP
|
||||
DPKG_USE_DISK_PREALLOCATE
|
||||
|
||||
# Checks for the build machinery.
|
||||
AC_DEFINE([LIBDPKG_VOLATILE_API], [1], [Acknowledge the volatility of the API.])
|
||||
DPKG_COMPILER_DIALECT
|
||||
DPKG_COMPILER_HARDENING
|
||||
DPKG_COMPILER_WARNINGS
|
||||
DPKG_COMPILER_SANITIZER
|
||||
DPKG_COMPILER_ANALYZER
|
||||
DPKG_COMPILER_OPTIMIZATIONS
|
||||
DPKG_LINKER_OPTIMIZATIONS
|
||||
DPKG_ARCHITECTURE
|
||||
AC_DEFINE([PACKAGE_RELEASE], [PACKAGE_VERSION " (" ARCHITECTURE ")"],
|
||||
[Define the project release information, version and architecture])
|
||||
|
||||
AC_CONFIG_TESTDIR([src/at])
|
||||
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
dselect/Makefile
|
||||
dselect/methods/Makefile
|
||||
dselect/po/Makefile.in
|
||||
lib/Makefile
|
||||
lib/compat/Makefile
|
||||
lib/dpkg/Makefile
|
||||
lib/dpkg/libdpkg.pc
|
||||
doc/Doxyfile
|
||||
man/Makefile
|
||||
po/Makefile.in
|
||||
scripts/Build.PL
|
||||
scripts/Makefile
|
||||
scripts/README.cpan
|
||||
scripts/mk/Makefile
|
||||
scripts/po/Makefile.in
|
||||
src/Makefile
|
||||
src/at/atlocal
|
||||
utils/Makefile
|
||||
])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_OUTPUT
|
||||
|
||||
# Print the current configuration
|
||||
cat <<CONFIG
|
||||
|
||||
Release:
|
||||
Version . . . . . : $PACKAGE_VERSION
|
||||
VCS id . . . . . : $PACKAGE_VCS_ID
|
||||
|
||||
Configuration:
|
||||
Arch attributes:
|
||||
cpu name . . . . . . . . . . : ${cpu_type}
|
||||
os name . . . . . . . . . . . : ${os_type}
|
||||
arch name . . . . . . . . . . : ${dpkg_arch}
|
||||
arch bits . . . . . . . . . . : ${dpkg_arch_bits}
|
||||
arch endian . . . . . . . . . : ${dpkg_arch_endian}
|
||||
char bits . . . . . . . . . . : ${dpkg_char_bits}
|
||||
char sign . . . . . . . . . . : ${dpkg_char_sign}
|
||||
sizeof(short) . . . . . . . . : ${ac_cv_sizeof_short}
|
||||
sizeof(int) . . . . . . . . . : ${ac_cv_sizeof_int}
|
||||
sizeof(long) . . . . . . . . : ${ac_cv_sizeof_long}
|
||||
sizeof(long long) . . . . . . : ${ac_cv_sizeof_long_long}
|
||||
sizeof(float) . . . . . . . . : ${ac_cv_sizeof_float}
|
||||
sizeof(double) . . . . . . . : ${ac_cv_sizeof_double}
|
||||
sizeof(long double) . . . . . : ${ac_cv_sizeof_long_double}
|
||||
sizeof(void *) . . . . . . . : ${ac_cv_sizeof_void_p}
|
||||
sizeof(off_t) . . . . . . . . : ${ac_cv_sizeof_off_t}
|
||||
sizeof(time_t) . . . . . . . : ${ac_cv_sizeof_time_t}
|
||||
alignof(max_align_t) . . . . : ${ac_cv_alignof_max_align_t}
|
||||
|
||||
Features:
|
||||
native language support . . . : $USE_NLS
|
||||
unicode support . . . . . . . : $USE_UNICODE
|
||||
development documentation . . : $build_devel_docs
|
||||
code coverage . . . . . . . . : $enable_coverage
|
||||
build shared libraries . . . : $enable_shared
|
||||
mmap loaders . . . . . . . . : $enable_mmap
|
||||
disk pre-allocation . . . . . : $enable_disk_preallocate
|
||||
default dpkg-deb compressor . : $with_deb_compressor
|
||||
default shell interpreter . . : $DPKG_SHELL
|
||||
default pager program . . . . : $DPKG_PAGER
|
||||
|
||||
Paths:
|
||||
devlibdir . . . . . . . . . . : $devlibdir
|
||||
pkgconfdir . . . . . . . . . : $pkgconfdir
|
||||
docspecdir . . . . . . . . . : $docspecdir
|
||||
methodsdir . . . . . . . . . : $methodsdir
|
||||
admindir . . . . . . . . . . : $admindir
|
||||
backupsdir . . . . . . . . . : $backupsdir
|
||||
logdir . . . . . . . . . . . : $logdir
|
||||
pkg-config dir . . . . . . . : $pkgconfigdir
|
||||
aclocal dir . . . . . . . . : $aclocaldir
|
||||
polkit actions dir . . . . . : $polkitactionsdir
|
||||
bash completions dir . . . . : $bashcompletionsdir
|
||||
zsh completions dir . . . . . : $zshcompletionsdir
|
||||
perl interpreter . . . . . . : $PERL
|
||||
perl libdir . . . . . . . . . : $PERL_LIBDIR
|
||||
|
||||
Programs:
|
||||
update-alternatives . . . . . : $build_update_alternatives
|
||||
start-stop-daemon . . . . . . : $build_start_stop_daemon
|
||||
dselect . . . . . . . . . . . : $build_dselect
|
||||
|
||||
System Libraries:
|
||||
librt . . . . . . . . . . . . : $have_librt
|
||||
libsocket . . . . . . . . . . : ${have_libsocket:-no}
|
||||
libps . . . . . . . . . . . . : ${have_libps:-no}
|
||||
libkvm . . . . . . . . . . . : ${have_libkvm:-no}
|
||||
libselinux . . . . . . . . . : $have_libselinux
|
||||
libmd . . . . . . . . . . . . : $have_libmd
|
||||
libz . . . . . . . . . . . . : $have_libz_impl
|
||||
liblzma . . . . . . . . . . . : $have_liblzma
|
||||
libzstd . . . . . . . . . . . : $have_libzstd
|
||||
libbz2 . . . . . . . . . . . : $have_libbz2
|
||||
libcurses . . . . . . . . . . : ${have_libcurses:-no}
|
||||
CONFIG
|
13
data/abitable
Normal file
13
data/abitable
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Version=2.0
|
||||
#
|
||||
# This file contains the table of arch ABI attribute overrides.
|
||||
#
|
||||
# If the ABI is not present here then the attribute information for a
|
||||
# Debian arch tuple matches the one on the cputable.
|
||||
#
|
||||
# - Column 1 is the Debian name for the ABI.
|
||||
# - Column 2 is the size (in bits) of the ABI pointers.
|
||||
#
|
||||
# <Debian name> <Bits>
|
||||
abin32 32
|
||||
x32 32
|
54
data/cputable
Normal file
54
data/cputable
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Version=1.0
|
||||
#
|
||||
# This file contains the table of known CPU names.
|
||||
#
|
||||
# Architecture names are formed as a combination of the system name
|
||||
# (from ostable) and CPU name (from this table) after mapping from
|
||||
# the Debian arch tuple (from tupletable).
|
||||
#
|
||||
# - Column 1 is the Debian name for the CPU, used to form the cpu part in
|
||||
# the Debian arch tuple.
|
||||
# - Column 2 is the GNU name for the CPU, used to output build, host and
|
||||
# target variables in ‘dpkg-architecture’.
|
||||
# - Column 3 is an extended regular expression used to fully match against
|
||||
# the CPU part of the output of the GNU config.guess script. The order of
|
||||
# this column is important when using wildcards as it is used in a first
|
||||
# match basis.
|
||||
# - Column 4 is the size (in bits) of pointers.
|
||||
# - Column 5 is the endianness (byte ordering in numbers).
|
||||
#
|
||||
# <Debian name> <GNU name> <config.guess regex> <Bits> <Endianness>
|
||||
alpha alpha alpha.* 64 little
|
||||
amd64 x86_64 (amd64|x86_64) 64 little
|
||||
arc arc arc 32 little
|
||||
armeb armeb arm.*b 32 big
|
||||
arm arm arm.* 32 little
|
||||
arm64 aarch64 aarch64 64 little
|
||||
hppa hppa hppa.* 32 big
|
||||
loong64 loongarch64 loongarch64 64 little
|
||||
i386 i686 (i[34567]86|pentium) 32 little
|
||||
ia64 ia64 ia64 64 little
|
||||
m68k m68k m68k 32 big
|
||||
mips mips mips(eb)? 32 big
|
||||
mipsel mipsel mipsel 32 little
|
||||
mipsr6 mipsisa32r6 mipsisa32r6 32 big
|
||||
mipsr6el mipsisa32r6el mipsisa32r6el 32 little
|
||||
mips64 mips64 mips64 64 big
|
||||
mips64el mips64el mips64el 64 little
|
||||
mips64r6 mipsisa64r6 mipsisa64r6 64 big
|
||||
mips64r6el mipsisa64r6el mipsisa64r6el 64 little
|
||||
nios2 nios2 nios2 32 little
|
||||
or1k or1k or1k 32 big
|
||||
powerpc powerpc (powerpc|ppc) 32 big
|
||||
powerpcel powerpcle powerpcle 32 little
|
||||
ppc64 powerpc64 (powerpc|ppc)64 64 big
|
||||
ppc64el powerpc64le powerpc64le 64 little
|
||||
riscv64 riscv64 riscv64 64 little
|
||||
s390 s390 s390 32 big
|
||||
s390x s390x s390x 64 big
|
||||
sh3 sh3 sh3 32 little
|
||||
sh3eb sh3eb sh3eb 32 big
|
||||
sh4 sh4 sh4 32 little
|
||||
sh4eb sh4eb sh4eb 32 big
|
||||
sparc sparc sparc 32 big
|
||||
sparc64 sparc64 sparc64 64 big
|
2
data/no-pie-compile.specs
Normal file
2
data/no-pie-compile.specs
Normal file
|
@ -0,0 +1,2 @@
|
|||
*self_spec:
|
||||
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:-fno-PIE}}}}}}
|
2
data/no-pie-link.specs
Normal file
2
data/no-pie-link.specs
Normal file
|
@ -0,0 +1,2 @@
|
|||
*self_spec:
|
||||
+ %{!shared:%{!r:%{!fPIE:%{!pie:-fno-PIE -no-pie}}}}
|
41
data/ostable
Normal file
41
data/ostable
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Version=2.0
|
||||
#
|
||||
# This file contains the table of known operating system names.
|
||||
#
|
||||
# Architecture names are formed as a combination of the system name
|
||||
# (from this table) and CPU name (from cputable) after mapping from
|
||||
# the Debian arch tuple (from tupletable).
|
||||
#
|
||||
# - Column 1 is the Debian name for the system, used to form the system part
|
||||
# in the Debian arch tuple.
|
||||
# - Column 2 is the GNU name for the system, used to output build, host and
|
||||
# target variables in ‘dpkg-architecture’.
|
||||
# - Column 3 is an extended regular expression used to fully match against
|
||||
# the system part of the output of the GNU config.guess script. The order
|
||||
# of this column is important when using wildcards as it is used in a first
|
||||
# match basis.
|
||||
#
|
||||
# <Debian name> <GNU name> <config.guess regex>
|
||||
eabi-uclibc-linux linux-uclibceabi linux[^-]*-uclibceabi
|
||||
base-uclibc-linux linux-uclibc linux[^-]*-uclibc
|
||||
eabihf-musl-linux linux-musleabihf linux[^-]*-musleabihf
|
||||
base-musl-linux linux-musl linux[^-]*-musl
|
||||
eabihf-gnu-linux linux-gnueabihf linux[^-]*-gnueabihf
|
||||
eabi-gnu-linux linux-gnueabi linux[^-]*-gnueabi
|
||||
abin32-gnu-linux linux-gnuabin32 linux[^-]*-gnuabin32
|
||||
abi64-gnu-linux linux-gnuabi64 linux[^-]*-gnuabi64
|
||||
spe-gnu-linux linux-gnuspe linux[^-]*-gnuspe
|
||||
x32-gnu-linux linux-gnux32 linux[^-]*-gnux32
|
||||
base-gnu-linux linux-gnu linux[^-]*(-gnu.*)?
|
||||
eabihf-gnu-kfreebsd kfreebsd-gnueabihf kfreebsd[^-]*-gnueabihf
|
||||
base-gnu-kfreebsd kfreebsd-gnu kfreebsd[^-]*(-gnu.*)?
|
||||
base-gnu-kopensolaris kopensolaris-gnu kopensolaris[^-]*(-gnu.*)?
|
||||
base-gnu-hurd gnu gnu[^-]*
|
||||
base-bsd-darwin darwin darwin[^-]*
|
||||
base-bsd-dragonflybsd dragonflybsd dragonfly[^-]*
|
||||
base-bsd-freebsd freebsd freebsd[^-]*
|
||||
base-bsd-netbsd netbsd netbsd[^-]*
|
||||
base-bsd-openbsd openbsd openbsd[^-]*
|
||||
base-sysv-aix aix aix[^-]*
|
||||
base-sysv-solaris solaris solaris[^-]*
|
||||
base-tos-mint mint mint[^-]*
|
2
data/pie-compile.specs
Normal file
2
data/pie-compile.specs
Normal file
|
@ -0,0 +1,2 @@
|
|||
*self_spec:
|
||||
+ %{!r:%{!fpie:%{!fPIE:%{!fpic:%{!fPIC:%{!fno-pic:%{!fno-PIE:%{!no-pie:-fPIE}}}}}}}}
|
2
data/pie-link.specs
Normal file
2
data/pie-link.specs
Normal file
|
@ -0,0 +1,2 @@
|
|||
*self_spec:
|
||||
+ %{!static:%{!shared:%{!r:%{!fno-PIE:%{!no-pie:-fPIE -pie}}}}}
|
69
data/tupletable
Normal file
69
data/tupletable
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Version=1.0
|
||||
#
|
||||
# Bidirectional mapping between a Debian arch tuple and a Debian arch name.
|
||||
#
|
||||
# Debian arch tuple names are formed as a combination of the Debian system
|
||||
# name (from the ostable) and the Debian CPU name (from the cputable) after
|
||||
# applying the variable substitutions.
|
||||
#
|
||||
# Debian arch names are the result of historical naming conventions in Debian,
|
||||
# where the predominant system architectures have many of their parts in
|
||||
# implicit form, by only exposing the CPU with the ABI bolted on, where less
|
||||
# common architectures have their OS part spelled out, and where even less
|
||||
# common ones, have their libc spelled out. This table maps between the ideal
|
||||
# architecture tuple, with the current messy reality.
|
||||
#
|
||||
# - Column 1 is the Debian arch tuple name, as the normalized form of the
|
||||
# architecture names, used as the internal representation.
|
||||
# - Column 2 is the Debian arch name, as the abbreviated form of the
|
||||
# architecture names, used as the public interface.
|
||||
#
|
||||
# Supported variables: <cpu>
|
||||
#
|
||||
# <Debian arch tuple> <Debian arch name>
|
||||
eabi-uclibc-linux-arm uclibc-linux-armel
|
||||
base-uclibc-linux-<cpu> uclibc-linux-<cpu>
|
||||
eabihf-musl-linux-arm musl-linux-armhf
|
||||
base-musl-linux-<cpu> musl-linux-<cpu>
|
||||
eabihf-gnu-linux-arm armhf
|
||||
eabi-gnu-linux-arm armel
|
||||
abin32-gnu-linux-mips64r6el mipsn32r6el
|
||||
abin32-gnu-linux-mips64r6 mipsn32r6
|
||||
abin32-gnu-linux-mips64el mipsn32el
|
||||
abin32-gnu-linux-mips64 mipsn32
|
||||
abi64-gnu-linux-mips64r6el mips64r6el
|
||||
abi64-gnu-linux-mips64r6 mips64r6
|
||||
abi64-gnu-linux-mips64el mips64el
|
||||
abi64-gnu-linux-mips64 mips64
|
||||
spe-gnu-linux-powerpc powerpcspe
|
||||
x32-gnu-linux-amd64 x32
|
||||
base-gnu-linux-<cpu> <cpu>
|
||||
base-gnu-kfreebsd-amd64 kfreebsd-amd64
|
||||
base-gnu-kfreebsd-i386 kfreebsd-i386
|
||||
base-gnu-kopensolaris-amd64 kopensolaris-amd64
|
||||
base-gnu-kopensolaris-i386 kopensolaris-i386
|
||||
base-gnu-hurd-amd64 hurd-amd64
|
||||
base-gnu-hurd-i386 hurd-i386
|
||||
base-bsd-dragonflybsd-amd64 dragonflybsd-amd64
|
||||
base-bsd-freebsd-amd64 freebsd-amd64
|
||||
base-bsd-freebsd-arm freebsd-arm
|
||||
base-bsd-freebsd-arm64 freebsd-arm64
|
||||
base-bsd-freebsd-i386 freebsd-i386
|
||||
base-bsd-freebsd-powerpc freebsd-powerpc
|
||||
base-bsd-freebsd-ppc64 freebsd-ppc64
|
||||
base-bsd-freebsd-riscv freebsd-riscv
|
||||
base-bsd-openbsd-<cpu> openbsd-<cpu>
|
||||
base-bsd-netbsd-<cpu> netbsd-<cpu>
|
||||
base-bsd-darwin-amd64 darwin-amd64
|
||||
base-bsd-darwin-arm darwin-arm
|
||||
base-bsd-darwin-arm64 darwin-arm64
|
||||
base-bsd-darwin-i386 darwin-i386
|
||||
base-bsd-darwin-powerpc darwin-powerpc
|
||||
base-bsd-darwin-ppc64 darwin-ppc64
|
||||
base-sysv-aix-powerpc aix-powerpc
|
||||
base-sysv-aix-ppc64 aix-ppc64
|
||||
base-sysv-solaris-amd64 solaris-amd64
|
||||
base-sysv-solaris-i386 solaris-i386
|
||||
base-sysv-solaris-sparc solaris-sparc
|
||||
base-sysv-solaris-sparc64 solaris-sparc64
|
||||
base-tos-mint-m68k mint-m68k
|
2807
doc/Doxyfile.in
Normal file
2807
doc/Doxyfile.in
Normal file
File diff suppressed because it is too large
Load diff
35
doc/README.api
Normal file
35
doc/README.api
Normal file
|
@ -0,0 +1,35 @@
|
|||
This is an (incomplete) list of currently provided APIs by dpkg, and
|
||||
their supported status.
|
||||
|
||||
|
||||
What: libdpkg.a (C static library)
|
||||
Status: volatile
|
||||
Description:
|
||||
The API provided by this library is highly volatile, still in the process
|
||||
of being cleaned up. It's only supposed to be used internally by dpkg for
|
||||
now. Header files, functions, variables and types might get renamed,
|
||||
removed or change semantics. If you still have a need to use it, which
|
||||
you'd be doing anyway, say by locally building dpkg to get the library,
|
||||
then define the C preprocessor macro LIBDPKG_VOLATILE_API in your build
|
||||
to acknowledge that fact.
|
||||
|
||||
What: libdpkg-perl (perl modules)
|
||||
Status: stable
|
||||
Description:
|
||||
Among the perl modules provided by libdpkg-perl, you can safely rely on
|
||||
those that have $VERSION set to 1.00 (or higher). Note however that the
|
||||
API is defined by what's documented in the corresponding manual pages and
|
||||
nothing more. You can't assume anything else based on what you read in
|
||||
the source code. If you feel the need for further refinements in the
|
||||
documented API, don't hesitate to file a wishlist bug against
|
||||
libdpkg-perl.
|
||||
.
|
||||
In case of API-breaking changes, the major number in $VERSION will be
|
||||
increased. For API extensions, the minor number will be increased.
|
||||
|
||||
What: custom changelog parsers as Dpkg::Changelog derived modules
|
||||
Status: stable
|
||||
Description:
|
||||
Since dpkg 1.18.8, custom changelog parsers are supported as modules
|
||||
derived from the Dpkg::Changelog module. The derived modules need to
|
||||
implement all required documented methods.
|
180
doc/README.feature-removal-schedule
Normal file
180
doc/README.feature-removal-schedule
Normal file
|
@ -0,0 +1,180 @@
|
|||
This is a list of features that are scheduled to be removed from dpkg.
|
||||
|
||||
What: fallback of dpkg-source to source format "1.0" without explicit debian/source/format
|
||||
Status: deprecated
|
||||
When: 1.17.x
|
||||
Warning: program and lintian (missing-debian-source-format)
|
||||
Why:
|
||||
With the support of multiple source formats, the user should be explicit
|
||||
about the desired source format. The fallback to "1.0" is there only for
|
||||
backwards compatibility but will be removed once all packages have the
|
||||
debian/source/format file. This is unlikely to happen before 1.17.x.
|
||||
|
||||
What --forget-old-unavail (dpkg option)
|
||||
Status: obsolete
|
||||
When: 1.16.x
|
||||
Warning: program
|
||||
Why:
|
||||
Purged packages are properly cleaned up now by dpkg, and old unavailable
|
||||
leftovers are automatically cleaned up on database parsing. So there's no
|
||||
need anymore for this manual action.
|
||||
|
||||
What: --control-path (dpkg-query option)
|
||||
Status: deprecated
|
||||
When: 1.18.x
|
||||
Warning: man page
|
||||
This was a semi-public interface now superseded by --control-list and
|
||||
--control-show, which are a better interface as they do not rely on any
|
||||
specific database layout. Although there might still be cases where it's
|
||||
required to avoid hardcoding the database layout, and it will be kept as
|
||||
long as there's legitimate uses for it and no viable replacements.
|
||||
|
||||
What: -L (dpkg-parsechangelog option)
|
||||
Status: obsolete
|
||||
Since: 1.18.8
|
||||
When: 1.19.x
|
||||
Warning: program
|
||||
Why:
|
||||
The custom parsers have been switched from programs to perl modules,
|
||||
and this option has no use any longer. The caller can set PERL5LIB or
|
||||
PERLLIB to specify the perl module search path now.
|
||||
|
||||
History of feature removals
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
What: cleanup-info (program)
|
||||
Status: removed
|
||||
Since: 1.15.0
|
||||
Why:
|
||||
This program was needed long time ago to fixup broken info dir files
|
||||
generated by buggy install-info programs. Should not be needed anymore.
|
||||
|
||||
What: --largemem, --smallmem (dpkg option)
|
||||
Status: removed
|
||||
When: 1.15.1
|
||||
Why:
|
||||
These options have been no-ops for a long time.
|
||||
|
||||
What: --force-auto-select (dpkg option)
|
||||
Status: removed
|
||||
When: 1.15.1
|
||||
Why:
|
||||
This option has been a no-op for so long, that there's no traces on git
|
||||
history of its usage.
|
||||
|
||||
What: recommended, contrib, base (priority)
|
||||
Status: removed
|
||||
When: 1.15.1
|
||||
Why:
|
||||
These priorities have been superseded by either other fields or values in
|
||||
other fields.
|
||||
|
||||
What: 822-date (program)
|
||||
Status: removed
|
||||
When: 1.15.1
|
||||
Why:
|
||||
Should switch to use 'date -R'.
|
||||
|
||||
What: support of custom changelog parsers understanding only -v
|
||||
Status: removed
|
||||
Since: 1.15.5
|
||||
Why:
|
||||
The debian changelog parser has been enhanced. It supports new options
|
||||
that enable more fine-grained retrieval of information. Those new options
|
||||
will be used by scripts (like dpkg-genchanges).
|
||||
.
|
||||
Custom changelog parsers must be updated to support the new API (see
|
||||
dpkg-parsechangelog(1) and README.api).
|
||||
|
||||
What: support for environment variable DPKG_NO_TSTP
|
||||
Status: removed
|
||||
Since: 1.15.6
|
||||
Why:
|
||||
Having two ways to let the administrator get to a shell on conffile prompt
|
||||
is confusing, it also impedes setting up a consistent environment to be
|
||||
used by external programs.
|
||||
|
||||
What: support for PGP
|
||||
Status: removed
|
||||
When: 1.16.4
|
||||
Warning: program
|
||||
Why:
|
||||
PGP is not part of Debian and GnuPG has been the standard tool for digital
|
||||
signatures for several years already. Supporting only GnuPG enables us to
|
||||
rely on some of its features.
|
||||
|
||||
What: -u, --udeb (dpkg-scanpackages option)
|
||||
Status: removed
|
||||
When: 1.16.4
|
||||
Warning: program
|
||||
Why:
|
||||
This option has been superseded by -tudeb.
|
||||
|
||||
What: support for custom changelog parsers as programs
|
||||
Status: removed
|
||||
Since: 1.18.8
|
||||
Why:
|
||||
Using programs to implement the custom changelog parsers was very inefficient
|
||||
as it required to parse the custom changelog, output deb822 formatted entries
|
||||
to then parse that and output again with the desired format.
|
||||
.
|
||||
These were implemented as programs because at the time the perl code in dpkg
|
||||
was not using perl modules, so it was not easy to extend. Using perl modules
|
||||
now is cleaner and allows for a faster implementation.
|
||||
.
|
||||
In addition there's no known users in Debian, so it was deemed safe to remove
|
||||
the support without a transition.
|
||||
|
||||
What: Source-Version (substvar)
|
||||
Status: removed
|
||||
When: 1.18.11
|
||||
Warning: program, lintian (substvar-source-version-is-deprecated)
|
||||
Why:
|
||||
The semantics of Source-Version were misleading when applied to binNMUs.
|
||||
Should switch to use binary:Version or source:Version substvars.
|
||||
.
|
||||
The code got changed to emit errors.
|
||||
|
||||
What: -Zlzma (dpkg-deb option value)
|
||||
Status: removed
|
||||
When: 1.18.11
|
||||
Warning: program
|
||||
Why:
|
||||
LZMA compression has some format deficiencies fixed by XZ, which is what
|
||||
upstream has replaced it with, as such there's no point in continuing to
|
||||
support compressing new .deb files with that format, although unpacking
|
||||
will be kept being supported to handle existing compressed files.
|
||||
|
||||
What: -Zbzip2 (dpkg-deb option value)
|
||||
Status: removed
|
||||
When: 1.18.11
|
||||
Warning: program
|
||||
Why:
|
||||
bzip2 compression has been superseded by xz when it comes to size, and
|
||||
gzip is still faster, in Debian there's really not many packages using
|
||||
that compression, as such there's no point in continuing to support
|
||||
compressing new .deb files with that format, although unpacking
|
||||
will be kept being supported to handle existing compressed files.
|
||||
|
||||
What: --new, --old (dpkg-deb options)
|
||||
Status: removed
|
||||
When: 1.18.11
|
||||
Warning: program
|
||||
Why:
|
||||
These options are not future-proof, and do not give the caller any
|
||||
guarantee of what exact format version will be used to produce the
|
||||
output file. They were replaced with a new --deb-format option.
|
||||
|
||||
What: --print-installation-architecture (dpkg option)
|
||||
Status: removed
|
||||
When: 1.18.11
|
||||
Warning: program
|
||||
Why:
|
||||
Obsoleted long time ago (2005-01-22). Remaining packages should switch to
|
||||
use 'dpkg --print-architecture'.
|
||||
|
||||
What: GCJ and GCJFLAGS support
|
||||
Status: removed
|
||||
When: 1.22.1
|
||||
Why:
|
||||
GCJ has been dead upstream since 2018.
|
334
doc/coding-style.txt
Normal file
334
doc/coding-style.txt
Normal file
|
@ -0,0 +1,334 @@
|
|||
Dpkg POD coding style 2021-06-25
|
||||
=====================
|
||||
|
||||
General
|
||||
~~~~~~~
|
||||
|
||||
Verbatim code sections that need to be formatted, need to be prefixed with
|
||||
a line containing exactly «Z<>», to trick the parser.
|
||||
|
||||
New sentences inside a paragraph should start on a new line, so that we
|
||||
do not need to reflow the text when adding new content.
|
||||
|
||||
Every new feature, option or behavior change needs to be documented with
|
||||
the version introducing the change.
|
||||
|
||||
|
||||
Dpkg M4sh/Autoconf coding style 2016-09-05
|
||||
===============================
|
||||
|
||||
General
|
||||
~~~~~~~
|
||||
|
||||
All dpkg specific macros need to be prefixed with «DPKG_». Complex checks
|
||||
should be defined as new macros under m4/dpkg-<name>.m4, and those used
|
||||
in configure.ac which should look pretty simple.
|
||||
|
||||
Quoting and indentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Code and arguments that wrap into the next line are indented by two spaces.
|
||||
|
||||
In principle all macro argument should always be quoted. Which brings one
|
||||
of the biggest readability issues with M4sh/Autoconf code, the amount of
|
||||
consecutive quotes and parenthesis pairs, which can make it very hard to
|
||||
notice if they are unbalanced. To avoid this we use a style that tries to
|
||||
avoid more than two consecutive blocks of «])».
|
||||
|
||||
We can either use a style resembling very simple function calls, when the
|
||||
arguments are as well very simple, such as:
|
||||
|
||||
AC_DEFINE_UNQUOTED([SOME_VARIABLE],
|
||||
[SOME_CONCOCTED_WAY_TO_GET_A_VALUE],
|
||||
[Some descriptive text here])
|
||||
|
||||
AS_CASE([condition],
|
||||
[case-a], [do-a],
|
||||
[case-b], [do-b])
|
||||
|
||||
Or one resembling curly-braced C-style blocks, such as this:
|
||||
|
||||
AS_IF([condition], [
|
||||
DO_SOMETHING([here])
|
||||
], [
|
||||
DO_OTHERWISE([there])
|
||||
])
|
||||
|
||||
Except for AC_ARG_WITH, AC_ARG_ENABLE and AM_CONDITIONAL which need their
|
||||
second argument quoted tightly surrounding the code, like this:
|
||||
|
||||
AC_ARG_ENABLE([feature],
|
||||
[AS_HELP_STRING([--disable-feature], [Disable feature])],
|
||||
[], [enable_feature="yes"])
|
||||
|
||||
AM_CONDITIONAL([HAVE_SOME_FEATURE],
|
||||
[test "$ac_cv_have_some_feature" = "yes" && \
|
||||
test "$ac_cv_have_some_feature" = "yes"])
|
||||
|
||||
or the output will get messed up.
|
||||
|
||||
|
||||
Dpkg C/C++ coding style 2024-07-24
|
||||
=======================
|
||||
|
||||
Standards
|
||||
~~~~~~~~~
|
||||
|
||||
The C code base assumes C99, except for the following features:
|
||||
|
||||
- Variable length arrays.
|
||||
- Mixed declaration and code.
|
||||
|
||||
The C++ code base assumes C++14.
|
||||
|
||||
The code base assumes a POSIX.1-2008 compatible environment.
|
||||
|
||||
The required features are checked at build time, and it will either use
|
||||
compatibility code in case the needed extensions are not supported and it
|
||||
is possible to support them, otherwise it will abort in case a needed one
|
||||
cannot be used.
|
||||
|
||||
General
|
||||
~~~~~~~
|
||||
|
||||
The coding style is a mix of parts from KNF [K] and the Linux CodingStyle [L].
|
||||
If in doubt or missing from this file please ask, although files using the
|
||||
tab based indentation can be considered canon.
|
||||
|
||||
[K] <https://www.freebsd.org/cgi/man.cgi?query=style>
|
||||
[L] <https://kernel.org/doc/Documentation/process/coding-style.rst>
|
||||
|
||||
The code has a mix of an old coding style being phased out and the new
|
||||
style. New files should use the new style, changes to files with the old
|
||||
style should switch the code being touched except for the indentation level,
|
||||
which should be preserved to match (2 spaces).
|
||||
|
||||
Code should generally strive for clarity. Monster functions should be split
|
||||
into logical and small pieces.
|
||||
|
||||
Variable and function names should be generally descriptive, not needed
|
||||
for variables commonly used (for example an index inside a loop, etc),
|
||||
acronyms should only be used if they are widely known externally or
|
||||
inside the project. The names should separate logical concepts within
|
||||
with underscores.
|
||||
|
||||
On comments use UTF-8 characters for quotes, copyright symbols, etc.
|
||||
|
||||
On strings in code use simple or double quotes «''» «""». Not the unpaired
|
||||
ones «`'». Strings marked for translation, should only be fixed if there's
|
||||
other changes to be done on them, otherwise we get unneeded fuzzies.
|
||||
|
||||
<https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html>
|
||||
|
||||
Code documentation
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Public declarations should be documented using JavaDoc style comments.
|
||||
|
||||
Documentation should always be close to its definition (usually in the .c
|
||||
or .cc files) and not its declaration, so that when the code changes it's
|
||||
less likely that they will get out of sync. For data types, macros and
|
||||
similar where there's only declarations, the documentation will usually
|
||||
go instead in the header files.
|
||||
|
||||
For enum values and struct members, the documentation should usually be
|
||||
one-line comments, preceding the item.
|
||||
|
||||
The comment title should be on the second line on its own, and the long
|
||||
description on its own paragraph.
|
||||
|
||||
Examples:
|
||||
|
||||
/**
|
||||
* This is the enum title.
|
||||
*/
|
||||
enum value_list {
|
||||
/** Value doing foo. */
|
||||
VALUE_A,
|
||||
/** Value doing bar. */
|
||||
VALUE_B,
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the title.
|
||||
*
|
||||
* This is the long description extending several lines, explaining in
|
||||
* detail what this item does.
|
||||
*
|
||||
* @param a This is the a parameter.
|
||||
* @param b This is the b parameter.
|
||||
*
|
||||
* @return This is the return value.
|
||||
*/
|
||||
|
||||
Indentation, alignment and spacing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Lines should be 80 chars max. Indentation is done with hard tabs (which
|
||||
should be considered to take 8 spaces width). Aligning with spaces:
|
||||
|
||||
static void
|
||||
function(void *ptr, int value)
|
||||
{
|
||||
void *ref_ptr = get_ref(ptr);
|
||||
int ref_value = get_value(ref);
|
||||
|
||||
if (value > 10)
|
||||
do_something(GLOBAL_MACRO, ptr, value, "some-string",
|
||||
ref_ptr, ref_value, "other-string",
|
||||
"extra-string");
|
||||
}
|
||||
|
||||
When wrapping, logical operators should be kept on the preceding line:
|
||||
|
||||
if (really_long_variable_to_be_checked_against_a &&
|
||||
really_long_variable_to_be_checked_against_b)
|
||||
foo();
|
||||
|
||||
Spaces around operators:
|
||||
|
||||
if (a && (b || c) && c == d)
|
||||
break;
|
||||
|
||||
a = (b + 4 * (5 - 6)) & 0xff;
|
||||
|
||||
Spaces around assignments:
|
||||
|
||||
a += b;
|
||||
|
||||
Spaces after comma:
|
||||
|
||||
foo(a, b);
|
||||
|
||||
Space after keywords (for, while, do, if, etc, but sizeof should be
|
||||
treated like a function):
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
foo(i);
|
||||
|
||||
memcpy(dst, src, sizeof(src));
|
||||
|
||||
Definition of local variables, related code blocks, functions bodies
|
||||
should be split with blank lines:
|
||||
|
||||
int
|
||||
function(void)
|
||||
{
|
||||
int a;
|
||||
|
||||
foo();
|
||||
bar();
|
||||
|
||||
quux();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Braces
|
||||
~~~~~~
|
||||
|
||||
Braces should be placed on the same line as the keyword, but on a new line
|
||||
for the function body. No braces should be used for unambiguous one line
|
||||
statements:
|
||||
|
||||
if (a > 0) {
|
||||
foo(a);
|
||||
bar(a);
|
||||
} else {
|
||||
quux(0)
|
||||
bar(0);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
|
||||
do {
|
||||
foo();
|
||||
bar();
|
||||
} while (quux());
|
||||
|
||||
switch (foo) {
|
||||
case a:
|
||||
bar();
|
||||
break;
|
||||
case b:
|
||||
default:
|
||||
baz();
|
||||
break;
|
||||
}
|
||||
|
||||
Code conventions
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Prefer assigning outside of conditionals:
|
||||
|
||||
n = read_items();
|
||||
if (n < 100)
|
||||
foo();
|
||||
|
||||
String comparisons should use comparison operators to make it easier to
|
||||
see what operation is being done:
|
||||
|
||||
if (strcmp(a, b) == 0)
|
||||
foo();
|
||||
|
||||
if (strcmp(a, b) < 0)
|
||||
foo();
|
||||
|
||||
|
||||
Dpkg Perl coding style 2019-03-27
|
||||
======================
|
||||
|
||||
Perl version
|
||||
~~~~~~~~~~~~
|
||||
|
||||
We don't want to impose a too-recent Perl version, so only use features
|
||||
supported by the Perl version that is currently in Debian oldstable when
|
||||
possible. Currently that means Perl 5.32.1.
|
||||
|
||||
General
|
||||
~~~~~~~
|
||||
|
||||
In general you should follow the conventions listed in perlstyle(1).
|
||||
All the code should run with the “use strict” and “use warnings” pragmas,
|
||||
and pass «make authorcheck».
|
||||
|
||||
Code documentation
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Public modules should be documented with POD (see perlpod(1)). Private
|
||||
code doesn't have to use POD, simple comment lines (starting with "#") are
|
||||
enough, but if they use POD they need to note the fact that the module is
|
||||
private in the CHANGES section and specify a version «0.xx». Public scripts
|
||||
are documented in their corresponding manual pages.
|
||||
|
||||
Indentation, alignment and spacing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Lines should be 80 chars max. The indentation level is 4 characters, and
|
||||
indentation is done with soft tabs (no hard tabs) and spaces.
|
||||
|
||||
if ($foo) {
|
||||
if ($bar) {
|
||||
print "Hello\n";
|
||||
unless ($baz) {
|
||||
print "Who are you?\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object methods
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Use a single line to retrieve all the arguments and use $self as name
|
||||
for the current object:
|
||||
|
||||
sub do_something {
|
||||
my ($self, $arg1, $arg2, %opts) = @_;
|
||||
...
|
||||
}
|
||||
|
||||
Supplementary optional arguments should be named and thus stored in a
|
||||
hash.
|
44
doc/spec/build-driver.txt
Normal file
44
doc/spec/build-driver.txt
Normal file
|
@ -0,0 +1,44 @@
|
|||
Support for build-drivers as alternatives to debian/rules
|
||||
=========================================================
|
||||
|
||||
Status: draft, experimental
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
This is currently an exploratory and experimental way to replace the current
|
||||
debian/rules usage with alternative interfaces for building packages.
|
||||
|
||||
It relies on a new Build-Driver field honored by dpkg-buildpackage, but that
|
||||
might eventually disappear or change semantics.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Our current packaging methods are built around the concept of a Makefile
|
||||
(debian/rules), which must contain every bit of logic needed to produce
|
||||
debs. Historically, this involved duplicating various runes in every
|
||||
package and then spending decades updating the runes in every package
|
||||
as we got wiser. Over time there have been many attempts to centralize
|
||||
these runes in package helpers such as debstd (obsolete), dbs (obsolete),
|
||||
yada (obsolete), debhelper (still in use) and cdbs (still in use).
|
||||
|
||||
Despite these improvements, our state of the art packaging flow suffers
|
||||
from this awkward "assume-nothing-do-everything" design. There are many
|
||||
cases where dpkg has the only "official" tools to implement a feature
|
||||
(e.g. dpkg-gencontrol and dpkg-deb), but we still expect that the helper
|
||||
tools manage all orchestration of calling these tools in the right order.
|
||||
Furthermore, the "Makefile as an entry point" also neuters any efficient
|
||||
communication between dpkg tools and the underlying helper, as it
|
||||
introduces an impedance layer which forces us to reparse the same files
|
||||
multiple times, does not make it possible to guarantee a sanitized build
|
||||
environment for the packaging, complicates our ability to enable certain
|
||||
features transparently or (in debhelper's case) via compat bumps, and
|
||||
also forces us into imperative packaging flows (making it difficult for
|
||||
lintian to spot issues). As "recent" examples we can mention "build-arch"
|
||||
targets, updating XXFLAGS to include basic hardening, and the
|
||||
Rules-Requires-Root field.
|
||||
|
||||
All of these things complicate the lower packaging stack, inhibits our
|
||||
ability to deploy various performance optimizations and neuters our
|
||||
ability to make packaging simpler.
|
30
doc/spec/frontend-api.txt
Normal file
30
doc/spec/frontend-api.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
Frontend Interfaces
|
||||
===================
|
||||
|
||||
Status: recommendation, stable
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This file will try to document some of the interfaces that dpkg makes
|
||||
available to frontends or that expects them to use, which are currently
|
||||
not covered by any other type of documentation.
|
||||
|
||||
|
||||
Database Locking
|
||||
----------------
|
||||
|
||||
Any frontend needing to make sure no write operation is currently happening,
|
||||
and no other frontend is running should first acquire the frontend lock at
|
||||
«<admindir>/lock-frontend», and then acquire the dpkg database lock at
|
||||
«<admindir>/lock». When the frontend invokes dpkg, it should set the
|
||||
environment variable DPKG_FRONTEND_LOCKED (to prevent dpkg from acquiring
|
||||
the frontend lock), and then release the dpkg database lock, which will be
|
||||
acquired by dpkg itself. This way no other frontend following this protocol
|
||||
can race to perform operations while another one has one in progress.
|
||||
|
||||
These locks must be file record locks (i.e. fcntl(2) advisory locking), and
|
||||
the whole file should be locked, as that's the most portable way to perform
|
||||
this operation; this can be achieved by using start=0, len=0 and
|
||||
whence=SEEK_SET.
|
74
doc/spec/protected-field.txt
Normal file
74
doc/spec/protected-field.txt
Normal file
|
@ -0,0 +1,74 @@
|
|||
Support for a Protected field
|
||||
=============================
|
||||
|
||||
Status: draft, experimental
|
||||
URL: https://wiki.debian.org/Teams/Dpkg/Spec/ProtectedField
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
The goal of the following proposal is to standardize a field to split
|
||||
part of the «Essential» packages, and add support for it in the package
|
||||
management stack. There is currently an Important field, that has the
|
||||
correct semantics but has a very confusing name and is only supported
|
||||
by apt anyway, so this new field would phase out that one.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Our current use of «Essential: yes» is confused, and it includes several
|
||||
conflated things, some of which would be worth splitting up.
|
||||
|
||||
We use «Essential» to:
|
||||
|
||||
* Denote that a package must be always installed and cannot be
|
||||
removed (easily), because it is essential to the system in some way.
|
||||
* Denote that a package must be functional even when just unpacked
|
||||
(after having been configured once / fully bootstrapped).
|
||||
* Mark auto-vivification, by making front-ends either complain very
|
||||
loudly or reinstalling these packages when missing.
|
||||
* Minimize dependency loops, by making these dependencies implicit.
|
||||
|
||||
One problem is that the first point above includes being essential for
|
||||
the packaging system during upgrades/installation, for the operation
|
||||
of the system in general, and for the operation of the system during
|
||||
boot.
|
||||
|
||||
The latter is not always necessary though, for example within a chroot,
|
||||
or some types of containers. There has been work on trying to trim down
|
||||
the pseudo-essential set as can be seen from:
|
||||
|
||||
<https://wiki.debian.org/Proposals/EssentialOnDiet>
|
||||
<https://wiki.debian.org/BusterPriorityRequalification>
|
||||
|
||||
And several of these switches made use of a pre-existing field called
|
||||
«Important», defined and currently only supported by apt, which had the
|
||||
following properties:
|
||||
|
||||
* These packages are not required to be installed.
|
||||
* They do not have to be usable while unconfigured.
|
||||
* Dependencies need to be spelled out.
|
||||
|
||||
Proposal
|
||||
--------
|
||||
|
||||
The proposal would be to add support for a new Protected field, with the
|
||||
following properties:
|
||||
|
||||
* Protected packages should not be trivial to remove (require a force
|
||||
option for example, like «Essential»).
|
||||
* Protected packages should not be required to be installed (i.e. once
|
||||
removed they should not be automatically brought back by a front-end,
|
||||
unlike «Essential»).
|
||||
* Protected packages must be depended on explicitly (unlike «Essential»).
|
||||
* Protected packages must be functional even when unpacked (think of
|
||||
a boot loader or an init system; like «Essential»). [XXX: This one is
|
||||
not entirely clear and might not match reality anyway, for example kernels,
|
||||
which might require building an initramfs, etc.]
|
||||
|
||||
This would make it possible to phase out the current «Important» field
|
||||
usage (because it has a name too confusing relative to the «Priority»
|
||||
value; and has small tooling coverage) and the usage of «Essential» for
|
||||
at least packages involved in the boot process, and perhaps also for
|
||||
packages essential for operation of the system in general (in contrast
|
||||
to packages required for the packaging system).
|
179
doc/spec/rootless-builds.txt
Normal file
179
doc/spec/rootless-builds.txt
Normal file
|
@ -0,0 +1,179 @@
|
|||
Supporting rootless builds
|
||||
==========================
|
||||
|
||||
Status: recommendation, stable
|
||||
Version: 1.0
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Traditionally, Debian packages have required (fake)root privileges for some
|
||||
of the "debian/rules" targets. This has required also a split between build
|
||||
and binary targets; making the builds slower, due to the increased amount
|
||||
of invocations of "debian/rules" and the overhead of using fakeroot(1) or
|
||||
equivalent fake environments, or less secure due to the increased dangers
|
||||
of running under real root via sudo or equivalent.
|
||||
|
||||
On this document when talking about "(fake)root" privileges, it will refer
|
||||
to any mechanism, supported by the dpkg-buildpackage "-r/--root-command"
|
||||
option, that can provide either a real or faked root user environment.
|
||||
|
||||
Specification
|
||||
-------------
|
||||
|
||||
We add a new field to the "Source" stanza of debian/control:
|
||||
|
||||
Rules-Requires-Root: no | binary-targets | <implementations-keywords>
|
||||
|
||||
The case sensitive values are defined as:
|
||||
|
||||
* If "no", then "debian/rules binary" will not require root at all (not even
|
||||
fakeroot). This is the default in dpkg-build-api level >= 1, or since
|
||||
dpkg 1.22.13.
|
||||
- If the "no" keyword is used, it MUST be the only keyword in that field
|
||||
and MUST appear exactly once.
|
||||
|
||||
* If "binary-targets", then "debian/rules binary" (etc.) must always be run
|
||||
under (fake)root. This was the status quo, default in dpkg-build-api level 0
|
||||
until dpkg 1.22.13.
|
||||
|
||||
* <implementations-keywords> will be a space separated list of keywords which
|
||||
define when root is required.
|
||||
|
||||
- Keywords consists of <namespace>/<cases>. The "namespace" part cannot
|
||||
contain "/" or whitespace. The "cases" part cannot contain whitespace.
|
||||
Furthermore, both parts MUST consist entirely of printable ASCII
|
||||
characters.
|
||||
|
||||
- Each tool/package will define a namespace named after itself and provide
|
||||
a number of cases where (fake)root is required.
|
||||
(See also "Implementation provided keywords".)
|
||||
|
||||
- When "Rules-Requires-Root" is set to <implementations-keywords>, the
|
||||
builder (i.e. whatever is executing debian/rules) will expose an
|
||||
interface that is used to run a command under (fake)root via the
|
||||
"Gain Root API". If the builder cannot provide such a command, it
|
||||
MUST behave like "Rules-Requires-Root" was set to "binary-targets",
|
||||
i.e. run "debian/rules binary" under (fake)root.
|
||||
|
||||
When the builder supports this specification, it MUST notify this fact to
|
||||
the rules file via the "DEB_RULES_REQUIRES_ROOT" environment variable, with
|
||||
the value it has obtained from the Rules-Requires-Root field or some builder
|
||||
specific override mechanism, which will denote the level of support the
|
||||
builder has chosen to commit to take effect during the build. When set,
|
||||
it MUST be a valid value for the Rules-Requires-Root field. If unset,
|
||||
the build system SHOULD assume that the builder does not recognize the
|
||||
Rules-Requires-Root field at all.
|
||||
|
||||
It is always permissible for a builder to ignore this field and fall back to
|
||||
running the binary targets under (fake)root. This is to ensure backwards
|
||||
compatibility when builds are performed by legacy builders or older versions
|
||||
of the tooling.
|
||||
|
||||
Tools called from the rules file MUST cope gracefully with being called under
|
||||
(fake)root even when Rules-Requires-Root is set to a value that implies they
|
||||
should not be (e.g. "no"). However, they MUST NOT attempt to run processes
|
||||
under (fake)root when run as a regular user when Rules-Requires-Root does
|
||||
not list any keywords they respond to.
|
||||
|
||||
Tools MUST gracefully ignore valid unknown keywords outside their namespace.
|
||||
They MAY warn about unknown keywords inside their namespace.
|
||||
|
||||
The value of this field MUST NOT change the content of the package in any
|
||||
way. Notably, packages that are bit-for-bit reproducible MUST still provide
|
||||
bit-for-bit identical results even when the field is ignored.
|
||||
|
||||
Implementation provided keywords
|
||||
--------------------------------
|
||||
|
||||
Keywords provided by various implementations:
|
||||
|
||||
* dpkg/target-subcommand: When the package needs to run a given command
|
||||
under (fake)root within the "debian/rules" files directly, this MUST be
|
||||
declared via this keyword.
|
||||
|
||||
* dpkg/target/<target-name>: When a specific "debian/rules" unofficial
|
||||
target (none of the root-requiring "binary-indep", "binary-arch", "binary",
|
||||
"clean", nor the non-root-requiring "build-indep", "build-arch", "build")
|
||||
needs to be run under (fake)root, this MUST be declared via this dynamic
|
||||
keyword, where <target-name> is the name of the "debian/rules" target.
|
||||
|
||||
* debhelper/upstream-make-install: The dh_auto_install command will run
|
||||
the "install" target from the upstream's Makefile under (fake)root (for
|
||||
the "makefile" build system or one derived from it).
|
||||
|
||||
Gain Root API
|
||||
-------------
|
||||
|
||||
The builder will provide a command to promote a given command to (fake)root
|
||||
by exposing it in the environment variable "DEB_GAIN_ROOT_CMD". Tools that
|
||||
need this promotion will then use it like the following:
|
||||
|
||||
$DEB_GAIN_ROOT_CMD cmd-that-needs-root ...
|
||||
|
||||
This command is subject to the same requirements as the "gain-root-command"
|
||||
that dpkg-buildpackage accepts via its "-r/--root-command" option, which
|
||||
means that it can contain space-separated parameters. If dpkg-buildpackage is
|
||||
called with "-r/--root-command", then dpkg-buildpackage shall use that value
|
||||
as the value for "DEB_GAIN_ROOT_CMD". The command SHOULD preserve all the
|
||||
environment variables, unmodified.
|
||||
|
||||
The variable SHOULD only be provided when there is a need for it. Notably
|
||||
when "Rules-Requires-Root" is either "no" or "binary-targets" the variable
|
||||
SHOULD NOT be defined.
|
||||
|
||||
(The "DEB_GAIN_ROOT_CMD" variable used to be named "DPKG_GAIN_ROOT_CMD"
|
||||
starting with dpkg 1.19.0 and before dpkg 1.19.1 when this specification
|
||||
got released as stable. The old name MUST not be used.)
|
||||
|
||||
Common cases
|
||||
------------
|
||||
|
||||
* Upstream installation insists on "sudo make install"-like behavior.
|
||||
=> Use dpkg/target-subcommand or debhelper/upstream-make-install.
|
||||
|
||||
* Files shipped in the package must be owned by another user than root.
|
||||
=> Not covered; use "binary-targets" for now until dpkg+debhelper
|
||||
provides the required interface.
|
||||
|
||||
Prototyping/preparation
|
||||
=======================
|
||||
|
||||
dpkg side
|
||||
---------
|
||||
|
||||
dpkg-deb --build provides the --root-owner-group option so that dh_builddeb
|
||||
or direct calls can control the owner/group file values w/o requiring
|
||||
(fake)root.
|
||||
|
||||
dpkg-buildpackage must export DEB_GAIN_ROOT_CMD when necessary (for
|
||||
prototyping, doing this unconditionally would be fine).
|
||||
|
||||
|
||||
debhelper side
|
||||
--------------
|
||||
|
||||
When the field is present:
|
||||
|
||||
* dh_testroot will behave as usual when Rules-Requires-Root is not present
|
||||
or set to "binary-targets".
|
||||
|
||||
* dh_testroot will be a no-op when Rules-Requires-Root is set to "no".
|
||||
|
||||
* Otherwise, dh_testroot will either verify that it is run under (fake)root
|
||||
(as usual) OR assert that DEB_GAIN_ROOT_CMD is defined.
|
||||
|
||||
* debhelper build systems will be patched to check for the
|
||||
"debhelper/upstream-make-install" keyword and use the "Gain Root API"
|
||||
accordingly.
|
||||
|
||||
* All other (src:)debhelper commands will skip their calls to chown
|
||||
(currently they just reset them to "0:0" anyway).
|
||||
|
||||
With the above, a default "dh $@" will no longer require (fake)root when
|
||||
built (and Rules-Requires-Root is "no").
|
||||
|
||||
Prototyping:
|
||||
|
||||
* During prototyping, dh_builddeb can wrap the dpkg-deb --build call with
|
||||
fakeroot (when not already root).
|
818
doc/spec/triggers.txt
Normal file
818
doc/spec/triggers.txt
Normal file
|
@ -0,0 +1,818 @@
|
|||
Triggers
|
||||
========
|
||||
|
||||
Status: recommendation, stable
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
A dpkg trigger is a facility that allows events caused by one package
|
||||
but of interest to another package to be recorded and aggregated, and
|
||||
processed later by the interested package. This feature simplifies
|
||||
various registration and system-update tasks and reduces duplication
|
||||
of processing.
|
||||
|
||||
(NB: Triggers are intended for events that occur during package
|
||||
installation, not events that occur in general operation.)
|
||||
|
||||
|
||||
Concepts
|
||||
--------
|
||||
|
||||
Each trigger is named, and at any time zero or more packages may be
|
||||
interested in it.
|
||||
|
||||
We currently envisage three kinds of triggers:
|
||||
* Explicit triggers. These can be activated by any program
|
||||
by running dpkg-trigger (at any time, but ideally from a maintainer
|
||||
script).
|
||||
* File triggers. These are activated automatically by dpkg
|
||||
when a matching file is installed, upgraded or removed as part
|
||||
of a package. They may also be explicitly activated by running
|
||||
dpkg-trigger.
|
||||
* Future kinds of special triggers, which are activated by magic code
|
||||
in dpkg itself. Currently none are defined besides file triggers.
|
||||
|
||||
A trigger is always activated by a particular package.
|
||||
|
||||
Trigger names contain only printing 7-bit ASCII characters (no
|
||||
whitespace). Each trigger kind has a distinct subset of the trigger
|
||||
name space so that the kind can be determined from the name. After we
|
||||
run out of straightforward syntaxes, we will use <kind>:<details>.
|
||||
|
||||
When a trigger is activated, it becomes pending for every package
|
||||
which is interested in the trigger at that time. Each package has a
|
||||
list of zero or more pending triggers. Repeated activation of the
|
||||
same trigger has no additional effect. Note that in general a trigger
|
||||
will not be processed immediately when it is activated; processing is
|
||||
deferred until it is convenient (as described below).
|
||||
|
||||
At a trigger activation, the interested packages(s) are added to the
|
||||
triggering package's list of triggers-awaited packages (unless the
|
||||
trigger has been configured to not require it); the triggering
|
||||
package is said to await the trigger processing.
|
||||
|
||||
A package which has pending triggers, or which awaits triggers, is not
|
||||
considered properly installed. There are two new dpkg status values,
|
||||
‘triggers-pending’ and ‘triggers-awaited’, which lie between
|
||||
‘config-failed’ and ‘installed’.
|
||||
|
||||
|
||||
Details - Overview table
|
||||
------------------------
|
||||
|
||||
Status Pending Awaited Satisfies Remedy
|
||||
triggers triggers Depends
|
||||
|
||||
unpacked never maybe No postinst configure
|
||||
c.-failed never maybe No postinst configure (when requested)
|
||||
t.-awaited yes always No postinst triggered + fix awaited pkg(s)
|
||||
t.-awaited no always No fix awaited package(s)
|
||||
t.-pending always never Yes postinst triggered
|
||||
installed never never Yes n/a
|
||||
|
||||
Packages in t-awaited and t-pending demand satisfaction of their
|
||||
dependencies just like packages in installed.
|
||||
|
||||
|
||||
Details - triggering package
|
||||
----------------------------
|
||||
|
||||
When a package <T> activates a trigger in which a package <I> is
|
||||
interested, <I> is added to the list of packages whose trigger
|
||||
processing is awaited by <T>. Zero or more packages <I> may be added as a
|
||||
result of any particular trigger activation, depending on how many
|
||||
packages were interested. (If <T> chooses, explicit trigger activation
|
||||
using dpkg-trigger of <I> by <T> need not make <T> become triggers-awaited
|
||||
in this way.)
|
||||
|
||||
A package which awaits trigger processing but would otherwise be
|
||||
‘installed’ or ‘triggers-pending’ is considered to be in state
|
||||
‘triggers-awaited’. Packages in ‘triggers-awaited’ do not satisfy
|
||||
Depends dependencies.
|
||||
|
||||
Every triggered package <I> in <T>'s list of awaited packages either has a
|
||||
nonempty list of pending triggers, or is in ‘config-failed’ or worse.
|
||||
When <I> enters ‘installed’ (or ‘config-files’ or ‘not-installed’), the
|
||||
entry in <T>'s list of awaited packages is removed so that <T> may, if it
|
||||
no longer awaits any packages, become ‘installed’ or ‘triggers-pending’.
|
||||
|
||||
Packages in ‘config-files’ or ‘not-installed’ do not await triggers.
|
||||
|
||||
|
||||
Details - triggered package
|
||||
---------------------------
|
||||
|
||||
When one of the triggers in which a package is interested is
|
||||
activated, the triggered package has the trigger added to its list of
|
||||
pending triggers. Packages with a nonempty list of pending triggers
|
||||
which would otherwise be in state ‘installed’ are in state
|
||||
‘triggers-pending’ instead, so if the package was previously
|
||||
‘installed’ it becomes ‘triggers-pending’.
|
||||
|
||||
If a package has nonempty lists both of pending and awaited triggers,
|
||||
then it is in ‘triggers-awaited’. Nevertheless efforts will still be
|
||||
made to process its triggers so as to make the list of pending
|
||||
triggers empty.
|
||||
|
||||
To restore a package in state ‘triggers-pending’ to ‘installed’, or to
|
||||
process pending triggers of a package with both pending and awaited
|
||||
triggers, dpkg will run the postinst script as:
|
||||
|
||||
postinst triggered "<trigger-name> <trigger-name> ..."
|
||||
|
||||
by passing a space-separated list of <trigger-name>s as the second argument.
|
||||
|
||||
This will be attempted for each relevant package at the end of each
|
||||
dpkg run; so, normally, in the same dpkg run as the event which made
|
||||
the package go to ‘triggers-pending’. This leaves packages in
|
||||
reasonable states by default.
|
||||
|
||||
If the “postinst triggered” run fails the package goes to
|
||||
‘config-failed’, so that the trigger processing will not be attempted
|
||||
again until explicitly requested.
|
||||
|
||||
|
||||
│
|
||||
v
|
||||
┌────────────┐
|
||||
│ unpacked │
|
||||
└─────┬──────┘
|
||||
│
|
||||
│
|
||||
(automatic)│ ┌───────────────┐
|
||||
│ │ config-failed │
|
||||
│ └─────┬─────────┘
|
||||
│ │ ^
|
||||
│ │ │
|
||||
├──────<─────┘ │ ┌──────────────────────────────────┐
|
||||
│ (user request) │ │ triggers-pending │
|
||||
postinst │ │ │ or │
|
||||
"configure" │ │ │ triggers-awaited w/ some pending │
|
||||
│ │ └────────────┬─────────────────────┘
|
||||
│ │ │ ^
|
||||
├────────>───────┤ postinst │ │
|
||||
│ error │ "triggered" │ │
|
||||
│ │ (automatic) │ │
|
||||
│ │ │ │ trigger(s)
|
||||
│ │ │ │ activated
|
||||
│ └────────<─────────┤ │
|
||||
│ error │ │
|
||||
│ │ │
|
||||
v v │
|
||||
┌──────────────────────────────────────────────┴────┐
|
||||
│ installed or triggers-awaited w/ none pending │
|
||||
└───────────────────────────────────────────────────┘
|
||||
|
||||
Packages in ‘config-failed’ or worse are never considered to have
|
||||
lists of pending triggers. A package whose postinst is being run
|
||||
can however acquire pending triggers during that run (ie, a package
|
||||
can trigger itself).
|
||||
|
||||
This means that if a triggering package <T> awaits trigger processing by
|
||||
an interested package <I>, and <I> goes to ‘config-failed’ or worse (eg,
|
||||
during unpack for upgrade), then when <I> is reconfigured (goes to
|
||||
‘installed’) or removed, <T> will no longer await processing by <I>, so
|
||||
that <T> may automatically go from ‘triggers-awaited’ to ‘installed’.
|
||||
|
||||
Or to put it another way, triggered actions are considered irrelevant
|
||||
if the interested package <I> is not configured. When <I>'s postinst is
|
||||
called with ‘configure’, it must do whatever actions are necessary to
|
||||
deal with any trigger activations which might have occurred while it
|
||||
was not configured, just as if the package was being configured for
|
||||
the first time.
|
||||
|
||||
Trigger processing should be idempotent. The list of triggers being
|
||||
processed is provided to the postinst only so that it can optimize
|
||||
away redundant processing.
|
||||
|
||||
In that case, where an interested package has more than one trigger
|
||||
and wants to process them differently, the list of triggers can
|
||||
be examined in a shell script like this:
|
||||
case " $2 " in
|
||||
*" trigger-name-a "*) process-trigger-a ;;
|
||||
esac
|
||||
Generally each trigger name should be tested for separately, as the
|
||||
postinst will often be called for several triggers at once.
|
||||
|
||||
Note that if a package both activates triggers in other packages, and
|
||||
is interested in triggers of its own, its postinst may run for trigger
|
||||
processing before the postinst(s) of the package(s) it has triggered.
|
||||
|
||||
|
||||
Timing guarantees, races, etc.
|
||||
------------------------------
|
||||
|
||||
Activating a trigger will not have any immediate effect, although
|
||||
putative resulting status changes will show up in dpkg --status etc.
|
||||
(Putative because the actual status changes may depend on the state of
|
||||
trigger interests when dpkg processes the trigger activation into
|
||||
the status database, rather than that when dpkg --status is run.)
|
||||
|
||||
A package is only guaranteed to become notified of a trigger
|
||||
activation if it is continuously interested in the trigger, and never
|
||||
in ‘config-failed’ or worse, during the period from when the trigger
|
||||
is activated until dpkg runs the package postinst (either due to
|
||||
--configure --pending, or at the end of the relevant run, as described
|
||||
above). Subsequent to activation and before notification, the
|
||||
interested package will not be considered in state ‘installed’, so
|
||||
long as the package remains interested, and the triggering package
|
||||
will not be considered ‘installed’.
|
||||
|
||||
If the package is not in state ‘installed’, ‘triggers-pending’ or
|
||||
‘triggers-awaited’ then pending triggers are not accumulated.
|
||||
However, if such a package (between ‘half-installed’ and
|
||||
‘config-failed’ inclusive) declares some trigger interests then the
|
||||
triggering packages *will* await their configuration (which implies
|
||||
completion of any necessary trigger processing) or removal.
|
||||
|
||||
It is not defined in what order triggers will run. dpkg will make
|
||||
some effort to minimize redundant work in the case where many packages
|
||||
have postinst trigger processing activating another package's triggers
|
||||
(for example, by processing triggers in fifo order during a single
|
||||
dpkg run). Cycles in the triggering graph are prohibited and will
|
||||
eventually, perhaps after some looping, be detected by dpkg and cause
|
||||
trigger processing to fail; when this happens one of the packages
|
||||
involved will be put in state ‘config-failed’ so that the trigger loop
|
||||
will not be reattempted. See “Cycle detection” below.
|
||||
|
||||
|
||||
Explicit triggers
|
||||
-----------------
|
||||
|
||||
Explicit triggers have names with the same syntax as package names,
|
||||
*but* should *not* normally be named identically to a package.
|
||||
|
||||
When choosing an explicit trigger name it is usually good to include a
|
||||
relevant package name or some other useful identifier to help make the
|
||||
trigger name unique. On the other hand, explicit triggers should
|
||||
generally not be renamed just because the interested or triggering
|
||||
packages' names change.
|
||||
|
||||
Explicit trigger names form part of the interface between packages.
|
||||
Therefore in case of wider use of any trigger the name and purpose
|
||||
should be discussed in the usual way and documented in the appropriate
|
||||
packaging guidelines (eg, in the distribution policy).
|
||||
|
||||
|
||||
File triggers
|
||||
-------------
|
||||
|
||||
File triggers have names of the form
|
||||
/path/to/directory/or/file
|
||||
and are activated when the specified filesystem object, or any object
|
||||
under the specified subdirectory, is created, updated or deleted by
|
||||
dpkg during package unpack or removal. The pathname must be absolute.
|
||||
|
||||
File triggers should not generally be used without mutual consent.
|
||||
The use of a file trigger, and the name of the trigger used, should be
|
||||
stated in the distribution policy, so that a package which creates a
|
||||
relevant file in a maintainer script can activate the trigger explicitly.
|
||||
|
||||
File triggers must definitely not be used as an escalation tool in
|
||||
disagreements between different packages as to the desired contents of
|
||||
the filesystem. Trigger activation due to a particular file should
|
||||
not generally modify that file again.
|
||||
|
||||
Configuration files (whether dpkg-handled conffiles or not), or any
|
||||
other files which are modified at times other than package management,
|
||||
should not rely on file triggers detecting all modifications; dpkg
|
||||
triggers are not a general mechanism for filesystem monitoring.
|
||||
|
||||
If there are or might be directory symlinks which result in packages
|
||||
referring to files by different names, then to be sure of activation
|
||||
all of the paths which might be included in packages should be listed.
|
||||
The path specified by the interested package is matched against the
|
||||
path included in the triggering package, not against the truename of
|
||||
the file as installed. Only textually identical filenames (or
|
||||
filenames where the interest is a directory prefix of the installed
|
||||
file) are guaranteed to match.
|
||||
|
||||
A file trigger is guaranteed to be activated before the file in
|
||||
question is modified by dpkg; on the other hand, a file trigger might
|
||||
be activated even though no file was actually modified. Changes made
|
||||
by dpkg to the link count of a file, or to solely the inode number
|
||||
(ie, if dpkg atomically replaces it with another identical file), are
|
||||
not guaranteed to cause trigger activation.
|
||||
|
||||
Because of the restriction on trigger names, it is not possible to
|
||||
declare a file trigger for a directory whose name contains whitespace,
|
||||
i18n characters, etc. Such a trigger should not be necessary.
|
||||
|
||||
|
||||
Package declarations regarding triggers
|
||||
---------------------------------------
|
||||
|
||||
See deb-triggers(5).
|
||||
|
||||
Support future extension of the trigger name syntax with additional
|
||||
dpkg-generated triggers is as follows: a package which is interested
|
||||
in any unsupported trigger kinds cannot be configured (since such a
|
||||
package cannot be guaranteed to have these triggers properly activated
|
||||
by dpkg). Therefore no package can be interested in any unsupported
|
||||
trigger kinds and they can be freely activated (both by ‘activate’ and
|
||||
by dpkg-trigger). dpkg-deb will be changed to warn about unrecognized
|
||||
trigger names syntaxes and unrecognized trigger control directives.
|
||||
|
||||
|
||||
New command line interfaces to dpkg tools
|
||||
-----------------------------------------
|
||||
|
||||
See dpkg(1).
|
||||
|
||||
Here is a summary of the behaviors:
|
||||
|
||||
Command line Trigproc Trigproc Configure
|
||||
these any triggered
|
||||
----------------------+---------------+---------------+-----------------
|
||||
--unpack no usually[1] none
|
||||
--remove n/a usually[1] none
|
||||
--install n/a usually[1] these
|
||||
--configure -a any needed usually[1] any needed
|
||||
--configure <some> if needed usually[1] must, or trigproc
|
||||
--triggers-only -a any needed usually[1] none
|
||||
--triggers-only <some> must usually not[1] none
|
||||
|
||||
[1] can be specified explicitly by --triggers or --no-triggers
|
||||
|
||||
|
||||
See dpkg-trigger(1).
|
||||
|
||||
A trigger may be activated explicitly with:
|
||||
dpkg-trigger [--by-package <package>] <name-of-trigger>
|
||||
dpkg-trigger --no-await <name-of-trigger>
|
||||
|
||||
There will be no output to stdout, and none to stderr unless
|
||||
dpkg-trigger is unable to make a record of the trigger activation.
|
||||
|
||||
NB that in the case of a file trigger the name of the trigger is
|
||||
needed, not the name of a file which would match the trigger.
|
||||
|
||||
|
||||
apt and aptitude
|
||||
----------------
|
||||
|
||||
These must be taught about the new ‘triggers-awaited’ and
|
||||
‘triggers-pending’ states. Packages in these states should be treated
|
||||
roughly like those in ‘unpacked’: the remedy is to run dpkg
|
||||
--configure.
|
||||
|
||||
Normally apt and aptitude will not see packages in ‘triggers-pending’
|
||||
since dpkg will generally attempt to run the triggers thus leaving the
|
||||
package in ‘config-failed’ or ‘installed’.
|
||||
|
||||
Note that automatic package management tools which call dpkg (like apt
|
||||
and aptitude) should not attempt to configure individual packages in
|
||||
state ‘triggers-pending’ (or indeed ‘triggers-awaited’) with dpkg
|
||||
--triggers-only <package>... or dpkg --no-triggers --configure <package>...,
|
||||
or similar approaches. This might defeat dpkg's trigger cycle detection.
|
||||
|
||||
A package management tool which will run dpkg --configure --pending at
|
||||
the end may use --no-triggers on its other dpkg runs. This would be
|
||||
more efficient as it allows more aggressive deferral (and hence more
|
||||
unification) of trigger processing.
|
||||
|
||||
|
||||
Error handling
|
||||
--------------
|
||||
|
||||
Packages should be written so that they DO NOT BREAK just because
|
||||
their pending triggers have not yet been run. It is allowed for the
|
||||
functionality relating to the unprocessed trigger to fail (ie, the
|
||||
package which is awaiting the trigger processing may be broken), but
|
||||
the remainder of the interested package must work normally.
|
||||
|
||||
For example, a package which uses file triggers to register addons
|
||||
must cope with (a) an addon being dropped into the filesystem but not
|
||||
yet registered and (b) an addon being removed but not yet
|
||||
deregistered. In both of these cases the package's main functionality
|
||||
must continue to work normally; failure of the addon in question is
|
||||
expected, warning messages are tolerable, but complete failure of the
|
||||
whole package, or failures of other addons, are not acceptable.
|
||||
|
||||
dpkg cannot ensure that triggers are run in a timely enough manner for
|
||||
pathological error behaviors to be tolerable.
|
||||
|
||||
|
||||
Where a trigger script finds bad data provided by a triggering
|
||||
package, it should generally report to stderr the problem with the bad
|
||||
data and exit nonzero, leaving the interested package in config-failed
|
||||
and the triggering package in triggers-awaited and thus signalling the
|
||||
problem to the user.
|
||||
|
||||
Alternatively, in some situations it may be more desirable to allow
|
||||
the interested package to be configured even though it can only
|
||||
provide partial service. In this case clear information will have to
|
||||
be given in appropriate places about the missing functionality, and a
|
||||
record should be made of the cause of the errors. This option is
|
||||
recommended for situations where the coupling between the interested
|
||||
and triggering package is particularly loose; an example of such a
|
||||
loose coupling would be Python modules.
|
||||
|
||||
|
||||
|
||||
WORKED EXAMPLE - SCROLLKEEPER
|
||||
=============================
|
||||
|
||||
Currently, every Gnome program which comes with some help installs the
|
||||
help files in /usr/share/gnome/help and then in the postinst runs
|
||||
scrollkeeper-update. scrollkeeper-update reads, parses and rewrites
|
||||
some large xml files in /var/lib/scrollkeeper; currently this
|
||||
occurs at every relevant package installation, upgrade or removal.
|
||||
|
||||
When triggers are available, this will work as follows:
|
||||
|
||||
* gnome-foobar will ship its «omf» file in /usr/share/omf as
|
||||
normal, but will not contain any special machinery to invoke
|
||||
scrollkeeper.
|
||||
|
||||
* scrollkeeper will in its triggers control file say:
|
||||
interest /usr/share/omf
|
||||
and in its postinst say:
|
||||
scrollkeeper-update-now -q
|
||||
|
||||
dpkg will arrange that this is run once at the end of each run
|
||||
where any documentation was updated.
|
||||
|
||||
Note that it is not necessary to execute this only on particular
|
||||
postinst "$1" values; however, at the time of writing, scrollkeeper
|
||||
does this:
|
||||
|
||||
if [ "$1" = "configure" ]; then
|
||||
printf "Rebuilding the database. This may take some time.\n"
|
||||
scrollkeeper-rebuilddb -q
|
||||
fi
|
||||
|
||||
and to retain this behavior, something along the following lines
|
||||
would be sensible:
|
||||
|
||||
if [ "$1" = "configure" ]; then
|
||||
printf "Rebuilding the database. This may take some time.\n"
|
||||
scrollkeeper-rebuilddb -q
|
||||
else
|
||||
printf "Updating GNOME help database.\n"
|
||||
scrollkeeper-update-now -q
|
||||
fi
|
||||
|
||||
* dh_scrollkeeper will only adjust the DTD declarations and no longer
|
||||
edit maintainer scripts.
|
||||
|
||||
|
||||
Full implementation of the transition plan defined below, for
|
||||
scrollkeeper, goes like this:
|
||||
|
||||
1. Update scrollkeeper:
|
||||
- Add a ‘triggers’ control archive file containing
|
||||
interest /usr/share/omf
|
||||
- Make the postinst modifications as described above.
|
||||
- Rename scrollkeeper-update to scrollkeeper-update-now
|
||||
- Provide a new wrapper script as scrollkeeper-update:
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if type dpkg-trigger >/dev/null 2>&1 && \
|
||||
dpkg-trigger /usr/share/omf; then
|
||||
exit 0
|
||||
fi
|
||||
exec scrollkeeper-update-now "$@"
|
||||
|
||||
2. In gnome-policy chapter 2, “Use of scrollkeeper”,
|
||||
- delete the requirement that the package must depend on
|
||||
scrollkeeper
|
||||
- delete the requirement that the package must invoke
|
||||
scrollkeeper in the postinst and postrm
|
||||
- instead say:
|
||||
|
||||
OMF files should be installed under /usr/share/omf in the
|
||||
usual way. A dpkg trigger is used to arrange to update the
|
||||
scrollkeeper documentation index automatically and no special
|
||||
care need be taken in packages which supply OMFs.
|
||||
|
||||
If an OMF file is placed, modified or removed other than as
|
||||
a file installed in the ordinary way by dpkg, the dpkg file
|
||||
trigger «/usr/share/omf» should be activated; see the dpkg
|
||||
triggers specification for details.
|
||||
|
||||
Existing packages which Depend on scrollkeeper (>= 3.8)
|
||||
because of dh_scrollkeeper or explicit calls to
|
||||
scrollkeeper-update should be modified not to Depend on
|
||||
scrollkeeper.
|
||||
|
||||
3. Update debhelper's dh_scrollkeeper not to edit maintainer
|
||||
scripts. One of dh_scrollkeeper or lintian should be changed to
|
||||
issue a warning for packages with scrollkeeper (>= 3.8) in the
|
||||
Depends control file line.
|
||||
|
||||
4. Remove the spurious dependencies on scrollkeeper, at our leisure.
|
||||
As a bonus, after this is complete it will be possible to remove
|
||||
scrollkeeper while keeping all of the documentation-supplying
|
||||
gnome packages installed.
|
||||
|
||||
5. If there are any packages which do by hand what dh_scrollkeeper
|
||||
does, change them not to call scrollkeeper-update and drop
|
||||
their dependency on scrollkeeper.
|
||||
|
||||
This is not 100% in keeping with the full transition plan defined
|
||||
below: if a new gnome package is used with an old scrollkeeper, there
|
||||
is some possibility that the help will not properly be available.
|
||||
|
||||
Unfortunately, dh_scrollkeeper doesn't generate the scrollkeeper
|
||||
dependency in the control file, which makes it excessively hard to get
|
||||
the dependency up to date. The bad consequences of the inaccurate
|
||||
dependencies are less severe than the contortions which would be
|
||||
required to deal with the problem.
|
||||
|
||||
|
||||
TRANSITION PLAN
|
||||
===============
|
||||
|
||||
|
||||
Old dpkg to new dpkg
|
||||
--------------------
|
||||
|
||||
The first time a trigger-supporting dpkg is run on any system, it will
|
||||
activate all triggers in which anyone is interested, immediately.
|
||||
|
||||
These trigger activations will not be processed in the same dpkg run,
|
||||
to avoid unexpectedly processing triggers while attempting an
|
||||
unrelated operation. dpkg --configure --pending (and not other dpkg
|
||||
operations) will run the triggers, and the dpkg postinst will warn the
|
||||
user about the need to run it (if this deferred triggers condition
|
||||
exists). (Any triggers activated or reactivated *after* this
|
||||
mass-activation will be processed in the normal way.)
|
||||
|
||||
To use this correctly:
|
||||
* Packages which are interested in triggers, or which want to
|
||||
explicitly activate triggers, should Depend on the
|
||||
triggers-supporting version of dpkg.
|
||||
* Update instructions and tools should arrange to run
|
||||
dpkg --configure --pending
|
||||
after the install; this will process the pending triggers.
|
||||
|
||||
dpkg's prerm will check for attempts to downgrade while triggers are
|
||||
pending and refuse. (Since the new dpkg would be installed but then
|
||||
refuse to read the status file.) In case this is necessary a separate
|
||||
tool will be provided which will:
|
||||
* Put all packages with any pending triggers into state
|
||||
‘config-failed’ and remove the list of pending triggers.
|
||||
* Remove the list of awaited triggers from every package. This
|
||||
may cause packages to go from ‘triggers-awaited’ to ‘installed’
|
||||
which is not 100% accurate but the best that can be done.
|
||||
* Remove /var/lib/dpkg/triggers (to put the situation to that which
|
||||
we would have seen if the trigger-supporting dpkg had never been
|
||||
installed).
|
||||
|
||||
|
||||
Higher-level programs
|
||||
---------------------
|
||||
|
||||
The new dpkg will declare versioned Conflicts against apt and aptitude
|
||||
and other critical package management tools which will be broken by
|
||||
the new Status field values. Therefore, the new higher-level tools
|
||||
will have to be deployed first.
|
||||
|
||||
The new dpkg will declare versioned Breaks against any known
|
||||
noncritical package management tools which will be broken by the new
|
||||
Status field value.
|
||||
|
||||
|
||||
Transition hints for existing packages
|
||||
--------------------------------------
|
||||
|
||||
When a central (consumer) package defines a directory where other leaf
|
||||
(producer) packages may place files and/or directories, and currently
|
||||
the producer packages are required to run an «update-consumer» script
|
||||
in their postinst:
|
||||
1. In the relevant policy, define a trigger name which is the name of
|
||||
the directory where the individual files are placed by producer
|
||||
packages.
|
||||
2. Update the consumer package:
|
||||
* Declare an interest in the trigger.
|
||||
* Edit «update-consumer» so that if it is called without --real
|
||||
it does the following:
|
||||
if type dpkg-trigger >/dev/null 2>&1 && \
|
||||
dpkg-trigger name-of-trigger; then
|
||||
exit 0
|
||||
fi
|
||||
If this fails to cause «update-consumer» to exit, it should do
|
||||
its normal update processing. Alternatively, if it is more
|
||||
convenient, «update-consumer» could be renamed and supplanted with
|
||||
a wrapper script which conditionally runs the real
|
||||
«update-consumer».
|
||||
* In the postinst, arrange for the new ‘triggered’ invocation to
|
||||
run «update-consumer --real». The consumer package's postinst
|
||||
will already run «update-consumer» during configuration, and this
|
||||
should be retained and supplemented with the --real option (or
|
||||
changed to call the real script rather than the wrapper).
|
||||
3. Update the producer packages:
|
||||
* In the postinst, remove the call to «update-consumer».
|
||||
* Change the dependency on consumer to be versioned, specifying a
|
||||
trigger-interested consumer.
|
||||
This can be done at our leisure. Ideally for loosely coupled
|
||||
packages this would be done only in the release after the one
|
||||
containing the triggers-interested consumer, to facilitate partial
|
||||
upgrades and backports.
|
||||
4. After all producer packages have been updated according to step 3,
|
||||
«update-consumer» has become an interface internal to the consumer
|
||||
and need no longer be kept stable. If un-updated producers are
|
||||
still of interest, incompatible changes to «update-consumer» imply
|
||||
a versioned Breaks against the old producers.
|
||||
(See also “Transition plan”, below.)
|
||||
|
||||
If there are several consumer packages all of which are interested in
|
||||
the features provided by producer packages, the current arrangements
|
||||
usually involve an additional central switchboard package (eg,
|
||||
emacsen-common). In this case:
|
||||
|
||||
-- NOTE - this part of the transition plan is still a proof of
|
||||
concept and we might yet improve on it
|
||||
|
||||
1. Define the trigger name.
|
||||
2. Update the switchboard to have any new functionality needed by the
|
||||
consumers in step 3 (2nd bullet).
|
||||
3. Update the consumer packages:
|
||||
* Declare an interest in the trigger.
|
||||
* In the postinst, arrange for the new ‘trigger’ invocation to run
|
||||
the compilation/registration process. This may involve scanning
|
||||
for new or removed producers, and may involve new common
|
||||
functionality from the switchboard (in which case a versioned
|
||||
Depends is needed).
|
||||
* The old interface allowing the switchboard to run
|
||||
compilation/registration should be preserved, including
|
||||
calls to the switchboard to register this consumer.
|
||||
4. When all consumers have been updated, update the switchboard:
|
||||
* Make the registration scripts called by producers try to
|
||||
activate the trigger and if that succeeds quit without
|
||||
doing any work (as for bullet 2 in the simple case above).
|
||||
* Versioned Breaks, against the old (pre-step-3) consumers.
|
||||
5. After the switchboard has been updated, producers can be updated:
|
||||
* Remove the calls to the switchboard registration/compilation
|
||||
functions.
|
||||
* Change the dependency on the switchboard to a versioned one,
|
||||
specifying the one which Breaks old consumers. Alternatively,
|
||||
it may be the case that the switchboard is no longer needed (or
|
||||
not needed for this producer), in which case the dependency on
|
||||
the switchboard can be removed in favour of an appropriate
|
||||
versioned Breaks (probably, identical to that in the new
|
||||
switchboard).
|
||||
6. After all the producers have been updated, the cruft in the
|
||||
consumers can go away:
|
||||
* Remove the calls to the switchboard's registration system.
|
||||
* Versioned Breaks against old switchboards, or versioned Depends
|
||||
on new switchboards, depending on whether the switchboard is
|
||||
still needed for other common functionality.
|
||||
7. After all of the producers and consumers have been updated, the
|
||||
cruft in the switchboard can go away:
|
||||
* Remove the switchboard's registration system (but not obviously
|
||||
the common functionality from step 3, discussed above).
|
||||
* Versioned Breaks against pre-step-6 consumers and pre-step-5
|
||||
producers.
|
||||
|
||||
|
||||
DISCUSSION
|
||||
==========
|
||||
|
||||
The activation of a trigger does not record details of the activating
|
||||
event. For example, file triggers do not inform the package of the
|
||||
filename. In the future this might be added as an additional feature,
|
||||
but there are some problems with this.
|
||||
|
||||
|
||||
Broken producer packages, and error reporting
|
||||
---------------------------------------------
|
||||
|
||||
Often trigger processing will involve a central package registering,
|
||||
compiling or generally parsing some data provided by a leaf package.
|
||||
|
||||
If the central package finds problems with the leaf package data it is
|
||||
usually more correct for only the individual leaf package to be
|
||||
recorded as not properly installed. There is not currently any way to
|
||||
do this and there are no plans to provide one.
|
||||
|
||||
The naive approach of giving the postinst a list of the triggering
|
||||
packages does not work because this information is not recorded in the
|
||||
right way (it might suffer from lacunae); enhancing the bookkeeping
|
||||
for this to work would be possible but it is far better simply to make
|
||||
the system more idempotent. See above for the recommended approach.
|
||||
|
||||
|
||||
|
||||
|
||||
INTERNALS
|
||||
=========
|
||||
|
||||
On-disk state
|
||||
-------------
|
||||
|
||||
A single file /var/lib/dpkg/triggers/File lists all of the filename
|
||||
trigger interests in the form
|
||||
/path/to/directory/or/file package
|
||||
|
||||
For each explicit trigger in which any package is interested,
|
||||
a file /var/lib/dpkg/triggers/<name-of-trigger> is a list of
|
||||
the interested packages, one per line.
|
||||
|
||||
These interest files are not updated to remove a package just because
|
||||
a state change causes it not to be interested in any triggers any more
|
||||
- they are updated when we remove or unpack.
|
||||
|
||||
For each package which has pending triggers, the status file contains
|
||||
a Triggers-Pending field which contains the space-separated names of
|
||||
the pending triggers. For each package which awaits triggers the
|
||||
status file contains a Triggers-Awaited field which contains the
|
||||
*package* names of the packages whose trigger processing is awaited.
|
||||
See “Details - Overview table” above for the invariants which relate
|
||||
Triggers-Pending, Triggers-Awaited, and Status.
|
||||
|
||||
During dpkg's execution, /var/lib/dpkg/triggers/Unincorp is a list of
|
||||
the triggers which have been requested by dpkg-trigger but not yet
|
||||
incorporated in the status file. Each line is a trigger name followed
|
||||
by one or more triggering package names. The triggering package name
|
||||
"-" is used to indicate one or more package(s) which did not need to
|
||||
await the trigger.
|
||||
|
||||
/var/lib/dpkg/triggers/Lock is the fcntl lockfile for the trigger
|
||||
system. Processes hang onto this lock only briefly: dpkg-trigger
|
||||
to add new activations, or dpkg to incorporate activations (and
|
||||
perhaps when it updates interests). Therefore this lock is always
|
||||
acquired with F_GETLKW so as to serialize rather than fail on
|
||||
contention.
|
||||
|
||||
|
||||
Processing
|
||||
----------
|
||||
|
||||
dpkg-trigger updates triggers/Unincorp, and does not read or write the
|
||||
status file or take out the dpkg status lock. dpkg (and dpkg-query)
|
||||
reads triggers/Unincorp after reading /var/lib/dpkg/status, and after
|
||||
running a maintainer script. If the status database is opened for
|
||||
writing then the data from Unincorp is moved to updates as
|
||||
Triggers-Pending and Triggers-Awaited entries and corresponding Status
|
||||
changes.
|
||||
|
||||
This means that dpkg is guaranteed to reincorporate pending trigger
|
||||
information into the status file only 1. when a maintainer script has
|
||||
finished, or 2. when dpkg starts up with a view to performing some
|
||||
operation.
|
||||
|
||||
When a package is unpacked or removed, its triggers control file will
|
||||
be parsed and /var/lib/dpkg/triggers/* updated accordingly.
|
||||
|
||||
Triggers are run as part of configuration. dpkg will try to first
|
||||
configure all packages which do not depend on packages which are
|
||||
awaiting triggers, and then run triggers one package at a time in the
|
||||
hope of making useful progress. (This will involve a new ‘dependtry’
|
||||
level in configure.c's algorithm.) The only constraint on the
|
||||
ordering of postinsts is only the normal Depends constraint, so the
|
||||
usual Depends cycle breaking will function properly. See “Cycle
|
||||
detection” below regarding cycles in the “A triggers B” relation.
|
||||
|
||||
|
||||
Processing - Transitional
|
||||
-------------------------
|
||||
|
||||
The case where a triggers-supporting dpkg is run for the first time is
|
||||
detected by the absence of /var/lib/dpkg/triggers/Unincorp. When the
|
||||
triggers-supporting dpkg starts up without this it will set each
|
||||
package's list of pending triggers equal to its interests (obviously
|
||||
only for packages which are in ‘installed’ or ‘triggers-pending’).
|
||||
This may result in a package going from ‘installed’ to
|
||||
‘triggers-pending’ but it will not create the directory at this time.
|
||||
Packages marked as triggers-pending in this way will not be scheduled
|
||||
for trigger processing in this dpkg run.
|
||||
|
||||
dpkg will also at this time create /var/lib/dpkg/triggers if
|
||||
necessary, triggers/File, triggers/Unincorp, and the per-trigger
|
||||
package lists in /var/lib/dpkg/triggers/<trigger-name>, so that future
|
||||
trigger activations will be processed properly.
|
||||
|
||||
Only dpkg may create /var/lib/dpkg/triggers and only when it is
|
||||
holding the overall dpkg status lock.
|
||||
|
||||
dpkg and/or dpkg-deb will be made to reject packages containing
|
||||
Triggers-Pending and Triggers-Awaited control file fields, to prevent
|
||||
accidents.
|
||||
|
||||
|
||||
Cycle detection
|
||||
---------------
|
||||
|
||||
In addition to dependency cycles, triggers raise the possibility of
|
||||
mutually triggering packages - a cycle detectable only dynamically,
|
||||
which we will call a “trigger cycle”.
|
||||
|
||||
Trigger cycles are detected using the usual hare-and-tortoise
|
||||
approach. Each time after dpkg runs a postinst for triggers, dpkg
|
||||
records the set of pending triggers (ie, the set of activated <pending
|
||||
package, trigger name> tuples). If the hare set is a superset of the
|
||||
tortoise set, a cycle has been found.
|
||||
|
||||
For guaranteed termination, it would be sufficient to declare a cycle
|
||||
only when the two sets are identical, but because of the requirement
|
||||
to make progress we can cut this short. Formally, there is supposed
|
||||
to be a complete ordering of pending trigger sets satisfying the
|
||||
condition that any set of pending triggers is (strictly) greater than
|
||||
all its (strict) subsets. Trigger processing is supposed to
|
||||
monotonically decrease the set in this ordering. (The set elements
|
||||
are <package, trigger name> tuples.)
|
||||
|
||||
(See “Processing” above for discussion of dependency cycles.)
|
81
dselect/Makefile.am
Normal file
81
dselect/Makefile.am
Normal file
|
@ -0,0 +1,81 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = methods po
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DLOCALEDIR=\"$(localedir)\" \
|
||||
-DADMINDIR=\"$(admindir)\" \
|
||||
-DLIBDIR=\"$(pkglibexecdir)\" \
|
||||
-DLOCALLIBDIR=\"/usr/local/lib/dpkg\" \
|
||||
-idirafter $(top_srcdir)/lib/compat \
|
||||
-iquote $(builddir) \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/lib \
|
||||
# EOL
|
||||
AM_CXXFLAGS = \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
# EOL
|
||||
if HAVE_LINKER_AS_NEEDED
|
||||
AM_LDFLAGS = \
|
||||
-Wl,--as-needed \
|
||||
# EOL
|
||||
endif
|
||||
|
||||
|
||||
bin_PROGRAMS = dselect
|
||||
|
||||
dselect_SOURCES = \
|
||||
cxx-support.cc \
|
||||
dselect.h \
|
||||
dselect-curses.h \
|
||||
basecmds.cc \
|
||||
baselist.cc \
|
||||
basetop.cc \
|
||||
bindings.cc bindings.h \
|
||||
curkeys.cc \
|
||||
helpmsgs.cc helpmsgs.h \
|
||||
main.cc \
|
||||
methkeys.cc \
|
||||
methlist.cc \
|
||||
method.cc method.h \
|
||||
methparse.cc \
|
||||
pkgcmds.cc \
|
||||
pkgdepcon.cc \
|
||||
pkgdisplay.cc \
|
||||
pkginfo.cc \
|
||||
pkgkeys.cc \
|
||||
pkglist.cc pkglist.h \
|
||||
pkgsublist.cc \
|
||||
pkgtop.cc \
|
||||
# EOL
|
||||
|
||||
dselect_LDADD = \
|
||||
$(CURSES_LIBS) \
|
||||
../lib/dpkg/libdpkg.la \
|
||||
$(LIBINTL) \
|
||||
../lib/compat/libcompat.la \
|
||||
# EOL
|
||||
|
||||
dist_bashcompletions_DATA = \
|
||||
# EOL
|
||||
|
||||
EXTRA_DIST = \
|
||||
keyoverride \
|
||||
mkcurkeys.pl \
|
||||
# EOL
|
||||
|
||||
CLEANFILES = \
|
||||
curkeys.hpp \
|
||||
curkeys.h \
|
||||
# EOL
|
||||
|
||||
curkeys.$(OBJEXT): curkeys.h
|
||||
curkeys.hpp: dselect-curses.h
|
||||
$(AM_V_GEN) echo '#include "dselect-curses.h"' | \
|
||||
$(CPP) -dD $(CPPFLAGS) -I$(top_builddir) -I $(srcdir) - >$@
|
||||
curkeys.h: $(srcdir)/keyoverride $(srcdir)/mkcurkeys.pl curkeys.hpp
|
||||
$(AM_V_GEN) $(PERL) $(srcdir)/mkcurkeys.pl $< curkeys.hpp >$@
|
||||
|
||||
install-data-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(pkgconfdir)/dselect.cfg.d
|
1081
dselect/Makefile.in
Normal file
1081
dselect/Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
327
dselect/basecmds.cc
Normal file
327
dselect/basecmds.cc
Normal file
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* basecmds.cc - base list keyboard commands display
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2000,2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "helpmsgs.h"
|
||||
|
||||
void baselist::kd_scrollon() {
|
||||
topofscreen += list_height;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
if (cursorline < topofscreen)
|
||||
setcursor(topofscreen);
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void baselist::kd_scrollon1() {
|
||||
if (topofscreen >= nitems - list_height) return;
|
||||
topofscreen++;
|
||||
if (cursorline < topofscreen)
|
||||
setcursor(topofscreen);
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void baselist::kd_scrollback() {
|
||||
topofscreen -= list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
if (cursorline >= topofscreen + list_height)
|
||||
setcursor(topofscreen + list_height - 1);
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void baselist::kd_scrollback1() {
|
||||
if (topofscreen <= 0) return;
|
||||
topofscreen--;
|
||||
if (cursorline >= topofscreen + list_height)
|
||||
setcursor(topofscreen + list_height - 1);
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void baselist::kd_top() {
|
||||
topofscreen= 0; setcursor(0);
|
||||
}
|
||||
|
||||
void baselist::kd_bottom() {
|
||||
topofscreen= nitems - list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
setcursor(min(topofscreen + list_height - 1, nitems - 1));
|
||||
}
|
||||
|
||||
void baselist::kd_redraw() {
|
||||
clearok(curscr,TRUE);
|
||||
redrawall();
|
||||
debug(dbg_general, "baselist[%p]::kd_redraw() done", this);
|
||||
}
|
||||
|
||||
void baselist::kd_searchagain() {
|
||||
if (!searchstring.len()) {
|
||||
beep();
|
||||
return;
|
||||
}
|
||||
dosearch();
|
||||
}
|
||||
|
||||
bool
|
||||
baselist::checksearch(varbuf &str)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
baselist::matchsearch(int index)
|
||||
{
|
||||
int lendiff, i;
|
||||
const char *name;
|
||||
|
||||
name = itemname(index);
|
||||
if (!name)
|
||||
return false; /* Skip things without a name (separators). */
|
||||
|
||||
lendiff = strlen(name) - searchstring.len();
|
||||
for (i=0; i<=lendiff; i++)
|
||||
if (strncasecmp(name + i, searchstring.str(), searchstring.len()) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void baselist::kd_search() {
|
||||
varbuf newsearchstring(128);
|
||||
newsearchstring = searchstring;
|
||||
|
||||
werase(querywin);
|
||||
mvwaddstr(querywin,0,0, _("Search for ? "));
|
||||
echo();
|
||||
if (wgetnstr(querywin, newsearchstring.buf, newsearchstring.size - 1) == ERR)
|
||||
searchstring.reset();
|
||||
newsearchstring.trunc(strlen(newsearchstring.buf));
|
||||
resize_window();
|
||||
noecho();
|
||||
if (whatinfo_height) { touchwin(whatinfowin); refreshinfo(); }
|
||||
else if (info_height) { touchwin(infopad); refreshinfo(); }
|
||||
else if (thisstate_height) redrawthisstate();
|
||||
else { touchwin(listpad); refreshlist(); }
|
||||
if (newsearchstring.len()) {
|
||||
if (!checksearch(newsearchstring)) {
|
||||
beep();
|
||||
return;
|
||||
}
|
||||
|
||||
searchstring = std::move(newsearchstring);
|
||||
dosearch();
|
||||
} else
|
||||
kd_searchagain();
|
||||
}
|
||||
|
||||
void
|
||||
baselist::displayerror(const char *str)
|
||||
{
|
||||
const char *pr = _("Error: ");
|
||||
int prlen=strlen(pr);
|
||||
|
||||
beep();
|
||||
werase(querywin);
|
||||
mvwaddstr(querywin,0,0,pr);
|
||||
mvwaddstr(querywin,0,prlen,str);
|
||||
wgetch(querywin);
|
||||
if (whatinfo_height) { touchwin(whatinfowin); refreshinfo(); }
|
||||
else if (info_height) { touchwin(infopad); refreshinfo(); }
|
||||
else if (thisstate_height) redrawthisstate();
|
||||
}
|
||||
|
||||
|
||||
void baselist::displayhelp(const struct helpmenuentry *helpmenu, int key) {
|
||||
int maxx, maxy, i, nextkey;
|
||||
|
||||
wbkgdset(stdscr, ' ' | part_attr[helpscreen]);
|
||||
clearok(stdscr,TRUE);
|
||||
for (;;) {
|
||||
getmaxyx(stdscr, maxy, maxx);
|
||||
werase(stdscr);
|
||||
const struct helpmenuentry *hme = helpmenu;
|
||||
while (hme->key && hme->key != key)
|
||||
hme++;
|
||||
if (hme->key) {
|
||||
int x, y DPKG_ATTR_UNUSED;
|
||||
|
||||
attrset(part_attr[helpscreen]);
|
||||
mvaddstr(1,0, gettext(hme->msg->text));
|
||||
attrset(part_attr[title]);
|
||||
mvaddstr(0,0, _("Help: "));
|
||||
addstr(gettext(hme->msg->title));
|
||||
getyx(stdscr,y,x);
|
||||
while (++x<maxx) addch(' ');
|
||||
attrset(part_attr[thisstate]);
|
||||
mvaddstr(maxy-1,0,
|
||||
_("Press ? for help menu, . for next topic, <space> to exit help."));
|
||||
getyx(stdscr,y,x);
|
||||
while (++x<maxx) addch(' ');
|
||||
move(maxy,maxx);
|
||||
attrset(A_NORMAL);
|
||||
nextkey= hme[1].key;
|
||||
} else {
|
||||
mvaddstr(1,1, _("Help information is available under the following topics:"));
|
||||
for (i=0, hme=helpmenu; hme->key; hme++,i++) {
|
||||
attrset(A_BOLD);
|
||||
mvaddch(i+3,3, hme->key);
|
||||
attrset(A_NORMAL);
|
||||
mvaddstr(i+3,6, gettext(hme->msg->title));
|
||||
}
|
||||
mvaddstr(i+4,1,
|
||||
_("Press a key from the list above, <space> or 'q' to exit help,\n"
|
||||
" or '.' (full stop) to read each help page in turn. "));
|
||||
nextkey= helpmenu[0].key;
|
||||
}
|
||||
refresh();
|
||||
do {
|
||||
int curkey = key;
|
||||
|
||||
key = getch();
|
||||
if (key == KEY_RESIZE) {
|
||||
resize_window();
|
||||
key = curkey;
|
||||
}
|
||||
} while (key == ERR && errno == EINTR);
|
||||
if (key == EOF) ohshite(_("error reading keyboard in help"));
|
||||
if (key == ' ' || key == 'q') {
|
||||
break;
|
||||
} else if (key == '?' || key == 'h') {
|
||||
key= 0;
|
||||
} else if (key == '.') {
|
||||
key= nextkey;
|
||||
}
|
||||
}
|
||||
werase(stdscr);
|
||||
clearok(stdscr,TRUE);
|
||||
wnoutrefresh(stdscr);
|
||||
|
||||
redrawtitle();
|
||||
refreshcolheads();
|
||||
refreshlist();
|
||||
redrawthisstate();
|
||||
refreshinfo();
|
||||
wnoutrefresh(whatinfowin);
|
||||
}
|
||||
|
||||
void baselist::kd_help() {
|
||||
displayhelp(helpmenulist(),0);
|
||||
}
|
||||
|
||||
void baselist::setcursor(int index) {
|
||||
if (listpad && cursorline != -1) {
|
||||
redrawitemsrange(cursorline,cursorline+1);
|
||||
redraw1itemsel(cursorline,0);
|
||||
}
|
||||
if (cursorline != index) infotopofscreen= 0;
|
||||
cursorline= index;
|
||||
if (listpad) {
|
||||
redrawitemsrange(cursorline,cursorline+1);
|
||||
redraw1itemsel(cursorline,1);
|
||||
refreshlist();
|
||||
redrawthisstate();
|
||||
}
|
||||
redrawinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_down() {
|
||||
int ncursor= cursorline;
|
||||
// scroll by one line unless the bottom is already visible
|
||||
// or we're in the top half of the screen ...
|
||||
if (topofscreen < nitems - list_height &&
|
||||
ncursor >= topofscreen + list_height - 3) topofscreen++;
|
||||
// move cursor if there are any more ...
|
||||
if (cursorline+1 < nitems) ncursor++;
|
||||
setcursor(ncursor);
|
||||
}
|
||||
|
||||
void baselist::kd_up() {
|
||||
int ncursor= cursorline;
|
||||
// scroll by one line if there are any lines not shown yet
|
||||
// and we're not in the bottom half the screen ...
|
||||
if (topofscreen > 0 &&
|
||||
ncursor <= topofscreen + 2) topofscreen--;
|
||||
// move cursor if there are any to move it to ...
|
||||
if (cursorline > 0) ncursor--;
|
||||
setcursor(ncursor);
|
||||
}
|
||||
|
||||
void baselist::kd_iscrollon() {
|
||||
infotopofscreen += info_height;
|
||||
if (infotopofscreen > infolines - info_height)
|
||||
infotopofscreen= infolines - info_height;
|
||||
if (infotopofscreen < 0) infotopofscreen= 0;
|
||||
refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_iscrollback() {
|
||||
infotopofscreen -= info_height;
|
||||
if (infotopofscreen < 0) infotopofscreen= 0;
|
||||
refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_iscrollon1() {
|
||||
if (infotopofscreen >= infolines - info_height) return;
|
||||
infotopofscreen++; refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_iscrollback1() {
|
||||
if (infotopofscreen <= 0) return;
|
||||
infotopofscreen--; refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_panon() {
|
||||
leftofscreen += xmax/3;
|
||||
if (leftofscreen > total_width - xmax) leftofscreen= total_width - xmax;
|
||||
if (leftofscreen < 0) leftofscreen= 0;
|
||||
refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_panback() {
|
||||
leftofscreen -= xmax/3;
|
||||
if (leftofscreen < 0) leftofscreen= 0;
|
||||
refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_panon1() {
|
||||
leftofscreen++;
|
||||
if (leftofscreen > total_width - xmax) leftofscreen= total_width - xmax;
|
||||
if (leftofscreen < 0) leftofscreen= 0;
|
||||
refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
|
||||
}
|
||||
|
||||
void baselist::kd_panback1() {
|
||||
leftofscreen--;
|
||||
if (leftofscreen < 0) leftofscreen= 0;
|
||||
refreshcolheads(); refreshlist(); redrawthisstate(); refreshinfo();
|
||||
}
|
412
dselect/baselist.cc
Normal file
412
dselect/baselist.cc
Normal file
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* baselist.cc - list of somethings
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
* Copyright © 2007-2013 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/c-ctype.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
|
||||
void mywerase(WINDOW *win) {
|
||||
int my,mx,y,x;
|
||||
getmaxyx(win,my,mx);
|
||||
for (y=0; y<my; y++) {
|
||||
wmove(win,y,0); for (x=0; x<mx; x++) waddch(win,' ');
|
||||
}
|
||||
wmove(win,0,0);
|
||||
}
|
||||
|
||||
void
|
||||
baselist::resize_window()
|
||||
{
|
||||
debug(dbg_general, "baselist::resize_window(), baselist=%p", this);
|
||||
enddisplay();
|
||||
startdisplay();
|
||||
if (doupdate() == ERR)
|
||||
ohshite(_("cannot update screen after window resize"));
|
||||
}
|
||||
|
||||
void
|
||||
baselist::add_column(column &col, const char *title, int width)
|
||||
{
|
||||
col.title = title;
|
||||
col.x = col_cur_x;
|
||||
col.width = width;
|
||||
|
||||
col_cur_x += col.width + gap_width;
|
||||
}
|
||||
|
||||
void
|
||||
baselist::end_column(column &col, const char *title)
|
||||
{
|
||||
col.title = title;
|
||||
col.x = col_cur_x;
|
||||
col.width = total_width - col.x;
|
||||
|
||||
col_cur_x += col.width + gap_width;
|
||||
}
|
||||
|
||||
void
|
||||
baselist::draw_column_head(const column &col)
|
||||
{
|
||||
mvwaddnstr(colheadspad, 0, col.x, col.title, col.width);
|
||||
}
|
||||
|
||||
void
|
||||
baselist::draw_column_sep(const column &col, int y)
|
||||
{
|
||||
mvwaddch(listpad, y, col.x - 1, ' ');
|
||||
}
|
||||
|
||||
void
|
||||
baselist::draw_column_item(const column &col, int y, const char *item)
|
||||
{
|
||||
mvwprintw(listpad, y, col.x, "%-*.*s", col.width, col.width, item);
|
||||
}
|
||||
|
||||
void baselist::setheights() {
|
||||
int y= ymax - (title_height + colheads_height + thisstate_height);
|
||||
|
||||
if (y < 1)
|
||||
internerr("widget y=%d < 1", y);
|
||||
|
||||
if (showinfo==2 && y>=7) {
|
||||
list_height= 5;
|
||||
whatinfo_height= 1;
|
||||
info_height= y-6;
|
||||
} else if (showinfo==1 && y>=10) {
|
||||
list_height= y/2;
|
||||
info_height= (y-1)/2;
|
||||
whatinfo_height= 1;
|
||||
} else {
|
||||
list_height= y;
|
||||
info_height= 0;
|
||||
whatinfo_height= 0;
|
||||
}
|
||||
colheads_row= title_height;
|
||||
list_row= colheads_row + colheads_height;
|
||||
thisstate_row= list_row + list_height;
|
||||
info_row= thisstate_row + thisstate_height;
|
||||
whatinfo_row= ymax - 1;
|
||||
}
|
||||
|
||||
void baselist::startdisplay() {
|
||||
debug(dbg_general, "baselist[%p]::startdisplay()", this);
|
||||
cbreak(); noecho(); nonl(); keypad(stdscr,TRUE);
|
||||
clear(); wnoutrefresh(stdscr);
|
||||
|
||||
// find attributes
|
||||
if (has_colors() && start_color()==OK && COLOR_PAIRS >= numscreenparts) {
|
||||
int i;
|
||||
printf("allocing\n");
|
||||
for (i = 1; i < numscreenparts; i++) {
|
||||
if (init_pair(i, color[i].fore, color[i].back) != OK)
|
||||
ohshite(_("cannot allocate color pair"));
|
||||
part_attr[i] = COLOR_PAIR(i) | color[i].attr;
|
||||
}
|
||||
} else {
|
||||
/* User defined attributes for B&W mode are not currently supported. */
|
||||
part_attr[title] = A_REVERSE;
|
||||
part_attr[thisstate] = A_STANDOUT;
|
||||
part_attr[list] = 0;
|
||||
part_attr[listsel] = A_STANDOUT;
|
||||
part_attr[selstate] = A_BOLD;
|
||||
part_attr[selstatesel] = A_STANDOUT;
|
||||
part_attr[colheads]= A_BOLD;
|
||||
part_attr[query] = part_attr[title];
|
||||
part_attr[info_body] = part_attr[list];
|
||||
part_attr[info_head] = A_BOLD;
|
||||
part_attr[whatinfo] = part_attr[thisstate];
|
||||
part_attr[helpscreen] = A_NORMAL;
|
||||
}
|
||||
|
||||
// set up windows and pads, based on screen size
|
||||
getmaxyx(stdscr,ymax,xmax);
|
||||
title_height= ymax>=6;
|
||||
colheads_height= ymax>=5;
|
||||
thisstate_height= ymax>=3;
|
||||
|
||||
setheights();
|
||||
setwidths();
|
||||
|
||||
titlewin= newwin(1,xmax, 0,0);
|
||||
if (!titlewin) ohshite(_("failed to create title window"));
|
||||
wattrset(titlewin, part_attr[title]);
|
||||
|
||||
whatinfowin= newwin(1,xmax, whatinfo_row,0);
|
||||
if (!whatinfowin) ohshite(_("failed to create whatinfo window"));
|
||||
wattrset(whatinfowin, part_attr[whatinfo]);
|
||||
|
||||
listpad = newpad(ymax, total_width);
|
||||
if (!listpad) ohshite(_("failed to create baselist pad"));
|
||||
|
||||
colheadspad= newpad(1, total_width);
|
||||
if (!colheadspad) ohshite(_("failed to create heading pad"));
|
||||
wattrset(colheadspad, part_attr[colheads]);
|
||||
|
||||
thisstatepad= newpad(1, total_width);
|
||||
if (!thisstatepad) ohshite(_("failed to create thisstate pad"));
|
||||
wattrset(thisstatepad, part_attr[thisstate]);
|
||||
|
||||
infopad= newpad(MAX_DISPLAY_INFO, total_width);
|
||||
if (!infopad) ohshite(_("failed to create info pad"));
|
||||
wattrset(infopad, part_attr[info_body]);
|
||||
wbkgdset(infopad, ' ' | part_attr[info_body]);
|
||||
|
||||
querywin= newwin(1,xmax,ymax-1,0);
|
||||
if (!querywin) ohshite(_("failed to create query window"));
|
||||
wbkgdset(querywin, ' ' | part_attr[query]);
|
||||
|
||||
if (cursorline >= topofscreen + list_height) topofscreen= cursorline;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
|
||||
infotopofscreen= 0; leftofscreen= 0;
|
||||
|
||||
redrawall();
|
||||
|
||||
debug(dbg_general,
|
||||
"baselist::startdisplay() done ...\n\n"
|
||||
" xmax=%d, ymax=%d;\n\n"
|
||||
" title_height=%d, colheads_height=%d, list_height=%d;\n"
|
||||
" thisstate_height=%d, info_height=%d, whatinfo_height=%d;\n\n"
|
||||
" colheads_row=%d, thisstate_row=%d, info_row=%d;\n"
|
||||
" whatinfo_row=%d, list_row=%d;\n\n",
|
||||
xmax, ymax, title_height, colheads_height, list_height,
|
||||
thisstate_height, info_height, whatinfo_height,
|
||||
colheads_row, thisstate_row, info_row, whatinfo_row, list_row);
|
||||
}
|
||||
|
||||
void baselist::enddisplay() {
|
||||
delwin(titlewin);
|
||||
delwin(whatinfowin);
|
||||
delwin(listpad);
|
||||
delwin(colheadspad);
|
||||
delwin(thisstatepad);
|
||||
delwin(infopad);
|
||||
wmove(stdscr,ymax,0); wclrtoeol(stdscr);
|
||||
listpad = nullptr;
|
||||
col_cur_x = 0;
|
||||
}
|
||||
|
||||
void baselist::redrawall() {
|
||||
redrawtitle();
|
||||
redrawcolheads();
|
||||
wattrset(listpad, part_attr[list]);
|
||||
mywerase(listpad);
|
||||
ldrawnstart= ldrawnend= -1; // start is first drawn; end is first undrawn; -1=none
|
||||
refreshlist();
|
||||
redrawthisstate();
|
||||
redrawinfo();
|
||||
}
|
||||
|
||||
void baselist::redraw1item(int index) {
|
||||
redraw1itemsel(index, index == cursorline);
|
||||
}
|
||||
|
||||
baselist::baselist(keybindings *kb) {
|
||||
debug(dbg_general, "baselist[%p]::baselist()", this);
|
||||
|
||||
bindings= kb;
|
||||
nitems= 0;
|
||||
|
||||
col_cur_x = 0;
|
||||
gap_width = 1;
|
||||
total_width = max(TOTAL_LIST_WIDTH, COLS);
|
||||
|
||||
xmax= -1;
|
||||
ymax = -1;
|
||||
|
||||
list_height = 0;
|
||||
info_height = 0;
|
||||
title_height = 0;
|
||||
whatinfo_height = 0;
|
||||
colheads_height = 0;
|
||||
thisstate_height = 0;
|
||||
|
||||
list_row = 0;
|
||||
info_row = 0;
|
||||
whatinfo_row = 0;
|
||||
colheads_row = 0;
|
||||
thisstate_row = 0;
|
||||
|
||||
topofscreen = 0;
|
||||
leftofscreen = 0;
|
||||
infotopofscreen = 0;
|
||||
infolines = 0;
|
||||
|
||||
listpad = nullptr;
|
||||
infopad = nullptr;
|
||||
colheadspad = nullptr;
|
||||
thisstatepad = nullptr;
|
||||
titlewin = nullptr;
|
||||
querywin = nullptr;
|
||||
whatinfowin = nullptr;
|
||||
|
||||
cursorline = -1;
|
||||
ldrawnstart = 0;
|
||||
ldrawnend = 0;
|
||||
showinfo= 1;
|
||||
|
||||
searchstring.reset();
|
||||
}
|
||||
|
||||
void baselist::itd_keys() {
|
||||
whatinfovb += _("Keybindings");
|
||||
|
||||
const int givek= xmax/3;
|
||||
bindings->describestart();
|
||||
const char **ta;
|
||||
while ((ta = bindings->describenext()) != nullptr) {
|
||||
const char **tap= ta+1;
|
||||
for (;;) {
|
||||
waddstr(infopad, gettext(*tap));
|
||||
tap++; if (!*tap) break;
|
||||
waddstr(infopad, ", ");
|
||||
}
|
||||
int y,x;
|
||||
getyx(infopad,y,x);
|
||||
if (x >= givek) y++;
|
||||
mvwaddstr(infopad, y,givek, ta[0]);
|
||||
waddch(infopad,'\n');
|
||||
delete [] ta;
|
||||
}
|
||||
}
|
||||
|
||||
void baselist::dosearch() {
|
||||
int offset, index;
|
||||
debug(dbg_general, "baselist[%p]::dosearch(); searchstring='%s'",
|
||||
this, searchstring.str());
|
||||
for (offset = 1, index = max(topofscreen, cursorline + 1);
|
||||
offset<nitems;
|
||||
offset++, index++) {
|
||||
if (index >= nitems) index -= nitems;
|
||||
if (matchsearch(index)) {
|
||||
topofscreen= index-1;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
setcursor(index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
beep();
|
||||
}
|
||||
|
||||
void baselist::refreshinfo() {
|
||||
pnoutrefresh(infopad, infotopofscreen,leftofscreen, info_row,0,
|
||||
min(info_row + info_height - 1, info_row + MAX_DISPLAY_INFO - 1),
|
||||
min(total_width - leftofscreen - 1, xmax - 1));
|
||||
|
||||
if (whatinfo_height) {
|
||||
mywerase(whatinfowin);
|
||||
mvwaddstr(whatinfowin,0,0, whatinfovb.str());
|
||||
if (infolines > info_height) {
|
||||
wprintw(whatinfowin,_(" -- %d%%, press "),
|
||||
(infotopofscreen + info_height) * 100 / infolines);
|
||||
if (infotopofscreen + info_height < infolines) {
|
||||
wprintw(whatinfowin, _("%s for more"), bindings->find("iscrollon").str());
|
||||
if (infotopofscreen) waddstr(whatinfowin, ", ");
|
||||
}
|
||||
if (infotopofscreen)
|
||||
wprintw(whatinfowin, _("%s to go back"), bindings->find("iscrollback").str());
|
||||
waddch(whatinfowin,'.');
|
||||
}
|
||||
wnoutrefresh(whatinfowin);
|
||||
}
|
||||
}
|
||||
|
||||
void baselist::wordwrapinfo(int offset, const char *m) {
|
||||
ssize_t usemax = xmax - 5;
|
||||
debug(dbg_general, "baselist[%p]::wordwrapinfo(%d, '%s')", this, offset, m);
|
||||
bool wrapping = false;
|
||||
|
||||
for (;;) {
|
||||
int offleft=offset; while (*m == ' ' && offleft>0) { m++; offleft--; }
|
||||
const char *p = strchrnul(m, '\n');
|
||||
ptrdiff_t l = p - m;
|
||||
|
||||
while (l && c_isspace(m[l - 1]))
|
||||
l--;
|
||||
if (!l || (*m == '.' && l == 1)) {
|
||||
if (wrapping) waddch(infopad,'\n');
|
||||
waddch(infopad, '\n');
|
||||
wrapping = false;
|
||||
} else if (*m == ' ' || usemax < 10) {
|
||||
if (wrapping) waddch(infopad,'\n');
|
||||
waddnstr(infopad, m, l);
|
||||
waddch(infopad, '\n');
|
||||
wrapping = false;
|
||||
} else {
|
||||
int x, y DPKG_ATTR_UNUSED;
|
||||
|
||||
if (wrapping) {
|
||||
getyx(infopad, y,x);
|
||||
if (x+1 >= usemax) {
|
||||
waddch(infopad,'\n');
|
||||
} else {
|
||||
waddch(infopad,' ');
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
getyx(infopad, y,x);
|
||||
ssize_t dosend = usemax - x;
|
||||
if (l <= dosend) {
|
||||
dosend=l;
|
||||
} else {
|
||||
ssize_t i = dosend;
|
||||
while (i > 0 && m[i] != ' ') i--;
|
||||
if (i > 0 || x > 0) dosend=i;
|
||||
}
|
||||
if (dosend) waddnstr(infopad, m, dosend);
|
||||
while (dosend < l && m[dosend] == ' ') dosend++;
|
||||
l-= dosend; m+= dosend;
|
||||
if (l <= 0) break;
|
||||
waddch(infopad,'\n');
|
||||
}
|
||||
wrapping = true;
|
||||
}
|
||||
if (*p == '\0')
|
||||
break;
|
||||
if (getcury(infopad) == (MAX_DISPLAY_INFO - 1)) {
|
||||
waddstr(infopad,
|
||||
"[The package description is too long and has been truncated...]");
|
||||
break;
|
||||
}
|
||||
m= ++p;
|
||||
}
|
||||
debug(dbg_general, "baselist[%p]::wordwrapinfo() done", this);
|
||||
}
|
||||
|
||||
baselist::~baselist() { }
|
52
dselect/basetop.cc
Normal file
52
dselect/basetop.cc
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* basetop.cc - base list class redraw of top
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
|
||||
void baselist::refreshlist() {
|
||||
redrawitemsrange(topofscreen, min(nitems, topofscreen + list_height));
|
||||
int y, x, maxy, maxx;
|
||||
y = min(list_row + list_height - 1, list_row + nitems - topofscreen - 1);
|
||||
x = min(total_width - leftofscreen - 1, xmax - 1);
|
||||
pnoutrefresh(listpad, 0, leftofscreen, list_row, 0, y, x);
|
||||
getmaxyx(listpad,maxy,maxx);
|
||||
y++;
|
||||
while (y < list_row + list_height - 1) {
|
||||
pnoutrefresh(listpad, maxy-1,leftofscreen, y,0, y,x);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
void baselist::redrawitemsrange(int start, int end) {
|
||||
int i;
|
||||
for (i = start; i < end; i++) {
|
||||
redraw1item(i);
|
||||
}
|
||||
}
|
||||
|
||||
void baselist::refreshcolheads() {
|
||||
pnoutrefresh(colheadspad, 0,leftofscreen, colheads_row,0,
|
||||
colheads_row, min(total_width - leftofscreen - 1, xmax - 1));
|
||||
}
|
184
dselect/bindings.cc
Normal file
184
dselect/bindings.cc
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* bindings.cc - keybinding manager object definitions and default bindings
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
|
||||
keybindings::keybindings(const interpretation *ints, const orgbinding *orgbindings) {
|
||||
interps= ints;
|
||||
bindings = nullptr;
|
||||
const orgbinding *b= orgbindings;
|
||||
while (b->action) { bind(b->key,b->action); b++; }
|
||||
describestart();
|
||||
}
|
||||
|
||||
bool
|
||||
keybindings::bind(int key, const char *action)
|
||||
{
|
||||
if (key == -1)
|
||||
return false;
|
||||
|
||||
const interpretation *interp = interps;
|
||||
while (interp->action && strcmp(interp->action, action))
|
||||
interp++;
|
||||
if (!interp->action)
|
||||
return false;
|
||||
|
||||
const description *desc = descriptions;
|
||||
while (desc->action && strcmp(desc->action, action))
|
||||
desc++;
|
||||
|
||||
binding *b = bindings;
|
||||
while (b && b->key != key)
|
||||
b = b->next;
|
||||
|
||||
if (!b) {
|
||||
b = new binding;
|
||||
b->key = key;
|
||||
b->next = bindings;
|
||||
bindings = b;
|
||||
}
|
||||
b->interp = interp;
|
||||
b->desc = desc->desc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
varbuf
|
||||
keybindings::find(const char *action) {
|
||||
binding *b = bindings;
|
||||
while (b && strcmp(action, b->interp->action))
|
||||
b = b->next;
|
||||
if (!b)
|
||||
return varbuf(_("[not bound]"));
|
||||
|
||||
const char *n= key2name(b->key);
|
||||
if (n)
|
||||
return varbuf(n);
|
||||
|
||||
varbuf unknown;
|
||||
unknown.set_fmt(_("[unk: %d]"), b->key);
|
||||
return unknown;
|
||||
}
|
||||
|
||||
const keybindings::interpretation *keybindings::operator()(int key) {
|
||||
binding *b = bindings;
|
||||
while (b && b->key != key)
|
||||
b = b->next;
|
||||
if (!b)
|
||||
return nullptr;
|
||||
return b->interp;
|
||||
}
|
||||
|
||||
const char **keybindings::describenext() {
|
||||
binding *search;
|
||||
int count;
|
||||
for (;;) {
|
||||
if (!iterate->action)
|
||||
return nullptr;
|
||||
for (count=0, search=bindings; search; search=search->next)
|
||||
if (strcmp(search->interp->action, iterate->action) == 0)
|
||||
count++;
|
||||
if (count) break;
|
||||
iterate++;
|
||||
}
|
||||
const char **retarray= new const char *[count+2];
|
||||
retarray[0]= iterate->desc;
|
||||
for (count=1, search=bindings; search; search=search->next)
|
||||
if (strcmp(search->interp->action, iterate->action) == 0)
|
||||
retarray[count++]= key2name(search->key);
|
||||
retarray[count] = nullptr;
|
||||
iterate++;
|
||||
return retarray;
|
||||
}
|
||||
|
||||
const char *keybindings::key2name(int key) {
|
||||
const keyname *search = keynames;
|
||||
while (search->key != -1 && search->key != key)
|
||||
search++;
|
||||
return search->kname;
|
||||
}
|
||||
|
||||
int keybindings::name2key(const char *name) {
|
||||
const keyname *search = keynames;
|
||||
while (search->kname && strcasecmp(search->kname, name))
|
||||
search++;
|
||||
return search->key;
|
||||
}
|
||||
|
||||
keybindings::~keybindings() {
|
||||
binding *search, *next;
|
||||
for (search=bindings; search; search=next) {
|
||||
next= search->next;
|
||||
delete search;
|
||||
}
|
||||
}
|
||||
|
||||
const keybindings::description keybindings::descriptions[]= {
|
||||
// Actions which apply to both types of list.
|
||||
{ "iscrollon", N_("Scroll onwards through help/information") },
|
||||
{ "iscrollback", N_("Scroll backwards through help/information") },
|
||||
{ "up", N_("Move up") },
|
||||
{ "down", N_("Move down") },
|
||||
{ "top", N_("Go to top of list") },
|
||||
{ "bottom", N_("Go to end of list") },
|
||||
{ "help", N_("Request help (cycle through help screens)") },
|
||||
{ "info", N_("Cycle through information displays") },
|
||||
{ "redraw", N_("Redraw display") },
|
||||
{ "scrollon1", N_("Scroll onwards through list by 1 line") },
|
||||
{ "scrollback1", N_("Scroll backwards through list by 1 line") },
|
||||
{ "iscrollon1", N_("Scroll onwards through help/information by 1 line") },
|
||||
{ "iscrollback1", N_("Scroll backwards through help/information by 1 line") },
|
||||
{ "scrollon", N_("Scroll onwards through list") },
|
||||
{ "scrollback", N_("Scroll backwards through list") },
|
||||
|
||||
// Actions which apply only to lists of packages.
|
||||
{ "install", N_("Mark package(s) for installation") },
|
||||
{ "remove", N_("Mark package(s) for deinstallation") },
|
||||
{ "purge", N_("Mark package(s) for deinstall and purge") },
|
||||
{ "morespecific", N_("Make highlight more specific") },
|
||||
{ "lessspecific", N_("Make highlight less specific") },
|
||||
{ "search", N_("Search for a package whose name contains a string") },
|
||||
{ "searchagain", N_("Repeat last search") },
|
||||
{ "swaporder", N_("Swap sort order priority/section") },
|
||||
{ "quitcheck", N_("Quit, confirming, and checking dependencies") },
|
||||
{ "quitnocheck", N_("Quit, confirming without check") },
|
||||
{ "quitrejectsug", N_("Quit, rejecting conflict/dependency suggestions") },
|
||||
{ "abortnocheck", N_("Abort - quit without making changes") },
|
||||
{ "revert", N_("Revert to old state for all packages") },
|
||||
{ "revertsuggest", N_("Revert to suggested state for all packages") },
|
||||
{ "revertdirect", N_("Revert to directly requested state for all packages") },
|
||||
{ "revertinstalled", N_("Revert to currently installed state for all packages") },
|
||||
|
||||
// Actions which apply only to lists of methods.
|
||||
{ "select-and-quit", N_("Select currently-highlighted access method") },
|
||||
{ "abort", N_("Quit without changing selected access method") },
|
||||
{ nullptr, nullptr }
|
||||
};
|
96
dselect/bindings.h
Normal file
96
dselect/bindings.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* bindings.h - keybindings class header file
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BINDINGS_H
|
||||
#define BINDINGS_H
|
||||
|
||||
struct keybindings {
|
||||
struct interpretation;
|
||||
|
||||
struct orgbinding {
|
||||
int key;
|
||||
const char *action;
|
||||
};
|
||||
|
||||
struct keyname {
|
||||
int key;
|
||||
const char *kname;
|
||||
};
|
||||
|
||||
struct description {
|
||||
const char *action, *desc;
|
||||
};
|
||||
|
||||
struct binding {
|
||||
binding *next;
|
||||
int key;
|
||||
const struct interpretation *interp;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
private:
|
||||
static const keyname keynames[];
|
||||
static const description descriptions[];
|
||||
|
||||
binding *bindings;
|
||||
const description *iterate;
|
||||
const interpretation *interps;
|
||||
|
||||
bool bind(int key, const char *action);
|
||||
|
||||
public:
|
||||
int name2key(const char *name);
|
||||
const char *key2name(int key);
|
||||
|
||||
bool bind(const char *name, const char *action)
|
||||
{ return bind(name2key(name), action); }
|
||||
const interpretation *operator()(int key);
|
||||
varbuf find(const char *action);
|
||||
|
||||
void describestart() { iterate=descriptions; }
|
||||
const char **describenext();
|
||||
//... returns array, null-term, first element is description, rest are key strings
|
||||
// caller must delete[] the array. Null means end.
|
||||
|
||||
keybindings(const interpretation *ints, const orgbinding *orgbindings);
|
||||
~keybindings();
|
||||
};
|
||||
|
||||
#include "pkglist.h"
|
||||
#include "method.h"
|
||||
|
||||
struct keybindings::interpretation {
|
||||
const char *action;
|
||||
void (methodlist::*mfn)();
|
||||
void (packagelist::*pfn)();
|
||||
quitaction qa;
|
||||
};
|
||||
|
||||
extern const keybindings::interpretation packagelist_kinterps[];
|
||||
extern const keybindings::orgbinding packagelist_korgbindings[];
|
||||
|
||||
extern const keybindings::interpretation methodlist_kinterps[];
|
||||
extern const keybindings::orgbinding methodlist_korgbindings[];
|
||||
|
||||
#ifndef CTRL
|
||||
#define CTRL(x) ((x) - 'a' + 1)
|
||||
#endif
|
||||
|
||||
#endif /* BINDINGS_H */
|
31
dselect/curkeys.cc
Normal file
31
dselect/curkeys.cc
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* curkeys.cc - list of ncurses keys for name <-> key mapping
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
|
||||
const keybindings::keyname keybindings::keynames[] = {
|
||||
#include "curkeys.h"
|
||||
};
|
82
dselect/cxx-support.cc
Normal file
82
dselect/cxx-support.cc
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* cxx-support.cc - C++ support code for dselect
|
||||
*
|
||||
* Copyright © 1994-1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_CXXABI_H
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <dpkg/dpkg.h>
|
||||
|
||||
extern void *
|
||||
operator new(size_t size) DPKG_ATTR_THROW(std::bad_alloc)
|
||||
{
|
||||
return m_malloc(size);
|
||||
}
|
||||
|
||||
extern void *
|
||||
operator new[](size_t size) DPKG_ATTR_THROW(std::bad_alloc)
|
||||
{
|
||||
return m_malloc(size);
|
||||
}
|
||||
|
||||
extern void
|
||||
operator delete(void *p) DPKG_ATTR_NOEXCEPT
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
extern void
|
||||
operator delete(void *p, size_t size) DPKG_ATTR_NOEXCEPT
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
extern void
|
||||
operator delete[](void *a) DPKG_ATTR_NOEXCEPT
|
||||
{
|
||||
free(a);
|
||||
}
|
||||
|
||||
extern void
|
||||
operator delete[](void *a, size_t size) DPKG_ATTR_NOEXCEPT
|
||||
{
|
||||
free(a);
|
||||
}
|
||||
|
||||
#ifdef HAVE___CXA_PURE_VIRTUAL
|
||||
namespace __cxxabiv1 {
|
||||
|
||||
extern "C" void
|
||||
__cxa_pure_virtual()
|
||||
{
|
||||
internerr("pure virtual function called");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
38
dselect/dselect-curses.h
Normal file
38
dselect/dselect-curses.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* dselect-curses.h - curses header wrapper
|
||||
*
|
||||
* Copyright © 2009 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DSELECT_CURSES_H
|
||||
#define DSELECT_CURSES_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#undef ERR
|
||||
|
||||
#if defined(HAVE_NCURSESW_NCURSES_H)
|
||||
#include <ncursesw/ncurses.h>
|
||||
#elif defined(HAVE_NCURSES_NCURSES_H)
|
||||
#include <ncurses/ncurses.h>
|
||||
#elif defined(HAVE_NCURSES_H)
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#endif /* DSELECT_CURSES_H */
|
204
dselect/dselect.h
Normal file
204
dselect/dselect.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* dselect.h - external definitions for this program
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DSELECT_H
|
||||
#define DSELECT_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
#include <dpkg/debug.h>
|
||||
|
||||
#include "dselect-curses.h"
|
||||
|
||||
#define DSELECT "dselect"
|
||||
|
||||
#define TOTAL_LIST_WIDTH 180
|
||||
#define MAX_DISPLAY_INFO 120
|
||||
|
||||
struct helpmenuentry {
|
||||
char key;
|
||||
const struct helpmessage *msg;
|
||||
};
|
||||
|
||||
struct keybindings;
|
||||
|
||||
enum screenparts {
|
||||
background,
|
||||
list,
|
||||
listsel,
|
||||
title,
|
||||
thisstate,
|
||||
selstate,
|
||||
selstatesel,
|
||||
colheads,
|
||||
query,
|
||||
info_body,
|
||||
info_head,
|
||||
whatinfo,
|
||||
helpscreen,
|
||||
numscreenparts,
|
||||
};
|
||||
|
||||
struct column {
|
||||
column(): title(nullptr), x(0), width(0) {}
|
||||
void blank() { title = nullptr; x = 0; width = 0; }
|
||||
|
||||
const char *title;
|
||||
int x;
|
||||
int width;
|
||||
};
|
||||
|
||||
class baselist {
|
||||
protected:
|
||||
// Screen dimensions &c.
|
||||
int xmax, ymax;
|
||||
int title_height, colheads_height, list_height;
|
||||
int thisstate_height, info_height, whatinfo_height;
|
||||
int colheads_row, thisstate_row, info_row, whatinfo_row, list_row;
|
||||
|
||||
int part_attr[numscreenparts];
|
||||
|
||||
int gap_width;
|
||||
int col_cur_x;
|
||||
int total_width;
|
||||
|
||||
void add_column(column &col, const char *title, int width);
|
||||
void end_column(column &col, const char *title);
|
||||
void draw_column_head(const column &col);
|
||||
void draw_column_sep(const column &col, int y);
|
||||
void draw_column_item(const column &col, int y, const char *item);
|
||||
|
||||
// (n)curses stuff
|
||||
WINDOW *listpad, *infopad, *colheadspad, *thisstatepad;
|
||||
WINDOW *titlewin, *whatinfowin, *querywin;
|
||||
// If listpad is null, then we have not started to display yet, and
|
||||
// so none of the auto-displaying update routines need to display.
|
||||
|
||||
// Window resize handling (via SIGWINCH).
|
||||
void resize_window();
|
||||
|
||||
int nitems, ldrawnstart, ldrawnend, showinfo;
|
||||
int topofscreen, leftofscreen, cursorline;
|
||||
int infotopofscreen, infolines;
|
||||
varbuf whatinfovb;
|
||||
varbuf searchstring;
|
||||
|
||||
virtual void setheights();
|
||||
void unsizes();
|
||||
void dosearch();
|
||||
void displayhelp(const struct helpmenuentry *menu, int key);
|
||||
void displayerror(const char *str);
|
||||
|
||||
void redrawall();
|
||||
void redrawitemsrange(int start /*inclusive*/, int end /*exclusive*/);
|
||||
void redraw1item(int index);
|
||||
void refreshlist();
|
||||
void refreshinfo();
|
||||
void refreshcolheads();
|
||||
void setcursor(int index);
|
||||
|
||||
void itd_keys();
|
||||
|
||||
virtual void redraw1itemsel(int index, int selected) =0;
|
||||
virtual void redrawcolheads() =0;
|
||||
virtual void redrawthisstate() =0;
|
||||
virtual void redrawinfo() =0;
|
||||
virtual void redrawtitle() =0;
|
||||
virtual void setwidths() =0;
|
||||
virtual const char *itemname(int index) =0;
|
||||
virtual const struct helpmenuentry *helpmenulist() =0;
|
||||
|
||||
virtual bool checksearch(varbuf &str);
|
||||
virtual bool matchsearch(int index);
|
||||
void wordwrapinfo(int offset, const char *string);
|
||||
|
||||
public:
|
||||
|
||||
keybindings *bindings;
|
||||
|
||||
void kd_up();
|
||||
void kd_down();
|
||||
void kd_redraw();
|
||||
void kd_scrollon();
|
||||
void kd_scrollback();
|
||||
void kd_scrollon1();
|
||||
void kd_scrollback1();
|
||||
void kd_panon();
|
||||
void kd_panback();
|
||||
void kd_panon1();
|
||||
void kd_panback1();
|
||||
void kd_top();
|
||||
void kd_bottom();
|
||||
void kd_iscrollon();
|
||||
void kd_iscrollback();
|
||||
void kd_iscrollon1();
|
||||
void kd_iscrollback1();
|
||||
void kd_search();
|
||||
void kd_searchagain();
|
||||
void kd_help();
|
||||
|
||||
void startdisplay();
|
||||
void enddisplay();
|
||||
|
||||
explicit baselist(keybindings *);
|
||||
virtual ~baselist();
|
||||
};
|
||||
|
||||
void displayhelp(const struct helpmenuentry *menu, int key);
|
||||
|
||||
void mywerase(WINDOW *win);
|
||||
|
||||
void curseson();
|
||||
void cursesoff();
|
||||
|
||||
extern bool expertmode;
|
||||
|
||||
struct colordata {
|
||||
int fore;
|
||||
int back;
|
||||
int attr;
|
||||
};
|
||||
extern colordata color[];
|
||||
|
||||
/* Evil recommends flag variable. */
|
||||
extern bool manual_install;
|
||||
|
||||
enum urqresult {
|
||||
urqr_normal,
|
||||
urqr_fail,
|
||||
urqr_quitmenu,
|
||||
};
|
||||
enum quitaction {
|
||||
qa_noquit,
|
||||
qa_quitchecksave,
|
||||
qa_quitnochecksave,
|
||||
};
|
||||
|
||||
typedef urqresult urqfunction(void);
|
||||
urqfunction urq_list, urq_quit, urq_menu;
|
||||
urqfunction urq_setup, urq_update, urq_install, urq_config, urq_remove;
|
||||
|
||||
#endif /* DSELECT_H */
|
217
dselect/helpmsgs.cc
Normal file
217
dselect/helpmsgs.cc
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* helpmsgs.cc - list of help messages
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
|
||||
#include "helpmsgs.h"
|
||||
|
||||
const struct helpmessage hlp_listkeys = {
|
||||
N_("Keystrokes"), N_("\
|
||||
Motion keys: Next/Previous, Top/End, Up/Down, Backwards/Forwards:\n\
|
||||
j, Down-arrow k, Up-arrow move highlight\n\
|
||||
N, Page-down, Space P, Page-up, Backspace scroll list by 1 page\n\
|
||||
^n ^p scroll list by 1 line\n\
|
||||
t, Home e, End jump to top/end of list\n\
|
||||
u d scroll info by 1 page\n\
|
||||
^u ^d scroll info by 1 line\n\
|
||||
B, Left-arrow F, Right-arrow pan display by 1/3 screen\n\
|
||||
^b ^f pan display by 1 character\n\n\
|
||||
\
|
||||
Mark packages for later processing:\n\
|
||||
+, Insert install or upgrade =, H hold in present version\n\
|
||||
-, Delete remove :, G unhold: upgrade or leave uninstalled\n\
|
||||
_ remove & purge config\n\
|
||||
Miscellaneous:\n\
|
||||
Quit, exit, overwrite (note capitals!): ?, F1 request help (also Help)\n\
|
||||
Return Confirm, quit (check dependencies) i, I toggle/cycle info displays\n\
|
||||
Q Confirm, quit (override dep.s) o, O cycle through sort options\n\
|
||||
X, Esc eXit, abandoning any changes made v, A, V change status display opts\n\
|
||||
R Revert to state before this list ^l redraw display\n\
|
||||
U set all to sUggested state / search (Return to cancel)\n\
|
||||
D set all to Directly requested state n, \\ repeat last search\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_mainintro = {
|
||||
N_("Introduction to package selections"), N_("\
|
||||
Welcome to dselect's main package listing.\n\n\
|
||||
\
|
||||
You will be presented with a list of packages which are installed or available\n\
|
||||
for installation. You can navigate around the list using the cursor keys,\n\
|
||||
mark packages for installation (using '+') or deinstallation (using '-').\n\
|
||||
Packages can be marked either singly or in groups; initially you will see that\n\
|
||||
the line 'All packages' is selected. '+', '-' and so on will affect all the\n\
|
||||
packages described by the highlighted line.\n\n\
|
||||
\
|
||||
Some of your choices will cause conflicts or dependency problems; you will be\n\
|
||||
given a sub-list of the relevant packages, so that you can solve the problems.\n\n\
|
||||
\
|
||||
You should read the list of keys and the explanations of the display.\n\
|
||||
Much on-line help is available, please make use of it - press '?' at\n\
|
||||
any time for help.\n\n\
|
||||
\
|
||||
When you have finished selecting packages, press <enter> to confirm changes,\n\
|
||||
or 'X' to quit without saving changes. A final check on conflicts and\n\
|
||||
dependencies will be done - here too you may see a sublist.\n\n\
|
||||
\
|
||||
Press <space> to leave help and enter the list now.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_readonlyintro = {
|
||||
N_("Introduction to read-only package list browser"), N_("\
|
||||
Welcome to dselect's main package listing.\n\n\
|
||||
\
|
||||
You will be presented with a list of packages which are installed or available\n\
|
||||
for installation. Since you do not have the privilege necessary to update\n\
|
||||
package states, you are in a read-only mode. You can navigate around the\n\
|
||||
list using the cursor keys (please see the 'Keystrokes' help screen), observe\n\
|
||||
the status of the packages and read information about them.\n\n\
|
||||
\
|
||||
You should read the list of keys and the explanations of the display.\n\
|
||||
Much on-line help is available, please make use of it - press '?' at\n\
|
||||
any time for help.\n\n\
|
||||
\
|
||||
When you have finished browsing, press 'Q' or <enter> to quit.\n\n\
|
||||
\
|
||||
Press <space> to leave help and enter the list now.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_recurintro = {
|
||||
N_("Introduction to conflict/dependency resolution sub-list"), N_("\
|
||||
Dependency/conflict resolution - introduction.\n\n\
|
||||
\
|
||||
One or more of your choices have raised a conflict or dependency problem -\n\
|
||||
some packages should only be installed in conjunction with certain others, and\n\
|
||||
some combinations of packages may not be installed together.\n\n\
|
||||
\
|
||||
You will see a sub-list containing the packages involved. The bottom half of\n\
|
||||
the display shows relevant conflicts and dependencies; use 'i' to cycle between\n\
|
||||
that, the package descriptions and the internal control information.\n\n\
|
||||
\
|
||||
A set of 'suggested' packages has been calculated, and the initial markings in\n\
|
||||
this sub-list have been set to match those, so you can just hit Return to\n\
|
||||
accept the suggestions if you wish. You may abort the change(s) which caused\n\
|
||||
the problem(s), and go back to the main list, by pressing capital 'X'.\n\n\
|
||||
\
|
||||
You can also move around the list and change the markings so that they are more\n\
|
||||
like what you want, and you can 'reject' my suggestions by using the capital\n\
|
||||
'D' or 'R' keys (see the keybindings help screen). You can use capital 'Q' to\n\
|
||||
force to accept the situation currently displayed, in case you want to\n\
|
||||
override a recommendation or think that the program is mistaken.\n\n\
|
||||
\
|
||||
Press <space> to leave help and enter the sub-list; remember: press '?' for help.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_displayexplain1 = {
|
||||
N_("Display, part 1: package listing and status chars"), N_("\
|
||||
The top half of the screen shows a list of packages. For each package you see\n\
|
||||
four columns for its current status on the system and mark. In terse mode (use\n\
|
||||
'v' to toggle verbose display) these are single characters, from left to right:\n\n\
|
||||
\
|
||||
Error flag: Space - no error (but package may be in broken state - see below)\n\
|
||||
'R' - serious error during installation, needs reinstallation;\n\
|
||||
Installed state: Space - not installed;\n\
|
||||
'*' - installed;\n\
|
||||
'-' - not installed but config files remain;\n\
|
||||
packages in these { 'U' - unpacked but not yet configured;\n\
|
||||
states are not { 'C' - half-configured (an error happened);\n\
|
||||
(quite) properly { 'I' - half-installed (an error happened);\n\
|
||||
installed { 'W','t' - triggers are awaited resp. pending.\n\
|
||||
Old mark: what was requested for this package before presenting this list;\n\
|
||||
Mark: what is requested for this package:\n\
|
||||
'*': marked for installation or upgrade;\n\
|
||||
'-': marked for removal, but any configuration files will remain;\n\
|
||||
'=': on hold: package will not be installed, upgraded or removed;\n\
|
||||
'_': marked for purge completely - even remove configuration;\n\
|
||||
'n': package is new and has yet to be marked for install/remove/&c.\n\n\
|
||||
\
|
||||
Also displayed are each package's Priority, Section, name, installed and\n\
|
||||
available version numbers (shift-V to display/hide) and summary description.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_displayexplain2 = {
|
||||
N_("Display, part 2: list highlight; information display"), N_("\
|
||||
* Highlight: One line in the package list will be highlighted. It indicates\n\
|
||||
which package(s) will be affected by presses of '+', '-' and '_'.\n\n\
|
||||
\
|
||||
* The dividing line in the middle of the screen shows a brief explanation of\n\
|
||||
the status of the currently-highlighted package, or a description of which\n\
|
||||
group is highlighted if a group line is. If you don't understand the\n\
|
||||
meaning of some of the status characters displayed, go to the relevant\n\
|
||||
package and look at this divider line, or use the 'v' key for a verbose\n\
|
||||
display (press 'v' again to go back to the terse display).\n\n\
|
||||
\
|
||||
* The bottom of the screen shows more information about the\n\
|
||||
currently-highlighted package (if there is only one).\n\n\
|
||||
\
|
||||
It can show an extended description of the package, the internal package\n\
|
||||
control details (either for the installed or available version of the\n\
|
||||
package), or information about conflicts and dependencies involving the\n\
|
||||
current package (in conflict/dependency resolution sublists).\n\n\
|
||||
\
|
||||
Use the 'i' key to cycle through the displays, and 'I' to hide the\n\
|
||||
information display or expand it to use almost all of the screen.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_methintro = {
|
||||
N_("Introduction to method selection display"), N_("\
|
||||
dselect and dpkg can do automatic installation, loading the package files to be\n\
|
||||
installed from one of a number of different possible places.\n\n\
|
||||
\
|
||||
This list allows you to select one of these installation methods.\n\n\
|
||||
\
|
||||
Move the highlight to the method you wish to use, and hit Enter. You will then\n\
|
||||
be prompted for the information required to do the installation.\n\n\
|
||||
\
|
||||
As you move the highlight a description of each method, where available, is\n\
|
||||
displayed in the bottom half of the screen.\n\n\
|
||||
\
|
||||
If you wish to quit without changing anything use the 'x' key while in the list\n\
|
||||
of installation methods.\n\n\
|
||||
\
|
||||
A full list of keystrokes is available by pressing 'k' now, or from the help\n\
|
||||
menu reachable by pressing '?'.\n")
|
||||
};
|
||||
|
||||
const struct helpmessage hlp_methkeys = {
|
||||
N_("Keystrokes for method selection"), N_("\
|
||||
Motion keys: Next/Previous, Top/End, Up/Down, Backwards/Forwards:\n\
|
||||
j, Down-arrow k, Up-arrow move highlight\n\
|
||||
N, Page-down, Space P, Page-up, Backspace scroll list by 1 page\n\
|
||||
^n ^p scroll list by 1 line\n\
|
||||
t, Home e, End jump to top/end of list\n\
|
||||
u d scroll info by 1 page\n\
|
||||
^u ^d scroll info by 1 line\n\
|
||||
B, Left-arrow F, Right-arrow pan display by 1/3 screen\n\
|
||||
^b ^f pan display by 1 character\n\
|
||||
(These are the same motion keys as in the package list display.)\n\n\
|
||||
\
|
||||
Quit:\n\
|
||||
Return, Enter select this method and go to its configuration dialogue\n\
|
||||
x, X exit without changing or setting up the installation method\n\n\
|
||||
\
|
||||
Miscellaneous:\n\
|
||||
?, Help, F1 request help\n\
|
||||
^l redraw display\n\
|
||||
/ search (just return to cancel)\n\
|
||||
\\ repeat last search\n")
|
||||
};
|
38
dselect/helpmsgs.h
Normal file
38
dselect/helpmsgs.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* helpmsgs.h - external definitions for the list of help messages
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HELPMSGS_H
|
||||
#define HELPMSGS_H
|
||||
|
||||
struct helpmessage {
|
||||
const char *title;
|
||||
const char *text;
|
||||
};
|
||||
|
||||
extern const struct helpmessage hlp_listkeys;
|
||||
extern const struct helpmessage hlp_mainintro;
|
||||
extern const struct helpmessage hlp_readonlyintro;
|
||||
extern const struct helpmessage hlp_recurintro;
|
||||
extern const struct helpmessage hlp_displayexplain1;
|
||||
extern const struct helpmessage hlp_displayexplain2;
|
||||
extern const struct helpmessage hlp_methintro;
|
||||
extern const struct helpmessage hlp_methkeys;
|
||||
|
||||
#endif /* HELPMSGS_H */
|
58
dselect/keyoverride
Normal file
58
dselect/keyoverride
Normal file
|
@ -0,0 +1,58 @@
|
|||
# dselect - Debian package maintenance user interface
|
||||
# keyoverride - override strings for ncurses key names
|
||||
#
|
||||
# Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
#
|
||||
# This 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 is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
32 Space
|
||||
13 Return
|
||||
27 Escape
|
||||
28 ^\
|
||||
29 ^]
|
||||
30 ^^
|
||||
31 ^_
|
||||
34 Quote
|
||||
39 Apostrophe
|
||||
44 Comma
|
||||
45 Hyphen
|
||||
47 Slash
|
||||
59 Semicolon
|
||||
92 Backslash
|
||||
96 Backquote
|
||||
127 DEL
|
||||
KEY_UP Up
|
||||
KEY_DOWN Down
|
||||
KEY_RIGHT Right
|
||||
KEY_LEFT Left
|
||||
KEY_IC Insert
|
||||
KEY_SIC Shift Insert
|
||||
KEY_DC Delete
|
||||
KEY_SDC Shift Delete
|
||||
KEY_NPAGE Page Down
|
||||
KEY_PPAGE Page Up
|
||||
KEY_CATAB Clear Tabs
|
||||
KEY_EIC EIC
|
||||
KEY_EOL EOL
|
||||
KEY_SEOL Shift EOL
|
||||
KEY_EOS EOS
|
||||
KEY_LL Bottom
|
||||
KEY_SF Scroll Forward
|
||||
KEY_SR Scroll Reverse
|
||||
KEY_SRESET Soft Reset
|
||||
KEY_SLEFT Shift Left
|
||||
KEY_SRIGHT Shift Right
|
||||
KEY_SPREVIOUS Shift Previous
|
||||
KEY_MAX [elide]
|
||||
KEY_MIN [elide]
|
567
dselect/main.cc
Normal file
567
dselect/main.cc
Normal file
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* main.cc - main program
|
||||
*
|
||||
* Copyright © 1994-1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2000,2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
* Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Solaris requires curses.h to be included before term.h
|
||||
#include "dselect-curses.h"
|
||||
|
||||
#if defined(HAVE_NCURSESW_TERM_H)
|
||||
#include <ncursesw/term.h>
|
||||
#elif defined(HAVE_NCURSES_TERM_H)
|
||||
#include <ncurses/term.h>
|
||||
#else
|
||||
#include <term.h>
|
||||
#endif
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
#include <dpkg/options.h>
|
||||
#include <dpkg/fsys.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
#include "pkglist.h"
|
||||
|
||||
static const char printforhelp[] = N_("Type dselect --help for help.");
|
||||
|
||||
bool expertmode = false;
|
||||
|
||||
static keybindings packagelistbindings(packagelist_kinterps,packagelist_korgbindings);
|
||||
|
||||
struct table_t {
|
||||
const char *name;
|
||||
const int num;
|
||||
};
|
||||
|
||||
static const struct table_t colortable[] = {
|
||||
{"black", COLOR_BLACK },
|
||||
{"red", COLOR_RED },
|
||||
{"green", COLOR_GREEN },
|
||||
{"yellow", COLOR_YELLOW },
|
||||
{"blue", COLOR_BLUE },
|
||||
{"magenta", COLOR_MAGENTA },
|
||||
{"cyan", COLOR_CYAN },
|
||||
{"white", COLOR_WHITE },
|
||||
{nullptr, 0},
|
||||
};
|
||||
|
||||
static const struct table_t attrtable[]= {
|
||||
{"normal", A_NORMAL },
|
||||
{"standout", A_STANDOUT },
|
||||
{"underline", A_UNDERLINE },
|
||||
{"reverse", A_REVERSE },
|
||||
{"blink", A_BLINK },
|
||||
{"bright", A_BLINK }, // on some terminals
|
||||
{"dim", A_DIM },
|
||||
{"bold", A_BOLD },
|
||||
{nullptr, 0},
|
||||
};
|
||||
|
||||
/* A slightly confusing mapping from dselect's internal names to
|
||||
* the user-visible names.*/
|
||||
static const struct table_t screenparttable[]= {
|
||||
{"list", list },
|
||||
{"listsel", listsel },
|
||||
{"title", title },
|
||||
{"infohead", thisstate },
|
||||
{"pkgstate", selstate },
|
||||
{"pkgstatesel", selstatesel },
|
||||
{"listhead", colheads },
|
||||
{"query", query },
|
||||
{"info", info_body },
|
||||
{"infodesc", info_head },
|
||||
{"infofoot", whatinfo },
|
||||
{"helpscreen", helpscreen },
|
||||
{nullptr, 0},
|
||||
};
|
||||
|
||||
/* Original colors. */
|
||||
struct colordata color[]= {
|
||||
/* fore back attr */
|
||||
{COLOR_WHITE, COLOR_BLACK, 0 }, // default, not used
|
||||
{COLOR_WHITE, COLOR_BLACK, 0 }, // list
|
||||
{COLOR_WHITE, COLOR_BLACK, A_REVERSE }, // listsel
|
||||
{COLOR_WHITE, COLOR_RED, 0 }, // title
|
||||
{COLOR_WHITE, COLOR_BLUE, 0 }, // thisstate
|
||||
{COLOR_WHITE, COLOR_BLACK, A_BOLD }, // selstate
|
||||
{COLOR_WHITE, COLOR_BLACK, A_REVERSE | A_BOLD }, // selstatesel
|
||||
{COLOR_WHITE, COLOR_BLUE, 0 }, // colheads
|
||||
{COLOR_WHITE, COLOR_RED, 0 }, // query
|
||||
{COLOR_WHITE, COLOR_BLACK, 0 }, // info_body
|
||||
{COLOR_WHITE, COLOR_BLACK, A_BOLD }, // info_head
|
||||
{COLOR_WHITE, COLOR_BLUE, 0 }, // whatinfo
|
||||
{COLOR_WHITE, COLOR_BLACK, 0 }, // help
|
||||
};
|
||||
|
||||
struct menuentry {
|
||||
const char *command;
|
||||
const char *key;
|
||||
const char *option;
|
||||
const char *menuent;
|
||||
urqfunction *fn;
|
||||
};
|
||||
|
||||
static const menuentry menuentries[]= {
|
||||
{ "access", N_("a"), N_("[A]ccess"), N_("Choose the access method to use."), &urq_setup },
|
||||
{ "update", N_("u"), N_("[U]pdate"), N_("Update list of available packages, if possible."), &urq_update },
|
||||
{ "select", N_("s"), N_("[S]elect"), N_("Request which packages you want on your system."), &urq_list },
|
||||
{ "install", N_("i"), N_("[I]nstall"),N_("Install and upgrade wanted packages."), &urq_install },
|
||||
{ "config", N_("c"), N_("[C]onfig"), N_("Configure any packages that are unconfigured."), &urq_config },
|
||||
{ "remove", N_("r"), N_("[R]emove"), N_("Remove unwanted software."), &urq_remove },
|
||||
{ "quit", N_("q"), N_("[Q]uit"), N_("Quit dselect."), &urq_quit },
|
||||
{ nullptr, nullptr, N_("menu"), nullptr, &urq_menu },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const char programdesc[]=
|
||||
N_("Debian '%s' package handling frontend version %s.\n");
|
||||
|
||||
static const char licensestring[]= N_(
|
||||
"This is free software; see the GNU General Public License version 2 or\n"
|
||||
"later for copying conditions. There is NO warranty.\n");
|
||||
|
||||
static void DPKG_ATTR_NORET
|
||||
printversion(const struct cmdinfo *ci, const char *value)
|
||||
{
|
||||
printf(gettext(programdesc), DSELECT, PACKAGE_RELEASE);
|
||||
printf("%s", gettext(licensestring));
|
||||
|
||||
m_output(stdout, _("<standard output>"));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void DPKG_ATTR_NORET
|
||||
usage(const struct cmdinfo *ci, const char *value)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf(_(
|
||||
"Usage: %s [<option>...] [<command>...]\n"
|
||||
"\n"), DSELECT);
|
||||
|
||||
printf(_("Commands:\n"));
|
||||
for (i = 0; menuentries[i].command; i++)
|
||||
printf(" %-10s %s\n", menuentries[i].command, menuentries[i].menuent);
|
||||
fputs("\n", stdout);
|
||||
|
||||
printf(_(
|
||||
"Options:\n"
|
||||
" --admindir <directory> Use <directory> instead of %s.\n"
|
||||
" --instdir <directory> Use <directory> instead of %s.\n"
|
||||
" --root <directory> Use <directory> instead of %s.\n"
|
||||
" --expert Turn on expert mode.\n"
|
||||
" -D, --debug <file> Turn on debugging, send output to <file>.\n"
|
||||
" --color <color-spec> Configure screen colors.\n"
|
||||
" --colour <color-spec> Ditto.\n"
|
||||
), ADMINDIR, "/", "/");
|
||||
|
||||
printf(_(
|
||||
" -?, --help Show this help message.\n"
|
||||
" --version Show the version.\n"
|
||||
"\n"));
|
||||
|
||||
printf(_("<color-spec> is <screen-part>:[<foreground>],[<background>][:<attr>[+<attr>]...]\n"));
|
||||
|
||||
printf(_("<screen-part> is:"));
|
||||
for (i=0; screenparttable[i].name; i++)
|
||||
printf(" %s", screenparttable[i].name);
|
||||
fputs("\n", stdout);
|
||||
|
||||
printf(_("<color> is:"));
|
||||
for (i = 0; colortable[i].name; i++)
|
||||
printf(" %s", colortable[i].name);
|
||||
fputs("\n", stdout);
|
||||
|
||||
printf(_("<attr> is:"));
|
||||
for (i=0; attrtable[i].name; i++)
|
||||
printf(" %s", attrtable[i].name);
|
||||
fputs("\n", stdout);
|
||||
|
||||
m_output(stdout, _("<standard output>"));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* These are called by C code, so need to have C calling convention */
|
||||
extern "C" {
|
||||
|
||||
static void
|
||||
set_debug(const struct cmdinfo*, const char *v)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(v, "a");
|
||||
if (!fp)
|
||||
ohshite(_("couldn't open debug file '%.255s'\n"), v);
|
||||
|
||||
debug_set_output(fp, v);
|
||||
debug_set_mask(dbg_general | dbg_depcon);
|
||||
}
|
||||
|
||||
static void
|
||||
set_expert(const struct cmdinfo*, const char *v)
|
||||
{
|
||||
expertmode = true;
|
||||
}
|
||||
|
||||
static int
|
||||
findintable(const struct table_t *table, const char *item, const char *tablename)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; item && (table[i].name != nullptr); i++)
|
||||
if (strcasecmp(item, table[i].name) == 0)
|
||||
return table[i].num;
|
||||
|
||||
ohshit(_("invalid %s '%s'"), tablename, item);
|
||||
}
|
||||
|
||||
/*
|
||||
* The string's format is:
|
||||
* screenpart:[forecolor][,backcolor][:[<attr>, ...]
|
||||
* Examples: --color title:black,cyan:bright+underline
|
||||
* --color list:red,yellow
|
||||
* --color colheads:,green:bright
|
||||
* --color selstate::reverse // doesn't work FIXME
|
||||
*/
|
||||
static void
|
||||
set_color(const struct cmdinfo*, const char *string)
|
||||
{
|
||||
char *s;
|
||||
char *colors, *attributes;
|
||||
int screenpart;
|
||||
|
||||
s = m_strdup(string); // strtok modifies strings, keep string const
|
||||
screenpart= findintable(screenparttable, strtok(s, ":"), _("screen part"));
|
||||
colors = strtok(nullptr, ":");
|
||||
attributes = strtok(nullptr, ":");
|
||||
|
||||
if ((colors == nullptr || ! strlen(colors)) &&
|
||||
(attributes == nullptr || ! strlen(attributes))) {
|
||||
ohshit(_("missing color specification"));
|
||||
}
|
||||
|
||||
if (colors != nullptr && strlen(colors)) {
|
||||
char *colorname;
|
||||
|
||||
colorname = strtok(colors, ",");
|
||||
if (colorname != nullptr && strlen(colorname)) {
|
||||
// normalize attributes to prevent confusion
|
||||
color[screenpart].attr= A_NORMAL;
|
||||
color[screenpart].fore = findintable(colortable, colorname, _("color"));
|
||||
}
|
||||
colorname = strtok(nullptr, ",");
|
||||
if (colorname != nullptr && strlen(colorname)) {
|
||||
color[screenpart].attr= A_NORMAL;
|
||||
color[screenpart].back = findintable(colortable, colorname, _("color"));
|
||||
}
|
||||
}
|
||||
|
||||
if (attributes != nullptr && strlen(attributes)) {
|
||||
for (char *attrib = strtok(attributes, "+");
|
||||
attrib != nullptr && strlen(attrib);
|
||||
attrib = strtok(nullptr, "+")) {
|
||||
int aval;
|
||||
|
||||
aval = findintable(attrtable, attrib, _("color attribute"));
|
||||
if (aval == A_NORMAL) // set to normal
|
||||
color[screenpart].attr= aval;
|
||||
else // add to existing attribs
|
||||
color[screenpart].attr= color[screenpart].attr | aval;
|
||||
}
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
} /* End of extern "C" */
|
||||
|
||||
static const struct cmdinfo cmdinfos[]= {
|
||||
{ "admindir", 0, 1, nullptr, nullptr, set_admindir, 1 },
|
||||
{ "instdir", 0, 1, nullptr, nullptr, set_instdir, 1 },
|
||||
{ "root", 0, 1, nullptr, nullptr, set_root, 1 },
|
||||
{ "debug", 'D', 1, nullptr, nullptr, set_debug },
|
||||
{ "expert", 'E', 0, nullptr, nullptr, set_expert },
|
||||
{ "help", '?', 0, nullptr, nullptr, usage },
|
||||
{ "version", 0, 0, nullptr, nullptr, printversion },
|
||||
{ "color", 0, 1, nullptr, nullptr, set_color }, /* US spelling */
|
||||
{ "colour", 0, 1, nullptr, nullptr, set_color }, /* UK spelling */
|
||||
{ nullptr, 0, 0, nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
||||
static bool cursesareon = false;
|
||||
void curseson() {
|
||||
if (!cursesareon) {
|
||||
const char *cup, *smso;
|
||||
initscr();
|
||||
cup= tigetstr("cup");
|
||||
smso= tigetstr("smso");
|
||||
if (!cup || !smso) {
|
||||
endwin();
|
||||
if (!cup)
|
||||
fputs(_("Terminal does not appear to support cursor addressing.\n"),stderr);
|
||||
if (!smso)
|
||||
fputs(_("Terminal does not appear to support highlighting.\n"),stderr);
|
||||
fprintf(stderr,
|
||||
_("Set your TERM variable correctly, use a better terminal,\n"
|
||||
"or make do with the per-package management tool %s.\n"),
|
||||
DPKG);
|
||||
ohshit(_("terminal lacks necessary features, giving up"));
|
||||
}
|
||||
}
|
||||
cursesareon = true;
|
||||
}
|
||||
|
||||
void cursesoff() {
|
||||
if (cursesareon) {
|
||||
clear();
|
||||
refresh();
|
||||
endwin();
|
||||
}
|
||||
cursesareon = false;
|
||||
}
|
||||
|
||||
urqresult urq_list(void) {
|
||||
modstatdb_open(static_cast<modstatdb_rw>(msdbrw_writeifposs |
|
||||
msdbrw_available_readonly));
|
||||
|
||||
curseson();
|
||||
|
||||
packagelist *l= new packagelist(&packagelistbindings);
|
||||
l->resolvesuggest();
|
||||
l->display();
|
||||
delete l;
|
||||
|
||||
modstatdb_shutdown();
|
||||
|
||||
return urqr_normal;
|
||||
}
|
||||
|
||||
static void
|
||||
display_menu_entry(int i, int so)
|
||||
{
|
||||
const menuentry *me= &menuentries[i];
|
||||
|
||||
varbuf buf;
|
||||
buf.add_fmt(" %c %d. %-11.11s %-80.80s ",
|
||||
so ? '*' : ' ', i,
|
||||
gettext(me->option),
|
||||
gettext(me->menuent));
|
||||
|
||||
int x, y DPKG_ATTR_UNUSED;
|
||||
getmaxyx(stdscr,y,x);
|
||||
|
||||
attrset(so ? A_REVERSE : A_NORMAL);
|
||||
mvaddnstr(i + 2, 0, buf.str(), x - 1);
|
||||
attrset(A_NORMAL);
|
||||
}
|
||||
|
||||
static int
|
||||
refreshmenu(void)
|
||||
{
|
||||
curseson(); cbreak(); noecho(); nonl(); keypad(stdscr,TRUE);
|
||||
|
||||
int x, y DPKG_ATTR_UNUSED;
|
||||
getmaxyx(stdscr,y,x);
|
||||
|
||||
varbuf buf;
|
||||
buf.add_fmt(gettext(programdesc), DSELECT, PACKAGE_RELEASE);
|
||||
|
||||
clear();
|
||||
attrset(A_BOLD);
|
||||
mvaddnstr(0, 0, buf.str(), x - 1);
|
||||
|
||||
attrset(A_NORMAL);
|
||||
const struct menuentry *mep; int i;
|
||||
for (mep=menuentries, i=0; mep->option && mep->menuent; mep++, i++)
|
||||
display_menu_entry(i, 0);
|
||||
|
||||
attrset(A_BOLD);
|
||||
addstr(_("\n\n"
|
||||
"Move around with ^P and ^N, cursor keys, initial letters, or digits;\n"
|
||||
"Press <enter> to confirm selection. ^L redraws screen.\n\n"));
|
||||
|
||||
attrset(A_NORMAL);
|
||||
addstr(_("Copyright (C) 1994-1996 Ian Jackson.\n"
|
||||
"Copyright (C) 2000,2001 Wichert Akkerman.\n"));
|
||||
addstr(gettext(licensestring));
|
||||
|
||||
modstatdb_init();
|
||||
if (!modstatdb_can_lock())
|
||||
addstr(_("\n\n"
|
||||
"Read-only access: only preview of selections is available!"));
|
||||
modstatdb_done();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
urqresult urq_menu(void) {
|
||||
int entries, c;
|
||||
entries= refreshmenu();
|
||||
int cursor=0;
|
||||
display_menu_entry(0, 1);
|
||||
for (;;) {
|
||||
refresh();
|
||||
do {
|
||||
c= getch();
|
||||
if (c == KEY_RESIZE) {
|
||||
refreshmenu();
|
||||
display_menu_entry(cursor, 1);
|
||||
continue;
|
||||
}
|
||||
} while (c == ERR && errno == EINTR);
|
||||
if (c==ERR) {
|
||||
if(errno != 0)
|
||||
ohshite(_("failed to getch in main menu"));
|
||||
else {
|
||||
clearok(stdscr, TRUE);
|
||||
clear();
|
||||
refreshmenu();
|
||||
display_menu_entry(cursor, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (c == CTRL('n') || c == KEY_DOWN || c == ' ' || c == 'j') {
|
||||
display_menu_entry(cursor, 0);
|
||||
cursor++;
|
||||
cursor %= entries;
|
||||
display_menu_entry(cursor, 1);
|
||||
} else if (c == CTRL('p') || c == KEY_UP || c == CTRL('h') ||
|
||||
c==KEY_BACKSPACE || c==KEY_DC || c=='k') {
|
||||
display_menu_entry(cursor, 0);
|
||||
cursor += entries - 1;
|
||||
cursor %= entries;
|
||||
display_menu_entry(cursor, 1);
|
||||
} else if (c=='\n' || c=='\r' || c==KEY_ENTER) {
|
||||
clear(); refresh();
|
||||
|
||||
/* FIXME: trap errors in urq_... */
|
||||
urqresult res = menuentries[cursor].fn();
|
||||
switch (res) {
|
||||
case urqr_quitmenu:
|
||||
return urqr_quitmenu;
|
||||
case urqr_normal:
|
||||
cursor++; cursor %= entries;
|
||||
case urqr_fail:
|
||||
break;
|
||||
default:
|
||||
internerr("unknown menufn %d", res);
|
||||
}
|
||||
refreshmenu();
|
||||
display_menu_entry(cursor, 1);
|
||||
} else if (c == CTRL('l')) {
|
||||
clearok(stdscr, TRUE);
|
||||
clear();
|
||||
refreshmenu();
|
||||
display_menu_entry(cursor, 1);
|
||||
} else if (isdigit(c)) {
|
||||
char buf[2]; buf[0]=c; buf[1]=0; c=atoi(buf);
|
||||
if (c < entries) {
|
||||
display_menu_entry(cursor, 0);
|
||||
cursor = c;
|
||||
display_menu_entry(cursor, 1);
|
||||
} else {
|
||||
beep();
|
||||
}
|
||||
} else if (isalpha(c)) {
|
||||
c= tolower(c);
|
||||
int i = 0;
|
||||
while (i < entries && gettext(menuentries[i].key)[0] != c)
|
||||
i++;
|
||||
if (i < entries) {
|
||||
display_menu_entry(cursor, 0);
|
||||
cursor = i;
|
||||
display_menu_entry(cursor, 1);
|
||||
} else {
|
||||
beep();
|
||||
}
|
||||
} else {
|
||||
beep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urqresult urq_quit(void) {
|
||||
/* FIXME: check packages OK. */
|
||||
return urqr_quitmenu;
|
||||
}
|
||||
|
||||
static void
|
||||
dselect_catch_fatal_error()
|
||||
{
|
||||
cursesoff();
|
||||
catch_fatal_error();
|
||||
}
|
||||
|
||||
int
|
||||
main(int, const char *const *argv)
|
||||
{
|
||||
dpkg_locales_init(DSELECT);
|
||||
dpkg_set_progname(DSELECT);
|
||||
|
||||
push_error_context_func(dselect_catch_fatal_error, print_fatal_error, nullptr);
|
||||
|
||||
dpkg_options_load(DSELECT, cmdinfos);
|
||||
dpkg_options_parse(&argv, cmdinfos, printforhelp);
|
||||
|
||||
debug(dbg_general, "root=%s admindir=%s", dpkg_fsys_get_dir(), dpkg_db_get_dir());
|
||||
|
||||
if (*argv) {
|
||||
const char *a;
|
||||
while ((a = *argv++) != nullptr) {
|
||||
const menuentry *me = menuentries;
|
||||
while (me->command && strcmp(me->command, a))
|
||||
me++;
|
||||
if (!me->command)
|
||||
badusage(_("unknown action string '%.50s'"), a);
|
||||
me->fn();
|
||||
}
|
||||
} else {
|
||||
urq_menu();
|
||||
}
|
||||
|
||||
cursesoff();
|
||||
dpkg_program_done();
|
||||
dpkg_locales_done();
|
||||
|
||||
return(0);
|
||||
}
|
109
dselect/methkeys.cc
Normal file
109
dselect/methkeys.cc
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* methkeys.cc - method list keybindings
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
|
||||
const keybindings::interpretation methodlist_kinterps[] = {
|
||||
{ "up", &methodlist::kd_up, nullptr, qa_noquit },
|
||||
{ "down", &methodlist::kd_down, nullptr, qa_noquit },
|
||||
{ "top", &methodlist::kd_top, nullptr, qa_noquit },
|
||||
{ "bottom", &methodlist::kd_bottom, nullptr, qa_noquit },
|
||||
{ "scrollon", &methodlist::kd_scrollon, nullptr, qa_noquit },
|
||||
{ "scrollback", &methodlist::kd_scrollback, nullptr, qa_noquit },
|
||||
{ "iscrollon", &methodlist::kd_iscrollon, nullptr, qa_noquit },
|
||||
{ "iscrollback", &methodlist::kd_iscrollback, nullptr, qa_noquit },
|
||||
{ "scrollon1", &methodlist::kd_scrollon1, nullptr, qa_noquit },
|
||||
{ "scrollback1", &methodlist::kd_scrollback1, nullptr, qa_noquit },
|
||||
{ "iscrollon1", &methodlist::kd_iscrollon1, nullptr, qa_noquit },
|
||||
{ "iscrollback1", &methodlist::kd_iscrollback1, nullptr, qa_noquit },
|
||||
{ "panon", &methodlist::kd_panon, nullptr, qa_noquit },
|
||||
{ "panback", &methodlist::kd_panback, nullptr, qa_noquit },
|
||||
{ "panon1", &methodlist::kd_panon1, nullptr, qa_noquit },
|
||||
{ "panback1", &methodlist::kd_panback1, nullptr, qa_noquit },
|
||||
{ "help", &methodlist::kd_help, nullptr, qa_noquit },
|
||||
{ "search", &methodlist::kd_search, nullptr, qa_noquit },
|
||||
{ "searchagain", &methodlist::kd_searchagain, nullptr, qa_noquit },
|
||||
{ "redraw", &methodlist::kd_redraw, nullptr, qa_noquit },
|
||||
{ "select-and-quit", &methodlist::kd_quit, nullptr, qa_quitchecksave },
|
||||
{ "abort", &methodlist::kd_abort, nullptr, qa_quitnochecksave },
|
||||
{ nullptr, nullptr, nullptr, qa_noquit }
|
||||
};
|
||||
|
||||
const keybindings::orgbinding methodlist_korgbindings[]= {
|
||||
{ 'j', "down" }, // vi style
|
||||
//{ 'n', "down" }, // no style
|
||||
{ KEY_DOWN, "down" },
|
||||
{ 'k', "up" }, // vi style
|
||||
//{ 'p', "up" }, // no style
|
||||
{ KEY_UP, "up" },
|
||||
|
||||
{ CTRL('f'), "scrollon" }, // vi style
|
||||
{ 'N', "scrollon" },
|
||||
{ KEY_NPAGE, "scrollon" },
|
||||
{ ' ', "scrollon" },
|
||||
{ CTRL('b'), "scrollback" }, // vi style
|
||||
{ 'P', "scrollback" },
|
||||
{ KEY_PPAGE, "scrollback" },
|
||||
{ KEY_BACKSPACE, "scrollback" },
|
||||
{ 0177,/*DEL*/ "scrollback" },
|
||||
{ CTRL('h'), "scrollback" },
|
||||
{ CTRL('n'), "scrollon1" },
|
||||
{ CTRL('p'), "scrollback1" },
|
||||
|
||||
{ 't', "top" },
|
||||
{ KEY_HOME, "top" },
|
||||
{ 'e', "bottom" },
|
||||
{ KEY_LL, "bottom" },
|
||||
{ KEY_END, "bottom" },
|
||||
|
||||
{ 'u', "iscrollback" },
|
||||
{ 'd', "iscrollon" },
|
||||
{ CTRL('u'), "iscrollback1" },
|
||||
{ CTRL('d'), "iscrollon1" },
|
||||
|
||||
{ 'B', "panback" },
|
||||
{ KEY_LEFT, "panback" },
|
||||
{ 'F', "panon" },
|
||||
{ KEY_RIGHT, "panon" },
|
||||
{ CTRL('b'), "panback1" },
|
||||
{ CTRL('f'), "panon1" },
|
||||
|
||||
{ '?', "help" },
|
||||
{ KEY_HELP, "help" },
|
||||
{ KEY_F(1), "help" },
|
||||
{ '/', "search" },
|
||||
{ 'n', "searchagain" },
|
||||
{ '\\', "searchagain" },
|
||||
{ CTRL('l'), "redraw" },
|
||||
|
||||
{ KEY_ENTER, "select-and-quit" },
|
||||
{ '\r', "select-and-quit" },
|
||||
{ 'x', "abort" },
|
||||
{ 'X', "abort" },
|
||||
{ 'Q', "abort" },
|
||||
|
||||
{ -1, nullptr }
|
||||
};
|
229
dselect/methlist.cc
Normal file
229
dselect/methlist.cc
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* methlist.cc - list of access methods and options
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
#include <dpkg/string.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
#include "method.h"
|
||||
#include "helpmsgs.h"
|
||||
|
||||
static keybindings methodlistbindings(methodlist_kinterps,methodlist_korgbindings);
|
||||
|
||||
const char *methodlist::itemname(int index) {
|
||||
return table[index]->name.str();
|
||||
}
|
||||
|
||||
void methodlist::kd_abort() { }
|
||||
|
||||
void methodlist::kd_quit() {
|
||||
debug(dbg_general, "methodlist[%p]::kd_quit() setting coption=%p",
|
||||
this, table[cursorline]);
|
||||
coption= table[cursorline];
|
||||
}
|
||||
|
||||
void methodlist::setheights() {
|
||||
debug(dbg_general, "methodlist[%p]::setheights()", this);
|
||||
baselist::setheights();
|
||||
list_height++;
|
||||
}
|
||||
|
||||
void methodlist::setwidths() {
|
||||
debug(dbg_general, "methodlist[%p]::setwidths()", this);
|
||||
|
||||
col_cur_x = 0;
|
||||
|
||||
add_column(col_status, " ", 1);
|
||||
add_column(col_name, _("Abbrev."), 14);
|
||||
end_column(col_desc, _("Description"));
|
||||
}
|
||||
|
||||
void methodlist::redrawtitle() {
|
||||
if (title_height) {
|
||||
mywerase(titlewin);
|
||||
mvwaddnstr(titlewin,0,0,_("dselect - list of access methods"),xmax);
|
||||
wnoutrefresh(titlewin);
|
||||
}
|
||||
}
|
||||
|
||||
void methodlist::redrawthisstate() {
|
||||
if (!thisstate_height) return;
|
||||
mywerase(thisstatepad);
|
||||
wprintw(thisstatepad,
|
||||
_("Access method '%s'."),
|
||||
table[cursorline]->name.str());
|
||||
pnoutrefresh(thisstatepad, 0,0, thisstate_row,0,
|
||||
thisstate_row, min(total_width - 1, xmax - 1));
|
||||
}
|
||||
|
||||
void methodlist::redraw1itemsel(int index, int selected) {
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
wattrset(listpad, part_attr[selected ? listsel : list]);
|
||||
mvwaddch(listpad,index,0,
|
||||
table[index] == coption ? '*' : ' ');
|
||||
wattrset(listpad, part_attr[selected ? listsel : list]);
|
||||
draw_column_sep(col_name, index);
|
||||
draw_column_item(col_name, index, table[index]->name.str());
|
||||
|
||||
draw_column_sep(col_desc, index);
|
||||
i = col_desc.width;
|
||||
p = table[index]->summary.str();
|
||||
while (i>0 && *p && *p != '\n') {
|
||||
waddch(listpad,*p);
|
||||
i--; p++;
|
||||
}
|
||||
while (i>0) {
|
||||
waddch(listpad,' ');
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
void methodlist::redrawcolheads() {
|
||||
if (colheads_height) {
|
||||
wattrset(colheadspad, part_attr[colheads]);
|
||||
mywerase(colheadspad);
|
||||
draw_column_head(col_status);
|
||||
draw_column_head(col_name);
|
||||
draw_column_head(col_desc);
|
||||
}
|
||||
refreshcolheads();
|
||||
}
|
||||
|
||||
methodlist::methodlist() : baselist(&methodlistbindings) {
|
||||
int newcursor= -1;
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::methodlist()", this);
|
||||
|
||||
table= new struct dselect_option*[noptions];
|
||||
|
||||
struct dselect_option *opt, **ip;
|
||||
for (opt=options, ip=table, nitems=0; opt; opt=opt->next, nitems++) {
|
||||
if (opt == coption) {
|
||||
if (newcursor != -1)
|
||||
internerr("multiple methods with same index");
|
||||
newcursor = nitems;
|
||||
}
|
||||
*ip++= opt;
|
||||
}
|
||||
if (nitems != noptions)
|
||||
internerr("inconsistent number of items: ntimes=%d != noptions=%d",
|
||||
nitems, noptions);
|
||||
|
||||
if (newcursor==-1) newcursor= 0;
|
||||
setcursor(newcursor);
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::methodlist done; noptions=%d",
|
||||
this, noptions);
|
||||
}
|
||||
|
||||
methodlist::~methodlist() {
|
||||
debug(dbg_general, "methodlist[%p]::~methodlist()", this);
|
||||
delete[] table;
|
||||
}
|
||||
|
||||
quitaction methodlist::display() {
|
||||
int response;
|
||||
const keybindings::interpretation *interp;
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::display()", this);
|
||||
|
||||
startdisplay();
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::display() entering loop", this);
|
||||
for (;;) {
|
||||
if (whatinfo_height) wcursyncup(whatinfowin);
|
||||
if (doupdate() == ERR) ohshite(_("doupdate failed"));
|
||||
do {
|
||||
response = getch();
|
||||
if (response == KEY_RESIZE) {
|
||||
resize_window();
|
||||
continue;
|
||||
}
|
||||
} while (response == ERR && errno == EINTR);
|
||||
if (response == ERR) ohshite(_("getch failed"));
|
||||
interp= (*bindings)(response);
|
||||
debug(dbg_general, "methodlist[%p]::display() response=%d interp=%s",
|
||||
this, response, interp ? interp->action : "[none]");
|
||||
if (!interp)
|
||||
continue;
|
||||
(this->*(interp->mfn))();
|
||||
if (interp->qa != qa_noquit) break;
|
||||
}
|
||||
enddisplay();
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::display() done", this);
|
||||
|
||||
return interp->qa;
|
||||
}
|
||||
|
||||
void methodlist::itd_description() {
|
||||
whatinfovb += _("Explanation");
|
||||
|
||||
wattrset(infopad, part_attr[info_head]);
|
||||
waddstr(infopad, table[cursorline]->name.str());
|
||||
waddstr(infopad," - ");
|
||||
waddstr(infopad, table[cursorline]->summary.str());
|
||||
wattrset(infopad, part_attr[info_body]);
|
||||
|
||||
const char *m = table[cursorline]->description.str();
|
||||
if (str_is_unset(m))
|
||||
m = _("No explanation available.");
|
||||
waddstr(infopad,"\n\n");
|
||||
wordwrapinfo(0,m);
|
||||
}
|
||||
|
||||
void methodlist::redrawinfo() {
|
||||
if (!info_height) return;
|
||||
whatinfovb.reset();
|
||||
werase(infopad); wmove(infopad,0,0);
|
||||
|
||||
debug(dbg_general, "methodlist[%p]::redrawinfo()", this);
|
||||
|
||||
itd_description();
|
||||
|
||||
int y,x;
|
||||
getyx(infopad, y,x);
|
||||
if (x) y++;
|
||||
infolines= y;
|
||||
|
||||
refreshinfo();
|
||||
}
|
||||
|
||||
const struct helpmenuentry *methodlist::helpmenulist() {
|
||||
static const struct helpmenuentry list[]= {
|
||||
{ 'i', &hlp_methintro },
|
||||
{ 'k', &hlp_methkeys },
|
||||
{ 0 }
|
||||
};
|
||||
return list;
|
||||
}
|
260
dselect/method.cc
Normal file
260
dselect/method.cc
Normal file
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* method.cc - access method handling
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2001,2002 Wichert Akkerman <wakkerma@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
#include <dpkg/subproc.h>
|
||||
#include <dpkg/command.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "method.h"
|
||||
|
||||
static const char *const methoddirectories[]= {
|
||||
LIBDIR "/" METHODSDIR,
|
||||
LOCALLIBDIR "/" METHODSDIR,
|
||||
nullptr
|
||||
};
|
||||
|
||||
static char *methodlockfile = nullptr;
|
||||
static int methlockfd= -1;
|
||||
|
||||
static void
|
||||
sthfailed(const char * reasoning)
|
||||
{
|
||||
curseson();
|
||||
clear();
|
||||
printw("\n\n%s: %s\n", DSELECT, reasoning);
|
||||
attrset(A_BOLD);
|
||||
addstr(_("\nPress <enter> to continue."));
|
||||
attrset(A_NORMAL);
|
||||
refresh(); getch();
|
||||
}
|
||||
|
||||
static void cu_unlockmethod(int, void**) {
|
||||
struct flock fl;
|
||||
|
||||
if (methodlockfile == nullptr)
|
||||
internerr("method lock file is nullptr");
|
||||
if (methlockfd < 0)
|
||||
internerr("method lock fd is %d < 0", methlockfd);
|
||||
fl.l_type=F_UNLCK; fl.l_whence= SEEK_SET; fl.l_start=fl.l_len=0;
|
||||
if (fcntl(methlockfd, F_SETLK, &fl) < 0)
|
||||
sthfailed(_("cannot unlock access method area"));
|
||||
}
|
||||
|
||||
static enum urqresult ensureoptions(void) {
|
||||
dselect_option *newoptions;
|
||||
int nread;
|
||||
|
||||
if (!options) {
|
||||
newoptions = nullptr;
|
||||
nread= 0;
|
||||
for (const char *const *ccpp = methoddirectories; *ccpp; ccpp++)
|
||||
readmethods(*ccpp, &newoptions, &nread);
|
||||
if (!newoptions) {
|
||||
sthfailed(_("no access methods are available"));
|
||||
return urqr_fail;
|
||||
}
|
||||
options= newoptions;
|
||||
noptions= nread;
|
||||
}
|
||||
return urqr_normal;
|
||||
}
|
||||
|
||||
static enum urqresult lockmethod(void) {
|
||||
struct flock fl;
|
||||
|
||||
if (methodlockfile == nullptr)
|
||||
methodlockfile = dpkg_db_get_path(METHLOCKFILE);
|
||||
|
||||
if (methlockfd < 0) {
|
||||
methlockfd= open(methodlockfile, O_RDWR|O_CREAT|O_TRUNC, 0660);
|
||||
if (methlockfd < 0) {
|
||||
if ((errno == EPERM) || (errno == EACCES)) {
|
||||
sthfailed(_("requested operation requires superuser privilege"));
|
||||
return urqr_fail;
|
||||
}
|
||||
sthfailed(_("cannot open or create access method lockfile"));
|
||||
return urqr_fail;
|
||||
}
|
||||
}
|
||||
fl.l_type=F_WRLCK; fl.l_whence=SEEK_SET; fl.l_start=fl.l_len=0;
|
||||
if (fcntl(methlockfd, F_SETLK, &fl) < 0) {
|
||||
if (errno == EACCES || errno == EAGAIN) {
|
||||
sthfailed(_("the access method area is already locked"));
|
||||
return urqr_fail;
|
||||
}
|
||||
sthfailed(_("cannot lock access method area"));
|
||||
return urqr_fail;
|
||||
}
|
||||
push_cleanup(cu_unlockmethod, ~0, 0);
|
||||
return urqr_normal;
|
||||
}
|
||||
|
||||
static urqresult
|
||||
falliblesubprocess(struct command *cmd)
|
||||
{
|
||||
pid_t pid;
|
||||
int i, c;
|
||||
|
||||
cursesoff();
|
||||
|
||||
subproc_signals_ignore(cmd->name);
|
||||
|
||||
pid = subproc_fork();
|
||||
if (pid == 0) {
|
||||
subproc_signals_cleanup(0, nullptr);
|
||||
command_exec(cmd);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
i = subproc_reap(pid, cmd->name, SUBPROC_WARN);
|
||||
|
||||
subproc_signals_restore();
|
||||
|
||||
if (i == 0) {
|
||||
sleep(1);
|
||||
return urqr_normal;
|
||||
}
|
||||
fprintf(stderr,_("Press <enter> to continue.\n"));
|
||||
m_output(stderr, _("<standard error>"));
|
||||
do {
|
||||
c = fgetc(stdin);
|
||||
} while ((c == EOF && errno == EINTR) || (c != '\n' && c != EOF));
|
||||
if (c == EOF)
|
||||
ohshite(_("error reading acknowledgement of program failure message"));
|
||||
return urqr_fail;
|
||||
}
|
||||
|
||||
static urqresult runscript(const char *exepath, const char *name) {
|
||||
urqresult ur;
|
||||
|
||||
ur= ensureoptions(); if (ur != urqr_normal) return ur;
|
||||
ur=lockmethod(); if (ur != urqr_normal) return ur;
|
||||
getcurrentopt();
|
||||
|
||||
if (coption) {
|
||||
struct command cmd;
|
||||
varbuf cmdpath;
|
||||
|
||||
cmdpath += coption->meth->path;
|
||||
cmdpath += exepath;
|
||||
|
||||
command_init(&cmd, cmdpath.str(), name);
|
||||
command_add_args(&cmd, exepath, dpkg_db_get_dir(),
|
||||
coption->meth->name.str(), coption->name.str(), nullptr);
|
||||
ur = falliblesubprocess(&cmd);
|
||||
command_destroy(&cmd);
|
||||
} else {
|
||||
sthfailed(_("no access method is selected or configured"));
|
||||
ur= urqr_fail;
|
||||
}
|
||||
pop_cleanup(ehflag_normaltidy);
|
||||
|
||||
return ur;
|
||||
}
|
||||
|
||||
urqresult urq_update(void) {
|
||||
return runscript(METHODUPDATESCRIPT,_("update available list script"));
|
||||
}
|
||||
|
||||
urqresult urq_install(void) {
|
||||
return runscript(METHODINSTALLSCRIPT,_("installation script"));
|
||||
}
|
||||
|
||||
static urqresult rundpkgauto(const char *name, const char *dpkgmode) {
|
||||
urqresult ur;
|
||||
struct command cmd;
|
||||
|
||||
command_init(&cmd, DPKG, name);
|
||||
command_add_args(&cmd, DPKG, "--admindir", dpkg_db_get_dir(), "--pending",
|
||||
dpkgmode, nullptr);
|
||||
|
||||
cursesoff();
|
||||
printf(_("running %s %s ...\n"), "dpkg --pending", dpkgmode);
|
||||
fflush(stdout);
|
||||
ur = falliblesubprocess(&cmd);
|
||||
command_destroy(&cmd);
|
||||
|
||||
return ur;
|
||||
}
|
||||
|
||||
urqresult urq_remove(void) {
|
||||
return rundpkgauto("dpkg --remove","--remove");
|
||||
}
|
||||
|
||||
urqresult urq_config(void) {
|
||||
return rundpkgauto("dpkg --configure","--configure");
|
||||
}
|
||||
|
||||
urqresult urq_setup(void) {
|
||||
quitaction qa;
|
||||
urqresult ur;
|
||||
|
||||
ur= ensureoptions(); if (ur != urqr_normal) return ur;
|
||||
ur=lockmethod(); if (ur != urqr_normal) return ur;
|
||||
getcurrentopt();
|
||||
|
||||
curseson();
|
||||
methodlist *l= new methodlist();
|
||||
qa= l->display();
|
||||
delete l;
|
||||
|
||||
if (qa == qa_quitchecksave) {
|
||||
struct command cmd;
|
||||
varbuf cmdpath;
|
||||
|
||||
cmdpath += coption->meth->path;
|
||||
cmdpath += METHODSETUPSCRIPT;
|
||||
|
||||
command_init(&cmd, cmdpath.str(), _("query/setup script"));
|
||||
command_add_args(&cmd, METHODSETUPSCRIPT, dpkg_db_get_dir(),
|
||||
coption->meth->name.str(), coption->name.str(), nullptr);
|
||||
ur = falliblesubprocess(&cmd);
|
||||
command_destroy(&cmd);
|
||||
if (ur == urqr_normal) writecurrentopt();
|
||||
} else {
|
||||
ur= urqr_fail;
|
||||
}
|
||||
|
||||
pop_cleanup(ehflag_normaltidy);
|
||||
return ur;
|
||||
}
|
96
dselect/method.h
Normal file
96
dselect/method.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* method.h - access method handling declarations
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef METHOD_H
|
||||
#define METHOD_H
|
||||
|
||||
#define CMETHOPTFILE "cmethopt"
|
||||
#define METHLOCKFILE "methlock"
|
||||
|
||||
#define METHODSDIR "methods"
|
||||
|
||||
#define IMETHODMAXLEN 50
|
||||
#define IOPTIONMAXLEN IMETHODMAXLEN
|
||||
#define METHODOPTIONSFILE "names"
|
||||
#define METHODSETUPSCRIPT "setup"
|
||||
#define METHODUPDATESCRIPT "update"
|
||||
#define METHODINSTALLSCRIPT "install"
|
||||
#define OPTIONSDESCPFX "desc."
|
||||
#define OPTIONINDEXMAXLEN 5
|
||||
|
||||
struct method {
|
||||
struct method *next, *prev;
|
||||
varbuf name, path;
|
||||
};
|
||||
|
||||
struct dselect_option {
|
||||
dselect_option *next;
|
||||
method *meth;
|
||||
varbuf index;
|
||||
varbuf name;
|
||||
varbuf summary;
|
||||
varbuf description;
|
||||
};
|
||||
|
||||
class methodlist : public baselist {
|
||||
protected:
|
||||
column col_status;
|
||||
column col_name;
|
||||
column col_desc;
|
||||
|
||||
// Table of methods
|
||||
struct dselect_option **table;
|
||||
|
||||
// Information displays
|
||||
void itd_description();
|
||||
|
||||
// Define these virtuals
|
||||
void redraw1itemsel(int index, int selected) override;
|
||||
void redrawcolheads() override;
|
||||
void redrawthisstate() override;
|
||||
void redrawinfo() override;
|
||||
void redrawtitle() override;
|
||||
void setwidths() override;
|
||||
void setheights() override;
|
||||
const char *itemname(int index) override;
|
||||
const struct helpmenuentry *helpmenulist() override;
|
||||
|
||||
public:
|
||||
// Keybinding functions */
|
||||
void kd_quit();
|
||||
void kd_abort();
|
||||
|
||||
methodlist();
|
||||
methodlist(const methodlist &) = delete;
|
||||
methodlist &operator =(const methodlist &) = delete;
|
||||
quitaction display();
|
||||
~methodlist() override;
|
||||
};
|
||||
|
||||
extern int noptions;
|
||||
extern struct dselect_option *options, *coption;
|
||||
extern struct method *methods;
|
||||
|
||||
void readmethods(const char *pathbase, dselect_option **optionspp, int *nread);
|
||||
void getcurrentopt();
|
||||
void writecurrentopt();
|
||||
|
||||
#endif /* METHOD_H */
|
267
dselect/methods/Dselect/Method.pm
Normal file
267
dselect/methods/Dselect/Method.pm
Normal file
|
@ -0,0 +1,267 @@
|
|||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Dselect::Method - dselect method support
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides support functions to implement methods.
|
||||
|
||||
B<Note>: This is a private module, its API can change at any time.
|
||||
|
||||
=cut
|
||||
|
||||
package Dselect::Method 0.01;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @EXPORT = qw(
|
||||
%CONFIG
|
||||
yesno
|
||||
nb
|
||||
view_mirrors
|
||||
add_site
|
||||
edit_site
|
||||
edit_config
|
||||
read_config
|
||||
store_config
|
||||
);
|
||||
|
||||
use Exporter qw(import);
|
||||
use Carp;
|
||||
|
||||
eval q{
|
||||
use Data::Dumper;
|
||||
|
||||
use Dpkg::File;
|
||||
};
|
||||
if ($@) {
|
||||
warn "Missing Dpkg modules required by the access method.\n\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
our %CONFIG;
|
||||
|
||||
sub yesno {
|
||||
my ($d, $msg) = @_;
|
||||
|
||||
my ($res, $r);
|
||||
$r = -1;
|
||||
$r = 0 if $d eq 'n';
|
||||
$r = 1 if $d eq 'y';
|
||||
croak 'incorrect usage of yesno, stopped' if $r == -1;
|
||||
while (1) {
|
||||
print $msg, " [$d]: ";
|
||||
$res = <STDIN>;
|
||||
$res =~ /^[Yy]/ and return 1;
|
||||
$res =~ /^[Nn]/ and return 0;
|
||||
$res =~ /^[ \t]*$/ and return $r;
|
||||
print "Please enter one of the letters 'y' or 'n'\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub nb {
|
||||
my $nb = shift;
|
||||
|
||||
if ($nb > 1024 ** 2) {
|
||||
return sprintf '%.2fM', $nb / 1024 ** 2;
|
||||
} elsif ($nb > 1024) {
|
||||
return sprintf '%.2fk', $nb / 1024;
|
||||
} else {
|
||||
return sprintf '%.2fb', $nb;
|
||||
}
|
||||
}
|
||||
|
||||
sub read_config {
|
||||
my $vars = shift;
|
||||
my ($code, $conf);
|
||||
|
||||
eval {
|
||||
$code = file_slurp($vars);
|
||||
};
|
||||
if ($@) {
|
||||
warn "$@\n";
|
||||
die "Try to relaunch the 'Access' step in dselect, thanks.\n";
|
||||
}
|
||||
|
||||
my $VAR1; ## no critic (Variables::ProhibitUnusedVariables)
|
||||
$conf = eval $code;
|
||||
die "couldn't eval $vars content: $@\n" if $@;
|
||||
if (ref($conf) =~ /HASH/) {
|
||||
foreach (keys %{$conf}) {
|
||||
$CONFIG{$_} = $conf->{$_};
|
||||
}
|
||||
} else {
|
||||
print "Bad $vars file : removing it.\n";
|
||||
print "Please relaunch the 'Access' step in dselect. Thanks.\n";
|
||||
unlink $vars;
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub store_config {
|
||||
my $vars = shift;
|
||||
|
||||
# Check that config is completed
|
||||
return if not $CONFIG{done};
|
||||
|
||||
file_dump($vars, Dumper(\%CONFIG));
|
||||
}
|
||||
|
||||
sub view_mirrors {
|
||||
print <<'MIRRORS';
|
||||
Please see <https://www.debian.org/mirror/list> for a current
|
||||
list of Debian mirror sites.
|
||||
MIRRORS
|
||||
}
|
||||
|
||||
sub edit_config {
|
||||
my ($method, $methdir) = @_;
|
||||
my $i;
|
||||
|
||||
# Get a config for the sites
|
||||
while (1) {
|
||||
$i = 1;
|
||||
print "\n\nList of selected $method sites :\n";
|
||||
foreach (@{$CONFIG{site}}) {
|
||||
print "$i. $method://$_->[0]$_->[1] @{$_->[2]}\n";
|
||||
$i++;
|
||||
}
|
||||
print "\nEnter a command (a=add e=edit d=delete q=quit m=mirror list) \n";
|
||||
print 'eventually followed by a site number : ';
|
||||
chomp($_ = <STDIN>);
|
||||
/q/i && last;
|
||||
/a/i && add_site($method);
|
||||
/d\s*(\d+)/i && do {
|
||||
splice(@{$CONFIG{site}}, $1 - 1, 1) if $1 <= @{$CONFIG{site}};
|
||||
next;
|
||||
};
|
||||
/e\s*(\d+)/i && do {
|
||||
edit_site($method, $CONFIG{site}[$1 - 1]) if $1 <= @{$CONFIG{site}};
|
||||
next;
|
||||
};
|
||||
/m/i && view_mirrors();
|
||||
}
|
||||
|
||||
print "\n";
|
||||
$CONFIG{use_auth_proxy} = yesno($CONFIG{use_auth_proxy} ? 'y' : 'n',
|
||||
'Go through an authenticated proxy');
|
||||
|
||||
if ($CONFIG{use_auth_proxy}) {
|
||||
print "\nEnter proxy hostname [$CONFIG{proxyhost}] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$CONFIG{proxyhost} = $_ || $CONFIG{proxyhost};
|
||||
|
||||
print "\nEnter proxy log name [$CONFIG{proxylogname}] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$CONFIG{proxylogname} = $_ || $CONFIG{proxylogname};
|
||||
|
||||
print "\nEnter proxy password [$CONFIG{proxypassword}] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$CONFIG{proxypassword} = $_ || $CONFIG{proxypassword};
|
||||
}
|
||||
|
||||
print "\nEnter directory to download binary package files to\n";
|
||||
print "(relative to $methdir)\n";
|
||||
while (1) {
|
||||
print "[$CONFIG{dldir}] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
s{/$}{};
|
||||
$CONFIG{dldir} = $_ if $_;
|
||||
last if -d "$methdir/$CONFIG{dldir}";
|
||||
print "$methdir/$CONFIG{dldir} is not a directory !\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub add_site {
|
||||
my $method = shift;
|
||||
|
||||
my $pas = 1;
|
||||
my $user = 'anonymous';
|
||||
my $email = qx(whoami);
|
||||
chomp $email;
|
||||
$email .= '@' . qx(cat /etc/mailname || dnsdomainname);
|
||||
chomp $email;
|
||||
my $dir = '/debian';
|
||||
|
||||
push @{$CONFIG{site}}, [
|
||||
'',
|
||||
$dir,
|
||||
[
|
||||
'dists/stable/main',
|
||||
'dists/stable/contrib',
|
||||
'dists/stable/non-free-firmware',
|
||||
'dists/stable/non-free',
|
||||
],
|
||||
$pas,
|
||||
$user,
|
||||
$email,
|
||||
];
|
||||
edit_site($method, $CONFIG{site}[@{$CONFIG{site}} - 1]);
|
||||
}
|
||||
|
||||
sub edit_site {
|
||||
my ($method, $site) = @_;
|
||||
|
||||
local $_;
|
||||
|
||||
print "\nEnter $method site [$site->[0]] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[0] = $_ || $site->[0];
|
||||
|
||||
print "\nUse passive mode [" . ($site->[3] ? 'y' : 'n') . '] : ';
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[3] = (/y/i ? 1 : 0) if $_;
|
||||
|
||||
print "\nEnter username [$site->[4]] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[4] = $_ || $site->[4];
|
||||
|
||||
print <<"EOF";
|
||||
|
||||
If you are using anonymous $method to retrieve files, enter your email
|
||||
address for use as a password. Otherwise enter your password,
|
||||
or "?" if you want the $method method to prompt you each time.
|
||||
|
||||
EOF
|
||||
|
||||
print "Enter password [$site->[5]] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[5] = $_ || $site->[5];
|
||||
|
||||
print "\nEnter debian directory [$site->[1]] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[1] = $_ || $site->[1];
|
||||
|
||||
print "\nEnter space separated list of distributions to get\n";
|
||||
print "[@{$site->[2]}] : ";
|
||||
chomp($_ = <STDIN>);
|
||||
$site->[2] = [ split(/\s+/) ] if $_;
|
||||
}
|
||||
|
||||
=head1 CHANGES
|
||||
|
||||
=head2 Version 0.xx
|
||||
|
||||
This is a private module.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
232
dselect/methods/Dselect/Method/Ftp.pm
Normal file
232
dselect/methods/Dselect/Method/Ftp.pm
Normal file
|
@ -0,0 +1,232 @@
|
|||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Dselect::Method::Ftp - dselect FTP method support
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides support functions for the FTP method.
|
||||
|
||||
B<Note>: This is a private module, its API can change at any time.
|
||||
|
||||
=cut
|
||||
|
||||
package Dselect::Method::Ftp 0.01;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @EXPORT = qw(
|
||||
do_connect
|
||||
do_mdtm
|
||||
);
|
||||
|
||||
use Exporter qw(import);
|
||||
use Carp;
|
||||
|
||||
eval q{
|
||||
use Net::FTP;
|
||||
use Data::Dumper;
|
||||
};
|
||||
if ($@) {
|
||||
warn "Missing Net::FTP modules required by the FTP access method.\n\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
sub do_connect {
|
||||
my (%opts) = @_;
|
||||
|
||||
my($rpass,$remotehost,$remoteuser,$ftp);
|
||||
|
||||
TRY_CONNECT:
|
||||
while(1) {
|
||||
my $exit = 0;
|
||||
|
||||
if ($opts{useproxy}) {
|
||||
$remotehost = $opts{proxyhost};
|
||||
$remoteuser = $opts{username} . '@' . $opts{ftpsite};
|
||||
} else {
|
||||
$remotehost = $opts{ftpsite};
|
||||
$remoteuser = $opts{username};
|
||||
}
|
||||
print "Connecting to $opts{ftpsite}...\n";
|
||||
$ftp = Net::FTP->new($remotehost, Passive => $opts{passive});
|
||||
if(!$ftp || !$ftp->ok) {
|
||||
print "Failed to connect\n";
|
||||
$exit = 1;
|
||||
}
|
||||
if (!$exit) {
|
||||
# $ftp->debug(1);
|
||||
if ($opts{useproxy}) {
|
||||
print "Login on $opts{proxyhost}...\n";
|
||||
$ftp->_USER($opts{proxylogname});
|
||||
$ftp->_PASS($opts{proxypassword});
|
||||
}
|
||||
print "Login as $opts{username}...\n";
|
||||
if ($opts{password} eq '?') {
|
||||
print 'Enter password for ftp: ';
|
||||
system('stty', '-echo');
|
||||
$rpass = <STDIN>;
|
||||
chomp $rpass;
|
||||
print "\n";
|
||||
system('stty', 'echo');
|
||||
} else {
|
||||
$rpass = $opts{password};
|
||||
}
|
||||
if(!$ftp->login($remoteuser, $rpass))
|
||||
{ print $ftp->message() . "\n"; $exit = 1; }
|
||||
}
|
||||
if (!$exit) {
|
||||
print "Setting transfer mode to binary...\n";
|
||||
if(!$ftp->binary()) { print $ftp->message . "\n"; $exit = 1; }
|
||||
}
|
||||
if (!$exit) {
|
||||
print "Cd to '$opts{ftpdir}'...\n";
|
||||
if (!$ftp->cwd($opts{ftpdir})) {
|
||||
print $ftp->message . "\n";
|
||||
$exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($exit) {
|
||||
if (yesno ('y', 'Retry connection at once')) {
|
||||
next TRY_CONNECT;
|
||||
} else {
|
||||
die 'error';
|
||||
}
|
||||
}
|
||||
|
||||
last TRY_CONNECT;
|
||||
}
|
||||
|
||||
# if(!$ftp->pasv()) { print $ftp->message . "\n"; die 'error'; }
|
||||
|
||||
return $ftp;
|
||||
}
|
||||
|
||||
##############################
|
||||
|
||||
# assume server supports MDTM - will be adjusted if needed
|
||||
my $has_mdtm = 1;
|
||||
|
||||
my %months = (
|
||||
Jan => 0,
|
||||
Feb => 1,
|
||||
Mar => 2,
|
||||
Apr => 3,
|
||||
May => 4,
|
||||
Jun => 5,
|
||||
Jul => 6,
|
||||
Aug => 7,
|
||||
Sep => 8,
|
||||
Oct => 9,
|
||||
Nov => 10,
|
||||
Dec => 11,
|
||||
);
|
||||
|
||||
my $ls_l_re = qr<
|
||||
([^ ]+\ *){5} # Perms, Links, User, Group, Size
|
||||
[^ ]+ # Blanks
|
||||
\ ([A-Z][a-z]{2}) # Month name (abbreviated)
|
||||
\ ([0-9 ][0-9]) # Day of month
|
||||
\ ([0-9 ][0-9][:0-9][0-9]{2}) # Filename
|
||||
>x;
|
||||
|
||||
sub do_mdtm {
|
||||
my ($ftp, $file) = @_;
|
||||
my ($time);
|
||||
|
||||
#if ($has_mdtm) {
|
||||
$time = $ftp->mdtm($file);
|
||||
# my $code = $ftp->code();
|
||||
# my $message = $ftp->message();
|
||||
# print " [ $code: $message ] ";
|
||||
if ($ftp->code() == 502 || # MDTM not implemented
|
||||
$ftp->code() == 500) { # command not understood (SUN firewall)
|
||||
$has_mdtm = 0;
|
||||
} elsif (!$ftp->ok()) {
|
||||
return;
|
||||
}
|
||||
#}
|
||||
|
||||
if (! $has_mdtm) {
|
||||
require Time::Local;
|
||||
|
||||
my @files = $ftp->dir($file);
|
||||
if (($#files == -1) ||
|
||||
($ftp->code == 550)) { # No such file or directory
|
||||
return;
|
||||
}
|
||||
|
||||
# my $code = $ftp->code();
|
||||
# my $message = $ftp->message();
|
||||
# print " [ $code: $message ] ";
|
||||
|
||||
# print "[$#files]";
|
||||
|
||||
# get the date components from the output of 'ls -l'
|
||||
if ($files[0] =~ $ls_l_re) {
|
||||
my($month_name, $day, $year_or_time, $month, $hours, $minutes,
|
||||
$year);
|
||||
|
||||
# what we can read
|
||||
$month_name = $2;
|
||||
$day = 0 + $3;
|
||||
$year_or_time = $4;
|
||||
|
||||
# translate the month name into number
|
||||
$month = $months{$month_name};
|
||||
|
||||
# recognize time or year, and compute missing one
|
||||
if ($year_or_time =~ /([0-9]{2}):([0-9]{2})/) {
|
||||
$hours = 0 + $1; $minutes = 0 + $2;
|
||||
my @this_date = gmtime(time());
|
||||
my $this_month = $this_date[4];
|
||||
my $this_year = $this_date[5];
|
||||
if ($month > $this_month) {
|
||||
$year = $this_year - 1;
|
||||
} else {
|
||||
$year = $this_year;
|
||||
}
|
||||
} elsif ($year_or_time =~ / [0-9]{4}/) {
|
||||
$hours = 0; $minutes = 0;
|
||||
$year = $year_or_time - 1900;
|
||||
} else {
|
||||
die 'cannot parse year-or-time';
|
||||
}
|
||||
|
||||
# build a system time
|
||||
$time = Time::Local::timegm(0, $minutes, $hours, $day, $month, $year);
|
||||
} else {
|
||||
die 'regex match failed on LIST output';
|
||||
}
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
=head1 CHANGES
|
||||
|
||||
=head2 Version 0.xx
|
||||
|
||||
This is a private module.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
54
dselect/methods/Makefile.am
Normal file
54
dselect/methods/Makefile.am
Normal file
|
@ -0,0 +1,54 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
nobase_dist_perllib_DATA = \
|
||||
Dselect/Method.pm \
|
||||
Dselect/Method/Ftp.pm \
|
||||
# EOL
|
||||
|
||||
nobase_dist_methods_DATA = \
|
||||
file/names \
|
||||
file/desc.file \
|
||||
ftp/names \
|
||||
ftp/desc.ftp \
|
||||
media/names \
|
||||
media/desc.media \
|
||||
# EOL
|
||||
|
||||
nobase_methods_SCRIPTS = \
|
||||
file/install \
|
||||
file/setup \
|
||||
file/update \
|
||||
ftp/install \
|
||||
ftp/setup \
|
||||
ftp/update \
|
||||
media/install \
|
||||
media/setup \
|
||||
media/update \
|
||||
# EOL
|
||||
|
||||
EXTRA_DIST = \
|
||||
file/setup.sh \
|
||||
file/update.sh \
|
||||
file/install.sh \
|
||||
ftp/setup.pl \
|
||||
ftp/update.pl \
|
||||
ftp/install.pl \
|
||||
media/setup.sh \
|
||||
media/update.sh \
|
||||
media/install.sh \
|
||||
media/README.media \
|
||||
# EOL
|
||||
|
||||
CLEANFILES = \
|
||||
$(nobase_methods_SCRIPTS) \
|
||||
# EOL
|
||||
|
||||
SUFFIXES =
|
||||
|
||||
include $(top_srcdir)/build-aux/subst.am
|
||||
|
||||
install-data-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/mnt
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/file
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/ftp
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/media
|
782
dselect/methods/Makefile.in
Normal file
782
dselect/methods/Makefile.in
Normal file
|
@ -0,0 +1,782 @@
|
|||
# Makefile.in generated by automake 1.17 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
#
|
||||
# Build time variable substitution for generated files.
|
||||
#
|
||||
|
||||
# Shell support.
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
am__rm_f = rm -f $(am__rm_f_notfound)
|
||||
am__rm_rf = rm -rf $(am__rm_f_notfound)
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = dselect/methods
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/build-to-host.m4 \
|
||||
$(top_srcdir)/m4/dpkg-arch.m4 $(top_srcdir)/m4/dpkg-build.m4 \
|
||||
$(top_srcdir)/m4/dpkg-compiler.m4 \
|
||||
$(top_srcdir)/m4/dpkg-coverage.m4 \
|
||||
$(top_srcdir)/m4/dpkg-funcs.m4 \
|
||||
$(top_srcdir)/m4/dpkg-headers.m4 $(top_srcdir)/m4/dpkg-libs.m4 \
|
||||
$(top_srcdir)/m4/dpkg-linker.m4 $(top_srcdir)/m4/dpkg-progs.m4 \
|
||||
$(top_srcdir)/m4/dpkg-types.m4 \
|
||||
$(top_srcdir)/m4/dpkg-unicode.m4 $(top_srcdir)/m4/gettext.m4 \
|
||||
$(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/iconv.m4 \
|
||||
$(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \
|
||||
$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
|
||||
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(nobase_dist_methods_DATA) \
|
||||
$(nobase_dist_perllib_DATA) $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(methodsdir)" \
|
||||
"$(DESTDIR)$(perllibdir)"
|
||||
SCRIPTS = $(nobase_methods_SCRIPTS)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
DATA = $(nobase_dist_methods_DATA) $(nobase_dist_perllib_DATA)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in \
|
||||
$(top_srcdir)/build-aux/subst.am
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOM4TE = @AUTOM4TE@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BUILD_DEVEL_DOCS = @BUILD_DEVEL_DOCS@
|
||||
BZ2_LIBS = @BZ2_LIBS@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CURSES_LIBS = @CURSES_LIBS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEB_DEFAULT_COMPRESSOR = @DEB_DEFAULT_COMPRESSOR@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DPKG_DEFAULT_PAGER = @DPKG_DEFAULT_PAGER@
|
||||
DPKG_DEFAULT_SHELL = @DPKG_DEFAULT_SHELL@
|
||||
DPKG_PAGER = @DPKG_PAGER@
|
||||
DPKG_SHELL = @DPKG_SHELL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GCOV = @GCOV@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
GREP = @GREP@
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
|
||||
KVM_LIBS = @KVM_LIBS@
|
||||
LCOV = @LCOV@
|
||||
LCOV_GENHTML = @LCOV_GENHTML@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
LZMA_LIBS = @LZMA_LIBS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MD_LIBS = @MD_LIBS@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MSGFMT = @MSGFMT@
|
||||
MSGMERGE = @MSGMERGE@
|
||||
MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_BUG_WEB = @PACKAGE_BUG_WEB@
|
||||
PACKAGE_COPYRIGHT_HOLDER = @PACKAGE_COPYRIGHT_HOLDER@
|
||||
PACKAGE_CPAN_NAME = @PACKAGE_CPAN_NAME@
|
||||
PACKAGE_DIST_IS_RELEASE = @PACKAGE_DIST_IS_RELEASE@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_RELEASE_DATE = @PACKAGE_RELEASE_DATE@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VCS_ID = @PACKAGE_VCS_ID@
|
||||
PACKAGE_VCS_TYPE = @PACKAGE_VCS_TYPE@
|
||||
PACKAGE_VCS_URL = @PACKAGE_VCS_URL@
|
||||
PACKAGE_VCS_WEB = @PACKAGE_VCS_WEB@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATCH = @PATCH@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PERL = @PERL@
|
||||
PERL_COVER = @PERL_COVER@
|
||||
PERL_COVERAGE = @PERL_COVERAGE@
|
||||
PERL_LIBDIR = @PERL_LIBDIR@
|
||||
PERL_MIN_VERSION = @PERL_MIN_VERSION@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
PO4A = @PO4A@
|
||||
POD2MAN = @POD2MAN@
|
||||
POSUB = @POSUB@
|
||||
PS_LIBS = @PS_LIBS@
|
||||
RANLIB = @RANLIB@
|
||||
RT_LIBS = @RT_LIBS@
|
||||
SED = @SED@
|
||||
SELINUX_CFLAGS = @SELINUX_CFLAGS@
|
||||
SELINUX_LIBS = @SELINUX_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SOCKET_LIBS = @SOCKET_LIBS@
|
||||
STRIP = @STRIP@
|
||||
TAR = @TAR@
|
||||
USE_NLS = @USE_NLS@
|
||||
USE_PO4A = @USE_PO4A@
|
||||
USE_UNICODE = @USE_UNICODE@
|
||||
VERSION = @VERSION@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
XGETTEXT_015 = @XGETTEXT_015@
|
||||
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
ZSTD_LIBS = @ZSTD_LIBS@
|
||||
Z_LIBS = @Z_LIBS@
|
||||
Z_NG_LIBS = @Z_NG_LIBS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
aclocaldir = @aclocaldir@
|
||||
admindir = @admindir@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__rm_f_notfound = @am__rm_f_notfound@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
am__xargs_n = @am__xargs_n@
|
||||
backupsdir = @backupsdir@
|
||||
bashcompletionsdir = @bashcompletionsdir@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
devlibdir = @devlibdir@
|
||||
docdir = @docdir@
|
||||
docspecdir = @docspecdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localedir_c = @localedir_c@
|
||||
localedir_c_make = @localedir_c_make@
|
||||
localstatedir = @localstatedir@
|
||||
logdir = @logdir@
|
||||
mandir = @mandir@
|
||||
methodsdir = @methodsdir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
perllibdir = @perllibdir@
|
||||
pkgconfdir = @pkgconfdir@
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
polkitactionsdir = @polkitactionsdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
zshcompletionsdir = @zshcompletionsdir@
|
||||
nobase_dist_perllib_DATA = \
|
||||
Dselect/Method.pm \
|
||||
Dselect/Method/Ftp.pm \
|
||||
# EOL
|
||||
|
||||
nobase_dist_methods_DATA = \
|
||||
file/names \
|
||||
file/desc.file \
|
||||
ftp/names \
|
||||
ftp/desc.ftp \
|
||||
media/names \
|
||||
media/desc.media \
|
||||
# EOL
|
||||
|
||||
nobase_methods_SCRIPTS = \
|
||||
file/install \
|
||||
file/setup \
|
||||
file/update \
|
||||
ftp/install \
|
||||
ftp/setup \
|
||||
ftp/update \
|
||||
media/install \
|
||||
media/setup \
|
||||
media/update \
|
||||
# EOL
|
||||
|
||||
EXTRA_DIST = \
|
||||
file/setup.sh \
|
||||
file/update.sh \
|
||||
file/install.sh \
|
||||
ftp/setup.pl \
|
||||
ftp/update.pl \
|
||||
ftp/install.pl \
|
||||
media/setup.sh \
|
||||
media/update.sh \
|
||||
media/install.sh \
|
||||
media/README.media \
|
||||
# EOL
|
||||
|
||||
CLEANFILES = \
|
||||
$(nobase_methods_SCRIPTS) \
|
||||
# EOL
|
||||
|
||||
SUFFIXES = .sh .pl
|
||||
subst_shell_rules = "\
|
||||
s{^ADMINDIR=.*$$}{ADMINDIR='$(admindir)'}; \
|
||||
s{^BACKUPSDIR=.*$$}{BACKUPSDIR='$(backupsdir)'}; \
|
||||
s{^PKGDATADIR_DEFAULT=.*$$}{PKGDATADIR_DEFAULT='$(pkgdatadir)'}; \
|
||||
s{^version=['\"][^'\"]*[\"']}{version=\"$(PACKAGE_VERSION)\"}; \
|
||||
s{^TAR=.*$$}{TAR='$(TAR)'}; \
|
||||
"
|
||||
|
||||
subst_shell_filter = $(PERL) -p -e $(subst_shell_rules)
|
||||
subst_shell_file = $(PERL) -i -p -e $(shell_subst_rules)
|
||||
|
||||
# Perl support.
|
||||
|
||||
# Note: We need to hex-escape '#' (0x23) to avoid portability issues with make.
|
||||
subst_perl_rules = "\
|
||||
s{^\x23!\s*/usr/bin/perl}{\x23!$(PERL)}; \
|
||||
s{our \\\$$CONFDIR = .*;}{our \\\$$CONFDIR = '$(pkgconfdir)';}; \
|
||||
s{our \\\$$ADMINDIR = .*;}{our \\\$$ADMINDIR = '$(admindir)';}; \
|
||||
s{our \\\$$LIBDIR = .*;}{our \\\$$LIBDIR = '$(pkglibexecdir)';}; \
|
||||
s{our \\\$$DATADIR = .*;}{our \\\$$DATADIR = '$(pkgdatadir)';}; \
|
||||
s{our \\\$$PROGMAKE = .*;}{our \\\$$PROGMAKE = '$(MAKE)';}; \
|
||||
s{our \\\$$PROGTAR = .*;}{our \\\$$PROGTAR = '$(TAR)';}; \
|
||||
s{our \\\$$PROGPATCH = .*;}{our \\\$$PROGPATCH = '$(PATCH)';}; \
|
||||
s{our \\\$$PROGVERSION = .*;}{our \\\$$PROGVERSION = '$(PACKAGE_VERSION)';}; \
|
||||
"
|
||||
|
||||
subst_perl_filter = $(PERL) -p -e $(subst_perl_rules)
|
||||
subst_perl_file = $(PERL) -i -p -e $(subst_perl_rules)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .sh .pl
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build-aux/subst.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dselect/methods/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign dselect/methods/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
$(top_srcdir)/build-aux/subst.am $(am__empty):
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-nobase_methodsSCRIPTS: $(nobase_methods_SCRIPTS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nobase_methods_SCRIPTS)'; test -n "$(methodsdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(methodsdir)" || exit 1; \
|
||||
fi; \
|
||||
$(am__nobase_strip_setup); \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n' \
|
||||
-e "s|$$srcdirstrip/||" -e 'h;s|[^/]*$$||; s|^$$|.|' \
|
||||
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
|
||||
if (++n[d] == $(am__install_max)) { \
|
||||
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
|
||||
else { print "f", d "/" $$4, $$1 } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
case $$type in \
|
||||
d) echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)/$$dir'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(methodsdir)/$$dir" || exit $$?;; \
|
||||
f) \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(methodsdir)$$dir'"; \
|
||||
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(methodsdir)$$dir" || exit $$?; \
|
||||
} \
|
||||
;; esac \
|
||||
; done
|
||||
|
||||
uninstall-nobase_methodsSCRIPTS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nobase_methods_SCRIPTS)'; test -n "$(methodsdir)" || exit 0; \
|
||||
$(am__nobase_strip_setup); \
|
||||
files=`$(am__nobase_strip) \
|
||||
-e 'h;s,.*/,,;$(transform);x;s|[^/]*$$||;G;s,\n,,'`; \
|
||||
dir='$(DESTDIR)$(methodsdir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-nobase_dist_methodsDATA: $(nobase_dist_methods_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nobase_dist_methods_DATA)'; test -n "$(methodsdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(methodsdir)" || exit 1; \
|
||||
fi; \
|
||||
$(am__nobase_list) | while read dir files; do \
|
||||
xfiles=; for file in $$files; do \
|
||||
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
|
||||
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
|
||||
test -z "$$xfiles" || { \
|
||||
test "x$$dir" = x. || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(methodsdir)/$$dir'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(methodsdir)/$$dir"; }; \
|
||||
echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(methodsdir)/$$dir'"; \
|
||||
$(INSTALL_DATA) $$xfiles "$(DESTDIR)$(methodsdir)/$$dir" || exit $$?; }; \
|
||||
done
|
||||
|
||||
uninstall-nobase_dist_methodsDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nobase_dist_methods_DATA)'; test -n "$(methodsdir)" || list=; \
|
||||
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
|
||||
dir='$(DESTDIR)$(methodsdir)'; $(am__uninstall_files_from_dir)
|
||||
install-nobase_dist_perllibDATA: $(nobase_dist_perllib_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(nobase_dist_perllib_DATA)'; test -n "$(perllibdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(perllibdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(perllibdir)" || exit 1; \
|
||||
fi; \
|
||||
$(am__nobase_list) | while read dir files; do \
|
||||
xfiles=; for file in $$files; do \
|
||||
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
|
||||
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
|
||||
test -z "$$xfiles" || { \
|
||||
test "x$$dir" = x. || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(perllibdir)/$$dir'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(perllibdir)/$$dir"; }; \
|
||||
echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(perllibdir)/$$dir'"; \
|
||||
$(INSTALL_DATA) $$xfiles "$(DESTDIR)$(perllibdir)/$$dir" || exit $$?; }; \
|
||||
done
|
||||
|
||||
uninstall-nobase_dist_perllibDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(nobase_dist_perllib_DATA)'; test -n "$(perllibdir)" || list=; \
|
||||
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
|
||||
dir='$(DESTDIR)$(perllibdir)'; $(am__uninstall_files_from_dir)
|
||||
tags TAGS:
|
||||
|
||||
ctags CTAGS:
|
||||
|
||||
cscope cscopelist:
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(SCRIPTS) $(DATA)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(methodsdir)" "$(DESTDIR)$(perllibdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-$(am__rm_f) $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-data-local install-nobase_dist_methodsDATA \
|
||||
install-nobase_dist_perllibDATA install-nobase_methodsSCRIPTS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-nobase_dist_methodsDATA \
|
||||
uninstall-nobase_dist_perllibDATA \
|
||||
uninstall-nobase_methodsSCRIPTS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||
cscopelist-am ctags-am distclean distclean-generic \
|
||||
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am \
|
||||
install-data-local install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-nobase_dist_methodsDATA \
|
||||
install-nobase_dist_perllibDATA install-nobase_methodsSCRIPTS \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags-am uninstall uninstall-am \
|
||||
uninstall-nobase_dist_methodsDATA \
|
||||
uninstall-nobase_dist_perllibDATA \
|
||||
uninstall-nobase_methodsSCRIPTS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
.sh: Makefile
|
||||
@test -d `dirname $@` || $(MKDIR_P) `dirname $@`
|
||||
$(AM_V_GEN) $(subst_shell_filter) <$< >$@
|
||||
$(AM_V_at) chmod +x $@
|
||||
|
||||
.pl: Makefile
|
||||
@test -d `dirname $@` || $(MKDIR_P) `dirname $@`
|
||||
$(AM_V_GEN) $(subst_perl_filter) <$< >$@
|
||||
$(AM_V_at) chmod +x $@
|
||||
|
||||
install-data-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/mnt
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/file
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/ftp
|
||||
$(MKDIR_P) $(DESTDIR)$(admindir)/methods/media
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
# Tell GNU make to disable its built-in pattern rules.
|
||||
%:: %,v
|
||||
%:: RCS/%,v
|
||||
%:: RCS/%
|
||||
%:: s.%
|
||||
%:: SCCS/s.%
|
9
dselect/methods/file/desc.file
Normal file
9
dselect/methods/file/desc.file
Normal file
|
@ -0,0 +1,9 @@
|
|||
Installation from a directory on the filesystem.
|
||||
|
||||
The area you are installing from should contain the Packages.gz file
|
||||
from each distribution area being installed (usually main and optionally
|
||||
contrib, non-free-firmware and non-free) as well as the corresponding
|
||||
binary/*/*.deb files.
|
||||
|
||||
The easiest way to do get this is to make a (partial) copy of the
|
||||
distribution site's directory hierarchy, if possible.
|
124
dselect/methods/file/install.sh
Executable file
124
dselect/methods/file/install.sh
Executable file
|
@ -0,0 +1,124 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
|
||||
cd "$vardir/methods/file"
|
||||
|
||||
. ./shvar.$option
|
||||
|
||||
xit=1
|
||||
trap '
|
||||
exit $xit
|
||||
' 0
|
||||
|
||||
predep="$vardir/predep-package"
|
||||
while true; do
|
||||
set +e
|
||||
dpkg --admindir "$vardir" --predep-package >"$predep"
|
||||
rc=$?
|
||||
set -e
|
||||
if test $rc = 1; then
|
||||
break
|
||||
fi
|
||||
test $rc = 0
|
||||
|
||||
perl -e '
|
||||
($binaryprefix,$predep) = @ARGV;
|
||||
$binaryprefix =~ s,/*$,/, if length($binaryprefix);
|
||||
open(P, "< $predep") or die "cannot open $predep: $!\n";
|
||||
while (<P>) {
|
||||
s/\s*\n$//;
|
||||
$package = $_ if s/^Package: //i;
|
||||
@filename = split(/ /,$_) if s/^Filename: //i;
|
||||
@msdosfilename = split(/ /,$_) if s/^MSDOS-Filename: //i;
|
||||
}
|
||||
die "internal error - no package" if length($package) == 0;
|
||||
die "internal error - no filename" if not @filename;
|
||||
die "internal error - mismatch >@filename< >@msdosfilename<"
|
||||
if @filename && @msdosfilename &&
|
||||
@filename != @msdosfilename;
|
||||
@invoke = (); $| = 1;
|
||||
for ($i = 0; $i <= $#filename; $i++) {
|
||||
$ppart = $i+1;
|
||||
print "Looking for part $ppart of $package ... ";
|
||||
if (-f "$binaryprefix$filename[$i]") {
|
||||
$print = $filename[$i];
|
||||
$invoke = "$binaryprefix$filename[$i]";
|
||||
} elsif (-f "$binaryprefix$msdosfilename[$i]") {
|
||||
$print = $msdosfilename[$i];
|
||||
$invoke = "$binaryprefix$msdosfilename[$i]";
|
||||
} else {
|
||||
$base = $filename[$i]; $base =~ s,.*/,,;
|
||||
$msdosbase = $msdosfilename[$i]; $msdosbase =~ s,.*/,,;
|
||||
$c = open(X, "-|"));
|
||||
if (not defined $c) {
|
||||
die "failed to fork for find: $!\n";
|
||||
}
|
||||
if (!$c) {
|
||||
exec("find", "-L",
|
||||
length($binaryprefix) ?
|
||||
$binaryprefix : ".",
|
||||
"-name",$base,"-o","-name",$msdosbase);
|
||||
die "failed to exec find: $!\n";
|
||||
}
|
||||
while (chop($invoke = <X>)) { last if -f $invoke; }
|
||||
$print = $invoke;
|
||||
if (substr($print,0,length($binaryprefix)+1) eq
|
||||
"$binaryprefix/") {
|
||||
$print = substr($print,length($binaryprefix));
|
||||
}
|
||||
}
|
||||
if (!length($invoke)) {
|
||||
warn "
|
||||
|
||||
Cannot find the appropriate file(s) anywhere needed to install or upgrade
|
||||
package $package. Expecting version $version or later, as listed in the
|
||||
Packages file.
|
||||
|
||||
Perhaps the package was downloaded with an unexpected name? In any case,
|
||||
you must find the file(s) and then either place it with the correct
|
||||
filename(s) (as listed in the Packages file or in $vardir/available)
|
||||
and rerun the installation, or upgrade the package by using
|
||||
\"dpkg --install --auto-deconfigure" by hand.
|
||||
|
||||
";
|
||||
exit(1);
|
||||
}
|
||||
print "$print\n";
|
||||
push(@invoke,$invoke);
|
||||
}
|
||||
print "Running dpkg -iB for $package ...\n";
|
||||
exec("dpkg","--admindir",$vardir,"-iB","--",@invoke);
|
||||
die "failed to exec dpkg: $!\n";
|
||||
' -- "$p_mountpoint$p_main_binary" "$predep"
|
||||
done
|
||||
|
||||
for f in main ctb nf lcl; do
|
||||
eval 'this_binary=$p_'$f'_binary'
|
||||
if [ -z "$this_binary" ]; then
|
||||
continue
|
||||
fi
|
||||
echo Running dpkg --admindir $vardir -iGROEB "$p_mountpoint$this_binary"
|
||||
dpkg --admindir $vardir -iGROEB "$p_mountpoint$this_binary"
|
||||
done
|
||||
|
||||
echo -n 'Installation OK. Hit RETURN. '
|
||||
read response
|
||||
|
||||
xit=0
|
1
dselect/methods/file/names
Normal file
1
dselect/methods/file/names
Normal file
|
@ -0,0 +1 @@
|
|||
42 file Install from a directory in the filesystem.
|
308
dselect/methods/file/setup.sh
Executable file
308
dselect/methods/file/setup.sh
Executable file
|
@ -0,0 +1,308 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
|
||||
cd "$vardir/methods/file"
|
||||
tp="$(mktemp --tmpdir $method.XXXXXXXXXX)"
|
||||
|
||||
iarch=$(dpkg --admindir $vardir --print-architecture)
|
||||
|
||||
xit=1
|
||||
trap '
|
||||
rm -f $tp.?
|
||||
exit $xit
|
||||
' 0
|
||||
|
||||
if ls -d "$tp.?" >/dev/null 2>&1; then
|
||||
rm $tp.?
|
||||
fi
|
||||
|
||||
yesno () {
|
||||
while true; do
|
||||
echo -n "$2 [$1] "
|
||||
read response
|
||||
if [ -z "$response" ]; then
|
||||
response="$1"
|
||||
fi
|
||||
case "$response" in
|
||||
[Nn]*)
|
||||
yesno=no
|
||||
return
|
||||
;;
|
||||
[Yy]*)
|
||||
yesno=yes
|
||||
return
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
outputparam () {
|
||||
echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3
|
||||
}
|
||||
|
||||
intrkey="$(stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p')"
|
||||
echo "
|
||||
If you make a mistake, use the interrupt key ($intrkey) to abort.
|
||||
"
|
||||
|
||||
# State variables, “best first”
|
||||
# {main,ctb,nf,lcl}_{packages,binary}
|
||||
# Empty before we've found them or if they're not available,
|
||||
# set to the relevant bit under mountpoint otherwise.
|
||||
# hierbase
|
||||
# A directory containing a Debian FTP site mirror tree for ONE distribution.
|
||||
# eg /pub/debian/dists/stable
|
||||
# mountpoint
|
||||
# The mountpoint for the filesystem containing the stuff
|
||||
# empty or unset if we don't know yet, or if we haven't mounted anything;
|
||||
# may also be empty if ‘directory’ was set.
|
||||
# fstype
|
||||
# The filesystem type to use.
|
||||
|
||||
if [ -f shvar.$option ]; then
|
||||
. ./shvar.$option
|
||||
fi
|
||||
|
||||
if [ -n "$mountpoint" ]; then
|
||||
# We must have $mountpoint
|
||||
echo \
|
||||
"All directory names should be entered relative to the root of the
|
||||
$fstype filesystem.
|
||||
"
|
||||
fi
|
||||
|
||||
while true; do
|
||||
echo \
|
||||
"In order to make it easy to find the relevant files, it is preferred
|
||||
to install from a straightforward copy of the Debian distribution.
|
||||
To use this, it is required to know where the top level of that copy of
|
||||
the distribution is (eg. 'debian/dists/stable') - this directory usually
|
||||
contains the Packages-Master file.
|
||||
|
||||
If you do not have a straightforward copy of the distribution available
|
||||
just answer 'none' and each needed part will be prompted individually."
|
||||
defhierbase=none
|
||||
# maybe ask for debian/dists and then show and ask for available dists
|
||||
# eg. {stable,frozen,unstable,bo,hamm,slink}
|
||||
if [ -n "$p_hierbase" ]; then
|
||||
if [ -d "$mountpoint/$p_hierbase/main/binary-$iarch" ]; then
|
||||
echo "
|
||||
Last time you said '$p_hierbase', and that looks plausible."
|
||||
defhierbase="$p_hierbase"
|
||||
else
|
||||
echo "
|
||||
Last time you said '$p_hierbase', but that doesn't look plausible,
|
||||
since '$p_hierbase/main/binary-$iarch' doesn't seem to exist."
|
||||
fi
|
||||
fi
|
||||
if [ none = "$defhierbase" ]; then
|
||||
if [ -d "$mountpoint/debian/dists/stable/main/binary-$iarch" ]; then
|
||||
echo "
|
||||
'/debian/dists/stable' exists and looks plausible, so that's the default."
|
||||
defhierbase=/debian/dists/stable
|
||||
elif [ -d "$mountpoint/dists/stable/main/binary-$iarch" ]; then
|
||||
echo "
|
||||
'/dists/stable' exists and looks plausible, so that's the default."
|
||||
defhierbase=/dists/stable
|
||||
fi
|
||||
fi
|
||||
echo -n \
|
||||
"Distribution top level ? [$defhierbase] "
|
||||
read response
|
||||
if [ -z "$response" ]; then
|
||||
response="$defhierbase"
|
||||
fi
|
||||
if [ none = "$response" ]; then
|
||||
hierbase=""
|
||||
break
|
||||
elif [ -d "$mountpoint/$response/main/binary-$iarch" ]; then
|
||||
hierbase="$(echo "$response" | sed -e 's:/*$::; s:^/*:/:')"
|
||||
break
|
||||
fi
|
||||
echo \
|
||||
"$response/main/binary-$iarch does not exist.
|
||||
"
|
||||
done
|
||||
|
||||
case "$hierbase" in
|
||||
/* )
|
||||
;;
|
||||
'' )
|
||||
;;
|
||||
* )
|
||||
hierbase="/$hierbase"
|
||||
;;
|
||||
esac
|
||||
|
||||
check_binary () {
|
||||
# args: area-in-messages directory
|
||||
# eg: main "$hierbase/main/binary-$iarch"
|
||||
# checks whether $2 contains *.deb
|
||||
if ! [ -d "$mountpoint$2/" ]; then
|
||||
echo "'$2' does not exist."
|
||||
return
|
||||
fi
|
||||
|
||||
if ! ( find -L "$mountpoint$2/" -name '*.deb' -print \
|
||||
| head -n 1 ) 2>/dev/null | grep . >/dev/null; then
|
||||
echo "'$2' does not contain any *.deb packages. Hmmpf."
|
||||
return
|
||||
fi
|
||||
echo "Using '$2' as $1 binary dir."
|
||||
this_binary="$2"
|
||||
}
|
||||
|
||||
find_area () {
|
||||
# args: area-in-messages area-in-vars subdirectory-in-hier
|
||||
# last-time-binary last-time-packages
|
||||
# eg: main main main
|
||||
# "$p_main_binary" "$p_main_packages"
|
||||
|
||||
this_binary=''
|
||||
this_packages=''
|
||||
if [ -n "$hierbase" ]; then
|
||||
check_binary $1 "$hierbase/$3/binary-$iarch"
|
||||
fi
|
||||
|
||||
if [ $2 = lcl ] && [ -z "$this_binary" ]; then
|
||||
echo "
|
||||
Note: By default there is no 'local' directory. It is intended for
|
||||
packages you made yourself."
|
||||
fi
|
||||
if [ $2 = nf -a -z "$this_binary" ]; then
|
||||
echo "
|
||||
Note: most media distributions of Debian do not include programs available
|
||||
in the 'non-free' directory of the distribution site.
|
||||
This is because these programs are under licenses that do not allow source
|
||||
modification or prevent distribution for profit on a media, or other
|
||||
restrictions that make them not free software.
|
||||
If you wish to install these programs you will have to get them from an
|
||||
alternative source."
|
||||
fi
|
||||
while [ -z "$this_binary" ]; do
|
||||
defaultbinary="$4"
|
||||
echo "
|
||||
Which directory contains the *.deb packages from the $1 distribution
|
||||
area (this directory is named '$3/binary-$iarch' on the distribution site) ?
|
||||
Say 'none' if this area is not available."
|
||||
if [ $2 != main ] && [ -z "$defaultbinary" ]; then
|
||||
defaultbinary=none
|
||||
fi
|
||||
echo -n \
|
||||
"Enter _$1_ binary dir. [$4]
|
||||
? "
|
||||
read response
|
||||
if [ -z "$response" ] && [ -n "$defaultbinary" ]; then
|
||||
response="$defaultbinary"
|
||||
fi
|
||||
if [ none = "$response" ]; then
|
||||
break
|
||||
fi
|
||||
case "$response" in
|
||||
'' | none)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
check_binary $1 "$(echo "$response" | sed -e 's:/$::; s:^/*:/:')"
|
||||
done
|
||||
if [ -n "$this_binary" ]; then
|
||||
for f in Packages.gz packages.gz Packages packages; do
|
||||
if [ -f "$mountpoint/$this_binary/$f" ]; then
|
||||
echo "Using '$this_binary/$f' for $1."
|
||||
this_packages="$this_binary/$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
while [ -z "$this_packages" ]; do
|
||||
echo -n "
|
||||
Cannot find the $1 'Packages' file. The information in the
|
||||
'Packages' file is important for package selection during new
|
||||
installations, and is very useful for upgrades.
|
||||
|
||||
If you overlooked it when downloading you should do get it now and
|
||||
return to this installation procedure when you have done so: you will
|
||||
find one Packages file and one Packages.gz file -- either will do --
|
||||
in the 'binary-$iarch' subdirectory of each area on the FTP sites and
|
||||
media discs. Alternatively (and this will be rather slow) the packages in
|
||||
the distribution area can be scanned - say 'scan' if you want to do so.
|
||||
|
||||
You need a separate Packages file from each of the distribution areas
|
||||
you wish to install.
|
||||
|
||||
Where is the _$1_ 'Packages' file (if none is available, say 'none')
|
||||
[$5]
|
||||
? "
|
||||
read response
|
||||
if [ -z "$response" ] && [ -n "$5" ]; then
|
||||
response="$5"
|
||||
fi
|
||||
case "$response" in
|
||||
'')
|
||||
continue
|
||||
;;
|
||||
none)
|
||||
break
|
||||
;;
|
||||
scan)
|
||||
this_packages=scan
|
||||
;;
|
||||
/*)
|
||||
this_packages="$response"
|
||||
;;
|
||||
*)
|
||||
this_packages="/$response"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
eval $2'_binary="$this_binary"'
|
||||
eval $2'_packages="$this_packages"'
|
||||
}
|
||||
|
||||
find_area main main main "$p_main_binary" "$p_main_packages"
|
||||
find_area contrib ctb contrib "$p_ctb_binary" "$p_ctb_packages"
|
||||
find_area non-free-firmware nff non-free-firmware "$p_nff_binary" "$p_nff_packages"
|
||||
find_area non-free nf non-free "$p_nf_binary" "$p_nf_packages"
|
||||
find_area local lcl local "$p_lcl_binary" "$p_lcl_packages"
|
||||
|
||||
echo -n '
|
||||
Hit RETURN to continue. '
|
||||
read response
|
||||
|
||||
exec 3>shvar.$option.new
|
||||
|
||||
outputparam p_fstype "$fstype"
|
||||
outputparam p_mountpoint "$mountpoint"
|
||||
outputparam p_hierbase "$hierbase"
|
||||
|
||||
outputparam p_main_packages "$main_packages"
|
||||
outputparam p_main_binary "$main_binary"
|
||||
outputparam p_ctb_packages "$ctb_packages"
|
||||
outputparam p_ctb_binary "$ctb_binary"
|
||||
outputparam p_nf_packages "$nf_packages"
|
||||
outputparam p_nf_binary "$nf_binary"
|
||||
outputparam p_nff_packages "$nff_packages"
|
||||
outputparam p_nff_binary "$nff_binary"
|
||||
outputparam p_lcl_packages "$lcl_packages"
|
||||
outputparam p_lcl_binary "$lcl_binary"
|
||||
|
||||
mv shvar.$option.new shvar.$option
|
||||
|
||||
xit=0
|
84
dselect/methods/file/update.sh
Executable file
84
dselect/methods/file/update.sh
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
|
||||
cd "$vardir/methods/file"
|
||||
|
||||
. ./shvar.$option
|
||||
|
||||
if [ -z "$p_main_packages" ] && [ -z "$p_ctb_packages" ] && \
|
||||
[ -z "$p_nf_packages" ] && [ -z "$p_lcl_packages" ]; then
|
||||
echo '
|
||||
No Packages files available, cannot update available packages list.
|
||||
Hit RETURN to continue. '
|
||||
read response
|
||||
exit 0
|
||||
fi
|
||||
|
||||
xit=1
|
||||
trap '
|
||||
rm -f packages-main packages-ctb packages-nf packages-lcl
|
||||
exit $xit
|
||||
' 0
|
||||
|
||||
updatetype=update
|
||||
|
||||
for f in main ctb nf lcl; do
|
||||
eval 'this_packages=$p_'$f'_packages'
|
||||
case "$this_packages" in
|
||||
'')
|
||||
continue
|
||||
;;
|
||||
scan)
|
||||
eval 'this_binary=$p_'$f'_binary'
|
||||
if [ -z "$this_binary" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$updatetype" = update ]; then
|
||||
dpkg --admindir $vardir --clear-avail
|
||||
updatetype=merge
|
||||
fi
|
||||
echo Running dpkg --record-avail -R "$p_mountpoint$this_binary"
|
||||
dpkg --admindir $vardir --record-avail -R "$p_mountpoint$this_binary"
|
||||
;;
|
||||
*)
|
||||
packagesfile="$p_mountpoint$this_packages"
|
||||
case "$packagesfile" in
|
||||
*.gz)
|
||||
echo -n "Uncompressing $packagesfile ... "
|
||||
zcat <"$packagesfile" >packages-$f
|
||||
echo done.
|
||||
dpkg --admindir $vardir --$updatetype-avail packages-$f
|
||||
updatetype=merge
|
||||
;;
|
||||
'')
|
||||
;;
|
||||
*)
|
||||
dpkg --admindir $vardir --$updatetype-avail "$packagesfile"
|
||||
updatetype=merge
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -n 'Update OK. Hit RETURN. '
|
||||
read response
|
||||
|
||||
xit=0
|
2
dselect/methods/ftp/desc.ftp
Normal file
2
dselect/methods/ftp/desc.ftp
Normal file
|
@ -0,0 +1,2 @@
|
|||
Installation using ftp, you must know one (or more) ftp site(s) and the
|
||||
correct directories for the Debian distribution.
|
622
dselect/methods/ftp/install.pl
Executable file
622
dselect/methods/ftp/install.pl
Executable file
|
@ -0,0 +1,622 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright © 1996 Andy Guy <andy@cyteen.org>
|
||||
# Copyright © 1998 Martin Schulze <joey@infodrom.north.de>
|
||||
# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use File::Basename;
|
||||
|
||||
eval q{
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
|
||||
use Dpkg::File;
|
||||
};
|
||||
if ($@) {
|
||||
warn "Missing Dpkg modules required by the FTP access method.\n\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
use Dselect::Method;
|
||||
use Dselect::Method::Ftp;
|
||||
|
||||
my $ftp;
|
||||
|
||||
# exit value
|
||||
my $exit = 0;
|
||||
|
||||
# deal with arguments
|
||||
my $vardir = $ARGV[0];
|
||||
my $method = $ARGV[1];
|
||||
my $option = $ARGV[2];
|
||||
|
||||
if ($option eq 'manual') {
|
||||
print "manual mode not supported yet\n";
|
||||
exit 1;
|
||||
}
|
||||
#print "vardir: $vardir, method: $method, option: $option\n";
|
||||
|
||||
my $methdir = "$vardir/methods/ftp";
|
||||
|
||||
# get info from control file
|
||||
read_config("$methdir/vars");
|
||||
|
||||
chdir "$methdir";
|
||||
make_path("$methdir/$CONFIG{dldir}", { mode => 0755 });
|
||||
|
||||
|
||||
#Read md5sums already calculated
|
||||
my %md5sums;
|
||||
if (-f "$methdir/md5sums") {
|
||||
my $code = file_slurp("$methdir/md5sums");
|
||||
my $VAR1; ## no critic (Variables::ProhibitUnusedVariables)
|
||||
my $res = eval $code;
|
||||
if ($@) {
|
||||
die "couldn't eval $methdir/md5sums content: $@\n";
|
||||
}
|
||||
if (ref($res)) { %md5sums = %{$res} }
|
||||
}
|
||||
|
||||
# Get a stanza.
|
||||
# returns a ref to a hash containing flds->fld contents
|
||||
# white space from the ends of lines is removed and newlines added
|
||||
# (no trailing newline).
|
||||
# die's if something unexpected happens
|
||||
sub get_stanza {
|
||||
my $fh = shift;
|
||||
my %flds;
|
||||
my $fld;
|
||||
while (<$fh>) {
|
||||
if (length != 0) {
|
||||
FLDLOOP: while (1) {
|
||||
if ( /^(\S+):\s*(.*)\s*$/ ) {
|
||||
$fld = lc($1);
|
||||
$flds{$fld} = $2;
|
||||
while (<$fh>) {
|
||||
if (length == 0) {
|
||||
return %flds;
|
||||
} elsif ( /^(\s.*)$/ ) {
|
||||
$flds{$fld} = $flds{$fld} . "\n" . $1;
|
||||
} else {
|
||||
next FLDLOOP;
|
||||
}
|
||||
}
|
||||
return %flds;
|
||||
} else {
|
||||
die "expected a start of field line, but got:\n$_";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return %flds;
|
||||
}
|
||||
|
||||
# process status file
|
||||
# create curpkgs hash with version (no version implies not currently installed)
|
||||
# of packages we want
|
||||
print "Processing status file...\n";
|
||||
my %curpkgs;
|
||||
sub procstatus {
|
||||
my (%flds, $fld);
|
||||
open(my $status_fh, '<', "$vardir/status") or
|
||||
die 'Could not open status file';
|
||||
while (%flds = get_stanza($status_fh), %flds) {
|
||||
if($flds{'status'} =~ /^install ok/) {
|
||||
my $cs = (split(/ /, $flds{'status'}))[2];
|
||||
if (($cs eq 'not-installed') ||
|
||||
($cs eq 'half-installed') ||
|
||||
($cs eq 'config-files')) {
|
||||
$curpkgs{$flds{'package'}} = '';
|
||||
} else {
|
||||
$curpkgs{$flds{'package'}} = $flds{'version'};
|
||||
}
|
||||
}
|
||||
}
|
||||
close($status_fh);
|
||||
}
|
||||
procstatus();
|
||||
|
||||
sub dcmpvers {
|
||||
my($a, $p, $b) = @_;
|
||||
my ($r);
|
||||
$r = system('dpkg', '--compare-versions', "$a", "$p", "$b");
|
||||
$r = $r/256;
|
||||
if ($r == 0) {
|
||||
return 1;
|
||||
} elsif ($r == 1) {
|
||||
return 0;
|
||||
}
|
||||
die "dpkg --compare-versions $a $p $b - failed with $r";
|
||||
}
|
||||
|
||||
# process package files, looking for packages to install
|
||||
# create a hash of these packages pkgname => version, filenames...
|
||||
# filename => md5sum, size
|
||||
# for all packages
|
||||
my %pkgs;
|
||||
my %pkgfiles;
|
||||
sub procpkgfile {
|
||||
my $fn = shift;
|
||||
my $site = shift;
|
||||
my $dist = shift;
|
||||
my (@files, @sizes, @md5sums, $pkg, $ver, $nfs, $fld);
|
||||
my(%flds);
|
||||
open(my $pkgfile_fh, '<', $fn) or die "could not open package file $fn";
|
||||
while (%flds = get_stanza($pkgfile_fh), %flds) {
|
||||
$pkg = $flds{'package'};
|
||||
$ver = $curpkgs{$pkg};
|
||||
@files = split(/[\s\n]+/, $flds{'filename'});
|
||||
@sizes = split(/[\s\n]+/, $flds{'size'});
|
||||
@md5sums = split(/[\s\n]+/, $flds{'md5sum'});
|
||||
if (defined($ver) && (($ver eq '') || dcmpvers($ver, 'lt', $flds{'version'}))) {
|
||||
$pkgs{$pkg} = [ $flds{'version'}, [ @files ], $site ];
|
||||
$curpkgs{$pkg} = $flds{'version'};
|
||||
}
|
||||
$nfs = scalar(@files);
|
||||
if(($nfs != scalar(@sizes)) || ($nfs != scalar(@md5sums)) ) {
|
||||
print "Different number of filenames, sizes and md5sums for $flds{'package'}\n";
|
||||
} else {
|
||||
my $i = 0;
|
||||
foreach my $fl (@files) {
|
||||
$pkgfiles{$fl} = [ $md5sums[$i], $sizes[$i], $site, $dist ];
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
close $pkgfile_fh or die "cannot close package file $fn: $!\n";
|
||||
}
|
||||
|
||||
print "\nProcessing Package files...\n";
|
||||
my ($i, $j);
|
||||
$i = 0;
|
||||
foreach my $site (@{$CONFIG{site}}) {
|
||||
$j = 0;
|
||||
foreach my $dist (@{$site->[2]}) {
|
||||
my $fn = $dist;
|
||||
$fn =~ tr#/#_#;
|
||||
$fn = "Packages.$site->[0].$fn";
|
||||
if (-f $fn) {
|
||||
print " $site->[0] $dist...\n";
|
||||
procpkgfile($fn,$i,$j);
|
||||
} else {
|
||||
print "Could not find packages file for $site->[0] $dist distribution (re-run Update)\n"
|
||||
}
|
||||
$j++;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
my $dldir = $CONFIG{dldir};
|
||||
# md5sum
|
||||
sub md5sum {
|
||||
my $fn = shift;
|
||||
my $m = qx(md5sum $fn);
|
||||
$m = (split(' ', $m))[0];
|
||||
$md5sums{"$dldir/$fn"} = $m;
|
||||
return $m;
|
||||
}
|
||||
|
||||
# construct list of files to get
|
||||
# hash of filenames => size of downloaded part
|
||||
# query user for each partial file
|
||||
print "\nConstructing list of files to get...\n";
|
||||
my %downloads;
|
||||
my ($dir, @info, @files, $csize, $size);
|
||||
my $totsize = 0;
|
||||
foreach my $pkg (keys(%pkgs)) {
|
||||
@files = @{$pkgs{$pkg}[1]};
|
||||
foreach my $fn (@files) {
|
||||
#Look for a partial file
|
||||
if (-f "$dldir/$fn.partial") {
|
||||
rename "$dldir/$fn.partial", "$dldir/$fn";
|
||||
}
|
||||
$dir = dirname($fn);
|
||||
if(! -d "$dldir/$dir") {
|
||||
make_path("$dldir/$dir", { mode => 0755 });
|
||||
}
|
||||
@info = @{$pkgfiles{$fn}};
|
||||
$csize = int($info[1]/1024)+1;
|
||||
if(-f "$dldir/$fn") {
|
||||
$size = -s "$dldir/$fn";
|
||||
if($info[1] > $size) {
|
||||
# partial download
|
||||
if (yesno('y', "continue file: $fn (" . nb($size) . '/' .
|
||||
nb($info[1]) . ')')) {
|
||||
$downloads{$fn} = $size;
|
||||
$totsize += $csize - int($size/1024);
|
||||
} else {
|
||||
$downloads{$fn} = 0;
|
||||
$totsize += $csize;
|
||||
}
|
||||
} else {
|
||||
# check md5sum
|
||||
if (! exists $md5sums{"$dldir/$fn"}) {
|
||||
$md5sums{"$dldir/$fn"} = md5sum("$dldir/$fn");
|
||||
}
|
||||
if ($md5sums{"$dldir/$fn"} eq $info[0]) {
|
||||
print "already got: $fn\n";
|
||||
} else {
|
||||
print "corrupted: $fn\n";
|
||||
$downloads{$fn} = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my $ffn = $fn;
|
||||
$ffn =~ s/binary-[^\/]+/.../;
|
||||
print 'want: ' .
|
||||
$CONFIG{site}[$pkgfiles{$fn}[2]][0] . " $ffn (${csize}k)\n";
|
||||
$downloads{$fn} = 0;
|
||||
$totsize += $csize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $avsp = qx(df -Pk $dldir| awk '{ print \$4}' | tail -n 1);
|
||||
chomp $avsp;
|
||||
|
||||
print "\nApproximate total space required: ${totsize}k\n";
|
||||
print "Available space in $dldir: ${avsp}k\n";
|
||||
|
||||
#$avsp = qx(df -k $::dldir| paste -s | awk '{ print \$11});
|
||||
#chomp $avsp;
|
||||
|
||||
if($totsize == 0) {
|
||||
print 'Nothing to get.';
|
||||
} else {
|
||||
if($totsize > $avsp) {
|
||||
print "Space required is greater than available space,\n";
|
||||
print "you will need to select which items to get.\n";
|
||||
}
|
||||
# ask user which files to get
|
||||
if (($totsize > $avsp) ||
|
||||
yesno('n', 'Do you want to select the files to get')) {
|
||||
$totsize = 0;
|
||||
my @files = sort(keys(%downloads));
|
||||
my $def = 'y';
|
||||
foreach my $fn (@files) {
|
||||
my @info = @{$pkgfiles{$fn}};
|
||||
my $csize = int($info[1] / 1024) + 1;
|
||||
my $rsize = int(($info[1] - $downloads{$fn}) / 1024) + 1;
|
||||
if ($rsize + $totsize > $avsp) {
|
||||
print "no room for: $fn\n";
|
||||
delete $downloads{$fn};
|
||||
} elsif (yesno($def, $downloads{$fn}
|
||||
? "download: $fn ${rsize}k/${csize}k (total = ${totsize}k)"
|
||||
: "download: $fn ${rsize}k (total = ${totsize}k)")) {
|
||||
$def = 'y';
|
||||
$totsize += $rsize;
|
||||
} else {
|
||||
$def = 'n';
|
||||
delete $downloads{$fn};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub download {
|
||||
my $i = 0;
|
||||
|
||||
foreach my $site (@{$CONFIG{site}}) {
|
||||
my @getfiles = grep { $pkgfiles{$_}[2] == $i } keys %downloads;
|
||||
my @pre_dist = (); # Directory to add before $fn
|
||||
|
||||
#Scan distributions for looking at "(../)+/dir/dir"
|
||||
my ($n,$cp);
|
||||
$cp = -1;
|
||||
foreach (@{$site->[2]}) {
|
||||
$cp++;
|
||||
$pre_dist[$cp] = '';
|
||||
$n = (s{\.\./}{../}g);
|
||||
next if (! $n);
|
||||
if (m<^((?:\.\./){$n}(?:[^/]+/){$n})>) {
|
||||
$pre_dist[$cp] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! @getfiles) { $i++; next; }
|
||||
|
||||
$ftp = do_connect(ftpsite => $site->[0],
|
||||
ftpdir => $site->[1],
|
||||
passive => $site->[3],
|
||||
username => $site->[4],
|
||||
password => $site->[5],
|
||||
useproxy => $CONFIG{use_auth_proxy},
|
||||
proxyhost => $CONFIG{proxyhost},
|
||||
proxylogname => $CONFIG{proxylogname},
|
||||
proxypassword => $CONFIG{proxypassword});
|
||||
|
||||
local $SIG{INT} = sub { die "Interrupted !\n"; };
|
||||
|
||||
my ($rsize, $res, $pre);
|
||||
foreach my $fn (@getfiles) {
|
||||
$pre = $pre_dist[$pkgfiles{$fn}[3]] || '';
|
||||
if ($downloads{$fn}) {
|
||||
$rsize = ${pkgfiles{$fn}}[1] - $downloads{$fn};
|
||||
print "getting: $pre$fn (" . nb($rsize) . '/' .
|
||||
nb($pkgfiles{$fn}[1]) . ")\n";
|
||||
} else {
|
||||
print "getting: $pre$fn (". nb($pkgfiles{$fn}[1]) . ")\n";
|
||||
}
|
||||
$res = $ftp->get("$pre$fn", "$dldir/$fn", $downloads{$fn});
|
||||
if(! $res) {
|
||||
my $r = $ftp->code();
|
||||
print $ftp->message() . "\n";
|
||||
if (!($r == 550 || $r == 450)) {
|
||||
return 1;
|
||||
} else {
|
||||
#Try to find another file or this package
|
||||
print "Looking for another version of the package...\n";
|
||||
my ($dir, $package) = ($fn =~ m{^(.*)/([^/]+)_[^/]+.deb$});
|
||||
my $list = $ftp->ls("$pre$dir");
|
||||
if ($ftp->ok() && ref($list)) {
|
||||
foreach my $file (@{$list}) {
|
||||
if ($file =~ m/($dir\/\Q$package\E_[^\/]+.deb)/i) {
|
||||
print "Package found : $file\n";
|
||||
print "getting: $file (size not known)\n";
|
||||
$res = $ftp->get($file, "$dldir/$1");
|
||||
if (! $res) {
|
||||
$r = $ftp->code();
|
||||
print $ftp->message() . "\n";
|
||||
return 1 if ($r != 550 and $r != 450);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# fully got, remove it from list in case we have to re-download
|
||||
delete $downloads{$fn};
|
||||
}
|
||||
$ftp->quit();
|
||||
$i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# download stuff (protect from ^C)
|
||||
if($totsize != 0) {
|
||||
if (yesno('y', "\nDo you want to download the required files")) {
|
||||
DOWNLOAD_TRY: while (1) {
|
||||
print "Downloading files... use ^C to stop\n";
|
||||
eval {
|
||||
if ((download() == 1) &&
|
||||
yesno('y', "\nDo you want to retry downloading at once")) {
|
||||
next DOWNLOAD_TRY;
|
||||
}
|
||||
};
|
||||
if($@ =~ /Interrupted|Timeout/i ) {
|
||||
# close the FTP connection if needed
|
||||
if ((ref($ftp) =~ /Net::FTP/) and ($@ =~ /Interrupted/i)) {
|
||||
$ftp->abort();
|
||||
$ftp->quit();
|
||||
undef $ftp;
|
||||
}
|
||||
print "FTP ERROR\n";
|
||||
if (yesno('y', "\nDo you want to retry downloading at once")) {
|
||||
# get the first $fn that foreach would give:
|
||||
# this is the one that got interrupted.
|
||||
my $fn;
|
||||
MY_ITER: foreach my $ffn (keys(%downloads)) {
|
||||
$fn = $ffn;
|
||||
last MY_ITER;
|
||||
}
|
||||
my $size = -s "$dldir/$fn";
|
||||
# partial download
|
||||
if (yesno('y', "continue file: $fn (at $size)")) {
|
||||
$downloads{$fn} = $size;
|
||||
} else {
|
||||
$downloads{$fn} = 0;
|
||||
}
|
||||
next DOWNLOAD_TRY;
|
||||
} else {
|
||||
$exit = 1;
|
||||
last DOWNLOAD_TRY;
|
||||
}
|
||||
} elsif ($@) {
|
||||
print "An error occurred ($@) : stopping download\n";
|
||||
}
|
||||
last DOWNLOAD_TRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# remove duplicate packages (keep latest versions)
|
||||
# move half downloaded files out of the way
|
||||
# delete corrupted files
|
||||
print "\nProcessing downloaded files...(for corrupt/old/partial)\n";
|
||||
my %vers; # package => version
|
||||
my %files; # package-version => files...
|
||||
|
||||
# check a deb or split deb file
|
||||
# return 1 if it a deb file, 2 if it is a split deb file
|
||||
# else 0
|
||||
sub chkdeb {
|
||||
my ($fn) = @_;
|
||||
# check to see if it is a .deb file
|
||||
if (!system "dpkg-deb --info $fn >/dev/null 2>&1 && dpkg-deb --contents $fn >/dev/null 2>&1") {
|
||||
return 1;
|
||||
} elsif (!system "dpkg-split --info $fn >/dev/null 2>&1") {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sub getdebinfo {
|
||||
my ($fn) = @_;
|
||||
my $type = chkdeb($fn);
|
||||
my ($pkg, $ver);
|
||||
if($type == 1) {
|
||||
open(my $pkgfile_fh, '-|', "dpkg-deb --field $fn")
|
||||
or die "cannot create pipe for 'dpkg-deb --field $fn'";
|
||||
my %fields = get_stanza($pkgfile_fh);
|
||||
close($pkgfile_fh);
|
||||
$pkg = $fields{'package'};
|
||||
$ver = $fields{'version'};
|
||||
return $pkg, $ver;
|
||||
} elsif ( $type == 2) {
|
||||
open(my $pkgfile_fh, '-|', "dpkg-split --info $fn")
|
||||
or die "cannot create pipe for 'dpkg-split --info $fn'";
|
||||
while (<$pkgfile_fh>) {
|
||||
/Part of package:\s*(\S+)/ and $pkg = $1;
|
||||
/\.\.\. version:\s*(\S+)/ and $ver = $1;
|
||||
}
|
||||
close($pkgfile_fh);
|
||||
return $pkg, $ver;
|
||||
}
|
||||
print "could not figure out type of $fn\n";
|
||||
return $pkg, $ver;
|
||||
}
|
||||
|
||||
# process deb file to make sure we only keep latest versions
|
||||
sub prcdeb {
|
||||
my ($dir, $fn) = @_;
|
||||
my ($pkg, $ver) = getdebinfo($fn);
|
||||
if(!defined($pkg) || !defined($ver)) {
|
||||
print "could not get package info from file\n";
|
||||
return 0;
|
||||
}
|
||||
if($vers{$pkg}) {
|
||||
if (dcmpvers($vers{$pkg}, 'eq', $ver)) {
|
||||
$files{$pkg . $ver} = [ $files{$pkg . $ver }, "$dir/$fn" ];
|
||||
} elsif (dcmpvers($vers{$pkg}, 'gt', $ver)) {
|
||||
print "old version\n";
|
||||
unlink $fn;
|
||||
} else { # else $ver is gt current version
|
||||
foreach my $c (@{$files{$pkg . $vers{$pkg}}}) {
|
||||
print "replaces: $c\n";
|
||||
unlink "$vardir/methods/ftp/$dldir/$c";
|
||||
}
|
||||
$vers{$pkg} = $ver;
|
||||
$files{$pkg . $ver} = [ "$dir/$fn" ];
|
||||
}
|
||||
} else {
|
||||
$vers{$pkg} = $ver;
|
||||
$files{$pkg . $ver} = [ "$dir/$fn" ];
|
||||
}
|
||||
}
|
||||
|
||||
sub prcfile {
|
||||
my ($fn) = $_;
|
||||
if (-f $fn and $fn ne '.') {
|
||||
my $dir = '.';
|
||||
if (length($File::Find::dir) > length($dldir)) {
|
||||
$dir = substr($File::Find::dir, length($dldir)+1);
|
||||
}
|
||||
print "$dir/$fn\n";
|
||||
if(defined($pkgfiles{"$dir/$fn"})) {
|
||||
my @info = @{$pkgfiles{"$dir/$fn"}};
|
||||
my $size = -s $fn;
|
||||
if($size == 0) {
|
||||
print "zero length file\n";
|
||||
unlink $fn;
|
||||
} elsif($size < $info[1]) {
|
||||
print "partial file\n";
|
||||
rename $fn, "$fn.partial";
|
||||
} elsif(( (exists $md5sums{"$dldir/$fn"})
|
||||
and ($md5sums{"$dldir/$fn"} ne $info[0]) )
|
||||
or
|
||||
(md5sum($fn) ne $info[0])) {
|
||||
print "corrupt file\n";
|
||||
unlink $fn;
|
||||
} else {
|
||||
prcdeb($dir, $fn);
|
||||
}
|
||||
} elsif($fn =~ /.deb$/) {
|
||||
if(chkdeb($fn)) {
|
||||
prcdeb($dir, $fn);
|
||||
} else {
|
||||
print "corrupt file\n";
|
||||
unlink $fn;
|
||||
}
|
||||
} else {
|
||||
print "non-debian file\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
find(\&prcfile, "$dldir/");
|
||||
|
||||
# install .debs
|
||||
if (yesno('y', "\nDo you want to install the files fetched")) {
|
||||
print "Installing files...\n";
|
||||
#Installing pre-dependent package before !
|
||||
my (@flds, $package, @filename, $r);
|
||||
while (@flds = qx(dpkg --predep-package), $? == 0) {
|
||||
foreach my $field (@flds) {
|
||||
$field =~ s/\s*\n//;
|
||||
$package = $field if $field =~ s/^Package: //i;
|
||||
@filename = split / +/, $field if $field =~ s/^Filename: //i;
|
||||
}
|
||||
@filename = map { "$dldir/$_" } @filename;
|
||||
next if (! @filename);
|
||||
$r = system('dpkg', '-iB', '--', @filename);
|
||||
if ($r) { print "DPKG ERROR\n"; $exit = 1; }
|
||||
}
|
||||
#Installing other packages after
|
||||
$r = system('dpkg', '-iGREOB', $dldir);
|
||||
if($r) {
|
||||
print "DPKG ERROR\n";
|
||||
$exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub removeinstalled {
|
||||
my $fn = $_;
|
||||
if (-f $fn and $fn ne '.') {
|
||||
my $dir = '.';
|
||||
if (length($File::Find::dir) > length($dldir)) {
|
||||
$dir = substr($File::Find::dir, length($dldir)+1);
|
||||
}
|
||||
if($fn =~ /.deb$/) {
|
||||
my($pkg, $ver) = getdebinfo($fn);
|
||||
if(!defined($pkg) || !defined($ver)) {
|
||||
print "Could not get info for: $dir/$fn\n";
|
||||
} elsif ($curpkgs{$pkg} and dcmpvers($ver, 'le', $curpkgs{$pkg})) {
|
||||
print "deleting: $dir/$fn\n";
|
||||
unlink $fn;
|
||||
} else {
|
||||
print "leaving: $dir/$fn\n";
|
||||
}
|
||||
} else {
|
||||
print "non-debian: $dir/$fn\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# remove .debs that have been installed (query user)
|
||||
# first need to reprocess status file
|
||||
if (yesno('y', "\nDo you wish to delete the installed package (.deb) files?")) {
|
||||
print "Removing installed files...\n";
|
||||
%curpkgs = ();
|
||||
procstatus();
|
||||
find(\&removeinstalled, "$dldir/");
|
||||
}
|
||||
|
||||
# remove whole ./debian directory if user wants to
|
||||
if (yesno('n', "\nDo you want to remove $dldir directory?")) {
|
||||
remove_tree($dldir);
|
||||
}
|
||||
|
||||
#Store useful md5sums
|
||||
foreach my $file (keys %md5sums) {
|
||||
next if -f $file;
|
||||
delete $md5sums{$file};
|
||||
}
|
||||
file_dump("$methdir/md5sums", Dumper(\%md5sums));
|
||||
|
||||
exit $exit;
|
1
dselect/methods/ftp/names
Normal file
1
dselect/methods/ftp/names
Normal file
|
@ -0,0 +1 @@
|
|||
60 ftp Install using ftp.
|
177
dselect/methods/ftp/setup.pl
Executable file
177
dselect/methods/ftp/setup.pl
Executable file
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright © 1996 Andy Guy <andy@cyteen.org>
|
||||
# Copyright © 1998 Martin Schulze <joey@infodrom.north.de>
|
||||
# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
eval q{
|
||||
use Dpkg; # Dummy import to require the presence of Dpkg::*.
|
||||
};
|
||||
if ($@) {
|
||||
warn "Missing Dpkg modules required by the FTP access method.\n\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
use Dselect::Method;
|
||||
use Dselect::Method::Ftp;
|
||||
|
||||
# deal with arguments
|
||||
my $vardir = $ARGV[0];
|
||||
my $method = $ARGV[1];
|
||||
my $option = $ARGV[2];
|
||||
|
||||
if ($option eq 'manual') {
|
||||
print "Manual package installation.\n";
|
||||
exit 0;
|
||||
}
|
||||
#print "vardir: $vardir, method: $method, option: $option\n";
|
||||
|
||||
#Defaults
|
||||
my $arch = qx(dpkg --print-architecture);
|
||||
$arch = 'i386' if $?;
|
||||
chomp $arch;
|
||||
|
||||
my $logname = qx(whoami);
|
||||
chomp $logname;
|
||||
my $host = qx(cat /etc/mailname || dnsdomainname);
|
||||
chomp $host;
|
||||
|
||||
$CONFIG{dldir} = 'debian';
|
||||
$CONFIG{use_auth_proxy} = 0;
|
||||
$CONFIG{proxyhost} = '';
|
||||
$CONFIG{proxylogname} = $logname;
|
||||
$CONFIG{proxypassword} = '';
|
||||
|
||||
my $methdir = "$vardir/methods/ftp";
|
||||
my $exit = 0;
|
||||
my $problem = 0;
|
||||
|
||||
if (-f "$methdir/vars") {
|
||||
read_config("$methdir/vars");
|
||||
}
|
||||
|
||||
chdir "$methdir";
|
||||
if (! -d 'debian') {
|
||||
mkdir 'debian', 0755;
|
||||
}
|
||||
# get info from user
|
||||
|
||||
$| = 1;
|
||||
|
||||
print <<"EOM";
|
||||
|
||||
You must supply an ftp site, use of passive mode, username, password,
|
||||
path to the debian directory,list of distributions you are interested
|
||||
in and place to download the binary package files to (relative to
|
||||
/var/lib/dpkg/methods/ftp). You can add as much sites as you like. Later
|
||||
entries will always override older ones.
|
||||
|
||||
Supply "?" as a password to be asked each time you connect.
|
||||
|
||||
Eg: ftp site: ftp.debian.org
|
||||
passive: y
|
||||
username: anonymous
|
||||
password: $logname\@$host
|
||||
ftp dir: /debian
|
||||
distributions: dists/stable/main dists/stable/contrib
|
||||
download dir: debian
|
||||
|
||||
You may have to use an authenticated FTP proxy in order to reach the
|
||||
FTP site:
|
||||
|
||||
Eg: use auth proxy: y
|
||||
proxy: proxy.isp.com
|
||||
proxy account: $CONFIG{proxylogname}
|
||||
proxy password: ?
|
||||
EOM
|
||||
|
||||
if (! $CONFIG{done}) {
|
||||
view_mirrors() if (yesno('y', 'Would you like to see a list of ftp mirrors'));
|
||||
add_site('ftp');
|
||||
}
|
||||
edit_config('ftp', $methdir);
|
||||
|
||||
my $ftp;
|
||||
sub download {
|
||||
foreach (@{$CONFIG{site}}) {
|
||||
$ftp = do_connect(ftpsite => $_->[0],
|
||||
ftpdir => $_->[1],
|
||||
passive => $_->[3],
|
||||
username => $_->[4],
|
||||
password => $_->[5],
|
||||
useproxy => $CONFIG{use_auth_proxy},
|
||||
proxyhost => $CONFIG{proxyhost},
|
||||
proxylogname => $CONFIG{proxylogname},
|
||||
proxypassword => $CONFIG{proxypassword});
|
||||
|
||||
my @dists = @{$_->[2]};
|
||||
|
||||
foreach my $dist (@dists) {
|
||||
my $dir = "$dist/binary-$arch";
|
||||
print "Checking $dir...\n";
|
||||
# if (!$ftp->pasv()) { print $ftp->message . "\n"; die 'error'; }
|
||||
my @dirlst = $ftp->ls("$dir/");
|
||||
my $got_pkgfile = 0;
|
||||
|
||||
foreach my $line (@dirlst) {
|
||||
if($line =~ /Packages/) {
|
||||
$got_pkgfile = 1;
|
||||
}
|
||||
}
|
||||
if( !$got_pkgfile) {
|
||||
print "warning: could not find a Packages file in $dir\n",
|
||||
"This may not be a problem if the directory is a symbolic link\n";
|
||||
$problem = 1;
|
||||
}
|
||||
}
|
||||
print "Closing ftp connection...\n";
|
||||
$ftp->quit();
|
||||
}
|
||||
}
|
||||
|
||||
# download stuff (protect from ^C)
|
||||
print "\nUsing FTP to check directories...(stop with ^C)\n\n";
|
||||
eval {
|
||||
local $SIG{INT} = sub {
|
||||
die "interrupted!\n";
|
||||
};
|
||||
download();
|
||||
};
|
||||
if($@) {
|
||||
$ftp->quit();
|
||||
print 'FTP ERROR - ';
|
||||
if ($@ eq 'connect') {
|
||||
print "config was untested\n";
|
||||
} else {
|
||||
print "$@\n";
|
||||
}
|
||||
$exit = 1;
|
||||
};
|
||||
|
||||
# output new vars file
|
||||
$CONFIG{done} = 1;
|
||||
store_config("$methdir/vars");
|
||||
chmod 0600, "$methdir/vars";
|
||||
|
||||
if($exit || $problem) {
|
||||
print "Press <enter> to continue\n";
|
||||
<STDIN>;
|
||||
}
|
||||
|
||||
exit $exit;
|
250
dselect/methods/ftp/update.pl
Executable file
250
dselect/methods/ftp/update.pl
Executable file
|
@ -0,0 +1,250 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright © 1996 Andy Guy <andy@cyteen.org>
|
||||
# Copyright © 1998 Martin Schulze <joey@infodrom.north.de>
|
||||
# Copyright © 1999, 2009 Raphaël Hertzog <hertzog@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
eval q{
|
||||
use Dpkg; # Dummy import to require the presence of Dpkg::*.
|
||||
};
|
||||
if ($@) {
|
||||
warn "Missing Dpkg modules required by the FTP access method.\n\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
use Dselect::Method;
|
||||
use Dselect::Method::Ftp;
|
||||
|
||||
# deal with arguments
|
||||
my $vardir = $ARGV[0];
|
||||
my $method = $ARGV[1];
|
||||
my $option = $ARGV[2];
|
||||
|
||||
if ($option eq 'manual') {
|
||||
print "Enter package file names or a blank line to finish\n";
|
||||
while(1) {
|
||||
print 'Enter package file name:';
|
||||
my $fn = <STDIN>;
|
||||
chomp $fn;
|
||||
if ($fn eq '') {
|
||||
exit 0;
|
||||
}
|
||||
if ( -f $fn ) {
|
||||
system('dpkg', '--merge-avail', $fn);
|
||||
} else {
|
||||
print "Could not find $fn, try again\n";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#print "vardir: $vardir, method: $method, option: $option\n";
|
||||
|
||||
my $arch = qx(dpkg --print-architecture);
|
||||
$arch = 'i386' if $?;
|
||||
chomp $arch;
|
||||
my $exit = 0;
|
||||
|
||||
# get info from control file
|
||||
read_config("$vardir/methods/ftp/vars");
|
||||
|
||||
chdir "$vardir/methods/ftp";
|
||||
|
||||
print "Getting Packages files...(stop with ^C)\n\n";
|
||||
|
||||
my @pkgfiles;
|
||||
my $ftp;
|
||||
my $packages_modified = 0;
|
||||
|
||||
sub download {
|
||||
foreach (@{$CONFIG{site}}) {
|
||||
my $site = $_;
|
||||
|
||||
$ftp = do_connect(ftpsite => $_->[0],
|
||||
ftpdir => $_->[1],
|
||||
passive => $_->[3],
|
||||
username => $_->[4],
|
||||
password => $_->[5],
|
||||
useproxy => $CONFIG{use_auth_proxy},
|
||||
proxyhost => $CONFIG{proxyhost},
|
||||
proxylogname => $CONFIG{proxylogname},
|
||||
proxypassword => $CONFIG{proxypassword});
|
||||
|
||||
my @dists = @{$_->[2]};
|
||||
PACKAGE:
|
||||
foreach my $dist (@dists) {
|
||||
my $dir = "$dist/binary-$arch";
|
||||
my $must_get = 0;
|
||||
my $newest_pack_date;
|
||||
|
||||
# check existing Packages on remote site
|
||||
print "\nChecking for Packages file... ";
|
||||
$newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
|
||||
if (defined $newest_pack_date) {
|
||||
print "$dir/Packages.gz\n";
|
||||
} else {
|
||||
$dir = "$dist";
|
||||
$newest_pack_date = do_mdtm ($ftp, "$dir/Packages.gz");
|
||||
if (defined $newest_pack_date) {
|
||||
print "$dir/Packages.gz\n";
|
||||
} else {
|
||||
print "Couldn't find Packages.gz in $dist/binary-$arch or $dist; ignoring.\n";
|
||||
print "Your setup is probably wrong, check the distributions directories,\n";
|
||||
print "and try with passive mode enabled/disabled (if you use a proxy/firewall)\n";
|
||||
next PACKAGE;
|
||||
}
|
||||
}
|
||||
|
||||
# we now have $dir set to point to an existing Packages.gz file
|
||||
|
||||
# check if we already have a Packages file (and get its date)
|
||||
$dist =~ tr/\//_/;
|
||||
my $file = "Packages.$site->[0].$dist";
|
||||
|
||||
# if not
|
||||
if (! -f $file) {
|
||||
# must get one
|
||||
# print "No Packages here; must get it.\n";
|
||||
$must_get = 1;
|
||||
} else {
|
||||
# else check last modification date
|
||||
my @pack_stat = stat($file);
|
||||
if($newest_pack_date > $pack_stat[9]) {
|
||||
# print "Packages has changed; must get it.\n";
|
||||
$must_get = 1;
|
||||
} elsif ($newest_pack_date < $pack_stat[9]) {
|
||||
print " Our file is newer than theirs; skipping.\n";
|
||||
} else {
|
||||
print " Already up-to-date; skipping.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($must_get) {
|
||||
-f 'Packages.gz' and unlink 'Packages.gz';
|
||||
-f 'Packages' and unlink 'Packages';
|
||||
my $size = 0;
|
||||
|
||||
TRY_GET_PACKAGES:
|
||||
while (1) {
|
||||
if ($size) {
|
||||
print ' Continuing ';
|
||||
} else {
|
||||
print ' Getting ';
|
||||
}
|
||||
print "Packages file from $dir...\n";
|
||||
eval {
|
||||
if ($ftp->get("$dir/Packages.gz", 'Packages.gz', $size)) {
|
||||
if (system('gunzip', 'Packages.gz')) {
|
||||
print " Couldn't gunzip Packages.gz, stopped";
|
||||
die 'error';
|
||||
}
|
||||
} else {
|
||||
print " Couldn't get Packages.gz from $dir !!! Stopped.";
|
||||
die 'error';
|
||||
}
|
||||
};
|
||||
if ($@) {
|
||||
$size = -s 'Packages.gz';
|
||||
if (ref($ftp)) {
|
||||
$ftp->abort();
|
||||
$ftp->quit();
|
||||
};
|
||||
if (yesno ('y', "Transfer failed at $size: retry at once")) {
|
||||
$ftp = do_connect(ftpsite => $site->[0],
|
||||
ftpdir => $site->[1],
|
||||
passive => $site->[3],
|
||||
username => $site->[4],
|
||||
password => $site->[5],
|
||||
useproxy => $CONFIG{use_auth_proxy},
|
||||
proxyhost => $CONFIG{proxyhost},
|
||||
proxylogname => $CONFIG{proxylogname},
|
||||
proxypassword => $CONFIG{proxypassword});
|
||||
|
||||
if ($newest_pack_date != do_mdtm ($ftp, "$dir/Packages.gz")) {
|
||||
print ("Packages file has changed !\n");
|
||||
$size = 0;
|
||||
}
|
||||
next TRY_GET_PACKAGES;
|
||||
} else {
|
||||
die 'error';
|
||||
}
|
||||
}
|
||||
last TRY_GET_PACKAGES;
|
||||
}
|
||||
|
||||
if (!rename 'Packages', "Packages.$site->[0].$dist") {
|
||||
print " Couldn't rename Packages to Packages.$site->[0].$dist";
|
||||
die 'error';
|
||||
} else {
|
||||
# set local Packages file to same date as the one it mirrors
|
||||
# to allow comparison to work.
|
||||
utime $newest_pack_date, $newest_pack_date, "Packages.$site->[0].$dist";
|
||||
$packages_modified = 1;
|
||||
}
|
||||
}
|
||||
push @pkgfiles, "Packages.$site->[0].$dist";
|
||||
}
|
||||
$ftp->quit();
|
||||
}
|
||||
}
|
||||
|
||||
eval {
|
||||
local $SIG{INT} = sub {
|
||||
die "interrupted!\n";
|
||||
};
|
||||
download();
|
||||
};
|
||||
if($@) {
|
||||
$ftp->quit() if (ref($ftp));
|
||||
if($@ =~ /timeout/i) {
|
||||
print "FTP TIMEOUT\n";
|
||||
} else {
|
||||
print "FTP ERROR - $@\n";
|
||||
}
|
||||
$exit = 1;
|
||||
};
|
||||
|
||||
# Don't clear if nothing changed.
|
||||
if ($packages_modified) {
|
||||
print <<'EOM';
|
||||
|
||||
It is a good idea to clear the available list of old packages.
|
||||
However if you have only downloaded a Package files from non-main
|
||||
distributions you might not want to do this.
|
||||
|
||||
EOM
|
||||
if (yesno ('y', 'Do you want to clear available list')) {
|
||||
print "Clearing...\n";
|
||||
if (system('dpkg', '--clear-avail')) {
|
||||
print 'dpkg --clear-avail failed.';
|
||||
die 'error';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$packages_modified) {
|
||||
print "No Packages files was updated.\n";
|
||||
} else {
|
||||
foreach my $file (@pkgfiles) {
|
||||
if (system('dpkg', '--merge-avail', $file)) {
|
||||
print "Dpkg merge available failed on $file";
|
||||
$exit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
exit $exit;
|
106
dselect/methods/media/README.media
Normal file
106
dselect/methods/media/README.media
Normal file
|
@ -0,0 +1,106 @@
|
|||
Installation method for multiple binary media
|
||||
---------------------------------------------
|
||||
|
||||
This directory contains a method to be used within dselect in order to
|
||||
access Debian binary packages stored across multiple binary media
|
||||
(CDs, DVDs, BDs, or USBs).
|
||||
|
||||
Acquiring package data
|
||||
---------------------
|
||||
|
||||
It is possible to access the following binary directories within
|
||||
«dists/stable»:
|
||||
|
||||
. main
|
||||
. contrib
|
||||
. non-free-firmware
|
||||
. non-free
|
||||
. local
|
||||
|
||||
The selected method will try to read the «Packages.cd» file from each
|
||||
of these directories if it is available.
|
||||
|
||||
Identifying the media
|
||||
----------------------
|
||||
|
||||
A unique name is associated to each media disc. This name should correspond
|
||||
with the label on the front of the media disc. The name is also available on
|
||||
the media disc, so the system can find out which media disc is inserted into
|
||||
the computer at any time.
|
||||
|
||||
Installing the files
|
||||
--------------------
|
||||
|
||||
At the beginning of the installation the “media” method will sort the list
|
||||
of to-be-installed packages and install them media disc by media disc. If a
|
||||
different media disc is required the user will be prompted to exchange
|
||||
the media disc.
|
||||
|
||||
Preparing multiple binary media discs
|
||||
-------------------------------------
|
||||
|
||||
Since the “media” method needs to know which packages are on which
|
||||
media disc one cannot use regular «Packages» files. An additional data
|
||||
field «X-Medium:» is required. The first media disc from the set should
|
||||
contain all «Packages.cd» files. To be more convenient you should
|
||||
include the «Packages.cd» files on all media discs. This ensures that
|
||||
you do not have to start with the first media disc all the time.
|
||||
|
||||
Additionally the package needs to gain information which media disc is
|
||||
currently used. Thus each media disc contains the file «.disk/info»
|
||||
which contains the symbolic name for the media disc as specified by
|
||||
«X-Medium:».
|
||||
|
||||
In order to be able to create the modified «Packages.cd» files, you
|
||||
have to use the «-M medium» option of dpkg-scanpackages (supported
|
||||
in dpkg-dev since 1.15.5).
|
||||
|
||||
To split the “main” distribution into two media discs you will need to
|
||||
create a «Packages.cd» file for each «binary-$arch» directory.
|
||||
Afterwards you simply append the second one to the first one and
|
||||
put the resulting «Packages.cd» file into both «binary-$arch»
|
||||
directories.
|
||||
|
||||
Sample Layout
|
||||
-------------
|
||||
|
||||
Media disc 1 .disk/info = "Debian GNU/Linux binary-amd64"
|
||||
dists/stable/main/binary-all/
|
||||
binary-amd64/Packages.cd.gz
|
||||
binary-amd64/net/foo.deb
|
||||
contrib/binary-amd64/Packages.cd.gz
|
||||
non-free-firmware/binary-amd64/Packages.cd.gz
|
||||
non-free/binary-amd64/Packages.cd.gz
|
||||
|
||||
Media disc 2 .disk/info = "Debian GNU/Linux contrib-amd64"
|
||||
dists/stable/main/binary-amd64/Packages.cd.gz
|
||||
contrib/binary-all/
|
||||
binary-amd64/Packages.cd.gz
|
||||
binary-amd64/net/foo.deb
|
||||
non-free-firmware/binary-amd64/Packages.cd.gz
|
||||
non-free/binary-amd64/Packages.cd.gz
|
||||
|
||||
Media disc 3 .disk/info = "Debian GNU/Linux non-free-amd64"
|
||||
dists/stable/main/binary-amd64/Packages.cd.gz
|
||||
contrib/binary-amd64/Packages.cd.gz
|
||||
non-free-firmware/binary-amd64/Packages.cd.gz
|
||||
non-free/binary-all/
|
||||
binary-amd64/Packages.cd.gz
|
||||
binary-amd64/net/foo.deb
|
||||
|
||||
To re-generate the Packages file you have to change directory into
|
||||
«dists/stable/$part» and issue «dpkg-scanpackages» as follows. It is
|
||||
assumed that you use regular compressed overrides files in
|
||||
«/pub/debian/indices».
|
||||
|
||||
Media disc 1: dpkg-scanpackages -M "Debian GNU/Linux binary-amd64" \
|
||||
binary-amd64 /pub/debian/indices/override.buster.gz \
|
||||
dists/stable/ > binary-amd64/Packages
|
||||
|
||||
Media disc 2: dpkg-scanpackages -M "Debian GNU/Linux contrib-amd64" \
|
||||
binary-amd64 /pub/debian/indices/override.buster.contrib.gz \
|
||||
dists/stable/ > binary-amd64/Packages
|
||||
|
||||
Media disc 3: dpkg-scanpackages -M "Debian GNU/Linux non-free-amd64" \
|
||||
binary-amd64 /pub/debian/indices/override.buster.non-free.gz \
|
||||
dists/stable/ > binary-amd64/Packages
|
3
dselect/methods/media/desc.media
Normal file
3
dselect/methods/media/desc.media
Normal file
|
@ -0,0 +1,3 @@
|
|||
Installation from a media set containing a Debian distribution. The
|
||||
media discs may be or not be mounted already and should contain a standard
|
||||
ISO9660 media filesystem.
|
282
dselect/methods/media/install.sh
Executable file
282
dselect/methods/media/install.sh
Executable file
|
@ -0,0 +1,282 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de>
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
|
||||
cd "$vardir/methods/$method"
|
||||
|
||||
. ./shvar.$option
|
||||
|
||||
#debug() { echo "DEBUG: $@"; }
|
||||
debug() {
|
||||
true
|
||||
}
|
||||
iarch=$(dpkg --print-architecture)
|
||||
|
||||
# 1/ mountpoint
|
||||
# 2/ hierarchy
|
||||
getdisklabel () {
|
||||
debug "$1" "$2"
|
||||
if [ -f $1/.disk/info ]; then
|
||||
echo -n $(head -1 "$1/.disk/info")
|
||||
elif [ -f $1$2/.disk/info ]; then
|
||||
echo -n $(head -1 "$1$2/.disk/info")
|
||||
else
|
||||
echo -n 'Non-Debian disc'
|
||||
fi
|
||||
}
|
||||
|
||||
xit=1
|
||||
|
||||
do_umount() {
|
||||
if [ -n "$umount" ]; then
|
||||
echo umount "$umount"
|
||||
#">/dev/null" "2>&1"
|
||||
fi
|
||||
}
|
||||
|
||||
do_mount() {
|
||||
if [ ! -b "$p_blockdev" ]; then
|
||||
loop=",loop"
|
||||
fi
|
||||
|
||||
if [ -n "$p_blockdev" ]; then
|
||||
umount="$p_mountpoint"
|
||||
echo mount -rt iso9660 -o nosuid,nodev${loop} "$p_blockdev" "$p_mountpoint"\; umount="$p_mountpoint"
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'eval $(do_umount); exit $xit' 0
|
||||
|
||||
eval $(do_mount)
|
||||
|
||||
predep="$vardir/predep-package"
|
||||
while true; do
|
||||
thisdisk="$(getdisklabel ${p_mountpoint} ${p_hierbase})"
|
||||
set +e
|
||||
dpkg --predep-package >"$predep"
|
||||
rc=$?
|
||||
set -e
|
||||
if test $rc = 1; then
|
||||
break
|
||||
fi
|
||||
test $rc = 0
|
||||
|
||||
perl -e '
|
||||
($binaryprefix,$predep,$thisdisk) = @ARGV;
|
||||
open(P, "< $predep") or die "cannot open $predep: $!\n";
|
||||
while (<P>) {
|
||||
s/\s*\n$//;
|
||||
$package = $_ if s/^Package: //i;
|
||||
/^X-Medium:\s+(.*)\s*/ and $medium = $1;
|
||||
@filename = split(/ /,$_) if s/^Filename: //i;
|
||||
@msdosfilename = split(/ /,$_) if s/^MSDOS-Filename: //i;
|
||||
}
|
||||
die "internal error - no package" if length($package) == 0;
|
||||
die "internal error - no filename" if not @filename;
|
||||
die "internal error - mismatch >@filename< >@msdosfilename<"
|
||||
if @filename && @msdosfilename &&
|
||||
@filename != @msdosfilename;
|
||||
if ($medium && ($medium ne $thisdisk)) {
|
||||
print "
|
||||
|
||||
This is
|
||||
$thisdisk
|
||||
However, $package is expected on disc:
|
||||
$medium
|
||||
Please change the discs and press <RETURN>.
|
||||
|
||||
";
|
||||
exit(1);
|
||||
}
|
||||
@invoke = (); $| =1;
|
||||
for ($i = 0; $i <= $#filename; $i++) {
|
||||
$ppart = $i+1;
|
||||
print "Looking for part $ppart of $package ... ";
|
||||
if (-f "$binaryprefix$filename[$i]") {
|
||||
$print = $filename[$i];
|
||||
$invoke = "$binaryprefix$filename[$i]";
|
||||
} elsif (-f "$binaryprefix$msdosfilename[$i]") {
|
||||
$print = $msdosfilename[$i];
|
||||
$invoke = "$binaryprefix$msdosfilename[$i]";
|
||||
} else {
|
||||
$base = $filename[$i]; $base =~ s,.*/,,;
|
||||
$msdosbase = $msdosfilename[$i]; $msdosbase =~ s,.*/,,;
|
||||
$c = open(X, "-|"));
|
||||
if (not defined $c) {
|
||||
die "failed to fork for find: $!\n";
|
||||
}
|
||||
if (!$c) {
|
||||
exec("find", "-L",
|
||||
length($binaryprefix) ? $binaryprefix : ".",
|
||||
"-name",$base,"-o","-name",$msdosbase);
|
||||
die "failed to exec find: $!\n";
|
||||
}
|
||||
while (chop($invoke = <X>)) { last if -f $invoke; }
|
||||
$print = $invoke;
|
||||
if (substr($print,0,length($binaryprefix)+1) eq
|
||||
"$binaryprefix/") {
|
||||
$print = substr($print,length($binaryprefix));
|
||||
}
|
||||
}
|
||||
if (!length($invoke)) {
|
||||
warn "
|
||||
|
||||
Cannot find the appropriate file(s) anywhere needed to install or upgrade
|
||||
package $package. Expecting version $version or later, as listed in the
|
||||
Packages file.
|
||||
|
||||
Perhaps the package was downloaded with an unexpected name? In any case,
|
||||
you must find the file(s) and then either place it with the correct
|
||||
filename(s) (as listed in the Packages file or in $vardir/available)
|
||||
and rerun the installation, or upgrade the package by using
|
||||
\"dpkg --install --auto-deconfigure" by hand.
|
||||
|
||||
";
|
||||
exit(1);
|
||||
}
|
||||
print "$print\n";
|
||||
push(@invoke,$invoke);
|
||||
}
|
||||
print "Running dpkg -iB for $package ...\n";
|
||||
exec("dpkg","-iB","--",@invoke);
|
||||
die "failed to exec dpkg: $!\n";
|
||||
' -- "$p_mountpoint$p_hierbase" "$predep" "$thisdisk"
|
||||
done
|
||||
|
||||
perl -e '
|
||||
$SIG{INT} = sub { cd $vardir; unlink <tmp/*>; exit 1; };
|
||||
$| = 1;
|
||||
my ($vardir, $mountpoint, $hierbase, $mount, $umount) = @ARGV;
|
||||
my $line;
|
||||
my $AVAIL = "$vardir/methods/media/available";
|
||||
my $STATUS = "$vardir/status";
|
||||
my %Installed, %Filename, %Medium;
|
||||
print "Get currently installed package versions...";
|
||||
open(IN, "$STATUS") or die "cannot open $STATUS: $!\n";
|
||||
$line = 0;
|
||||
{ local $/ = "";
|
||||
while (<IN>) {
|
||||
my %status;
|
||||
my @pstat;
|
||||
$line++ % 20 or print ".";
|
||||
s/\n\s+/ /g;
|
||||
%status = ("", split /^(\S*?):\s*/m, $_);
|
||||
map { chomp $status{$_}; $status{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %status;
|
||||
@pstat = split(/ /, $status{Status});
|
||||
next unless ($pstat[0] eq "install");
|
||||
if ($pstat[2] eq "config-files" || $pstat[2] eq "not-installed") {
|
||||
$Installed{$status{Package}} = "0.0";
|
||||
} else {
|
||||
$Installed{$status{Package}} = $status{Version} || "" ;
|
||||
}
|
||||
}; }
|
||||
print "\nGot ", scalar keys %Installed, " installed/pending packages\n";
|
||||
print "Scanning available packages...";
|
||||
$line = 0;
|
||||
open(IN, "$AVAIL") or die("Cannot open $AVAIL: $!\n");
|
||||
{ local $/ = "";
|
||||
while (<IN>) {
|
||||
my $updated;
|
||||
$line++ % 20 or print ".";
|
||||
|
||||
s/\n\s+/ /g;
|
||||
%avail = ("", split /^(\S*?):\s*/m, $_);
|
||||
map { chomp $avail{$_}; $avail{$_} =~ s/^\s*(.*?)\s*$/$1/;} keys %avail;
|
||||
|
||||
next unless defined $Installed{$avail{Package}};
|
||||
|
||||
system "dpkg", "--compare-versions", $avail{Version}, "gt", $Installed{$avail{Package}};
|
||||
$updated = ($? == 0);
|
||||
#print "$avail{Package}(" . ($updated ? "+" : "=") . ") ";
|
||||
$updated or next;
|
||||
|
||||
$Filename{$avail{Package}} = $avail{Filename};
|
||||
|
||||
next unless defined $avail{"X-Medium"};
|
||||
${Medium{$avail{"X-Medium"}}} or ${Medium{$avail{"X-Medium"}}} = [];
|
||||
push @{${Medium{$avail{"X-Medium"}}}}, $avail{Package};
|
||||
}; };
|
||||
print "\n";
|
||||
|
||||
if (@_ = keys(%Medium)) {
|
||||
print "You will need the following distribution disc(s):\n",
|
||||
join (", ", @_), "\n";
|
||||
}
|
||||
|
||||
foreach $need (sort @_) {
|
||||
if (-r "$mountpoint/.disk/info") {
|
||||
open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n");
|
||||
} else {
|
||||
open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n");
|
||||
}
|
||||
$disk = <IN>; chomp $disk; close(IN);
|
||||
|
||||
print "Processing disc\n $need\n";
|
||||
|
||||
while ($disk ne $need) {
|
||||
print "Wrong disc. This is disc\n $disk\n";
|
||||
print "However, the needed disc is\n $need\n";
|
||||
print "Please change the discs and press <RETURN>\n";
|
||||
system($umount);
|
||||
<STDIN>;
|
||||
system($mount);
|
||||
$? and warn("cannot mount $mount\n");
|
||||
} continue {
|
||||
if (-r "$mountpoint/.disk/info") {
|
||||
open(IN, "$mountpoint/.disk/info") or die("$mountpoint/.disk/info: $!\n");
|
||||
} else {
|
||||
open(IN, "$mountpoint/$hierbase/.disk/info") or die("$mountpoint/$hierbase/.disk/info: $!\n");
|
||||
}
|
||||
$disk = <IN>; chomp $disk; close(IN);
|
||||
}
|
||||
|
||||
-d "tmp" || mkdir "tmp", 0755 or die("Cannot mkdir tmp: $!\n");
|
||||
unlink <tmp/*>;
|
||||
|
||||
print "creating symlinks...\n";
|
||||
foreach (@{$Medium{$need}}) {
|
||||
($basename = $Filename{$_}) =~ s/.*\///;
|
||||
symlink "$mountpoint/$hierbase/$Filename{$_}",
|
||||
"tmp/$basename";
|
||||
}
|
||||
chdir "tmp" or die "cannot chdir to tmp: $!\n";
|
||||
system "dpkg", "-iGROEB", ".";
|
||||
unlink <*>;
|
||||
chdir "..";
|
||||
|
||||
if ($?) {
|
||||
print "\nThe dpkg run produced errors. Please state whether to\n",
|
||||
"continue with the next media disc. [Y/n]: ";
|
||||
$answer = <STDIN>;
|
||||
exit 1 if $answer =~ /^n/i;
|
||||
$ouch = $?;
|
||||
}
|
||||
}
|
||||
|
||||
exit $ouch;
|
||||
|
||||
' "$vardir" "$p_mountpoint" "$p_hierbase" "$(do_mount)" "$(do_umount)"
|
||||
|
||||
echo -n 'Installation OK. Hit RETURN. '
|
||||
read response
|
||||
|
||||
xit=0
|
1
dselect/methods/media/names
Normal file
1
dselect/methods/media/names
Normal file
|
@ -0,0 +1 @@
|
|||
31 media Install from a media set (CDs, DVDs, BDs, USBs).
|
489
dselect/methods/media/setup.sh
Executable file
489
dselect/methods/media/setup.sh
Executable file
|
@ -0,0 +1,489 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de>
|
||||
# Copyright © 1998-1999 Martin Schulze <joey@infodrom.north.de>
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
|
||||
test -d "$vardir/methods/$method" || mkdir "$vardir/methods/$method"
|
||||
cd "$vardir/methods/$method"
|
||||
tp="$(mktemp --tmpdir $method.XXXXXXXXXX)"
|
||||
|
||||
iarch=$(dpkg --print-architecture)
|
||||
dist=stable
|
||||
|
||||
xit=1
|
||||
trap '
|
||||
rm -f $tp.?
|
||||
if [ -n "$umount" ]; then
|
||||
umount "$umount" >/dev/null 2>&1
|
||||
fi
|
||||
exit $xit
|
||||
' 0
|
||||
|
||||
if ls -d "$tp.?" >/dev/null 2>&1; then
|
||||
rm $tp.?
|
||||
fi
|
||||
|
||||
#debug() { echo "DEBUG: $@"; }
|
||||
debug() {
|
||||
true
|
||||
}
|
||||
ismulti() {
|
||||
debug $1 $2; test -e "$1/.disk/info" || test -e "$1$2/.disk/info"
|
||||
}
|
||||
|
||||
# 1/ mountpoint
|
||||
# 2/ hierarchy
|
||||
getdisklabel () {
|
||||
debug "$1" "$2"
|
||||
if [ -f $1/.disk/info ]; then
|
||||
echo -n $(head -1 "$1/.disk/info")
|
||||
elif [ -f $1$2/.disk/info ]; then
|
||||
echo -n $(head -1 "$1$2/.disk/info")
|
||||
else
|
||||
echo -n 'Non-Debian disc'
|
||||
fi
|
||||
}
|
||||
|
||||
yesno () {
|
||||
while true; do
|
||||
echo -n "$2 [$1] "
|
||||
read response
|
||||
if [ -z "$response" ]; then
|
||||
response="$1"
|
||||
fi
|
||||
case "$response" in
|
||||
[Nn]*)
|
||||
yesno=no
|
||||
return
|
||||
;;
|
||||
[Yy]*)
|
||||
yesno=yes
|
||||
return
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
getblockdev () {
|
||||
mountpoint="$vardir/methods/mnt"
|
||||
if [ -z "$defaultdevice" ]; then
|
||||
defaultdevice="$newdefaultdevice"
|
||||
elif [ "$defaultdevice" != "$newdefaultdevice" ]; then
|
||||
echo "Last time you specified installation from $defaultdevice."
|
||||
fi
|
||||
promptstring="$1"
|
||||
while [ -z "$blockdevice" ]; do
|
||||
echo -n "$promptstring [$defaultdevice]: "
|
||||
read response
|
||||
if [ -z "$response" ]; then
|
||||
response="$defaultdevice"
|
||||
fi
|
||||
if [ ! -b "$response" ]; then
|
||||
echo "$response is not a block device - will try as loopback."
|
||||
loop=",loop"
|
||||
fi
|
||||
tryblockdevice="$response"
|
||||
fstype=iso9660
|
||||
umount="$mountpoint"
|
||||
if mount -rt "$fstype" -o nosuid,nodev$loop "$tryblockdevice" "$mountpoint"
|
||||
then
|
||||
echo
|
||||
blockdevice="$tryblockdevice"
|
||||
else
|
||||
umount=""
|
||||
echo "Unable to mount $tryblockdevice on $mountpoint, type $fstype."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
outputparam () {
|
||||
echo "$2" | sed -e "s/'/'\\\\''/; s/^/$1='/; s/$/'/" >&3
|
||||
}
|
||||
|
||||
## MAIN
|
||||
intrkey="$(stty -a | sed -n 's/.*intr = \([^;]*\);.*/\1/p')"
|
||||
echo "
|
||||
If you make a mistake, use the interrupt key ($intrkey) to abort.
|
||||
"
|
||||
|
||||
# State variables, “best first”
|
||||
# {main,ctb,nf,lcl}_{packages,binary}
|
||||
# Empty before we've found them or if they're not available,
|
||||
# set to the relevant bit under mountpoint otherwise.
|
||||
# hierbase
|
||||
# A directory containing a Debian FTP site mirror tree.
|
||||
# mountpoint
|
||||
# The mountpoint for the filesystem containing the stuff
|
||||
# empty or unset if we don't know yet, or if we haven't mounted anything;
|
||||
# may also be empty if ‘directory’ was set.
|
||||
# blockdevice
|
||||
# The actual block device to mount.
|
||||
# fstype
|
||||
# The filesystem type to use.
|
||||
# defaultdevice
|
||||
# The default block device to mount.
|
||||
|
||||
p_usedevel=no
|
||||
if [ -f shvar.$option ]; then
|
||||
. ./shvar.$option
|
||||
defaultdevice="$p_blockdev"
|
||||
usedevel="$p_usedevel"
|
||||
fi
|
||||
|
||||
mount >$tp.m
|
||||
sed -n 's/ ([^)]*)$//; s/^[^ ]* on //; s/ type iso9660$//p' <$tp.m >$tp.l
|
||||
ncdroms=$(wc -l <$tp.l)
|
||||
if [ $ncdroms -gt 1 ]; then
|
||||
response=""
|
||||
while [ -z "$response" ]; do
|
||||
echo 'Several media discs (ISO9660 filesystems) are mounted:'
|
||||
grep -E 'type iso9660 \([^)]*\)$' <$tp.m | nl
|
||||
echo -n "Is it any of these ? Type a number, or 'n' for none. "
|
||||
read response
|
||||
response="$(echo "$response" | sed -e 's/[ ]*$//')"
|
||||
if expr "$response" : '[0-9][0-9]*$' >/dev/null && \
|
||||
[ $response -ge 1 -a $response -le $ncdroms ]; then
|
||||
mountpoint="$(sed -n $response'p' <$tp.l)"
|
||||
echo
|
||||
elif expr "$response" : '[Nn]' >/dev/null; then
|
||||
mountpoint=""
|
||||
else
|
||||
response=""
|
||||
fi
|
||||
done
|
||||
elif [ $ncdroms = 1 ]; then
|
||||
mountpoint="$(cat $tp.l)"
|
||||
perl -ne 'print if s/ type iso9660 \([^)]*\)$// && s/ on .*$//;' \
|
||||
<$tp.m >$tp.d
|
||||
blockdevice="$(cat $tp.d)"
|
||||
yesno yes \
|
||||
"Found a media disc: $blockdevice, mounted on $mountpoint. Is it the right one?"
|
||||
if [ $yesno = no ]; then
|
||||
echo 'Unmounting it ...'
|
||||
umount="$mountpoint"
|
||||
while true; do
|
||||
echo -n 'Please insert the right disc, and hit return: '
|
||||
read response
|
||||
if mount -rt iso9660 -o nosuid,nodev \
|
||||
"$blockdevice" "$mountpoint"; then
|
||||
echo
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if [ -z "$mountpoint" ]; then
|
||||
if [ -b /dev/cdrom ]; then
|
||||
echo 'Found that /dev/cdrom exists and is a block device.'
|
||||
newdefaultdevice=/dev/cdrom
|
||||
fi
|
||||
getblockdev 'Insert the media and enter the block device name'
|
||||
fi
|
||||
|
||||
if [ -n "$mountpoint" ]; then
|
||||
# We must have $mountpoint
|
||||
echo \
|
||||
'All directory names should be entered relative to the root of the media disc.
|
||||
'
|
||||
fi
|
||||
|
||||
# now try to get the users idea where the debian
|
||||
# hierarchy start below the mointpoint
|
||||
|
||||
debug "mountpoint: $mountpoint"
|
||||
while true; do
|
||||
if ismulti "${mountpoint}" "${hierbase}"; then
|
||||
multi=yes
|
||||
fi
|
||||
|
||||
echo \
|
||||
"Need to know where on the media disc the top level of the Debian
|
||||
distribution is - this will usually contain the 'dists' directory.
|
||||
|
||||
If the media disc is badly organized and doesn't have a straightforward copy of
|
||||
the distribution you may answer 'none' and the needed parts will be prompted
|
||||
individually."
|
||||
|
||||
defhierbase=none
|
||||
if [ -n "$p_hierbase" ]; then
|
||||
if [ -d "$mountpoint/$p_hierbase/dists/$dist/main/binary-$iarch" \
|
||||
-o -n "$multi" ]; then
|
||||
echo "Last time you said '$p_hierbase', and that looks plausible."
|
||||
defhierbase="$p_hierbase"
|
||||
else
|
||||
echo "
|
||||
Last time you said '$p_hierbase', but that doesn't look plausible,
|
||||
since '$p_hierbase/dists/$dist/main/binary-$iarch' doesn't seem to exist.
|
||||
And it does not appear that you are using a multiple media set."
|
||||
fi
|
||||
fi
|
||||
|
||||
# at this point defhierbase is set if it looks plausible
|
||||
# if ‘none’ was entered, we assume a media with a debian/ directory
|
||||
|
||||
if [ none = "$defhierbase" -a -d "$mountpoint/debian/dists/$dist/main/binary-$iarch" ]
|
||||
then
|
||||
echo "'/debian' exists and looks plausible, so that's the default."
|
||||
defhierbase=/debian
|
||||
fi
|
||||
|
||||
echo -n "Distribution top level ? [$defhierbase] "
|
||||
read response
|
||||
if [ -z "$response" ]; then
|
||||
response="$defhierbase"
|
||||
fi
|
||||
if [ none = "$response" ]; then
|
||||
hierbase=""
|
||||
break
|
||||
elif ismulti "$mountpoint" "$response" && [ -z "$multi" ]; then
|
||||
multi=yes
|
||||
fi
|
||||
|
||||
if ! [ -d "$mountpoint/$response/dists/$dist/main/binary-$iarch" \
|
||||
-o -n "$multi" ]; then
|
||||
echo \
|
||||
"Neither $response/dists/$dist/main/binary-$iarch does not exist,
|
||||
nor are you using a multiple media set"
|
||||
break
|
||||
fi
|
||||
|
||||
hierbase="$(echo "$response" | sed -e 's:/$::; s:^/*:/:; s:/\+:/:g;')"
|
||||
debug "hierbase: [$hierbase]"
|
||||
|
||||
if [ -n "$multi" ]; then
|
||||
disklabel=$(getdisklabel "$mountpoint" "/$response")
|
||||
echo "Ok, this is disc"
|
||||
echo " $disklabel"
|
||||
#echo "Updating multiple media contents file cache ..."
|
||||
#multi_contentsfile="${mountpoint}/${response}/.disk/contents.gz"
|
||||
#zcat "$multi_contentsfile" > disk-contents.$option
|
||||
fi
|
||||
|
||||
break;
|
||||
done
|
||||
|
||||
distribution=$dist
|
||||
if [ -n "$hierbase" ]; then
|
||||
if [ -d "$mountpoint/$hierbase/dists/unstable/binary-$iarch" ]; then
|
||||
echo \
|
||||
'
|
||||
Both a stable released distribution and a work-in-progress
|
||||
development tree are available for installation. Would you like to
|
||||
use the unreleased development tree (this is only recommended for
|
||||
experts who like to live dangerously and want to help with testing) ?'
|
||||
yesno "$p_usedevel" 'Use unreleased development distribution ?'
|
||||
usedevel="$yesno"
|
||||
if [ "$usedevel" = yes ]; then
|
||||
distribution=development
|
||||
fi
|
||||
else
|
||||
usedevel=no
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
|
||||
case "$hierbase" in
|
||||
/* )
|
||||
;;
|
||||
'' )
|
||||
;;
|
||||
* )
|
||||
hierbase="/$hierbase"
|
||||
;;
|
||||
esac
|
||||
|
||||
check_binary () {
|
||||
# args: area-in-messages directory
|
||||
debug "check_binary($@)"
|
||||
|
||||
if [ ! -d "${mountpoint}$2" -a -z "$multi" ]; then
|
||||
echo "'$2' does not exist."
|
||||
return
|
||||
fi
|
||||
|
||||
# In this special case it is ok for a sub-distribution to not contain any
|
||||
# .deb files. Each media should contain all Packages.cd files but does not
|
||||
# need to contain the .deb files.
|
||||
#
|
||||
# if ! { find -L "$mountpoint$2" -name '*.deb' -print \
|
||||
# | head -1 | grep . ; } >/dev/null 2>&1 && [ -z "$multi" ];
|
||||
# then
|
||||
# echo "'$2' does not contain any *.deb packages."
|
||||
# return
|
||||
# fi
|
||||
|
||||
this_binary="$2"
|
||||
echo -n "Using '$this_binary' as $1 binary directory"
|
||||
|
||||
if [ -n "$multi" ]; then
|
||||
this_disk=$(getdisklabel ${mountpoint} "/$hierbase")
|
||||
echo " from disc"
|
||||
echo " '$this_disk'"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
find_area () {
|
||||
# args: area-in-messages area-in-vars subdirectory-in-hier
|
||||
# last-time-binary last-time-packages
|
||||
debug "find_area($@)"
|
||||
this_binary=''
|
||||
this_packages=''
|
||||
this_disk=''
|
||||
if [ -n "$hierbase" ]; then
|
||||
check_binary $1 $(echo "$hierbase/dists/$3/$1/binary-$iarch" | sed 's:/\+:/:g')
|
||||
debug "THIS_BINARY $this_binary"
|
||||
fi
|
||||
if [ $2 = nf -a -z "$this_binary" ]; then
|
||||
echo "
|
||||
Note: most media distributions of Debian do not include programs available
|
||||
in the 'non-free' directory of the distribution site.
|
||||
This is because these programs are under licenses that do not allow source
|
||||
modification or prevent distribution for profit on a media, or other
|
||||
restrictions that make them not free software.
|
||||
If you wish to install these programs you will have to get them from an
|
||||
alternative source."
|
||||
fi
|
||||
while [ -z "$this_binary" ]; do
|
||||
defaultbinary="$4"
|
||||
echo "
|
||||
Which directory contains the *.deb packages from the $1 distribution
|
||||
area (this directory is named '$3/binary' on the distribution site) ?
|
||||
Say 'none' if this area is not available."
|
||||
if [ $2 != main -a -z "$defaultbinary" ]; then
|
||||
defaultbinary=none
|
||||
fi
|
||||
echo -n \
|
||||
"Enter _$1_ binary directory. [$4]
|
||||
? "
|
||||
read response
|
||||
if [ -z "$response" -a -n "$defaultbinary" ]; then
|
||||
response="$defaultbinary"
|
||||
fi
|
||||
if [ none = "$response" ]; then
|
||||
break
|
||||
fi
|
||||
case "$response" in
|
||||
'' | none)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
check_binary $1 "$(echo "$response" | sed -e 's:/$::; s:^/*:/:')"
|
||||
done
|
||||
if [ -n "$this_binary" ]; then
|
||||
if [ "$multi" = "yes" ]; then
|
||||
for f in Packages.cd.gz packages.cd.gz Packages.cd packages.cd; do
|
||||
if [ -f "$mountpoint/$this_binary/$f" ]; then
|
||||
this_packages="$this_binary/$f"
|
||||
echo "Using '$this_packages' for $1."
|
||||
break
|
||||
fi
|
||||
done
|
||||
elif [ -f "${mountpoint}${hierbase}/.disk/packages/$1/Packages.gz" ]; then
|
||||
this_packages=$(echo "${hierbase}/.disk/packages/$1/Packages.gz"|sed 's:/\+:/:g')
|
||||
echo "Using '${this_packages}' for $1."
|
||||
fi
|
||||
while [ -z "$this_packages" ]; do
|
||||
echo -n "
|
||||
Cannot find the $1 'Packages.cd' file. The information in the
|
||||
'Packages.cd' file is important for package selection during new
|
||||
installations, and is very useful for upgrades.
|
||||
|
||||
If you overlooked it when downloading you should do get it now and
|
||||
return to this installation procedure when you have done so: you will
|
||||
find one Packages.cd file and one Packages.cd.gz file -- either will do --
|
||||
in the 'binary' subdirectory of each area on the FTP sites and
|
||||
media discs. Alternatively (and this will be rather slow) the packages in
|
||||
the distribution area can be scanned - say 'scan' if you want to do so.
|
||||
|
||||
You need a separate Packages.cd file from each of the distribution areas
|
||||
you wish to install.
|
||||
|
||||
Where is the _$1_ 'Packages.cd' file (if none is available, say 'none')
|
||||
[$5]
|
||||
? "
|
||||
read response
|
||||
if [ -z "$response" -a -n "$5" ]; then
|
||||
response="$5"
|
||||
fi
|
||||
case "$response" in
|
||||
'')
|
||||
break
|
||||
;;
|
||||
none)
|
||||
break
|
||||
;;
|
||||
scan)
|
||||
this_packages=scan
|
||||
;;
|
||||
/*)
|
||||
this_packages="$response"
|
||||
;;
|
||||
*)
|
||||
this_packages="/$response"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
eval $2'_binary="$this_binary"'
|
||||
eval $2'_packages="$this_packages"'
|
||||
eval $2'_disk="$this_disk"'
|
||||
}
|
||||
|
||||
find_area main main "$distribution" "$p_main_binary" "$p_main_packages"
|
||||
find_area contrib ctb "$distribution" "$p_ctb_binary" "$p_ctb_packages"
|
||||
find_area non-free-firmware nff "$distribution" "$p_nff_binary" "$p_nff_packages"
|
||||
find_area non-free nf "$distribution" "$p_nf_binary" "$p_nf_packages"
|
||||
find_area local lcl local "$p_lcl_binary" "$p_lcl_packages"
|
||||
|
||||
echo -n '
|
||||
Hit RETURN to continue. '
|
||||
read response
|
||||
|
||||
exec 3>shvar.$option.new
|
||||
|
||||
outputparam p_blockdev "$blockdevice"
|
||||
outputparam p_fstype "$fstype"
|
||||
outputparam p_mountpoint "$mountpoint"
|
||||
outputparam p_hierbase "$hierbase"
|
||||
outputparam p_usedevel "$usedevel"
|
||||
outputparam p_main_packages "$main_packages"
|
||||
outputparam p_main_binary "$main_binary"
|
||||
outputparam p_main_disk "$main_disk"
|
||||
outputparam p_ctb_packages "$ctb_packages"
|
||||
outputparam p_ctb_binary "$ctb_binary"
|
||||
outputparam p_ctb_disk "$ctb_disk"
|
||||
outputparam p_nff_packages "$nff_packages"
|
||||
outputparam p_nff_binary "$nff_binary"
|
||||
outputparam p_nff_disk "$nff_disk"
|
||||
outputparam p_nf_packages "$nf_packages"
|
||||
outputparam p_nf_binary "$nf_binary"
|
||||
outputparam p_nf_disk "$nf_disk"
|
||||
outputparam p_lcl_packages "$lcl_packages"
|
||||
outputparam p_lcl_binary "$lcl_binary"
|
||||
outputparam p_multi "$multi"
|
||||
outputparam p_multi_contentsfile "$multi_contentsfile"
|
||||
|
||||
mv shvar.$option.new shvar.$option
|
||||
|
||||
xit=0
|
121
dselect/methods/media/update.sh
Executable file
121
dselect/methods/media/update.sh
Executable file
|
@ -0,0 +1,121 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright © 1995-1998 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
# Copyright © 1998 Heiko Schlittermann <hs@schlittermann.de>
|
||||
#
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
vardir="$1"
|
||||
method=$2
|
||||
option=$3
|
||||
iarch=$(dpkg --print-architecture)
|
||||
|
||||
cd "$vardir/methods/$method"
|
||||
|
||||
. ./shvar.$option
|
||||
|
||||
#debug() { echo "DEBUG: $@"; }
|
||||
debug() {
|
||||
true
|
||||
}
|
||||
|
||||
packages=0
|
||||
for f in main ctb nf lcl; do
|
||||
eval 'this_packages=$p_'$f'_packages'
|
||||
|
||||
if [ -n "$this_packages" ]; then
|
||||
packages=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $packages eq 0 ]; then
|
||||
echo '
|
||||
No Packages files available, cannot update available packages list.
|
||||
Hit RETURN to continue. '
|
||||
read response
|
||||
exit 0
|
||||
fi
|
||||
|
||||
xit=1
|
||||
trap '
|
||||
for area in main ctb nf lcl; do
|
||||
rm -f packages-$area
|
||||
done
|
||||
if [ -n "$umount" ]; then
|
||||
umount "$umount" >/dev/null 2>&1
|
||||
fi
|
||||
exit $xit
|
||||
' 0
|
||||
|
||||
if [ ! -b "$p_blockdev" ]; then
|
||||
loop=",loop"
|
||||
fi
|
||||
|
||||
if [ -n "$p_blockdev" ]; then
|
||||
umount="$p_mountpoint"
|
||||
mount -rt "$p_fstype" -o nosuid,nodev${loop} "$p_blockdev" "$p_mountpoint"
|
||||
fi
|
||||
|
||||
updatetype=update
|
||||
|
||||
if [ -z "$p_multi" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for f in main ctb nf lcl; do
|
||||
eval 'this_packages=$p_'$f'_packages'
|
||||
case "$this_packages" in
|
||||
'')
|
||||
continue
|
||||
;;
|
||||
scan)
|
||||
eval 'this_binary=$p_'$f'_binary'
|
||||
if [ -z "$this_binary" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$updatetype" = update ]; then
|
||||
dpkg --clear-avail
|
||||
updatetype=merge
|
||||
fi
|
||||
echo Running dpkg --record-avail -R "$p_mountpoint$this_binary"
|
||||
dpkg --record-avail -R "$p_mountpoint$this_binary"
|
||||
;;
|
||||
*)
|
||||
packagesfile="$p_mountpoint$this_packages"
|
||||
case "$packagesfile" in
|
||||
*.gz)
|
||||
echo -n "Uncompressing $packagesfile ... "
|
||||
zcat <"$packagesfile" >packages-$f
|
||||
echo done.
|
||||
dpkg --$updatetype-avail packages-$f
|
||||
updatetype=merge
|
||||
;;
|
||||
'')
|
||||
;;
|
||||
*)
|
||||
dpkg --$updatetype-avail "$packagesfile"
|
||||
updatetype=merge
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cp -f $vardir/available $vardir/methods/$method
|
||||
|
||||
echo -n 'Update OK. Hit RETURN. '
|
||||
read response
|
||||
|
||||
xit=0
|
294
dselect/methparse.cc
Normal file
294
dselect/methparse.cc
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* methparse.cc - access method list parsing
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2008-2011, 2013-2015 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/i18n.h>
|
||||
#include <dpkg/c-ctype.h>
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
#include <dpkg/file.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "bindings.h"
|
||||
#include "method.h"
|
||||
|
||||
int noptions=0;
|
||||
struct dselect_option *options = nullptr, *coption = nullptr;
|
||||
struct method *methods = nullptr;
|
||||
|
||||
static void DPKG_ATTR_NORET
|
||||
badmethod(varbuf &pathname, const char *why)
|
||||
{
|
||||
ohshit(_("syntax error in method options file '%.250s' -- %s"),
|
||||
pathname.str(), why);
|
||||
}
|
||||
|
||||
static void DPKG_ATTR_NORET
|
||||
eofmethod(varbuf &pathname, FILE *f, const char *why)
|
||||
{
|
||||
if (ferror(f))
|
||||
ohshite(_("error reading options file '%.250s'"), pathname.str());
|
||||
badmethod(pathname,why);
|
||||
}
|
||||
|
||||
void readmethods(const char *pathbase, dselect_option **optionspp, int *nread) {
|
||||
static const char *const methodprograms[]= {
|
||||
METHODSETUPSCRIPT,
|
||||
METHODUPDATESCRIPT,
|
||||
METHODINSTALLSCRIPT,
|
||||
nullptr
|
||||
};
|
||||
const char *const *ccpp;
|
||||
int methodlen;
|
||||
DIR *dir;
|
||||
FILE *names;
|
||||
struct dirent *dent;
|
||||
struct varbuf vb;
|
||||
method *meth;
|
||||
dselect_option *opt;
|
||||
|
||||
varbuf path;
|
||||
path += pathbase;
|
||||
path += "/";
|
||||
|
||||
dir = opendir(path.str());
|
||||
if (!dir) {
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
ohshite(_("unable to read '%.250s' directory for reading methods"),
|
||||
path.str());
|
||||
}
|
||||
|
||||
debug(dbg_general, "readmethods('%s',...) directory open", pathbase);
|
||||
|
||||
while ((dent = readdir(dir)) != nullptr) {
|
||||
int c = dent->d_name[0];
|
||||
debug(dbg_general, "readmethods('%s',...) considering '%s' ...",
|
||||
pathbase, dent->d_name);
|
||||
if (c != '_' && !c_isalpha(c))
|
||||
continue;
|
||||
char *p = dent->d_name + 1;
|
||||
while ((c = *p) != 0 && c_isalnum(c) && c != '_')
|
||||
p++;
|
||||
if (c) continue;
|
||||
methodlen= strlen(dent->d_name);
|
||||
if (methodlen > IMETHODMAXLEN)
|
||||
ohshit(_("method '%.250s' has name that is too long (%d > %d characters)"),
|
||||
dent->d_name, methodlen, IMETHODMAXLEN);
|
||||
/* Check if there is a localized version of this method */
|
||||
|
||||
path.reset();
|
||||
path += pathbase;
|
||||
path += "/";
|
||||
path += dent->d_name;
|
||||
path += "/";
|
||||
|
||||
varbuf pathmeth;
|
||||
|
||||
for (ccpp= methodprograms; *ccpp; ccpp++) {
|
||||
pathmeth = path;
|
||||
pathmeth += *ccpp;
|
||||
if (access(pathmeth.str(), R_OK | X_OK))
|
||||
ohshite(_("unable to access method script '%.250s'"), pathmeth.str());
|
||||
}
|
||||
debug(dbg_general, " readmethods('%s',...) scripts ok", pathbase);
|
||||
|
||||
varbuf pathopts;
|
||||
pathopts = path;
|
||||
pathopts += METHODOPTIONSFILE;
|
||||
names = fopen(pathopts.str(), "r");
|
||||
if (!names)
|
||||
ohshite(_("unable to read method options file '%.250s'"), pathopts.str());
|
||||
|
||||
meth= new method;
|
||||
meth->name = varbuf(dent->d_name);
|
||||
meth->path = path;
|
||||
meth->next= methods;
|
||||
meth->prev = nullptr;
|
||||
if (methods)
|
||||
methods->prev = meth;
|
||||
methods= meth;
|
||||
debug(dbg_general, " readmethods('%s',...) new method"
|
||||
" name='%s' path='%s'",
|
||||
pathbase, meth->name.str(), meth->path.str());
|
||||
|
||||
while ((c= fgetc(names)) != EOF) {
|
||||
if (c_isspace(c))
|
||||
continue;
|
||||
opt= new dselect_option;
|
||||
opt->meth= meth;
|
||||
vb.reset();
|
||||
do {
|
||||
if (!c_isdigit(c))
|
||||
badmethod(pathopts, _("non-digit where digit wanted"));
|
||||
vb += c;
|
||||
c= fgetc(names);
|
||||
if (c == EOF)
|
||||
eofmethod(pathopts, names, _("end of file in index string"));
|
||||
} while (!c_isspace(c));
|
||||
if (vb.len() > OPTIONINDEXMAXLEN)
|
||||
badmethod(pathopts, _("index string too long"));
|
||||
opt->index = vb;
|
||||
do {
|
||||
if (c == '\n')
|
||||
badmethod(pathopts, _("newline before option name start"));
|
||||
c= fgetc(names);
|
||||
if (c == EOF)
|
||||
eofmethod(pathopts, names, _("end of file before option name start"));
|
||||
} while (c_isspace(c));
|
||||
vb.reset();
|
||||
if (!c_isalpha(c) && c != '_')
|
||||
badmethod(pathopts, _("nonalpha where option name start wanted"));
|
||||
do {
|
||||
if (!c_isalnum(c) && c != '_')
|
||||
badmethod(pathopts, _("non-alphanum in option name"));
|
||||
vb += c;
|
||||
c= fgetc(names);
|
||||
if (c == EOF)
|
||||
eofmethod(pathopts, names, _("end of file in option name"));
|
||||
} while (!c_isspace(c));
|
||||
opt->name = vb;
|
||||
do {
|
||||
if (c == '\n')
|
||||
badmethod(pathopts, _("newline before summary"));
|
||||
c= fgetc(names);
|
||||
if (c == EOF)
|
||||
eofmethod(pathopts, names, _("end of file before summary"));
|
||||
} while (c_isspace(c));
|
||||
vb.reset();
|
||||
do {
|
||||
vb += c;
|
||||
c= fgetc(names);
|
||||
if (c == EOF)
|
||||
eofmethod(pathopts, names, _("end of file in summary - missing newline"));
|
||||
} while (c != '\n');
|
||||
opt->summary = vb;
|
||||
|
||||
varbuf pathoptsdesc;
|
||||
pathoptsdesc += pathopts;
|
||||
pathoptsdesc += OPTIONSDESCPFX;
|
||||
pathoptsdesc += opt->name;
|
||||
|
||||
dpkg_error err = DPKG_ERROR_INIT;
|
||||
|
||||
if (file_slurp(pathoptsdesc.str(), &opt->description, &err) < 0) {
|
||||
if (err.syserrno != ENOENT)
|
||||
dpkg_error_print(&err, _("cannot load option description file '%s'"),
|
||||
pathoptsdesc.str());
|
||||
}
|
||||
|
||||
debug(dbg_general,
|
||||
" readmethods('%s',...) new option index='%s' name='%s'"
|
||||
" summary='%.20s' len(description=%s)=%zu method name='%s'"
|
||||
" path='%s'",
|
||||
pathbase,
|
||||
opt->index.str(), opt->name.str(), opt->summary.str(),
|
||||
opt->description.len() ? "'...'" : "<none>",
|
||||
opt->description.len() ? opt->description.len() : -1,
|
||||
opt->meth->name.str(), opt->meth->path.str());
|
||||
|
||||
dselect_option **optinsert = optionspp;
|
||||
while (*optinsert && strcmp(opt->index.str(), (*optinsert)->index.str()) > 0)
|
||||
optinsert = &(*optinsert)->next;
|
||||
opt->next= *optinsert;
|
||||
*optinsert= opt;
|
||||
(*nread)++;
|
||||
}
|
||||
if (ferror(names))
|
||||
ohshite(_("error during read of method options file '%.250s'"), pathopts.str());
|
||||
fclose(names);
|
||||
}
|
||||
closedir(dir);
|
||||
debug(dbg_general, "readmethods('%s',...) done", pathbase);
|
||||
}
|
||||
|
||||
static char *methoptfile = nullptr;
|
||||
|
||||
void getcurrentopt() {
|
||||
char methoptbuf[IMETHODMAXLEN+1+IOPTIONMAXLEN+2];
|
||||
FILE *cmo;
|
||||
int l;
|
||||
char *p;
|
||||
|
||||
if (methoptfile == nullptr)
|
||||
methoptfile = dpkg_db_get_path(CMETHOPTFILE);
|
||||
|
||||
coption = nullptr;
|
||||
cmo= fopen(methoptfile,"r");
|
||||
if (!cmo) {
|
||||
if (errno == ENOENT) return;
|
||||
ohshite(_("unable to open current option file '%.250s'"), methoptfile);
|
||||
}
|
||||
debug(dbg_general, "getcurrentopt() cmethopt open");
|
||||
if (!fgets(methoptbuf,sizeof(methoptbuf),cmo)) { fclose(cmo); return; }
|
||||
if (fgetc(cmo) != EOF) { fclose(cmo); return; }
|
||||
if (!feof(cmo)) { fclose(cmo); return; }
|
||||
debug(dbg_general, "getcurrentopt() cmethopt eof");
|
||||
fclose(cmo);
|
||||
debug(dbg_general, "getcurrentopt() cmethopt read");
|
||||
l= strlen(methoptbuf); if (!l || methoptbuf[l-1] != '\n') return;
|
||||
methoptbuf[--l]= 0;
|
||||
debug(dbg_general, "getcurrentopt() cmethopt len and newline");
|
||||
p= strchr(methoptbuf,' '); if (!p) return;
|
||||
debug(dbg_general, "getcurrentopt() cmethopt space");
|
||||
*p++= 0;
|
||||
debug(dbg_general, "getcurrentopt() cmethopt meth name '%s'", methoptbuf);
|
||||
method *meth = methods;
|
||||
while (meth && strcmp(methoptbuf, meth->name.str()))
|
||||
meth = meth->next;
|
||||
if (!meth) return;
|
||||
debug(dbg_general, "getcurrentopt() cmethopt meth found; opt '%s'", p);
|
||||
dselect_option *opt = options;
|
||||
while (opt && (opt->meth != meth || strcmp(p, opt->name.str())))
|
||||
opt = opt->next;
|
||||
if (!opt) return;
|
||||
debug(dbg_general, "getcurrentopt() cmethopt opt found");
|
||||
coption= opt;
|
||||
}
|
||||
|
||||
void writecurrentopt() {
|
||||
struct atomic_file *file;
|
||||
|
||||
if (methoptfile == nullptr)
|
||||
internerr("method options filename is nullptr");
|
||||
|
||||
file = atomic_file_new(methoptfile, ATOMIC_FILE_NORMAL);
|
||||
atomic_file_open(file);
|
||||
if (fprintf(file->fp, "%s %s\n", coption->meth->name.str(), coption->name.str()) == EOF)
|
||||
ohshite(_("unable to write new option to '%.250s'"), file->name_new);
|
||||
atomic_file_close(file);
|
||||
atomic_file_commit(file);
|
||||
atomic_file_free(file);
|
||||
}
|
144
dselect/mkcurkeys.pl
Executable file
144
dselect/mkcurkeys.pl
Executable file
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# dselect - Debian package maintenance user interface
|
||||
# mkcurkeys.pl - generate strings mapping key names to ncurses numbers
|
||||
#
|
||||
# Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
#
|
||||
# This 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 is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Scalar::Util qw(looks_like_number);
|
||||
|
||||
die 'usage: mkcurkeys.pl <filename> <curses.h>' if @ARGV != 2;
|
||||
|
||||
my (%over, %base, %name);
|
||||
|
||||
open(my $override_fh, '<', $ARGV[0]) or die $!;
|
||||
while (<$override_fh>) {
|
||||
chomp;
|
||||
/^#/ && next; # skip comments
|
||||
/\S/ || next; # ignore blank lines
|
||||
if (/^(\w+)\s+(\S.*\S)\s*$/) {
|
||||
$over{$1} = $2;
|
||||
$base{$1} = '';
|
||||
} else {
|
||||
die "cannot parse line:\n$_\n";
|
||||
}
|
||||
}
|
||||
close($override_fh);
|
||||
|
||||
my $let = 'A';
|
||||
for my $i (1 .. 26) {
|
||||
$name{$i} = "^$let";
|
||||
$base{$i} = '';
|
||||
$let++;
|
||||
}
|
||||
|
||||
open(my $header_fh, '<', $ARGV[1]) or die $!;
|
||||
while (<$header_fh>) {
|
||||
s/\s+$//;
|
||||
m/#define KEY_(\w+)\s+\d+\s+/p || next;
|
||||
my $rhs = ${^POSTMATCH};
|
||||
my $k = "KEY_$1";
|
||||
$base{$k} = capit($1);
|
||||
$rhs =~ s/(\w)[\(\)]/$1/g;
|
||||
$rhs =~ s/\w+ \((\w+)\)/$1/;
|
||||
next unless $rhs =~ m{^/\* (\w[\w ]+\w) \*/$};
|
||||
my $name = $1;
|
||||
$name =~ s/ key$//;
|
||||
if ($name =~ s/^shifted /shift /) {
|
||||
next if $name =~ m/ .* .* /;
|
||||
} else {
|
||||
next if $name =~ m/ .* /;
|
||||
}
|
||||
$name{$k} = capit($name);
|
||||
}
|
||||
close($header_fh);
|
||||
|
||||
printf(<<'END') or die $!;
|
||||
/*
|
||||
* WARNING - THIS FILE IS GENERATED AUTOMATICALLY - DO NOT EDIT
|
||||
* It is generated by mkcurkeys.pl from <curses.h>
|
||||
* and keyoverride. If you want to override things try adding
|
||||
* them to keyoverride.
|
||||
*/
|
||||
|
||||
END
|
||||
|
||||
my ($comma);
|
||||
|
||||
for my $i (33 .. 126) {
|
||||
my $k = $i;
|
||||
my $v = pack('C', $i);
|
||||
if ($v eq ',') { $comma = $k; next; }
|
||||
p($k, $v);
|
||||
}
|
||||
|
||||
## no critic (BuiltinFunctions::ProhibitReverseSortBlock)
|
||||
for my $k (sort {
|
||||
looks_like_number($a) ?
|
||||
looks_like_number($b) ? $a <=> $b : -1
|
||||
: looks_like_number($b) ? 1 :
|
||||
$a cmp $b
|
||||
} keys %base) {
|
||||
## use critic
|
||||
my $v;
|
||||
$v = $base{$k};
|
||||
$v = $name{$k} if defined($name{$k});
|
||||
$v = $over{$k} if defined($over{$k});
|
||||
next if $v eq '[elide]';
|
||||
p($k, $v);
|
||||
}
|
||||
|
||||
for my $i (1 .. 63) {
|
||||
p("KEY_F($i)", "F$i");
|
||||
}
|
||||
|
||||
p($comma, ',');
|
||||
|
||||
print(<<'END') or die $!;
|
||||
{ -1, nullptr }
|
||||
END
|
||||
|
||||
close(STDOUT) or die $!;
|
||||
exit(0);
|
||||
|
||||
sub capit {
|
||||
my $str = shift;
|
||||
my $o = '';
|
||||
|
||||
$str =~ y/A-Z/a-z/;
|
||||
$str = " $str";
|
||||
while ($str =~ m/ (\w)/p) {
|
||||
$o .= ${^PREMATCH} . ' ';
|
||||
$str = $1;
|
||||
$str =~ y/a-z/A-Z/;
|
||||
$o .= $str;
|
||||
$str = ${^POSTMATCH};
|
||||
}
|
||||
$str = $o . $str;
|
||||
$str =~ s/^ //;
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub p {
|
||||
my ($k, $v) = @_;
|
||||
|
||||
$v =~ s/(["\\])/\\$1/g;
|
||||
printf(" { %-15s \"%-20s },\n", $k . ',', $v . '"') or die $!;
|
||||
}
|
353
dselect/pkgcmds.cc
Normal file
353
dselect/pkgcmds.cc
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* pkgcmds.cc - package list keyboard commands
|
||||
*
|
||||
* Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "pkglist.h"
|
||||
|
||||
bool
|
||||
packagelist::affectedmatches(struct pkginfo *pkg, struct pkginfo *comparewith) {
|
||||
switch (statsortorder) {
|
||||
case sso_avail:
|
||||
if (comparewith->clientdata->ssavail != pkg->clientdata->ssavail)
|
||||
return false;
|
||||
break;
|
||||
case sso_state:
|
||||
if (comparewith->clientdata->ssstate != pkg->clientdata->ssstate)
|
||||
return false;
|
||||
break;
|
||||
case sso_unsorted:
|
||||
break;
|
||||
default:
|
||||
internerr("unknown statsortorder %d", statsortorder);
|
||||
}
|
||||
if (comparewith->priority != PKG_PRIO_UNSET &&
|
||||
(comparewith->priority != pkg->priority ||
|
||||
(comparewith->priority == PKG_PRIO_OTHER &&
|
||||
strcasecmp(comparewith->otherpriority, pkg->otherpriority))))
|
||||
return false;
|
||||
if (comparewith->section &&
|
||||
strcasecmp(comparewith->section,
|
||||
pkg->section ?
|
||||
pkg->section : ""))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void packagelist::affectedrange(int *startp, int *endp) {
|
||||
if (table[cursorline]->pkg->set->name) {
|
||||
*startp= cursorline;
|
||||
*endp= cursorline+1;
|
||||
return;
|
||||
}
|
||||
int index = cursorline;
|
||||
while (index < nitems && !table[index]->pkg->set->name)
|
||||
index++;
|
||||
if (index >= nitems) {
|
||||
*startp= *endp= cursorline;
|
||||
return;
|
||||
}
|
||||
*startp= index;
|
||||
while (index < nitems && affectedmatches(table[index]->pkg,table[cursorline]->pkg))
|
||||
index++;
|
||||
*endp= index;
|
||||
}
|
||||
|
||||
void packagelist::movecursorafter(int ncursor) {
|
||||
if (ncursor >= nitems) ncursor= nitems-1;
|
||||
topofscreen += ncursor-cursorline;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
setcursor(ncursor);
|
||||
refreshlist(); redrawthisstate();
|
||||
}
|
||||
|
||||
pkgwant
|
||||
packagelist::reallywant(pkgwant nwarg, struct perpackagestate *pkgstate)
|
||||
{
|
||||
if (nwarg != PKG_WANT_SENTINEL)
|
||||
return nwarg;
|
||||
pkgstatus status = pkgstate->pkg->status;
|
||||
if (status == PKG_STAT_NOTINSTALLED)
|
||||
return PKG_WANT_PURGE;
|
||||
if (status == PKG_STAT_CONFIGFILES)
|
||||
return PKG_WANT_DEINSTALL;
|
||||
return PKG_WANT_INSTALL;
|
||||
}
|
||||
|
||||
void
|
||||
packagelist::setwant(pkgwant nwarg)
|
||||
{
|
||||
int bot;
|
||||
|
||||
if (modstatdb_get_status() == msdbrw_readonly) {
|
||||
beep();
|
||||
return;
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
redrawitemsrange(cursorline,cursorline+1);
|
||||
table[cursorline]->selected= reallywant(nwarg,table[cursorline]);
|
||||
redraw1item(cursorline);
|
||||
bot= cursorline+1;
|
||||
} else {
|
||||
int top;
|
||||
pkgwant nw;
|
||||
|
||||
packagelist *sub = new packagelist(bindings, nullptr);
|
||||
|
||||
affectedrange(&top,&bot);
|
||||
for (int index = top; index < bot; index++) {
|
||||
if (!table[index]->pkg->set->name)
|
||||
continue;
|
||||
nw= reallywant(nwarg,table[index]);
|
||||
if (table[index]->selected == nw ||
|
||||
(table[index]->selected == PKG_WANT_PURGE &&
|
||||
nw == PKG_WANT_DEINSTALL))
|
||||
continue;
|
||||
sub->add(table[index]->pkg,nw);
|
||||
}
|
||||
|
||||
repeatedlydisplay(sub,dp_may,this);
|
||||
for (int index = top; index < bot; index++)
|
||||
redraw1item(index);
|
||||
}
|
||||
movecursorafter(bot);
|
||||
}
|
||||
|
||||
bool manual_install = false;
|
||||
|
||||
void packagelist::kd_select() {
|
||||
manual_install = true;
|
||||
setwant(PKG_WANT_INSTALL);
|
||||
manual_install = false;
|
||||
}
|
||||
void packagelist::kd_hold() { setwant(PKG_WANT_HOLD); }
|
||||
void packagelist::kd_deselect() { setwant(PKG_WANT_DEINSTALL); }
|
||||
void packagelist::kd_unhold() { setwant(PKG_WANT_SENTINEL); }
|
||||
void packagelist::kd_purge() { setwant(PKG_WANT_PURGE); }
|
||||
|
||||
int
|
||||
would_like_to_install(pkgwant wantvalue, pkginfo *pkg)
|
||||
{
|
||||
/* Returns: 1 for yes, 0 for no, -1 for if they want to preserve an error condition. */
|
||||
debug(dbg_general, "would_like_to_install(%d, %s) status %d",
|
||||
wantvalue, pkg_name(pkg, pnaw_always), pkg->status);
|
||||
|
||||
if (wantvalue == PKG_WANT_INSTALL)
|
||||
return 1;
|
||||
if (wantvalue != PKG_WANT_HOLD)
|
||||
return 0;
|
||||
if (pkg->status == PKG_STAT_INSTALLED)
|
||||
return 1;
|
||||
if (pkg->status == PKG_STAT_NOTINSTALLED ||
|
||||
pkg->status == PKG_STAT_CONFIGFILES)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *packagelist::itemname(int index) {
|
||||
return table[index]->pkg->set->name;
|
||||
}
|
||||
|
||||
void packagelist::kd_swapstatorder() {
|
||||
if (sortorder == so_unsorted) return;
|
||||
switch (statsortorder) {
|
||||
case sso_avail: statsortorder= sso_state; break;
|
||||
case sso_state: statsortorder= sso_unsorted; break;
|
||||
case sso_unsorted: statsortorder= sso_avail; break;
|
||||
default:
|
||||
internerr("unknown statsort %d", statsortorder);
|
||||
}
|
||||
resortredisplay();
|
||||
}
|
||||
|
||||
void packagelist::kd_swaporder() {
|
||||
switch (sortorder) {
|
||||
case so_priority: sortorder= so_section; break;
|
||||
case so_section: sortorder= so_alpha; break;
|
||||
case so_alpha: sortorder= so_priority; break;
|
||||
case so_unsorted: return;
|
||||
default:
|
||||
internerr("unknown sort %d", sortorder);
|
||||
}
|
||||
resortredisplay();
|
||||
}
|
||||
|
||||
void packagelist::resortredisplay() {
|
||||
const char *oldname = table[cursorline]->pkg->set->name;
|
||||
sortmakeheads();
|
||||
int newcursor;
|
||||
newcursor= 0;
|
||||
if (oldname) {
|
||||
int index;
|
||||
for (index=0; index<nitems; index++) {
|
||||
if (table[index]->pkg->set->name &&
|
||||
strcasecmp(oldname, table[index]->pkg->set->name) == 0) {
|
||||
newcursor= index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
topofscreen= newcursor-1;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
setwidths();
|
||||
redrawtitle();
|
||||
redrawcolheads();
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
cursorline= -1;
|
||||
setcursor(newcursor);
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void
|
||||
packagelist::kd_archdisplay()
|
||||
{
|
||||
switch (archdisplayopt) {
|
||||
case ado_both:
|
||||
archdisplayopt = ado_none;
|
||||
break;
|
||||
case ado_none:
|
||||
archdisplayopt = ado_available;
|
||||
break;
|
||||
case ado_available:
|
||||
archdisplayopt = ado_both;
|
||||
break;
|
||||
default:
|
||||
internerr("unknown archdisplayopt %d", archdisplayopt);
|
||||
}
|
||||
setwidths();
|
||||
leftofscreen = 0;
|
||||
ldrawnstart = ldrawnend = -1;
|
||||
redrawtitle();
|
||||
redrawcolheads();
|
||||
redrawitemsrange(topofscreen, min(topofscreen + list_height, nitems));
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void packagelist::kd_versiondisplay() {
|
||||
switch (versiondisplayopt) {
|
||||
case vdo_both: versiondisplayopt= vdo_none; break;
|
||||
case vdo_none: versiondisplayopt= vdo_available; break;
|
||||
case vdo_available: versiondisplayopt= vdo_both; break;
|
||||
default:
|
||||
internerr("unknown versiondisplayopt %d", versiondisplayopt);
|
||||
}
|
||||
setwidths();
|
||||
leftofscreen= 0;
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
redrawtitle();
|
||||
redrawcolheads();
|
||||
redrawitemsrange(topofscreen, min(topofscreen + list_height, nitems));
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void packagelist::kd_verbose() {
|
||||
verbose= !verbose;
|
||||
setwidths();
|
||||
leftofscreen= 0;
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
redrawtitle();
|
||||
redrawcolheads();
|
||||
redrawitemsrange(topofscreen, min(topofscreen + list_height, nitems));
|
||||
refreshlist();
|
||||
}
|
||||
|
||||
void packagelist::kd_quit_noop() { }
|
||||
|
||||
void packagelist::kd_revert_abort() {
|
||||
int index;
|
||||
for (index=0; index<nitems; index++) {
|
||||
if (table[index]->pkg->set->name)
|
||||
table[index]->selected= table[index]->original;
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
}
|
||||
refreshlist(); redrawthisstate();
|
||||
}
|
||||
|
||||
void packagelist::kd_revertdirect() {
|
||||
int index;
|
||||
for (index=0; index<nitems; index++) {
|
||||
if (table[index]->pkg->set->name)
|
||||
table[index]->selected= table[index]->direct;
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
}
|
||||
refreshlist(); redrawthisstate();
|
||||
}
|
||||
|
||||
void packagelist::kd_revertsuggest() {
|
||||
int index;
|
||||
for (index=0; index<nitems; index++) {
|
||||
if (table[index]->pkg->set->name)
|
||||
table[index]->selected= table[index]->suggested;
|
||||
ldrawnstart= ldrawnend= -1;
|
||||
}
|
||||
refreshlist(); redrawthisstate();
|
||||
}
|
||||
|
||||
void
|
||||
packagelist::kd_revertinstalled()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
if (table[i]->pkg->set->name)
|
||||
table[i]->selected = reallywant(PKG_WANT_SENTINEL, table[i]);
|
||||
ldrawnstart = ldrawnend = -1;
|
||||
}
|
||||
|
||||
refreshlist();
|
||||
redrawthisstate();
|
||||
}
|
||||
|
||||
/* FIXME: configurable purge/deselect */
|
||||
|
||||
void packagelist::kd_toggleinfo() {
|
||||
showinfo= (showinfo+2) % 3;
|
||||
setheights();
|
||||
if (cursorline >= topofscreen+list_height) topofscreen += list_height;
|
||||
if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
|
||||
if (topofscreen < 0) topofscreen= 0;
|
||||
infotopofscreen= 0;
|
||||
redraw1item(cursorline);
|
||||
refreshlist();
|
||||
redrawthisstate();
|
||||
redrawinfo();
|
||||
}
|
||||
|
||||
void packagelist::kd_info() {
|
||||
if (!showinfo) {
|
||||
showinfo= 2; kd_toggleinfo();
|
||||
} else {
|
||||
currentinfo++;
|
||||
infotopofscreen=0;
|
||||
redrawinfo();
|
||||
}
|
||||
}
|
461
dselect/pkgdepcon.cc
Normal file
461
dselect/pkgdepcon.cc
Normal file
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
* dselect - Debian package maintenance user interface
|
||||
* pkgdepcon.cc - dependency and conflict resolution
|
||||
*
|
||||
* Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
|
||||
* Copyright © 2008-2014 Guillem Jover <guillem@debian.org>
|
||||
*
|
||||
* This 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 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <compat.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dpkg/dpkg.h>
|
||||
#include <dpkg/dpkg-db.h>
|
||||
|
||||
#include "dselect.h"
|
||||
#include "pkglist.h"
|
||||
|
||||
bool
|
||||
packagelist::useavailable(pkginfo *pkg)
|
||||
{
|
||||
if (pkg->clientdata &&
|
||||
pkg->clientdata->selected == PKG_WANT_INSTALL &&
|
||||
pkg_is_informative(pkg, &pkg->available) &&
|
||||
(!(pkg->status == PKG_STAT_INSTALLED ||
|
||||
pkg->status == PKG_STAT_TRIGGERSAWAITED ||
|
||||
pkg->status == PKG_STAT_TRIGGERSPENDING) ||
|
||||
dpkg_version_compare(&pkg->available.version,
|
||||
&pkg->installed.version) > 0))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
pkgbin *
|
||||
packagelist::find_pkgbin(pkginfo *pkg)
|
||||
{
|
||||
pkgbin *pkgbin;
|
||||
|
||||
pkgbin = useavailable(pkg) ? &pkg->available : &pkg->installed;
|
||||
debug(dbg_general, "packagelist[%p]::find_pkgbin(%s) useavailable=%d",
|
||||
this, pkgbin_name(pkg, pkgbin, pnaw_always), useavailable(pkg));
|
||||
|
||||
return pkgbin;
|
||||
}
|
||||
|
||||
int packagelist::checkdependers(pkginfo *pkg, int changemade) {
|
||||
struct deppossi *possi;
|
||||
|
||||
for (possi = pkg->set->depended.available; possi; possi = possi->rev_next) {
|
||||
if (!useavailable(possi->up->up))
|
||||
continue;
|
||||
changemade = max(changemade, resolvedepcon(possi->up));
|
||||
}
|
||||
for (possi = pkg->set->depended.installed; possi; possi = possi->rev_next) {
|
||||
if (useavailable(possi->up->up))
|
||||
continue;
|
||||
changemade = max(changemade, resolvedepcon(possi->up));
|
||||
}
|
||||
return changemade;
|
||||
}
|
||||
|
||||
int packagelist::resolvesuggest() {
|
||||
// We continually go around looking for things to change, but we may
|
||||
// only change the ‘suggested’ value if we also increase the ‘priority’
|
||||
// Return 2 if we made a change due to a Recommended, Depends or Conflicts,
|
||||
// or 1 if we offered or made a change because of an Optional line.
|
||||
debug(dbg_general, "packagelist[%p]::resolvesuggest()", this);
|
||||
int maxchangemade = 0;
|
||||
|
||||
for (;;) {
|
||||
int changemade = 0;
|
||||
int index;
|
||||
|
||||
for (index=0; index<nitems; index++) {
|
||||
if (!table[index]->pkg->set->name)
|
||||
continue;
|
||||
debug(dbg_depcon, "packagelist[%p]::resolvesuggest() loop[%i] %s / %d",
|
||||
this, index, pkg_name(table[index]->pkg, pnaw_always), changemade);
|
||||
dependency *depends;
|
||||
for (depends = find_pkgbin(table[index]->pkg)->depends;
|
||||
depends;
|
||||
depends= depends->next) {
|
||||
changemade = max(changemade, resolvedepcon(depends));
|
||||
}
|
||||
changemade= checkdependers(table[index]->pkg,changemade);
|
||||
for (depends = find_pkgbin(table[index]->pkg)->depends;
|
||||
depends;
|
||||
depends= depends->next) {
|
||||
if (depends->type != dep_provides) continue;
|
||||
changemade = checkdependers(&depends->list->ed->pkg, changemade);
|
||||
}
|
||||
debug(dbg_depcon, "packagelist[%p]::resolvesuggest() loop[%i] %s / -> %d",
|
||||
this, index, pkg_name(table[index]->pkg, pnaw_always), changemade);
|
||||
}
|
||||
if (!changemade) break;
|
||||
maxchangemade = max(maxchangemade, changemade);
|
||||
}
|
||||
debug(dbg_general, "packagelist[%p]::resolvesuggest() done; maxchangemade=%d",
|
||||
this, maxchangemade);
|
||||
return maxchangemade;
|
||||
}
|
||||
|
||||
static bool
|
||||
dep_update_best_to_change_stop(perpackagestate *& best, pkginfo *trythis)
|
||||
{
|
||||
// There's no point trying to select a pure virtual package.
|
||||
if (!trythis->clientdata)
|
||||
return false;
|
||||
|
||||
debug(dbg_depcon, "update_best_to_change(best=%s{%d}, test=%s{%d});",
|
||||
best ? pkg_name(best->pkg, pnaw_always) : "",
|
||||
best ? best->spriority : -1,
|
||||
trythis->set->name, trythis->clientdata->spriority);
|
||||
|
||||
// If the problem is caused by us deselecting one of these packages
|
||||
// we should not try to select another one instead.
|
||||
if (trythis->clientdata->spriority == sp_deselecting)
|
||||
return true;
|
||||
|
||||
// If we haven't found anything yet then this is our best so far.
|
||||
if (!best) goto yes;
|
||||
|
||||
// If only one of the packages is available, use that one
|
||||
if (!pkg_is_informative(trythis, &trythis->available) &&
|
||||
pkg_is_informative(best->pkg, &best->pkg->available))
|
||||
return false;
|
||||
if (pkg_is_informative(trythis, &trythis->available) &&
|
||||
!pkg_is_informative(best->pkg, &best->pkg->available))
|
||||
goto yes;
|
||||
|
||||
// Select the package with the lowest priority (i.e., the one of whom
|
||||
// we were least sure we wanted it deselected).
|
||||
if (trythis->clientdata->spriority > best->spriority)
|
||||
return false;
|
||||
if (trythis->clientdata->spriority < best->spriority) goto yes;
|
||||
|
||||
// Pick the package with the must fundamental recommendation level.
|
||||
if (trythis->priority > best->pkg->priority)
|
||||
return false;
|
||||
if (trythis->priority < best->pkg->priority) goto yes;
|
||||
|
||||
// If we're still unsure we'll change the first one in the list.
|
||||
return false;
|
||||
|
||||
yes:
|
||||
debug(dbg_depcon, "update_best_to_change(); yes");
|
||||
|
||||
best = trythis->clientdata;
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
packagelist::deselect_one_of(pkginfo *per, pkginfo *ped, dependency *dep)
|
||||
{
|
||||
perpackagestate *er= per->clientdata;
|
||||
perpackagestate *ed= ped->clientdata;
|
||||
|
||||
if (!er || !would_like_to_install(er->selected,per) ||
|
||||
!ed || !would_like_to_install(ed->selected,ped)) return 0;
|
||||
|
||||
add(dep, dp_must);
|
||||
|
||||
er= per->clientdata; // these can be changed by add
|
||||
ed= ped->clientdata;
|
||||
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::deselect_one_of(): er %s{%d} ed %s{%d} [%p]",
|
||||
this, pkg_name(er->pkg, pnaw_always), er->spriority,
|
||||
pkg_name(ed->pkg, pnaw_always), ed->spriority, dep);
|
||||
|
||||
perpackagestate *best;
|
||||
|
||||
// Try not keep packages needing reinstallation.
|
||||
if (per->eflag & PKG_EFLAG_REINSTREQ)
|
||||
best = ed;
|
||||
else if (ped->eflag & PKG_EFLAG_REINSTREQ)
|
||||
best = er;
|
||||
// We'd rather change the one with the lowest priority.
|
||||
else if (er->spriority > ed->spriority)
|
||||
best = ed;
|
||||
else if (er->spriority < ed->spriority)
|
||||
best = er;
|
||||
// ... failing that the one with the highest priority.
|
||||
else if (er->pkg->priority < ed->pkg->priority)
|
||||
best = ed;
|
||||
else if (er->pkg->priority > ed->pkg->priority)
|
||||
best = er;
|
||||
// ... failing that, the second.
|
||||
else
|
||||
best = ed;
|
||||
|
||||
debug(dbg_depcon, "packagelist[%p]::deselect_one_of(): best %s{%d}",
|
||||
this, pkg_name(best->pkg, pnaw_always), best->spriority);
|
||||
|
||||
if (best->spriority >= sp_deselecting) return 0;
|
||||
best->suggested=
|
||||
best->pkg->status == PKG_STAT_NOTINSTALLED
|
||||
? PKG_WANT_PURGE : PKG_WANT_DEINSTALL; // FIXME: configurable.
|
||||
best->selected= best->suggested;
|
||||
best->spriority= sp_deselecting;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int packagelist::resolvedepcon(dependency *depends) {
|
||||
perpackagestate *best, *fixbyupgrade;
|
||||
deppossi *possi, *provider;
|
||||
bool foundany;
|
||||
int rc;
|
||||
|
||||
if (debug_has_flag(dbg_depcon)) {
|
||||
varbuf pkg_names;
|
||||
|
||||
for (possi = depends->list; possi; possi = possi->next) {
|
||||
pkg_names += ' ';
|
||||
pkg_names += possi->ed->name;
|
||||
}
|
||||
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p] %s --%s-->%s); (ing)->want=%s",
|
||||
this, depends, pkg_name(depends->up, pnaw_always),
|
||||
relatestrings[depends->type],
|
||||
pkg_names.str(), depends->up->clientdata ?
|
||||
wantstrings[depends->up->clientdata->suggested] : "(no clientdata)");
|
||||
}
|
||||
|
||||
if (!depends->up->clientdata) return 0;
|
||||
|
||||
switch (depends->type) {
|
||||
case dep_provides:
|
||||
case dep_replaces:
|
||||
return 0;
|
||||
|
||||
case dep_enhances:
|
||||
case dep_suggests:
|
||||
case dep_recommends:
|
||||
case dep_depends:
|
||||
case dep_predepends:
|
||||
if (would_like_to_install(depends->up->clientdata->selected,depends->up) <= 0)
|
||||
return 0;
|
||||
|
||||
fixbyupgrade = nullptr;
|
||||
|
||||
possi = depends->list;
|
||||
while (possi && !deppossatisfied(possi, &fixbyupgrade))
|
||||
possi = possi->next;
|
||||
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): depends found %s",
|
||||
this, depends, possi ? possi->ed->name : "[none]");
|
||||
if (possi) return 0;
|
||||
|
||||
// Ensures all in the recursive list; adds info strings; ups priorities
|
||||
switch (depends->type) {
|
||||
case dep_enhances:
|
||||
case dep_suggests:
|
||||
rc = add(depends, dp_may);
|
||||
return rc;
|
||||
case dep_recommends:
|
||||
rc = add(depends, dp_should);
|
||||
break;
|
||||
default:
|
||||
rc = add(depends, dp_must);
|
||||
}
|
||||
|
||||
if (fixbyupgrade) {
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): fixbyupgrade %s",
|
||||
this, depends, pkg_name(fixbyupgrade->pkg, pnaw_always));
|
||||
best= fixbyupgrade;
|
||||
} else {
|
||||
best = nullptr;
|
||||
for (possi= depends->list;
|
||||
possi;
|
||||
possi= possi->next) {
|
||||
foundany = false;
|
||||
if (possi->ed->pkg.clientdata)
|
||||
foundany = true;
|
||||
if (dep_update_best_to_change_stop(best, &possi->ed->pkg))
|
||||
goto mustdeselect;
|
||||
for (provider = possi->ed->depended.available;
|
||||
provider;
|
||||
provider = provider->rev_next) {
|
||||
if (provider->up->type != dep_provides) continue;
|
||||
if (provider->up->up->clientdata)
|
||||
foundany = true;
|
||||
if (dep_update_best_to_change_stop(best, provider->up->up)) goto mustdeselect;
|
||||
}
|
||||
if (!foundany) addunavailable(possi);
|
||||
}
|
||||
if (!best) {
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): mustdeselect nobest",
|
||||
this, depends);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): select best=%s{%d}",
|
||||
this, depends, pkg_name(best->pkg, pnaw_always), best->spriority);
|
||||
if (best->spriority >= sp_selecting)
|
||||
return rc;
|
||||
/* Always select depends. Only select recommends if we got here because
|
||||
* of a manually-initiated install request. */
|
||||
if (depends->type != dep_recommends || manual_install) {
|
||||
best->selected = best->suggested = PKG_WANT_INSTALL;
|
||||
best->spriority= sp_selecting;
|
||||
}
|
||||
return rc ? 2 : 0;
|
||||
|
||||
mustdeselect:
|
||||
best= depends->up->clientdata;
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): mustdeselect best=%s{%d}",
|
||||
this, depends, pkg_name(best->pkg, pnaw_always), best->spriority);
|
||||
|
||||
if (best->spriority >= sp_deselecting)
|
||||
return rc;
|
||||
/* Always remove depends, but never remove recommends. */
|
||||
if (depends->type != dep_recommends) {
|
||||
best->selected= best->suggested=
|
||||
best->pkg->status == PKG_STAT_NOTINSTALLED
|
||||
? PKG_WANT_PURGE : PKG_WANT_DEINSTALL; // FIXME: configurable
|
||||
best->spriority= sp_deselecting;
|
||||
}
|
||||
return rc ? 2 : 0;
|
||||
|
||||
case dep_conflicts:
|
||||
case dep_breaks:
|
||||
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): conflict",
|
||||
this, depends);
|
||||
|
||||
if (would_like_to_install(depends->up->clientdata->selected,depends->up) == 0)
|
||||
return 0;
|
||||
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): conflict installing 1",
|
||||
this, depends);
|
||||
|
||||
if (!deppossatisfied(depends->list, nullptr))
|
||||
return 0;
|
||||
|
||||
debug(dbg_depcon,
|
||||
"packagelist[%p]::resolvedepcon([%p]): conflict satisfied - ouch",
|
||||
this, depends);
|
||||
|
||||
if (depends->up->set != depends->list->ed) {
|
||||
rc = deselect_one_of(depends->up, &depends->list->ed->pkg, depends);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
for (provider = depends->list->ed->depended.available;
|
||||
provider;
|
||||
provider = provider->rev_next) {
|
||||
if (provider->up->type != dep_provides) continue;
|
||||
if (provider->up->up == depends->up) continue; // conflicts & provides same thing
|
||||
rc = deselect_one_of(depends->up, provider->up->up, depends);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
debug(dbg_depcon, "packagelist[%p]::resolvedepcon([%p]): no desel",
|
||||
this, depends);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
internerr("unknown deptype %d", depends->type);
|
||||
}
|
||||
/* never reached, make gcc happy */
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool
|
||||
packagelist::deppossatisfied(deppossi *possi, perpackagestate **fixbyupgrade)
|
||||
{
|
||||
// ‘satisfied’ here for Conflicts and Breaks means that the
|
||||
// restriction is violated, that is, that the target package is wanted
|
||||
int would;
|
||||
pkgwant want = PKG_WANT_PURGE;
|
||||
|
||||
if (possi->ed->pkg.clientdata) {
|
||||
want = possi->ed->pkg.clientdata->selected;
|
||||
would = would_like_to_install(want, &possi->ed->pkg);
|
||||
} else {
|
||||
would= 0;
|
||||
}
|
||||
|
||||
if ((possi->up->type == dep_conflicts || possi->up->type == dep_breaks)
|
||||
? possi->up->up->set != possi->ed && would != 0
|
||||
: would > 0) {
|
||||
// If it's to be installed or left installed, then either it's of
|
||||
// the right version, and therefore OK, or a version must have
|
||||
// been specified, in which case we don't need to look at the rest
|
||||
// anyway.
|
||||
if (useavailable(&possi->ed->pkg)) {
|
||||
if (want != PKG_WANT_INSTALL)
|
||||
internerr("depossi package is not want-install, is %d", want);
|
||||
return versionsatisfied(&possi->ed->pkg.available, possi);
|
||||
} else {
|
||||
if (versionsatisfied(&possi->ed->pkg.installed, possi))
|
||||
return true;
|
||||
if (want == PKG_WANT_HOLD && fixbyupgrade && !*fixbyupgrade &&
|
||||
versionsatisfied(&possi->ed->pkg.available, possi) &&
|
||||
dpkg_version_compare(&possi->ed->pkg.available.version,
|
||||
&possi->ed->pkg.installed.version) > 1)
|
||||
*fixbyupgrade = possi->ed->pkg.clientdata;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
deppossi *provider;
|
||||
|
||||
for (provider = possi->ed->depended.installed;
|
||||
provider;
|
||||
provider = provider->rev_next) {
|
||||
if (provider->up->type == dep_provides &&
|
||||
((possi->up->type != dep_conflicts && possi->up->type != dep_breaks) ||
|
||||
provider->up->up->set != possi->up->up->set) &&
|
||||
provider->up->up->clientdata &&
|
||||
!useavailable(provider->up->up) &&
|
||||
would_like_to_install(provider->up->up->clientdata->selected,
|
||||
provider->up->up) &&
|
||||
pkg_virtual_deppossi_satisfied(possi, provider))
|
||||
return true;
|
||||
}
|
||||
for (provider = possi->ed->depended.available;
|
||||
provider;
|
||||
provider = provider->rev_next) {
|
||||
if (provider->up->type != dep_provides ||
|
||||
((possi->up->type == dep_conflicts || possi->up->type == dep_breaks) &&
|
||||
provider->up->up->set == possi->up->up->set) ||
|
||||
!provider->up->up->clientdata ||
|
||||
!would_like_to_install(provider->up->up->clientdata->selected,
|
||||
provider->up->up) ||
|
||||
!pkg_virtual_deppossi_satisfied(possi, provider))
|
||||
continue;
|
||||
if (useavailable(provider->up->up))
|
||||
return true;
|
||||
if (fixbyupgrade && !*fixbyupgrade &&
|
||||
(!(provider->up->up->status == PKG_STAT_INSTALLED ||
|
||||
provider->up->up->status == PKG_STAT_TRIGGERSPENDING ||
|
||||
provider->up->up->status == PKG_STAT_TRIGGERSAWAITED) ||
|
||||
dpkg_version_compare(&provider->up->up->available.version,
|
||||
&provider->up->up->installed.version) > 1))
|
||||
*fixbyupgrade = provider->up->up->clientdata;
|
||||
}
|
||||
return false;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue