pax_global_header 0000666 0000000 0000000 00000000064 15235417303 0014515 g ustar 00root root 0000000 0000000 52 comment=ee243d83360214806cbb85dcf1d76bb568af7536
ssgelm-checkinstall-59a004a/ 0000775 0000000 0000000 00000000000 15235417303 0015776 5 ustar 00root root 0000000 0000000 ssgelm-checkinstall-59a004a/.gitignore 0000664 0000000 0000000 00000000302 15235417303 0017761 0 ustar 00root root 0000000 0000000 # build products
/checkinstall
locale/*.mo
installwatch/*.o
installwatch/installwatch.so
installwatch/localdecls.h
installwatch/libctest
installwatch/libcfiletest
installwatch/test-installwatch
ssgelm-checkinstall-59a004a/BUGS 0000664 0000000 0000000 00000001351 15235417303 0016461 0 ustar 00root root 0000000 0000000 ==========
KNOWN BUGS
==========
* You can have some trouble if the source directory's path has white spaces in
it, when building rpm packages or Slackware tarballs. These problems are
caused by bugs in the packaging applications used in those systmes (Namely
"rpm" and "installpkg"). Checkinstall makes it's best effort to work around
these bugs, but you should try to avoid source directories' names with spaces.
There's no problem when building Debian packages, though.
* Some directories are not removed when removing a checkinstall-generated
rpm package.
* The installwatch library seems to have some problems with glibc-2.2.1. You
should use glibc-2.2.2+
* There are problems when using installwatch and libsafe together
ssgelm-checkinstall-59a004a/COPYING 0000664 0000000 0000000 00000043100 15235417303 0017027 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
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.
Copyright (C)
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 .
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.
, 1 April 1989
Moe Ghoul, 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.
ssgelm-checkinstall-59a004a/CREDITS 0000664 0000000 0000000 00000001135 15235417303 0017016 0 ustar 00root root 0000000 0000000 Kevin D. Knerr, Sr.
Chris Spiegel
Christian Ruzicka
Chris Kuklewicz
Matt Conway
Nicholas Young-Soares
Ferdi Franceschini
Tobias Fritz
Dima Vukolov
Bernhard Kaindl
Sergey Kryaczevskih
Sven Mueller
Christian Tusche
Guglielmo Bondioni
Paul Wagland
Uwe Koloska
olivier fleurigeon
Max Norton
Felipe Sateler
See the Changelog for details
Patches imported from the Debian package
========================================
Damien
Felipe Sateler
Geoffrey Hausheer
Giulio Moro
John David Anglin
King Jin
Lukas Märdian
Reuben Thomas
Stephen Gelman
Timo Juhani Lindfors
Vincent Jaquet
wuruilong
ssgelm-checkinstall-59a004a/Changelog 0000664 0000000 0000000 00000102027 15235417303 0017612 0 ustar 00root root 0000000 0000000 This file is a dump of the commit log, kept by hand up to 1.6.2. It stops
there. Everything since is in git, which says the same thing without going
stale:
git log
========== Checkinstall 1.6.2 is released ===========
commit 3af2ebd909675c7e6c75dfc8516894208c8b9797
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:18:58 2008 -0600
Fixed typo when finding files created under /home
commit e4a3eda80922bcc1c6a065b39ccc1a5f6279675e
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:15:58 2008 -0600
fixed type issues on 64 bit glibc 2.7
Patrick Ohly
commit e02fd179f57d8808238a20507d8615c091ca5951
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:14:54 2008 -0600
--replaces option, similar to --conflicts (Debian only)
Patrick Ohly
commit 897fa9da37b215d441faf5cc73032705fc892043
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:14:14 2008 -0600
No epoch in Debian version
Do not use the epoch in a package version (: prefix)
for the package name (that's also what dpkg-buildpackage does).
Patrick Ohly
commit 932082d084c2e8aa50c958b03d190c2b5884fce3
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:13:08 2008 -0600
docdir without package name
With the traditional --docdir option it is not possible
to select a path which does not include the package name
and version. With this patch one can use
--docdir=:
to select a directory that nothing gets appended to.
Patrick Ohly
commit d49c9b09e576056374ba8491238ce43b769363eb
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:12:24 2008 -0600
Avoid hard-coded installation directory
Instead of hard-coding /usr/local as installation directory,
find out where the checkinstall script is actually located
and find the other files relative to that:
/bin/checkinstall
/lib/checkinstall/...
/lib/installwatch.so
Patrick Ohly
commit 90f2cf5d71638bb5512e7d2f1db76b19b94a7c7c
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:07:29 2008 -0600
Allow package creation without being root via fakeroot
Note that the default location of checkinstall is not normally
in PATH of normal users, so call it explicitly or set PATH:
fakeroot /usr/local/sbin/checkinstall ...
Patrick Ohly
commit 51a2bfc55ac0ab444ffff58440478d5bf5028b95
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Sun Nov 16 10:06:25 2008 -0600
--conflicts, similar to --provides (Debian only)
Patrick Ohly
commit f241975428f39ed25ffc44dc4d9c505ebe070314
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 11:51:10 2008 -0600
The test for AT_SYMLINK_NOFOLLOW wasn't being done in all the places we needed it.
commit efb7b13a16190bd390d5cafbe357883769b9009c
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 11:27:42 2008 -0600
Added unlinkat() support
commit 25e30f61125481a72594e94dae5ba2dd3d085eed
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 11:03:56 2008 -0600
Added symlinkat() support
commit 422349e61249b7eb9eed1cc6cdba002e191c0cfd
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 10:33:23 2008 -0600
Added renameat() support. Fixed filenames with spaces regression.
Sebastien's patch had trouble copying files with spaces in their name. Fixed it.
commit 93f567e76a686c242412acf01bec33f28bbb18ce
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 10:02:43 2008 -0600
Added mknodat() support.
Just like fstatat(), it requires us to define __xmknodat()
commit 26cc029823ca5e4cf965ce948a25a5b4b4bf3bf9
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 09:18:58 2008 -0600
Added readlinkat() support
commit 8c74edad883d74283e171c70f49613e0fd77dcc7
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 08:59:00 2008 -0600
Added mkdirat() support, fixed link() ommission.
commit e993c1f9f7cca1e69576ab7dd7538e146106c298
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 01:24:50 2008 -0600
Patch from Sebastien Vasey for permissions and symlinks issues.
Fixes a permission issue that, for example would let a package created
by checkinstall change the owner of a user's home directory to root. This is
done by ensuring permissions are preserved at each step.
An issue with symlinks is also fixed. The patch makes checkinstall
dereference all symbolic links that are not created by the installation script,
while the others are kept.
commit 66e142436759e8085a274f57f8c4d9d7a549e8f7
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Fri Nov 14 01:01:37 2008 -0600
Added linkat() support
In instw_setpathrel():
If dirfd is AT_FDCWD then we got nothing to do, return the path as-is
In linkat():
FIXME: If we have AT_SYMLINK_NOFOLLOW we need to dereference the links
commit 653cc2da7a885c5688e12af31c12dc58db16d7f2
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 18:30:24 2008 -0600
Updated checkinstall version Id, minor debug message format fix for fopen()
commit 380e3a4520097464681442cf64022bd86aab18ab
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 18:24:19 2008 -0600
Added support for chownat() and fstatat()
Included fstatat() support which in fact requires
__fxstatat() and __fxstatat64(). Just like __xstat() and its relatives,
they are the back-end for fstatat(), which in glibc is implemented as
an inline function. See the details in sys/stat.h.
While doing a strace of the chown utility I found out it calls chmod32()
so I added a small hook to support it.
commit e9ccdd2f8c0f846e62203d4f1d3c77cfa7d8c9d8
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 16:15:31 2008 -0600
checkinstall: Keep tmp dir and debug file if in debug mode
installwatch: Use the right variable name for fchmodat() debug call
commit e954f02a9697bd342baff65353b59162e5621f0b
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 15:22:00 2008 -0600
Cleaned up the source directory
commit 8efcfadff61443642cda7b888d1b7da0f0759f0a
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 15:12:00 2008 -0600
Removed execve() support
I don't need it right now and it's causing segfaults when running checkinstall.
I'll look into it later.
commit c0c4ff9855de594e9b7ac3240bb728277cda557a
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 15:09:56 2008 -0600
Added fchownat() support
commit d084a5e13a3dc3530ec11f2fd7e7bb55a02c0cbf
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Wed Nov 12 08:06:42 2008 -0600
Added a comment explaining the way openat()-ish functions are implemented.
commit 18e25050c33020e8f52e41016d43c141ed9890bd
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:43:43 2008 -0600
Added locale files
commit 22f158b0a2f8b297e5ea4e4cdb2462458b3ac6a3
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:22:43 2008 -0600
Eiminated the installwatch version from checkinstall's Makefile
commit 7a66fe38c23eda68ec19e14e5c88365ec1095e56
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:14:34 2008 -0600
Support for 64-bit architectures in the installwatch script
commit 24709aa3e4635b9b5adcc3b4a6b3f3f2ad975400
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:08:20 2008 -0600
Update localdecls for newer glibc minor versions
commit 3a8f06f1b33bb02fb899b7e65200d9285d047ca6
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:04:34 2008 -0600
Support for readlink() variations from different glibc versions.
commit 8985cab38df1abfb9b36b1275577601021878038
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 20:01:30 2008 -0600
Added reduce() invocation in instw_setpath() to clean up the path
commit a3cea18f491fa5db6b4d1c0558d96dcd4247c7d8
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:58:30 2008 -0600
Fix minor debug messages formatting errors
commit 40c03122c5b615ce151f7a4cf2bb088d547d7af2
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:57:23 2008 -0600
fchmodat() support
commit 8414cfda5031039a91a2ee3ef7fd5455d151c2b0
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:56:11 2008 -0600
Added reduce()
It simplyfies paths, by reducing all occurences of "..", ".", and extra "/"
in path.
commit dcf3294b15f1bb89aa1b809513a68be29a9caf25
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:54:12 2008 -0600
openat() support
commit 41fcd29f564980e0604200e3ad8d79b6133cbf74
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:50:01 2008 -0600
Switch log() for logg()
commit 8afe5835ed8930aa7140a1c4182e4be320bfefe0
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:40:53 2008 -0600
removexattr() from Alex Kern
commit ef703d588638e76f6dc6e69d87eba26ead7fd066
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:39:16 2008 -0600
setxattr() support from Alex Kern
commit ec51e682ea122291e14aa4ed8deb835474838174
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:33:29 2008 -0600
Initialize trlen, from the code-cleanups.patch from SuSE installwatch-1.6.1-40
commit b26ba653f386051e94691721921c650d833c2b79
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:32:27 2008 -0600
Save errno, sent by Benoît PAPILLAULT at Source Mage linux
commit 7c2b1b3528f53d6e5d44261d2b1c77951e466e2f
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 19:30:21 2008 -0600
Modified some grammar / spelling mistakes
commit c48d9af661e762fbff5bb31aaefa72bf088bb120
Author: Felipe Eduardo Sanchez Diaz Duran
Date: Tue Nov 11 13:35:00 2008 -0600
Switch to git. Checkinstall pre 1.6.2
nov/01/2006
* Provides/Requires bug fixed
* Applied the patches from Felipe Sateler:
- We now explicitly run bash (It has always benn a requiremente anyway)
- In Debian we set the architecture with dpkg-architecture.
- If we're creating a .dpkg then we eliminate uderscores and put
dashes instead in the package name.
- Tag all files in /etc inside the package as config files
june/23/2005 ====== Checkinstall 1.6.0 is released ======
* Applied the PAGER patch from Tomas Pospisek
* Changed the Provides/Requires option in the menu
* Applied the "Copyright patch" from Andy Hanton to fix some issues
with newer rpm versions. Also his buildroot patch
december/01/2004 ====== Checkinstall 1.6.0beta4 is released ======
* CK_SLACKWARE, CK_REDHAT and CK_DEBIAN were being ignored if
set in checkinstallrc. Fixed.
* Fixed "libdirs: file not found"
* Improved postinstall-pak handling
* Fixed variable name typo: It said PROVODES instead of PROVIDES.
Reported by Bernd Weigelt.
* Cosmetic fix in "--help" output
* Added command line flag "--addso".
* The default for ADD_SO is now NO. So no more auto-editing of
/etc/ld.so.conf unless explicitly requested.
* Fixed detection of postinstall scripts (PINST_EXISTS bug)
* Added MAKEPKG_FLAGS to checkinstallrc. By default sets flags useful
to users of newer Slackware versions.
* Added SHOW_MAKEPKG to checkinstallrc.
* Fixed the famous "segfault on newer glibc's" bug in installwatch
december/25/2003
* Fixed another "argument list too long" bug.
* Merged in some suggestions from Tobias G: more docs filenames for
automatic inclusion in doc-pak and better handling of symlinks when
copying the documentation files.
* Added a "--reset-uids" option that resets the permissions of all
files and directories to "755" and the owner and group of all
directories to root.root, in a way similar to what Slackware's
makepkg prompts you to do.
* Added a patch from Thomas Rausck to also add symlinked directories.
* Fixed the support for recycling a pre-existing .spec file. Part of
the fix was based on a patch sent by Karlheinz Pischke.
* The PKG_GROUP variable is correctly set when using the -R, -S or -D
command line options.
* Added a "--fstrans" command line option for enabling or disabling
the filesystem translation code.
* Fixed the problem many people found when copying the documentation
files. Now the documentation and the included (With "--include") files
are handled outside the installscript.sh script. This keeps the
filesystem translation code from messing with those.
* The package information menu was moved to the first stages of the
script. Now you can modify the package's name or version and the
documentation directory will be correctly named.
* Improved the domain name detection algorithm used when setting the
"Maintainer" field. We start with the env variable HOSTNAME, then
try running "hostname -f" and finally we default to "localhost".
* A pre-existing .spec file will not be erased when checkinstall exits.
* If a pre-existing slack-desc file is found then we use it to generate
the description-pak file UNLESS we already have a description-pak file.
* CheckInstall attempts to identify any ELF shared libraries in the
package and append their locations to the /etc/ld.so.conf file, if
they are not already there.
december/14/2003
* Fixed a small typo, reported by Andrej Lajovic.
* Added default values that were missing for BASE_TMP_DIR, PAK_DIR,
RPM_FLAGS and DPKG_FLAGS. Also fixed a bug that made checkinstall
ignore the setting of INSTALLWATCH_PREFIX and INSTALLWATCH. Reported
by Karlheinz Pischke.
november/28/2003
* Fixed a problem in printf when the $format variable contained a "--"
march/28/2003
* More echog() and echogn() modifications. They now properly escape
asterisks and probably the rest of the special characters.
march/23/2003
* Created two new echog() and echogn() functions for using gettext with
printf()-like formatting. All references in the script were modified
for using these new functions.
march/16/2003
* Applied another patch from Dmitry, this time to include directories
in the .spec file when building rpm packages. The root directory is
excluded, wich fixes the problem we had before that made us not including
directories at all.
march/15/2003
* Added a check to see if rpmbuild is in the PATH when we are
expecting it to be there.
march/13/2003 --- 1.6.0beta3 begins ---
* Applied patches from Dmitry Vukolov for CK_DEBIAN and CK_REDHAT
handling. Several patches for handling spaces in directories and
a "$" that was not properly escaped in a warning message.
march/12/2003
* Added version setting patch sent by Lawrie Abbott
* Added new command line options "--rpmi" and "--rpmu" for telling
rpm to (i)nstall or (U)pdate new rpm packages.
* In slackware, tar-1.13 is used if present (Fixes some issues when
building packages in newer Slackware versions).
* Added command line option: "--with-tar" which can be used to manually
specify the path to the tar binary to be used when building packages.
* Fixed document directory handling
* The MAKEPKG variable can now be set in the checkinstallrc file
march/11/2003
* Merged in the patches from Dima Vukolov for erasing the temp .tgz file
used when building a rpm package and finding the RPM source directory
path using the %_topdir macro from rpm
* Added Thomas Rausch's patches for symlink handling
november/27/2002
* Added internationalization support via GNU gettext
november/24/2002
* Added support for preinstall-pak, postinstall-pak, preremove-pak
and postremove-pak scripts on both RPM and Debian packages. In Slackware
the postinstall script was already supported as "install-pak".
* Added support for inclusion of a custom list of files in the package,
via the "--include" command line option. It takes a file as argument.
That file should contain the list of files to be included, one per
line.
* Added the "--inspect" command line option. It allows you to view and
optionally edit the list of files to be included in the package, before
the package is created. Suggested by Max Norton.
* Added the "--review-spec" and "--review-control" command line options that
allow you to review the .spec or DEBIAN/control files when creating
.rpm or .deb packages, before the packages are created.
* Merged in the patches sent by Max Norton for fixing some man page
handling bugs and to copy directories with special permissions.
* The RPM packages now include directories so these should be also deleted
when a .rpm package is removed.
november/23/2002
* Added Olivier Fleurigeon's patches for support of the new installwatch
0.7.0beta1, that allows us to do the whole installation procedure
in an alternative root, therefore allowing to create a package
without actually installing it in the system. This functionality
is invoked with the "--install=" command line option.
* Added support for "--requires" for specifying package requirements
for RPM packages. This patch was sent by Ulrich Baur.
october/26/2002
* The rpmbuild program is used only if using rpm 4.x. Otherwise we still
use "rpm -bb"
* If there's an install-pak file, --ss is implied (Run the Slackware
install script interactively)
september/10/2002
* The user's umask is ignored and automatically set to "0022", unless the
user explicitly request a custom umask value with the new "--umask"
command line option.
* Added support for the new Slackware package description format. It
can be activated with the "--newslack" command line switch.
august/25/2002
* We use "rpmbuild -bb" instead of "rpm -bb", because newer rpm versions
no longer support the use of "b" switches with the "rpm" program.
* Fixed a bug introduced in version 1.5.2. The description file for
Slackware packages was not handled properly by the doinst.sh script.
* The architecture string is set to "powerpc" when building a Debian
package.
july/09/2002
* Applied patch from Simon Munton for filtering out only the file names
that begin with "/dev" and not every file name with "/dev" in it.
june/28/2002
* Man pages under /usr/local are compressed too.
april/24/2002
* Automatic man page compressing is now available when the "--gzman=yes"
command line option is selected. This includes code from the brb-compress
script included in the rpm-4.0.2 distribution.
* Various fixes and workarounds for the case when the source directory's
path contains white spaces. Read the BUGS file.
april/22/2002
* Added "OpenLinux" to the list of possible locations for the rpm sources
directory. Suggested by Michael v.Ostheim.
* Added the "debianize" patch from Matt Hope. Now the .deb packages built
with checkinstall should be a bit more Debian-standard-compliant.
* The pager used by checkinstall can now be selected via the
PAGER environment variable.
* The pkgtool info display warning is now issued only if the Slackware
packaging system is selected. Suggested by Acid Hippy.
* If the Debian packaging system is selected, the package version is
verified to ensure that it contains at least one digit, otherwise dpkg
would complain about it. Suggested by Uri David Akavia.
* Another dpkg-friendly correction: the package name is forced to lower
case, another thing demanded by dpkg :-). Suggested by Simon Rutishauser.
* Included a patch from Vladimir Bilyov to enable symbol stripping from
shared libraries. Use it carefully. Active only when "--strip=yes" and
"--stripso=yes" is selected.
december/22/2001 ====== checkinstall 1.5.1 is released ======
* Modified the slackware package creation module to use the new
(Post-Slackware 8.0) Slackware package naming scheme:
name-version-architecture-release.tgz.
* Added command line options: "--provides" and "--maintainer"
december/19/2001
* Corrected the checkinstall.log creation to prevent it from being
overwritten with each file created.
* Use "." instead of "*" to get all the files in a directory with tar,
including any dot files found. Thanks to Tom for both of these.
* Merged in the patch from Guglielmo Bondioni to add support for the
"Mantainer:" field in the Debian control file.
* Added support for the "Provides:" field in the RPM spec file. Sent by
Uwe Koloska.
* If "description-pak" and/or "doc-pak" are already in the source
directory then checkinstall won't delete them when finished unless it is
asked to. Suggested by Uwe Koloska.
november/27/2001
* Added the "--nodoc" option to answer "no" to the question about including
default documentation in the package.
* Applied patches from Olivier Fleurigeon: getopt argument parsing and
fix a bad behaviour when using "--backup=no" (checkinstall tought that
the installation had failed).
november/23/2001
* Applied the Paul Wagland patch for a DOC_DIR variable. Now you can
specify the path where the package docs will be installed (instead of
/usr/doc). I completed it with the "--docdir" command line option.
* Corrected a tar invocation explicitly telling it to use stdout. Thanks
to George Sipe for noting it.
november/18/2001 ====== checkinstall 1.5.0 is released ======
* Finally found the two other file descriptor leaks in installwatch
that were still causing the "Too many open files" error when installing
huge packages.
november/13/2001
* Added new checkinstallrc options: DPKG_FLAGS and RPM_FLAGS.
RPMFLAGS is now deprecated. Use RPM_FLAGS instead.
* Changed the format of the information displayed by "--help".
november/11/2001
* Applied a patch to correctly name the Debian packages.
This patch was sent by Guglielmo Bondioni .
* Now all the "Package information section" values can be set with
command line options. Suggested by Olivier Fleurigeon.
october/20/2001 ====== checkinstall 1.5.0beta2 is released ======
* Fixed the "invalid option" problem with rpm.
* Added support for a central package repository. If the "PAK_DIR" variable
is set (It can be set in the checkinstallrc file) then checkinstall will
attempt to create the directory named by PAK_DIR and save the newly
created package instead of leaving it at the default location. Now you
can automatically keep all your created packages in one single place :)
* There's a verification to check if the required binaries to build the
selected package type are present.
* Miscellaneous changes: "debug: " is prepended to every debugging echo in
the script, the yorn() function now uses lower case letters (cosmetic),
etc. Make a diff to view details.
august/09/2001
* Added a more robust way to create the .spec file's file list, it is now
generated from the files found in the buildroot. No more duplicate files
(or cuasi-duplicate like "/usr/local/file" and "/usr/local/./file").
* The Slackware package name can now be changed in the Package Information
menu. Now you can use a name different to the name of the source
directory.
* The "-y" command line option now also causes checkinstall to skip the
package information menu. Now checkinstall is truly "scriptable".
* When the "-y" option is specified the default answer is printed like if
the user had typed it in. This is a cosmetic fix.
july/20/2001 ====== checkinstall 1.5.0beta1 is released ======
* Started checkinstall-1.5.0 development. CheckInstall can now build
Debian packages.
* "-D" is now used to tell checkinstall to build a Debian package.
"--type=debian" has the same effect.
* The package info section is now common to all three packaging sections.
If you use Slackware it won't be of much use (yet). One useful thing
about it is that you can now change the name of the generated package
so it can be different to the current directory's name.
* Included the Slackware 8.0 makepkg patch in the "makepak" script. The
patch will be effective only if a Slackware 8.0 installation is detected.
june/25/2001 ====== checkinstall 1.4.1 is released ======
* Default values are assumed if checkinstallrc is missing
* Merged in the tar patches from Sven Mueller
Now tar is told to use stdin/stdout instead of just assuming it will.
* Fixed the detection of an empty/nonexistent backup directory
* "-bk" option is now actually used
* Added the "--default" option to assume the default answers to all
questions (useful for scripting). "-y" is a sinonym for "--default"
* "--exclude" now can specify file names in addition to directory names.
* The return status from the install command is now correctly reported.
We were reporting "Installation succesful" even if the command returned
an error condition.
* INSTALLWATCH: Patched to fix the "Too many files open" problem that
some people reported. Thanks to Christian Tusche for this one.
june/08/2001 ====== checkinstall 1.4.0 is released ======
* Added "--exclude" and "--autodoinst" options
* Fixed a bug in the install command parsing
* Fixed the backup code
april/19/2001 - Felipe Sanchez
* Fixed an incorrect path to the checkinstallrc file.
* cleanup() no longer deletes doc-pak, the spec file and the description
file.
* Fixed the "missing ']'" problem when testing the less pager.
april/17/2001 - Felipe Sanchez
* Started development of checkinstall-1.4.0
* Modified the installwatch library to backup files modified by the
installation command _before_ they are modified. This is done at the
system call level. CheckInstall now can backup those files and write for
you a file containing them.
See the RELNOTES file for details.
* CheckInstall behavior is now fully configurable via command line flags.
Try "checkinstall --help" to see them =)
april/16/2001 ====== checkinstall 1.3.2 is released ======
* Made a fix to avoid a possible symlink attack when creating the temp dir.
* Fixed handling of filenames with spaces on them.
april/07/2001 ====== checkinstall 1.3.1 is released ======
* When the Slackware package creation option is chosen a Slackware
installation script is automatically created which will display the
package description and put it in the package's log file in
/var/log/packages, every time the package is installed with "installpkg".
* Fixed the problem with rpm-4.0 about the "target" argument parsing.
* Removed some macros from the RPM spec file, including the one that
caused RPM to automatically gzip all man pages
* ELF binaries are automatically stripped by default. This was copied from
one of the rpm-4.0's scripts. I guess that code is Copyrighted by it's
author but has no Copyright notice in it. I'm assuming it's GPL'ed as
a part of the rpm distribution.
* Improved some features and added a few ones.
* Included the patches suggested by Bernhard Kaindl
- New temp dir (/var/tmp)
- No more dummy .tgz source file
- Now all arguments are used as a single install command,
no quotes needed.
* Made some spelling corrections (Thanks to Sergei Kryaczevski)
* RPM install flags are now customizable.
march/01/2001 ====== checkinstall 1.3.0 stable has been released ======
* description-pak file format has changed. No more
"-pak:" prefix on every line
This gives us a more easier to write description-pak and fixes the
colon-in-the-middle problem reported by Tobias Fritz.
* Added options to control various defaults:
Package type
Display of the output from the install command
Package description
Deletion of doc-pak, description-pak and .spec file
Many of these were suggested by Chris Spiegel.
* The yorn function has been largely extended to allow a default value
to be specified and displayed, suggested by Sergey Kryaczevskih
* The .spec file customization now correctly handles the case where you
change the package's name, version or target architecture.
This also fixes the LANG problems while detecting the actual created
package's name.
* Fixed auto-detection of the rpm source directory
* Fixed the duplicated files problem with rpm.
Thanks to Ferdi Franceschini for this one.
* Added debugging mode (see the description inside the script)
* Re-organized the variables section in the script. I guess a rc file
will come handy very soon.. ;-)
* Patched installwatch so it can be compiled with glibc-2.2.1
(Reported by Nicholas Young-Soares)
BTW, I took over the development of installwatch; it's author is no
longer reachable.
jan/20/2001 by Felipe Sanchez
* Fixed the nasty bug that prevented operation in nearly every rpm-based
distribution
* The BuildRoot for RPM package building now points to a much saner place
(The build dir inside the temp dir). Thanks to Chris Kuklewicz for the
report.
* Fixed the install script to make it actually report the exit status of
the INSTALLCMD
Thanks to all the people who reported bugs in the 1.3.0beta release!
jan/18/2001 by Felipe Sanchez
* RPM package creation support is in place !
* Now is possible to write multi-line descriptions
jan/12/2001 by Felipe Sanchez
* Fixed bug which set incorrect (755) permissions to /tmp after the
package was installed if the installation procedure created any files
inside /tmp.
* Fixed typo (chown instead of chmod, duh!) which made useless the security
enhancements of the 1.2 release. Now the permission of the new temp dir
( /var/checkinstalltmp by default) should correctly be set to 700. If
you used checkinstall 1.2 (now should be known as 1.2.0) then read the
RELNOTES file to fix this.
Thanks to Chris Spiegel for noting these two!
* Changed checkinstall's versioning scheme: major.minor.patchlevel
jan/07/2001 by Felipe Sanchez
* Fixed a couple of bugs which prevented symlinks from being added to the
package and detection of files created inside scripts run by child shells.
* Detection of the INT (ctrl-c) signal to allow for proper clean up and
termination.
* The package description file is now called "description-pak"
dec/10/2000 by Felipe Sanchez
* Added the "okfail" function
* Modified the program's look to be a bit more terse. I hope you like it.
dec/09/2000 by Felipe Sanchez
* Added even more variables :)
* Reorganized temporary files structure under a common TMP_DIR, named
after the process' ID to avoid problems with concurrent execution
* Changed the yorn funcion (Yes or No) to return true for "Y" and
false for "N"
* Added an option to ignore files created under the source directory,
when these files where installed the owner of that directory (and
it's parents) became root:root, a pretty annoying thing when this
was your home directory ;)
* Modified Slackware's makepkg to avoid the questions about symlinks
and permissions. The modified file is called "makepak".
nov/18/2000 by Kevin D. Knerr, Sr.
* Incorporated more variables to simplify the script & ease maintenance
* Added ${} syntax to existing variables when concatenated w/ strings
* Created a simple function to handle Y/N inputs
* Added an option to let checkinstall create a basic set of package docs
based on commonly used doc names
* Reorganized some sections to improve program flow while reducing
some instances of duplication
===========
ssgelm-checkinstall-59a004a/FAQ 0000664 0000000 0000000 00000004525 15235417303 0016336 0 ustar 00root root 0000000 0000000 FAQ
1. I ran CheckInstall and everything seems to run fine, but when I check my
new package I only find the documentation files!
CheckInstall can't trace (yet) the actions of three kind of binaries:
* SUID programs
* SGID programs
* Statically linked binaries
You may now go to check the binaries you're using in the installation
process ;-).
2. I built my Linux system from scratch (LFS, anyone?) and nothing gets
included in the packages I create with CheckInstall!
Most likely you installed GNU make from source, which by default installs
the make binary with SUID and/or SGID permissions. A quick fix:
chmod 0755 `which make`
Which means to remove the SUID and SGID bits from the make binary.
Please refer to the first question in this FAQ for the details.
3. I use Slackware Linux 8.0 and the symbolic links created by my
installation do not get into the package!
The ln binary shipped with Slackware 8.0 is statically linked. Replace it
with a dynamically linked one.
The one shipped with Slackware 7.1 works just fine. You can download it
here: http://checkinstall.izto.org/ln.gz
Please refer to the first question in this FAQ for the details.
4. I used CheckInstall to install the latest XFree86 distribution, but the
drivers are being corrupted! If I install XFree86 without CheckInstall
everything runs fine. Is this some evil bug?
It's not a bug. It's your driver's files being stripped by the automatic
ELF stripping process. Run checkinstall with the "--strip=no" command
line option.
5. I use a RPM based distribution and CheckInstall says it built the rpm
package OK but reports an error when installing the .rpm file:
Building RPM package...OK
Installing RPM package... FAILED!
And in the install.log file I find something like this:
error: open of /usr/src/RPM/RPMS/i386/package-1.0-1.i386.rpm failed no
such file or directory
What's wrong?
There's something wrong with your RPM installation. Check your system and
see if the "rpm-build" and "spec-helper" packages are installed. Also
verify that their versions match the version of the rpm binary installed
in your system.
ssgelm-checkinstall-59a004a/INSTALL 0000664 0000000 0000000 00000001114 15235417303 0017024 0 ustar 00root root 0000000 0000000 =========================
INSTALLATION INSTRUCTIONS
=========================
Simple enough:
make
su
make install
checkinstall
"make install" goes first because we have no checkinstall installed yet :)
"checkinstall" goes latter so we can have a properly installed (and removable)
package for checkinstall-1.7.0
(Be sure to read the README if you're planning on building RPM or
Debian binary packages)
This will install checkinstall-1.7.0, makepak (modified makepkg) and
installwatch-0.7.0
==========
ssgelm-checkinstall-59a004a/Makefile 0000664 0000000 0000000 00000002652 15235417303 0017443 0 ustar 00root root 0000000 0000000 # Where to install.
PREFIX=/usr/local
BINDIR=$(PREFIX)/sbin
LCDIR=$(PREFIX)/lib/checkinstall/locale
CONFDIR=$(PREFIX)/lib/checkinstall
all:
for file in locale/checkinstall-*.po ; do \
out=`echo $$file | sed -s 's/po/mo/'` ; \
msgfmt -o $${out} $${file} || exit 1 ; \
done
sed 's%MAKEFILE_PREFIX%$(PREFIX)%g' checkinstall.in > checkinstall
$(MAKE) -C installwatch
install: all
export
$(MAKE) -C installwatch install
mkdir -p $(BINDIR)
mkdir -p $(LCDIR)
install -m 0755 checkinstall makepak $(BINDIR)
for file in locale/*.mo ; do \
CKLNG=`echo $$file | sed -e 's|locale/checkinstall-||' \
-e 's|\.mo||'` && \
mkdir -p $(LCDIR)/$${CKLNG}/LC_MESSAGES && \
cp $$file $(LCDIR)/$${CKLNG}/LC_MESSAGES/checkinstall.mo || \
exit 1 ; \
done
mkdir -p $(CONFDIR)
install -m644 checkinstallrc-dist $(CONFDIR)
@if ! [ -f $(CONFDIR)/checkinstallrc ]; then \
cp $(CONFDIR)/checkinstallrc-dist $(CONFDIR)/checkinstallrc; \
else \
echo; \
echo; \
echo ======================================================== ;\
echo; \
echo An existing checkinstallrc file has been found. ;\
echo The one from this distribution can be found at: ; \
echo; \
echo -e \\t$(CONFDIR)/checkinstallrc-dist ; \
echo; \
echo; \
echo ======================================================== ;\
echo; \
fi
clean:
for file in locale/checkinstall-*.mo checkinstall ; do \
rm -f $${file} ; \
done
$(MAKE) -C installwatch clean
ssgelm-checkinstall-59a004a/NLS_SUPPORT 0000664 0000000 0000000 00000002745 15235417303 0017621 0 ustar 00root root 0000000 0000000 Native Language Support
=======================
Checkinstall now uses GNU gettext to support native language translation of
all messages sent to the terminal. Set your LC_ALL variable to your
ISO-639 language and ISO-3166 country codes. For example, to set spanish and
Mexico you would use:
export LC_ALL=es_MX
How to translate to your language
=================================
5 simple steps:
1) Edit the file checkinstall.pot and fill in the msgstr lines with
the translation for the phrase located in the matching msgid line.
Example:
- Original lines
msgid "Restoring overwritten files from backup..."
msgstr ""
- Translation to spanish:
msgid "Restoring overwritten files from backup..."
msgstr "Restaurando los archivos sobreescritos..."
2) After editing the file, save it as checkinstall-ll.po, where "ll" stands for
your language's ISO-639 two-letter code. In the case of the example, this
would be "es" for spanish:
checkinstall-es.po
3) Now create the locale directory for your language. Remember to use the same
ISO codes you use in your LC_ALL environment variable:
mkdir -p /usr/local/lib/checkinstall/locale/es_MX/LC_MESSAGES
4) Next, you should generate the .mo binary message file. Run msgfmt:
msgfmt -o /usr/local/lib/checkinstall/locale/es_MX/LC_MESSAGES/checkinstall.mo \
checkinstall-es.po
(The above goes all in one line)
5) Finally, send me an e-mail message with the .po file attached so I can
include it in the next checkinstall release :-).
ssgelm-checkinstall-59a004a/README.md 0000664 0000000 0000000 00000064653 15235417303 0017273 0 ustar 00root root 0000000 0000000 # checkinstall
Installs a compiled program from the program's source directory using `make
install` or any other command supplied on checkinstall's command line.
checkinstall will create a Slackware, RPM or Debian compatible package and
install it using your distribution's standard package administration
utilities.
This version of checkinstall needs enough free space on the partition holding
the temp dir (`/var/tmp` by default) to write there a temporary copy of the
package.
## About this fork
checkinstall was written by Felipe Eduardo Sanchez Diaz Duran. Upstream
development ended with the last commit in April 2017, and the bug tracker the
source points at is gone.
This fork continues from there. It starts at that last upstream commit and
adds the patches Debian had accumulated, which by 2026 came to around forty.
Most of them matter on any distribution:
- Filesystem translation, which lets `checkinstall make install` run without
scattering files over your system, had stopped seeing most of what an
install does. glibc 2.33 turned `stat()` and its relatives into ordinary
exported functions, and the interposed library was still looking for the old
ones.
- A failed install could replace `/lib` with a directory, leaving a
merged-`/usr` system unable to run a single binary.
- Built packages carried no dependencies, and put files under `/lib` rather
than `/usr/lib`.
The `tests/` directory holds a suite covering these. Changes that belong to
Debian's packaging rather than to checkinstall itself stay in Debian.
Bugs and patches: https://github.com/ssgelm/checkinstall
## Licensing
Three licences apply here, and they differ:
| file | licence |
| --- | --- |
| `checkinstall.in` | GPL-2.0-only |
| `installwatch/` | GPL-2.0-or-later |
| `makepak` | BSD-1-Clause, Slackware's own notice at the top of the file |
`checkinstall.in` carries no "or later" clause, so the program as a whole is
GPL-2.0-only even though most of the tree allows later versions. That is the
licence to name when redistributing it.
Files that carry a licence header also carry an `SPDX-License-Identifier`
line. `COPYING` holds the GPL-2 text.
Copyright is held by Felipe Eduardo Sanchez Diaz Duran for checkinstall,
Pancrazio 'Ezio' de Mauro for installwatch, Patrick Volkerding for makepak,
and the people listed in CREDITS for everything since.
## Contents
1. [Introduction](#1-introduction)
2. [Usage](#2-usage)
- [2.1 Download, configure, build](#21-download-configure-build)
- [2.2 The "doc-pak" directory](#22-the-doc-pak-directory)
- [2.3 Package description](#23-package-description)
- [2.4 Preinstall, postinstall, preremove and postremove scripts](#24-preinstall-postinstall-preremove-and-postremove-scripts)
- [2.5 Package information](#25-package-information)
- [2.6 Package creation](#26-package-creation)
- [2.6.1 Slackware packages](#261-slackware-packages)
- [2.6.2 RPM packages](#262-rpm-packages)
- [2.6.3 Debian packages](#263-debian-packages)
3. [Customization](#3-customization)
- [3.1 The checkinstallrc file](#31-the-checkinstallrc-file)
- [3.2 Command line options](#32-command-line-options)
- [3.3 Native language support](#33-native-language-support)
4. [Notes](#4-notes)
## 1. Introduction
A lot of people has asked me how can they remove from their boxes a program
they compiled and installed from source. Some times - very few - the program's
author adds an "uninstall" rule to the Makefile, but that's not usually the
case. That's my primary reason to write checkinstall. After you
`./configure; make` your program, It will run `make install` (or whatever you
tell it to run) and keep track of every file modified by this installation,
using the excellent installwatch utility written by Pancrazio 'Ezio' de Mauro
\
.
When `make install` is done, checkinstall will create a Slackware, RPM or
Debian package and install it with Slackware's `installpkg`, `rpm -i` or
`dpkg -i` as appropriate, so you can view it's contents in `/var/log/packages`
or remove it with `removepkg` (for Slackware), `rpm -ql` and `rpm -e` (RPM) or
`dpkg -I` and `dpkg -r` (Debian).
Additionally, this script will leave a copy of the installed package in the
source directory or in the storage directory you specify (see the `PAK_DIR`
option later in the checkinstallrc file) so you can install it wherever you
want, which is my second motivation: I don't have to compile the same software
again and again every time I need to install it on another box :-).
Another nice thing about checkinstall is that it can be run simultaneously by
any number of users and each instance will get only the files modified by it's
processes and no one else's, unlike some other tools based on a
`find / -atime etc etc etc`. Not to mention that checkinstall is A LOT faster
=)
It is important to note that checkinstall can keep track of files modified by
any command line, not just a `make install`. You can create your own
installation script with lots of command in it and then have checkinstall
track them for you.
## 2. Usage
### 2.1 Download, configure, build
- Download your software, i.e. Afterstep-1.8.4.tgz
- Extract the files:
tar xzvf Afterstep-1.8.4
- cd to the source directory, configure and compile:
cd Afterstep-1.8.4
./configure
make
### 2.2 The "doc-pak" directory
Optionally you can make a directory called "doc-pak" whose contents will be
installed in `/usr/doc/` inside the package you're about to
create. checkinstall will remind you about this one if it notices there is no
"doc-pak" on the source directory. Good candidates to be there are: README,
INSTALL, COPYING, Changelog, TODO, CREDITS, etc. It's up to you what to copy
in there.
mkdir doc-pak
cp README INSTALL COPYING Changelog TODO CREDITS doc-pak
As of checkinstall-1.1 if you don't create the "doc-pak" directory then
checkinstall will ask if you want it to build a default documentation
directory with files having common documentation names like those mentioned in
the above paragraph. If you say no, your package will have no documentation.
### 2.3 Package description
Changed in checkinstall-1.3.0.
If you create a file named "description-pak" it's contents will be used to
include a description and summary in the new package, which will be displayed
when you use `pkgtool` or `rpm -qi`. For example, create the file
"description-pak":
AfterStep window manager
The one and only!
This is a window manager with a NexT inspiration.
If checkinstall doesn't find that file it will create one, asking you for a
description to put in it.
NOTE: Slackware's pkgtool doesn't seem to handle package filenames longer than
8 characters when displaying the package list in the "Remove" section, but the
"View" option works OK. I hope that Pat or someone can take the time to fix
this. I'll try to fix it myself if i find the time to do it.
As a result, I've decided not to prepend every line in the PACKAGE DESCRIPTION
section of the `/var/log/packages` entry with `package-name:`. It is difficult
to read in the `/var/log/packages` file and it's pretty useless in the
pkgtool's remove package section listing. The description is stored "as is".
Anyway, it's not that bad.. ;-)
NOTE 2: As of checkinstall 1.5.3, support for the new (8.1+) Slackware
description file format is included, available when using the `--newslack`
command line switch.
### 2.4 Preinstall, postinstall, preremove and postremove scripts
CheckInstall supports preinstall, postinstall, preremove and postremove
scripts for RPM and Debian packages.
For Debian, these scripts must meet some requirements to be accepted by dpkg
while building the .deb package. See:
http://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
In short, any shell script will do as long as it specifies an interpreter
(i.e. put `#!/bin/sh` as the first line) and has an exit status of zero for
success or non-zero for failure.
To include the scripts in your package, put them in the current directory and
name them:
| Script name | Action |
| --- | --- |
| `preinstall-pak` | Run BEFORE the package is INSTALLED |
| `postinstall-pak` | Run AFTER the package is INSTALLED |
| `preremove-pak` | Run BEFORE the package is REMOVED |
| `postremove-pak` | Run AFTER the package is REMOVED |
All scripts are optional. You can write all of them if you need them, or only
the ones you need, or even none.
Remember that the scripts are run only when the .rpm or .deb package is
installed or removed. NOT when the initial install command (i.e.
`make install`) is run.
For Slackware packages, the "postinstall-pak" script is already supported as
"install-pak". Either name will work.
### 2.5 Package information
CheckInstall will display a menu with several values that can be customized
for this package, like the package's name, version, release number, etc.
Most of the values are self-descriptive, however there are three values that
deserve special attention: "Name", "Source Location" and "Alternate Source
Location".
The "Name" field allows you to change the name for the package you are about
to create. This is useful when CheckInstall fails to properly set this name
from the source directory's name. This also applies to the version field.
The "Source Location" values are -for now- only hooks for the upcoming
"auto-unpack-configure-compile-install" feature in future CheckInstall's
versions. The "Source Location" will tipically be the original source archive
and the "Alternate Source Location" would be some FTP or HTTP URL where the
source archive can be retrieved from. Keep your eyes on these ones ;-).
Please note that as of checkinstall-1.5.0 (not 1.5.0betax) all of these values
can be specified via command line options. See
[3.2 Command line options](#32-command-line-options) below.
### 2.6 Package creation
- You normally would su and make install. Now it's only su:
su
password: xxxxx
- Run checkinstall:
checkinstall
NOTE: If you give no arguments to checkinstall it will run a `make install`.
If you give arguments, the first non-option argument will be used as the
install command. This is useful when the install command is not `make install`
but something else like `make install_packages` or `setup` or whatever, i.e.
checkinstall make install_packages
checkinstall make modules_install
checkinstall install.sh
checkinstall setup
checkinstall rpm -i my-package-1.0.i386-1.rpm
#### 2.6.1 Slackware packages
checkinstall will ask if you want to see the installation results, then run
the modified Slackware package maker `makepak`. If you want checkinstall to
use the original Slackware's `makepkg` then change the `MAKEPKG` variable
inside the checkinstall script and read this:
makepkg will ask you a couple of questions:
If there are any symbolic links in the installed package it will ask you to
remove them and make an installation script to re-create them whenever you
install the package. This is a GOOD THING, so answer YES. --> BTW, makepkg
doesn't always ask you this (depending on whether you have symbolic links or
not) so be careful and read before you answer, you could be answering the
wrong question. Read on:
makepkg will *always* ask if you want to change the owner, group and
permissions of EVERY file in the package to root:root:755. This is BAD most of
the times, always answer NO to that question, unless you know what you are
doing, of course ;)
In the end, checkinstall will install the package with `installpkg` so you can
remove it later with Slackware's `removepkg` (Our initial intention :) ).
Additionally, it will leave a copy of the package in the source directory, the
package's name will be name-version-architecture-release.tgz. Using the
Afterstep example, the file would be named Afterstep-1.8.4-i386-1.tgz.
Starting with checkinstall-1.5.1, the created packages will be named using the
new (post-Slackware 8.0) Slackware package naming scheme.
You can add a customized installation script which will be run by `installpkg`
every time you use it to install your new package. Write it and name it
"install-pak" or "postinstall-pak" and checkinstall will include it for you.
This script can be useful to set up the system to fit the newly installed
package: create new users, set permissions, initialize databases, rcscripts,
etc.
#### 2.6.2 RPM packages
CheckInstall has the ability to build binary RPM packages. After you write the
package's description the script will prompt you to choose a package type. If
you chose RPM ("R") then it will figure out some sane values and write a
minimal spec file. You can of course supply your own file, in this case
checkinstall will use the values you put in there to build the rpm and skip
the spec file writing step. If any problems arise while building/installing
the rpm you'll get a chance to see the log files and figure out what went
wrong.
#### 2.6.3 Debian packages
That's right, CheckInstall can now create Debian packages. Do I need to say
more? =)
The Debian support in CheckInstall is still new, so handle it with care. It
has been reported to work OK in some Debian systems and it certainly works OK
in my Slackware development system with dpkg installed. Your mileage may vary.
And of course, it it *does* vary, I'd really like it if you send me a message
telling me about it so I can fix it ;-).
**NOTE to non-Debian-based users:**
To build Debian packages you need the dpkg utility. I got mine from:
http://www.debian.org/Packages/unstable/base/dpkg.html
Also, you should have all of your basic filesystem structure included
("installed") in your dpkg database, or you won't be able to remove most .deb
packages installed (either checkinstall-generated ones or not). dpkg seems to
be unwilling to remove things like "/", "/usr" and such, wich are obviously
included in nearly every package you install. The way to avoid this particular
problem is to have a "base" package installed containing those directories, in
this way dpkg won't complain about removing other packages.
I've put a "aaa_base-1.0-1.deb" package in the CheckInstall's home page as a
work-around for this problem. Install it with `dpkg -i aaa_base-1.0-1.deb` and
then forget about it =).
`dpkg -I aaa_base-1.0-1.deb` should give you some useful info about the
package.
## 3. Customization
### 3.1 The checkinstallrc file
CHANGE in CheckInstall 1.4.0: the variable declaration section in the
checkinstall script has been removed, you should now edit the checkinstallrc
file, normally installed under `/usr/local/lib/checkinstall`.
In the checkinstallrc file you will find some variables wich modify
checkinstall's default behaviour. They're described here (and are also well
commented in the file, BTW). The checkinstallrc values are these:
- `DEBUG`: Set the debug level (Default: 0)
- `0` No debug
- `1` Keep all files except the ones inside the package
- `3` Keep those files too
- `INSTALLWATCH_PREFIX`: Prefix to installwatch's library and program
- `INSTALLWATCH`: Location of the installwatch program
- `MAKEPKG`: Location of Slackware's makepkg. "makepak" is the default, and is
included with checkinstall. If you want to use Slackware's native "makepkg"
then set this to "makepkg"
- `MAKEPKG_FLAGS`: makepkg optional flags. These are recommended if running a
newer Slackware version: `-l y -c n`
- `SHOW_MAKEPKG`: Boolean (Default: 0)
Show -or not- the results of the MAKEPKG command as it runs. Useful when
running it with interactive options. If checkinstall seems to halt and sleep
after saying "Building Slackware package..." then you might want to set this
to 1.
- `BASE_TMP_DIR`: Prefix to all checkinstall's temporary files/dirs
NEVER, EVER set this to "/tmp" or "/". Setting it to "/tmp" will change
/tmp's permission to 700 (definitely no good) and setting it to "/" one will
erase all of your files by means of a `rm -rf /*`. You have been warned!
- `DOC_DIR`: Where to place the installed document files
- `ARCHITECTURE`: Default target architecture for the package (Default: empty)
If your rpm program is configured to build packages for i686 instead of i386
(for example) then you'll find this handy to avoid the need to tell
checkinstall your architecture type every time it is run. The default is
auto-detect.
- `INSTYPE`: What kind of packages are we building? (Default: empty)
Set it to "S" for Slackware's .tgz, "R" for RedHat and friends' .rpm, "D"
for Debian and leave it empty to have checkinstall ask you every time.
- `RPM_FLAGS`: RPM install command optional flags
- `DPKG_FLAGS`: dpkg install command optional flags
- `PAK_DIR`: Package storage directory
If non-empty, all the created packages will be saved in this directory. In
this way you can keep all of your packages in one place.
- `CKUMASK`: Set the umask to this value (Default: 0022)
- `SHOW_INSTALL`: Boolean (0 or 1) (Default: 1)
Show -or not- the results of the install command as it runs. Useful for
interactive install commands.
- `SHOW_SLACK_INSTALL`: Boolean (0 or 1) (Default: 0)
Show -or not- the results of the Slackware's installpkg command as it runs.
As the option above, this can be useful for interactive install scripts.
- `DEL_DOCPAK`: Boolean (Default: 1). Delete -or not- the "doc-pak" directory
upon program's termination.
- `DEL_SPEC`: Boolean (Default: 1). Delete -or not- the .spec file upon
termination.
- `DEL_DESC`: Boolean (Default: 1). Delete -or not- the "description-pak"
file.
- `STRIP_ELF`: Boolean (Default: 1). Strip -or not- any ELF binaries found
inside the package.
- `STRIP_SO_ELF`: Boolean (Default: 0). Automatically strip all ELF shared
libraries? Note: this setting will automatically be set to "0" if
`STRIP_ELF=0`
- `ADD_SO`: Boolean (Default: 0). Automatically search for shared libraries
and add them to /etc/ld.so.conf?
- `COMPRESS_MAN`: Boolean (Default: 1). Automatically compress all man pages?
- `BACKUP`: Boolean (Default: 1). Backup -or not- any pre-existent files that
would be overwritten by the package installation.
- `AUTODOINST`: Boolean (Default: 1). Write a doinst.sh script wich will be
executed everytime you install the package with installpkg.
- `NEW_SLACK`: Boolean (Default: 1). Use the new (8.1+) Slackware description
file format?
- `EXCLUDE`: Comma delimited list of files/directories to be ignored when
searching for files to be included in the package.
Example: `EXCLUDE="/dev,/tmp,bad_file,bad_dir"`
- `CK_INCLUDE_FILE`: Path to a file. This file should contain a list of files
and directories that will be included in the package in addition to the ones
installed by your installation command. The files or directories should be
listed one per line.
Example: `INCLUDE="/home/include-list.txt"`
- `ACCEPT_DEFAULT`: Boolean (Default: 0). Accept default values for all
questions?
- `CK_INSPECT`: Boolean. Enable inspection of the list of files that will be
included in the package, before the package is created.
- `REVIEW_SPEC`: Boolean. Enable review of the .spec file before the creation
of a RPM package.
- `REVIEW_CONTROL`: Boolean. Enable review of the Debian control file before
the creation of a Debian package.
- `INSTALL`: Boolean. Install or not the package as we create it.
### 3.2 Command line options
Starting at version 1.4.0, checkinstall supports a lot of command line
switches, which if specified will override the options set in the
checkinstallrc file. The command line options are these:
Usage: checkinstall [options] [command [command arguments]]
Options:
*Package type selection*
-t,--type= Choose packaging system
-S Build a Slackware package
-R Build a RPM package
-D Build a Debian package
*Install options*
--install= Toggle created package installation
--fstrans= Enable/disable the filesystem translation code
*Scripting options*
-y, --default Accept default answers to all questions
--pkgname= Set name
--pkgversion= Set version
-A, --arch, --pkgarch= Set architecture
--pkgrelease= Set release
--pkglicense= Set license
--pkggroup= Set software group
--pkgsource= Set source location
--pkgaltsource= Set alternate source location
--pakdir= The new package will be saved here
--maintainer= The package maintainer (.deb)
--provides= Features provided by this package (.rpm)
--requires= Features required by this package (.rpm)
--rpmflags= Pass this flags to the rpm installer
--rpmi Use the -i flag for rpm when installing a .rpm
--rpmu Use the -U flag for rpm when installing a .rpm
--dpkgflags= Pass this flags to the dpkg installer
--spec= .spec file location
--nodoc Do not include documentacion files
*Info display options*
-d<0|1|2> Set debug level
-si Run an interactive install command
--showinstall= Toggle interactive install command
-ss Run an interactive Slackware installation script
--showslack= Toggle interactive Slackware installation script
*Package tuning options*
--autodoinst= Toggle the creation of a doinst.sh script
--strip= Strip any ELF binaries found inside the package
--stripso= Strip any ELF binary libraries (.so files)
--addso= Search for any shared libs and add
them to /etc/ld.so.conf
--reset-uids= Reset perms for all files/dirs to 755 aand
the owner/group for all dirs to root.root
--gzman= Compress any man pages found inside the package
--docdir= Where to put documentation files
--umask= Set the umask value
--exclude= Exclude these files/directories from the package
--include= Force the inclusion in the package of the
files/dirs listed in "listfile"
--inspect Inspect the package's file list
--review-spec Review the spec file before creating a .rpm
--review-control Review the control file before creating a .deb
--newslack Use the new (8.1+) Slackware description format
("--newslack" implies "-S")
--with-tar=/path/to/tar Manually set the path to the tar binary
in this system
*Cleanup options*
--deldoc= Delete doc-pak upon termination
--deldesc= Delete description-pak upon termination
--delspec= Delete spec file upon termination
--bk Backup any overwritten files
--backup= Toggle backup
*About CheckInstall*
--help, -h Show this message
--copyright Show Copyright information
--version Show version information
### 3.3 Native language support
Checkinstall now uses GNU gettext to support native language translation of
all messages sent to the terminal. Set your `LC_ALL` variable to your ISO-639
language and ISO-3166 country codes. For example, to set spanish and Mexico
you would use:
export LC_ALL=es_MX
Translators needed! Please read the file NLS_SUPPORT for information on how to
translate checkinstall if your language is not already supported.
The supported languages so far are:
- English
- Spanish
## 4. Notes
So far I've seen -or heard of- checkinstall running and building packages in
these distributions/operating systems:
- Slackware 7.x/8.x,9.x
- RedHat 6.2/7.x/8.x
- SuSe 7.x/8.x/9.x
- Mandrake 7.x/8.x/9.x
- Gentoo Linux
- Solaris (version?)
- Debian 2.x/3.0
In x86, ppc, sparc and arm, BTW.
If you have succesfully used checkinstall in some other distro I'd really
appreciate if you let me know =).
CheckInstall currently is unable to track any file system changes made by
statically linked programs. This is being worked on and I hope to have it
ready in a couple of weeks or so. Then again, it could be a couple of months,
but the important thing is that it will be ready soon ;).
NOTE ON SUID/SGID PROGRAMS: CheckInstall can't track their actions because of
some limitations in the LD_PRELOAD system that installwatch uses. This is good
for security reasons, but it can generate unexpected results when the
installation process uses SUID/SGID binaries.
So, before asking questions about some files not being included in your
package, check the binaries that you're using ;-).
SLACKWARE 8.0 USERS: Slack8.0 ships with a statically linked `ln`, so any
symlinks your installation process creates WON'T be detected nor included in
your package. The way to fix this is to substitute your static `ln` for a
dynamically linked one, like the one from a Slackware 7.x installation.
There's link to download it from the CheckInstall's homepage.
Debian support is now included!
UPDATE jan-18-2001: RPM support is already in place, inst2rpm supplied the
template for the mini-spec file used by checkinstall. Thanks to Jon A.
Christopher for writing it.
Another thing in the works is the addition of a friendlier interface based on
the dialog tool (which will give us curses-like character based menus AND X11
graphical menus at no extra cost =) )
There are some extra features planned like package updating, automated
friendly installation process going from extracting the files to the
installation including configure options, build, etc.
Sometime in the future I will rewrite this in C/Gtk or something, too.
Ideas, bug reports, patches: https://github.com/ssgelm/checkinstall
Upstream's own addresses follow, from before development stopped in 2017.
They may no longer be read.
- CheckInstall author: \
- CheckInstall users list: \
To join the list, send an empty message to:
\
- CheckInstall developers list: \
To join the list, send an empty message to:
\
ssgelm-checkinstall-59a004a/RELNOTES 0000664 0000000 0000000 00000036147 15235417303 0017167 0 ustar 00root root 0000000 0000000 Checkinstall 1.7.0
======================================
The first release since 2010, and the first from the fork at
https://github.com/ssgelm/checkinstall. It carries the patches Debian had
accumulated over the years, together with fixes for bugs reported against
Debian and Ubuntu.
* Filesystem translation works again. glibc 2.33 turned stat() and its
relatives into ordinary exported functions, so a library defining only
__xstat() stopped seeing most of what an install did, and every tool that
checks a path before acting on it was told the file was not there. statx(),
the fortified open() variants, the mkstemp family, linkat(), openat64(),
utimensat() and the 64-bit time entry points are all intercepted now.
* A failed or interrupted install can no longer replace /lib with a real
directory, which left a merged-/usr system unable to run a single binary.
* A mode set on a symlink no longer reaches the file it points at. A binary
installed 755 could come out of the package writable by anyone.
* Built packages record the shared libraries they need, with --autodeps.
They also record files under their real parent directories, so an install
writing to /lib/systemd/system ships /usr/lib/systemd/system.
* Values given on the command line are used as written rather than being
re-evaluated by the shell, so --maintainer="Jane Doe "
reaches the package intact.
* Names containing spaces survive the file list.
* New options: --autodeps for shared library dependencies, --debcompression
to choose what dpkg-deb packs a .deb with, and --prerequires for Debian
Pre-Depends.
* Builds on hppa and alpha, and on 32-bit architectures using 64-bit time or
large file offsets. Honours CPPFLAGS, CFLAGS and LDFLAGS. Installing no
longer needs root.
* Added a French translation, and regenerated the message template, which
dated from 2002 and was missing 44 of the strings the program prints.
* Added a test suite under tests/.
Checkinstall 1.6.2
* Added support for at-style functions
Checkinstall 1.6.1
======================================
* Fixed the famous getcwd() bug (Thanks to David Brown for hunting it down!)
* Added translations:
Indonesian - Tedi Heriyanto
Italian - Michele Petrecca
Norwegian - cizu jones
German - Andreas Muck
Chinese - Xinkui Hao
Japanese - UTUMI Hirosi
CheckInstall 1.6.0beta4
======================================
* This should be the last beta before releasing version 1.6.0. Please report
any outstanding bugs!
* Fixed the bug in installwatch that caused segfaults when running on newer
glibc versions (And therefore newer distros like FC and SuSe 9.1).
* The default for ADD_SO is now NO so we are no longer auto-updating
/etc/ld.so.conf by default. If you need this behavior you can enable it
with "--addso=yes" or by setting ADD_SO=1 in checkinstallrc.
* We use the new Slackware package format by default ( NEW_SLACK=1 ) when
creating Slackware packages. Note that in previous versions of checkinstall
up to 1.6.0beta3 the default was the old package format.
* There are other smaller bugfixes. Read the Changelog file for details.
* New checkinstallrc options:
o MAKEPKG_FLAGS: makepkg optional flags.
These are recommended if running a newer Slackware version: "-l y -c n"
o SHOW_MAKEPKG: Boolean (Default: 0)
Show -or not- the results of the MAKEPKG command as it runs. Useful when
running it with interactive options. If checkinstall seems to halt and
sleep after saying "Building Slackware package..." then you might want to
set this to 1.
o ADD_SO: Boolean (Default: 0)
Automatically search for shared libraries and add them to /etc/ld.so.conf?
CheckInstall 1.6.0beta3
======================================
* Internationalization support has been enhanced (And severely modified).
Many new languages have been added, too.
* Added a command line option: "--fstrans". It will allow you to enable
or disable the filesystem translation code. It is enabled by default.
* Added a command line option: "--reset-uids". It will allow you to sanitize
the file and directories permissions in the package. It will cause
checkinstall to set the permissions of all files and directories to "755"
and the owner and group of all directories to root.root. DO NOT USE IT IF
YOUR PACKAGE USES CUSTOM PERMISSIONS OR OWNERS.
* The problem many people had when copying the documentation files should
now be fixed.
* The package information menu was moved to the first stages of the
script. Now you can modify the package's name or version and the
documentation directory will be correctly named.
* You can recycle a previously written .spec file, with the "--spec" command
line option. It will work to set some package parameters even if you are
building a Slackware or Debian package.
* CheckInstall will try to add to /etc/ld.so.conf the path to any ELF shared
libraries it finds, and run ldconfig afterwards. This is added to the
postinstall script of your package.
CheckInstall 1.6.0beta2
======================================
* Checkinstall 1.6.0 now sports brand-new internationalization support :-).
The supported languages so far are English and Spanish. Translators needed!
If you want to contribute by translating Checkinstall to your language,
please read the NLS_SUPPORT file for instructions on how to do it. It's very
easy actually.
* Support for Slackware's tar-1.13 binary is included, the Slackware packages
created by checkinstall should now be more Slackware-compatible than before.
* You can tell Checkinstall to use Slackware's native "makepkg" by setting
the MAKEPKG variable to "makepkg" in checkinstallrc.
* Symlinks are now correctly detected again.
See more details in the ChangeLog.
CheckInstall 1.6.0beta1
======================================
* The "--install=" command line option indicates wether you want
to actually install the package on your system or just create it
without installing it. This is a new feature and still in beta stage.
Please test it and report any bugs you find (Or success, too! :-) )
* In this release support for preinstall, postinstall, preremove and postremove
scripts is introduced for RPM and Debian packages.
For Debian, these scripts must meet some requirements to be accepted by dpkg
while building the .deb package. See:
http://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
In short, any shell script will do as long as it specifies an interpreter
(i.e. put #!/bin/sh as the first line) and has an exit status of zero for
success or non-zero for failure.
To include the scripts in your package, put them in the current directory
and name them:
preinstall-pak
postinstall-pak
preremove-pak
postremove-pak
All scripts are optional. You can write all of them if you need them, or
only the ones you need, or even none.
For Slackware packages, the "postinstall-pak" script is already supported as
"install-pak". Either name will work.
* This release also adds other three command line options: "--inspect",
"--review-spec" and "--review-control". See the ChangeLog file for
details.
CheckInstall 1.5.3
======================================
* The user's umask is ignored while creating/installing the package. If you
really want to have the umask set to something unusual while checkinstall
creates the package, you can use the "--umask" command line option.
The default umask used by checkinstall is "0022" which is a standard,
non-paranoid reasonable value.
* This version introduces support for the new Slackware description file format,
whit handy-rule and all. Use the "--newslack" command line switch to activate
it. The use of "--newslack" implies "-S", that is, it automatically selects
the creation of a Slackware package.
CheckInstall 1.5.2
======================================
* This version introduces automatic man pages compression, enabled by default.
You can control this option with the "--gzman" flag.
* The .deb packages created by checkinstall 1.5.2 should be a bit more
Debian-friendly.
* There's a new shared library stripping feature in CheckInstall. Please test
it and report any trouble you might run into.
CheckInstall 1.5.1
======================================
* There's a new checkinstall mailing list! The list address is:
To subscribe, send an empty message to:
* A new installwatch version is included, with some patches from Olivier
Fleurigeon. The test program included with installwatch now works again.
* New command line options: "--docdir" and "--nodoc" to control the creation
of the package documentation.
* New command line options: "--provides" and "--maintainer" to specify each
value in the RPM spec file and in the Debian control file, respectively.
CheckInstall 1.5.0
======================================
* CheckInstall is now even more "scriptable", look for the "--pkgxxx" options
in the README.
* The installwatch version (0.6.2) included with this release of checkinstall
fixes a couple of file descriptor leaks that were present in 0.6.1. The
"Too many open files" problem shouldn't appear again. I can no longer
reproduce it with the Emacs21 installation, at least ;-).
* Checkinstall is one year old! Version 1.0 was released on nov/11/200 =)
CheckInstall 1.5.0beta2:
======================================
* About the "invalid option" problem with rpm: the RPM folks have once again
changed their minds about the rpm's argument parsing. In rpm versions < 4.0.0
the right way was "--target ", in 4.0.x with x < 3, it was
"--target=" and finally in rpm 4.0.x with x >= 3 it is back to
"--target ". CheckInstall now attempts to identify the installed rpm
version and set this flag accordingly. If you have any problems about it,
please send me a mail message telling me the error message and the rpm version
you have installed.
* Check the new PAK_DIR variable in the checkinstallrc file. If set to a
directory name, checkinstall will save there your newly created packages
If the directory doesn't exist, checkinstall will ask you if it should be
created. This should help you to keep all your new packages in one place.
* CheckInstall is now completely "scriptable"! If you give it the "-y"
command line option it will run completely unattended, accepting the
default answer to all questions.
CheckInstall 1.5.0beta1:
======================================
* Debian support is in place! Read the Debian packaging section of the
README file. This is an experimental feature. Please report any bugs or
problems so they can be fixed :).
CheckInstall 1.4.0:
======================================
A long time has passed since the last checkinstall release, thanks to my
final exams and an unusually big load of work. Now I have more free time and
will be working hard to add two important features: tracking of statically
linked binaries and .deb packaging format support. Stay tuned :).
* I modified the installwatch library to make it backup any files modified
by the install command, _before_ they are modified. This is done at the
system call level.
This allows checkinstall to write a tarball including all files that
were overwritten/deleted/etc by the install command -i.e "make install"-,
giving you the chance to return your system to the exact same state it was
before installing your program.
An example: suppose you have installed AfterStep, which by default keeps its
global configuration files under /usr/local/share/afterstep,and you have
customized them to meet your own tastes. Then you download and compile a new
version, and then you install it with "make install" or with "checkinstall".
You restart your afterstep session only to discover that all of your
carefully configured files under /usr/local/share/afterstep have been
overwritten by the installation process and substituted by the standard
dist versions! Well.. that was until the arrival of CheckInstall 1.4 ;-)
CheckInstall 1.4.0 would have saved all of those about-to-be-overwritten
files just before they were modified, and wrote a tarball containing all
of them. So in the example before, you'd just do a:
tar xzvf backup-xxxxx-pre-afterstep-v.v.v.tgz -C /
And you'd get your files back. Nice, isn't it?
Another nice thing is that if you cancel checkinstall at any time, it will
automatically restore any already modified/overwritten files.
The xxxxx in the filename are a timestamp made with the date and time when
the file was created, so you can run checkinstall multiple times and you'll
get incremental-style backups of the modified files.
The new installwatch library (0.6.0) has a lot of applications, I'll talk
about them in installwatch's own documentation.
* CheckInstall now has full command line switches parsing.
Try "checkinstall --help".
* The variable definition section inside the checkinstall script is gone.
Now you should edit the checkinstallrc file, normally installed under
/usr/local/lib/checkinstall
* Added an option ("--exclude") to tell checkinstall wich directories to ignore
while searchig for modified files.
CheckInstall 1.3.2:
======================================
* Security fix for the temp dir, preventing symlink attacks.
* File names with spaces in them are now correctly handled.
CheckInstall 1.3.1:
======================================
* Fix for a bug found when using rpm 4.0, and new features.
* Slackware: If you create a script called "install-pak" inside the source
directory, checkinstall will add it to the new package. The script will
be run every time you install the package with Slackware's installpkg.
This is useful for setting permissions, adding users and setting the system
up after installing that package.
CheckInstall 1.3.0:
======================================
Lots of bug fixes and a couple of changes. Read the Changelog and the README.
CheckInstall 1.3.0beta3:
======================================
The bug that prevented checkinstall from working on your rpm-based distribution
has been fixed -seems fixed, at least!-
So far I've tested v1.3.0beta3 in:
o RedHat 6.2
o Slackware 7.1
RedHat 7.x, SuSe and Mandrake should be OK but I haven't confirmed it. Maybe you
could do that and write me a note to include them on the list ;-).
I've added a DEBUG flag to allow checkinstall to gather some useful info and
pack it in a tarball. Check the variable definition section inside the script.
CheckInstall 1.3.0beta :
======================================
RPM support is now included. See the bottom of the README for details.
This is a beta release, please report bugs and post comments to:
CheckInstall 1.2.1 :
======================================
Because of a couple of bugs introduced by checkinstall 1.2, you may have to
check the owner and permissions of /tmp and /var/checkinstalltmp :
/tmp ==> 1777/root:root
/var/checkinstalltmp ==> 0700/root:root
Just to make sure, run:
chmod 1777 /tmp
rm -rf /var/checkinstalltmp
mkdir /var/checkinstalltmp
chmod 0700 /var/checkinstalltmp
ssgelm-checkinstall-59a004a/TODO 0000664 0000000 0000000 00000000761 15235417303 0016472 0 ustar 00root root 0000000 0000000 =========
TODO list
=========
o man page
o Add a dialog interface
o Extend functionality to allow for automatic software extraction,
configuration and compilation
o Rewrite in C/Gtk
o Give the user a choice to select which /dev/???? files should be allowed in
the package. The script currently just throws them all away.
o Cryptographic signing of created packages
o SRPM creation
o Version 2.0.0
o Suggestions?
ssgelm-checkinstall-59a004a/checkinstall-man.sgml 0000664 0000000 0000000 00000035170 15235417303 0022105 0 ustar 00root root 0000000 0000000
Felipe">
Sateler">
November 13, 2007">
8">
fsateler@gmail.com">
CheckInstall">
Debian">
GNU">
GPL">
]>
&dhemail;
&dhfirstname;
&dhsurname;
2006&dhusername;
&dhdate;
&dhucpackage;
&dhsection;
&dhpackage;
Track installation of local software, and produce a binary manageable
with your package management software.
&dhpackage;optionsinstall commandDESCRIPTION&dhpackage; is a program that monitors an installation
procedure (such as make install, install.sh
), and creates a standard package for your distribution
(currently deb, rpm and tgz packages are supported) that you can install
through your distribution's package management system (dpkg, rpm or
installpkg).
Note that for most useful actions, &dhpackage; must
be run as root.
OPTIONSThese programs follow the usual &gnu; command line syntax,
with long options starting with two dashes ('-'). A summary of
options is included below.All the options that toggle a switch default to activate the option.
To force activation or deactivation, call them with '=yes' or '=no'. As
an example, to disable stripping use --strip=no.Show summary of options.Show version information.Show Copyright informationChoose packaging system. Can be one of 'slackware', 'debian'
or 'rpm'.Create a Debian package.Create a RPM package.Create a Slackware Package.Toggle installation of the created package.Enable/disable filesystem translation. Filesystem translation
enabled causes the install to proceed in a temporary directory, thus
not actually touching your system.Accept default answers to all questions.Set the package name.Set package version.Set package architecture.Set the package release.Set package license.Set the package group.Set source locationSet alternate source locationWhere to save the new package.Set the package maintainer, for example
="Jane Doe
<jane@example.org>". The value is used as
given, with no shell expansion.Features provided by this package (currently only on RPM and Deb).Dependencies required by this package.Dependencies that must be installed and configured before this package.Pass this flags to the rpm installer.Use the -i flag when installing a rpm.Use the -U flag when installing a rpm.Pass this flags to the dpkg installerWhere the .spec file is locatedDo not include documentation files.Set debug level. Must be one of 0, 1 and 2.Run an interactive install commandToggle interactive install command.Run an interactive Slackware installation script.Toggle interactive Slackware installation script.Toggle creation of a doinst.sh script.Toggle stripping any ELF binaries found inside the package.Toggle stripping any ELF libraries (.so) found inside the package.Work out the shared library dependencies of the
installed binaries with dpkg-shlibdeps and record them in the
package, as a normally packaged program would. Debian packages
only. On by default.Compression to use when building a Debian package:
gzip, xz, zstd or none. Leave it unset and dpkg-deb chooses.
On a large package gzip and zstd finish much faster than xz,
and produce a bigger file.Search for any shared libs and add them to /etc/ld.so.confReset perms for all files/dirs to 755 and the owner/group for all dirs to root.rootCompress any man pages found inside the package.Where to put documentation files.Set the umask value.Exclude these files/directories from the package.Force the inclusion in the package of the files/dirs listed in the argument (a file).Inspect the package's file listReview the spec file before creating a .rpm.Review the control file before creating a .deb.Use the new (8.1+) Slackware description format ("--newslack" implies "-S")Manually set the path to the tar binary.Toggle deletion of doc-pak upon termination.Toggle deletion of description-pak upon termination.Toggle deletion of spec file upon termination.Backup any overwritten filesToggle backupFILESThis program reads its configuration from /etc/checkinstallrc, which can be used to override defaults.
Command line arguments override settings in the configuration file.
AUTHORThis manual page was written by &dhusername; <&dhemail> for
the &debian; system (but may be used by others). Permission is
granted to copy, distribute and/or modify this document under
the terms of the &gnu; General Public License, Version 2.
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
ssgelm-checkinstall-59a004a/checkinstall.in 0000775 0000000 0000000 00000261654 15235417303 0021013 0 ustar 00root root 0000000 0000000 #!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
##############################################################################
# ########################
#
#
# CheckInstall v1.7.0
#
# Installs a compiled program from the program's source directory using
# "make install" or any other command supplied on checkinstall's command
# line. checkinstall will create a Slackware, RPM or Debian compatible package
# named after the source directory's name and install it using your standard
# package administration utilities.
#
# This version of checkinstall needs enough free space on the partition
# holding the temp dir (see BASE_TEMP_DIR below) to write there a temporary
# copy of the package.
#
# Copyright (C) 2010 Felipe Eduardo Sanchez Diaz Duran
# Copyright (C) 2026 Stephen Gelman
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the version 2 of the GNU General Public License
# as published by the Free Software Foundation
#
# 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 .
#
############################################################################
# Trap the INT signal (ctrl-c, for example)
trap trapint 2
CHECKINSTALL_VERSION=1.7.0
# locate the file or directory that the parameter corresponds to;
# always prints absolute path
function followlinks () {
local entry="$1"
local symlink
case "$entry" in /*) true ;;
*) entry="`pwd`/$entry";;
esac
if [ -L "$entry" ]; then
symlink=`ls -l "$entry" | sed -e 's/.* -> //'`
case "$symlink" in /*) entry="$symlink";;
*) entry=`dirname "$entry"`/$symlink;;
esac
followlinks "$entry"
else
echo "$entry"
fi
}
INSTALLDIR=MAKEFILE_PREFIX
# gettext variables
export TEXTDOMAINDIR="$INSTALLDIR"/lib/checkinstall/locale
export TEXTDOMAIN=checkinstall
# .spec file path
DIRECTORIO_FUENTE=`pwd`
PKG_BASENAME="`basename "$DIRECTORIO_FUENTE"`"
SPEC_PATH=${PKG_BASENAME}.spec
#############################################################################
# Function definitions #
########################
# Enable alias expansion in command substitution
shopt -s expand_aliases
# Vefify that we have gettext available
gettext "Bye." &> /dev/null
if [ $? -gt 0 ]; then
alias ck_gettext="echo -e"
else
alias ck_gettext="gettext -s --"
fi
## gettext echo with newline at the end
function echog() {
local format="$1"
shift
printf -- "$(ck_gettext "$format")\n" "$@" >&2
}
## gettext echo with NO newline at the end
function echogn() {
local format="$1"
shift
printf -- "$(ck_gettext "$format")" "$@" >&2
}
function ckversion {
echo
echo "checkinstall $CHECKINSTALL_VERSION, Copyright 2010 Felipe Eduardo Sanchez Diaz Duran"
echog " This software is released under the GNU GPL."
}
function usage() {
# If the user has a default pager defined in the PAGER environment variable,
# we'll use that. If not, we'll use "more".
! [ "$PAGER" ] && PAGER=more
echo
echog "Usage: checkinstall [options] [command [command arguments]]"
echog "Options:"
echo
echog "*Package type selection*"
echo
echog "-t,--type= Choose packaging system"
echog "-S Build a Slackware package"
echog "-R Build a RPM package"
echog "-D Build a Debian package"
echo
echog "*Install options*"
echo
echog "--install= Toggle created package installation"
echog "--fstrans= Enable/disable the filesystem translation code"
echo
echog "*Scripting options*"
echo
echog "-y, --default Accept default answers to all questions"
echog "--pkgname= Set name"
echog "--pkgversion= Set version"
echog "-A, --arch, --pkgarch= Set architecture"
echog "--pkgrelease= Set release"
echog "--pkglicense= Set license"
echog "--pkggroup= Set software group"
echog "--pkgsource= Set source location"
echog "--pkgaltsource= Set alternate source location"
echog "--pakdir= The new package will be saved here"
echog "--maintainer= The package maintainer (.deb)"
echog "--provides= Features provided by this package"
echog "--requires= Features required by this package"
echog "--prerequires= Packages that must be installed and configured before this package"
echog "--recommends= Features recommended by this package"
echog "--suggests= Features suggested by this package"
echog "--conflicts= Packages that this package cannot be installed with (.deb)"
echog "--replaces= Packages that this package replaces (.deb)"
echog "--rpmflags= Pass this flags to the rpm installer"
echog "--rpmi Use the -i flag for rpm when installing a .rpm"
echog "--rpmu Use the -U flag for rpm when installing a .rpm"
echog "--dpkgflags= Pass this flags to the dpkg installer"
echog "--spec= .spec file location"
echog "--nodoc Do not include documentation files"
echo
echog "*Info display options*"
echo
echog "-d<0|1|2> Set debug level"
echog "-si Run an interactive install command"
echog "--showinstall= Toggle interactive install command"
echog "-ss Run an interactive Slackware installation script"
echog "--showslack= Toggle interactive Slackware installation script"
echo
echog "*Package tuning options*"
echo
echog "--autodoinst= Toggle the creation of a doinst.sh script"
echog "--strip= Strip any ELF binaries found inside the package"
echog "--stripso= Strip any ELF binary libraries (.so files)"
echog "--autodeps= Work out the shared library dependencies of\n the installed binaries with dpkg-shlibdeps"
echog "--debcompression= Compression for the .deb: gzip, xz, zstd or\n none. Leave it unset and dpkg-deb chooses"
echog "--addso= Search for any shared libs and add"
echog " them to /etc/ld.so.conf"
echog "--reset-uids= Reset perms for all files to o=g, dirs to 755 and"
echog " the owner/group for all dirs to root.root"
echog "--gzman= Compress any man pages found inside the package"
echog "--docdir= Where to put documentation files"
echog " The package name+version gets automatically appended."
echog " To avoid that prefix the path with a colon (:)."
echog "--umask= Set the umask value"
echog "--exclude= Exclude these files/directories from the package"
echog "--include= Force the inclusion in the package of the"
echog " files/dirs listed in \"listfile\""
echog "--inspect Inspect the package's file list"
echog "--review-spec Review the spec file before creating a .rpm"
echog "--review-control Review the control file before creating a .deb"
echog "--newslack Use the new (8.1+) Slackware description format"
echog " (\"--newslack\" implies \"-S\")"
echog "--with-tar=/path/to/tar Manually set the path to the tar binary"
echog " in this system"
echo
echog "*Cleanup options*"
echo
echog "--deldoc= Delete doc-pak upon termination"
echog "--deldesc= Delete description-pak upon termination"
echog "--delspec= Delete spec file upon termination"
echog "--bk Backup any overwritten files"
echog "--backup= Toggle backup"
echo
echog "*About CheckInstall*"
echo
echog "--help, -h Show this message"
echog "--copyright Show Copyright information"
echog "--version Show version information"
echo
exit 1
}
function help_notice() {
echo
echog "Use --help or -h to get more information"
echo
exit 1
}
function boolean_usage() {
echo
echog "%s is an invalid value for %s" "$2" "$1"
help_notice
exit 1
}
# 001117-BaP: Define a function or two
function yorn {
if [ "$1" ]; then # If there is no default value specified
DEFAULTYN="$1" # then the default is "y"
else
DEFAULTYN="y"
fi
DEFAULTYN=`echo $DEFAULTYN | tr 'A-Z' 'a-z'`
if [ "$DEFAULTYN" = "y" ]; then
echo -n " [y]: " # Print the default option
else
echo -n " [n]: "
fi
if [ $ACCEPT_DEFAULT -eq 0 ]; then # Should we accept all the defaults?
read YN
YN=`echo $YN | tr 'A-Z' 'a-z'`
! [ "$YN" ] && YN=$DEFAULTYN # If the user pressed ENTER then
else
YN=$DEFAULTYN
echo $YN
fi
if [ "$YN" = "y" ] ;then # We return something useful for a
return 0 # simpler sintax ahead (12/dic/2000-Izto)
else
return 1
fi
}
# dec/10/2000-Izto
# Prints OK or FAILED! depending on previous command return value
function okfail () {
if [ $? -gt 0 ]; then
echog ' FAILED!'
return 1
else
echog 'OK'
return 0
fi
}
function restore_backup {
# If we have translation turned on then we didn't do a backup
if [ "${TRANSLATE}" = "1" ]; then return 0; fi
# Else, restore the backup if it exists
rm -rf ${TMP_DIR}/BACKUP/no-backup &> /dev/null
ls ${TMP_DIR}/BACKUP/* &> /dev/null
if [ $? -eq 0 ]; then
echogn "Restoring overwritten files from backup..."
cd ${TMP_DIR}/BACKUP
files=$(ls -A)
$TAR -cpf - $files | $TAR $TAR_KEEPSYMLINK -f - -xvpC / &> /dev/null
okfail
echo
fi
}
function trapint {
echo
echo
echog "*** SIGINT received ***"
cleanup
}
function cleanup {
echo
restore_backup
echogn "Cleaning up..."
cd "$DIRECTORIO_FUENTE"
[ -n "${BUILDROOT}" ] && [ -d ${BUILDROOT} ] && rm -rf "${BUILDROOT}"
if [ "$DEBUG" -eq 0 ]; then
[ -n "${TMP_DIR}" ] && [ -d ${TMP_DIR} ] && rm -rf ${TMP_DIR}
rm -f checkinstall-debug*
else
echogn "(Debugging mode on, KEEPING temp dir $TMP_DIR)..."
fi
[ -n "${RPMSOURCEDIR}" ] &&
[ -f "${RPMSOURCEDIR}/SOURCES/${PKG_BASENAME}.tgz" ] &&
rm -f "${RPMSOURCEDIR}/SOURCES/${PKG_BASENAME}.tgz"
# If we had a pre-existing postinstall-pak, we keep it as it was.
if [ -f "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" ]; then
mv "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" "${DIRECTORIO_FUENTE}/postinstall-pak"
fi
true; okfail
echo
echog "Bye."
echo
exit 1
}
# Function to copy a directory with permissions, honours setuid, setgid,
# sticky bits, owner, group etc.
#
# A bit lengthy and slow but very few directories in the largest of
# packages have to be copied like this.
function dircopy() {
src_dir="$1" dest_dir="$2"
getflags() {
col=$1 dir="$2"
permissions="`ls -ld "$dir" | awk '{print $1}'`"
mask="."
bit=2
while [ $bit -lt $col ]; do mask="$mask."; bit=`expr $bit + 1`; done
mask="$mask\(.\)"
bit=$col
while [ $bit -lt 10 ]; do mask="$mask."; bit=`expr $bit + 1`; done
permission="`echo $permissions | sed "s/$mask/\1/" | grep -v -- '-'`"
case "$permission" in
s) echo "xs";; S) echo "s";; t) echo "xt";; T) echo "t";;
*) echo $permission;;
esac
}
col=2 chmod_args=""
set=u flags=""
while [ $col -le 4 ]; do
flags="$flags`getflags $col "$src_dir"`"; col=`expr $col + 1`
done
[ -n "$flags" ] && {
chmod_args="$set+$flags"
}
set=g flags=""
while [ $col -le 7 ]; do
flags="$flags`getflags $col "$src_dir"`"; col=`expr $col + 1`
done
[ -n "$flags" ] && {
[ -n "$chmod_args" ] && chmod_args="$chmod_args,"
chmod_args="$chmod_args$set+$flags"
}
set=o flags=""
while [ $col -le 10 ]; do
flags="$flags`getflags $col "$src_dir"`"; col=`expr $col + 1`
done
[ -n "$flags" ] && {
[ -n "$chmod_args" ] && chmod_args="$chmod_args,"
chmod_args="$chmod_args$set+$flags"
}
[ -d "$dest_dir" ] || {
mkdir -p "$dest_dir"
chmod 700 "$dest_dir"
}
[ -n "$chmod_args" ] && chmod $chmod_args "$dest_dir"
chown "`ls -ld "$src_dir" | awk '{print $3}'`" "$dest_dir"
chgrp "`ls -ld "$src_dir" | awk '{print $4}'`" "$dest_dir"
}
#
# Read spec file if it exists or (pre)set variables if they don't exist
#
function getparameter () {
RES=`egrep "$1" < ${SPEC_PATH} \
| cut -f2 -d: | sed 's/^ *//g' | sed 's/ *$//g' `
shift
while echo "$RES" | egrep -q '(^|[^%])%[a-zA-Z0-9]'; do
VAR=`echo "$RES" | sed 's/\(^\|^.*[^%]\)%\([a-zA-Z0-9]*\).*$/\2/'`
egrep -q "^%define\s+$VAR\s" < ${SPEC_PATH} || break
VAL=`egrep "^%define\s+$VAR\s" < ${SPEC_PATH} \
| awk '{ print $3 }'`
RES=`echo "$RES" | sed 's/\(^\|[^%]\)%'"$VAR/"'\1'"$VAL/g"`
done
echo "$RES" | sed 's/^ *//g' | sed 's/ *$//g'
}
# This function is used to properly escape shell commands, so
# we don't interpret the install command twice. This is useful
# for making commands like 'make CC="gcc -some -options" install'
# work as expected.
function shell_escape() {
for str in "$@" ; do
echo -n "\"$str\" "
done;
echo
}
# Output all the parents of the files given as arguments to stdout. Remove
# duplicates.
function list_parents {
# One path in, one parent per line out. Anything space separated here
# loses paths that contain a space.
printf '%s\n' "$1" | awk '
BEGIN{
FS = "/"
}
{
for (i=1;i
This program is free software; you can redistribute it and/or modify
it under the terms of the version 2 of the GNU General Public License
as published by the Free Software Foundation.
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 .
EOF
exit 0;;
--autodoinst)
shift
case "$1" in
1|yes|'')
AUTODOINST=1;;
0|no)
AUTODOINST=0;;
*)
boolean_usage "--autodoinst" $1
esac
;;
--reset-uids)
shift
case "$1" in
1|yes|'')
RESET_UIDS=1;;
0|no)
RESET_UIDS=0;;
*)
boolean_usage "--reset-uids" $1
esac
;;
--fstrans)
shift
case "$1" in
1|yes|'')
TRANSLATE=1;;
0|no)
TRANSLATE=0;;
*)
boolean_usage "--fstrans" $1
esac
;;
--exclude)
shift
EXCLUDE="$1"
;;
--include)
shift
CK_INCLUDE_FILE="$1"
;;
esac
shift
done
# See if we have and install command
shift
[ "$1" = "" ] && set -- make install
# End of argument parsing
#############################################################################
# We initialize some useful variables #
#######################################
################################################################
# User-configurable variables were moved to the checkinstallrc #
# file which is probably found at /usr/local/lib/checkinstall #
# #
# DO NOT modify them here!! #
################################################################
# Debug level
! [ "$DEBUG" ] && DEBUG=0
! [ "$INSTALLWATCH_PREFIX" ] && INSTALLWATCH_PREFIX="$INSTALLDIR"
! [ "$INSTALLWATCH" ] && INSTALLWATCH=${INSTALLWATCH_PREFIX}/bin/installwatch
# Which makepkg to use
! [ "$MAKEPKG" ] && MAKEPKG=/sbin/makepkg
# Default MAKEPKG flags
! [ "$MAKEPKG_FLAGS" ] && MAKEPKG_FLAGS="-l y -c n"
# Default architecture type
! [ "$ARCHITECTURE" ] && ARCHITECTURE=""
# Default package type
! [ "$INSTYPE" ] && INSTYPE=""
# Interactively show the results of the install command
# This is useful for interactive installation commands
! [ "$SHOW_INSTALL" ] && SHOW_INSTALL=1
# Show Slackware package installation script while it runs? Again, useful if
# it's an interactive script
! [ "$SHOW_SLACK_INSTALL" ] && SHOW_SLACK_INSTALL=0
# Automatic deletion of "doc-pak" upon termination
! [ "$DEL_DOCPAK" ] && DEL_DOCPAK=1
# Automatic deletion of the spec file
! [ "$DEL_SPEC" ] && DEL_SPEC=1
# Automatic deletion of "description-pak"
! [ "$DEL_DESC" ] && DEL_DESC=1
# Automatically strip all ELF binaries
! [ "$STRIP_ELF" ] && STRIP_ELF=1
# Don't automatically strip all ELF binaries
! [ "$STRIP_SO_ELF" ] && STRIP_SO_ELF=0
# Don't automatically search shared libraries
# nor add them to /etc/ld.so.conf
! [ "$ADD_SO" ] && ADD_SO=0
# Automatically compress all man pages
! [ "$COMPRESS_MAN" ] && COMPRESS_MAN=1
# Backup all files modified by the install command supplied by the user
! [ "$BACKUP" ] && BACKUP=1
# Work out the library dependencies unless told otherwise
! [ "$AUTODEPS" ] && AUTODEPS=1
# Write description installing code to doinst.sh
! [ "$AUTODOINST" ] && AUTODOINST=1
# Are we going to use filesystem translation?
! [ "$TRANSLATE" ] && TRANSLATE=1
# Reset the owner/group of all files to root.root?
! [ "$RESET_UIDS" ] && RESET_UIDS=0
# We won't include anything under this directories
! [ "$EXCLUDE" ] && EXCLUDE=""
# We will include anything listed in this file
! [ "$CK_INCLUDE_FILE" ] && CK_INCLUDE_FILE=""
# Accept the default answer for all the questions
! [ "$ACCEPT_DEFAULT" ] && ACCEPT_DEFAULT=0
# Use the default doc directory of /usr/doc
! [ "$DOC_DIR" ] && DOC_DIR=/usr/doc
# Do not include common documentation
! [ "$NODOC" ] && NODOC=0
# Use "-U" flag in rpm by default when installing a rpm package
# This tells rpm to (U)pdate the package instead of (i)nstalling it.
! [ "$RPM_IU" ] && RPM_IU=U
# Use the new (8.1+) Slackware description format
! [ "$NEW_SLACK" ] && NEW_SLACK=1
# Inspect the file list before creating the package
! [ "$CK_INSPECT" ] && CK_INSPECT=0
# Review the .spec file before creating a .rpm
! [ "$REVIEW_SPEC" ] && REVIEW_SPEC=0
# Review the control file before creating a .deb
! [ "$REVIEW_CONTROL" ] && REVIEW_CONTROL=0
# Set the umask
! [ "$CKUMASK" ] && CKUMASK=0022
# No real installation if not explicitly asked
! [ "$INSTALL" ] && INSTALL=0
# The place where we will be storing the temp files
! [ "$BASE_TMP_DIR" ] && BASE_TMP_DIR=/var/tmp
# Default RPM FLAGS
! [ "$RPM_FLAGS" ] && RPM_FLAGS=" --force --nodeps --replacepkgs "
# Default DPKG FLAGS
! [ "$DPKG_FLAGS" ] && DPKG_FLAGS=""
# Default MAKEPKG FLAGS
! [ "$MAKEPKG_FLAGS" ] && MAKEPKG_FLAGS=""
# Show the makepkg program's output?
! [ "$SHOW_MAKEPKG" ] && SHOW_MAKEPKG=0
####################
# Non-configurable #
####################
# Existing configuration files are always preserved
[ -f description-pak ] && DEL_DESC=0
[ -f SPEC_PATH ] && DEL_SPEC=0
[ -d doc-pak ] && DEL_DOCPAK=0
INSTALLCMD=("$@")
[ -z "${INSTALLCMD[*]}" ] && INSTALLCMD=(make install)
# The editor we use to review the file list and .spec or control file
if ! [ -x "$VISUAL" ]; then
if [ -x "$EDITOR" ]; then
VISUAL=$EDITOR
else
VISUAL=`which vi`
fi
fi
# pkgtools in Slackware 8.1+ don't like the default tar binary and instead
# use "tar-1.13". We'll use that too if we can find it.
BADTAR=0
if [ "$TAR" ]; then
! [ -x "$TAR" ] && BADTAR=1
else
TAR=`which tar-1.13 2> /dev/null`
fi
if ! [ -x "$TAR" ]; then
TAR="tar"
fi
# If the user gave us a bad path to tar then we should warn him/her about it
if [ $BADTAR -gt 0 ]; then
echo
echog "Warning: The path to tar specified in the command line is invalid.\nWarning: It has been set to %s" "$TAR"
echo
fi
# Restoring a backup into / must not let tar replace a symlinked directory
# with a real one. On a merged-/usr system that turns /bin, /lib and the
# other aliased directories into real ones, leaving the system unable to run
# a single binary. GNU tar 1.27 and later can be told to leave them alone.
# tar-1.13 and other implementations cannot, so there we do without it.
TAR_KEEPSYMLINK=""
if $TAR --keep-directory-symlink --version > /dev/null 2>&1; then
TAR_KEEPSYMLINK="--keep-directory-symlink"
fi
[ $DEBUG -gt 0 ] && echo "debug: TAR=$TAR"
[ $DEBUG -gt 0 ] && echo "debug: TAR_KEEPSYMLINK=$TAR_KEEPSYMLINK"
[ $DEBUG -gt 0 ] && echo "debug: VISUAL=$VISUAL"
#################################
# Variable definition ends here #
#############################################################################
if [ ! -x $INSTALLWATCH ]; then
echo
echog "I can't find $INSTALLWATCH."
echo
echog "I can't continue. Either install installwatch or\nmodify the INSTALLWATCH variable in this script,\nthen run checkinstall again."
echo
exit 1
fi
echo
# Set the umask. If not specified with "--umask" then we'll use 0022, a
# standard, non-paranoid reasonable value.
if [ $DEBUG -gt 0 ] ;then
echo "debug: Setting umask => $CKUMASK"
fi
umask $CKUMASK
# Find a safe TMP_DIR
TMP_DIR=`mktemp -q -d -p "${BASE_TMP_DIR}"`
RETURN=$?
if [ "$TMP_DIR" = "$BASE_TMP_DIR" -o "$TMP_DIR" = "/" ]; then
echo
echog "%s is an unacceptable value for the temp dir. Please \nedit the variable definition for %s and try again." "$TMP_DIR" "$TMP_DIR"
echo
echog "*** Aborting"
echo
exit 1
fi
if [ $RETURN -gt 0 ]; then
echo
echog "**** Failed to create temp dir! \n**** Do you have write permission for %s? \n\n**** Aborting installation." "$BASE_TMP_DIR"
echo
exit $RETURN
fi
BUILD_DIR=${TMP_DIR}/package
mkdir $BUILD_DIR
if [ $DEBUG -gt 0 ] ;then
echo "debug: The temporary directory is: [ $TMP_DIR ]"
echo
fi
# 001117-BaP: We can create a default set of docs on the fly . . .
# The list I've included should cover most packages adequately. If not,
# then you should really create the package doc set *manually*
# Check if --nodoc was specified
if [ "$NODOC" = "0" ]; then
if ! [ -d "$DIRECTORIO_FUENTE/doc-pak" ]; then
echogn "The package documentation directory ./doc-pak does not exist. \nShould I create a default set of package docs? "
if yorn ; then
echo
echogn "Preparing package documentation..."
mkdir doc-pak
for f in ABOUT ABOUT-NLS ANNOUNCE AUTHORS *BUGS* CHANGES CONFIGURATION *COPYING* *COPYRIGHT* CREDITS ChangeLog Changelog CHANGELOG CONTRIBUTORS *FAQ* FEATURES FILES HACKING History HISTORY INSTALL* LICENSE LSM MANIFEST NEWS *README* *Readme* SITES *RELEASE* RELNOTES THANKS TIPS TODO VERSION CONFIGURATION* GPL License Doc doc Docs* docs* Roadmap ROADMAP; do
if [ -e $f ]; then
if ! [ -L $f ]; then
cp -a $f doc-pak
else
cp -LpR $f doc-pak
fi
fi
done
okfail
DOCS=`ls doc-pak`
if ! [ "$DOCS" ]; then
echo
echog "*** No known documentation files were found. The new package \n*** won\'t include a documentation directory."
rm -rf doc-pak # If doc-pak is empty then we
fi # don't need it
fi
fi
fi # End of NODOC
##############################################################################
#
# Find out the packaging method to use
#
while ! [ "$INSTYPE" ]; do
echo
echog "Please choose the packaging method you want to use."
echogn "Slackware [S], RPM [R] or Debian [D]? "
read INSTYPE
echo
case $INSTYPE in
S|s)
INSTYPE=S
CK_SLACKWARE=1
;;
R|r)
INSTYPE=R
CK_REDHAT=1
;;
D|d)
INSTYPE=D
CK_DEBIAN=1
;;
*)
echo
echog '*** Invalid type.'
echo
INSTYPE=""
;;
esac
done
## Do we have a package description file? If we don't then
## we should write one
cd "$DIRECTORIO_FUENTE"
# If we already have a slack-desc we use it unless
# we have a description-pak too
if [ -r slack-desc -a ! -r description-pak ]; then
cat -s slack-desc | grep -v \# | grep -v \| | cut -d : -f 2 | sed '/./,/^$/!d' > description-pak
fi
if [ $ACCEPT_DEFAULT -eq 0 ]; then # If --default is given, we skip this
if ! [ -r description-pak ]; then
DESCRIPTION="Package created with checkinstall $CHECKINSTALL_VERSION"
echo
echogn "Please write a description for the package."
# If we selected Slackware, then give the pkgtool warning
if [ "$CK_SLACKWARE" ]; then
echog " Remember that pkgtool shows\nonly the first one when listing packages so make that one descriptive."
fi
echo
echog "End your description with an empty line or EOF."
while [ "$DESCRIPTION" ]; do
echo -n ">> "
read DESCRIPTION
[ "$DESCRIPTION" ] && echo "$DESCRIPTION" >> description-pak
done
fi
fi
# We still don't have it??
! [ -r description-pak ] && echo "Package created with checkinstall $CHECKINSTALL_VERSION" > description-pak
# Warn the user if we're using the new Slackware description format
# and the description is bigger than 11 lines
if [ $NEW_SLACK -gt 0 ]; then
if [ `wc -l < description-pak` -gt 11 ]; then
echo
echog "Warning: Your package description is bigger than 11 lines.\nWarning: The Slackware 8.1+ pkgtools might not like it."
echo
fi
fi
INSTYPE=`echo $INSTYPE | tr a-z A-Z`
case $INSTYPE in
S|s)
CK_SLACKWARE=1
echo
echog "********************************************\n**** Slackware package creation selected ***\n********************************************"
;;
R|r)
CK_REDHAT=1
echo
echog "**************************************\n**** RPM package creation selected ***\n**************************************"
;;
D|d)
CK_DEBIAN=1
echo
echog "*****************************************\n**** Debian package creation selected ***\n*****************************************"
esac
########## Acquire some info about the package ##########
# Figure out what kind of machine are we running on
if ! [ "$ARCHITECTURE" ]; then
ARCHITECTURE=`uname -m`
echo $ARCHITECTURE | grep -e "i[3456]86" &> /dev/null
[ $? -eq 0 ] && ARCHITECTURE=i386 # Arch will be "i386" for any of
# i386, i486, i586 or i686.
# You can change this with "--arch"
# Fix the PowerPC & Amd64 architecture description if we're on Debian
if [ "$CK_DEBIAN" = "1" ] ; then
ARCHITECTURE=`dpkg-architecture -qDEB_HOST_ARCH`
fi
fi
if [ -f "$SPEC_PATH" ]; then
SUMMARY=`getparameter "^[Ss]ummary"`
NAME=`getparameter "^[Nn]ame"`
VERSION=`getparameter "^[Vv]ersion"`
RELEASE=`getparameter "^[Rr]elease"`
LICENSE=`getparameter "^[Cc]opyright"`
PKG_GROUP=`getparameter "^[Gg]roup"`
PROVIDES=`getparameter "^[Pp]rovides"`
REQUIRES=`getparameter "^[Rr]equires"`
PREREQUIRES=`getparameter "^[Pp]rerequires"`
RECOMMENDS=`getparameter "^[Rr]commends"`
SUGGESTS=`getparameter "^[Ss]uggests"`
CONFLICTS=`getparameter "^[Cc]onflicts"`
REPLACES=`getparameter "^[Rr]eplaces"`
fi
OPTION=junk
while [ "$OPTION" ]; do
# Some sanity checks
! [ "$SUMMARY" ] && SUMMARY=`head -1 description-pak`
# An out-of-source build runs in a subdirectory, so guess from the
# source directory above it rather than from "build" itself.
PKG_GUESS="$PKG_BASENAME"
case "$PKG_GUESS" in
build|_build|builddir)
PKG_GUESS=$(basename "$(dirname "$DIRECTORIO_FUENTE")")
[ "$PKG_GUESS" = "/" ] && PKG_GUESS="$PKG_BASENAME"
;;
esac
# Split a trailing field off as the version only when it looks like
# one. Without that, a directory named gr-binviz gives the package
# gr, version binviz.
PKG_TAIL=$(echo "$PKG_GUESS" | rev | cut -f1 -d"-" | rev)
case "$PKG_TAIL" in
*[0-9]*)
! [ "$NAME" ] && NAME=`echo "$PKG_GUESS" | rev | cut -f2- -d"-" | rev`
! [ "$VERSION" ] && VERSION="$PKG_TAIL"
;;
*)
! [ "$NAME" ] && NAME="$PKG_GUESS"
;;
esac
echo "$NAME" | grep -e "[[:blank:]]" &> /dev/null
if [ $? -eq 0 ]; then
echo
echog "*** Warning: The package name \"%s\" contains spaces.\n*** Warning: Package names with spaces in them are not valid in most\n*** Warning: packaging systems so I changed all spaces to underscores." "$NAME"
NAME=`echo "$NAME" | tr ' \t' '__'`
fi
if [ "$CK_DEBIAN" ]; then # Make the name policy compliant
echo "$NAME" | grep -e "[[:upper:]]" &> /dev/null
if [ $? -eq 0 ]; then
echo
echog "*** Warning: The package name \"%s\" contains upper case\n*** Warning: letters. dpkg might not like that so I changed\n*** Warning: them to lower case." "$NAME"
NAME=`echo "$NAME" | tr 'A-Z' 'a-z'`
fi
echo "$NAME" | grep -e '^[^0-9a-z]' &> /dev/null
if [ $? -eq 0 ]; then
echo
echog "*** Warning: The package name \"%s\" does not start with\n*** Warning: an alphanumetic character. dpkg might not like that so I prefixed\n*** Warning: it with a number 0." "$NAME"
NAME=`echo "$NAME" | sed -e 's/^/0/'`
fi
echo "$NAME" | grep -e '[^0-9a-z+.-]' &> /dev/null
if [ $? -eq 0 ]; then
echo
echog "*** Warning: The package name \"%s\" contains illegal\n*** Warning: characters. dpkg might not like that so I changed\n*** Warning: them to dashes." "$NAME"
NAME=`echo "$NAME" | sed -e 's/[^0-9a-z+.-]/-/g'`
fi
fi
## Did we get a usable version?
if ! [ "$VERSION" ]; then
# If we did not then try getting it from the config.log file
if [ -f "$DIRECTORIO_FUENTE/config.log" ]; then
VERSION=`grep '#define VERSION' config.log| awk -F \" '{print $ 2}'`
fi
# We use the current date if everything else fails
! [ "$VERSION" ] && VERSION=`date +%Y%m%d`
fi
if [ "$CK_DEBIAN" ]; then # Check for a valid version for dpkg
NEWVERS=$(echo $VERSION | egrep '^([[:alnum:]]+:)?[[:alnum:]]+([-:.+~][[:alnum:]]+)*(-[.[:alnum:]]+)?$' 2> /dev/null)
while [ "$NEWVERS" != "$VERSION" ]; do
echo
echog "*** Warning: The package version \"%s\" is not a\n*** Warning: debian policy compliant one. Please specify an alternate one" "$VERSION"
if [ $ACCEPT_DEFAULT -eq 0 ] ; then
read VERSION
NEWVERS=$(echo $VERSION | egrep '^([[:alnum:]]+:)?[[:alnum:]]+([-:.+~][[:alnum:]]+)*(-[.[:alnum:]]+)?$' 2> /dev/null)
else
VERSION=0
NEWVERS=0
fi
done
fi
if [ ! "$PAGER" ]; then # no default pager defined
if [ "$CK_DEBIAN" ]; then # use Debian's pager if on Debian
PAGER=/usr/bin/sensible-pager
else
PAGER=less # use less otherwise
fi
fi
! [ "$RELEASE" ] && RELEASE="1"
! [ "$LICENSE" ] && LICENSE="GPL"
! [ "$PKG_GROUP" ] && [ "$CK_REDHAT" ] && PKG_GROUP="Applications/System"
! [ "$PKG_GROUP" ] && [ "$CK_DEBIAN" ] && PKG_GROUP="checkinstall"
! [ "$PKG_GROUP" ] && [ "$CK_SLACKWARE" ] && PKG_GROUP="Applications/System"
! [ "$ARCHITECTURE" ] && ARCHITECTURE="i386"
! [ "$SOURCE" ] && SOURCE="$PKG_BASENAME"
! [ "$ALTSOURCE" ] && ALTSOURCE=""
! [ "$PROVIDES" ] && PROVIDES="$NAME"
! [ "$REQUIRES" ] && REQUIRES=""
! [ "$PREREQUIRES" ] && PREREQUIRES=""
! [ "$RECOMMENDS" ] && RECOMMENDS=""
! [ "$SUGGESTS" ] && SUGGESTS=""
! [ "$CONFLICTS" ] && CONFLICTS=""
! [ "$REPLACES" ] && REPLACES=""
# bond: added this so it is easy to change the Maintainer: field
# just by setting the MAINTAINER environment variable
# Try to find the hostname in the environment
if [ "$HOSTNAME" ]; then
MAINTDOMAIN=$HOSTNAME
else
hostname -f &> /dev/null
if [ $? -gt 0]; then
MAINTDOMAIN="localhost"
else
MAINTDOMAIN=`hostname -f`
fi
fi
! [ "$MAINTAINER" ] && MAINTAINER=${LOGNAME:-root}@${MAINTDOMAIN}
echo
echog "This package will be built according to these values: "
echo
# Debian maintainers use the Maintainer: field and want to be able
# to change it. If we are not on debian we don't need the field...
[ "$CK_DEBIAN" ] && echog "0 - Maintainer: [ %s ]" "$MAINTAINER"
echog "1 - Summary: [ %s ]" "$SUMMARY"
echog "2 - Name: [ %s ]" "$NAME"
echog "3 - Version: [ %s ]" "$VERSION"
echog "4 - Release: [ %s ]" "$RELEASE"
echog "5 - License: [ %s ]" "$LICENSE"
echog "6 - Group: [ %s ]" "$PKG_GROUP"
echog "7 - Architecture: [ %s ]" "$ARCHITECTURE"
echog "8 - Source location: [ %s ]" "$SOURCE"
echog "9 - Alternate source location: [ %s ]" "$ALTSOURCE"
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] &&
echog "10 - Requires: [ %s ]" "$REQUIRES"
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] &&
echog "11 - Recommends: [ %s ]" "$RECOMMENDS"
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] &&
echog "12 - Suggests: [ %s ]" "$SUGGESTS"
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] &&
echog "13 - Provides: [ %s ]" "$PROVIDES"
[ "$CK_DEBIAN" ] && echog "14 - Conflicts: [ %s ]" "$CONFLICTS"
[ "$CK_DEBIAN" ] && echog "15 - Replaces: [ %s ]" "$REPLACES"
[ "$CK_DEBIAN" ] && echog "16 - Prerequires: [ %s ]" "$PREREQUIRES"
echo
echogn "Enter a number to change any of them or press ENTER to continue: "
if [ $ACCEPT_DEFAULT -eq 1 ]; then
echo
OPTION=""
else
read OPTION
fi
case $OPTION in
1)
echog "Enter new summary: "
echo -n ">> "
read SUMMARY
;;
2)
echog "Enter new name: "
echo -n ">> "
read NAME
;;
3)
echog "Enter new version: "
echo -n ">> "
read VERSION
;;
4)
echog "Enter new release number: "
echo -n ">> "
read RELEASE
;;
5)
echog "Enter the license type: "
echo -n ">> "
read LICENSE
;;
6)
echog "Enter the new software group: "
echo -n ">> "
read PKG_GROUP
;;
7)
echog "Enter the architecture type: "
echo -n ">> "
read ARCHITECTURE
;;
8)
echog "Enter the source location: "
echo -n ">> "
read SOURCE
;;
9)
echog "Enter the alternate source location: "
echo -n ">> "
read ALTSOURCE
;;
0) # bond: again, debian-specific
[ "$CK_DEBIAN" ] && {
echog "Enter the maintainer's name and e-mail address: "
echo -n ">> "
read MAINTAINER
}
;;
10)
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] && {
echog "Enter the additional requirements: "
echo -n ">> "
read REQUIRES
}
;;
11)
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] && {
echog "Enter the additional recommendations: "
echo -n ">> "
read RECOMMENDS
}
;;
12)
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] && {
echog "Enter the additional suggestions: "
echo -n ">> "
read SUGGESTS
}
;;
13)
# 01-12-06 UKo: new feature
[ "$CK_REDHAT" -o "$CK_DEBIAN" ] && {
echog "Enter the provided features: "
echo -n ">> "
read PROVIDES
}
;;
14)
[ "$CK_DEBIAN" ] && { echog "Enter the conflicting packages: "
echo -n ">> "
read CONFLICTS
}
;;
15)
[ "$CK_DEBIAN" ] && { echog "Enter the replaced packages: "
echo -n ">> "
read REPLACES
}
;;
16)
[ "$CK_DEBIAN" ] && { echog "Enter the pre-required packages: "
echo -n ">> "
read PREREQUIRES
}
;;
esac
done
# The PKG_BASENAME is adjusted to reflect any changes
# in the NAME and VERSION of the package
# NOTE: on debian we use NAME alone, instead - see below
PKG_BASENAME="$NAME-$VERSION"
##############################################################################
#
# We run the program installation from the source directory
#
# Write a small script to run the install command. This way the LD_PRELOAD
# environment variable will be available to it, wich among other things
# will allow proper detection of new symbolic links and files created by
# subshells.
[ $DEBUG -gt 0 ] && echo "debug: CK_INCLUDE_FILE = $CK_INCLUDE_FILE"
TMP_SCRIPT=${TMP_DIR}/installscript.sh
cat << EOF > $TMP_SCRIPT
#!/bin/sh
cd "$DIRECTORIO_FUENTE"
EOF
shell_escape "${INSTALLCMD[@]}" >> $TMP_SCRIPT
cat << EOF >> $TMP_SCRIPT
# Report success or failure
if [ \$? -eq 0 ]; then
exit 0
else
exit 1
fi
EOF
# No one needs to see what we are doing. It's safer this way.
chmod 700 $TMP_SCRIPT
echo
echogn "Installing with %s..." "${INSTALLCMD[*]}"
#
# We exclude as many "dangerous" directories as possible from translation.
# installwatch excludes itself some directories, but we put them all here,
# to be explicit.
#
IEXCLUDE="${DIRECTORIO_FUENTE},/dev,/proc,/tmp,/var/tmp"
# Run the install command, showing the results interactively if we were asked
# to do so in the configuration section (see the SHOW_INSTALL switch above)
INSTALL_FAILED=0
if [ $SHOW_INSTALL -eq 0 ]; then
$INSTALLWATCH --logfile=${TMP_DIR}/newfiles.tmp --exclude="${IEXCLUDE}" \
--root=${TMP_DIR} --transl=${TRANSLATE} --backup=${BACKUP} --dbglvl=$DEBUG\
$TMP_SCRIPT &> /${TMP_DIR}/install.log
okfail
INSTALL_FAILED=$?
else
echo
echo
echog "========================= Installation results ==========================="
$INSTALLWATCH --logfile=${TMP_DIR}/newfiles.tmp --exclude="${IEXCLUDE}" \
--root=${TMP_DIR} --transl=${TRANSLATE} --backup=${BACKUP} --dbglvl=$DEBUG\
$TMP_SCRIPT 2>&1
if [ $? -eq 0 ]; then
echo
echog "======================== Installation successful =========================="
else
INSTALL_FAILED=1
fi
fi
# preserve LD_PRELOAD, might have been set by fakeroot
# unset LD_PRELOAD
VIEWLOG="n"
if [ $INSTALL_FAILED -gt 0 ]; then
echo
echog "**** Installation failed. Aborting package creation."
VIEWLOG="y"
fi
if [ $SHOW_INSTALL -eq 0 ]; then
echo
echogn "Do you want to view the installation log file? "
if yorn $VIEWLOG ; then
(echo
echogn ' ***************************************************************\n Installation results. You can find them in\n %s\n ***************************************************************\n' "${TMP_DIR}/install.log"
cat /${TMP_DIR}/install.log) | $PAGER
fi
fi
if [ $INSTALL_FAILED -gt 0 ]; then
cleanup
exit $INSTALL_FAILED
fi
# If translation was active, the installed files are under /transl
TRANSLROOT="/"
if [ "${TRANSLATE}" = "1" ]; then
TRANSLROOT="${TMP_DIR}/TRANSL"
fi
# Copy the documentation files
if [ -d "$DIRECTORIO_FUENTE/doc-pak" ]; then # Are there any files?
echo
echo "Copying documentation directory..."
case "${DOC_DIR}" in
:*) doc_dir=`echo "${DOC_DIR}" | sed -e 's/://'`;;
*) doc_dir="${DOC_DIR}/${NAME}";;
esac
mkdir -p "${BUILD_DIR}/${doc_dir}"
copy_dir_hierarchy . "$DIRECTORIO_FUENTE/doc-pak" \
"${BUILD_DIR}/${doc_dir}"
chown -R root:root "${BUILD_DIR}/${doc_dir}"
fi
# If we have a --include list file, copy the files listed there to /
# If translation is on, it will catch these too.
if [ -f "${DIRECTORIO_FUENTE}/${CK_INCLUDE_FILE}" ]; then
cat "${DIRECTORIO_FUENTE}/${CK_INCLUDE_FILE}" | while IFS= read -r include_file; do
copy_dir_hierarchy --deref-parents "$include_file" "." "${BUILD_DIR}" &>/dev/null
done
fi
#
# Extract the relevant files from the modified files list
#
# Find regular files first
[ $DEBUG -gt 0 ] && echo "debug: BASE_TMP_DIR: $BASE_TMP_DIR"
cat /${TMP_DIR}/newfiles.tmp | egrep -v '^[-0-9][0-9]*[[:space:]]*(unlink|access)' | cut -f 3 | egrep -v "^(/dev|$BASE_TMP_DIR|/tmp)" | sort -u > /${TMP_DIR}/newfiles
# symlinks are next
cat /${TMP_DIR}/newfiles.tmp | egrep -v '^[-0-9][0-9]*[[:space:]]*(unlink|access)' | cut -f 4 | egrep -v "^(/dev|$BASE_TMP_DIR|/tmp)" | grep -v "#success" | sort -u >> /${TMP_DIR}/newfiles
# Create another list of modified files that exclude all files the
# install script wanted to create but did not, e.g because they already
# existed.
egrep "#success$" /${TMP_DIR}/newfiles.tmp | cut -f 3 | sort -u \
>/${TMP_DIR}/modified
egrep "#success$" /${TMP_DIR}/newfiles.tmp | cut -f 4 \
| egrep -v "#success" | sort -u >> /${TMP_DIR}/modified
# OK, now we clean it up a bit
mv /${TMP_DIR}/newfiles.tmp /${TMP_DIR}/newfiles.installwatch
sort -u < /${TMP_DIR}/newfiles | uniq | while IFS= read -r file; do
if [ -e "${TRANSLROOT}${file}" ]; then
printf '%s\n' "$file" >> /${TMP_DIR}/newfiles.tmp
else
FILE_SYM=`file "${TRANSLROOT}${file}" | grep 'symbolic link'`
[ "${FILE_SYM}" != "" ] && printf '%s\n' "$file" >> /${TMP_DIR}/newfiles.tmp
fi
done
cp /${TMP_DIR}/newfiles.tmp /${TMP_DIR}/newfiles
# Don't include anything under the directories specified with "--exclude"
[ $DEBUG -gt 0 ] && echo "debug: EXCLUDE=$EXCLUDE"
for exclude in `echo $EXCLUDE | awk '{ split ($0, files,","); for(i=1; files[i] != ""; i++) print files[i];}'`; do
if [ -d "$exclude" ]; then # If it's a directory, ignore everything below it
egrep -v "^$exclude" < /${TMP_DIR}/newfiles > /${TMP_DIR}/newfiles.tmp
else
if [ -f "$exclude" ]; then # If it's a file, ignore just this one
egrep -v "^$exclude$" < /${TMP_DIR}/newfiles > /${TMP_DIR}/newfiles.tmp
else
# Not on this host, which is the ordinary case with filesystem
# translation, so match it against the list as a leading path
egrep -v "^$exclude" < /${TMP_DIR}/newfiles > /${TMP_DIR}/newfiles.tmp
fi
fi
cp /${TMP_DIR}/newfiles.tmp /${TMP_DIR}/newfiles
done
# Find files created under /home
grep '^/home' ${TMP_DIR}/newfiles > /${TMP_DIR}/unwanted
if [ $? -eq 0 ]; then
echo
echog "Some of the files created by the installation are inside the home directory: /home"
echo
echog "You probably don't want them to be included in the package."
echogn "Do you want me to list them? "
if yorn "n"; then
$PAGER ${TMP_DIR}/unwanted
fi
echogn "Should I exclude them from the package? (Saying yes is a good idea) "
if yorn "n"; then
sed -i -e '/^\/home/d' ${TMP_DIR}/newfiles
fi
fi
## Find any files created in `pwd`. We probably don't want them here
grep "^`pwd`" ${TMP_DIR}/newfiles > /${TMP_DIR}/unwanted
if [ $? = 0 ]; then
echo
echog "Some of the files created by the installation are inside the build\ndirectory: %s" "`pwd`"
echo
echogn "You probably don't want them to be included in the package,\nespecially if they are inside your home directory.\nDo you want me to list them? "
if yorn "n"; then
$PAGER ${TMP_DIR}/unwanted
fi
echogn "Should I exclude them from the package? (Saying yes is a good idea) "
if yorn ; then
grep -v "^`pwd`" ${TMP_DIR}/newfiles > /${TMP_DIR}/newfiles.tmp
mv /${TMP_DIR}/newfiles.tmp /${TMP_DIR}/newfiles
fi
fi
# If requested with "--inspect" we run an editor on the newfiles list
if [ $CK_INSPECT -gt 0 ]; then
echo
echog "You requested to review the list of files that will be\nincluded in this package.\n\nNow you'll have the chance to review and optionally modify it."
echo
echog "Press ENTER to continue."
read junk
$VISUAL ${TMP_DIR}/newfiles
# Check if new files were added by the user
cat /${TMP_DIR}/newfiles | while IFS= read -r file; do
if ! [ -e "${TRANSLROOT}${file}" ]; then
copy_dir_hierarchy --deref-parents "${file}" "/" "${BUILD_DIR}" >> /${TMP_DIR}/updated-by-user.log 2>&1
fi
done
fi
# Copy the files to the temporary directory
#
echo
echogn "Copying files to the temporary directory..."
cd /
( cat /${TMP_DIR}/newfiles | while IFS= read -r i; do
if [ ! -d "${TRANSLROOT}${i}" -o -L "${TRANSLROOT}${i}" ]; then
echo ".${i}"
fi
done ) > /${TMP_DIR}/newfiles-tar
# Here it gets tricky: we need to copy all new files to our build dir,
# keeping permissions as they are for parents directories as well as for
# the files themselves. If the parents or the file are symlinks, we
# dereference them only if they were not modified by the installation
# script.
NEWFILES="${TMP_DIR}/modified"
LOGFILE="/${TMP_DIR}/checkinstall.log"
while IFS= read -r file; do
list_parents "${file}" | while IFS= read -r p; do
# We have to remove the ./ at the beginning
truep=${p#.}
# Parent has been modified: do _not_ dereference. Match the
# whole line: an unanchored pattern also hits a longer path
# that happens to end the same way.
if grep -qxF "${truep}" "${NEWFILES}"; then
printf '%s\n' "$p" \
| $TAR --no-recursion -C "${TRANSLROOT}" -cpf - -T - \
| $TAR -f - -xvpC "${BUILD_DIR}" >> $LOGFILE 2>&1
else
# Parent wasn't touched by the install script: dereference
printf '%s\n' "$p" \
| $TAR --no-recursion -C "${TRANSLROOT}" -cphf - -T - \
| $TAR -f - -xvpC "${BUILD_DIR}" >> $LOGFILE 2>&1
fi
done
truefile=${file#.}
# No recursion here: if $file is a directory, then the files created
# in it will follow.
if grep -qxF "${truefile}" "${NEWFILES}"; then
printf '%s\n' "$file" \
| $TAR --no-recursion -C "${TRANSLROOT}" -cpf - -T - \
| $TAR -f - -xvpC "${BUILD_DIR}" >> $LOGFILE 2>&1
else
printf '%s\n' "$file" \
| $TAR --no-recursion -C "${TRANSLROOT}" -cphf - -T - \
| $TAR -f - -xvpC "${BUILD_DIR}" >> $LOGFILE 2>&1
fi
done < /${TMP_DIR}/newfiles-tar
okfail
cd /
# Reset all files' owner/group to root.root, and all dirs' perms to 755
#
# We do this if asked with "--reset-uids" in the command line, like the
# similar option in Slackware's makepkg.
if [ $RESET_UIDS -gt 0 ]; then
find "$BUILD_DIR" -exec chown root:root {} \;
find "$BUILD_DIR" -type d -exec chmod 755 {} \;
find "$BUILD_DIR" -type f -exec chmod o=g {} \;
fi
##############################################################################
# Strip ELF binaries #
######################
#
# Note: The code in this section was taken from the brp-strip script included
# in rpm-4.0.2, which is distributed under the GNU GPL. The copyright
# for this code belongs to its owner. See the file COPYING for details.
#
if [ $STRIP_ELF -eq 1 ]; then
echo
if [ $STRIP_SO_ELF -eq 1 ]; then
echogn "Stripping ELF binaries and libraries..."
else
echogn "Stripping ELF binaries..."
fi
# No execute bit is required: a shared library is installed 0644
# and still wants stripping.
for f in `find ${BUILD_DIR} -type f` ; do
ftype=`file "$f"`
# Only ELF objects that still carry their symbols
case "$ftype" in
*ELF*not\ stripped*) ;;
*) continue;;
esac
# Shared objects only when we were asked for them
if [ $STRIP_SO_ELF -eq 0 ]; then
case "$ftype" in
*\ shared\ object,*) continue;;
esac
fi
strip -p "$f" || :
done
okfail
fi
###################
# End of stripping #
##############################################################################
##############################################################################
# Compress man pages #
######################
#
# Note: The code in this section is based on the brp-compress script
# included in rpm-4.0.2, which is distributed under the GNU GPL. The
# copyright for this code belongs to its owner. See the file COPYING for
# details.
#
if [ $COMPRESS_MAN -eq 1 ]; then
echo
echogn "Compressing man pages..."
cd $BUILD_DIR
# Compress man pages
COMPRESS="gzip -9"
COMPRESS_EXT=.gz
for d in ./usr/local/man/man* ./usr/local/man/*/man* ./usr/local/info \
./usr/local/share/man/man* ./usr/local/share/man/*/man* \
./usr/local/share/info \
./usr/local/kerberos/man \
./usr/local/share/doc/*/man/man* ./usr/local/lib/*/man/man* \
././usr/man/man* ./usr/man/*/man* ./usr/info \
./usr/share/man/man* ./usr/share/man/*/man* ./usr/share/info \
./usr/kerberos/man ./usr/X11R6/man/man* ./usr/lib/perl5/man/man* \
./usr/share/doc/*/man/man* ./usr/lib/*/man/man*
do
[ -d $d ] || continue
for f in `find $d -type f`
do
[ -f "$f" ] || continue
[ "`basename $f`" = "dir" ] && continue
# decompress manpage by "cat"ing it, this allows decompression of
# hardlinked manpages and allows gunzip of a compressed page which is
# actually called "man.1" and not "man.1.gz", something it won't do
# when operating directly on file.
# this overcomes installs that create (un)compressed pages with names
# that don't correspond with the compression.
# this is done to a temporary file so we can detect hardlinks to
# original file.
b=`echo $f | sed -e 's/\.Z$//;s/\.gz$//;s/\.bz2$//'`
cp -p $f $b.tmp # setup up permissions on our new file
cat $f | gunzip -c 2>/dev/null >$b.tmp || {
cat $f | bunzip2 -c 2>/dev/null >$b.tmp || {
cat $f >$b.tmp
}
}
$COMPRESS $b.tmp
# find any hard links to the old manpage and link to the new one..
inode=`ls -i $f | awk '{ print $1 }'`
others=`find $d -type f -inum $inode`
if [ -n "$others" ]; then
for afile in $others ; do
[ "$afile" = "$f" ] && continue
rm -f ${TRANSLROOT}/${afile} ${afile}
afile=`echo $afile | sed -e 's/\.Z$//;s/\.gz$//;s/\.bz2$//'`
ln $b.tmp$COMPRESS_EXT $afile$COMPRESS_EXT
done
fi
rm -f ${TRANSLROOT}/${f} ${f}
mv $b.tmp$COMPRESS_EXT $b$COMPRESS_EXT
done
for f in `find $d -type l`
do
l=`ls -l $f | awk '{ print $11 }' | sed -e 's/\.gz$//' -e 's/\.bz2$//' -e 's/\.Z$//'`
rm -f ${TRANSLROOT}/${f}
b=`echo $f | sed -e 's/\.gz$//' -e 's/\.bz2$//' -e 's/\.Z$//'`
ln -sf $l$COMPRESS_EXT $b$COMPRESS_EXT
done
done
okfail
fi
################################
# End of man pages compressing #
##############################################################################
# Now we get the TRUE list of files from the directory listing (kind of)
# of the BUILD_DIR. This is the true one simply because THESE are the files
# that will actually get packaged.
echo
echogn "Building file list..."
rm ${TMP_DIR}/newfiles
cd $BUILD_DIR
$TAR -cpf - . | $TAR -f - -t 2>&1 | sed -e 's#^\./#/#' | egrep -v "^/$" > ${TMP_DIR}/newfiles
okfail
# Do we have a postinstall script?
PINST_EXISTS=0
[ -f "${DIRECTORIO_FUENTE}/postinstall-pak" ] && PINST_EXISTS=1
##############################################################################
# Identify shared libraries #
#############################
if [ $ADD_SO -eq 1 ]; then
# Here we identify the shared libraries locations so we can add them
# to /etc/ld.so.conf file if they're not already there. This will be done
# in the postinstall script.
cat ${TMP_DIR}/newfiles | while read libfile; do
# Inspect the staged file rather than its final absolute path.
FILETYPE=`file "${BUILD_DIR}${libfile}"`
if echo /$FILETYPE | grep -e ".*ELF.*hared.*bject" &> /dev/null; then
echo `dirname $libfile` >> ${TMP_DIR}/libdirs
fi
done
# Did we find any libdirs?
if [ -f ${TMP_DIR}/libdirs ]; then
echo
echog "Shared libraries found. Adding them to the postinstall script."
# If we have a pre-existing postinstall-pak we save it
if [ $PINST_EXISTS -gt 0 ]; then
mv "${DIRECTORIO_FUENTE}/postinstall-pak" "${DIRECTORIO_FUENTE}/postinstall-pak.tmp"
PINST_EXISTS=1
fi
if ! [ $PINST_EXISTS -gt 0 ]; then
cat << EOF > "${DIRECTORIO_FUENTE}/postinstall-pak"
#!/bin/sh
#
# postinstall script, created by checkinstall-${CHECKINSTALL_VERSION}
#
EOF
fi
echo "echo" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
cat ${TMP_DIR}/libdirs | while read libdir; do
# libdir already has a leading slash.
libdir="/${libdir#/}"
(
# The generated script runs under /bin/sh, so use POSIX redirection.
echo "if ! egrep \"^${libdir} *\$\" /etc/ld.so.conf >/dev/null 2>&1; then"
echo " echo \"Adding \"${libdir}\" to /etc/ld.so.conf\""
echo " echo ${libdir} >> /etc/ld.so.conf"
echo fi
) >> "${DIRECTORIO_FUENTE}/postinstall-pak"
done
echo ldconfig >> "${DIRECTORIO_FUENTE}/postinstall-pak"
# If we had an existing postinstall-pak, append it to the new one
if [ -f "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" ]; then
cat "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
fi
fi # End of did we find any libdirs?
fi
####################################
# End of Identify shared libraries #
##############################################################################
##############################################################################
# Identify kernel modules #
###########################
# Find out if we installed a kernel module, and if so run depmod in the postinst
# and delete the files depmod touches (they conflict with other packages)
# These files are modules.* inside the kernel modules directory.
DEPFILES=$(cat ${TMP_DIR}/newfiles | grep -E 'modules\.(dep|pcimap|usbmap|ccwmap|ieee1394map|isapnpmap|inputmap|ofmap|seriomap|alias|symbols)' )
if [ ! -z "$DEPFILES" ] ; then
echo
echog "Kernel modules found. Calling depmod in the postinstall script"
# Delete references to the depmod generated files
sed -r -i -e '\,modules\.(dep|pcimap|usbmap|ccwmap|ieee1394map|isapnpmap|inputmap|ofmap|seriomap|alias|symbols),d' ${TMP_DIR}/newfiles
# And the files themselves
for file in $DEPFILES ; do
rm ${BUILD_DIR}/$file
done
# Find out the kernel version.
# Ugly hack, but works in Debian and should on many other systems.
# The file must be /any/dir//modules.*
KVER=$(echo $DEPFILES | awk '{print $1}' | sed -e 's|/modules\..*||' | xargs basename )
# Add depmod to the postinst
# This will be redundant if we already have a postinstall script.
# Nevertheless, it is harmless.
echo "#!/bin/sh" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
echo "#" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
echo "# postinstall script, created by checkinstall-${CHECKINSTALL_VERSION}" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
echo "#" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
echo "depmod $KVER" >> "${DIRECTORIO_FUENTE}/postinstall-pak"
fi
##################################
# End of Identify kernel modules #
##############################################################################
cd "$DIRECTORIO_FUENTE"
FAILED=0
case $INSTYPE in
##############################################################################
# Create Slackware compatible tarball #
#######################################
s|S)
# The new Slackware naming scheme
SLACK_PKG_BASENAME="${PKG_BASENAME}-${ARCHITECTURE}-${RELEASE}"
FAILED=0
# If we're not installing the package then there is no problem if
# installpkg is not in our execution path
if [ $INSTALL -gt 0 ]; then
# Verify that we have the "installpkg" command in our path
INSTALLPKG_PATH=`which installpkg 2> /dev/null`
if ! [ -x "$INSTALLPKG_PATH" ]; then
echo
echog "*** The \"installpkg\" program is not in your PATH!"
echo
echog "*** Slackware package creation aborted"
FAILED=1
fi
fi
if ! [ $FAILED -gt 0 ]; then
# Create the Slackware installation script
echo
echogn "Preparing Slackware install directory..."
mkdir -p ${BUILD_DIR}/install
touch ${BUILD_DIR}/install/doinst.sh
okfail
echo
echogn "Writing package description..."
# If we're building for Slackware 8.1+, then we use the new description
# file format
if [ $NEW_SLACK -gt 0 ]; then
cat << EOF > ${BUILD_DIR}/install/slack-desc
# HOW TO EDIT THIS FILE:
# The "handy ruler" below makes it easier to edit a package description. Line
# up the first '|' above the ':' following the base package name, and the '|' on
# the right side marks the last column you can put a character in. You must make
# exactly 11 lines for the formatting to be correct. It's also customary to
# leave one space after the ':'.
EOF
# Calculate the spaces before the "handy-ruler"
HR_SPACES=`echo $NAME | wc -c| awk '{ for (i=1;substr ($0,i,1) ~ /[[:blank:]]/ ;i++); print substr ($0,i);}'`
awk -v S=$HR_SPACES 'BEGIN {ORS=""; for (i=1; i < S; i++) print " ";}' >> ${BUILD_DIR}/install/slack-desc
echo "|-----handy-ruler------------------------------------------------------|" >> ${BUILD_DIR}/install/slack-desc
# Add the prefixed description
cat description-pak | while read line; do
echo "$NAME: $line" >> ${BUILD_DIR}/install/slack-desc
done
okfail
# End of NEW_SLACK block
else
#
# Generate the description-installing doinst.sh
#
if [ $AUTODOINST -eq 1 ]; then
echo "PACKAGE DESCRIPTION:" > ${BUILD_DIR}/install/description
cat description-pak | while read line; do
echo $line >> ${BUILD_DIR}/install/description
done
okfail
echo
echogn "Writing Slackware install script..."
cat << EOF >> ${BUILD_DIR}/install/doinst.sh
#
# doinst.sh, auto-generated by checkinstall-${CHECKINSTALL_VERSION}
#
echo
cat /install/description
sed '/PACKAGE LOCATION/r /install/description' < "/var/log/packages/$SLACK_PKG_BASENAME" > description.tmp
mv description.tmp "/var/log/packages/${SLACK_PKG_BASENAME}"
rm /install/description
EOF
okfail
fi
fi # End of description creation
# If we have a Slackware install script already, add it to this one
# and force an interactive slackware install script
for file in postinstall-pak install-pak; do
if [ -f $file ]; then
INSTALL_PAK=${file}
fi
done
if [ -f "$INSTALL_PAK" ]; then
echo
# We want to say this only if we actually had a preexisting postinstall-pak
if [ $PINST_EXISTS -gt 0 ]; then
echogn "Appending your script to the main install script..."
cat $INSTALL_PAK >> ${BUILD_DIR}/install/doinst.sh
okfail
echo
else
cat $INSTALL_PAK >> ${BUILD_DIR}/install/doinst.sh
fi
SHOW_SLACK_INSTALL=1
fi
echo
echogn "Creating package ${SLACK_PKG_BASENAME}..."
cd $BUILD_DIR
chmod 755 $BUILD_DIR
# Make the "TAR" variable available to MAKEPKG
export TAR
if [ $SHOW_MAKEPKG -gt 0 ]; then
$MAKEPKG $MAKEPKG_FLAGS ${TMP_DIR}/"${SLACK_PKG_BASENAME}.tgz"
okfail
else
$MAKEPKG $MAKEPKG_FLAGS ${TMP_DIR}/"${SLACK_PKG_BASENAME}.tgz" &> /dev/null
okfail
fi
mv ${TMP_DIR}/"${SLACK_PKG_BASENAME}.tgz" "$DIRECTORIO_FUENTE"
#
# If requested, we install the package to register it in Slackware's
# installed packages list so we can list it's contents with pkgtool
# or remove it with removepkg
#
if [ "$INSTALL" = "1" ]; then
# Go back to where we started
cd "$DIRECTORIO_FUENTE"
echo
if [ $SHOW_SLACK_INSTALL -eq 0 ]; then
echogn "Installing package..."
installpkg "${SLACK_PKG_BASENAME}.tgz" &> ${TMP_DIR}/slackinstall.log
okfail
[ $? -gt 0 ] && FAILED=1
else
echog "========================= Installation results ==========================="
echo
installpkg "${SLACK_PKG_BASENAME}.tgz"
if [ $? -gt 0 ]; then
FAILED=1
else
echo
echog "======================== Installation successful =========================="
fi
fi
if [ $FAILED -eq 1 ]; then
echo
echog "*** Failed to install the package"
echo
if [ $SHOW_SLACK_INSTALL -eq 0 ]; then
echogn "Do you want to see the log file? "
if yorn ; then
$PAGER ${TMP_DIR}/slackinstall.log
cleanup
exit 1
fi
fi
fi
else
echo
echog "NOTE: The package will not be installed."
fi
PKG_LOCATION="${DIRECTORIO_FUENTE}/${SLACK_PKG_BASENAME}.tgz"
INSTALLSTRING="installpkg ${SLACK_PKG_BASENAME}.tgz"
REMOVESTRING="removepkg ${SLACK_PKG_BASENAME}"
fi
;;
#################################
# End Slackware package section #
##############################################################################
##############################################################################
# RPM package installation #
############################
r|R)
FAILED=0
# Verify that we have the rpm command in our path
RPM_PATH=`which rpm 2> /dev/null`
if ! [ -x "$RPM_PATH" ]; then
echo
echog "*** The \"rpm\" program is not in your PATH!"
echo
echog "*** RPM package creation aborted"
FAILED=1
fi
if ! [ $FAILED -gt 0 ]; then
# Identify the rpm version
RPM_VERSION=`rpm --version | awk '{ print $3 }'`
RPM_MAJOR_VERSION=`echo $RPM_VERSION | cut -f1 -d"."`
RPM_MINOR_VERSION=`echo $RPM_VERSION | cut -f2 -d"."`
RPM_PATCH_LEVEL=`echo $RPM_VERSION | cut -f3 -d"."`
if [ "$RPM_PATCH_LEVEL" = "" ]; then
RPM_PATCH_LEVEL=0
fi
if [ $DEBUG -gt 0 ]; then
echo "debug: RPM_VERSION=${RPM_VERSION}"
echo "debug: RPM_MAJOR_VERSION=$RPM_MAJOR_VERSION"
echo "debug: RPM_MINOR_VERSION=$RPM_MINOR_VERSION"
echo "debug: RPM_PATCH_LEVEL=$RPM_PATCH_LEVEL"
echo "debug: RPM_IU=$RPM_IU"
fi
# AFAIK, the only rpm versions that accept
# "--target=arch" instead of "--target arch"
# are 3.x < version < 4.0.3
if [ $RPM_MAJOR_VERSION -eq 4 -a $RPM_PATCH_LEVEL -lt 3 ]; then
RPM_TARGET_FLAG="--target="
else
RPM_TARGET_FLAG="--target "
fi
# rpmbuild seems to exist only in RPM 4
if [ $RPM_MAJOR_VERSION -eq 4 ]; then
RPMBUILD="rpmbuild"
else
RPMBUILD="rpm"
fi
if [ "$RPMBUILD" = "rpmbuild" -a ! -x "`which rpmbuild 2> /dev/null`" ]; then
echo
echo "*** The \"rpmbuild\" program is not in your PATH!"
echo
echo "*** RPM package creation aborted"
FAILED=1
fi
if ! [ $FAILED -gt 0 ]; then
# Find out the RPM source directory path
if ! [ "$RPMSOURCEDIR" ]; then
if [ $RPM_MAJOR_VERSION -eq 3 -a $RPM_PATCH_LEVEL -ge 3 -o $RPM_MAJOR_VERSION -gt 3 ]; then
RPMSOURCEDIR="`rpm --eval=%_topdir`"
else
RPMSOURCEDIR="NOT-FOUND"
for directory in packages OpenLinux redhat RedHat rpm RPM "" ; do
[ -d /usr/src/${directory}/SOURCES ] && RPMSOURCEDIR="/usr/src/${directory}"
done
fi
fi
[ $DEBUG -gt 0 ] && echo "debug: RPMSOURCEDIR=$RPMSOURCEDIR"
while ! [ -d "$RPMSOURCEDIR/SOURCES" ]; do
echo
echogn "%s has no SOURCES directory. Please write the path to\nthe RPM source directory tree: " "$RPMSOURCEDIR"
read RPMSOURCEDIR
! [ "$RPMSOURCEDIR" ] && RPMSOURCEDIR="NOT-FOUND"
done
# We'll write a basic spec file
if ! [ -f "$SPEC_PATH" ]; then
# If the buildroot path has spaces then we'll use the BUILD_DIR instead.
# rpm can't have a buildroot path with spaces in it (Bug?)
#
# This is obviously a hack, I hope we can do it the right way when rpm is
# fixed.
if ( echo "$DIRECTORIO_FUENTE" | grep " " &> /dev/null ); then
BROOTPATH="${DIRECTORIO_FUENTE}/buildroot"
else
BROOTPATH=$BUILD_DIR
fi
# Here comes the .spec file:
cat > "$SPEC_PATH" << EOF
Summary: $SUMMARY
Name: $NAME
Version: $VERSION
Release: $RELEASE
License: $LICENSE
Packager: checkinstall-$CHECKINSTALL_VERSION
Group: $PKG_GROUP
BuildRoot: $BROOTPATH
Provides: $PROVIDES
Requires: $REQUIRES,/bin/sh
Recommends: $RECOMMENDS
Suggests: $SUGGESTS
%description
EOF
cat description-pak >> "$SPEC_PATH"
# Use the preinstall-pak script if we have it
if [ -f preinstall-pak ]; then
echo >> "$SPEC_PATH"
echo '%pre' >> "$SPEC_PATH"
cat preinstall-pak >> "$SPEC_PATH"
fi
# Use the postinstall-pak script if we have it
if [ -f postinstall-pak ]; then
echo >> "$SPEC_PATH"
echo '%post' >> "$SPEC_PATH"
cat postinstall-pak >> "$SPEC_PATH"
fi
# Use the preremove-pak script if we have it
if [ -f preremove-pak ]; then
echo >> "$SPEC_PATH"
echo '%preun' >> "$SPEC_PATH"
cat preremove-pak >> "$SPEC_PATH"
fi
# Use the postremove-pak script if we have it
if [ -f postremove-pak ]; then
echo >> "$SPEC_PATH"
echo '%postun' >> "$SPEC_PATH"
cat postremove-pak >> "$SPEC_PATH"
fi
cat >> "$SPEC_PATH" << EOF
%files
EOF
# Prepare directories to be included in the .spec file
mv ${TMP_DIR}/newfiles ${TMP_DIR}/newfiles.tmp
cat ${TMP_DIR}/newfiles.tmp | while read line; do
[ -d "${BUILD_DIR}/${line}" -o -L "${BUILD_DIR}/${line}" ] && echo -n "%dir " >> ${TMP_DIR}/newfiles
echo "\"/${line}\"" >> ${TMP_DIR}/newfiles
done
# Append the file list to the .spec file
cat ${TMP_DIR}/newfiles >> "$SPEC_PATH"
fi
# If requested with --review-spec, we run an editor on the .spec file
if [ $REVIEW_SPEC -gt 0 ]; then
echo
echog "You requested to review the .spec file for this package.\nNow you\'ll have the chance to review and optionally modify this file."
echo
echog "Press ENTER to continue."
read junk
$VISUAL "$SPEC_PATH"
fi
BUILDROOT=`egrep '^[Bb]uild[Rr]oot' < "$SPEC_PATH" | cut -f2 -d:| sed 's/^ *//g'| sed 's/ *$//g'` # The sed commands remove leading/trailing whitespaces
# We make sure that we have a valid RELEASE number
! [ "$RELEASE" ] && RELEASE=`egrep '^Release:' < "$SPEC_PATH"|cut -f2 -d: | awk '{ for (i=1;substr ($0,i,1) ~ /[[:blank:]]/ ;i++); print substr ($0,i); }'`
[ $DEBUG -gt 0 ] && echo "debug: BUILDROOT=$BUILDROOT"
! [ -d "$BUILDROOT" ] && ln -s "$BUILD_DIR" "$BUILDROOT"
# We make sure that the architecture directory exists
! [ -d "${RPMSOURCEDIR}/RPMS/${ARCHITECTURE}" ] && mkdir -p "${RPMSOURCEDIR}/RPMS/${ARCHITECTURE}"
mkdir "${TMP_DIR}/$PKG_BASENAME"
cd $TMP_DIR
$TAR -cz -f "${RPMSOURCEDIR}/SOURCES/${PKG_BASENAME}.tgz" "$PKG_BASENAME"
rm -rf "${TMP_DIR}/$PKG_BASENAME"
cd "$DIRECTORIO_FUENTE"
echo
echogn "Building RPM package..."
$RPMBUILD -bb ${RPM_TARGET_FLAG}${ARCHITECTURE} "$SPEC_PATH" --buildroot="$BROOTPATH" &> ${TMP_DIR}/rpmbuild.log
okfail
if [ $? -gt 0 ]; then
echo
echog "*** Failed to build the package"
echo
echogn "Do you want to see the log file? "
if yorn ; then
$PAGER ${TMP_DIR}/rpmbuild.log
fi
FAILED=1
fi
RPMPKG="${RPMSOURCEDIR}/RPMS/${ARCHITECTURE}/${PKG_BASENAME}-${RELEASE}.${ARCHITECTURE}.rpm"
# Check for the old RPMFLAGS
if [ "$RPMFLAGS" ]; then
echo
echog "Warning: the use of RPMFLAGS is deprecated.\nWarning: You should now use RPM_FLAGS,\nWarning: please update your checkinstallrc file."
fi
if ! [ $FAILED -gt 0 ]; then
if [ "$INSTALL" = "1" ]; then
echo
echogn "Installing RPM package..."
rpm -$RPM_IU $RPM_FLAGS "${RPMPKG}" &> ${TMP_DIR}/rpminstall.log
okfail
if [ $? -gt 0 ]; then
echo
echog "*** Failed to install the package"
echo
echogn "Do you want to see the log file? "
if yorn ; then
$PAGER ${TMP_DIR}/rpminstall.log
fi
FAILED=1
fi
else
echo
echog "NOTE: The package will not be installed"
fi
fi
if ! [ $FAILED -gt 0 ]; then
PKG_LOCATION="$RPMPKG"
INSTALLSTRING="rpm -i `basename "$RPMPKG"`"
REMOVESTRING="rpm -e ${PKG_BASENAME}-${RELEASE}"
fi
fi # End of the "no rpmbuild in the path" if
fi # End of the "no rpm in the path" if
;;
#################################
# End RPM package section #
##############################################################################
##############################################################################
# Debian package installation #
################################
d|D)
# As we said before:
# Work out the shared library dependencies the way a regular package does.
# The binaries are staged by now, so this cannot happen before the summary.
AUTOREQUIRES=""
if [ $AUTODEPS -gt 0 ] && [ -x "`which dpkg-shlibdeps 2> /dev/null`" ]; then
echogn "Looking for shared library dependencies..."
SHLIB_BINARIES=`find "$BUILD_DIR" -type f | while read f; do
file "$f" | egrep -q 'ELF.*(executable|shared object)' && echo "$f"
done`
if [ -n "$SHLIB_BINARIES" ]; then
# Point dpkg-shlibdeps at the libraries the package itself ships. It
# stops at the first library it cannot account for otherwise.
SHLIB_DIRS=""
for d in `find "$BUILD_DIR" -name '*.so*' -type f | while read f; do dirname "$f"; done | sort -u`; do
SHLIB_DIRS="$SHLIB_DIRS -l$d"
done
mkdir -p "${TMP_DIR}/shlibdeps/debian"
: > "${TMP_DIR}/shlibdeps/debian/control"
AUTOREQUIRES=`cd "${TMP_DIR}/shlibdeps" &&
dpkg-shlibdeps -O --ignore-missing-info $SHLIB_DIRS $SHLIB_BINARIES \
2> ${TMP_DIR}/shlibdeps.log | sed -e 's/^shlibs:Depends=//'`
if [ -n "$AUTOREQUIRES" ]; then
if [ -n "$REQUIRES" ]; then
REQUIRES="$REQUIRES, $AUTOREQUIRES"
else
REQUIRES="$AUTOREQUIRES"
fi
fi
fi
okfail
[ -n "$AUTOREQUIRES" ] && echog "Depends: %s" "$AUTOREQUIRES"
fi
PKG_BASENAME="$NAME"
# maybe PKG_BASENAME should be defined locally for all the install
# types, and not only on debian...
FAILED=0
# Verify that we have the dpkg command in our path
DPKG_PATH=`which dpkg 2> /dev/null`
if ! [ -x "$DPKG_PATH" ]; then
echo
echog "*** The \"dpkg\" program is not in your PATH!"
echo
echog "*** Debian package creation aborted"
FAILED=1
fi
if ! [ $FAILED -gt 0 ]; then
cd "$DIRECTORIO_FUENTE"
# We'll write a basic Debian control file
mkdir $BUILD_DIR/DEBIAN
cat << EOF | sed "s/ $//" | egrep ": " >> $BUILD_DIR/DEBIAN/control
Package: $PKG_BASENAME
Priority: extra
Section: $(echo $PKG_GROUP | tr '\n' ' ')
Installed-Size: `du -s $BUILD_DIR | awk '{print $1}'`
Maintainer: $MAINTAINER
Architecture: $ARCHITECTURE
Version: ${VERSION}-${RELEASE}
Depends: $REQUIRES
Pre-Depends: $PREREQUIRES
Recommends: $RECOMMENDS
Suggests: $SUGGESTS
Provides: $PROVIDES
Conflicts: $CONFLICTS
Replaces: $REPLACES
Description: $SUMMARY
EOF
# Add the description
cat "$DIRECTORIO_FUENTE/description-pak"| grep -Fxv "$SUMMARY" | egrep -v "^[ ]*$" | while read line; do
echo " "$line >> $BUILD_DIR/DEBIAN/control
done
# Use the preinstall-pak script if we have it
if [ -f preinstall-pak ]; then
cat preinstall-pak > $BUILD_DIR/DEBIAN/preinst
chmod 755 $BUILD_DIR/DEBIAN/preinst
fi
# Use the postinstall-pak script if we have it
if [ -f postinstall-pak ]; then
cat postinstall-pak > $BUILD_DIR/DEBIAN/postinst
chmod 755 $BUILD_DIR/DEBIAN/postinst
fi
# Use the preremove-pak script if we have it
if [ -f preremove-pak ]; then
cat preremove-pak > $BUILD_DIR/DEBIAN/prerm
chmod 755 $BUILD_DIR/DEBIAN/prerm
fi
# Use the postremove-pak script if we have it
if [ -f postremove-pak ]; then
cat postremove-pak > $BUILD_DIR/DEBIAN/postrm
chmod 755 $BUILD_DIR/DEBIAN/postrm
fi
# Tag files in /etc to be conffiles
find -L $BUILD_DIR/etc -type f 2> /dev/null | sed -e "s,$BUILD_DIR,," \
> $BUILD_DIR/DEBIAN/conffiles
# The package will be saved here (ignores : prefix):
DEBPKG="${DIRECTORIO_FUENTE}/${NAME}_`echo ${VERSION} | sed -e 's/^[0123456789]*://'`-${RELEASE}_${ARCHITECTURE}.deb"
# This one is for 2.2 "Potato" (or older) style packages
#DEBPKG="${DIRECTORIO_FUENTE}/${NAME}_${VERSION}-${RELEASE}.deb"
# Leave dpkg-deb to pick for itself unless the user named a compression
DEB_COMPRESSION_FLAG=""
[ "$DEB_COMPRESSION" ] && DEB_COMPRESSION_FLAG="-Z$DEB_COMPRESSION"
if [ $DEBUG -gt 0 ]; then
echo
echo debug: PKG_BASENAME=${PKG_BASENAME}
echo debug: BUILD_DIR=${BUILD_DIR}
echo debug: DEBPKG=${DEBPKG}
echo debug: dpkg command:
echo " \"dpkg-deb $DEB_COMPRESSION_FLAG -b $BUILD_DIR $DEBPKG &> ${TMP_DIR}/dpkgbuild.log\""
fi
# If requested with --review-control, we run an editor on the control file
if [ $REVIEW_CONTROL -gt 0 ]; then
echo
echog "You requested to review the control file for this package.\nNow you'll have the chance to review and optionally modify this file."
echo
echog "Press ENTER to continue."
read junk
$VISUAL ${BUILD_DIR}/DEBIAN/control
fi
echo
echogn "Building Debian package..."
dpkg-deb $DEB_COMPRESSION_FLAG -b $BUILD_DIR "$DEBPKG" &> ${TMP_DIR}/dpkgbuild.log
okfail
if [ $? -gt 0 ]; then
echo
echog "*** Failed to build the package"
echo
echogn "Do you want to see the log file? "
if yorn ; then
$PAGER ${TMP_DIR}/dpkgbuild.log
fi
FAILED=1
fi
if ! [ $FAILED -gt 0 ]; then
if [ "$INSTALL" = "1" ]; then
echo
echogn "Installing Debian package..."
dpkg -i $DPKG_FLAGS "$DEBPKG" &> ${TMP_DIR}/dpkginstall.log
okfail
if [ $? -gt 0 ]; then
echo
echog "*** Failed to install the package"
echo
echogn "Do you want to see the log file? "
if yorn ; then
$PAGER ${TMP_DIR}/dpkginstall.log
fi
FAILED=1
fi
else
echo
echog "NOTE: The package will not be installed"
fi
fi
if ! [ $FAILED -gt 0 ]; then
PKG_LOCATION="$DEBPKG"
INSTALLSTRING="dpkg -i `basename "$DEBPKG"`"
REMOVESTRING="dpkg -r ${PKG_BASENAME}"
fi
fi
;;
################################
# End Debian package section #
##############################################################################
esac
# If we have a package repository set, move the package there
if ! [ $FAILED -gt 0 ]; then
if [ "$PAK_DIR" ]; then
if ! [ -d "$PAK_DIR" ]; then
echo
echogn "The package storage directory [ %s ]\ndoesn\'t exist. Do you want to create it?" "$PAK_DIR"
if yorn ; then
echo
echogn "Creating package storage directory..."
mkdir -p "$PAK_DIR" &> ${TMP_DIR}/mkpakdir.log
okfail
if [ $? -gt 0 ]; then
echo
echog "*** Unable to create %s" "$PAK_DIR"
echo "*** `cat ${TMP_DIR}/mkpakdir.log`"
echo
fi
fi
fi
if [ -d "$PAK_DIR" ]; then
echo
echogn "Transferring package to %s..." "$PAK_DIR"
mv "$PKG_LOCATION" "${PAK_DIR}" &> $TMP_DIR/transfer.log
okfail
if [ $? -gt 0 ]; then
echo
echogn "*** Transfer failed:"
cat $TMP_DIR/transfer.log
echo
else
# Update the package location
PKG_LOCATION="${PAK_DIR}/`basename "$PKG_LOCATION"`"
fi
else
echo
echog "There\'s no package storage directory, the package\nwill be stored at the default location."
fi
fi
fi
#
# Remove trash from TMP_DIR
#
echo
echogn "Erasing temporary files..."
# Preserve the Debian control file if debug is on
if [ $DEBUG -gt 0 ]; then
if [ -d ${BUILD_DIR}/DEBIAN ]; then
mv ${BUILD_DIR}/DEBIAN $TMP_DIR
fi
fi
[ $DEBUG -lt 2 ] && rm -rf ${BUILD_DIR}
rm -f checkinstall-debug*
rm -f "$BUILDROOT"
rm -f "${RPMSOURCEDIR}/SOURCES/${PKG_BASENAME}.tgz"
okfail
# Delete doc-pak directory
if [ $DEL_DOCPAK -gt 0 ]; then
echo
echogn "Deleting doc-pak directory..."
rm -rf doc-pak
okfail
fi
# Preserve the spec file if debugging is on
[ $DEBUG -gt 0 ] && [ -f "$SPEC_PATH" ] && cp "$SPEC_PATH" $TMP_DIR
# Delete spec file
[ $DEL_SPEC -gt 0 ] && rm -f "$SPEC_PATH"
# Delete the package description file
[ $DEL_DESC -gt 0 ] && rm -f description-pak
# If we had a pre-existing postinstall-pak, we keep it as it was.
# If PINST_EXISTS=0 and there is a postinstall-pak file, then
# it's the one we created and has to be deleted
if [ $PINST_EXISTS -eq 0 ]; then
rm -f "${DIRECTORIO_FUENTE}/postinstall-pak"
fi
if [ -f "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" ]; then
mv "${DIRECTORIO_FUENTE}/postinstall-pak.tmp" "${DIRECTORIO_FUENTE}/postinstall-pak"
fi
# If we have a backup, pack it up
rm -rf ${TMP_DIR}/BACKUP/no-backup &> /dev/null
ls ${TMP_DIR}/BACKUP/* &> /dev/null
if [ $? -eq 0 ]; then
cd ${TMP_DIR}/BACKUP
echo
echogn "Writing backup package..."
# We do this for the same reason as in restore_backup
FILES=$(ls -A)
$TAR -cpf - $FILES | gzip -9 > "${DIRECTORIO_FUENTE}/backup-`date +%m%d%Y%H%M`-pre-${PKG_BASENAME}.tgz"
okfail
fi
if [ $DEBUG -eq 0 ]; then
echo
echogn "Deleting temp dir..."
rm -rf ${TMP_DIR}
okfail
echo
else
echo
echogn "Building debug information package..."
cd ${TMP_DIR}
echo `uname -a` > sysinfo
echo `rpm --version` >> sysinfo
$TAR -cpzvf "${DIRECTORIO_FUENTE}/checkinstall-debug.$$.tgz" * &> /dev/null
okfail
fi
if ! [ $FAILED -gt 0 ]; then
if [ "${INSTALL}" = "1" ]; then
echo
echo '**********************************************************************'
echo
echog " Done. The new package has been installed and saved to\n\n %s\n\n You can remove it from your system anytime using: \n\n %s" "$PKG_LOCATION" "$REMOVESTRING"
echo
echo '**********************************************************************'
echo
else
echo
echo '**********************************************************************'
echo
echog " Done. The new package has been saved to\n\n %s\n You can install it in your system anytime using: \n\n %s" "$PKG_LOCATION" "$INSTALLSTRING"
echo
echo '**********************************************************************'
echo
fi
fi
ssgelm-checkinstall-59a004a/checkinstallrc-dist 0000664 0000000 0000000 00000007725 15235417303 0021666 0 ustar 00root root 0000000 0000000
#############################################################################
# CheckInstall configuration file #
########################################
####################################################################
# These are default settings for CheckInstall, modify them as you #
# need. Remember that command line switches will override them. #
####################################################################
# Debug level
# 0: No debug
# 1: Keep all temp files except the package's files
# 2: Keep the package's files too
DEBUG=0
# Location of the "installwatch" program
INSTALLWATCH_PREFIX="/usr/local"
INSTALLWATCH=${INSTALLWATCH_PREFIX}/bin/installwatch
# Location of the makepkg program. "makepak" is the default, and is
# included with checkinstall. If you want to use Slackware's native "makepkg"
# then set this to "makepkg"
MAKEPKG=/sbin/makepkg
# makepkg optional flags. These are recommended if running a newer Slackware
# version: "-l y -c n"
MAKEPKG_FLAGS="-l y -c n"
# Is MAKEPKG running interactively? If so, you might want
# to see what it's doing:
SHOW_MAKEPKG=0
# Where will we keep our temp files?
BASE_TMP_DIR=/var/tmp ## Don't set this to /tmp or / !!
# Where to place the installed document files
DOC_DIR=""
# Default architecture type (Leave it empty to allow auto-guessing)
ARCHITECTURE=""
# Default package type. Leave it empty to enable asking everytime
# S : Slackware
# R : RPM
# D : Debian
INSTYPE=""
# Storage directory for newly created packages
# By default they will be stored at the default
# location defined for the package type
PAK_DIR=""
# RPM optional flags
RPM_FLAGS=" --force --nodeps --replacepkgs "
# dpkg optional flags
DPKG_FLAGS=""
# Compression for the Debian package: gzip, xz, zstd or none.
# Leave it empty and dpkg-deb chooses. On a large package gzip and zstd
# finish much faster than xz, and produce a bigger file.
DEB_COMPRESSION=""
## These are boolean. Set them to 1 or 0
# Interactively show the results of the install command (i.e. "make install")?
# This is useful for interactive installation commands
SHOW_INSTALL=1
# Show Slackware package installation script while it runs? Again, useful if
# it's an interactive script
SHOW_SLACK_INSTALL=0
# Automatic deletion of "doc-pak" upon termination?
DEL_DOCPAK=1
# Automatic deletion of the spec file?
DEL_SPEC=1
# Automatic deletion of "description-pak"?
DEL_DESC=1
# Automatically strip all ELF binaries?
STRIP_ELF=1
# Automatically strip all ELF shared libraries?
# Note: this setting will automatically be set to "0" if STRIP_ELF=0
STRIP_SO_ELF=1
# Work out the shared library dependencies of the installed binaries with
# dpkg-shlibdeps and record them in the package. Debian packages only.
AUTODEPS=1
# Automatically search for shared libraries and add them to /etc/ld.so.conf?
# This is experimental and could mess up your dynamic loader configuration.
# Use it only if you know what you are doing.
ADD_SO=0
# Automatically compress all man pages?
COMPRESS_MAN=1
# Set the umask to this value
CKUMASK=0022
# Backup files overwritten or modified by your install command?
BACKUP=1
# Write a doinst.sh file that installs your description (Slackware)?
AUTODOINST=1
# Are we going to use filesystem translation?
TRANSLATE=1
# Reset the owner/group of all files to root.root?
RESET_UIDS=0
# Use the new (8.1+) Slackware description file format?
NEW_SLACK=1
# Comma delimited list of files/directories to be ignored
EXCLUDE=""
# Accept default values for all questions?
ACCEPT_DEFAULT=0
# Use "-U" flag in rpm by default when installing a rpm package
# This tells rpm to (U)pdate the package instead of (i)nstalling it.
RPM_IU=U
# Inspect the file list before creating the package
CK_INSPECT=0
# Review the .spec file before creating a .rpm
REVIEW_SPEC=0
# Review the control file before creating a .deb
REVIEW_CONTROL=0
# Install the package or just create it?
INSTALL=0
ssgelm-checkinstall-59a004a/description-pak 0000664 0000000 0000000 00000000610 15235417303 0021012 0 ustar 00root root 0000000 0000000 CheckInstall installations tracker, version 1.7.0
CheckInstall keeps track of all the files created or
modified by your installation script ("make install"
"make install_modules", "setup", etc), builds a
standard binary package and installs it in your
system giving you the ability to uninstall it with your
distribution's standard package management utilities.
ssgelm-checkinstall-59a004a/installwatch-man.sgml 0000664 0000000 0000000 00000013730 15235417303 0022134 0 ustar 00root root 0000000 0000000
Felipe">
Sateler">
June 21, 2006">
1">
fsateler@gmail.com">
installwatch">
Debian">
GNU">
GPL">
]>
&dhemail;
&dhfirstname;
&dhsurname;
2006&dhusername;
&dhdate;
&dhucpackage;
&dhsection;
&dhpackage;Track installation of software&dhpackage;optionscommandDESCRIPTION&dhpackage; is a program that is used in order
to track the changes made while installing local software (i.e.
"make install"). It monitors the requested command, and produces
a log which indicates all created and modified files. By default
it outputs to syslog(3) using a priority
of "LOG_USER | LOG_INFO". This may be overridden by the use of the
flag. The log format is as follows:
<return-value> <syscall-name> <argument> #<comment>
Each field is delimited by a "⁁I" character if logging to
syslog(3), or by a tab when logging to a file.
ENVIRONMENTINSTALLWATCH_BACKUP_PATHSet this variable to the location that you want
installwatch to copy the original version of files which
get modified. The directory will be created if it does
not exist, assuming that the parent is writable.OPTIONSThese program follow the usual &gnu; command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below.Directs that output from the logged command be written to
the filename specified. If the specified file already exists,
it will be truncated.Sets the directory under which meta-info and translated
files will be stored.Toggle translation capabilities.Sets a comma separated neutral directory list, that won't
be concerned by translation or backups.Specify a debug file.Sets the debug level to be used.Show help information.BUGS
&dhpackage; does not work with programs which are statically linked with
libc. Due to LD_PRELOAD limitations, it does not work with suid programs
(this would probably introduce security problems, anyway).
mknod(2) is not monitored.
AUTHORThis manual page was written by &dhusername; <&dhemail;> for
the &debian; system (but may be used by others). Original text
by Greg Norris <adric@debian.org>. Permission is
granted to copy, distribute and/or modify this document under
the terms of the &gnu; General Public License, Version 2.
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
ssgelm-checkinstall-59a004a/installwatch/ 0000775 0000000 0000000 00000000000 15235417303 0020473 5 ustar 00root root 0000000 0000000 ssgelm-checkinstall-59a004a/installwatch/BUGS 0000664 0000000 0000000 00000000527 15235417303 0021162 0 ustar 00root root 0000000 0000000 Here's a list of things that need to be fixed, in no particular order.
* Installwatch does not work with programs that statically link libc.
Uhm... I should take a look at strace(1)
* Due to LD_PRELOAD limitations, it does not work with suid binaries
neither. Believe me, this is a very good thing anyway :-)
* mknod(2) is not watched
ssgelm-checkinstall-59a004a/installwatch/CHANGELOG 0000664 0000000 0000000 00000006052 15235417303 0021710 0 ustar 00root root 0000000 0000000 20061101 --
* getwcd() patch from David Brown
* utimes() support from David Brown
* access() support from David Brown
* Makefile patch from Felipe Sateler
20040613 -- version 0.7.0beta4
* _init() patch
20031214 -- version 0.7.0beta3
* fopen64() patch
20030312 -- version 0.7.0beta2 -- Thomas Rausch
* Small patch for correct symlink call reporting
20021125 -- version 0.7.0beta1 -- olivier fleurigeon
* Added translation fs support
20011122 -- version 0.6.3 -- olivier fleurigeon
* Fixed the test-installwatch test program.
20011118 -- version 0.6.2 -- Felipe Sanchez
* Fixed two other descriptor leaks that were causing the "Too many open files"
problem when tracing large installations.
20011111 -- olivier fleurigeon
* Patched installwatch.c to trace the fopen() call
20010625 -- version 0.6.1 -- Felipe Sanchez
* Fixed the installwatch shell script to make it report the return status from
the watched program
20010624 -- David Jarvie
* Patched create-localdecls to correctly detect the libc version in systems
without a libc-2* file
20010610 -- Christian Tusche
* Patched installwatch.c to make it close the file descriptors in backup().
This prevents the "Too many open files" problem when a watched program
opens lots of files in one run (i.e. cp -vr / /some/dir)
20010608 -- version 0.6.0 -- Felipe Sanchez
* The backup actually works now ;)
20010415 -- version 0.6.0beta -- Felipe Sanchez
* Added functions: backup() and makepath(). Installwatch now can make a backup
of any file that will be overwritten or deleted by the true glibc functions.
20010301 -- version 0.5.6 -- Development now continued by
Felipe Eduardo Sanchez Diaz Duran
* Removed the RTLD_NEXT line, we'll deal with all glibc's as if they were
broken.
19990514 -- version 0.5.5
* Added support for glibc2.1 (used for example in RedHat 6.0)
* Added a test program (run "make test" to see if installwatch works
correctly with your configuration)
19990331 -- version 0.5.4
* inst2rpm: patch from nbecker@fred.net to detect and use renamed
and linked files (often used by install.sh scripts)
19990325 -- version 0.5.3
* Fixed canonicize(). It always returns absolute paths now
Thanks to Jon A. Christopher
* Renamed canonicize() to canonicalize(), which happens to be an
existing word :-)
* Improved inst2rpm script from Jon
19981107 -- version 0.5.2
* Fixed a bug regarding non-absolute paths used with the -o option.
Thanks to Jon A. Christopher for pointing this
out
* Greg Norris has volunteered to maintain then
Debian package of installwatch. Thanks Greg!
* Added the contrib section. Thanks to
Jon A. Christopher , first contributor with the
inst2rpm script. Very useful!
19980930 -- version 0.5.1
* Added libc5 support
* Cosmetic fixes on the documentation
* Removed support for mknod(2), I'll add it again later
ssgelm-checkinstall-59a004a/installwatch/COPYING 0000664 0000000 0000000 00000043100 15235417303 0021524 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
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.
Copyright (C)
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 .
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.
, 1 April 1989
Moe Ghoul, 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.
ssgelm-checkinstall-59a004a/installwatch/INSTALL 0000664 0000000 0000000 00000001750 15235417303 0021527 0 ustar 00root root 0000000 0000000 Installwatch has been tested on Linux only.
To compile it, a simple `make' followed by `make install' should do
the magic.
By default, it will install itself to /usr/local/{bin,lib}
but you can change that by specifying PREFIX during install as in
make
make PREFIX=/usr install
Also, for packagers and such, Makefile obeys DESTDIR ala Autotools.
You need an ELF system, but I don't think it's a problem today...
Let me know if things go wrong. My address is izto@mayams.net
Don't forget to tell me your OS version, libraries version and every
other relevant detail.
If you want to try installwatch on itself for the first time, do
the following instead of `make install'.
Bash family:
LD_PRELOAD=./installwatch.so make install
Tcsh family:
setenv LD_PRELOAD ./installwatch.so ; make install
Of course, you must be root in the installwatch source directory.
Remember, if you belong to the tcsh family, LD_PRELOAD will remain
set after `make install', so be sure to clear the variable.
ssgelm-checkinstall-59a004a/installwatch/Makefile 0000664 0000000 0000000 00000002771 15235417303 0022142 0 ustar 00root root 0000000 0000000 # Makefile for installwatch
# Well, the only configurable part is the following variable.
# Make sure the directory you specify exists.
PREFIX=/usr/local
# End of configurable part
VERSION=0.7.0beta7
BINDIR=$(PREFIX)/bin
LIBDIR=$(PREFIX)/lib
LIBGCC=`gcc -print-libgcc-file-name`
all: installwatch.so
installwatch.so: installwatch.o
# --build-id: linking with ld rather than gcc means nothing adds the
# note otherwise, and without it there are no separate debug symbols.
ld --build-id -znow -shared -o installwatch.so installwatch.o -ldl -lc $(LIBGCC)
installwatch.o: installwatch.c localdecls.h
gcc $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -c -g -D_GNU_SOURCE -DPIC -fPIC -D_REENTRANT -DVERSION=\"$(VERSION)\" installwatch.c
localdecls.h: create-localdecls
./create-localdecls
install: all
mkdir -p $(LIBDIR)
mkdir -p $(BINDIR)
if [ -r $(LIBDIR)/installwatch.so ]; then \
rm -f $(LIBDIR)/installwatch.so; \
fi
install installwatch.so $(LIBDIR)
sed -e "s|#PREFIX#|$(PREFIX)|" < installwatch > $(BINDIR)/installwatch
chmod 755 $(BINDIR)/installwatch
uninstall:
rm -f $(LIBDIR)/installwatch.so
rm -f $(BINDIR)/installwatch
clean:
rm -f *~ *.bak *.o installwatch.so core localdecls.h libcfiletest libctest test-installwatch
tarball: clean
tar -czvC .. -f ../installwatch-$(VERSION).tar.gz installwatch-$(VERSION)
test: install
gcc -Wall -DVERSION=\"$(VERSION)\" -DLIBDIR=\"$(LIBDIR)\" -o test-installwatch test-installwatch.c -ldl
PREFIX=$(PREFIX) $(PREFIX)/bin/installwatch ./test-installwatch
ssgelm-checkinstall-59a004a/installwatch/README 0000664 0000000 0000000 00000006665 15235417303 0021370 0 ustar 00root root 0000000 0000000 ######################################
# Welcome to installwatch 0.7.0beta7 #
######################################
================
The short story:
Installwatch is Copyright 1998 by Pancrazio `Ezio' de Mauro
* Installwatch is no longer mantained by Pancrazio, you should now contact
me with any issues relating to it:
Felipe Eduardo Sanchez Diaz Duran
http://asic-linux.com.mx/~izto
This package is distributed under the GPL license. Have a look at
COPYING if you don't know what it means.
To use it, just type:
installwatch
This monitors and logs using the syslog(3) facility every created
or modified file.
installwatch -o
does the same thing, but writing data in , which is truncated
if it already exixts.
The typical use is:
installwatch -o ~/install/foobar-x.y make install
Extra options are displayed by running:
installwatch --help
===============
The long story:
Installwatch is an extremely simple utility I wrote to keep track of
created and modified files during the installation of a new program.
It's fast and easy to use. It doesn't require a ``pre-install'' phase
because it monitors processes while they run.
Installwatch works with every dynamically linked ELF program,
overriding system calls that cause file system alterations. Some of
such system calls are open(2) and unlink(2).
Installwatch is especially useful on RedHat, Debian and similar
distributions, where you can use a package system to keep track
of installed software. (See specific package details below).
Of course a simple `make install' does not update the package database,
making your installation ``dirty'' -- well, kind of.
If your room is a mess but you make RPMS even for your home directory,
then installwatch is for you. (See RPMS below).
Here's a typical installwatch use. After compiling your brand new
package, just type
installwatch make install
instead of a simple make install. Then have a look at your logs.
Installwatch logs by default using syslog(3), with a
``LOG_USER | LOG_INFO'' priority.
Usually the log file is /var/log/messages, but if may vary.
If you want to log on a particular file (my preferred method) just
type:
installwatch -o filename make install
The log format may look ugly at first glance, but it is designed to
be easily processed by programs.
Every record ends with a newline, every field is delimited with a TAB
character (it is ``^I'' when you use syslog.)
The fields of a record are, in order:
#
So made lines are really easy to process, if arguments don't contain
TABs or pound signs.
=====
RPMS:
Ok, so you've done a "installwatch -o logfile make install", but how do
you tell the RPM database about this? You use CheckInstall.
http://asic-linux.com.mx/~izto/checkinstall
The inst2rpm script that used to be distributed along with installwatch
is not supported by me, it has been superseeded by CheckInstall.
If you still want it, you can get an older version of installwatch (0.5.6),
where you will find it inside the contrib directory. Installwatch's versions
starting from 0.5.5 are available at
http://asic-linux.com.mx/~izto/installwatch.html
ssgelm-checkinstall-59a004a/installwatch/TODO 0000664 0000000 0000000 00000000562 15235417303 0021166 0 ustar 00root root 0000000 0000000 Here's a list of things I would like to add, in no particular order.
If you can/want to contribute, send me a message: izto@asic-linux.com.mx
* Make it work with statically linked programs (see BUGS)
* Make it as portable as possible. I only tested installwatch with
Linux, but it should work with other systems with
Solaris comes in mind
* Use autoconf
ssgelm-checkinstall-59a004a/installwatch/VERSION 0000664 0000000 0000000 00000000013 15235417303 0021535 0 ustar 00root root 0000000 0000000 0.7.0beta7
ssgelm-checkinstall-59a004a/installwatch/create-localdecls 0000775 0000000 0000000 00000004120 15235417303 0023764 0 ustar 00root root 0000000 0000000 #!/bin/sh
# This is a quick'n'dirty hack to make the program behave correctly
# under different systems.
# Example:
# when using libc5, (f)trucate's offset argument type is size_t with
# libc5, but it's off_t with libc6 (glibc2).
#
# Uhm... time to learn GNU autoconf :-)
OUTFILE='localdecls.h'
echo '/* This file is automatically generated *' > $OUTFILE
echo ' * Modify create-localdecls instead of this */' >> $OUTFILE
echo >> $OUTFILE
echo '#ifndef __LOCALDECLS_H_' > $OUTFILE
echo '#define __LOCALDECLS_H_' >> $OUTFILE
echo >> $OUTFILE
###
###
###
echo -n 'Checking truncate argument type... '
if grep -q 'truncate.*size_t' /usr/include/unistd.h ; then
echo 'size_t'
echo '#define TRUNCATE_T size_t' >> $OUTFILE
else
echo 'off_t' # At least, I HOPE it's off_t :-)
echo '#define TRUNCATE_T off_t' >> $OUTFILE
fi
echo -n 'Checking readlinkat result type... '
if grep -q 'ssize_t.*readlinkat' /usr/include/unistd.h ; then
echo 'ssize_t'
echo '#define READLINKAT_T ssize_t' >> $OUTFILE
else
echo 'int' # according to man page
echo '#define READLINKAT_T int' >> $OUTFILE
fi
###
###
###
echo -n 'Checking which libc we are using... '
gcc -Wall -o libcfiletest libcfiletest.c
LIBC_FILE=`ldd libcfiletest | grep libc\\.so | awk '{print $1}'`
echo $LIBC_FILE
echo "#define LIBC_FILE \"$LIBC_FILE\"" >> $OUTFILE
case "$LIBC_FILE" in
libc.so.5)
echo '#define BROKEN_RTLD_NEXT' >> $OUTFILE
echo '#define LIBC 5' >> $OUTFILE
;;
# alpha and ia64 call it libc.so.6.1
libc.so.6 | libc.so.6.*)
echo -n 'Checking libc version... '
gcc -Wall -o libctest libctest.c
LIBC_VERSION=`./libctest`
echo $LIBC_VERSION
echo "#define LIBC_VERSION \"$LIBC_VERSION\"" >> $OUTFILE
echo -en 'glibc >= 2 found\nChecking glibc subversion... '
OsLibcMajor=`echo $LIBC_VERSION | cut -f1 -d.`
OsLibcMinor=`echo $LIBC_VERSION | cut -f2 -d.`
echo "#define GLIBC_MAJOR $OsLibcMajor" >> $OUTFILE
echo "#define GLIBC_MINOR $OsLibcMinor" >> $OUTFILE
echo $OsLibcMinor
;;
*)
echo "Unknown libc found ($LIBC_FILE). Please update the create-localdecls script."
exit 1
;;
esac
echo >> $OUTFILE
echo '#endif' >> $OUTFILE
ssgelm-checkinstall-59a004a/installwatch/installwatch 0000775 0000000 0000000 00000016067 15235417303 0023130 0 ustar 00root root 0000000 0000000 #!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
#set -x
PREFIX=${PREFIX:-#PREFIX#}
HACK="PREFIX"
HACK="#$HACK#";
if test "$PREFIX" = "$HACK" ; then
echo 'This script has not been installed'
echo 'Please run "make install"'
exit 1
fi
LIBDIR=$DESTDIR$PREFIX/lib
LIB64_PLATFORM=false
case `uname -m` in
x86_64|ppc64|s390x)
LIB64_PLATFORM=true
;;
esac
if test -d $PREFIX/lib64 && test "$LIB64_PLATFORM" = "true" ; then
LIBDIR=$PREFIX/lib64
else
LIBDIR=$PREFIX/lib
fi
BASE_TMP_DIR=/tmp
INSTALLWATCH_VERSION=0.7.0beta7
#
# ##############################################################################
#
# Function definitions
#
#
function ckversion {
echo
echo -n "installwatch $INSTALLWATCH_VERSION, "
echo "Copyright 1998 Pancrazio de Mauro"
echo "Copyright 2010 Felipe Eduardo Sanchez Diaz Duran"
echo " This software is released under the GNU GPL."
}
function usage() {
(
ckversion
echo
echo "Usage: installwatch [options] [command [command arguments]]"
echo "Options:"
echo
echo "-r, --root= Sets the directory under which will be stored "
echo " meta-infos and translated files. "
echo "-t, --transl= Toggle translation capabilities "
echo "-b, --backup= Toggle backup capabilities "
echo "-e, --exclude= Sets a neutral directory list, that won't be"
echo " concerned by translation or backups. "
echo "-o, --logfile= Sets the log file to be used. "
echo "-d, --dbgfile= Sets the debug file to be used. "
echo "-v, --dbglvl= Sets the debug level to be used. "
)
exit 1
}
function help_notice() {
echo
echo "Use --help or -h to get more information"
echo
exit 1
}
function boolean_usage() {
echo
echo "$2 is an invalid value for $1"
help_notice
exit 1
}
function make_temp {
local mkt_refdir=$1
local mkt_wrkdir=""
mkt_wrkdir=`mktemp -q -d -p ${BASE_TMP_DIR}`
eval $mkt_refdir=\$mkt_wrkdir
}
#
#
# Function definitions
#
# ##############################################################################
#
#
# ##############################################################################
#
# Options and arguments parsing and validation
#
#
CKNAME=`basename $0`
PARAMS=`getopt -a -n $CKNAME -o +r:e:o:d:v:tb -l root:,transl:,backup:,exclude:,logfile:,dbgfile:,dbglvl:,help,version,copyright -- "$@"`
[ $? -gt 0 ] && help_notice
eval set -- $PARAMS
unset INSTW_ROOTPATH
unset INSTW_TRANSL
unset INSTW_BACKUP
unset INSTW_LOGFILE
unset INSTW_DBGFILE
unset INSTW_DBGLVL
unset INSTW_EXCLUDE
while [ "$1" != "--" ]; do
case "$1" in
-h|-H|--help)
usage;;
-r|--root)
shift
INSTW_ROOTPATH=`eval echo $1`
;;
-e|--exclude)
shift
INSTW_EXCLUDE=`eval echo $1`
;;
-o|--logfile)
shift
INSTW_LOGFILE=`eval echo $1`
;;
-d|--dbgfile)
shift
INSTW_DBGFILE=`eval echo $1`
;;
-v|--dbglvl)
shift
INSTW_DBGLVL=`eval echo $1`
;;
-t)
INSTW_TRANSL=1
;;
--transl)
shift
case `eval echo $1` in
"1"|"yes"|"")
INSTW_TRANSL=1
;;
"0"|"no")
INSTW_TRANSL=0
;;
*)
boolean_usage "--transl" $1
esac
;;
-b)
INSTW_BACKUP=1
;;
--backup)
shift
case `eval echo $1` in
"1"|"yes"|"")
INSTW_BACKUP=1
;;
"0"|"no")
INSTW_BACKUP=0
;;
*)
boolean_usage "--backup" $1
esac
;;
--copyright|--version)
cat << EOF
Copyright (C) 1998 Pancrazio 'Ezio' de Mauro
Copyright (C) 2010 Felipe Eduardo Sanchez Diaz Duran
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 .
EOF
exit 0
;;
esac
shift
done
#
# ##############################################
#
# do we have an installation process command
shift
if [ "$1" = "" ]; then
echo
echo "Error : You must specify a command !!!"
echo
usage
exit 1
fi
if [ -u "$1" ]; then
echo "Warning: `basename $0` may not work with suid programs"
fi
# we must have a root path defined
if [ "${INSTW_ROOTPATH}_" = "_" ]; then
make_temp "INSTW_ROOTPATH"
echo
echo "INFO : Using a default root directory : ${INSTW_ROOTPATH}"
echo
fi
if [ ! -d "${INSTW_ROOTPATH}" ]; then
echo
echo "The root directory is mandatory ."
echo
usage
exit 1
fi
if [ "${INSTW_ROOTPATH:((${#INSTW_ROOTPATH}-1)):1}" = "/" ]; then
INSTW_ROOTPATH="${INSTW_ROOTPATH%/}"
fi
export INSTW_ROOTPATH
if [ "${INSTW_BACKUP}_" = "_" ]; then
INSTW_BACKUP=0;
fi
export INSTW_BACKUP
if [ "${INSTW_TRANSL}_" = "_" ]; then
INSTW_TRANSL=0;
fi
export INSTW_TRANSL
if [ "${INSTW_LOGFILE}_" = "_" ]; then
INSTW_LOGFILE="${INSTW_ROOTPATH}/logfile"
fi
export INSTW_LOGFILE
if [ "${INSTW_DBGFILE}_" = "_" ]; then
INSTW_DBGFILE="${INSTW_ROOTPATH}/dbgfile"
fi
export INSTW_DBGFILE
if [ "${INSTW_DBGLVL}_" = "_" ]; then
INSTW_DBGLVL=0
fi
export INSTW_DBGLVL
[ $INSTW_DBGLVL -gt 0 ] && echo "debug: INSTW_EXCLUD before sort =${INSTW_EXCLUDE}"
INSTW_EXCLUDE="/dev,/proc,/tmp,/var/tmp,${INSTW_EXCLUDE}"
OFS="$IFS"
IFS=','
INSTW_EXCLUDE=$(for name in $INSTW_EXCLUDE; do
echo $name
done | sort -u |
while read elem; do
echo -n "$elem,"
done)
export INSTW_EXCLUDE
IFS="$OIFS"
if [ "${INSTW_LOGFILE}_" != "_" ]; then
# If INSTW_LOGFILE is a relative path, it must become absolute
if echo ${INSTW_LOGFILE} | grep -qv '^/' ; then
INSTW_LOGFILE="$(pwd)/${INSTW_LOGFILE}"
fi
export INSTW_LOGFILE
if cat /dev/null >"${INSTW_LOGFILE}"; then
true
else
echo
echo "Error : Unable to prepare ${INSTW_LOGFILE}"
echo
exit 1
fi
fi
if [ "${INSTW_DBGFILE}_" != "_" ]; then
# If INSTW_DBGFILE is a relative path, it must become absolute
if echo ${INSTW_DBGFILE} | grep -qv '^/' ; then
INSTW_DBGFILE="$(pwd)/${INSTW_DBGFILE}"
fi
export INSTW_DBGFILE
if cat /dev/null >"${INSTW_DBGFILE}"; then
true
else
echo
echo "Error : Unable to prepare ${INSTW_DBGFILE}"
echo
exit 1
fi
fi
#
#
# Options and arguments parsing and validation
#
# ##############################################################################
#
if [ "$LD_PRELOAD" ]; then
LD_PRELOAD="$LIBDIR/installwatch.so:$LD_PRELOAD"
else
LD_PRELOAD="$LIBDIR/installwatch.so"
fi
export LD_PRELOAD
if [ $INSTW_DBGLVL -gt 0 ]; then
echo "debug: INSTW_EXCLUDE=${INSTW_EXCLUDE}"
echo "debug: INSTW_ROOTPATH=${INSTW_ROOTPATH}"
echo "debug: INSTW_LOGFILE=${INSTW_LOGFILE}"
echo "debug: INSTW_DBGFILE=${INSTW_DBGFILE}"
echo "debug: INSTW_DBGLVL=${INSTW_DBGLVL}"
fi
"$@"
if [ $? -eq 0 ]; then
FAIL=0
else
FAIL=1
fi
unset LD_PRELOAD
exit $FAIL
ssgelm-checkinstall-59a004a/installwatch/installwatch.c 0000664 0000000 0000000 00000416234 15235417303 0023346 0 ustar 00root root 0000000 0000000 /* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro
* Copyright (C) 2026 Stephen Gelman
*
* 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 .
*
*
* april-15-2001 - Modifications by Felipe Eduardo Sanchez Diaz Duran
*
* Added backup() and make_path() functions.
*
* november-25-2002 - Modifications by Olivier Fleurigeon
*
*
* march-31-2007 - Modifications by Frederick Emmott
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#undef basename
#include
#include
#include
#include
#include
/* There's no d_off on GNU/kFreeBSD */
#if defined(__FreeBSD_kernel__)
#define D_OFF(X) (-1)
#else
#define D_OFF(X) (X)
#endif
#include "localdecls.h"
#define DEBUG 1
#define LOGLEVEL (LOG_USER | LOG_INFO | LOG_PID)
#define BUFSIZE 1024
#define error(X) (X < 0 ? strerror(errno) : "success")
int __installwatch_refcount = 0;
int __installwatch_timecount = 0;
#define REFCOUNT __installwatch_refcount++
#define TIMECOUNT __installwatch_timecount++
static time_t (*true_time) (time_t *);
static int (*true_chdir)(const char *);
static int (*true_chmod)(const char *, mode_t);
static int (*true_chown)(const char *, uid_t, gid_t);
static int (*true_chroot)(const char *);
static int (*true_creat)(const char *, mode_t);
static int (*true_fchmod)(int, mode_t);
static int (*true_fchown)(int, uid_t, gid_t);
static FILE *(*true_fopen)(const char *,const char*);
static int (*true_ftruncate)(int, TRUNCATE_T);
static char *(*true_getcwd)(char*,size_t);
static int (*true_lchown)(const char *, uid_t, gid_t);
static int (*true_link)(const char *, const char *);
static int (*true_mkdir)(const char *, mode_t);
static int (*true_xmknod)(int ver,const char *, mode_t, dev_t *);
static int (*true_open)(const char *, int, ...);
static DIR *(*true_opendir)(const char *);
static struct dirent *(*true_readdir)(DIR *dir);
static ssize_t (*true_readlink)(const char*,char *,size_t);
static char *(*true_realpath)(const char *,char *);
static int (*true_rename)(const char *, const char *);
static int (*true_rmdir)(const char *);
static int (*true_xstat)(int,const char *,struct stat *);
static int (*true_lxstat)(int,const char *,struct stat *);
#if(GLIBC_MINOR >= 10)
static int (*true_scandir)( const char *,struct dirent ***,
int (*)(const struct dirent *),
int (*)(const struct dirent **,const struct dirent **));
#else
static int (*true_scandir)( const char *,struct dirent ***,
int (*)(const struct dirent *),
int (*)(const void *,const void *));
#endif
static int (*true_symlink)(const char *, const char *);
static int (*true_truncate)(const char *, TRUNCATE_T);
static int (*true_unlink)(const char *);
static int (*true_utime)(const char *,const struct utimbuf *);
static int (*true_utimes)(const char *,const struct timeval *);
static int (*true_utimensat)(int, const char *, const struct timespec *, int);
/*
* Where time_t is 32 bits, a program built with _TIME_BITS=64 is given
* these entry points in place of the ordinary ones, and coreutils among
* others is built that way. We never look inside the buffer a caller hands
* us, so it stays a void * here and only the path needs translating.
* Build installwatch itself that way, as armhf does by default, and
* glibc renames the wrappers below to these same symbols. Defining them
* again is then a duplicate, so leave that to the renaming.
*/
#if defined(__TIMESIZE) && __TIMESIZE == 32 && \
!defined(__USE_TIME_BITS64) && !defined(__USE_TIME64_REDIRECTS)
#define WRAP_TIME64_ENTRY_POINTS
#endif
#ifdef WRAP_TIME64_ENTRY_POINTS
static int (*true_stat64_time64)(const char *, void *);
static int (*true_lstat64_time64)(const char *, void *);
static int (*true_fstatat64_time64)(int, const char *, void *, int);
static int (*true_utime64)(const char *, const void *);
static int (*true_utimes64)(const char *, const void *);
static int (*true_utimensat64)(int, const char *, const void *, int);
#endif
static int (*true_access)(const char *, int);
static int (*true_setxattr)(const char *,const char *,const void *,
size_t, int);
static int (*true_removexattr)(const char *,const char *);
static int (*true_creat64)(const char *, __mode_t);
static FILE *(*true_fopen64)(const char *,const char *);
static int (*true_ftruncate64)(int, __off64_t);
static int (*true_open64)(const char *, int, ...);
static struct dirent64 *(*true_readdir64)(DIR *dir);
#if(GLIBC_MINOR >= 10)
static int (*true_scandir64)( const char *,struct dirent64 ***,
int (*)(const struct dirent64 *),
int (*)(const struct dirent64 **,const struct dirent64 **));
#else
static int (*true_scandir64)( const char *,struct dirent64 ***,
int (*)(const struct dirent64 *),
int (*)(const void *,const void *));
#endif
static int (*true_xstat64)(int,const char *, struct stat64 *);
static int (*true_lxstat64)(int,const char *, struct stat64 *);
static int (*true_truncate64)(const char *, __off64_t);
static int (*true_openat)(int, const char *, int, ...);
static int (*true_fchmodat)(int, const char *, mode_t, int);
static int (*true_fchownat)(int, const char *, uid_t, gid_t, int);
static int (*true_fxstatat)(int, int, const char *, struct stat *, int);
static int (*true_fxstatat64)(int, int, const char *, struct stat64 *, int);
static int (*true_linkat)(int, const char *, int, const char *, int);
static int (*true_mkdirat)(int, const char *, mode_t);
static int (*true_readlinkat)(int, const char *, char *, size_t);
static int (*true_xmknodat)(int, int, const char *, mode_t, dev_t *);
static int (*true_renameat)(int, const char *, int, const char *);
static int (*true_renameat2)(int, const char *, int, const char *);
static int (*true_symlinkat)(const char *, int, const char *);
static int (*true_unlinkat)(int, const char *, int);
/*
* statx() arrived in glibc 2.28 and has no older form to stand in for
* it. coreutils calls it directly, so it needs a wrapper of its own.
* Without one, a translated file is invisible to ls(1), stat(1) and
* anything else that asks this way.
*/
#if (GLIBC_MINOR >= 28)
static int (*true_statx)(int, const char *, int, unsigned int,
struct statx *);
#endif
/* These functions open their files internally, bypassing open(). */
static int (*true_mkstemp)(char *);
static int (*true_mkstemp64)(char *);
static int (*true_mkostemp)(char *, int);
static int (*true_mkostemp64)(char *, int);
static int (*true_mkstemps)(char *, int);
static int (*true_mkstemps64)(char *, int);
static int (*true_mkostemps)(char *, int, int);
static int (*true_mkostemps64)(char *, int, int);
static char *(*true_mkdtemp)(char *);
/* glibc 2.33 exports these names directly. Keep the __xstat wrappers */
/* below for binaries built against older glibc. */
#if (GLIBC_MINOR >= 33)
static int (*true_stat)(const char *, struct stat *);
static int (*true_stat64)(const char *, struct stat64 *);
static int (*true_mknod)(const char *, mode_t, dev_t);
static int (*true_lstat)(const char *, struct stat *);
static int (*true_lstat64)(const char *, struct stat64 *);
static int (*true_fstatat)(int, const char *, struct stat *, int);
static int (*true_fstatat64)(int, const char *, struct stat64 *, int);
static int (*true_mknodat)(int, const char *, mode_t, dev_t);
#endif
#if defined __GNUC__ && __GNUC__>=2
#define inline inline
#else
#define inline
#endif
#ifndef _STAT_VER
#if defined (__aarch64__) || defined(__riscv)
#define _STAT_VER 0
#elif defined (__s390x__)
# define _STAT_VER 1
#elif defined (__x86_64__)
#define _STAT_VER 1
#else
#define _STAT_VER 3
#endif
#endif
#ifndef _MKNOD_VER
#if defined (__aarch64__) || defined(__riscv)
#define _MKNOD_VER 0
#elif defined (__x86_64__)
#define _MKNOD_VER 0
#else
#define _MKNOD_VER 1
#endif
#endif
#if (GLIBC_MINOR < 33)
static inline int true_stat(const char *pathname,struct stat *info) {
return true_xstat(_STAT_VER,pathname,info);
}
static inline int true_mknod(const char *pathname,mode_t mode,dev_t dev) {
return true_xmknod(_MKNOD_VER,pathname,mode,&dev);
}
static inline int true_lstat(const char *pathname,struct stat *info) {
return true_lxstat(_STAT_VER,pathname,info);
}
static inline int true_fstatat(int dirfd, const char *pathname, struct stat *info, int flags) {
return true_fxstatat(_STAT_VER, dirfd, pathname, info, flags);
}
static inline int true_fstatat64(int dirfd, const char *pathname, struct stat64 *info, int flags) {
return true_fxstatat64(_STAT_VER, dirfd, pathname, info, flags);
}
static inline int true_mknodat(int dirfd, const char *pathname,mode_t mode,dev_t dev) {
return true_xmknodat(_MKNOD_VER, dirfd, pathname, mode, &dev);
}
#endif
/* A few defines to fix things a little */
#define INSTW_OK 0
/* If not set, no work with translation is allowed */
#define INSTW_INITIALIZED (1<<0)
/* If not set, a wrapped function only do its "real" job */
#define INSTW_OKWRAP (1<<1)
#define INSTW_OKBACKUP (1<<2)
#define INSTW_OKTRANSL (1<<3)
#define INSTW_TRANSLATED (1<<0)
/* Indicates that a translated file is identical to original */
#define INSTW_IDENTITY (1<<1)
/* The file currently exists in the root filesystem */
#define INSTW_ISINROOT (1<<6)
/* The file currently exists in the translated filesystem */
#define INSTW_ISINTRANSL (1<<7)
#define _BACKUP "/BACKUP"
#define _TRANSL "/TRANSL"
/* The root that contains all the needed metas-infos */
#define _META "/META"
/* We store under this subtree the translated status */
#define _MTRANSL _TRANSL
/* We construct under this subtree fake directory listings */
#define _MDIRLS "/DIRLS"
/* String cell used to chain excluded paths */
typedef struct string_t string_t;
struct string_t {
char *string;
string_t *next;
};
/* Used to keep all infos needed to cope with backup, translated fs... */
typedef struct instw_t {
/*
* global fields
*/
int gstatus;
int dbglvl;
pid_t pid;
char *root;
char *backup;
char *transl;
char *meta;
char *mtransl;
char *mdirls;
/* the list of all the paths excluded from translation */
string_t *exclude;
/*
* per instance fields
*/
int error;
int status;
/* the public path, hiding translation */
char path[PATH_MAX+1];
/* the public resolved path, hiding translation */
char reslvpath[PATH_MAX+1];
/* the real resolved path, exposing tranlsation */
char truepath[PATH_MAX+1];
/* the real translated path */
char translpath[PATH_MAX+1];
/* the list of all the equiv paths conducing to "reslvpath" */
string_t *equivpaths;
/* the real path used to flag translation status */
char mtranslpath[PATH_MAX+1];
/* the path given to a wrapped opendir */
char mdirlspath[PATH_MAX+1];
} instw_t;
static instw_t __instw;
static int canonicalize(const char *,char *);
static int reduce(char *);
static int make_path(const char *);
static int copy_path(const char *,const char *);
static const char *resolve_parent(const char *,char *,size_t);
static const char *resolve_dir(const char *,char *,size_t);
static inline int path_excluded(const char *);
static int unlink_recursive(const char *);
int expand_path(string_t **,const char *,const char *);
int parse_suffix(char *,char *,const char *);
/* a lazy way to avoid sizeof */
#define mallok(T,N) (T *)malloc((N)*sizeof(T))
/* single method used to minimize excessive returns */
#define finalize(code) {rcod=code;goto finalize;}
#if DEBUG
#ifndef __USE_FILE_OFFSET64
static int __instw_printdirent(struct dirent*);
#endif
static int __instw_printdirent64(struct dirent64*);
#endif
#ifdef DEBUG
static int instw_print(instw_t *);
#endif
static int instw_init(void);
static int instw_fini(void);
static int instw_new(instw_t *);
static int instw_delete(instw_t *);
/* references a translated file in /mtransl */
static int instw_setmetatransl(instw_t *);
static int instw_setpath(instw_t *,const char *);
static int instw_setpathrel(instw_t *, int, const char *);
static int instw_getstatus(instw_t *,int *);
static int instw_apply(instw_t *);
static int instw_filldirls(instw_t *);
static int instw_makedirls(instw_t *);
static int backup(const char *);
static int vlambda_log(const char *logname,const char *format,va_list ap);
/*
static int lambda_log(const char *logname,const char *format,...)
#ifdef __GNUC__
__attribute__((format(printf,2,3)))
#endif
;
*/
static inline int logg(const char *format,...)
#ifdef __GNUC__
/* Tell gcc that this function behaves like printf()
* for parameters 1 and 2 */
__attribute__((format(printf, 1, 2)))
#endif /* defined __GNUC__ */
;
static inline int debug(int dbglvl,const char *format,...)
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
;
#define unset_okwrap() (__instw.gstatus &= ~INSTW_OKWRAP)
#define reset_okwrap() (__instw.gstatus |= INSTW_OKWRAP)
/*
* *****************************************************************************
*/
static void *libc_handle=NULL;
static void initialize(void) {
if (libc_handle)
return;
#ifdef BROKEN_RTLD_NEXT
// printf ("RTLD_LAZY");
libc_handle = dlopen(LIBC_FILE, RTLD_LAZY);
#else
// printf ("RTLD_NEXT");
libc_handle = RTLD_NEXT;
#endif
true_time = dlsym(libc_handle, "time");
true_chdir = dlsym(libc_handle, "chdir");
true_chmod = dlsym(libc_handle, "chmod");
true_chown = dlsym(libc_handle, "chown");
true_chroot = dlsym(libc_handle, "chroot");
true_creat = dlsym(libc_handle, "creat");
true_fchmod = dlsym(libc_handle, "fchmod");
true_fchown = dlsym(libc_handle, "fchown");
true_fopen = dlsym(libc_handle, "fopen");
true_ftruncate = dlsym(libc_handle, "ftruncate");
true_getcwd = dlsym(libc_handle, "getcwd");
true_lchown = dlsym(libc_handle, "lchown");
true_link = dlsym(libc_handle, "link");
true_mkdir = dlsym(libc_handle, "mkdir");
true_xmknod = dlsym(libc_handle, "__xmknod");
true_open = dlsym(libc_handle, "open");
true_opendir = dlsym(libc_handle, "opendir");
true_readdir = dlsym(libc_handle, "readdir");
true_readlink = dlsym(libc_handle, "readlink");
true_realpath = dlsym(libc_handle, "realpath");
true_rename = dlsym(libc_handle, "rename");
true_rmdir = dlsym(libc_handle, "rmdir");
true_scandir = dlsym(libc_handle, "scandir");
true_xstat = dlsym(libc_handle, "__xstat");
true_lxstat = dlsym(libc_handle, "__lxstat");
true_symlink = dlsym(libc_handle, "symlink");
true_truncate = dlsym(libc_handle, "truncate");
true_unlink = dlsym(libc_handle, "unlink");
true_utime = dlsym(libc_handle, "utime");
true_setxattr = dlsym(libc_handle, "setxattr");
true_utimes = dlsym(libc_handle, "utimes");
true_utimensat = dlsym(libc_handle, "utimensat");
#ifdef WRAP_TIME64_ENTRY_POINTS
true_stat64_time64 = dlsym(libc_handle, "__stat64_time64");
true_lstat64_time64 = dlsym(libc_handle, "__lstat64_time64");
true_fstatat64_time64 = dlsym(libc_handle, "__fstatat64_time64");
true_utime64 = dlsym(libc_handle, "__utime64");
true_utimes64 = dlsym(libc_handle, "__utimes64");
true_utimensat64 = dlsym(libc_handle, "__utimensat64");
#endif
true_access = dlsym(libc_handle, "access");
true_creat64 = dlsym(libc_handle, "creat64");
true_fopen64 = dlsym(libc_handle, "fopen64");
true_ftruncate64 = dlsym(libc_handle, "ftruncate64");
true_open64 = dlsym(libc_handle, "open64");
true_readdir64 = dlsym(libc_handle, "readdir64");
true_scandir64 = dlsym(libc_handle, "scandir64");
true_xstat64 = dlsym(libc_handle, "__xstat64");
true_lxstat64 = dlsym(libc_handle, "__lxstat64");
true_truncate64 = dlsym(libc_handle, "truncate64");
true_removexattr = dlsym(libc_handle, "removexattr");
true_openat = dlsym(libc_handle, "openat");
true_fchmodat = dlsym(libc_handle, "fchmodat");
true_fchownat = dlsym(libc_handle, "fchownat");
true_fxstatat = dlsym(libc_handle, "__fxstatat");
true_fxstatat64 = dlsym(libc_handle, "__fxstatat64");
true_linkat = dlsym(libc_handle, "linkat");
true_mkdirat = dlsym(libc_handle, "mkdirat");
true_readlinkat = dlsym(libc_handle, "readlinkat");
true_xmknodat = dlsym(libc_handle, "__xmknodat");
true_renameat = dlsym(libc_handle, "renameat");
true_renameat2 = dlsym(libc_handle, "renameat2");
true_symlinkat = dlsym(libc_handle, "symlinkat");
true_unlinkat = dlsym(libc_handle, "unlinkat");
#if (GLIBC_MINOR >= 28)
true_statx = dlsym(libc_handle, "statx");
#endif
true_mkstemp = dlsym(libc_handle, "mkstemp");
true_mkstemp64 = dlsym(libc_handle, "mkstemp64");
true_mkostemp = dlsym(libc_handle, "mkostemp");
true_mkostemp64 = dlsym(libc_handle, "mkostemp64");
true_mkstemps = dlsym(libc_handle, "mkstemps");
true_mkstemps64 = dlsym(libc_handle, "mkstemps64");
true_mkostemps = dlsym(libc_handle, "mkostemps");
true_mkostemps64 = dlsym(libc_handle, "mkostemps64");
true_mkdtemp = dlsym(libc_handle, "mkdtemp");
#if (GLIBC_MINOR >= 33)
true_stat = dlsym(libc_handle, "stat");
true_stat64 = dlsym(libc_handle, "stat64");
true_mknod = dlsym(libc_handle, "mknod");
true_mknodat = dlsym(libc_handle, "mknodat");
true_lstat = dlsym(libc_handle, "lstat");
true_lstat64 = dlsym(libc_handle, "lstat64");
true_fstatat = dlsym(libc_handle, "fstatat");
true_fstatat64 = dlsym(libc_handle, "fstatat64");
#endif
if(instw_init()) exit(-1);
}
void _init(void) {
initialize();
}
void _fini(void) {
instw_fini();
}
/*
* *****************************************************************************
*/
/*
* procedure = / rc:=vlambda_log(logname,format,ap) /
*
* task = / the va_list version of the lambda_log() procedure. /
*/
static int vlambda_log(const char *logname,const char *format,va_list ap) {
char buffer[BUFSIZE];
int count;
int logfd;
int rcod=0;
int s_errno;
/* save errno */
s_errno = errno;
buffer[BUFSIZE-2] = '\n';
buffer[BUFSIZE-1] = '\0';
count=vsnprintf(buffer,BUFSIZE,format,ap);
if(count == -1) {
/* The buffer was not big enough */
strcpy(&(buffer[BUFSIZE - 5]), "...\n");
count=BUFSIZE-1;
}
else
{
count = strlen(buffer);
}
if(logname!=NULL) {
logfd=true_open(logname,O_WRONLY|O_CREAT|O_APPEND,0666);
if(logfd>=0) {
if(write(logfd,buffer,count)!=count)
syslog( LOGLEVEL,
"Count not write `%s' in `%s': %s\n",
buffer,logname,strerror(errno));
if(close(logfd) < 0)
syslog( LOGLEVEL,
"Could not close `%s': %s\n",
logname,strerror(errno));
} else {
syslog( LOGLEVEL,
"Could not open `%s' to write `%s': %s\n",
logname,buffer,strerror(errno));
}
} else {
syslog(LOGLEVEL, "%s", buffer);
}
/* restore errno */
errno = s_errno;
return rcod;
}
/*
* procedure = / rc:=lambda_log(logname,format,...) /
*
* task = / logs a message to the specified file, or via syslog
* if no file is specified. /
*
* returns = / 0 ok. message logged /
*
* note = /
* --This *general* log procedure was justified by the debug mode
* which used either stdout or stderr, thus interfering with the
* observed process.
* --From now, we output nothing to stdout/stderr.
* /
*
*/
/*
static int lambda_log(const char *logname,const char *format, ...) {
va_list ap;
int rcod=0;;
va_start(ap,format);
rcod=vlambda_log(logname,format,ap);
va_end(ap);
return rcod;
}
*/
static inline int logg(const char *format,...) {
char *logname;
va_list ap;
int rcod;
logname=getenv("INSTW_LOGFILE");
va_start(ap,format);
rcod=vlambda_log(logname,format,ap);
va_end(ap);
return rcod;
}
static inline int debug(int dbglvl,const char *format,...) {
int rcod=0;
#ifdef DEBUG
char *logname;
va_list ap;
if( __instw.dbglvl==0 ||
dbglvl>__instw.dbglvl ||
dbglvl<0 ) return rcod;
logname=getenv("INSTW_DBGFILE");
va_start(ap,format);
rcod=vlambda_log(logname,format,ap);
va_end(ap);
#endif
return rcod;
}
/*
* procedure = / rc:=canonicalize(path,resolved_path) /
*
* note = /
* --We use realpath here, but this function calls __lxstat().
* We want to only use "real" calls in wrapping code, hence the
* barrier established by unset_okwrap()/reset_okwrap().
* --We try to canonicalize as much as possible, considering that
* /
*/
static int canonicalize(const char *path, char *resolved_path) {
int s_errno;
/* save errno */
s_errno = errno;
unset_okwrap();
if(!realpath(path,resolved_path)) {
if((path[0] != '/')) {
/* The path could not be canonicalized, append it
* to the current working directory if it was not
* an absolute path */
true_getcwd(resolved_path, PATH_MAX-2);
resolved_path[MAXPATHLEN-2] = '\0';
strcat(resolved_path, "/");
strncat(resolved_path, path, MAXPATHLEN - 1 - strlen(resolved_path));
} else {
strcpy(resolved_path,path);
}
}
reset_okwrap();
#if DEBUG
debug(4,"canonicalize(%s,%s)\n",path,resolved_path);
#endif
/* restore errno */
errno = s_errno;
return 0;
}
/*
* procedure = / rc:=reduce(path) /
*
* task = / reduces all occurences of "..", ".", and extra "/" in path.
*
* inputs = / path The modifiable string containing the path
* outputs = / path The reduced path.
*
* returns = / 0 ok. path reduced
* -1 failed. cf errno /
* note = /
* --Very similar to canonicalize()/realpath() except we don’t do link-
* expansion
* --This is purely a string manipulation function (i.e., no verification
* of a path’s validity occurs).
* --Additionally, we try to do reduction “in-place†since the ending
* path is shorter than the beginning path.
* --Also, we want only absolute paths (other paths will throw an error)
* /
*/
static int reduce(char *path) {
int len;
char *off;
if(path == NULL || *path != '/') {
errno = EINVAL;
return -1;
}
len = strlen(path);
/* First, get rid of double / */
if((off = strstr(path, "//"))) {
memmove(off, off+1, len - (off-path));
return reduce(path);
}
/* Then, worry about /./ */
if((off = strstr(path, "/./"))) {
memmove(off, off+2, len - 1 - (off-path));
return reduce(path);
}
/* Finally, do /../ */
if((off = strstr(path, "/../"))) {
char *off2 = off;
if(off2++ != path)
while((--off2)[-1] != '/');
memmove(off2, off+4, len - 3 - (off-path));
return reduce(path);
}
/* Beautify ending */
switch(path[len - 1]) {
case '.':
switch(path[len - 2]) {
default:
return 0;
case '.':
if(len != 3) {
off = path+len-3;
if(*off-- != '/')
return 0;
while(*--off != '/');
off[1] = 0;
return reduce(path);
}
case '/': ;
}
case '/':
if(len != 1) {
path[len-1] = 0;
return reduce(path);
}
default:
return 0;
}
}
/*
* procedure = / result:=resolve_parent(path,canonical,canonsz) /
*
* task = / resolve the symlinks found in the directory part of 'path',
* leaving its last component untouched, and store the outcome
* in 'canonical', a buffer of 'canonsz' bytes.
*
* This matters when mirroring a path into a directory tree of
* our own, the backup area. We recreate the parent
* directories there with mkdir(), so a file reached through a
* symlinked directory such as /lib on a merged-/usr system
* lands under a real directory named 'lib'. Restore that tree
* over / and the /lib symlink becomes a directory, leaving
* the system unable to run a single binary.
*
* The last component stays as it is, on purpose: a symlink
* there has to be saved as a symlink. /
*
* returns = / 'canonical' on success, 'path' itself if the parent
* directory cannot be resolved or the result does not fit /
*/
static const char *resolve_parent(const char *path,char *canonical,size_t canonsz) {
char parent[PATH_MAX+1];
char resolved[PATH_MAX+1];
const char *base;
size_t plen,rlen;
int s_errno;
/* realpath() clobbers errno even when it succeeds */
s_errno=errno;
if((base=strrchr(path,'/'))==NULL) return path;
base++;
/* the parent is / itself (or path *is* /): nothing to resolve */
if((plen=base-path)<=1) return path;
/* everything but the trailing '/' */
if((plen-1)>PATH_MAX) return path;
memcpy(parent,path,plen-1);
parent[plen-1]='\0';
if(realpath(parent,resolved)==NULL) {
errno=s_errno;
return path;
}
/* realpath() only yields a trailing '/' for the root directory */
rlen=strlen(resolved);
if(rlen && resolved[rlen-1]=='/') resolved[--rlen]='\0';
if((rlen+1+strlen(base))>=canonsz) {
errno=s_errno;
return path;
}
strcpy(canonical,resolved);
canonical[rlen]='/';
strcpy(canonical+rlen+1,base);
errno=s_errno;
#if DEBUG
if(strcmp(path,canonical))
debug(3,"resolve_parent: %s -> %s\n",path,canonical);
#endif
return canonical;
}
/* Resolve an existing symlink to a directory, as mkdir() needs for */
/* aliases such as /lib -> /usr/lib. */
static const char *resolve_dir(const char *path,char *canonical,size_t canonsz) {
char resolved[PATH_MAX+1];
struct stat inode;
int s_errno;
/* realpath() and the failed stats clobber errno */
s_errno=errno;
if( true_lstat(path,&inode)==0 && S_ISLNK(inode.st_mode) &&
true_stat(path,&inode)==0 && S_ISDIR(inode.st_mode) &&
realpath(path,resolved)!=NULL &&
strlen(resolved) %s\n",path,canonical);
#endif
return canonical;
}
errno=s_errno;
return path;
}
static int make_path (const char *path) {
char checkdir[BUFSIZ];
struct stat inode;
int s_errno;
int i = 0;
/* save errno */
s_errno = errno;
#if DEBUG
debug(2,"===== make_path: %s\n", path);
#endif
while ( path[i] != '\0' ) {
checkdir[i] = path[i];
if (checkdir[i] == '/') { /* Each time a '/' is found, check if the */
checkdir[i+1] = '\0'; /* path exists. If it doesn't, we create it. */
if (true_stat (checkdir, &inode) < 0)
true_mkdir (checkdir, S_IRWXU);
}
i++;
}
/* restore errno */
errno = s_errno;
return 0;
}
/*
* procedure = / rc:=copy_path(truepath,translroot) /
*
* task = / do an exact translation of 'truepath' under 'translroot',
* the directory path to the new objet is not created /
*
* returns = / 0 ok. translation done
* -1 failed. cf errno /
*
* note = /
* --we suppose that 'translroot' has no trailing '/'
* --no overwrite is done is the target object already exists
* --the copy method depends on the source object type.
* --we don't fail if the source object doesn't exist.
* --we don't create the directory path because that would lead in the
* the translation case not to reference the newly created directories
* /
*/
static int copy_path(const char *truepath,const char *translroot) {
int rcod;
char buffer[BUFSIZ];
int bytes;
char translpath[PATH_MAX+1];
struct stat trueinfo;
struct stat translinfo;
int truefd;
int translfd;
struct utimbuf timbuf;
size_t truesz;
char linkpath[PATH_MAX+1];
ssize_t linksz;
#if DEBUG
debug(2,"copy_path(%s,%s)\n",truepath,translroot);
#endif
rcod=true_lstat(truepath,&trueinfo);
if(rcod<0 && errno!=ENOENT) return -1;
if(!rcod) {
if((truesz=strlen(truepath)+strlen(translpath))>PATH_MAX) {
errno=ENAMETOOLONG;
return -1;
}
strncpy(translpath,translroot,PATH_MAX);
strncat(translpath,truepath,PATH_MAX-truesz);
if(!true_lstat(translpath,&translinfo)) return 0;
/* symbolic links */
if(S_ISLNK(trueinfo.st_mode)) {
if((linksz=true_readlink(truepath,linkpath,PATH_MAX))<0) return -1;
linkpath[linksz]='\0';
if(true_symlink(linkpath,translpath)!=0) return -1;
}
/* regular file */
if(S_ISREG(trueinfo.st_mode)) {
if((truefd=true_open(truepath,O_RDONLY))<0) return -1;
if((translfd=true_open( translpath,
O_WRONLY|O_CREAT|O_TRUNC,
trueinfo.st_mode))<0 ) {
close(truefd);
return -1;
}
while((bytes=read(truefd,buffer,BUFSIZ))>0)
write(translfd,buffer,bytes);
close(truefd);
close(translfd);
}
/* directory */
if(S_ISDIR(trueinfo.st_mode)) {
if(true_mkdir(translpath,trueinfo.st_mode)) return -1;
}
/* block special file */
if(S_ISBLK(trueinfo.st_mode)) {
if(true_mknod( translpath,trueinfo.st_mode|S_IFBLK,
trueinfo.st_rdev )) return -1;
}
/* character special file */
if(S_ISCHR(trueinfo.st_mode)) {
if(true_mknod( translpath,trueinfo.st_mode|S_IFCHR,
trueinfo.st_rdev )) return -1;
}
/* fifo special file */
if(S_ISFIFO(trueinfo.st_mode)) {
if(true_mknod(translpath,trueinfo.st_mode|S_IFIFO,0))
return -1;
}
timbuf.actime=trueinfo.st_atime;
timbuf.modtime=trueinfo.st_mtime;
true_utime(translpath,&timbuf);
if(!S_ISLNK(trueinfo.st_mode)) {
true_chown(translpath,trueinfo.st_uid,trueinfo.st_gid);
true_chmod(translpath,trueinfo.st_mode);
}
}
return 0;
}
/*
* procedure = / rc:=path_excluded(truepath) /
*
* task = / indicates if the given path is or is hosted under any
* of the exclusion list members. /
*
* returns = / 0 is not a member
* 1 is a member /
*
* note = / __instw.exclude must be initialized /
*
*/
static inline int path_excluded(const char *truepath) {
string_t *pnext;
int result;
result=0;
pnext=__instw.exclude;
while(pnext!=NULL) {
if(strstr(truepath,pnext->string)==truepath) {
result=1;
break;
}
pnext=pnext->next;
}
return result;
}
/*
* procedure = / rc:=unlink_recursive(truepath) /
*
* task = / dangerous function that unlink either a file or
* an entire subtree. /
*
* returns = / 0 ok. recursive unlink done
* -1 failed. cf errno /
*
* note = /
* --this procedure was needed by instw_makedirls(), in order to
* erase a previously created temporary subtree.
* --it must be called with an absolute path, and only to delete
* well identified trees.
* --i think it is a very weak implementation, so avoid using it
* to unlink too deep trees, or rewrite it to avoid recursivity.
* /
*
*/
static int unlink_recursive(const char *truepath) {
int rcod;
struct stat trueinfo;
DIR *wdir;
struct dirent *went;
char wpath[PATH_MAX+1];
struct stat winfo;
#if DEBUG
debug(2,"unlink_recursive(%s)\n",truepath);
#endif
rcod=true_lstat(truepath,&trueinfo);
if(rcod<0 && errno!=ENOENT) return -1;
if(rcod!=0) return 0;
if(S_ISDIR(trueinfo.st_mode)) {
wdir=true_opendir(truepath);
if(wdir==NULL) return -1;
while((went=true_readdir(wdir))!=NULL) {
/* we avoid big inifinite recursion troubles */
if( went->d_name[0]=='.' &&
( (went->d_name[1]=='\0') ||
( went->d_name[1]=='.' &&
went->d_name[2]=='\0') ) )
{ continue; }
/* let's get the absolute path to this entry */
strcpy(wpath,truepath);
strcat(wpath,"/");
strcat(wpath,went->d_name);
rcod=true_lstat(wpath,&winfo);
if(rcod!=0) {
closedir(wdir);
return -1;
}
if(S_ISDIR(winfo.st_mode)) {
unlink_recursive(wpath);
true_rmdir(wpath);
} else {
true_unlink(wpath);
}
}
closedir(wdir);
true_rmdir(truepath);
} else {
true_unlink(truepath);
}
return rcod;
}
/*
* procedure = / rc:=expand_path(&list,prefix,suffix) /
*
* task = / from a given path, generates all the paths that could
* be derived from it, through symlinks expansion. /
*
* note = /
* --this procedure has been implemented to enhance the method used
* to reference files that have been translated.
* --briefly, it is necessary to reference all the paths that could
* lead to a file, not only the path and the associated real path.
* /
*/
int expand_path(string_t **list,const char *prefix,const char *suffix) {
char nprefix[PATH_MAX+1];
char nwork[PATH_MAX+1];
char nsuffix[PATH_MAX+1];
char lnkpath[PATH_MAX+1];
size_t lnksz=0;
string_t *pthis=NULL;
string_t *list1=NULL;
string_t *list2=NULL;
struct stat ninfo;
int rcod=0;
char pnp[PATH_MAX+1];
char pns[PATH_MAX+1];
size_t len;
#if DEBUG
debug(4,"expand_path(%p,%s,%s)\n",list,prefix,suffix);
#endif
/* nothing more to expand, stop condition */
if(suffix[0]=='\0') {
(*list)=mallok(string_t,1);
(*list)->string=malloc(strlen(prefix)+1);
strcpy((*list)->string,prefix);
(*list)->next=NULL;
finalize(0);
}
/* we parse the next suffix subscript */
parse_suffix(pnp,pns,suffix);
strcpy(nprefix,prefix);
strcat(nprefix,pnp);
strcpy(nsuffix,pns);
rcod=true_lstat(nprefix,&ninfo);
if( (rcod!=0) ||
(rcod==0 && !S_ISLNK(ninfo.st_mode))) {
expand_path(list,nprefix,nsuffix);
} else {
expand_path(&list1,nprefix,nsuffix);
lnksz=true_readlink(nprefix,lnkpath,PATH_MAX);
lnkpath[lnksz]='\0';
if(lnkpath[0]!='/') {
strcpy(nprefix,prefix);
len=strlen(lnkpath);
if(lnkpath[len-1]=='/') {lnkpath[len-1]='\0';}
strcpy(nwork,"/");
strcat(nwork,lnkpath);
strcat(nwork,nsuffix);
strcpy(nsuffix,nwork);
expand_path(&list2,nprefix,nsuffix);
} else {
len=strlen(lnkpath);
if(lnkpath[len-1]=='/') {lnkpath[len-1]='\0';}
strcpy(nprefix,"");
strcpy(nwork,lnkpath);
strcat(nwork,nsuffix);
strcpy(nsuffix,nwork);
expand_path(&list2,nprefix,nsuffix);
}
*list=list1;
pthis=*list;
while(pthis->next!=NULL) {pthis=pthis->next;}
pthis->next=list2;
}
finalize:
return rcod;
}
int parse_suffix(char *pnp,char *pns,const char *suffix) {
int rcod=0;
char *p;
strcpy(pnp,suffix);
strcpy(pns,"");
p=pnp;
if(*p=='\0') {
strcpy(pns,"");
} else {
p++;
while((*p)!='\0') {
if(*p=='/') {
strcpy(pns,p);
*p='\0';
break;
}
p++;
}
}
return rcod;
}
/*
* *****************************************************************************
*/
#ifndef __USE_FILE_OFFSET64
static int __instw_printdirent(struct dirent *entry) {
if(entry!=NULL) {
debug( 4,
"entry(%p) {\n"
"\td_ino : %" PRId64 "\n"
"\td_off : %" PRId64 "\n"
"\td_reclen : %d\n"
"\td_type : %d\n"
"\td_name : \"%.*s\"\n",
entry,
(int64_t) entry->d_ino,
(int64_t) D_OFF(entry->d_off),
entry->d_reclen,
(int)entry->d_type,
(int)entry->d_reclen,(char*)(entry->d_name)
);
} else {
debug( 4,"entry(null) \n");
}
return 0;
}
#endif
static int __instw_printdirent64(struct dirent64 *entry) {
if(entry!=NULL) {
debug( 4,
"entry(%p) {\n"
"\td_ino : %" PRId64 "\n"
"\td_off : %" PRId64 "d\n"
"\td_reclen : %d\n"
"\td_type : %d\n"
"\td_name : \"%.*s\"\n",
entry,
entry->d_ino,
D_OFF(entry->d_off),
entry->d_reclen,
(int)entry->d_type,
(int)entry->d_reclen,(char*)(entry->d_name)
);
} else {
debug( 4,"entry(null) \n");
}
return 0;
}
/*
* *****************************************************************************
*/
#ifdef DEBUG
static int instw_print(instw_t *instw) {
string_t *pnext;
int i;
debug( 4,
"instw(%p) {\n"
"\tgstatus : %d\n"
"\terror : %d\n"
"\tstatus : %d\n"
"\tdbglvl : %d\n"
"\tpid : %d\n"
"\troot : \"%.*s\"\n"
"\tbackup : \"%.*s\"\n"
"\ttransl : \"%.*s\"\n"
"\tmeta : \"%.*s\"\n"
"\tmtransl : \"%.*s\"\n"
"\tmdirls : \"%.*s\"\n",
instw,
instw->gstatus,
instw->error,
instw->status,
instw->dbglvl,
instw->pid,
PATH_MAX,(char*)((instw->root)?:"(null)"),
PATH_MAX,(char*)((instw->backup)?:"(null)"),
PATH_MAX,(char*)((instw->transl)?:"(null)"),
PATH_MAX,(char*)((instw->meta)?:"(null)"),
PATH_MAX,(char*)((instw->mtransl)?:"(null)"),
PATH_MAX,(char*)((instw->mdirls)?:"(null)")
);
pnext=instw->exclude;
i=0;
while(pnext!=NULL) {
debug( 4,
"\texclude : (%02d) \"%.*s\"\n",
++i,PATH_MAX,pnext->string );
pnext=pnext->next;
}
debug( 4,
"\tpath : \"%.*s\"\n"
"\treslvpath : \"%.*s\"\n"
"\ttruepath : \"%.*s\"\n"
"\ttranslpath : \"%.*s\"\n",
PATH_MAX,(char*)(instw->path),
PATH_MAX,(char*)(instw->reslvpath),
PATH_MAX,(char*)(instw->truepath),
PATH_MAX,(char*)(instw->translpath)
);
pnext=instw->equivpaths;
i=0;
while(pnext!=NULL) {
debug( 4,
"\tequivpaths : (%02d) \"%.*s\"\n",
++i,PATH_MAX,pnext->string );
pnext=pnext->next;
}
debug( 4,
"\tmtranslpath : \"%.*s\"\n"
"\tmdirlspath : \"%.*s\"\n"
"}\n",
PATH_MAX,(char*)(instw->mtranslpath),
PATH_MAX,(char*)(instw->mdirlspath)
);
return 0;
}
#endif
/*
* procedure = / rc:=instw_init() /
*
* task = / initializes the '__transl' fields, and fills the fields
* provided by the environment.
* this structure is a reference enabling faster
* local structure creations. /
*
* returns = / 0 ok. env set
* -1 failed. /
*/
static int instw_init(void) {
char *proot;
char *pbackup;
char *ptransl;
char *pdbglvl;
struct stat info;
char wrkpath[PATH_MAX+1];
char *pexclude;
char *exclude;
string_t **ppnext;
int okinit;
int okbackup;
int oktransl;
int okwrap;
#if DEBUG
/*
* We set the requested dynamic debug level
*/
__instw.dbglvl=0;
if((pdbglvl=getenv("INSTW_DBGLVL"))) {
__instw.dbglvl=atoi(pdbglvl);
if(__instw.dbglvl>4) { __instw.dbglvl=4; }
if(__instw.dbglvl<0) { __instw.dbglvl=0; }
}
debug(2,"instw_init()\n");
#endif
okinit=0;
okbackup=0;
oktransl=0;
okwrap=0;
__instw.gstatus=0;
__instw.error=0;
__instw.status=0;
__instw.pid=getpid();
__instw.root=NULL;
__instw.backup=NULL;
__instw.transl=NULL;
__instw.meta=NULL;
__instw.mtransl=NULL;
__instw.mdirls=NULL;
__instw.exclude=NULL;
__instw.path[0]='\0';
__instw.reslvpath[0]='\0';
__instw.truepath[0]='\0';
__instw.translpath[0]='\0';
__instw.equivpaths=NULL;
__instw.mtranslpath[0]='\0';
__instw.mdirlspath[0]='\0';
/* nothing can be activated without that, anyway */
if((proot=getenv("INSTW_ROOTPATH"))) {
realpath(proot,wrkpath);
if(wrkpath[strlen(wrkpath)-1]=='/')
wrkpath[strlen(wrkpath)-1]='\0';
__instw.root=malloc(strlen(wrkpath)+1);
if(NULL==__instw.root) return -1;
strcpy(__instw.root,wrkpath);
/* this root path must exist */
if(__instw.root[0]=='\0' || true_stat(__instw.root,&info)) {
fprintf(stderr,
"Please check the INSTW_ROOTPATH and "
"be sure that it does exist please !\n"
"given value : %s\n", __instw.root);
return -1;
}
if((pbackup=getenv("INSTW_BACKUP"))) {
if( !strcmp(pbackup,"1") ||
!strcmp(pbackup,"yes") ||
!strcmp(pbackup,"true") ) {
if((strlen(__instw.root)+strlen(_BACKUP))>PATH_MAX) {
fprintf(stderr,
"Backup path would exceed PATH_MAX. Aborting.\n");
return -1;
}
__instw.backup=malloc(strlen(__instw.root)+strlen(_BACKUP)+1);
if(NULL==__instw.backup) return -1;
strcpy(__instw.backup,__instw.root);
strcat(__instw.backup,_BACKUP);
/* we create the path that precautiously shouldn't exist */
true_mkdir(__instw.backup,S_IRWXU);
okbackup=1;
}
else if( strcmp(pbackup,"0") &&
strcmp(pbackup,"no") &&
strcmp(pbackup,"false") ) {
fprintf(stderr,
"Please check the INSTW_BACKUP value please !\n"
"Recognized values are : 1/0,yes/no,true/false.\n");
return -1;
}
}
if((ptransl=getenv("INSTW_TRANSL"))) {
if( !strcmp(ptransl,"1") ||
!strcmp(ptransl,"yes") ||
!strcmp(ptransl,"true") ) {
if((strlen(__instw.root)+strlen(_TRANSL))>PATH_MAX) {
fprintf(stderr,
"Transl path would exceed PATH_MAX. Aborting.\n");
return -1;
}
__instw.transl=malloc(strlen(__instw.root)+strlen(_TRANSL)+1);
if(NULL==__instw.transl) return -1;
strcpy(__instw.transl,__instw.root);
strcat(__instw.transl,_TRANSL);
/* we create the path that precautiously shouldn't exist */
true_mkdir(__instw.transl,S_IRWXU);
if((strlen(__instw.root)+strlen(_META))>PATH_MAX) {
fprintf(stderr,
"Meta path would exceed PATH_MAX. Aborting.\n");
return -1;
}
__instw.meta=malloc(strlen(__instw.root)+strlen(_META)+1);
if(NULL==__instw.meta) return -1;
strcpy(__instw.meta,__instw.root);
strcat(__instw.meta,_META);
/* we create the path that precautiously shouldn't exist */
true_mkdir(__instw.meta,S_IRWXU);
__instw.mtransl=malloc(strlen(__instw.meta)+strlen(_MTRANSL)+1);
if(NULL==__instw.mtransl) return -1;
strcpy(__instw.mtransl,__instw.meta);
strcat(__instw.mtransl,_MTRANSL);
/* we create the path that precautiously shouldn't exist */
true_mkdir(__instw.mtransl,S_IRWXU);
__instw.mdirls=malloc(strlen(__instw.meta)+strlen(_MDIRLS)+1);
if(NULL==__instw.mdirls) return -1;
strcpy(__instw.mdirls,__instw.meta);
strcat(__instw.mdirls,_MDIRLS);
/* we create the path that precautiously shouldn't exist */
true_mkdir(__instw.mdirls,S_IRWXU);
oktransl=1;
}
else if( strcmp(ptransl,"0") &&
strcmp(ptransl,"no") &&
strcmp(ptransl,"false") ) {
fprintf(stderr,
"Please check the INSTW_TRANSL value please !\n"
"Recognized values are : 1/0,yes/no,true/false.\n");
return -1;
}
}
}
/*
* we end up constructing the exclusion list
*/
ppnext=&__instw.exclude;
/* we systematically add the root directory */
if(__instw.gstatus&INSTW_OKTRANSL) {
*ppnext=mallok(string_t,1);
if(*ppnext==NULL) return -1;
(*ppnext)->string=NULL;
(*ppnext)->next=NULL;
realpath(__instw.root,wrkpath);
(*ppnext)->string=malloc(strlen(wrkpath)+1);
strcpy((*ppnext)->string,wrkpath);
ppnext=&(*ppnext)->next;
}
if((pexclude=getenv("INSTW_EXCLUDE"))) {
exclude=malloc(strlen(pexclude)+1);
strcpy(exclude,pexclude);
pexclude=strtok(exclude,",");
while(pexclude!=NULL) {
*ppnext=malloc(sizeof(string_t));
if(*ppnext==NULL) return -1;
(*ppnext)->string=NULL;
(*ppnext)->next=NULL;
/* let's store the next excluded path */
if(strlen(pexclude)>PATH_MAX) return -1;
realpath(pexclude,wrkpath);
(*ppnext)->string=malloc(strlen(wrkpath)+1);
strcpy((*ppnext)->string,wrkpath);
ppnext=&(*ppnext)->next;
pexclude=strtok(NULL,",");
}
}
okinit=1;
okwrap=1;
if(okinit) __instw.gstatus |= INSTW_INITIALIZED;
if(okwrap) __instw.gstatus |= INSTW_OKWRAP;
if(okbackup) __instw.gstatus |= INSTW_OKBACKUP;
if(oktransl) __instw.gstatus |= INSTW_OKTRANSL;
#if DEBUG
debug(4,"__instw(%p)\n",&__instw);
instw_print(&__instw);
#endif
return 0;
}
/*
* procedure = / rc:=instw_fini() /
*
* task = / properly finalizes the instw job /
*
* returns = / 0 ok. env set
* -1 failed. /
*/
static int instw_fini(void) {
int rcod=0;
string_t *pnext;
string_t *pthis;
#if DEBUG
debug(2,"instw_fini()\n");
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ) finalize(0);
__instw.gstatus &= ~INSTW_INITIALIZED;
if(__instw.root != NULL) {free(__instw.root);__instw.root=NULL;}
if(__instw.backup != NULL) {free(__instw.backup);__instw.backup=NULL;}
if(__instw.transl != NULL) {free(__instw.transl);__instw.transl=NULL;}
if(__instw.meta != NULL) {free(__instw.meta);__instw.meta=NULL;}
if(__instw.mtransl != NULL) {free(__instw.mtransl);__instw.mtransl=NULL;}
if(__instw.mdirls != NULL) {free(__instw.mdirls);__instw.mdirls=NULL;}
pthis=__instw.exclude;
while(pthis != NULL) {
free(pthis->string);
pnext=pthis->next;
free(pthis);
pthis=pnext;
}
__instw.exclude=NULL;
finalize:
return rcod;
}
/*
* procedure = / rc:=instw_new(instw) /
*
* task = / Initializes a new instw_t structure before any work on it /
*
* returns = / 0 ok. ready to be used
* -1 failed. /
*/
static int instw_new(instw_t *instw) {
int rcod=0;
*instw=__instw;
instw->error=0;
instw->status=0;
instw->path[0]='\0';
instw->reslvpath[0]='\0';
instw->truepath[0]='\0';
instw->translpath[0]='\0';
instw->equivpaths=NULL;
instw->mtranslpath[0]='\0';
instw->mdirlspath[0]='\0';
return rcod;
}
/*
* procedure = / rc:=instw_delete(instw) /
*
* task = / properly finalizes an instw structure /
*
* returns = / 0 ok. ready to be used
* -1 failed. /
*/
static int instw_delete(instw_t *instw) {
int rcod=0;
string_t *pnext;
string_t *pthis;
pthis=instw->equivpaths;
while(pthis != NULL) {
free(pthis->string);
pnext=pthis->next;
free(pthis);
pthis=pnext;
}
instw->status=0;
return rcod;
}
/*
* procedure = / rc:=instw_setmetatransl(instw) /
*
* task = / Refreshes as mush as possible the translation
* status of a translated file /
*
* note = /
* --this procedure is meant to be called after the various
* translation status flags have been setted.
* the only thing it does is referencing a file that has been
* flagged as "translated".
* if it is, we musn't try to use the eventual real version
* of the file anymore, hence the full referencement under /mtransl.
*
* --in some cases, for example when you create manually a subtree
* and a file in this subtree directly directly in the translated fs
* (yes, it is possible) the meta infos won't exist.
* so, to be able to cope with this case, we firstly try to
* create the full reference to the file, and if this fails, we try
* to reference all the traversed directories.
* /
*/
static int instw_setmetatransl(instw_t *instw) {
int rcod=0;
struct stat info;
char mtransldir[PATH_MAX+1];
char mtranslpath[PATH_MAX+1];
char reslvpath[PATH_MAX+1];
size_t mesz=0;
int i=0;
string_t *pthis;
#if DEBUG
debug(3,"instw_setmetatransl(%p)\n",instw);
instw_print(instw);
#endif
if( !(instw->gstatus & INSTW_INITIALIZED) ||
!(instw->gstatus & INSTW_OKTRANSL) ) finalize(0);
if(!(instw->status & INSTW_TRANSLATED) ) finalize(0);
if(instw->equivpaths==NULL) {
expand_path(&(instw->equivpaths),"",instw->reslvpath);
}
#if DEBUG
instw_print(instw);
#endif
pthis=instw->equivpaths;
while(pthis!=NULL) {
strcpy(mtranslpath,instw->mtransl);
strcat(mtranslpath,pthis->string);
strcpy(reslvpath,pthis->string);
if( (true_stat(mtranslpath,&info)) &&
(true_mkdir(mtranslpath,S_IRWXU)) ) {
strcpy(mtransldir,mtranslpath);
mesz=strlen(instw->mtransl);
for(i=0;reslvpath[i]!='\0';i++) {
mtransldir[mesz+i]=reslvpath[i];
if(reslvpath[i]=='/') {
mtransldir[mesz+i+1]='\0';
true_mkdir(mtransldir,S_IRWXU);
}
}
true_mkdir(mtranslpath,S_IRWXU);
}
pthis=pthis->next;
}
finalize:
return rcod;
}
/*
* procedure = / rc:=instw_setpath(instw,path) /
*
* task = / sets the 'instw->path' field and updates all the fields that
* can be deduced from 'path', such as 'instw->translpath'. /
*
* inputs = / path The given path, as is
* outputs = / instw->path A stored copy of 'path'
* instw->truepath The given path, canonicalized
* instw->translpath The real translated path
* instw->mtranslpath The translation status path /
*
* returns = / 0 ok. path set
* -1 failed. cf errno /
*/
static int instw_setpath(instw_t *instw,const char *path) {
char canonical[PATH_MAX+1];
const char *pcanon;
size_t relen;
size_t trlen = 0;
size_t melen;
#if DEBUG
debug(2,"instw_setpath(%p,%s)\n",instw,path);
#endif
instw->status=0;
strncpy(instw->path,path,PATH_MAX);
instw->truepath[0]='\0';
if(instw->path[0]!='/') {
true_getcwd(instw->truepath,PATH_MAX+1);
if(instw->truepath[strlen(instw->truepath)-1]!='/'){
strcat(instw->truepath,"/");
}
strcat(instw->truepath,instw->path);
} else {
reduce(instw->path);
strcpy(instw->truepath,instw->path);
}
/* remove relative elements from the truepath */
reduce(instw->truepath);
/* Record paths under their real parent directories. Leave the final */
/* component unresolved so operations still see a symlink there. */
pcanon=resolve_parent(instw->truepath,canonical,sizeof(canonical));
if(pcanon!=instw->truepath) {
strncpy(instw->truepath,pcanon,PATH_MAX);
instw->truepath[PATH_MAX]='\0';
}
relen=strlen(instw->truepath);
/*
* if library is not completely initialized, or if translation
* is not active, we make things so it is equivalent to the
* to the identity, this avoid needs to cope with special cases.
*/
if( !(instw->gstatus&INSTW_INITIALIZED) ||
!(instw->gstatus&INSTW_OKTRANSL)) {
strncpy(instw->reslvpath,instw->truepath,PATH_MAX);
strncpy(instw->translpath,instw->truepath,PATH_MAX);
return 0;
}
/*
* we fill instw->reslvpath , applying the inversed translation
* if truepath is inside /transl.
*/
if(strstr(instw->truepath,instw->transl)==instw->truepath) {
strcpy(instw->reslvpath,instw->truepath+strlen(instw->transl));
} else {
strcpy(instw->reslvpath,instw->truepath);
}
/*
* if instw->path is relative, no troubles.
* but if it is absolute and located under /transl, we have
* to untranslate it.
*/
if( (instw->path[0]=='/') &&
(strstr(instw->path,instw->transl)==instw->path)) {
strcpy(instw->path,instw->reslvpath);
}
/*
* We must detect early 'path' matching with already translated files
*/
if(path_excluded(instw->truepath)) {
strncpy(instw->translpath,instw->truepath,PATH_MAX);
instw->status |= ( INSTW_TRANSLATED | INSTW_IDENTITY);
} else {
/* Building the real translated path */
strncpy(instw->translpath,instw->transl,PATH_MAX);
trlen=strlen(instw->translpath);
if((trlen+relen)>PATH_MAX) {
instw->error=errno=ENAMETOOLONG;
return -1;
}
strncat(instw->translpath,instw->reslvpath,PATH_MAX-trlen);
instw->translpath[PATH_MAX]='\0';
}
/* Building the translation status path */
strncpy(instw->mtranslpath,instw->mtransl,PATH_MAX);
instw->mtranslpath[PATH_MAX]='\0';
melen=strlen(instw->mtranslpath);
if((melen+relen)>PATH_MAX) {
instw->error=errno=ENAMETOOLONG;
return -1;
}
strncat(instw->mtranslpath,instw->reslvpath,PATH_MAX-trlen);
instw->mtranslpath[PATH_MAX]='\0';
return 0;
}
/*
* procedure = / rc:=instw_setpathrel(instw,dirfd,relpath) /
*
* task = / sets the 'instw->path' field and updates all the fields that
* can be deduced from 'path', such as 'instw->translpath'. Much
* like instw_setpath, except for paths relative to a dirfd. /
*
* inputs = / dirfd An open file descriptor to a directory
* relpath The given path relative to dirfd, as is
* outputs = / instw->path The full absolute (non-relative) path
* instw->truepath The given path, canonicalized
* instw->translpath The real translated path
* instw->mtranslpath The translation status path /
*
* returns = / 0 ok. path set
* -1 failed. cf errno /
*/
static int instw_setpathrel(instw_t *instw, int dirfd, const char *relpath) {
/* This constant should be large enough to make a string that holds
* /proc/self/fd/xxxxx if you have an open fd with more than five digits,
* something is seriously messed up.
*/
#define PROC_PATH_LEN 20
debug(2,"instw_setpathrel(%p,%d,%s)\n",instw,dirfd,relpath);
int retval = -1, l;
char *newpath;
char proc_path[PROC_PATH_LEN];
struct stat s;
/* If dirfd is AT_FDCWD then we got nothing to do, return the */
/* path as-is */
if ( dirfd == AT_FDCWD ) return instw_setpath(instw, relpath);
snprintf(proc_path, PROC_PATH_LEN, "/proc/self/fd/%d", dirfd);
if(true_lstat(proc_path, &s) == -1)
goto out;
if(!(newpath = malloc(PATH_MAX+strlen(relpath)+2)))
goto out;
if((l = true_readlink(proc_path, newpath, PATH_MAX)) == -1)
goto free_out;
newpath[l] = '/';
strcpy(newpath + l + 1, relpath);
retval = instw_setpath(instw, newpath);
free_out:
free(newpath);
out:
return retval;
#undef PROC_PATH_LEN
}
/*
* procedure = / rc:=instw_getstatus(instw,status) /
*
* outputs = / status instw->path flags field status in the translated fs
* INSTW_ISINROOT file exists in the real fs
* INSTW_ISINTRANSL file exists in the translated fs
* INSTW_TRANSLATED file has been translated /
*
* returns = / 0 ok. stated
* -1 failed. cf errno /
*/
static int instw_getstatus(instw_t *instw,int *status) {
struct stat inode;
struct stat rinode;
struct stat tinode;
#if DEBUG
debug(2,"instw_getstatus(%p,%p)\n",instw,status);
#endif
/*
* is the file referenced as being translated ?
*/
if( (instw->gstatus&INSTW_INITIALIZED) &&
(instw->gstatus&INSTW_OKTRANSL) &&
!(instw->status&INSTW_TRANSLATED) &&
!true_stat(instw->mtranslpath,&inode) ) {
instw->status |= INSTW_TRANSLATED;
}
/*
* do the file currently exist in the translated fs ?
*/
if( (instw->gstatus&INSTW_INITIALIZED) &&
(instw->gstatus&INSTW_OKTRANSL) &&
!true_stat(instw->translpath,&tinode) ) {
instw->status |= INSTW_ISINTRANSL;
}
/*
* is it a newly created file, or a modified one ?
*/
if( instw->gstatus&INSTW_INITIALIZED &&
!true_stat(instw->reslvpath,&rinode) ) {
instw->status |= INSTW_ISINROOT;
}
/*
* if the file exists, why is it not referenced as
* being translated ?
* we have to reference it and all the traversed
* directories leading to it.
*/
if( (instw->gstatus&INSTW_INITIALIZED) &&
(instw->gstatus&INSTW_OKTRANSL) &&
(instw->status&INSTW_ISINTRANSL) &&
!(instw->status&INSTW_TRANSLATED) ) {
instw->status |= INSTW_TRANSLATED;
instw_setmetatransl(instw);
}
/*
* are the public resolved path and its translated counterpart
* identical ? if so, we flag it
*/
if( (instw->gstatus & INSTW_INITIALIZED) &&
(instw->gstatus & INSTW_OKTRANSL) &&
(instw->status & INSTW_TRANSLATED) &&
(0==(strcmp(instw->truepath,instw->translpath))) ) {
instw->status |= INSTW_IDENTITY;
}
*status=instw->status;
return 0;
}
/*
* procedure = / rc:=instw_apply(instw) /
*
* task = / actually do the translation prepared in 'transl' /
*
* note = / --after a call to instw_apply(), the translation related
* status flags are updated.
* --if a translation is requested and if the original file
* exists, all parent directories are created and referenced
* if necessary.
* if the original file does not exist, we translate at
* least the existing path. /
*
* returns = / 0 ok. translation done
* -1 failed. cf errno /
*/
static int instw_apply(instw_t *instw) {
int rcod=0;
int status=0;
char dirpart[PATH_MAX+1];
char basepart[PATH_MAX+1];
char *pdir;
char *pbase;
struct stat reslvinfo;
instw_t iw;
char wpath[PATH_MAX+1];
size_t wsz=0;
char linkpath[PATH_MAX+1];
#if DEBUG
debug(2,"instw_apply(%p)\n",instw);
instw_print(instw);
#endif
/*
* if library incompletely initialized or if translation
* is inactive, nothing to apply
*/
if( !(instw->gstatus&INSTW_INITIALIZED) ||
!(instw->gstatus&INSTW_OKTRANSL) ) finalize(0);
/* let's get the file translation status */
if(instw_getstatus(instw,&status)) finalize(-1);
/* we ignore files already translated */
if(status & INSTW_TRANSLATED) return 0;
strcpy(basepart,instw->reslvpath);
strcpy(dirpart,instw->reslvpath);
pbase=basename(basepart);
pdir=dirname(dirpart);
/* recursivity termination test, */
if(pdir[0]=='/' && pdir[1]=='\0' && pbase[0]=='\0') {
instw->status|=INSTW_TRANSLATED;
finalize(0);
}
instw_new(&iw);
instw_setpath(&iw,pdir);
instw_apply(&iw);
instw_delete(&iw);
/* will we have to copy the original file ? */
if(!true_lstat(instw->reslvpath,&reslvinfo)) {
copy_path(instw->reslvpath,instw->transl);
/* a symlink ! we have to translate the target */
if(S_ISLNK(reslvinfo.st_mode)) {
wsz=true_readlink(instw->reslvpath,wpath,PATH_MAX);
wpath[wsz]='\0';
instw_new(&iw);
if(wpath[0]!='/') {
strcpy(linkpath,pdir);
strcat(linkpath,"/");
strcat(linkpath,wpath);
} else {
strcpy(linkpath,wpath);
}
instw_setpath(&iw,linkpath);
instw_apply(&iw);
instw_delete(&iw);
}
}
instw->status|=INSTW_TRANSLATED;
instw_setmetatransl(instw);
finalize:
return rcod;
}
/*
* procedure = / rc:=instw_filldirls(instw) /
*
* task = / used to create dummy entries in the mdirlspath reflecting
* the content that would have been accessible with no
* active translation. /
*
* note = /
* --This procedure must be called after instw_makedirls() has been
* called itself.
* --It implies that the translated directory and the real one are
* distincts, but it does not matter if one of them, or both is empty
* /
*/
static int instw_filldirls(instw_t *instw) {
int rcod=0;
DIR *wdir;
struct dirent *went;
char spath[PATH_MAX+1];
char dpath[PATH_MAX+1];
char lpath[PATH_MAX+1];
struct stat sinfo;
struct stat dinfo;
int wfd;
size_t wsz;
instw_t iw_entry;
int status=0;
#if DEBUG
debug(2,"instw_filldirls(%p)\n",instw);
#endif
if((wdir=true_opendir(instw->translpath))==NULL) { return -1; }
while((went=true_readdir(wdir))!=NULL) {
if( went->d_name[0]=='.' &&
( (went->d_name[1]=='\0') ||
( went->d_name[1]=='.' &&
went->d_name[2]=='\0') ) )
{ continue; }
strcpy(spath,instw->translpath);
strcat(spath,"/");
strcat(spath,went->d_name);
if(true_lstat(spath,&sinfo)) { continue; }
strcpy(dpath,instw->mdirlspath);
strcat(dpath,"/");
strcat(dpath,went->d_name);
/* symbolic links */
if(S_ISLNK(sinfo.st_mode)) {
if((wsz=true_readlink(spath,lpath,PATH_MAX))>=0) {
lpath[wsz]='\0';
true_symlink(lpath,dpath);
#if DEBUG
debug(4,"\tfilled symlink : %s\n",dpath);
#endif
}
}
/* regular file */
if(S_ISREG(sinfo.st_mode)) {
if((wfd=true_creat(dpath,sinfo.st_mode))>=0) {
close(wfd);
#if DEBUG
debug(4,"\tfilled regular file : %s\n",dpath);
#endif
}
}
/* directory */
if(S_ISDIR(sinfo.st_mode)) {
true_mkdir(dpath,sinfo.st_mode);
#if DEBUG
debug(4,"\tfilled directory : %s\n",dpath);
#endif
}
/* block special file */
if(S_ISBLK(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFBLK,sinfo.st_rdev);
#if DEBUG
debug(4,"\tfilled special block : %s\n",dpath);
#endif
}
/* character special file */
if(S_ISCHR(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFCHR,sinfo.st_rdev);
#if DEBUG
debug(4,"\tfilled special char : %s\n",dpath);
#endif
}
/* fifo special file */
if(S_ISFIFO(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFIFO,0);
#if DEBUG
debug(4,"\tfilled special fifo : %s\n",dpath);
#endif
}
}
closedir(wdir);
if((wdir=true_opendir(instw->reslvpath))==NULL) return -1;
while((went=true_readdir(wdir))!=NULL) {
if( went->d_name[0]=='.' &&
( (went->d_name[1]=='\0') ||
( went->d_name[1]=='.' &&
went->d_name[2]=='\0') ) )
{ continue; }
strcpy(spath,instw->reslvpath);
strcat(spath,"/");
strcat(spath,went->d_name);
if(true_lstat(spath,&sinfo)) { continue; }
instw_new(&iw_entry);
instw_setpath(&iw_entry,spath);
instw_getstatus(&iw_entry,&status);
/*
* This entry exists in the real fs, but has been
* translated and destroyed in the translated fs.
* So, we mustn't present it !!!
*/
if( (status & INSTW_TRANSLATED) &&
!(status & INSTW_ISINTRANSL) ) { continue; }
strcpy(dpath,instw->mdirlspath);
strcat(dpath,"/");
strcat(dpath,went->d_name);
/* already exists in the translated fs, we iterate */
if(!true_lstat(dpath,&dinfo)) { continue; }
/* symbolic links */
if(S_ISLNK(sinfo.st_mode)) {
if((wsz=true_readlink(spath,lpath,PATH_MAX))>=0) {
lpath[wsz]='\0';
true_symlink(lpath,dpath);
#if DEBUG
debug(4,"\tfilled symlink : %s\n",dpath);
#endif
}
}
/* regular file */
if(S_ISREG(sinfo.st_mode)) {
if((wfd=true_creat(dpath,sinfo.st_mode))>=0) {
close(wfd);
#if DEBUG
debug(4,"\tfilled regular file : %s\n",dpath);
#endif
}
}
/* directory */
if(S_ISDIR(sinfo.st_mode)) {
true_mkdir(dpath,sinfo.st_mode);
#if DEBUG
debug(4,"\tfilled directory : %s\n",dpath);
#endif
}
/* block special file */
if(S_ISBLK(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFBLK,sinfo.st_rdev);
#if DEBUG
debug(4,"\tfilled special block : %s\n",dpath);
#endif
}
/* character special file */
if(S_ISCHR(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFCHR,sinfo.st_rdev);
#if DEBUG
debug(4,"\tfilled special char : %s\n",dpath);
#endif
}
/* fifo special file */
if(S_ISFIFO(sinfo.st_mode)) {
true_mknod(dpath,sinfo.st_mode|S_IFIFO,0);
#if DEBUG
debug(4,"\tfilled special fifo : %s\n",dpath);
#endif
}
instw_delete(&iw_entry);
}
closedir(wdir);
return rcod;
}
/*
* procedure = / rc:=instw_makedirls(instw) /
*
* task = / eventually prepares a fake temporary directory used to
* present 'overlaid' content to opendir(),readdir()... /
*
* note = /
* --This procedure must be called after instw_setpath().
*
* --The "fake" temporary directories are created and...forgotten.
* If we need to reuse later the same directory, it is previously
* erased, which ensures that it is correclty refreshed.
* /
*
* returns = / 0 ok. makedirls done
* -1 failed. cf errno /
*/
static int instw_makedirls(instw_t *instw) {
int rcod=0;
int status=0;
struct stat translinfo;
struct stat dirlsinfo;
char wdirname[NAME_MAX+1];
#if DEBUG
debug(2,"instw_makedirls(%p)\n",instw);
#endif
/*
* if library incompletely initialized or if translation
* is inactive, nothing to do
*/
if( !(instw->gstatus&INSTW_INITIALIZED) ||
!(instw->gstatus&INSTW_OKTRANSL)) {
strcpy(instw->mdirlspath,instw->path);
return 0;
}
/* let's get the file translation status */
if(instw_getstatus(instw,&status)) return -1;
if( !(status&INSTW_TRANSLATED) ||
((status&INSTW_TRANSLATED) && (status&INSTW_IDENTITY)) ) {
strcpy(instw->mdirlspath,instw->path);
} else {
/* if it's a new directory, we open it in
* the translated fs .
* otherwise, it means that we will have to construct a
* merged directory.
*/
if(!(status & INSTW_ISINROOT)) {
strcpy(instw->mdirlspath,instw->translpath);
} else {
rcod=true_stat(instw->translpath,&translinfo);
sprintf(wdirname,"/%d_%lld_%lld",
instw->pid,
(long long int) translinfo.st_dev,
(long long int) translinfo.st_ino);
strcpy(instw->mdirlspath,instw->mdirls);
strcat(instw->mdirlspath,wdirname);
/* we erase a previous identical dirls */
if(!true_stat(instw->mdirlspath,&dirlsinfo)) {
unlink_recursive(instw->mdirlspath);
}
true_mkdir(instw->mdirlspath,S_IRWXU);
/* we construct the merged directory here */
instw_filldirls(instw);
}
}
#if DEBUG
instw_print(instw);
#endif
return rcod;
}
/*
*
*/
static int backup(const char *path) {
char checkdir[BUFSIZ];
char backup_path[BUFSIZ];
char canonical[PATH_MAX+1];
int placeholder,
i,
blen;
struct stat inode,backup_inode;
struct utimbuf timbuf;
#if DEBUG
debug(2,"========= backup () ========= path: %s\n", path);
#endif
/* INSTW_OKBACKUP not set, we won't do any backups */
if (!(__instw.gstatus&INSTW_OKBACKUP)) {
#ifdef DEBUG
debug(3,"Backup not enabled, path: %s\n", path);
#endif
return 0;
}
/* Mirror the file under the name its parent directories really have, */
/* so a symlinked directory never gets recreated here as a real one. */
/* Everything below works on that name, exclusions included: a */
/* symlink leading into /tmp or into the backup area has to be caught */
/* just the same. */
path = resolve_parent(path,canonical,sizeof(canonical));
/* Check if this is inside /dev */
if (strstr (path, "/dev") == path) {
#if DEBUG
debug(3,"%s is inside /dev. Ignoring.\n", path);
#endif
return 0;
}
/* Now check for /tmp */
if (strstr (path, "/tmp") == path) {
#if DEBUG
debug(3,"%s is inside /tmp. Ignoring.\n", path);
#endif
return 0;
}
/* Finally, the backup path itself */
if (strstr (path,__instw.backup ) == path) {
#if DEBUG
debug(3,"%s is inside the backup path. Ignoring.\n", path);
#endif
return 0;
}
/* Does it exist already? */
#if DEBUG
debug(3,"Exists %s?\n", path);
#endif
if (true_stat(path, &inode) < 0) {
/* It doesn't exist, we'll tag it so we won't back it up */
/* if we run into it later */
strcpy(backup_path,__instw.backup );
strncat(backup_path, "/no-backup", 11);
strcat(backup_path, path);
make_path(backup_path);
/* This one's just a placeholder */
placeholder = true_creat(backup_path, S_IREAD);
if (!(placeholder < 0)) close (placeholder);
#if DEBUG
debug(3,"does not exist\n");
#endif
return 0;
}
/* Is this one tagged for no backup (i.e. it didn't previously exist)? */
strcpy (backup_path,__instw.backup);
strncat (backup_path, "/no-backup", 11);
strcat (backup_path, path);
if (true_stat (backup_path, &backup_inode) >= 0) {
#if DEBUG
debug(3,"%s should not be backed up\n", backup_path);
#endif
return 0;
}
#if DEBUG
debug(3,"Exists in real path. Lets see what it is.\n");
#endif
/* Append the path to the backup_path */
strcpy (backup_path,__instw.backup);
strcat (backup_path, path);
/* Create the directory tree for this file in the backup dir */
make_path (backup_path);
/* let's backup the source file */
if(copy_path(path,__instw.backup))
return -1;
/* Check the owner and permission of the created directories */
i=0;
blen = strlen (__instw.backup);
while ( path[i] != '\0' ) {
checkdir[i] = backup_path[blen+i] = path[i];
if (checkdir[i] == '/') { /* Each time a '/' is found, check if the */
checkdir[i+1] = '\0'; /* path exists. If it does, set it's perms. */
if (!true_stat (checkdir, &inode)) {
backup_path[blen+i+1]='\0';
timbuf.actime=inode.st_atime;
timbuf.modtime=inode.st_mtime;
true_utime(backup_path, &timbuf);
true_chmod(backup_path, inode.st_mode);
true_chown(backup_path, inode.st_uid, inode.st_gid);
}
}
i++;
}
return 0;
}
time_t time (time_t *timer) {
TIMECOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"time\n");
#endif
return true_time(timer);
}
/*
* *****************************************************************************
*/
int chdir(const char *pathname) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"chdir(%s)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_chdir(pathname);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED && !(status&INSTW_ISINROOT)) {
result=true_chdir(instw.translpath);
debug(3,"\teffective chdir(%s)\n",instw.translpath);
} else {
result=true_chdir(pathname);
debug(3,"\teffective chdir(%s)\n",pathname);
}
instw_delete(&instw);
return result;
}
int chmod(const char *path, mode_t mode) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"chmod(%s,mode)\n",path);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_chmod(path,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
#if DEBUG
instw_print(&instw);
#endif
backup (instw.truepath);
instw_apply(&instw);
result = true_chmod(instw.translpath, mode);
logg("%d\tchmod\t%s\t0%04o\t#%s\n",result,
instw.reslvpath,mode,error(result));
instw_delete(&instw);
return result;
}
int chown(const char *path, uid_t owner, gid_t group) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"chown(%s,owner,group)\n",path);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_chown(path,owner,group);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_chown(instw.translpath,owner,group);
logg("%d\tchown\t%s\t%d\t%d\t#%s\n",result,
instw.reslvpath,owner,group,error(result));
instw_delete(&instw);
return result;
}
int chown32(const char *path, uid_t owner, gid_t group) {
return chown(path, owner, group);
}
int chroot(const char *path) {
int result;
char canonic[MAXPATHLEN];
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"chroot(%s)\n",path);
#endif
canonicalize(path, canonic);
result = true_chroot(path);
/*
* From now on, another log file will be written if
* INSTW_LOGFILE is set
*/
logg("%d\tchroot\t%s\t#%s\n", result, canonic, error(result));
return result;
}
#ifndef __USE_FILE_OFFSET64
int creat(const char *pathname, mode_t mode) {
/* Is it a system call? */
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"creat(%s,mode)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_creat(pathname,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result = true_open(instw.translpath,O_CREAT|O_WRONLY|O_TRUNC,mode);
logg("%d\tcreat\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int fchmod(int filedes, mode_t mode) {
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"fchmod\n");
#endif
result = true_fchmod(filedes, mode);
logg("%d\tfchmod\t%d\t0%04o\t#%s\n",result,filedes,mode,error(result));
return result;
}
int fchown(int fd, uid_t owner, gid_t group) {
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"fchown\n");
#endif
result = true_fchown(fd, owner, group);
logg("%d\tfchown\t%d\t%d\t%d\t#%s\n",result,fd,owner,group,error(result));
return result;
}
#ifndef __USE_FILE_OFFSET64
FILE *fopen(const char *pathname, const char *mode) {
FILE *result = NULL;
instw_t instw;
int status=0;
REFCOUNT;
if (!libc_handle)
initialize();
result = NULL;
#if DEBUG
debug(2,"fopen(%s,%s)\n",pathname,mode);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_fopen(pathname,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
if(mode[0]=='w'||mode[0]=='a'||mode[1]=='+') {
backup(instw.truepath);
instw_apply(&instw);
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
instw.reslvpath,error(result));
}
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective fopen(%s)\n",instw.translpath);
result=true_fopen(instw.translpath,mode);
} else {
debug(4,"\teffective fopen(%s)\n",instw.path);
result=true_fopen(instw.path,mode);
}
if(mode[0]=='w'||mode[0]=='a'||mode[1]=='+')
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int ftruncate(int fd, TRUNCATE_T length) {
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"ftruncate\n");
#endif
result = true_ftruncate(fd, length);
logg("%d\tftruncate\t%d\t%d\t#%s\n",result,fd,(int)length,error(result));
return result;
}
#endif
char *getcwd(char *buffer,size_t size) {
char wpath[PATH_MAX+1];
char *result;
char *wptr;
size_t wsize;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"getcwd(%p,%ld)\n",buffer,(long int)size);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_getcwd(buffer,size);
return result;
}
if( __instw.gstatus&INSTW_INITIALIZED &&
__instw.gstatus&INSTW_OKTRANSL &&
(NULL!=(result=true_getcwd(wpath,sizeof(wpath)))) ) {
/* we untranslate any translated path */
if(strstr(wpath,__instw.transl)==wpath) {
wptr=wpath+strlen(__instw.transl);
wsize=strlen(wptr)+1;
} else {
wptr=wpath;
wsize=strlen(wptr)+1;
}
if (buffer == NULL) {
if (size !=0 && size < wsize) {
result=NULL;
errno=(size<=0?EINVAL:ERANGE);
} else {
result=malloc(wsize);
if(result == NULL) {
errno=ENOMEM;
} else {
strcpy(result,wptr);
}
}
} else {
if(size>=wsize) {
strcpy(buffer,wptr);
} else {
result=NULL;
errno=(size<=0?EINVAL:ERANGE);
}
}
} else {
result=true_getcwd(buffer,size);
}
#if DEBUG
debug(3,"\teffective getcwd(%s,%ld)\n",
(result?buffer:"(null)"),(long int)size);
#endif
return result;
}
int lchown(const char *path, uid_t owner, gid_t group) {
/* Linux specific? */
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"lchown(%s,owner,group)\n",path);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_lchown(path,owner,group);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_lchown(instw.translpath,owner,group);
logg("%d\tlchown\t%s\t%d\t%d\t#%s\n",result,
instw.reslvpath,owner,group,error(result));
instw_delete(&instw);
return result;
}
int link(const char *oldpath, const char *newpath) {
int result;
instw_t instw_o;
instw_t instw_n;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"link(%s,%s)\n",oldpath,newpath);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_link(oldpath,newpath);
return result;
}
instw_new(&instw_o);
instw_new(&instw_n);
instw_setpath(&instw_o,oldpath);
instw_setpath(&instw_n,newpath);
#if DEBUG
instw_print(&instw_o);
instw_print(&instw_n);
#endif
backup(instw_o.truepath);
instw_apply(&instw_o);
instw_apply(&instw_n);
result=true_link(instw_o.translpath,instw_n.translpath);
logg("%d\tlink\t%s\t%s\t#%s\n",result,
instw_o.reslvpath,instw_n.reslvpath,error(result));
instw_delete(&instw_o);
instw_delete(&instw_n);
return result;
}
int mkdir(const char *pathname, mode_t mode) {
char canonical[PATH_MAX+1];
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkdir(%s,mode)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_mkdir(pathname,mode);
return result;
}
/* An existing symlink to a directory is the directory it points */
/* at: creating "/lib" is creating "/usr/lib". */
instw_new(&instw);
instw_setpath(&instw,resolve_dir(pathname,canonical,sizeof(canonical)));
#if DEBUG
instw_print(&instw);
#endif
instw_apply(&instw);
result=true_mkdir(instw.translpath,mode);
logg("%d\tmkdir\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
int mknod(const char *pathname, mode_t mode, dev_t dev) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mknod(%s,mode,dev)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_mknod(pathname,mode,dev);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
instw_apply(&instw);
backup(instw.truepath);
result=true_mknod(instw.translpath,mode,dev);
logg("%d\tmknod\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int __xmknod(int version,const char *pathname, mode_t mode,dev_t *dev) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mknod(%s,mode,dev)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_xmknod(version,pathname,mode,dev);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
instw_apply(&instw);
backup(instw.truepath);
result=true_xmknod(version,instw.translpath,mode,dev);
logg("%d\tmknod\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
int open(const char *pathname, int flags, ...) {
/* Eventually, there is a third parameter: it's mode_t mode */
va_list ap;
mode_t mode;
int result;
instw_t instw;
int status;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"open(%s,%d,mode)\n",pathname,flags);
#endif
va_start(ap, flags);
mode = va_arg(ap, int /*promoted from mode_t*/);
va_end(ap);
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_open(pathname,flags,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
if(flags & (O_WRONLY | O_RDWR)) {
backup(instw.truepath);
instw_apply(&instw);
}
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED)
result=true_open(instw.translpath,flags,mode);
else
result=true_open(instw.path,flags,mode);
if(flags & (O_WRONLY | O_RDWR))
logg("%d\topen\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
/*
*
*/
DIR *opendir(const char *dirname) {
DIR *result;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"opendir(%s)\n",dirname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_opendir(dirname);
return result;
}
instw_new(&instw);
instw_setpath(&instw,dirname);
instw_makedirls(&instw);
#if DEBUG
instw_print(&instw);
#endif
result=true_opendir(instw.mdirlspath);
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
struct dirent *readdir(DIR *dir) {
struct dirent *result;
if (!libc_handle)
initialize();
#if DEBUG
debug(3,"readdir(%p)\n",dir);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_readdir(dir);
return result;
}
result=true_readdir(dir);
#if DEBUG
__instw_printdirent(result);
#endif
return result;
}
ssize_t readlink(const char *path,char *buf,size_t bufsiz) {
ssize_t result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"readlink(\"%s\",%p,%ld)\n",path,buf,(long int)bufsiz);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_readlink(path,buf,bufsiz);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED)
result=true_readlink(instw.translpath,buf,bufsiz);
else
result=true_readlink(instw.path,buf,bufsiz);
instw_delete(&instw);
return result;
}
#endif
char *realpath(const char *file_name,char *resolved_name) {
char *result;
if (!libc_handle)
initialize();
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_realpath(file_name,resolved_name);
return result;
}
result=true_realpath(file_name,resolved_name);
return result;
}
int rename(const char *oldpath, const char *newpath) {
int result;
instw_t oldinstw;
instw_t newinstw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"rename(\"%s\",\"%s\")\n",oldpath,newpath);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_rename(oldpath,newpath);
return result;
}
instw_new(&oldinstw);
instw_new(&newinstw);
instw_setpath(&oldinstw,oldpath);
instw_setpath(&newinstw,newpath);
#if DEBUG
instw_print(&oldinstw);
instw_print(&newinstw);
#endif
backup(oldinstw.truepath);
instw_apply(&oldinstw);
instw_apply(&newinstw);
result=true_rename(oldinstw.translpath,newinstw.translpath);
logg("%d\trename\t%s\t%s\t#%s\n",result,
oldinstw.reslvpath,newinstw.reslvpath,error(result));
instw_delete(&oldinstw);
instw_delete(&newinstw);
return result;
}
int rmdir(const char *pathname) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"rmdir(%s)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_rmdir(pathname);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
backup(instw.truepath);
instw_apply(&instw);
result=true_rmdir(instw.translpath);
logg("%d\trmdir\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
int scandir( const char *dir,struct dirent ***namelist,
int (*select)(const struct dirent *),
#if (GLIBC_MINOR >= 10)
int (*compar)(const struct dirent **,const struct dirent **) ) {
#else
int (*compar)(const void *,const void *) ) {
#endif
int result;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"scandir(%s,%p,%p,%p)\n",dir,namelist,select,compar);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_scandir(dir,namelist,select,compar);
return result;
}
result=true_scandir(dir,namelist,select,compar);
return result;
}
#endif
#if (GLIBC_MINOR >= 33)
#ifndef __USE_FILE_OFFSET64
int stat(const char *pathname, struct stat *info) {
int result;
instw_t instw;
int status;
if(!libc_handle)
initialize();
#if DEBUG
debug(2, "stat(%s, %p)\n", pathname, info);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
result = true_stat(pathname, info);
return result;
}
instw_new(&instw);
instw_setpath(&instw, pathname);
instw_getstatus(&instw, &status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective stat(%s,%p)\n",
instw.translpath,info);
result=true_stat(instw.translpath,info);
} else {
debug(4,"\teffective stat(%s,%p)\n",
instw.path,info);
result=true_stat(instw.path,info);
}
instw_delete(&instw);
return result;
}
#endif
#endif
int __xstat(int version,const char *pathname,struct stat *info) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"stat(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_xstat(version,pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective stat(%s,%p)\n",
instw.translpath,info);
result=true_xstat(version,instw.translpath,info);
} else {
debug(4,"\teffective stat(%s,%p)\n",
instw.path,info);
result=true_xstat(version,instw.path,info);
}
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
#ifndef __USE_FILE_OFFSET64
int lstat(const char *pathname,struct stat *info) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"lstat(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_lstat(pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective lstat(%s,%p)\n",
instw.translpath,info);
result=true_lstat(instw.translpath,info);
} else {
debug(4,"\teffective lstat(%s,%p)\n",
instw.path,info);
result=true_lstat(instw.path,info);
}
instw_delete(&instw);
return result;
}
#endif
#endif
int __lxstat(int version,const char *pathname,struct stat *info) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"lstat(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_lxstat(version,pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective lstat(%s,%p)\n",
instw.translpath,info);
result=true_lxstat(version,instw.translpath,info);
} else {
debug(4,"\teffective lstat(%s,%p)\n",
instw.path,info);
result=true_lxstat(version,instw.path,info);
}
instw_delete(&instw);
return result;
}
int symlink(const char *pathname, const char *slink) {
int result;
instw_t instw;
instw_t instw_slink;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"symlink(%s,%s)\n",pathname,slink);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_symlink(pathname,slink);
return result;
}
instw_new(&instw);
instw_new(&instw_slink);
instw_setpath(&instw,pathname);
instw_setpath(&instw_slink,slink);
#if DEBUG
instw_print(&instw_slink);
#endif
backup(instw_slink.truepath);
instw_apply(&instw_slink);
result=true_symlink(pathname,instw_slink.translpath);
logg("%d\tsymlink\t%s\t%s\t#%s\n",
result,instw.path,instw_slink.reslvpath,error(result));
instw_delete(&instw);
instw_delete(&instw_slink);
return result;
}
#ifndef __USE_FILE_OFFSET64
int truncate(const char *path, TRUNCATE_T length) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"truncate(%s,length)\n",path);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_truncate(path,length);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_truncate(instw.translpath,length);
logg("%d\ttruncate\t%s\t%d\t#%s\n",result,
instw.reslvpath,(int)length,error(result));
instw_delete(&instw);
return result;
}
#endif
int unlink(const char *pathname) {
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"unlink(%s)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_unlink(pathname);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_unlink(instw.translpath);
logg("%d\tunlink\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int utime (const char *pathname, const struct utimbuf *newtimes) {
int result;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"utime(%s,newtimes)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_utime(pathname,newtimes);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_utime(instw.translpath,newtimes);
logg("%d\tutime\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int utimes (const char *pathname, const struct timeval *newtimes) {
int result;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"utimes(%s,newtimes)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_utimes(pathname,newtimes);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_utimes(instw.translpath,newtimes);
logg("%d\tutimes\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int utimensat (int dirfd, const char *pathname,
const struct timespec times[2], int flags) {
int result;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"utimensat(%d,%s,times,0%o)\n",dirfd,pathname,flags);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_utimensat(dirfd,pathname,times,flags);
/* A null path means the descriptor itself, which needs no */
/* translating: it already refers to the translated file. */
if(pathname==NULL)
return true_utimensat(dirfd,pathname,times,flags);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
/* instw resolved an absolute path, so the descriptor is spent */
result=true_utimensat(AT_FDCWD,instw.translpath,times,flags);
logg("%d\tutimensat\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifdef WRAP_TIME64_ENTRY_POINTS
int __stat64_time64(const char *pathname, void *info) {
int result;
instw_t instw;
int status;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_stat64_time64(pathname,info);
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED)
result=true_stat64_time64(instw.translpath,info);
else
result=true_stat64_time64(instw.path,info);
instw_delete(&instw);
return result;
}
int __lstat64_time64(const char *pathname, void *info) {
int result;
instw_t instw;
int status;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_lstat64_time64(pathname,info);
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED)
result=true_lstat64_time64(instw.translpath,info);
else
result=true_lstat64_time64(instw.path,info);
instw_delete(&instw);
return result;
}
int __fstatat64_time64(int dirfd, const char *path, void *s, int flags) {
int result;
instw_t instw;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
if(flags & AT_SYMLINK_NOFOLLOW)
return true_lstat64_time64(path,s);
return true_stat64_time64(path,s);
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
/* instw resolved an absolute path, so the descriptor is spent */
if(flags & AT_SYMLINK_NOFOLLOW)
result=__lstat64_time64(instw.path,s);
else
result=__stat64_time64(instw.path,s);
instw_delete(&instw);
return result;
}
int __utime64(const char *pathname, const void *newtimes) {
int result;
instw_t instw;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_utime64(pathname,newtimes);
instw_new(&instw);
instw_setpath(&instw,pathname);
backup(instw.truepath);
instw_apply(&instw);
result=true_utime64(instw.translpath,newtimes);
logg("%d\tutime\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int __utimes64(const char *pathname, const void *newtimes) {
int result;
instw_t instw;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_utimes64(pathname,newtimes);
instw_new(&instw);
instw_setpath(&instw,pathname);
backup(instw.truepath);
instw_apply(&instw);
result=true_utimes64(instw.translpath,newtimes);
logg("%d\tutimes\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int __utimensat64(int dirfd, const char *pathname, const void *times, int flags) {
int result;
instw_t instw;
if(!libc_handle)
initialize();
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_utimensat64(dirfd,pathname,times,flags);
if(pathname==NULL)
return true_utimensat64(dirfd,pathname,times,flags);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,pathname);
backup(instw.truepath);
instw_apply(&instw);
result=true_utimensat64(AT_FDCWD,instw.translpath,times,flags);
logg("%d\tutimensat\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int access (const char *pathname, int type) {
int result;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"access(%s,%d)\n",pathname,type);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_access(pathname,type);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
/* access() cannot modify anything, so there is nothing to save */
instw_apply(&instw);
result=true_access(instw.translpath,type);
logg("%d\taccess\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int setxattr (const char *pathname, const char *name,
const void *value, size_t size, int flags)
{
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"setxattr(%s,%s)\n",pathname,name);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_setxattr(pathname,name,
value,size,flags);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_setxattr(instw.translpath,name,value,size,flags);
logg("%d\tsetxattr\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int removexattr (const char *pathname, const char *name)
{
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"removexattr(%s,%s)\n",pathname,name);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_removexattr(pathname,name);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_removexattr(instw.translpath,name);
logg("%d\tremovexattr\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int creat64(const char *pathname, __mode_t mode) {
/* Is it a system call? */
int result;
instw_t instw;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"creat64(%s,mode)\n",pathname);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_creat64(pathname,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_open64(instw.translpath,O_CREAT | O_WRONLY | O_TRUNC, mode);
logg("%d\tcreat\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int ftruncate64(int fd, __off64_t length) {
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"ftruncate64\n");
#endif
result = true_ftruncate64(fd, length);
logg("%d\tftruncate\t%d\t%d\t#%s\n",result,fd,(int)length,error(result));
return result;
}
FILE *fopen64(const char *pathname, const char *mode) {
FILE *result;
instw_t instw;
int status;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"fopen64(%s,%s)\n",pathname,mode);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_fopen64(pathname,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
if(mode[0]=='w'||mode[0]=='a'||mode[1]=='+') {
backup(instw.truepath);
instw_apply(&instw);
}
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective fopen64(%s)\n",instw.translpath);
result=true_fopen64(instw.translpath,mode);
} else {
debug(4,"\teffective fopen64(%s)\n",instw.path);
result=true_fopen64(instw.path,mode);
}
if(mode[0]=='w'||mode[0]=='a'||mode[1]=='+')
logg("%" PRIdPTR "\tfopen64\t%s\t#%s\n",(intptr_t)result,
instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
int open64(const char *pathname, int flags, ...) {
/* Eventually, there is a third parameter: it's mode_t mode */
va_list ap;
mode_t mode;
int result;
instw_t instw;
int status;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"open64(%s,%d,mode)\n",pathname,flags);
#endif
va_start(ap, flags);
mode = va_arg(ap, int /*promoted from mode_t*/);
va_end(ap);
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_open64(pathname,flags,mode);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
#if DEBUG
instw_print(&instw);
#endif
if(flags & (O_WRONLY | O_RDWR)) {
backup(instw.truepath);
instw_apply(&instw);
}
instw_getstatus(&instw,&status);
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective open64(%s)\n",instw.translpath);
result=true_open64(instw.translpath,flags,mode);
} else {
debug(4,"\teffective open64(%s)\n",instw.path);
result=true_open64(instw.path,flags,mode);
}
if(flags & (O_WRONLY | O_RDWR))
logg("%d\topen\t%s\t#%s\n",result,
instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
struct dirent64 *readdir64(DIR *dir) {
struct dirent64 *result;
if (!libc_handle)
initialize();
#if DEBUG
debug(3,"readdir64(%p)\n",dir);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_readdir64(dir);
return result;
}
result=true_readdir64(dir);
#if DEBUG
__instw_printdirent64(result);
#endif
return result;
}
int scandir64( const char *dir,struct dirent64 ***namelist,
int (*select)(const struct dirent64 *),
#if (GLIBC_MINOR >= 10)
int (*compar)(const struct dirent64 **,const struct dirent64 **) ) {
#else
int (*compar)(const void *,const void *) ) {
#endif
int result;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"scandir64(%s,%p,%p,%p)\n",dir,namelist,select,compar);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_scandir64(dir,namelist,select,compar);
return result;
}
result=true_scandir64(dir,namelist,select,compar);
return result;
}
#if (GLIBC_MINOR >= 33)
int stat64(const char *pathname,struct stat64 *info) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"stat64(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_stat64(pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
if (!libc_handle)
initialize();
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective stat64(%s,%p)\n",
instw.translpath,info);
result=true_stat64(instw.translpath,info);
} else {
debug(4,"\teffective stat64(%s,%p)\n",
instw.path,info);
result=true_stat64(instw.path,info);
}
instw_delete(&instw);
return result;
}
#endif
int __xstat64(int version,const char *pathname,struct stat64 *info) {
int result;
instw_t instw;
int status;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"stat64(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_xstat64(version,pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
if (!libc_handle)
initialize();
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective stat64(%s,%p)\n",
instw.translpath,info);
result=true_xstat64(version,instw.translpath,info);
} else {
debug(4,"\teffective stat64(%s,%p)\n",
instw.path,info);
result=true_xstat64(version,instw.path,info);
}
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
int lstat64(const char *pathname,struct stat64 *info) {
int result;
instw_t instw;
int status;
if(!libc_handle)
initialize();
#if DEBUG
debug(2,"lstat64(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_lstat64(pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective lstat64(%s,%p)\n",
instw.translpath,info);
result=true_lstat64(instw.translpath,info);
} else {
debug(4,"\teffective lstat64(%s,%p)\n",
instw.path,info);
result=true_lstat64(instw.path,info);
}
instw_delete(&instw);
return result;
}
#endif
int __lxstat64(int version,const char *pathname,struct stat64 *info) {
int result;
instw_t instw;
int status;
if(!libc_handle)
initialize();
#if DEBUG
debug(2,"lstat64(%s,%p)\n",pathname,info);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_lxstat64(version,pathname,info);
return result;
}
instw_new(&instw);
instw_setpath(&instw,pathname);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective lstat64(%s,%p)\n",
instw.translpath,info);
result=true_lxstat64(version,instw.translpath,info);
} else {
debug(4,"\teffective lstat64(%s,%p)\n",
instw.path,info);
result=true_lxstat64(version,instw.path,info);
}
instw_delete(&instw);
return result;
}
int truncate64(const char *path, __off64_t length) {
int result;
instw_t instw;
if (!libc_handle)
initialize();
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"truncate64(%s,length)\n",path);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) ) {
result=true_truncate64(path,length);
return result;
}
instw_new(&instw);
instw_setpath(&instw,path);
#if DEBUG
instw_print(&instw);
#endif
backup(instw.truepath);
instw_apply(&instw);
result=true_truncate64(instw.translpath,length);
logg("%d\ttruncate\t%s\t%d\t#%s\n",result,
instw.reslvpath,(int)length,error(result));
instw_delete(&instw);
return result;
}
/***********************************************
* openat() and its relatives are defined here
*
* They are mostly wrappers for the already
* defined "non-at" functions defined above.
*
* They transform the path relative to the
* fd into an absolute path and then call
* the normal functions. The transformation
* is done by calling instw_setpathrel().
*
* Maybe we could wrap all of these into a
* single generic wrap-any function?
*
* Thanks to Gilbert Ashley for his work on this!
*/
#ifndef __USE_FILE_OFFSET64
int openat (int dirfd, const char *path, int flags, ...) {
mode_t mode = 0;
va_list arg;
if(flags & O_CREAT) {
va_start(arg, flags);
mode = va_arg(arg, int /*promoted from mode_t*/);
va_end (arg);
}
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
return open(path, flags, mode);
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "openat(%d, %s, 0x%x, 0%o)\n", dirfd, path, flags, mode);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_open(path,flags,mode);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
result=open(instw.path,flags,mode);
instw_delete(&instw);
return result;
}
#endif
/* Programs built for large files call this one, and on a 32-bit system
* that is most of them. Left unwrapped, their writes went straight to
* the real filesystem. */
int openat64 (int dirfd, const char *path, int flags, ...) {
mode_t mode = 0;
va_list arg;
if(flags & O_CREAT) {
va_start(arg, flags);
mode = va_arg(arg, int /*promoted from mode_t*/);
va_end (arg);
}
return openat(dirfd, path, flags, mode);
}
int fchmodat (int dirfd, const char *path, mode_t mode, int flag) {
int result;
instw_t instw;
/* Without AT_SYMLINK_NOFOLLOW this is chmod() on a path, and the
* chmod() wrapper below does the translating. The flag has to be
* carried when it is set, because chmod() follows the link and the
* mode then lands on the target: a dangling link fails with ENOENT,
* and a live one has the link's permissions written over its own.
* tar sets the flag for every symlink it extracts. */
/* If all we are doing is normal open, forgo refcounting, etc. */
if(!(flag & AT_SYMLINK_NOFOLLOW) && (dirfd == AT_FDCWD || *path == '/'))
{
#if DEBUG
debug(2, "fchmodat(%d,%s,0%o)\n", dirfd, path, mode);
#endif
return chmod(path, mode);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "fchmodat(%d,%s,0%o)\n", dirfd, path, mode);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_fchmodat(dirfd,path,mode,flag);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
if(flag & AT_SYMLINK_NOFOLLOW) {
/* Nothing is backed up here: this changes the link rather
* than the file it names. */
instw_apply(&instw);
result=true_fchmodat(AT_FDCWD,instw.translpath,mode,flag);
logg("%d\tfchmodat\t%s\t0%04o\t#%s\n",result,
instw.reslvpath,mode,error(result));
} else {
result=chmod(instw.path,mode);
}
instw_delete(&instw);
return result;
}
int fchownat (int dirfd, const char *path,uid_t owner,gid_t group,int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "fchownat(%d,%s,%d,%d,0%o)\n", dirfd, path, owner, group, flags);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lchwon() behaviour, according to fchownat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return lchown(path, owner, group);
}
else {
return chown(path, owner, group);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"fchownat(%d,%s,%d,%d,0%o)\n", dirfd, path, owner, group, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lchwon() behaviour, according to fchownat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return true_lchown(path, owner, group);
}
else {
return true_chown(path, owner, group);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lchwon() behaviour, according to fchownat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
result=lchown(instw.path, owner, group);
}
else {
result=chown(instw.path, owner, group);
}
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
#ifndef __USE_FILE_OFFSET64
int fstatat (int dirfd, const char *path, struct stat *s, int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "fstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return lstat(path, s);
}
else {
return stat(path, s);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "fstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return true_lstat(path, s);
}
else {
return true_stat(path, s);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
result=lstat(instw.path, s);
}
else {
result=stat(instw.path, s);
}
instw_delete(&instw);
return result;
}
#endif
#endif
int __fxstatat (int version, int dirfd, const char *path, struct stat *s, int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "__fxstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return __lxstat(version, path, s);
}
else {
return __xstat(version, path, s);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "__fxstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return true_lxstat(version, path, s);
}
else {
return true_xstat(version, path, s);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
result=__lxstat(version, instw.path, s);
}
else {
result=__xstat(version, instw.path, s);
}
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
int fstatat64 (int dirfd, const char *path, struct stat64 *s, int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "fstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return lstat64(path, s);
}
else {
return stat64(path, s);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "fstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return true_lstat64(path, s);
}
else {
return true_stat64(path, s);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
result=lstat64(instw.path, s);
}
else {
result=stat64(instw.path, s);
}
instw_delete(&instw);
return result;
}
#endif
int __fxstatat64 (int version, int dirfd, const char *path, struct stat64 *s, int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "__fxstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return __lxstat64(version, path, s);
}
else {
return __xstat64(version, path, s);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "__fxstatat(%d,%s,%p,0%o)\n", dirfd, path, s, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
return true_lxstat64(version, path, s);
}
else {
return true_xstat64(version, path, s);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_SYMLINK_NOFOLLOW then we need */
/* lstat() behaviour, according to fstatat(2) */
if ( flags & AT_SYMLINK_NOFOLLOW ) {
result=__lxstat64(version, instw.path, s);
}
else {
result=__xstat64(version, instw.path, s);
}
instw_delete(&instw);
return result;
}
int linkat (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, int flags) {
int result;
int unnamed_source;
instw_t instwold;
instw_t instwnew;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "linkat(%d, %s, %d, %s, 0%o)\n", olddirfd, oldpath, newdirfd, newpath, flags );
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
/* An empty oldpath with AT_EMPTY_PATH names olddirfd itself, which */
/* may be an O_TMPFILE with no path to translate. */
unnamed_source=(flags&AT_EMPTY_PATH) && oldpath[0]=='\0';
instw_new(&instwold);
instw_new(&instwnew);
if(!unnamed_source) instw_setpathrel(&instwold,olddirfd,oldpath);
instw_setpathrel(&instwnew,newdirfd,newpath);
#if DEBUG
instw_print(&instwold);
instw_print(&instwnew);
#endif
if(!unnamed_source) {
backup(instwold.truepath);
instw_apply(&instwold);
}
instw_apply(&instwnew);
/* instw resolved the named ends to absolute paths, so those */
/* descriptors are spent and the files to link are the translated */
/* ones. */
if(unnamed_source)
result=true_linkat(olddirfd, oldpath,
AT_FDCWD, instwnew.translpath, flags);
else
result=true_linkat(AT_FDCWD, instwold.translpath,
AT_FDCWD, instwnew.translpath, flags);
logg("%d\tlinkat\t%s\t%s\t#%s\n",result,
instwold.reslvpath,instwnew.reslvpath,error(result));
instw_delete(&instwold);
instw_delete(&instwnew);
return result;
}
int mkdirat (int dirfd, const char *path, mode_t mode) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "mkdirat(%d,%s,0%o)\n", dirfd, path, mode);
#endif
return mkdir(path, mode);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "mkdirat(%d,%s,0%o)\n", dirfd, path, mode);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_mkdir(path,mode);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
result=mkdir(instw.path,mode);
instw_delete(&instw);
return result;
}
/* Translate the template before passing it to glibc. */
static int temp_prepare(instw_t *instw,const char *template,
char *translated,size_t translsz) {
int status;
instw_new(instw);
instw_setpath(instw,template);
instw_apply(instw);
instw_getstatus(instw,&status);
if(!(status&INSTW_TRANSLATED)) return 0;
if(strlen(instw->translpath)>=translsz) return 0;
strcpy(translated,instw->translpath);
return 1;
}
/* Copy the six generated characters back to the caller's template. Only */
/* the X's differ between the two names, and mkstemps() keeps suffixlen */
/* characters after them, so count from the end. */
static void temp_commit(char *template,const char *created,int suffixlen) {
size_t tlen,clen;
tlen=strlen(template);
clen=strlen(created);
if(tlen<(size_t)(6+suffixlen) || clen<(size_t)(6+suffixlen)) return;
memcpy(template+tlen-6-suffixlen,created+clen-6-suffixlen,6);
}
#ifndef __USE_FILE_OFFSET64
int mkstemp(char *template) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkstemp(%s)\n",template);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkstemp(template);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkstemp(template);
}
result=true_mkstemp(translated);
if(result>=0) {
temp_commit(template,translated,0);
/* re-read the path: it names a real file now */
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int mkstemp64(char *template) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkstemp64(%s)\n",template);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkstemp64(template);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkstemp64(template);
}
result=true_mkstemp64(translated);
if(result>=0) {
temp_commit(template,translated,0);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
int mkostemp(char *template,int flags) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkostemp(%s,0%o)\n",template,flags);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkostemp(template,flags);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkostemp(template,flags);
}
result=true_mkostemp(translated,flags);
if(result>=0) {
temp_commit(template,translated,0);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int mkostemp64(char *template,int flags) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkostemp64(%s,0%o)\n",template,flags);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkostemp64(template,flags);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkostemp64(template,flags);
}
result=true_mkostemp64(translated,flags);
if(result>=0) {
temp_commit(template,translated,0);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
int mkstemps(char *template,int suffixlen) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkstemps(%s,%d)\n",template,suffixlen);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkstemps(template,suffixlen);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkstemps(template,suffixlen);
}
result=true_mkstemps(translated,suffixlen);
if(result>=0) {
temp_commit(template,translated,suffixlen);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int mkstemps64(char *template,int suffixlen) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkstemps64(%s,%d)\n",template,suffixlen);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkstemps64(template,suffixlen);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkstemps64(template,suffixlen);
}
result=true_mkstemps64(translated,suffixlen);
if(result>=0) {
temp_commit(template,translated,suffixlen);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#ifndef __USE_FILE_OFFSET64
int mkostemps(char *template,int suffixlen,int flags) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkostemps(%s,%d,0%o)\n",template,suffixlen,flags);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkostemps(template,suffixlen,flags);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkostemps(template,suffixlen,flags);
}
result=true_mkostemps(translated,suffixlen,flags);
if(result>=0) {
temp_commit(template,translated,suffixlen);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
#endif
int mkostemps64(char *template,int suffixlen,int flags) {
char translated[PATH_MAX+1];
instw_t instw;
int result;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkostemps64(%s,%d,0%o)\n",template,suffixlen,flags);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkostemps64(template,suffixlen,flags);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkostemps64(template,suffixlen,flags);
}
result=true_mkostemps64(translated,suffixlen,flags);
if(result>=0) {
temp_commit(template,translated,suffixlen);
instw_setpath(&instw,template);
}
logg("%d\tmkstemp\t%s\t#%s\n",result,instw.reslvpath,error(result));
instw_delete(&instw);
return result;
}
char *mkdtemp(char *template) {
char translated[PATH_MAX+1];
instw_t instw;
char *result;
int rcod;
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"mkdtemp(%s)\n",template);
#endif
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_mkdtemp(template);
if(!temp_prepare(&instw,template,translated,sizeof(translated))) {
instw_delete(&instw);
return true_mkdtemp(template);
}
result=true_mkdtemp(translated);
rcod=(result==NULL)?-1:0;
if(result!=NULL) {
temp_commit(template,translated,0);
instw_setpath(&instw,template);
}
logg("%d\tmkdtemp\t%s\t#%s\n",rcod,instw.reslvpath,error(rcod));
instw_delete(&instw);
/* the caller owns the template; hand back their own buffer */
return (result==NULL)?NULL:template;
}
/* Fortified calls bypass the ordinary interposed symbols. */
/* The caller supplies no mode, so pass one explicitly. */
#ifndef __USE_FILE_OFFSET64
int __open_2(const char *pathname, int flags) {
return open(pathname, flags, 0);
}
#endif
int __open64_2(const char *pathname, int flags) {
return open64(pathname, flags, 0);
}
#ifndef __USE_FILE_OFFSET64
int __openat_2(int dirfd, const char *pathname, int flags) {
return openat(dirfd, pathname, flags, 0);
}
#endif
int __openat64_2(int dirfd, const char *pathname, int flags) {
return openat(dirfd, pathname, flags, 0);
}
#if (GLIBC_MINOR >= 28)
int statx(int dirfd, const char *path, int flags,
unsigned int mask, struct statx *buf) {
int result;
int status;
instw_t instw;
if (!libc_handle)
initialize();
#if DEBUG
debug(2,"statx(%d,%s,0%o,%u,%p)\n",dirfd,path,flags,mask,buf);
#endif
/* We were asked to work in "real" mode */
if( !(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP) )
return true_statx(dirfd,path,flags,mask,buf);
/* An empty path asks about 'dirfd' itself (AT_EMPTY_PATH), */
/* so there is nothing for us to translate. */
if(path==NULL || *path=='\0')
return true_statx(dirfd,path,flags,mask,buf);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
instw_getstatus(&instw,&status);
#if DEBUG
instw_print(&instw);
#endif
/* instw gave us an absolute path, so 'dirfd' is spent */
if(status&INSTW_TRANSLATED) {
debug(4,"\teffective statx(%s)\n",instw.translpath);
result=true_statx(AT_FDCWD,instw.translpath,flags,mask,buf);
} else {
debug(4,"\teffective statx(%s)\n",instw.path);
result=true_statx(AT_FDCWD,instw.path,flags,mask,buf);
}
instw_delete(&instw);
return result;
}
#endif
READLINKAT_T readlinkat (int dirfd, const char *path,
char *buf, size_t bufsiz) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "readlinkat(%d,%s, %s, %ld)\n", dirfd, path, buf, (long)bufsiz);
#endif
return readlink(path, buf, bufsiz);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "readlinkat(%d,%s, %s, %ld)\n", dirfd, path, buf, (long)bufsiz);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_readlink(path, buf, bufsiz);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
result=readlink(instw.path, buf, bufsiz);
instw_delete(&instw);
return result;
}
#if (GLIBC_MINOR >= 33)
int mknodat (int dirfd,const char *path,mode_t mode,dev_t dev) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "mknod(%s, mode, dev)\n", path);
#endif
return mknod(path, mode, dev);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "mknod(%s, mode, dev)\n", path);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_mknod(path, mode, dev);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
result=mknod(instw.path, mode, dev);
instw_delete(&instw);
return result;
}
#endif
int __xmknodat (int version, int dirfd,const char *path,mode_t mode,dev_t *dev) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "__xmknod(%d, %s, 0%o, %p)\n", version, path, mode, dev);
#endif
return __xmknod(version, path, mode, dev);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "__xmknod(%d, %s, 0%o, %p)\n", version, path, mode, dev);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_xmknod(version, path, mode, dev);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
result=__xmknod(version, instw.path, mode, dev);
instw_delete(&instw);
return result;
}
int renameat (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath) {
int result;
instw_t instwold;
instw_t instwnew;
/* If all we are doing is normal open, forgo refcounting, etc. */
if( (olddirfd == AT_FDCWD || *oldpath == '/') &&
(newdirfd == AT_FDCWD || *newpath == '/') )
{
#if DEBUG
debug(2, "renameat(%d, %s, %d, %s)\n", olddirfd, oldpath, newdirfd, newpath);
#endif
return rename(oldpath, newpath);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "renameat(%d, %s, %d, %s)\n", olddirfd, oldpath, newdirfd, newpath);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_rename(oldpath, newpath);
instw_new(&instwold);
instw_new(&instwnew);
instw_setpathrel(&instwold,olddirfd,oldpath);
instw_setpathrel(&instwnew,newdirfd,newpath);
#if DEBUG
instw_print(&instwold);
instw_print(&instwnew);
#endif
result=rename(instwold.path, instwnew.path);
instw_delete(&instwold);
instw_delete(&instwnew);
return result;
}
/* Note that this only implements RENAME_NOREPLACE */
int renameat2 (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, unsigned int flags) {
if (!libc_handle)
initialize();
if ( (flags & RENAME_NOREPLACE) == RENAME_NOREPLACE ) {
instw_t instwnew;
instw_new(&instwnew);
instw_setpathrel(&instwnew,newdirfd,newpath);
struct stat buf;
if (stat(instwnew.path, &buf) == 0) return EEXIST;
}
return renameat (olddirfd, oldpath, newdirfd, newpath);
}
int symlinkat (const char *oldpath, int dirfd, const char *newpath) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *newpath == '/')
{
#if DEBUG
debug(2, "symlinkat(%s, %d, %s)\n", oldpath, dirfd, newpath);
#endif
return symlink(oldpath, newpath);
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "symlinkat(%s, %d, %s)\n", oldpath, dirfd, newpath);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_symlink(oldpath, newpath);
instw_new(&instw);
instw_setpathrel(&instw,dirfd,newpath);
#if DEBUG
instw_print(&instw);
#endif
result=symlink(oldpath, instw.path);
instw_delete(&instw);
return result;
}
int unlinkat (int dirfd, const char *path, int flags) {
int result;
instw_t instw;
/* If all we are doing is normal open, forgo refcounting, etc. */
if(dirfd == AT_FDCWD || *path == '/')
{
#if DEBUG
debug(2, "unlinkat(%d,%s,0%o)\n", dirfd, path, flags);
#endif
/* If we have AT_REMOVEDIR then we need */
/* rmdir() behaviour, according to unlinkat(2) */
if ( flags & AT_REMOVEDIR ) {
return rmdir(path);
}
else {
return unlink(path);
}
}
REFCOUNT;
if (!libc_handle)
initialize();
#if DEBUG
debug(2, "unlinkat(%d,%s,0%o)\n", dirfd, path, flags);
#endif
/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP)) {
/* If we have AT_REMOVEDIR then we need */
/* rmdir() behaviour, according to unlinkat(2) */
if ( flags & AT_REMOVEDIR ) {
result=true_rmdir(path);
}
else {
result=true_unlink(path);
}
}
instw_new(&instw);
instw_setpathrel(&instw,dirfd,path);
#if DEBUG
instw_print(&instw);
#endif
/* If we have AT_REMOVEDIR then we need */
/* rmdir() behaviour, according to unlinkat(2) */
if ( flags & AT_REMOVEDIR ) {
result=rmdir(instw.path);
}
else {
result=unlink(instw.path);
}
instw_delete(&instw);
return result;
}
ssgelm-checkinstall-59a004a/installwatch/libcfiletest.c 0000664 0000000 0000000 00000000045 15235417303 0023307 0 ustar 00root root 0000000 0000000 int main(void) {
return 0;
}
ssgelm-checkinstall-59a004a/installwatch/libctest.c 0000664 0000000 0000000 00000000247 15235417303 0022453 0 ustar 00root root 0000000 0000000 /* Dummy program to check your libc version */
#include
#include
int main (void) {
puts (gnu_get_libc_version ());
return 0;
}
ssgelm-checkinstall-59a004a/installwatch/test-installwatch.c 0000664 0000000 0000000 00000012716 15235417303 0024320 0 ustar 00root root 0000000 0000000 /* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 1998-99 Pancrazio `Ezio' de Mauro
*
* 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 .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "localdecls.h"
#ifndef LIBDIR
#define LIBDIR "/usr/local/lib"
#endif
#define TESTFILE "/tmp/installwatch-test"
#define TESTFILE2 TESTFILE "2"
int *refcount;
int *timecount;
int passed, failed;
void* libc_handle=NULL;
void check_installwatch(void) {
char *error;
time(NULL);
libc_handle=dlopen(LIBDIR"/installwatch.so",RTLD_LAZY);
if(!libc_handle) {
puts("Unable to open "LIBDIR"/installwatch.so");
exit(255);
}
time(NULL);
timecount=(int*)dlsym(libc_handle,"__installwatch_timecount");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(255);
}
if((*timecount)<2) {
puts("This program must be run with installwatch");
dlclose(libc_handle);
exit(255);
}
refcount=(int*)dlsym(libc_handle,"__installwatch_refcount");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(255);
}
}
void test_chmod(void) {
int fd;
fd = creat(TESTFILE, 0600);
close(fd);
chmod(TESTFILE, 0600);
unlink(TESTFILE);
}
void test_chown(void) {
int fd;
fd = creat(TESTFILE, 0600);
close(fd);
chown(TESTFILE, geteuid(), getegid());
unlink(TESTFILE);
}
void test_chroot(void) {
chroot("/");
}
void test_creat(void) {
int fd;
fd = creat(TESTFILE, 0600);
close(fd);
unlink(TESTFILE);
}
void test_fchmod(void) {
int fd;
fd = creat(TESTFILE, 0600);
fchmod(fd, 0600);
close(fd);
unlink(TESTFILE);
}
void test_fchown(void) {
int fd;
fd = creat(TESTFILE, 0600);
fchown(fd, geteuid(), getegid());
close(fd);
unlink(TESTFILE);
}
void test_fopen(void) {
FILE *fd;
fd = fopen(TESTFILE,"w");
fclose(fd);
unlink(TESTFILE);
}
void test_ftruncate(void) {
int fd;
fd = creat(TESTFILE, 0600);
ftruncate(fd, 0);
close(fd);
unlink(TESTFILE);
}
void test_lchown(void) {
int fd;
fd = creat(TESTFILE, 0600);
close(fd);
lchown(TESTFILE, geteuid(), getegid());
unlink(TESTFILE);
}
void test_link(void) {
int fd;
fd = creat(TESTFILE, 0600);
close(fd);
link(TESTFILE, TESTFILE2);
unlink(TESTFILE);
unlink(TESTFILE2);
}
void test_mkdir(void) {
mkdir(TESTFILE, 0700);
rmdir(TESTFILE);
}
void test_open(void) {
int fd;
fd = open(TESTFILE, O_CREAT, O_RDWR, 0700);
close(fd);
unlink(TESTFILE);
}
void test_rename(void) {
int fd;
fd = creat(TESTFILE, 0700);
close(fd);
rename(TESTFILE, TESTFILE2);
unlink(TESTFILE2);
}
void test_symlink(void) {
int fd;
fd = creat(TESTFILE, 0700);
close(fd);
symlink(TESTFILE, TESTFILE2);
unlink(TESTFILE);
unlink(TESTFILE2);
}
void test_truncate(void) {
int fd;
fd = creat(TESTFILE, 0700);
close(fd);
truncate(TESTFILE, 0);
unlink(TESTFILE);
}
void test_unlink(void) {
int fd;
fd = creat(TESTFILE, 0700);
close(fd);
unlink(TESTFILE);
}
int do_test(const char *name, void (*function)(void), int increment) {
int old_refcount;
printf("Testing %s... ", name);
old_refcount = *refcount;
function();
if(*refcount == old_refcount + increment) {
printf("wanted refcount=%d returned refcount=%d",
(old_refcount+increment),*refcount);
puts("passed");
passed++;
return 0;
} else {
printf("wanted refcount=%d returned refcount=%d",
(old_refcount+increment),*refcount);
puts("failed");
failed++;
return 1;
}
}
int main(int argc, char **argv) {
struct stat statbuf;
check_installwatch();
if(stat(TESTFILE, &statbuf) != -1) {
printf(TESTFILE " already exists. Please remove it and run %s again\n", argv[0]);
exit(254);
}
if(stat(TESTFILE2, &statbuf) != -1) {
printf(TESTFILE2 " already exists. Please remove it and run %s again\n", argv[0]);
exit(254);
}
puts("Testing installwatch " VERSION);
puts("Using " TESTFILE " and " TESTFILE2 " as a test files\n");
passed = failed = 0;
do_test("chmod", test_chmod, 3);
do_test("chown", test_chown, 3);
do_test("chroot", test_chroot, 1);
do_test("creat", test_creat, 2);
do_test("fchmod", test_fchmod, 3);
do_test("fchown", test_fchown, 3);
do_test("fopen",test_fopen,2);
do_test("ftruncate", test_ftruncate, 3);
do_test("lchown", test_lchown, 3);
do_test("link", test_link, 4);
do_test("mkdir", test_mkdir, 2);
/* do_test("mknod", test_mknod, 2); */
do_test("open", test_open, 2);
do_test("rename", test_rename, 3);
do_test("rmdir", test_mkdir, 2);
do_test("symlink", test_symlink, 4);
do_test("truncate", test_truncate, 3);
do_test("unlink", test_unlink, 2);
putchar('\n');
if(failed != 0) {
printf("%d tests were not successful!\n", failed);
printf("Please email this log to the maintainer with the output of\n");
printf("\tnm %s\n", argv[0]);
} else
printf("All tests successful!\n");
if(libc_handle!=NULL)
dlclose(libc_handle);
return failed;
}
ssgelm-checkinstall-59a004a/locale/ 0000775 0000000 0000000 00000000000 15235417303 0017235 5 ustar 00root root 0000000 0000000 ssgelm-checkinstall-59a004a/locale/checkinstall-de.po 0000664 0000000 0000000 00000115351 15235417303 0022635 0 ustar 00root root 0000000 0000000 # MESSAGES FOR CHECKINSTALL-1.6.0beta1 in
# Copyright (C) 2002 Felipe Eduardo Sanchez Diaz Duran
# Felipe Eduardo Sanchez Diaz Duran , 2002.
#
#
# Replace the above and following info with the appropriate data for
# your name, date and language.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 1.6.0beta1\n"
"Report-Msgid-Bugs-To: https://github.com/ssgelm/checkinstall/issues\n"
"POT-Creation-Date: 2026-08-07 02:20-0500\n"
"PO-Revision-Date: 2003-03-17 13:30+0100\n"
"Last-Translator: Andreas Muck \n"
"Language-Team: DE \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-15\n"
"Content-Transfer-Encoding: 8bit\n"
#: checkinstall.in:83 checkinstall.in:337
msgid "Bye."
msgstr "Auf Wiedersehen!"
#: checkinstall.in:110
msgid " This software is released under the GNU GPL."
msgstr " Diese Software wurde unter der GNU GPL veröffentlicht"
#: checkinstall.in:124
msgid "Usage: checkinstall [options] [command [command arguments]]"
msgstr "Benutzung: checkinstall [Optionen] [Befehl [Befehls-Argumente]]"
#: checkinstall.in:125
msgid "Options:"
msgstr "Optionen:"
#: checkinstall.in:127
msgid "*Package type selection*"
msgstr "*Auswahl des Paket-Typs*"
#: checkinstall.in:129
msgid "-t,--type= Choose packaging system"
msgstr "-t, --type= Wählen Sie Ihr Paket-System"
#: checkinstall.in:130
msgid "-S Build a Slackware package"
msgstr "-S Erstelle ein Slackware-Paket"
#: checkinstall.in:131
msgid "-R Build a RPM package"
msgstr "-R Erstelle ein RPM-Paket"
#: checkinstall.in:132
msgid "-D Build a Debian package"
msgstr "-D Erstelle ein Debian-Paket"
#: checkinstall.in:134
msgid "*Install options*"
msgstr "*Installations-Optionen*"
#: checkinstall.in:136
msgid "--install= Toggle created package installation"
msgstr "--install= Soll des erstellte Paket installiert werden?"
#: checkinstall.in:137
#, fuzzy
#| msgid "--delspec= Delete spec file upon termination"
msgid ""
"--fstrans= Enable/disable the filesystem translation code"
msgstr ""
"--delspec= Lösche die spec-Datei nach Fertigstellung"
#: checkinstall.in:139
msgid "*Scripting options*"
msgstr "*Scripting Optionen*"
#: checkinstall.in:141
msgid "-y, --default Accept default answers to all questions"
msgstr "-y, --default Verwendet die Standard-Antwort bei allen Fragen"
#: checkinstall.in:142
msgid "--pkgname= Set name"
msgstr "--pkgname= Setzt den Paket-Namen"
#: checkinstall.in:143
msgid "--pkgversion= Set version"
msgstr "--pkgversion= Setzt die Paket-Version"
#: checkinstall.in:144
msgid "-A, --arch, --pkgarch= Set architecture"
msgstr "-A, --arch, --pkgarch= Setzt die Rechner-Architektur"
#: checkinstall.in:145
msgid "--pkgrelease= Set release"
msgstr "--pkgrelease= Setzt die Paket-Nummer"
#: checkinstall.in:146
msgid "--pkglicense= Set license"
msgstr "--pkglicense= Setzt die Paket-Lizenz"
#: checkinstall.in:147
msgid "--pkggroup= Set software group"
msgstr "--pkggroup= Setzt die Software-Gruppe"
#: checkinstall.in:148
msgid "--pkgsource= Set source location"
msgstr "--pkgsource= Setzt die Software-Quelle"
#: checkinstall.in:149
msgid "--pkgaltsource= Set alternate source location"
msgstr "--pkgaltsource= Setzt alternative Software-Quelle"
#: checkinstall.in:150
msgid "--pakdir= The new package will be saved here"
msgstr "--pakdir= Speichert hier das erstellte Paket"
#: checkinstall.in:151
msgid "--maintainer= The package maintainer (.deb)"
msgstr "--maintainer= Paket-Verantwortlicher (.deb)"
#: checkinstall.in:152
#, fuzzy
#| msgid ""
#| "--provides= Features provided by this package (.rpm)"
msgid "--provides= Features provided by this package"
msgstr "--provides= Eigenschaften dieses Pakets (.rpm)"
#: checkinstall.in:153
#, fuzzy
#| msgid ""
#| "--requires= Features required by this package (.rpm)"
msgid "--requires= Features required by this package"
msgstr ""
"--requires= Von diesem Paket benötigte Pakete (.rpm)"
#: checkinstall.in:154
#, fuzzy
#| msgid ""
#| "--requires= Features required by this package (.rpm)"
msgid ""
"--prerequires= Packages that must be installed and "
"configured before this package"
msgstr ""
"--requires= Von diesem Paket benötigte Pakete (.rpm)"
#: checkinstall.in:155
#, fuzzy
#| msgid ""
#| "--provides= Features provided by this package (.rpm)"
msgid "--recommends= Features recommended by this package"
msgstr "--provides= Eigenschaften dieses Pakets (.rpm)"
#: checkinstall.in:156
#, fuzzy
#| msgid ""
#| "--requires= Features required by this package (.rpm)"
msgid "--suggests= Features suggested by this package"
msgstr ""
"--requires= Von diesem Paket benötigte Pakete (.rpm)"
#: checkinstall.in:157
#, fuzzy
#| msgid "--rpmflags= Pass this flags to the rpm installer"
msgid ""
"--conflicts= Packages that this package cannot be "
"installed with (.deb)"
msgstr "--rpmflags= Installiert mit diesen Optionen (RPM)"
#: checkinstall.in:158
#, fuzzy
#| msgid ""
#| "--requires= Features required by this package (.rpm)"
msgid ""
"--replaces= Packages that this package replaces (.deb)"
msgstr ""
"--requires= Von diesem Paket benötigte Pakete (.rpm)"
#: checkinstall.in:159
msgid "--rpmflags= Pass this flags to the rpm installer"
msgstr "--rpmflags= Installiert mit diesen Optionen (RPM)"
#: checkinstall.in:160
#, fuzzy
#| msgid ""
#| "--review-spec Review the spec file before creating a .rpm"
msgid ""
"--rpmi Use the -i flag for rpm when installing a .rpm"
msgstr ""
"--review-spec Zeige die spec-Datei vor Paket-Erstellung"
#: checkinstall.in:161
#, fuzzy
#| msgid ""
#| "--review-spec Review the spec file before creating a .rpm"
msgid ""
"--rpmu Use the -U flag for rpm when installing a .rpm"
msgstr ""
"--review-spec Zeige die spec-Datei vor Paket-Erstellung"
#: checkinstall.in:162
msgid "--dpkgflags= Pass this flags to the dpkg installer"
msgstr "--dpkgflags= Installiert mit diesen Optionen (DPKG)"
#: checkinstall.in:163
msgid "--spec= .spec file location"
msgstr "--spec= Pfad zur .spec-Datei"
#: checkinstall.in:164
msgid "--nodoc Do not include documentation files"
msgstr "--nodoc Schließt Dokumentations-Dateien aus"
#: checkinstall.in:166
msgid "*Info display options*"
msgstr "*Optionen zur Info-Anzeige*"
#: checkinstall.in:168
msgid "-d<0|1|2> Set debug level"
msgstr "-d<0|1|2> Variiert den Fehlerinfo-Status"
#: checkinstall.in:169
msgid "-si Run an interactive install command"
msgstr ""
"-si Führe interaktiven Installations-Befehl aus"
#: checkinstall.in:170
msgid "--showinstall= Toggle interactive install command"
msgstr ""
"--showinstall= Aktiviert interaktiven Installations-Befehl"
#: checkinstall.in:171
msgid ""
"-ss Run an interactive Slackware installation "
"script"
msgstr ""
"-ss Führe interaktives Slackware-"
"Installationsprogramm aus"
#: checkinstall.in:172
msgid ""
"--showslack= Toggle interactive Slackware installation "
"script"
msgstr ""
"--showslack= Aktiviert interaktives Slackware-"
"Installationsprogramm"
#: checkinstall.in:174
msgid "*Package tuning options*"
msgstr "*Paket-Optimierungs-Optionen*"
#: checkinstall.in:176
msgid ""
"--autodoinst= Toggle the creation of a doinst.sh script"
msgstr ""
"--autodoinst= Aktiviert die Erstellung eines doinst.sh-"
"Skripts"
#: checkinstall.in:177
msgid ""
"--strip= Strip any ELF binaries found inside the "
"package"
msgstr ""
"--strip= Strippe alle ELF-Binärdateien des Pakets"
#: checkinstall.in:178
msgid ""
"--stripso= Strip any ELF binary libraries (.so files)"
msgstr ""
"--stripso= Strippe alle ELF-Binärbibliotheken (.so "
"Dateien)"
#: checkinstall.in:179
msgid ""
"--autodeps= Work out the shared library dependencies "
"of\\n the installed binaries with dpkg-"
"shlibdeps"
msgstr ""
#: checkinstall.in:180
#, fuzzy
#| msgid ""
#| "--strip= Strip any ELF binaries found inside the "
#| "package"
msgid "--addso= Search for any shared libs and add"
msgstr ""
"--strip= Strippe alle ELF-Binärdateien des Pakets"
#: checkinstall.in:181
#, fuzzy
#| msgid "-si Run an interactive install command"
msgid " them to /etc/ld.so.conf"
msgstr ""
"-si Führe interaktiven Installations-Befehl aus"
#: checkinstall.in:182
msgid ""
"--reset-uids= Reset perms for all files to o=g, dirs to 755 "
"and"
msgstr ""
#: checkinstall.in:183
msgid ""
" the owner/group for all dirs to root.root"
msgstr ""
#: checkinstall.in:184
msgid ""
"--gzman= Compress any man pages found inside the "
"package"
msgstr ""
"--gzman= Komprimiere die Manual-Dateien des Pakets"
#: checkinstall.in:185
msgid "--docdir= Where to put documentation files"
msgstr "--docdir= Pfad zu den System-Dokumentationen"
#: checkinstall.in:186
#, fuzzy
#| msgid "-si Run an interactive install command"
msgid ""
" The package name+version gets automatically "
"appended."
msgstr ""
"-si Führe interaktiven Installations-Befehl aus"
#: checkinstall.in:187
#, fuzzy
#| msgid "-D Build a Debian package"
msgid ""
" To avoid that prefix the path with a colon "
"(:)."
msgstr "-D Erstelle ein Debian-Paket"
#: checkinstall.in:188
msgid "--umask= Set the umask value"
msgstr "--umask= Setzt den Wert für 'umask'"
#: checkinstall.in:189
msgid ""
"--exclude= Exclude these files/directories from the "
"package"
msgstr ""
"--exclude= Schließe diese Dateien/Verzeichnisse aus "
"dem Paket aus"
#: checkinstall.in:190
msgid ""
"--include= Force the inclusion in the package of the"
msgstr ""
"--include= Baue die in angegebenen "
"Dateien in das Paket ein"
#: checkinstall.in:191
#, fuzzy
#| msgid "-D Build a Debian package"
msgid " files/dirs listed in \"listfile\""
msgstr "-D Erstelle ein Debian-Paket"
#: checkinstall.in:192
msgid "--inspect Inspect the package's file list"
msgstr "--inspect Zeige die Datei-Liste des Pakets"
#: checkinstall.in:193
msgid ""
"--review-spec Review the spec file before creating a .rpm"
msgstr ""
"--review-spec Zeige die spec-Datei vor Paket-Erstellung"
#: checkinstall.in:194
msgid ""
"--review-control Review the control file before creating a .deb"
msgstr ""
"--review-control Zeige die control-Datei vor Paket-Erstellung"
#: checkinstall.in:195
msgid ""
"--newslack Use the new (8.1+) Slackware description "
"format"
msgstr ""
"--newslack Nutze das neue (8.1+) Slackware-"
"Beschreibungsformat"
#: checkinstall.in:196
msgid " (\"--newslack\" implies \"-S\")"
msgstr " (\"--newslack\" impliziert \"-S\")"
#: checkinstall.in:197
msgid "--with-tar=/path/to/tar Manually set the path to the tar binary"
msgstr ""
#: checkinstall.in:198
#, fuzzy
#| msgid "-R Build a RPM package"
msgid " in this system"
msgstr "-R Erstelle ein RPM-Paket"
#: checkinstall.in:200
msgid "*Cleanup options*"
msgstr "*Nachbearbeitungs-Optionen*"
#: checkinstall.in:202
msgid "--deldoc= Delete doc-pak upon termination"
msgstr "--deldoc= Lösche doc-pak nach Fertigstellung"
#: checkinstall.in:203
msgid "--deldesc= Delete description-pak upon termination"
msgstr ""
"--deldesc= Lösche description-pak nach Fertigstellung"
#: checkinstall.in:204
msgid "--delspec= Delete spec file upon termination"
msgstr ""
"--delspec= Lösche die spec-Datei nach Fertigstellung"
#: checkinstall.in:205
msgid "--bk Backup any overwritten files"
msgstr "--bk Bewahre alle überschriebenen Dateien"
#: checkinstall.in:206
msgid "--backup= Toggle backup"
msgstr "--backup= Aktiviere Backup-Funktion"
#: checkinstall.in:208
msgid "*About CheckInstall*"
msgstr "*]ber CheckInstall*"
#: checkinstall.in:210
msgid "--help, -h Show this message"
msgstr "--help, -h Zeige diese Informationen"
#: checkinstall.in:211
msgid "--copyright Show Copyright information"
msgstr "--copyright Zeige Urheber-Informationen"
#: checkinstall.in:212
msgid "--version Show version information"
msgstr "--version Zeige Versions-Informationen"
#: checkinstall.in:220
msgid "Use --help or -h to get more information"
msgstr "Verwenden Sie --help oder -h für mehr Informationen"
#: checkinstall.in:228
#, fuzzy, sh-printf-format
#| msgid "is an invalid value for"
msgid "%s is an invalid value for %s"
msgstr "ist ein unzulässiger Wert für"
#: checkinstall.in:279
msgid " FAILED!"
msgstr ""
#: checkinstall.in:282
msgid "OK"
msgstr ""
#: checkinstall.in:297
msgid "Restoring overwritten files from backup..."
msgstr "Stelle überschriebene Dateien wieder her..."
#: checkinstall.in:310
msgid "*** SIGINT received ***"
msgstr "*** SIGINT erhalten ***"
#: checkinstall.in:317
msgid "Cleaning up..."
msgstr "Räume auf..."
#: checkinstall.in:509
msgid "Assuming default values."
msgstr "Verwende Standard-Werte."
#: checkinstall.in:828
#, sh-printf-format
msgid ""
"Warning: .spec file path \"%s\" not found.\\nWarning: Defaulting to \"%s\"."
msgstr ""
#: checkinstall.in:1072
#, sh-printf-format
msgid ""
"Warning: The path to tar specified in the command line is invalid."
"\\nWarning: It has been set to %s"
msgstr ""
#: checkinstall.in:1100
msgid ""
"I can't continue. Either install installwatch or\\nmodify the INSTALLWATCH "
"variable in this script,\\nthen run checkinstall again."
msgstr ""
#: checkinstall.in:1123
#, fuzzy, sh-printf-format
#| msgid "is an unacceptable value for the temp dir. Please"
msgid ""
"%s is an unacceptable value for the temp dir. Please \\nedit the variable "
"definition for %s and try again."
msgstr "ist kein akzeptabler Wert für das temporäre Verzeichnis. Bitte"
#: checkinstall.in:1125
msgid "*** Aborting"
msgstr "*** Abruch"
#: checkinstall.in:1132
#, sh-printf-format
msgid ""
"**** Failed to create temp dir! \\n**** Do you have write permission for %s? "
"\\n\\n**** Aborting installation."
msgstr ""
#: checkinstall.in:1155
#, fuzzy
#| msgid "The package documentation directory ./doc-pak does not exist."
msgid ""
"The package documentation directory ./doc-pak does not exist. \\nShould I "
"create a default set of package docs? "
msgstr "Das Paket-Dokumentationsverzeichnis ./doc-pak existiert nicht."
#: checkinstall.in:1158
msgid "Preparing package documentation..."
msgstr "Bereite Paket-Dokumentation vor..."
#: checkinstall.in:1174
#, fuzzy
#| msgid "*** No known documentation files were found. The new package"
msgid ""
"*** No known documentation files were found. The new package \\n*** won't "
"include a documentation directory."
msgstr "*** Keine bekannten Dokumentations-Dateien gefunden. Das Paket"
#: checkinstall.in:1192
msgid "Please choose the packaging method you want to use."
msgstr "Wählen Sie die Paket-Art, die Sie erzeugen wollen."
#: checkinstall.in:1193
msgid "Slackware [S], RPM [R] or Debian [D]? "
msgstr "Slackware [S], RPM [R] oder Debian [D]? "
#: checkinstall.in:1213
msgid "*** Invalid type."
msgstr ""
#: checkinstall.in:1237
msgid "Please write a description for the package."
msgstr "Bitte geben Sie eine Beschreibung für das Paket ein."
#: checkinstall.in:1242
#, fuzzy
#| msgid ""
#| "only the first one when listing packages so make that one descriptive."
msgid ""
" Remember that pkgtool shows\\nonly the first one when listing packages so "
"make that one descriptive."
msgstr "wenn Pakete gelistet werden. Diese sollte daher aussagekräftig sein."
#: checkinstall.in:1245
msgid "End your description with an empty line or EOF."
msgstr "Beenden Sie Ihre Beschreibung mit einer leeren Zeile oder EOF."
#: checkinstall.in:1263
#, fuzzy
#| msgid "Warning: Your package description is bigger than 11 lines."
msgid ""
"Warning: Your package description is bigger than 11 lines.\\nWarning: The "
"Slackware 8.1+ pkgtools might not like it."
msgstr "WARNUNG: Ihre Paketbeschreibung ist länger als 11 Zeilen."
#: checkinstall.in:1275
msgid ""
"********************************************\\n**** Slackware package "
"creation selected ***\\n********************************************"
msgstr ""
#: checkinstall.in:1280
msgid ""
"**************************************\\n**** RPM package creation selected "
"***\\n**************************************"
msgstr ""
#: checkinstall.in:1285
msgid ""
"*****************************************\\n**** Debian package creation "
"selected ***\\n*****************************************"
msgstr ""
#: checkinstall.in:1355
#, sh-printf-format
msgid ""
"*** Warning: The package name \"%s\" contains spaces.\\n*** Warning: Package "
"names with spaces in them are not valid in most\\n*** Warning: packaging "
"systems so I changed all spaces to underscores."
msgstr ""
#: checkinstall.in:1364
#, sh-printf-format
msgid ""
"*** Warning: The package name \"%s\" contains upper case\\n*** Warning: "
"letters. dpkg might not like that so I changed\\n*** Warning: them to lower "
"case."
msgstr ""
#: checkinstall.in:1372
#, sh-printf-format
msgid ""
"*** Warning: The package name \"%s\" does not start with\\n*** Warning: an "
"alphanumetic character. dpkg might not like that so I prefixed\\n*** "
"Warning: it with a number 0."
msgstr ""
#: checkinstall.in:1378
#, sh-printf-format
msgid ""
"*** Warning: The package name \"%s\" contains illegal\\n*** Warning: "
"characters. dpkg might not like that so I changed\\n*** Warning: them to "
"dashes."
msgstr ""
#: checkinstall.in:1403
#, sh-printf-format
msgid ""
"*** Warning: The package version \"%s\" is not a\\n*** Warning: debian "
"policy compliant one. Please specify an alternate one"
msgstr ""
#: checkinstall.in:1460
msgid "This package will be built according to these values: "
msgstr "Das Paket wird entsprechend dieser Vorgaben erstellt:"
#: checkinstall.in:1464
#, fuzzy, sh-printf-format
#| msgid "0 - Maintainer:"
msgid "0 - Maintainer: [ %s ]"
msgstr "0 - Programm-Verantwortlicher:"
#: checkinstall.in:1466
#, fuzzy, sh-printf-format
#| msgid "1 - Summary:"
msgid "1 - Summary: [ %s ]"
msgstr "1 - Zusammenfassung:"
#: checkinstall.in:1467
#, fuzzy, sh-printf-format
#| msgid "2 - Name:"
msgid "2 - Name: [ %s ]"
msgstr "2 - Name:"
#: checkinstall.in:1468
#, fuzzy, sh-printf-format
#| msgid "3 - Version:"
msgid "3 - Version: [ %s ]"
msgstr "3 - Version:"
#: checkinstall.in:1469
#, sh-printf-format
msgid "4 - Release: [ %s ]"
msgstr ""
#: checkinstall.in:1470
#, fuzzy, sh-printf-format
#| msgid "5 - License:"
msgid "5 - License: [ %s ]"
msgstr "5 - Lizenz:"
#: checkinstall.in:1471
#, fuzzy, sh-printf-format
#| msgid "6 - Group:"
msgid "6 - Group: [ %s ]"
msgstr "6 - Gruppe:"
#: checkinstall.in:1472
#, fuzzy, sh-printf-format
#| msgid "7 - Architecture:"
msgid "7 - Architecture: [ %s ]"
msgstr "7 - Rechner-Architektur:"
#: checkinstall.in:1473
#, fuzzy, sh-printf-format
#| msgid "8 - Source location:"
msgid "8 - Source location: [ %s ]"
msgstr "8 - Quellen-Angabe:"
#: checkinstall.in:1474
#, fuzzy, sh-printf-format
#| msgid "9 - Alternate source location:"
msgid "9 - Alternate source location: [ %s ]"
msgstr "9 - Alternative Quellen-Angabe:"
#: checkinstall.in:1476
#, fuzzy, sh-printf-format
#| msgid "11 - Requires:"
msgid "10 - Requires: [ %s ]"
msgstr "11 - Benötigt:"
#: checkinstall.in:1478
#, sh-printf-format
msgid "11 - Recommends: [ %s ]"
msgstr ""
#: checkinstall.in:1480
#, sh-printf-format
msgid "12 - Suggests: [ %s ]"
msgstr ""
#: checkinstall.in:1482
#, fuzzy, sh-printf-format
#| msgid "10 - Provides:"
msgid "13 - Provides: [ %s ]"
msgstr "10 - Stellt zur Verfügung:"
#: checkinstall.in:1483
#, sh-printf-format
msgid "14 - Conflicts: [ %s ]"
msgstr ""
#: checkinstall.in:1484
#, sh-printf-format
msgid "15 - Replaces: [ %s ]"
msgstr ""
#: checkinstall.in:1485
#, fuzzy, sh-printf-format
#| msgid "11 - Requires:"
msgid "16 - Prerequires: [ %s ]"
msgstr "11 - Benötigt:"
#: checkinstall.in:1488
msgid "Enter a number to change any of them or press ENTER to continue: "
msgstr "Geben Sie die betreffende Nummer ein, um die Vorgaben zu ändern: "
#: checkinstall.in:1498
msgid "Enter new summary: "
msgstr "Geben Sie eine neue Zusammenfassung ein: "
#: checkinstall.in:1503
msgid "Enter new name: "
msgstr "Geben Sie einen neuen Namen ein: "
#: checkinstall.in:1508
msgid "Enter new version: "
msgstr "Geben Sie die neue Versionsbezeichnung ein: "
#: checkinstall.in:1513
msgid "Enter new release number: "
msgstr "Geben Sie die neue Veröffentlichungsnummer ein: "
#: checkinstall.in:1518
msgid "Enter the license type: "
msgstr "Geben Sie den Lizenz-Typ ein: "
#: checkinstall.in:1523
msgid "Enter the new software group: "
msgstr "Geben Sie die neue Software-Gruppe ein: "
#: checkinstall.in:1528
msgid "Enter the architecture type: "
msgstr "Geben Sie die Rechner-Architektur an: "
#: checkinstall.in:1533
msgid "Enter the source location: "
msgstr "Geben Sie die Quellen-Angabe ein: "
#: checkinstall.in:1538
msgid "Enter the alternate source location: "
msgstr "Geben Sie die alternative Quelle ein: "
#: checkinstall.in:1544
#, fuzzy
#| msgid "Enter the maintaner's name and e-mail address: "
msgid "Enter the maintainer's name and e-mail address: "
msgstr "Geben Sie Namen und e-mail-Adresse des Paket-Verantwortlichen ein: "
#: checkinstall.in:1551
msgid "Enter the additional requirements: "
msgstr "Geben Sie zusätzlich erforderliche Pakete ein: "
#: checkinstall.in:1558
#, fuzzy
#| msgid "Enter the additional requirements: "
msgid "Enter the additional recommendations: "
msgstr "Geben Sie zusätzlich erforderliche Pakete ein: "
#: checkinstall.in:1565
#, fuzzy
#| msgid "Enter the additional requirements: "
msgid "Enter the additional suggestions: "
msgstr "Geben Sie zusätzlich erforderliche Pakete ein: "
#: checkinstall.in:1573
msgid "Enter the provided features: "
msgstr "Geben Sie die bereitgestellten Eigenschaften ein: "
#: checkinstall.in:1644
#, fuzzy, sh-printf-format
#| msgid "Installing with"
msgid "Installing with %s..."
msgstr "Installiere mit"
#: checkinstall.in:1669 checkinstall.in:2341
msgid ""
"========================= Installation results ==========================="
msgstr ""
"====================== Installations-Ergebnisse =========================="
#: checkinstall.in:1675 checkinstall.in:2348
msgid ""
"======================== Installation successful =========================="
msgstr ""
"====================== Installation erfolgreich =========================="
#: checkinstall.in:1688
msgid "**** Installation failed. Aborting package creation."
msgstr "**** Installation fehlgeschlagen. Breche Paket-Erzeugung ab."
#: checkinstall.in:1694
msgid "Do you want to view the installation log file? "
msgstr "Möchten Sie die Ereignis-Datei einsehen?"
#: checkinstall.in:1699
#, sh-printf-format
msgid ""
" ***************************************************************\\n "
"Installation results. You can find them in\\n %s\\n "
"***************************************************************\\n"
msgstr ""
#: checkinstall.in:1797
#, fuzzy
#| msgid "Some of the files created by the installation are inside the build"
msgid ""
"Some of the files created by the installation are inside the home "
"directory: /home"
msgstr ""
"Einige der Dateien, die während der Installation erzeugt wurden, stammen"
#: checkinstall.in:1799
#, fuzzy
#| msgid "You probably don't want them to be included in the package,"
msgid "You probably don't want them to be included in the package."
msgstr "Sie wollen diese wahrscheinlich nicht in das Paket einschließen,"
#: checkinstall.in:1800
msgid "Do you want me to list them? "
msgstr "Soll ich diese Dateien anzeigen?"
#: checkinstall.in:1804 checkinstall.in:1821
msgid "Should I exclude them from the package? (Saying yes is a good idea) "
msgstr "Soll ich sie aus dem Paket ausschließen? (yes ist hier eine gute Idee)"
#: checkinstall.in:1815
#, fuzzy, sh-printf-format
#| msgid "Some of the files created by the installation are inside the build"
msgid ""
"Some of the files created by the installation are inside the "
"build\\ndirectory: %s"
msgstr ""
"Einige der Dateien, die während der Installation erzeugt wurden, stammen"
#: checkinstall.in:1817
msgid ""
"You probably don't want them to be included in the package,\\nespecially if "
"they are inside your home directory.\\nDo you want me to list them? "
msgstr ""
#: checkinstall.in:1831
msgid ""
"You requested to review the list of files that will be\\nincluded in this "
"package.\\n\\nNow you'll have the chance to review and optionally modify it."
msgstr ""
#: checkinstall.in:1833 checkinstall.in:2569 checkinstall.in:2804
msgid "Press ENTER to continue."
msgstr "Drücken Sie ENTER um fortzufahren."
#: checkinstall.in:1851
msgid "Copying files to the temporary directory..."
msgstr "Kopiere Dateien in das temporäre Verzeichnis..."
#: checkinstall.in:1928
#, fuzzy
#| msgid "Striping ELF binaries and libraries..."
msgid "Stripping ELF binaries and libraries..."
msgstr "Strippe ELF Binär-Dateien und -Bibliotheken..."
#: checkinstall.in:1930
#, fuzzy
#| msgid "Striping ELF binaries..."
msgid "Stripping ELF binaries..."
msgstr "Strippe ELF Binär-Dateien..."
#: checkinstall.in:1972
msgid "Compressing man pages..."
msgstr "Komprimiere man-Seiten..."
#: checkinstall.in:2049
msgid "Building file list..."
msgstr "Erzeuge Datei-Liste..."
#: checkinstall.in:2082
msgid "Shared libraries found. Adding them to the postinstall script."
msgstr ""
#: checkinstall.in:2140
msgid "Kernel modules found. Calling depmod in the postinstall script"
msgstr ""
#: checkinstall.in:2194
msgid "*** The \"installpkg\" program is not in your PATH!"
msgstr "*** Das Programm \"installpkg\" ist nicht in Ihrem Suchpfad!"
#: checkinstall.in:2196
msgid "*** Slackware package creation aborted"
msgstr "*** Slackware-Paketerstellung abgebrochen"
#: checkinstall.in:2206
msgid "Preparing Slackware install directory..."
msgstr "Bereite Slackware-Installationsverzeichnis vor..."
#: checkinstall.in:2212
msgid "Writing package description..."
msgstr "Schreibe Paket-Beschreibung..."
#: checkinstall.in:2261
msgid "Writing Slackware install script..."
msgstr "Schreibe Slackware-Installationsskript..."
#: checkinstall.in:2291
msgid "Appending your script to the main install script..."
msgstr "Hänge Ihr Skript an das Haupt-Installationsskript an..."
#: checkinstall.in:2335
msgid "Installing package..."
msgstr "Installiere das Paket..."
#: checkinstall.in:2354 checkinstall.in:2628 checkinstall.in:2835
msgid "*** Failed to install the package"
msgstr "*** Installation des Pakets fehlgeschlagen"
#: checkinstall.in:2357 checkinstall.in:2604 checkinstall.in:2630
#: checkinstall.in:2818 checkinstall.in:2837
msgid "Do you want to see the log file? "
msgstr "Möchten Sie die log-Datei sehen? "
#: checkinstall.in:2368
msgid "NOTE: The package will not be installed."
msgstr "ANMERKUNG: Das Paket wird nicht installiert."
#: checkinstall.in:2401
msgid "*** The \"rpm\" program is not in your PATH!"
msgstr "*** Das Programm \"rpm\" ist nicht in Ihrem Suchpfad!"
#: checkinstall.in:2403
msgid "*** RPM package creation aborted"
msgstr "*** RPM-Paketerstellung abgebrochen"
#: checkinstall.in:2476
#, fuzzy, sh-printf-format
#| msgid "$RPMSOURCEDIR has no SOURCES directory. Please write the path to"
msgid ""
"%s has no SOURCES directory. Please write the path to\\nthe RPM source "
"directory tree: "
msgstr "$RPMSOURCEDIR hat kein Verzeichnis SOURCES. Bitte geben Sie den Pfad"
#: checkinstall.in:2567
#, fuzzy
#| msgid ""
#| "Now you'll have the chance to review and optionally modify this file."
msgid ""
"You requested to review the .spec file for this package.\\nNow you'll have "
"the chance to review and optionally modify this file."
msgstr ""
"Jetzt haben Sie die Möglichkeit, die Datei einzusehen und ggf. zu verändern."
#: checkinstall.in:2596
msgid "Building RPM package..."
msgstr "Erstelle das RPM-Paket..."
#: checkinstall.in:2602 checkinstall.in:2816
msgid "*** Failed to build the package"
msgstr "*** Paket-Erstellung fehlgeschlagen"
#: checkinstall.in:2616
msgid ""
"Warning: the use of RPMFLAGS is deprecated.\\nWarning: You should now use "
"RPM_FLAGS,\\nWarning: please update your checkinstallrc file."
msgstr ""
#: checkinstall.in:2623
msgid "Installing RPM package..."
msgstr "Installiere RPM Paket..."
#: checkinstall.in:2638 checkinstall.in:2845
msgid "NOTE: The package will not be installed"
msgstr "ANMERKUNG: Das Paket wird nicht installiert"
#: checkinstall.in:2672
msgid "Looking for shared library dependencies..."
msgstr ""
#: checkinstall.in:2702
#, sh-printf-format
msgid "Depends: %s"
msgstr ""
#: checkinstall.in:2718
msgid "*** The \"dpkg\" program is not in your PATH!"
msgstr "*** Das Programm \"dpkg\" ist nicht im Suchpfad!"
#: checkinstall.in:2720
msgid "*** Debian package creation aborted"
msgstr "*** Erstellung des Debian-Pakets abgebrochen"
#: checkinstall.in:2802
#, fuzzy
#| msgid ""
#| "Now you'll have the chance to review and optionally modify this file."
msgid ""
"You requested to review the control file for this package.\\nNow you'll have "
"the chance to review and optionally modify this file."
msgstr ""
"Jetzt haben Sie die Möglichkeit, die Datei einzusehen und ggf. zu verändern."
#: checkinstall.in:2810
msgid "Building Debian package..."
msgstr "Erstelle Debian-Paket..."
#: checkinstall.in:2830
msgid "Installing Debian package..."
msgstr "Installiere Debian-Paket..."
#: checkinstall.in:2875
#, fuzzy, sh-printf-format
#| msgid "doesn't exist. Do you want to create it?"
msgid ""
"The package storage directory [ %s ]\\ndoesn't exist. Do you want to create "
"it?"
msgstr "Wollen Sie es erstellen?"
#: checkinstall.in:2878
msgid "Creating package storage directory..."
msgstr "Erstelle Paket-Verzeichnis..."
#: checkinstall.in:2883
#, fuzzy, sh-printf-format
#| msgid "*** Unable to create $PAK_DIR"
msgid "*** Unable to create %s"
msgstr "*** Kann $PAK_DIR nicht erstellen"
#: checkinstall.in:2891
#, fuzzy, sh-printf-format
#| msgid "Transferring package to"
msgid "Transferring package to %s..."
msgstr "Übertrage Paket nach"
#: checkinstall.in:2896
msgid "*** Transfer failed:"
msgstr ""
#: checkinstall.in:2905
#, fuzzy
#| msgid "There's no package storage directory, the package"
msgid ""
"There's no package storage directory, the package\\nwill be stored at the "
"default location."
msgstr "Es existiert kein Paket-Verzeichnis, das Paket"
#: checkinstall.in:2915
msgid "Erasing temporary files..."
msgstr "Lösche temporäre Dateien..."
#: checkinstall.in:2933
msgid "Deleting doc-pak directory..."
msgstr "Lösche doc-pak-Verzeichnis..."
#: checkinstall.in:2968
msgid "Writing backup package..."
msgstr "Schreibe Sicherungs-Paket..."
#: checkinstall.in:2979
msgid "Deleting temp dir..."
msgstr "Lösche temporäres Verzeichnis..."
#: checkinstall.in:2985
msgid "Building debug information package..."
msgstr "Erstelle Fehlerinfo-Paket..."
#: checkinstall.in:3001
#, sh-printf-format
msgid ""
" Done. The new package has been installed and saved to\\n\\n %s\\n\\n You "
"can remove it from your system anytime using: \\n\\n %s"
msgstr ""
#: checkinstall.in:3011
#, fuzzy, sh-printf-format
#| msgid " You can install it in your system anytime using: "
msgid ""
" Done. The new package has been saved to\\n\\n %s\\n You can install it in "
"your system anytime using: \\n\\n %s"
msgstr " Sie können es in Ihr System installieren mit dem Befehl: "
#~ msgid "The checkinstallrc file was not found at:"
#~ msgstr "Die Datei checkinstallrc wurde nicht gefunden in:"
#~ msgid "I can't find $INSTALLWATCH."
#~ msgstr "$INSTALLWATCH wurde nicht gefunden"
#~ msgid "I can't continue. Either install installwatch or"
#~ msgstr "Weitere Verarbeitung nicht möglich. Installieren Sie installwatch"
#~ msgid "modify the INSTALLWATCH variable in this script,"
#~ msgstr "oder ändern Sie die variable INSTALLWATCH in diesem Skript,"
#~ msgid "then run checkinstall again."
#~ msgstr "starten Sie dann checkinstall erneut."
#~ msgid "My temp dir exists already."
#~ msgstr "Mein temporäres Verzeichnis existiert schon."
#~ msgid "This looks like a symlink attack!"
#~ msgstr "Dies sieht aus wie eine Symlink-Attacke!"
#~ msgid "edit the variable definition for"
#~ msgstr "Ändern Sie die Variablen-Definition für"
#~ msgid "and try again."
#~ msgstr "und versuchen Sie es erneut."
#~ msgid "**** Failed to create temp dir!"
#~ msgstr "**** Das temporäre Verzeichnis konnte nicht erstellt werden!"
#~ msgid "**** Do you have write permission for ${BASE_TMP_DIR}?"
#~ msgstr "**** Haben Sie Schreibzugriff auf ${BASE_TMP_DIR}?"
#~ msgid "Should I create a default set of package docs? "
#~ msgstr "Soll ein Standard-Satz Dokumentations-Dateien erzeugt werden?"
#~ msgid "*** won't include a documentation directory."
#~ msgstr "*** wird kein Dokumentations-Verzeichnis enthalten."
#~ msgid "Copying documentation directory..."
#~ msgstr "Kopiere Dokumentations-Verzeichnis..."
#~ msgid "directory: `pwd`"
#~ msgstr "aus dem Build-Verzeichnis: `pwd`"
#~ msgid "especially if they are inside your home directory."
#~ msgstr "besonders, wenn sie sich in Ihrem Home-Verzeichnis befinden."
#~ msgid "You requested to review the list of files that will be"
#~ msgstr "Sie wollten die Liste der Dateien einsehen, die"
#~ msgid "included in this package."
#~ msgstr "im Paket enthalten sein werden."
#~ msgid "Now you'll have the chance to review and optionally modify it."
#~ msgstr "Jetzt können Sie sie durchsehen und ggf. verändern."
#~ msgid " Remember that pkgtool shows"
#~ msgstr "Bedenken Sie, daß pkgtool nur die erste Zeile anzeigt,"
#~ msgid "Package created with checkinstall $CHECKINSTALL_VERSION"
#~ msgstr "Das Paket wurde mit checkinstall $CHECKINSTALL_VERSION erzeugt"
#~ msgid "Warning: The Slackware 8.1+ pkgtools might not like it."
#~ msgstr "WARNUNG: Die Slackware 8.1+ pkgtools werden das nicht mögen."
#~ msgid "*** Warning: The package name"
#~ msgstr "*** WARNUNG: Der Paket-Name"
#~ msgid "contains upper case"
#~ msgstr "enthält GROSSBUCHSTABEN"
#~ msgid "*** Warning: letters. dpkg might not like that so I changed"
#~ msgstr "*** WARNUNG: dpkg mag das nicht, ich habe sie daher durch"
#~ msgid "*** Warning: them to lower case."
#~ msgstr "*** WARNUNG: Kleinbuchstaben ersetzt."
#~ msgid "*** Warning: The package version \"${VERSION}\" does not"
#~ msgstr "*** WARNUNG: Die Paket-Version \"${VERSION}\" enthält keinerlei"
#~ msgid "*** Warning: contain any digits. dpkg might not like that."
#~ msgstr "Zahlenangaben. dpkg wird das nicht mögen."
#~ msgid "********************************************"
#~ msgstr "********************************************"
#~ msgid "**** Slackware package creation selected ***"
#~ msgstr "**** Erstellung eines Slackware-Pakets gew{hlt ***"
#~ msgid "Creating package ${SLACK_PKG_BASENAME}..."
#~ msgstr "Erstelle Paket ${SLACK_PKG_BASENAME}..."
#~ msgid "**************************************"
#~ msgstr "**************************************"
#~ msgid "**** RPM package creation selected ***"
#~ msgstr "**** Erstellung eines RPM-Pakets gewählt ***"
#~ msgid "the RPM source directory tree: "
#~ msgstr "zum RPM Quell-Verzeichnisbaum an: "
#~ msgid "You requested to review the .spec file for this package."
#~ msgstr "Sie wollten die .spec-Datei für dieses Paket einsehen."
#~ msgid "Warning: the use of RPMFLAGS is deprecated."
#~ msgstr "WARNUNG: Die Benutzung von RPMFLAGS wird nicht empfohlen."
#~ msgid "Warning: You should now use RPM_FLAGS,"
#~ msgstr "WARNUNG: Sie sollten jetzt RPM_FLAGS benutzen,"
#~ msgid "Warning: please update your checkinstallrc file."
#~ msgstr "WARNUNG: bitte korrigieren Sie Ihre checkinstallrc-Datei."
#~ msgid "*****************************************"
#~ msgstr "*****************************************"
#~ msgid "**** Debian package creation selected ***"
#~ msgstr "**** Erstellung eines Debian-Pakets gewählt ***"
#~ msgid "You requested to review the control file for this package."
#~ msgstr "Sie wollten die control-Datei für dieses Paket einsehen."
#~ msgid "*** No method was selected, I won't build any package."
#~ msgstr ""
#~ "*** Es wurde keine Methode ausgewählt, Ich werde kein Paket erstellen."
#~ msgid "*** The installation command \"$INSTALLCMD\""
#~ msgstr "*** Das Installations-Kommando \"$INSTALLCMD\""
#~ msgid "*** has already been executed."
#~ msgstr "*** wurde schon ausgeführt."
#~ msgid "The package storage directory"
#~ msgstr "Das Paket-Verzeichnis existiert nicht."
#~ msgid "will be stored at the default location."
#~ msgstr "wird am Standard-Ort gespeichert."
#~ msgid " Done. The new package has been installed and saved to"
#~ msgstr " Geschafft. Das neue Paket wurde installiert und gespeichert nach"
#~ msgid " You can remove it from your system anytime using: "
#~ msgstr " Sie können es aus Ihrem System entfernen mit dem Befehl: "
#~ msgid " Done. The new package has been saved to"
#~ msgstr " Geschafft. Das neue Paket wurde gespeichert nach"
ssgelm-checkinstall-59a004a/locale/checkinstall-es.po 0000664 0000000 0000000 00000115354 15235417303 0022657 0 ustar 00root root 0000000 0000000 # MENSAJES PARA CHECKINSTALL-1.6.3 en ESPAÑOL
# Copyright (C) 2002 - 2010 Felipe Eduardo Sánchez Díaz Durán
# Felipe Eduardo Sanchez Diaz Duran , 2010.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 1.6.0beta1\n"
"Report-Msgid-Bugs-To: https://github.com/ssgelm/checkinstall/issues\n"
"POT-Creation-Date: 2026-08-07 02:20-0500\n"
"PO-Revision-Date: 2002-11-27 00:58-0600\n"
"Last-Translator: Felipe Eduardo Sanchez Diaz Duran \n"
"Language-Team: ES \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
#: checkinstall.in:83 checkinstall.in:337
msgid "Bye."
msgstr "Adiós."
#: checkinstall.in:110
msgid " This software is released under the GNU GPL."
msgstr " Este software es distribuído de acuerdo a la GNU GPL"
#: checkinstall.in:124
msgid "Usage: checkinstall [options] [command [command arguments]]"
msgstr "Uso: checkinstall [opciones] [comando [argumentos del comando]]"
#: checkinstall.in:125
msgid "Options:"
msgstr "Opciones:"
#: checkinstall.in:127
msgid "*Package type selection*"
msgstr "*Selección del tipo de paquete*"
#: checkinstall.in:129
msgid "-t,--type= Choose packaging system"
msgstr "-t,--type= Escoge tipo de paquete"
#: checkinstall.in:130
msgid "-S Build a Slackware package"
msgstr "-S Crea un paquete de Slackware"
#: checkinstall.in:131
msgid "-R Build a RPM package"
msgstr "-R Crea un paquete RPM"
#: checkinstall.in:132
msgid "-D Build a Debian package"
msgstr "-D Crea un paquete de Debian"
#: checkinstall.in:134
msgid "*Install options*"
msgstr "*Opciones de instalación*"
#: checkinstall.in:136
msgid "--install= Toggle created package installation"
msgstr ""
"--install= Activa la instalación del paquete al crearlo"
#: checkinstall.in:137
#, fuzzy
#| msgid "--delspec= Delete spec file upon termination"
msgid ""
"--fstrans= Enable/disable the filesystem translation code"
msgstr "--delspec= Borra el archivo .spec al terminar"
#: checkinstall.in:139
msgid "*Scripting options*"
msgstr "*Opciones de automatización*"
#: checkinstall.in:141
msgid "-y, --default Accept default answers to all questions"
msgstr ""
"-y, --default Acepta los defaults a todas las preguntas"
#: checkinstall.in:142
msgid "--pkgname= Set name"
msgstr "--pkgname= El nombre del paquete"
#: checkinstall.in:143
msgid "--pkgversion=