Initial import

pull/2/head
Timothy Pearson 9 years ago
commit 9b92536e6c

File diff suppressed because it is too large Load Diff

@ -0,0 +1,6 @@
Timothy Pearson (kb9vqf at pearsoncomputing dot net)
Erich Hoover (ehoover at mines dot edu)
Read-only Backend:
Martin Rosenau

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

@ -0,0 +1,39 @@
0.6.0:
* Fixed some bugs with libbfd on Ubuntu 10.10.
* Added some additional error checking for libbfd.
* Deprecated "GUID naming" in favor of "UUID naming".
* Added support for extracting special 'one canvas' SVG icons.
0.5.0:
* Added read-only backend.
* Added documentation for the icon management API.
* Added pkg-config file generation and installation.
* Added initial support for manpages through doxygen.
* Added documentation for the main resource management API.
0.4.2:
* Temporary files are no-longer stored in the active directory.
* Handles are now automatically cleaned up when libr exits memory.
0.4.1:
* New procedure for producing packages.
* Fixed a bug with sscanf under specific new GCC versions.
0.4.0:
* Created a convenience API for using libr with gettext.
* Added support for GtkBuilder in GTK+ convenience functions.
* Now using weak linking to simplify testing whether GTK+ symbols are available.
* GTK+ routines can now auto-load other resources (such as bitmaps) from binaries.
Major bug fixes:
1) Fixed a problem with dynamically loading GTK+ on 64-bit systems.
2) Fixed several problems keeping libr from being statically linked in applications.
0.3.1:
* Report descriptive errors for problems.
* Made icon routines thread safe.
Major bug fixes:
1) Replacing an icon added duplicate entries to the icon table
2) File uid and gid were not preserved
0.3.0:
* Created a convenience API for using libr with GTK+.
0.2.1:
* Minor bug fixes.
0.2.0:
* Initial public "libr" library implementation with option (default) of using libbfd.

@ -0,0 +1,302 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
6. Often, you can also type `make uninstall' to remove the installed
files again.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *Note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

@ -0,0 +1,24 @@
EXTRA_DIST = config.rpath m4/ChangeLog
LIBTOOL_DEPS = @LIBTOOL_DEPS@
instdir = @libdir@/pkgconfig
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = po src man
SED_REPLACE = \
-e 's=\@prefix\@=@prefix@=' \
-e 's=\@libdir\@=@libdir@=' \
-e 's=\@VERSION\@=@VERSION@=' \
-e 's=\@exec_prefix\@=@exec_prefix@=' \
-e 's=\@includedir\@=@includedir@/libr='
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
# Generate the pkg-config configuration file with all of
# the accurate installation parameters
libr.pc: libr.pc.in
cat libr.pc.in | sed $(SED_REPLACE) > libr.pc
CLEANFILES=libr.pc
# Install the pkg-config configuration file
dist_inst_DATA = \
libr.pc

@ -0,0 +1,41 @@
libr - Library to manage resources in ELF binaries
See the INSTALL file for general installation instructions.
* What is the purpose of this library?
This library is intended to provide an easy to use mechanism for managing
(embedding, retrieving, deleting) resources in ELF binaries. The library
provides a solid API and ABI that implements the preliminary spec for adding
ELF resources (icons or otherwise) documented at:
https://wiki.ubuntu.com/ELFIconSpec
Please note that should a backward-incompatible change occur to the API/ABI
then the shared library version code will be bumped.
* Why are there multiple backends?
Originally this library was written to use libelf, unfortunately libelf has
some issues with reordering data in small executables. Until these issues are
resolved please use libbfd (the default backend) or the read-only backend.
If you would like to experiment with the libelf backend you can try and set
resources on the application "alsamixer", which is a commonly installed
application that is known to break.
* What is the read-only backend?
The read-only backend is a dependency-free backend that is capable of reading
libr resources. Support for this backend is thanks to Martin Rosenau.
This backend is currently a new edition to libr, however, in the long-run the
read-only backend will be the recommended (default) backend for the purpose of
most applications. Only a special class of application (primarily elfres)
needs to actually add and remove resources in a binary, most applications
need only read resources already added by elfres.
NOTICE! This library is licensed under the LGPL v2.1 while the backend for
libbfd is licensed under the LGPL v3. You may choose to distribute your
modifications to this variant of the library under the LGPL v3, in accordance
with Section 5 of that license. Should you wish to excise libbfd from this
library you may choose to remove libr_bfd.h and libr_bfd.c and compile against
libelf instead, the backend may be selected at configure time:
./configure --libr-backend=libelf
I consider the ability to select the library backend as satisfying the LGPL v3
Section 5a requirement and this notice (and the notice contained within
libr_bfd.c) to satisfy the Section 5b requirement.

177
TRASH

@ -0,0 +1,177 @@
#ifdef __LINK_AT_RUNTIME__
DEFINE_SYMBOL(long, bfd_canonicalize_reloc,
bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
DEFINE_SYMBOL(bfd_boolean, bfd_close,
bfd *abfd);
DEFINE_SYMBOL(bfd_boolean, bfd_check_format,
bfd *abfd, bfd_format format);
DEFINE_SYMBOL(const char *, bfd_errmsg,
bfd_error_type error_tag);
DEFINE_SYMBOL(enum bfd_architecture, bfd_get_arch,
bfd *abfd);
DEFINE_SYMBOL(bfd_error_type, bfd_get_error,
void);
DEFINE_SYMBOL(unsigned long, bfd_get_mach,
bfd *abfd);
DEFINE_SYMBOL(long, bfd_get_reloc_upper_bound,
bfd *abfd, asection *sect);
DEFINE_SYMBOL(bfd_boolean, bfd_get_section_contents,
bfd *abfd, asection *section, void *location, file_ptr offset,
bfd_size_type count);
DEFINE_SYMBOL(asection *, bfd_make_section,
bfd *, const char *name);
DEFINE_SYMBOL(asection *, bfd_make_section_anyway_with_flags,
bfd *abfd, const char *name, flagword flags);
DEFINE_SYMBOL(bfd *, bfd_openr, const char *filename,
const char *target);
DEFINE_SYMBOL(bfd *, bfd_openw,
const char *filename, const char *target);
DEFINE_SYMBOL(bfd_boolean, bfd_set_file_flags,
bfd *abfd, flagword flags);
DEFINE_SYMBOL(void, bfd_set_reloc,
bfd *abfd, asection *sec, arelent **rel, unsigned int count);
DEFINE_SYMBOL(bfd_boolean, bfd_set_section_contents,
bfd *abfd, asection *section, const void *data, file_ptr offset,
bfd_size_type count);
DEFINE_SYMBOL(bfd_boolean, bfd_set_format,
bfd *abfd, bfd_format format);
DEFINE_SYMBOL(bfd_boolean, bfd_set_section_flags,
bfd *abfd, asection *sec, flagword flags);
DEFINE_SYMBOL(bfd_boolean, bfd_set_section_size,
bfd *abfd, asection *sec, bfd_size_type val);
DEFINE_SYMBOL(bfd_boolean, bfd_set_start_address,
bfd *abfd, bfd_vma vma);
DEFINE_SYMBOL(bfd_boolean, bfd_set_symtab,
bfd *abfd, asymbol **location, unsigned int count);
#define bfd_canonicalize_reloc
OVERRIDE_SYMBOL(bfd_canonicalize_reloc)
#define bfd_close OVERRIDE_SYMBOL(bfd_close)
#define bfd_check_format
OVERRIDE_SYMBOL(bfd_check_format)
#define bfd_errmsg OVERRIDE_SYMBOL(bfd_errmsg)
#define bfd_get_arch OVERRIDE_SYMBOL(bfd_get_arch)
#define bfd_get_error
OVERRIDE_SYMBOL(bfd_get_error)
#define bfd_get_mach OVERRIDE_SYMBOL(bfd_get_mach)
#define bfd_get_reloc_upper_bound
OVERRIDE_SYMBOL(bfd_get_reloc_upper_bound)
#define bfd_get_section_contents
OVERRIDE_SYMBOL(bfd_get_section_contents)
#define bfd_make_section
OVERRIDE_SYMBOL(bfd_make_section)
#define bfd_make_section_anyway_with_flags
OVERRIDE_SYMBOL(bfd_make_section_anyway_with_flags)
#define bfd_openr OVERRIDE_SYMBOL(bfd_openr)
#define bfd_openw OVERRIDE_SYMBOL(bfd_openw)
#define bfd_set_file_flags
OVERRIDE_SYMBOL(bfd_set_file_flags)
#define bfd_set_format
OVERRIDE_SYMBOL(bfd_set_format)
#define bfd_set_reloc
OVERRIDE_SYMBOL(bfd_set_reloc)
#define bfd_set_section_contents
OVERRIDE_SYMBOL(bfd_set_section_contents)
#define bfd_set_section_flags
OVERRIDE_SYMBOL(bfd_set_section_flags)
#define bfd_set_section_size
OVERRIDE_SYMBOL(bfd_set_section_size)
#define bfd_set_start_address
OVERRIDE_SYMBOL(bfd_set_start_address)
#define bfd_set_symtab
OVERRIDE_SYMBOL(bfd_set_symtab)
SYMBOL_TABLE(libbfd_symbols,
SYMBOL(bfd_openr),
SYMBOL(bfd_set_format),
);
#endif
#include <librsvg/rsvg.h>
DEFINE_SYMBOL(void, rsvg_init, void);
DEFINE_SYMBOL(RsvgHandle *, rsvg_handle_new, void);
DEFINE_SYMBOL(GdkPixbuf *, rsvg_handle_get_pixbuf, RsvgHandle *handle);
DEFINE_SYMBOL(gboolean, rsvg_handle_close, RsvgHandle * handle, GError ** error);
DEFINE_SYMBOL(void, rsvg_handle_get_dimensions, RsvgHandle * handle, RsvgDimensionData * dimension_data);
DEFINE_SYMBOL(gboolean, rsvg_handle_write, RsvgHandle * handle, const guchar * buf, gsize count, GError ** error);
DEFINE_SYMBOL(void, rsvg_handle_set_size_callback, RsvgHandle * handle, RsvgSizeFunc size_func, gpointer user_data, GDestroyNotify user_data_destroy);
#define rsvg_init OVERRIDE_SYMBOL(rsvg_init)
#define rsvg_handle_new OVERRIDE_SYMBOL(rsvg_handle_new)
#define rsvg_handle_get_pixbuf OVERRIDE_SYMBOL(rsvg_handle_get_pixbuf)
#define rsvg_handle_close OVERRIDE_SYMBOL(rsvg_handle_close)
#define rsvg_handle_write OVERRIDE_SYMBOL(rsvg_handle_write)
#define rsvg_handle_set_size_callback OVERRIDE_SYMBOL(rsvg_handle_set_size_callback)
#define rsvg_handle_get_dimensions OVERRIDE_SYMBOL(rsvg_handle_get_dimensions)
SYMBOL_TABLE(librsvg_symbols,
SYMBOL(rsvg_init),
SYMBOL(rsvg_handle_new),
SYMBOL(rsvg_handle_close),
SYMBOL(rsvg_handle_write),
SYMBOL(rsvg_handle_get_pixbuf),
SYMBOL(rsvg_handle_get_dimensions),
SYMBOL(rsvg_handle_set_size_callback),
);
/*
* Scale the SVG image to the required icon size
*/
static void rsvg_set_iconsize(int *width, int *height, gpointer data)
{
float multiplier = *(float*)data;
(*width) *= multiplier;
(*height) *= multiplier;
}
if(!rsvg_linked)
{
if(!LOAD_SYMBOLS("librsvg-2.so", librsvg_symbols))
{
// libr_icon_gtk requires that your application be linked to librsvg
return NULL;
}
}
RsvgHandle *rsvg = NULL;
libr_icontype_t type;
type = icon_handle->type;
if(type == LIBR_SVG)
{
RsvgHandle *rsvg = rsvg_handle_new();
if(rsvg != NULL)
{
if(rsvg_handle_write(rsvg, iconfile, iconfile_size, NULL))
{
if(rsvg_handle_close(rsvg, NULL))
{
RsvgDimensionData dim;
float multiplier;
int old_size;
rsvg_handle_get_dimensions(rsvg, &dim);
if(dim.width > dim.height)
old_size = dim.width;
else
old_size = dim.height;
multiplier = ((float)sizes[i])/old_size;
rsvg_handle_set_size_callback(rsvg, rsvg_set_iconsize, (void *) &multiplier, NULL);
icon = rsvg_handle_get_pixbuf(rsvg);
icons = g_list_append(icons, icon);
}
}
}
free(iconfile);
}
else if(type == LIBR_PNG)
{
}
else
{
/* Unhandled image type */
continue;
}

@ -0,0 +1,20 @@
printf("loads...\n");
if(!LOAD_SYMBOLS("libgtk-x11-2.0", null_symbols))
printf("err 0\n");
if(!LOAD_SYMBOLS("libgdk-x11-2.0", null_symbols))
printf("err 1\n");
if(!LOAD_SYMBOLS("libatk-1.0", null_symbols))
printf("err 2\n");
if(!LOAD_SYMBOLS("libgdk_pixbuf-2.0", null_symbols))
printf("err 3\n");
if(!LOAD_SYMBOLS("libpangocairo-1.0", null_symbols))
printf("err 4\n");
if(!LOAD_SYMBOLS("libpango-1.0", null_symbols))
printf("err 5\n");
if(!LOAD_SYMBOLS("libcairo", null_symbols))
printf("err 6\n");
if(!LOAD_SYMBOLS("libfreetype", null_symbols))
printf("err 7\n");
if(!LOAD_SYMBOLS("libxml2", null_symbols))
printf("err 8\n");

1174
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,93 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
CoreFoundation framework. */
#undef HAVE_CFLOCALECOPYCURRENT
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
the CoreFoundation framework. */
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#undef HAVE_DCGETTEXT
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <math.h> header file. */
#undef HAVE_MATH_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION

@ -0,0 +1,666 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2007 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | cygwin* | pw32* | os2*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux* | k*bsd*-gnu)
case $cc_basename in
icc* | ecc*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
wl='-Wl,'
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix3* | aix4* | aix5*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | k*bsd*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix4* | aix5*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix4* | aix5*)
library_names_spec='$libname$shrext'
;;
amigaos*)
library_names_spec='$libname.a'
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd1*)
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

@ -0,0 +1,81 @@
AC_INIT(libr.c)
AM_INIT_AUTOMAKE(libr,0.6.0)
AC_CONFIG_SRCDIR([src/libr.c])
AC_PROG_CC
AC_PROG_CC_STDC
AC_HEADER_STDC
AC_PROG_INSTALL
AM_GNU_GETTEXT([external])
# It is important to build both a static and a shared version of the libr
# library. The shared version is for future-proofing, whereas the static
# version should be used to make a more portable binary until libr is
# more widely distributed (as in distributed at all).
AC_ENABLE_SHARED
AC_ENABLE_STATIC
# Setup libtool
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
## Handle optional libraries (only header files are used)
PKG_CHECK_MODULES(LIBGLADE, libglade-2.0 >= 2.0.0)
## Handle required components
# Is this the best check for zlib that can be made?
AC_CHECK_HEADERS(zlib.h math.h pthread.h)
EXTRA_LIBS="-lz -lm -lpthread"
EXTRA_CFLAGS="-fvisibility=hidden"
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(EXTRA_LIBS)
## Handle backend configuration
LIBR_BACKEND="bfd"
BACKEND_NAME="libbfd"
AC_ARG_ENABLE(libelf, [ --enable-libelf use the libelf backend ], [
if test "$enableval" = "yes" ; then
LIBR_BACKEND="elf"
BACKEND_NAME="libelf"
fi
])
AC_ARG_ENABLE(libbfd, [ --enable-libbfd use the libbfd backend (default) ], [
if test "$enableval" == "yes" ; then
LIBR_BACKEND="bfd"
BACKEND_NAME="libbfd"
fi
])
AC_ARG_ENABLE(ro, [ --enable-ro use the read-only backend ], [
if test "$enableval" == "yes" ; then
LIBR_BACKEND="ro"
BACKEND_NAME="readonly"
fi
])
echo "Using ${BACKEND_NAME} backend."
if test "${LIBR_BACKEND}" == "bfd" ; then
AC_CHECK_HEADER([bfd.h], [], [
AC_MSG_ERROR([Could not find libbfd header file (bfd.h)! This file is usually included in the package binutils-dev.])
])
BACKEND_PKG="binutils"
BACKEND_LIBS="-lbfd"
BACKEND_CFLAGS=""
AC_SUBST(BACKEND_LIBS)
AC_SUBST(BACKEND_CFLAGS)
elif test "${LIBR_BACKEND}" == "elf" ; then
# Is libelf 0.8.2 safe enough? testing is currently on 0.8.6
BACKEND_PKG="elfutils"
pkg_modules="libelf >= 0.8.2"
PKG_CHECK_MODULES(BACKEND, [$pkg_modules])
fi
AC_SUBST(BACKEND_NAME)
AC_SUBST(LIBR_BACKEND)
AC_SUBST(BACKEND_PKG)
AC_CONFIG_HEADERS(config.h)
AC_OUTPUT(
src/Makefile
man/Makefile
po/Makefile.in
Makefile
)

@ -0,0 +1,630 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
# Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u="sed s,\\\\\\\\,/,g"
depmode=msvisualcpp
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

@ -0,0 +1,520 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2009-04-28.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libr
Description: libr ELF resource manager library
Version: @VERSION@
Requires:
Libs: -L${libdir} -lr
Cflags: -I${includedir}

@ -0,0 +1,11 @@
2009-09-08 gettextize <bug-gnu-gettext@gnu.org>
* gettext.m4: New file, from gettext-0.17.
* iconv.m4: New file, from gettext-0.17.
* lib-ld.m4: New file, from gettext-0.17.
* lib-link.m4: New file, from gettext-0.17.
* lib-prefix.m4: New file, from gettext-0.17.
* nls.m4: New file, from gettext-0.17.
* po.m4: New file, from gettext-0.17.
* progtest.m4: New file, from gettext-0.17.

@ -0,0 +1,5 @@
man3/*.3:
doxygen ../doc/libr.cfg
man_MANS = man3/*.3
CLEANFILES = man3/*.3

@ -0,0 +1,471 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
$(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff
MANS = $(man_MANS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BACKEND_CFLAGS = @BACKEND_CFLAGS@
BACKEND_LIBS = @BACKEND_LIBS@
BACKEND_NAME = @BACKEND_NAME@
BACKEND_PKG = @BACKEND_PKG@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTRA_CFLAGS = @EXTRA_CFLAGS@
EXTRA_LIBS = @EXTRA_LIBS@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBGLADE_CFLAGS = @LIBGLADE_CFLAGS@
LIBGLADE_LIBS = @LIBGLADE_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBOBJS = @LIBOBJS@
LIBR_BACKEND = @LIBR_BACKEND@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
man_MANS = man3/*.3
CLEANFILES = man3/*.3
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu man/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man3: $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
@list=''; test -n "$(man3dir)" || exit 0; \
{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
done; }
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man3dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
test -z "$$files" || { \
echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@list='$(MANS)'; if test -n "$$list"; then \
list=`for p in $$list; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
if test -n "$$list" && \
grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
echo " typically \`make maintainer-clean' will remove them" >&2; \
exit 1; \
else :; fi; \
else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
for dir in "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man3
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-man3 \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-man uninstall-man3
man3/*.3:
doxygen ../doc/libr.cfg
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

@ -0,0 +1,376 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar*)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

@ -0,0 +1,12 @@
2009-09-08 gettextize <bug-gnu-gettext@gnu.org>
* Makefile.in.in: New file, from gettext-0.17.
* Rules-quot: New file, from gettext-0.17.
* boldquot.sed: New file, from gettext-0.17.
* en@boldquot.header: New file, from gettext-0.17.
* en@quot.header: New file, from gettext-0.17.
* insert-header.sin: New file, from gettext-0.17.
* quot.sed: New file, from gettext-0.17.
* remove-potcdate.sin: New file, from gettext-0.17.
* POTFILES.in: New file.

@ -0,0 +1,433 @@
# Makefile for PO directory in any package using GNU gettext.
# Copyright (C) 1995-1997, 2000-2007 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU General Public
# License but which still want to provide support for the GNU gettext
# functionality.
# Please note that the actual code of GNU gettext is covered by the GNU
# General Public License and is *not* in the public domain.
#
# Origin: gettext-0.17
GETTEXT_MACRO_VERSION = 0.17
PACKAGE = @PACKAGE@
VERSION = @VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
SHELL = /bin/sh
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
datadir = @datadir@
localedir = @localedir@
gettextsrcdir = $(datadir)/gettext/po
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
# We use $(mkdir_p).
# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as
# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions,
# @install_sh@ does not start with $(SHELL), so we add it.
# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined
# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake
# versions, $(mkinstalldirs) and $(install_sh) are unused.
mkinstalldirs = $(SHELL) @install_sh@ -d
install_sh = $(SHELL) @install_sh@
MKDIR_P = @MKDIR_P@
mkdir_p = @mkdir_p@
GMSGFMT_ = @GMSGFMT@
GMSGFMT_no = @GMSGFMT@
GMSGFMT_yes = @GMSGFMT_015@
GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
MSGFMT_ = @MSGFMT@
MSGFMT_no = @MSGFMT@
MSGFMT_yes = @MSGFMT_015@
MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
XGETTEXT_ = @XGETTEXT@
XGETTEXT_no = @XGETTEXT@
XGETTEXT_yes = @XGETTEXT_015@
XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
MSGMERGE = msgmerge
MSGMERGE_UPDATE = @MSGMERGE@ --update
MSGINIT = msginit
MSGCONV = msgconv
MSGFILTER = msgfilter
POFILES = @POFILES@
GMOFILES = @GMOFILES@
UPDATEPOFILES = @UPDATEPOFILES@
DUMMYPOFILES = @DUMMYPOFILES@
DISTFILES.common = Makefile.in.in remove-potcdate.sin \
$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
$(POFILES) $(GMOFILES) \
$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
POTFILES = \
CATALOGS = @CATALOGS@
# Makevars gets inserted here. (Don't remove this line!)
.SUFFIXES:
.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
.po.mo:
@echo "$(MSGFMT) -c -o $@ $<"; \
$(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
.po.gmo:
@lang=`echo $* | sed -e 's,.*/,,'`; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \
cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
.sin.sed:
sed -e '/^#/d' $< > t-$@
mv t-$@ $@
all: check-macro-version all-@USE_NLS@
all-yes: stamp-po
all-no:
# Ensure that the gettext macros and this Makefile.in.in are in sync.
check-macro-version:
@test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
|| { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
exit 1; \
}
# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
# we don't want to bother translators with empty POT files). We assume that
# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
# In this case, stamp-po is a nop (i.e. a phony target).
# stamp-po is a timestamp denoting the last time at which the CATALOGS have
# been loosely updated. Its purpose is that when a developer or translator
# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
# invocations of "make" will do nothing. This timestamp would not be necessary
# if updating the $(CATALOGS) would always touch them; however, the rule for
# $(POFILES) has been designed to not touch files that don't need to be
# changed.
stamp-po: $(srcdir)/$(DOMAIN).pot
test ! -f $(srcdir)/$(DOMAIN).pot || \
test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
@test ! -f $(srcdir)/$(DOMAIN).pot || { \
echo "touch stamp-po" && \
echo timestamp > stamp-poT && \
mv stamp-poT stamp-po; \
}
# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
# otherwise packages like GCC can not be built if only parts of the source
# have been downloaded.
# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \
package_gnu='GNU '; \
else \
package_gnu=''; \
fi; \
if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
else \
msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
fi; \
case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
'' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--msgid-bugs-address="$$msgid_bugs_address" \
;; \
*) \
$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--package-name="$${package_gnu}@PACKAGE@" \
--package-version='@VERSION@' \
--msgid-bugs-address="$$msgid_bugs_address" \
;; \
esac
test ! -f $(DOMAIN).po || { \
if test -f $(srcdir)/$(DOMAIN).pot; then \
sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
else \
rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
fi; \
else \
mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
fi; \
}
# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
# every "make" invocation, only create it when it is missing.
# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
$(srcdir)/$(DOMAIN).pot:
$(MAKE) $(DOMAIN).pot-update
# This target rebuilds a PO file if $(DOMAIN).pot has changed.
# Note that a PO file is not touched if it doesn't need to be changed.
$(POFILES): $(srcdir)/$(DOMAIN).pot
@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
if test -f "$(srcdir)/$${lang}.po"; then \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \
cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \
else \
$(MAKE) $${lang}.po-create; \
fi
install: install-exec install-data
install-exec:
install-data: install-data-@USE_NLS@
if test "$(PACKAGE)" = "gettext-tools"; then \
$(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
for file in $(DISTFILES.common) Makevars.template; do \
$(INSTALL_DATA) $(srcdir)/$$file \
$(DESTDIR)$(gettextsrcdir)/$$file; \
done; \
for file in Makevars; do \
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
done; \
else \
: ; \
fi
install-data-no: all
install-data-yes: all
$(mkdir_p) $(DESTDIR)$(datadir)
@catalogs='$(CATALOGS)'; \
for cat in $$catalogs; do \
cat=`basename $$cat`; \
lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
dir=$(localedir)/$$lang/LC_MESSAGES; \
$(mkdir_p) $(DESTDIR)$$dir; \
if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
$(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
if test -n "$$lc"; then \
if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
(cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
for file in *; do \
if test -f $$file; then \
ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
fi; \
done); \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
else \
if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
:; \
else \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
fi; \
fi; \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
fi; \
done; \
done
install-strip: install
installdirs: installdirs-exec installdirs-data
installdirs-exec:
installdirs-data: installdirs-data-@USE_NLS@
if test "$(PACKAGE)" = "gettext-tools"; then \
$(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
else \
: ; \
fi
installdirs-data-no:
installdirs-data-yes:
$(mkdir_p) $(DESTDIR)$(datadir)
@catalogs='$(CATALOGS)'; \
for cat in $$catalogs; do \
cat=`basename $$cat`; \
lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
dir=$(localedir)/$$lang/LC_MESSAGES; \
$(mkdir_p) $(DESTDIR)$$dir; \
for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
if test -n "$$lc"; then \
if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
(cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
for file in *; do \
if test -f $$file; then \
ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
fi; \
done); \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
else \
if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
:; \
else \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
fi; \
fi; \
fi; \
done; \
done
# Define this as empty until I found a useful application.
installcheck:
uninstall: uninstall-exec uninstall-data
uninstall-exec:
uninstall-data: uninstall-data-@USE_NLS@
if test "$(PACKAGE)" = "gettext-tools"; then \
for file in $(DISTFILES.common) Makevars.template; do \
rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
done; \
else \
: ; \
fi
uninstall-data-no:
uninstall-data-yes:
catalogs='$(CATALOGS)'; \
for cat in $$catalogs; do \
cat=`basename $$cat`; \
lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
done; \
done
check: all
info dvi ps pdf html tags TAGS ctags CTAGS ID:
mostlyclean:
rm -f remove-potcdate.sed
rm -f stamp-poT
rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
rm -fr *.o
clean: mostlyclean
distclean: clean
rm -f Makefile Makefile.in POTFILES *.mo
maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
rm -f stamp-po $(GMOFILES)
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
dist distdir:
$(MAKE) update-po
@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
dist2: stamp-po $(DISTFILES)
dists="$(DISTFILES)"; \
if test "$(PACKAGE)" = "gettext-tools"; then \
dists="$$dists Makevars.template"; \
fi; \
if test -f $(srcdir)/$(DOMAIN).pot; then \
dists="$$dists $(DOMAIN).pot stamp-po"; \
fi; \
if test -f $(srcdir)/ChangeLog; then \
dists="$$dists ChangeLog"; \
fi; \
for i in 0 1 2 3 4 5 6 7 8 9; do \
if test -f $(srcdir)/ChangeLog.$$i; then \
dists="$$dists ChangeLog.$$i"; \
fi; \
done; \
if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
for file in $$dists; do \
if test -f $$file; then \
cp -p $$file $(distdir) || exit 1; \
else \
cp -p $(srcdir)/$$file $(distdir) || exit 1; \
fi; \
done
update-po: Makefile
$(MAKE) $(DOMAIN).pot-update
test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
$(MAKE) update-gmo
# General rule for creating PO files.
.nop.po-create:
@lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
exit 1
# General rule for updating PO files.
.nop.po-update:
@lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
tmpdir=`pwd`; \
echo "$$lang:"; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
cd $(srcdir); \
if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \
if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
rm -f $$tmpdir/$$lang.new.po; \
else \
if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
:; \
else \
echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
exit 1; \
fi; \
fi; \
else \
echo "msgmerge for $$lang.po failed!" 1>&2; \
rm -f $$tmpdir/$$lang.new.po; \
fi
$(DUMMYPOFILES):
update-gmo: Makefile $(GMOFILES)
@:
# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
# because execution permission bits may not work on the current file system.
# Use @SHELL@, which is the shell determined by autoconf for the use by its
# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
cd $(top_builddir) \
&& @SHELL@ ./config.status $(subdir)/$@.in po-directories
force:
# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

@ -0,0 +1,41 @@
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS =
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =

@ -0,0 +1 @@
# List of source files which contain translatable strings.

@ -0,0 +1,47 @@
# Special Makefile rules for English message catalogs with quotation marks.
DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
.SUFFIXES: .insert-header .po-update-en
en@quot.po-create:
$(MAKE) en@quot.po-update
en@boldquot.po-create:
$(MAKE) en@boldquot.po-update
en@quot.po-update: en@quot.po-update-en
en@boldquot.po-update: en@boldquot.po-update-en
.insert-header.po-update-en:
@lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
tmpdir=`pwd`; \
echo "$$lang:"; \
ll=`echo $$lang | sed -e 's/@.*//'`; \
LC_ALL=C; export LC_ALL; \
cd $(srcdir); \
if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
rm -f $$tmpdir/$$lang.new.po; \
else \
if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
:; \
else \
echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
exit 1; \
fi; \
fi; \
else \
echo "creation of $$lang.po failed!" 1>&2; \
rm -f $$tmpdir/$$lang.new.po; \
fi
en@quot.insert-header: insert-header.sin
sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header
en@boldquot.insert-header: insert-header.sin
sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header
mostlyclean: mostlyclean-quot
mostlyclean-quot:
rm -f *.insert-header

@ -0,0 +1,10 @@
s/"\([^"]*\)"/“\1”/g
s/`\([^`']*\)'/\1/g
s/ '\([^`']*\)' / \1 /g
s/ '\([^`']*\)'$/ \1/g
s/^'\([^`']*\)' /\1 /g
s/“”/""/g
s///g
s//”/g
s///g
s///g

@ -0,0 +1,25 @@
# All this catalog "translates" are quotation characters.
# The msgids must be ASCII and therefore cannot contain real quotation
# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
# and double quote (0x22). These substitutes look strange; see
# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
#
# This catalog translates grave accent (0x60) and apostrophe (0x27) to
# left single quotation mark (U+2018) and right single quotation mark (U+2019).
# It also translates pairs of apostrophe (0x27) to
# left single quotation mark (U+2018) and right single quotation mark (U+2019)
# and pairs of quotation mark (0x22) to
# left double quotation mark (U+201C) and right double quotation mark (U+201D).
#
# When output to an UTF-8 terminal, the quotation characters appear perfectly.
# When output to an ISO-8859-1 terminal, the single quotation marks are
# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
# grave/acute accent (by libiconv), and the double quotation marks are
# transliterated to 0x22.
# When output to an ASCII terminal, the single quotation marks are
# transliterated to apostrophes, and the double quotation marks are
# transliterated to 0x22.
#
# This catalog furthermore displays the text between the quotation marks in
# bold face, assuming the VT100/XTerm escape sequences.
#

@ -0,0 +1,22 @@
# All this catalog "translates" are quotation characters.
# The msgids must be ASCII and therefore cannot contain real quotation
# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
# and double quote (0x22). These substitutes look strange; see
# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
#
# This catalog translates grave accent (0x60) and apostrophe (0x27) to
# left single quotation mark (U+2018) and right single quotation mark (U+2019).
# It also translates pairs of apostrophe (0x27) to
# left single quotation mark (U+2018) and right single quotation mark (U+2019)
# and pairs of quotation mark (0x22) to
# left double quotation mark (U+201C) and right double quotation mark (U+201D).
#
# When output to an UTF-8 terminal, the quotation characters appear perfectly.
# When output to an ISO-8859-1 terminal, the single quotation marks are
# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
# grave/acute accent (by libiconv), and the double quotation marks are
# transliterated to 0x22.
# When output to an ASCII terminal, the single quotation marks are
# transliterated to apostrophes, and the double quotation marks are
# transliterated to 0x22.
#

@ -0,0 +1,23 @@
# Sed script that inserts the file called HEADER before the header entry.
#
# At each occurrence of a line starting with "msgid ", we execute the following
# commands. At the first occurrence, insert the file. At the following
# occurrences, do nothing. The distinction between the first and the following
# occurrences is achieved by looking at the hold space.
/^msgid /{
x
# Test if the hold space is empty.
s/m/m/
ta
# Yes it was empty. First occurrence. Read the file.
r HEADER
# Output the file's contents by reading the next line. But don't lose the
# current line while doing this.
g
N
bb
:a
# The hold space was nonempty. Following occurrences. Do nothing.
x
:b
}

@ -0,0 +1,6 @@
s/"\([^"]*\)"/“\1”/g
s/`\([^`']*\)'/\1/g
s/ '\([^`']*\)' / \1 /g
s/ '\([^`']*\)'$/ \1/g
s/^'\([^`']*\)' /\1 /g
s/“”/""/g

@ -0,0 +1,19 @@
# Sed script that remove the POT-Creation-Date line in the header entry
# from a POT file.
#
# The distinction between the first and the following occurrences of the
# pattern is achieved by looking at the hold space.
/^"POT-Creation-Date: .*"$/{
x
# Test if the hold space is empty.
s/P/P/
ta
# Yes it was empty. First occurrence. Remove the line.
g
d
bb
:a
# The hold space was nonempty. Following occurrences. Do nothing.
x
:b
}

@ -0,0 +1,39 @@
libr_la_includedir = $(includedir)/libr
LIBTOOL_DEPS = @LIBTOOL_DEPS@
INCLUDES = \
-D__LIBR_BACKEND_@BACKEND_NAME@__ \
-D__LIBR_BUILD__ \
@LIBGLADE_CFLAGS@ \
@BACKEND_CFLAGS@ \
@EXTRA_CFLAGS@
lib_LTLIBRARIES = \
libr.la
libr_la_SOURCES = \
libr-@LIBR_BACKEND@.c \
tempfiles.c \
onecanvas.c \
libr-icons.c \
libr-i18n.c \
libr-gtk.c \
libr.c
libr_la_include_HEADERS = \
gettext.h \
libr-icons.h \
libr-i18n.h \
libr-gtk.h \
libr.h
libr_la_LIBADD = \
@BACKEND_LIBS@ \
@EXTRA_LIBS@
# If not in a fakeroot environment then run ldconfig
install: install-am
@if [ ! -n "${FAKEROOTKEY}" ]; then \
echo "Regenerating system dependencies..."; \
ldconfig; \
fi

@ -0,0 +1,94 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#define ENABLE_NLS 1
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
CoreFoundation framework. */
/* #undef HAVE_CFLOCALECOPYCURRENT */
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
the CoreFoundation framework. */
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#define HAVE_DCGETTEXT 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if the GNU gettext() function is already present or preinstalled. */
#define HAVE_GETTEXT 1
/* Define if you have the iconv() function and it works. */
/* #undef HAVE_ICONV */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libr"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.4.0"

@ -0,0 +1,48 @@
#ifndef __CVTENDIAN_H
#define __CVTENDIAN_H
/* Support for swapping bytes (endian conversion) */
#include <byteswap.h>
/* For obtaining the host endian type */
#include <endian.h>
#if (__BYTE_ORDER == __LITTLE_ENDIAN)
# define HOST_ENDIAN ELFDATA2LSB
#elif (__BYTE_ORDER == __BIG_ENDIAN)
# define HOST_ENDIAN ELFDATA2MSB
#else
# error "Failed to detect host endian type"
#endif
/*
* Convert the endian of a parameter
*/
static int ConvertEndian(void *ptr, int bytes)
{
switch(bytes)
{
case 2:
{
uint16_t *value = (uint16_t *) ptr;
*value = bswap_16(*value);
} return 1;
case 4:
{
uint32_t *value = (uint32_t *) ptr;
*value = bswap_32(*value);
} return 1;
case 8:
{
uint64_t *value = (uint64_t *) ptr;
*value = bswap_64(*value);
} return 1;
default:
break;
}
return 0;
}
#endif /* __CVTENDIAN_H */

@ -0,0 +1,271 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

@ -0,0 +1,22 @@
#ifndef __LIBR_BACKENDS_H
#define __LIBR_BACKENDS_H
/*
* All of the backend functions are explicitly declared internal to prevent any custom backend
* from leaving out one of these critical functions.
*/
INTERNAL_FN libr_intstatus add_section(libr_file *file_handle, char *resource_name, libr_section **retscn);
INTERNAL_FN void *data_pointer(libr_section *scn, libr_data *data);
INTERNAL_FN size_t data_size(libr_section *scn, libr_data *data);
INTERNAL_FN libr_intstatus find_section(libr_file *file_handle, char *section, libr_section **retscn);
INTERNAL_FN libr_data *get_data(libr_file *file_handle, libr_section *scn);
INTERNAL_FN void initialize_backend(void);
INTERNAL_FN libr_data *new_data(libr_file *file_handle, libr_section *scn);
INTERNAL_FN libr_section *next_section(libr_file *file_handle, libr_section *scn);
INTERNAL_FN libr_intstatus remove_section(libr_file *file_handle, libr_section *scn);
INTERNAL_FN char *section_name(libr_file *file_handle, libr_section *scn);
INTERNAL_FN libr_intstatus set_data(libr_file *file_handle, libr_section *scn, libr_data *data, off_t offset, char *buffer, size_t size);
INTERNAL_FN libr_intstatus open_handles(libr_file *file_handle, char *filename, libr_access_t access);
INTERNAL_FN void write_output(libr_file *file_handle);
#endif /* __LIBR_BACKENDS_H */

@ -0,0 +1,533 @@
/*
*
* Copyright (c) 2008-2011 Erich Hoover
*
* libr libbfd Backend - Add resources into ELF binaries using libbfd
*
* *** PLEASE READ THE README FILE FOR LICENSE DETAILS SPECIFIC TO THIS FILE ***
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr.h"
#include "libr-internal.h"
/* File access */
#include <fcntl.h>
/* Safe rename requires some errno() knowledge */
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
/*
* Build the libr_file handle for processing with libbfd
*/
libr_intstatus open_handles(libr_file *file_handle, char *filename, libr_access_t access)
{
bfd *handle = NULL;
handle = bfd_openr(filename, "default");
if(!handle)
RETURN(LIBR_ERROR_OPENFAILED, "Failed to open input file");
if(!bfd_check_format(handle, bfd_object))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: not a libbfd object");
if(bfd_get_flavour(handle) != bfd_target_elf_flavour)
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: not an ELF file");
bfd_set_error(bfd_error_no_error);
file_handle->filename = filename;
file_handle->bfd_read = handle;
file_handle->access = access;
if(access == LIBR_READ_WRITE)
{
struct stat file_stat;
int fd;
/* Check for write permission on the file */
fd = open(filename, O_WRONLY);
if(fd == ERROR)
RETURN(LIBR_ERROR_WRITEPERM, "No write permission for file");
close(fd);
/* Obtain the access mode of the input file */
if(stat(filename, &file_stat) == ERROR)
RETURN(LIBR_ERROR_NOSIZE, "Failed to obtain file size");
file_handle->filemode = file_stat.st_mode;
file_handle->fileowner = file_stat.st_uid;
file_handle->filegroup = file_stat.st_gid;
/* Open a temporary file with the same settings as the input file */
strcpy(file_handle->tempfile, LIBR_TEMPFILE);
file_handle->fd_handle = mkstemp(file_handle->tempfile);
handle = bfd_openw(file_handle->tempfile, bfd_get_target(file_handle->bfd_read));
if(!bfd_set_format(handle, bfd_get_format(file_handle->bfd_read)))
RETURN(LIBR_ERROR_SETFORMAT, "Failed to set output file format to input file format");
if(!bfd_set_arch_mach(handle, bfd_get_arch(file_handle->bfd_read), bfd_get_mach(file_handle->bfd_read)))
RETURN(LIBR_ERROR_SETARCH, "Failed to set output file architecture to input file architecture");
/* twice needed ? */
if(!bfd_set_format(handle, bfd_get_format(file_handle->bfd_read)))
RETURN(LIBR_ERROR_SETFORMAT, "Failed to set output file format to input file format");
file_handle->bfd_write = handle;
}
else
{
file_handle->fd_handle = 0;
file_handle->bfd_write = NULL;
}
RETURN_OK;
}
/*
* Check to see if a symbol should be kept
*/
int keep_symbol(libr_section *sections, libr_section *chkscn)
{
libr_section *scn;
/* Check that the section is publicly exposed */
for(scn = sections; scn != NULL; scn = scn->next)
{
if(scn == chkscn)
{
/* if it is, and has size zero, then it was marked for deletion */
if(bfd_get_section_size(chkscn) == 0)
return false;
return true;
}
}
return true;
}
/*
* Remove the symbol corresponding to a deleted section
*/
void remove_sections(libr_section *sections, void *symtab_buffer, long *symtab_count)
{
asymbol **symtab = (asymbol **) symtab_buffer;
long i, cnt = *symtab_count;
for(i=0;i<cnt;i++)
{
libr_section *chkscn = NULL;
asymbol *symbol = symtab[i];
if(symbol != NULL)
chkscn = bfd_get_section(symbol);
if(chkscn != NULL && !keep_symbol(sections, chkscn))
{
/* remove the symbol from the table */
asymbol **tmp = (asymbol **) malloc(sizeof(asymbol *) * (cnt-(i+1)));
memcpy(&tmp[0], &symtab[i+1], sizeof(asymbol *) * (cnt-(i+1)));
memcpy(&symtab[i], &tmp[0], sizeof(asymbol *) * (cnt-(i+1)));
free(tmp);
cnt--;
}
}
*symtab_count = cnt;
}
int setup_sections(bfd *ihandle, bfd *ohandle)
{
libr_section *iscn, *oscn;
bfd_vma vma;
for(iscn = ihandle->sections; iscn != NULL; iscn = iscn->next)
{
if(bfd_get_section_size(iscn) == 0)
{
continue; /* Section has been marked for deletion */
}
/* Use SEC_LINKER_CREATED to ask the libbfd backend to take care of configuring the section */
// Keep the ARM_ATTRIBUTES section type intact on armhf systems
// If this is not done, readelf -A will not print any architecture information for the modified library,
// and ldd will report that the library cannot be found
if (strcmp(iscn->name, ".ARM.attributes") == 0)
{
oscn = bfd_make_section_anyway_with_flags(ohandle, iscn->name, iscn->flags);
}
else
{
oscn = bfd_make_section_anyway_with_flags(ohandle, iscn->name, iscn->flags | SEC_LINKER_CREATED);
}
if(oscn == NULL)
{
printf("failed to create out section: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
if(!bfd_set_section_size(ohandle, oscn, iscn->size))
{
printf("failed to set data size: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
vma = bfd_section_vma(ihandle, iscn);
if(!bfd_set_section_vma(ohandle, oscn, vma))
{
printf("failed to set virtual memory address: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
oscn->lma = iscn->lma;
if(!bfd_set_section_alignment(ohandle, oscn, bfd_section_alignment(ihandle, iscn)))
{
printf("failed to compute section alignment: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
oscn->entsize = iscn->entsize;
iscn->output_section = oscn;
iscn->output_offset = vma;
if(!bfd_copy_private_section_data(ihandle, iscn, ohandle, oscn))
{
printf("failed to compute section alignment: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
}
return true;
}
/*
* Go through the rather complicated process of using libbfd to build the output file
*/
int build_output(libr_file *file_handle)
{
void *symtab_buffer = NULL, *reloc_buffer = NULL, *buffer = NULL;
bfd_size_type symtab_size, reloc_size, size;
bfd *ohandle = file_handle->bfd_write;
bfd *ihandle = file_handle->bfd_read;
long symtab_count, reloc_count;
libr_section *iscn, *oscn;
if(!bfd_set_start_address(ohandle, bfd_get_start_address(ihandle)))
{
printf("failed to set start address: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
if(!bfd_set_file_flags(ohandle, bfd_get_file_flags(ihandle)))
{
printf("failed to set file flags: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
/* Setup the sections in the output file */
if(!setup_sections(ihandle, ohandle))
return false; /* error already printed */
if(!bfd_copy_private_header_data(ihandle, ohandle))
{
printf("failed to copy header: %s\n", bfd_errmsg(bfd_get_error()));
return false; /* failed to create section */
}
/* Get the old symbol table */
if((bfd_get_file_flags(ihandle) & HAS_SYMS) == 0)
{
printf("file has no symbol table: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
symtab_size = bfd_get_symtab_upper_bound(ihandle);
if((signed)symtab_size < 0)
{
printf("failed to get symbol table size: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
symtab_buffer = malloc(symtab_size);
symtab_count = bfd_canonicalize_symtab(ihandle, symtab_buffer);
if(symtab_count < 0)
{
printf("failed to get symbol table number of entries: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
/* Tweak the symbol table to remove sections that no-longer exist */
remove_sections(ihandle->sections, symtab_buffer, &symtab_count);
bfd_set_symtab(ohandle, symtab_buffer, symtab_count);
/* Actually copy section data */
for(iscn = ihandle->sections; iscn != NULL; iscn = iscn->next)
{
size = bfd_get_section_size(iscn);
if(size == 0)
continue; /* Section has been marked for deletion */
oscn = iscn->output_section;
reloc_size = bfd_get_reloc_upper_bound(ihandle, iscn);
if(reloc_size == 0)
bfd_set_reloc(ohandle, oscn, NULL, 0);
else
{
reloc_buffer = malloc(reloc_size);
reloc_count = bfd_canonicalize_reloc(ihandle, iscn, reloc_buffer, symtab_buffer);
bfd_set_reloc(ohandle, oscn, reloc_buffer, reloc_count);
}
if(bfd_get_section_flags(ihandle, iscn) & SEC_HAS_CONTENTS)
{
/* NOTE: if the section is just being copied then do that, otherwise grab
* the user data for the section (stored previously by set_data)
*/
if(iscn->userdata == NULL)
{
buffer = malloc(size);
if(!bfd_get_section_contents(ihandle, iscn, buffer, 0, size))
{
printf("failed to get section contents: %s\n", bfd_errmsg(bfd_get_error()));
free(buffer);
return false;
}
}
else
buffer = iscn->userdata;
if(!bfd_set_section_contents(ohandle, oscn, buffer, 0, size))
{
printf("failed to set section contents: %s\n", bfd_errmsg(bfd_get_error()));
free(buffer);
return false;
}
free(buffer);
if(!bfd_copy_private_section_data(ihandle, iscn, ohandle, oscn))
{
printf("failed to copy private section data: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
}
}
if(!bfd_copy_private_bfd_data(ihandle, ohandle))
{
printf("failed to copy private data: %s\n", bfd_errmsg(bfd_get_error()));
return false;
}
return true;
}
/*
* Perform a cross-device safe rename
*/
int safe_rename(const char *old, const char *new)
{
char buffer[1024];
FILE *in, *out;
int read;
in = fopen(old, "r");
if(!in)
return -1;
out = fopen(new, "w");
if(!out)
return -1;
while(!feof(in) && !ferror(in))
{
read = fread(buffer, 1, sizeof(buffer), in);
fwrite(buffer, read, 1, out);
}
fclose(in);
fclose(out);
if(ferror(in))
{
remove(new);
return -1;
}
return remove(old);
}
/*
* Write the output file using the libbfd method
*/
void write_output(libr_file *file_handle)
{
int write_ok = false;
if(file_handle->bfd_write != NULL)
{
write_ok = true;
if(!build_output(file_handle))
{
printf("failed to build output file.\n");
write_ok = false;
}
if(!bfd_close(file_handle->bfd_write))
{
printf("failed to close write handle.\n");
write_ok = false;
}
if(file_handle->fd_handle != 0 && close(file_handle->fd_handle))
{
write_ok = false;
printf("failed to close write file descriptor.\n");
}
}
/* The read handle must be closed last since it is used in the write process */
if(!bfd_close(file_handle->bfd_read))
printf("failed to close read handle.\n");
/* Copy the temporary output over the input */
if(write_ok)
{
if(rename(file_handle->tempfile, file_handle->filename) < 0)
{
if(errno != EXDEV || safe_rename(file_handle->tempfile, file_handle->filename) < 0)
printf("failed to rename output file: %m\n");
}
if(chmod(file_handle->filename, file_handle->filemode) < 0)
printf("failed to set file mode.\n");
if(chown(file_handle->filename, file_handle->fileowner, file_handle->filegroup) < 0)
printf("failed to set file ownership.\n");
}
}
/*
* Find a named section from the ELF file using libbfd
*/
libr_intstatus find_section(libr_file *file_handle, char *section_name, libr_section **retscn)
{
libr_section *scn;
for(scn = file_handle->bfd_read->sections; scn != NULL; scn = scn->next)
{
if(strcmp(scn->name, section_name) == 0)
{
*retscn = scn;
RETURN_OK;
}
}
RETURN(LIBR_ERROR_NOSECTION, "ELF resource section not found");
}
/*
* Obtain the data from a section using libbfd
*/
libr_data *get_data(libr_file *file_handle, libr_section *scn)
{
libr_data *data = malloc(scn->size);
if(!bfd_get_section_contents(file_handle->bfd_read, scn, data, 0, scn->size))
{
free(data);
data = NULL;
}
scn->userdata = data;
return data;
}
/*
* Create new data for a section using libbfd
*/
libr_data *new_data(libr_file *file_handle, libr_section *scn)
{
/* NOTE: expanding data is handled by set_data for libbfd */
if(scn->userdata != NULL)
return scn->userdata;
scn->size = 0;
scn->userdata = malloc(0);
return scn->userdata;
}
/*
* Create new data for a section using libbfd (at least, do so memory-wise)
*/
libr_intstatus set_data(libr_file *file_handle, libr_section *scn, libr_data *data, off_t offset, char *buffer, size_t size)
{
char *intbuffer = NULL;
/* special case: clear buffer */
if(buffer == NULL)
{
scn->size = 0;
if(scn->userdata != NULL)
free(scn->userdata);
RETURN_OK;
}
/* normal case: add new data to the buffer */
scn->size = offset + size;
scn->userdata = realloc(data, scn->size);
if(scn->userdata == NULL)
RETURN(LIBR_ERROR_MEMALLOC, "Failed to allocate memory for data");
intbuffer = scn->userdata;
memcpy(&intbuffer[offset], buffer, size);
RETURN_OK;
}
/*
* Create a new section using libbfd
*/
libr_intstatus add_section(libr_file *file_handle, char *resource_name, libr_section **retscn)
{
libr_section *scn = NULL;
scn = bfd_make_section(file_handle->bfd_read, resource_name);
if(scn == NULL)
RETURN(LIBR_ERROR_NEWSECTION, "Failed to create new section");
if(!bfd_set_section_flags(file_handle->bfd_read, scn, SEC_HAS_CONTENTS | SEC_DATA | SEC_IN_MEMORY))
RETURN(LIBR_ERROR_SETFLAGS, "Failed to set flags for section");
*retscn = scn;
RETURN_OK;
}
/*
* Remove a section and eliminate it from the ELF string table using libbfd
*/
libr_intstatus remove_section(libr_file *file_handle, libr_section *scn)
{
scn->size = 0;
RETURN_OK;
}
/*
* Return the pointer to the actual data in the section
*/
void *data_pointer(libr_section *scn, libr_data *data)
{
return data;
}
/*
* Return the size of the data in the section
*/
size_t data_size(libr_section *scn, libr_data *data)
{
return scn->size;
}
/*
* Return the next section in the ELF file
*/
libr_section *next_section(libr_file *file_handle, libr_section *scn)
{
/* get the first section */
if(scn == NULL)
{
if(file_handle->bfd_read == NULL)
return NULL;
return file_handle->bfd_read->sections;
}
return scn->next;
}
/*
* Return the name of a section
*/
char *section_name(libr_file *file_handle, libr_section *scn)
{
return (char *) scn->name;
}
/*
* Initialize libbfd
*/
void initialize_backend(void)
{
bfd_init();
}

@ -0,0 +1,40 @@
#ifndef __LIBR_BFD_H
#define __LIBR_BFD_H
#include "config.h"
#include <sys/types.h>
#include <stdint.h>
#include <bfd.h>
#if BFD_HOST_64BIT_LONG
#if defined(__i386)
#error "Using incorrect binutils header file for architecture."
#endif
#else
#if defined(__amd64)
#error "Using incorrect binutils header file for architecture."
#endif
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _libr_file {
int fd_handle;
bfd *bfd_read;
bfd *bfd_write;
char *filename;
mode_t filemode;
uid_t fileowner;
gid_t filegroup;
char tempfile[LIBR_TEMPFILE_LEN];
libr_access_t access;
} libr_file;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/* for a clean internal API */
typedef asection libr_section;
typedef void libr_data;
#endif /* __LIBR_BFD_H */

@ -0,0 +1,412 @@
/*
*
* Copyright (c) 2008 Erich Hoover
*
* libr libelf Backend - Add resources into ELF binaries using libelf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr.h"
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
//#define MANUAL_LAYOUT true
extern void libr_set_error(libr_intstatus error);
/*
* Write the output file using libelf
*/
void write_output(libr_file *file_handle)
{
/* Update the ELF file on the disk */
if(elf_update(file_handle->elf_handle, ELF_C_NULL) < 0)
{
printf("elf_update() failed: %s.", elf_errmsg(-1));
return;
}
if(elf_update(file_handle->elf_handle, ELF_C_WRITE) < 0)
{
printf("elf_update() failed: %s.", elf_errmsg(-1));
return;
}
/* Close the handles */
elf_end(file_handle->elf_handle);
close(file_handle->fd_handle);
}
/*
* Return the size of the file represented by the file descriptor
*/
off_t file_size(int fd)
{
struct stat file_stat;
if(fstat(fd, &file_stat) == ERROR)
return ERROR;
return file_stat.st_size;
}
/*
* Open the handles for working with the file using libelf
*/
libr_intstatus open_handles(libr_file *file_handle, char *filename, libr_access_t access)
{
const int elf_access[2] = {ELF_C_READ, ELF_C_RDWR};
const int fd_access[2] = {O_RDONLY, O_RDWR};
Elf *e = NULL;
int fd = 0;
if((fd = open(filename, fd_access[access], 0)) < 0)
RETURN(LIBR_ERROR_OPENFAILED, "Failed to open input file");
if((e = elf_begin(fd, elf_access[access], NULL)) == NULL)
RETURN(LIBR_ERROR_BEGINFAILED, "Failed to open ELF file: %s.", elf_errmsg(-1));
if(elf_kind(e) != ELF_K_ELF)
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format");
file_handle->access = access;
file_handle->fd_handle = fd;
file_handle->elf_handle = e;
file_handle->file_size = file_size(fd);
file_handle->version = EV_CURRENT; /* This should probably match the rest of the file */
RETURN_OK;
}
/*
* Expand a section
* (Only used when manually controlling ELF layout)
*/
#ifdef MANUAL_LAYOUT
libr_intstatus expand_section(Elf *e, Elf_Scn *scn, size_t size, int reset)
{
size_t offset = 0, delta = 0;
Elf_Scn *tmpscn = NULL;
GElf_Shdr shdr;
if(gelf_getshdr(scn, &shdr) != &shdr)
RETURN(LIBR_INTERROR_GETSHDR, "Failed to obtain ELF header: %s", elf_errmsg(-1));
if(reset)
{
delta = (size-shdr.sh_size);
shdr.sh_size = size;
}
else
{
delta = size;
shdr.sh_size += size;
}
offset = shdr.sh_offset;
if(gelf_update_shdr(scn, &shdr) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
if(elf_update(e, ELF_C_NULL) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
/* Update any section that follows this one data-wise */
/*
****** This does not work yet
while((tmpscn = elf_nextscn(e, tmpscn)) != NULL)
{
if(tmpscn == scn)
continue;
if(gelf_getshdr(tmpscn, &shdr) != &shdr)
return LIBR_INTERROR_GETSHDR;
if(offset < shdr.sh_offset)
{
if((name = elf_strptr(e, ehdr.e_shstrndx, shdr.sh_name)) == NULL)
RETURN(LIBR_ERROR_STRPTR, "Failed to obtain section string pointer: %s.", elf_errmsg(-1));
shdr.sh_offset += delta;
if(gelf_update_shdr(tmpscn, &shdr) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
if(elf_update(e, ELF_C_NULL) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
}
}
*/
return LIBR_OK;
}
#endif /* MANUAL_LAYOUT */
/*
* Obtain the data from a section using libelf
*/
libr_data *get_data(libr_file *file_handle, libr_section *scn)
{
return elf_getdata(scn, NULL);
}
/*
* Create new data for a section using libelf
*/
libr_data *new_data(libr_file *file_handle, libr_section *scn)
{
return elf_newdata(scn);
}
/*
* Set data for a section using libelf (not written yet)
*/
libr_intstatus set_data(libr_file *file_handle, libr_section *scn, libr_data *data, off_t offset, char *buffer, size_t size)
{
data->d_align = 1;
data->d_off = offset;
data->d_buf = buffer;
data->d_type = ELF_T_BYTE;
data->d_size = size;
data->d_version = file_handle->version;
#ifdef MANUAL_LAYOUT
if(expand_section(file_handle->elf_handle, scn, data->d_size, true) != LIBR_OK)
RETURN(LIBR_ERROR_EXPANDSECTION, "Failed to expand section");
#else
if(elf_update(file_handle->elf_handle, ELF_C_NULL) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
if(elf_update(file_handle->elf_handle, ELF_C_WRITE) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
#endif /* MANUAL_LAYOUT */
RETURN_OK;
}
/*
* Find a named section from the ELF file using libelf
*/
libr_intstatus find_section(libr_file *file_handle, char *section, libr_section **retscn)
{
Elf *e = file_handle->elf_handle;
Elf_Scn *scn = NULL;
char *name = NULL;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
uintmax_t si;
if(gelf_getehdr(e, &ehdr) == NULL)
RETURN(LIBR_ERROR_GETEHDR, "Failed to obtain ELF header: %s", elf_errmsg(-1));
while((scn = elf_nextscn(e, scn)) != NULL)
{
if(gelf_getshdr(scn, &shdr) != &shdr)
RETURN(LIBR_ERROR_GETSHDR, "Failed to obtain ELF section header: %s", elf_errmsg(-1));
if((name = elf_strptr(e, ehdr.e_shstrndx, shdr.sh_name)) == NULL)
RETURN(LIBR_ERROR_STRPTR, "Failed to obtain section string pointer: %s.", elf_errmsg(-1));
si = (uintmax_t) elf_ndxscn(scn);
/*
printf("%d: %s (%d %d)\n", (long) si, name, (long) shdr.sh_offset, (long) shdr.sh_size);
*/
if(strcmp(name, section) == 0)
{
*retscn = scn;
RETURN_OK;
}
}
RETURN(LIBR_ERROR_NOSECTION, "ELF resource section not found");
}
/*
* Add a new section and create a name for it in the ELF string table using libelf
*/
libr_intstatus add_section(libr_file *file_handle, char *section, Elf_Scn **retscn)
{
Elf_Scn *scn = NULL, *strscn = NULL;
Elf *e = file_handle->elf_handle;
#ifdef MANUAL_LAYOUT
size_t tblsize = 0;
#endif /* MANUAL_LAYOUT */
Elf_Data *data;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
if(gelf_getehdr(e, &ehdr) == NULL)
RETURN(LIBR_ERROR_GETEHDR, "Failed to obtain ELF header: %s", elf_errmsg(-1));
/* TODO: Support creating a string table for objects that don't have one */
if(!ehdr.e_shstrndx)
RETURN(LIBR_ERROR_NOTABLE, "No ELF string table");
strscn = elf_getscn(e, ehdr.e_shstrndx);
if(strscn == NULL)
RETURN(LIBR_ERROR_TABLE, "Failed to open string table: %s.", elf_errmsg(-1));
data = elf_newdata(strscn);
if(data == NULL)
RETURN(LIBR_ERROR_NEWDATA, "Failed to create data for section");
data->d_align = 1;
#ifdef MANUAL_LAYOUT
{
GElf_Shdr strshdr;
if(gelf_getshdr(strscn, &strshdr) != &strshdr)
RETURN(LIBR_ERROR_GETSHDR, "Failed to obtain ELF section header: %s", elf_errmsg(-1));
data->d_off = strshdr.sh_size;
#endif /* MANUAL_LAYOUT */
data->d_size = (size_t) strlen(section)+1;
data->d_type = ELF_T_BYTE;
data->d_buf = section;
data->d_version = file_handle->version;
#ifdef MANUAL_LAYOUT
if(expand_section(e, strscn, data->d_size, false) != LIBR_OK)
return false;
}
#else
/* Update the internal offset information */
if(elf_update(e, ELF_C_NULL) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
#endif /* MANUAL_LAYOUT */
/* seek to the end of the section data */
if((scn = elf_newscn(e)) == NULL)
RETURN(LIBR_ERROR_NEWSECTION, "Failed to create new section");
if(gelf_getshdr(scn, &shdr) != &shdr)
RETURN(LIBR_ERROR_GETSHDR, "Failed to obtain ELF section header: %s", elf_errmsg(-1));
shdr.sh_addralign = 1;
#ifdef MANUAL_LAYOUT
shdr.sh_offset = file_handle->file_size;
#endif /* MANUAL_LAYOUT */
shdr.sh_size = 0;
shdr.sh_name = data->d_off;
shdr.sh_type = SHT_NOTE; /* TODO: Does "NOTE" type fit best? */
shdr.sh_flags = SHF_WRITE;
shdr.sh_entsize = 0;
if(gelf_update_shdr(scn, &shdr) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
*retscn = scn;
RETURN_OK;
}
/*
* Remove a section and eliminate it from the ELF string table using libelf
*/
libr_intstatus remove_section(libr_file *file_handle, libr_section *scn)
{
unsigned int table_size, str_size;
char *buffer = NULL, *tmp = NULL;
Elf *e = file_handle->elf_handle;
int remaining_size;
Elf_Scn *strscn;
Elf_Data *data;
GElf_Ehdr ehdr;
GElf_Shdr shdr;
if(gelf_getehdr(e, &ehdr) == NULL)
RETURN(LIBR_ERROR_GETEHDR, "Failed to obtain ELF header: %s", elf_errmsg(-1));
/* Grab the string table */
if(!ehdr.e_shstrndx)
RETURN(LIBR_ERROR_NOTABLE, "No ELF string table");
strscn = elf_getscn(e, ehdr.e_shstrndx);
if(strscn == NULL)
RETURN(LIBR_ERROR_TABLE, "Failed to open string table: %s.", elf_errmsg(-1));
if((data = elf_getdata(strscn, NULL)) == NULL)
RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section");
/* Find where the section name is in the string table */
if(gelf_getshdr(scn, &shdr) != &shdr)
RETURN(LIBR_ERROR_GETSHDR, "Failed to obtain ELF section header: %s", elf_errmsg(-1));
table_size = data->d_size;
buffer = (char *) data->d_buf;
/* Excise the string from the table */
str_size = strlen(&buffer[shdr.sh_name])+1;
remaining_size = table_size-(shdr.sh_name+str_size);
if(remaining_size < 0)
RETURN(LIBR_ERROR_SIZEMISMATCH, "Section's data size does not make sense");
if(remaining_size > 0)
{
/* If there is data after our icon entry in the table then it must be moved before resizing
* NOTE: Using memcpy with overlapping addresses is not allowed, use temporary buffer.
*/
tmp = (char *) malloc(remaining_size);
memcpy(tmp, &buffer[shdr.sh_name+str_size], remaining_size);
memcpy(&buffer[shdr.sh_name], tmp, remaining_size);
free(tmp);
}
data->d_size -= str_size;
/* Update the internal offset information */
if(elf_update(e, ELF_C_NULL) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
#ifdef MANUAL_LAYOUT
{
GElf_Shdr strshdr;
if(gelf_getshdr(strscn, &strshdr) != &strshdr)
RETURN(LIBR_ERROR_GETSHDR, "Failed to obtain ELF section header: %s", elf_errmsg(-1));
strshdr.sh_size -= str_size;
if(gelf_update_shdr(strscn, &strshdr) < 0)
RETURN(LIBR_ERROR_UPDATE, "Failed to perform dynamic update: %s.", elf_errmsg(-1));
}
#endif /* MANUAL_LAYOUT */
/* Clear the section itself and update the offsets */
if(elfx_remscn(e, scn) == 0)
RETURN(LIBR_ERROR_REMOVESECTION, "Failed to remove section: %s.", elf_errmsg(-1));
RETURN_OK;
}
/*
* Return the pointer to the actual data in the section
*/
void *data_pointer(libr_section *scn, libr_data *data)
{
return data->d_buf;
}
/*
* Return the size of the data in the section
*/
size_t data_size(libr_section *scn, libr_data *data)
{
return data->d_size;
}
/*
* Return the next section in the ELF file
*/
libr_section *next_section(libr_file *file_handle, libr_section *scn)
{
return elf_nextscn(file_handle->elf_handle, scn);
}
/*
* Retrieve the name of a section
*/
char *section_name(libr_file *file_handle, libr_section *scn)
{
char *name = NULL;
GElf_Shdr shdr;
GElf_Ehdr ehdr;
if(gelf_getehdr(file_handle->elf_handle, &ehdr) == NULL)
return NULL;
if(gelf_getshdr(scn, &shdr) != &shdr)
return NULL;
if((name = elf_strptr(file_handle->elf_handle, ehdr.e_shstrndx, shdr.sh_name)) == NULL)
return NULL;
return strdup(name);
}
/*
* Initialize the libelf backend
*/
void initialize_backend(void)
{
if(elf_version(EV_CURRENT) == EV_NONE)
return; //errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1));
}

@ -0,0 +1,24 @@
#ifndef __LIBR_ELF_H
#define __LIBR_ELF_H
/* Handle ELF files */
#include <libelf.h>
#include <gelf.h>
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _libr_file {
int fd_handle;
Elf *elf_handle;
size_t file_size;
libr_access_t access;
unsigned int version;
} libr_file;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/* for a clean internal API */
typedef Elf_Scn libr_section;
typedef Elf_Data libr_data;
#endif /* __LIBR_ELF_H */

@ -0,0 +1,443 @@
/*
*
* Copyright (c) 2008-2009 Erich Hoover
*
* libr GTK support - Convenience functions for using resources in GTK applications
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr.h"
#include "libr-gtk.h"
#include "libr-icons.h"
#include "tempfiles.h"
/* For loading GTK/GDK images */
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib.h>
/* For loading GLADE files */
#include <glade/glade.h>
/* For loading GTK+ Builder files */
#include <gtk/gtk.h>
/* For malloc/free */
#include <stdlib.h>
/* For string handling */
#include <string.h>
typedef gchar * (*GladeFileCallback)(GladeXML *, const gchar *, guint *);
GladeFileCallback glade_set_file_callback(GladeFileCallback callback, gpointer user_data);
/* Use weak binding for all glade and GTK+ requirements */
#pragma weak glade_set_file_callback
#pragma weak gtk_window_set_default_icon_list
#pragma weak gdk_pixbuf_loader_get_pixbuf
#pragma weak gtk_builder_add_from_string
#pragma weak gdk_pixbuf_loader_set_size
#pragma weak g_type_check_instance_cast
#pragma weak gtk_builder_add_from_file
#pragma weak glade_xml_new_from_buffer
#pragma weak gdk_pixbuf_loader_write
#pragma weak gdk_pixbuf_loader_close
#pragma weak gdk_pixbuf_loader_new
#pragma weak g_signal_connect_data
#pragma weak g_signal_connect
#pragma weak gtk_builder_new
#pragma weak g_object_unref
#pragma weak glade_xml_new
#pragma weak g_list_append
#pragma weak glade_init
#pragma weak gtk_init
#pragma weak g_free
#define GLADE_SECTION ".glade"
#define BUILDER_SECTION ".ui"
/*
* Handle the resource request from libglade
*/
gchar *libr_glade_read_resource(GladeXML *gladefile, const gchar *filename, guint *size, gpointer user_data)
{
return libr_malloc((libr_file *) user_data, (char *) filename, (size_t *) size);
}
/*
* Handle the resource request from GtkBuilder
*/
gboolean libr_gtk_read_resource(GtkBuilder *builder, const gchar *filename, gchar **data, gsize *size, GError **error, gpointer user_data)
{
if(data == NULL)
return FALSE;
*data = libr_malloc((libr_file *) user_data, (char *) filename, (size_t *) size);
if(*data == NULL)
return FALSE;
return TRUE;
}
/*
* Load the libglade resource appropriately for the currently installed version
* (AKA, hurray hacks!)
*/
GladeXML *libr_new_glade(libr_file *handle, char *gladefile, size_t gladefile_size)
{
if(glade_set_file_callback) /* The not-yet (ever?) existing way */
{
/* Register a callback for libglade to load our resources */
if(glade_set_file_callback((GladeFileCallback) libr_glade_read_resource, handle) != NULL)
printf("warning: over-wrote an application callback!\n");
/* Initialize libglade almost as usual, just use a buffer instead of a file */
return glade_xml_new_from_buffer(gladefile, gladefile_size, NULL, NULL);
}
else /* The hacky way */
{
char *glade_file[PATH_MAX];
GladeXML *ret = NULL;
char *temp_folder;
temp_folder = libr_extract_resources(handle);
if(temp_folder == NULL)
return NULL;
strcpy((char*)glade_file, temp_folder);
strcat((char*)glade_file, "/");
strcat((char*)glade_file, GLADE_SECTION);
ret = glade_xml_new((char*)glade_file, NULL, NULL);
if(ret == NULL)
cleanup_folder(temp_folder);
else
register_folder_cleanup(temp_folder);
return ret;
}
}
/*
* Load the GtkBuilder resource appropriately for the currently installed version
* (AKA, hurray hacks!)
*/
int libr_new_builder(libr_file *handle, char *builderfile, size_t builderfile_size, GtkBuilder *builder)
{
/* Register a callback for GtkBuilder to load our resources */
if(g_signal_connect(builder, "load-resource", (GCallback) libr_gtk_read_resource, handle))
{
/* Initialize GtkBuilder almost as usual, just use a buffer instead of a file */
if(gtk_builder_add_from_string(builder, builderfile, builderfile_size, NULL) == 0)
return false;
return true;
}
else /* The hacky way */
{
char *builder_file[PATH_MAX];
char *temp_folder;
int ret = false;
temp_folder = libr_extract_resources(handle);
if(temp_folder == NULL)
return false;
strcpy((char*)builder_file, temp_folder);
strcat((char*)builder_file, "/");
strcat((char*)builder_file, BUILDER_SECTION);
ret = gtk_builder_add_from_file(builder, (char*)builder_file, NULL);
if(ret == 0)
cleanup_folder(temp_folder);
else
register_folder_cleanup(temp_folder);
g_free(temp_folder);
return (ret != 0);
}
}
/*
* Return a GTK icon list
*/
EXPORT_FN IconList *libr_gtk_iconlist(libr_file *handle)
{
int sizes[] = {16, 32, 48, 96, 128};
IconList *icons = NULL;
GdkPixbuf *icon = NULL;
int sizes_len = 5, i;
if(handle == NULL)
{
/* Must pass a file handle to obtain the icons from */
return NULL;
}
if(gtk_init == NULL)
{
/* GTK+ was not linked with the application */
return false;
}
/* Go through the list of GTK "required" image sizes and build the icons */
for(i=0;i<sizes_len;i++)
{
libr_icon *icon_handle = libr_icon_geticon_bysize(handle, sizes[i]);
GdkPixbufLoader *stream = gdk_pixbuf_loader_new();
char *iconfile = NULL;
size_t iconfile_size;
if(icon_handle == NULL)
{
/* Failed to find an icon */
printf("Failed to find an icon\n");
continue;
}
iconfile = libr_icon_malloc(icon_handle, &iconfile_size);
if(iconfile == NULL)
{
/* Failed to obtain embedded icon */
continue;
}
libr_icon_close(icon_handle);
/* TODO: Use the "size-prepared" signal to properly scale the width and height
void user_function (GdkPixbufLoader *loader, gint width, gint height, gpointer user_data)
*/
gdk_pixbuf_loader_set_size(stream, sizes[i], sizes[i]);
if(!gdk_pixbuf_loader_write(stream, (unsigned char *)iconfile, iconfile_size, NULL))
{
/* Failed to process image */
continue;
}
if(!gdk_pixbuf_loader_close(stream, NULL))
{
/* Failed to create image */
continue;
}
icon = gdk_pixbuf_loader_get_pixbuf(stream);
if(icon == NULL)
{
/* Failed to convert image to pixbuf */
continue;
}
icons = g_list_append(icons, icon);
}
return icons;
}
/*
* Shared GtkBuilder resource loading
*/
GtkBuilder *libr_gtk_load_internal(libr_file *handle, char *resource_name)
{
GtkBuilder *builder = NULL;
size_t builder_length;
char *builder_data;
/* Obtain the GtkBuilder XML definition */
builder_data = libr_malloc(handle, resource_name, &builder_length);
if(builder_data == NULL)
{
/* Failed to obtain embedded GtkBuilder definition file */
goto failed;
}
/* Setup the GtkBuilder environment */
builder = gtk_builder_new();
if(builder == NULL)
goto failed;
if(!libr_new_builder(handle, builder_data, builder_length, builder))
{
/* Failed to build interface from resource file */
g_object_unref(G_OBJECT(builder));
goto failed;
}
failed:
free(builder_data);
return builder;
}
/*
* Load the requested GtkBuilder resource and any applicable icons
*/
EXPORT_FN int libr_gtk_load(BuilderHandle **gtk_ret, char *resource_name)
{
libr_file *handle;
int ret = false;
if(gtk_ret == NULL)
{
/* Why on earth would you call this without obtaining the handle to the resource? */
return false;
}
if(gtk_builder_new == NULL)
{
/* GtkBuilder was not linked with the application */
return false;
}
/* Obtain the handle to the executable */
if((handle = libr_open(NULL, LIBR_READ)) == NULL)
{
/* "Failed to open this executable (%s) for resources", progname() */
return false;
}
register_internal_handle(handle);
*gtk_ret = libr_gtk_load_internal(handle, resource_name);
if(*gtk_ret == NULL)
goto failed;
ret = true;
failed:
if(!ret)
libr_close(handle);
return ret;
}
/*
* Automatically load the ".ui" GtkBuilder resource and any applicable icons
*/
EXPORT_FN int libr_gtk_autoload(BuilderHandle **gtk_ret, IconList **icons_ret, int set_default_icon)
{
GList *icons = NULL;
libr_file *handle;
int ret = false;
if(gtk_ret == NULL)
{
/* Why on earth would you call this without obtaining the handle to the resource? */
return false;
}
if(gtk_builder_new == NULL)
{
/* GtkBuilder was not linked with the application */
return false;
}
/* Obtain the handle to the executable */
if((handle = libr_open(NULL, LIBR_READ)) == NULL)
{
/* "Failed to open this executable (%s) for resources", progname() */
return false;
}
register_internal_handle(handle);
/* Obtain the icons from the ELF binary */
icons = libr_gtk_iconlist(handle);
/* Set the embedded icons as the default icon list (if requested) */
if(icons != NULL && set_default_icon)
gtk_window_set_default_icon_list(icons);
*gtk_ret = libr_gtk_load_internal(handle, BUILDER_SECTION);
if(*gtk_ret == NULL)
goto failed;
if(icons_ret)
*icons_ret = icons;
ret = true;
failed:
if(!ret)
libr_close(handle);
return ret;
}
/*
* Shared libglade resource loading
*/
GladeXML *libr_glade_load_internal(libr_file *handle, char *resource_name)
{
GladeXML *glade = NULL;
size_t glade_length;
char *glade_data;
/* Obtain the GLADE XML definition */
glade_data = libr_malloc(handle, resource_name, &glade_length);
if(glade_data == NULL)
{
/* Failed to obtain embedded glade file */
goto failed;
}
/* Initialize libglade appropriate for the available version */
glade = libr_new_glade(handle, glade_data, glade_length);
if(glade == NULL)
{
/* Failed to initialize embedded glade file */
goto failed;
}
failed:
free(glade_data);
return glade;
}
/*
* Load the requested libglade resource and any applicable icons
*/
EXPORT_FN int libr_glade_load(GladeHandle **glade_ret, char *resource_name)
{
libr_file *handle;
int ret = false;
if(glade_ret == NULL)
{
/* Why on earth would you call this without obtaining the handle to the resource? */
return false;
}
if(glade_init == NULL)
{
/* libglade was not linked with the application */
return false;
}
/* Obtain the handle to the executable */
if((handle = libr_open(NULL, LIBR_READ)) == NULL)
{
/* "Failed to open this executable (%s) for resources", progname() */
return false;
}
register_internal_handle(handle);
*glade_ret = libr_glade_load_internal(handle, resource_name);
if(*glade_ret == NULL)
goto failed;
ret = true;
failed:
if(!ret)
libr_close(handle);
return ret;
}
/*
* Automatically load the ".glade" resource and any applicable icons
*/
EXPORT_FN int libr_glade_autoload(GladeHandle **glade_ret, IconList **icons_ret, int set_default_icon)
{
libr_file *handle = NULL;
GList *icons = NULL;
if(glade_ret == NULL)
{
/* Why on earth would you call this without obtaining the handle to the resource? */
return false;
}
if(glade_init == NULL)
{
/* libglade was not linked with the application */
return false;
}
/* Obtain the handle to the executable */
if((handle = libr_open(NULL, LIBR_READ)) == NULL)
{
/* "Failed to open this executable (%s) for resources", progname() */
return false;
}
register_internal_handle(handle);
icons = libr_gtk_iconlist(handle);
/* Set the embedded icons as the default icon list (if requested) */
if(icons != NULL && set_default_icon)
gtk_window_set_default_icon_list(icons);
/* Return the libglade and icon handles for the application */
*glade_ret = libr_glade_load_internal(handle, GLADE_SECTION);
if(icons_ret)
*icons_ret = icons;
return true;
}

@ -0,0 +1,55 @@
/*
*
* Copyright (c) 2008 Erich Hoover
*
* libr-gtk - Convenience support for GTK+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
#ifndef __LIBR_GTK_H
#define __LIBR_GTK_H
#include "libr.h"
#ifndef GLADE_H
typedef void GladeHandle;
#else
typedef GladeXML GladeHandle;
#endif
#ifndef __GTK_BUILDER_H__
typedef void BuilderHandle;
#else
typedef GtkBuilder BuilderHandle;
#endif
#ifndef __G_LIB_H__
typedef void IconList;
#else
typedef GList IconList;
#endif
/* GTK Convenience API */
IconList *libr_gtk_iconlist(libr_file *handle);
int libr_gtk_autoload(BuilderHandle **gtk_ret, IconList **icons_ret, int set_default_icon);
int libr_gtk_load(BuilderHandle **gtk_ret, char *resource_name);
int libr_glade_autoload(GladeHandle **glade_ret, IconList **icons_ret, int set_default_icon);
int libr_glade_load(GladeHandle **glade_ret, char *resource_name);
#endif /* __LIBR_GTK_H */

@ -0,0 +1,84 @@
/*
*
* Copyright (c) 2009 Erich Hoover
*
* libr i18n - Add language resources into ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr-i18n.h"
#include "tempfiles.h"
/* Internationalization support */
#include <locale.h>
/* For string handling */
#include <string.h>
#include <stdio.h>
/*
* Extract the internationalization resources from the binary
* and setup gettext with the extracted folder.
*/
EXPORT_FN int libr_i18n_load(libr_file *handle, const char *domain)
{
char *temp_folder;
int ret = true;
temp_folder = libr_extract_resources(handle);
if(temp_folder == NULL)
return false;
if(!setlocale(LC_ALL, ""))
ret = false;
if(!bindtextdomain(domain, temp_folder))
ret = false;
if(!textdomain(domain))
ret = false;
if(!ret)
cleanup_folder(temp_folder);
else
register_folder_cleanup(temp_folder);
return ret;
}
EXPORT_FN int libr_i18n_autoload(const char *domain)
{
libr_file *handle;
/* Obtain the handle to the executable */
if((handle = libr_open(NULL, LIBR_READ)) == NULL)
{
/* "Failed to open this executable (%s) for resources", progname() */
return false;
}
/* Obtain the language files from the ELF binary */
if(!libr_i18n_load(handle, domain))
{
/* "Failed to load language resources!" */
goto failed;
}
failed:
libr_close(handle);
return true;
}

@ -0,0 +1,14 @@
#ifndef __LIBR_I18N_H
#define __LIBR_I18N_H
#include "libr.h"
#include "gettext.h"
#define _(string) gettext(string)
/* for strings used in structures (must manually call gettext!): */
#define N_(string) (string)
int libr_i18n_autoload(const char *domain);
int libr_i18n_load(libr_file *handle, const char *domain);
#endif /* __LIBR_I18N_H */

@ -0,0 +1,643 @@
/*
*
* Copyright (c) 2008-2011 Erich Hoover
*
* libr icons - Add icon resources into ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr-icons.h"
/* For "one canvas" SVG documents */
#include "onecanvas.h"
/* For string manipulation */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
/* For handling files */
#include <sys/stat.h>
/* For C99 number types */
#include <stdint.h>
#define ICON_SECTION ".icon"
#define TERM_LEN 1
#define OFFSET_ENTRIES 0
#define OFFSET_GUID OFFSET_ENTRIES+sizeof(uint32_t)
#if defined(__i386)
#define ID12FORMAT "%012llx"
#elif defined(__x86_64)
#define ID12FORMAT "%012lx"
#else
#define ID12FORMAT "%012lx"
#warning "string formatting may be incorrect on this architecture."
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef uint32_t ID8;
typedef uint16_t ID4;
typedef struct {uint64_t p:48;} __attribute__((__packed__)) ID12;
typedef struct {
ID8 g1;
ID4 g2;
ID4 g3;
ID4 g4;
ID12 g5;
} __attribute__((__packed__)) UUID;
typedef struct {
char *name;
size_t offset;
size_t entry_size;
libr_icontype_t type;
unsigned int icon_size;
} iconentry;
typedef struct{
size_t size;
char *buffer;
iconentry entry;
} iconlist;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/*
* Decode a UUID to its binary representation
*
* NOTE: The last 12-bit parameter cannot be obtained using (uint64_t *) with
* some versions of GCC using some optimization levels. This problem is very
* frustrating to debug, so I do not recommend playing with it yourself.
*/
UUID guid_decode(char *guid)
{
UUID id = {0x00000000, 0x0000, 0x0000, 0x0000, {0x000000000000} };
uint64_t tmp12;
sscanf(guid, "%08x-%04hx-%04hx-%04hx-" ID12FORMAT, &id.g1, &id.g2, &id.g3, &id.g4, &tmp12);
id.g5.p = tmp12;
return id;
}
/*
* Return the size of the file represented by the file stream
*/
off_t fsize(FILE *handle)
{
struct stat file_stat;
if(fstat(fileno(handle), &file_stat) == ERROR)
return ERROR;
return file_stat.st_size;
}
/*
* Create a new icon handle
*/
libr_icon *new_icon_handle(libr_icontype_t type, unsigned int icon_size, char *buffer, size_t buffer_size)
{
libr_icon *icon_handle = (libr_icon *) malloc(sizeof(libr_icon));
icon_handle->type = type;
icon_handle->buffer = buffer;
icon_handle->icon_size = icon_size;
icon_handle->buffer_size = buffer_size;
return icon_handle;
}
/*
* Obtain an existing icon resource list
*/
int get_iconlist(libr_file *file_handle, iconlist *icons)
{
if(icons == NULL)
{
/* Need to be able to return SOMETHING */
return false;
}
/* Obtain the icon resource list */
icons->buffer = libr_malloc(file_handle, ICON_SECTION, &(icons->size));
if(icons->buffer == NULL)
return false;
return true;
}
/*
* Get the next entry in an icon resource list
*/
iconentry *get_nexticon(iconlist *icons, iconentry *last_entry)
{
size_t i;
/* The icon list is needed both for the data buffer and for a call-specific iconentry instance */
if(icons == NULL)
return NULL;
/* If this is the first call (last_entry == NULL) then return the first entry */
if(last_entry == NULL)
icons->entry.offset = sizeof(uint32_t)+sizeof(UUID);
else
icons->entry.offset += icons->entry.entry_size;
/* Check to see if we've run out of entries */
if(icons->entry.offset >= icons->size)
return NULL;
i = icons->entry.offset;
memcpy(&(icons->entry.entry_size), &(icons->buffer[i]), sizeof(uint32_t));
i += sizeof(uint32_t);
icons->entry.type = icons->buffer[i];
i += sizeof(unsigned char);
switch(icons->entry.type)
{
case LIBR_SVG:
icons->entry.icon_size = 0;
icons->entry.name = &(icons->buffer[i]);
break;
case LIBR_PNG:
memcpy(&(icons->entry.icon_size), &(icons->buffer[i]), sizeof(uint32_t));
i += sizeof(uint32_t);
icons->entry.name = &(icons->buffer[i]);
break;
default:
/* Invalid entry type */
return NULL;
}
return &(icons->entry);
}
/*
* Free an icon handle
*/
EXPORT_FN int libr_icon_close(libr_icon *icon)
{
if(icon == NULL)
return false;
if(icon->buffer == NULL)
return false;
free(icon->buffer);
free(icon);
return true;
}
/*
* Read an icon resource from an ELF file by name
*/
EXPORT_FN libr_icon *libr_icon_geticon_byname(libr_file *handle, char *icon_name)
{
iconentry *entry = NULL;
libr_icon *icon = NULL;
size_t buffer_size = 0;
unsigned int icon_size;
libr_icontype_t type;
char *buffer = NULL;
int inlist = false;
iconlist icons;
if(!get_iconlist(handle, &icons))
{
/* Failed to obtain a list of ELF icons */
return NULL;
}
/* Look for the icon name in the entry list */
while((entry = get_nexticon(&icons, entry)) != NULL)
{
if(!strcmp(entry->name, icon_name))
{
type = entry->type;
icon_size = entry->icon_size;
inlist = true;
break;
}
}
if(!inlist)
{
/* Could not find icon name in the list of icons */
return false;
}
/* Get the icon from the ELF binary */
if(!libr_size(handle, icon_name, &buffer_size))
{
/* Failed to obtain ELF icon size */
return NULL;
}
/* Allocate memory for the icon */
buffer = (char *) malloc(buffer_size);
if(buffer == NULL)
{
/* Failed to allocate memory for icon */
return NULL;
}
/* Get the compressed icon from the ELF file */
if(!libr_read(handle, icon_name, buffer))
{
/* Failed to obtain ELF icon */
goto geticon_byname_complete;
}
icon = new_icon_handle(type, icon_size, buffer, buffer_size);
geticon_byname_complete:
if(icon == NULL)
free(buffer);
return icon;
}
/*
* Read an icon resource from an ELF file by the square icon size
*/
EXPORT_FN libr_icon *libr_icon_geticon_bysize(libr_file *handle, unsigned int iconsize)
{
unsigned int closest_id = 0, i = 0, j = 0;
int found_png = false, found_svg = false;
unsigned long closest_size = 0;
iconentry *entry = NULL;
iconlist icons;
if(!get_iconlist(handle, &icons))
{
/* Failed to obtain a list of ELF icons */
return NULL;
}
/* Look for the closest size match, ignore SVG in case there are multiple icons */
while((entry = get_nexticon(&icons, entry)) != NULL)
{
if(entry->type == LIBR_SVG)
found_svg = true;
if(entry->type == LIBR_PNG)
{
if(j == 0)
{
closest_size = entry->icon_size;
found_png = true;
}
if(abs(iconsize-entry->icon_size) < closest_size)
{
closest_size = entry->icon_size;
closest_id = i;
}
j++;
}
i++;
}
/* If any PNG files were found then use the file if:
* 1) There are no SVG files <OR>
* 2) The PNG is an EXACT size match
*/
if(found_png)
{
i=0;
entry = NULL;
while((entry = get_nexticon(&icons, entry)) != NULL)
{
if(i == closest_id)
{
if(entry->icon_size == iconsize || !found_svg)
return libr_icon_geticon_byname(handle, entry->name);
break;
}
i++;
}
}
/* Otherwise use the SVG (provided that there is one) */
if(found_svg)
{
entry = NULL;
while((entry = get_nexticon(&icons, entry)) != NULL)
{
if(entry->type == LIBR_SVG)
{
libr_icon *icon = libr_icon_geticon_byname(handle, entry->name);
if (icon) {
libr_icon *icon_onecanvas;
char *buffer;
/* should we report the requested size for SVG? */
icon->icon_size = iconsize;
/* if the SVG is a "one canvas" document then extract the correctly sized icon */
if((buffer = onecanvas_geticon_bysize(icon->buffer, iconsize)) != NULL)
{
libr_icon_close(icon);
icon_onecanvas = new_icon_handle(LIBR_SVG, iconsize, buffer, strlen(buffer));
return icon_onecanvas;
}
}
return icon;
}
}
}
/* Give up */
return NULL;
}
/*
* Obtains the icon UUID for the ELF file
*/
EXPORT_FN int libr_icon_getuuid(libr_file *handle, char *uuid)
{
UUID id = {0x00000000, 0x0000, 0x0000, 0x0000, {0x000000000000} };
iconlist icons;
if(!get_iconlist(handle, &icons))
{
/* Failed to obtain the list of ELF icons */
return false;
}
/* Now store the GUID to the return string */
memcpy(&id, &(icons.buffer[OFFSET_GUID]), sizeof(UUID));
snprintf(uuid, GUIDSTR_LENGTH, "%08x-%04hx-%04hx-%04hx-" ID12FORMAT "\n", id.g1, id.g2, id.g3, id.g4, (uint64_t) id.g5.p);
free(icons.buffer);
return true;
}
EXPORT_FN int libr_icon_getguid(libr_file *handle, char *uuid) ALIAS_FN(libr_icon_getuuid);
/*
* Allocate a buffer containing the data of an icon
*/
EXPORT_FN char *libr_icon_malloc(libr_icon *icon, size_t *size)
{
char *iconfile = NULL;
if(size == NULL)
{
/* No return size passed */
return NULL;
}
if(!libr_icon_size(icon, size))
{
/* Failed to obtain embedded icon file size */
return NULL;
}
iconfile = (char *) malloc(*size);
if(!libr_icon_read(icon, iconfile))
{
/* Failed to obtain embedded icon file */
free(iconfile);
return NULL;
}
return iconfile;
}
/*
* Create an icon resource to represent a file on the hard disk
*/
EXPORT_FN libr_icon *libr_icon_newicon_byfile(libr_icontype_t type, unsigned int icon_size, char *icon_file)
{
libr_icon *icon_handle = NULL;
size_t len, buffer_size = 0;
char *buffer = NULL;
FILE *handle = NULL;
/* Open a handle to the icon file */
if((handle = fopen(icon_file, "r")) == NULL)
{
/* Failed to open icon file */
return NULL;
}
/* Get the size of the icon file */
if((buffer_size = fsize(handle)) == ERROR)
{
/* Failed to obtain the icon's file size */
return NULL;
}
/* Allocate a buffer for the uncompressed icon */
buffer = (char *) malloc(buffer_size);
if(buffer == NULL)
{
/* Failed to allocate a buffer for the icon data */
return NULL;
}
/* Read the uncompressed image from the disk */
if((len = fread(buffer, 1, buffer_size, handle)) <= 0)
{
/* Failed to read icon from disk */
goto newicon_complete;
}
fclose(handle);
if(len != buffer_size)
{
/* Failed to read the entire icon */
goto newicon_complete;
}
/* Allocate the icon handle */
icon_handle = new_icon_handle(type, icon_size, buffer, buffer_size);
newicon_complete:
if(icon_handle == NULL)
free(buffer);
return icon_handle;
}
/*
* Copy the icon resource into a buffer
*/
EXPORT_FN int libr_icon_read(libr_icon *icon, char *buffer)
{
if(icon == NULL)
return false;
memcpy(buffer, icon->buffer, icon->buffer_size);
return true;
}
/*
* Get the memory size of an icon resource
*/
EXPORT_FN int libr_icon_size(libr_icon *icon, size_t *size)
{
if(icon == NULL)
return false;
*size = icon->buffer_size;
return true;
}
/*
* Save the icon resource to a file
*/
EXPORT_FN int libr_icon_save(libr_icon *icon, char *filename)
{
FILE *file = NULL;
int ret = false;
size_t len;
if(icon == NULL)
return false;
/* Open the file to store the image */
if((file = fopen(filename, "w")) == NULL)
{
/* Failed to open file to write the icon */
return false;
}
/* Store the uncompressed icon to disk */
if((len = fwrite(icon->buffer, 1, icon->buffer_size, file)) <= 0)
{
/* Failed to write output file */
goto saveicon_complete;
}
if(len != icon->buffer_size)
{
/* Did not write the entire file */
goto saveicon_complete;
}
ret = true;
saveicon_complete:
/* Close remaining resources */
fclose(file);
return ret;
}
/*
* Sets the icon GUID for the ELF file
*/
EXPORT_FN int libr_icon_setuuid(libr_file *handle, char *guid)
{
int ret = false;
iconlist icons;
UUID id;
int i;
/* First check the GUID string */
for(i=0;i<strlen(guid);i++)
{
if(!isxdigit(guid[i]))
{
if(guid[i] == '-' && (i == 8 || i == 13 || i == 18 || i == 23))
continue;
/* not a valid GUID string */
return false;
}
}
id = guid_decode(guid);
/* Now check existing resources */
if(!get_iconlist(handle, &icons))
{
/* No icons exist in the file, create a new icon section with the GUID */
uint32_t entries = 0;
icons.size = sizeof(uint32_t)+sizeof(UUID);
icons.buffer = (char *) malloc(icons.size);
memcpy(&(icons.buffer[OFFSET_ENTRIES]), &entries, sizeof(uint32_t));
}
/* Set the GUID and write the resource */
if(!libr_write(handle, ICON_SECTION, icons.buffer, icons.size, LIBR_UNCOMPRESSED, LIBR_OVERWRITE))
{
/* failed to write icon resource */
goto setguid_complete;
}
ret = true;
setguid_complete:
free(icons.buffer);
return ret;
}
EXPORT_FN int libr_icon_setguid(libr_file *handle, char *uuid) ALIAS_FN(libr_icon_setuuid);
/*
* Add an icon resource to an ELF file
*/
EXPORT_FN int libr_icon_write(libr_file *handle, libr_icon *icon, char *icon_name, libr_overwrite_t overwrite)
{
size_t entry_size, i;
iconentry *entry = NULL;
iconlist icons;
int ret = false;
/* Check to make sure the user did not make a poor name choice */
if(!strcmp(icon_name, ICON_SECTION))
{
/* ".icon" is a reserved section name */
return false;
}
/* Check to make sure the file supports icon resources */
if(!get_iconlist(handle, &icons))
{
/* A GUID must be set first */
return false;
}
/* First add the icon as a new named section */
if(!libr_write(handle, icon_name, icon->buffer, icon->buffer_size, LIBR_COMPRESSED, overwrite))
{
/* Failed to add the icon as a resource */
goto writeicon_complete;
}
/* Look to see if the icon already has an entry */
while((entry = get_nexticon(&icons, entry)) != NULL)
{
if(!strcmp(entry->name, icon_name))
{
ret = true;
goto writeicon_complete;
}
}
/* Now add the icon to the list of icon resources in the ".icon" section */
switch(icon->type)
{
case LIBR_SVG:
entry_size = sizeof(uint32_t)+sizeof(unsigned char)+strlen(icon_name)+TERM_LEN;
break;
case LIBR_PNG:
entry_size = sizeof(uint32_t)+sizeof(unsigned char)+sizeof(uint32_t)+strlen(icon_name)+TERM_LEN;
break;
default:
/* Unhandled icon type */
goto writeicon_complete;
}
icons.buffer = (char *) realloc(icons.buffer, icons.size+entry_size);
if(icons.buffer == NULL)
{
/* Failed to expand memory size */
goto writeicon_complete;
}
i = icons.size;
memcpy(&(icons.buffer[i]), &entry_size, sizeof(uint32_t));
i+=sizeof(uint32_t);
icons.buffer[i] = icon->type;
i+=sizeof(unsigned char);
if(icon->type == LIBR_PNG)
{
memcpy(&(icons.buffer[i]), &icon->icon_size, sizeof(uint32_t));
i+=sizeof(uint32_t);
}
memcpy(&(icons.buffer[i]), icon_name, strlen(icon_name));
i+=strlen(icon_name);
icons.buffer[i] = '\0';
icons.size += entry_size;
if(i != (icons.size-1))
printf("Really dangerous, buffer size mismatch!\n");
/* Write the updated icon table */
if(!libr_write(handle, ICON_SECTION, icons.buffer, icons.size, LIBR_UNCOMPRESSED, LIBR_OVERWRITE))
{
/* failed to write icon resource */
goto writeicon_complete;
}
ret = true;
writeicon_complete:
if(icons.buffer)
free(icons.buffer);
return ret;
}

@ -0,0 +1,201 @@
/*
*
* Copyright (c) 2008-2010 Erich Hoover
*
* libr-icons - Handle icon resources in ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
#ifndef __LIBR_ICONS_H
#define __LIBR_ICONS_H
#include "libr.h"
typedef enum {
LIBR_SVG = 0,
LIBR_PNG = 1
} libr_icontype_t;
#define UUIDSTR_LENGTH 37
#define GUIDSTR_LENGTH UUIDSTR_LENGTH
#ifdef __LIBR_BUILD__
typedef struct {
char *buffer;
size_t buffer_size;
libr_icontype_t type;
unsigned int icon_size;
} libr_icon;
#else
typedef void libr_icon;
#endif
/*************************************************************************
* libr Icon API
*************************************************************************/
/**
* @page libr_icon_close Release an icon resource handle.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_icon_close(libr_icon *icon);</b>
*
* @section DESCRIPTION
* Release the icon resource allocated by a call to
* <b>libr_icon_geticon_byid</b>(3), <b>libr_icon_geticon_byname</b>(3),
* <b>libr_icon_geticon_bysize</b>(3), <b>libr_icon_newicon_byfile</b>(3),
* or <b>libr_icon_newicon_frombuffer</b>(3).
*
* @param icon The icon handle to release.
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_icon_geticon_byid</b>(3), <b>libr_icon_geticon_byname</b>(3),
* <b>libr_icon_geticon_bysize</b>(3), <b>libr_icon_newicon_byfile</b>(3),
* <b>libr_icon_newicon_frombuffer</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_icon_close(libr_icon *icon);
/*
libr_icon *libr_icon_geticon_byid(libr_file *handle, unsigned int iconid);
*/
/**
* @page libr_icon_geticon_byname Retrieve an icon resource from an ELF
* binary (by the icon resource's name).
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>libr_icon *libr_icon_geticon_byname(libr_file *handle, char *iconname);</b>
*
* @section DESCRIPTION
* Return a resource handle to an icon stored in a libr-compatible ELF
* binary. When this handle is no-longer needed it must be unallocated
* using <b>libr_icon_close</b>(3).
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param iconname The exact name of the resource to return.
* @return Returns a handle on success, NULL on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_icon_close</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
libr_icon *libr_icon_geticon_byname(libr_file *handle, char *iconname);
/**
* @page libr_icon_geticon_bysize Retrieve an icon resource from an ELF
* binary (by the desired icon size).
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>libr_icon *libr_icon_geticon_bysize(libr_file *handle, unsigned int iconsize);</b>
*
* @section DESCRIPTION
* Return a resource handle to the closest requested size icon stored
* in a libr-compatible ELF binary. When this handle is no-longer
* needed it must be unallocated using <b>libr_icon_close</b>(3).
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param iconsize The size of the resource to return, use 0
* to request an SVG icon.
* @return Returns a handle on success, NULL on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_icon_close</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
libr_icon *libr_icon_geticon_bysize(libr_file *handle, unsigned int iconsize);
/**
* @page libr_icon_getuuid Retrieve the UUID of an application.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_icon_getuuid(libr_file *handle, char *uuid);</b>
*
* @section DESCRIPTION
* Returns the icon UUID corresponding to the ELF binary in hex notation
* (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), which requires a 37 character
* buffer (36 data characters and a NULL terminator).
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param uuid A buffer to store the UUID of the application.
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_icon_close</b>(3),
* <b>libr_icon_setuuid</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_icon_getuuid(libr_file *handle, char *uuid);
DEPRECATED_FN int libr_icon_getguid(libr_file *handle, char *uuid);
char *libr_icon_malloc(libr_icon *icon, size_t *size);
/*
libr_icon *libr_icon_newicon_frombuffer(libr_icontype_t type, int iconsize, char *buffer, size_t size);
*/
libr_icon *libr_icon_newicon_byfile(libr_icontype_t type, unsigned int iconsize, char *iconfile);
/*
unsigned int libr_icon_num(libr_file *handle);
*/
int libr_icon_read(libr_icon *icon, char *buffer);
int libr_icon_size(libr_icon *icon, size_t *size);
int libr_icon_save(libr_icon *icon, char *filename);
/**
* @page libr_icon_setuuid Write a UUID into an application binary.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_icon_setuuid(libr_file *handle, char *uuid);</b>
*
* @section DESCRIPTION
* Sets the icon UUID corresponding to the ELF binary in hex notation
* (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), which requires a 37 character
* buffer (36 data characters and a NULL terminator).
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param uuid A UUID to set for the application, can be generated by
* the terminal program "uuid".
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_icon_close</b>(3),
* <b>libr_icon_getuuid</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_icon_setuuid(libr_file *handle, char *uuid);
DEPRECATED_FN int libr_icon_setguid(libr_file *handle, char *guid);
int libr_icon_write(libr_file *handle, libr_icon *icon, char *iconname, libr_overwrite_t overwrite);
#endif /* __LIBR_ICONS_H */

@ -0,0 +1,34 @@
#ifndef __LIBR_INTERNAL_H
#define __LIBR_INTERNAL_H
#define false 0
#define true 1
#define ERROR -1
#define EXPORT_FN __attribute__((visibility ("protected")))
#define INTERNAL_FN __attribute__ ((visibility ("internal")))
#define LIBR_TEMPFILE "/tmp/libr-temp.XXXXXX"
#define LIBR_TEMPFILE_LEN 22
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct {
char *message;
libr_status status;
const char *function;
} libr_intstatus;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
struct _libr_file;
void libr_set_error(libr_intstatus error);
libr_intstatus make_status(const char *function, libr_status code, char *message, ...);
/* Only called directly by cleanup routine, all other calls should be through libr_close */
void libr_close_internal(struct _libr_file *file_handle);
#define SET_ERROR(code,...) make_status(__FUNCTION__, code, __VA_ARGS__)
#define RETURN(code,...) return SET_ERROR(code, __VA_ARGS__)
#define RETURN_OK return SET_ERROR(LIBR_OK, NULL)
#define PUBLIC_RETURN(code,message) {SET_ERROR(code, message); return (code == LIBR_OK);}
#endif /* __LIBR_INTERNAL_H */

@ -0,0 +1,26 @@
#ifndef __LIBR_LINK_H
#define __LIBR_LINK_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct {
void **symbol;
char *name;
} symbol_table;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#define SYMBOL_TABLE(tbl, ...) \
const symbol_table tbl[] = { \
__VA_ARGS__ \
{NULL, NULL} \
}
#define OVERRIDE_SYMBOL(a) FN_##a
#define SYMBOL(sym) {(void **)&FN_##sym, #sym}
#define DEFINE_SYMBOL(ret, fn, ...) ret (*OVERRIDE_SYMBOL(fn))(__VA_ARGS__)
#define LOAD_SYMBOLS(lib, tbl) load_symbols(lib, tbl, sizeof(tbl)/sizeof(symbol_table))
int load_symbols(const char *library, const symbol_table *table, int entries);
#endif /* __LIBR_LINK_H */

@ -0,0 +1,351 @@
/*
*
* Copyright (c) 2009 Erich Hoover
* Copyright (c) 2008-2009 Martin Rosenau
*
* libr read-only Backend - Read resources from ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr.h"
#include "libr-internal.h"
/* malloc/free */
#include <stdlib.h>
/* For memory byte-wise compare */
#include <string.h>
/* For endian conversion */
#include "cvtendian.h"
#define RETURN_UNSUPPORTED RETURN(LIBR_ERROR_UNSUPPORTED, "The read-only backend does not support this operation");
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct {
unsigned char magic[4];
eClass byte_size;
eEncoding endian;
unsigned char version;
unsigned char padding[9];
} ElfPreHeader;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#define ELF_HALF(b) sizeof(uint16_t)
#define ELF_WORD(b) sizeof(uint32_t)
#define ELF_XWORD(b) ((b == ELFCLASS32) ? sizeof(uint32_t) : sizeof(uint64_t))
#define ELF_ADDR(b) ELF_XWORD(b)
#define ELF_OFF(b) ELF_XWORD(b)
/* ELF Header Offsets */
#define HDROFF_TYPE(b) sizeof(ElfPreHeader) /* ElfXX_Half e_type; */
#define HDROFF_MACHINE(b) HDROFF_TYPE(b)+ELF_HALF(b) /* ElfXX_Half e_machine; */
#define HDROFF_VERSION(b) HDROFF_MACHINE(b)+ELF_HALF(b) /* ElfXX_Word e_version; */
#define HDROFF_ENTRY(b) HDROFF_VERSION(b)+ELF_WORD(b) /* ElfXX_Addr e_entry; */
#define HDROFF_PHOFF(b) HDROFF_ENTRY(b)+ELF_ADDR(b) /* ElfXX_Off e_phoff; */
#define HDROFF_SHOFF(b) HDROFF_PHOFF(b)+ELF_OFF(b) /* ElfXX_Off e_shoff; */
#define HDROFF_FLAGS(b) HDROFF_SHOFF(b)+ELF_OFF(b) /* ElfXX_Word e_flags; */
#define HDROFF_EHSIZE(b) HDROFF_FLAGS(b)+ELF_WORD(b) /* ElfXX_Half e_ehsize; */
#define HDROFF_PHENTSIZE(b) HDROFF_EHSIZE(b)+ELF_HALF(b) /* ElfXX_Half e_phentsize; */
#define HDROFF_PHNUM(b) HDROFF_PHENTSIZE(b)+ELF_HALF(b) /* ElfXX_Half e_phnum; */
#define HDROFF_SHENTSIZE(b) HDROFF_PHNUM(b)+ELF_HALF(b) /* ElfXX_Half e_shentsize; */
#define HDROFF_SHNUM(b) HDROFF_SHENTSIZE(b)+ELF_HALF(b) /* ElfXX_Half e_shnum; */
#define HDROFF_SHSTRNDX(b) HDROFF_SHNUM(b)+ELF_HALF(b) /* ElfXX_Half e_shstrndx; */
/* ELF Section Offsets */
#define SECOFF_NAME(b) 0 /* ElfXX_Word sh_name; */
#define SECOFF_TYPE(b) SECOFF_NAME(b)+ELF_WORD(b) /* ElfXX_Word sh_type; */
#define SECOFF_FLAGS(b) SECOFF_TYPE(b)+ELF_WORD(b) /* ElfXX_XWord sh_flags; */
#define SECOFF_ADDR(b) SECOFF_FLAGS(b)+ELF_XWORD(b) /* ElfXX_Addr sh_addr; */
#define SECOFF_OFFSET(b) SECOFF_ADDR(b)+ELF_ADDR(b) /* ElfXX_Off sh_offset; */
#define SECOFF_SIZE(b) SECOFF_OFFSET(b)+ELF_OFF(b) /* ElfXX_XWord sh_size; */
#define SECOFF_LINK(b) SECOFF_SIZE(b)+ELF_XWORD(b) /* ElfXX_Word sh_link; */
#define SECOFF_INFO(b) SECOFF_LINK(b)+ELF_WORD(b) /* ElfXX_Word sh_info; */
#define SECOFF_ADDRALIGN SECOFF_INFO(b)+ELF_WORD(b) /* ElfXX_XWord sh_addralign; */
#define SECOFF_ENTSIZE SECOFF_ADDRALIGN(b)+ELF_XWORD(b) /* ElfXX_XWord sh_entsize; */
/*
* Safely read a parameter from the ELF binary
*/
static int read_param(FILE *handle, void *result, size_t bytes, eClass endian)
{
if(fread(result, 1, bytes, handle) != bytes)
return 0;
if(ferror(handle))
return 0;
if(endian != HOST_ENDIAN && !ConvertEndian(result, bytes))
return 0;
return 1;
}
/*
* The read-only backend requires no initialization
*/
void initialize_backend(void)
{
if(sizeof(ElfPreHeader) != 16)
fprintf(stderr, "WARNING: Your compiler did not properly pack important structures!\n");
}
/*
* The read-only backend cannot write an output file
*/
void write_output(libr_file *file_handle) {}
/*
* The read-only backend cannot add sections
*/
libr_intstatus add_section(libr_file *file_handle, char *resource_name, libr_section **retscn)
{
RETURN_UNSUPPORTED;
}
/*
* Return the name of a section
*/
char *section_name(libr_file *file_handle, libr_section *scn)
{
if(scn == NULL)
return NULL;
return scn->name;
}
/*
* Return the pointer to the actual data in the section
*/
void *data_pointer(libr_section *scn, libr_data *data)
{
return (void *) data;
}
/*
* Return the size of the data in the section
*/
size_t data_size(libr_section *scn, libr_data *data)
{
return scn->size;
}
/*
* Find the resource stored in the ELF binary
*/
libr_intstatus find_section(libr_file *file_handle, char *section, libr_section **retscn)
{
char *test_name;
int i;
for(i=0; i<file_handle->total_sections; i++)
{
test_name = section_name(file_handle, &(file_handle->secdata[i]));
if(test_name != NULL && strcmp(test_name, section) == 0)
break;
}
if(i >= file_handle->total_sections)
RETURN(LIBR_ERROR_NOSECTION, "ELF resource section not found");
/* Found the resource, hurray! */
*retscn = &(file_handle->secdata[i]);
RETURN_OK;
}
/*
* Read the section from the ELF binary
*/
libr_data *get_data(libr_file *file_handle, libr_section *scn)
{
FILE *handle = file_handle->handle;
libr_data *data = NULL;
size_t n;
fseek(handle, scn->data_offset, SEEK_SET);
data = (libr_data *) malloc(scn->size);
n = fread(data, 1, scn->size, handle);
if(n == 0)
goto failed; /* Empty section? */
if(ferror(handle))
goto failed;
/* Succeeded in reading the data */
return data;
failed:
free(data);
return NULL;
}
/*
* UNSUPORTED BY BACKEND: Create a new data section
*/
libr_data *new_data(libr_file *file_handle, libr_section *scn)
{
return NULL;
}
/*
* Find the next section given a section pointer
*/
libr_section *next_section(libr_file *file_handle, libr_section *scn)
{
int total_sections = file_handle->total_sections;
libr_section *test_scn = NULL;
int i;
if(total_sections == 0)
return NULL;
/* Requesting the first section */
if(scn == NULL)
{
i = 0;
/* Do not return an empty section */
while(test_scn == NULL || test_scn->size == 0)
{
if(i > total_sections)
return NULL;
test_scn = &(file_handle->secdata[i++]);
}
return test_scn;
}
/* Return the next section given a section pointer */
for(i=0; i<total_sections; i++)
{
test_scn = &(file_handle->secdata[i]);
if(test_scn == scn && (i+1) < total_sections)
{
libr_section *next_scn = &(file_handle->secdata[i+1]);
/* Returning empty sections is pointless */
if(next_scn->size != 0)
return next_scn;
}
}
return NULL;
}
/*
* UNSUPORTED BY BACKEND: Remove a section
*/
libr_intstatus remove_section(libr_file *file_handle, libr_section *scn)
{
RETURN_UNSUPPORTED;
}
/*
* UNSUPORTED BY BACKEND: Set the data for a section
*/
libr_intstatus set_data(libr_file *file_handle, libr_section *scn, libr_data *data, off_t offset, char *buffer, size_t size)
{
RETURN_UNSUPPORTED;
}
/*
* Open a handle to the ELF binary (provided that read-only access is requested)
*/
libr_intstatus open_handles(libr_file *file_handle, char *filename, libr_access_t access)
{
const char elf_magic[] = {'\x7F','E','L','F'};
uint16_t total_sections, sh_size, strings_sec;
ElfPreHeader file_info;
libr_section *secdata;
FILE *handle = NULL;
uint64_t sh_offset;
unsigned long i;
if(access == LIBR_READ_WRITE)
RETURN_UNSUPPORTED;
handle = fopen(filename, "rb");
if(!handle)
RETURN(LIBR_ERROR_OPENFAILED, "Failed to open input file");
if(fread(&file_info, 1, sizeof(ElfPreHeader), handle) != sizeof(ElfPreHeader))
RETURN(LIBR_ERROR_WRONGFORMAT, "Failed to read pre-header bytes from input file");
if(memcmp(file_info.magic, elf_magic, sizeof(elf_magic)) != 0)
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: not an ELF binary");
/* Confirm processor (byte size) and packing (endian) */
if(!enum_valid(file_info.byte_size, ELFCLASS))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: invalid byte size");
if(!enum_valid(file_info.endian, ELFDATA))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: invalid endian type");
/* Get the file offset to the Section Header tables */
fseek(handle, HDROFF_SHOFF(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &sh_offset, ELF_OFF(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read section header offset");
/* Get the size of the Section Header tables */
fseek(handle, HDROFF_SHENTSIZE(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &sh_size, ELF_HALF(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read section header size");
/* Get the total number of sections */
fseek(handle, HDROFF_SHNUM(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &total_sections, ELF_HALF(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read total number of sections");
/* Get the ID of the "strings" section */
fseek(handle, HDROFF_SHSTRNDX(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &strings_sec, ELF_HALF(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read string section ID");
if(strings_sec >= total_sections)
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: invalid string section ID");
secdata = (libr_section *) malloc(sizeof(libr_section)*total_sections);
/* Load section information */
for(i=0; i<total_sections; i++)
{
long sec_start = sh_offset+sh_size*i;
/* Grab the offset in the string table to the name of the section */
fseek(handle, sec_start+SECOFF_NAME(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &(secdata[i].name_offset), ELF_WORD(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read section name offset");
/* Grab the offset to the data for the section */
fseek(handle, sec_start+SECOFF_OFFSET(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &(secdata[i].data_offset), ELF_OFF(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read section data offset");
/* Grab the size of the data for the section */
fseek(handle, sec_start+SECOFF_SIZE(file_info.byte_size), SEEK_SET);
if(!read_param(handle, &(secdata[i].size), ELF_XWORD(file_info.byte_size), file_info.endian))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read section size");
}
/* Locate the name offset within the "strings" section and load the string */
for(i=0; i<total_sections; i++)
{
long stringsec_start = secdata[strings_sec].data_offset;
size_t n;
fseek(handle, stringsec_start+secdata[i].name_offset, SEEK_SET);
n = fread(secdata[i].name, 1, ELFSTRING_MAX-1, handle);
if(ferror(handle))
RETURN(LIBR_ERROR_WRONGFORMAT, "Invalid input file format: failed to read string");
secdata[i].name[n] = '\0';
}
/* Hold onto the important parameters */
file_handle->secdata = secdata;
file_handle->total_sections = total_sections;
file_handle->endian = file_info.endian;
file_handle->byte_size = file_info.byte_size;
file_handle->handle = handle;
file_handle->filename = filename;
file_handle->access = access;
RETURN_OK;
}

@ -0,0 +1,62 @@
#ifndef __LIBRRO_H
#define __LIBRRO_H
/* For file handle support */
#include <stdio.h>
/* For integer types with set bit-sizes */
#include <stdint.h>
/*
* NOTE: Packing the enum uses the smallest number of bytes
* possible to represent the value. This packing does not
* guarantee that a "short enum" will be 8 bits, however,
* for the small enumerations in the ELF specification this
* IS the case (no enum requires more than 8 bits).
*/
#define SHORT_ENUM __attribute__ ((__packed__))
/* Type of byte-packing (endian) */
typedef enum SHORT_ENUM {
ELFDATANONE, /* Invalid */
ELFDATA2LSB, /* Least Significant Byte First */
ELFDATA2MSB, /* Most Significant Byte First */
ELFDATAMAX, /* Invalid */
} eEncoding;
/* Type of target processor */
typedef enum SHORT_ENUM {
ELFCLASSNONE, /* Invalid */
ELFCLASS32, /* 32-bit Field Alignment */
ELFCLASS64, /* 64-bit Field Alignment */
ELFCLASSMAX, /* Invalid */
} eClass;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define ELFSTRING_MAX 200
typedef struct _libr_section {
uint64_t size;
uint64_t data_offset;
uint32_t name_offset;
char name[ELFSTRING_MAX];
} libr_section;
typedef struct _libr_file {
FILE *handle;
char *filename;
eEncoding endian;
eClass byte_size;
libr_access_t access;
libr_section *secdata;
unsigned long total_sections;
} libr_file;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/* for a clean internal API */
typedef void libr_data;
#define enum_valid(val, name) (val > name##NONE && val < name##MAX)
#endif /* __LIBRRO_H */

@ -0,0 +1,489 @@
/*
*
* Copyright (c) 2008-2009 Erich Hoover
*
* libr - Add resources into ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
/* Include compile-time parameters */
#include "config.h"
#include "libr.h"
#include "tempfiles.h"
/* Obtain file information */
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
/* Compress files */
#include <zlib.h>
#include <math.h> /* for ceil */
/* Handle strings and variable arguments*/
#include <string.h>
#include <stdarg.h>
/* For C99 number types */
#include <stdint.h>
/* Handle status codes for multiple threads */
#include <pthread.h>
#define SPEC_VERSION '1'
#define OFFSET_TYPE ((unsigned long) 4)
#define OFFSET_UNCOMPRESSED ((unsigned long) OFFSET_TYPE+sizeof(unsigned char))
#define OFFSET_UNCOMPRESSED_SIZE ((unsigned long) OFFSET_TYPE+sizeof(unsigned char))
#define OFFSET_COMPRESSED ((unsigned long) OFFSET_UNCOMPRESSED_SIZE+sizeof(uint32_t))
#if 0
extern const char * __progname_full;
#define progpath() (char *) __progname_full
#endif
#define getself() ((char *) "/proc/self/exe")
pthread_key_t error_key;
/*
* Free the error status code/message structure
* (called on thread destruction or when a new code is set)
*/
void free_error_key(void *_m)
{
libr_intstatus *error = (libr_intstatus *) _m;
if(error != NULL)
{
/* Free the error structure */
if(error->message != NULL)
free(error->message);
free(error);
}
}
/*
* Set the error code and message for retrieval
*/
void libr_set_error(libr_intstatus error)
{
static int thread_key_initialized = false;
libr_intstatus *status = NULL;
if(!thread_key_initialized)
{
if(pthread_key_create(&error_key, free_error_key) != 0)
return; /* a serious pthread-related error occurred */
if(pthread_setspecific(error_key, NULL) != 0)
return; /* a serious pthread-related error occurred */
thread_key_initialized = true;
}
free_error_key(pthread_getspecific(error_key));
status = (libr_intstatus *) malloc(sizeof(libr_intstatus));
memcpy(status, &error, sizeof(libr_intstatus));
if(pthread_setspecific(error_key, (void *) status) != 0)
return; /* a serious pthread-related error occurred */
}
/*
* Make an internal status passing structure, set the error code with this status
* if the status is not LIBR_OK.
*/
libr_intstatus make_status(const char *function, libr_status code, char *message, ...)
{
libr_intstatus status = {NULL, code, function};
va_list args;
if(message != NULL)
{
status.message = (char *) malloc(1024);
va_start(args, message);
vsnprintf(status.message, 1024, message, args);
va_end(args);
}
libr_set_error(status);
return status;
}
/*
* Make sure that the section is libr-compatible
*/
libr_intstatus section_ok(libr_section *scn, libr_data *data)
{
char required_header[5], test_header[4] = {'R', 'E', 'S', SPEC_VERSION};
void *ptr = data_pointer(scn, data);
size_t size = data_size(scn, data);
if(ptr == NULL || size < sizeof(required_header))
RETURN(LIBR_ERROR_NOTRESOURCE, "Not a valid libr-resource");
memcpy(required_header, ptr, sizeof(required_header));
if(strncmp(required_header, test_header, sizeof(test_header)) != 0)
RETURN(LIBR_ERROR_NOTRESOURCE, "Not a valid libr-resource");
RETURN_OK;
}
/*
* Remove a resourcefrom the ELF binary handle
*/
EXPORT_FN int libr_clear(libr_file *file_handle, char *resource_name)
{
libr_data *data = NULL;
libr_section *scn = NULL;
/* Ensure valid inputs */
if(file_handle == NULL || resource_name == NULL)
PUBLIC_RETURN(LIBR_ERROR_INVALIDPARAMS, "Invalid parameters passed to function");
if(file_handle->access != LIBR_READ_WRITE)
PUBLIC_RETURN(LIBR_ERROR_NOPERM, "Open handle with LIBR_READ_WRITE access");
/* Find the section containing the icon */
if(find_section(file_handle, resource_name, &scn).status != LIBR_OK)
return false; /* error already set */
/* Get the section data (interested in header) */
if((data = get_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section");
/* Confirm that this resource is libr-compatible */
if(section_ok(scn, data).status != LIBR_OK)
return false; /* error already set */
/* Clear the data resource */
if(set_data(file_handle, scn, data, 0, NULL, 0).status != LIBR_OK)
return false; /* error already set */
/* Remove the section */
if(remove_section(file_handle, scn).status != LIBR_OK)
return false; /* error already set */
return true;
}
/*
* Close the specified ELF binary handle
*/
EXPORT_FN void libr_close(libr_file *file_handle)
{
unregister_handle_cleanup(file_handle);
libr_close_internal(file_handle);
}
/* Only called directly by cleanup routine, all other calls should be through libr_close */
void libr_close_internal(libr_file *file_handle)
{
write_output(file_handle);
free(file_handle);
}
/*
* Return the last error message for the active thread
*/
EXPORT_FN char *libr_errmsg(void)
{
libr_intstatus *error = (libr_intstatus *) pthread_getspecific(error_key);
if(error == NULL)
return NULL;
return error->message;
}
/*
* Return the last error code for the active thread (or LIBR_OK for no error)
*/
EXPORT_FN libr_status libr_errno(void)
{
libr_intstatus *error = (libr_intstatus *) pthread_getspecific(error_key);
if(error == NULL) /* Nothing has happened yet */
return LIBR_OK;
return error->status;
}
/*
* Return the name of a libr-compatible resource
*/
EXPORT_FN char *libr_list(libr_file *file_handle, unsigned int resourceid)
{
libr_section *scn = NULL;
libr_data *data = NULL;
int i = 0;
while((scn = next_section(file_handle, scn)) != NULL)
{
/* Get the section data (interested in header) */
if((data = get_data(file_handle, scn)) == NULL)
return NULL;
if(section_ok(scn, data).status == LIBR_OK)
{
if(i == resourceid)
return strdup(section_name(file_handle, scn));
i++;
}
}
return NULL;
}
/*
* Allocate a buffer containing the data of a resource
*/
EXPORT_FN char *libr_malloc(libr_file *file_handle, char *resource_name, size_t *size)
{
char *buffer = NULL;
size_t size_local;
if(size == NULL)
size = &size_local;
if(!libr_size(file_handle, resource_name, size))
return NULL; /* error already set */
buffer = (char *) malloc(*size);
if(!libr_read(file_handle, resource_name, buffer))
{
free(buffer);
return NULL; /* error already set */
}
return buffer;
}
/*
* Open the specified ELF binary (caller if filename is NULL)
*/
EXPORT_FN libr_file *libr_open(char *filename, libr_access_t access)
{
libr_file *file_handle = NULL;
static int initialized = false;
if(!initialized)
{
if(strncmp(zlibVersion(), ZLIB_VERSION, 1) != 0)
{
SET_ERROR(LIBR_ERROR_ZLIBINIT, "zlib library initialization failed");
return NULL;
}
initialize_backend();
initialized = true;
}
if(filename == NULL)
filename = getself();
file_handle = (libr_file *) malloc(sizeof(libr_file));
memset(file_handle, 0, sizeof(libr_file));
if(open_handles(file_handle, filename, access).status != LIBR_OK)
{
/* failed to open file for processing, error already set */
free(file_handle);
file_handle = NULL;
}
/* Cleanup handles automatically when libr exits memory */
if(file_handle != NULL)
register_handle_cleanup(file_handle);
return file_handle;
}
/*
* Read a resource from the specified ELF binary handle
*/
EXPORT_FN int libr_read(libr_file *file_handle, char *resource_name, char *buffer)
{
unsigned long uncompressed_size = 0, compressed_size = 0;
char *data_buffer = NULL;
libr_section *scn = NULL;
libr_data *data = NULL;
libr_type_t type;
/* Find the section containing the icon */
if(find_section(file_handle, resource_name, &scn).status != LIBR_OK)
return false; /* error already set */
/* Get the section data (interested in header) */
if((data = get_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section");
/* Confirm that this resource is libr-compatible */
if(section_ok(scn, data).status != LIBR_OK)
return false; /* error already set */
data_buffer = (char *) data_pointer(scn, data);
/* Get the size of the data resource */
type = (libr_type_t) data_buffer[OFFSET_TYPE];
switch(type)
{
case LIBR_UNCOMPRESSED:
{ if(data_size(scn, data)-OFFSET_UNCOMPRESSED < 0)
PUBLIC_RETURN(LIBR_ERROR_SIZEMISMATCH, "Section's data size does not make sense");
uncompressed_size = data_size(scn, data)-OFFSET_UNCOMPRESSED;
memcpy(buffer, &data_buffer[OFFSET_UNCOMPRESSED], uncompressed_size);
} break;
case LIBR_COMPRESSED:
{
uint32_t size_temp;
memcpy(&size_temp, &data_buffer[OFFSET_UNCOMPRESSED_SIZE], sizeof(uint32_t));
uncompressed_size = size_temp;
compressed_size = data_size(scn, data)-OFFSET_COMPRESSED;
if(uncompress((unsigned char *)buffer, &uncompressed_size, (unsigned char *)&data_buffer[OFFSET_COMPRESSED], compressed_size) != Z_OK)
PUBLIC_RETURN(LIBR_ERROR_UNCOMPRESS, "Failed to uncompress resource data");
} break;
default:
PUBLIC_RETURN(LIBR_ERROR_INVALIDTYPE, "Invalid data storage type specified");
}
return true;
}
/*
* Retrieve the number of libr-compatible resources
*/
EXPORT_FN unsigned int libr_resources(libr_file *file_handle)
{
libr_section *scn = NULL;
libr_data *data = NULL;
int i = 0;
while((scn = next_section(file_handle, scn)) != NULL)
{
if((data = get_data(file_handle, scn)) == NULL)
continue;
if(section_ok(scn, data).status == LIBR_OK)
i++;
}
return i;
}
/*
* Get the size of a resource from the specified ELF binary handle
*/
EXPORT_FN int libr_size(libr_file *file_handle, char *resource_name, size_t *retsize)
{
char *data_buffer = NULL;
libr_section *scn = NULL;
libr_data *data = NULL;
unsigned long size = 0;
libr_type_t type;
/* Find the section containing the icon */
if(find_section(file_handle, resource_name, &scn).status != LIBR_OK)
return false; /* error already set */
/* Get the section data (interested in header) */
if((data = get_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section");
/* Confirm that this resource is libr-compatible */
if(section_ok(scn, data).status != LIBR_OK)
return false; /* error already set */
data_buffer = (char *) data_pointer(scn, data);
/* Get the size of the data resource */
type = (libr_type_t) data_buffer[OFFSET_TYPE];
switch(type)
{
case LIBR_UNCOMPRESSED:
{
size_t full_size = data_size(scn, data);
if(full_size-OFFSET_UNCOMPRESSED < 0)
PUBLIC_RETURN(LIBR_ERROR_SIZEMISMATCH, "Section's data size does not make sense");
size = full_size - OFFSET_UNCOMPRESSED;
} break;
case LIBR_COMPRESSED:
{
memcpy(&size, &data_buffer[OFFSET_UNCOMPRESSED_SIZE], sizeof(uint32_t));
} break;
default:
PUBLIC_RETURN(LIBR_ERROR_INVALIDTYPE, "Invalid data storage type specified");
}
*retsize = size;
return true;
}
/*
* Write a resource to the specified ELF binary handle
*/
EXPORT_FN int libr_write(libr_file *file_handle, char *resource_name, char *buffer, size_t size, libr_type_t type, libr_overwrite_t overwrite)
{
char header[9] = {'R', 'E', 'S', SPEC_VERSION};
unsigned int header_size = 4;
libr_section *scn = NULL;
libr_data *data = NULL;
libr_intstatus ret;
/* Ensure valid inputs */
if(file_handle == NULL || resource_name == NULL || buffer == NULL)
PUBLIC_RETURN(LIBR_ERROR_INVALIDPARAMS, "Invalid parameters passed to function");
if(file_handle->access != LIBR_READ_WRITE)
PUBLIC_RETURN(LIBR_ERROR_NOPERM, "Open handle with LIBR_READ_WRITE access");
/* Get the section if it already exists */
ret = find_section(file_handle, resource_name, &scn);
if(ret.status == LIBR_OK)
{
/* If the section exists (and overwrite is not specified) then fail */
if(!overwrite)
PUBLIC_RETURN(LIBR_ERROR_OVERWRITE, "Section already exists, over-write not specified");
/* Grab the existing data section for overwriting */
if((data = get_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_GETDATA, "Failed to obtain data of section");
}
else if(ret.status == LIBR_ERROR_NOSECTION)
{
/* Create a new section named "resource_name" */
if(add_section(file_handle, resource_name, &scn).status != LIBR_OK)
return false; /* error already set */
/* Create a data segment to store the compressed image */
if((data = new_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_NEWDATA, "Failed to create data for section");
}
else
return false; /* error already set */
header[header_size++] = (char) type;
switch(type)
{
case LIBR_UNCOMPRESSED:
/* Do nothing, just stick the data in */
break;
case LIBR_COMPRESSED:
{
char *compressed_buffer = NULL, *uncompressed_buffer = buffer;
unsigned long compressed_size = 0, uncompressed_size = size;
uint32_t size_temp;
/* Store the uncompressed size to the header */
size_temp = uncompressed_size;
memcpy(&header[header_size], &size_temp, sizeof(uint32_t));
header_size += sizeof(uint32_t);
/* Compress the data for storage */
compressed_size = ceil((uncompressed_size+12)*1.1);
compressed_buffer = (char *) malloc(compressed_size);
if(compress((unsigned char *)compressed_buffer, &compressed_size, (unsigned char *)uncompressed_buffer, uncompressed_size) != Z_OK)
{
free(compressed_buffer);
PUBLIC_RETURN(LIBR_ERROR_COMPRESS, "Failed to compress resource data");
}
/* From here on treat the compressed buffer as the data */
buffer = compressed_buffer;
size = compressed_size;
} break;
default:
PUBLIC_RETURN(LIBR_ERROR_INVALIDTYPE, "Invalid data storage type specified");
}
/* Store the resource header data */
if(set_data(file_handle, scn, data, 0, &header[0], header_size).status != LIBR_OK)
return false; /* error already set */
/* Create a data segment to store the post-header data
* NOTE: For existing files the data of the section is represented as a continuous stream
* (so calling elf_getdata now WILL NOT return the post-header data)
*/
if((data = new_data(file_handle, scn)) == NULL)
PUBLIC_RETURN(LIBR_ERROR_NEWDATA, "Failed to create data for section");
/* Store the actual user data to the section */
if(set_data(file_handle, scn, data, header_size, buffer, size).status != LIBR_OK)
return false; /* error already set */
/* Close compression resources */
if(type == LIBR_COMPRESSED)
free(buffer);
return true;
}

@ -0,0 +1,416 @@
/*
*
* Copyright (c) 2008-2011 Erich Hoover
*
* libr - Add resources into ELF binaries
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
#ifndef __LIBR_H
#define __LIBR_H
#include <sys/types.h>
#define DEPRECATED_FN __attribute__ ((deprecated))
#define ALIAS_FN(fn) __attribute__ ((weak, alias (#fn)))
/**
* @addtogroup libr_status libr_status
* @brief Enumeration of possible libr status values.
* @{
* \#include <libr.h>
*/
/** Possible libr status values */
typedef enum {
LIBR_OK = 0, /**< Success */
LIBR_ERROR_GETEHDR = -1, /**< Failed to obtain ELF header: */
LIBR_ERROR_NOTABLE = -2, /**< No ELF string table */
LIBR_ERROR_TABLE = -3, /**< Failed to open string table: */
LIBR_ERROR_GETDATA = -4, /**< Failed to obtain data of section */
LIBR_ERROR_GETSHDR = -5, /**< Failed to obtain ELF section header: */
LIBR_ERROR_SIZEMISMATCH = -6, /**< Section's data size does not make sense */
LIBR_ERROR_UPDATE = -7, /**< Failed to perform dynamic update: */
LIBR_ERROR_NEWSECTION = -8, /**< Failed to create new section */
LIBR_ERROR_NEWDATA = -9, /**< Failed to create data for section */
LIBR_ERROR_REMOVESECTION = -10, /**< Failed to remove section: */
LIBR_ERROR_NOSECTION = -11, /**< ELF resource section not found */
LIBR_ERROR_STRPTR = -12, /**< Failed to obtain section string pointer: */
LIBR_ERROR_NOTRESOURCE = -13, /**< Not a valid libr-resource */
LIBR_ERROR_EXPANDSECTION = -14, /**< Failed to expand section */
LIBR_ERROR_WRONGFORMAT = -15, /**< Invalid input file format */
LIBR_ERROR_SETFLAGS = -16, /**< Failed to set flags for section */
LIBR_ERROR_NOPERM = -17, /**< Open handle with LIBR_READ_WRITE access */
LIBR_ERROR_NOSIZE = -18, /**< Failed to obtain file size */
LIBR_ERROR_SETFORMAT = -19, /**< Failed to set output file format to input file format */
LIBR_ERROR_SETARCH = -20, /**< Failed to set output file architecture to input file architecture */
LIBR_ERROR_OVERWRITE = -21, /**< Section already exists, over-write not specified */
LIBR_ERROR_COMPRESS = -22, /**< Failed to compress resource data */
LIBR_ERROR_INVALIDTYPE = -23, /**< Invalid data storage type specified */
LIBR_ERROR_MEMALLOC = -24, /**< Failed to allocate memory for data */
LIBR_ERROR_INVALIDPARAMS = -25, /**< Invalid parameters passed to function */
LIBR_ERROR_UNCOMPRESS = -26, /**< Failed to uncompress resource data */
LIBR_ERROR_ZLIBINIT = -27, /**< zlib library initialization failed */
LIBR_ERROR_OPENFAILED = -28, /**< Failed to open input file */
LIBR_ERROR_BEGINFAILED = -29, /**< Failed to open ELF file: */
LIBR_ERROR_WRITEPERM = -30, /**< No write permission for file */
LIBR_ERROR_UNSUPPORTED = -31, /**< The requested operation is not supported by the backend */
} libr_status;
/**
* @}
*/
typedef enum {
LIBR_READ = 0,
LIBR_READ_WRITE = 1,
} libr_access_t;
typedef enum {
LIBR_UNCOMPRESSED = 0,
LIBR_COMPRESSED = 1
} libr_type_t;
typedef enum {
LIBR_NOOVERWRITE = 0,
LIBR_OVERWRITE = 1
} libr_overwrite_t;
#ifdef __LIBR_BUILD__
#include "libr-internal.h"
#if __LIBR_BACKEND_libbfd__
#include "libr-bfd.h"
#elif __LIBR_BACKEND_libelf__
#include "libr-elf.h"
#elif __LIBR_BACKEND_readonly__
#include "libr-ro.h"
#else /* LIBR_BACKEND */
#error "Unhandled backend"
#endif /* LIBR_BACKEND */
#include "libr-backends.h"
#else
struct _libr_file;
typedef struct _libr_file libr_file;
#endif /* __LIBR_BUILD__ */
/*************************************************************************
* libr Resource Management API
*************************************************************************/
/**
* @page libr_clear Remove a resource from an ELF executable.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_clear(libr_file *handle, char *resourcename);</b>
*
* @section DESCRIPTION
* Removes a libr-compatible resource from an ELF executable. The handle
* must be opened using <b>libr_open</b>(3) with either <b>LIBR_WRITE</b>
* or <b>LIBR_READ_WRITE</b> access in order to remove a resource.
*
* Please note that resource removal does not occur until the handle is
* closed using <b>libr_close</b>(3).
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param resourcename The name of the libr-compatible resource to remove.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_close</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_clear(libr_file *handle, char *resourcename);
/**
* @page libr_close Close a handle to an ELF executable.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>void libr_close(libr_file *handle);</b>
*
* @section DESCRIPTION
* Handles opened with <b>libr_open</b>(3) should be closed with
* <b>libr_close</b>() when they are no-longer needed by the calling
* application.
*
* @param handle The handle to close.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
void libr_close(libr_file *handle);
/**
* @page libr_errmsg Return a detailed description of the last
* libr-related error.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>char *libr_errmsg(void);</b>
*
* @section DESCRIPTION
* Returns a detailed string describing the last error encountered by
* the libr resource library. The string is an internal error
* description, so it should not be freed.
*
* If no errors have been encountered then NULL is returned.
*
* @section SA SEE ALSO
* <b>libr_errno</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
char *libr_errmsg(void);
/**
* @page libr_errno Return a status code describing the last
* libr-related error.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>libr_status libr_errno(void);</b>
*
* @section DESCRIPTION
* Returns a code corresponding to the last error encountered by
* the libr resource library. For a detailed description of possible
* return values see <b>libr_status</b>(3).
*
* To get a user-readable string corresponding to the last error the
* <b>libr_errmsg</b>(3) function should be used instead.
*
* If no errors have been encountered then <b>LIBR_OK</b> is returned.
*
* @section SA SEE ALSO
* <b>libr_errmsg</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
libr_status libr_errno(void);
/**
* @page libr_list Obtain the name of a libr ELF resource (by index).
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>char *libr_list(libr_file *file_handle, unsigned int resourceid);</b>
*
* @section DESCRIPTION
* Returns the name of a libr-compatible resource stored in an ELF binary
* corresponding to the given resource index. The index value ranges from
* 0 to the value returned by <b>libr_resources</b>(3), which returns the
* total number of libr-compatible resources stored in the ELF binary.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param resourceid The index of the libr-compatible resource for which
* the name will be returned.
*
* @return Returns a string containing the name of the resource section. This
* string is allocated when the function is called, so it <i>must be
* unallocated</i> with a call to <b>free</b>(3) when it is no-longer
* needed. NULL is returned on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>free</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
char *libr_list(libr_file *file_handle, unsigned int resourceid);
/**
* @page libr_malloc Obtain the data corresponding to a libr ELF resource.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>char *libr_malloc(libr_file *handle, char *resourcename, size_t *size);</b>
*
* @section DESCRIPTION
* Returns the contents of a libr-compatible resource stored in an ELF binary
* corresponding to the given resource name.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param resourcename The name of the libr-compatible resource for which
* the data will be returned.
* @param size A pointer for storing the length of the data contained in the
* the resource. May be NULL.
*
* @return Returns NULL on failure, the pointer to a buffer containing the data
* for the resource on success. When the buffer is no-longer used it must
* be unallocated using a call to <b>free</b>(3).
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>free</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
char *libr_malloc(libr_file *handle, char *resourcename, size_t *size);
/**
* @page libr_open Open an ELF executable file for resource management.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>libr_file *libr_open(char *filename, libr_access_t access);</b>
*
* @section DESCRIPTION
* <b>libr_open</b>() can be used on any ELF executable, however,
* <b>libr_open</b>() called with <b>LIBR_READ</b> access is only useful
* for executables that already contain libr-compatible stored resources.
*
* An application can easily access its own resources by passing NULL for
* the filename and requesting <b>LIBR_READ</b> access. For the obvious
* reason that an actively-open application cannot edit itself, the
* calling binary may only request <b>LIBR_READ</b> access.
*
* @param filename ELF executable to manage. Pass a NULL pointer as the
* filename in order to access the calling binary (<b>LIBR_READ</b>
* access only) @param access Requested access type (<b>LIBR_READ</b>,
* <b>LIBR_WRITE</b>, <b>LIBR_READ_WRITE</b>), the valid operations for
* the returned handle will be restricted based upon the requested access.
* @return Returns a libr file handle on success, NULL on failure. The
* handle should be freed with <b>libr_close</b>(3) when no-longer used.
*
* @section SA SEE ALSO
* <b>libr_close</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
libr_file *libr_open(char *filename, libr_access_t access);
/**
* @page libr_read Read out the contents of a libr ELF resource.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_read(libr_file *handle, char *resourcename, char *buffer);</b>
*
* @section WARNING
* This function does not allocate memory for the buffer, so the buffer must
* be large enough to fit the resource data. For this reason it is suggested
* that <b>libr_malloc</b>(3) be used in preference over this function.
*
* @section DESCRIPTION
* Reads the contents of a resource embedded in an ELF binary, the resource
* must be compatible with the libr specification.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_read(libr_file *handle, char *resourcename, char *buffer);
/**
* @page libr_resources Returns the number of resources contained in
* the ELF binary.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>unsigned int libr_resources(libr_file *handle);</b>
*
* @section DESCRIPTION
* Returns the total number of libr-compatible resources contained
* in the ELF binary. Intended to be used with <b>libr_list</b>(3)
* to return the full list of resources contained in the binary.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @return The total number of libr resources in the binary.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_list</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
unsigned int libr_resources(libr_file *handle);
/**
* @page libr_size Returns the uncompressed size of a libr resource.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_size(libr_file *handle, char *resourcename, size_t *size);</b>
*
* @section DESCRIPTION
* Obtain the total number of bytes consumed by the uncompressed
* version of the specific libr-resource. Intended to be used with
* <b>libr_read</b>(3) in order to allocate a large enough buffer
* for the resource.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param resourcename The name of the resource for which the
* size of the data section will be returned.
* @param size A pointer for storing the size of the data section.
* This pointer cannot be NULL.
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3), <b>libr_read</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_size(libr_file *handle, char *resourcename, size_t *size);
/**
* @page libr_write Adds a libr resource to an ELF binary.
* @section SYNOPSIS
* \#include <libr.h>
*
* <b>int libr_write(libr_file *handle, char *resourcename, char *buffer, size_t size, libr_type_t type, libr_overwrite_t overwrite);</b>
*
* @section DESCRIPTION
* Adds a libr-compatible resource into the ELF binary. The handle
* must be opened using <b>libr_open</b>(3) with either <b>LIBR_WRITE</b>
* or <b>LIBR_READ_WRITE</b> access in order to add a resource.
*
* @param handle A handle returned by <b>libr_open</b>(3).
* @param resourcename The name of the resource to create.
* @param buffer A string containing the data of the resource.
* @param size The total size of the buffer.
* @param type The method which should be used for storing the
* data (either <b>LIBR_UNCOMPRESSED</b> or
* <b>LIBR_COMPRESSED</b>).
* @param overwrite Whether overwriting an existing resource
* should be permitted (either <b>LIBR_NOOVERWRITE</b> or
* <b>LIBR_OVERWRITE</b>).
* @return Returns 1 on success, 0 on failure.
*
* @section SA SEE ALSO
* <b>libr_open</b>(3)
*
* @section AUTHOR
* Erich Hoover <ehoover@mines.edu>
*/
int libr_write(libr_file *handle, char *resourcename, char *buffer, size_t size, libr_type_t type, libr_overwrite_t overwrite);
#endif /* __LIBR_H */

@ -0,0 +1,446 @@
/*
*
* Copyright (c) 2010 Erich Hoover
*
* libr "one canvas" - Handle multiple icons stored in a single "one canvas"
* SVG document.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
typedef struct {
double x;
double y;
double width;
double height;
int icon_width;
int icon_height;
} IconSVG;
typedef enum {
STATUS_FINDSVG,
STATUS_FINDMETADATA,
STATUS_FINDPUBLISHER_START,
STATUS_FINDPUBLISHER_STOP,
STATUS_FINDHIDDEN,
STATUS_FINDBOUNDS,
STATUS_FAILED,
STATUS_DONE,
} eStatus;
typedef struct {
IconSVG **iconlist;
int iconlist_num;
eStatus status;
char *hidden_stop;
char *hidden_start;
char *publisher_stop;
char *publisher_start;
char *coordinate_stop;
char *coordinate_start;
} OneCanvasIconInfo;
/*
* Find the start of the next XML tag (search for '<')
*/
static inline char *xml_nextTag(char *c)
{
c++;
if(c == NULL)
return NULL;
return strchr(c, '<');
}
/*
* Pull out the name/type of a tag.
*/
static inline char *xml_getTagName(char *c)
{
char *tag_end = NULL, *tag_space, *tag_close, *tag_feed, *tag_line;
static char tagname[20];
int tag_len;
if(++c == NULL)
return NULL;
tag_space = strchr(c, ' ');
tag_close = strchr(c, '>');
tag_feed = strchr(c, '\r');
tag_line = strchr(c, '\n');
if(tag_space)
tag_end = tag_space;
if(tag_close && tag_end > tag_close)
tag_end = tag_close;
if(tag_feed && tag_end > tag_feed)
tag_end = tag_feed;
if(tag_line && tag_end > tag_line)
tag_end = tag_line;
if(!tag_end)
return NULL;
tag_len = tag_end - c;
tag_len = tag_len > 19 ? 19 : tag_len;
strncpy(tagname, c, tag_len);
tagname[tag_len] = '\0';
return tagname;
}
/*
* Find the position in the string corresponding to a particular named attribute.
*/
static inline char *xml_getTagAttributePtr(char *c, char *attrname)
{
char *end, *name;
int found;
if(++c == NULL)
return NULL;
end = strchr(c, '>');
while(c < end)
{
int name_len;
char *equal;
equal = c = strchr(c, '=');
if(c == NULL)
break;
c++;
name = equal;
while(name[0] != ' ' && name[0] != '\t' && name[0] != '\n')
name--;
name++; /* don't include the space */
name_len = equal-name;
if(name_len != strlen(attrname))
continue;
if(strncasecmp(attrname, name, name_len) == 0)
{
found = TRUE;
break;
}
}
if(!found)
return NULL;
return c-strlen(attrname)-1;
}
/*
* Return the value of an XML tag's named attribute.
*/
static inline char *xml_getTagAttribute(char *c, char *attrname)
{
char *data_end;
int data_len;
char *attr;
c = xml_getTagAttributePtr(c, attrname);
if(c == NULL)
return NULL;
c+=strlen(attrname); /* skip the name */
c+=2; /* skip the equals sign and the quote */
data_end = strchr(c, '"');
data_len = data_end - c;
attr = (char *) malloc(data_len+1);
strncpy(attr, c, data_len);
attr[data_len] = '\0';
return attr;
}
/*
* Find the value of an XML tag attribute and convert it to a number.
*/
static inline double xml_getTagAttributeFloat(char *c, char *attrname)
{
char *value = xml_getTagAttribute(c, attrname);
double ret;
if(!value)
return nan("nan");
sscanf(value, "%lf", &ret);
free(value);
return ret;
}
/*
* Match the beginning an XML tag by "id" (preferred) or Inkscape's
* label (undesireable but acceptable).
*/
static inline char *xml_idMatchStart(char *stream_pos, char *layer_name)
{
char *id_acceptable = xml_getTagAttribute(stream_pos, "inkscape:label");
char *id_preferred = xml_getTagAttribute(stream_pos, "id");
if(id_preferred && strncasecmp(id_preferred, layer_name, strlen(layer_name)) == 0)
{
free(id_acceptable);
return id_preferred;
}
if(id_acceptable && strncasecmp(id_acceptable, layer_name, strlen(layer_name)) == 0)
{
free(id_preferred);
return id_acceptable;
}
free(id_acceptable);
free(id_preferred);
return NULL;
}
/*
* Match the entirety of an XML tag by "id" (preferred) or Inkscape's
* label (undesireable but acceptable).
*/
static inline int xml_idMatch(char *stream_pos, char *layer_name)
{
char *id_acceptable = xml_getTagAttribute(stream_pos, "inkscape:label");
char *id_preferred = xml_getTagAttribute(stream_pos, "id");
int ret = FALSE;
if((id_preferred && strcasecmp(id_preferred, layer_name) == 0)
|| (id_acceptable && strcasecmp(id_acceptable, layer_name) == 0))
ret = TRUE;
free(id_acceptable);
free(id_preferred);
return ret;
}
/*
* Strip all the XML tags from a string and return only the data not
* contained within any tags.
*/
static inline char *xml_stripTags(char *data, int len)
{
char *ret = (char *) malloc(len+1);
char *tag_left, *tag_right;
memcpy(ret, data, len+1);
ret[len] = '\0';
while((tag_left = strchr(ret, '<')) != NULL)
{
tag_right = strchr(ret, '>');
memmove(tag_left, tag_right+1, strlen(ret)-(tag_right-ret));
}
return ret;
}
/*
* Return the information for all of the icons within a "one-canvas"
* data stream.
*/
OneCanvasIconInfo onecanvas_geticons(char *stream)
{
eStatus status = STATUS_FINDSVG;
unsigned int stream_size = 0;
OneCanvasIconInfo info;
char *publisher = NULL;
char *stream_pos;
int i;
memset(&info, 0, sizeof(info));
stream_pos = stream;
while(stream_pos)
{
char *name = xml_getTagName(stream_pos);
if(!name)
{
stream_pos = xml_nextTag(stream_pos);
continue;
}
switch(status)
{
case STATUS_FINDSVG:
{
if(strcasecmp(name, "svg") == 0)
{
info.coordinate_start = xml_getTagAttributePtr(stream_pos, "x");
info.coordinate_stop = xml_getTagAttributePtr(stream_pos, "viewBox");
if(info.coordinate_start == NULL || info.coordinate_stop == NULL)
{
status = STATUS_FAILED;
break;
}
info.coordinate_stop = strchr(info.coordinate_stop, '"')+1;
info.coordinate_stop = strchr(info.coordinate_stop, '"')+1;
status = STATUS_FINDMETADATA;
}
} break;
case STATUS_FINDMETADATA:
{
if(strcasecmp(name, "metadata") == 0)
{
status = STATUS_FINDPUBLISHER_START;
}
else if(strcasecmp(name, "/svg") == 0)
{
status = STATUS_FAILED;
}
} break;
case STATUS_FINDPUBLISHER_START:
{
if(strcasecmp(name, "dc:publisher") == 0)
{
status = STATUS_FINDPUBLISHER_STOP;
info.publisher_start = stream_pos + strlen("<dc:publisher>");
}
else if(strcasecmp(name, "/metadata") == 0)
{
status = STATUS_FAILED;
}
} break;
case STATUS_FINDPUBLISHER_STOP:
{
if(strcasecmp(name, "/dc:publisher") == 0)
{
info.publisher_stop = stream_pos;
publisher = xml_stripTags(info.publisher_start, info.publisher_stop-info.publisher_start);
if(strcasecmp(publisher, "one-canvas") == 0)
status = STATUS_FINDHIDDEN;
else
status = STATUS_FAILED;
}
else if(strcasecmp(name, "/metadata") == 0)
{
status = STATUS_FAILED;
}
} break;
case STATUS_FINDHIDDEN:
{
if(strcasecmp(name, "g") == 0)
{
if(xml_idMatch(stream_pos, "hidden"))
{
char *style_start;
info.hidden_start = stream_pos;
info.hidden_stop = info.hidden_start;
style_start = xml_getTagAttributePtr(stream_pos, "style");
if(style_start)
{
info.hidden_start = style_start;
info.hidden_stop = strchr(style_start, '"')+1;
info.hidden_stop = strchr(info.hidden_stop, '"')+1;
}
else
{
info.hidden_start += strlen("<g ");
info.hidden_stop += strlen("<g ");
}
status = STATUS_FINDBOUNDS;
}
}
} break;
case STATUS_FINDBOUNDS:
{
if(strcasecmp(name, "rect") == 0)
{
char *layer_name = xml_idMatchStart(stream_pos, "iconlayer-");
if(layer_name != NULL)
{
IconSVG *icon = (IconSVG *) malloc(sizeof(IconSVG));
icon->x = xml_getTagAttributeFloat(stream_pos, "x");
icon->y = xml_getTagAttributeFloat(stream_pos, "y");
icon->width = xml_getTagAttributeFloat(stream_pos, "width");
icon->height = xml_getTagAttributeFloat(stream_pos, "height");
sscanf(layer_name, "iconlayer-%dx%d", &(icon->icon_width), &(icon->icon_height));
free(layer_name);
status = STATUS_FINDBOUNDS;
info.iconlist = (IconSVG **) realloc(info.iconlist, (info.iconlist_num+1)*sizeof(IconSVG *));
info.iconlist[info.iconlist_num] = icon;
info.iconlist_num++;
}
}
else if(strcasecmp(name, "/g") == 0)
{
status = STATUS_DONE;
}
} break;
default:
break;
}
if(status == STATUS_DONE || status == STATUS_FAILED)
break;
stream_pos = xml_nextTag(stream_pos);
}
free(publisher);
info.status = status;
return info;
}
/*
* Obtain a single icon from the "one-canvas" stream corresponding
* to a particular icon size.
*/
char *onecanvas_geticon_bysize(char *icon_data, int requested_size)
{
OneCanvasIconInfo info = onecanvas_geticons(icon_data);
char *ret = NULL;
int i;
if(info.status == STATUS_DONE && info.iconlist_num > 0)
{
int closest_diff = abs(info.iconlist[0]->icon_width - requested_size);
int tocoord_length, topubl_length, tohidden_length;
int icon_id = 0;
IconSVG *icon;
int ret_max;
for(i=0;i<info.iconlist_num;i++)
{
int size_diff = abs(info.iconlist[i]->icon_width - requested_size);
if(size_diff < closest_diff)
{
closest_diff = size_diff;
icon_id = i;
}
}
icon = info.iconlist[icon_id];
/* Note: 200 characters is a very generous over estimate for the data we add in */
ret_max = strlen(icon_data)+1+200;
ret = (char *) malloc(ret_max);
tocoord_length = info.coordinate_start-icon_data;
snprintf(ret, ret_max, "%.*s", tocoord_length, icon_data);
/* Output the coordinates of the icon */
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "\nx=\"0px\"\ny=\"0px\"\n");
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "width=\"%d\"\n", icon->icon_width);
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "height=\"%d\"\n", icon->icon_height);
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "viewBox=\"%lf %lf %lf %lf\"\n", icon->x, icon->y, icon->width, icon->height);
topubl_length = info.publisher_start-info.coordinate_stop;
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "%.*s", topubl_length, info.coordinate_stop);
/* Hide the "hidden" layer */
tohidden_length = info.hidden_start-info.publisher_stop;
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "%.*s", tohidden_length, info.publisher_stop);
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "\ndisplay=\"none\"\n");
/* Output the rest of the document */
snprintf(&ret[strlen(ret)], ret_max-strlen(ret), "%s", info.hidden_stop);
}
for(i=0;i<info.iconlist_num;i++)
free(info.iconlist[i]);
free(info.iconlist);
return ret;
}

@ -0,0 +1,6 @@
#ifndef __ONECANVAS_H
#define __ONECANVAS_H
char *onecanvas_geticon_bysize(char *icon_data, int requested_size);
#endif /* __ONECANVAS_H */

@ -0,0 +1,317 @@
/*
*
* Copyright (c) 2009 Erich Hoover
*
* libr temp files - Handle temporary files and handles that require cleanup
* when libr closes.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* To provide feedback, report bugs, or otherwise contact me:
* ehoover at mines dot edu
*
*/
#include "tempfiles.h"
/* For malloc/free and mkdtemp */
#include <stdlib.h>
/* For string handling */
#include <string.h>
#include <stdio.h>
/* For directory cleanup */
#include <unistd.h>
#include <dirent.h>
/* For directory creation */
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* Hold on to folder names for cleanup when libr is removed from memory */
typedef struct CLEANUPFOLDER {
char *folder;
struct CLEANUPFOLDER *next;
} CleanupFolder;
CleanupFolder *folders_to_remove = NULL;
/* Hold on to libr handles for cleanup when libr is removed from memory */
typedef struct CLEANUPHANDLE {
int internal; /* do not warn the user about cleaning this handle up */
libr_file *handle;
struct CLEANUPHANDLE *next;
} CleanupHandle;
CleanupHandle *handles_to_remove = NULL;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/*
* Register a folder for cleanup when libr is removed from memory
*/
void register_folder_cleanup(char *temp_folder)
{
CleanupFolder *folder = malloc(sizeof(CleanupFolder));
folder->folder = strdup(temp_folder);
folder->next = NULL;
if(folders_to_remove != NULL)
{
CleanupFolder *f;
for(f = folders_to_remove; f->next != NULL; f = f->next) {}
f->next = folder;
}
else
folders_to_remove = folder;
}
/*
* Register a libr handle for cleanup when libr is removed from memory
*/
void register_handle_cleanup(libr_file *handle)
{
CleanupHandle *h = malloc(sizeof(CleanupHandle));
h->handle = handle;
h->internal = FALSE;
h->next = NULL;
if(handles_to_remove != NULL)
{
CleanupHandle *i;
for(i = handles_to_remove; i->next != NULL; i = i->next) {}
i->next = h;
}
else
handles_to_remove = h;
}
/*
* Remove a libr handle from the cleanup list
*/
void unregister_handle_cleanup(libr_file *handle)
{
CleanupHandle *i, *last = NULL;
int found = FALSE;
if(handles_to_remove == NULL)
{
printf("Unregistering handle with no list of cleanup handles!\n");
return;
}
for(i = handles_to_remove; i != NULL; last = i, i = i->next)
{
if(i->handle == handle)
{
if(last == NULL)
handles_to_remove = i->next;
else
last->next = i->next;
free(i);
found = TRUE;
break;
}
}
if(!found)
printf("Could not find handle to remove from cleanup list!\n");
}
/*
* Flag a handle as internal (do not warn about unsafe cleanup)
*/
void register_internal_handle(libr_file *handle)
{
int found = FALSE;
CleanupHandle *i;
if(handles_to_remove == NULL)
{
printf("No cleanup list!\n");
return;
}
for(i = handles_to_remove; i != NULL; i = i->next)
{
if(i->handle == handle)
{
i->internal = TRUE;
found = TRUE;
break;
}
}
if(!found)
printf("Could not find handle in cleanup list!\n");
}
/*
* Cleanup a temporary folder used to hack the inability to load resources from a buffer
*/
void cleanup_folder(char *temp_folder)
{
char *filepath = (char *) malloc(PATH_MAX);
DIR *dir = opendir(temp_folder);
struct dirent *file;
while((file = readdir(dir)) != NULL)
{
char *filename = file->d_name;
/* Do not delete "self" or "parent" directory entries */
if(!strcmp(filename, ".") || !strcmp(filename, ".."))
continue;
/* But delete anything else */
strcpy(filepath, temp_folder);
strcat(filepath, "/");
strcat(filepath, filename);
if(file->d_type == DT_DIR)
cleanup_folder(filepath);
else
{
if(unlink(filepath))
printf("libr failed to cleanup '%s' in temporary folder: %m\n", filename);
}
}
free(filepath);
closedir(dir);
if(rmdir(temp_folder) != 0)
printf("libr failed to remove temporary folder: %m\n");
}
/*
* Perform cleanup when libr is removed from memory
*/
void do_cleanup(void) __attribute__((destructor));
void do_cleanup(void)
{
CleanupFolder *f, *fnext;
CleanupHandle *h, *hnext;
/* Cleanup folders */
for(f = folders_to_remove; f != NULL; f = fnext)
{
folders_to_remove = NULL;
fnext = f->next;
cleanup_folder(f->folder);
free(f->folder);
free(f);
}
/* Cleanup handles */
for(h = handles_to_remove; h != NULL; h = hnext)
{
handles_to_remove = NULL;
hnext = h->next;
/* Unless the handle was created internally then warn the developer to cleanup their act */
if(!h->internal)
printf("Warning: Application did not cleanup resource handle: %p\n", h->handle);
libr_close_internal(h->handle);
free(h);
}
}
/*
* Build all the directories required by a resource
* (and construct the output string)
*/
int make_valid_path(char *out_path, size_t maxpath, char *start_folder, char *resource_name)
{
char *a, *c = resource_name;
strcpy(out_path, start_folder);
while((a=strchr(c, '/')) != NULL)
{
strcat(out_path, "/");
strncat(out_path, c, (size_t) (a-c));
if(mkdir(out_path, S_IRUSR|S_IWUSR|S_IXUSR) != 0)
{
if(errno != EEXIST)
{
printf("failed to make directory: %s %m\n", out_path);
return false;
}
}
c = a+1;
}
strcat(out_path, "/");
strcat(out_path, c);
return true;
}
/*
* Extract all the resources from the ELF file for use by the resource loader
*/
char *libr_extract_resources(libr_file *handle)
{
char *temp_mask = strdup(LIBR_TEMPFILE);
char *temp_folder;
int i = 0;
temp_folder = mkdtemp(temp_mask);
if(temp_folder == NULL)
{
/* failed to extract ELF resources, could not create a temporary path */
goto failed;
}
/* If this library cannot dynamically load resources then pull out all the resources to a temporary directory */
for(i=0;i<libr_resources(handle);i++)
{
char *resource_name = libr_list(handle, i);
char *file_path[PATH_MAX];
size_t resource_size;
FILE *file_handle;
char *resource;
resource = libr_malloc(handle, resource_name, &resource_size);
if(!make_valid_path((char *)file_path, sizeof(file_path), temp_folder, resource_name))
{
/* failed to build the path required by a resource */
cleanup_folder(temp_folder);
temp_folder = NULL;
goto failed;
}
file_handle = fopen((const char *) file_path, "w");
if(file_handle == NULL)
{
/* failed to extract ELF resources, could not write to temporary path */
cleanup_folder(temp_folder);
temp_folder = NULL;
goto failed;
}
/* if the resource is empty then fwrite will fail */
if( (resource_size != 0) && (fwrite(resource, resource_size, 1, file_handle) != 1) )
{
/* failed to extract ELF resources, temporary path out of space? */
cleanup_folder(temp_folder);
temp_folder = NULL;
goto failed;
}
fclose(file_handle);
free(resource);
}
failed:
if(temp_folder != NULL)
temp_folder = strdup(temp_folder);
free(temp_mask);
return temp_folder;
}

@ -0,0 +1,13 @@
#ifndef __TEMPFILES_H
#define __TEMPFILES_H
#include "libr.h"
void cleanup_folder(char *temp_folder);
void register_handle_cleanup(libr_file *handle);
void unregister_handle_cleanup(libr_file *handle);
void register_internal_handle(libr_file *handle);
void register_folder_cleanup(char *temp_folder);
char *libr_extract_resources(libr_file *handle);
#endif /* __TEMPFILES_H */
Loading…
Cancel
Save