This commit was generated by cvs2svn to compensate for changes in r150765,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
c41ca4418d
705
contrib/cpio/ABOUT-NLS
Normal file
705
contrib/cpio/ABOUT-NLS
Normal file
@ -0,0 +1,705 @@
|
||||
Notes on the Free Translation Project
|
||||
*************************************
|
||||
|
||||
Free software is going international! The Free Translation Project is
|
||||
a way to get maintainers of free software, translators, and users all
|
||||
together, so that will gradually become able to speak many languages.
|
||||
A few packages already provide translations for their messages.
|
||||
|
||||
If you found this `ABOUT-NLS' file inside a distribution, you may
|
||||
assume that the distributed package does use GNU `gettext' internally,
|
||||
itself available at your nearest GNU archive site. But you do _not_
|
||||
need to install GNU `gettext' prior to configuring, installing or using
|
||||
this package with messages translated.
|
||||
|
||||
Installers will find here some useful hints. These notes also
|
||||
explain how users should proceed for getting the programs to use the
|
||||
available translations. They tell how people wanting to contribute and
|
||||
work at translations should contact the appropriate team.
|
||||
|
||||
When reporting bugs in the `intl/' directory or bugs which may be
|
||||
related to internationalization, you should tell about the version of
|
||||
`gettext' which is used. The information can be found in the
|
||||
`intl/VERSION' file, in internationalized packages.
|
||||
|
||||
Quick configuration advice
|
||||
==========================
|
||||
|
||||
If you want to exploit the full power of internationalization, you
|
||||
should configure it using
|
||||
|
||||
./configure --with-included-gettext
|
||||
|
||||
to force usage of internationalizing routines provided within this
|
||||
package, despite the existence of internationalizing capabilities in the
|
||||
operating system where this package is being installed. So far, only
|
||||
the `gettext' implementation in the GNU C library version 2 provides as
|
||||
many features (such as locale alias, message inheritance, automatic
|
||||
charset conversion or plural form handling) as the implementation here.
|
||||
It is also not possible to offer this additional functionality on top
|
||||
of a `catgets' implementation. Future versions of GNU `gettext' will
|
||||
very likely convey even more functionality. So it might be a good idea
|
||||
to change to GNU `gettext' as soon as possible.
|
||||
|
||||
So you need _not_ provide this option if you are using GNU libc 2 or
|
||||
you have installed a recent copy of the GNU gettext package with the
|
||||
included `libintl'.
|
||||
|
||||
INSTALL Matters
|
||||
===============
|
||||
|
||||
Some packages are "localizable" when properly installed; the programs
|
||||
they contain can be made to speak your own native language. Most such
|
||||
packages use GNU `gettext'. Other packages have their own ways to
|
||||
internationalization, predating GNU `gettext'.
|
||||
|
||||
By default, this package will be installed to allow translation of
|
||||
messages. It will automatically detect whether the system already
|
||||
provides the GNU `gettext' functions. If not, the GNU `gettext' own
|
||||
library will be used. This library is wholly contained within this
|
||||
package, usually in the `intl/' subdirectory, so prior installation of
|
||||
the GNU `gettext' package is _not_ required. Installers may use
|
||||
special options at configuration time for changing the default
|
||||
behaviour. The commands:
|
||||
|
||||
./configure --with-included-gettext
|
||||
./configure --disable-nls
|
||||
|
||||
will respectively bypass any pre-existing `gettext' to use the
|
||||
internationalizing routines provided within this package, or else,
|
||||
_totally_ disable translation of messages.
|
||||
|
||||
When you already have GNU `gettext' installed on your system and run
|
||||
configure without an option for your new package, `configure' will
|
||||
probably detect the previously built and installed `libintl.a' file and
|
||||
will decide to use this. This might be not what is desirable. You
|
||||
should use the more recent version of the GNU `gettext' library. I.e.
|
||||
if the file `intl/VERSION' shows that the library which comes with this
|
||||
package is more recent, you should use
|
||||
|
||||
./configure --with-included-gettext
|
||||
|
||||
to prevent auto-detection.
|
||||
|
||||
The configuration process will not test for the `catgets' function
|
||||
and therefore it will not be used. The reason is that even an
|
||||
emulation of `gettext' on top of `catgets' could not provide all the
|
||||
extensions of the GNU `gettext' library.
|
||||
|
||||
Internationalized packages have usually many `po/LL.po' files, where
|
||||
LL gives an ISO 639 two-letter code identifying the language. Unless
|
||||
translations have been forbidden at `configure' time by using the
|
||||
`--disable-nls' switch, all available translations are installed
|
||||
together with the package. However, the environment variable `LINGUAS'
|
||||
may be set, prior to configuration, to limit the installed set.
|
||||
`LINGUAS' should then contain a space separated list of two-letter
|
||||
codes, stating which languages are allowed.
|
||||
|
||||
Using This Package
|
||||
==================
|
||||
|
||||
As a user, if your language has been installed for this package, you
|
||||
only have to set the `LANG' environment variable to the appropriate
|
||||
`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
|
||||
and `CC' is an ISO 3166 two-letter country code. For example, let's
|
||||
suppose that you speak German and live in Germany. At the shell
|
||||
prompt, merely execute `setenv LANG de_DE' (in `csh'),
|
||||
`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
|
||||
This can be done from your `.login' or `.profile' file, once and for
|
||||
all.
|
||||
|
||||
You might think that the country code specification is redundant.
|
||||
But in fact, some languages have dialects in different countries. For
|
||||
example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
|
||||
country code serves to distinguish the dialects.
|
||||
|
||||
The locale naming convention of `LL_CC', with `LL' denoting the
|
||||
language and `CC' denoting the country, is the one use on systems based
|
||||
on GNU libc. On other systems, some variations of this scheme are
|
||||
used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
|
||||
locales supported by your system for your country by running the command
|
||||
`locale -a | grep '^LL''.
|
||||
|
||||
Not all programs have translations for all languages. By default, an
|
||||
English message is shown in place of a nonexistent translation. If you
|
||||
understand other languages, you can set up a priority list of languages.
|
||||
This is done through a different environment variable, called
|
||||
`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
|
||||
for the purpose of message handling, but you still need to have `LANG'
|
||||
set to the primary language; this is required by other parts of the
|
||||
system libraries. For example, some Swedish users who would rather
|
||||
read translations in German than English for when Swedish is not
|
||||
available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
|
||||
|
||||
In the `LANGUAGE' environment variable, but not in the `LANG'
|
||||
environment variable, `LL_CC' combinations can be abbreviated as `LL'
|
||||
to denote the language's main dialect. For example, `de' is equivalent
|
||||
to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
|
||||
(Portuguese as spoken in Portugal) in this context.
|
||||
|
||||
Translating Teams
|
||||
=================
|
||||
|
||||
For the Free Translation Project to be a success, we need interested
|
||||
people who like their own language and write it well, and who are also
|
||||
able to synergize with other translators speaking the same language.
|
||||
Each translation team has its own mailing list. The up-to-date list of
|
||||
teams can be found at the Free Translation Project's homepage,
|
||||
`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
|
||||
area.
|
||||
|
||||
If you'd like to volunteer to _work_ at translating messages, you
|
||||
should become a member of the translating team for your own language.
|
||||
The subscribing address is _not_ the same as the list itself, it has
|
||||
`-request' appended. For example, speakers of Swedish can send a
|
||||
message to `sv-request@li.org', having this message body:
|
||||
|
||||
subscribe
|
||||
|
||||
Keep in mind that team members are expected to participate
|
||||
_actively_ in translations, or at solving translational difficulties,
|
||||
rather than merely lurking around. If your team does not exist yet and
|
||||
you want to start one, or if you are unsure about what to do or how to
|
||||
get started, please write to `translation@iro.umontreal.ca' to reach the
|
||||
coordinator for all translator teams.
|
||||
|
||||
The English team is special. It works at improving and uniformizing
|
||||
the terminology in use. Proven linguistic skill are praised more than
|
||||
programming skill, here.
|
||||
|
||||
Available Packages
|
||||
==================
|
||||
|
||||
Languages are not equally supported in all packages. The following
|
||||
matrix shows the current state of internationalization, as of November
|
||||
2003. The matrix shows, in regard of each package, for which languages
|
||||
PO files have been submitted to translation coordination, with a
|
||||
translation percentage of at least 50%.
|
||||
|
||||
Ready PO files am az be bg ca cs da de el en en_GB eo es
|
||||
+-------------------------------------------+
|
||||
a2ps | [] [] [] [] |
|
||||
aegis | () |
|
||||
ant-phone | () |
|
||||
anubis | |
|
||||
ap-utils | |
|
||||
bash | [] [] [] [] |
|
||||
batchelor | |
|
||||
bfd | [] [] |
|
||||
binutils | [] [] |
|
||||
bison | [] [] [] |
|
||||
bluez-pin | [] [] |
|
||||
clisp | [] [] [] |
|
||||
clisp | |
|
||||
coreutils | [] [] [] [] |
|
||||
cpio | [] [] [] |
|
||||
darkstat | [] () [] |
|
||||
diffutils | [] [] [] [] [] [] [] |
|
||||
e2fsprogs | [] [] |
|
||||
enscript | [] [] [] [] |
|
||||
error | [] [] [] [] [] |
|
||||
fetchmail | [] () [] [] [] [] |
|
||||
fileutils | [] [] [] |
|
||||
findutils | [] [] [] [] [] [] [] |
|
||||
flex | [] [] [] [] |
|
||||
fslint | |
|
||||
gas | [] |
|
||||
gawk | [] [] [] [] |
|
||||
gbiff | [] |
|
||||
gcal | [] |
|
||||
gcc | [] [] |
|
||||
gettext | [] [] [] [] [] |
|
||||
gettext-examples | [] [] [] |
|
||||
gettext-runtime | [] [] [] [] [] |
|
||||
gettext-tools | [] [] [] |
|
||||
gimp-print | [] [] [] [] [] |
|
||||
gliv | |
|
||||
glunarclock | [] [] [] |
|
||||
gnubiff | [] |
|
||||
gnucash | [] () [] [] |
|
||||
gnucash-glossary | [] () [] |
|
||||
gnupg | [] () [] [] [] [] |
|
||||
gpe-aerial | [] |
|
||||
gpe-beam | [] [] |
|
||||
gpe-calendar | [] [] |
|
||||
gpe-clock | [] [] |
|
||||
gpe-conf | [] [] |
|
||||
gpe-contacts | [] [] |
|
||||
gpe-edit | [] |
|
||||
gpe-go | [] |
|
||||
gpe-login | [] [] |
|
||||
gpe-ownerinfo | [] [] |
|
||||
gpe-sketchbook | [] [] |
|
||||
gpe-su | [] [] |
|
||||
gpe-taskmanager | [] [] |
|
||||
gpe-timesheet | [] |
|
||||
gpe-today | [] [] |
|
||||
gpe-todo | [] [] |
|
||||
gphoto2 | [] [] [] [] |
|
||||
gprof | [] [] [] |
|
||||
gpsdrive | () () () |
|
||||
gramadoir | [] |
|
||||
grep | [] [] [] [] [] [] |
|
||||
gretl | [] |
|
||||
gtick | () |
|
||||
hello | [] [] [] [] [] [] |
|
||||
id-utils | [] [] |
|
||||
indent | [] [] [] [] |
|
||||
jpilot | [] [] [] |
|
||||
jtag | |
|
||||
jwhois | [] |
|
||||
kbd | [] [] [] [] [] |
|
||||
latrine | () |
|
||||
ld | [] [] |
|
||||
libc | [] [] [] [] [] [] |
|
||||
libgpewidget | [] [] |
|
||||
libiconv | [] [] [] [] [] |
|
||||
lifelines | [] () |
|
||||
lilypond | [] |
|
||||
lingoteach | |
|
||||
lingoteach_lessons | () () |
|
||||
lynx | [] [] [] [] |
|
||||
m4 | [] [] [] [] |
|
||||
mailutils | [] [] |
|
||||
make | [] [] [] |
|
||||
man-db | [] () [] [] () |
|
||||
minicom | [] [] [] |
|
||||
mysecretdiary | [] [] [] |
|
||||
nano | [] () [] [] [] |
|
||||
nano_1_0 | [] () [] [] [] |
|
||||
opcodes | [] |
|
||||
parted | [] [] [] [] [] |
|
||||
ptx | [] [] [] [] [] |
|
||||
python | |
|
||||
radius | |
|
||||
recode | [] [] [] [] [] [] [] |
|
||||
screem | |
|
||||
scrollkeeper | [] [] [] [] [] [] |
|
||||
sed | [] [] [] [] [] |
|
||||
sh-utils | [] [] [] |
|
||||
shared-mime-info | |
|
||||
sharutils | [] [] [] [] [] [] |
|
||||
sketch | [] () [] |
|
||||
soundtracker | [] [] [] |
|
||||
sp | [] |
|
||||
tar | [] [] [] [] |
|
||||
texinfo | [] [] [] |
|
||||
textutils | [] [] [] [] |
|
||||
tin | () () |
|
||||
tuxpaint | [] [] [] [] [] [] [] |
|
||||
util-linux | [] [] [] [] [] |
|
||||
vorbis-tools | [] [] [] [] |
|
||||
wastesedge | () |
|
||||
wdiff | [] [] [] [] |
|
||||
wget | [] [] [] [] [] [] |
|
||||
xchat | [] [] [] [] |
|
||||
xfree86_xkb_xml | [] |
|
||||
xpad | [] |
|
||||
+-------------------------------------------+
|
||||
am az be bg ca cs da de el en en_GB eo es
|
||||
0 1 8 3 37 37 54 73 15 1 5 12 62
|
||||
|
||||
et fa fi fr ga gl he hr hu id is it ja
|
||||
+----------------------------------------+
|
||||
a2ps | [] [] [] () |
|
||||
aegis | |
|
||||
ant-phone | |
|
||||
anubis | [] |
|
||||
ap-utils | [] |
|
||||
bash | [] [] |
|
||||
batchelor | [] |
|
||||
bfd | [] |
|
||||
binutils | [] [] |
|
||||
bison | [] [] [] [] |
|
||||
bluez-pin | [] [] [] [] [] |
|
||||
clisp | [] |
|
||||
clisp | |
|
||||
coreutils | [] [] [] [] [] [] |
|
||||
cpio | [] [] [] |
|
||||
darkstat | () [] [] [] |
|
||||
diffutils | [] [] [] [] [] [] [] |
|
||||
e2fsprogs | |
|
||||
enscript | [] [] |
|
||||
error | [] [] [] [] |
|
||||
fetchmail | [] |
|
||||
fileutils | [] [] [] [] [] [] |
|
||||
findutils | [] [] [] [] [] [] [] [] [] [] |
|
||||
flex | [] [] |
|
||||
fslint | |
|
||||
gas | [] |
|
||||
gawk | [] [] [] |
|
||||
gbiff | |
|
||||
gcal | [] |
|
||||
gcc | [] |
|
||||
gettext | [] [] |
|
||||
gettext-examples | [] [] |
|
||||
gettext-runtime | [] [] [] [] |
|
||||
gettext-tools | [] [] |
|
||||
gimp-print | [] [] |
|
||||
gliv | () |
|
||||
glunarclock | [] [] [] [] [] |
|
||||
gnubiff | |
|
||||
gnucash | () [] |
|
||||
gnucash-glossary | [] |
|
||||
gnupg | [] [] [] [] [] [] [] |
|
||||
gpe-aerial | [] |
|
||||
gpe-beam | [] |
|
||||
gpe-calendar | [] [] [] |
|
||||
gpe-clock | [] |
|
||||
gpe-conf | [] |
|
||||
gpe-contacts | [] [] |
|
||||
gpe-edit | [] [] |
|
||||
gpe-go | [] |
|
||||
gpe-login | [] [] |
|
||||
gpe-ownerinfo | [] [] [] |
|
||||
gpe-sketchbook | [] |
|
||||
gpe-su | [] |
|
||||
gpe-taskmanager | [] |
|
||||
gpe-timesheet | [] [] [] |
|
||||
gpe-today | [] [] |
|
||||
gpe-todo | [] [] |
|
||||
gphoto2 | [] [] [] |
|
||||
gprof | [] [] |
|
||||
gpsdrive | () [] () () |
|
||||
gramadoir | [] |
|
||||
grep | [] [] [] [] [] [] [] [] [] [] [] |
|
||||
gretl | [] |
|
||||
gtick | [] [] |
|
||||
hello | [] [] [] [] [] [] [] [] [] [] [] [] |
|
||||
id-utils | [] [] [] [] |
|
||||
indent | [] [] [] [] [] [] [] [] [] |
|
||||
jpilot | [] () |
|
||||
jtag | |
|
||||
jwhois | [] [] [] [] |
|
||||
kbd | [] |
|
||||
latrine | |
|
||||
ld | [] |
|
||||
libc | [] [] [] [] [] |
|
||||
libgpewidget | [] [] [] [] |
|
||||
libiconv | [] [] [] [] [] [] [] [] [] |
|
||||
lifelines | () |
|
||||
lilypond | [] |
|
||||
lingoteach | [] [] |
|
||||
lingoteach_lessons | |
|
||||
lynx | [] [] [] [] |
|
||||
m4 | [] [] [] [] |
|
||||
mailutils | |
|
||||
make | [] [] [] [] [] |
|
||||
man-db | () () |
|
||||
minicom | [] [] [] [] |
|
||||
mysecretdiary | [] [] |
|
||||
nano | [] [] [] [] |
|
||||
nano_1_0 | [] [] [] [] |
|
||||
opcodes | [] |
|
||||
parted | [] [] [] |
|
||||
ptx | [] [] [] [] [] [] [] |
|
||||
python | |
|
||||
radius | |
|
||||
recode | [] [] [] [] [] [] |
|
||||
screem | |
|
||||
scrollkeeper | [] |
|
||||
sed | [] [] [] [] [] [] [] [] [] |
|
||||
sh-utils | [] [] [] [] [] [] [] |
|
||||
shared-mime-info | [] |
|
||||
sharutils | [] [] [] [] [] |
|
||||
sketch | [] |
|
||||
soundtracker | [] [] [] [] |
|
||||
sp | [] () |
|
||||
tar | [] [] [] [] [] [] [] [] [] |
|
||||
texinfo | [] [] [] [] |
|
||||
textutils | [] [] [] [] [] |
|
||||
tin | [] () |
|
||||
tuxpaint | [] [] [] [] [] [] [] [] |
|
||||
util-linux | [] [] [] [] () [] |
|
||||
vorbis-tools | [] |
|
||||
wastesedge | () |
|
||||
wdiff | [] [] [] [] [] [] |
|
||||
wget | [] [] [] [] [] [] [] |
|
||||
xchat | [] [] [] |
|
||||
xfree86_xkb_xml | |
|
||||
xpad | [] |
|
||||
+----------------------------------------+
|
||||
et fa fi fr ga gl he hr hu id is it ja
|
||||
21 1 24 84 24 24 8 10 38 31 1 22 33
|
||||
|
||||
ko lg lt lv ms nb nl nn no pl pt pt_BR ro
|
||||
+-------------------------------------------+
|
||||
a2ps | () [] [] () () [] [] |
|
||||
aegis | () () |
|
||||
ant-phone | [] [] |
|
||||
anubis | [] [] [] [] [] |
|
||||
ap-utils | [] () [] |
|
||||
bash | [] [] |
|
||||
batchelor | [] |
|
||||
bfd | [] |
|
||||
binutils | |
|
||||
bison | [] [] [] [] |
|
||||
bluez-pin | [] [] [] |
|
||||
clisp | [] |
|
||||
clisp | |
|
||||
coreutils | [] |
|
||||
cpio | [] [] [] [] [] |
|
||||
darkstat | [] [] [] [] |
|
||||
diffutils | [] [] [] [] |
|
||||
e2fsprogs | [] |
|
||||
enscript | [] [] [] |
|
||||
error | [] [] [] |
|
||||
fetchmail | [] [] () |
|
||||
fileutils | [] |
|
||||
findutils | [] [] [] [] [] |
|
||||
flex | [] [] [] [] |
|
||||
fslint | [] [] |
|
||||
gas | |
|
||||
gawk | [] [] [] |
|
||||
gbiff | [] [] |
|
||||
gcal | |
|
||||
gcc | |
|
||||
gettext | [] [] [] |
|
||||
gettext-examples | [] [] |
|
||||
gettext-runtime | [] [] [] |
|
||||
gettext-tools | [] [] [] |
|
||||
gimp-print | [] |
|
||||
gliv | [] [] [] |
|
||||
glunarclock | [] [] [] |
|
||||
gnubiff | |
|
||||
gnucash | [] [] () |
|
||||
gnucash-glossary | [] [] |
|
||||
gnupg | [] |
|
||||
gpe-aerial | [] [] [] |
|
||||
gpe-beam | [] [] [] |
|
||||
gpe-calendar | [] [] [] |
|
||||
gpe-clock | [] [] [] |
|
||||
gpe-conf | [] [] [] |
|
||||
gpe-contacts | [] [] [] |
|
||||
gpe-edit | [] [] [] |
|
||||
gpe-go | [] [] |
|
||||
gpe-login | [] [] [] |
|
||||
gpe-ownerinfo | [] [] [] |
|
||||
gpe-sketchbook | [] [] [] |
|
||||
gpe-su | [] [] [] |
|
||||
gpe-taskmanager | [] [] [] |
|
||||
gpe-timesheet | [] [] [] |
|
||||
gpe-today | [] [] [] |
|
||||
gpe-todo | [] [] [] |
|
||||
gphoto2 | [] |
|
||||
gprof | [] [] |
|
||||
gpsdrive | () () () [] |
|
||||
gramadoir | [] |
|
||||
grep | [] [] [] [] |
|
||||
gretl | |
|
||||
gtick | [] [] |
|
||||
hello | [] [] [] [] [] [] [] [] [] [] |
|
||||
id-utils | [] [] [] |
|
||||
indent | [] [] [] |
|
||||
jpilot | () () |
|
||||
jtag | |
|
||||
jwhois | [] [] [] [] |
|
||||
kbd | [] [] [] |
|
||||
latrine | [] |
|
||||
ld | |
|
||||
libc | [] [] [] [] [] |
|
||||
libgpewidget | [] [] [] |
|
||||
libiconv | [] [] [] [] |
|
||||
lifelines | |
|
||||
lilypond | |
|
||||
lingoteach | |
|
||||
lingoteach_lessons | |
|
||||
lynx | [] [] |
|
||||
m4 | [] [] [] [] |
|
||||
mailutils | [] |
|
||||
make | [] [] [] [] |
|
||||
man-db | [] |
|
||||
minicom | [] [] [] |
|
||||
mysecretdiary | [] [] [] |
|
||||
nano | [] [] [] [] |
|
||||
nano_1_0 | [] [] [] [] [] |
|
||||
opcodes | [] [] |
|
||||
parted | [] [] [] [] |
|
||||
ptx | [] [] [] [] [] [] [] |
|
||||
python | |
|
||||
radius | [] |
|
||||
recode | [] [] [] |
|
||||
screem | |
|
||||
scrollkeeper | [] [] [] [] |
|
||||
sed | [] [] [] |
|
||||
sh-utils | [] |
|
||||
shared-mime-info | [] |
|
||||
sharutils | [] |
|
||||
sketch | [] [] |
|
||||
soundtracker | |
|
||||
sp | |
|
||||
tar | [] [] [] [] [] [] |
|
||||
texinfo | [] [] [] |
|
||||
textutils | [] [] |
|
||||
tin | |
|
||||
tuxpaint | [] [] [] [] [] [] [] [] [] |
|
||||
util-linux | [] [] |
|
||||
vorbis-tools | [] [] |
|
||||
wastesedge | |
|
||||
wdiff | [] [] [] [] |
|
||||
wget | [] [] |
|
||||
xchat | [] [] |
|
||||
xfree86_xkb_xml | [] |
|
||||
xpad | [] [] |
|
||||
+-------------------------------------------+
|
||||
ko lg lt lv ms nb nl nn no pl pt pt_BR ro
|
||||
11 0 1 2 12 10 60 4 4 38 23 34 74
|
||||
|
||||
ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
|
||||
+-------------------------------------------+
|
||||
a2ps | [] [] [] [] [] | 16
|
||||
aegis | () | 0
|
||||
ant-phone | | 2
|
||||
anubis | [] [] [] | 9
|
||||
ap-utils | () | 3
|
||||
bash | [] | 9
|
||||
batchelor | | 2
|
||||
bfd | [] [] | 6
|
||||
binutils | [] [] [] | 7
|
||||
bison | [] [] [] | 14
|
||||
bluez-pin | [] [] [] | 13
|
||||
clisp | | 5
|
||||
clisp | | 0
|
||||
coreutils | [] [] [] [] [] | 16
|
||||
cpio | [] [] [] | 14
|
||||
darkstat | [] [] [] () () | 12
|
||||
diffutils | [] [] [] [] | 22
|
||||
e2fsprogs | [] [] | 5
|
||||
enscript | [] [] [] | 12
|
||||
error | [] [] [] | 15
|
||||
fetchmail | [] [] [] | 11
|
||||
fileutils | [] [] [] [] [] [] | 16
|
||||
findutils | [] [] [] [] [] [] [] | 29
|
||||
flex | [] [] [] | 13
|
||||
fslint | | 2
|
||||
gas | [] | 3
|
||||
gawk | [] [] | 12
|
||||
gbiff | | 3
|
||||
gcal | [] [] | 4
|
||||
gcc | [] | 4
|
||||
gettext | [] [] [] [] [] [] | 16
|
||||
gettext-examples | [] [] | 9
|
||||
gettext-runtime | [] [] [] [] [] [] [] [] [] | 21
|
||||
gettext-tools | [] [] [] [] [] [] | 14
|
||||
gimp-print | [] [] | 10
|
||||
gliv | | 3
|
||||
glunarclock | [] [] [] [] | 15
|
||||
gnubiff | | 1
|
||||
gnucash | [] [] [] | 9
|
||||
gnucash-glossary | [] [] [] | 8
|
||||
gnupg | [] [] [] [] | 17
|
||||
gpe-aerial | [] [] | 7
|
||||
gpe-beam | [] [] | 8
|
||||
gpe-calendar | [] [] [] [] [] | 13
|
||||
gpe-clock | [] [] [] | 9
|
||||
gpe-conf | [] [] [] | 9
|
||||
gpe-contacts | [] [] [] [] | 11
|
||||
gpe-edit | [] [] [] [] [] | 11
|
||||
gpe-go | [] | 5
|
||||
gpe-login | [] [] [] [] [] | 12
|
||||
gpe-ownerinfo | [] [] [] [] | 12
|
||||
gpe-sketchbook | [] [] [] | 9
|
||||
gpe-su | [] [] [] | 9
|
||||
gpe-taskmanager | [] [] [] | 9
|
||||
gpe-timesheet | [] [] [] [] | 11
|
||||
gpe-today | [] [] [] [] [] | 12
|
||||
gpe-todo | [] [] [] [] [] | 12
|
||||
gphoto2 | [] [] [] | 11
|
||||
gprof | [] [] | 9
|
||||
gpsdrive | [] [] | 4
|
||||
gramadoir | | 3
|
||||
grep | [] [] [] [] [] | 26
|
||||
gretl | | 2
|
||||
gtick | [] | 5
|
||||
hello | [] [] [] [] [] | 33
|
||||
id-utils | [] [] [] | 12
|
||||
indent | [] [] [] [] [] | 21
|
||||
jpilot | [] [] [] [] [] | 9
|
||||
jtag | [] | 1
|
||||
jwhois | () () [] [] | 11
|
||||
kbd | [] [] | 11
|
||||
latrine | | 1
|
||||
ld | [] [] | 5
|
||||
libc | [] [] [] [] | 20
|
||||
libgpewidget | [] [] [] | 12
|
||||
libiconv | [] [] [] [] [] [] [] [] [] | 27
|
||||
lifelines | [] | 2
|
||||
lilypond | [] | 3
|
||||
lingoteach | | 2
|
||||
lingoteach_lessons | () | 0
|
||||
lynx | [] [] [] [] | 14
|
||||
m4 | [] [] [] | 15
|
||||
mailutils | [] | 4
|
||||
make | [] [] [] [] | 16
|
||||
man-db | [] | 5
|
||||
minicom | [] | 11
|
||||
mysecretdiary | [] [] | 10
|
||||
nano | [] [] [] [] [] | 17
|
||||
nano_1_0 | [] [] [] [] | 17
|
||||
opcodes | [] [] | 6
|
||||
parted | [] [] [] | 15
|
||||
ptx | [] [] [] | 22
|
||||
python | | 0
|
||||
radius | [] | 2
|
||||
recode | [] [] [] [] | 20
|
||||
screem | [] [] | 2
|
||||
scrollkeeper | [] [] [] [] | 15
|
||||
sed | [] [] [] [] [] [] | 23
|
||||
sh-utils | [] [] [] | 14
|
||||
shared-mime-info | [] [] | 4
|
||||
sharutils | [] [] [] [] [] | 17
|
||||
sketch | [] | 6
|
||||
soundtracker | [] [] | 9
|
||||
sp | [] | 3
|
||||
tar | [] [] [] [] [] | 24
|
||||
texinfo | [] [] [] [] | 14
|
||||
textutils | [] [] [] [] [] | 16
|
||||
tin | | 1
|
||||
tuxpaint | [] [] [] [] [] | 29
|
||||
util-linux | [] [] [] | 15
|
||||
vorbis-tools | [] | 8
|
||||
wastesedge | | 0
|
||||
wdiff | [] [] [] [] | 18
|
||||
wget | [] [] [] [] [] [] [] [] | 23
|
||||
xchat | [] [] [] [] [] | 14
|
||||
xfree86_xkb_xml | [] [] [] [] | 6
|
||||
xpad | | 4
|
||||
+-------------------------------------------+
|
||||
51 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
|
||||
117 domains 58 41 16 16 78 0 53 12 1 10 21 22 1230
|
||||
|
||||
Some counters in the preceding matrix are higher than the number of
|
||||
visible blocks let us expect. This is because a few extra PO files are
|
||||
used for implementing regional variants of languages, or language
|
||||
dialects.
|
||||
|
||||
For a PO file in the matrix above to be effective, the package to
|
||||
which it applies should also have been internationalized and
|
||||
distributed as such by its maintainer. There might be an observable
|
||||
lag between the mere existence a PO file and its wide availability in a
|
||||
distribution.
|
||||
|
||||
If November 2003 seems to be old, you may fetch a more recent copy
|
||||
of this `ABOUT-NLS' file on most GNU archive sites. The most
|
||||
up-to-date matrix with full percentage details can be found at
|
||||
`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
|
||||
|
||||
Using `gettext' in new packages
|
||||
===============================
|
||||
|
||||
If you are writing a freely available program and want to
|
||||
internationalize it you are welcome to use GNU `gettext' in your
|
||||
package. Of course you have to respect the GNU Library General Public
|
||||
License which covers the use of the GNU `gettext' library. This means
|
||||
in particular that even non-free programs can use `libintl' as a shared
|
||||
library, whereas only free software can use `libintl' as a static
|
||||
library or use modified versions of `libintl'.
|
||||
|
||||
Once the sources are changed appropriately and the setup can handle
|
||||
the use of `gettext' the only thing missing are the translations. The
|
||||
Free Translation Project is also available for packages which are not
|
||||
developed inside the GNU project. Therefore the information given above
|
||||
applies also for every other Free Software Project. Contact
|
||||
`translation@iro.umontreal.ca' to make the `.pot' files available to
|
||||
the translation teams.
|
||||
|
6
contrib/cpio/AUTHORS
Normal file
6
contrib/cpio/AUTHORS
Normal file
@ -0,0 +1,6 @@
|
||||
Authors of GNU cpio
|
||||
|
||||
Phil Nelson <phil@cs.wwu.edu>
|
||||
David MacKenzie <djm@gnu.ai.mit.edu>
|
||||
John Oleynick <juo@klinzhai.rutgers.edu>
|
||||
Sergey Poznyakoff <gray@mirddin.farlep.net>
|
@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -305,14 +305,15 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
@ -1,3 +1,433 @@
|
||||
2004-12-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
Released version 2.6. Sources up to this point are tagged
|
||||
release_2_6.
|
||||
|
||||
* configure.ac: Raised version number to 2.6
|
||||
* NEWS: Likewise
|
||||
* bootstrap (update_po): Give -r to wget. Always remove index.html
|
||||
Ignore alloca-opt module (it duplicates alloca)
|
||||
|
||||
2004-11-23 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/main.c (enum cpio_options): Bugfix: Initialize first enum
|
||||
value to 256.
|
||||
* bootstrap: Add unlocked-io
|
||||
* headers/argp.h: Removed
|
||||
* headers/getopt.h: Removed
|
||||
* headers/Makefile.am: Updated
|
||||
|
||||
2004-10-14 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/copyout.c: Add trailing slash to directory names in
|
||||
ustar format.
|
||||
* src/makepath.c: Removed redeclaration of error().
|
||||
* src/tar.c: Fixed deviations from POSIX.1-1988:
|
||||
Properly split long file names. Fill in octal fields with zeros,
|
||||
not spaces. Save only protection modes, not the whole mode.
|
||||
|
||||
* NEWS: Updated
|
||||
|
||||
2004-09-08 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* NEWS: Updated
|
||||
* TODO: Updated
|
||||
* bootstrap: Install po files by default
|
||||
* po/LINGUAS: Removed. File is generated automatically
|
||||
* po/.cvsignore: Updated
|
||||
* src/copyin.c: Implemented --to-stdout option
|
||||
* src/copyout.c: Display the annoying 'truncating inode number'
|
||||
message only if the user wishes it.
|
||||
* src/extern.h: Added new globals.
|
||||
* src/global.c: Likewise.
|
||||
|
||||
* src/main.c: Added support for --to-stdout and --warning options
|
||||
* src/tar.c (read_in_tar_header): Use warn_junk_bytes()
|
||||
* src/util.c (create_all_directories): Use dir_name.
|
||||
|
||||
* configure.ac: Added support for the test suite
|
||||
* Makefile.am: Likewise
|
||||
|
||||
* tests: New directory
|
||||
* tests/.cvsignore: New file
|
||||
* tests/Makefile.am: New file
|
||||
* tests/testsuite.at: New file
|
||||
* tests/inout.at: New file
|
||||
* tests/version.at: New file
|
||||
* tests/atlocal.in: New file
|
||||
|
||||
2004-09-07 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/main.c (process_args): Bugfix. Allow extra arguments
|
||||
in copy_in mode.
|
||||
* src/util.c (write_nuls_to_file): Use buffered I/O. All
|
||||
callers changed. Thanks Matthew Braithwaite <mab@cnet.com>
|
||||
for noticing.
|
||||
Bugfix: extra_bytes was mistakenly used instead of blocks.
|
||||
* THANKS: Added Matthew Braithwaite.
|
||||
|
||||
2004-09-06 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
Started merging with tar into paxutils. Sources before
|
||||
this point are tagged alpha-2_50_90.
|
||||
|
||||
* bootstrap: New file
|
||||
* autogen.sh: Removed
|
||||
* Makefile.am: Updated
|
||||
* NEWS: Updated
|
||||
* README-alpha: Updated
|
||||
* configure.ac: Updated
|
||||
* doc/cpio.1: Updated
|
||||
* po/POTFILES.in: Updated
|
||||
|
||||
* src/Makefile.am: Updated
|
||||
* src/error.c: Removed
|
||||
* src/dirname.c: Likewise
|
||||
* src/xmalloc.c: Likewise
|
||||
* src/stripslash.c: Likewise
|
||||
* src/xstrdup.c
|
||||
* src/gettext.h: Likewise
|
||||
* src/system.h: Likewise
|
||||
* src/rmt.h: Likewise
|
||||
* src/getopt.c: Likewise
|
||||
* src/getopt1.c: Likewise
|
||||
* src/bcopy.c: Likewise
|
||||
* src/fnmatch.c: Likewise
|
||||
* src/mkdir.c: Likewise
|
||||
* src/strdup.c: Likewise
|
||||
* src/argp-ba.c: Likewise
|
||||
* src/argp-eexst.c: Likewise
|
||||
* src/argp-fmtstream.c: Likewise
|
||||
* src/argp-fs-xinl.c: Likewise
|
||||
* src/argp-help.c: Likewise
|
||||
* src/argp-parse.c: Likewise
|
||||
* src/argp-pv.c: Likewise
|
||||
* src/argp-pvh.c: Likewise
|
||||
* src/argp-xinl.c: Likewise
|
||||
* src/pin.c: Likewise
|
||||
* src/alloca.c: Likewise
|
||||
* src/argmatch.c: Likewise
|
||||
* src/rmt.c: Likewise
|
||||
* src/rtapelib.c: Likewise
|
||||
* src/strerror.c: Likewise
|
||||
|
||||
* src/copyin.c: Switched to ANSI C (sigh)
|
||||
* src/copyout.c: Likewise
|
||||
* src/copypass.c: Likewise
|
||||
* src/defer.c: Likewise
|
||||
* src/defer.h: Likewise
|
||||
* src/dstring.c: Likewise
|
||||
* src/dstring.h: Likewise
|
||||
* src/extern.h: Likewise
|
||||
* src/filemode.c: Likewise
|
||||
* src/global.c: Likewise
|
||||
* src/idcache.c: Likewise
|
||||
* src/main.c: Likewise
|
||||
* src/makepath.c: Likewise
|
||||
* src/mt.c: Likewise
|
||||
* src/tar.c: Likewise
|
||||
* src/userspec.c: Likewise
|
||||
* src/util.c: Likewise
|
||||
|
||||
* lib: New directory
|
||||
* lib/Makefile.tmpl: New file
|
||||
* lib/bcopy.c: Moved from ../src
|
||||
* lib/mkdir.c: Likewise.
|
||||
* lib/strdup.c: Likewise.
|
||||
* lib/strerror.c: Likewise.
|
||||
|
||||
2004-08-30 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* Makefile.am: Added headers to SUBDIRS.
|
||||
* configure.ac: Check for AC_SYS_LARGEFILE.
|
||||
Use AC_CONFIG_LINKS to provide for fnmatch.h and getopt.h on
|
||||
the systems where these are missing
|
||||
Check for argp and replace it if necessary.
|
||||
* src/Makefile.am: Updated
|
||||
* src/fnmatch.h: Moved to headers/
|
||||
* src/getopt.h: Likewise.
|
||||
* src/main.c: Option parsing rewritten using argp. Improved
|
||||
option consistency checking.
|
||||
* src/rmt.c: Include getopt.h
|
||||
|
||||
* src/argp-ba.c: New file
|
||||
* src/argp-eexst.c: New file
|
||||
* src/argp-fmtstream.c: New file
|
||||
* src/argp-fs-xinl.c: New file
|
||||
* src/argp-help.c: New file
|
||||
* src/argp-parse.c: New file
|
||||
* src/argp-pv.c: New file
|
||||
* src/argp-pvh.c: New file
|
||||
* src/argp-xinl.c: New file
|
||||
* src/pin.c: New file
|
||||
|
||||
* headers: New directory
|
||||
* headers/Makefile.am: New file
|
||||
* headers/getopt.h: New file
|
||||
* headers/argp.h: New file
|
||||
* headers/fnmatch.h: New file
|
||||
* headers/.cvsignore: New file
|
||||
|
||||
2004-03-02 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/util.c (copy_files_disk_to_disk): Bugfix. If a file
|
||||
grew n bytes in copy-pass mode, these n bytes got prepended
|
||||
to the contents of all subsequent files. Fix provided by
|
||||
Holger Fleischmann <holger_fleischmann@mra.man.de>
|
||||
* THANKS: Added Holger Fleischmann.
|
||||
|
||||
2004-02-27 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/makepath.c: Remove unneded typedefs
|
||||
|
||||
* src/copyin.c: Remove __MSDOS__ conditionals
|
||||
* src/copyout.c: Likewise
|
||||
* src/copypass.c: Likewise
|
||||
* src/main.c: Likewise
|
||||
* src/tar.c: Likewise
|
||||
* src/util.c: Likewise
|
||||
|
||||
2004-02-27 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
Changed from flat to deep package layout. Added the framework
|
||||
for NLS support.
|
||||
|
||||
* .cvsignore: Updated
|
||||
* Makefile.am: Updated
|
||||
* configure.ac: Updated
|
||||
* NEWS: Updated
|
||||
* README-alpha: Updated
|
||||
* THANKS: Updated
|
||||
|
||||
* autogen.sh: New file
|
||||
|
||||
* alloca.c: Moved to src
|
||||
* argmatch.c: Likewise
|
||||
* bcopy.c: Likewise
|
||||
* dstring.h: Likewise
|
||||
* copyin.c: Likewise
|
||||
* copyout.c: Likewise
|
||||
* copypass.c: Likewise
|
||||
* cpio.h: Likewise
|
||||
* cpiohdr.h: Likewise
|
||||
* defer.c: Likewise
|
||||
* defer.h: Likewise
|
||||
* dirname.c: Likewise
|
||||
* dstring.c: Likewise
|
||||
* dstring.h: Likewise
|
||||
* error.c: Likewise
|
||||
* extern.h: Likewise
|
||||
* filemode.c: Likewise
|
||||
* filetypes.h: Likewise
|
||||
* fnmatch.c: Likewise
|
||||
* fnmatch.h: Likewise
|
||||
* getopt.c: Likewise
|
||||
* getopt.h: Likewise
|
||||
* getopt1.c: Likewise
|
||||
* global.c: Likewise
|
||||
* idcache.c: Likewise
|
||||
* main.c: Likewise
|
||||
* makepath.c: Likewise
|
||||
* mkdir.c: Likewise
|
||||
* mt.c: Likewise
|
||||
* rmt.c: Likewise
|
||||
* rmt.h: Likewise
|
||||
* rtapelib.c: Likewise
|
||||
* safe-stat.h: Likewise
|
||||
* strdup.c: Likewise
|
||||
* strerror.c: Likewise
|
||||
* stripslash.c: Likewise
|
||||
* system.h: Likewise
|
||||
* tar.c: Likewise
|
||||
* tar.h: Likewise
|
||||
* tarhdr.h: Likewise
|
||||
* userspec.c: Likewise
|
||||
* util.c: Likewise
|
||||
* xmalloc.c: Likewise
|
||||
* xstrdup.c: Likewise
|
||||
|
||||
* cpio.1: Moved to doc
|
||||
* cpio.texi: Likewise
|
||||
* mt.1: Likewise
|
||||
|
||||
* src: New directory
|
||||
* src/.cvsignore: New file
|
||||
* src/Makefile.am: Likewise
|
||||
* src/alloca.c: Likewise
|
||||
* src/argmatch.c: Likewise
|
||||
* src/bcopy.c: Likewise
|
||||
* src/copyin.c: Likewise
|
||||
* src/copyout.c: Likewise
|
||||
* src/copypass.c: Likewise
|
||||
* src/cpio.h: Likewise
|
||||
* src/cpiohdr.h: Likewise
|
||||
* src/defer.c: Likewise
|
||||
* src/defer.h: Likewise
|
||||
* src/dirname.c: Likewise
|
||||
* src/dstring.c: Likewise
|
||||
* src/dstring.h: Likewise
|
||||
* src/error.c: Likewise
|
||||
* src/extern.h: Likewise
|
||||
* src/filemode.c: Likewise
|
||||
* src/filetypes.h: Likewise
|
||||
* src/fnmatch.c: Likewise
|
||||
* src/fnmatch.h: Likewise
|
||||
* src/getopt.c: Likewise
|
||||
* src/getopt.h: Likewise
|
||||
* src/getopt1.c: Likewise
|
||||
* src/gettext.h: Likewise
|
||||
* src/global.c: Likewise
|
||||
* src/idcache.c: Likewise
|
||||
* src/main.c: Likewise
|
||||
* src/makepath.c: Likewise
|
||||
* src/mkdir.c: Likewise
|
||||
* src/mt.c: Likewise
|
||||
* src/rmt.c: Likewise
|
||||
* src/rmt.h: Likewise
|
||||
* src/rtapelib.c: Likewise
|
||||
* src/safe-stat.h: Likewise
|
||||
* src/strdup.c: Likewise
|
||||
* src/strerror.c: Likewise
|
||||
* src/stripslash.c: Likewise
|
||||
* src/system.h: Likewise
|
||||
* src/tar.c: Likewise
|
||||
* src/tar.h: Likewise
|
||||
* src/tarhdr.h: Likewise
|
||||
* src/userspec.c: Likewise
|
||||
* src/util.c: Likewise
|
||||
* src/xmalloc.c: Likewise
|
||||
* src/xstrdup.c: Likewise
|
||||
|
||||
* doc: New directory
|
||||
* doc/.cvsignore: New file
|
||||
* doc/Makefile.am: New file
|
||||
* doc/cpio.1: New file
|
||||
* doc/cpio.info: New file
|
||||
* doc/cpio.texi: New file
|
||||
* doc/mt.1: New file
|
||||
|
||||
* po: New directory
|
||||
* po/.cvsignore: New file
|
||||
* po/LINGUAS: New file
|
||||
* po/Makevars: New file
|
||||
* po/POTFILES.in: New file
|
||||
|
||||
2003-11-28 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* configure.ac: Added various checks
|
||||
* Makefile.am (rmt_LDADD): Added.
|
||||
* error.c: Updated
|
||||
* rmt.c: Removed useless private_errstring
|
||||
* system.h: Updated
|
||||
* userspec.c: Changed the way of handling declared vs. undeclared
|
||||
system calls.
|
||||
* strerror.c: New file. Borrowed from GNU Radius.
|
||||
|
||||
* copyin.c: Removed kludgy declaration of delayed_seek_count.
|
||||
* copypass.c: Likewise
|
||||
* extern.h: Declare delayed_seek_count.
|
||||
* mkdir.c: Fixed handling of undeclared errno
|
||||
* mt.c: Likewise
|
||||
* util.c: Likewise
|
||||
* rtapelib.c: Likewise
|
||||
|
||||
2003-11-28 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* TODO: New file
|
||||
|
||||
* README-alpha: New file
|
||||
* Makefile.am: Require at least version 1.7.1
|
||||
* configure.ac: Check for locale.h
|
||||
* main.c (main): Call setlocale. Thanks
|
||||
Mitsuru Chinen <mchinen@yamato.ibm.com> for the patch.
|
||||
* THANKS: Updated
|
||||
|
||||
2003-11-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* configure.ac: Added to the repository
|
||||
* Makefile.am: Likewise
|
||||
* NEWS: Likewise
|
||||
* README: Likewise
|
||||
* AUTHORS: Likewise
|
||||
* .cvsignore: Likewise
|
||||
|
||||
* configure.in: Removed
|
||||
* Makefile.in: Removed
|
||||
* makefile.pc: Removed
|
||||
* configure: Removed
|
||||
|
||||
* alloca.c: Added to the repository
|
||||
* argmatch.c: Likewise
|
||||
* bcopy.c: Likewise
|
||||
* cpio.h: Likewise
|
||||
* cpiohdr.h: Likewise
|
||||
* defer.c: Likewise
|
||||
* defer.h: Likewise
|
||||
* dirname.c: Likewise
|
||||
* dstring.c: Likewise
|
||||
* dstring.h: Likewise
|
||||
* error.c: Likewise
|
||||
* filemode.c: Likewise
|
||||
* filetypes.h: Likewise
|
||||
* fnmatch.c: Likewise
|
||||
* fnmatch.h: Likewise
|
||||
* getopt.c: Likewise
|
||||
* getopt.h: Likewise
|
||||
* getopt1.c: Likewise
|
||||
* idcache.c: Likewise
|
||||
* mkdir.c: Likewise
|
||||
* rmt.h: Likewise
|
||||
* rtapelib.c: Likewise
|
||||
* safe-stat.h: Likewise
|
||||
* strdup.c: Likewise
|
||||
* stripslash.c: Likewise
|
||||
* tar.c: Likewise
|
||||
* tar.h: Likewise
|
||||
* tarhdr.h: Likewise
|
||||
* xmalloc.c: Likewise
|
||||
* xstrdup.c: Likewise
|
||||
|
||||
* makepath.c: Updated
|
||||
* mt.c: Likewise.
|
||||
* rmt.c: Likewise.
|
||||
* util.c: Likewise.
|
||||
* copyin.c: Likewise.
|
||||
* copyout.c: Likewise.
|
||||
* copypass.c: Likewise.
|
||||
* global.c: Likewise.
|
||||
* main.c: Likewise.
|
||||
|
||||
Thu Jun 13 20:14:48 2002 John Oleynick (juo@gnu.org)
|
||||
* copyin.c: Strip leading / on absolute filenames after
|
||||
comparing to the list of files specified on the command line
|
||||
(instead of before). Problem reported by Jeff Holt.
|
||||
* Version 2.5 released.
|
||||
|
||||
Thu Jun 13 00:20:30 2002 John Oleynick (juo@gnu.org)
|
||||
* Makefile.in: Fixed problem of looking in srcdir for info files.
|
||||
Bug reported by Mike Castle.
|
||||
* cpio.texi: Fixed typo. Problem reported by Fabrice Bauzac.
|
||||
|
||||
Sun Jan 13 18:45:02 2002 John Oleynick (juo@gnu.org)
|
||||
* copyin.c: Fixed a problem skipping files with multiple links
|
||||
in a newc or CRC format archive. If the file with the shared copy
|
||||
of the data was skipped, but other links were not skipped, the
|
||||
other links were created as empty files. Bug reported by
|
||||
Hendrik-Jan Thomassen.
|
||||
|
||||
Thu Dec 6 20:05:10 2001 John Oleynick (juo@gnu.org)
|
||||
* mt.c, mt.1: Merged Debian --rsh-command option and -V fix.
|
||||
* copyout.c, copypass.c, util.c, extern.h: Modified to warn
|
||||
if a file grows or its mtime is changed while it is being
|
||||
copied.
|
||||
|
||||
Wed Dec 6 00:02:04 2001 John Oleynick (juo@gnu.org)
|
||||
* Many files: Updated FSF's address in copyright notices.
|
||||
|
||||
Wed Aug 29 23:57:05 2001 John Oleynick (juo@gnu.org)
|
||||
* Many files: Numerous fixes from Debian, Red Hat and SuSE
|
||||
GNU/Linux distributions.
|
||||
|
||||
Tue Jan 16 19:03:05 1996 John Oleynick (juo@wombat.gnu.ai.mit.edu)
|
||||
* util.c: An I/O error reading a file would cause the last byte
|
||||
of the next file to be corrupted in the archive. Thanks to a
|
||||
@ -962,7 +1392,6 @@ Sat Dec 2 13:22:37 1989 David J. MacKenzie (djm at hobbes.ai.mit.edu)
|
||||
(usage): Mention long options in message.
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
left-margin: 8
|
||||
mode: change-log
|
||||
version-control: never
|
||||
End:
|
||||
|
231
contrib/cpio/INSTALL
Normal file
231
contrib/cpio/INSTALL
Normal file
@ -0,0 +1,231 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
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 only 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. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 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 must use a version of `make' that
|
||||
supports the `VPATH' variable, such as 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 `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', 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
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option 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
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
@ -1,3 +1,44 @@
|
||||
GNU cpio NEWS -- history of user-visible changes. 2004-12-20
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
See the end of file for copying conditions.
|
||||
|
||||
Please send cpio bug reports to <bug-cpio@gnu.org>.
|
||||
|
||||
Version 2.6
|
||||
|
||||
* Added NLS support
|
||||
|
||||
* Improved configure script
|
||||
|
||||
* Improved invocation consistency checking and help output
|
||||
|
||||
* Printing warning about truncation of inode numbers is suppressed by
|
||||
default. See below.
|
||||
|
||||
* New option --warning (-W) controls the level of output warnings:
|
||||
|
||||
-Wnone Disables all warnings
|
||||
-Wtruncate Enable warning about truncation of the inode number
|
||||
-Wall Enables all warnings
|
||||
|
||||
To disable a particular warning, prefix its name with 'no-', just
|
||||
like in gcc.
|
||||
|
||||
* New option --to-stdout extracts files to standard output.
|
||||
|
||||
* The output of `cpio --help' is largely improved.
|
||||
|
||||
* Bugfixes:
|
||||
** If a file grew n bytes in copy-pass mode, these n bytes got prepended
|
||||
to the contents of all subsequent files.
|
||||
** Padding the archive with zero bytes upon truncation of the file being
|
||||
archived was broken.
|
||||
|
||||
|
||||
Major changes in version 2.5:
|
||||
|
||||
* bug fixes from Debian, Red Hat, and SuSE GNU/Linux Distribution patches
|
||||
* --rsh-command option
|
||||
|
||||
Major changes in version 2.4:
|
||||
|
||||
@ -62,3 +103,23 @@ Some options have changed meaning in 2.0, for SVR4 compatibility:
|
||||
|
||||
Version 2.0 also fixes several bugs in the handling of files with
|
||||
multiple links and of multi-volume archives on floppy disks.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Copyright information:
|
||||
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to anyone to make or distribute verbatim copies
|
||||
of this document as received, in any medium, provided that the
|
||||
copyright notice and this permission notice are preserved,
|
||||
thus giving the recipient permission to redistribute in turn.
|
||||
|
||||
Permission is granted to distribute modified versions
|
||||
of this document, or of portions of it,
|
||||
under the above conditions, provided also that they
|
||||
carry prominent notices stating who last changed them.
|
||||
|
||||
Local variables:
|
||||
mode: outline
|
||||
paragraph-separate: "[ ]*$"
|
||||
end:
|
||||
|
@ -9,7 +9,8 @@ operations, respectively.
|
||||
|
||||
See the file INSTALL for compilation and installation instructions for Unix.
|
||||
|
||||
For non-Unix systems:
|
||||
For non-Unix systems [ Note: The non-Unix makefiles have not been tested
|
||||
for this release ]
|
||||
|
||||
makefile.pc is a makefile for Turbo C or C++ or Borland C++ on MS-DOS.
|
||||
|
||||
@ -67,5 +68,4 @@ than 100 characters. That's why it's not an official part of GNU tar.
|
||||
*stdp = 1;
|
||||
if (wantug) {
|
||||
|
||||
Mail suggestions and bug reports for GNU cpio to
|
||||
bug-gnu-utils@prep.ai.mit.edu.
|
||||
Mail suggestions and bug reports for GNU cpio to bug-cpio@gnu.org.
|
||||
|
14
contrib/cpio/THANKS
Normal file
14
contrib/cpio/THANKS
Normal file
@ -0,0 +1,14 @@
|
||||
GNU cpio THANKS file
|
||||
|
||||
GNU cpio has originally been written by Phil Nelson <phil@cs.wwu.edu>
|
||||
and David MacKenzie <djm@gnu.ai.mit.edu>. It was further modified
|
||||
by John Oleynick <juo@gnu.org> and Sergey Poznyakoff <gray@gnu.org>
|
||||
who currently maintains it.
|
||||
|
||||
The following is a list of people who contributed to GNU cpio by
|
||||
reporting problems, suggesting various improvements or submitting actual
|
||||
code. Help us keep it complete and exempt of errors.
|
||||
|
||||
Matthew Braithwaite <mab@cnet.com>
|
||||
Mitsuru Chinen <mchinen@yamato.ibm.com>
|
||||
Holger Fleischmann <holger_fleischmann@mra.man.de>
|
356
contrib/cpio/TODO
Normal file
356
contrib/cpio/TODO
Normal file
@ -0,0 +1,356 @@
|
||||
Following is the list of cpio-related reports to bug-gnu-utils.
|
||||
Many of them appear to be fixed, but quite a number of them is
|
||||
probably still waiting for being handled. The list is sorted
|
||||
in reverse chronological order.
|
||||
|
||||
4. copyin.c cpio probably questions/rfc (score: 35)
|
||||
Author: Grzegorz Jaskiewicz <gj@pointblue.com.pl>
|
||||
Date: Tue, 24 Jun 2003 17:12:45 +0100
|
||||
Hi! I am currently working on module that (in GNU software)
|
||||
will be able to read/write cpio format (only ascii). Thus i am
|
||||
separating some of cpio structures into libcpio. I've been
|
||||
going through cop
|
||||
/archive/html/bug-gnu-utils/2003-06/msg00422.html (5,430 bytes)
|
||||
|
||||
5. RE: Problem when building on HP-UX 11i(11.11) (score: 4)
|
||||
Author: "Leon Strydom" <leon.strydom@tasima.co.za>
|
||||
Date: Thu, 13 Mar 2003 09:10:02 +0200
|
||||
Hi Bob, I got it to compile, thanks. The reason why I had to
|
||||
try GNU-Tar is because of the 2GB file size limit problems:
|
||||
Here are the errors I got: With TAR(hp-ux 11i tar): CMD: tar
|
||||
cvf backup.tar /a
|
||||
/archive/html/bug-gnu-utils/2003-03/msg00106.html (5,191 bytes)
|
||||
|
||||
6. cpio - large file support (score: 35)
|
||||
Author: "Keith Ansell" <keitha@edp.fastfreenet.com>
|
||||
Date: Tue, 4 Mar 2003 16:24:37 -0000
|
||||
Can you help. I need to archive a large database, this will
|
||||
create a cpio file greater than 2 Gigabytes. Have you added
|
||||
large file support to the build of cpio. Regards Keith
|
||||
Ansell.....
|
||||
/archive/html/bug-gnu-utils/2003-03/msg00024.html (4,329 bytes)
|
||||
|
||||
7. cpio-2.5 typos (score: 36)
|
||||
Author: Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at>
|
||||
Date: Sat, 21 Dec 2002 23:53:38 +0100
|
||||
In cpio-2.5, in cpio.texi (and thus cpio.1) and main.c the word
|
||||
'compatibility' is misspelled as 'compatability'. Please fix,
|
||||
thanks. Thomas -- Thomas Klausner - wiz@bogus.example.com What
|
||||
is wanted
|
||||
/archive/html/bug-gnu-utils/2002-12/msg00200.html (3,783 bytes)
|
||||
|
||||
9. Re: bug in cpio with tapechange in copy-in-mode (score: 46)
|
||||
Author: Paul Eggert <eggert@twinsun.com>
|
||||
Date: Mon, 5 Aug 2002 12:28:33 -0700 (PDT)
|
||||
Thanks for your bug report. Can you please verify that the bug
|
||||
still exists in the latest CPIO version
|
||||
<ftp://ftp.gnu.org/gnu/cpio/cpio-2.5.tar.gz>, and if so, please
|
||||
send a patch to <bug-cpio@bogus.
|
||||
/archive/html/bug-gnu-utils/2002-08/msg00127.html (4,275 bytes)
|
||||
|
||||
10. bug in cpio with tapechange in copy-in-mode (score: 34)
|
||||
Author: Bernd =?ISO-8859-1?Q?Sch=FCler?=
|
||||
<b.schueler@eckert-buerotechnik.de>
|
||||
Date: 05 Aug 2002 18:37:56 +0200
|
||||
Hello, last i made a restore from tape, and no request for next
|
||||
tape happend, only an read-error occured. Here is an quick
|
||||
patch, please verify the problem and the patch-code. I'm not
|
||||
sure, if the pr
|
||||
/archive/html/bug-gnu-utils/2002-08/msg00122.html (4,518 bytes)
|
||||
|
||||
11. Re: CPIO Bug ? (score: 36)
|
||||
Author: Albert Chin <bug-gnu-utils@lists.thewrittenword.com>
|
||||
Date: Thu, 4 Jul 2002 19:31:04 -0500
|
||||
I think the default CPIO format understands only 16-bit inodes.
|
||||
Look at the -H option. '-H newc' should work better for you. --
|
||||
albert chin (china@bogus.example.com)
|
||||
/archive/html/bug-gnu-utils/2002-07/msg00091.html (4,286 bytes)
|
||||
|
||||
14. Re: bug in cpio? (score: 40)
|
||||
Author: kasal@matsrv.math.cas.cz (Stepan Kasal)
|
||||
Date: Thu, 13 Jun 2002 07:44:14 +0000 (UTC)
|
||||
Hallo, the following option should help: -d, --make-directories
|
||||
Create leading directories where needed. Details: cpio won't
|
||||
create the directory for the file. Observe: kasal$ echo
|
||||
/home/kasal/tmp/db
|
||||
/archive/html/bug-gnu-utils/2002-06/msg00306.html (4,862 bytes)
|
||||
|
||||
15. bug in cpio? (score: 34)
|
||||
Author: "Jeff Holt" <jeff.holt@hotsos.com>
|
||||
Date: Wed, 12 Jun 2002 14:07:59 -0500
|
||||
According to the man page, I should be able to extract an
|
||||
absolute pathname from an archive and have the file created
|
||||
relative to the current directory (by removing the leading
|
||||
‘/’).<o:p>
|
||||
/archive/html/bug-gnu-utils/2002-06/msg00296.html (5,331 bytes)
|
||||
|
||||
16. CPIO Bug ? (score: 35)
|
||||
Author: =?iso-8859-1?Q?Gr=E9goire_Fiot?=
|
||||
<gfiot@eiffageconstruction.fr>
|
||||
Date: Tue, 14 May 2002 17:01:18 +0200
|
||||
Hello, We ve got a problem here using cpio: many "troncating
|
||||
inode number" appear during the process: cpio -ocv Is that a
|
||||
real problem? Does it corrupt files? Well.. what does that
|
||||
mean? We have look
|
||||
/archive/html/bug-gnu-utils/2002-05/msg00333.html (3,855 bytes)
|
||||
|
||||
23. [cpio texinfo] typo (score: 2)
|
||||
Author: fabrice bauzac <fabrice.bauzac@wanadoo.fr>
|
||||
Date: Tue, 7 May 2002 16:37:28 +0200
|
||||
Good afternoon, There is a typo in the Texinfo documentation of
|
||||
GNU cpio, node "Copy-in mode": [--format=format]
|
||||
[--owner=[user][:.][group]] [--no- preserve-owner]
|
||||
[--message=message] [--help] [--ver
|
||||
/archive/html/bug-gnu-utils/2002-05/msg00153.html (4,040 bytes)
|
||||
|
||||
26. cpio: memory exhausted (score: 43)
|
||||
Author: Thomas McLaughlin <tamm@scotlegal.com>
|
||||
Date: Thu, 18 Apr 2002 09:51:18 +0100
|
||||
This is probably not the place for my query, but I have
|
||||
exhausted other avenues and would be glad of some help. I can't
|
||||
work out what's going on with my nightly cpio backup. If I do:
|
||||
cd / find . -pri
|
||||
/archive/html/bug-gnu-utils/2002-04/msg00406.html (4,988 bytes)
|
||||
|
||||
30. cpio 2.4.2 bug? (score: 40)
|
||||
Author: "H.J. Thomassen" <H.J.Thomassen@ATComputing.nl>
|
||||
Date: Thu, 10 Jan 2002 18:09:10 +0100 (CET)
|
||||
Hello, We use GNU-cpio 2.4.2 and have the following problem:
|
||||
Short: Assume I have a directory with two filenames, which are
|
||||
hardlinks to the same i-node. I make a crc-cpio archive with
|
||||
both files; th
|
||||
/archive/html/bug-gnu-utils/2002-01/msg00161.html (5,624 bytes)
|
||||
|
||||
32. GNU cpio suggestion (score: 42)
|
||||
Author: "H.J.Thomassen" <hjt@ATComputing.nl>
|
||||
Date: Mon, 17 Dec 2001 11:27:11 +0100
|
||||
Re: suggestion for GNU-cpio extension (plus reference
|
||||
implementation) We use cpio for our backup purposes. The backup
|
||||
is started automatically in the middle of the night. To chase
|
||||
away all users we d
|
||||
/archive/html/bug-gnu-utils/2001-12/msg00244.html (7,474 bytes)
|
||||
|
||||
35. GNU cpio compile problem (score: 34)
|
||||
Author: Daniel Savard <dsavard@videotron.ca>
|
||||
Date: Wed, 14 Nov 2001 12:43:11 -0500
|
||||
Hi, I am trying to make the GNU cpio utility (version 2.4.2)
|
||||
using the gcc 3.0.2 compiler. The make failed on the userspec.c
|
||||
file compilation. I then tried to compile with gcc 2.95.3 with
|
||||
the followi
|
||||
/archive/html/bug-gnu-utils/2001-11/msg00180.html (5,518 bytes)
|
||||
|
||||
36. cpio -d bug (fwd) (score: 47)
|
||||
Author: Christian Smith <csmith@micromuse.com>
|
||||
Date: Wed, 14 Nov 2001 02:06:46 +0000 (GMT)
|
||||
This was bounced from bug-cpio@bogus.example.com I guess that
|
||||
isn't set up yet. -- /"\ \ / ASCII RIBBON CAMPAIGN - AGAINST
|
||||
HTML MAIL X - AGAINST MS ATTACHMENTS / \ $ cpio --version GNU
|
||||
cpio version 2
|
||||
/archive/html/bug-gnu-utils/2001-11/msg00170.html (4,548 bytes)
|
||||
|
||||
38. [cpio] man page enhancement: a Example section ? (score: 5)
|
||||
Author: Yannick Patois <patois@calvix.org>
|
||||
Date: Wed, 24 Oct 2001 12:48:33 +0200 (CEST)
|
||||
Hello, I seldom use cpio (as I think many people) and only had
|
||||
to use it once or twice. IMHA, would be good to have a small
|
||||
section with an example of most often performed actions
|
||||
(creating an archiv
|
||||
/archive/html/bug-gnu-utils/2001-10/msg00270.html (4,336 bytes)
|
||||
|
||||
39. Patch to cpio to enable verbose *skipping* of files (score: 40)
|
||||
Author: Tomas Pospisek <tpo@sourcepole.ch>
|
||||
Date: Mon, 8 Oct 2001 13:54:14 +0200 (CEST)
|
||||
This patch enables cpio to be verbose about the files that it
|
||||
does not copy, which is very handy for seeing cpio's progress
|
||||
through a tape or simply for debuging. The patch along with a
|
||||
Debian packag
|
||||
/archive/html/bug-gnu-utils/2001-10/msg00083.html (4,548 bytes)
|
||||
|
||||
40. cpio-2.4.2 patch (score: 39)
|
||||
Author: Alex Efros <powerman@sky.net.ua>
|
||||
Date: Wed, 29 Aug 2001 07:36:31 +0300 (EEST)
|
||||
Hi. Linux-2.4.9, GCC-3.0, GLIBC-2.2.4, cpio-2.4.2. Compile-time
|
||||
errors: --cut-- gcc -c -DRETSIGTYPE=void -DHAVE_SYS_MTIO_H=1
|
||||
-DHAVE_NETDB_H=1 -DSTDC_HEADERS=1 -DHAVE_UNISTD_H=1
|
||||
-DHAVE_STRING_H=1 -DHA
|
||||
/archive/html/bug-gnu-utils/2001-08/msg00264.html (5,259 bytes)
|
||||
|
||||
41. cpio copy-in and multiply-linked files (score: 35)
|
||||
Author: Chris Jaeger <cjaeger@ensim.com>
|
||||
Date: Tue, 07 Aug 2001 23:46:04 -0700
|
||||
Hi, I was wondering whether it was a bug or a feature that GNU
|
||||
cpio, while in copy-in mode, will create a multiply-linked set
|
||||
of files all of size 0 if the last linked file is not copied in
|
||||
due to th
|
||||
/archive/html/bug-gnu-utils/2001-08/msg00074.html (4,142 bytes)
|
||||
|
||||
42. Re: minor problems with slackware-current (score: 7)
|
||||
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
||||
Date: Wed, 1 Aug 2001 10:43:37 +0200
|
||||
"cpio --sparse" corrupts data. A fix attached. C.S. Attachment:
|
||||
cpio-2.4.2-sparse.diff Description: Text document
|
||||
/archive/html/bug-gnu-utils/2001-08/msg00000.html (3,989 bytes)
|
||||
|
||||
43. (no subject) (score: 2)
|
||||
Author: brian@debian.org (Brian Mays)
|
||||
Date: Sat, 07 Jul 2001 16:35:13 -0400
|
||||
When hard-linked files (along with many other files) are
|
||||
archived to a cpio ustar format archive, the files are _not_
|
||||
all archived as hard links to each other in the archive. When
|
||||
the same set of fil
|
||||
/archive/html/bug-gnu-utils/2001-07/msg00080.html (5,666 bytes)
|
||||
|
||||
44. gnu cpio and files over 2G (score: 37)
|
||||
Author: J.S.Peatfield@damtp.cam.ac.uk
|
||||
Date: Wed, 2 May 2001 06:28:18 +0100
|
||||
As an increasing number of opertaing systems now support files
|
||||
over 2G I took a look at the cpio (2.4.2) source to see how
|
||||
hard it would be to make it cope, and was slightly shocked at
|
||||
the number of
|
||||
/archive/html/bug-gnu-utils/2001-05/msg00010.html (4,802 bytes)
|
||||
|
||||
45. cpio suggestion + patch (score: 38)
|
||||
Author: Taylor Gautier <tgautier@s8.com>
|
||||
Date: Fri, 20 Apr 2001 09:40:05 -0700
|
||||
I have a suggestion for cpio. The suggestion is to make it copy
|
||||
files into a temporary name and then rename the file as the
|
||||
last operation. Since UNIX filesystems are supposed to
|
||||
gaurantee atomicity
|
||||
/archive/html/bug-gnu-utils/2001-04/msg00169.html (10,674
|
||||
bytes)
|
||||
|
||||
46. [cpio 2.4.2] rmt build fails (score: 8)
|
||||
Author: Gert <n8w8@n8w8.wox.org>
|
||||
Date: Thu, 29 Mar 2001 21:28:52 +0200 (CEST)
|
||||
Hi, The cpio 2.4.2 rmt tool fails to build on my system. I run
|
||||
the following software: - Linux 2.4.2 - GCC 2.95.2 - GNU Make
|
||||
3.79.1 - GNU ld 2.10 (with BFD 2.10) - glibc 2.1.3 The build
|
||||
fails like th
|
||||
/archive/html/bug-gnu-utils/2001-03/msg00262.html (5,498 bytes)
|
||||
|
||||
47. cpio --sparse (score: 34)
|
||||
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
||||
Date: Mon, 26 Mar 2001 10:43:34 +0200 (CEST)
|
||||
the '--sparse' option of gnu cpio causes data corruption
|
||||
(blocks of zeros are lost or appended to other files). C.S.
|
||||
/archive/html/bug-gnu-utils/2001-03/msg00235.html (3,671 bytes)
|
||||
|
||||
49. Re: bug with gnu cpio 2.4.2 (score: 38)
|
||||
Author: Hans-Bernhard Broeker <broeker@physik.rwth-aachen.de>
|
||||
Date: 6 Mar 2001 15:19:34 GMT
|
||||
This would happen if cpio want to do any user interaction (ask
|
||||
for the next tape cartridge, because the current one is full,
|
||||
e.g.). Cron jobs don't have access to a terminal (/dev/tty), so
|
||||
this will
|
||||
/archive/html/bug-gnu-utils/2001-03/msg00029.html (5,062 bytes)
|
||||
|
||||
50. bug with gnu cpio 2.4.2 (score: 37)
|
||||
Author: dominique.bieber@sagem.com
|
||||
Date: Tue, 6 Mar 2001 12:27:14 +0100
|
||||
Hi, I have a problem using cpio with a Red Hat 6.2 whith a
|
||||
2.2.14-5.0smp kernel. The backup device is a HP DAT DDS4 20/40
|
||||
with the right cartridge. The cpio is launched by the cron.
|
||||
During the backup
|
||||
/archive/html/bug-gnu-utils/2001-03/msg00024.html (4,315 bytes)
|
||||
|
||||
52. [PATCH] cpio 2.4.2 does not compile with libc 2.2, gcc 2.95
|
||||
(score: 38)
|
||||
Author: "John Fremlin" <chief@bandits.org>
|
||||
Date: 11 Feb 2001 22:19:09 +0000
|
||||
In fact it violates the GNU coding standards by declaring stuff
|
||||
when it shouldn't. Tsk, tsk. Attachment: cpio-2.4.2-build.patch
|
||||
Description: Text Data -- http://www.penguinpowered.com/~vii
|
||||
/archive/html/bug-gnu-utils/2001-02/msg00065.html (4,169 bytes)
|
||||
|
||||
53. cpio-2.4.2: data corruption bug (score: 35)
|
||||
Author: Todd Kelley <toddk@oeone.com>
|
||||
Date: Fri, 09 Feb 2001 17:00:06 -0500
|
||||
Hello, Recently at OEone we fixed a bug in GNU cpio-2.4.2: When
|
||||
a file over about 0.5 megabyes grows while it is being
|
||||
archived, it and all files following it in the archive are
|
||||
corrupted. The crc do
|
||||
/archive/html/bug-gnu-utils/2001-02/msg00062.html (4,297 bytes)
|
||||
|
||||
54. cpio 2.4.2 unconditionally takes the tape drive offline (score:
|
||||
39)
|
||||
Author: Scott Larson <scowl@plaza.ds.adp.com>
|
||||
Date: Thu, 11 Jan 2001 13:15:52 -0800
|
||||
We have been copying multiple volumes to a single tape with the
|
||||
System 5 version of cpio. The gnu version of cpio doesn't
|
||||
support this since it takes the tape offline (i.e. ejects the
|
||||
tape) after rea
|
||||
/archive/html/bug-gnu-utils/2001-01/msg00087.html (4,264 bytes)
|
||||
|
||||
55. cpio -t can see international filenames, find -ls also suffers
|
||||
(score: 35)
|
||||
Author: "Dan Jacobson" <jidanni@kimo.FiXcomTHiS.tw>
|
||||
Date: Tue, 26 Dec 2000 07:38:53 +0800
|
||||
GNU cpio version 2.4.2 with cpio -t I can see Chinese [big5]
|
||||
filenames. with -tv, they become \267\247 etc Just like what
|
||||
happens with find . -print vs. find . -ls --
|
||||
http://www.geocities.com/jidanni
|
||||
/archive/html/bug-gnu-utils/2000-12/msg00143.html (4,084 bytes)
|
||||
|
||||
56. cpio-2.4.2 compilation problems (score: 34)
|
||||
Author: Thomas =?iso-8859-1?q?K=F6ller?= <tkoeller@gmx.net>
|
||||
Date: Wed, 20 Dec 2000 02:50:24 +0100
|
||||
I encountered several problems building cpio-2.4.2. I am
|
||||
running linux-2.2.17, glibc-2.1.3 and gcc 2.95.2. The errors I
|
||||
received were mostly due to the source files re-declaring
|
||||
things unconditionall
|
||||
/archive/html/bug-gnu-utils/2000-12/msg00109.html (5,782 bytes)
|
||||
|
||||
58. cpio-2.4.2 & glibc-2.* (score: 46)
|
||||
Author: Florian Wunderlich <fwunderlich@devbrain.de>
|
||||
Date: Mon, 18 Dec 2000 16:25:00 +0100
|
||||
I still do not see a new version of cpio or at least extra
|
||||
patches that fix it so it works with the glibc. Thus, here is a
|
||||
simple patch to make it compile with glibc: diff -u
|
||||
cpio-2.4.2-old/rmt.c cpi
|
||||
/archive/html/bug-gnu-utils/2000-12/msg00098.html (4,846 bytes)
|
||||
|
||||
60. cpio-2.4.2 signed-unsigned int disagreement with malloc (score:
|
||||
39)
|
||||
Author: Antonomasia <ant@notatla.demon.co.uk>
|
||||
Date: Mon, 27 Nov 2000 07:05:01 GMT
|
||||
copyin.c: 534 link_name = (char *) xmalloc ((unsigned int)
|
||||
file_hdr.c_filesize + 1); 535 link_name[file_hdr.c_filesize] =
|
||||
'\0'; file_hdr.c_filesize can be a large negative number as
|
||||
seen here then th
|
||||
/archive/html/bug-gnu-utils/2000-11/msg00171.html (4,718 bytes)
|
||||
|
||||
61. gnu CPIO (score: 38)
|
||||
Author: Clark Cooper <Clark.Cooper@vc3.com>
|
||||
Date: Mon, 13 Nov 2000 13:21:07 -0500 (EST)
|
||||
The gnu version of CPIO appears to send all output to stderr.
|
||||
Take for instance a need to have the list of files copied and
|
||||
any errors separated as should be produced by the following:
|
||||
find . -print
|
||||
/archive/html/bug-gnu-utils/2000-11/msg00089.html (3,903 bytes)
|
||||
|
||||
62. Desire enhancement to GNU cpio 2.4.2 (score: 35)
|
||||
Author: Dave Dykstra <dwd@bell-labs.com>
|
||||
Date: Mon, 13 Nov 2000 10:24:56 -0600
|
||||
I have a new GNU/Linux system with large disks on which I need
|
||||
to generate cpio files for many different systems including
|
||||
older ones that don't support the "newc" format, only the "odc"
|
||||
format. The
|
||||
/archive/html/bug-gnu-utils/2000-11/msg00087.html (5,115 bytes)
|
||||
|
||||
65. cpio pass-through can corrupt files (score: 36)
|
||||
Author: "Parrott, Jeff" <Jeff.Parrott@sea.siemens.com>
|
||||
Date: Mon, 16 Oct 2000 13:32:57 -0400
|
||||
I have seen corrupted files as a result of using the
|
||||
pass-through option in cpio. The corruption occurs when
|
||||
active/in-use (and growing) files are being copied. The problem
|
||||
is that the file size has
|
||||
/archive/html/bug-gnu-utils/2000-10/msg00087.html (4,974 bytes)
|
||||
|
||||
66. [Bug-gnu-utils] A small problem with cpio (score: 36)
|
||||
Author: Chris Hall <Chris@clapham.org>
|
||||
Date: Fri, 15 Sep 2000 11:05:56 +0100
|
||||
Hi, I'm running cpio 2.4.2 on AIX 4.3.3 and have a problem with
|
||||
very large files, I get this output when running the command: $
|
||||
ls -l total 2867988 drwxrwxrwx 2 root sys 512 Sep 14 17:05
|
||||
chris/ -rw-r
|
||||
/archive/html/bug-gnu-utils/2000-09/msg00004.html (4,481 bytes)
|
41
contrib/cpio/doc/cpio.1
Normal file
41
contrib/cpio/doc/cpio.1
Normal file
@ -0,0 +1,41 @@
|
||||
.TH CPIO 1L \" -*- nroff -*-
|
||||
.SH NAME
|
||||
cpio \- copy files to and from archives
|
||||
.SH SYNOPSIS
|
||||
.B cpio
|
||||
{\-o|\-\-create} [\-0acvABLV] [\-C bytes] [\-H format] [\-M message]
|
||||
[\-O [[user@]host:]archive] [\-F [[user@]host:]archive]
|
||||
[\-\-file=[[user@]host:]archive] [\-\-format=format] [\-\-message=message]
|
||||
[\-\-null] [\-\-reset-access-time] [\-\-verbose] [\-\-dot] [\-\-append]
|
||||
[\-\-block-size=blocks] [\-\-dereference] [\-\-io-size=bytes] [\-\-quiet]
|
||||
[\-\-force\-local] [\-\-rsh-command=command] [\-\-help] [\-\-version]
|
||||
< name-list [> archive]
|
||||
|
||||
.B cpio
|
||||
{\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format]
|
||||
[\-M message] [\-R [user][:.][group]] [\-I [[user@]host:]archive]
|
||||
[\-F [[user@]host:]archive] [\-\-file=[[user@]host:]archive]
|
||||
[\-\-make-directories] [\-\-nonmatching] [\-\-preserve-modification-time]
|
||||
[\-\-numeric-uid-gid] [\-\-rename] [\-t|\-\-list] [\-\-swap-bytes] [\-\-swap] [\-\-dot]
|
||||
[\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords]
|
||||
[\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format]
|
||||
[\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
|
||||
[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse]
|
||||
[\-\-only\-verify\-crc] [\-\-quiet] [\-\-rsh-command=command] [\-\-help]
|
||||
[\-\-version] [pattern...] [< archive]
|
||||
|
||||
.B cpio
|
||||
{\-p|\-\-pass-through} [\-0adlmuvLV] [\-R [user][:.][group]]
|
||||
[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link] [\-\-quiet]
|
||||
[\-\-preserve-modification-time] [\-\-unconditional] [\-\-verbose] [\-\-dot]
|
||||
[\-\-dereference] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner]
|
||||
[\-\-sparse] [\-\-help] [\-\-version] destination-directory < name-list
|
||||
.SH DESCRIPTION
|
||||
GNU cpio is fully documented in the texinfo documentation. To access the
|
||||
help from your command line, type
|
||||
.PP
|
||||
\fBinfo cpio
|
||||
.PP
|
||||
The online copy of the documentation is available at the following address:
|
||||
.PP
|
||||
http://www.gnu.org/software/cpio/manual
|
563
contrib/cpio/doc/cpio.texi
Normal file
563
contrib/cpio/doc/cpio.texi
Normal file
@ -0,0 +1,563 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename cpio.info
|
||||
@settitle cpio
|
||||
@setchapternewpage off
|
||||
@set VERSION GNU cpio 2.5
|
||||
@set RELEASEDATE June 2002
|
||||
@c %**end of header
|
||||
|
||||
@ifinfo
|
||||
@format
|
||||
START-INFO-DIR-ENTRY
|
||||
* cpio: (cpio). Making tape (or disk) archives.
|
||||
END-INFO-DIR-ENTRY
|
||||
@end format
|
||||
@end ifinfo
|
||||
|
||||
@ifinfo
|
||||
This file documents @value{VERSION}.
|
||||
|
||||
Copyright (C) 1995, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
|
||||
|
||||
@end ignore
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
@end ifinfo
|
||||
|
||||
|
||||
@titlepage
|
||||
@title GNU CPIO
|
||||
@subtitle @value{VERSION} @value{RELEASEDATE}
|
||||
@author by Robert Carleton
|
||||
@c copyright page
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1995, 2001, 2002 Free Software Foundation, Inc.
|
||||
@sp 2
|
||||
This is the first edition of the GNU cpio documentation,@*
|
||||
and is consistent with @value{VERSION}.@*
|
||||
@sp 2
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place - Suite 330, @*
|
||||
Boston, MA 02111-1307, USA @*
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation
|
||||
approved by the Free Software Foundation.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top, Introduction, (dir), (dir)
|
||||
@comment node-name, next, previous, up
|
||||
@top
|
||||
|
||||
GNU cpio is a tool for creating and extracting archives, or copying
|
||||
files from one place to another. It handles a number of cpio formats as
|
||||
well as reading and writing tar files. This is the first edition of the
|
||||
GNU cpio documentation and is consistant with @value{VERSION}.
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
* Tutorial:: Getting started.
|
||||
* Invoking `cpio':: How to invoke `cpio'.
|
||||
* Media:: Using tapes and other archive media.
|
||||
* Concept Index:: Concept index.
|
||||
|
||||
--- The Detailed Node Listing ---
|
||||
|
||||
Invoking cpio
|
||||
|
||||
* Copy-out mode::
|
||||
* Copy-in mode::
|
||||
* Copy-pass mode::
|
||||
* Options::
|
||||
@end menu
|
||||
|
||||
@end ifinfo
|
||||
|
||||
@node Introduction, Tutorial, Top, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Introduction
|
||||
|
||||
GNU cpio copies files into or out of a cpio or tar archive, The archive
|
||||
can be another file on the disk, a magnetic tape, or a pipe.
|
||||
|
||||
GNU cpio supports the following archive formats: binary, old ASCII, new
|
||||
ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The
|
||||
tar format is provided for compatability with the tar program. By
|
||||
default, cpio creates binary format archives, for compatibility with
|
||||
older cpio programs. When extracting from archives, cpio automatically
|
||||
recognizes which kind of archive it is reading and can read archives
|
||||
created on machines with a different byte-order.
|
||||
|
||||
@node Tutorial, Invoking `cpio', Introduction, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Tutorial
|
||||
@cindex creating a cpio archive
|
||||
@cindex extracting a cpio archive
|
||||
@cindex copying directory structures
|
||||
@cindex passing directory structures
|
||||
|
||||
|
||||
GNU cpio performs three primary functions. Copying files to an
|
||||
archive, Extracting files from an archive, and passing files to another
|
||||
directory tree. An archive can be a file on disk, one or more floppy
|
||||
disks, or one or more tapes.
|
||||
|
||||
When creating an archive, cpio takes the list of files to be processed
|
||||
from the standard input, and then sends the archive to the standard
|
||||
output, or to the device defined by the @samp{-F} option.
|
||||
@xref{Copy-out mode}. Usually find or ls is used to provide this list
|
||||
to the standard input. In the following example you can see the
|
||||
possibilities for archiving the contents of a single directory.
|
||||
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% ls | cpio -ov > directory.cpio
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
The @samp{-o} option creates the archive, and the @samp{-v} option
|
||||
prints the names of the files archived as they are added. Notice that
|
||||
the options can be put together after a single @samp{-} or can be placed
|
||||
separately on the command line. The @samp{>} redirects the cpio output
|
||||
to the file @samp{directory.cpio}.
|
||||
|
||||
|
||||
If you wanted to archive an entire directory tree, the find command can
|
||||
provide the file list to cpio:
|
||||
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% find . -print -depth | cpio -ov > tree.cpio
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
|
||||
This will take all the files in the current directory, the directories
|
||||
below and place them in the archive tree.cpio. Again the @samp{-o}
|
||||
creates an archive, and the @samp{-v} option shows you the name of the
|
||||
files as they are archived. @xref{Copy-out mode}. Using the `.' in the
|
||||
find statement will give you more flexibility when doing restores, as it
|
||||
will save file names with a relative path vice a hard wired, absolute
|
||||
path. The @samp{-depth} option forces @samp{find} to print of the
|
||||
entries in a directory before printing the directory itself. This
|
||||
limits the effects of restrictive directory permissions by printing the
|
||||
directory entries in a directory before the directory name itself.
|
||||
|
||||
|
||||
|
||||
|
||||
Extracting an archive requires a bit more thought because cpio will not
|
||||
create directories by default. Another characteristic, is it will not
|
||||
overwrite existing files unless you tell it to.
|
||||
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% cpio -iv < directory.cpio
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
This will retrieve the files archived in the file directory.cpio and
|
||||
place them in the present directory. The @samp{-i} option extracts the
|
||||
archive and the @samp{-v} shows the file names as they are extracted.
|
||||
If you are dealing with an archived directory tree, you need to use the
|
||||
@samp{-d} option to create directories as necessary, something like:
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% cpio -idv < tree.cpio
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
This will take the contents of the archive tree.cpio and extract it to
|
||||
the current directory. If you try to extract the files on top of files
|
||||
of the same name that already exist (and have the same or later
|
||||
modification time) cpio will not extract the file unless told to do so
|
||||
by the -u option. @xref{Copy-in mode}.
|
||||
|
||||
|
||||
In copy-pass mode, cpio copies files from one directory tree to another,
|
||||
combining the copy-out and copy-in steps without actually using an
|
||||
archive. It reads the list of files to copy from the standard input;
|
||||
the directory into which it will copy them is given as a non-option
|
||||
argument. @xref{Copy-pass mode}.
|
||||
|
||||
@example
|
||||
@cartouche
|
||||
% find . -depth -print0 | cpio --null -pvd new-dir
|
||||
@end cartouche
|
||||
@end example
|
||||
|
||||
|
||||
The example shows copying the files of the present directory, and
|
||||
sub-directories to a new directory called new-dir. Some new options are
|
||||
the @samp{-print0} available with GNU find, combined with the
|
||||
@samp{--null} option of cpio. These two options act together to send
|
||||
file names between find and cpio, even if special characters are
|
||||
embedded in the file names. Another is @samp{-p}, which tells cpio to
|
||||
pass the files it finds to the directory @samp{new-dir}.
|
||||
|
||||
@node Invoking `cpio', Media, Tutorial, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Invoking cpio
|
||||
@cindex invoking cpio
|
||||
@cindex command line options
|
||||
|
||||
@menu
|
||||
* Copy-out mode::
|
||||
* Copy-in mode::
|
||||
* Copy-pass mode::
|
||||
* Options::
|
||||
@end menu
|
||||
|
||||
@node Copy-out mode, Copy-in mode, Invoking `cpio', Invoking `cpio'
|
||||
@comment node-name, next, previous, up
|
||||
@section Copy-out mode
|
||||
|
||||
In copy-out mode, cpio copies files into an archive. It reads a list
|
||||
of filenames, one per line, on the standard input, and writes the
|
||||
archive onto the standard output. A typical way to generate the list
|
||||
of filenames is with the find command; you should give find the -depth
|
||||
option to minimize problems with permissions on directories that are
|
||||
unreadable.
|
||||
@xref{Options}.
|
||||
|
||||
@example
|
||||
cpio @{-o|--create@} [-0acvABLV] [-C bytes] [-H format]
|
||||
[-M message] [-O [[user@@]host:]archive] [-F [[user@@]host:]archive]
|
||||
[--file=[[user@@]host:]archive] [--format=format]
|
||||
[--message=message][--null] [--reset-access-time] [--verbose]
|
||||
[--dot] [--append] [--block-size=blocks] [--dereference]
|
||||
[--io-size=bytes] [--rsh-command=command] [--help] [--version]
|
||||
< name-list [> archive]
|
||||
@end example
|
||||
|
||||
@node Copy-in mode, Copy-pass mode, Copy-out mode, Invoking `cpio'
|
||||
@comment node-name, next, previous, up
|
||||
@section Copy-in mode
|
||||
|
||||
In copy-in mode, cpio copies files out of an archive or lists the
|
||||
archive contents. It reads the archive from the standard input. Any
|
||||
non-option command line arguments are shell globbing patterns; only
|
||||
files in the archive whose names match one or more of those patterns are
|
||||
copied from the archive. Unlike in the shell, an initial `.' in a
|
||||
filename does match a wildcard at the start of a pattern, and a `/' in a
|
||||
filename can match wildcards. If no patterns are given, all files are
|
||||
extracted. @xref{Options}.
|
||||
|
||||
@example
|
||||
cpio @{-i|--extract@} [-bcdfmnrtsuvBSV] [-C bytes] [-E file]
|
||||
[-H format] [-M message] [-R [user][:.][group]]
|
||||
[-I [[user@@]host:]archive] [-F [[user@@]host:]archive]
|
||||
[--file=[[user@@]host:]archive] [--make-directories]
|
||||
[--nonmatching] [--preserve-modification-time]
|
||||
[--numeric-uid-gid] [--rename] [--list] [--swap-bytes] [--swap]
|
||||
[--dot] [--unconditional] [--verbose] [--block-size=blocks]
|
||||
[--swap-halfwords] [--io-size=bytes] [--pattern-file=file]
|
||||
[--format=format] [--owner=[user][:.][group]]
|
||||
[--no-preserve-owner] [--message=message] [--help] [--version]
|
||||
[-no-absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
|
||||
[--rsh-command=command] [pattern...] [< archive]
|
||||
@end example
|
||||
|
||||
@node Copy-pass mode, Options, Copy-in mode, Invoking `cpio'
|
||||
@comment node-name, next, previous, up
|
||||
@section Copy-pass mode
|
||||
|
||||
In copy-pass mode, cpio copies files from one directory tree to
|
||||
another, combining the copy-out and copy-in steps without actually
|
||||
using an archive. It reads the list of files to copy from the
|
||||
standard input; the directory into which it will copy them is given as
|
||||
a non-option argument.
|
||||
@xref{Options}.
|
||||
|
||||
@example
|
||||
cpio @{-p|--pass-through@} [-0adlmuvLV] [-R [user][:.][group]]
|
||||
[--null] [--reset-access-time] [--make-directories] [--link]
|
||||
[--preserve-modification-time] [--unconditional] [--verbose]
|
||||
[--dot] [--dereference] [--owner=[user][:.][group]] [--sparse]
|
||||
[--no-preserve-owner] [--help] [--version] destination-directory
|
||||
< name-list
|
||||
@end example
|
||||
|
||||
|
||||
|
||||
@node Options, , Copy-pass mode, Invoking `cpio'
|
||||
@comment node-name, next, previous, up
|
||||
@section Options
|
||||
|
||||
|
||||
@table @code
|
||||
|
||||
|
||||
@item -0, --null
|
||||
Read a list of filenames terminated by a null character, instead of a
|
||||
newline, so that files whose names contain newlines can be archived.
|
||||
GNU find is one way to produce a list of null-terminated filenames.
|
||||
This option may be used in copy-out and copy-pass modes.
|
||||
|
||||
@item -a, --reset-access-time
|
||||
Reset the access times of files after reading them, so
|
||||
that it does not look like they have just been read.
|
||||
|
||||
@item -A, --append
|
||||
Append to an existing archive. Only works in copy-out
|
||||
mode. The archive must be a disk file specified with
|
||||
the -O or -F (--file) option.
|
||||
|
||||
@item -b, --swap
|
||||
Swap both halfwords of words and bytes of halfwords in the data.
|
||||
Equivalent to -sS. This option may be used in copy-in mode. Use this
|
||||
option to convert 32-bit integers between big-endian and little-endian
|
||||
machines.
|
||||
|
||||
@item -B
|
||||
Set the I/O block size to 5120 bytes. Initially the
|
||||
block size is 512 bytes.
|
||||
|
||||
@item --block-size=BLOCK-SIZE
|
||||
Set the I/O block size to BLOCK-SIZE * 512 bytes.
|
||||
|
||||
@item -c
|
||||
Use the old portable (ASCII) archive format.
|
||||
|
||||
@item -C IO-SIZE, --io-size=IO-SIZE
|
||||
Set the I/O block size to IO-SIZE bytes.
|
||||
|
||||
@item -d, --make-directories
|
||||
Create leading directories where needed.
|
||||
|
||||
@item -E FILE, --pattern-file=FILE
|
||||
Read additional patterns specifying filenames to extract or list from
|
||||
FILE. The lines of FILE are treated as if they had been non-option
|
||||
arguments to cpio. This option is used in copy-in mode,
|
||||
|
||||
@item -f, --nonmatching
|
||||
Only copy files that do not match any of the given
|
||||
patterns.
|
||||
|
||||
@item -F, --file=archive
|
||||
Archive filename to use instead of standard input or output. To use a
|
||||
tape drive on another machine as the archive, use a filename that starts
|
||||
with `HOSTNAME:'. The hostname can be preceded by a username and an
|
||||
`@@' to access the remote tape drive as that user, if you have
|
||||
permission to do so (typically an entry in that user's `~/.rhosts'
|
||||
file).
|
||||
|
||||
@item --force-local
|
||||
With -F, -I, or -O, take the archive file name to be a
|
||||
local file even if it contains a colon, which would
|
||||
ordinarily indicate a remote host name.
|
||||
|
||||
@item -H FORMAT, --format=FORMAT
|
||||
Use archive format FORMAT. The valid formats are listed below; the same
|
||||
names are also recognized in all-caps. The default in copy-in mode is
|
||||
to automatically detect the archive format, and in copy-out mode is
|
||||
@samp{bin}.
|
||||
|
||||
@table @samp
|
||||
@item bin
|
||||
The obsolete binary format.
|
||||
|
||||
@item odc
|
||||
The old (POSIX.1) portable format.
|
||||
|
||||
@item newc
|
||||
The new (SVR4) portable format, which supports file systems having more
|
||||
than 65536 i-nodes.
|
||||
|
||||
@item crc
|
||||
The new (SVR4) portable format with a checksum added.
|
||||
|
||||
@item tar
|
||||
The old tar format.
|
||||
|
||||
@item ustar
|
||||
The POSIX.1 tar format. Also recognizes GNU tar archives, which are
|
||||
similar but not identical.
|
||||
|
||||
@item hpbin
|
||||
The obsolete binary format used by HPUX's cpio (which stores device
|
||||
files differently).
|
||||
|
||||
@item hpodc
|
||||
The portable format used by HPUX's cpio (which stores device files
|
||||
differently).
|
||||
@end table
|
||||
|
||||
@item -i, --extract
|
||||
Run in copy-in mode.
|
||||
@xref{Copy-in mode}.
|
||||
|
||||
@item -I archive
|
||||
Archive filename to use instead of standard input. To use a tape drive
|
||||
on another machine as the archive, use a filename that starts with
|
||||
`HOSTNAME:'. The hostname can be preceded by a username and an `@@' to
|
||||
access the remote tape drive as that user, if you have permission to do
|
||||
so (typically an entry in that user's `~/.rhosts' file).
|
||||
|
||||
@item -k
|
||||
Ignored; for compatibility with other versions of cpio.
|
||||
|
||||
@item -l, --link
|
||||
Link files instead of copying them, when possible.
|
||||
|
||||
@item -L, --dereference
|
||||
Copy the file that a symbolic link points to, rather than the symbolic
|
||||
link itself.
|
||||
|
||||
@item -m, --preserve-modification-time
|
||||
Retain previous file modification times when creating files.
|
||||
|
||||
@item -M MESSAGE, --message=MESSAGE
|
||||
Print MESSAGE when the end of a volume of the backup media (such as a
|
||||
tape or a floppy disk) is reached, to prompt the user to insert a new
|
||||
volume. If MESSAGE contains the string "%d", it is replaced by the
|
||||
current volume number (starting at 1).
|
||||
|
||||
@item -n, --numeric-uid-gid
|
||||
Show numeric UID and GID instead of translating them into names when using the
|
||||
@samp{--verbose option}.
|
||||
|
||||
@item --no-absolute-filenames
|
||||
Create all files relative to the current directory in copy-in mode, even
|
||||
if they have an absolute file name in the archive.
|
||||
|
||||
@item --no-preserve-owner
|
||||
Do not change the ownership of the files; leave them owned by the user
|
||||
extracting them. This is the default for non-root users, so that users
|
||||
on System V don't inadvertantly give away files. This option can be
|
||||
used in copy-in mode and copy-pass mode
|
||||
|
||||
@item -o, --create
|
||||
Run in copy-out mode.
|
||||
@xref{Copy-out mode}.
|
||||
|
||||
@item -O archive
|
||||
Archive filename to use instead of standard output. To use a tape drive
|
||||
on another machine as the archive, use a filename that starts with
|
||||
`HOSTNAME:'. The hostname can be preceded by a username and an `@@' to
|
||||
access the remote tape drive as that user, if you have permission to do
|
||||
so (typically an entry in that user's `~/.rhosts' file).
|
||||
|
||||
@item --only-verify-crc
|
||||
Verify the CRC's of each file in the archive, when reading a CRC format
|
||||
archive. Don't actually extract the files.
|
||||
|
||||
@item -p, --pass-through
|
||||
Run in copy-pass mode.
|
||||
@xref{Copy-pass mode}.
|
||||
|
||||
@item --quiet
|
||||
Do not print the number of blocks copied.
|
||||
|
||||
@item -r, --rename
|
||||
Interactively rename files.
|
||||
|
||||
@item -R [user][:.][group], --owner [user][:.][group]
|
||||
Set the ownership of all files created to the specified user and/or
|
||||
group in copy-out and copy-pass modes. Either the user, the group, or
|
||||
both, must be present. If the group is omitted but the ":" or "."
|
||||
separator is given, use the given user's login group. Only the
|
||||
super-user can change files' ownership.
|
||||
|
||||
@item --rsh-command=COMMAND
|
||||
Notifies cpio that is should use COMMAND to communicate with remote
|
||||
devices.
|
||||
|
||||
@item -s, --swap-bytes
|
||||
Swap the bytes of each halfword (pair of bytes) in the files.This option
|
||||
can be used in copy-in mode.
|
||||
|
||||
@item -S, --swap-halfwords
|
||||
Swap the halfwords of each word (4 bytes) in the files. This option may
|
||||
be used in copy-in mode.
|
||||
|
||||
@item --sparse
|
||||
Write files with large blocks of zeros as sparse files. This option is
|
||||
used in copy-in and copy-pass modes.
|
||||
|
||||
@item -t, --list
|
||||
Print a table of contents of the input.
|
||||
|
||||
@item -u, --unconditional
|
||||
Replace all files, without asking whether to replace
|
||||
existing newer files with older files.
|
||||
|
||||
@item -v, --verbose
|
||||
List the files processed, or with @samp{-t}, give an @samp{ls -l} style
|
||||
table of contents listing. In a verbose table of contents of a ustar
|
||||
archive, user and group names in the archive that do not exist on the
|
||||
local system are replaced by the names that correspond locally to the
|
||||
numeric UID and GID stored in the archive.
|
||||
|
||||
@item -V --dot
|
||||
Print a @kbd{.} for each file processed.
|
||||
|
||||
@item --version
|
||||
Print the cpio program version number and exit.
|
||||
@end table
|
||||
|
||||
|
||||
@node Media, Concept Index, Invoking `cpio', Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Magnetic Media
|
||||
@cindex magnetic media
|
||||
|
||||
Archives are usually written on removable media--tape cartridges, mag
|
||||
tapes, or floppy disks.
|
||||
|
||||
The amount of data a tape or disk holds depends not only on its size,
|
||||
but also on how it is formatted. A 2400 foot long reel of mag tape
|
||||
holds 40 megabytes of data when formated at 1600 bits per inch. The
|
||||
physically smaller EXABYTE tape cartridge holds 2.3 gigabytes.
|
||||
|
||||
Magnetic media are re-usable--once the archive on a tape is no longer
|
||||
needed, the archive can be erased and the tape or disk used over. Media
|
||||
quality does deteriorate with use, however. Most tapes or disks should
|
||||
be disgarded when they begin to produce data errors.
|
||||
|
||||
Magnetic media are written and erased using magnetic fields, and should
|
||||
be protected from such fields to avoid damage to stored data. Sticking
|
||||
a floppy disk to a filing cabinet using a magnet is probably not a good
|
||||
idea.
|
||||
|
||||
|
||||
@node Concept Index, , Media, Top
|
||||
@comment node-name, next, previous, up
|
||||
@unnumbered Concept Index
|
||||
@printindex cp
|
||||
@contents
|
||||
@bye
|
54
contrib/cpio/lib/alloca_.h
Normal file
54
contrib/cpio/lib/alloca_.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001, 2002, 2003, 2004 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, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
/* When this file is included, it may be preceded only by preprocessor
|
||||
declarations. Thanks to AIX. Therefore we include it right after
|
||||
"config.h", not later. */
|
||||
|
||||
#ifndef _ALLOCA_H
|
||||
# define _ALLOCA_H
|
||||
|
||||
/* alloca (N) returns a pointer to N bytes of memory
|
||||
allocated on the stack, which will last until the function returns.
|
||||
Use of alloca should be avoided:
|
||||
- inside arguments of function calls - undefined behaviour,
|
||||
- in inline functions - the allocation may actually last until the
|
||||
calling function returns,
|
||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
||||
the stack is, and when the stack cannot fulfill the memory allocation
|
||||
request, the program just crashes.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define alloca __builtin_alloca
|
||||
#elif defined _AIX
|
||||
# define alloca __alloca
|
||||
#elif defined _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
#else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *alloca (size_t);
|
||||
#endif
|
||||
|
||||
#endif /* _ALLOCA_H */
|
25
contrib/cpio/lib/argp-ba.c
Normal file
25
contrib/cpio/lib/argp-ba.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
|
||||
Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* If set by the user program, it should point to string that is the
|
||||
bug-reporting address for the program. It will be printed by argp_help if
|
||||
the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
|
||||
messages), embedded in a sentence that says something like `Report bugs to
|
||||
ADDR.'. */
|
||||
const char *argp_program_bug_address;
|
31
contrib/cpio/lib/argp-eexst.c
Normal file
31
contrib/cpio/lib/argp-eexst.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* Default definition for ARGP_ERR_EXIT_STATUS
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sysexits.h>
|
||||
|
||||
#include "argp.h"
|
||||
|
||||
/* The exit status that argp will use when exiting due to a parsing error.
|
||||
If not defined or set by the user program, this defaults to EX_USAGE from
|
||||
<sysexits.h>. */
|
||||
error_t argp_err_exit_status = EX_USAGE;
|
440
contrib/cpio/lib/argp-fmtstream.c
Normal file
440
contrib/cpio/lib/argp-fmtstream.c
Normal file
@ -0,0 +1,440 @@
|
||||
/* Word-wrapping and line-truncating streams
|
||||
Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||
don't have that. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "argp-fmtstream.h"
|
||||
#include "argp-namefrob.h"
|
||||
|
||||
#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
|
||||
#ifndef isblank
|
||||
#define isblank(ch) ((ch)==' ' || (ch)=='\t')
|
||||
#endif
|
||||
|
||||
#if defined _LIBC && defined USE_IN_LIBIO
|
||||
# include <wchar.h>
|
||||
# include <libio/libioP.h>
|
||||
# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
|
||||
#endif
|
||||
|
||||
#define INIT_BUF_SIZE 200
|
||||
#define PRINTF_SIZE_GUESS 150
|
||||
|
||||
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
|
||||
written on it with LMARGIN spaces and limits them to RMARGIN columns
|
||||
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
|
||||
replacing the whitespace before them with a newline and WMARGIN spaces.
|
||||
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
|
||||
Returns NULL if there was an error. */
|
||||
argp_fmtstream_t
|
||||
__argp_make_fmtstream (FILE *stream,
|
||||
size_t lmargin, size_t rmargin, ssize_t wmargin)
|
||||
{
|
||||
argp_fmtstream_t fs;
|
||||
|
||||
fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
|
||||
if (fs != NULL)
|
||||
{
|
||||
fs->stream = stream;
|
||||
|
||||
fs->lmargin = lmargin;
|
||||
fs->rmargin = rmargin;
|
||||
fs->wmargin = wmargin;
|
||||
fs->point_col = 0;
|
||||
fs->point_offs = 0;
|
||||
|
||||
fs->buf = (char *) malloc (INIT_BUF_SIZE);
|
||||
if (! fs->buf)
|
||||
{
|
||||
free (fs);
|
||||
fs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs->p = fs->buf;
|
||||
fs->end = fs->buf + INIT_BUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
#if 0
|
||||
/* Not exported. */
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Flush FS to its stream, and free it (but don't close the stream). */
|
||||
void
|
||||
__argp_fmtstream_free (argp_fmtstream_t fs)
|
||||
{
|
||||
__argp_fmtstream_update (fs);
|
||||
if (fs->p > fs->buf)
|
||||
{
|
||||
#ifdef USE_IN_LIBIO
|
||||
if (_IO_fwide (fs->stream, 0) > 0)
|
||||
__fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
|
||||
else
|
||||
#endif
|
||||
fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||
}
|
||||
free (fs->buf);
|
||||
free (fs);
|
||||
}
|
||||
#if 0
|
||||
/* Not exported. */
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
|
||||
end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
|
||||
void
|
||||
__argp_fmtstream_update (argp_fmtstream_t fs)
|
||||
{
|
||||
char *buf, *nl;
|
||||
size_t len;
|
||||
|
||||
/* Scan the buffer for newlines. */
|
||||
buf = fs->buf + fs->point_offs;
|
||||
while (buf < fs->p)
|
||||
{
|
||||
size_t r;
|
||||
|
||||
if (fs->point_col == 0 && fs->lmargin != 0)
|
||||
{
|
||||
/* We are starting a new line. Print spaces to the left margin. */
|
||||
const size_t pad = fs->lmargin;
|
||||
if (fs->p + pad < fs->end)
|
||||
{
|
||||
/* We can fit in them in the buffer by moving the
|
||||
buffer text up and filling in the beginning. */
|
||||
memmove (buf + pad, buf, fs->p - buf);
|
||||
fs->p += pad; /* Compensate for bigger buffer. */
|
||||
memset (buf, ' ', pad); /* Fill in the spaces. */
|
||||
buf += pad; /* Don't bother searching them. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No buffer space for spaces. Must flush. */
|
||||
size_t i;
|
||||
for (i = 0; i < pad; i++)
|
||||
{
|
||||
#ifdef USE_IN_LIBIO
|
||||
if (_IO_fwide (fs->stream, 0) > 0)
|
||||
putwc_unlocked (L' ', fs->stream);
|
||||
else
|
||||
#endif
|
||||
putc_unlocked (' ', fs->stream);
|
||||
}
|
||||
}
|
||||
fs->point_col = pad;
|
||||
}
|
||||
|
||||
len = fs->p - buf;
|
||||
nl = memchr (buf, '\n', len);
|
||||
|
||||
if (fs->point_col < 0)
|
||||
fs->point_col = 0;
|
||||
|
||||
if (!nl)
|
||||
{
|
||||
/* The buffer ends in a partial line. */
|
||||
|
||||
if (fs->point_col + len < fs->rmargin)
|
||||
{
|
||||
/* The remaining buffer text is a partial line and fits
|
||||
within the maximum line width. Advance point for the
|
||||
characters to be written and stop scanning. */
|
||||
fs->point_col += len;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* Set the end-of-line pointer for the code below to
|
||||
the end of the buffer. */
|
||||
nl = fs->p;
|
||||
}
|
||||
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
|
||||
{
|
||||
/* The buffer contains a full line that fits within the maximum
|
||||
line width. Reset point and scan the next line. */
|
||||
fs->point_col = 0;
|
||||
buf = nl + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This line is too long. */
|
||||
r = fs->rmargin - 1;
|
||||
|
||||
if (fs->wmargin < 0)
|
||||
{
|
||||
/* Truncate the line by overwriting the excess with the
|
||||
newline and anything after it in the buffer. */
|
||||
if (nl < fs->p)
|
||||
{
|
||||
memmove (buf + (r - fs->point_col), nl, fs->p - nl);
|
||||
fs->p -= buf + (r - fs->point_col) - nl;
|
||||
/* Reset point for the next line and start scanning it. */
|
||||
fs->point_col = 0;
|
||||
buf += r + 1; /* Skip full line plus \n. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The buffer ends with a partial line that is beyond the
|
||||
maximum line width. Advance point for the characters
|
||||
written, and discard those past the max from the buffer. */
|
||||
fs->point_col += len;
|
||||
fs->p -= fs->point_col - r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do word wrap. Go to the column just past the maximum line
|
||||
width and scan back for the beginning of the word there.
|
||||
Then insert a line break. */
|
||||
|
||||
char *p, *nextline;
|
||||
int i;
|
||||
|
||||
p = buf + (r + 1 - fs->point_col);
|
||||
while (p >= buf && !isblank (*p))
|
||||
--p;
|
||||
nextline = p + 1; /* This will begin the next line. */
|
||||
|
||||
if (nextline > buf)
|
||||
{
|
||||
/* Swallow separating blanks. */
|
||||
if (p >= buf)
|
||||
do
|
||||
--p;
|
||||
while (p >= buf && isblank (*p));
|
||||
nl = p + 1; /* The newline will replace the first blank. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A single word that is greater than the maximum line width.
|
||||
Oh well. Put it on an overlong line by itself. */
|
||||
p = buf + (r + 1 - fs->point_col);
|
||||
/* Find the end of the long word. */
|
||||
do
|
||||
++p;
|
||||
while (p < nl && !isblank (*p));
|
||||
if (p == nl)
|
||||
{
|
||||
/* It already ends a line. No fussing required. */
|
||||
fs->point_col = 0;
|
||||
buf = nl + 1;
|
||||
continue;
|
||||
}
|
||||
/* We will move the newline to replace the first blank. */
|
||||
nl = p;
|
||||
/* Swallow separating blanks. */
|
||||
do
|
||||
++p;
|
||||
while (isblank (*p));
|
||||
/* The next line will start here. */
|
||||
nextline = p;
|
||||
}
|
||||
|
||||
/* Note: There are a bunch of tests below for
|
||||
NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
|
||||
at the end of the buffer, and NEXTLINE is in fact empty (and so
|
||||
we need not be careful to maintain its contents). */
|
||||
|
||||
if ((nextline == buf + len + 1
|
||||
? fs->end - nl < fs->wmargin + 1
|
||||
: nextline - (nl + 1) < fs->wmargin)
|
||||
&& fs->p > nextline)
|
||||
{
|
||||
/* The margin needs more blanks than we removed. */
|
||||
if (fs->end - fs->p > fs->wmargin + 1)
|
||||
/* Make some space for them. */
|
||||
{
|
||||
size_t mv = fs->p - nextline;
|
||||
memmove (nl + 1 + fs->wmargin, nextline, mv);
|
||||
nextline = nl + 1 + fs->wmargin;
|
||||
len = nextline + mv - buf;
|
||||
*nl++ = '\n';
|
||||
}
|
||||
else
|
||||
/* Output the first line so we can use the space. */
|
||||
{
|
||||
#ifdef USE_IN_LIBIO
|
||||
if (_IO_fwide (fs->stream, 0) > 0)
|
||||
__fwprintf (fs->stream, L"%.*s\n",
|
||||
(int) (nl - fs->buf), fs->buf);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (nl > fs->buf)
|
||||
fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
|
||||
putc_unlocked ('\n', fs->stream);
|
||||
}
|
||||
len += buf - fs->buf;
|
||||
nl = buf = fs->buf;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* We can fit the newline and blanks in before
|
||||
the next word. */
|
||||
*nl++ = '\n';
|
||||
|
||||
if (nextline - nl >= fs->wmargin
|
||||
|| (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
|
||||
/* Add blanks up to the wrap margin column. */
|
||||
for (i = 0; i < fs->wmargin; ++i)
|
||||
*nl++ = ' ';
|
||||
else
|
||||
for (i = 0; i < fs->wmargin; ++i)
|
||||
#ifdef USE_IN_LIBIO
|
||||
if (_IO_fwide (fs->stream, 0) > 0)
|
||||
putwc_unlocked (L' ', fs->stream);
|
||||
else
|
||||
#endif
|
||||
putc_unlocked (' ', fs->stream);
|
||||
|
||||
/* Copy the tail of the original buffer into the current buffer
|
||||
position. */
|
||||
if (nl < nextline)
|
||||
memmove (nl, nextline, buf + len - nextline);
|
||||
len -= nextline - buf;
|
||||
|
||||
/* Continue the scan on the remaining lines in the buffer. */
|
||||
buf = nl;
|
||||
|
||||
/* Restore bufp to include all the remaining text. */
|
||||
fs->p = nl + len;
|
||||
|
||||
/* Reset the counter of what has been output this line. If wmargin
|
||||
is 0, we want to avoid the lmargin getting added, so we set
|
||||
point_col to a magic value of -1 in that case. */
|
||||
fs->point_col = fs->wmargin ? fs->wmargin : -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember that we've scanned as far as the end of the buffer. */
|
||||
fs->point_offs = fs->p - fs->buf;
|
||||
}
|
||||
|
||||
/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
|
||||
growing the buffer, or by flushing it. True is returned iff we succeed. */
|
||||
int
|
||||
__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
||||
{
|
||||
if ((size_t) (fs->end - fs->p) < amount)
|
||||
{
|
||||
ssize_t wrote;
|
||||
|
||||
/* Flush FS's buffer. */
|
||||
__argp_fmtstream_update (fs);
|
||||
|
||||
#ifdef USE_IN_LIBIO
|
||||
if (_IO_fwide (fs->stream, 0) > 0)
|
||||
{
|
||||
__fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
|
||||
wrote = fs->p - fs->buf;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||
if (wrote == fs->p - fs->buf)
|
||||
{
|
||||
fs->p = fs->buf;
|
||||
fs->point_offs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs->p -= wrote;
|
||||
fs->point_offs -= wrote;
|
||||
memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t) (fs->end - fs->buf) < amount)
|
||||
/* Gotta grow the buffer. */
|
||||
{
|
||||
size_t old_size = fs->end - fs->buf;
|
||||
size_t new_size = old_size + amount;
|
||||
char *new_buf;
|
||||
|
||||
if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs->buf = new_buf;
|
||||
fs->end = new_buf + new_size;
|
||||
fs->p = fs->buf;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
|
||||
{
|
||||
int out;
|
||||
size_t avail;
|
||||
size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
|
||||
|
||||
do
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (! __argp_fmtstream_ensure (fs, size_guess))
|
||||
return -1;
|
||||
|
||||
va_start (args, fmt);
|
||||
avail = fs->end - fs->p;
|
||||
out = __vsnprintf (fs->p, avail, fmt, args);
|
||||
va_end (args);
|
||||
if ((size_t) out >= avail)
|
||||
size_guess = out + 1;
|
||||
}
|
||||
while ((size_t) out >= avail);
|
||||
|
||||
fs->p += out;
|
||||
|
||||
return out;
|
||||
}
|
||||
#if 0
|
||||
/* Not exported. */
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
309
contrib/cpio/lib/argp-fmtstream.h
Normal file
309
contrib/cpio/lib/argp-fmtstream.h
Normal file
@ -0,0 +1,309 @@
|
||||
/* Word-wrapping and line-truncating streams.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||
don't have that. If the system does have it, it is just a wrapper for
|
||||
that. This header file is only used internally while compiling argp, and
|
||||
shouldn't be installed. */
|
||||
|
||||
#ifndef _ARGP_FMTSTREAM_H
|
||||
#define _ARGP_FMTSTREAM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
|
||||
# define __format__ format
|
||||
# define __printf__ printf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
|
||||
|| (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
|
||||
/* line_wrap_stream is available, so use that. */
|
||||
#define ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
#endif
|
||||
|
||||
#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
|
||||
/* Just be a simple wrapper for line_wrap_stream; the semantics are
|
||||
*slightly* different, as line_wrap_stream doesn't actually make a new
|
||||
object, it just modifies the given stream (reversibly) to do
|
||||
line-wrapping. Since we control who uses this code, it doesn't matter. */
|
||||
|
||||
#include <linewrap.h>
|
||||
|
||||
typedef FILE *argp_fmtstream_t;
|
||||
|
||||
#define argp_make_fmtstream line_wrap_stream
|
||||
#define __argp_make_fmtstream line_wrap_stream
|
||||
#define argp_fmtstream_free line_unwrap_stream
|
||||
#define __argp_fmtstream_free line_unwrap_stream
|
||||
|
||||
#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
|
||||
#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
|
||||
#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
|
||||
#define argp_fmtstream_puts(fs,str) fputs(str,fs)
|
||||
#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
|
||||
#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
|
||||
#define __argp_fmtstream_printf fprintf
|
||||
#define argp_fmtstream_printf fprintf
|
||||
|
||||
#define __argp_fmtstream_lmargin line_wrap_lmargin
|
||||
#define argp_fmtstream_lmargin line_wrap_lmargin
|
||||
#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
|
||||
#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
|
||||
#define __argp_fmtstream_rmargin line_wrap_rmargin
|
||||
#define argp_fmtstream_rmargin line_wrap_rmargin
|
||||
#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
|
||||
#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
|
||||
#define __argp_fmtstream_wmargin line_wrap_wmargin
|
||||
#define argp_fmtstream_wmargin line_wrap_wmargin
|
||||
#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
|
||||
#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
|
||||
#define __argp_fmtstream_point line_wrap_point
|
||||
#define argp_fmtstream_point line_wrap_point
|
||||
|
||||
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||
/* Guess we have to define our own version. */
|
||||
|
||||
#ifndef __const
|
||||
#define __const const
|
||||
#endif
|
||||
|
||||
struct argp_fmtstream
|
||||
{
|
||||
FILE *stream; /* The stream we're outputting to. */
|
||||
|
||||
size_t lmargin, rmargin; /* Left and right margins. */
|
||||
ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
|
||||
|
||||
/* Point in buffer to which we've processed for wrapping, but not output. */
|
||||
size_t point_offs;
|
||||
/* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
|
||||
ssize_t point_col;
|
||||
|
||||
char *buf; /* Output buffer. */
|
||||
char *p; /* Current end of text in BUF. */
|
||||
char *end; /* Absolute end of BUF. */
|
||||
};
|
||||
|
||||
typedef struct argp_fmtstream *argp_fmtstream_t;
|
||||
|
||||
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
|
||||
written on it with LMARGIN spaces and limits them to RMARGIN columns
|
||||
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
|
||||
replacing the whitespace before them with a newline and WMARGIN spaces.
|
||||
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
|
||||
Returns NULL if there was an error. */
|
||||
extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
|
||||
size_t __lmargin,
|
||||
size_t __rmargin,
|
||||
ssize_t __wmargin);
|
||||
extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
|
||||
size_t __lmargin,
|
||||
size_t __rmargin,
|
||||
ssize_t __wmargin);
|
||||
|
||||
/* Flush __FS to its stream, and free it (but don't close the stream). */
|
||||
extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
|
||||
extern void argp_fmtstream_free (argp_fmtstream_t __fs);
|
||||
|
||||
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||
__const char *__fmt, ...)
|
||||
__attribute__ ((__format__ (printf, 2, 3)));
|
||||
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||
__const char *__fmt, ...)
|
||||
__attribute__ ((__format__ (printf, 2, 3)));
|
||||
|
||||
extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||
extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||
|
||||
extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
||||
extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
||||
|
||||
extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len);
|
||||
extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len);
|
||||
|
||||
/* Access macros for various bits of state. */
|
||||
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
|
||||
#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
|
||||
#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
|
||||
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
|
||||
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
|
||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||
|
||||
/* Set __FS's left margin to LMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
|
||||
size_t __lmargin);
|
||||
extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
|
||||
size_t __lmargin);
|
||||
|
||||
/* Set __FS's right margin to __RMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
|
||||
size_t __rmargin);
|
||||
extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
|
||||
size_t __rmargin);
|
||||
|
||||
/* Set __FS's wrap margin to __WMARGIN and return the old value. */
|
||||
extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
|
||||
size_t __wmargin);
|
||||
extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
|
||||
size_t __wmargin);
|
||||
|
||||
/* Return the column number of the current output point in __FS. */
|
||||
extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
|
||||
extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
|
||||
|
||||
/* Internal routines. */
|
||||
extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
|
||||
extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
|
||||
extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
|
||||
extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
/* Inline versions of above routines. */
|
||||
|
||||
#if !_LIBC
|
||||
#define __argp_fmtstream_putc argp_fmtstream_putc
|
||||
#define __argp_fmtstream_puts argp_fmtstream_puts
|
||||
#define __argp_fmtstream_write argp_fmtstream_write
|
||||
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
|
||||
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
|
||||
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
|
||||
#define __argp_fmtstream_point argp_fmtstream_point
|
||||
#define __argp_fmtstream_update _argp_fmtstream_update
|
||||
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
|
||||
#endif
|
||||
|
||||
#ifndef ARGP_FS_EI
|
||||
#define ARGP_FS_EI extern inline
|
||||
#endif
|
||||
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||
__const char *__str, size_t __len)
|
||||
{
|
||||
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
|
||||
{
|
||||
memcpy (__fs->p, __str, __len);
|
||||
__fs->p += __len;
|
||||
return __len;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARGP_FS_EI int
|
||||
__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
|
||||
{
|
||||
size_t __len = strlen (__str);
|
||||
if (__len)
|
||||
{
|
||||
size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
|
||||
return __wrote == __len ? 0 : -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARGP_FS_EI int
|
||||
__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
|
||||
{
|
||||
if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
|
||||
return *__fs->p++ = __ch;
|
||||
else
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Set __FS's left margin to __LMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->lmargin;
|
||||
__fs->lmargin = __lmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Set __FS's right margin to __RMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->rmargin;
|
||||
__fs->rmargin = __rmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Set FS's wrap margin to __WMARGIN and return the old value. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
|
||||
{
|
||||
size_t __old;
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
__old = __fs->wmargin;
|
||||
__fs->wmargin = __wmargin;
|
||||
return __old;
|
||||
}
|
||||
|
||||
/* Return the column number of the current output point in __FS. */
|
||||
ARGP_FS_EI size_t
|
||||
__argp_fmtstream_point (argp_fmtstream_t __fs)
|
||||
{
|
||||
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
|
||||
__argp_fmtstream_update (__fs);
|
||||
return __fs->point_col >= 0 ? __fs->point_col : 0;
|
||||
}
|
||||
|
||||
#if !_LIBC
|
||||
#undef __argp_fmtstream_putc
|
||||
#undef __argp_fmtstream_puts
|
||||
#undef __argp_fmtstream_write
|
||||
#undef __argp_fmtstream_set_lmargin
|
||||
#undef __argp_fmtstream_set_rmargin
|
||||
#undef __argp_fmtstream_set_wmargin
|
||||
#undef __argp_fmtstream_point
|
||||
#undef __argp_fmtstream_update
|
||||
#undef __argp_fmtstream_ensure
|
||||
#endif
|
||||
|
||||
#endif /* __OPTIMIZE__ */
|
||||
|
||||
#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||
|
||||
#endif /* argp-fmtstream.h */
|
43
contrib/cpio/lib/argp-fs-xinl.c
Normal file
43
contrib/cpio/lib/argp-fs-xinl.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* Real definitions for extern inline functions in argp-fmtstream.h
|
||||
Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define ARGP_FS_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp-fmtstream.h"
|
||||
|
||||
#if 0
|
||||
/* Not exported. */
|
||||
/* Add weak aliases. */
|
||||
#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
|
||||
|
||||
weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
|
||||
weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
|
||||
weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
|
||||
weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
|
||||
weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
|
||||
weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
|
||||
weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
|
||||
|
||||
#endif
|
||||
#endif
|
1884
contrib/cpio/lib/argp-help.c
Normal file
1884
contrib/cpio/lib/argp-help.c
Normal file
File diff suppressed because it is too large
Load Diff
156
contrib/cpio/lib/argp-namefrob.h
Normal file
156
contrib/cpio/lib/argp-namefrob.h
Normal file
@ -0,0 +1,156 @@
|
||||
/* Name frobnication for compiling argp outside of glibc
|
||||
Copyright (C) 1997, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !_LIBC
|
||||
/* This code is written for inclusion in gnu-libc, and uses names in the
|
||||
namespace reserved for libc. If we're not compiling in libc, define those
|
||||
names to be the normal ones instead. */
|
||||
|
||||
/* argp-parse functions */
|
||||
#undef __argp_parse
|
||||
#define __argp_parse argp_parse
|
||||
#undef __option_is_end
|
||||
#define __option_is_end _option_is_end
|
||||
#undef __option_is_short
|
||||
#define __option_is_short _option_is_short
|
||||
#undef __argp_input
|
||||
#define __argp_input _argp_input
|
||||
|
||||
/* argp-help functions */
|
||||
#undef __argp_help
|
||||
#define __argp_help argp_help
|
||||
#undef __argp_error
|
||||
#define __argp_error argp_error
|
||||
#undef __argp_failure
|
||||
#define __argp_failure argp_failure
|
||||
#undef __argp_state_help
|
||||
#define __argp_state_help argp_state_help
|
||||
#undef __argp_usage
|
||||
#define __argp_usage argp_usage
|
||||
|
||||
/* argp-fmtstream functions */
|
||||
#undef __argp_make_fmtstream
|
||||
#define __argp_make_fmtstream argp_make_fmtstream
|
||||
#undef __argp_fmtstream_free
|
||||
#define __argp_fmtstream_free argp_fmtstream_free
|
||||
#undef __argp_fmtstream_putc
|
||||
#define __argp_fmtstream_putc argp_fmtstream_putc
|
||||
#undef __argp_fmtstream_puts
|
||||
#define __argp_fmtstream_puts argp_fmtstream_puts
|
||||
#undef __argp_fmtstream_write
|
||||
#define __argp_fmtstream_write argp_fmtstream_write
|
||||
#undef __argp_fmtstream_printf
|
||||
#define __argp_fmtstream_printf argp_fmtstream_printf
|
||||
#undef __argp_fmtstream_set_lmargin
|
||||
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
|
||||
#undef __argp_fmtstream_set_rmargin
|
||||
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
|
||||
#undef __argp_fmtstream_set_wmargin
|
||||
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
|
||||
#undef __argp_fmtstream_point
|
||||
#define __argp_fmtstream_point argp_fmtstream_point
|
||||
#undef __argp_fmtstream_update
|
||||
#define __argp_fmtstream_update _argp_fmtstream_update
|
||||
#undef __argp_fmtstream_ensure
|
||||
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
|
||||
#undef __argp_fmtstream_lmargin
|
||||
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
|
||||
#undef __argp_fmtstream_rmargin
|
||||
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
|
||||
#undef __argp_fmtstream_wmargin
|
||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||
|
||||
#include "mempcpy.h"
|
||||
#include "strcase.h"
|
||||
#include "strchrnul.h"
|
||||
#include "strndup.h"
|
||||
|
||||
/* normal libc functions we call */
|
||||
#undef __flockfile
|
||||
#define __flockfile flockfile
|
||||
#undef __funlockfile
|
||||
#define __funlockfile funlockfile
|
||||
#undef __mempcpy
|
||||
#define __mempcpy mempcpy
|
||||
#undef __sleep
|
||||
#define __sleep sleep
|
||||
#undef __strcasecmp
|
||||
#define __strcasecmp strcasecmp
|
||||
#undef __strchrnul
|
||||
#define __strchrnul strchrnul
|
||||
#undef __strerror_r
|
||||
#define __strerror_r strerror_r
|
||||
#undef __strndup
|
||||
#define __strndup strndup
|
||||
#undef __vsnprintf
|
||||
#define __vsnprintf vsnprintf
|
||||
|
||||
#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
|
||||
# define clearerr_unlocked(x) clearerr (x)
|
||||
#endif
|
||||
#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
|
||||
# define feof_unlocked(x) feof (x)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
|
||||
# define ferror_unlocked(x) ferror (x)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
|
||||
# define fflush_unlocked(x) fflush (x)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
|
||||
# define fgets_unlocked(x,y,z) fgets (x,y,z)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
|
||||
# define fputc_unlocked(x,y) fputc (x,y)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
|
||||
# define fputs_unlocked(x,y) fputs (x,y)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
|
||||
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
|
||||
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
|
||||
# define getc_unlocked(x) getc (x)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
|
||||
# define getchar_unlocked() getchar ()
|
||||
# endif
|
||||
#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
|
||||
# define putc_unlocked(x,y) putc (x,y)
|
||||
# endif
|
||||
#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
|
||||
# define putchar_unlocked(x) putchar (x)
|
||||
# endif
|
||||
|
||||
extern char *__argp_basename (char *name);
|
||||
|
||||
#endif /* !_LIBC */
|
||||
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(e) (errno = (e))
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||
# define __argp_short_program_name() (program_invocation_short_name)
|
||||
#else
|
||||
extern char *__argp_short_program_name (void);
|
||||
#endif
|
926
contrib/cpio/lib/argp-parse.c
Normal file
926
contrib/cpio/lib/argp-parse.c
Normal file
@ -0,0 +1,926 @@
|
||||
/* Hierarchial argument parsing, layered over getopt
|
||||
Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <alloca.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <getopt.h>
|
||||
#include <getopt_int.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
# undef dgettext
|
||||
# define dgettext(domain, msgid) \
|
||||
INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
|
||||
#else
|
||||
# include "gettext.h"
|
||||
#endif
|
||||
#define N_(msgid) (msgid)
|
||||
|
||||
#include "argp.h"
|
||||
#include "argp-namefrob.h"
|
||||
|
||||
/* Getopt return values. */
|
||||
#define KEY_END (-1) /* The end of the options. */
|
||||
#define KEY_ARG 1 /* A non-option argument. */
|
||||
#define KEY_ERR '?' /* An error parsing the options. */
|
||||
|
||||
/* The meta-argument used to prevent any further arguments being interpreted
|
||||
as options. */
|
||||
#define QUOTE "--"
|
||||
|
||||
/* The number of bits we steal in a long-option value for our own use. */
|
||||
#define GROUP_BITS CHAR_BIT
|
||||
|
||||
/* The number of bits available for the user value. */
|
||||
#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
|
||||
#define USER_MASK ((1 << USER_BITS) - 1)
|
||||
|
||||
/* EZ alias for ARGP_ERR_UNKNOWN. */
|
||||
#define EBADKEY ARGP_ERR_UNKNOWN
|
||||
|
||||
/* Default options. */
|
||||
|
||||
/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
|
||||
for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
|
||||
you can force the program to continue by attaching a debugger and setting
|
||||
it to 0 yourself. */
|
||||
static volatile int _argp_hang;
|
||||
|
||||
#define OPT_PROGNAME -2
|
||||
#define OPT_USAGE -3
|
||||
#define OPT_HANG -4
|
||||
|
||||
static const struct argp_option argp_default_options[] =
|
||||
{
|
||||
{"help", '?', 0, 0, N_("Give this help list"), -1},
|
||||
{"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0},
|
||||
{"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0},
|
||||
{"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
|
||||
N_("Hang for SECS seconds (default 3600)"), 0},
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static error_t
|
||||
argp_default_parser (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '?':
|
||||
__argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
|
||||
break;
|
||||
case OPT_USAGE:
|
||||
__argp_state_help (state, state->out_stream,
|
||||
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
||||
break;
|
||||
|
||||
case OPT_PROGNAME: /* Set the program name. */
|
||||
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||
program_invocation_name = arg;
|
||||
#endif
|
||||
/* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
|
||||
__PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
|
||||
to be that, so we have to be a bit careful here.] */
|
||||
|
||||
/* Update what we use for messages. */
|
||||
state->name = strrchr (arg, '/');
|
||||
if (state->name)
|
||||
state->name++;
|
||||
else
|
||||
state->name = arg;
|
||||
|
||||
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||
program_invocation_short_name = state->name;
|
||||
#endif
|
||||
|
||||
if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
|
||||
== ARGP_PARSE_ARGV0)
|
||||
/* Update what getopt uses too. */
|
||||
state->argv[0] = arg;
|
||||
|
||||
break;
|
||||
|
||||
case OPT_HANG:
|
||||
_argp_hang = atoi (arg ? arg : "3600");
|
||||
while (_argp_hang-- > 0)
|
||||
__sleep (1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return EBADKEY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct argp argp_default_argp =
|
||||
{argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
|
||||
|
||||
|
||||
static const struct argp_option argp_version_options[] =
|
||||
{
|
||||
{"version", 'V', 0, 0, N_("Print program version"), -1},
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
static error_t
|
||||
argp_version_parser (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 'V':
|
||||
if (argp_program_version_hook)
|
||||
(*argp_program_version_hook) (state->out_stream, state);
|
||||
else if (argp_program_version)
|
||||
fprintf (state->out_stream, "%s\n", argp_program_version);
|
||||
else
|
||||
__argp_error (state, dgettext (state->root_argp->argp_domain,
|
||||
"(PROGRAM ERROR) No version known!?"));
|
||||
if (! (state->flags & ARGP_NO_EXIT))
|
||||
exit (0);
|
||||
break;
|
||||
default:
|
||||
return EBADKEY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct argp argp_version_argp =
|
||||
{argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
|
||||
|
||||
/* Returns the offset into the getopt long options array LONG_OPTIONS of a
|
||||
long option with called NAME, or -1 if none is found. Passing NULL as
|
||||
NAME will return the number of options. */
|
||||
static int
|
||||
find_long_option (struct option *long_options, const char *name)
|
||||
{
|
||||
struct option *l = long_options;
|
||||
while (l->name != NULL)
|
||||
if (name != NULL && strcmp (l->name, name) == 0)
|
||||
return l - long_options;
|
||||
else
|
||||
l++;
|
||||
if (name == NULL)
|
||||
return l - long_options;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* The state of a `group' during parsing. Each group corresponds to a
|
||||
particular argp structure from the tree of such descending from the top
|
||||
level argp passed to argp_parse. */
|
||||
struct group
|
||||
{
|
||||
/* This group's parsing function. */
|
||||
argp_parser_t parser;
|
||||
|
||||
/* Which argp this group is from. */
|
||||
const struct argp *argp;
|
||||
|
||||
/* Points to the point in SHORT_OPTS corresponding to the end of the short
|
||||
options for this group. We use it to determine from which group a
|
||||
particular short options is from. */
|
||||
char *short_end;
|
||||
|
||||
/* The number of non-option args sucessfully handled by this parser. */
|
||||
unsigned args_processed;
|
||||
|
||||
/* This group's parser's parent's group. */
|
||||
struct group *parent;
|
||||
unsigned parent_index; /* And the our position in the parent. */
|
||||
|
||||
/* These fields are swapped into and out of the state structure when
|
||||
calling this group's parser. */
|
||||
void *input, **child_inputs;
|
||||
void *hook;
|
||||
};
|
||||
|
||||
/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
|
||||
from STATE before calling, and back into state afterwards. If GROUP has
|
||||
no parser, EBADKEY is returned. */
|
||||
static error_t
|
||||
group_parse (struct group *group, struct argp_state *state, int key, char *arg)
|
||||
{
|
||||
if (group->parser)
|
||||
{
|
||||
error_t err;
|
||||
state->hook = group->hook;
|
||||
state->input = group->input;
|
||||
state->child_inputs = group->child_inputs;
|
||||
state->arg_num = group->args_processed;
|
||||
err = (*group->parser)(key, arg, state);
|
||||
group->hook = state->hook;
|
||||
return err;
|
||||
}
|
||||
else
|
||||
return EBADKEY;
|
||||
}
|
||||
|
||||
struct parser
|
||||
{
|
||||
const struct argp *argp;
|
||||
|
||||
/* SHORT_OPTS is the getopt short options string for the union of all the
|
||||
groups of options. */
|
||||
char *short_opts;
|
||||
/* LONG_OPTS is the array of getop long option structures for the union of
|
||||
all the groups of options. */
|
||||
struct option *long_opts;
|
||||
/* OPT_DATA is the getopt data used for the re-entrant getopt. */
|
||||
struct _getopt_data opt_data;
|
||||
|
||||
/* States of the various parsing groups. */
|
||||
struct group *groups;
|
||||
/* The end of the GROUPS array. */
|
||||
struct group *egroup;
|
||||
/* An vector containing storage for the CHILD_INPUTS field in all groups. */
|
||||
void **child_inputs;
|
||||
|
||||
/* True if we think using getopt is still useful; if false, then
|
||||
remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
|
||||
cleared whenever getopt returns KEY_END, but may be set again if the user
|
||||
moves the next argument pointer backwards. */
|
||||
int try_getopt;
|
||||
|
||||
/* State block supplied to parsing routines. */
|
||||
struct argp_state state;
|
||||
|
||||
/* Memory used by this parser. */
|
||||
void *storage;
|
||||
};
|
||||
|
||||
/* The next usable entries in the various parser tables being filled in by
|
||||
convert_options. */
|
||||
struct parser_convert_state
|
||||
{
|
||||
struct parser *parser;
|
||||
char *short_end;
|
||||
struct option *long_end;
|
||||
void **child_inputs_end;
|
||||
};
|
||||
|
||||
/* Converts all options in ARGP (which is put in GROUP) and ancestors
|
||||
into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
|
||||
CVT->LONG_END are the points at which new options are added. Returns the
|
||||
next unused group entry. CVT holds state used during the conversion. */
|
||||
static struct group *
|
||||
convert_options (const struct argp *argp,
|
||||
struct group *parent, unsigned parent_index,
|
||||
struct group *group, struct parser_convert_state *cvt)
|
||||
{
|
||||
/* REAL is the most recent non-alias value of OPT. */
|
||||
const struct argp_option *real = argp->options;
|
||||
const struct argp_child *children = argp->children;
|
||||
|
||||
if (real || argp->parser)
|
||||
{
|
||||
const struct argp_option *opt;
|
||||
|
||||
if (real)
|
||||
for (opt = real; !__option_is_end (opt); opt++)
|
||||
{
|
||||
if (! (opt->flags & OPTION_ALIAS))
|
||||
/* OPT isn't an alias, so we can use values from it. */
|
||||
real = opt;
|
||||
|
||||
if (! (real->flags & OPTION_DOC))
|
||||
/* A real option (not just documentation). */
|
||||
{
|
||||
if (__option_is_short (opt))
|
||||
/* OPT can be used as a short option. */
|
||||
{
|
||||
*cvt->short_end++ = opt->key;
|
||||
if (real->arg)
|
||||
{
|
||||
*cvt->short_end++ = ':';
|
||||
if (real->flags & OPTION_ARG_OPTIONAL)
|
||||
*cvt->short_end++ = ':';
|
||||
}
|
||||
*cvt->short_end = '\0'; /* keep 0 terminated */
|
||||
}
|
||||
|
||||
if (opt->name
|
||||
&& find_long_option (cvt->parser->long_opts, opt->name) < 0)
|
||||
/* OPT can be used as a long option. */
|
||||
{
|
||||
cvt->long_end->name = opt->name;
|
||||
cvt->long_end->has_arg =
|
||||
(real->arg
|
||||
? (real->flags & OPTION_ARG_OPTIONAL
|
||||
? optional_argument
|
||||
: required_argument)
|
||||
: no_argument);
|
||||
cvt->long_end->flag = 0;
|
||||
/* we add a disambiguating code to all the user's
|
||||
values (which is removed before we actually call
|
||||
the function to parse the value); this means that
|
||||
the user loses use of the high 8 bits in all his
|
||||
values (the sign of the lower bits is preserved
|
||||
however)... */
|
||||
cvt->long_end->val =
|
||||
((opt->key | real->key) & USER_MASK)
|
||||
+ (((group - cvt->parser->groups) + 1) << USER_BITS);
|
||||
|
||||
/* Keep the LONG_OPTS list terminated. */
|
||||
(++cvt->long_end)->name = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group->parser = argp->parser;
|
||||
group->argp = argp;
|
||||
group->short_end = cvt->short_end;
|
||||
group->args_processed = 0;
|
||||
group->parent = parent;
|
||||
group->parent_index = parent_index;
|
||||
group->input = 0;
|
||||
group->hook = 0;
|
||||
group->child_inputs = 0;
|
||||
|
||||
if (children)
|
||||
/* Assign GROUP's CHILD_INPUTS field some space from
|
||||
CVT->child_inputs_end.*/
|
||||
{
|
||||
unsigned num_children = 0;
|
||||
while (children[num_children].argp)
|
||||
num_children++;
|
||||
group->child_inputs = cvt->child_inputs_end;
|
||||
cvt->child_inputs_end += num_children;
|
||||
}
|
||||
|
||||
parent = group++;
|
||||
}
|
||||
else
|
||||
parent = 0;
|
||||
|
||||
if (children)
|
||||
{
|
||||
unsigned index = 0;
|
||||
while (children->argp)
|
||||
group =
|
||||
convert_options (children++->argp, parent, index++, group, cvt);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Find the merged set of getopt options, with keys appropiately prefixed. */
|
||||
static void
|
||||
parser_convert (struct parser *parser, const struct argp *argp, int flags)
|
||||
{
|
||||
struct parser_convert_state cvt;
|
||||
|
||||
cvt.parser = parser;
|
||||
cvt.short_end = parser->short_opts;
|
||||
cvt.long_end = parser->long_opts;
|
||||
cvt.child_inputs_end = parser->child_inputs;
|
||||
|
||||
if (flags & ARGP_IN_ORDER)
|
||||
*cvt.short_end++ = '-';
|
||||
else if (flags & ARGP_NO_ARGS)
|
||||
*cvt.short_end++ = '+';
|
||||
*cvt.short_end = '\0';
|
||||
|
||||
cvt.long_end->name = NULL;
|
||||
|
||||
parser->argp = argp;
|
||||
|
||||
if (argp)
|
||||
parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
|
||||
else
|
||||
parser->egroup = parser->groups; /* No parsers at all! */
|
||||
}
|
||||
|
||||
/* Lengths of various parser fields which we will allocated. */
|
||||
struct parser_sizes
|
||||
{
|
||||
size_t short_len; /* Getopt short options string. */
|
||||
size_t long_len; /* Getopt long options vector. */
|
||||
size_t num_groups; /* Group structures we allocate. */
|
||||
size_t num_child_inputs; /* Child input slots. */
|
||||
};
|
||||
|
||||
/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
|
||||
argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
|
||||
the maximum lengths of the resulting merged getopt short options string and
|
||||
long-options array, respectively. */
|
||||
static void
|
||||
calc_sizes (const struct argp *argp, struct parser_sizes *szs)
|
||||
{
|
||||
const struct argp_child *child = argp->children;
|
||||
const struct argp_option *opt = argp->options;
|
||||
|
||||
if (opt || argp->parser)
|
||||
{
|
||||
szs->num_groups++;
|
||||
if (opt)
|
||||
{
|
||||
int num_opts = 0;
|
||||
while (!__option_is_end (opt++))
|
||||
num_opts++;
|
||||
szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
|
||||
szs->long_len += num_opts;
|
||||
}
|
||||
}
|
||||
|
||||
if (child)
|
||||
while (child->argp)
|
||||
{
|
||||
calc_sizes ((child++)->argp, szs);
|
||||
szs->num_child_inputs++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
|
||||
static error_t
|
||||
parser_init (struct parser *parser, const struct argp *argp,
|
||||
int argc, char **argv, int flags, void *input)
|
||||
{
|
||||
error_t err = 0;
|
||||
struct group *group;
|
||||
struct parser_sizes szs;
|
||||
struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
|
||||
|
||||
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
|
||||
szs.long_len = 0;
|
||||
szs.num_groups = 0;
|
||||
szs.num_child_inputs = 0;
|
||||
|
||||
if (argp)
|
||||
calc_sizes (argp, &szs);
|
||||
|
||||
/* Lengths of the various bits of storage used by PARSER. */
|
||||
#define GLEN (szs.num_groups + 1) * sizeof (struct group)
|
||||
#define CLEN (szs.num_child_inputs * sizeof (void *))
|
||||
#define LLEN ((szs.long_len + 1) * sizeof (struct option))
|
||||
#define SLEN (szs.short_len + 1)
|
||||
|
||||
parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
|
||||
if (! parser->storage)
|
||||
return ENOMEM;
|
||||
|
||||
parser->groups = parser->storage;
|
||||
parser->child_inputs = parser->storage + GLEN;
|
||||
parser->long_opts = parser->storage + GLEN + CLEN;
|
||||
parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
|
||||
parser->opt_data = opt_data;
|
||||
|
||||
memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
|
||||
parser_convert (parser, argp, flags);
|
||||
|
||||
memset (&parser->state, 0, sizeof (struct argp_state));
|
||||
parser->state.root_argp = parser->argp;
|
||||
parser->state.argc = argc;
|
||||
parser->state.argv = argv;
|
||||
parser->state.flags = flags;
|
||||
parser->state.err_stream = stderr;
|
||||
parser->state.out_stream = stdout;
|
||||
parser->state.next = 0; /* Tell getopt to initialize. */
|
||||
parser->state.pstate = parser;
|
||||
|
||||
parser->try_getopt = 1;
|
||||
|
||||
/* Call each parser for the first time, giving it a chance to propagate
|
||||
values to child parsers. */
|
||||
if (parser->groups < parser->egroup)
|
||||
parser->groups->input = input;
|
||||
for (group = parser->groups;
|
||||
group < parser->egroup && (!err || err == EBADKEY);
|
||||
group++)
|
||||
{
|
||||
if (group->parent)
|
||||
/* If a child parser, get the initial input value from the parent. */
|
||||
group->input = group->parent->child_inputs[group->parent_index];
|
||||
|
||||
if (!group->parser
|
||||
&& group->argp->children && group->argp->children->argp)
|
||||
/* For the special case where no parsing function is supplied for an
|
||||
argp, propagate its input to its first child, if any (this just
|
||||
makes very simple wrapper argps more convenient). */
|
||||
group->child_inputs[0] = group->input;
|
||||
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
|
||||
}
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (parser->state.flags & ARGP_NO_ERRS)
|
||||
{
|
||||
parser->opt_data.opterr = 0;
|
||||
if (parser->state.flags & ARGP_PARSE_ARGV0)
|
||||
/* getopt always skips ARGV[0], so we have to fake it out. As long
|
||||
as OPTERR is 0, then it shouldn't actually try to access it. */
|
||||
parser->state.argv--, parser->state.argc++;
|
||||
}
|
||||
else
|
||||
parser->opt_data.opterr = 1; /* Print error messages. */
|
||||
|
||||
if (parser->state.argv == argv && argv[0])
|
||||
/* There's an argv[0]; use it for messages. */
|
||||
{
|
||||
char *short_name = strrchr (argv[0], '/');
|
||||
parser->state.name = short_name ? short_name + 1 : argv[0];
|
||||
}
|
||||
else
|
||||
parser->state.name = __argp_short_program_name ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Free any storage consumed by PARSER (but not PARSER itself). */
|
||||
static error_t
|
||||
parser_finalize (struct parser *parser,
|
||||
error_t err, int arg_ebadkey, int *end_index)
|
||||
{
|
||||
struct group *group;
|
||||
|
||||
if (err == EBADKEY && arg_ebadkey)
|
||||
/* Suppress errors generated by unparsed arguments. */
|
||||
err = 0;
|
||||
|
||||
if (! err)
|
||||
{
|
||||
if (parser->state.next == parser->state.argc)
|
||||
/* We successfully parsed all arguments! Call all the parsers again,
|
||||
just a few more times... */
|
||||
{
|
||||
for (group = parser->groups;
|
||||
group < parser->egroup && (!err || err==EBADKEY);
|
||||
group++)
|
||||
if (group->args_processed == 0)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
|
||||
for (group = parser->egroup - 1;
|
||||
group >= parser->groups && (!err || err==EBADKEY);
|
||||
group--)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
|
||||
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
|
||||
/* Tell the user that all arguments are parsed. */
|
||||
if (end_index)
|
||||
*end_index = parser->state.next;
|
||||
}
|
||||
else if (end_index)
|
||||
/* Return any remaining arguments to the user. */
|
||||
*end_index = parser->state.next;
|
||||
else
|
||||
/* No way to return the remaining arguments, they must be bogus. */
|
||||
{
|
||||
if (!(parser->state.flags & ARGP_NO_ERRS)
|
||||
&& parser->state.err_stream)
|
||||
fprintf (parser->state.err_stream,
|
||||
dgettext (parser->argp->argp_domain,
|
||||
"%s: Too many arguments\n"),
|
||||
parser->state.name);
|
||||
err = EBADKEY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Okay, we're all done, with either an error or success; call the parsers
|
||||
to indicate which one. */
|
||||
|
||||
if (err)
|
||||
{
|
||||
/* Maybe print an error message. */
|
||||
if (err == EBADKEY)
|
||||
/* An appropriate message describing what the error was should have
|
||||
been printed earlier. */
|
||||
__argp_state_help (&parser->state, parser->state.err_stream,
|
||||
ARGP_HELP_STD_ERR);
|
||||
|
||||
/* Since we didn't exit, give each parser an error indication. */
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
|
||||
}
|
||||
else
|
||||
/* Notify parsers of success, and propagate back values from parsers. */
|
||||
{
|
||||
/* We pass over the groups in reverse order so that child groups are
|
||||
given a chance to do there processing before passing back a value to
|
||||
the parent. */
|
||||
for (group = parser->egroup - 1
|
||||
; group >= parser->groups && (!err || err == EBADKEY)
|
||||
; group--)
|
||||
err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
|
||||
if (err == EBADKEY)
|
||||
err = 0; /* Some parser didn't understand. */
|
||||
}
|
||||
|
||||
/* Call parsers once more, to do any final cleanup. Errors are ignored. */
|
||||
for (group = parser->egroup - 1; group >= parser->groups; group--)
|
||||
group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
|
||||
|
||||
if (err == EBADKEY)
|
||||
err = EINVAL;
|
||||
|
||||
free (parser->storage);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call the user parsers to parse the non-option argument VAL, at the current
|
||||
position, returning any error. The state NEXT pointer is assumed to have
|
||||
been adjusted (by getopt) to point after this argument; this function will
|
||||
adjust it correctly to reflect however many args actually end up being
|
||||
consumed. */
|
||||
static error_t
|
||||
parser_parse_arg (struct parser *parser, char *val)
|
||||
{
|
||||
/* Save the starting value of NEXT, first adjusting it so that the arg
|
||||
we're parsing is again the front of the arg vector. */
|
||||
int index = --parser->state.next;
|
||||
error_t err = EBADKEY;
|
||||
struct group *group;
|
||||
int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */
|
||||
|
||||
/* Try to parse the argument in each parser. */
|
||||
for (group = parser->groups
|
||||
; group < parser->egroup && err == EBADKEY
|
||||
; group++)
|
||||
{
|
||||
parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */
|
||||
key = ARGP_KEY_ARG;
|
||||
err = group_parse (group, &parser->state, key, val);
|
||||
|
||||
if (err == EBADKEY)
|
||||
/* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
|
||||
{
|
||||
parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */
|
||||
key = ARGP_KEY_ARGS;
|
||||
err = group_parse (group, &parser->state, key, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (! err)
|
||||
{
|
||||
if (key == ARGP_KEY_ARGS)
|
||||
/* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
|
||||
changed by the user, *all* arguments should be considered
|
||||
consumed. */
|
||||
parser->state.next = parser->state.argc;
|
||||
|
||||
if (parser->state.next > index)
|
||||
/* Remember that we successfully processed a non-option
|
||||
argument -- but only if the user hasn't gotten tricky and set
|
||||
the clock back. */
|
||||
(--group)->args_processed += (parser->state.next - index);
|
||||
else
|
||||
/* The user wants to reparse some args, give getopt another try. */
|
||||
parser->try_getopt = 1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call the user parsers to parse the option OPT, with argument VAL, at the
|
||||
current position, returning any error. */
|
||||
static error_t
|
||||
parser_parse_opt (struct parser *parser, int opt, char *val)
|
||||
{
|
||||
/* The group key encoded in the high bits; 0 for short opts or
|
||||
group_number + 1 for long opts. */
|
||||
int group_key = opt >> USER_BITS;
|
||||
error_t err = EBADKEY;
|
||||
|
||||
if (group_key == 0)
|
||||
/* A short option. By comparing OPT's position in SHORT_OPTS to the
|
||||
various starting positions in each group's SHORT_END field, we can
|
||||
determine which group OPT came from. */
|
||||
{
|
||||
struct group *group;
|
||||
char *short_index = strchr (parser->short_opts, opt);
|
||||
|
||||
if (short_index)
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
if (group->short_end > short_index)
|
||||
{
|
||||
err = group_parse (group, &parser->state, opt,
|
||||
parser->opt_data.optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* A long option. We use shifts instead of masking for extracting
|
||||
the user value in order to preserve the sign. */
|
||||
err =
|
||||
group_parse (&parser->groups[group_key - 1], &parser->state,
|
||||
(opt << GROUP_BITS) >> GROUP_BITS,
|
||||
parser->opt_data.optarg);
|
||||
|
||||
if (err == EBADKEY)
|
||||
/* At least currently, an option not recognized is an error in the
|
||||
parser, because we pre-compute which parser is supposed to deal
|
||||
with each option. */
|
||||
{
|
||||
static const char bad_key_err[] =
|
||||
N_("(PROGRAM ERROR) Option should have been recognized!?");
|
||||
if (group_key == 0)
|
||||
__argp_error (&parser->state, "-%c: %s", opt,
|
||||
dgettext (parser->argp->argp_domain, bad_key_err));
|
||||
else
|
||||
{
|
||||
struct option *long_opt = parser->long_opts;
|
||||
while (long_opt->val != opt && long_opt->name)
|
||||
long_opt++;
|
||||
__argp_error (&parser->state, "--%s: %s",
|
||||
long_opt->name ? long_opt->name : "???",
|
||||
dgettext (parser->argp->argp_domain, bad_key_err));
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
|
||||
Any error from the parsers is returned, and *ARGP_EBADKEY indicates
|
||||
whether a value of EBADKEY is due to an unrecognized argument (which is
|
||||
generally not fatal). */
|
||||
static error_t
|
||||
parser_parse_next (struct parser *parser, int *arg_ebadkey)
|
||||
{
|
||||
int opt;
|
||||
error_t err = 0;
|
||||
|
||||
if (parser->state.quoted && parser->state.next < parser->state.quoted)
|
||||
/* The next argument pointer has been moved to before the quoted
|
||||
region, so pretend we never saw the quoting `--', and give getopt
|
||||
another chance. If the user hasn't removed it, getopt will just
|
||||
process it again. */
|
||||
parser->state.quoted = 0;
|
||||
|
||||
if (parser->try_getopt && !parser->state.quoted)
|
||||
/* Give getopt a chance to parse this. */
|
||||
{
|
||||
/* Put it back in OPTIND for getopt. */
|
||||
parser->opt_data.optind = parser->state.next;
|
||||
/* Distinguish KEY_ERR from a real option. */
|
||||
parser->opt_data.optopt = KEY_END;
|
||||
if (parser->state.flags & ARGP_LONG_ONLY)
|
||||
opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
|
||||
parser->short_opts, parser->long_opts, 0,
|
||||
&parser->opt_data);
|
||||
else
|
||||
opt = _getopt_long_r (parser->state.argc, parser->state.argv,
|
||||
parser->short_opts, parser->long_opts, 0,
|
||||
&parser->opt_data);
|
||||
/* And see what getopt did. */
|
||||
parser->state.next = parser->opt_data.optind;
|
||||
|
||||
if (opt == KEY_END)
|
||||
/* Getopt says there are no more options, so stop using
|
||||
getopt; we'll continue if necessary on our own. */
|
||||
{
|
||||
parser->try_getopt = 0;
|
||||
if (parser->state.next > 1
|
||||
&& strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
|
||||
== 0)
|
||||
/* Not only is this the end of the options, but it's a
|
||||
`quoted' region, which may have args that *look* like
|
||||
options, so we definitely shouldn't try to use getopt past
|
||||
here, whatever happens. */
|
||||
parser->state.quoted = parser->state.next;
|
||||
}
|
||||
else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
|
||||
/* KEY_ERR can have the same value as a valid user short
|
||||
option, but in the case of a real error, getopt sets OPTOPT
|
||||
to the offending character, which can never be KEY_END. */
|
||||
{
|
||||
*arg_ebadkey = 0;
|
||||
return EBADKEY;
|
||||
}
|
||||
}
|
||||
else
|
||||
opt = KEY_END;
|
||||
|
||||
if (opt == KEY_END)
|
||||
{
|
||||
/* We're past what getopt considers the options. */
|
||||
if (parser->state.next >= parser->state.argc
|
||||
|| (parser->state.flags & ARGP_NO_ARGS))
|
||||
/* Indicate that we're done. */
|
||||
{
|
||||
*arg_ebadkey = 1;
|
||||
return EBADKEY;
|
||||
}
|
||||
else
|
||||
/* A non-option arg; simulate what getopt might have done. */
|
||||
{
|
||||
opt = KEY_ARG;
|
||||
parser->opt_data.optarg = parser->state.argv[parser->state.next++];
|
||||
}
|
||||
}
|
||||
|
||||
if (opt == KEY_ARG)
|
||||
/* A non-option argument; try each parser in turn. */
|
||||
err = parser_parse_arg (parser, parser->opt_data.optarg);
|
||||
else
|
||||
err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
|
||||
|
||||
if (err == EBADKEY)
|
||||
*arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
|
||||
FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
|
||||
index in ARGV of the first unparsed option is returned in it. If an
|
||||
unknown option is present, EINVAL is returned; if some parser routine
|
||||
returned a non-zero value, it is returned; otherwise 0 is returned. */
|
||||
error_t
|
||||
__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
|
||||
int *end_index, void *input)
|
||||
{
|
||||
error_t err;
|
||||
struct parser parser;
|
||||
|
||||
/* If true, then err == EBADKEY is a result of a non-option argument failing
|
||||
to be parsed (which in some cases isn't actually an error). */
|
||||
int arg_ebadkey = 0;
|
||||
|
||||
if (! (flags & ARGP_NO_HELP))
|
||||
/* Add our own options. */
|
||||
{
|
||||
struct argp_child *child = alloca (4 * sizeof (struct argp_child));
|
||||
struct argp *top_argp = alloca (sizeof (struct argp));
|
||||
|
||||
/* TOP_ARGP has no options, it just serves to group the user & default
|
||||
argps. */
|
||||
memset (top_argp, 0, sizeof (*top_argp));
|
||||
top_argp->children = child;
|
||||
|
||||
memset (child, 0, 4 * sizeof (struct argp_child));
|
||||
|
||||
if (argp)
|
||||
(child++)->argp = argp;
|
||||
(child++)->argp = &argp_default_argp;
|
||||
if (argp_program_version || argp_program_version_hook)
|
||||
(child++)->argp = &argp_version_argp;
|
||||
child->argp = 0;
|
||||
|
||||
argp = top_argp;
|
||||
}
|
||||
|
||||
/* Construct a parser for these arguments. */
|
||||
err = parser_init (&parser, argp, argc, argv, flags, input);
|
||||
|
||||
if (! err)
|
||||
/* Parse! */
|
||||
{
|
||||
while (! err)
|
||||
err = parser_parse_next (&parser, &arg_ebadkey);
|
||||
err = parser_finalize (&parser, err, arg_ebadkey, end_index);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_parse, argp_parse)
|
||||
#endif
|
||||
|
||||
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
||||
by the help routines. */
|
||||
void *
|
||||
__argp_input (const struct argp *argp, const struct argp_state *state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
struct group *group;
|
||||
struct parser *parser = state->pstate;
|
||||
|
||||
for (group = parser->groups; group < parser->egroup; group++)
|
||||
if (group->argp == argp)
|
||||
return group->input;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__argp_input, _argp_input)
|
||||
#endif
|
24
contrib/cpio/lib/argp-pv.c
Normal file
24
contrib/cpio/lib/argp-pv.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* Default definition for ARGP_PROGRAM_VERSION.
|
||||
Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* If set by the user program to a non-zero value, then a default option
|
||||
--version is added (unless the ARGP_NO_HELP flag is used), which will
|
||||
print this this string followed by a newline and exit (unless the
|
||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||
const char *argp_program_version;
|
31
contrib/cpio/lib/argp-pvh.c
Normal file
31
contrib/cpio/lib/argp-pvh.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
|
||||
Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "argp.h"
|
||||
|
||||
/* If set by the user program to a non-zero value, then a default option
|
||||
--version is added (unless the ARGP_NO_HELP flag is used), which calls
|
||||
this function with a stream to print the version to and a pointer to the
|
||||
current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
|
||||
used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
|
||||
void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL;
|
43
contrib/cpio/lib/argp-xinl.c
Normal file
43
contrib/cpio/lib/argp-xinl.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* Real definitions for extern inline functions in argp.h
|
||||
Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined _LIBC || defined HAVE_FEATURES_H
|
||||
# include <features.h>
|
||||
#endif
|
||||
|
||||
#ifndef __USE_EXTERN_INLINES
|
||||
# define __USE_EXTERN_INLINES 1
|
||||
#endif
|
||||
#define ARGP_EI
|
||||
#undef __OPTIMIZE__
|
||||
#define __OPTIMIZE__ 1
|
||||
#include "argp.h"
|
||||
|
||||
/* Add weak aliases. */
|
||||
#if _LIBC - 0 && defined (weak_alias)
|
||||
|
||||
weak_alias (__argp_usage, argp_usage)
|
||||
weak_alias (__option_is_short, _option_is_short)
|
||||
weak_alias (__option_is_end, _option_is_end)
|
||||
|
||||
#endif
|
604
contrib/cpio/lib/argp.h
Normal file
604
contrib/cpio/lib/argp.h
Normal file
@ -0,0 +1,604 @@
|
||||
/* Hierarchial argument parsing, layered over getopt.
|
||||
Copyright (C) 1995-1999,2003,2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _ARGP_H
|
||||
#define _ARGP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define __need_error_t
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef __const
|
||||
# define __const const
|
||||
#endif
|
||||
|
||||
#ifndef __THROW
|
||||
# define __THROW
|
||||
#endif
|
||||
#ifndef __NTH
|
||||
# define __NTH(fct) fct __THROW
|
||||
#endif
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__
|
||||
# define __format__ format
|
||||
# define __printf__ printf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* GCC 2.95 and later have "__restrict"; C99 compilers have
|
||||
"restrict", and "configure" may have defined "restrict". */
|
||||
#ifndef __restrict
|
||||
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
|
||||
# if defined restrict || 199901L <= __STDC_VERSION__
|
||||
# define __restrict restrict
|
||||
# else
|
||||
# define __restrict
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __error_t_defined
|
||||
typedef int error_t;
|
||||
# define __error_t_defined
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* A description of a particular option. A pointer to an array of
|
||||
these is passed in the OPTIONS field of an argp structure. Each option
|
||||
entry can correspond to one long option and/or one short option; more
|
||||
names for the same option can be added by following an entry in an option
|
||||
array with options having the OPTION_ALIAS flag set. */
|
||||
struct argp_option
|
||||
{
|
||||
/* The long option name. For more than one name for the same option, you
|
||||
can use following options with the OPTION_ALIAS flag set. */
|
||||
__const char *name;
|
||||
|
||||
/* What key is returned for this option. If > 0 and printable, then it's
|
||||
also accepted as a short option. */
|
||||
int key;
|
||||
|
||||
/* If non-NULL, this is the name of the argument associated with this
|
||||
option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
|
||||
__const char *arg;
|
||||
|
||||
/* OPTION_ flags. */
|
||||
int flags;
|
||||
|
||||
/* The doc string for this option. If both NAME and KEY are 0, This string
|
||||
will be printed outdented from the normal option column, making it
|
||||
useful as a group header (it will be the first thing printed in its
|
||||
group); in this usage, it's conventional to end the string with a `:'. */
|
||||
__const char *doc;
|
||||
|
||||
/* The group this option is in. In a long help message, options are sorted
|
||||
alphabetically within each group, and the groups presented in the order
|
||||
0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with
|
||||
if this field 0 will inherit the group number of the previous entry, or
|
||||
zero if it's the first one, unless its a group header (NAME and KEY both
|
||||
0), in which case, the previous entry + 1 is the default. Automagic
|
||||
options such as --help are put into group -1. */
|
||||
int group;
|
||||
};
|
||||
|
||||
/* The argument associated with this option is optional. */
|
||||
#define OPTION_ARG_OPTIONAL 0x1
|
||||
|
||||
/* This option isn't displayed in any help messages. */
|
||||
#define OPTION_HIDDEN 0x2
|
||||
|
||||
/* This option is an alias for the closest previous non-alias option. This
|
||||
means that it will be displayed in the same help entry, and will inherit
|
||||
fields other than NAME and KEY from the aliased option. */
|
||||
#define OPTION_ALIAS 0x4
|
||||
|
||||
/* This option isn't actually an option (and so should be ignored by the
|
||||
actual option parser), but rather an arbitrary piece of documentation that
|
||||
should be displayed in much the same manner as the options. If this flag
|
||||
is set, then the option NAME field is displayed unmodified (e.g., no `--'
|
||||
prefix is added) at the left-margin (where a *short* option would normally
|
||||
be displayed), and the documentation string in the normal place. The NAME
|
||||
field will be translated using gettext, unless OPTION_NO_TRANS is set (see
|
||||
below). For purposes of sorting, any leading whitespace and punctuation is
|
||||
ignored, except that if the first non-whitespace character is not `-', this
|
||||
entry is displayed after all options (and OPTION_DOC entries with a leading
|
||||
`-') in the same group. */
|
||||
#define OPTION_DOC 0x8
|
||||
|
||||
/* This option shouldn't be included in `long' usage messages (but is still
|
||||
included in help messages). This is mainly intended for options that are
|
||||
completely documented in an argp's ARGS_DOC field, in which case including
|
||||
the option in the generic usage list would be redundant. For instance,
|
||||
if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
|
||||
distinguish these two cases, -x should probably be marked
|
||||
OPTION_NO_USAGE. */
|
||||
#define OPTION_NO_USAGE 0x10
|
||||
|
||||
/* Valid only in conjunction with OPTION_DOC. This option disables translation
|
||||
of option name. */
|
||||
#define OPTION_NO_TRANS 0x20
|
||||
|
||||
|
||||
struct argp; /* fwd declare this type */
|
||||
struct argp_state; /* " */
|
||||
struct argp_child; /* " */
|
||||
|
||||
/* The type of a pointer to an argp parsing function. */
|
||||
typedef error_t (*argp_parser_t) (int key, char *arg,
|
||||
struct argp_state *state);
|
||||
|
||||
/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such
|
||||
returns will simply be ignored. For user keys, this error will be turned
|
||||
into EINVAL (if the call to argp_parse is such that errors are propagated
|
||||
back to the user instead of exiting); returning EINVAL itself would result
|
||||
in an immediate stop to parsing in *all* cases. */
|
||||
#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */
|
||||
|
||||
/* Special values for the KEY argument to an argument parsing function.
|
||||
ARGP_ERR_UNKNOWN should be returned if they aren't understood.
|
||||
|
||||
The sequence of keys to a parsing function is either (where each
|
||||
uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
|
||||
|
||||
INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all
|
||||
or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed
|
||||
or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized
|
||||
|
||||
The third case is where every parser returned ARGP_KEY_UNKNOWN for an
|
||||
argument, in which case parsing stops at that argument (returning the
|
||||
unparsed arguments to the caller of argp_parse if requested, or stopping
|
||||
with an error message if not).
|
||||
|
||||
If an error occurs (either detected by argp, or because the parsing
|
||||
function returned an error value), then the parser is called with
|
||||
ARGP_KEY_ERROR, and no further calls are made. */
|
||||
|
||||
/* This is not an option at all, but rather a command line argument. If a
|
||||
parser receiving this key returns success, the fact is recorded, and the
|
||||
ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the
|
||||
argument, a parser function decrements the NEXT field of the state it's
|
||||
passed, the option won't be considered processed; this is to allow you to
|
||||
actually modify the argument (perhaps into an option), and have it
|
||||
processed again. */
|
||||
#define ARGP_KEY_ARG 0
|
||||
/* There are remaining arguments not parsed by any parser, which may be found
|
||||
starting at (STATE->argv + STATE->next). If success is returned, but
|
||||
STATE->next left untouched, it's assumed that all arguments were consume,
|
||||
otherwise, the parser should adjust STATE->next to reflect any arguments
|
||||
consumed. */
|
||||
#define ARGP_KEY_ARGS 0x1000006
|
||||
/* There are no more command line arguments at all. */
|
||||
#define ARGP_KEY_END 0x1000001
|
||||
/* Because it's common to want to do some special processing if there aren't
|
||||
any non-option args, user parsers are called with this key if they didn't
|
||||
successfully process any non-option arguments. Called just before
|
||||
ARGP_KEY_END (where more general validity checks on previously parsed
|
||||
arguments can take place). */
|
||||
#define ARGP_KEY_NO_ARGS 0x1000002
|
||||
/* Passed in before any parsing is done. Afterwards, the values of each
|
||||
element of the CHILD_INPUT field, if any, in the state structure is
|
||||
copied to each child's state to be the initial value of the INPUT field. */
|
||||
#define ARGP_KEY_INIT 0x1000003
|
||||
/* Use after all other keys, including SUCCESS & END. */
|
||||
#define ARGP_KEY_FINI 0x1000007
|
||||
/* Passed in when parsing has successfully been completed (even if there are
|
||||
still arguments remaining). */
|
||||
#define ARGP_KEY_SUCCESS 0x1000004
|
||||
/* Passed in if an error occurs. */
|
||||
#define ARGP_KEY_ERROR 0x1000005
|
||||
|
||||
/* An argp structure contains a set of options declarations, a function to
|
||||
deal with parsing one, documentation string, a possible vector of child
|
||||
argp's, and perhaps a function to filter help output. When actually
|
||||
parsing options, getopt is called with the union of all the argp
|
||||
structures chained together through their CHILD pointers, with conflicts
|
||||
being resolved in favor of the first occurrence in the chain. */
|
||||
struct argp
|
||||
{
|
||||
/* An array of argp_option structures, terminated by an entry with both
|
||||
NAME and KEY having a value of 0. */
|
||||
__const struct argp_option *options;
|
||||
|
||||
/* What to do with an option from this structure. KEY is the key
|
||||
associated with the option, and ARG is any associated argument (NULL if
|
||||
none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be
|
||||
returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
|
||||
parsing is stopped immediately, and that value is returned from
|
||||
argp_parse(). For special (non-user-supplied) values of KEY, see the
|
||||
ARGP_KEY_ definitions below. */
|
||||
argp_parser_t parser;
|
||||
|
||||
/* A string describing what other arguments are wanted by this program. It
|
||||
is only used by argp_usage to print the `Usage:' message. If it
|
||||
contains newlines, the strings separated by them are considered
|
||||
alternative usage patterns, and printed on separate lines (lines after
|
||||
the first are prefix by ` or: ' instead of `Usage:'). */
|
||||
__const char *args_doc;
|
||||
|
||||
/* If non-NULL, a string containing extra text to be printed before and
|
||||
after the options in a long help message (separated by a vertical tab
|
||||
`\v' character). */
|
||||
__const char *doc;
|
||||
|
||||
/* A vector of argp_children structures, terminated by a member with a 0
|
||||
argp field, pointing to child argps should be parsed with this one. Any
|
||||
conflicts are resolved in favor of this argp, or early argps in the
|
||||
CHILDREN list. This field is useful if you use libraries that supply
|
||||
their own argp structure, which you want to use in conjunction with your
|
||||
own. */
|
||||
__const struct argp_child *children;
|
||||
|
||||
/* If non-zero, this should be a function to filter the output of help
|
||||
messages. KEY is either a key from an option, in which case TEXT is
|
||||
that option's help text, or a special key from the ARGP_KEY_HELP_
|
||||
defines, below, describing which other help text TEXT is. The function
|
||||
should return either TEXT, if it should be used as-is, a replacement
|
||||
string, which should be malloced, and will be freed by argp, or NULL,
|
||||
meaning `print nothing'. The value for TEXT is *after* any translation
|
||||
has been done, so if any of the replacement text also needs translation,
|
||||
that should be done by the filter function. INPUT is either the input
|
||||
supplied to argp_parse, or NULL, if argp_help was called directly. */
|
||||
char *(*help_filter) (int __key, __const char *__text, void *__input);
|
||||
|
||||
/* If non-zero the strings used in the argp library are translated using
|
||||
the domain described by this string. Otherwise the currently installed
|
||||
default domain is used. */
|
||||
const char *argp_domain;
|
||||
};
|
||||
|
||||
/* Possible KEY arguments to a help filter function. */
|
||||
#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */
|
||||
#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */
|
||||
#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */
|
||||
#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation;
|
||||
TEXT is NULL for this key. */
|
||||
/* Explanatory note emitted when duplicate option arguments have been
|
||||
suppressed. */
|
||||
#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
|
||||
#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */
|
||||
|
||||
/* When an argp has a non-zero CHILDREN field, it should point to a vector of
|
||||
argp_child structures, each of which describes a subsidiary argp. */
|
||||
struct argp_child
|
||||
{
|
||||
/* The child parser. */
|
||||
__const struct argp *argp;
|
||||
|
||||
/* Flags for this child. */
|
||||
int flags;
|
||||
|
||||
/* If non-zero, an optional header to be printed in help output before the
|
||||
child options. As a side-effect, a non-zero value forces the child
|
||||
options to be grouped together; to achieve this effect without actually
|
||||
printing a header string, use a value of "". */
|
||||
__const char *header;
|
||||
|
||||
/* Where to group the child options relative to the other (`consolidated')
|
||||
options in the parent argp; the values are the same as the GROUP field
|
||||
in argp_option structs, but all child-groupings follow parent options at
|
||||
a particular group level. If both this field and HEADER are zero, then
|
||||
they aren't grouped at all, but rather merged with the parent options
|
||||
(merging the child's grouping levels with the parents). */
|
||||
int group;
|
||||
};
|
||||
|
||||
/* Parsing state. This is provided to parsing functions called by argp,
|
||||
which may examine and, as noted, modify fields. */
|
||||
struct argp_state
|
||||
{
|
||||
/* The top level ARGP being parsed. */
|
||||
__const struct argp *root_argp;
|
||||
|
||||
/* The argument vector being parsed. May be modified. */
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
/* The index in ARGV of the next arg that to be parsed. May be modified. */
|
||||
int next;
|
||||
|
||||
/* The flags supplied to argp_parse. May be modified. */
|
||||
unsigned flags;
|
||||
|
||||
/* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
|
||||
number of the current arg, starting at zero, and incremented after each
|
||||
such call returns. At all other times, this is the number of such
|
||||
arguments that have been processed. */
|
||||
unsigned arg_num;
|
||||
|
||||
/* If non-zero, the index in ARGV of the first argument following a special
|
||||
`--' argument (which prevents anything following being interpreted as an
|
||||
option). Only set once argument parsing has proceeded past this point. */
|
||||
int quoted;
|
||||
|
||||
/* An arbitrary pointer passed in from the user. */
|
||||
void *input;
|
||||
/* Values to pass to child parsers. This vector will be the same length as
|
||||
the number of children for the current parser. */
|
||||
void **child_inputs;
|
||||
|
||||
/* For the parser's use. Initialized to 0. */
|
||||
void *hook;
|
||||
|
||||
/* The name used when printing messages. This is initialized to ARGV[0],
|
||||
or PROGRAM_INVOCATION_NAME if that is unavailable. */
|
||||
char *name;
|
||||
|
||||
/* Streams used when argp prints something. */
|
||||
FILE *err_stream; /* For errors; initialized to stderr. */
|
||||
FILE *out_stream; /* For information; initialized to stdout. */
|
||||
|
||||
void *pstate; /* Private, for use by argp. */
|
||||
};
|
||||
|
||||
/* Flags for argp_parse (note that the defaults are those that are
|
||||
convenient for program command line parsing): */
|
||||
|
||||
/* Don't ignore the first element of ARGV. Normally (and always unless
|
||||
ARGP_NO_ERRS is set) the first element of the argument vector is
|
||||
skipped for option parsing purposes, as it corresponds to the program name
|
||||
in a command line. */
|
||||
#define ARGP_PARSE_ARGV0 0x01
|
||||
|
||||
/* Don't print error messages for unknown options to stderr; unless this flag
|
||||
is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
|
||||
name in the error messages. This flag implies ARGP_NO_EXIT (on the
|
||||
assumption that silent exiting upon errors is bad behaviour). */
|
||||
#define ARGP_NO_ERRS 0x02
|
||||
|
||||
/* Don't parse any non-option args. Normally non-option args are parsed by
|
||||
calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
|
||||
as the value. Since it's impossible to know which parse function wants to
|
||||
handle it, each one is called in turn, until one returns 0 or an error
|
||||
other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
|
||||
argp_parse returns prematurely (but with a return value of 0). If all
|
||||
args have been parsed without error, all parsing functions are called one
|
||||
last time with a key of ARGP_KEY_END. This flag needn't normally be set,
|
||||
as the normal behavior is to stop parsing as soon as some argument can't
|
||||
be handled. */
|
||||
#define ARGP_NO_ARGS 0x04
|
||||
|
||||
/* Parse options and arguments in the same order they occur on the command
|
||||
line -- normally they're rearranged so that all options come first. */
|
||||
#define ARGP_IN_ORDER 0x08
|
||||
|
||||
/* Don't provide the standard long option --help, which causes usage and
|
||||
option help information to be output to stdout, and exit (0) called. */
|
||||
#define ARGP_NO_HELP 0x10
|
||||
|
||||
/* Don't exit on errors (they may still result in error messages). */
|
||||
#define ARGP_NO_EXIT 0x20
|
||||
|
||||
/* Use the gnu getopt `long-only' rules for parsing arguments. */
|
||||
#define ARGP_LONG_ONLY 0x40
|
||||
|
||||
/* Turns off any message-printing/exiting options. */
|
||||
#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
|
||||
|
||||
/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
|
||||
FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the
|
||||
index in ARGV of the first unparsed option is returned in it. If an
|
||||
unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
|
||||
routine returned a non-zero value, it is returned; otherwise 0 is
|
||||
returned. This function may also call exit unless the ARGP_NO_HELP flag
|
||||
is set. INPUT is a pointer to a value to be passed in to the parser. */
|
||||
extern error_t argp_parse (__const struct argp *__restrict __argp,
|
||||
int __argc, char **__restrict __argv,
|
||||
unsigned __flags, int *__restrict __arg_index,
|
||||
void *__restrict __input);
|
||||
extern error_t __argp_parse (__const struct argp *__restrict __argp,
|
||||
int __argc, char **__restrict __argv,
|
||||
unsigned __flags, int *__restrict __arg_index,
|
||||
void *__restrict __input);
|
||||
|
||||
/* Global variables. */
|
||||
|
||||
/* If defined or set by the user program to a non-zero value, then a default
|
||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||
will print this string followed by a newline and exit (unless the
|
||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||
extern __const char *argp_program_version;
|
||||
|
||||
/* If defined or set by the user program to a non-zero value, then a default
|
||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||
calls this function with a stream to print the version to and a pointer to
|
||||
the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
|
||||
used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
|
||||
extern void (*argp_program_version_hook) (FILE *__restrict __stream,
|
||||
struct argp_state *__restrict
|
||||
__state);
|
||||
|
||||
/* If defined or set by the user program, it should point to string that is
|
||||
the bug-reporting address for the program. It will be printed by
|
||||
argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
|
||||
standard help messages), embedded in a sentence that says something like
|
||||
`Report bugs to ADDR.'. */
|
||||
extern __const char *argp_program_bug_address;
|
||||
|
||||
/* The exit status that argp will use when exiting due to a parsing error.
|
||||
If not defined or set by the user program, this defaults to EX_USAGE from
|
||||
<sysexits.h>. */
|
||||
extern error_t argp_err_exit_status;
|
||||
|
||||
/* Flags for argp_help. */
|
||||
#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
|
||||
#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */
|
||||
#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */
|
||||
#define ARGP_HELP_LONG 0x08 /* a long help message. */
|
||||
#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */
|
||||
#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */
|
||||
#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
|
||||
#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */
|
||||
#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to
|
||||
reflect ARGP_LONG_ONLY mode. */
|
||||
|
||||
/* These ARGP_HELP flags are only understood by argp_state_help. */
|
||||
#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */
|
||||
#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */
|
||||
|
||||
/* The standard thing to do after a program command line parsing error, if an
|
||||
error message has already been printed. */
|
||||
#define ARGP_HELP_STD_ERR \
|
||||
(ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
|
||||
/* The standard thing to do after a program command line parsing error, if no
|
||||
more specific error message has been printed. */
|
||||
#define ARGP_HELP_STD_USAGE \
|
||||
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
|
||||
/* The standard thing to do in response to a --help option. */
|
||||
#define ARGP_HELP_STD_HELP \
|
||||
(ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
|
||||
| ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
|
||||
|
||||
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
|
||||
ARGP_HELP_*. */
|
||||
extern void argp_help (__const struct argp *__restrict __argp,
|
||||
FILE *__restrict __stream,
|
||||
unsigned __flags, char *__restrict __name);
|
||||
extern void __argp_help (__const struct argp *__restrict __argp,
|
||||
FILE *__restrict __stream, unsigned __flags,
|
||||
char *__name);
|
||||
|
||||
/* The following routines are intended to be called from within an argp
|
||||
parsing routine (thus taking an argp_state structure as the first
|
||||
argument). They may or may not print an error message and exit, depending
|
||||
on the flags in STATE -- in any case, the caller should be prepared for
|
||||
them *not* to exit, and should return an appropiate error after calling
|
||||
them. [argp_usage & argp_error should probably be called argp_state_...,
|
||||
but they're used often enough that they should be short] */
|
||||
|
||||
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
|
||||
from the set ARGP_HELP_*. */
|
||||
extern void argp_state_help (__const struct argp_state *__restrict __state,
|
||||
FILE *__restrict __stream,
|
||||
unsigned int __flags);
|
||||
extern void __argp_state_help (__const struct argp_state *__restrict __state,
|
||||
FILE *__restrict __stream,
|
||||
unsigned int __flags);
|
||||
|
||||
/* Possibly output the standard usage message for ARGP to stderr and exit. */
|
||||
extern void argp_usage (__const struct argp_state *__state);
|
||||
extern void __argp_usage (__const struct argp_state *__state);
|
||||
|
||||
/* If appropriate, print the printf string FMT and following args, preceded
|
||||
by the program name and `:', to stderr, and followed by a `Try ... --help'
|
||||
message, then exit (1). */
|
||||
extern void argp_error (__const struct argp_state *__restrict __state,
|
||||
__const char *__restrict __fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
extern void __argp_error (__const struct argp_state *__restrict __state,
|
||||
__const char *__restrict __fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
|
||||
/* Similar to the standard gnu error-reporting function error(), but will
|
||||
respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
|
||||
to STATE->err_stream. This is useful for argument parsing code that is
|
||||
shared between program startup (when exiting is desired) and runtime
|
||||
option parsing (when typically an error code is returned instead). The
|
||||
difference between this function and argp_error is that the latter is for
|
||||
*parsing errors*, and the former is for other problems that occur during
|
||||
parsing but don't reflect a (syntactic) problem with the input. */
|
||||
extern void argp_failure (__const struct argp_state *__restrict __state,
|
||||
int __status, int __errnum,
|
||||
__const char *__restrict __fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
extern void __argp_failure (__const struct argp_state *__restrict __state,
|
||||
int __status, int __errnum,
|
||||
__const char *__restrict __fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||
|
||||
/* Returns true if the option OPT is a valid short option. */
|
||||
extern int _option_is_short (__const struct argp_option *__opt) __THROW;
|
||||
extern int __option_is_short (__const struct argp_option *__opt) __THROW;
|
||||
|
||||
/* Returns true if the option OPT is in fact the last (unused) entry in an
|
||||
options array. */
|
||||
extern int _option_is_end (__const struct argp_option *__opt) __THROW;
|
||||
extern int __option_is_end (__const struct argp_option *__opt) __THROW;
|
||||
|
||||
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
||||
by the help routines. */
|
||||
extern void *_argp_input (__const struct argp *__restrict __argp,
|
||||
__const struct argp_state *__restrict __state)
|
||||
__THROW;
|
||||
extern void *__argp_input (__const struct argp *__restrict __argp,
|
||||
__const struct argp_state *__restrict __state)
|
||||
__THROW;
|
||||
|
||||
#ifdef __USE_EXTERN_INLINES
|
||||
|
||||
# if !_LIBC
|
||||
# define __argp_usage argp_usage
|
||||
# define __argp_state_help argp_state_help
|
||||
# define __option_is_short _option_is_short
|
||||
# define __option_is_end _option_is_end
|
||||
# endif
|
||||
|
||||
# ifndef ARGP_EI
|
||||
# define ARGP_EI extern __inline__
|
||||
# endif
|
||||
|
||||
ARGP_EI void
|
||||
__NTH (__argp_usage (__const struct argp_state *__state))
|
||||
{
|
||||
__argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
|
||||
}
|
||||
|
||||
ARGP_EI int
|
||||
__NTH (__option_is_short (__const struct argp_option *__opt))
|
||||
{
|
||||
if (__opt->flags & OPTION_DOC)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int __key = __opt->key;
|
||||
return __key > 0 && isprint (__key);
|
||||
}
|
||||
}
|
||||
|
||||
ARGP_EI int
|
||||
__NTH (__option_is_end (__const struct argp_option *__opt))
|
||||
{
|
||||
return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
|
||||
}
|
||||
|
||||
# if !_LIBC
|
||||
# undef __argp_usage
|
||||
# undef __argp_state_help
|
||||
# undef __option_is_short
|
||||
# undef __option_is_end
|
||||
# endif
|
||||
#endif /* Use extern inlines. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* argp.h */
|
79
contrib/cpio/lib/basename.c
Normal file
79
contrib/cpio/lib/basename.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* basename.c -- return the last element in a path
|
||||
|
||||
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "dirname.h"
|
||||
#include <string.h>
|
||||
|
||||
/* In general, we can't use the builtin `basename' function if available,
|
||||
since it has different meanings in different environments.
|
||||
In some environments the builtin `basename' modifies its argument.
|
||||
|
||||
Return the address of the last file name component of NAME. If
|
||||
NAME has no file name components because it is all slashes, return
|
||||
NAME if it is empty, the address of its last slash otherwise. */
|
||||
|
||||
char *
|
||||
base_name (char const *name)
|
||||
{
|
||||
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
||||
char const *p;
|
||||
|
||||
for (p = base; *p; p++)
|
||||
{
|
||||
if (ISSLASH (*p))
|
||||
{
|
||||
/* Treat multiple adjacent slashes like a single slash. */
|
||||
do p++;
|
||||
while (ISSLASH (*p));
|
||||
|
||||
/* If the file name ends in slash, use the trailing slash as
|
||||
the basename if no non-slashes have been found. */
|
||||
if (! *p)
|
||||
{
|
||||
if (ISSLASH (*base))
|
||||
base = p - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* *P is a non-slash preceded by a slash. */
|
||||
base = p;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *) base;
|
||||
}
|
||||
|
||||
/* Return the length of of the basename NAME. Typically NAME is the
|
||||
value returned by base_name. Act like strlen (NAME), except omit
|
||||
redundant trailing slashes. */
|
||||
|
||||
size_t
|
||||
base_len (char const *name)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
||||
continue;
|
||||
|
||||
return len;
|
||||
}
|
121
contrib/cpio/lib/dirname.c
Normal file
121
contrib/cpio/lib/dirname.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* dirname.c -- return all but the last element in a path
|
||||
|
||||
Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "xalloc.h"
|
||||
|
||||
/* Return the length of `dirname (PATH)', or zero if PATH is
|
||||
in the working directory. Works properly even if
|
||||
there are trailing slashes (by effectively ignoring them). */
|
||||
size_t
|
||||
dir_len (char const *path)
|
||||
{
|
||||
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (path);
|
||||
size_t length;
|
||||
|
||||
/* Strip the basename and any redundant slashes before it. */
|
||||
for (length = base_name (path) - path; prefix_length < length; length--)
|
||||
if (! ISSLASH (path[length - 1]))
|
||||
return length;
|
||||
|
||||
/* But don't strip the only slash from "/". */
|
||||
return prefix_length + ISSLASH (path[prefix_length]);
|
||||
}
|
||||
|
||||
/* Return the leading directories part of PATH,
|
||||
allocated with xmalloc.
|
||||
Works properly even if there are trailing slashes
|
||||
(by effectively ignoring them). */
|
||||
|
||||
char *
|
||||
dir_name (char const *path)
|
||||
{
|
||||
size_t length = dir_len (path);
|
||||
bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (path));
|
||||
char *newpath = xmalloc (length + append_dot + 1);
|
||||
memcpy (newpath, path, length);
|
||||
if (append_dot)
|
||||
newpath[length++] = '.';
|
||||
newpath[length] = 0;
|
||||
return newpath;
|
||||
}
|
||||
|
||||
#ifdef TEST_DIRNAME
|
||||
/*
|
||||
|
||||
Run the test like this (expect no output):
|
||||
gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \
|
||||
basename.c dirname.c xmalloc.c error.c
|
||||
sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out
|
||||
|
||||
If it's been built on a DOS or Windows platforms, run another test like
|
||||
this (again, expect no output):
|
||||
sed -n '/^BEGIN-DOS-DATA$/,/^END-DOS-DATA$/p' dirname.c|grep -v DATA|./a.out
|
||||
|
||||
BEGIN-DATA
|
||||
foo//// .
|
||||
bar/foo//// bar
|
||||
foo/ .
|
||||
/ /
|
||||
. .
|
||||
a .
|
||||
END-DATA
|
||||
|
||||
BEGIN-DOS-DATA
|
||||
c:///// c:/
|
||||
c:/ c:/
|
||||
c:/. c:/
|
||||
c:foo c:.
|
||||
c:foo/bar c:foo
|
||||
END-DOS-DATA
|
||||
|
||||
*/
|
||||
|
||||
# define MAX_BUFF_LEN 1024
|
||||
# include <stdio.h>
|
||||
|
||||
char *program_name;
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
char buff[MAX_BUFF_LEN + 1];
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
buff[MAX_BUFF_LEN] = 0;
|
||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
||||
{
|
||||
char path[MAX_BUFF_LEN];
|
||||
char expected_result[MAX_BUFF_LEN];
|
||||
char const *result;
|
||||
sscanf (buff, "%s %s", path, expected_result);
|
||||
result = dir_name (path);
|
||||
if (strcmp (result, expected_result))
|
||||
printf ("%s: got %s, expected %s\n", path, result, expected_result);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
47
contrib/cpio/lib/dirname.h
Normal file
47
contrib/cpio/lib/dirname.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Take file names apart into directory and base names.
|
||||
|
||||
Copyright (C) 1998, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef DIRNAME_H_
|
||||
# define DIRNAME_H_ 1
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stddef.h>
|
||||
|
||||
# ifndef DIRECTORY_SEPARATOR
|
||||
# define DIRECTORY_SEPARATOR '/'
|
||||
# endif
|
||||
|
||||
# ifndef ISSLASH
|
||||
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
|
||||
# endif
|
||||
|
||||
# ifndef FILE_SYSTEM_PREFIX_LEN
|
||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
|
||||
# endif
|
||||
|
||||
# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
|
||||
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
|
||||
|
||||
char *base_name (char const *path);
|
||||
char *dir_name (char const *path);
|
||||
size_t base_len (char const *path);
|
||||
size_t dir_len (char const *path);
|
||||
|
||||
bool strip_trailing_slashes (char *path);
|
||||
|
||||
#endif /* not DIRNAME_H_ */
|
306
contrib/cpio/lib/error.c
Normal file
306
contrib/cpio/lib/error.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* Error handler for noninteractive utilities
|
||||
Copyright (C) 1990-1998, 2000-2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
#else
|
||||
# include "gettext.h"
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <wchar.h>
|
||||
# define mbsrtowcs __mbsrtowcs
|
||||
#endif
|
||||
|
||||
#if USE_UNLOCKED_IO
|
||||
# include "unlocked-io.h"
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
# define _(String) String
|
||||
#endif
|
||||
|
||||
/* If NULL, error will flush stdout, then print on stderr the program
|
||||
name, a colon and a space. Otherwise, error will call this
|
||||
function without parameters instead. */
|
||||
void (*error_print_progname) (void);
|
||||
|
||||
/* This variable is incremented each time `error' is called. */
|
||||
unsigned int error_message_count;
|
||||
|
||||
#ifdef _LIBC
|
||||
/* In the GNU C library, there is a predefined variable for this. */
|
||||
|
||||
# define program_name program_invocation_name
|
||||
# include <errno.h>
|
||||
# include <libio/libioP.h>
|
||||
|
||||
/* In GNU libc we want do not want to use the common name `error' directly.
|
||||
Instead make it a weak alias. */
|
||||
extern void __error (int status, int errnum, const char *message, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
extern void __error_at_line (int status, int errnum, const char *file_name,
|
||||
unsigned int line_number, const char *message,
|
||||
...)
|
||||
__attribute__ ((__format__ (__printf__, 5, 6)));;
|
||||
# define error __error
|
||||
# define error_at_line __error_at_line
|
||||
|
||||
# include <libio/iolibio.h>
|
||||
# define fflush(s) INTUSE(_IO_fflush) (s)
|
||||
# undef putc
|
||||
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
|
||||
|
||||
# include <bits/libc-lock.h>
|
||||
|
||||
#else /* not _LIBC */
|
||||
|
||||
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
|
||||
# ifndef HAVE_DECL_STRERROR_R
|
||||
"this configure-time declaration test was not run"
|
||||
# endif
|
||||
char *strerror_r ();
|
||||
# endif
|
||||
|
||||
# ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
# endif
|
||||
|
||||
/* The calling program should define program_name and set it to the
|
||||
name of the executing program. */
|
||||
extern char *program_name;
|
||||
|
||||
# if HAVE_STRERROR_R || defined strerror_r
|
||||
# define __strerror_r strerror_r
|
||||
# endif
|
||||
#endif /* not _LIBC */
|
||||
|
||||
static void
|
||||
print_errno_message (int errnum)
|
||||
{
|
||||
char const *s = NULL;
|
||||
|
||||
#if defined HAVE_STRERROR_R || _LIBC
|
||||
char errbuf[1024];
|
||||
# if STRERROR_R_CHAR_P || _LIBC
|
||||
s = __strerror_r (errnum, errbuf, sizeof errbuf);
|
||||
# else
|
||||
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
|
||||
s = errbuf;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !_LIBC
|
||||
if (! s && ! (s = strerror (errnum)))
|
||||
s = _("Unknown system error");
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
{
|
||||
__fwprintf (stderr, L": %s", s);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf (stderr, ": %s", s);
|
||||
}
|
||||
|
||||
static void
|
||||
error_tail (int status, int errnum, const char *message, va_list args)
|
||||
{
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
{
|
||||
# define ALLOCA_LIMIT 2000
|
||||
size_t len = strlen (message) + 1;
|
||||
const wchar_t *wmessage = L"out of memory";
|
||||
wchar_t *wbuf = (len < ALLOCA_LIMIT
|
||||
? alloca (len * sizeof *wbuf)
|
||||
: len <= SIZE_MAX / sizeof *wbuf
|
||||
? malloc (len * sizeof *wbuf)
|
||||
: NULL);
|
||||
|
||||
if (wbuf)
|
||||
{
|
||||
size_t res;
|
||||
mbstate_t st;
|
||||
const char *tmp = message;
|
||||
memset (&st, '\0', sizeof (st));
|
||||
res = mbsrtowcs (wbuf, &tmp, len, &st);
|
||||
wmessage = res == (size_t) -1 ? L"???" : wbuf;
|
||||
}
|
||||
|
||||
__vfwprintf (stderr, wmessage, args);
|
||||
if (! (len < ALLOCA_LIMIT))
|
||||
free (wbuf);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
vfprintf (stderr, message, args);
|
||||
va_end (args);
|
||||
|
||||
++error_message_count;
|
||||
if (errnum)
|
||||
print_errno_message (errnum);
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
putwc (L'\n', stderr);
|
||||
else
|
||||
#endif
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (status)
|
||||
exit (status);
|
||||
}
|
||||
|
||||
|
||||
/* Print the program name and error message MESSAGE, which is a printf-style
|
||||
format string with optional args.
|
||||
If ERRNUM is nonzero, print its corresponding system error message.
|
||||
Exit with status STATUS if it is nonzero. */
|
||||
void
|
||||
error (int status, int errnum, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
#if defined _LIBC && defined __libc_ptf_call
|
||||
/* We do not want this call to be cut short by a thread
|
||||
cancellation. Therefore disable cancellation for now. */
|
||||
int state = PTHREAD_CANCEL_ENABLE;
|
||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
||||
0);
|
||||
#endif
|
||||
|
||||
fflush (stdout);
|
||||
#ifdef _LIBC
|
||||
_IO_flockfile (stderr);
|
||||
#endif
|
||||
if (error_print_progname)
|
||||
(*error_print_progname) ();
|
||||
else
|
||||
{
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
__fwprintf (stderr, L"%s: ", program_name);
|
||||
else
|
||||
#endif
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
}
|
||||
|
||||
va_start (args, message);
|
||||
error_tail (status, errnum, message, args);
|
||||
|
||||
#ifdef _LIBC
|
||||
_IO_funlockfile (stderr);
|
||||
# ifdef __libc_ptf_call
|
||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Sometimes we want to have at most one error per line. This
|
||||
variable controls whether this mode is selected or not. */
|
||||
int error_one_per_line;
|
||||
|
||||
void
|
||||
error_at_line (int status, int errnum, const char *file_name,
|
||||
unsigned int line_number, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (error_one_per_line)
|
||||
{
|
||||
static const char *old_file_name;
|
||||
static unsigned int old_line_number;
|
||||
|
||||
if (old_line_number == line_number
|
||||
&& (file_name == old_file_name
|
||||
|| strcmp (old_file_name, file_name) == 0))
|
||||
/* Simply return and print nothing. */
|
||||
return;
|
||||
|
||||
old_file_name = file_name;
|
||||
old_line_number = line_number;
|
||||
}
|
||||
|
||||
#if defined _LIBC && defined __libc_ptf_call
|
||||
/* We do not want this call to be cut short by a thread
|
||||
cancellation. Therefore disable cancellation for now. */
|
||||
int state = PTHREAD_CANCEL_ENABLE;
|
||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
||||
0);
|
||||
#endif
|
||||
|
||||
fflush (stdout);
|
||||
#ifdef _LIBC
|
||||
_IO_flockfile (stderr);
|
||||
#endif
|
||||
if (error_print_progname)
|
||||
(*error_print_progname) ();
|
||||
else
|
||||
{
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
__fwprintf (stderr, L"%s: ", program_name);
|
||||
else
|
||||
#endif
|
||||
fprintf (stderr, "%s:", program_name);
|
||||
}
|
||||
|
||||
if (file_name != NULL)
|
||||
{
|
||||
#if _LIBC
|
||||
if (_IO_fwide (stderr, 0) > 0)
|
||||
__fwprintf (stderr, L"%s:%d: ", file_name, line_number);
|
||||
else
|
||||
#endif
|
||||
fprintf (stderr, "%s:%d: ", file_name, line_number);
|
||||
}
|
||||
|
||||
va_start (args, message);
|
||||
error_tail (status, errnum, message, args);
|
||||
|
||||
#ifdef _LIBC
|
||||
_IO_funlockfile (stderr);
|
||||
# ifdef __libc_ptf_call
|
||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
/* Make the weak alias. */
|
||||
# undef error
|
||||
# undef error_at_line
|
||||
weak_alias (__error, error)
|
||||
weak_alias (__error_at_line, error_at_line)
|
||||
#endif
|
66
contrib/cpio/lib/error.h
Normal file
66
contrib/cpio/lib/error.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* Declaration for error-reporting function
|
||||
Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _ERROR_H
|
||||
#define _ERROR_H 1
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
||||
# define __format__ format
|
||||
# define __printf__ printf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Print a message with `fprintf (stderr, FORMAT, ...)';
|
||||
if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
|
||||
If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
|
||||
|
||||
extern void error (int __status, int __errnum, const char *__format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
|
||||
extern void error_at_line (int __status, int __errnum, const char *__fname,
|
||||
unsigned int __lineno, const char *__format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 5, 6)));
|
||||
|
||||
/* If NULL, error will flush stdout, then print on stderr the program
|
||||
name, a colon and a space. Otherwise, error will call this
|
||||
function without parameters instead. */
|
||||
extern void (*error_print_progname) (void);
|
||||
|
||||
/* This variable is incremented each time `error' is called. */
|
||||
extern unsigned int error_message_count;
|
||||
|
||||
/* Sometimes we want to have at most one error per line. This
|
||||
variable controls whether this mode is selected or not. */
|
||||
extern int error_one_per_line;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* error.h */
|
32
contrib/cpio/lib/exit.h
Normal file
32
contrib/cpio/lib/exit.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* exit() function.
|
||||
Copyright (C) 1995, 2001 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _EXIT_H
|
||||
#define _EXIT_H
|
||||
|
||||
/* Get exit() declaration. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
|
||||
#ifndef EXIT_SUCCESS
|
||||
# define EXIT_SUCCESS 0
|
||||
#endif
|
||||
#ifndef EXIT_FAILURE
|
||||
# define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
#endif /* _EXIT_H */
|
27
contrib/cpio/lib/exitfail.c
Normal file
27
contrib/cpio/lib/exitfail.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* Failure exit status
|
||||
|
||||
Copyright (C) 2002, 2003 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; see the file COPYING.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "exitfail.h"
|
||||
#include "exit.h"
|
||||
|
||||
int volatile exit_failure = EXIT_FAILURE;
|
20
contrib/cpio/lib/exitfail.h
Normal file
20
contrib/cpio/lib/exitfail.h
Normal file
@ -0,0 +1,20 @@
|
||||
/* Failure exit status
|
||||
|
||||
Copyright (C) 2002 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; see the file COPYING.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
extern int volatile exit_failure;
|
83
contrib/cpio/lib/full-write.c
Normal file
83
contrib/cpio/lib/full-write.c
Normal file
@ -0,0 +1,83 @@
|
||||
/* An interface to read and write that retries (if necessary) until complete.
|
||||
|
||||
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||
2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#ifdef FULL_READ
|
||||
# include "full-read.h"
|
||||
#else
|
||||
# include "full-write.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef FULL_READ
|
||||
# include "safe-read.h"
|
||||
# define safe_rw safe_read
|
||||
# define full_rw full_read
|
||||
# undef const
|
||||
# define const /* empty */
|
||||
#else
|
||||
# include "safe-write.h"
|
||||
# define safe_rw safe_write
|
||||
# define full_rw full_write
|
||||
#endif
|
||||
|
||||
#ifdef FULL_READ
|
||||
/* Set errno to zero upon EOF. */
|
||||
# define ZERO_BYTE_TRANSFER_ERRNO 0
|
||||
#else
|
||||
/* Some buggy drivers return 0 when one tries to write beyond
|
||||
a device's end. (Example: Linux 1.2.13 on /dev/fd0.)
|
||||
Set errno to ENOSPC so they get a sensible diagnostic. */
|
||||
# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC
|
||||
#endif
|
||||
|
||||
/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if
|
||||
interrupted or if a partial write(read) occurs. Return the number
|
||||
of bytes transferred.
|
||||
When writing, set errno if fewer than COUNT bytes are written.
|
||||
When reading, if fewer than COUNT bytes are read, you must examine
|
||||
errno to distinguish failure from EOF (errno == 0). */
|
||||
size_t
|
||||
full_rw (int fd, const void *buf, size_t count)
|
||||
{
|
||||
size_t total = 0;
|
||||
const char *ptr = buf;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
size_t n_rw = safe_rw (fd, ptr, count);
|
||||
if (n_rw == (size_t) -1)
|
||||
break;
|
||||
if (n_rw == 0)
|
||||
{
|
||||
errno = ZERO_BYTE_TRANSFER_ERRNO;
|
||||
break;
|
||||
}
|
||||
total += n_rw;
|
||||
ptr += n_rw;
|
||||
count -= n_rw;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
35
contrib/cpio/lib/full-write.h
Normal file
35
contrib/cpio/lib/full-write.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* An interface to write() that writes all it is asked to write.
|
||||
|
||||
Copyright (C) 2002-2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted
|
||||
or if partial writes occur. Return the number of bytes successfully
|
||||
written, setting errno if that is less than COUNT. */
|
||||
extern size_t full_write (int fd, const void *buf, size_t count);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1241
contrib/cpio/lib/getopt.c
Normal file
1241
contrib/cpio/lib/getopt.c
Normal file
File diff suppressed because it is too large
Load Diff
174
contrib/cpio/lib/getopt1.c
Normal file
174
contrib/cpio/lib/getopt1.c
Normal file
@ -0,0 +1,174 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <getopt.h>
|
||||
#else
|
||||
# include "getopt.h"
|
||||
#endif
|
||||
#include "getopt_int.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
|
||||
const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, (char **) argv, options, long_options,
|
||||
opt_index, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
_getopt_long_r (int argc, char **argv, const char *options,
|
||||
const struct option *long_options, int *opt_index,
|
||||
struct _getopt_data *d)
|
||||
{
|
||||
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
|
||||
0, 0, d);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (int argc, char *__getopt_argv_const *argv,
|
||||
const char *options,
|
||||
const struct option *long_options, int *opt_index)
|
||||
{
|
||||
return _getopt_internal (argc, (char **) argv, options, long_options,
|
||||
opt_index, 1, 0);
|
||||
}
|
||||
|
||||
int
|
||||
_getopt_long_only_r (int argc, char **argv, const char *options,
|
||||
const struct option *long_options, int *opt_index,
|
||||
struct _getopt_data *d)
|
||||
{
|
||||
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
|
||||
1, 0, d);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
227
contrib/cpio/lib/getopt_.h
Normal file
227
contrib/cpio/lib/getopt_.h
Normal file
@ -0,0 +1,227 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* Standalone applications should #define __GETOPT_PREFIX to an
|
||||
identifier that prefixes the external functions and variables
|
||||
defined in this header. When this happens, include the
|
||||
headers that might declare getopt so that they will not cause
|
||||
confusion if included after this file. Then systematically rename
|
||||
identifiers so that they do not collide with the system functions
|
||||
and variables. Renaming avoids problems with some compilers and
|
||||
linkers. */
|
||||
#if defined __GETOPT_PREFIX && !defined __need_getopt
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
# undef __need_getopt
|
||||
# undef getopt
|
||||
# undef getopt_long
|
||||
# undef getopt_long_only
|
||||
# undef optarg
|
||||
# undef opterr
|
||||
# undef optind
|
||||
# undef optopt
|
||||
# define __GETOPT_CONCAT(x, y) x ## y
|
||||
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
|
||||
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
|
||||
# define getopt __GETOPT_ID (getopt)
|
||||
# define getopt_long __GETOPT_ID (getopt_long)
|
||||
# define getopt_long_only __GETOPT_ID (getopt_long_only)
|
||||
# define optarg __GETOPT_ID (optarg)
|
||||
# define opterr __GETOPT_ID (opterr)
|
||||
# define optind __GETOPT_ID (optind)
|
||||
# define optopt __GETOPT_ID (optopt)
|
||||
#endif
|
||||
|
||||
/* Standalone applications get correct prototypes for getopt_long and
|
||||
getopt_long_only; they declare "char **argv". libc uses prototypes
|
||||
with "char *const *argv" that are incorrect because getopt_long and
|
||||
getopt_long_only can permute argv; this is required for backward
|
||||
compatibility (e.g., for LSB 2.0.1).
|
||||
|
||||
This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
|
||||
but it caused redefinition warnings if both unistd.h and getopt.h were
|
||||
included, since unistd.h includes getopt.h having previously defined
|
||||
__need_getopt.
|
||||
|
||||
The only place where __getopt_argv_const is used is in definitions
|
||||
of getopt_long and getopt_long_only below, but these are visible
|
||||
only if __need_getopt is not defined, so it is quite safe to rewrite
|
||||
the conditional as follows:
|
||||
*/
|
||||
#if !defined __need_getopt
|
||||
# if defined __GETOPT_PREFIX
|
||||
# define __getopt_argv_const /* empty */
|
||||
# else
|
||||
# define __getopt_argv_const const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
||||
standalone, or this is the first header included in the source file.
|
||||
If we are being used with glibc, we need to include <features.h>, but
|
||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
||||
#if !defined __GNU_LIBRARY__
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifndef __THROW
|
||||
# ifndef __GNUC_PREREQ
|
||||
# define __GNUC_PREREQ(maj, min) (0)
|
||||
# endif
|
||||
# if defined __cplusplus && __GNUC_PREREQ (2,8)
|
||||
# define __THROW throw ()
|
||||
# else
|
||||
# define __THROW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
||||
__THROW;
|
||||
|
||||
#ifndef __need_getopt
|
||||
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW;
|
||||
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind)
|
||||
__THROW;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
131
contrib/cpio/lib/getopt_int.h
Normal file
131
contrib/cpio/lib/getopt_int.h
Normal file
@ -0,0 +1,131 @@
|
||||
/* Internal declarations for getopt.
|
||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GETOPT_INT_H
|
||||
#define _GETOPT_INT_H 1
|
||||
|
||||
extern int _getopt_internal (int ___argc, char **___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only, int __posixly_correct);
|
||||
|
||||
|
||||
/* Reentrant versions which can handle parsing multiple argument
|
||||
vectors at the same time. */
|
||||
|
||||
/* Data type for reentrant functions. */
|
||||
struct _getopt_data
|
||||
{
|
||||
/* These have exactly the same meaning as the corresponding global
|
||||
variables, except that they are used for the reentrant
|
||||
versions of getopt. */
|
||||
int optind;
|
||||
int opterr;
|
||||
int optopt;
|
||||
char *optarg;
|
||||
|
||||
/* Internal members. */
|
||||
|
||||
/* True if the internal members have been initialized. */
|
||||
int __initialized;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
char *__nextchar;
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters, or by calling getopt.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we
|
||||
scan, so that eventually all the non-options are at the end.
|
||||
This allows options to be given in any order, even with programs
|
||||
that were not written to expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were
|
||||
written to expect options and other ARGV-elements in any order
|
||||
and that care about the ordering of the two. We describe each
|
||||
non-option ARGV-element as if it were the argument of an option
|
||||
with character code 1. Using `-' as the first character of the
|
||||
list of option characters selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
||||
|
||||
enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} __ordering;
|
||||
|
||||
/* If the POSIXLY_CORRECT environment variable is set
|
||||
or getopt was called. */
|
||||
int __posixly_correct;
|
||||
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first
|
||||
of them; `last_nonopt' is the index after the last of them. */
|
||||
|
||||
int __first_nonopt;
|
||||
int __last_nonopt;
|
||||
|
||||
#if defined _LIBC && defined USE_NONOPTION_FLAGS
|
||||
int __nonoption_flags_max_len;
|
||||
int __nonoption_flags_len;
|
||||
# endif
|
||||
};
|
||||
|
||||
/* The initializer is necessary to set OPTIND and OPTERR to their
|
||||
default values and to clear the initialization flag. */
|
||||
#define _GETOPT_DATA_INITIALIZER { 1, 1 }
|
||||
|
||||
extern int _getopt_internal_r (int ___argc, char **___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only, int __posixly_correct,
|
||||
struct _getopt_data *__data);
|
||||
|
||||
extern int _getopt_long_r (int ___argc, char **___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
struct _getopt_data *__data);
|
||||
|
||||
extern int _getopt_long_only_r (int ___argc, char **___argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts,
|
||||
int *__longind,
|
||||
struct _getopt_data *__data);
|
||||
|
||||
#endif /* getopt_int.h */
|
68
contrib/cpio/lib/gettext.h
Normal file
68
contrib/cpio/lib/gettext.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000-2002 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
|
||||
|
||||
#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
|
||||
|
||||
/* 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) ((const char *) (Msgid))
|
||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
||||
# define bind_textdomain_codeset(Domainname, Codeset) ((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
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
4
contrib/cpio/lib/localedir.h
Normal file
4
contrib/cpio/lib/localedir.h
Normal file
@ -0,0 +1,4 @@
|
||||
#define LOCALEDIR "/usr/local/share/locale"
|
||||
#ifndef DEFAULT_RMT_COMMAND
|
||||
# define DEFAULT_RMT_COMMAND "/usr/local/libexec/rmt"
|
||||
#endif
|
29
contrib/cpio/lib/mempcpy.c
Normal file
29
contrib/cpio/lib/mempcpy.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copy memory area and return pointer after last written byte.
|
||||
Copyright (C) 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Specification. */
|
||||
#include "mempcpy.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
||||
last written byte. */
|
||||
void *
|
||||
mempcpy (void *dest, const void *src, size_t n)
|
||||
{
|
||||
return (char *) memcpy (dest, src, n) + n;
|
||||
}
|
36
contrib/cpio/lib/mempcpy.h
Normal file
36
contrib/cpio/lib/mempcpy.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copy memory area and return pointer after last written byte.
|
||||
Copyright (C) 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef mempcpy
|
||||
|
||||
# if HAVE_MEMPCPY
|
||||
|
||||
/* Get mempcpy() declaration. */
|
||||
# include <string.h>
|
||||
|
||||
# else
|
||||
|
||||
/* Get size_t */
|
||||
# include <stddef.h>
|
||||
|
||||
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
||||
last written byte. */
|
||||
extern void *mempcpy (void *dest, const void *src, size_t n);
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
99
contrib/cpio/lib/rmt.h
Normal file
99
contrib/cpio/lib/rmt.h
Normal file
@ -0,0 +1,99 @@
|
||||
/* Definitions for communicating with a remote tape drive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
extern char *rmt_command;
|
||||
extern char *rmt_dev_name__;
|
||||
|
||||
int rmt_open__ (const char *, int, int, const char *);
|
||||
int rmt_close__ (int);
|
||||
size_t rmt_read__ (int, char *, size_t);
|
||||
size_t rmt_write__ (int, char *, size_t);
|
||||
off_t rmt_lseek__ (int, off_t, int);
|
||||
int rmt_ioctl__ (int, int, char *);
|
||||
|
||||
extern bool force_local_option;
|
||||
|
||||
/* A filename is remote if it contains a colon not preceded by a slash,
|
||||
to take care of `/:/' which is a shorthand for `/.../<CELL-NAME>/fs'
|
||||
on machines running OSF's Distributing Computing Environment (DCE) and
|
||||
Distributed File System (DFS). However, when --force-local, a
|
||||
filename is never remote. */
|
||||
|
||||
#define _remdev(dev_name) \
|
||||
(!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \
|
||||
&& rmt_dev_name__ > (dev_name) \
|
||||
&& ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name)))
|
||||
|
||||
#define _isrmt(fd) \
|
||||
((fd) >= __REM_BIAS)
|
||||
|
||||
#define __REM_BIAS (1 << 30)
|
||||
|
||||
#ifndef O_CREAT
|
||||
# define O_CREAT 01000
|
||||
#endif
|
||||
|
||||
#define rmtopen(dev_name, oflag, mode, command) \
|
||||
(_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \
|
||||
: open (dev_name, oflag, mode))
|
||||
|
||||
#define rmtaccess(dev_name, amode) \
|
||||
(_remdev (dev_name) ? 0 : access (dev_name, amode))
|
||||
|
||||
#define rmtstat(dev_name, buffer) \
|
||||
(_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer))
|
||||
|
||||
#define rmtcreat(dev_name, mode, command) \
|
||||
(_remdev (dev_name) \
|
||||
? rmt_open__ (dev_name, 1 | O_CREAT, __REM_BIAS, command) \
|
||||
: creat (dev_name, mode))
|
||||
|
||||
#define rmtlstat(dev_name, muffer) \
|
||||
(_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer))
|
||||
|
||||
#define rmtread(fd, buffer, length) \
|
||||
(_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \
|
||||
: safe_read (fd, buffer, length))
|
||||
|
||||
#define rmtwrite(fd, buffer, length) \
|
||||
(_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \
|
||||
: full_write (fd, buffer, length))
|
||||
|
||||
#define rmtlseek(fd, offset, where) \
|
||||
(_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \
|
||||
: lseek (fd, offset, where))
|
||||
|
||||
#define rmtclose(fd) \
|
||||
(_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd))
|
||||
|
||||
#define rmtioctl(fd, request, argument) \
|
||||
(_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \
|
||||
: ioctl (fd, request, argument))
|
||||
|
||||
#define rmtdup(fd) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd))
|
||||
|
||||
#define rmtfstat(fd, buffer) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer))
|
||||
|
||||
#define rmtfcntl(cd, command, argument) \
|
||||
(_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument))
|
||||
|
||||
#define rmtisatty(fd) \
|
||||
(_isrmt (fd) ? 0 : isatty (fd))
|
740
contrib/cpio/lib/rtapelib.c
Normal file
740
contrib/cpio/lib/rtapelib.c
Normal file
@ -0,0 +1,740 @@
|
||||
/* Functions for communicating with a remote tape drive.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol
|
||||
which rdump and rrestore use. Unfortunately, the man page is *WRONG*.
|
||||
The author of the routines I'm including originally wrote his code just
|
||||
based on the man page, and it didn't work, so he went to the rdump source
|
||||
to figure out why. The only thing he had to change was to check for the
|
||||
'F' return code in addition to the 'E', and to separate the various
|
||||
arguments with \n instead of a space. I personally don't think that this
|
||||
is much of a problem, but I wanted to point it out. -- Arnold Robbins
|
||||
|
||||
Originally written by Jeff Lee, modified some by Arnold Robbins. Redone
|
||||
as a library that can replace open, read, write, etc., by Fred Fish, with
|
||||
some additional work by Arnold Robbins. Modified to make all rmt* calls
|
||||
into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec
|
||||
code, courtesy of Dan Kegel. */
|
||||
|
||||
#include "system.h"
|
||||
#include <safe-read.h>
|
||||
#include <full-write.h>
|
||||
|
||||
/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h,
|
||||
3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */
|
||||
|
||||
#ifndef EOPNOTSUPP
|
||||
# if HAVE_NET_ERRNO_H
|
||||
# include <net/errno.h>
|
||||
# endif
|
||||
# if HAVE_SYS_INET_H
|
||||
# include <sys/inet.h>
|
||||
# endif
|
||||
# ifndef EOPNOTSUPP
|
||||
# define EOPNOTSUPP EINVAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#if HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <rmt.h>
|
||||
#include <localedir.h>
|
||||
|
||||
/* Exit status if exec errors. */
|
||||
#define EXIT_ON_EXEC_ERROR 128
|
||||
|
||||
/* FIXME: Size of buffers for reading and writing commands to rmt. */
|
||||
#define COMMAND_BUFFER_SIZE 64
|
||||
|
||||
#ifndef RETSIGTYPE
|
||||
# define RETSIGTYPE void
|
||||
#endif
|
||||
|
||||
/* FIXME: Maximum number of simultaneous remote tape connections. */
|
||||
#define MAXUNIT 4
|
||||
|
||||
#define PREAD 0 /* read file descriptor from pipe() */
|
||||
#define PWRITE 1 /* write file descriptor from pipe() */
|
||||
|
||||
/* Return the parent's read side of remote tape connection Fd. */
|
||||
#define READ_SIDE(Fd) (from_remote[Fd][PREAD])
|
||||
|
||||
/* Return the parent's write side of remote tape connection Fd. */
|
||||
#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE])
|
||||
|
||||
/* The pipes for receiving data from remote tape drives. */
|
||||
static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
|
||||
|
||||
/* The pipes for sending data to remote tape drives. */
|
||||
static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}};
|
||||
|
||||
char *rmt_command = DEFAULT_RMT_COMMAND;
|
||||
|
||||
/* Temporary variable used by macros in rmt.h. */
|
||||
char *rmt_dev_name__;
|
||||
|
||||
/* If true, always consider file names to be local, even if they contain
|
||||
colons */
|
||||
bool force_local_option;
|
||||
|
||||
|
||||
|
||||
/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */
|
||||
static void
|
||||
_rmt_shutdown (int handle, int errno_value)
|
||||
{
|
||||
close (READ_SIDE (handle));
|
||||
close (WRITE_SIDE (handle));
|
||||
READ_SIDE (handle) = -1;
|
||||
WRITE_SIDE (handle) = -1;
|
||||
errno = errno_value;
|
||||
}
|
||||
|
||||
/* Attempt to perform the remote tape command specified in BUFFER on
|
||||
remote tape connection HANDLE. Return 0 if successful, -1 on
|
||||
error. */
|
||||
static int
|
||||
do_command (int handle, const char *buffer)
|
||||
{
|
||||
/* Save the current pipe handler and try to make the request. */
|
||||
|
||||
size_t length = strlen (buffer);
|
||||
RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN);
|
||||
ssize_t written = full_write (WRITE_SIDE (handle), buffer, length);
|
||||
signal (SIGPIPE, pipe_handler);
|
||||
|
||||
if (written == length)
|
||||
return 0;
|
||||
|
||||
/* Something went wrong. Close down and go home. */
|
||||
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_status_string (int handle, char *command_buffer)
|
||||
{
|
||||
char *cursor;
|
||||
int counter;
|
||||
|
||||
/* Read the reply command line. */
|
||||
|
||||
for (counter = 0, cursor = command_buffer;
|
||||
counter < COMMAND_BUFFER_SIZE;
|
||||
counter++, cursor++)
|
||||
{
|
||||
if (safe_read (READ_SIDE (handle), cursor, 1) != 1)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
if (*cursor == '\n')
|
||||
{
|
||||
*cursor = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (counter == COMMAND_BUFFER_SIZE)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the return status. */
|
||||
|
||||
for (cursor = command_buffer; *cursor; cursor++)
|
||||
if (*cursor != ' ')
|
||||
break;
|
||||
|
||||
if (*cursor == 'E' || *cursor == 'F')
|
||||
{
|
||||
/* Skip the error message line. */
|
||||
|
||||
/* FIXME: there is better to do than merely ignoring error messages
|
||||
coming from the remote end. Translate them, too... */
|
||||
|
||||
{
|
||||
char character;
|
||||
|
||||
while (safe_read (READ_SIDE (handle), &character, 1) == 1)
|
||||
if (character == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
errno = atoi (cursor + 1);
|
||||
|
||||
if (*cursor == 'F')
|
||||
_rmt_shutdown (handle, errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for mis-synced pipes. */
|
||||
|
||||
if (*cursor != 'A')
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Got an `A' (success) response. */
|
||||
|
||||
return cursor + 1;
|
||||
}
|
||||
|
||||
/* Read and return the status from remote tape connection HANDLE. If
|
||||
an error occurred, return -1 and set errno. */
|
||||
static long int
|
||||
get_status (int handle)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
const char *status = get_status_string (handle, command_buffer);
|
||||
if (status)
|
||||
{
|
||||
long int result = atol (status);
|
||||
if (0 <= result)
|
||||
return result;
|
||||
errno = EIO;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static off_t
|
||||
get_status_off (int handle)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
const char *status = get_status_string (handle, command_buffer);
|
||||
|
||||
if (! status)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
/* Parse status, taking care to check for overflow.
|
||||
We can't use standard functions,
|
||||
since off_t might be longer than long. */
|
||||
|
||||
off_t count = 0;
|
||||
int negative;
|
||||
|
||||
for (; *status == ' ' || *status == '\t'; status++)
|
||||
continue;
|
||||
|
||||
negative = *status == '-';
|
||||
status += negative || *status == '+';
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *status++ - '0';
|
||||
if (9 < (unsigned) digit)
|
||||
break;
|
||||
else
|
||||
{
|
||||
off_t c10 = 10 * count;
|
||||
off_t nc = negative ? c10 - digit : c10 + digit;
|
||||
if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
|
||||
return -1;
|
||||
count = nc;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_REXEC
|
||||
|
||||
/* Execute /etc/rmt as user USER on remote system HOST using rexec.
|
||||
Return a file descriptor of a bidirectional socket for stdin and
|
||||
stdout. If USER is zero, use the current username.
|
||||
|
||||
By default, this code is not used, since it requires that the user
|
||||
have a .netrc file in his/her home directory, or that the
|
||||
application designer be willing to have rexec prompt for login and
|
||||
password info. This may be unacceptable, and .rhosts files for use
|
||||
with rsh are much more common on BSD systems. */
|
||||
static int
|
||||
_rmt_rexec (char *host, char *user)
|
||||
{
|
||||
int saved_stdin = dup (STDIN_FILENO);
|
||||
int saved_stdout = dup (STDOUT_FILENO);
|
||||
struct servent *rexecserv;
|
||||
int result;
|
||||
|
||||
/* When using cpio -o < filename, stdin is no longer the tty. But the
|
||||
rexec subroutine reads the login and the passwd on stdin, to allow
|
||||
remote execution of the command. So, reopen stdin and stdout on
|
||||
/dev/tty before the rexec and give them back their original value
|
||||
after. */
|
||||
|
||||
if (! freopen ("/dev/tty", "r", stdin))
|
||||
freopen ("/dev/null", "r", stdin);
|
||||
if (! freopen ("/dev/tty", "w", stdout))
|
||||
freopen ("/dev/null", "w", stdout);
|
||||
|
||||
if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv)
|
||||
error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available"));
|
||||
|
||||
result = rexec (&host, rexecserv->s_port, user, 0, rmt_command, 0);
|
||||
if (fclose (stdin) == EOF)
|
||||
error (0, errno, _("stdin"));
|
||||
fdopen (saved_stdin, "r");
|
||||
if (fclose (stdout) == EOF)
|
||||
error (0, errno, _("stdout"));
|
||||
fdopen (saved_stdout, "w");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* WITH_REXEC */
|
||||
|
||||
/* Place into BUF a string representing OFLAG, which must be suitable
|
||||
as argument 2 of `open'. BUF must be large enough to hold the
|
||||
result. This function should generate a string that decode_oflag
|
||||
can parse. */
|
||||
static void
|
||||
encode_oflag (char *buf, int oflag)
|
||||
{
|
||||
sprintf (buf, "%d ", oflag);
|
||||
|
||||
switch (oflag & O_ACCMODE)
|
||||
{
|
||||
case O_RDONLY: strcat (buf, "O_RDONLY"); break;
|
||||
case O_RDWR: strcat (buf, "O_RDWR"); break;
|
||||
case O_WRONLY: strcat (buf, "O_WRONLY"); break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
#ifdef O_APPEND
|
||||
if (oflag & O_APPEND) strcat (buf, "|O_APPEND");
|
||||
#endif
|
||||
if (oflag & O_CREAT) strcat (buf, "|O_CREAT");
|
||||
#ifdef O_DSYNC
|
||||
if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC");
|
||||
#endif
|
||||
if (oflag & O_EXCL) strcat (buf, "|O_EXCL");
|
||||
#ifdef O_LARGEFILE
|
||||
if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE");
|
||||
#endif
|
||||
#ifdef O_NOCTTY
|
||||
if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
|
||||
#endif
|
||||
#ifdef O_NONBLOCK
|
||||
if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
|
||||
#endif
|
||||
#ifdef O_RSYNC
|
||||
if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
|
||||
#endif
|
||||
#ifdef O_SYNC
|
||||
if (oflag & O_SYNC) strcat (buf, "|O_SYNC");
|
||||
#endif
|
||||
if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC");
|
||||
}
|
||||
|
||||
/* Open a file (a magnetic tape device?) on the system specified in
|
||||
FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'.
|
||||
OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the
|
||||
remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On
|
||||
error, return -1. */
|
||||
int
|
||||
rmt_open__ (const char *file_name, int open_mode, int bias,
|
||||
const char *remote_shell)
|
||||
{
|
||||
int remote_pipe_number; /* pseudo, biased file descriptor */
|
||||
char *file_name_copy; /* copy of file_name string */
|
||||
char *remote_host; /* remote host name */
|
||||
char *remote_file; /* remote file name (often a device) */
|
||||
char *remote_user; /* remote user name */
|
||||
|
||||
/* Find an unused pair of file descriptors. */
|
||||
|
||||
for (remote_pipe_number = 0;
|
||||
remote_pipe_number < MAXUNIT;
|
||||
remote_pipe_number++)
|
||||
if (READ_SIDE (remote_pipe_number) == -1
|
||||
&& WRITE_SIDE (remote_pipe_number) == -1)
|
||||
break;
|
||||
|
||||
if (remote_pipe_number == MAXUNIT)
|
||||
{
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Pull apart the system and device, and optional user. */
|
||||
|
||||
{
|
||||
char *cursor;
|
||||
|
||||
file_name_copy = xstrdup (file_name);
|
||||
remote_host = file_name_copy;
|
||||
remote_user = 0;
|
||||
remote_file = 0;
|
||||
|
||||
for (cursor = file_name_copy; *cursor; cursor++)
|
||||
switch (*cursor)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
/* Do not allow newlines in the file_name, since the protocol
|
||||
uses newline delimiters. */
|
||||
free (file_name_copy);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
|
||||
case '@':
|
||||
if (!remote_user)
|
||||
{
|
||||
remote_user = remote_host;
|
||||
*cursor = '\0';
|
||||
remote_host = cursor + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (!remote_file)
|
||||
{
|
||||
*cursor = '\0';
|
||||
remote_file = cursor + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Should somewhat validate the decoding, here. */
|
||||
|
||||
if (remote_user && *remote_user == '\0')
|
||||
remote_user = 0;
|
||||
|
||||
#if WITH_REXEC
|
||||
|
||||
/* Execute the remote command using rexec. */
|
||||
|
||||
READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);
|
||||
if (READ_SIDE (remote_pipe_number) < 0)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number);
|
||||
|
||||
#else /* not WITH_REXEC */
|
||||
{
|
||||
const char *remote_shell_basename;
|
||||
pid_t status;
|
||||
|
||||
/* Identify the remote command to be executed. */
|
||||
|
||||
if (!remote_shell)
|
||||
{
|
||||
#ifdef REMOTE_SHELL
|
||||
remote_shell = REMOTE_SHELL;
|
||||
#else
|
||||
free (file_name_copy);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
remote_shell_basename = base_name (remote_shell);
|
||||
|
||||
/* Set up the pipes for the `rsh' command, and fork. */
|
||||
|
||||
if (pipe (to_remote[remote_pipe_number]) == -1
|
||||
|| pipe (from_remote[remote_pipe_number]) == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = fork ();
|
||||
if (status == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (file_name_copy);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
/* Child. */
|
||||
|
||||
close (STDIN_FILENO);
|
||||
dup (to_remote[remote_pipe_number][PREAD]);
|
||||
close (to_remote[remote_pipe_number][PREAD]);
|
||||
close (to_remote[remote_pipe_number][PWRITE]);
|
||||
|
||||
close (STDOUT_FILENO);
|
||||
dup (from_remote[remote_pipe_number][PWRITE]);
|
||||
close (from_remote[remote_pipe_number][PREAD]);
|
||||
close (from_remote[remote_pipe_number][PWRITE]);
|
||||
|
||||
sys_reset_uid_gid ();
|
||||
|
||||
if (remote_user)
|
||||
execl (remote_shell, remote_shell_basename, remote_host,
|
||||
"-l", remote_user, rmt_command, (char *) 0);
|
||||
else
|
||||
execl (remote_shell, remote_shell_basename, remote_host,
|
||||
rmt_command, (char *) 0);
|
||||
|
||||
/* Bad problems if we get here. */
|
||||
|
||||
/* In a previous version, _exit was used here instead of exit. */
|
||||
error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell"));
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
close (from_remote[remote_pipe_number][PWRITE]);
|
||||
close (to_remote[remote_pipe_number][PREAD]);
|
||||
}
|
||||
#endif /* not WITH_REXEC */
|
||||
|
||||
/* Attempt to open the tape device. */
|
||||
|
||||
{
|
||||
size_t remote_file_len = strlen (remote_file);
|
||||
char *command_buffer = xmalloc (remote_file_len + 1000);
|
||||
sprintf (command_buffer, "O%s\n", remote_file);
|
||||
encode_oflag (command_buffer + remote_file_len + 2, open_mode);
|
||||
strcat (command_buffer, "\n");
|
||||
if (do_command (remote_pipe_number, command_buffer) == -1
|
||||
|| get_status (remote_pipe_number) == -1)
|
||||
{
|
||||
int e = errno;
|
||||
free (command_buffer);
|
||||
free (file_name_copy);
|
||||
_rmt_shutdown (remote_pipe_number, e);
|
||||
return -1;
|
||||
}
|
||||
free (command_buffer);
|
||||
}
|
||||
|
||||
free (file_name_copy);
|
||||
return remote_pipe_number + bias;
|
||||
}
|
||||
|
||||
/* Close remote tape connection HANDLE and shut down. Return 0 if
|
||||
successful, -1 on error. */
|
||||
int
|
||||
rmt_close__ (int handle)
|
||||
{
|
||||
long int status;
|
||||
|
||||
if (do_command (handle, "C\n") == -1)
|
||||
return -1;
|
||||
|
||||
status = get_status (handle);
|
||||
_rmt_shutdown (handle, errno);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.
|
||||
Return the number of bytes read on success, SAFE_READ_ERROR on error. */
|
||||
size_t
|
||||
rmt_read__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
size_t status;
|
||||
size_t rlen;
|
||||
size_t counter;
|
||||
|
||||
sprintf (command_buffer, "R%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1
|
||||
|| (status = get_status (handle)) == SAFE_READ_ERROR)
|
||||
return SAFE_READ_ERROR;
|
||||
|
||||
for (counter = 0; counter < status; counter += rlen, buffer += rlen)
|
||||
{
|
||||
rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
|
||||
if (rlen == SAFE_READ_ERROR || rlen == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return SAFE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.
|
||||
Return the number of bytes written. */
|
||||
size_t
|
||||
rmt_write__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
RETSIGTYPE (*pipe_handler) ();
|
||||
size_t written;
|
||||
|
||||
sprintf (command_buffer, "W%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return 0;
|
||||
|
||||
pipe_handler = signal (SIGPIPE, SIG_IGN);
|
||||
written = full_write (WRITE_SIDE (handle), buffer, length);
|
||||
signal (SIGPIPE, pipe_handler);
|
||||
if (written == length)
|
||||
{
|
||||
long int r = get_status (handle);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
if (r == length)
|
||||
return length;
|
||||
written = r;
|
||||
}
|
||||
|
||||
/* Write error. */
|
||||
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Perform an imitation lseek operation on remote tape connection
|
||||
HANDLE. Return the new file offset if successful, -1 if on error. */
|
||||
off_t
|
||||
rmt_lseek__ (int handle, off_t offset, int whence)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset;
|
||||
char *p = operand_buffer + sizeof operand_buffer;
|
||||
|
||||
*--p = 0;
|
||||
do
|
||||
*--p = '0' + (int) (u % 10);
|
||||
while ((u /= 10) != 0);
|
||||
if (offset < 0)
|
||||
*--p = '-';
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET: whence = 0; break;
|
||||
case SEEK_CUR: whence = 1; break;
|
||||
case SEEK_END: whence = 2; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
sprintf (command_buffer, "L%s\n%d\n", p, whence);
|
||||
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
|
||||
return get_status_off (handle);
|
||||
}
|
||||
|
||||
/* Perform a raw tape operation on remote tape connection HANDLE.
|
||||
Return the results of the ioctl, or -1 on error. */
|
||||
int
|
||||
rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
|
||||
#ifdef MTIOCTOP
|
||||
case MTIOCTOP:
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
char operand_buffer[UINTMAX_STRSIZE_BOUND];
|
||||
uintmax_t u = (((struct mtop *) argument)->mt_count < 0
|
||||
? - (uintmax_t) ((struct mtop *) argument)->mt_count
|
||||
: (uintmax_t) ((struct mtop *) argument)->mt_count);
|
||||
char *p = operand_buffer + sizeof operand_buffer;
|
||||
|
||||
*--p = 0;
|
||||
do
|
||||
*--p = '0' + (int) (u % 10);
|
||||
while ((u /= 10) != 0);
|
||||
if (((struct mtop *) argument)->mt_count < 0)
|
||||
*--p = '-';
|
||||
|
||||
/* MTIOCTOP is the easy one. Nothing is transferred in binary. */
|
||||
|
||||
sprintf (command_buffer, "I%d\n%s\n",
|
||||
((struct mtop *) argument)->mt_op, p);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
|
||||
return get_status (handle);
|
||||
}
|
||||
#endif /* MTIOCTOP */
|
||||
|
||||
#ifdef MTIOCGET
|
||||
case MTIOCGET:
|
||||
{
|
||||
ssize_t status;
|
||||
size_t counter;
|
||||
|
||||
/* Grab the status and read it directly into the structure. This
|
||||
assumes that the status buffer is not padded and that 2 shorts
|
||||
fit in a long without any word alignment problems; i.e., the
|
||||
whole struct is contiguous. NOTE - this is probably NOT a good
|
||||
assumption. */
|
||||
|
||||
if (do_command (handle, "S") == -1
|
||||
|| (status = get_status (handle), status == -1))
|
||||
return -1;
|
||||
|
||||
for (; status > 0; status -= counter, argument += counter)
|
||||
{
|
||||
counter = safe_read (READ_SIDE (handle), argument, status);
|
||||
if (counter == SAFE_READ_ERROR || counter == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for byte position. mt_type (or mt_model) is a small integer
|
||||
field (normally) so we will check its magnitude. If it is larger
|
||||
than 256, we will assume that the bytes are swapped and go through
|
||||
and reverse all the bytes. */
|
||||
|
||||
if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256)
|
||||
return 0;
|
||||
|
||||
for (counter = 0; counter < status; counter += 2)
|
||||
{
|
||||
char copy = argument[counter];
|
||||
|
||||
argument[counter] = argument[counter + 1];
|
||||
argument[counter + 1] = copy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MTIOCGET */
|
||||
|
||||
}
|
||||
}
|
82
contrib/cpio/lib/safe-read.c
Normal file
82
contrib/cpio/lib/safe-read.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* An interface to read and write that retries after interrupts.
|
||||
|
||||
Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Specification. */
|
||||
#ifdef SAFE_WRITE
|
||||
# include "safe-write.h"
|
||||
#else
|
||||
# include "safe-read.h"
|
||||
#endif
|
||||
|
||||
/* Get ssize_t. */
|
||||
#include <sys/types.h>
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef EINTR
|
||||
# define IS_EINTR(x) ((x) == EINTR)
|
||||
#else
|
||||
# define IS_EINTR(x) 0
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef SAFE_WRITE
|
||||
# define safe_rw safe_write
|
||||
# define rw write
|
||||
#else
|
||||
# define safe_rw safe_read
|
||||
# define rw read
|
||||
# undef const
|
||||
# define const /* empty */
|
||||
#endif
|
||||
|
||||
/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
|
||||
interrupted. Return the actual number of bytes read(written), zero for EOF,
|
||||
or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */
|
||||
size_t
|
||||
safe_rw (int fd, void const *buf, size_t count)
|
||||
{
|
||||
/* Work around a bug in Tru64 5.1. Attempting to read more than
|
||||
INT_MAX bytes fails with errno == EINVAL. See
|
||||
<http://lists.gnu.org/archive/html/bug-gnu-utils/2002-04/msg00010.html>.
|
||||
When decreasing COUNT, keep it block-aligned. */
|
||||
enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 };
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ssize_t result = rw (fd, buf, count);
|
||||
|
||||
if (0 <= result)
|
||||
return result;
|
||||
else if (IS_EINTR (errno))
|
||||
continue;
|
||||
else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count)
|
||||
count = BUGGY_READ_MAXIMUM;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
}
|
25
contrib/cpio/lib/safe-read.h
Normal file
25
contrib/cpio/lib/safe-read.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* An interface to read() that retries after interrupts.
|
||||
Copyright (C) 2002 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define SAFE_READ_ERROR ((size_t) -1)
|
||||
|
||||
/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
|
||||
Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
|
||||
upon error. */
|
||||
extern size_t safe_read (int fd, void *buf, size_t count);
|
19
contrib/cpio/lib/safe-write.c
Normal file
19
contrib/cpio/lib/safe-write.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* An interface to write that retries after interrupts.
|
||||
Copyright (C) 2002 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define SAFE_WRITE
|
||||
#include "safe-read.c"
|
25
contrib/cpio/lib/safe-write.h
Normal file
25
contrib/cpio/lib/safe-write.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* An interface to write() that retries after interrupts.
|
||||
Copyright (C) 2002 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define SAFE_WRITE_ERROR ((size_t) -1)
|
||||
|
||||
/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted.
|
||||
Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR
|
||||
upon error. */
|
||||
extern size_t safe_write (int fd, const void *buf, size_t count);
|
123
contrib/cpio/lib/savedir.c
Normal file
123
contrib/cpio/lib/savedir.c
Normal file
@ -0,0 +1,123 @@
|
||||
/* savedir.c -- save the list of files in a directory in a string
|
||||
|
||||
Copyright 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "savedir.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
#else
|
||||
# define dirent direct
|
||||
# if HAVE_SYS_NDIR_H
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if HAVE_SYS_DIR_H
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if HAVE_NDIR_H
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CLOSEDIR_VOID
|
||||
/* Fake a return value. */
|
||||
# define CLOSEDIR(d) (closedir (d), 0)
|
||||
#else
|
||||
# define CLOSEDIR(d) closedir (d)
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xalloc.h"
|
||||
|
||||
/* Return a freshly allocated string containing the filenames
|
||||
in directory DIR, separated by '\0' characters;
|
||||
the end is marked by two '\0' characters in a row.
|
||||
Return NULL (setting errno) if DIR cannot be opened, read, or closed. */
|
||||
|
||||
#ifndef NAME_SIZE_DEFAULT
|
||||
# define NAME_SIZE_DEFAULT 512
|
||||
#endif
|
||||
|
||||
char *
|
||||
savedir (const char *dir)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *name_space;
|
||||
size_t allocated = NAME_SIZE_DEFAULT;
|
||||
size_t used = 0;
|
||||
int save_errno;
|
||||
|
||||
dirp = opendir (dir);
|
||||
if (dirp == NULL)
|
||||
return NULL;
|
||||
|
||||
name_space = xmalloc (allocated);
|
||||
|
||||
errno = 0;
|
||||
while ((dp = readdir (dirp)) != NULL)
|
||||
{
|
||||
/* Skip "", ".", and "..". "" is returned by at least one buggy
|
||||
implementation: Solaris 2.4 readdir on NFS file systems. */
|
||||
char const *entry = dp->d_name;
|
||||
if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
|
||||
{
|
||||
size_t entry_size = strlen (entry) + 1;
|
||||
if (used + entry_size < used)
|
||||
xalloc_die ();
|
||||
if (allocated <= used + entry_size)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (2 * allocated < allocated)
|
||||
xalloc_die ();
|
||||
allocated *= 2;
|
||||
}
|
||||
while (allocated <= used + entry_size);
|
||||
|
||||
name_space = xrealloc (name_space, allocated);
|
||||
}
|
||||
memcpy (name_space + used, entry, entry_size);
|
||||
used += entry_size;
|
||||
}
|
||||
}
|
||||
name_space[used] = '\0';
|
||||
save_errno = errno;
|
||||
if (CLOSEDIR (dirp) != 0)
|
||||
save_errno = errno;
|
||||
if (save_errno != 0)
|
||||
{
|
||||
free (name_space);
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
}
|
||||
return name_space;
|
||||
}
|
26
contrib/cpio/lib/savedir.h
Normal file
26
contrib/cpio/lib/savedir.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* Save the list of files in a directory in a string.
|
||||
|
||||
Copyright 1997, 1999, 2001, 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#if !defined SAVEDIR_H_
|
||||
# define SAVEDIR_H_
|
||||
|
||||
char *savedir (const char *dir);
|
||||
|
||||
#endif
|
47
contrib/cpio/lib/strcase.h
Normal file
47
contrib/cpio/lib/strcase.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Case-insensitive string comparison functions.
|
||||
Copyright (C) 1995-1996, 2001, 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _STRCASE_H
|
||||
#define _STRCASE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
||||
than S2.
|
||||
Note: This function does not work correctly in multibyte locales. */
|
||||
extern int strcasecmp (const char *s1, const char *s2);
|
||||
|
||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
||||
returning less than, equal to or greater than zero if S1 is
|
||||
lexicographically less than, equal to or greater than S2.
|
||||
Note: This function can not work correctly in multibyte locales. */
|
||||
extern int strncasecmp (const char *s1, const char *s2, size_t n);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _STRCASE_H */
|
30
contrib/cpio/lib/strchrnul.c
Normal file
30
contrib/cpio/lib/strchrnul.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Searching in a string.
|
||||
Copyright (C) 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Specification. */
|
||||
#include "strchrnul.h"
|
||||
|
||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||
char *
|
||||
strchrnul (const char *s, int c_in)
|
||||
{
|
||||
char c = c_in;
|
||||
while (*s && (*s != c))
|
||||
s++;
|
||||
|
||||
return (char *) s;
|
||||
}
|
28
contrib/cpio/lib/strchrnul.h
Normal file
28
contrib/cpio/lib/strchrnul.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* Searching in a string.
|
||||
Copyright (C) 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_STRCHRNUL
|
||||
|
||||
/* Get strchrnul() declaration. */
|
||||
#include <string.h>
|
||||
|
||||
#else
|
||||
|
||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||
extern char *strchrnul (const char *s, int c_in);
|
||||
|
||||
#endif
|
39
contrib/cpio/lib/stripslash.c
Normal file
39
contrib/cpio/lib/stripslash.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* stripslash.c -- remove redundant trailing slashes from a file name
|
||||
Copyright (C) 1990, 2001, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
/* Remove trailing slashes from PATH.
|
||||
Return true if a trailing slash was removed.
|
||||
This is useful when using filename completion from a shell that
|
||||
adds a "/" after directory names (such as tcsh and bash), because
|
||||
the Unix rename and rmdir system calls return an "Invalid argument" error
|
||||
when given a path that ends in "/" (except for the root directory). */
|
||||
|
||||
bool
|
||||
strip_trailing_slashes (char *path)
|
||||
{
|
||||
char *base = base_name (path);
|
||||
char *base_lim = base + base_len (base);
|
||||
bool had_slash = (*base_lim != '\0');
|
||||
*base_lim = '\0';
|
||||
return had_slash;
|
||||
}
|
55
contrib/cpio/lib/strndup.c
Normal file
55
contrib/cpio/lib/strndup.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1996, 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_DECL_STRNLEN
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRNLEN
|
||||
size_t strnlen ();
|
||||
#endif
|
||||
|
||||
#undef __strndup
|
||||
#undef strndup
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __strndup strndup
|
||||
#endif
|
||||
|
||||
char *
|
||||
__strndup (const char *s, size_t n)
|
||||
{
|
||||
size_t len = strnlen (s, n);
|
||||
char *new = malloc (len + 1);
|
||||
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
new[len] = '\0';
|
||||
return memcpy (new, s, len);
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__strndup, strndup)
|
||||
#endif
|
30
contrib/cpio/lib/strndup.h
Normal file
30
contrib/cpio/lib/strndup.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* Duplicate a size-bounded string.
|
||||
Copyright (C) 2003 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_STRNDUP
|
||||
|
||||
/* Get strndup() declaration. */
|
||||
#include <string.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Return a newly allocated copy of at most N bytes of STRING. */
|
||||
extern char *strndup (const char *string, size_t n);
|
||||
|
||||
#endif
|
48
contrib/cpio/lib/strnlen.c
Normal file
48
contrib/cpio/lib/strnlen.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* Find the length of STRING, but scan at most MAXLEN characters.
|
||||
Copyright (C) 1996, 1997, 1998, 2000-2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#undef strnlen
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef __strnlen
|
||||
#undef strnlen
|
||||
|
||||
#ifndef _LIBC
|
||||
# define strnlen rpl_strnlen
|
||||
#endif
|
||||
|
||||
#ifndef weak_alias
|
||||
# define __strnlen strnlen
|
||||
#endif
|
||||
|
||||
/* Find the length of STRING, but scan at most MAXLEN characters.
|
||||
If no '\0' terminator is found in that many characters, return MAXLEN. */
|
||||
|
||||
size_t
|
||||
__strnlen (const char *string, size_t maxlen)
|
||||
{
|
||||
const char *end = memchr (string, '\0', maxlen);
|
||||
return end ? (size_t) (end - string) : maxlen;
|
||||
}
|
||||
#ifdef weak_alias
|
||||
weak_alias (__strnlen, strnlen)
|
||||
#endif
|
524
contrib/cpio/lib/system.h
Normal file
524
contrib/cpio/lib/system.h
Normal file
@ -0,0 +1,524 @@
|
||||
/* System dependent definitions for GNU tar.
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||
2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||
# define __attribute__(spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
|
||||
as an argument to <ctype.h> macros like `isspace'. */
|
||||
#if STDC_HEADERS
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
|
||||
#endif
|
||||
|
||||
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
|
||||
#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7)
|
||||
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
|
||||
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
|
||||
|
||||
/* Declare string and memory handling routines. Take care that an ANSI
|
||||
string.h and pre-ANSI memory.h might conflict, and that memory.h and
|
||||
strings.h conflict on some systems. */
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
#else
|
||||
# include <strings.h>
|
||||
# ifndef strchr
|
||||
# define strchr index
|
||||
# endif
|
||||
# ifndef strrchr
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
# ifndef memcpy
|
||||
# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n)
|
||||
# endif
|
||||
# ifndef memcmp
|
||||
# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Declare errno. */
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Declare open parameters. */
|
||||
|
||||
#if HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
/* Pick only one of the next three: */
|
||||
#ifndef O_RDONLY
|
||||
# define O_RDONLY 0 /* only allow read */
|
||||
#endif
|
||||
#ifndef O_WRONLY
|
||||
# define O_WRONLY 1 /* only allow write */
|
||||
#endif
|
||||
#ifndef O_RDWR
|
||||
# define O_RDWR 2 /* both are allowed */
|
||||
#endif
|
||||
#ifndef O_ACCMODE
|
||||
# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY)
|
||||
#endif
|
||||
/* The rest can be OR-ed in to the above: */
|
||||
#ifndef O_CREAT
|
||||
# define O_CREAT 8 /* create file if needed */
|
||||
#endif
|
||||
#ifndef O_EXCL
|
||||
# define O_EXCL 16 /* file cannot already exist */
|
||||
#endif
|
||||
#ifndef O_TRUNC
|
||||
# define O_TRUNC 32 /* truncate file on open */
|
||||
#endif
|
||||
/* MS-DOG forever, with my love! */
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/* Declare file status routines and bits. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !HAVE_LSTAT && !defined lstat
|
||||
# define lstat stat
|
||||
#endif
|
||||
|
||||
#if STX_HIDDEN && !_LARGE_FILES /* AIX */
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN)
|
||||
# ifdef lstat
|
||||
# undef lstat
|
||||
# endif
|
||||
# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK)
|
||||
#endif
|
||||
|
||||
#if STAT_MACROS_BROKEN
|
||||
# undef S_ISBLK
|
||||
# undef S_ISCHR
|
||||
# undef S_ISCTG
|
||||
# undef S_ISDIR
|
||||
# undef S_ISFIFO
|
||||
# undef S_ISLNK
|
||||
# undef S_ISREG
|
||||
# undef S_ISSOCK
|
||||
#endif
|
||||
|
||||
/* On MSDOS, there are missing things from <sys/stat.h>. */
|
||||
#if MSDOS
|
||||
# define S_ISUID 0
|
||||
# define S_ISGID 0
|
||||
# define S_ISVTX 0
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISBLK
|
||||
# ifdef S_IFBLK
|
||||
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
# else
|
||||
# define S_ISBLK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISCHR
|
||||
# ifdef S_IFCHR
|
||||
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
# else
|
||||
# define S_ISCHR(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISCTG
|
||||
# ifdef S_IFCTG
|
||||
# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG)
|
||||
# else
|
||||
# define S_ISCTG(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISDOOR
|
||||
# define S_ISDOOR(mode) 0
|
||||
#endif
|
||||
#ifndef S_ISFIFO
|
||||
# ifdef S_IFIFO
|
||||
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
# else
|
||||
# define S_ISFIFO(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISLNK
|
||||
# ifdef S_IFLNK
|
||||
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
# else
|
||||
# define S_ISLNK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef S_ISSOCK
|
||||
# ifdef S_IFSOCK
|
||||
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
# else
|
||||
# define S_ISSOCK(mode) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO
|
||||
# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0))
|
||||
#endif
|
||||
|
||||
#ifndef S_ISUID
|
||||
# define S_ISUID 0004000
|
||||
#endif
|
||||
#ifndef S_ISGID
|
||||
# define S_ISGID 0002000
|
||||
#endif
|
||||
#ifndef S_ISVTX
|
||||
# define S_ISVTX 0001000
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
# define S_IRUSR 0000400
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
# define S_IWUSR 0000200
|
||||
#endif
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0000100
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0000040
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
# define S_IWGRP 0000020
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
# define S_IXGRP 0000010
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
# define S_IROTH 0000004
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
# define S_IWOTH 0000002
|
||||
#endif
|
||||
#ifndef S_IXOTH
|
||||
# define S_IXOTH 0000001
|
||||
#endif
|
||||
|
||||
#define MODE_WXUSR (S_IWUSR | S_IXUSR)
|
||||
#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
|
||||
#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
|
||||
#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
|
||||
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
||||
|
||||
/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
# define SEEK_CUR 1
|
||||
#endif
|
||||
#ifndef SEEK_END
|
||||
# define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
# define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
# define STDOUT_FILENO 1
|
||||
#endif
|
||||
#ifndef STDERR_FILENO
|
||||
# define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
/* Declare make device, major and minor. Since major is a function on
|
||||
SVR4, we have to resort to GOT_MAJOR instead of just testing if
|
||||
major is #define'd. */
|
||||
|
||||
#if MAJOR_IN_MKDEV
|
||||
# include <sys/mkdev.h>
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
#if MAJOR_IN_SYSMACROS
|
||||
# include <sys/sysmacros.h>
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
/* Some <sys/types.h> defines the macros. */
|
||||
#ifdef major
|
||||
# define GOT_MAJOR
|
||||
#endif
|
||||
|
||||
#ifndef GOT_MAJOR
|
||||
# if MSDOS
|
||||
# define major(device) (device)
|
||||
# define minor(device) (device)
|
||||
# define makedev(major, minor) (((major) << 8) | (minor))
|
||||
# define GOT_MAJOR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* For HP-UX before HP-UX 8, major/minor are not in <sys/sysmacros.h>. */
|
||||
#ifndef GOT_MAJOR
|
||||
# if defined(hpux) || defined(__hpux__) || defined(__hpux)
|
||||
# include <sys/mknod.h>
|
||||
# define GOT_MAJOR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef GOT_MAJOR
|
||||
# define major(device) (((device) >> 8) & 0xff)
|
||||
# define minor(device) ((device) & 0xff)
|
||||
# define makedev(major, minor) (((major) << 8) | (minor))
|
||||
#endif
|
||||
|
||||
#undef GOT_MAJOR
|
||||
|
||||
/* Declare wait status. */
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(s) (((s) >> 8) & 0xff)
|
||||
#endif
|
||||
#ifndef WIFSIGNALED
|
||||
# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff)
|
||||
#endif
|
||||
#ifndef WTERMSIG
|
||||
# define WTERMSIG(s) ((s) & 0x7f)
|
||||
#endif
|
||||
|
||||
/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block
|
||||
size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation
|
||||
for some cleanup in this area, later. */
|
||||
|
||||
/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the
|
||||
optimal I/O blocksize for the file, in bytes. Some systems, like
|
||||
Sequents, return st_blksize of 0 on pipes. */
|
||||
|
||||
#define DEFAULT_ST_BLKSIZE 512
|
||||
|
||||
#if !HAVE_ST_BLKSIZE
|
||||
# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE
|
||||
#else
|
||||
# define ST_BLKSIZE(statbuf) \
|
||||
((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE)
|
||||
#endif
|
||||
|
||||
/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the
|
||||
number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks).
|
||||
HP-UX counts st_blocks in 1024-byte units,
|
||||
this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2
|
||||
counts st_blocks in 4K units. */
|
||||
|
||||
#if !HAVE_ST_BLOCKS
|
||||
# if defined(_POSIX_SOURCE) || !defined(BSIZE)
|
||||
# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
|
||||
# else
|
||||
off_t st_blocks ();
|
||||
# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size))
|
||||
# endif
|
||||
#else
|
||||
# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
|
||||
# if defined(hpux) || defined(__hpux__) || defined(__hpux)
|
||||
# define ST_NBLOCKSIZE 1024
|
||||
# else
|
||||
# if defined(_AIX) && defined(_I386)
|
||||
# define ST_NBLOCKSIZE (4 * 1024)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ST_NBLOCKSIZE
|
||||
#define ST_NBLOCKSIZE 512
|
||||
#endif
|
||||
|
||||
/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses
|
||||
<sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires
|
||||
<sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It
|
||||
seems that the rest use <sys/mtio.h>, which itself requires other files,
|
||||
depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */
|
||||
|
||||
#if HAVE_SYS_GENTAPE_H
|
||||
# include <sys/gentape.h>
|
||||
#else
|
||||
# if HAVE_SYS_TAPE_H
|
||||
# if HAVE_SYS_DEVICE_H
|
||||
# include <sys/device.h>
|
||||
# endif
|
||||
# if HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# if HAVE_SYS_BUF_H
|
||||
# include <sys/buf.h>
|
||||
# endif
|
||||
# if HAVE_SYS_TPRINTF_H
|
||||
# include <sys/tprintf.h>
|
||||
# endif
|
||||
# include <sys/tape.h>
|
||||
# else
|
||||
# if HAVE_SYS_MTIO_H
|
||||
# include <sys/ioctl.h>
|
||||
# if HAVE_SGTTY_H
|
||||
# include <sgtty.h>
|
||||
# endif
|
||||
# if HAVE_SYS_IO_TRIOCTL_H
|
||||
# include <sys/io/trioctl.h>
|
||||
# endif
|
||||
# include <sys/mtio.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Declare standard functions. */
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
void *malloc ();
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#if !defined _POSIX_VERSION && MSDOS
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if WITH_DMALLOC
|
||||
# undef HAVE_DECL_VALLOC
|
||||
# define DMALLOC_FUNC_CHECK
|
||||
# include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef MB_LEN_MAX
|
||||
# define MB_LEN_MAX 1
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* These macros work even on ones'-complement hosts (!).
|
||||
The extra casts work around common compiler bugs. */
|
||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
#define TYPE_MINIMUM(t) (TYPE_SIGNED (t) \
|
||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
||||
: (t) 0)
|
||||
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
||||
|
||||
/* Bound on length of the string representing an integer value of type t.
|
||||
Subtract one for the sign bit if t is signed;
|
||||
302 / 1000 is log10 (2) rounded up;
|
||||
add one for integer division truncation;
|
||||
add one more for a minus sign if t is signed. */
|
||||
#define INT_STRLEN_BOUND(t) \
|
||||
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
|
||||
+ 1 + TYPE_SIGNED (t))
|
||||
|
||||
#define UINTMAX_STRSIZE_BOUND (INT_STRLEN_BOUND (uintmax_t) + 1)
|
||||
|
||||
/* Prototypes for external functions. */
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#if !HAVE_SETLOCALE
|
||||
# define setlocale(category, locale) /* empty */
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#if defined(HAVE_SYS_TIME_H) && defined(TIME_WITH_SYS_TIME)
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#if ! HAVE_DECL_TIME
|
||||
time_t time ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
||||
/* Library modules. */
|
||||
|
||||
#include <dirname.h>
|
||||
#include <error.h>
|
||||
#include <savedir.h>
|
||||
#include <unlocked-io.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include <gettext.h>
|
||||
#define _(msgid) gettext (msgid)
|
||||
#define N_(msgid) msgid
|
||||
|
||||
#if MSDOS
|
||||
# include <process.h>
|
||||
# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY)
|
||||
# define ERRNO_IS_EACCES errno == EACCES
|
||||
# define mkdir(file, mode) (mkdir) (file)
|
||||
# define TTY_NAME "con"
|
||||
# define sys_reset_uid_gid()
|
||||
#else
|
||||
# include <pwd.h>
|
||||
# include <grp.h>
|
||||
# define SET_BINARY_MODE(arc)
|
||||
# define ERRNO_IS_EACCES 0
|
||||
# define TTY_NAME "/dev/tty"
|
||||
# define sys_reset_uid_gid() \
|
||||
do { setuid (getuid ()); setgid (getgid ()); } while (0)
|
||||
#endif
|
||||
|
||||
#if XENIX
|
||||
# include <sys/inode.h>
|
||||
#endif
|
137
contrib/cpio/lib/unlocked-io.h
Normal file
137
contrib/cpio/lib/unlocked-io.h
Normal file
@ -0,0 +1,137 @@
|
||||
/* Prefer faster, non-thread-safe stdio functions if available.
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by Jim Meyering. */
|
||||
|
||||
#ifndef UNLOCKED_IO_H
|
||||
#define UNLOCKED_IO_H 1
|
||||
|
||||
/* These are wrappers for functions/macros from the GNU C library, and
|
||||
from other C libraries supporting POSIX's optional thread-safe functions.
|
||||
|
||||
The standard I/O functions are thread-safe. These *_unlocked ones are
|
||||
more efficient but not thread-safe. That they're not thread-safe is
|
||||
fine since all of the applications in this package are single threaded.
|
||||
|
||||
Also, some code that is shared with the GNU C library may invoke
|
||||
the *_unlocked functions directly. On hosts that lack those
|
||||
functions, invoke the non-thread-safe versions instead. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if HAVE_DECL_CLEARERR_UNLOCKED
|
||||
# undef clearerr
|
||||
# define clearerr(x) clearerr_unlocked (x)
|
||||
#else
|
||||
# define clearerr_unlocked(x) clearerr (x)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FEOF_UNLOCKED
|
||||
# undef feof
|
||||
# define feof(x) feof_unlocked (x)
|
||||
#else
|
||||
# define feof_unlocked(x) feof (x)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FERROR_UNLOCKED
|
||||
# undef ferror
|
||||
# define ferror(x) ferror_unlocked (x)
|
||||
#else
|
||||
# define ferror_unlocked(x) ferror (x)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FFLUSH_UNLOCKED
|
||||
# undef fflush
|
||||
# define fflush(x) fflush_unlocked (x)
|
||||
#else
|
||||
# define fflush_unlocked(x) fflush (x)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FGETS_UNLOCKED
|
||||
# undef fgets
|
||||
# define fgets(x,y,z) fgets_unlocked (x,y,z)
|
||||
#else
|
||||
# define fgets_unlocked(x,y,z) fgets (x,y,z)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FPUTC_UNLOCKED
|
||||
# undef fputc
|
||||
# define fputc(x,y) fputc_unlocked (x,y)
|
||||
#else
|
||||
# define fputc_unlocked(x,y) fputc (x,y)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FPUTS_UNLOCKED
|
||||
# undef fputs
|
||||
# define fputs(x,y) fputs_unlocked (x,y)
|
||||
#else
|
||||
# define fputs_unlocked(x,y) fputs (x,y)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FREAD_UNLOCKED
|
||||
# undef fread
|
||||
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
|
||||
#else
|
||||
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_FWRITE_UNLOCKED
|
||||
# undef fwrite
|
||||
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
|
||||
#else
|
||||
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_GETC_UNLOCKED
|
||||
# undef getc
|
||||
# define getc(x) getc_unlocked (x)
|
||||
#else
|
||||
# define getc_unlocked(x) getc (x)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_GETCHAR_UNLOCKED
|
||||
# undef getchar
|
||||
# define getchar() getchar_unlocked ()
|
||||
#else
|
||||
# define getchar_unlocked() getchar ()
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_PUTC_UNLOCKED
|
||||
# undef putc
|
||||
# define putc(x,y) putc_unlocked (x,y)
|
||||
#else
|
||||
# define putc_unlocked(x,y) putc (x,y)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_PUTCHAR_UNLOCKED
|
||||
# undef putchar
|
||||
# define putchar(x) putchar_unlocked (x)
|
||||
#else
|
||||
# define putchar_unlocked(x) putchar (x)
|
||||
#endif
|
||||
|
||||
#undef flockfile
|
||||
#define flockfile(x) ((void) 0)
|
||||
|
||||
#undef ftrylockfile
|
||||
#define ftrylockfile(x) 0
|
||||
|
||||
#undef funlockfile
|
||||
#define funlockfile(x) ((void) 0)
|
||||
|
||||
#endif /* UNLOCKED_IO_H */
|
45
contrib/cpio/lib/xalloc-die.c
Normal file
45
contrib/cpio/lib/xalloc-die.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Report a memory allocation failure and exit.
|
||||
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "xalloc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "exitfail.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
#define N_(msgid) msgid
|
||||
|
||||
void
|
||||
xalloc_die (void)
|
||||
{
|
||||
error (exit_failure, 0, "%s", _("memory exhausted"));
|
||||
|
||||
/* The `noreturn' cannot be given to error, since it may return if
|
||||
its first argument is 0. To help compilers understand the
|
||||
xalloc_die does not return, call abort. Also, the abort is a
|
||||
safety feature if exit_failure is 0 (which shouldn't happen). */
|
||||
abort ();
|
||||
}
|
79
contrib/cpio/lib/xalloc.h
Normal file
79
contrib/cpio/lib/xalloc.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* xalloc.h -- malloc with out-of-memory checking
|
||||
|
||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef XALLOC_H_
|
||||
# define XALLOC_H_
|
||||
|
||||
# include <stddef.h>
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
|
||||
# ifndef __attribute__
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
|
||||
# define __attribute__(x)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef ATTRIBUTE_NORETURN
|
||||
# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
# endif
|
||||
|
||||
/* This function is always triggered when memory is exhausted.
|
||||
It must be defined by the application, either explicitly
|
||||
or by using gnulib's xalloc-die module. This is the
|
||||
function to call when one wants the program to die because of a
|
||||
memory allocation failure. */
|
||||
extern void xalloc_die (void) ATTRIBUTE_NORETURN;
|
||||
|
||||
void *xmalloc (size_t s);
|
||||
void *xnmalloc (size_t n, size_t s);
|
||||
void *xzalloc (size_t s);
|
||||
void *xcalloc (size_t n, size_t s);
|
||||
void *xrealloc (void *p, size_t s);
|
||||
void *xnrealloc (void *p, size_t n, size_t s);
|
||||
void *x2realloc (void *p, size_t *pn);
|
||||
void *x2nrealloc (void *p, size_t *pn, size_t s);
|
||||
void *xmemdup (void const *p, size_t s);
|
||||
char *xstrdup (char const *str);
|
||||
|
||||
/* Return 1 if an array of N objects, each of size S, cannot exist due
|
||||
to size arithmetic overflow. S must be positive and N must be
|
||||
nonnegative. This is a macro, not an inline function, so that it
|
||||
works correctly even when SIZE_MAX < N.
|
||||
|
||||
By gnulib convention, SIZE_MAX represents overflow in size
|
||||
calculations, so the conservative dividend to use here is
|
||||
SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
|
||||
However, malloc (SIZE_MAX) fails on all known hosts where
|
||||
sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
|
||||
exactly-SIZE_MAX allocations on such hosts; this avoids a test and
|
||||
branch when S is known to be 1. */
|
||||
# define xalloc_oversized(n, s) \
|
||||
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
#endif /* !XALLOC_H_ */
|
229
contrib/cpio/lib/xmalloc.c
Normal file
229
contrib/cpio/lib/xmalloc.c
Normal file
@ -0,0 +1,229 @@
|
||||
/* xmalloc.c -- malloc with out of memory checking
|
||||
|
||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2002, 2003, 2004 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "xalloc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
/* Allocate an array of N objects, each with S bytes of memory,
|
||||
dynamically, with error checking. S must be nonzero. */
|
||||
|
||||
static inline void *
|
||||
xnmalloc_inline (size_t n, size_t s)
|
||||
{
|
||||
void *p;
|
||||
if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
|
||||
xalloc_die ();
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
xnmalloc (size_t n, size_t s)
|
||||
{
|
||||
return xnmalloc_inline (n, s);
|
||||
}
|
||||
|
||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||
|
||||
void *
|
||||
xmalloc (size_t n)
|
||||
{
|
||||
return xnmalloc_inline (n, 1);
|
||||
}
|
||||
|
||||
/* Change the size of an allocated block of memory P to an array of N
|
||||
objects each of S bytes, with error checking. S must be nonzero. */
|
||||
|
||||
static inline void *
|
||||
xnrealloc_inline (void *p, size_t n, size_t s)
|
||||
{
|
||||
if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
|
||||
xalloc_die ();
|
||||
return p;
|
||||
}
|
||||
|
||||
void *
|
||||
xnrealloc (void *p, size_t n, size_t s)
|
||||
{
|
||||
return xnrealloc_inline (p, n, s);
|
||||
}
|
||||
|
||||
/* Change the size of an allocated block of memory P to N bytes,
|
||||
with error checking. */
|
||||
|
||||
void *
|
||||
xrealloc (void *p, size_t n)
|
||||
{
|
||||
return xnrealloc_inline (p, n, 1);
|
||||
}
|
||||
|
||||
|
||||
/* If P is null, allocate a block of at least *PN such objects;
|
||||
otherwise, reallocate P so that it contains more than *PN objects
|
||||
each of S bytes. *PN must be nonzero unless P is null, and S must
|
||||
be nonzero. Set *PN to the new number of objects, and return the
|
||||
pointer to the new block. *PN is never set to zero, and the
|
||||
returned pointer is never null.
|
||||
|
||||
Repeated reallocations are guaranteed to make progress, either by
|
||||
allocating an initial block with a nonzero size, or by allocating a
|
||||
larger block.
|
||||
|
||||
In the following implementation, nonzero sizes are doubled so that
|
||||
repeated reallocations have O(N log N) overall cost rather than
|
||||
O(N**2) cost, but the specification for this function does not
|
||||
guarantee that sizes are doubled.
|
||||
|
||||
Here is an example of use:
|
||||
|
||||
int *p = NULL;
|
||||
size_t used = 0;
|
||||
size_t allocated = 0;
|
||||
|
||||
void
|
||||
append_int (int value)
|
||||
{
|
||||
if (used == allocated)
|
||||
p = x2nrealloc (p, &allocated, sizeof *p);
|
||||
p[used++] = value;
|
||||
}
|
||||
|
||||
This causes x2nrealloc to allocate a block of some nonzero size the
|
||||
first time it is called.
|
||||
|
||||
To have finer-grained control over the initial size, set *PN to a
|
||||
nonzero value before calling this function with P == NULL. For
|
||||
example:
|
||||
|
||||
int *p = NULL;
|
||||
size_t used = 0;
|
||||
size_t allocated = 0;
|
||||
size_t allocated1 = 1000;
|
||||
|
||||
void
|
||||
append_int (int value)
|
||||
{
|
||||
if (used == allocated)
|
||||
{
|
||||
p = x2nrealloc (p, &allocated1, sizeof *p);
|
||||
allocated = allocated1;
|
||||
}
|
||||
p[used++] = value;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static inline void *
|
||||
x2nrealloc_inline (void *p, size_t *pn, size_t s)
|
||||
{
|
||||
size_t n = *pn;
|
||||
|
||||
if (! p)
|
||||
{
|
||||
if (! n)
|
||||
{
|
||||
/* The approximate size to use for initial small allocation
|
||||
requests, when the invoking code specifies an old size of
|
||||
zero. 64 bytes is the largest "small" request for the
|
||||
GNU C library malloc. */
|
||||
enum { DEFAULT_MXFAST = 64 };
|
||||
|
||||
n = DEFAULT_MXFAST / s;
|
||||
n += !n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SIZE_MAX / 2 / s < n)
|
||||
xalloc_die ();
|
||||
n *= 2;
|
||||
}
|
||||
|
||||
*pn = n;
|
||||
return xrealloc (p, n * s);
|
||||
}
|
||||
|
||||
void *
|
||||
x2nrealloc (void *p, size_t *pn, size_t s)
|
||||
{
|
||||
return x2nrealloc_inline (p, pn, s);
|
||||
}
|
||||
|
||||
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
||||
reallocate P so that it contains more than *PN bytes. *PN must be
|
||||
nonzero unless P is null. Set *PN to the new block's size, and
|
||||
return the pointer to the new block. *PN is never set to zero, and
|
||||
the returned pointer is never null. */
|
||||
|
||||
void *
|
||||
x2realloc (void *p, size_t *pn)
|
||||
{
|
||||
return x2nrealloc_inline (p, pn, 1);
|
||||
}
|
||||
|
||||
/* Allocate S bytes of zeroed memory dynamically, with error checking.
|
||||
There's no need for xnzalloc (N, S), since it would be equivalent
|
||||
to xcalloc (N, S). */
|
||||
|
||||
void *
|
||||
xzalloc (size_t s)
|
||||
{
|
||||
return memset (xmalloc (s), 0, s);
|
||||
}
|
||||
|
||||
/* Allocate zeroed memory for N elements of S bytes, with error
|
||||
checking. S must be nonzero. */
|
||||
|
||||
void *
|
||||
xcalloc (size_t n, size_t s)
|
||||
{
|
||||
void *p;
|
||||
/* Test for overflow, since some calloc implementations don't have
|
||||
proper overflow checks. */
|
||||
if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
|
||||
xalloc_die ();
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Clone an object P of size S, with error checking. There's no need
|
||||
for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
|
||||
need for an arithmetic overflow check. */
|
||||
|
||||
void *
|
||||
xmemdup (void const *p, size_t s)
|
||||
{
|
||||
return memcpy (xmalloc (s), p, s);
|
||||
}
|
||||
|
||||
/* Clone STRING. */
|
||||
|
||||
char *
|
||||
xstrdup (char const *string)
|
||||
{
|
||||
return xmemdup (string, strlen (string) + 1);
|
||||
}
|
1588
contrib/cpio/src/copyin.c
Normal file
1588
contrib/cpio/src/copyin.c
Normal file
File diff suppressed because it is too large
Load Diff
803
contrib/cpio/src/copyout.c
Normal file
803
contrib/cpio/src/copyout.c
Normal file
@ -0,0 +1,803 @@
|
||||
/* copyout.c - create a cpio archive
|
||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "filetypes.h"
|
||||
#include "cpiohdr.h"
|
||||
#include "dstring.h"
|
||||
#include "extern.h"
|
||||
#include "defer.h"
|
||||
#include <rmt.h>
|
||||
|
||||
/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
|
||||
compute and return a checksum for them. */
|
||||
|
||||
static unsigned long
|
||||
read_for_checksum (int in_file_des, int file_size, char *file_name)
|
||||
{
|
||||
unsigned long crc;
|
||||
char buf[BUFSIZ];
|
||||
int bytes_left;
|
||||
int bytes_read;
|
||||
int i;
|
||||
|
||||
crc = 0;
|
||||
|
||||
for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read)
|
||||
{
|
||||
bytes_read = read (in_file_des, buf, BUFSIZ);
|
||||
if (bytes_read < 0)
|
||||
error (1, errno, _("cannot read checksum for %s"), file_name);
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
if (bytes_left < bytes_read)
|
||||
bytes_read = bytes_left;
|
||||
for (i = 0; i < bytes_read; ++i)
|
||||
crc += buf[i] & 0xff;
|
||||
}
|
||||
if (lseek (in_file_des, 0L, SEEK_SET))
|
||||
error (1, errno, _("cannot read checksum for %s"), file_name);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* Write out NULs to fill out the rest of the current block on
|
||||
OUT_FILE_DES. */
|
||||
|
||||
static void
|
||||
tape_clear_rest_of_block (int out_file_des)
|
||||
{
|
||||
while (output_size < io_block_size)
|
||||
{
|
||||
if ((io_block_size - output_size) > 512)
|
||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
||||
else
|
||||
tape_buffered_write (zeros_512, out_file_des, io_block_size - output_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
|
||||
to the end of the header. */
|
||||
|
||||
static void
|
||||
tape_pad_output (int out_file_des, int offset)
|
||||
{
|
||||
int pad;
|
||||
|
||||
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
||||
pad = (4 - (offset % 4)) % 4;
|
||||
else if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
pad = (512 - (offset % 512)) % 512;
|
||||
else if (archive_format != arf_oldascii && archive_format != arf_hpoldascii)
|
||||
pad = (2 - (offset % 2)) % 2;
|
||||
else
|
||||
pad = 0;
|
||||
|
||||
if (pad != 0)
|
||||
tape_buffered_write (zeros_512, out_file_des, pad);
|
||||
}
|
||||
|
||||
|
||||
/* When creating newc and crc archives if a file has multiple (hard)
|
||||
links, we don't put any of them into the archive until we have seen
|
||||
all of them (or until we get to the end of the list of files that
|
||||
are going into the archive and know that we have seen all of the links
|
||||
to the file that we will see). We keep these "defered" files on
|
||||
this list. */
|
||||
|
||||
struct deferment *deferouts = NULL;
|
||||
|
||||
/* Count the number of other (hard) links to this file that have
|
||||
already been defered. */
|
||||
|
||||
static int
|
||||
count_defered_links_to_dev_ino (struct new_cpio_header *file_hdr)
|
||||
{
|
||||
struct deferment *d;
|
||||
int ino;
|
||||
int maj;
|
||||
int min;
|
||||
int count;
|
||||
ino = file_hdr->c_ino;
|
||||
maj = file_hdr->c_dev_maj;
|
||||
min = file_hdr->c_dev_min;
|
||||
count = 0;
|
||||
for (d = deferouts; d != NULL; d = d->next)
|
||||
{
|
||||
if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
|
||||
&& (d->header.c_dev_min == min) )
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Is this file_hdr the last (hard) link to a file? I.e., have
|
||||
we already seen and defered all of the other links? */
|
||||
|
||||
static int
|
||||
last_link (struct new_cpio_header *file_hdr)
|
||||
{
|
||||
int other_files_sofar;
|
||||
|
||||
other_files_sofar = count_defered_links_to_dev_ino (file_hdr);
|
||||
if (file_hdr->c_nlink == (other_files_sofar + 1) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Add the file header for a link that is being defered to the deferouts
|
||||
list. */
|
||||
|
||||
static void
|
||||
add_link_defer (struct new_cpio_header *file_hdr)
|
||||
{
|
||||
struct deferment *d;
|
||||
d = create_deferment (file_hdr);
|
||||
d->next = deferouts;
|
||||
deferouts = d;
|
||||
}
|
||||
|
||||
/* We are about to put a file into a newc or crc archive that is
|
||||
multiply linked. We have already seen and defered all of the
|
||||
other links to the file but haven't written them into the archive.
|
||||
Write the other links into the archive, and remove them from the
|
||||
deferouts list. */
|
||||
|
||||
static void
|
||||
writeout_other_defers (struct new_cpio_header *file_hdr, int out_des)
|
||||
{
|
||||
struct deferment *d;
|
||||
struct deferment *d_prev;
|
||||
int ino;
|
||||
int maj;
|
||||
int min;
|
||||
ino = file_hdr->c_ino;
|
||||
maj = file_hdr->c_dev_maj;
|
||||
min = file_hdr->c_dev_min;
|
||||
d_prev = NULL;
|
||||
d = deferouts;
|
||||
while (d != NULL)
|
||||
{
|
||||
if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
|
||||
&& (d->header.c_dev_min == min) )
|
||||
{
|
||||
struct deferment *d_free;
|
||||
d->header.c_filesize = 0;
|
||||
write_out_header (&d->header, out_des);
|
||||
if (d_prev != NULL)
|
||||
d_prev->next = d->next;
|
||||
else
|
||||
deferouts = d->next;
|
||||
d_free = d;
|
||||
d = d->next;
|
||||
free_deferment (d_free);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_prev = d;
|
||||
d = d->next;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write a file into the archive. This code is the same as
|
||||
the code in process_copy_out(), but we need it here too
|
||||
for writeout_final_defers() to call. */
|
||||
|
||||
static void
|
||||
writeout_defered_file (struct new_cpio_header *header, int out_file_des)
|
||||
{
|
||||
int in_file_des;
|
||||
struct new_cpio_header file_hdr;
|
||||
struct utimbuf times; /* For setting file times. */
|
||||
/* Initialize this in case it has members we don't know to set. */
|
||||
bzero (×, sizeof (struct utimbuf));
|
||||
|
||||
file_hdr = *header;
|
||||
|
||||
|
||||
in_file_des = open (header->c_name,
|
||||
O_RDONLY | O_BINARY, 0);
|
||||
if (in_file_des < 0)
|
||||
{
|
||||
error (0, errno, "%s", header->c_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (archive_format == arf_crcascii)
|
||||
file_hdr.c_chksum = read_for_checksum (in_file_des,
|
||||
file_hdr.c_filesize,
|
||||
header->c_name);
|
||||
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, header->c_name);
|
||||
warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
|
||||
|
||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
|
||||
file_hdr.c_dev_min);
|
||||
|
||||
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
||||
|
||||
if (close (in_file_des) < 0)
|
||||
error (0, errno, "%s", header->c_name);
|
||||
if (reset_time_flag)
|
||||
{
|
||||
times.actime = file_hdr.c_mtime;
|
||||
times.modtime = file_hdr.c_mtime;
|
||||
/* Debian hack: Silently ignore EROFS because reading the file
|
||||
won't have upset its timestamp if it's on a read-only
|
||||
filesystem. This has been submitted as a suggestion to
|
||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
||||
if (utime (file_hdr.c_name, ×) < 0
|
||||
&& errno != EROFS)
|
||||
error (0, errno, "%s", file_hdr.c_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* When writing newc and crc format archives we defer multiply linked
|
||||
files until we have seen all of the links to the file. If a file
|
||||
has links to it that aren't going into the archive, then we will
|
||||
never see the "last" link to the file, so at the end we just write
|
||||
all of the leftover defered files into the archive. */
|
||||
|
||||
static void
|
||||
writeout_final_defers (int out_des)
|
||||
{
|
||||
struct deferment *d;
|
||||
int other_count;
|
||||
while (deferouts != NULL)
|
||||
{
|
||||
d = deferouts;
|
||||
other_count = count_defered_links_to_dev_ino (&d->header);
|
||||
if (other_count == 1)
|
||||
{
|
||||
writeout_defered_file (&d->header, out_des);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct new_cpio_header file_hdr;
|
||||
file_hdr = d->header;
|
||||
file_hdr.c_filesize = 0;
|
||||
write_out_header (&file_hdr, out_des);
|
||||
}
|
||||
deferouts = deferouts->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write out header FILE_HDR, including the file name, to file
|
||||
descriptor OUT_DES. */
|
||||
|
||||
void
|
||||
write_out_header (struct new_cpio_header *file_hdr, int out_des)
|
||||
{
|
||||
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
||||
{
|
||||
char ascii_header[112];
|
||||
char *magic_string;
|
||||
|
||||
if (archive_format == arf_crcascii)
|
||||
magic_string = "070702";
|
||||
else
|
||||
magic_string = "070701";
|
||||
sprintf (ascii_header,
|
||||
"%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
|
||||
magic_string,
|
||||
file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
|
||||
file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
|
||||
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
|
||||
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
|
||||
file_hdr->c_chksum);
|
||||
tape_buffered_write (ascii_header, out_des, 110L);
|
||||
|
||||
/* Write file name to output. */
|
||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
||||
tape_pad_output (out_des, file_hdr->c_namesize + 110);
|
||||
}
|
||||
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
|
||||
{
|
||||
char ascii_header[78];
|
||||
dev_t dev;
|
||||
dev_t rdev;
|
||||
|
||||
if (archive_format == arf_oldascii)
|
||||
{
|
||||
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HP/UX cpio creates archives that look just like ordinary archives,
|
||||
but for devices it sets major = 0, minor = 1, and puts the
|
||||
actual major/minor number in the filesize field. */
|
||||
switch (file_hdr->c_mode & CP_IFMT)
|
||||
{
|
||||
case CP_IFCHR:
|
||||
case CP_IFBLK:
|
||||
#ifdef CP_IFSOCK
|
||||
case CP_IFSOCK:
|
||||
#endif
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
#endif
|
||||
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
|
||||
file_hdr->c_rdev_min);
|
||||
rdev = 1;
|
||||
break;
|
||||
default:
|
||||
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
|
||||
error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
|
||||
|
||||
/* Debian hack: The type of dev_t has changed in glibc. Fixed output
|
||||
to ensure that a long int is passed to sprintf. This has been
|
||||
reported to "bug-gnu-utils@prep.ai.mit.edu". (1998/5/26) -BEM */
|
||||
sprintf (ascii_header,
|
||||
"%06ho%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
|
||||
file_hdr->c_magic & 0xFFFF, (long) dev & 0xFFFF,
|
||||
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
|
||||
file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
|
||||
file_hdr->c_nlink & 0xFFFF, (long) rdev & 0xFFFF,
|
||||
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
|
||||
file_hdr->c_filesize);
|
||||
tape_buffered_write (ascii_header, out_des, 76L);
|
||||
|
||||
/* Write file name to output. */
|
||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
||||
}
|
||||
else if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
{
|
||||
write_out_tar_header (file_hdr, out_des);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct old_cpio_header short_hdr;
|
||||
|
||||
short_hdr.c_magic = 070707;
|
||||
short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
||||
|
||||
if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
|
||||
error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
|
||||
|
||||
short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
|
||||
short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
|
||||
short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
|
||||
short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
|
||||
short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
|
||||
if (archive_format != arf_hpbinary)
|
||||
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||
else
|
||||
{
|
||||
switch (file_hdr->c_mode & CP_IFMT)
|
||||
{
|
||||
/* HP/UX cpio creates archives that look just like ordinary
|
||||
archives, but for devices it sets major = 0, minor = 1, and
|
||||
puts the actual major/minor number in the filesize field. */
|
||||
case CP_IFCHR:
|
||||
case CP_IFBLK:
|
||||
#ifdef CP_IFSOCK
|
||||
case CP_IFSOCK:
|
||||
#endif
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
#endif
|
||||
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
|
||||
file_hdr->c_rdev_min);
|
||||
short_hdr.c_rdev = makedev (0, 1);
|
||||
break;
|
||||
default:
|
||||
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj,
|
||||
file_hdr->c_rdev_min);
|
||||
break;
|
||||
}
|
||||
}
|
||||
short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
|
||||
short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
|
||||
|
||||
short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
|
||||
|
||||
short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
|
||||
short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
|
||||
|
||||
/* Output the file header. */
|
||||
tape_buffered_write ((char *) &short_hdr, out_des, 26L);
|
||||
|
||||
/* Write file name to output. */
|
||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
||||
|
||||
tape_pad_output (out_des, file_hdr->c_namesize + 26);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a list of file names from the standard input
|
||||
and write a cpio collection on the standard output.
|
||||
The format of the header depends on the compatibility (-c) flag. */
|
||||
|
||||
void
|
||||
process_copy_out ()
|
||||
{
|
||||
int res; /* Result of functions. */
|
||||
dynamic_string input_name; /* Name of file read from stdin. */
|
||||
struct utimbuf times; /* For resetting file times after copy. */
|
||||
struct stat file_stat; /* Stat record for file. */
|
||||
struct new_cpio_header file_hdr; /* Output header information. */
|
||||
int in_file_des; /* Source file descriptor. */
|
||||
int out_file_des; /* Output file descriptor. */
|
||||
char *p;
|
||||
|
||||
/* Initialize the copy out. */
|
||||
ds_init (&input_name, 128);
|
||||
/* Initialize this in case it has members we don't know to set. */
|
||||
bzero (×, sizeof (struct utimbuf));
|
||||
file_hdr.c_magic = 070707;
|
||||
|
||||
/* Check whether the output file might be a tape. */
|
||||
out_file_des = archive_des;
|
||||
if (_isrmt (out_file_des))
|
||||
{
|
||||
output_is_special = 1;
|
||||
output_is_seekable = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fstat (out_file_des, &file_stat))
|
||||
error (1, errno, _("standard output is closed"));
|
||||
output_is_special =
|
||||
#ifdef S_ISBLK
|
||||
S_ISBLK (file_stat.st_mode) ||
|
||||
#endif
|
||||
S_ISCHR (file_stat.st_mode);
|
||||
output_is_seekable = S_ISREG (file_stat.st_mode);
|
||||
}
|
||||
|
||||
if (append_flag)
|
||||
{
|
||||
process_copy_in ();
|
||||
prepare_append (out_file_des);
|
||||
}
|
||||
|
||||
/* Copy files with names read from stdin. */
|
||||
while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
||||
{
|
||||
/* Check for blank line. */
|
||||
if (input_name.ds_string[0] == 0)
|
||||
{
|
||||
error (0, 0, _("blank line ignored"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Process next file. */
|
||||
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
else
|
||||
{
|
||||
/* Set values in output header. */
|
||||
file_hdr.c_dev_maj = major (file_stat.st_dev);
|
||||
file_hdr.c_dev_min = minor (file_stat.st_dev);
|
||||
file_hdr.c_ino = file_stat.st_ino;
|
||||
/* For POSIX systems that don't define the S_IF macros,
|
||||
we can't assume that S_ISfoo means the standard Unix
|
||||
S_IFfoo bit(s) are set. So do it manually, with a
|
||||
different name. Bleah. */
|
||||
file_hdr.c_mode = (file_stat.st_mode & 07777);
|
||||
if (S_ISREG (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFREG;
|
||||
else if (S_ISDIR (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFDIR;
|
||||
#ifdef S_ISBLK
|
||||
else if (S_ISBLK (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFBLK;
|
||||
#endif
|
||||
#ifdef S_ISCHR
|
||||
else if (S_ISCHR (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFCHR;
|
||||
#endif
|
||||
#ifdef S_ISFIFO
|
||||
else if (S_ISFIFO (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFIFO;
|
||||
#endif
|
||||
#ifdef S_ISLNK
|
||||
else if (S_ISLNK (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFLNK;
|
||||
#endif
|
||||
#ifdef S_ISSOCK
|
||||
else if (S_ISSOCK (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFSOCK;
|
||||
#endif
|
||||
#ifdef S_ISNWK
|
||||
else if (S_ISNWK (file_stat.st_mode))
|
||||
file_hdr.c_mode |= CP_IFNWK;
|
||||
#endif
|
||||
file_hdr.c_uid = file_stat.st_uid;
|
||||
file_hdr.c_gid = file_stat.st_gid;
|
||||
file_hdr.c_nlink = file_stat.st_nlink;
|
||||
file_hdr.c_rdev_maj = major (file_stat.st_rdev);
|
||||
file_hdr.c_rdev_min = minor (file_stat.st_rdev);
|
||||
file_hdr.c_mtime = file_stat.st_mtime;
|
||||
file_hdr.c_filesize = file_stat.st_size;
|
||||
file_hdr.c_chksum = 0;
|
||||
file_hdr.c_tar_linkname = NULL;
|
||||
|
||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
{
|
||||
if (file_hdr.c_mode & CP_IFDIR)
|
||||
{
|
||||
int len = strlen (input_name.ds_string);
|
||||
/* Make sure the name ends with a slash */
|
||||
if (input_name.ds_string[len-1] != '/')
|
||||
{
|
||||
ds_resize (&input_name, len + 2);
|
||||
input_name.ds_string[len] = '/';
|
||||
input_name.ds_string[len+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Strip leading `./' from the filename. */
|
||||
p = input_name.ds_string;
|
||||
while (*p == '.' && *(p + 1) == '/')
|
||||
{
|
||||
++p;
|
||||
while (*p == '/')
|
||||
++p;
|
||||
}
|
||||
#ifndef HPUX_CDF
|
||||
file_hdr.c_name = p;
|
||||
file_hdr.c_namesize = strlen (p) + 1;
|
||||
#else
|
||||
if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
|
||||
{
|
||||
/* We mark CDF's in cpio files by adding a 2nd `/' after the
|
||||
"hidden" directory name. We need to do this so we can
|
||||
properly recreate the directory as hidden (in case the
|
||||
files of a directory go into the archive before the
|
||||
directory itself (e.g from "find ... -depth ... | cpio")). */
|
||||
file_hdr.c_name = add_cdf_double_slashes (p);
|
||||
file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't mark CDF's in tar files. We assume the "hidden"
|
||||
directory will always go into the archive before any of
|
||||
its files. */
|
||||
file_hdr.c_name = p;
|
||||
file_hdr.c_namesize = strlen (p) + 1;
|
||||
}
|
||||
#endif
|
||||
if ((archive_format == arf_tar || archive_format == arf_ustar)
|
||||
&& is_tar_filename_too_long (file_hdr.c_name))
|
||||
{
|
||||
error (0, 0, _("%s: file name too long"),
|
||||
file_hdr.c_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy the named file to the output. */
|
||||
switch (file_hdr.c_mode & CP_IFMT)
|
||||
{
|
||||
case CP_IFREG:
|
||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
{
|
||||
char *otherfile;
|
||||
if ((otherfile = find_inode_file (file_hdr.c_ino,
|
||||
file_hdr.c_dev_maj,
|
||||
file_hdr.c_dev_min)))
|
||||
{
|
||||
file_hdr.c_tar_linkname = otherfile;
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
|
||||
&& (file_hdr.c_nlink > 1) )
|
||||
{
|
||||
if (last_link (&file_hdr) )
|
||||
{
|
||||
writeout_other_defers (&file_hdr, out_file_des);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_link_defer (&file_hdr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
in_file_des = open (input_name.ds_string,
|
||||
O_RDONLY | O_BINARY, 0);
|
||||
if (in_file_des < 0)
|
||||
{
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (archive_format == arf_crcascii)
|
||||
file_hdr.c_chksum = read_for_checksum (in_file_des,
|
||||
file_hdr.c_filesize,
|
||||
input_name.ds_string);
|
||||
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, input_name.ds_string);
|
||||
warn_if_file_changed(input_name.ds_string, file_hdr.c_filesize,
|
||||
file_hdr.c_mtime);
|
||||
|
||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
|
||||
file_hdr.c_dev_min);
|
||||
|
||||
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
||||
|
||||
if (close (in_file_des) < 0)
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
if (reset_time_flag)
|
||||
{
|
||||
times.actime = file_stat.st_atime;
|
||||
times.modtime = file_stat.st_mtime;
|
||||
/* Debian hack: Silently ignore EROFS because
|
||||
reading the file won't have upset its timestamp
|
||||
if it's on a read-only filesystem. This has been
|
||||
submitted as a suggestion to
|
||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
||||
if (utime (file_hdr.c_name, ×) < 0
|
||||
&& errno != EROFS)
|
||||
error (0, errno, "%s", file_hdr.c_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case CP_IFDIR:
|
||||
file_hdr.c_filesize = 0;
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
break;
|
||||
|
||||
case CP_IFCHR:
|
||||
case CP_IFBLK:
|
||||
#ifdef CP_IFSOCK
|
||||
case CP_IFSOCK:
|
||||
#endif
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
#endif
|
||||
if (archive_format == arf_tar)
|
||||
{
|
||||
error (0, 0, _("%s not dumped: not a regular file"),
|
||||
file_hdr.c_name);
|
||||
continue;
|
||||
}
|
||||
else if (archive_format == arf_ustar)
|
||||
{
|
||||
char *otherfile;
|
||||
if ((otherfile = find_inode_file (file_hdr.c_ino,
|
||||
file_hdr.c_dev_maj,
|
||||
file_hdr.c_dev_min)))
|
||||
{
|
||||
/* This file is linked to another file already in the
|
||||
archive, so write it out as a hard link. */
|
||||
file_hdr.c_mode = (file_stat.st_mode & 07777);
|
||||
file_hdr.c_mode |= CP_IFREG;
|
||||
file_hdr.c_tar_linkname = otherfile;
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
break;
|
||||
}
|
||||
add_inode (file_hdr.c_ino, file_hdr.c_name,
|
||||
file_hdr.c_dev_maj, file_hdr.c_dev_min);
|
||||
}
|
||||
file_hdr.c_filesize = 0;
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
break;
|
||||
|
||||
#ifdef CP_IFLNK
|
||||
case CP_IFLNK:
|
||||
{
|
||||
char *link_name = (char *) xmalloc (file_stat.st_size + 1);
|
||||
int link_size;
|
||||
|
||||
link_size = readlink (input_name.ds_string, link_name,
|
||||
file_stat.st_size);
|
||||
if (link_size < 0)
|
||||
{
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
free (link_name);
|
||||
continue;
|
||||
}
|
||||
file_hdr.c_filesize = link_size;
|
||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||
{
|
||||
if (link_size + 1 > 100)
|
||||
{
|
||||
error (0, 0, _("%s: symbolic link too long"),
|
||||
file_hdr.c_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
link_name[link_size] = '\0';
|
||||
file_hdr.c_tar_linkname = link_name;
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
tape_buffered_write (link_name, out_file_des, link_size);
|
||||
tape_pad_output (out_file_des, link_size);
|
||||
}
|
||||
free (link_name);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
error (0, 0, _("%s: unknown file type"), input_name.ds_string);
|
||||
}
|
||||
|
||||
if (verbose_flag)
|
||||
fprintf (stderr, "%s\n", input_name.ds_string);
|
||||
if (dot_flag)
|
||||
fputc ('.', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
writeout_final_defers(out_file_des);
|
||||
/* The collection is complete; append the trailer. */
|
||||
file_hdr.c_ino = 0;
|
||||
file_hdr.c_mode = 0;
|
||||
file_hdr.c_uid = 0;
|
||||
file_hdr.c_gid = 0;
|
||||
file_hdr.c_nlink = 1; /* Must be 1 for crc format. */
|
||||
file_hdr.c_dev_maj = 0;
|
||||
file_hdr.c_dev_min = 0;
|
||||
file_hdr.c_rdev_maj = 0;
|
||||
file_hdr.c_rdev_min = 0;
|
||||
file_hdr.c_mtime = 0;
|
||||
file_hdr.c_chksum = 0;
|
||||
|
||||
file_hdr.c_filesize = 0;
|
||||
file_hdr.c_namesize = 11;
|
||||
file_hdr.c_name = "TRAILER!!!";
|
||||
if (archive_format != arf_tar && archive_format != arf_ustar)
|
||||
write_out_header (&file_hdr, out_file_des);
|
||||
else
|
||||
{
|
||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
||||
}
|
||||
|
||||
/* Fill up the output block. */
|
||||
tape_clear_rest_of_block (out_file_des);
|
||||
tape_empty_output_buffer (out_file_des);
|
||||
if (dot_flag)
|
||||
fputc ('\n', stderr);
|
||||
if (!quiet_flag)
|
||||
{
|
||||
res = (output_bytes + io_block_size - 1) / io_block_size;
|
||||
fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
|
||||
}
|
||||
}
|
||||
|
||||
|
464
contrib/cpio/src/copypass.c
Normal file
464
contrib/cpio/src/copypass.c
Normal file
@ -0,0 +1,464 @@
|
||||
/* copypass.c - cpio copy pass sub-function.
|
||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "filetypes.h"
|
||||
#include "cpiohdr.h"
|
||||
#include "dstring.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifndef HAVE_LCHOWN
|
||||
#define lchown chown
|
||||
#endif
|
||||
|
||||
/* Copy files listed on the standard input into directory `directory_name'.
|
||||
If `link_flag', link instead of copying. */
|
||||
|
||||
void
|
||||
process_copy_pass ()
|
||||
{
|
||||
dynamic_string input_name; /* Name of file from stdin. */
|
||||
dynamic_string output_name; /* Name of new file. */
|
||||
int dirname_len; /* Length of `directory_name'. */
|
||||
int res; /* Result of functions. */
|
||||
char *slash; /* For moving past slashes in input name. */
|
||||
struct utimbuf times; /* For resetting file times after copy. */
|
||||
struct stat in_file_stat; /* Stat record for input file. */
|
||||
struct stat out_file_stat; /* Stat record for output file. */
|
||||
int in_file_des; /* Input file descriptor. */
|
||||
int out_file_des; /* Output file descriptor. */
|
||||
int existing_dir; /* True if file is a dir & already exists. */
|
||||
#ifdef HPUX_CDF
|
||||
int cdf_flag;
|
||||
int cdf_char;
|
||||
#endif
|
||||
|
||||
/* Initialize the copy pass. */
|
||||
dirname_len = strlen (directory_name);
|
||||
ds_init (&input_name, 128);
|
||||
ds_init (&output_name, dirname_len + 2);
|
||||
strcpy (output_name.ds_string, directory_name);
|
||||
output_name.ds_string[dirname_len] = '/';
|
||||
output_is_seekable = true;
|
||||
/* Initialize this in case it has members we don't know to set. */
|
||||
bzero (×, sizeof (struct utimbuf));
|
||||
|
||||
/* Copy files with names read from stdin. */
|
||||
while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
||||
{
|
||||
int link_res = -1;
|
||||
|
||||
/* Check for blank line and ignore it if found. */
|
||||
if (input_name.ds_string[0] == '\0')
|
||||
{
|
||||
error (0, 0, _("blank line ignored"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for current directory and ignore it if found. */
|
||||
if (input_name.ds_string[0] == '.'
|
||||
&& (input_name.ds_string[1] == '\0'
|
||||
|| (input_name.ds_string[1] == '/'
|
||||
&& input_name.ds_string[2] == '\0')))
|
||||
continue;
|
||||
|
||||
if ((*xstat) (input_name.ds_string, &in_file_stat) < 0)
|
||||
{
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make the name of the new file. */
|
||||
for (slash = input_name.ds_string; *slash == '/'; ++slash)
|
||||
;
|
||||
#ifdef HPUX_CDF
|
||||
/* For CDF's we add a 2nd `/' after all "hidden" directories.
|
||||
This kind of a kludge, but it's what we do when creating
|
||||
archives, and it's easier to do this than to separately
|
||||
keep track of which directories in a path are "hidden". */
|
||||
slash = add_cdf_double_slashes (slash);
|
||||
#endif
|
||||
ds_resize (&output_name, dirname_len + strlen (slash) + 2);
|
||||
strcpy (output_name.ds_string + dirname_len + 1, slash);
|
||||
|
||||
existing_dir = false;
|
||||
if (lstat (output_name.ds_string, &out_file_stat) == 0)
|
||||
{
|
||||
if (S_ISDIR (out_file_stat.st_mode)
|
||||
&& S_ISDIR (in_file_stat.st_mode))
|
||||
{
|
||||
/* If there is already a directory there that
|
||||
we are trying to create, don't complain about it. */
|
||||
existing_dir = true;
|
||||
}
|
||||
else if (!unconditional_flag
|
||||
&& in_file_stat.st_mtime <= out_file_stat.st_mtime)
|
||||
{
|
||||
error (0, 0, _("%s not created: newer or same age version exists"),
|
||||
output_name.ds_string);
|
||||
continue; /* Go to the next file. */
|
||||
}
|
||||
else if (S_ISDIR (out_file_stat.st_mode)
|
||||
? rmdir (output_name.ds_string)
|
||||
: unlink (output_name.ds_string))
|
||||
{
|
||||
error (0, errno, _("cannot remove current %s"),
|
||||
output_name.ds_string);
|
||||
continue; /* Go to the next file. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the real copy or link. */
|
||||
if (S_ISREG (in_file_stat.st_mode))
|
||||
{
|
||||
/* Can the current file be linked to a another file?
|
||||
Set link_name to the original file name. */
|
||||
if (link_flag)
|
||||
/* User said to link it if possible. Try and link to
|
||||
the original copy. If that fails we'll still try
|
||||
and link to a copy we've already made. */
|
||||
link_res = link_to_name (output_name.ds_string,
|
||||
input_name.ds_string);
|
||||
if ( (link_res < 0) && (in_file_stat.st_nlink > 1) )
|
||||
link_res = link_to_maj_min_ino (output_name.ds_string,
|
||||
major (in_file_stat.st_dev),
|
||||
minor (in_file_stat.st_dev),
|
||||
in_file_stat.st_ino);
|
||||
|
||||
/* If the file was not linked, copy contents of file. */
|
||||
if (link_res < 0)
|
||||
{
|
||||
in_file_des = open (input_name.ds_string,
|
||||
O_RDONLY | O_BINARY, 0);
|
||||
if (in_file_des < 0)
|
||||
{
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
continue;
|
||||
}
|
||||
out_file_des = open (output_name.ds_string,
|
||||
O_CREAT | O_WRONLY | O_BINARY, 0600);
|
||||
if (out_file_des < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (output_name.ds_string);
|
||||
out_file_des = open (output_name.ds_string,
|
||||
O_CREAT | O_WRONLY | O_BINARY, 0600);
|
||||
}
|
||||
if (out_file_des < 0)
|
||||
{
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
close (in_file_des);
|
||||
continue;
|
||||
}
|
||||
|
||||
copy_files_disk_to_disk (in_file_des, out_file_des, in_file_stat.st_size, input_name.ds_string);
|
||||
disk_empty_output_buffer (out_file_des);
|
||||
/* Debian hack to fix a bug in the --sparse option.
|
||||
This bug has been reported to
|
||||
"bug-gnu-utils@prep.ai.mit.edu". (96/7/10) -BEM */
|
||||
if (delayed_seek_count > 0)
|
||||
{
|
||||
lseek (out_file_des, delayed_seek_count-1, SEEK_CUR);
|
||||
write (out_file_des, "", 1);
|
||||
delayed_seek_count = 0;
|
||||
}
|
||||
if (close (in_file_des) < 0)
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
if (close (out_file_des) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
|
||||
/* Set the attributes of the new file. */
|
||||
if (!no_chown_flag)
|
||||
if ((chown (output_name.ds_string,
|
||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
||||
&& errno != EPERM)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
/* chown may have turned off some permissions we wanted. */
|
||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
if (reset_time_flag)
|
||||
{
|
||||
times.actime = in_file_stat.st_atime;
|
||||
times.modtime = in_file_stat.st_mtime;
|
||||
/* Debian hack: Silently ignore EROFS because
|
||||
reading the file won't have upset its timestamp
|
||||
if it's on a read-only filesystem. This has been
|
||||
submitted as a suggestion to
|
||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
||||
if (utime (input_name.ds_string, ×) < 0
|
||||
&& errno != EROFS)
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
if (utime (output_name.ds_string, ×) < 0
|
||||
&& errno != EROFS)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
}
|
||||
if (retain_time_flag)
|
||||
{
|
||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
||||
if (utime (output_name.ds_string, ×) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
}
|
||||
warn_if_file_changed(input_name.ds_string, in_file_stat.st_size,
|
||||
in_file_stat.st_mtime);
|
||||
}
|
||||
}
|
||||
else if (S_ISDIR (in_file_stat.st_mode))
|
||||
{
|
||||
#ifdef HPUX_CDF
|
||||
cdf_flag = 0;
|
||||
#endif
|
||||
if (!existing_dir)
|
||||
{
|
||||
#ifdef HPUX_CDF
|
||||
/* If the directory name ends in a + and is SUID,
|
||||
then it is a CDF. Strip the trailing + from the name
|
||||
before creating it. */
|
||||
cdf_char = strlen (output_name.ds_string) - 1;
|
||||
if ( (cdf_char > 0) &&
|
||||
(in_file_stat.st_mode & 04000) &&
|
||||
(output_name.ds_string [cdf_char] == '+') )
|
||||
{
|
||||
output_name.ds_string [cdf_char] = '\0';
|
||||
cdf_flag = 1;
|
||||
}
|
||||
#endif
|
||||
res = mkdir (output_name.ds_string, in_file_stat.st_mode);
|
||||
|
||||
}
|
||||
else
|
||||
res = 0;
|
||||
if (res < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (output_name.ds_string);
|
||||
res = mkdir (output_name.ds_string, in_file_stat.st_mode);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
/* In some odd cases where the output_name includes `.',
|
||||
the directory may have actually been created by
|
||||
create_all_directories(), so the mkdir will fail
|
||||
because the directory exists. If that's the case,
|
||||
don't complain about it. */
|
||||
if ( (errno != EEXIST) ||
|
||||
(lstat (output_name.ds_string, &out_file_stat) != 0) ||
|
||||
!(S_ISDIR (out_file_stat.st_mode) ) )
|
||||
{
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!no_chown_flag)
|
||||
if ((chown (output_name.ds_string,
|
||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
||||
&& errno != EPERM)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
/* chown may have turned off some permissions we wanted. */
|
||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
#ifdef HPUX_CDF
|
||||
if (cdf_flag)
|
||||
/* Once we "hide" the directory with the chmod(),
|
||||
we have to refer to it using name+ isntead of name. */
|
||||
output_name.ds_string [cdf_char] = '+';
|
||||
#endif
|
||||
if (retain_time_flag)
|
||||
{
|
||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
||||
if (utime (output_name.ds_string, ×) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
}
|
||||
}
|
||||
else if (S_ISCHR (in_file_stat.st_mode) ||
|
||||
S_ISBLK (in_file_stat.st_mode) ||
|
||||
#ifdef S_ISFIFO
|
||||
S_ISFIFO (in_file_stat.st_mode) ||
|
||||
#endif
|
||||
#ifdef S_ISSOCK
|
||||
S_ISSOCK (in_file_stat.st_mode) ||
|
||||
#endif
|
||||
0)
|
||||
{
|
||||
/* Can the current file be linked to a another file?
|
||||
Set link_name to the original file name. */
|
||||
if (link_flag)
|
||||
/* User said to link it if possible. */
|
||||
link_res = link_to_name (output_name.ds_string,
|
||||
input_name.ds_string);
|
||||
if ( (link_res < 0) && (in_file_stat.st_nlink > 1) )
|
||||
link_res = link_to_maj_min_ino (output_name.ds_string,
|
||||
major (in_file_stat.st_dev),
|
||||
minor (in_file_stat.st_dev),
|
||||
in_file_stat.st_ino);
|
||||
|
||||
if (link_res < 0)
|
||||
{
|
||||
res = mknod (output_name.ds_string, in_file_stat.st_mode,
|
||||
in_file_stat.st_rdev);
|
||||
if (res < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (output_name.ds_string);
|
||||
res = mknod (output_name.ds_string, in_file_stat.st_mode,
|
||||
in_file_stat.st_rdev);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
continue;
|
||||
}
|
||||
if (!no_chown_flag)
|
||||
if ((chown (output_name.ds_string,
|
||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
||||
&& errno != EPERM)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
/* chown may have turned off some permissions we wanted. */
|
||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
if (retain_time_flag)
|
||||
{
|
||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
||||
if (utime (output_name.ds_string, ×) < 0)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef S_ISLNK
|
||||
else if (S_ISLNK (in_file_stat.st_mode))
|
||||
{
|
||||
char *link_name;
|
||||
int link_size;
|
||||
link_name = (char *) xmalloc ((unsigned int) in_file_stat.st_size + 1);
|
||||
|
||||
link_size = readlink (input_name.ds_string, link_name,
|
||||
in_file_stat.st_size);
|
||||
if (link_size < 0)
|
||||
{
|
||||
error (0, errno, "%s", input_name.ds_string);
|
||||
free (link_name);
|
||||
continue;
|
||||
}
|
||||
link_name[link_size] = '\0';
|
||||
|
||||
res = UMASKED_SYMLINK (link_name, output_name.ds_string,
|
||||
in_file_stat.st_mode);
|
||||
if (res < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (output_name.ds_string);
|
||||
res = UMASKED_SYMLINK (link_name, output_name.ds_string,
|
||||
in_file_stat.st_mode);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
free (link_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set the attributes of the new link. */
|
||||
if (!no_chown_flag)
|
||||
if ((lchown (output_name.ds_string,
|
||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
||||
&& errno != EPERM)
|
||||
error (0, errno, "%s", output_name.ds_string);
|
||||
free (link_name);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
error (0, 0, _("%s: unknown file type"), input_name.ds_string);
|
||||
}
|
||||
|
||||
if (verbose_flag)
|
||||
fprintf (stderr, "%s\n", output_name.ds_string);
|
||||
if (dot_flag)
|
||||
fputc ('.', stderr);
|
||||
}
|
||||
|
||||
if (dot_flag)
|
||||
fputc ('\n', stderr);
|
||||
if (!quiet_flag)
|
||||
{
|
||||
res = (output_bytes + io_block_size - 1) / io_block_size;
|
||||
fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try and create a hard link from FILE_NAME to another file
|
||||
with the given major/minor device number and inode. If no other
|
||||
file with the same major/minor/inode numbers is known, add this file
|
||||
to the list of known files and associated major/minor/inode numbers
|
||||
and return -1. If another file with the same major/minor/inode
|
||||
numbers is found, try and create another link to it using
|
||||
link_to_name, and return 0 for success and -1 for failure. */
|
||||
|
||||
int
|
||||
link_to_maj_min_ino (char *file_name, int st_dev_maj, int st_dev_min,
|
||||
int st_ino)
|
||||
{
|
||||
int link_res;
|
||||
char *link_name;
|
||||
link_res = -1;
|
||||
/* Is the file a link to a previously copied file? */
|
||||
link_name = find_inode_file (st_ino,
|
||||
st_dev_maj,
|
||||
st_dev_min);
|
||||
if (link_name == NULL)
|
||||
add_inode (st_ino, file_name,
|
||||
st_dev_maj,
|
||||
st_dev_min);
|
||||
else
|
||||
link_res = link_to_name (file_name, link_name);
|
||||
return link_res;
|
||||
}
|
||||
|
||||
/* Try and create a hard link from LINK_NAME to LINK_TARGET. If
|
||||
`create_dir_flag' is set, any non-existent (parent) directories
|
||||
needed by LINK_NAME will be created. If the link is successfully
|
||||
created and `verbose_flag' is set, print "LINK_TARGET linked to LINK_NAME\n".
|
||||
If the link can not be created and `link_flag' is set, print
|
||||
"cannot link LINK_TARGET to LINK_NAME\n". Return 0 if the link
|
||||
is created, -1 otherwise. */
|
||||
|
||||
int
|
||||
link_to_name (char *link_name, char *link_target)
|
||||
{
|
||||
int res = link (link_target, link_name);
|
||||
if (res < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (link_name);
|
||||
res = link (link_target, link_name);
|
||||
}
|
||||
if (res == 0)
|
||||
{
|
||||
if (verbose_flag)
|
||||
error (0, 0, _("%s linked to %s"),
|
||||
link_target, link_name);
|
||||
}
|
||||
else if (link_flag)
|
||||
{
|
||||
error (0, errno, _("cannot link %s to %s"),
|
||||
link_target, link_name);
|
||||
}
|
||||
return res;
|
||||
}
|
69
contrib/cpio/src/cpio.h
Normal file
69
contrib/cpio/src/cpio.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* Extended cpio format from POSIX.1.
|
||||
Copyright (C) 1992 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _CPIO_H
|
||||
|
||||
#define _CPIO_H 1
|
||||
|
||||
/* A cpio archive consists of a sequence of files.
|
||||
Each file has a 76 byte header,
|
||||
a variable length, NUL terminated filename,
|
||||
and variable length file data.
|
||||
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
||||
|
||||
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
||||
of octal numbers, left padded, not NUL terminated.
|
||||
|
||||
Field Name Length in Bytes Notes
|
||||
c_magic 6 must be "070707"
|
||||
c_dev 6
|
||||
c_ino 6
|
||||
c_mode 6 see below for value
|
||||
c_uid 6
|
||||
c_gid 6
|
||||
c_nlink 6
|
||||
c_rdev 6 only valid for chr and blk special files
|
||||
c_mtime 11
|
||||
c_namesize 6 count includes terminating NUL in pathname
|
||||
c_filesize 11 must be 0 for FIFOs and directories */
|
||||
|
||||
/* Values for c_mode, OR'd together: */
|
||||
|
||||
#define C_IRUSR 000400
|
||||
#define C_IWUSR 000200
|
||||
#define C_IXUSR 000100
|
||||
#define C_IRGRP 000040
|
||||
#define C_IWGRP 000020
|
||||
#define C_IXGRP 000010
|
||||
#define C_IROTH 000004
|
||||
#define C_IWOTH 000002
|
||||
#define C_IXOTH 000001
|
||||
|
||||
#define C_ISUID 004000
|
||||
#define C_ISGID 002000
|
||||
#define C_ISVTX 001000
|
||||
|
||||
#define C_ISBLK 060000
|
||||
#define C_ISCHR 020000
|
||||
#define C_ISDIR 040000
|
||||
#define C_ISFIFO 010000
|
||||
#define C_ISSOCK 0140000
|
||||
#define C_ISLNK 0120000
|
||||
#define C_ISCTG 0110000
|
||||
#define C_ISREG 0100000
|
||||
|
||||
#endif /* cpio.h */
|
90
contrib/cpio/src/cpiohdr.h
Normal file
90
contrib/cpio/src/cpiohdr.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* Extended cpio header from POSIX.1.
|
||||
Copyright (C) 1992 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _CPIOHDR_H
|
||||
|
||||
#define _CPIOHDR_H 1
|
||||
|
||||
#include <cpio.h>
|
||||
|
||||
struct old_cpio_header
|
||||
{
|
||||
unsigned short c_magic;
|
||||
short c_dev;
|
||||
unsigned short c_ino;
|
||||
unsigned short c_mode;
|
||||
unsigned short c_uid;
|
||||
unsigned short c_gid;
|
||||
unsigned short c_nlink;
|
||||
short c_rdev;
|
||||
unsigned short c_mtimes[2];
|
||||
unsigned short c_namesize;
|
||||
unsigned short c_filesizes[2];
|
||||
unsigned long c_mtime; /* Long-aligned copy of `c_mtimes'. */
|
||||
unsigned long c_filesize; /* Long-aligned copy of `c_filesizes'. */
|
||||
char *c_name;
|
||||
};
|
||||
|
||||
/* "New" portable format and CRC format:
|
||||
|
||||
Each file has a 110 byte header,
|
||||
a variable length, NUL terminated filename,
|
||||
and variable length file data.
|
||||
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
||||
|
||||
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
||||
of hexadecimal numbers, left padded, not NUL terminated.
|
||||
|
||||
Field Name Length in Bytes Notes
|
||||
c_magic 6 "070701" for "new" portable format
|
||||
"070702" for CRC format
|
||||
c_ino 8
|
||||
c_mode 8
|
||||
c_uid 8
|
||||
c_gid 8
|
||||
c_nlink 8
|
||||
c_mtime 8
|
||||
c_filesize 8 must be 0 for FIFOs and directories
|
||||
c_maj 8
|
||||
c_min 8
|
||||
c_rmaj 8 only valid for chr and blk special files
|
||||
c_rmin 8 only valid for chr and blk special files
|
||||
c_namesize 8 count includes terminating NUL in pathname
|
||||
c_chksum 8 0 for "new" portable format; for CRC format
|
||||
the sum of all the bytes in the file */
|
||||
|
||||
struct new_cpio_header
|
||||
{
|
||||
unsigned short c_magic;
|
||||
unsigned long c_ino;
|
||||
unsigned long c_mode;
|
||||
unsigned long c_uid;
|
||||
unsigned long c_gid;
|
||||
unsigned long c_nlink;
|
||||
unsigned long c_mtime;
|
||||
unsigned long c_filesize;
|
||||
long c_dev_maj;
|
||||
long c_dev_min;
|
||||
long c_rdev_maj;
|
||||
long c_rdev_min;
|
||||
unsigned long c_namesize;
|
||||
unsigned long c_chksum;
|
||||
char *c_name;
|
||||
char *c_tar_linkname;
|
||||
};
|
||||
|
||||
#endif /* cpiohdr.h */
|
42
contrib/cpio/src/defer.c
Normal file
42
contrib/cpio/src/defer.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* defer.c - handle "defered" links in newc and crc archives
|
||||
Copyright (C) 1993,2003,2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "cpiohdr.h"
|
||||
#include "extern.h"
|
||||
#include "defer.h"
|
||||
|
||||
struct deferment *
|
||||
create_deferment (struct new_cpio_header *file_hdr)
|
||||
{
|
||||
struct deferment *d;
|
||||
d = (struct deferment *) xmalloc (sizeof (struct deferment) );
|
||||
d->header = *file_hdr;
|
||||
d->header.c_name = (char *) xmalloc (strlen (file_hdr->c_name) + 1);
|
||||
strcpy (d->header.c_name, file_hdr->c_name);
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
free_deferment (struct deferment *d)
|
||||
{
|
||||
free (d->header.c_name);
|
||||
free (d);
|
||||
}
|
25
contrib/cpio/src/defer.h
Normal file
25
contrib/cpio/src/defer.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* defer.h
|
||||
Copyright (C) 1993, 2001, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
struct deferment
|
||||
{
|
||||
struct deferment *next;
|
||||
struct new_cpio_header header;
|
||||
};
|
||||
|
||||
struct deferment *create_deferment P_((struct new_cpio_header *file_hdr));
|
||||
void free_deferment P_((struct deferment *d));
|
107
contrib/cpio/src/dstring.c
Normal file
107
contrib/cpio/src/dstring.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* dstring.c - The dynamic string handling routines used by cpio.
|
||||
Copyright (C) 1990, 1991, 1992, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include "dstring.h"
|
||||
|
||||
#if __STDC__
|
||||
# define P_(s) s
|
||||
#else
|
||||
# define P_(s) ()
|
||||
#endif
|
||||
char *xmalloc P_((unsigned n));
|
||||
char *xrealloc P_((char *p, unsigned n));
|
||||
|
||||
/* Initialiaze dynamic string STRING with space for SIZE characters. */
|
||||
|
||||
void
|
||||
ds_init (dynamic_string *string, int size)
|
||||
{
|
||||
string->ds_length = size;
|
||||
string->ds_string = (char *) xmalloc (size);
|
||||
}
|
||||
|
||||
/* Expand dynamic string STRING, if necessary, to hold SIZE characters. */
|
||||
|
||||
void
|
||||
ds_resize (dynamic_string *string, int size)
|
||||
{
|
||||
if (size > string->ds_length)
|
||||
{
|
||||
string->ds_length = size;
|
||||
string->ds_string = (char *) xrealloc ((char *) string->ds_string, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dynamic string S gets a string terminated by the EOS character
|
||||
(which is removed) from file F. S will increase
|
||||
in size during the function if the string from F is longer than
|
||||
the current size of S.
|
||||
Return NULL if end of file is detected. Otherwise,
|
||||
Return a pointer to the null-terminated string in S. */
|
||||
|
||||
char *
|
||||
ds_fgetstr (FILE *f, dynamic_string *s, char eos)
|
||||
{
|
||||
int insize; /* Amount needed for line. */
|
||||
int strsize; /* Amount allocated for S. */
|
||||
int next_ch;
|
||||
|
||||
/* Initialize. */
|
||||
insize = 0;
|
||||
strsize = s->ds_length;
|
||||
|
||||
/* Read the input string. */
|
||||
next_ch = getc (f);
|
||||
while (next_ch != eos && next_ch != EOF)
|
||||
{
|
||||
if (insize >= strsize - 1)
|
||||
{
|
||||
ds_resize (s, strsize * 2 + 2);
|
||||
strsize = s->ds_length;
|
||||
}
|
||||
s->ds_string[insize++] = next_ch;
|
||||
next_ch = getc (f);
|
||||
}
|
||||
s->ds_string[insize++] = '\0';
|
||||
|
||||
if (insize == 1 && next_ch == EOF)
|
||||
return NULL;
|
||||
else
|
||||
return s->ds_string;
|
||||
}
|
||||
|
||||
char *
|
||||
ds_fgets (FILE *f, dynamic_string *s)
|
||||
{
|
||||
return ds_fgetstr (f, s, '\n');
|
||||
}
|
||||
|
||||
char *
|
||||
ds_fgetname (FILE *f, dynamic_string *s)
|
||||
{
|
||||
return ds_fgetstr (f, s, '\0');
|
||||
}
|
49
contrib/cpio/src/dstring.h
Normal file
49
contrib/cpio/src/dstring.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* dstring.h - Dynamic string handling include file. Requires strings.h.
|
||||
Copyright (C) 1990, 1991, 1992, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* A dynamic string consists of record that records the size of an
|
||||
allocated string and the pointer to that string. The actual string
|
||||
is a normal zero byte terminated string that can be used with the
|
||||
usual string functions. The major difference is that the
|
||||
dynamic_string routines know how to get more space if it is needed
|
||||
by allocating new space and copying the current string. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ds_length; /* Actual amount of storage allocated. */
|
||||
char *ds_string; /* String. */
|
||||
} dynamic_string;
|
||||
|
||||
|
||||
/* Macros that look similar to the original string functions.
|
||||
WARNING: These macros work only on pointers to dynamic string records.
|
||||
If used with a real record, an "&" must be used to get the pointer. */
|
||||
#define ds_strlen(s) strlen ((s)->ds_string)
|
||||
#define ds_strcmp(s1, s2) strcmp ((s1)->ds_string, (s2)->ds_string)
|
||||
#define ds_strncmp(s1, s2, n) strncmp ((s1)->ds_string, (s2)->ds_string, n)
|
||||
#define ds_index(s, c) index ((s)->ds_string, c)
|
||||
#define ds_rindex(s, c) rindex ((s)->ds_string, c)
|
||||
|
||||
void ds_init (dynamic_string *string, int size);
|
||||
void ds_resize (dynamic_string *string, int size);
|
||||
char *ds_fgetname (FILE *f, dynamic_string *s);
|
||||
char *ds_fgets (FILE *f, dynamic_string *s);
|
||||
char *ds_fgetstr (FILE *f, dynamic_string *s, char eos);
|
200
contrib/cpio/src/extern.h
Normal file
200
contrib/cpio/src/extern.h
Normal file
@ -0,0 +1,200 @@
|
||||
/* extern.h - External declarations for cpio. Requires system.h.
|
||||
Copyright (C) 1990, 1991, 1992, 2001 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
enum archive_format
|
||||
{
|
||||
arf_unknown, arf_binary, arf_oldascii, arf_newascii, arf_crcascii,
|
||||
arf_tar, arf_ustar, arf_hpoldascii, arf_hpbinary
|
||||
};
|
||||
extern enum archive_format archive_format;
|
||||
extern int reset_time_flag;
|
||||
extern int io_block_size;
|
||||
extern int create_dir_flag;
|
||||
extern int rename_flag;
|
||||
extern char *rename_batch_file;
|
||||
extern int table_flag;
|
||||
extern int unconditional_flag;
|
||||
extern int verbose_flag;
|
||||
extern int dot_flag;
|
||||
extern int link_flag;
|
||||
extern int retain_time_flag;
|
||||
extern int crc_i_flag;
|
||||
extern int append_flag;
|
||||
extern int swap_bytes_flag;
|
||||
extern int swap_halfwords_flag;
|
||||
extern int swapping_bytes;
|
||||
extern int swapping_halfwords;
|
||||
extern int set_owner_flag;
|
||||
extern uid_t set_owner;
|
||||
extern int set_group_flag;
|
||||
extern gid_t set_group;
|
||||
extern int no_chown_flag;
|
||||
extern int sparse_flag;
|
||||
extern int quiet_flag;
|
||||
extern int only_verify_crc_flag;
|
||||
extern int no_abs_paths_flag;
|
||||
extern unsigned int warn_option;
|
||||
|
||||
/* Values for warn_option */
|
||||
#define CPIO_WARN_NONE 0
|
||||
#define CPIO_WARN_TRUNCATE 0x01
|
||||
#define CPIO_WARN_ALL (unsigned int)-1
|
||||
|
||||
extern bool to_stdout_option;
|
||||
|
||||
extern int last_header_start;
|
||||
extern int copy_matching_files;
|
||||
extern int numeric_uid;
|
||||
extern char *pattern_file_name;
|
||||
extern char *new_media_message;
|
||||
extern char *new_media_message_with_number;
|
||||
extern char *new_media_message_after_number;
|
||||
extern int archive_des;
|
||||
extern char *archive_name;
|
||||
extern char *rsh_command_option;
|
||||
extern unsigned long crc;
|
||||
extern int delayed_seek_count;
|
||||
#ifdef DEBUG_CPIO
|
||||
extern int debug_flag;
|
||||
#endif
|
||||
|
||||
extern char *input_buffer, *output_buffer;
|
||||
extern char *in_buff, *out_buff;
|
||||
extern long input_buffer_size;
|
||||
extern long input_size, output_size;
|
||||
#ifdef __GNUC__
|
||||
extern long long input_bytes, output_bytes;
|
||||
#else
|
||||
extern long input_bytes, output_bytes;
|
||||
#endif
|
||||
extern char zeros_512[];
|
||||
extern char *directory_name;
|
||||
extern char **save_patterns;
|
||||
extern int num_patterns;
|
||||
extern char name_end;
|
||||
extern char input_is_special;
|
||||
extern char output_is_special;
|
||||
extern char input_is_seekable;
|
||||
extern char output_is_seekable;
|
||||
extern char *program_name;
|
||||
extern int (*xstat) ();
|
||||
extern void (*copy_function) ();
|
||||
|
||||
#if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
||||
# define P_(s) s
|
||||
#else
|
||||
# define P_(s) ()
|
||||
#endif
|
||||
|
||||
/* copyin.c */
|
||||
void warn_junk_bytes P_((long bytes_skipped));
|
||||
void read_in_header P_((struct new_cpio_header *file_hdr, int in_des));
|
||||
void read_in_old_ascii P_((struct new_cpio_header *file_hdr, int in_des));
|
||||
void read_in_new_ascii P_((struct new_cpio_header *file_hdr, int in_des));
|
||||
void read_in_binary P_((struct new_cpio_header *file_hdr, int in_des));
|
||||
void swab_array P_((char *arg, int count));
|
||||
void process_copy_in P_((void));
|
||||
void long_format P_((struct new_cpio_header *file_hdr, char *link_name));
|
||||
void print_name_with_quoting P_((char *p));
|
||||
|
||||
/* copyout.c */
|
||||
void write_out_header P_((struct new_cpio_header *file_hdr, int out_des));
|
||||
void process_copy_out P_((void));
|
||||
|
||||
/* copypass.c */
|
||||
void process_copy_pass P_((void));
|
||||
int link_to_maj_min_ino P_((char *file_name, int st_dev_maj,
|
||||
int st_dev_min, int st_ino));
|
||||
int link_to_name P_((char *link_name, char *link_target));
|
||||
|
||||
/* dirname.c */
|
||||
char *dirname P_((char *path));
|
||||
|
||||
/* filemode.c */
|
||||
void mode_string P_((unsigned int mode, char *str));
|
||||
|
||||
/* idcache.c */
|
||||
#ifndef __MSDOS__
|
||||
char *getgroup ();
|
||||
char *getuser ();
|
||||
uid_t *getuidbyname ();
|
||||
gid_t *getgidbyname ();
|
||||
#endif
|
||||
|
||||
/* main.c */
|
||||
void process_args P_((int argc, char *argv[]));
|
||||
void initialize_buffers P_((void));
|
||||
|
||||
/* makepath.c */
|
||||
int make_path P_((char *argpath, int mode, int parent_mode,
|
||||
uid_t owner, gid_t group, char *verbose_fmt_string));
|
||||
|
||||
/* tar.c */
|
||||
void write_out_tar_header P_((struct new_cpio_header *file_hdr, int out_des));
|
||||
int null_block P_((long *block, int size));
|
||||
void read_in_tar_header P_((struct new_cpio_header *file_hdr, int in_des));
|
||||
int otoa P_((char *s, unsigned long *n));
|
||||
int is_tar_header P_((char *buf));
|
||||
int is_tar_filename_too_long P_((char *name));
|
||||
|
||||
/* userspec.c */
|
||||
#ifndef __MSDOS__
|
||||
char *parse_user_spec P_((char *name, uid_t *uid, gid_t *gid,
|
||||
char **username, char **groupname));
|
||||
#endif
|
||||
|
||||
/* util.c */
|
||||
void tape_empty_output_buffer P_((int out_des));
|
||||
void disk_empty_output_buffer P_((int out_des));
|
||||
void swahw_array P_((char *ptr, int count));
|
||||
void tape_buffered_write P_((char *in_buf, int out_des, long num_bytes));
|
||||
void tape_buffered_read P_((char *in_buf, int in_des, long num_bytes));
|
||||
int tape_buffered_peek P_((char *peek_buf, int in_des, int num_bytes));
|
||||
void tape_toss_input P_((int in_des, long num_bytes));
|
||||
void copy_files_tape_to_disk P_((int in_des, int out_des, long num_bytes));
|
||||
void copy_files_disk_to_tape P_((int in_des, int out_des, long num_bytes, char *filename));
|
||||
void copy_files_disk_to_disk P_((int in_des, int out_des, long num_bytes, char *filename));
|
||||
void warn_if_file_changed P_((char *file_name, unsigned long old_file_size,
|
||||
unsigned long old_file_mtime));
|
||||
void create_all_directories P_((char *name));
|
||||
void prepare_append P_((int out_file_des));
|
||||
char *find_inode_file P_((unsigned long node_num,
|
||||
unsigned long major_num, unsigned long minor_num));
|
||||
void add_inode P_((unsigned long node_num, char *file_name,
|
||||
unsigned long major_num, unsigned long minor_num));
|
||||
int open_archive P_((char *file));
|
||||
void tape_offline P_((int tape_des));
|
||||
void get_next_reel P_((int tape_des));
|
||||
void set_new_media_message P_((char *message));
|
||||
#if defined(__MSDOS__) && !defined(__GNUC__)
|
||||
int chown P_((char *path, int owner, int group));
|
||||
#endif
|
||||
#ifdef __TURBOC__
|
||||
int utime P_((char *filename, struct utimbuf *utb));
|
||||
#endif
|
||||
#ifdef HPUX_CDF
|
||||
char *add_cdf_double_slashes P_((char *filename));
|
||||
#endif
|
||||
|
||||
#define DISK_IO_BLOCK_SIZE (512)
|
||||
|
||||
/* FIXME: Move to system.h? */
|
||||
#ifndef SYMLINK_USES_UMASK
|
||||
# define UMASKED_SYMLINK(name1,name2,mode) symlink(name1,name2)
|
||||
#else
|
||||
# define UMASKED_SYMLINK(name1,name2,mode) umasked_symlink(name1,name2,mode)
|
||||
#endif /* SYMLINK_USES_UMASK */
|
242
contrib/cpio/src/filemode.c
Normal file
242
contrib/cpio/src/filemode.c
Normal file
@ -0,0 +1,242 @@
|
||||
/* filemode.c -- make a string describing file modes
|
||||
Copyright (C) 1985, 1990, 1993, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !S_IRUSR
|
||||
# if S_IREAD
|
||||
# define S_IRUSR S_IREAD
|
||||
# else
|
||||
# define S_IRUSR 00400
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !S_IWUSR
|
||||
# if S_IWRITE
|
||||
# define S_IWUSR S_IWRITE
|
||||
# else
|
||||
# define S_IWUSR 00200
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !S_IXUSR
|
||||
# if S_IEXEC
|
||||
# define S_IXUSR S_IEXEC
|
||||
# else
|
||||
# define S_IXUSR 00100
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISBLK
|
||||
#undef S_ISCHR
|
||||
#undef S_ISDIR
|
||||
#undef S_ISFIFO
|
||||
#undef S_ISLNK
|
||||
#undef S_ISMPB
|
||||
#undef S_ISMPC
|
||||
#undef S_ISNWK
|
||||
#undef S_ISREG
|
||||
#undef S_ISSOCK
|
||||
#endif /* STAT_MACROS_BROKEN. */
|
||||
|
||||
#if !defined(S_ISBLK) && defined(S_IFBLK)
|
||||
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR) && defined(S_IFCHR)
|
||||
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISFIFO) && defined(S_IFIFO)
|
||||
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISLNK) && defined(S_IFLNK)
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
|
||||
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
|
||||
#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
|
||||
#endif
|
||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||
#endif
|
||||
|
||||
/* Return a character indicating the type of file described by
|
||||
file mode BITS:
|
||||
'd' for directories
|
||||
'b' for block special files
|
||||
'c' for character special files
|
||||
'm' for multiplexor files
|
||||
'l' for symbolic links
|
||||
's' for sockets
|
||||
'p' for fifos
|
||||
'-' for regular files
|
||||
'?' for any other file type. */
|
||||
|
||||
static char
|
||||
ftypelet (long bits)
|
||||
{
|
||||
#ifdef S_ISBLK
|
||||
if (S_ISBLK (bits))
|
||||
return 'b';
|
||||
#endif
|
||||
if (S_ISCHR (bits))
|
||||
return 'c';
|
||||
if (S_ISDIR (bits))
|
||||
return 'd';
|
||||
if (S_ISREG (bits))
|
||||
return '-';
|
||||
#ifdef S_ISFIFO
|
||||
if (S_ISFIFO (bits))
|
||||
return 'p';
|
||||
#endif
|
||||
#ifdef S_ISLNK
|
||||
if (S_ISLNK (bits))
|
||||
return 'l';
|
||||
#endif
|
||||
#ifdef S_ISSOCK
|
||||
if (S_ISSOCK (bits))
|
||||
return 's';
|
||||
#endif
|
||||
#ifdef S_ISMPC
|
||||
if (S_ISMPC (bits))
|
||||
return 'm';
|
||||
#endif
|
||||
#ifdef S_ISNWK
|
||||
if (S_ISNWK (bits))
|
||||
return 'n';
|
||||
#endif
|
||||
return '?';
|
||||
}
|
||||
|
||||
/* Look at read, write, and execute bits in BITS and set
|
||||
flags in CHARS accordingly. */
|
||||
|
||||
static void
|
||||
rwx (unsigned short bits, char *chars)
|
||||
{
|
||||
chars[0] = (bits & S_IRUSR) ? 'r' : '-';
|
||||
chars[1] = (bits & S_IWUSR) ? 'w' : '-';
|
||||
chars[2] = (bits & S_IXUSR) ? 'x' : '-';
|
||||
}
|
||||
|
||||
/* Set the 's' and 't' flags in file attributes string CHARS,
|
||||
according to the file mode BITS. */
|
||||
|
||||
static void
|
||||
setst (unsigned short bits, char *chars)
|
||||
{
|
||||
#ifdef S_ISUID
|
||||
if (bits & S_ISUID)
|
||||
{
|
||||
if (chars[3] != 'x')
|
||||
/* Set-uid, but not executable by owner. */
|
||||
chars[3] = 'S';
|
||||
else
|
||||
chars[3] = 's';
|
||||
}
|
||||
#endif
|
||||
#ifdef S_ISGID
|
||||
if (bits & S_ISGID)
|
||||
{
|
||||
if (chars[6] != 'x')
|
||||
/* Set-gid, but not executable by group. */
|
||||
chars[6] = 'S';
|
||||
else
|
||||
chars[6] = 's';
|
||||
}
|
||||
#endif
|
||||
#ifdef S_ISVTX
|
||||
if (bits & S_ISVTX)
|
||||
{
|
||||
if (chars[9] != 'x')
|
||||
/* Sticky, but not executable by others. */
|
||||
chars[9] = 'T';
|
||||
else
|
||||
chars[9] = 't';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Like filemodestring (see below), but only the relevant part of the
|
||||
`struct stat' is given as an argument. */
|
||||
|
||||
void
|
||||
mode_string (unsigned short mode, char *str)
|
||||
{
|
||||
str[0] = ftypelet ((long) mode);
|
||||
rwx ((mode & 0700) << 0, &str[1]);
|
||||
rwx ((mode & 0070) << 3, &str[4]);
|
||||
rwx ((mode & 0007) << 6, &str[7]);
|
||||
setst (mode, str);
|
||||
}
|
||||
|
||||
/* filemodestring - fill in string STR with an ls-style ASCII
|
||||
representation of the st_mode field of file stats block STATP.
|
||||
10 characters are stored in STR; no terminating null is added.
|
||||
The characters stored in STR are:
|
||||
|
||||
0 File type. 'd' for directory, 'c' for character
|
||||
special, 'b' for block special, 'm' for multiplex,
|
||||
'l' for symbolic link, 's' for socket, 'p' for fifo,
|
||||
'-' for regular, '?' for any other file type
|
||||
|
||||
1 'r' if the owner may read, '-' otherwise.
|
||||
|
||||
2 'w' if the owner may write, '-' otherwise.
|
||||
|
||||
3 'x' if the owner may execute, 's' if the file is
|
||||
set-user-id, '-' otherwise.
|
||||
'S' if the file is set-user-id, but the execute
|
||||
bit isn't set.
|
||||
|
||||
4 'r' if group members may read, '-' otherwise.
|
||||
|
||||
5 'w' if group members may write, '-' otherwise.
|
||||
|
||||
6 'x' if group members may execute, 's' if the file is
|
||||
set-group-id, '-' otherwise.
|
||||
'S' if it is set-group-id but not executable.
|
||||
|
||||
7 'r' if any user may read, '-' otherwise.
|
||||
|
||||
8 'w' if any user may write, '-' otherwise.
|
||||
|
||||
9 'x' if any user may execute, 't' if the file is "sticky"
|
||||
(will be retained in swap space after execution), '-'
|
||||
otherwise.
|
||||
'T' if the file is sticky but not executable. */
|
||||
|
||||
void
|
||||
filemodestring (struct stat *statp, char *str)
|
||||
{
|
||||
mode_string (statp->st_mode, str);
|
||||
}
|
||||
|
84
contrib/cpio/src/filetypes.h
Normal file
84
contrib/cpio/src/filetypes.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* filetypes.h - deal with POSIX annoyances
|
||||
Copyright (C) 1991 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Include sys/types.h and sys/stat.h before this file. */
|
||||
|
||||
#ifndef S_ISREG /* Doesn't have POSIX.1 stat stuff. */
|
||||
#define mode_t unsigned short
|
||||
#endif
|
||||
|
||||
/* Define the POSIX macros for systems that lack them. */
|
||||
#if !defined(S_ISBLK) && defined(S_IFBLK)
|
||||
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR) && defined(S_IFCHR)
|
||||
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISFIFO) && defined(S_IFIFO)
|
||||
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISLNK) && defined(S_IFLNK)
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX network special */
|
||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||
#endif
|
||||
|
||||
/* Define the file type bits used in cpio archives.
|
||||
They have the same values as the S_IF bits in traditional Unix. */
|
||||
|
||||
#define CP_IFMT 0170000 /* Mask for all file type bits. */
|
||||
|
||||
#if defined(S_ISBLK)
|
||||
#define CP_IFBLK 0060000
|
||||
#endif
|
||||
#if defined(S_ISCHR)
|
||||
#define CP_IFCHR 0020000
|
||||
#endif
|
||||
#if defined(S_ISDIR)
|
||||
#define CP_IFDIR 0040000
|
||||
#endif
|
||||
#if defined(S_ISREG)
|
||||
#define CP_IFREG 0100000
|
||||
#endif
|
||||
#if defined(S_ISFIFO)
|
||||
#define CP_IFIFO 0010000
|
||||
#endif
|
||||
#if defined(S_ISLNK)
|
||||
#define CP_IFLNK 0120000
|
||||
#endif
|
||||
#if defined(S_ISSOCK)
|
||||
#define CP_IFSOCK 0140000
|
||||
#endif
|
||||
#if defined(S_ISNWK)
|
||||
#define CP_IFNWK 0110000
|
||||
#endif
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#define lstat stat
|
||||
#endif
|
||||
int lstat ();
|
||||
int stat ();
|
203
contrib/cpio/src/global.c
Normal file
203
contrib/cpio/src/global.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* global.c - global variables and initial values for cpio.
|
||||
Copyright (C) 1990, 1991, 1992, 2001 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "cpiohdr.h"
|
||||
#include "dstring.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* If true, reset access times after reading files (-a). */
|
||||
int reset_time_flag = false;
|
||||
|
||||
/* Block size value, initially 512. -B sets to 5120. */
|
||||
int io_block_size = 512;
|
||||
|
||||
/* The header format to recognize and produce. */
|
||||
enum archive_format archive_format = arf_unknown;
|
||||
|
||||
/* If true, create directories as needed. (-d with -i or -p) */
|
||||
int create_dir_flag = false;
|
||||
|
||||
/* If true, interactively rename files. (-r) */
|
||||
int rename_flag = false;
|
||||
|
||||
/* If non-NULL, the name of a file that will be read to
|
||||
rename all of the files in the archive. --rename-batch-file. */
|
||||
char *rename_batch_file = NULL;
|
||||
|
||||
/* If true, print a table of contents of input. (-t) */
|
||||
int table_flag = false;
|
||||
|
||||
/* If true, copy unconditionally (older replaces newer). (-u) */
|
||||
int unconditional_flag = false;
|
||||
|
||||
/* If true, list the files processed, or ls -l style output with -t. (-v) */
|
||||
int verbose_flag = false;
|
||||
|
||||
/* If true, print a . for each file processed. (-V) */
|
||||
int dot_flag = false;
|
||||
|
||||
/* If true, link files whenever possible. Used with -p option. (-l) */
|
||||
int link_flag = false;
|
||||
|
||||
/* If true, retain previous file modification time. (-m) */
|
||||
int retain_time_flag = false;
|
||||
|
||||
/* Set true if crc_flag is true and we are doing a cpio -i. Used
|
||||
by copy_files so it knows whether to compute the crc. */
|
||||
int crc_i_flag = false;
|
||||
|
||||
/* If true, append to end of archive. (-A) */
|
||||
int append_flag = false;
|
||||
|
||||
/* If true, swap bytes of each file during cpio -i. */
|
||||
int swap_bytes_flag = false;
|
||||
|
||||
/* If true, swap halfwords of each file during cpio -i. */
|
||||
int swap_halfwords_flag = false;
|
||||
|
||||
/* If true, we are swapping halfwords on the current file. */
|
||||
int swapping_halfwords = false;
|
||||
|
||||
/* If true, we are swapping bytes on the current file. */
|
||||
int swapping_bytes = false;
|
||||
|
||||
/* If true, set ownership of all files to UID `set_owner'. */
|
||||
int set_owner_flag = false;
|
||||
uid_t set_owner;
|
||||
|
||||
/* If true, set group ownership of all files to GID `set_group'. */
|
||||
int set_group_flag = false;
|
||||
gid_t set_group;
|
||||
|
||||
/* If true, do not chown the files. */
|
||||
int no_chown_flag = false;
|
||||
|
||||
/* If true, try to write sparse ("holey") files. */
|
||||
int sparse_flag = false;
|
||||
|
||||
/* If true, don't report number of blocks copied. */
|
||||
int quiet_flag = false;
|
||||
|
||||
/* If true, only read the archive and verify the files' CRC's, don't
|
||||
actually extract the files. */
|
||||
int only_verify_crc_flag = false;
|
||||
|
||||
/* If true, don't use any absolute paths, prefix them by `./'. */
|
||||
int no_abs_paths_flag = false;
|
||||
|
||||
#ifdef DEBUG_CPIO
|
||||
/* If true, print debugging information. */
|
||||
int debug_flag = false;
|
||||
#endif
|
||||
|
||||
/* File position of last header read. Only used during -A to determine
|
||||
where the old TRAILER!!! record started. */
|
||||
int last_header_start = 0;
|
||||
|
||||
/* With -i; if true, copy only files that match any of the given patterns;
|
||||
if false, copy only files that do not match any of the patterns. (-f) */
|
||||
int copy_matching_files = true;
|
||||
|
||||
/* With -itv; if true, list numeric uid and gid instead of translating them
|
||||
into names. */
|
||||
int numeric_uid = false;
|
||||
|
||||
/* Name of file containing additional patterns (-E). */
|
||||
char *pattern_file_name = NULL;
|
||||
|
||||
/* Message to print when end of medium is reached (-M). */
|
||||
char *new_media_message = NULL;
|
||||
|
||||
/* With -M with %d, message to print when end of medium is reached. */
|
||||
char *new_media_message_with_number = NULL;
|
||||
char *new_media_message_after_number = NULL;
|
||||
|
||||
/* File descriptor containing the archive. */
|
||||
int archive_des;
|
||||
|
||||
/* Name of file containing the archive, if known; NULL if stdin/out. */
|
||||
char *archive_name = NULL;
|
||||
|
||||
/* Name of the remote shell command, if known; NULL otherwise. */
|
||||
char *rsh_command_option = NULL;
|
||||
|
||||
/* CRC checksum. */
|
||||
unsigned long crc;
|
||||
|
||||
/* Input and output buffers. */
|
||||
char *input_buffer, *output_buffer;
|
||||
|
||||
/* The size of the input buffer. */
|
||||
long input_buffer_size;
|
||||
|
||||
/* Current locations in `input_buffer' and `output_buffer'. */
|
||||
char *in_buff, *out_buff;
|
||||
|
||||
/* Current number of bytes stored at `input_buff' and `output_buff'. */
|
||||
long input_size, output_size;
|
||||
|
||||
/* Total number of bytes read and written for all files.
|
||||
Now that many tape drives hold more than 4Gb we need more than 32
|
||||
bits to hold input_bytes and output_bytes. But it's not worth
|
||||
the trouble of adding special multi-precision arithmetic if the
|
||||
compiler doesn't support 64 bit ints since input_bytes and
|
||||
output_bytes are only used to print the number of blocks copied. */
|
||||
#ifdef __GNUC__
|
||||
long long input_bytes, output_bytes;
|
||||
#else
|
||||
long input_bytes, output_bytes;
|
||||
#endif
|
||||
|
||||
/* 512 bytes of 0; used for various padding operations. */
|
||||
char zeros_512[512];
|
||||
|
||||
/* Saving of argument values for later reference. */
|
||||
char *directory_name = NULL;
|
||||
char **save_patterns;
|
||||
int num_patterns;
|
||||
|
||||
/* Character that terminates file names read from stdin. */
|
||||
char name_end = '\n';
|
||||
|
||||
/* true if input (cpio -i) or output (cpio -o) is a device node. */
|
||||
char input_is_special = false;
|
||||
char output_is_special = false;
|
||||
|
||||
/* true if lseek works on the input. */
|
||||
char input_is_seekable = false;
|
||||
|
||||
/* true if lseek works on the output. */
|
||||
char output_is_seekable = false;
|
||||
|
||||
/* Print extra warning messages */
|
||||
unsigned int warn_option = 0;
|
||||
|
||||
/* Extract to standard output? */
|
||||
bool to_stdout_option = false;
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
/* A pointer to either lstat or stat, depending on whether
|
||||
dereferencing of symlinks is done for input files. */
|
||||
int (*xstat) ();
|
||||
|
||||
/* Which copy operation to perform. (-i, -o, -p) */
|
||||
void (*copy_function) () = 0;
|
206
contrib/cpio/src/idcache.c
Normal file
206
contrib/cpio/src/idcache.c
Normal file
@ -0,0 +1,206 @@
|
||||
/* idcache.c -- map user and group IDs, cached for speed
|
||||
Copyright (C) 1985, 1988, 1989, 1990, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifndef _POSIX_VERSION
|
||||
struct passwd *getpwuid ();
|
||||
struct passwd *getpwnam ();
|
||||
struct group *getgrgid ();
|
||||
struct group *getgrnam ();
|
||||
#endif
|
||||
|
||||
char *xmalloc ();
|
||||
char *xstrdup ();
|
||||
|
||||
struct userid
|
||||
{
|
||||
union
|
||||
{
|
||||
uid_t u;
|
||||
gid_t g;
|
||||
} id;
|
||||
char *name;
|
||||
struct userid *next;
|
||||
};
|
||||
|
||||
static struct userid *user_alist;
|
||||
|
||||
/* The members of this list have names not in the local passwd file. */
|
||||
static struct userid *nouser_alist;
|
||||
|
||||
/* Translate UID to a login name or a stringified number,
|
||||
with cache. */
|
||||
|
||||
char *
|
||||
getuser (uid_t uid)
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct passwd *pwent;
|
||||
char usernum_string[20];
|
||||
|
||||
for (tail = user_alist; tail; tail = tail->next)
|
||||
if (tail->id.u == uid)
|
||||
return tail->name;
|
||||
|
||||
pwent = getpwuid (uid);
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->id.u = uid;
|
||||
if (pwent == 0)
|
||||
{
|
||||
sprintf (usernum_string, "%u", (unsigned) uid);
|
||||
tail->name = xstrdup (usernum_string);
|
||||
}
|
||||
else
|
||||
tail->name = xstrdup (pwent->pw_name);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
tail->next = user_alist;
|
||||
user_alist = tail;
|
||||
return tail->name;
|
||||
}
|
||||
|
||||
/* Translate USER to a UID, with cache.
|
||||
Return NULL if there is no such user.
|
||||
(We also cache which user names have no passwd entry,
|
||||
so we don't keep looking them up.) */
|
||||
|
||||
uid_t *
|
||||
getuidbyname (char *user)
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct passwd *pwent;
|
||||
|
||||
for (tail = user_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *user && !strcmp (tail->name, user))
|
||||
return &tail->id.u;
|
||||
|
||||
for (tail = nouser_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *user && !strcmp (tail->name, user))
|
||||
return 0;
|
||||
|
||||
pwent = getpwnam (user);
|
||||
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->name = xstrdup (user);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
if (pwent)
|
||||
{
|
||||
tail->id.u = pwent->pw_uid;
|
||||
tail->next = user_alist;
|
||||
user_alist = tail;
|
||||
return &tail->id.u;
|
||||
}
|
||||
|
||||
tail->next = nouser_alist;
|
||||
nouser_alist = tail;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use the same struct as for userids. */
|
||||
static struct userid *group_alist;
|
||||
static struct userid *nogroup_alist;
|
||||
|
||||
/* Translate GID to a group name or a stringified number,
|
||||
with cache. */
|
||||
|
||||
char *
|
||||
getgroup (gid_t gid)
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct group *grent;
|
||||
char groupnum_string[20];
|
||||
|
||||
for (tail = group_alist; tail; tail = tail->next)
|
||||
if (tail->id.g == gid)
|
||||
return tail->name;
|
||||
|
||||
grent = getgrgid (gid);
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->id.g = gid;
|
||||
if (grent == 0)
|
||||
{
|
||||
sprintf (groupnum_string, "%u", (unsigned int) gid);
|
||||
tail->name = xstrdup (groupnum_string);
|
||||
}
|
||||
else
|
||||
tail->name = xstrdup (grent->gr_name);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
tail->next = group_alist;
|
||||
group_alist = tail;
|
||||
return tail->name;
|
||||
}
|
||||
|
||||
/* Translate GROUP to a UID, with cache.
|
||||
Return NULL if there is no such group.
|
||||
(We also cache which group names have no group entry,
|
||||
so we don't keep looking them up.) */
|
||||
|
||||
gid_t *
|
||||
getgidbyname (char *group)
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct group *grent;
|
||||
|
||||
for (tail = group_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *group && !strcmp (tail->name, group))
|
||||
return &tail->id.g;
|
||||
|
||||
for (tail = nogroup_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *group && !strcmp (tail->name, group))
|
||||
return 0;
|
||||
|
||||
grent = getgrnam (group);
|
||||
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->name = xstrdup (group);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
if (grent)
|
||||
{
|
||||
tail->id.g = grent->gr_gid;
|
||||
tail->next = group_alist;
|
||||
group_alist = tail;
|
||||
return &tail->id.g;
|
||||
}
|
||||
|
||||
tail->next = nogroup_alist;
|
||||
nogroup_alist = tail;
|
||||
return 0;
|
||||
}
|
763
contrib/cpio/src/main.c
Normal file
763
contrib/cpio/src/main.c
Normal file
@ -0,0 +1,763 @@
|
||||
/* main.c - main program and argument processing for cpio.
|
||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by Phil Nelson <phil@cs.wwu.edu>,
|
||||
David MacKenzie <djm@gnu.ai.mit.edu>,
|
||||
John Oleynick <juo@klinzhai.rutgers.edu>,
|
||||
and Sergey Poznyakoff <gray@mirddin.farlep.net> */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <argp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
#include "filetypes.h"
|
||||
#include "cpiohdr.h"
|
||||
#include "dstring.h"
|
||||
#include "extern.h"
|
||||
#include <rmt.h>
|
||||
#include <localedir.h>
|
||||
|
||||
enum cpio_options {
|
||||
NO_ABSOLUTE_FILENAMES_OPTION=256,
|
||||
NO_PRESERVE_OWNER_OPTION,
|
||||
ONLY_VERIFY_CRC_OPTION,
|
||||
RENAME_BATCH_FILE_OPTION,
|
||||
RSH_COMMAND_OPTION,
|
||||
QUIET_OPTION,
|
||||
SPARSE_OPTION,
|
||||
FORCE_LOCAL_OPTION,
|
||||
DEBUG_OPTION,
|
||||
BLOCK_SIZE_OPTION,
|
||||
TO_STDOUT_OPTION,
|
||||
|
||||
USAGE_OPTION,
|
||||
LICENSE_OPTION,
|
||||
VERSION_OPTION
|
||||
};
|
||||
|
||||
const char *argp_program_version = "cpio (" PACKAGE_NAME ") " VERSION;
|
||||
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
|
||||
static char doc[] = N_("GNU `cpio' copies files to and from archives\n\
|
||||
\n\
|
||||
Examples:\n\
|
||||
# Copy files named in name-list to the archive\n\
|
||||
cpio -o < name-list [> archive]\n\
|
||||
# Extract files from the archive\n\
|
||||
cpio -i [< archive]\n\
|
||||
# Copy files named in name-list to destination-directory\n\
|
||||
cpio -p destination-directory < name-list\n");
|
||||
|
||||
/* Print usage error message and exit with error. */
|
||||
|
||||
#define USAGE_ERROR(args) do { error args; exit(2); } while (0)
|
||||
#define CHECK_USAGE(cond, opt, mode_opt) \
|
||||
if (cond) USAGE_ERROR((0, 0, _("%s is meaningless with %s"), opt, mode_opt));
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Main operation mode:"), 10},
|
||||
{"create", 'o', 0, 0,
|
||||
N_("Create the archive (run in copy-out mode)"), 10},
|
||||
{"extract", 'i', 0, 0,
|
||||
N_("Extract files from an archive (run in copy-in mode)")},
|
||||
{"pass-through", 'p', 0, 0,
|
||||
N_("Run in copy-pass mode"), 10},
|
||||
{"list", 't', 0, 0,
|
||||
N_("Print a table of contents of the input"), 10},
|
||||
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid in any mode:"), 100},
|
||||
|
||||
{"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||
N_("Use this FILE-NAME instead of standard input or output. Optional USER and HOST specify the user and host names in case of a remote archive"), 110},
|
||||
{"force-local", FORCE_LOCAL_OPTION, 0, 0,
|
||||
N_("Archive file is local, even if its name contains colons"), 110},
|
||||
{"format", 'H', N_("FORMAT"), 0,
|
||||
N_("Use given archive FORMAT"), 110},
|
||||
{NULL, 'B', NULL, 0,
|
||||
N_("Set the I/O block size to 5120 bytes"), 110},
|
||||
{"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0,
|
||||
N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), 110},
|
||||
{NULL, 'c', NULL, 0,
|
||||
N_("Use the old portable (ASCII) archive format"), 0},
|
||||
{"dot", 'V', NULL, 0,
|
||||
N_("Print a \".\" for each file processed"), 110},
|
||||
{"io-size", 'C', N_("NUMBER"), 0,
|
||||
N_("Set the I/O block size to the given NUMBER of bytes"), 110},
|
||||
{"message", 'M', N_("STRING"), 0,
|
||||
N_("Print STRING when the end of a volume of the backup media is reached"),
|
||||
110},
|
||||
{"nonmatching", 'f', 0, 0,
|
||||
N_("Only copy files that do not match any of the given patterns"), 110},
|
||||
{"numeric-uid-gid", 'n', 0, 0,
|
||||
N_("In the verbose table of contents listing, show numeric UID and GID"),
|
||||
110},
|
||||
{"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
|
||||
N_("Use remote COMMAND instead of rsh"), 110},
|
||||
{"quiet", QUIET_OPTION, NULL, 0,
|
||||
N_("Do not print the number of blocks copied"), 110},
|
||||
{"verbose", 'v', NULL, 0,
|
||||
N_("Verbosely list the files processed"), 110},
|
||||
#ifdef DEBUG_CPIO
|
||||
{"debug", DEBUG_OPTION, NULL, 0,
|
||||
N_("Enable debugging info"), 110},
|
||||
#endif
|
||||
{"warning", 'W', N_("FLAG"), 0,
|
||||
N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), 110 },
|
||||
|
||||
/* ********** */
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid only in copy-in mode:"), 200},
|
||||
{"pattern-file", 'E', N_("FILE"), 0,
|
||||
N_("In copy-in mode, read additional patterns specifying filenames to extract or list from FILE"), 210},
|
||||
{"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
|
||||
N_("Create all files relative to the current directory"), 210},
|
||||
{"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
|
||||
N_("When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
|
||||
{"rename", 'r', 0, 0,
|
||||
N_("Interactively rename files"), 210},
|
||||
{"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN,
|
||||
"", 210},
|
||||
{"swap", 'b', NULL, 0,
|
||||
N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), 210},
|
||||
{"swap-bytes", 's', NULL, 0,
|
||||
N_("Swap the bytes of each halfword in the files"), 210},
|
||||
{"swap-halfwords", 'S', NULL, 0,
|
||||
N_("Swap the halfwords of each word (4 bytes) in the files"),
|
||||
210},
|
||||
{"to-stdout", TO_STDOUT_OPTION, NULL, 0,
|
||||
N_("Extract files to standard output"), 210},
|
||||
|
||||
/* ********** */
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid only in copy-out mode:"), 300},
|
||||
{"append", 'A', 0, 0,
|
||||
N_("Append to an existing archive."), 310 },
|
||||
{NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||
N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), 310},
|
||||
|
||||
/* ********** */
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid only in copy-pass mode:"), 400},
|
||||
{"link", 'l', 0, 0,
|
||||
N_("Link files instead of copying them, when possible"), 410},
|
||||
|
||||
/* ********** */
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid for copy-out and copy-pass modes:"), 500},
|
||||
{"null", '0', 0, 0,
|
||||
N_("A list of filenames is terminated by a null character instead of a newline"), 510 },
|
||||
{NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||
N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), 510},
|
||||
{"dereference", 'L', 0, 0,
|
||||
N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), 510},
|
||||
{"owner", 'R', N_("[USER][:.][GROUP]"), 0,
|
||||
N_("Set the ownership of all files created to the specified USER and/or GROUP"), 510},
|
||||
{"sparse", SPARSE_OPTION, NULL, 0,
|
||||
N_("Write files with large blocks of zeros as sparse files"), 510},
|
||||
{"reset-access-time", 'a', NULL, 0,
|
||||
N_("Reset the access times of files after reading them"), 510},
|
||||
|
||||
/* ********** */
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Operation modifiers valid for copy-in and copy-pass modes:"), 600},
|
||||
{"preserve-modification-time", 'm', 0, 0,
|
||||
N_("Retain previous file modification times when creating files"), 610},
|
||||
{"make-directories", 'd', 0, 0,
|
||||
N_("Create leading directories where needed"), 610},
|
||||
{"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
|
||||
N_("Do not change the ownership of the files"), 610},
|
||||
{"unconditional", 'u', NULL, 0,
|
||||
N_("Replace all files unconditionally"), 610},
|
||||
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Informative options:"), 700 },
|
||||
|
||||
{"help", '?', 0, 0, N_("Give this help list"), -1},
|
||||
{"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
|
||||
{"license", LICENSE_OPTION, 0, 0, N_("Print license and exit"), -1},
|
||||
{"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
|
||||
/* FIXME -V (--dot) conflicts with the default short option for
|
||||
--version */
|
||||
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static char *input_archive_name = 0;
|
||||
static char *output_archive_name = 0;
|
||||
|
||||
static void
|
||||
license ()
|
||||
{
|
||||
printf ("%s (%s) %s\n%s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION,
|
||||
"Copyright (C) 2004 Free Software Foundation, Inc.\n");
|
||||
printf (_(" GNU cpio is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
" (at your option) any later version.\n"
|
||||
"\n"
|
||||
" GNU cpio is distributed in the hope that it will be useful,\n"
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
" GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
" You should have received a copy of the GNU General Public License\n"
|
||||
" along with GNU cpio; if not, write to the Free Software\n"
|
||||
" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"));
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static int
|
||||
warn_control (char *arg)
|
||||
{
|
||||
static struct warn_tab {
|
||||
char *name;
|
||||
int flag;
|
||||
} warn_tab[] = {
|
||||
{ "none", CPIO_WARN_ALL },
|
||||
{ "truncate", CPIO_WARN_TRUNCATE },
|
||||
{ "all", CPIO_WARN_ALL },
|
||||
{ NULL }
|
||||
};
|
||||
struct warn_tab *wt;
|
||||
int offset = 0;
|
||||
|
||||
if (strcmp (arg, "none") == 0)
|
||||
{
|
||||
warn_option = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strlen (arg) > 2 && memcmp (arg, "no-", 3) == 0)
|
||||
offset = 3;
|
||||
|
||||
for (wt = warn_tab; wt->name; wt++)
|
||||
if (strcmp (arg + offset, wt->name) == 0)
|
||||
{
|
||||
if (offset)
|
||||
warn_option &= ~wt->flag;
|
||||
else
|
||||
warn_option |= wt->flag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static error_t
|
||||
parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '0': /* Read null-terminated filenames. */
|
||||
name_end = '\0';
|
||||
break;
|
||||
|
||||
case 'a': /* Reset access times. */
|
||||
reset_time_flag = true;
|
||||
break;
|
||||
|
||||
case 'A': /* Append to the archive. */
|
||||
append_flag = true;
|
||||
break;
|
||||
|
||||
case 'b': /* Swap bytes and halfwords. */
|
||||
swap_bytes_flag = true;
|
||||
swap_halfwords_flag = true;
|
||||
break;
|
||||
|
||||
case 'B': /* Set block size to 5120. */
|
||||
io_block_size = 5120;
|
||||
break;
|
||||
|
||||
case BLOCK_SIZE_OPTION: /* --block-size */
|
||||
io_block_size = atoi (arg);
|
||||
if (io_block_size < 1)
|
||||
error (2, 0, _("invalid block size"));
|
||||
io_block_size *= 512;
|
||||
break;
|
||||
|
||||
case 'c': /* Use the old portable ASCII format. */
|
||||
if (archive_format != arf_unknown)
|
||||
USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
|
||||
#ifdef SVR4_COMPAT
|
||||
archive_format = arf_newascii; /* -H newc. */
|
||||
#else
|
||||
archive_format = arf_oldascii; /* -H odc. */
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'C': /* Block size. */
|
||||
io_block_size = atoi (arg);
|
||||
if (io_block_size < 1)
|
||||
error (2, 0, _("invalid block size"));
|
||||
break;
|
||||
|
||||
case 'd': /* Create directories where needed. */
|
||||
create_dir_flag = true;
|
||||
break;
|
||||
|
||||
case 'f': /* Only copy files not matching patterns. */
|
||||
copy_matching_files = false;
|
||||
break;
|
||||
|
||||
case 'E': /* Pattern file name. */
|
||||
pattern_file_name = arg;
|
||||
break;
|
||||
|
||||
case 'F': /* Archive file name. */
|
||||
archive_name = arg;
|
||||
break;
|
||||
|
||||
case 'H': /* Header format name. */
|
||||
if (archive_format != arf_unknown)
|
||||
USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
|
||||
if (!strcasecmp (arg, "crc"))
|
||||
archive_format = arf_crcascii;
|
||||
else if (!strcasecmp (arg, "newc"))
|
||||
archive_format = arf_newascii;
|
||||
else if (!strcasecmp (arg, "odc"))
|
||||
archive_format = arf_oldascii;
|
||||
else if (!strcasecmp (arg, "bin"))
|
||||
archive_format = arf_binary;
|
||||
else if (!strcasecmp (arg, "ustar"))
|
||||
archive_format = arf_ustar;
|
||||
else if (!strcasecmp (arg, "tar"))
|
||||
archive_format = arf_tar;
|
||||
else if (!strcasecmp (arg, "hpodc"))
|
||||
archive_format = arf_hpoldascii;
|
||||
else if (!strcasecmp (arg, "hpbin"))
|
||||
archive_format = arf_hpbinary;
|
||||
else
|
||||
error (2, 0, _("\
|
||||
invalid archive format `%s'; valid formats are:\n\
|
||||
crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
||||
break;
|
||||
|
||||
case 'i': /* Copy-in mode. */
|
||||
if (copy_function != 0)
|
||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
||||
copy_function = process_copy_in;
|
||||
break;
|
||||
|
||||
case 'I': /* Input archive file name. */
|
||||
input_archive_name = arg;
|
||||
break;
|
||||
|
||||
case 'k': /* Handle corrupted archives. We always handle
|
||||
corrupted archives, but recognize this
|
||||
option for compatability. */
|
||||
break;
|
||||
|
||||
case 'l': /* Link files when possible. */
|
||||
link_flag = true;
|
||||
break;
|
||||
|
||||
case 'L': /* Dereference symbolic links. */
|
||||
xstat = stat;
|
||||
break;
|
||||
|
||||
case 'm': /* Retain previous file modify times. */
|
||||
retain_time_flag = true;
|
||||
break;
|
||||
|
||||
case 'M': /* New media message. */
|
||||
set_new_media_message (arg);
|
||||
break;
|
||||
|
||||
case 'n': /* Long list owner and group as numbers. */
|
||||
numeric_uid = true;
|
||||
break;
|
||||
|
||||
case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
|
||||
no_abs_paths_flag = true;
|
||||
break;
|
||||
|
||||
case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
|
||||
if (set_owner_flag || set_group_flag)
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("--no-preserve-owner cannot be used with --owner")));
|
||||
no_chown_flag = true;
|
||||
break;
|
||||
|
||||
case 'o': /* Copy-out mode. */
|
||||
if (copy_function != 0)
|
||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
||||
copy_function = process_copy_out;
|
||||
break;
|
||||
|
||||
case 'O': /* Output archive file name. */
|
||||
output_archive_name = arg;
|
||||
break;
|
||||
|
||||
case ONLY_VERIFY_CRC_OPTION:
|
||||
only_verify_crc_flag = true;
|
||||
break;
|
||||
|
||||
case 'p': /* Copy-pass mode. */
|
||||
if (copy_function != 0)
|
||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
||||
copy_function = process_copy_pass;
|
||||
break;
|
||||
|
||||
case RSH_COMMAND_OPTION:
|
||||
rsh_command_option = arg;
|
||||
break;
|
||||
|
||||
case 'r': /* Interactively rename. */
|
||||
rename_flag = true;
|
||||
break;
|
||||
|
||||
case RENAME_BATCH_FILE_OPTION:
|
||||
rename_batch_file = arg;
|
||||
break;
|
||||
|
||||
case QUIET_OPTION:
|
||||
quiet_flag = true;
|
||||
break;
|
||||
|
||||
case 'R': /* Set the owner. */
|
||||
if (no_chown_flag)
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("--owner cannot be used with --no-preserve-owner")));
|
||||
{
|
||||
char *e, *u, *g;
|
||||
|
||||
e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
|
||||
if (e)
|
||||
error (2, 0, "%s: %s", arg, e);
|
||||
if (u)
|
||||
{
|
||||
free (u);
|
||||
set_owner_flag = true;
|
||||
}
|
||||
if (g)
|
||||
{
|
||||
free (g);
|
||||
set_group_flag = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 's': /* Swap bytes. */
|
||||
swap_bytes_flag = true;
|
||||
break;
|
||||
|
||||
case 'S': /* Swap halfwords. */
|
||||
swap_halfwords_flag = true;
|
||||
break;
|
||||
|
||||
case 't': /* Only print a list. */
|
||||
table_flag = true;
|
||||
break;
|
||||
|
||||
case 'u': /* Replace all! Unconditionally! */
|
||||
unconditional_flag = true;
|
||||
break;
|
||||
|
||||
case 'v': /* Verbose! */
|
||||
verbose_flag = true;
|
||||
break;
|
||||
|
||||
case 'V': /* Print `.' for each file. */
|
||||
dot_flag = true;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
if (warn_control (arg))
|
||||
argp_error (state, _("Invalid value for --warning option: %s"), arg);
|
||||
break;
|
||||
|
||||
case SPARSE_OPTION:
|
||||
sparse_flag = true;
|
||||
break;
|
||||
|
||||
case FORCE_LOCAL_OPTION:
|
||||
force_local_option = 1;
|
||||
break;
|
||||
|
||||
#ifdef DEBUG_CPIO
|
||||
case DEBUG_OPTION:
|
||||
debug_flag = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TO_STDOUT_OPTION:
|
||||
to_stdout_option = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
|
||||
break;
|
||||
|
||||
case USAGE_OPTION:
|
||||
argp_state_help (state, state->out_stream,
|
||||
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
||||
break;
|
||||
|
||||
case VERSION_OPTION:
|
||||
fprintf (state->out_stream, "%s\n", argp_program_version);
|
||||
exit (0);
|
||||
|
||||
case LICENSE_OPTION:
|
||||
license ();
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp argp = {
|
||||
options,
|
||||
parse_opt,
|
||||
N_("[destination-directory]"),
|
||||
doc,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Process the arguments. Set all options and set up the copy pass
|
||||
directory or the copy in patterns. */
|
||||
|
||||
void
|
||||
process_args (int argc, char *argv[])
|
||||
{
|
||||
void (*copy_in) (); /* Work around for pcc bug. */
|
||||
void (*copy_out) ();
|
||||
int index;
|
||||
|
||||
if (argc < 2)
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
||||
program_name, program_name));
|
||||
|
||||
xstat = lstat;
|
||||
|
||||
if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, &index, NULL))
|
||||
exit (1);
|
||||
|
||||
/* Do error checking and look at other args. */
|
||||
|
||||
if (copy_function == 0)
|
||||
{
|
||||
if (table_flag)
|
||||
copy_function = process_copy_in;
|
||||
else
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
||||
program_name, program_name));
|
||||
}
|
||||
|
||||
/* Work around for pcc bug. */
|
||||
copy_in = process_copy_in;
|
||||
copy_out = process_copy_out;
|
||||
|
||||
if (copy_function == copy_in)
|
||||
{
|
||||
archive_des = 0;
|
||||
CHECK_USAGE(link_flag, "--link", "--extract");
|
||||
CHECK_USAGE(reset_time_flag, "--reset", "--extract");
|
||||
CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
|
||||
CHECK_USAGE(append_flag, "--append", "--extract");
|
||||
CHECK_USAGE(sparse_flag, "--sparse", "--extract");
|
||||
CHECK_USAGE(output_archive_name, "-O", "--extract");
|
||||
if (to_stdout_option)
|
||||
{
|
||||
CHECK_USAGE(create_dir_flag, "--make-directories", "--to-stdout");
|
||||
CHECK_USAGE(rename_flag, "--rename", "--to-stdout");
|
||||
CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--to-stdout");
|
||||
CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--to-stdout");
|
||||
CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
|
||||
"--to-stdout");
|
||||
}
|
||||
|
||||
if (archive_name && input_archive_name)
|
||||
USAGE_ERROR((0, 0, _("Both -I and -F are used in copy-in mode")));
|
||||
|
||||
if (archive_format == arf_crcascii)
|
||||
crc_i_flag = true;
|
||||
num_patterns = argc - index;
|
||||
save_patterns = &argv[index];
|
||||
if (input_archive_name)
|
||||
archive_name = input_archive_name;
|
||||
}
|
||||
else if (copy_function == copy_out)
|
||||
{
|
||||
if (index != argc)
|
||||
USAGE_ERROR ((0, 0, _("Too many arguments")));
|
||||
|
||||
archive_des = 1;
|
||||
CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
|
||||
CHECK_USAGE(rename_flag, "--rename", "--create");
|
||||
CHECK_USAGE(table_flag, "--list", "--create");
|
||||
CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
|
||||
CHECK_USAGE(link_flag, "--link", "--create");
|
||||
CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
|
||||
"--create");
|
||||
CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
|
||||
CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--create");
|
||||
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
|
||||
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
||||
"--create");
|
||||
CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
|
||||
|
||||
if (append_flag && !(archive_name || output_archive_name))
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("--append is used but no archive file name is given (use -F or -O options")));
|
||||
|
||||
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
|
||||
CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", "--create");
|
||||
CHECK_USAGE(input_archive_name, "-I", "--create");
|
||||
if (archive_name && output_archive_name)
|
||||
USAGE_ERROR ((0, 0, _("Both -O and -F are used in copy-out mode")));
|
||||
|
||||
if (archive_format == arf_unknown)
|
||||
archive_format = arf_binary;
|
||||
if (output_archive_name)
|
||||
archive_name = output_archive_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy pass. */
|
||||
if (index != argc - 1)
|
||||
USAGE_ERROR ((0, 0, _("Too many arguments")));
|
||||
|
||||
if (archive_format != arf_unknown)
|
||||
USAGE_ERROR((0, 0,
|
||||
_("Archive format is not specified in copy-pass mode (use --format option)")));
|
||||
|
||||
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
|
||||
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
||||
"--pass-through");
|
||||
CHECK_USAGE(table_flag, "--list", "--pass-through");
|
||||
CHECK_USAGE(rename_flag, "--rename", "--pass-through");
|
||||
CHECK_USAGE(append_flag, "--append", "--pass-through");
|
||||
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
|
||||
CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
|
||||
"--pass-through");
|
||||
CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
|
||||
|
||||
directory_name = argv[index];
|
||||
}
|
||||
|
||||
if (archive_name)
|
||||
{
|
||||
if (copy_function != copy_in && copy_function != copy_out)
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("-F can be used only with --create or --extract")));
|
||||
archive_des = open_archive (archive_name);
|
||||
if (archive_des < 0)
|
||||
error (1, errno, "%s", archive_name);
|
||||
}
|
||||
|
||||
/* Prevent SysV non-root users from giving away files inadvertantly.
|
||||
This happens automatically on BSD, where only root can give
|
||||
away files. */
|
||||
if (set_owner_flag == false && set_group_flag == false && geteuid ())
|
||||
no_chown_flag = true;
|
||||
}
|
||||
|
||||
/* Initialize the input and output buffers to their proper size and
|
||||
initialize all variables associated with the input and output
|
||||
buffers. */
|
||||
|
||||
void
|
||||
initialize_buffers ()
|
||||
{
|
||||
int in_buf_size, out_buf_size;
|
||||
|
||||
if (copy_function == process_copy_in)
|
||||
{
|
||||
/* Make sure the input buffer can always hold 2 blocks and that it
|
||||
is big enough to hold 1 tar record (512 bytes) even if it
|
||||
is not aligned on a block boundary. The extra buffer space
|
||||
is needed by process_copyin and peek_in_buf to automatically
|
||||
figure out what kind of archive it is reading. */
|
||||
if (io_block_size >= 512)
|
||||
in_buf_size = 2 * io_block_size;
|
||||
else
|
||||
in_buf_size = 1024;
|
||||
out_buf_size = DISK_IO_BLOCK_SIZE;
|
||||
}
|
||||
else if (copy_function == process_copy_out)
|
||||
{
|
||||
in_buf_size = DISK_IO_BLOCK_SIZE;
|
||||
out_buf_size = io_block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_buf_size = DISK_IO_BLOCK_SIZE;
|
||||
out_buf_size = DISK_IO_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
input_buffer = (char *) xmalloc (in_buf_size);
|
||||
in_buff = input_buffer;
|
||||
input_buffer_size = in_buf_size;
|
||||
input_size = 0;
|
||||
input_bytes = 0;
|
||||
|
||||
output_buffer = (char *) xmalloc (out_buf_size);
|
||||
out_buff = output_buffer;
|
||||
output_size = 0;
|
||||
output_bytes = 0;
|
||||
|
||||
/* Clear the block of zeros. */
|
||||
bzero (zeros_512, 512);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef HAVE_LOCALE_H
|
||||
setlocale (LC_ALL, "");
|
||||
#endif
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
program_name = argv[0];
|
||||
umask (0);
|
||||
|
||||
#ifdef __TURBOC__
|
||||
_fmode = O_BINARY; /* Put stdin and stdout in binary mode. */
|
||||
#endif
|
||||
#ifdef __EMX__ /* gcc on OS/2. */
|
||||
_response (&argc, &argv);
|
||||
_wildcard (&argc, &argv);
|
||||
#endif
|
||||
|
||||
process_args (argc, argv);
|
||||
|
||||
initialize_buffers ();
|
||||
|
||||
(*copy_function) ();
|
||||
|
||||
if (archive_des >= 0 && rmtclose (archive_des) == -1)
|
||||
error (1, errno, _("error closing archive"));
|
||||
|
||||
exit (0);
|
||||
}
|
301
contrib/cpio/src/makepath.c
Normal file
301
contrib/cpio/src/makepath.c
Normal file
@ -0,0 +1,301 @@
|
||||
/* makepath.c -- Ensure that a directory path exists.
|
||||
Copyright (C) 1990 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
|
||||
Jim Meyering <meyering@cs.utexas.edu>. */
|
||||
|
||||
/* This copy of makepath is almost like the fileutils one, but has
|
||||
changes for HPUX CDF's. Maybe the 2 versions of makepath can
|
||||
come together again in the future. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#else
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#ifndef index
|
||||
#define index strchr
|
||||
#endif
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
/* Ensure that the directory ARGPATH exists.
|
||||
Remove any trailing slashes from ARGPATH before calling this function.
|
||||
|
||||
Make any leading directories that don't already exist, with
|
||||
permissions PARENT_MODE.
|
||||
If the last element of ARGPATH does not exist, create it as
|
||||
a new directory with permissions MODE.
|
||||
If OWNER and GROUP are non-negative, make them the UID and GID of
|
||||
created directories.
|
||||
If VERBOSE_FMT_STRING is nonzero, use it as a printf format
|
||||
string for printing a message after successfully making a directory,
|
||||
with the name of the directory that was just made as an argument.
|
||||
|
||||
Return 0 if ARGPATH exists as a directory with the proper
|
||||
ownership and permissions when done, otherwise 1. */
|
||||
|
||||
int
|
||||
make_path (char *argpath,
|
||||
int mode,
|
||||
int parent_mode,
|
||||
uid_t owner,
|
||||
gid_t group,
|
||||
char *verbose_fmt_string)
|
||||
{
|
||||
char *dirpath; /* A copy we can scribble NULs on. */
|
||||
struct stat stats;
|
||||
int retval = 0;
|
||||
int oldmask = umask (0);
|
||||
dirpath = alloca (strlen (argpath) + 1);
|
||||
strcpy (dirpath, argpath);
|
||||
|
||||
if (stat (dirpath, &stats))
|
||||
{
|
||||
char *slash;
|
||||
int tmp_mode; /* Initial perms for leading dirs. */
|
||||
int re_protect; /* Should leading dirs be unwritable? */
|
||||
struct ptr_list
|
||||
{
|
||||
char *dirname_end;
|
||||
struct ptr_list *next;
|
||||
};
|
||||
struct ptr_list *p, *leading_dirs = NULL;
|
||||
|
||||
/* If leading directories shouldn't be writable or executable,
|
||||
or should have set[ug]id or sticky bits set and we are setting
|
||||
their owners, we need to fix their permissions after making them. */
|
||||
if (((parent_mode & 0300) != 0300)
|
||||
|| (owner != (uid_t) -1 && group != (gid_t) -1
|
||||
&& (parent_mode & 07000) != 0))
|
||||
{
|
||||
tmp_mode = 0700;
|
||||
re_protect = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_mode = parent_mode;
|
||||
re_protect = 0;
|
||||
}
|
||||
|
||||
slash = dirpath;
|
||||
while (*slash == '/')
|
||||
slash++;
|
||||
while ((slash = index (slash, '/')))
|
||||
{
|
||||
#ifdef HPUX_CDF
|
||||
int iscdf;
|
||||
iscdf = 0;
|
||||
#endif
|
||||
*slash = '\0';
|
||||
if (stat (dirpath, &stats))
|
||||
{
|
||||
#ifdef HPUX_CDF
|
||||
/* If this component of the pathname ends in `+' and is
|
||||
followed by 2 `/'s, then this is a CDF. We remove the
|
||||
`+' from the name and create the directory. Later
|
||||
we will "hide" the directory. */
|
||||
if ( (*(slash +1) == '/') && (*(slash -1) == '+') )
|
||||
{
|
||||
iscdf = 1;
|
||||
*(slash -1) = '\0';
|
||||
}
|
||||
#endif
|
||||
if (mkdir (dirpath, tmp_mode))
|
||||
{
|
||||
error (0, errno, _("cannot make directory `%s'"), dirpath);
|
||||
umask (oldmask);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose_fmt_string != NULL)
|
||||
error (0, 0, verbose_fmt_string, dirpath);
|
||||
|
||||
if (owner != (uid_t) -1 && group != (gid_t) -1
|
||||
&& chown (dirpath, owner, group)
|
||||
#ifdef AFS
|
||||
&& errno != EPERM
|
||||
#endif
|
||||
)
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
if (re_protect)
|
||||
{
|
||||
struct ptr_list *new = (struct ptr_list *)
|
||||
alloca (sizeof (struct ptr_list));
|
||||
new->dirname_end = slash;
|
||||
new->next = leading_dirs;
|
||||
leading_dirs = new;
|
||||
}
|
||||
#ifdef HPUX_CDF
|
||||
if (iscdf)
|
||||
{
|
||||
/* If this is a CDF, "hide" the directory by setting
|
||||
its hidden/setuid bit. Also add the `+' back to
|
||||
its name (since once it's "hidden" we must refer
|
||||
to as `name+' instead of `name'). */
|
||||
chmod (dirpath, 04700);
|
||||
*(slash - 1) = '+';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (!S_ISDIR (stats.st_mode))
|
||||
{
|
||||
error (0, 0, _("`%s' exists but is not a directory"), dirpath);
|
||||
umask (oldmask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*slash++ = '/';
|
||||
|
||||
/* Avoid unnecessary calls to `stat' when given
|
||||
pathnames containing multiple adjacent slashes. */
|
||||
while (*slash == '/')
|
||||
slash++;
|
||||
}
|
||||
|
||||
/* We're done making leading directories.
|
||||
Make the final component of the path. */
|
||||
|
||||
if (mkdir (dirpath, mode))
|
||||
{
|
||||
/* In some cases, if the final component in dirpath was `.' then we
|
||||
just got an EEXIST error from that last mkdir(). If that's
|
||||
the case, ignore it. */
|
||||
if ( (errno != EEXIST) ||
|
||||
(stat (dirpath, &stats) != 0) ||
|
||||
(!S_ISDIR (stats.st_mode) ) )
|
||||
{
|
||||
error (0, errno, _("cannot make directory `%s'"), dirpath);
|
||||
umask (oldmask);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (verbose_fmt_string != NULL)
|
||||
error (0, 0, verbose_fmt_string, dirpath);
|
||||
|
||||
if (owner != (uid_t) -1 && group != (gid_t) -1)
|
||||
{
|
||||
if (chown (dirpath, owner, group)
|
||||
#ifdef AFS
|
||||
&& errno != EPERM
|
||||
#endif
|
||||
)
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
/* chown may have turned off some permission bits we wanted. */
|
||||
if ((mode & 07000) != 0 && chmod (dirpath, mode))
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
/* If the mode for leading directories didn't include owner "wx"
|
||||
privileges, we have to reset their protections to the correct
|
||||
value. */
|
||||
for (p = leading_dirs; p != NULL; p = p->next)
|
||||
{
|
||||
*(p->dirname_end) = '\0';
|
||||
#if 0
|
||||
/* cpio always calls make_path with parent mode 0700, so
|
||||
we don't have to do this. If we ever do have to do this,
|
||||
we have to stat the directory first to get the setuid
|
||||
bit so we don't break HP CDF's. */
|
||||
if (chmod (dirpath, parent_mode))
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We get here if the entire path already exists. */
|
||||
|
||||
if (!S_ISDIR (stats.st_mode))
|
||||
{
|
||||
error (0, 0, _("`%s' exists but is not a directory"), dirpath);
|
||||
umask (oldmask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* chown must precede chmod because on some systems,
|
||||
chown clears the set[ug]id bits for non-superusers,
|
||||
resulting in incorrect permissions.
|
||||
On System V, users can give away files with chown and then not
|
||||
be able to chmod them. So don't give files away. */
|
||||
|
||||
if (owner != (uid_t) -1 && group != (gid_t) -1
|
||||
&& chown (dirpath, owner, group)
|
||||
#ifdef AFS
|
||||
&& errno != EPERM
|
||||
#endif
|
||||
)
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
if (chmod (dirpath, mode))
|
||||
{
|
||||
error (0, errno, "%s", dirpath);
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
umask (oldmask);
|
||||
return retval;
|
||||
}
|
1
contrib/cpio/src/safe-stat.h
Normal file
1
contrib/cpio/src/safe-stat.h
Normal file
@ -0,0 +1 @@
|
||||
#define SAFE_STAT(path,pbuf) stat(path,pbuf)
|
500
contrib/cpio/src/tar.c
Normal file
500
contrib/cpio/src/tar.c
Normal file
@ -0,0 +1,500 @@
|
||||
/* tar.c - read in write tar headers for cpio
|
||||
Copyright (C) 1992, 2001, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "filetypes.h"
|
||||
#include "cpiohdr.h"
|
||||
#include "dstring.h"
|
||||
#include "extern.h"
|
||||
#include <rmt.h>
|
||||
#include "tarhdr.h"
|
||||
|
||||
/* Stash the tar linkname in static storage. */
|
||||
|
||||
static char *
|
||||
stash_tar_linkname (char *linkname)
|
||||
{
|
||||
static char hold_tar_linkname[TARLINKNAMESIZE + 1];
|
||||
|
||||
strncpy (hold_tar_linkname, linkname, TARLINKNAMESIZE);
|
||||
hold_tar_linkname[TARLINKNAMESIZE] = '\0';
|
||||
return hold_tar_linkname;
|
||||
}
|
||||
|
||||
/* Try to split a long file name into prefix and suffix parts separated
|
||||
by a slash. Return the length of the prefix (not counting the slash). */
|
||||
|
||||
static size_t
|
||||
split_long_name (const char *name, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (length > TARPREFIXSIZE)
|
||||
length = TARPREFIXSIZE+2;
|
||||
for (i = length - 1; i > 0; i--)
|
||||
if (name[i] == '/')
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Stash the tar filename and optional prefix in static storage. */
|
||||
|
||||
static char *
|
||||
stash_tar_filename (char *prefix, char *filename)
|
||||
{
|
||||
static char hold_tar_filename[TARNAMESIZE + TARPREFIXSIZE + 2];
|
||||
if (prefix == NULL || *prefix == '\0')
|
||||
{
|
||||
strncpy (hold_tar_filename, filename, TARNAMESIZE);
|
||||
hold_tar_filename[TARNAMESIZE] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy (hold_tar_filename, prefix, TARPREFIXSIZE);
|
||||
hold_tar_filename[TARPREFIXSIZE] = '\0';
|
||||
strcat (hold_tar_filename, "/");
|
||||
strncat (hold_tar_filename, filename, TARNAMESIZE);
|
||||
hold_tar_filename[TARPREFIXSIZE + TARNAMESIZE] = '\0';
|
||||
}
|
||||
return hold_tar_filename;
|
||||
}
|
||||
|
||||
/* Convert a number into a string of octal digits.
|
||||
Convert long VALUE into a DIGITS-digit field at WHERE,
|
||||
including a trailing space and room for a NUL. DIGITS==3 means
|
||||
1 digit, a space, and room for a NUL.
|
||||
|
||||
We assume the trailing NUL is already there and don't fill it in.
|
||||
This fact is used by start_header and finish_header, so don't change it!
|
||||
|
||||
This is be equivalent to:
|
||||
sprintf (where, "%*lo ", digits - 2, value);
|
||||
except that sprintf fills in the trailing NUL and we don't. */
|
||||
|
||||
static void
|
||||
to_oct (register long value, register int digits, register char *where)
|
||||
{
|
||||
--digits; /* Leave the trailing NUL slot alone. */
|
||||
|
||||
/* Produce the digits -- at least one. */
|
||||
do
|
||||
{
|
||||
where[--digits] = '0' + (char) (value & 7); /* One octal digit. */
|
||||
value >>= 3;
|
||||
}
|
||||
while (digits > 0 && value != 0);
|
||||
|
||||
/* Add leading zeroes, if necessary. */
|
||||
while (digits > 0)
|
||||
where[--digits] = '0';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Compute and return a checksum for TAR_HDR,
|
||||
counting the checksum bytes as if they were spaces. */
|
||||
|
||||
unsigned long
|
||||
tar_checksum (struct tar_header *tar_hdr)
|
||||
{
|
||||
unsigned long sum = 0;
|
||||
char *p = (char *) tar_hdr;
|
||||
char *q = p + TARRECORDSIZE;
|
||||
int i;
|
||||
|
||||
while (p < tar_hdr->chksum)
|
||||
sum += *p++ & 0xff;
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
sum += ' ';
|
||||
++p;
|
||||
}
|
||||
while (p < q)
|
||||
sum += *p++ & 0xff;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Write out header FILE_HDR, including the file name, to file
|
||||
descriptor OUT_DES. */
|
||||
|
||||
void
|
||||
write_out_tar_header (struct new_cpio_header *file_hdr, int out_des)
|
||||
{
|
||||
int name_len;
|
||||
union tar_record tar_rec;
|
||||
struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
|
||||
|
||||
bzero ((char *) &tar_rec, TARRECORDSIZE);
|
||||
|
||||
/* process_copy_out must ensure that file_hdr->c_name is short enough,
|
||||
or we will lose here. */
|
||||
|
||||
name_len = strlen (file_hdr->c_name);
|
||||
if (name_len <= TARNAMESIZE)
|
||||
{
|
||||
strncpy (tar_hdr->name, file_hdr->c_name, name_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fit as much as we can into `name', the rest into `prefix'. */
|
||||
int prefix_len = split_long_name (file_hdr->c_name, name_len);
|
||||
|
||||
strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len);
|
||||
strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1,
|
||||
name_len - prefix_len - 1);
|
||||
}
|
||||
|
||||
/* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal
|
||||
digits */
|
||||
to_oct (file_hdr->c_mode & MODE_ALL, 8, tar_hdr->mode);
|
||||
to_oct (file_hdr->c_uid, 8, tar_hdr->uid);
|
||||
to_oct (file_hdr->c_gid, 8, tar_hdr->gid);
|
||||
to_oct (file_hdr->c_filesize, 12, tar_hdr->size);
|
||||
to_oct (file_hdr->c_mtime, 12, tar_hdr->mtime);
|
||||
|
||||
switch (file_hdr->c_mode & CP_IFMT)
|
||||
{
|
||||
case CP_IFREG:
|
||||
if (file_hdr->c_tar_linkname)
|
||||
{
|
||||
/* process_copy_out makes sure that c_tar_linkname is shorter
|
||||
than TARLINKNAMESIZE. */
|
||||
strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
|
||||
TARLINKNAMESIZE);
|
||||
tar_hdr->typeflag = LNKTYPE;
|
||||
to_oct (0, 12, tar_hdr->size);
|
||||
}
|
||||
else
|
||||
tar_hdr->typeflag = REGTYPE;
|
||||
break;
|
||||
case CP_IFDIR:
|
||||
tar_hdr->typeflag = DIRTYPE;
|
||||
break;
|
||||
case CP_IFCHR:
|
||||
tar_hdr->typeflag = CHRTYPE;
|
||||
break;
|
||||
case CP_IFBLK:
|
||||
tar_hdr->typeflag = BLKTYPE;
|
||||
break;
|
||||
#ifdef CP_IFIFO
|
||||
case CP_IFIFO:
|
||||
tar_hdr->typeflag = FIFOTYPE;
|
||||
break;
|
||||
#endif /* CP_IFIFO */
|
||||
#ifdef CP_IFLNK
|
||||
case CP_IFLNK:
|
||||
tar_hdr->typeflag = SYMTYPE;
|
||||
/* process_copy_out makes sure that c_tar_linkname is shorter
|
||||
than TARLINKNAMESIZE. */
|
||||
strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
|
||||
TARLINKNAMESIZE);
|
||||
to_oct (0, 12, tar_hdr->size);
|
||||
break;
|
||||
#endif /* CP_IFLNK */
|
||||
}
|
||||
|
||||
if (archive_format == arf_ustar)
|
||||
{
|
||||
char *name;
|
||||
|
||||
strncpy (tar_hdr->magic, TMAGIC, TMAGLEN);
|
||||
strncpy (tar_hdr->magic + TMAGLEN, TVERSION, TVERSLEN);
|
||||
|
||||
name = getuser (file_hdr->c_uid);
|
||||
if (name)
|
||||
strcpy (tar_hdr->uname, name);
|
||||
name = getgroup (file_hdr->c_gid);
|
||||
if (name)
|
||||
strcpy (tar_hdr->gname, name);
|
||||
|
||||
to_oct (file_hdr->c_rdev_maj, 8, tar_hdr->devmajor);
|
||||
to_oct (file_hdr->c_rdev_min, 8, tar_hdr->devminor);
|
||||
}
|
||||
|
||||
to_oct (tar_checksum (tar_hdr), 8, tar_hdr->chksum);
|
||||
|
||||
tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
|
||||
}
|
||||
|
||||
/* Return nonzero iff all the bytes in BLOCK are NUL.
|
||||
SIZE is the number of bytes to check in BLOCK; it must be a
|
||||
multiple of sizeof (long). */
|
||||
|
||||
int
|
||||
null_block (long *block, int size)
|
||||
{
|
||||
register long *p = block;
|
||||
register int i = size / sizeof (long);
|
||||
|
||||
while (i--)
|
||||
if (*p++)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read a tar header, including the file name, from file descriptor IN_DES
|
||||
into FILE_HDR. */
|
||||
|
||||
void
|
||||
read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
||||
{
|
||||
long bytes_skipped = 0;
|
||||
int warned = false;
|
||||
union tar_record tar_rec;
|
||||
struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
|
||||
uid_t *uidp;
|
||||
gid_t *gidp;
|
||||
|
||||
tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
|
||||
|
||||
/* Check for a block of 0's. */
|
||||
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
|
||||
{
|
||||
#if 0
|
||||
/* Found one block of 512 0's. If the next block is also all 0's
|
||||
then this is the end of the archive. If not, assume the
|
||||
previous block was all corruption and continue reading
|
||||
the archive. */
|
||||
/* Commented out because GNU tar sometimes creates archives with
|
||||
only one block of 0's at the end. This happened for the
|
||||
cpio 2.0 distribution! */
|
||||
tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
|
||||
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
|
||||
#endif
|
||||
{
|
||||
file_hdr->c_name = "TRAILER!!!";
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
bytes_skipped = TARRECORDSIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
otoa (tar_hdr->chksum, &file_hdr->c_chksum);
|
||||
|
||||
if (file_hdr->c_chksum != tar_checksum (tar_hdr))
|
||||
{
|
||||
/* If the checksum is bad, skip 1 byte and try again. When
|
||||
we try again we do not look for an EOF record (all zeros),
|
||||
because when we start skipping bytes in a corrupted archive
|
||||
the chances are pretty good that we might stumble across
|
||||
2 blocks of 512 zeros (that probably is not really the last
|
||||
record) and it is better to miss the EOF and give the user
|
||||
a "premature EOF" error than to give up too soon on a corrupted
|
||||
archive. */
|
||||
if (!warned)
|
||||
{
|
||||
error (0, 0, _("invalid header: checksum error"));
|
||||
warned = true;
|
||||
}
|
||||
bcopy (((char *) &tar_rec) + 1, (char *) &tar_rec,
|
||||
TARRECORDSIZE - 1);
|
||||
tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
|
||||
++bytes_skipped;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (archive_format != arf_ustar)
|
||||
file_hdr->c_name = stash_tar_filename (NULL, tar_hdr->name);
|
||||
else
|
||||
file_hdr->c_name = stash_tar_filename (tar_hdr->prefix, tar_hdr->name);
|
||||
file_hdr->c_nlink = 1;
|
||||
otoa (tar_hdr->mode, &file_hdr->c_mode);
|
||||
file_hdr->c_mode = file_hdr->c_mode & 07777;
|
||||
/* Debian hack: This version of cpio uses the -n flag also to extract
|
||||
tar archives using the numeric UID/GID instead of the user/group
|
||||
names in /etc/passwd and /etc/groups. (98/10/15) -BEM */
|
||||
if (archive_format == arf_ustar && !numeric_uid
|
||||
&& (uidp = getuidbyname (tar_hdr->uname)))
|
||||
file_hdr->c_uid = *uidp;
|
||||
else
|
||||
otoa (tar_hdr->uid, &file_hdr->c_uid);
|
||||
|
||||
if (archive_format == arf_ustar && !numeric_uid
|
||||
&& (gidp = getgidbyname (tar_hdr->gname)))
|
||||
file_hdr->c_gid = *gidp;
|
||||
else
|
||||
otoa (tar_hdr->gid, &file_hdr->c_gid);
|
||||
otoa (tar_hdr->size, &file_hdr->c_filesize);
|
||||
otoa (tar_hdr->mtime, &file_hdr->c_mtime);
|
||||
otoa (tar_hdr->devmajor, (unsigned long *) &file_hdr->c_rdev_maj);
|
||||
otoa (tar_hdr->devminor, (unsigned long *) &file_hdr->c_rdev_min);
|
||||
file_hdr->c_tar_linkname = NULL;
|
||||
|
||||
switch (tar_hdr->typeflag)
|
||||
{
|
||||
case REGTYPE:
|
||||
case CONTTYPE: /* For now, punt. */
|
||||
default:
|
||||
file_hdr->c_mode |= CP_IFREG;
|
||||
break;
|
||||
case DIRTYPE:
|
||||
file_hdr->c_mode |= CP_IFDIR;
|
||||
break;
|
||||
case CHRTYPE:
|
||||
file_hdr->c_mode |= CP_IFCHR;
|
||||
/* If a POSIX tar header has a valid linkname it's always supposed
|
||||
to set typeflag to be LNKTYPE. System V.4 tar seems to
|
||||
be broken, and for device files with multiple links it
|
||||
puts the name of the link into linkname, but leaves typeflag
|
||||
as CHRTYPE, BLKTYPE, FIFOTYPE, etc. */
|
||||
file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
|
||||
|
||||
/* Does POSIX say that the filesize must be 0 for devices? We
|
||||
assume so, but HPUX's POSIX tar sets it to be 1 which causes
|
||||
us problems (when reading an archive we assume we can always
|
||||
skip to the next file by skipping filesize bytes). For
|
||||
now at least, it's easier to clear filesize for devices,
|
||||
rather than check everywhere we skip in copyin.c. */
|
||||
file_hdr->c_filesize = 0;
|
||||
break;
|
||||
case BLKTYPE:
|
||||
file_hdr->c_mode |= CP_IFBLK;
|
||||
file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
|
||||
file_hdr->c_filesize = 0;
|
||||
break;
|
||||
#ifdef CP_IFIFO
|
||||
case FIFOTYPE:
|
||||
file_hdr->c_mode |= CP_IFIFO;
|
||||
file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
|
||||
file_hdr->c_filesize = 0;
|
||||
break;
|
||||
#endif
|
||||
case SYMTYPE:
|
||||
#ifdef CP_IFLNK
|
||||
file_hdr->c_mode |= CP_IFLNK;
|
||||
file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
|
||||
file_hdr->c_filesize = 0;
|
||||
break;
|
||||
/* Else fall through. */
|
||||
#endif
|
||||
case LNKTYPE:
|
||||
file_hdr->c_mode |= CP_IFREG;
|
||||
file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
|
||||
file_hdr->c_filesize = 0;
|
||||
break;
|
||||
|
||||
case AREGTYPE:
|
||||
/* Old tar format; if the last char in filename is '/' then it is
|
||||
a directory, otherwise it's a regular file. */
|
||||
if (file_hdr->c_name[strlen (file_hdr->c_name) - 1] == '/')
|
||||
file_hdr->c_mode |= CP_IFDIR;
|
||||
else
|
||||
file_hdr->c_mode |= CP_IFREG;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (bytes_skipped > 0)
|
||||
warn_junk_bytes (bytes_skipped);
|
||||
}
|
||||
|
||||
/* Convert the string of octal digits S into a number and store
|
||||
it in *N. Return nonzero if the whole string was converted,
|
||||
zero if there was something after the number.
|
||||
Skip leading and trailing spaces. */
|
||||
|
||||
int
|
||||
otoa (char *s, unsigned long *n)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
while (*s == ' ')
|
||||
++s;
|
||||
while (*s >= '0' && *s <= '7')
|
||||
val = 8 * val + *s++ - '0';
|
||||
while (*s == ' ')
|
||||
++s;
|
||||
*n = val;
|
||||
return *s == '\0';
|
||||
}
|
||||
|
||||
/* Return
|
||||
2 if BUF is a valid POSIX tar header (the checksum is correct
|
||||
and it has the "ustar" magic string),
|
||||
1 if BUF is a valid old tar header (the checksum is correct),
|
||||
0 otherwise. */
|
||||
|
||||
int
|
||||
is_tar_header (char *buf)
|
||||
{
|
||||
struct tar_header *tar_hdr = (struct tar_header *) buf;
|
||||
unsigned long chksum;
|
||||
|
||||
otoa (tar_hdr->chksum, &chksum);
|
||||
|
||||
if (chksum != tar_checksum (tar_hdr))
|
||||
return 0;
|
||||
|
||||
/* GNU tar 1.10 and previous set the magic field to be "ustar " instead
|
||||
of "ustar\0". Only look at the first 5 characters of the magic
|
||||
field so we can recognize old GNU tar ustar archives. */
|
||||
if (!strncmp (tar_hdr->magic, TMAGIC, TMAGLEN - 1))
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return true if the filename is too long to fit in a tar header.
|
||||
For old tar headers, if the filename's length is less than or equal
|
||||
to 100 then it will fit, otherwise it will not. For POSIX tar headers,
|
||||
if the filename's length is less than or equal to 100 then it
|
||||
will definitely fit, and if it is greater than 256 then it
|
||||
will definitely not fit. If the length is between 100 and 256,
|
||||
then the filename will fit only if it is possible to break it
|
||||
into a 155 character "prefix" and 100 character "name". There
|
||||
must be a slash between the "prefix" and the "name", although
|
||||
the slash is not stored or counted in either the "prefix" or
|
||||
the "name", and there must be at least one character in both
|
||||
the "prefix" and the "name". If it is not possible to break down
|
||||
the filename like this then it will not fit. */
|
||||
|
||||
int
|
||||
is_tar_filename_too_long (char *name)
|
||||
{
|
||||
int whole_name_len;
|
||||
int prefix_name_len;
|
||||
char *p;
|
||||
|
||||
whole_name_len = strlen (name);
|
||||
if (whole_name_len <= TARNAMESIZE)
|
||||
return false;
|
||||
|
||||
if (archive_format != arf_ustar)
|
||||
return true;
|
||||
|
||||
if (whole_name_len > TARNAMESIZE + TARPREFIXSIZE + 1)
|
||||
return true;
|
||||
|
||||
/* See whether we can split up the name into acceptably-sized
|
||||
`prefix' and `name' (`p') pieces. */
|
||||
prefix_name_len = split_long_name (name, whole_name_len);
|
||||
|
||||
/* Interestingly, a name consisting of a slash followed by
|
||||
TARNAMESIZE characters can't be stored, because the prefix
|
||||
would be empty, and thus ignored. */
|
||||
if (prefix_name_len == 0
|
||||
|| whole_name_len - prefix_name_len - 1 > TARNAMESIZE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
112
contrib/cpio/src/tar.h
Normal file
112
contrib/cpio/src/tar.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* Extended tar format from POSIX.1.
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
Written by David J. MacKenzie.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _TAR_H
|
||||
|
||||
#define _TAR_H 1
|
||||
|
||||
|
||||
/* A tar archive consists of 512-byte blocks.
|
||||
Each file in the archive has a header block followed by 0+ data blocks.
|
||||
Two blocks of NUL bytes indicate the end of the archive. */
|
||||
|
||||
/* The fields of header blocks:
|
||||
All strings are stored as ISO 646 (approximately ASCII) strings.
|
||||
|
||||
Fields are numeric unless otherwise noted below; numbers are ISO 646
|
||||
representations of octal numbers, with leading zeros as needed.
|
||||
|
||||
linkname is only valid when typeflag==LNKTYPE. It doesn't use prefix;
|
||||
files that are links to pathnames >100 chars long can not be stored
|
||||
in a tar archive.
|
||||
|
||||
If typeflag=={LNKTYPE,SYMTYPE,DIRTYPE} then size must be 0.
|
||||
|
||||
devmajor and devminor are only valid for typeflag=={BLKTYPE,CHRTYPE}.
|
||||
|
||||
chksum contains the sum of all 512 bytes in the header block,
|
||||
treating each byte as an 8-bit unsigned value and treating the
|
||||
8 bytes of chksum as blank characters.
|
||||
|
||||
uname and gname are used in preference to uid and gid, if those
|
||||
names exist locally.
|
||||
|
||||
Field Name Byte Offset Length in Bytes Field Type
|
||||
name 0 100 NUL-terminated if NUL fits
|
||||
mode 100 8
|
||||
uid 108 8
|
||||
gid 116 8
|
||||
size 124 12
|
||||
mtime 136 12
|
||||
chksum 148 8
|
||||
typeflag 156 1 see below
|
||||
linkname 157 100 NUL-terminated if NUL fits
|
||||
magic 257 6 must be TMAGIC (NUL term.)
|
||||
version 263 2 must be TVERSION
|
||||
uname 265 32 NUL-terminated
|
||||
gname 297 32 NUL-terminated
|
||||
devmajor 329 8
|
||||
devminor 337 8
|
||||
prefix 345 155 NUL-terminated if NUL fits
|
||||
|
||||
If the first character of prefix is '\0', the file name is name;
|
||||
otherwise, it is prefix/name. Files whose pathnames don't fit in that
|
||||
length can not be stored in a tar archive. */
|
||||
|
||||
/* The bits in mode: */
|
||||
#define TSUID 04000
|
||||
#define TSGID 02000
|
||||
#define TSVTX 01000
|
||||
#define TUREAD 00400
|
||||
#define TUWRITE 00200
|
||||
#define TUEXEC 00100
|
||||
#define TGREAD 00040
|
||||
#define TGWRITE 00020
|
||||
#define TGEXEC 00010
|
||||
#define TOREAD 00004
|
||||
#define TOWRITE 00002
|
||||
#define TOEXEC 00001
|
||||
|
||||
/* The values for typeflag:
|
||||
Values 'A'-'Z' are reserved for custom implementations.
|
||||
All other values are reserved for future POSIX.1 revisions. */
|
||||
|
||||
#define REGTYPE '0' /* Regular file (preferred code). */
|
||||
#define AREGTYPE '\0' /* Regular file (alternate code). */
|
||||
#define LNKTYPE '1' /* Hard link. */
|
||||
#define SYMTYPE '2' /* Symbolic link (hard if not supported). */
|
||||
#define CHRTYPE '3' /* Character special. */
|
||||
#define BLKTYPE '4' /* Block special. */
|
||||
#define DIRTYPE '5' /* Directory. */
|
||||
#define FIFOTYPE '6' /* Named pipe. */
|
||||
#define CONTTYPE '7' /* Contiguous file */
|
||||
/* (regular file if not supported). */
|
||||
|
||||
/* Contents of magic field and its length. */
|
||||
#define TMAGIC "ustar"
|
||||
#define TMAGLEN 6
|
||||
|
||||
/* Contents of the version field and its length. */
|
||||
#define TVERSION "00"
|
||||
#define TVERSLEN 2
|
||||
|
||||
|
||||
#endif /* tar.h */
|
62
contrib/cpio/src/tarhdr.h
Normal file
62
contrib/cpio/src/tarhdr.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* Extended tar header from POSIX.1.
|
||||
Copyright (C) 1992 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _TARHDR_H
|
||||
|
||||
#define _TARHDR_H 1
|
||||
|
||||
#include <tar.h>
|
||||
|
||||
/* Size of `name' field. */
|
||||
#define TARNAMESIZE 100
|
||||
|
||||
/* Size of `linkname' field. */
|
||||
#define TARLINKNAMESIZE 100
|
||||
|
||||
/* Size of `prefix' field. */
|
||||
#define TARPREFIXSIZE 155
|
||||
|
||||
/* Size of entire tar header. */
|
||||
#define TARRECORDSIZE 512
|
||||
|
||||
struct tar_header
|
||||
{
|
||||
char name[TARNAMESIZE];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char typeflag;
|
||||
char linkname[TARLINKNAMESIZE];
|
||||
char magic[6];
|
||||
char version[2];
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char prefix[TARPREFIXSIZE];
|
||||
};
|
||||
|
||||
union tar_record
|
||||
{
|
||||
struct tar_header header;
|
||||
char buffer[TARRECORDSIZE];
|
||||
};
|
||||
|
||||
#endif /* tarhdr.h */
|
257
contrib/cpio/src/userspec.c
Normal file
257
contrib/cpio/src/userspec.c
Normal file
@ -0,0 +1,257 @@
|
||||
/* userspec.c -- Parse a user and group string.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 2001, 2004 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, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#else
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if !HAVE_DECL_GETPWNAM
|
||||
extern struct passwd *getpwnam (const char *name);
|
||||
#endif
|
||||
#if !HAVE_DECL_GETGRNAM
|
||||
extern struct group *getgrnam (const char *name);
|
||||
#endif
|
||||
#if !HAVE_DECL_GETGRGID
|
||||
extern struct group *getgrgid (gid_t gid);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ENDPWENT
|
||||
# define endpwent()
|
||||
#endif
|
||||
#ifndef HAVE_ENDGRENT
|
||||
# define endgrent()
|
||||
#endif
|
||||
|
||||
/* Perform the equivalent of the statement `dest = strdup (src);',
|
||||
but obtaining storage via alloca instead of from the heap. */
|
||||
|
||||
#define V_STRDUP(dest, src) \
|
||||
do \
|
||||
{ \
|
||||
int _len = strlen ((src)); \
|
||||
(dest) = (char *) alloca (_len + 1); \
|
||||
strcpy (dest, src); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Return nonzero if STR represents an unsigned decimal integer,
|
||||
otherwise return 0. */
|
||||
|
||||
static int
|
||||
isnumber (const char *str)
|
||||
{
|
||||
for (; *str; str++)
|
||||
if (!isdigit (*str))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract from NAME, which has the form "[user][:.][group]",
|
||||
a USERNAME, UID U, GROUPNAME, and GID G.
|
||||
Either user or group, or both, must be present.
|
||||
If the group is omitted but the ":" or "." separator is given,
|
||||
use the given user's login group.
|
||||
|
||||
USERNAME and GROUPNAME will be in newly malloc'd memory.
|
||||
Either one might be NULL instead, indicating that it was not
|
||||
given and the corresponding numeric ID was left unchanged.
|
||||
|
||||
Return NULL if successful, a static error message string if not. */
|
||||
|
||||
const char *
|
||||
parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
|
||||
char **username_arg, char **groupname_arg)
|
||||
{
|
||||
static const char *tired = "virtual memory exhausted";
|
||||
const char *error_msg;
|
||||
char *spec; /* A copy we can write on. */
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
char *g, *u, *separator;
|
||||
char *groupname;
|
||||
|
||||
error_msg = NULL;
|
||||
*username_arg = *groupname_arg = NULL;
|
||||
groupname = NULL;
|
||||
|
||||
V_STRDUP (spec, spec_arg);
|
||||
|
||||
/* Find the separator if there is one. */
|
||||
separator = index (spec, ':');
|
||||
if (separator == NULL)
|
||||
separator = index (spec, '.');
|
||||
|
||||
/* Replace separator with a NUL. */
|
||||
if (separator != NULL)
|
||||
*separator = '\0';
|
||||
|
||||
/* Set U and G to non-zero length strings corresponding to user and
|
||||
group specifiers or to NULL. */
|
||||
u = (*spec == '\0' ? NULL : spec);
|
||||
|
||||
g = (separator == NULL || *(separator + 1) == '\0'
|
||||
? NULL
|
||||
: separator + 1);
|
||||
|
||||
if (u == NULL && g == NULL)
|
||||
return "can not omit both user and group";
|
||||
|
||||
if (u != NULL)
|
||||
{
|
||||
pwd = getpwnam (u);
|
||||
if (pwd == NULL)
|
||||
{
|
||||
|
||||
if (!isnumber (u))
|
||||
error_msg = _("invalid user");
|
||||
else
|
||||
{
|
||||
int use_login_group;
|
||||
use_login_group = (separator != NULL && g == NULL);
|
||||
if (use_login_group)
|
||||
error_msg = _("cannot get the login group of a numeric UID");
|
||||
else
|
||||
*uid = atoi (u);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*uid = pwd->pw_uid;
|
||||
if (g == NULL && separator != NULL)
|
||||
{
|
||||
/* A separator was given, but a group was not specified,
|
||||
so get the login group. */
|
||||
*gid = pwd->pw_gid;
|
||||
grp = getgrgid (pwd->pw_gid);
|
||||
if (grp == NULL)
|
||||
{
|
||||
/* This is enough room to hold the unsigned decimal
|
||||
representation of any 32-bit quantity and the trailing
|
||||
zero byte. */
|
||||
char uint_buf[21];
|
||||
sprintf (uint_buf, "%u", (unsigned) (pwd->pw_gid));
|
||||
V_STRDUP (groupname, uint_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_STRDUP (groupname, grp->gr_name);
|
||||
}
|
||||
endgrent ();
|
||||
}
|
||||
}
|
||||
endpwent ();
|
||||
}
|
||||
|
||||
if (g != NULL && error_msg == NULL)
|
||||
{
|
||||
/* Explicit group. */
|
||||
grp = getgrnam (g);
|
||||
if (grp == NULL)
|
||||
{
|
||||
if (!isnumber (g))
|
||||
error_msg = _("invalid group");
|
||||
else
|
||||
*gid = atoi (g);
|
||||
}
|
||||
else
|
||||
*gid = grp->gr_gid;
|
||||
endgrent (); /* Save a file descriptor. */
|
||||
|
||||
if (error_msg == NULL)
|
||||
V_STRDUP (groupname, g);
|
||||
}
|
||||
|
||||
if (error_msg == NULL)
|
||||
{
|
||||
if (u != NULL)
|
||||
{
|
||||
*username_arg = strdup (u);
|
||||
if (*username_arg == NULL)
|
||||
error_msg = tired;
|
||||
}
|
||||
|
||||
if (groupname != NULL && error_msg == NULL)
|
||||
{
|
||||
*groupname_arg = strdup (groupname);
|
||||
if (*groupname_arg == NULL)
|
||||
{
|
||||
if (*username_arg != NULL)
|
||||
{
|
||||
free (*username_arg);
|
||||
*username_arg = NULL;
|
||||
}
|
||||
error_msg = tired;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#define NULL_CHECK(s) ((s) == NULL ? "(null)" : (s))
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
const char *e;
|
||||
char *username, *groupname;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *tmp;
|
||||
|
||||
tmp = strdup (argv[i]);
|
||||
e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
|
||||
free (tmp);
|
||||
printf ("%s: %u %u %s %s %s\n",
|
||||
argv[i],
|
||||
(unsigned int) uid,
|
||||
(unsigned int) gid,
|
||||
NULL_CHECK (username),
|
||||
NULL_CHECK (groupname),
|
||||
NULL_CHECK (e));
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif
|
1247
contrib/cpio/src/util.c
Normal file
1247
contrib/cpio/src/util.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user