mirror of
https://github.com/mirror/wget.git
synced 2025-01-27 21:00:31 +08:00
[svn] Initial revision
This commit is contained in:
parent
c5f1f6a779
commit
31d6616c48
16
AUTHORS
Normal file
16
AUTHORS
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Authors of GNU Wget.
|
||||||
|
|
||||||
|
[ Note that this file does not attempt to list all the contributors to
|
||||||
|
Wget; look at the ChangeLog for that. This is a list of people who
|
||||||
|
contributed sizeable amounts of code and assigned the copyright to the
|
||||||
|
FSF. ]
|
||||||
|
|
||||||
|
Hrvoje Niksic. Designed and implemented Wget.
|
||||||
|
|
||||||
|
Gordon Matzigkeit. Wrote netrc.c and netrc.h.
|
||||||
|
|
||||||
|
Darko Budor. Added Windows support, wrote wsstartup.c, wsstartup.h
|
||||||
|
and windecl.h.
|
||||||
|
|
||||||
|
Junio Hamano. Added support for FTP Opie and HTTP digest
|
||||||
|
authentication.
|
339
COPYING
Normal file
339
COPYING
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
211
ChangeLog
Normal file
211
ChangeLog
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
1998-06-23 Dave Love <d.love@dl.ac.uk>
|
||||||
|
|
||||||
|
* configure.in (exext): Define.
|
||||||
|
|
||||||
|
1998-06-06 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* configure.in: Check for access().
|
||||||
|
|
||||||
|
1998-05-20 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* po/hr.po: Some fixes, as per suggestions by Francois Pinard.
|
||||||
|
|
||||||
|
1998-05-19 Dominique Delamarre <dominique.delamarre@hol.fr>
|
||||||
|
|
||||||
|
* po/fr.po: New file.
|
||||||
|
|
||||||
|
1998-05-19 Toomas Soome <tsoome@ut.ee>
|
||||||
|
|
||||||
|
* po/et.po: Updated.
|
||||||
|
|
||||||
|
1998-05-11 Simos KSenitellis <simos@teiath.gr>
|
||||||
|
|
||||||
|
* po/el.po: New file.
|
||||||
|
|
||||||
|
1998-05-09 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* aclocal.m4 (WGET_WITH_NLS): Print available catalogs.
|
||||||
|
|
||||||
|
1998-05-09 Toomas Soome <tsoome@ut.ee>
|
||||||
|
|
||||||
|
* po/et.po: New file.
|
||||||
|
|
||||||
|
1998-05-06 Douglas E. Wegscheid <wegscd@whirlpool.com>
|
||||||
|
|
||||||
|
* configure.bat: set up for either Borland or Visual C
|
||||||
|
|
||||||
|
* windows/wget.dep: new file
|
||||||
|
|
||||||
|
* windows/Makefile.*: use wget.dep
|
||||||
|
|
||||||
|
* rename windows/Makefile.bor to Makefile.src.bor
|
||||||
|
|
||||||
|
1998-05-06 Douglas E. Wegscheid <wegscd@whirlpool.com>
|
||||||
|
|
||||||
|
* windows/makefile.bor: Updated.
|
||||||
|
|
||||||
|
* windows/Makefile.src: Ditto.
|
||||||
|
|
||||||
|
1998-04-30 Douglas E. Wegscheid <wegscd@whirlpool.com>
|
||||||
|
|
||||||
|
* windows/config.h.bor: New file.
|
||||||
|
|
||||||
|
* windows/makefile.bor: New file.
|
||||||
|
|
||||||
|
1998-04-27 John Burden <john@futuresguide.com>
|
||||||
|
|
||||||
|
* windows/Makefile.*: Cleanup.
|
||||||
|
|
||||||
|
1998-04-27 Gregor Hoffleit <flight@mathi.uni-heidelberg.de>
|
||||||
|
|
||||||
|
* configure.in: Check for PID_T.
|
||||||
|
|
||||||
|
1998-04-19 Giovanni Bortolozzo <borto@dei.unipd.it>
|
||||||
|
|
||||||
|
* po/it.po: Updated.
|
||||||
|
|
||||||
|
1998-04-19 Jan Prikryl <prikryl@cg.tuwien.ac.at>
|
||||||
|
|
||||||
|
* po/cs.po: Updated.
|
||||||
|
|
||||||
|
1998-04-19 Wanderlei Cavassin <cavassin@conectiva.com.br>
|
||||||
|
|
||||||
|
* po/pt_BR.po: Updated.
|
||||||
|
|
||||||
|
1998-04-08 Stefan Hornburg <racke@gundel.han.de>
|
||||||
|
|
||||||
|
* Makefile (dist): New target.
|
||||||
|
|
||||||
|
1998-04-08 Wanderlei Cavassin <cavassin@conectiva.com.br>
|
||||||
|
|
||||||
|
* po/pt_BR.po: Updated.
|
||||||
|
|
||||||
|
1998-04-04 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* aclocal.m4 (WGET_WITH_NLS): Renamed USE_NLS to HAVE_NLS.
|
||||||
|
|
||||||
|
* ABOUT-NLS: Removed.
|
||||||
|
|
||||||
|
* Makefile.in (stamp-h): Clean up stamp-h-related dependencies.
|
||||||
|
Don't attempt to write to stamp-h.in.
|
||||||
|
|
||||||
|
* aclocal.m4 (WGET_PROCESS_PO): Reset srcdir to ac_given_srcdir.
|
||||||
|
|
||||||
|
1998-04-03 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (distclean-top): Remove stamp-h.
|
||||||
|
|
||||||
|
1998-04-02 Robert Schmidt <rsc@vingmed.no>
|
||||||
|
|
||||||
|
* po/no.po: New file.
|
||||||
|
|
||||||
|
1998-04-01 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* configure.in: New option `--disable-debug'.
|
||||||
|
|
||||||
|
1998-03-31 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* configure.in: Check for endianness.
|
||||||
|
|
||||||
|
1998-03-29 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* aclocal.m4 (WGET_PROCESS_PO): Use echo instead of AC_MSG_RESULT.
|
||||||
|
|
||||||
|
1998-03-28 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* aclocal.m4 (WGET_WITH_NLS): Disable USE_NLS if gettext is
|
||||||
|
unavailable.
|
||||||
|
|
||||||
|
* aclocal.m4: Renamed AM_STRUCT_UTIMBUF to WGET_STRUCT_UTIMBUF;
|
||||||
|
renamed AM_WITH_NLS to WGET_WITH_NLS.
|
||||||
|
|
||||||
|
* aclocal.m4: Eliminate POSUBS.
|
||||||
|
|
||||||
|
1998-03-17 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in: config.h* -> src/config.h*
|
||||||
|
|
||||||
|
* configure.in: Check for vsnprintf().
|
||||||
|
|
||||||
|
* po/POTFILES.in: Updated.
|
||||||
|
|
||||||
|
1998-03-16 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* po/POTFILES.in: Removed extraneous newline at end of line, which
|
||||||
|
caused an error in `Makefile' which Sun make choked on.
|
||||||
|
|
||||||
|
1998-03-16 Jan Prikryl <prikryl@cg.tuwien.ac.at>
|
||||||
|
|
||||||
|
* po/cs.po: New file.
|
||||||
|
|
||||||
|
1998-03-12 Wanderlei Cavassin <cavassin@conectiva.com.br>
|
||||||
|
|
||||||
|
* po/pt_BR.po: New file.
|
||||||
|
|
||||||
|
1998-03-07 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* PROBLEMS: New file.
|
||||||
|
|
||||||
|
1998-02-22 Karl Eichwalder <ke@suse.de>
|
||||||
|
|
||||||
|
* po/Makefile.in.in (install-data-yes): Fix creation of
|
||||||
|
directories for LC_MESSAGE files.
|
||||||
|
|
||||||
|
1998-02-22 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* configure.in: Removed `-Wno-switch' for gcc.
|
||||||
|
|
||||||
|
* po/Makefile.in.in (install-data-yes): Use mkinstalldirs to
|
||||||
|
create the directory first.
|
||||||
|
|
||||||
|
1998-02-21 Karl Eichwalder <karl@suse.de>
|
||||||
|
|
||||||
|
* po/de.po: Updated.
|
||||||
|
|
||||||
|
1998-02-19 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (check): New empty target.
|
||||||
|
|
||||||
|
1998-02-11 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* po/it.po: New file, by Antonio Rosella.
|
||||||
|
|
||||||
|
1998-02-08 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* aclocal.m4: Cleaned up.
|
||||||
|
|
||||||
|
* po/hr.po: Updated.
|
||||||
|
|
||||||
|
* configure.in: Removed check for POSIXized ISC.
|
||||||
|
|
||||||
|
1998-02-08 Karl Eichwalder <karl@suse.de>
|
||||||
|
|
||||||
|
* po/de.po: Updated.
|
||||||
|
|
||||||
|
1998-02-07 Karl Eichwalder <ke@suse.de>
|
||||||
|
|
||||||
|
* Makefile.in (install.info uninstall.info install.man
|
||||||
|
uninstall.man install.wgetrc): Use it.
|
||||||
|
|
||||||
|
* Makefile.in (install.mo): New target.
|
||||||
|
|
||||||
|
1998-02-03 Karl Eichwalder <ke@suse.de>
|
||||||
|
|
||||||
|
* po/POTFILES.in: Touch it (needed for NLS); add src/ftp.c,
|
||||||
|
src/getopt.c, src/host.c, src/html.c, src/http.c, src/init.c,
|
||||||
|
src/main.c, src/mswindows.c, src/netrc.c, src/recur.c, src/retr.c,
|
||||||
|
src/url.c, and src/utils.c.
|
||||||
|
|
||||||
|
* intl/po2tbl.sed.in: Add from gettext-0.10.32 (needed for NLS).
|
||||||
|
|
||||||
|
* po/Makefile.in.in: Add from gettext-0.10.32.
|
||||||
|
|
||||||
|
* Makefile.in (SUBDIRS): Add po/.
|
||||||
|
|
||||||
|
* configure.in (ALL_LINGUAS): New variable. Add "de" and "hr".
|
||||||
|
(AM_GNU_GETTEXT): Add.
|
||||||
|
(AC_OUTPUT): Add po/Makefile.in; run the sed command.
|
||||||
|
|
||||||
|
* aclocal.m4 (AM_WITH_NLS, AM_GNU_GETTEXT, AM_LC_MESSAGES,
|
||||||
|
AM_PATH_PROG_WITH_TEST): from gettext-0.10.32.
|
||||||
|
|
75
INSTALL
Normal file
75
INSTALL
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
-*- text -*-
|
||||||
|
Installation Procedure
|
||||||
|
|
||||||
|
0) Preparation
|
||||||
|
|
||||||
|
To build and install GNU Wget, you need to unpack the archive (which
|
||||||
|
you have presumably done, since you are reading this), and read on.
|
||||||
|
Like most GNU utilities, Wget uses the GNU Autoconf mechanism for
|
||||||
|
build and installation; those of you familiar with compiling GNU
|
||||||
|
software will feel at home.
|
||||||
|
|
||||||
|
1) Configuration
|
||||||
|
|
||||||
|
To configure Wget, run the configure script provided with the
|
||||||
|
distribution. You may use all the standard arguments configure
|
||||||
|
scripts take. The most important ones are:
|
||||||
|
|
||||||
|
--help print help message
|
||||||
|
|
||||||
|
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||||
|
(/usr/local by default)
|
||||||
|
--bindir=DIR user executables in DIR (PREFIX/bin)
|
||||||
|
--infodir=DIR info documentation in DIR [PREFIX/info]
|
||||||
|
--mandir=DIR man documentation in DIR [PREFIX/man]
|
||||||
|
|
||||||
|
--build=BUILD configure for building on BUILD [BUILD=HOST]
|
||||||
|
--host=HOST configure for HOST [guessed]
|
||||||
|
--target=TARGET configure for TARGET [TARGET=HOST]
|
||||||
|
|
||||||
|
--enable and --with options recognized (mostly Wget-specific):
|
||||||
|
--with-socks use the socks library
|
||||||
|
--disable-opie disable support for opie or s/key FTP login
|
||||||
|
--disable-digest disable support for HTTP digest authorization
|
||||||
|
--disable-debug disable support for debugging output
|
||||||
|
--disable-nls do not use Native Language Support
|
||||||
|
|
||||||
|
So, if you want to configure Wget for installation in your home
|
||||||
|
directory, you can type:
|
||||||
|
./configure --prefix=$HOME
|
||||||
|
|
||||||
|
You can customize many default settings by editing Makefile and
|
||||||
|
config.h. The program will work very well without your touching these
|
||||||
|
files, but it is useful to have a look at things you can change there.
|
||||||
|
|
||||||
|
If you use socks, it is useful to add -L/usr/local/lib (or wherever
|
||||||
|
the socks library is installed) to LDFLAGS in Makefile.
|
||||||
|
|
||||||
|
To configure Wget on Windows, run configure.bat and follow the
|
||||||
|
instructions in the windows/ directory. If this doesn't work for any
|
||||||
|
reason, talk to the Windows developers listed in `windows/README'; I
|
||||||
|
do not maintain the port.
|
||||||
|
|
||||||
|
2) Compilation
|
||||||
|
|
||||||
|
To compile the program, type make and cross your fingers. If you do
|
||||||
|
not have an ANSI compiler, Wget will try to KNR-ize its sources "on
|
||||||
|
the fly". This should make GNU Wget compilable virtually anywhere.
|
||||||
|
|
||||||
|
After the compilation a ready to use `wget' executable should reside
|
||||||
|
in the src directory. I do not have any kind of test-suite as of this
|
||||||
|
moment, but it should be easy enough to test whether the basic stuff
|
||||||
|
works.
|
||||||
|
|
||||||
|
3) Installation
|
||||||
|
|
||||||
|
Use `make install' to install GNU Wget to directories specified to
|
||||||
|
configure (/usr/local/* by default).
|
||||||
|
|
||||||
|
The standard installation process will copy the wget binary to
|
||||||
|
/usr/local/bin, install the info pages (wget.info*) to
|
||||||
|
/usr/local/info. You can customize the directories either through the
|
||||||
|
configuration process or making the necessary changes in the Makefile.
|
||||||
|
|
||||||
|
To delete the files created by Wget installation, you can use make
|
||||||
|
uninstall.
|
28
MACHINES
Normal file
28
MACHINES
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
This files lists the architectures on which this version of GNU Wget
|
||||||
|
was tried on. If you compile Wget on a new architecture, please drop
|
||||||
|
me a note, or send a patch to this file.
|
||||||
|
|
||||||
|
|
||||||
|
Sun SunOS, Solaris (sparc-sun-solaris*, sparc-sun-sunos*)
|
||||||
|
|
||||||
|
GNU/Linux (i[3456]86-*-linux*)
|
||||||
|
|
||||||
|
DEC Ultrix, Digital Unix (mips-dec-ultrix*, alpha-dec-osf*)
|
||||||
|
|
||||||
|
HP BSD (m68k-hp-bsd)
|
||||||
|
|
||||||
|
HP HPUX (hppa1.0-hp-hpux7.00, hppa1.1-hp-hpux9.01 and others)
|
||||||
|
|
||||||
|
IBM AIX (powerpc-ibm-aix4.1.4.0)
|
||||||
|
|
||||||
|
Amiga NetBSD (m68k-cbm-netbsd1.2)
|
||||||
|
|
||||||
|
SGI IRIX (mips-sgi-irix4.0.5, mips-sgi-irix5.3)
|
||||||
|
|
||||||
|
SCO Unix (i586-pc-sco3.2v5.0.4)
|
||||||
|
|
||||||
|
NeXTStep 3.3 Intel (i386-next-nextstep3)
|
||||||
|
|
||||||
|
FreeBSD (i386-unknown-freebsd2.2.6)
|
||||||
|
|
||||||
|
Windows 95/NT (i[3456]86)
|
16
MAILING-LIST
Normal file
16
MAILING-LIST
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-*- text -*-
|
||||||
|
|
||||||
|
Mailing List Info
|
||||||
|
|
||||||
|
|
||||||
|
Thanks to Karsten Thygesen, Wget has its own mailing list for
|
||||||
|
discussion and announcements. The list address is hosted at Sunsite
|
||||||
|
Denmark, <wget@sunsite.auc.dk>. To subscribe, send mail to
|
||||||
|
<wget-subscribe@sunsite.auc.dk>.
|
||||||
|
|
||||||
|
The list is fairly low-volume -- one or two messages per day and with
|
||||||
|
sporadic periods of intensive activity. If you are interested in
|
||||||
|
using or hacking Wget, or wish to read the important announcements,
|
||||||
|
you are very welcome to subscribe.
|
||||||
|
|
||||||
|
The list is archived at <URL:http://fly.cc.fer.hr/archive/wget>.
|
170
Makefile.in
Normal file
170
Makefile.in
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
# Makefile for `Wget' utility
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Version: @VERSION@
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
#
|
||||||
|
# User configuration section
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Install variables
|
||||||
|
#
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = @bindir@
|
||||||
|
infodir = @infodir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
mandir = @mandir@
|
||||||
|
manext = 1
|
||||||
|
localedir = $(prefix)/share/locale
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
#
|
||||||
|
# End of user configuration section. There should be no need to change
|
||||||
|
# anything below this line.
|
||||||
|
#
|
||||||
|
|
||||||
|
DISTNAME = wget-@VERSION@
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
# These are used for maintenance only, so they are safe without
|
||||||
|
# special autoconf cruft.
|
||||||
|
FIND = find
|
||||||
|
GZIP = gzip
|
||||||
|
TAR = tar
|
||||||
|
|
||||||
|
# flags passed to recursive makes in subdirectories
|
||||||
|
MAKEDEFS = CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' DEFS='$(DEFS)' \
|
||||||
|
CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)' \
|
||||||
|
prefix='$(prefix)' exec_prefix='$(exec_prefix)' bindir='$(bindir)' \
|
||||||
|
infodir='$(infodir)' mandir='$(mandir)' manext='$(manext)'
|
||||||
|
|
||||||
|
# subdirectories in the distribution
|
||||||
|
SUBDIRS = src doc po util
|
||||||
|
|
||||||
|
# default target
|
||||||
|
all: src/config.h Makefile $(SUBDIRS)
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
$(SUBDIRS): FORCE
|
||||||
|
cd $@ && $(MAKE) $(MAKEDEFS)
|
||||||
|
|
||||||
|
# install everything
|
||||||
|
install: install.bin install.info install.wgetrc install.mo # install.man
|
||||||
|
|
||||||
|
# install/uninstall the binary
|
||||||
|
install.bin uninstall.bin:
|
||||||
|
cd src && $(MAKE) $(MAKEDEFS) $@
|
||||||
|
|
||||||
|
# install/uninstall the info/man pages
|
||||||
|
install.info uninstall.info install.man uninstall.man install.wgetrc:
|
||||||
|
cd doc && $(MAKE) $(MAKEDEFS) $@
|
||||||
|
|
||||||
|
# Install `.mo' files
|
||||||
|
install.mo:
|
||||||
|
cd po && $(MAKE) $(MAKEDEFS) $@
|
||||||
|
|
||||||
|
# create tag files for Emacs
|
||||||
|
TAGS:
|
||||||
|
cd src && $(MAKE) $@
|
||||||
|
|
||||||
|
dist: $(srcdir)/configure DISTFILES
|
||||||
|
mkdir $(DISTNAME)
|
||||||
|
for d in `$(FIND) . -type d ! -name RCS -print`; do \
|
||||||
|
if [ "$$d" != "." -a "$$d" != "./$(DISTNAME)" ]; then \
|
||||||
|
mkdir $(DISTNAME)/$$d; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
for f in `cat DISTFILES`; do \
|
||||||
|
ln $(srcdir)/$$f $(DISTNAME)/$$f || \
|
||||||
|
{ echo copying $$f; cp -p $(srcdir)/$$f $(DISTNAME)/$$f ; } \
|
||||||
|
done
|
||||||
|
(cd $(DISTNAME); $(MAKE) distclean)
|
||||||
|
$(TAR) chvf - $(DISTNAME) | $(GZIP) -c --best >$(DISTNAME).tar.gz
|
||||||
|
$(RM) -r $(DISTNAME)
|
||||||
|
$(RM) DISTFILES
|
||||||
|
|
||||||
|
DISTFILES: FORCE
|
||||||
|
rm -rf $(DISTNAME)
|
||||||
|
(cd $(srcdir); find . ! -type d -print) \
|
||||||
|
| sed '/\/RCS\//d; \
|
||||||
|
/$@/d; \
|
||||||
|
/\.tar.*/d; \
|
||||||
|
s/^.\///; /^\.$$/d;' \
|
||||||
|
| sort | uniq > $@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cleanup dependencies
|
||||||
|
#
|
||||||
|
|
||||||
|
clean: clean-recursive clean-top
|
||||||
|
distclean: distclean-recursive distclean-top
|
||||||
|
realclean: realclean-recursive realclean-top
|
||||||
|
|
||||||
|
clean-top:
|
||||||
|
$(RM) *~ *.bak $(DISTNAME).tar.gz
|
||||||
|
|
||||||
|
distclean-top: clean-top
|
||||||
|
$(RM) Makefile config.status config.log config.cache stamp-h
|
||||||
|
|
||||||
|
realclean-top: distclean-top
|
||||||
|
|
||||||
|
clean-recursive distclean-recursive realclean-recursive:
|
||||||
|
for subdir in $(SUBDIRS); do \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
(cd $$subdir && $(MAKE) $(MAKEDEFS) $$target) || exit 1; \
|
||||||
|
done
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for maintenance
|
||||||
|
#
|
||||||
|
|
||||||
|
Makefile: Makefile.in config.status
|
||||||
|
CONFIG_HEADERS= ./config.status
|
||||||
|
|
||||||
|
config.status: configure
|
||||||
|
./config.status --recheck
|
||||||
|
|
||||||
|
configure: configure.in aclocal.m4
|
||||||
|
cd $(srcdir) && autoconf
|
||||||
|
|
||||||
|
src/config.h: stamp-h
|
||||||
|
stamp-h: src/config.h.in config.status
|
||||||
|
CONFIG_FILES= CONFIG_HEADERS=src/config.h ./config.status
|
||||||
|
|
||||||
|
src/config.h.in: stamp-h.in
|
||||||
|
stamp-h.in: configure.in aclocal.m4
|
||||||
|
echo timestamp > $@
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
238
NEWS
Normal file
238
NEWS
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
GNU Wget NEWS -- history of user-visible changes.
|
||||||
|
|
||||||
|
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
See the end for copying conditions.
|
||||||
|
|
||||||
|
Please send GNU Wget bug reports to <bug-wget@gnu.org>.
|
||||||
|
|
||||||
|
* Wget 1.5.3 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Wget 1.5.2 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Wget 1.5.1 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Changes in Wget 1.5.0
|
||||||
|
|
||||||
|
** Wget speaks many languages!
|
||||||
|
|
||||||
|
On systems with gettext(), Wget will output messages in the language
|
||||||
|
set by the current locale, if available. At this time we support
|
||||||
|
Czech, German, Croatian, Italian, Norwegian and Portuguese.
|
||||||
|
|
||||||
|
** Opie (Skey) is now supported with FTP.
|
||||||
|
|
||||||
|
** HTTP Digest Access Authentication (RFC2069) is now supported.
|
||||||
|
|
||||||
|
** The new `-b' option makes Wget go to background automatically.
|
||||||
|
|
||||||
|
** The `-I' and `-X' options now accept wildcard arguments.
|
||||||
|
|
||||||
|
** The `-w' option now accepts suffixes `s' for seconds, `m' for
|
||||||
|
minutes, `h' for hours, `d' for days and `w' for weeks.
|
||||||
|
|
||||||
|
** Upon getting SIGHUP, the whole previous log is now copied to
|
||||||
|
`wget-log'.
|
||||||
|
|
||||||
|
** Wget now understands proxy settings with explicit usernames and
|
||||||
|
passwords, e.g. `http://user:password@proxy.foo.com/'.
|
||||||
|
|
||||||
|
** You can use the new `--cut-dirs' option to make Wget create less
|
||||||
|
directories.
|
||||||
|
|
||||||
|
** The `;type=a' appendix to FTP URLs is now recognized. For
|
||||||
|
instance, the following command will retrieve the welcoming message in
|
||||||
|
ASCII type transfer:
|
||||||
|
|
||||||
|
wget "ftp://ftp.somewhere.com/welcome.msg;type=a"
|
||||||
|
|
||||||
|
** `--help' and `--version' options have been redone to to conform to
|
||||||
|
standards set by other GNU utilities.
|
||||||
|
|
||||||
|
** Wget should now be compilable under MS Windows environment. MS
|
||||||
|
Visual C++ and Watcom C have been used successfully.
|
||||||
|
|
||||||
|
** If the file length is known, percentages are displayed during
|
||||||
|
download.
|
||||||
|
|
||||||
|
** The manual page, now hopelessly out of date, is no longer
|
||||||
|
distributed with Wget.
|
||||||
|
|
||||||
|
* Wget 1.4.5 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Wget 1.4.4 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Changes in Wget 1.4.3
|
||||||
|
|
||||||
|
** Wget is now a GNU utility.
|
||||||
|
|
||||||
|
** Can do passive FTP.
|
||||||
|
|
||||||
|
** Reads .netrc.
|
||||||
|
|
||||||
|
** Info documentation expanded.
|
||||||
|
|
||||||
|
** Compiles on pre-ANSI compilers.
|
||||||
|
|
||||||
|
** Global wgetrc now goes to /usr/local/etc (i.e. $sysconfdir).
|
||||||
|
|
||||||
|
** Lots of bugfixes.
|
||||||
|
|
||||||
|
* Changes in Wget 1.4.2
|
||||||
|
|
||||||
|
** New mirror site at ftp://sunsite.auc.dk/pub/infosystems/wget/,
|
||||||
|
thanks to Karsten Thygesen.
|
||||||
|
|
||||||
|
** Mailing list! Mail to wget-request@sunsite.auc.dk to subscribe.
|
||||||
|
|
||||||
|
** New option --delete-after for proxy prefetching.
|
||||||
|
|
||||||
|
** New option --retr-symlinks to retrieve symbolic links like plain
|
||||||
|
files.
|
||||||
|
|
||||||
|
** rmold.pl -- script to remove files deleted on the remote server
|
||||||
|
|
||||||
|
** --convert-links should work now.
|
||||||
|
|
||||||
|
** Minor bugfixes.
|
||||||
|
|
||||||
|
* Changes in Wget 1.4.1
|
||||||
|
|
||||||
|
** Minor bugfixes.
|
||||||
|
|
||||||
|
** Added -I (the opposite of -X).
|
||||||
|
|
||||||
|
** Dot tracing is now customizable; try wget --dot-style=binary
|
||||||
|
|
||||||
|
* Changes in Wget 1.4.0
|
||||||
|
|
||||||
|
** Wget 1.4.0 [formerly known as Geturl] is an extensive rewrite of
|
||||||
|
Geturl. Although many things look suspiciously similar, most of the
|
||||||
|
stuff was rewritten, like recursive retrieval, HTTP, FTP and mostly
|
||||||
|
everything else. Wget should be now easier to debug, maintain and,
|
||||||
|
most importantly, use.
|
||||||
|
|
||||||
|
** Recursive HTTP should now work without glitches, even with Location
|
||||||
|
changes, server-generated directory listings and other naughty stuff.
|
||||||
|
|
||||||
|
** HTTP regetting is supported on servers that support Range
|
||||||
|
specification. WWW authorization is supported -- try
|
||||||
|
wget http://user:password@hostname/
|
||||||
|
|
||||||
|
** FTP support was rewritten and widely enhanced. Globbing should now
|
||||||
|
work flawlessly. Symbolic links are created locally. All the
|
||||||
|
information the Unix-style ls listing can give is now recognized.
|
||||||
|
|
||||||
|
** Recursive FTP is supported, e.g.
|
||||||
|
wget -r ftp://gnjilux.cc.fer.hr/pub/unix/util/
|
||||||
|
|
||||||
|
** You can specify "rejected" directories, to which you do not want to
|
||||||
|
enter, e.g. with wget -X /pub
|
||||||
|
|
||||||
|
** Time-stamping is supported, with both HTTP and FTP. Try wget -N URL.
|
||||||
|
|
||||||
|
** A new texinfo reference manual is provided. It can be read with
|
||||||
|
Emacs, standalone info, or converted to HTML, dvi or postscript.
|
||||||
|
|
||||||
|
** Fixed a long-standing bug, so that Wget now works over SLIP
|
||||||
|
connections.
|
||||||
|
|
||||||
|
** You can have a system-wide wgetrc (/usr/local/lib/wgetrc by
|
||||||
|
default). Settings in $HOME/.wgetrc override the global ones, of
|
||||||
|
course :-)
|
||||||
|
|
||||||
|
** You can set up quota in .wgetrc to prevent sucking too much
|
||||||
|
data. Try `quota = 5M' in .wgetrc (or quota = 100K if you want your
|
||||||
|
sysadmin to like you).
|
||||||
|
|
||||||
|
** Download rate is printed after retrieval.
|
||||||
|
|
||||||
|
** Wget now sends the `Referer' header when retrieving
|
||||||
|
recursively.
|
||||||
|
|
||||||
|
** With the new --no-parent option Wget can retrieve FTP recursively
|
||||||
|
through a proxy server.
|
||||||
|
|
||||||
|
** HTML parser, as well as the whole of Wget was rewritten to be much
|
||||||
|
faster and less memory-consuming (yes, both).
|
||||||
|
|
||||||
|
** Absolute links can be converted to relative links locally. Check
|
||||||
|
wget -k.
|
||||||
|
|
||||||
|
** Wget catches hangup, filtering the output to a log file and
|
||||||
|
resuming work. Try kill -HUP %?wget.
|
||||||
|
|
||||||
|
** User-defined headers can be sent. Try
|
||||||
|
|
||||||
|
wget http://fly.cc.her.hr/ --header='Accept-Charset: iso-8859-2'
|
||||||
|
|
||||||
|
** Acceptance/Rejection lists may contain wildcards.
|
||||||
|
|
||||||
|
** Wget can display HTTP headers and/or FTP server response with the
|
||||||
|
new `-S' option. It can save the original HTTP headers with `-s'.
|
||||||
|
|
||||||
|
** socks library is now supported (thanks to Antonio Rosella
|
||||||
|
<Antonio.Rosella@agip.it>). Configure with --with-socks.
|
||||||
|
|
||||||
|
** There is a nicer display of REST-ed output.
|
||||||
|
|
||||||
|
** Many new options (like -x to force directory hierarchy, or -m to
|
||||||
|
turn on mirroring options).
|
||||||
|
|
||||||
|
** Wget is now distributed under GNU General Public License (GPL).
|
||||||
|
|
||||||
|
** Lots of small features I can't remember. :-)
|
||||||
|
|
||||||
|
** A host of bugfixes.
|
||||||
|
|
||||||
|
* Changes in Geturl 1.3
|
||||||
|
|
||||||
|
** Added FTP globbing support (ftp://fly.cc.fer.hr/*)
|
||||||
|
|
||||||
|
** Added support for no_proxy
|
||||||
|
|
||||||
|
** Added support for ftp://user:password@host/
|
||||||
|
|
||||||
|
** Added support for %xx in URL syntax
|
||||||
|
|
||||||
|
** More natural command-line options
|
||||||
|
|
||||||
|
** Added -e switch to execute .geturlrc commands from the command-line
|
||||||
|
|
||||||
|
** Added support for robots.txt
|
||||||
|
|
||||||
|
** Fixed some minor bugs
|
||||||
|
|
||||||
|
* Geturl 1.2 is a bugfix release with no user-visible changes.
|
||||||
|
|
||||||
|
* Changes in Geturl 1.1
|
||||||
|
|
||||||
|
** REST supported in FTP
|
||||||
|
|
||||||
|
** Proxy servers supported
|
||||||
|
|
||||||
|
** GNU getopt used, which enables command-line arguments to be ordered
|
||||||
|
as you wish, e.g. geturl http://fly.cc.fer.hr/ -vo log is the same as
|
||||||
|
geturl -vo log http://fly.cc.fer.hr/
|
||||||
|
|
||||||
|
** Netscape-compatible URL syntax for HTTP supported: host[:port]/dir/file
|
||||||
|
|
||||||
|
** NcFTP-compatible colon URL syntax for FTP supported: host:/dir/file
|
||||||
|
|
||||||
|
** <base href="xxx"> supported
|
||||||
|
|
||||||
|
** autoconf supported
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright information:
|
||||||
|
|
||||||
|
Copyright (C) 1997, 1998 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.
|
80
README
Normal file
80
README
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
-*- text -*-
|
||||||
|
GNU Wget README
|
||||||
|
|
||||||
|
GNU Wget is a free network utility to retrieve files from the World
|
||||||
|
Wide Web using HTTP and FTP, the two most widely used Internet
|
||||||
|
protocols. It works non-interactively, thus enabling work in the
|
||||||
|
background, after having logged off.
|
||||||
|
|
||||||
|
The recursive retrieval of HTML pages, as well as FTP sites is
|
||||||
|
supported -- you can use Wget to make mirrors of archives and home
|
||||||
|
pages, or traverse the web like a WWW robot (Wget understands
|
||||||
|
/robots.txt).
|
||||||
|
|
||||||
|
Wget works exceedingly well on slow or unstable connections, keeping
|
||||||
|
getting the document until it is fully retrieved. Re-getting files
|
||||||
|
from where it left off works on servers (both HTTP and FTP) that
|
||||||
|
support it. Matching of wildcards and recursive mirroring of
|
||||||
|
directories are available when retrieving via FTP. Both HTTP and FTP
|
||||||
|
retrievals can be time-stamped, thus Wget can see if the remote file
|
||||||
|
has changed since last retrieval and automatically retrieve the new
|
||||||
|
version if it has.
|
||||||
|
|
||||||
|
Wget supports proxy servers, which can lighten the network load, speed
|
||||||
|
up retrieval and provide access behind firewalls. If you are behind a
|
||||||
|
firewall that requires the use of a socks style gateway, you can get
|
||||||
|
the socks library and compile wget with support for socks.
|
||||||
|
|
||||||
|
Most of the features are configurable, either through command-line
|
||||||
|
options, or via initialization file .wgetrc. Wget allows you to
|
||||||
|
install a global startup file (/usr/local/etc/wgetrc by default) for
|
||||||
|
site settings.
|
||||||
|
|
||||||
|
Wget works under almost all modern Unix variants and, unlike many
|
||||||
|
other similar utilities, is written entirely in C, thus requiring no
|
||||||
|
additional software (like perl). As Wget uses the GNU Autoconf, it is
|
||||||
|
easily built on and ported to other Unix's. Installation procedure is
|
||||||
|
described in the INSTALL file.
|
||||||
|
|
||||||
|
Like all GNU utilities, the latest version of Wget can be found at the
|
||||||
|
master GNU archive site prep.ai.mit.edu, and its mirrors. For
|
||||||
|
example, Wget 1.5.2 is at:
|
||||||
|
<URL:ftp://prep.ai.mit.edu/pub/gnu/wget-1.5.2.tar.gz>.
|
||||||
|
|
||||||
|
The latest version is also available via FTP from the maintainer's
|
||||||
|
machine, at:
|
||||||
|
<URL:ftp://gnjilux.cc.fer.hr/pub/unix/util/wget/wget.tar.gz>.
|
||||||
|
|
||||||
|
This location is mirrored at:
|
||||||
|
<URL:ftp://sunsite.auc.dk/pub/infosystems/wget/> and
|
||||||
|
<URL:http://sunsite.auc.dk/ftp/pub/infosystems/wget/>.
|
||||||
|
|
||||||
|
Please report bugs in Wget to <bug-wget@prep.ai.mit.edu>.
|
||||||
|
|
||||||
|
Wget has a own mailing list at <wget@sunsite.auc.dk>. To subscribe,
|
||||||
|
mail to <wget-subscribe@sunsite.auc.dk>.
|
||||||
|
|
||||||
|
Wget is free in all senses -- it is freely redistributable, and no
|
||||||
|
payment is required. If you still wish to donate money to the author,
|
||||||
|
or wish to sponsor implementation of specific features, please email
|
||||||
|
me at <hniksic@srce.hr>.
|
||||||
|
|
||||||
|
|
||||||
|
AUTHOR: Hrvoje Niksic <URL:mailto:hniksic@srce.hr>
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 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 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
78
TODO
Normal file
78
TODO
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
Hey Emacs, this is -*- outline -*- mode
|
||||||
|
|
||||||
|
This is the todo list for Wget. I don't have any time-table of when I
|
||||||
|
plan to implement these features; this is just a list of things I'd
|
||||||
|
like to see in Wget. I'll work on some of them myself, and I will
|
||||||
|
accept patches in their direction. The items are not listed in any
|
||||||
|
particular order. Not all of them are user-visible changes.
|
||||||
|
|
||||||
|
* Make `-k' convert <base href=...> too.
|
||||||
|
|
||||||
|
* Add option to clobber existing file names (no `.N' suffixes).
|
||||||
|
|
||||||
|
* Introduce a concept of "boolean" options. For instance, every
|
||||||
|
boolean option `--foo' would have a `--no-foo' equivalent for
|
||||||
|
turning it off. Get rid of `--foo=no' stuff. Short options would
|
||||||
|
be handled as `-x' vs. `-nx'.
|
||||||
|
|
||||||
|
* Implement "thermometer" display (not all that hard; use an
|
||||||
|
alternative show_progress() if the output goes to a terminal.)
|
||||||
|
|
||||||
|
* Add option to only list wildcard matches without doing the download.
|
||||||
|
|
||||||
|
* Add case-insensitivity as an option.
|
||||||
|
|
||||||
|
* Add option to download all files needed to display a web page
|
||||||
|
(images, etc.)
|
||||||
|
|
||||||
|
* Handle MIME types correctly. There should be an option to (not)
|
||||||
|
retrieve files based on MIME types, e.g. `--accept-types=image/*'.
|
||||||
|
|
||||||
|
* Implement "persistent" retrieving. In "persistent" mode Wget should
|
||||||
|
treat most of the errors as transient.
|
||||||
|
|
||||||
|
* Allow time-stamping by arbitrary date.
|
||||||
|
|
||||||
|
* Fix Unix directory parser to allow for spaces in file names.
|
||||||
|
|
||||||
|
* Allow size limit to files.
|
||||||
|
|
||||||
|
* -k should convert convert relative references to absolute if not
|
||||||
|
downloaded.
|
||||||
|
|
||||||
|
* Recognize HTML comments correctly. Add more options for handling
|
||||||
|
bogus HTML found all over the 'net.
|
||||||
|
|
||||||
|
* Implement breadth-first retrieval.
|
||||||
|
|
||||||
|
* Download to .in* when mirroring.
|
||||||
|
|
||||||
|
* Add an option to delete or move no-longer-existent files when
|
||||||
|
mirroring.
|
||||||
|
|
||||||
|
* Implement a switch to avoid downloading multiple files (e.g. x and
|
||||||
|
x.gz).
|
||||||
|
|
||||||
|
* Implement uploading (--upload URL?) in FTP and HTTP.
|
||||||
|
|
||||||
|
* Rewrite FTP code to allow for easy addition of new commands. It
|
||||||
|
should probably be coded as a simple DFA engine.
|
||||||
|
|
||||||
|
* Recognize more FTP servers (VMS).
|
||||||
|
|
||||||
|
* Make HTTP timestamping use If-Modified-Since facility.
|
||||||
|
|
||||||
|
* Implement better spider options.
|
||||||
|
|
||||||
|
* Add more protocols (e.g. gopher and news), implementing them in a
|
||||||
|
modular fashion.
|
||||||
|
|
||||||
|
* Implement a concept of "packages" a la mirror.
|
||||||
|
|
||||||
|
* Implement correct RFC1808 URL parsing.
|
||||||
|
|
||||||
|
* Implement HTTP cookies.
|
||||||
|
|
||||||
|
* Implement more HTTP/1.1 bells and whistles (ETag, Content-MD5 etc.)
|
||||||
|
|
||||||
|
* Support SSL encryption through SSLeay.
|
251
aclocal.m4
vendored
Normal file
251
aclocal.m4
vendored
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
AC_DEFUN(AM_C_PROTOTYPES,
|
||||||
|
[AC_REQUIRE([AM_PROG_CC_STDC])
|
||||||
|
AC_BEFORE([$0], [AC_C_INLINE])
|
||||||
|
AC_MSG_CHECKING([for function prototypes])
|
||||||
|
if test "$am_cv_prog_cc_stdc" != no; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(PROTOTYPES)
|
||||||
|
U= ANSI2KNR=
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
U=_ ANSI2KNR=./ansi2knr
|
||||||
|
# Ensure some checks needed by ansi2knr itself.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS(string.h)
|
||||||
|
fi
|
||||||
|
AC_SUBST(U)dnl
|
||||||
|
AC_SUBST(ANSI2KNR)dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# serial 1
|
||||||
|
|
||||||
|
# @defmac AC_PROG_CC_STDC
|
||||||
|
# @maindex PROG_CC_STDC
|
||||||
|
# @ovindex CC
|
||||||
|
# If the C compiler in not in ANSI C mode by default, try to add an option
|
||||||
|
# to output variable @code{CC} to make it so. This macro tries various
|
||||||
|
# options that select ANSI C on some system or another. It considers the
|
||||||
|
# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
|
||||||
|
# handles function prototypes correctly.
|
||||||
|
#
|
||||||
|
# If you use this macro, you should check after calling it whether the C
|
||||||
|
# compiler has been set to accept ANSI C; if not, the shell variable
|
||||||
|
# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
|
||||||
|
# code in ANSI C, you can make an un-ANSIfied copy of it by using the
|
||||||
|
# program @code{ansi2knr}, which comes with Ghostscript.
|
||||||
|
# @end defmac
|
||||||
|
|
||||||
|
AC_DEFUN(AM_PROG_CC_STDC,
|
||||||
|
[AC_REQUIRE([AC_PROG_CC])
|
||||||
|
AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
|
||||||
|
AC_CACHE_VAL(am_cv_prog_cc_stdc,
|
||||||
|
[am_cv_prog_cc_stdc=no
|
||||||
|
ac_save_CC="$CC"
|
||||||
|
# Don't try gcc -ansi; that turns off useful extensions and
|
||||||
|
# breaks some systems' header files.
|
||||||
|
# AIX -qlanglvl=ansi
|
||||||
|
# Ultrix and OSF/1 -std1
|
||||||
|
# HP-UX -Aa -D_HPUX_SOURCE
|
||||||
|
# SVR4 -Xc -D__EXTENSIONS__
|
||||||
|
for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
|
||||||
|
do
|
||||||
|
CC="$ac_save_CC $ac_arg"
|
||||||
|
AC_TRY_COMPILE(
|
||||||
|
[#if !defined(__STDC__) || __STDC__ != 1
|
||||||
|
choke me
|
||||||
|
#endif
|
||||||
|
/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
|
||||||
|
#ifdef _SEQUENT_
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
], [
|
||||||
|
int test (int i, double x);
|
||||||
|
struct s1 {int (*f) (int a);};
|
||||||
|
struct s2 {int (*f) (double a);};],
|
||||||
|
[am_cv_prog_cc_stdc="$ac_arg"; break])
|
||||||
|
done
|
||||||
|
CC="$ac_save_CC"
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($am_cv_prog_cc_stdc)
|
||||||
|
case "x$am_cv_prog_cc_stdc" in
|
||||||
|
x|xno) ;;
|
||||||
|
*) CC="$CC $am_cv_prog_cc_stdc" ;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN(WGET_STRUCT_UTIMBUF,
|
||||||
|
[AC_MSG_CHECKING(for struct utimbuf)
|
||||||
|
if test x"$ac_cv_header_utime_h" = xyes; then
|
||||||
|
AC_EGREP_CPP([struct[ ]+utimbuf],
|
||||||
|
[#include <utime.h>],
|
||||||
|
[AC_DEFINE(HAVE_STRUCT_UTIMBUF)
|
||||||
|
AC_MSG_RESULT(yes)],
|
||||||
|
AC_MSG_RESULT(no))
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi])
|
||||||
|
|
||||||
|
|
||||||
|
# This code originates from Ulrich Drepper's AM_WITH_NLS.
|
||||||
|
|
||||||
|
AC_DEFUN(WGET_WITH_NLS,
|
||||||
|
[AC_MSG_CHECKING([whether NLS is requested])
|
||||||
|
dnl Default is enabled NLS
|
||||||
|
AC_ARG_ENABLE(nls,
|
||||||
|
[ --disable-nls do not use Native Language Support],
|
||||||
|
HAVE_NLS=$enableval, HAVE_NLS=yes)
|
||||||
|
AC_MSG_RESULT($HAVE_NLS)
|
||||||
|
|
||||||
|
dnl If something goes wrong, we may still decide not to use NLS.
|
||||||
|
dnl For this reason, defer AC_SUBST'ing HAVE_NLS until the very
|
||||||
|
dnl last moment.
|
||||||
|
|
||||||
|
if test x"$HAVE_NLS" = xyes; then
|
||||||
|
AC_MSG_RESULT("language catalogs: $ALL_LINGUAS")
|
||||||
|
AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
|
||||||
|
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
|
||||||
|
AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
|
||||||
|
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
|
||||||
|
AC_SUBST(MSGFMT)
|
||||||
|
AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
|
||||||
|
CATOBJEXT=.gmo
|
||||||
|
INSTOBJEXT=.mo
|
||||||
|
DATADIRNAME=share
|
||||||
|
|
||||||
|
dnl Test whether we really found GNU xgettext.
|
||||||
|
if test "$XGETTEXT" != ":"; then
|
||||||
|
dnl If it is no GNU xgettext we define it as : so that the
|
||||||
|
dnl Makefiles still can work.
|
||||||
|
if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
|
||||||
|
: ;
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(
|
||||||
|
[found xgettext programs is not GNU xgettext; ignore it])
|
||||||
|
XGETTEXT=":"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(locale.h libintl.h)
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS(gettext, [], [
|
||||||
|
AC_CHECK_LIB(intl, gettext, [
|
||||||
|
dnl gettext is in libintl; announce the fact manually.
|
||||||
|
LIBS="-lintl $LIBS"
|
||||||
|
AC_DEFINE(HAVE_GETTEXT)
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(
|
||||||
|
[gettext not found; disabling NLS])
|
||||||
|
HAVE_NLS=no
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl These rules are solely for the distribution goal. While doing this
|
||||||
|
dnl we only have to keep exactly one list of the available catalogs
|
||||||
|
dnl in configure.in.
|
||||||
|
for lang in $ALL_LINGUAS; do
|
||||||
|
GMOFILES="$GMOFILES $lang.gmo"
|
||||||
|
POFILES="$POFILES $lang.po"
|
||||||
|
done
|
||||||
|
dnl Construct list of names of catalog files to be constructed.
|
||||||
|
for lang in $ALL_LINGUAS; do
|
||||||
|
CATALOGS="$CATALOGS ${lang}${CATOBJEXT}"
|
||||||
|
done
|
||||||
|
|
||||||
|
dnl Make all variables we use known to autoconf.
|
||||||
|
AC_SUBST(CATALOGS)
|
||||||
|
AC_SUBST(CATOBJEXT)
|
||||||
|
AC_SUBST(DATADIRNAME)
|
||||||
|
AC_SUBST(GMOFILES)
|
||||||
|
AC_SUBST(INSTOBJEXT)
|
||||||
|
AC_SUBST(INTLLIBS)
|
||||||
|
AC_SUBST(POFILES)
|
||||||
|
fi
|
||||||
|
AC_SUBST(HAVE_NLS)
|
||||||
|
dnl Some independently maintained files, such as po/Makefile.in,
|
||||||
|
dnl use `USE_NLS', so support it.
|
||||||
|
USE_NLS=$HAVE_NLS
|
||||||
|
AC_SUBST(USE_NLS)
|
||||||
|
if test "x$HAVE_NLS" = xyes; then
|
||||||
|
AC_DEFINE(HAVE_NLS)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Generate list of files to be processed by xgettext which will
|
||||||
|
dnl be included in po/Makefile.
|
||||||
|
dnl
|
||||||
|
dnl This is not strictly an Autoconf macro, because it is run from
|
||||||
|
dnl within `config.status' rather than from within configure. This
|
||||||
|
dnl is why special rules must be applied for it.
|
||||||
|
AC_DEFUN(WGET_PROCESS_PO,
|
||||||
|
[srcdir=$ac_given_srcdir # Advanced autoconf hackery
|
||||||
|
dnl I wonder what the following several lines do...
|
||||||
|
if test "x$srcdir" != "x."; then
|
||||||
|
if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
|
||||||
|
posrcprefix="$srcdir/"
|
||||||
|
else
|
||||||
|
posrcprefix="../$srcdir/"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
posrcprefix="../"
|
||||||
|
fi
|
||||||
|
rm -f po/POTFILES
|
||||||
|
dnl Use `echo' rather than AC_MSG_RESULT, because this is run from
|
||||||
|
dnl `config.status'.
|
||||||
|
echo "generating po/POTFILES from $srcdir/po/POTFILES.in"
|
||||||
|
sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," \
|
||||||
|
-e "\$s/\(.*\) \\\\/\1/" \
|
||||||
|
< $srcdir/po/POTFILES.in > po/POTFILES
|
||||||
|
echo "creating po/Makefile"
|
||||||
|
sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
|
||||||
|
])
|
||||||
|
|
||||||
|
# Search path for a program which passes the given test.
|
||||||
|
# Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
|
#
|
||||||
|
# This file may be copied and used freely without restrictions. It
|
||||||
|
# can be used in projects which are not available under the GNU Public
|
||||||
|
# License but which still want to provide support for the GNU gettext
|
||||||
|
# functionality. Please note that the actual code is *not* freely
|
||||||
|
# available.
|
||||||
|
|
||||||
|
# serial 1
|
||||||
|
|
||||||
|
dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
|
||||||
|
dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
|
||||||
|
AC_DEFUN(AM_PATH_PROG_WITH_TEST,
|
||||||
|
[# Extract the first word of "$2", so it can be a program name with args.
|
||||||
|
set dummy $2; ac_word=[$]2
|
||||||
|
AC_MSG_CHECKING([for $ac_word])
|
||||||
|
AC_CACHE_VAL(ac_cv_path_$1,
|
||||||
|
[case "[$]$1" in
|
||||||
|
/*)
|
||||||
|
ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||||
|
for ac_dir in ifelse([$5], , $PATH, [$5]); do
|
||||||
|
test -z "$ac_dir" && ac_dir=.
|
||||||
|
if test -f $ac_dir/$ac_word; then
|
||||||
|
if [$3]; then
|
||||||
|
ac_cv_path_$1="$ac_dir/$ac_word"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$ac_save_ifs"
|
||||||
|
dnl If no 4th arg is given, leave the cache variable unset,
|
||||||
|
dnl so AC_PATH_PROGS will keep looking.
|
||||||
|
ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
|
||||||
|
])dnl
|
||||||
|
;;
|
||||||
|
esac])dnl
|
||||||
|
$1="$ac_cv_path_$1"
|
||||||
|
if test -n "[$]$1"; then
|
||||||
|
AC_MSG_RESULT([$]$1)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
AC_SUBST($1)dnl
|
||||||
|
])
|
693
config.guess
vendored
Executable file
693
config.guess
vendored
Executable file
@ -0,0 +1,693 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Attempt to guess a canonical system name.
|
||||||
|
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Written by Per Bothner <bothner@cygnus.com>.
|
||||||
|
# The master version of this file is at the FSF in /home/gd/gnu/lib.
|
||||||
|
#
|
||||||
|
# This script attempts to guess a canonical system name similar to
|
||||||
|
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||||
|
# exits with 0. Otherwise, it exits with 1.
|
||||||
|
#
|
||||||
|
# The plan is that this can be called by configure scripts if you
|
||||||
|
# don't specify an explicit system type (host/target name).
|
||||||
|
#
|
||||||
|
# Only a few systems have been added to this list; please add others
|
||||||
|
# (but try to keep the structure clean).
|
||||||
|
#
|
||||||
|
|
||||||
|
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||||
|
# (ghazi@noc.rutgers.edu 8/24/94.)
|
||||||
|
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
|
||||||
|
PATH=$PATH:/.attbin ; export PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
|
||||||
|
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||||
|
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||||
|
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||||
|
|
||||||
|
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
|
||||||
|
|
||||||
|
# Note: order is significant - the case branches are not exclusive.
|
||||||
|
|
||||||
|
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
|
alpha:OSF1:*:*)
|
||||||
|
# A Vn.n version is a released version.
|
||||||
|
# A Tn.n version is a released field test version.
|
||||||
|
# A Xn.n version is an unreleased experimental baselevel.
|
||||||
|
# 1.2 uses "1.2" for uname -r.
|
||||||
|
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
|
||||||
|
exit 0 ;;
|
||||||
|
21064:Windows_NT:50:3)
|
||||||
|
echo alpha-dec-winnt3.5
|
||||||
|
exit 0 ;;
|
||||||
|
Amiga*:UNIX_System_V:4.0:*)
|
||||||
|
echo m68k-cbm-sysv4
|
||||||
|
exit 0;;
|
||||||
|
amiga:NetBSD:*:*)
|
||||||
|
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
amiga:OpenBSD:*:*)
|
||||||
|
echo m68k-cbm-openbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||||
|
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||||
|
exit 0;;
|
||||||
|
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
|
||||||
|
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
|
||||||
|
if test "`(/bin/universe) 2>/dev/null`" = att ; then
|
||||||
|
echo pyramid-pyramid-sysv3
|
||||||
|
else
|
||||||
|
echo pyramid-pyramid-bsd
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
NILE:*:*:dcosx)
|
||||||
|
echo pyramid-pyramid-svr4
|
||||||
|
exit 0 ;;
|
||||||
|
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||||
|
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
i86pc:SunOS:5.*:*)
|
||||||
|
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
sun4*:SunOS:6*:*)
|
||||||
|
# According to config.sub, this is the proper way to canonicalize
|
||||||
|
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
|
||||||
|
# it's likely to be more like Solaris than SunOS4.
|
||||||
|
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
sun4*:SunOS:*:*)
|
||||||
|
case "`/usr/bin/arch -k`" in
|
||||||
|
Series*|S4*)
|
||||||
|
UNAME_RELEASE=`uname -v`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Japanese Language versions have a version number like `4.1.3-JL'.
|
||||||
|
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
|
||||||
|
exit 0 ;;
|
||||||
|
sun3*:SunOS:*:*)
|
||||||
|
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
aushp:SunOS:*:*)
|
||||||
|
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
atari*:NetBSD:*:*)
|
||||||
|
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
atari*:OpenBSD:*:*)
|
||||||
|
echo m68k-atari-openbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
sun3*:NetBSD:*:*)
|
||||||
|
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
sun3*:OpenBSD:*:*)
|
||||||
|
echo m68k-sun-openbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
mac68k:NetBSD:*:*)
|
||||||
|
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
mac68k:OpenBSD:*:*)
|
||||||
|
echo m68k-apple-openbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
powerpc:machten:*:*)
|
||||||
|
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
RISC*:Mach:*:*)
|
||||||
|
echo mips-dec-mach_bsd4.3
|
||||||
|
exit 0 ;;
|
||||||
|
RISC*:ULTRIX:*:*)
|
||||||
|
echo mips-dec-ultrix${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
VAX*:ULTRIX*:*:*)
|
||||||
|
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||||
|
sed 's/^ //' << EOF >dummy.c
|
||||||
|
int main (argc, argv) int argc; char **argv; {
|
||||||
|
#if defined (host_mips) && defined (MIPSEB)
|
||||||
|
#if defined (SYSTYPE_SYSV)
|
||||||
|
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
|
||||||
|
#endif
|
||||||
|
#if defined (SYSTYPE_SVR4)
|
||||||
|
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
|
||||||
|
#endif
|
||||||
|
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
|
||||||
|
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
${CC-cc} dummy.c -o dummy \
|
||||||
|
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||||
|
&& rm dummy.c dummy && exit 0
|
||||||
|
rm -f dummy.c dummy
|
||||||
|
echo mips-mips-riscos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
Night_Hawk:Power_UNIX:*:*)
|
||||||
|
echo powerpc-harris-powerunix
|
||||||
|
exit 0 ;;
|
||||||
|
m88k:CX/UX:7*:*)
|
||||||
|
echo m88k-harris-cxux7
|
||||||
|
exit 0 ;;
|
||||||
|
m88k:*:4*:R4*)
|
||||||
|
echo m88k-motorola-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
m88k:*:3*:R3*)
|
||||||
|
echo m88k-motorola-sysv3
|
||||||
|
exit 0 ;;
|
||||||
|
AViiON:dgux:*:*)
|
||||||
|
# DG/UX returns AViiON for all architectures
|
||||||
|
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||||
|
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||||
|
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
|
||||||
|
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
|
||||||
|
echo m88k-dg-dgux${UNAME_RELEASE}
|
||||||
|
else
|
||||||
|
echo m88k-dg-dguxbcs${UNAME_RELEASE}
|
||||||
|
fi
|
||||||
|
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||||
|
echo m88k-dolphin-sysv3
|
||||||
|
exit 0 ;;
|
||||||
|
M88*:*:R3*:*)
|
||||||
|
# Delta 88k system running SVR3
|
||||||
|
echo m88k-motorola-sysv3
|
||||||
|
exit 0 ;;
|
||||||
|
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
|
||||||
|
echo m88k-tektronix-sysv3
|
||||||
|
exit 0 ;;
|
||||||
|
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
|
||||||
|
echo m68k-tektronix-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
*:IRIX*:*:*)
|
||||||
|
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
|
||||||
|
exit 0 ;;
|
||||||
|
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
|
||||||
|
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
|
||||||
|
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
|
||||||
|
i?86:AIX:*:*)
|
||||||
|
echo i386-ibm-aix
|
||||||
|
exit 0 ;;
|
||||||
|
*:AIX:2:3)
|
||||||
|
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||||
|
sed 's/^ //' << EOF >dummy.c
|
||||||
|
#include <sys/systemcfg.h>
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
if (!__power_pc())
|
||||||
|
exit(1);
|
||||||
|
puts("powerpc-ibm-aix3.2.5");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||||
|
rm -f dummy.c dummy
|
||||||
|
echo rs6000-ibm-aix3.2.5
|
||||||
|
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||||
|
echo rs6000-ibm-aix3.2.4
|
||||||
|
else
|
||||||
|
echo rs6000-ibm-aix3.2
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
*:AIX:*:4)
|
||||||
|
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
|
||||||
|
IBM_ARCH=rs6000
|
||||||
|
else
|
||||||
|
IBM_ARCH=powerpc
|
||||||
|
fi
|
||||||
|
if [ -x /usr/bin/oslevel ] ; then
|
||||||
|
IBM_REV=`/usr/bin/oslevel`
|
||||||
|
else
|
||||||
|
IBM_REV=4.${UNAME_RELEASE}
|
||||||
|
fi
|
||||||
|
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
|
||||||
|
exit 0 ;;
|
||||||
|
*:AIX:*:*)
|
||||||
|
echo rs6000-ibm-aix
|
||||||
|
exit 0 ;;
|
||||||
|
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
|
||||||
|
echo romp-ibm-bsd4.4
|
||||||
|
exit 0 ;;
|
||||||
|
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||||
|
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
|
||||||
|
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||||
|
*:BOSX:*:*)
|
||||||
|
echo rs6000-bull-bosx
|
||||||
|
exit 0 ;;
|
||||||
|
DPX/2?00:B.O.S.:*:*)
|
||||||
|
echo m68k-bull-sysv3
|
||||||
|
exit 0 ;;
|
||||||
|
9000/[34]??:4.3bsd:1.*:*)
|
||||||
|
echo m68k-hp-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
|
||||||
|
echo m68k-hp-bsd4.4
|
||||||
|
exit 0 ;;
|
||||||
|
9000/[3478]??:HP-UX:*:*)
|
||||||
|
case "${UNAME_MACHINE}" in
|
||||||
|
9000/31? ) HP_ARCH=m68000 ;;
|
||||||
|
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||||
|
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
|
||||||
|
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||||
|
esac
|
||||||
|
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
|
||||||
|
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||||
|
exit 0 ;;
|
||||||
|
3050*:HI-UX:*:*)
|
||||||
|
sed 's/^ //' << EOF >dummy.c
|
||||||
|
#include <unistd.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
long cpu = sysconf (_SC_CPU_VERSION);
|
||||||
|
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
|
||||||
|
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
|
||||||
|
results, however. */
|
||||||
|
if (CPU_IS_PA_RISC (cpu))
|
||||||
|
{
|
||||||
|
switch (cpu)
|
||||||
|
{
|
||||||
|
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
|
||||||
|
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
|
||||||
|
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
|
||||||
|
default: puts ("hppa-hitachi-hiuxwe2"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CPU_IS_HP_MC68K (cpu))
|
||||||
|
puts ("m68k-hitachi-hiuxwe2");
|
||||||
|
else puts ("unknown-hitachi-hiuxwe2");
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||||
|
rm -f dummy.c dummy
|
||||||
|
echo unknown-hitachi-hiuxwe2
|
||||||
|
exit 0 ;;
|
||||||
|
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||||
|
echo hppa1.1-hp-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
9000/8??:4.3bsd:*:*)
|
||||||
|
echo hppa1.0-hp-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
|
||||||
|
echo hppa1.1-hp-osf
|
||||||
|
exit 0 ;;
|
||||||
|
hp8??:OSF1:*:*)
|
||||||
|
echo hppa1.0-hp-osf
|
||||||
|
exit 0 ;;
|
||||||
|
i?86:OSF1:*:*)
|
||||||
|
if [ -x /usr/sbin/sysversion ] ; then
|
||||||
|
echo ${UNAME_MACHINE}-unknown-osf1mk
|
||||||
|
else
|
||||||
|
echo ${UNAME_MACHINE}-unknown-osf1
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
parisc*:Lites*:*:*)
|
||||||
|
echo hppa1.1-hp-lites
|
||||||
|
exit 0 ;;
|
||||||
|
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||||
|
echo c1-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||||
|
if getsysinfo -f scalar_acc
|
||||||
|
then echo c32-convex-bsd
|
||||||
|
else echo c2-convex-bsd
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||||
|
echo c34-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||||
|
echo c38-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||||
|
echo c4-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
CRAY*X-MP:*:*:*)
|
||||||
|
echo xmp-cray-unicos
|
||||||
|
exit 0 ;;
|
||||||
|
CRAY*Y-MP:*:*:*)
|
||||||
|
echo ymp-cray-unicos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
CRAY*[A-Z]90:*:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
|
||||||
|
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
|
||||||
|
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||||
|
exit 0 ;;
|
||||||
|
CRAY*TS:*:*:*)
|
||||||
|
echo t90-cray-unicos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
CRAY-2:*:*:*)
|
||||||
|
echo cray2-cray-unicos
|
||||||
|
exit 0 ;;
|
||||||
|
F300:UNIX_System_V:*:*)
|
||||||
|
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||||
|
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||||
|
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||||
|
exit 0 ;;
|
||||||
|
F301:UNIX_System_V:*:*)
|
||||||
|
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
hp3[0-9][05]:NetBSD:*:*)
|
||||||
|
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
hp3[0-9][05]:OpenBSD:*:*)
|
||||||
|
echo m68k-hp-openbsd${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
i?86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
*:FreeBSD:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
*:NetBSD:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||||
|
exit 0 ;;
|
||||||
|
*:OpenBSD:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||||
|
exit 0 ;;
|
||||||
|
i*:CYGWIN*:*)
|
||||||
|
echo i386-pc-cygwin32
|
||||||
|
exit 0 ;;
|
||||||
|
p*:CYGWIN*:*)
|
||||||
|
echo powerpcle-unknown-cygwin32
|
||||||
|
exit 0 ;;
|
||||||
|
prep*:SunOS:5.*:*)
|
||||||
|
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||||
|
exit 0 ;;
|
||||||
|
*:GNU:*:*)
|
||||||
|
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||||
|
exit 0 ;;
|
||||||
|
*:Linux:*:*)
|
||||||
|
# The BFD linker knows what the default object file format is, so
|
||||||
|
# first see if it will tell us.
|
||||||
|
ld_help_string=`ld --help 2>&1`
|
||||||
|
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0
|
||||||
|
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0
|
||||||
|
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then
|
||||||
|
echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0
|
||||||
|
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
|
||||||
|
echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0
|
||||||
|
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
|
||||||
|
echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0
|
||||||
|
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then
|
||||||
|
echo "powerpc-unknown-linux-gnu" ; exit 0
|
||||||
|
elif test "${UNAME_MACHINE}" = "alpha" ; then
|
||||||
|
echo alpha-unknown-linux-gnu ; exit 0
|
||||||
|
elif test "${UNAME_MACHINE}" = "sparc" ; then
|
||||||
|
echo sparc-unknown-linux-gnu ; exit 0
|
||||||
|
else
|
||||||
|
# Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us
|
||||||
|
# useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout.
|
||||||
|
test ! -d /usr/lib/ldscripts/. \
|
||||||
|
&& echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
|
||||||
|
# Determine whether the default compiler is a.out or elf
|
||||||
|
cat >dummy.c <<EOF
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
#ifdef __ELF__
|
||||||
|
printf ("%s-pc-linux-gnu\n", argv[1]);
|
||||||
|
#else
|
||||||
|
printf ("%s-pc-linux-gnuaout\n", argv[1]);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||||
|
rm -f dummy.c dummy
|
||||||
|
fi ;;
|
||||||
|
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
|
||||||
|
# are messed up and put the nodename in both sysname and nodename.
|
||||||
|
i?86:DYNIX/ptx:4*:*)
|
||||||
|
echo i386-sequent-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
|
||||||
|
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||||
|
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
|
||||||
|
else
|
||||||
|
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
i?86:*:3.2:*)
|
||||||
|
if test -f /usr/options/cb.name; then
|
||||||
|
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
|
||||||
|
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
|
||||||
|
elif /bin/uname -X 2>/dev/null >/dev/null ; then
|
||||||
|
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
|
||||||
|
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||||
|
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||||
|
&& UNAME_MACHINE=i586
|
||||||
|
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||||
|
else
|
||||||
|
echo ${UNAME_MACHINE}-pc-sysv32
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
Intel:Mach:3*:*)
|
||||||
|
echo i386-pc-mach3
|
||||||
|
exit 0 ;;
|
||||||
|
paragon:*:*:*)
|
||||||
|
echo i860-intel-osf1
|
||||||
|
exit 0 ;;
|
||||||
|
i860:*:4.*:*) # i860-SVR4
|
||||||
|
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
|
||||||
|
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
|
||||||
|
else # Add other i860-SVR4 vendors below as they are discovered.
|
||||||
|
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
mini*:CTIX:SYS*5:*)
|
||||||
|
# "miniframe"
|
||||||
|
echo m68010-convergent-sysv
|
||||||
|
exit 0 ;;
|
||||||
|
M68*:*:R3V[567]*:*)
|
||||||
|
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||||
|
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
|
||||||
|
OS_REL=''
|
||||||
|
test -r /etc/.relid \
|
||||||
|
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||||
|
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||||
|
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
|
||||||
|
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||||
|
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
|
||||||
|
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||||
|
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||||
|
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||||
|
m68*:LynxOS:2.*:*)
|
||||||
|
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
mc68030:UNIX_System_V:4.*:*)
|
||||||
|
echo m68k-atari-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
i?86:LynxOS:2.*:*)
|
||||||
|
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
TSUNAMI:LynxOS:2.*:*)
|
||||||
|
echo sparc-unknown-lynxos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
|
||||||
|
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
SM[BE]S:UNIX_SV:*:*)
|
||||||
|
echo mips-dde-sysv${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
RM*:SINIX-*:*:*)
|
||||||
|
echo mips-sni-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
*:SINIX-*:*:*)
|
||||||
|
if uname -p 2>/dev/null >/dev/null ; then
|
||||||
|
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||||
|
echo ${UNAME_MACHINE}-sni-sysv4
|
||||||
|
else
|
||||||
|
echo ns32k-sni-sysv
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
*:UNIX_System_V:4*:FTX*)
|
||||||
|
# From Gerald Hewes <hewes@openmarket.com>.
|
||||||
|
# How about differentiating between stratus architectures? -djm
|
||||||
|
echo hppa1.1-stratus-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
*:*:*:FTX*)
|
||||||
|
# From seanf@swdc.stratus.com.
|
||||||
|
echo i860-stratus-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
mc68*:A/UX:*:*)
|
||||||
|
echo m68k-apple-aux${UNAME_RELEASE}
|
||||||
|
exit 0 ;;
|
||||||
|
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
|
||||||
|
if [ -d /usr/nec ]; then
|
||||||
|
echo mips-nec-sysv${UNAME_RELEASE}
|
||||||
|
else
|
||||||
|
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||||
|
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||||
|
echo i586-unisys-sysv4
|
||||||
|
exit 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||||
|
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||||
|
|
||||||
|
cat >dummy.c <<EOF
|
||||||
|
#ifdef _SEQUENT_
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
#if defined (sony)
|
||||||
|
#if defined (MIPSEB)
|
||||||
|
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
|
||||||
|
I don't know.... */
|
||||||
|
printf ("mips-sony-bsd\n"); exit (0);
|
||||||
|
#else
|
||||||
|
#include <sys/param.h>
|
||||||
|
printf ("m68k-sony-newsos%s\n",
|
||||||
|
#ifdef NEWSOS4
|
||||||
|
"4"
|
||||||
|
#else
|
||||||
|
""
|
||||||
|
#endif
|
||||||
|
); exit (0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__arm) && defined (__acorn) && defined (__unix)
|
||||||
|
printf ("arm-acorn-riscix"); exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (hp300) && !defined (hpux)
|
||||||
|
printf ("m68k-hp-bsd\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (NeXT)
|
||||||
|
#if !defined (__ARCHITECTURE__)
|
||||||
|
#define __ARCHITECTURE__ "m68k"
|
||||||
|
#endif
|
||||||
|
int version;
|
||||||
|
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
|
||||||
|
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||||
|
exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (MULTIMAX) || defined (n16)
|
||||||
|
#if defined (UMAXV)
|
||||||
|
printf ("ns32k-encore-sysv\n"); exit (0);
|
||||||
|
#else
|
||||||
|
#if defined (CMU)
|
||||||
|
printf ("ns32k-encore-mach\n"); exit (0);
|
||||||
|
#else
|
||||||
|
printf ("ns32k-encore-bsd\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__386BSD__)
|
||||||
|
printf ("i386-pc-bsd\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (sequent)
|
||||||
|
#if defined (i386)
|
||||||
|
printf ("i386-sequent-dynix\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
#if defined (ns32000)
|
||||||
|
printf ("ns32k-sequent-dynix\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (_SEQUENT_)
|
||||||
|
struct utsname un;
|
||||||
|
|
||||||
|
uname(&un);
|
||||||
|
|
||||||
|
if (strncmp(un.version, "V2", 2) == 0) {
|
||||||
|
printf ("i386-sequent-ptx2\n"); exit (0);
|
||||||
|
}
|
||||||
|
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
|
||||||
|
printf ("i386-sequent-ptx1\n"); exit (0);
|
||||||
|
}
|
||||||
|
printf ("i386-sequent-ptx\n"); exit (0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (vax)
|
||||||
|
#if !defined (ultrix)
|
||||||
|
printf ("vax-dec-bsd\n"); exit (0);
|
||||||
|
#else
|
||||||
|
printf ("vax-dec-ultrix\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (alliant) && defined (i860)
|
||||||
|
printf ("i860-alliant-bsd\n"); exit (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
|
||||||
|
rm -f dummy.c dummy
|
||||||
|
|
||||||
|
# Apollos put the system type in the environment.
|
||||||
|
|
||||||
|
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
|
||||||
|
|
||||||
|
# Convex versions that predate uname can use getsysinfo(1)
|
||||||
|
|
||||||
|
if [ -x /usr/convex/getsysinfo ]
|
||||||
|
then
|
||||||
|
case `getsysinfo -f cpu_type` in
|
||||||
|
c1*)
|
||||||
|
echo c1-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
c2*)
|
||||||
|
if getsysinfo -f scalar_acc
|
||||||
|
then echo c32-convex-bsd
|
||||||
|
else echo c2-convex-bsd
|
||||||
|
fi
|
||||||
|
exit 0 ;;
|
||||||
|
c34*)
|
||||||
|
echo c34-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
c38*)
|
||||||
|
echo c38-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
c4*)
|
||||||
|
echo c4-convex-bsd
|
||||||
|
exit 0 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
#echo '(Unable to guess system type)' 1>&2
|
||||||
|
|
||||||
|
exit 1
|
927
config.sub
vendored
Executable file
927
config.sub
vendored
Executable file
@ -0,0 +1,927 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Configuration validation subroutine script, version 1.1.
|
||||||
|
# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
|
||||||
|
# This file is (in principle) common to ALL GNU software.
|
||||||
|
# The presence of a machine in this file suggests that SOME GNU software
|
||||||
|
# can handle that machine. It does not imply ALL GNU software can.
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||||
|
# Supply the specified configuration type as an argument.
|
||||||
|
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||||
|
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||||
|
|
||||||
|
# This file is supposed to be the same for all GNU packages
|
||||||
|
# and recognize all the CPU types, system types and aliases
|
||||||
|
# that are meaningful with *any* GNU software.
|
||||||
|
# Each package is responsible for reporting which valid configurations
|
||||||
|
# it does not support. The user should be able to distinguish
|
||||||
|
# a failure to support a valid configuration from a meaningless
|
||||||
|
# configuration.
|
||||||
|
|
||||||
|
# The goal of this file is to map all the various variations of a given
|
||||||
|
# machine specification into a single specification in the form:
|
||||||
|
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||||
|
# or in some cases, the newer four-part form:
|
||||||
|
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||||
|
# It is wrong to echo any other type of specification.
|
||||||
|
|
||||||
|
if [ x$1 = x ]
|
||||||
|
then
|
||||||
|
echo Configuration name missing. 1>&2
|
||||||
|
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
|
||||||
|
echo "or $0 ALIAS" 1>&2
|
||||||
|
echo where ALIAS is a recognized configuration type. 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# First pass through any local machine types.
|
||||||
|
case $1 in
|
||||||
|
*local*)
|
||||||
|
echo $1
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
||||||
|
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||||
|
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||||
|
case $maybe_os in
|
||||||
|
linux-gnu*)
|
||||||
|
os=-$maybe_os
|
||||||
|
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||||
|
if [ $basic_machine != $1 ]
|
||||||
|
then os=`echo $1 | sed 's/.*-/-/'`
|
||||||
|
else os=; fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
### Let's recognize common machines as not being operating systems so
|
||||||
|
### that things like config.sub decstation-3100 work. We also
|
||||||
|
### recognize some manufacturers as not being operating systems, so we
|
||||||
|
### can provide default operating systems below.
|
||||||
|
case $os in
|
||||||
|
-sun*os*)
|
||||||
|
# Prevent following clause from handling this invalid input.
|
||||||
|
;;
|
||||||
|
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
|
||||||
|
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
|
||||||
|
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
|
||||||
|
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||||
|
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||||
|
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||||
|
-apple)
|
||||||
|
os=
|
||||||
|
basic_machine=$1
|
||||||
|
;;
|
||||||
|
-hiux*)
|
||||||
|
os=-hiuxwe2
|
||||||
|
;;
|
||||||
|
-sco5)
|
||||||
|
os=sco3.2v5
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-sco4)
|
||||||
|
os=-sco3.2v4
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-sco3.2.[4-9]*)
|
||||||
|
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-sco3.2v[4-9]*)
|
||||||
|
# Don't forget version if it is 3.2v4 or newer.
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-sco*)
|
||||||
|
os=-sco3.2v2
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-isc)
|
||||||
|
os=-isc2.2
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-clix*)
|
||||||
|
basic_machine=clipper-intergraph
|
||||||
|
;;
|
||||||
|
-isc*)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||||
|
;;
|
||||||
|
-lynx*)
|
||||||
|
os=-lynxos
|
||||||
|
;;
|
||||||
|
-ptx*)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
|
||||||
|
;;
|
||||||
|
-windowsnt*)
|
||||||
|
os=`echo $os | sed -e 's/windowsnt/winnt/'`
|
||||||
|
;;
|
||||||
|
-psos*)
|
||||||
|
os=-psos
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Decode aliases for certain CPU-COMPANY combinations.
|
||||||
|
case $basic_machine in
|
||||||
|
# Recognize the basic CPU types without company name.
|
||||||
|
# Some are omitted here because they have special meanings below.
|
||||||
|
tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
|
||||||
|
| arme[lb] | pyramid \
|
||||||
|
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
|
||||||
|
| alpha | we32k | ns16k | clipper | i370 | sh \
|
||||||
|
| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
|
||||||
|
| pdp11 | mips64el | mips64orion | mips64orionel \
|
||||||
|
| sparc | sparclet | sparclite | sparc64)
|
||||||
|
basic_machine=$basic_machine-unknown
|
||||||
|
;;
|
||||||
|
# We use `pc' rather than `unknown'
|
||||||
|
# because (1) that's what they normally are, and
|
||||||
|
# (2) the word "unknown" tends to confuse beginning users.
|
||||||
|
i[3456]86)
|
||||||
|
basic_machine=$basic_machine-pc
|
||||||
|
;;
|
||||||
|
# Object if more than one company name word.
|
||||||
|
*-*-*)
|
||||||
|
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
# Recognize the basic CPU types with company name.
|
||||||
|
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
|
||||||
|
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
|
||||||
|
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
|
||||||
|
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
|
||||||
|
| hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
|
||||||
|
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
|
||||||
|
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
|
||||||
|
| mips64el-* | mips64orion-* | mips64orionel-* | f301-*)
|
||||||
|
;;
|
||||||
|
# Recognize the various machine names and aliases which stand
|
||||||
|
# for a CPU type and a company and sometimes even an OS.
|
||||||
|
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
||||||
|
basic_machine=m68000-att
|
||||||
|
;;
|
||||||
|
3b*)
|
||||||
|
basic_machine=we32k-att
|
||||||
|
;;
|
||||||
|
alliant | fx80)
|
||||||
|
basic_machine=fx80-alliant
|
||||||
|
;;
|
||||||
|
altos | altos3068)
|
||||||
|
basic_machine=m68k-altos
|
||||||
|
;;
|
||||||
|
am29k)
|
||||||
|
basic_machine=a29k-none
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
amdahl)
|
||||||
|
basic_machine=580-amdahl
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
amiga | amiga-*)
|
||||||
|
basic_machine=m68k-cbm
|
||||||
|
;;
|
||||||
|
amigados)
|
||||||
|
basic_machine=m68k-cbm
|
||||||
|
os=-amigados
|
||||||
|
;;
|
||||||
|
amigaunix | amix)
|
||||||
|
basic_machine=m68k-cbm
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
apollo68)
|
||||||
|
basic_machine=m68k-apollo
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
aux)
|
||||||
|
basic_machine=m68k-apple
|
||||||
|
os=-aux
|
||||||
|
;;
|
||||||
|
balance)
|
||||||
|
basic_machine=ns32k-sequent
|
||||||
|
os=-dynix
|
||||||
|
;;
|
||||||
|
convex-c1)
|
||||||
|
basic_machine=c1-convex
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
convex-c2)
|
||||||
|
basic_machine=c2-convex
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
convex-c32)
|
||||||
|
basic_machine=c32-convex
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
convex-c34)
|
||||||
|
basic_machine=c34-convex
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
convex-c38)
|
||||||
|
basic_machine=c38-convex
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
cray | ymp)
|
||||||
|
basic_machine=ymp-cray
|
||||||
|
os=-unicos
|
||||||
|
;;
|
||||||
|
cray2)
|
||||||
|
basic_machine=cray2-cray
|
||||||
|
os=-unicos
|
||||||
|
;;
|
||||||
|
[ctj]90-cray)
|
||||||
|
basic_machine=c90-cray
|
||||||
|
os=-unicos
|
||||||
|
;;
|
||||||
|
crds | unos)
|
||||||
|
basic_machine=m68k-crds
|
||||||
|
;;
|
||||||
|
da30 | da30-*)
|
||||||
|
basic_machine=m68k-da30
|
||||||
|
;;
|
||||||
|
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
|
||||||
|
basic_machine=mips-dec
|
||||||
|
;;
|
||||||
|
delta | 3300 | motorola-3300 | motorola-delta \
|
||||||
|
| 3300-motorola | delta-motorola)
|
||||||
|
basic_machine=m68k-motorola
|
||||||
|
;;
|
||||||
|
delta88)
|
||||||
|
basic_machine=m88k-motorola
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
dpx20 | dpx20-*)
|
||||||
|
basic_machine=rs6000-bull
|
||||||
|
os=-bosx
|
||||||
|
;;
|
||||||
|
dpx2* | dpx2*-bull)
|
||||||
|
basic_machine=m68k-bull
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
ebmon29k)
|
||||||
|
basic_machine=a29k-amd
|
||||||
|
os=-ebmon
|
||||||
|
;;
|
||||||
|
elxsi)
|
||||||
|
basic_machine=elxsi-elxsi
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
encore | umax | mmax)
|
||||||
|
basic_machine=ns32k-encore
|
||||||
|
;;
|
||||||
|
fx2800)
|
||||||
|
basic_machine=i860-alliant
|
||||||
|
;;
|
||||||
|
genix)
|
||||||
|
basic_machine=ns32k-ns
|
||||||
|
;;
|
||||||
|
gmicro)
|
||||||
|
basic_machine=tron-gmicro
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
h3050r* | hiux*)
|
||||||
|
basic_machine=hppa1.1-hitachi
|
||||||
|
os=-hiuxwe2
|
||||||
|
;;
|
||||||
|
h8300hms)
|
||||||
|
basic_machine=h8300-hitachi
|
||||||
|
os=-hms
|
||||||
|
;;
|
||||||
|
harris)
|
||||||
|
basic_machine=m88k-harris
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
hp300-*)
|
||||||
|
basic_machine=m68k-hp
|
||||||
|
;;
|
||||||
|
hp300bsd)
|
||||||
|
basic_machine=m68k-hp
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
hp300hpux)
|
||||||
|
basic_machine=m68k-hp
|
||||||
|
os=-hpux
|
||||||
|
;;
|
||||||
|
hp9k2[0-9][0-9] | hp9k31[0-9])
|
||||||
|
basic_machine=m68000-hp
|
||||||
|
;;
|
||||||
|
hp9k3[2-9][0-9])
|
||||||
|
basic_machine=m68k-hp
|
||||||
|
;;
|
||||||
|
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
|
||||||
|
basic_machine=hppa1.1-hp
|
||||||
|
;;
|
||||||
|
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
||||||
|
basic_machine=hppa1.0-hp
|
||||||
|
;;
|
||||||
|
hppa-next)
|
||||||
|
os=-nextstep3
|
||||||
|
;;
|
||||||
|
i370-ibm* | ibm*)
|
||||||
|
basic_machine=i370-ibm
|
||||||
|
os=-mvs
|
||||||
|
;;
|
||||||
|
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||||
|
i[3456]86v32)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
|
os=-sysv32
|
||||||
|
;;
|
||||||
|
i[3456]86v4*)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
i[3456]86v)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
i[3456]86sol2)
|
||||||
|
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||||
|
os=-solaris2
|
||||||
|
;;
|
||||||
|
iris | iris4d)
|
||||||
|
basic_machine=mips-sgi
|
||||||
|
case $os in
|
||||||
|
-irix*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
os=-irix4
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
isi68 | isi)
|
||||||
|
basic_machine=m68k-isi
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
m88k-omron*)
|
||||||
|
basic_machine=m88k-omron
|
||||||
|
;;
|
||||||
|
magnum | m3230)
|
||||||
|
basic_machine=mips-mips
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
merlin)
|
||||||
|
basic_machine=ns32k-utek
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
miniframe)
|
||||||
|
basic_machine=m68000-convergent
|
||||||
|
;;
|
||||||
|
mips3*-*)
|
||||||
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||||
|
;;
|
||||||
|
mips3*)
|
||||||
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||||
|
;;
|
||||||
|
ncr3000)
|
||||||
|
basic_machine=i486-ncr
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
news | news700 | news800 | news900)
|
||||||
|
basic_machine=m68k-sony
|
||||||
|
os=-newsos
|
||||||
|
;;
|
||||||
|
news1000)
|
||||||
|
basic_machine=m68030-sony
|
||||||
|
os=-newsos
|
||||||
|
;;
|
||||||
|
news-3600 | risc-news)
|
||||||
|
basic_machine=mips-sony
|
||||||
|
os=-newsos
|
||||||
|
;;
|
||||||
|
next | m*-next )
|
||||||
|
basic_machine=m68k-next
|
||||||
|
case $os in
|
||||||
|
-nextstep* )
|
||||||
|
;;
|
||||||
|
-ns2*)
|
||||||
|
os=-nextstep2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
os=-nextstep3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
nh3000)
|
||||||
|
basic_machine=m68k-harris
|
||||||
|
os=-cxux
|
||||||
|
;;
|
||||||
|
nh[45]000)
|
||||||
|
basic_machine=m88k-harris
|
||||||
|
os=-cxux
|
||||||
|
;;
|
||||||
|
nindy960)
|
||||||
|
basic_machine=i960-intel
|
||||||
|
os=-nindy
|
||||||
|
;;
|
||||||
|
np1)
|
||||||
|
basic_machine=np1-gould
|
||||||
|
;;
|
||||||
|
pa-hitachi)
|
||||||
|
basic_machine=hppa1.1-hitachi
|
||||||
|
os=-hiuxwe2
|
||||||
|
;;
|
||||||
|
paragon)
|
||||||
|
basic_machine=i860-intel
|
||||||
|
os=-osf
|
||||||
|
;;
|
||||||
|
pbd)
|
||||||
|
basic_machine=sparc-tti
|
||||||
|
;;
|
||||||
|
pbb)
|
||||||
|
basic_machine=m68k-tti
|
||||||
|
;;
|
||||||
|
pc532 | pc532-*)
|
||||||
|
basic_machine=ns32k-pc532
|
||||||
|
;;
|
||||||
|
pentium | p5)
|
||||||
|
basic_machine=i586-intel
|
||||||
|
;;
|
||||||
|
pentiumpro | p6)
|
||||||
|
basic_machine=i686-intel
|
||||||
|
;;
|
||||||
|
pentium-* | p5-*)
|
||||||
|
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
|
;;
|
||||||
|
pentiumpro-* | p6-*)
|
||||||
|
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
|
;;
|
||||||
|
k5)
|
||||||
|
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
|
||||||
|
basic_machine=i586-amd
|
||||||
|
;;
|
||||||
|
nexen)
|
||||||
|
# We don't have specific support for Nexgen yet, so just call it a Pentium
|
||||||
|
basic_machine=i586-nexgen
|
||||||
|
;;
|
||||||
|
pn)
|
||||||
|
basic_machine=pn-gould
|
||||||
|
;;
|
||||||
|
power) basic_machine=rs6000-ibm
|
||||||
|
;;
|
||||||
|
ppc) basic_machine=powerpc-unknown
|
||||||
|
;;
|
||||||
|
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
|
;;
|
||||||
|
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||||
|
basic_machine=powerpcle-unknown
|
||||||
|
;;
|
||||||
|
ppcle-* | powerpclittle-*)
|
||||||
|
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||||
|
;;
|
||||||
|
ps2)
|
||||||
|
basic_machine=i386-ibm
|
||||||
|
;;
|
||||||
|
rm[46]00)
|
||||||
|
basic_machine=mips-siemens
|
||||||
|
;;
|
||||||
|
rtpc | rtpc-*)
|
||||||
|
basic_machine=romp-ibm
|
||||||
|
;;
|
||||||
|
sequent)
|
||||||
|
basic_machine=i386-sequent
|
||||||
|
;;
|
||||||
|
sh)
|
||||||
|
basic_machine=sh-hitachi
|
||||||
|
os=-hms
|
||||||
|
;;
|
||||||
|
sps7)
|
||||||
|
basic_machine=m68k-bull
|
||||||
|
os=-sysv2
|
||||||
|
;;
|
||||||
|
spur)
|
||||||
|
basic_machine=spur-unknown
|
||||||
|
;;
|
||||||
|
sun2)
|
||||||
|
basic_machine=m68000-sun
|
||||||
|
;;
|
||||||
|
sun2os3)
|
||||||
|
basic_machine=m68000-sun
|
||||||
|
os=-sunos3
|
||||||
|
;;
|
||||||
|
sun2os4)
|
||||||
|
basic_machine=m68000-sun
|
||||||
|
os=-sunos4
|
||||||
|
;;
|
||||||
|
sun3os3)
|
||||||
|
basic_machine=m68k-sun
|
||||||
|
os=-sunos3
|
||||||
|
;;
|
||||||
|
sun3os4)
|
||||||
|
basic_machine=m68k-sun
|
||||||
|
os=-sunos4
|
||||||
|
;;
|
||||||
|
sun4os3)
|
||||||
|
basic_machine=sparc-sun
|
||||||
|
os=-sunos3
|
||||||
|
;;
|
||||||
|
sun4os4)
|
||||||
|
basic_machine=sparc-sun
|
||||||
|
os=-sunos4
|
||||||
|
;;
|
||||||
|
sun4sol2)
|
||||||
|
basic_machine=sparc-sun
|
||||||
|
os=-solaris2
|
||||||
|
;;
|
||||||
|
sun3 | sun3-*)
|
||||||
|
basic_machine=m68k-sun
|
||||||
|
;;
|
||||||
|
sun4)
|
||||||
|
basic_machine=sparc-sun
|
||||||
|
;;
|
||||||
|
sun386 | sun386i | roadrunner)
|
||||||
|
basic_machine=i386-sun
|
||||||
|
;;
|
||||||
|
symmetry)
|
||||||
|
basic_machine=i386-sequent
|
||||||
|
os=-dynix
|
||||||
|
;;
|
||||||
|
tower | tower-32)
|
||||||
|
basic_machine=m68k-ncr
|
||||||
|
;;
|
||||||
|
udi29k)
|
||||||
|
basic_machine=a29k-amd
|
||||||
|
os=-udi
|
||||||
|
;;
|
||||||
|
ultra3)
|
||||||
|
basic_machine=a29k-nyu
|
||||||
|
os=-sym1
|
||||||
|
;;
|
||||||
|
vaxv)
|
||||||
|
basic_machine=vax-dec
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
vms)
|
||||||
|
basic_machine=vax-dec
|
||||||
|
os=-vms
|
||||||
|
;;
|
||||||
|
vpp*|vx|vx-*)
|
||||||
|
basic_machine=f301-fujitsu
|
||||||
|
;;
|
||||||
|
vxworks960)
|
||||||
|
basic_machine=i960-wrs
|
||||||
|
os=-vxworks
|
||||||
|
;;
|
||||||
|
vxworks68)
|
||||||
|
basic_machine=m68k-wrs
|
||||||
|
os=-vxworks
|
||||||
|
;;
|
||||||
|
vxworks29k)
|
||||||
|
basic_machine=a29k-wrs
|
||||||
|
os=-vxworks
|
||||||
|
;;
|
||||||
|
xmp)
|
||||||
|
basic_machine=xmp-cray
|
||||||
|
os=-unicos
|
||||||
|
;;
|
||||||
|
xps | xps100)
|
||||||
|
basic_machine=xps100-honeywell
|
||||||
|
;;
|
||||||
|
none)
|
||||||
|
basic_machine=none-none
|
||||||
|
os=-none
|
||||||
|
;;
|
||||||
|
|
||||||
|
# Here we handle the default manufacturer of certain CPU types. It is in
|
||||||
|
# some cases the only manufacturer, in others, it is the most popular.
|
||||||
|
mips)
|
||||||
|
basic_machine=mips-mips
|
||||||
|
;;
|
||||||
|
romp)
|
||||||
|
basic_machine=romp-ibm
|
||||||
|
;;
|
||||||
|
rs6000)
|
||||||
|
basic_machine=rs6000-ibm
|
||||||
|
;;
|
||||||
|
vax)
|
||||||
|
basic_machine=vax-dec
|
||||||
|
;;
|
||||||
|
pdp11)
|
||||||
|
basic_machine=pdp11-dec
|
||||||
|
;;
|
||||||
|
we32k)
|
||||||
|
basic_machine=we32k-att
|
||||||
|
;;
|
||||||
|
sparc)
|
||||||
|
basic_machine=sparc-sun
|
||||||
|
;;
|
||||||
|
cydra)
|
||||||
|
basic_machine=cydra-cydrome
|
||||||
|
;;
|
||||||
|
orion)
|
||||||
|
basic_machine=orion-highlevel
|
||||||
|
;;
|
||||||
|
orion105)
|
||||||
|
basic_machine=clipper-highlevel
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Here we canonicalize certain aliases for manufacturers.
|
||||||
|
case $basic_machine in
|
||||||
|
*-digital*)
|
||||||
|
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
|
||||||
|
;;
|
||||||
|
*-commodore*)
|
||||||
|
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Decode manufacturer-specific aliases for certain operating systems.
|
||||||
|
|
||||||
|
if [ x"$os" != x"" ]
|
||||||
|
then
|
||||||
|
case $os in
|
||||||
|
# First match some system type aliases
|
||||||
|
# that might get confused with valid system types.
|
||||||
|
# -solaris* is a basic system type, with this one exception.
|
||||||
|
-solaris1 | -solaris1.*)
|
||||||
|
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||||
|
;;
|
||||||
|
-solaris)
|
||||||
|
os=-solaris2
|
||||||
|
;;
|
||||||
|
-unixware* | svr4*)
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
-gnu/linux*)
|
||||||
|
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
||||||
|
;;
|
||||||
|
# First accept the basic system types.
|
||||||
|
# The portable systems comes first.
|
||||||
|
# Each alternative MUST END IN A *, to match a version number.
|
||||||
|
# -sysv* is not here because it comes later, after sysvr4.
|
||||||
|
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||||
|
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||||
|
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||||
|
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
|
||||||
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
|
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||||
|
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
|
||||||
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
|
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||||
|
| -linux-gnu* | -uxpv*)
|
||||||
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
|
;;
|
||||||
|
-linux*)
|
||||||
|
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||||
|
;;
|
||||||
|
-sunos5*)
|
||||||
|
os=`echo $os | sed -e 's|sunos5|solaris2|'`
|
||||||
|
;;
|
||||||
|
-sunos6*)
|
||||||
|
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
||||||
|
;;
|
||||||
|
-osfrose*)
|
||||||
|
os=-osfrose
|
||||||
|
;;
|
||||||
|
-osf*)
|
||||||
|
os=-osf
|
||||||
|
;;
|
||||||
|
-utek*)
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
-dynix*)
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
-acis*)
|
||||||
|
os=-aos
|
||||||
|
;;
|
||||||
|
-ctix* | -uts*)
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
-ns2 )
|
||||||
|
os=-nextstep2
|
||||||
|
;;
|
||||||
|
# Preserve the version number of sinix5.
|
||||||
|
-sinix5.*)
|
||||||
|
os=`echo $os | sed -e 's|sinix|sysv|'`
|
||||||
|
;;
|
||||||
|
-sinix*)
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
-triton*)
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
-oss*)
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
-svr4)
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
-svr3)
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
-sysvr4)
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
# This must come after -sysvr4.
|
||||||
|
-sysv*)
|
||||||
|
;;
|
||||||
|
-xenix)
|
||||||
|
os=-xenix
|
||||||
|
;;
|
||||||
|
-none)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Get rid of the `-' at the beginning of $os.
|
||||||
|
os=`echo $os | sed 's/[^-]*-//'`
|
||||||
|
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
|
||||||
|
# Here we handle the default operating systems that come with various machines.
|
||||||
|
# The value should be what the vendor currently ships out the door with their
|
||||||
|
# machine or put another way, the most popular os provided with the machine.
|
||||||
|
|
||||||
|
# Note that if you're going to try to match "-MANUFACTURER" here (say,
|
||||||
|
# "-sun"), then you have to tell the case statement up towards the top
|
||||||
|
# that MANUFACTURER isn't an operating system. Otherwise, code above
|
||||||
|
# will signal an error saying that MANUFACTURER isn't an operating
|
||||||
|
# system, and we'll never get to this point.
|
||||||
|
|
||||||
|
case $basic_machine in
|
||||||
|
*-acorn)
|
||||||
|
os=-riscix1.2
|
||||||
|
;;
|
||||||
|
arm*-semi)
|
||||||
|
os=-aout
|
||||||
|
;;
|
||||||
|
pdp11-*)
|
||||||
|
os=-none
|
||||||
|
;;
|
||||||
|
*-dec | vax-*)
|
||||||
|
os=-ultrix4.2
|
||||||
|
;;
|
||||||
|
m68*-apollo)
|
||||||
|
os=-domain
|
||||||
|
;;
|
||||||
|
i386-sun)
|
||||||
|
os=-sunos4.0.2
|
||||||
|
;;
|
||||||
|
m68000-sun)
|
||||||
|
os=-sunos3
|
||||||
|
# This also exists in the configure program, but was not the
|
||||||
|
# default.
|
||||||
|
# os=-sunos4
|
||||||
|
;;
|
||||||
|
*-tti) # must be before sparc entry or we get the wrong os.
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
sparc-* | *-sun)
|
||||||
|
os=-sunos4.1.1
|
||||||
|
;;
|
||||||
|
*-ibm)
|
||||||
|
os=-aix
|
||||||
|
;;
|
||||||
|
*-hp)
|
||||||
|
os=-hpux
|
||||||
|
;;
|
||||||
|
*-hitachi)
|
||||||
|
os=-hiux
|
||||||
|
;;
|
||||||
|
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
*-cbm)
|
||||||
|
os=-amigados
|
||||||
|
;;
|
||||||
|
*-dg)
|
||||||
|
os=-dgux
|
||||||
|
;;
|
||||||
|
*-dolphin)
|
||||||
|
os=-sysv3
|
||||||
|
;;
|
||||||
|
m68k-ccur)
|
||||||
|
os=-rtu
|
||||||
|
;;
|
||||||
|
m88k-omron*)
|
||||||
|
os=-luna
|
||||||
|
;;
|
||||||
|
*-next )
|
||||||
|
os=-nextstep
|
||||||
|
;;
|
||||||
|
*-sequent)
|
||||||
|
os=-ptx
|
||||||
|
;;
|
||||||
|
*-crds)
|
||||||
|
os=-unos
|
||||||
|
;;
|
||||||
|
*-ns)
|
||||||
|
os=-genix
|
||||||
|
;;
|
||||||
|
i370-*)
|
||||||
|
os=-mvs
|
||||||
|
;;
|
||||||
|
*-next)
|
||||||
|
os=-nextstep3
|
||||||
|
;;
|
||||||
|
*-gould)
|
||||||
|
os=-sysv
|
||||||
|
;;
|
||||||
|
*-highlevel)
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
*-encore)
|
||||||
|
os=-bsd
|
||||||
|
;;
|
||||||
|
*-sgi)
|
||||||
|
os=-irix
|
||||||
|
;;
|
||||||
|
*-siemens)
|
||||||
|
os=-sysv4
|
||||||
|
;;
|
||||||
|
*-masscomp)
|
||||||
|
os=-rtu
|
||||||
|
;;
|
||||||
|
f301-fujitsu)
|
||||||
|
os=-uxpv
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
os=-none
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Here we handle the case where we know the os, and the CPU type, but not the
|
||||||
|
# manufacturer. We pick the logical manufacturer.
|
||||||
|
vendor=unknown
|
||||||
|
case $basic_machine in
|
||||||
|
*-unknown)
|
||||||
|
case $os in
|
||||||
|
-riscix*)
|
||||||
|
vendor=acorn
|
||||||
|
;;
|
||||||
|
-sunos*)
|
||||||
|
vendor=sun
|
||||||
|
;;
|
||||||
|
-aix*)
|
||||||
|
vendor=ibm
|
||||||
|
;;
|
||||||
|
-hpux*)
|
||||||
|
vendor=hp
|
||||||
|
;;
|
||||||
|
-hiux*)
|
||||||
|
vendor=hitachi
|
||||||
|
;;
|
||||||
|
-unos*)
|
||||||
|
vendor=crds
|
||||||
|
;;
|
||||||
|
-dgux*)
|
||||||
|
vendor=dg
|
||||||
|
;;
|
||||||
|
-luna*)
|
||||||
|
vendor=omron
|
||||||
|
;;
|
||||||
|
-genix*)
|
||||||
|
vendor=ns
|
||||||
|
;;
|
||||||
|
-mvs*)
|
||||||
|
vendor=ibm
|
||||||
|
;;
|
||||||
|
-ptx*)
|
||||||
|
vendor=sequent
|
||||||
|
;;
|
||||||
|
-vxsim* | -vxworks*)
|
||||||
|
vendor=wrs
|
||||||
|
;;
|
||||||
|
-aux*)
|
||||||
|
vendor=apple
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo $basic_machine$os
|
47
configure.bat
Normal file
47
configure.bat
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@echo off
|
||||||
|
rem Configure batch file for `Wget' utility
|
||||||
|
rem Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
rem This program is free software; you can redistribute it and/or modify
|
||||||
|
rem it under the terms of the GNU General Public License as published by
|
||||||
|
rem the Free Software Foundation; either version 2 of the License, or
|
||||||
|
rem (at your option) any later version.
|
||||||
|
|
||||||
|
rem This program is distributed in the hope that it will be useful,
|
||||||
|
rem but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
rem GNU General Public License for more details.
|
||||||
|
|
||||||
|
rem You should have received a copy of the GNU General Public License
|
||||||
|
rem along with this program; if not, write to the Free Software
|
||||||
|
rem Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
cls
|
||||||
|
if .%1 == .--borland goto :borland
|
||||||
|
if .%1 == .--msvc goto :msvc
|
||||||
|
if not .%BORPATH% == . goto :borland
|
||||||
|
if not .%1 == . goto :usage
|
||||||
|
|
||||||
|
:msvc
|
||||||
|
copy windows\config.h.ms src\config.h > nul
|
||||||
|
copy windows\Makefile.top Makefile > nul
|
||||||
|
copy windows\Makefile.src src\Makefile > nul
|
||||||
|
copy windows\Makefile.doc doc\Makefile > nul
|
||||||
|
|
||||||
|
echo Type NMAKE to start compiling.
|
||||||
|
echo If it doesn't work, try executing MSDEV\BIN\VCVARS32.BAT first,
|
||||||
|
echo and then NMAKE.
|
||||||
|
goto :end
|
||||||
|
|
||||||
|
:borland
|
||||||
|
copy windows\config.h.bor src\config.h > nul
|
||||||
|
copy windows\Makefile.top.bor Makefile > nul
|
||||||
|
copy windows\Makefile.src.bor src\Makefile > nul
|
||||||
|
copy windows\Makefile.doc doc\Makefile > nul
|
||||||
|
|
||||||
|
echo Type MAKE to start compiling.
|
||||||
|
goto :end
|
||||||
|
|
||||||
|
:usage
|
||||||
|
echo Usage: Configure [--borland | --msvc]
|
||||||
|
:end
|
209
configure.in
Normal file
209
configure.in
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
dnl Template file for GNU Autoconf
|
||||||
|
dnl Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
dnl This program is free software; you can redistribute it and/or modify
|
||||||
|
dnl it under the terms of the GNU General Public License as published by
|
||||||
|
dnl the Free Software Foundation; either version 2 of the License, or
|
||||||
|
dnl (at your option) any later version.
|
||||||
|
|
||||||
|
dnl This program is distributed in the hope that it will be useful,
|
||||||
|
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
dnl GNU General Public License for more details.
|
||||||
|
|
||||||
|
dnl You should have received a copy of the GNU General Public License
|
||||||
|
dnl along with this program; if not, write to the Free Software
|
||||||
|
dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
dnl
|
||||||
|
|
||||||
|
AC_INIT(src/version.c)
|
||||||
|
AC_PREREQ(2.12)
|
||||||
|
AC_CONFIG_HEADER(src/config.h)
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl What version of Wget are we building?
|
||||||
|
dnl
|
||||||
|
VERSION=`sed -e 's/^.*"\(.*\)";$/\1/' ${srcdir}/src/version.c`
|
||||||
|
echo "configuring for GNU Wget $VERSION"
|
||||||
|
AC_SUBST(VERSION)
|
||||||
|
PACKAGE=wget
|
||||||
|
AC_SUBST(PACKAGE)
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Get cannonical host
|
||||||
|
dnl
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
AC_DEFINE_UNQUOTED(OS_TYPE, "$host_os")
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Process features.
|
||||||
|
dnl
|
||||||
|
AC_ARG_WITH(socks,
|
||||||
|
[ --with-socks use the socks library],
|
||||||
|
[AC_DEFINE(HAVE_SOCKS)])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(opie,
|
||||||
|
[ --disable-opie disable support for opie or s/key FTP login],
|
||||||
|
USE_OPIE=$enableval, USE_OPIE=yes)
|
||||||
|
test x"${USE_OPIE}" = xyes && AC_DEFINE(USE_OPIE)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(digest,
|
||||||
|
[ --disable-digest disable support for HTTP digest authorization],
|
||||||
|
USE_DIGEST=$enableval, USE_DIGEST=yes)
|
||||||
|
test x"${USE_DIGEST}" = xyes && AC_DEFINE(USE_DIGEST)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
[ --disable-debug disable support for debugging output],
|
||||||
|
DEBUG=$enableval, DEBUG=yes)
|
||||||
|
test x"${DEBUG}" = xyes && AC_DEFINE(DEBUG)
|
||||||
|
|
||||||
|
case "${USE_OPIE}${USE_DIGEST}" in
|
||||||
|
*yes*)
|
||||||
|
MD5_OBJ='md5$o'
|
||||||
|
esac
|
||||||
|
if test x"$USE_OPIE" = xyes; then
|
||||||
|
OPIE_OBJ='ftp-opie$o'
|
||||||
|
fi
|
||||||
|
AC_SUBST(MD5_OBJ)
|
||||||
|
AC_SUBST(OPIE_OBJ)
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Whether make sets $(MAKE)...
|
||||||
|
dnl
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Find a good install
|
||||||
|
dnl
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Find the compiler
|
||||||
|
dnl
|
||||||
|
|
||||||
|
dnl We want these before the checks, so the checks can modify their values.
|
||||||
|
test -z "$CFLAGS" && CFLAGS= auto_cflags=1
|
||||||
|
test -z "$CC" && cc_specified=yes
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl if the user hasn't specified CFLAGS, then
|
||||||
|
dnl if compiler is gcc, then use -O2 and some warning flags
|
||||||
|
dnl else use os-specific flags or -O
|
||||||
|
dnl
|
||||||
|
if test -n "$auto_cflags"; then
|
||||||
|
if test -n "$GCC"; then
|
||||||
|
CFLAGS="$CFLAGS -O2 -Wall -Wno-implicit"
|
||||||
|
else
|
||||||
|
case "$host_os" in
|
||||||
|
*hpux*) CFLAGS="$CFLAGS +O3" ;;
|
||||||
|
*ultrix* | *osf*) CFLAGS="$CFLAGS -O -Olimit 2000" ;;
|
||||||
|
*) CFLAGS="$CFLAGS -O" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Handle AIX
|
||||||
|
dnl
|
||||||
|
AC_AIX
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl In case of {cyg,gnu}win32. Should be a _target_ test.
|
||||||
|
dnl Might also be erelevant for DJGPP.
|
||||||
|
dnl
|
||||||
|
case "$host_os" in
|
||||||
|
*win32) exeext='.exe';;
|
||||||
|
*) exeext='';;
|
||||||
|
esac
|
||||||
|
AC_SUBST(exeext)
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check if we can handle prototypes.
|
||||||
|
dnl
|
||||||
|
AM_C_PROTOTYPES
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
dnl
|
||||||
|
AC_C_CONST
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
dnl #### This generates a warning. What do I do to shut it up?
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Checks for headers
|
||||||
|
dnl
|
||||||
|
AC_CHECK_HEADERS(string.h stdarg.h unistd.h sys/time.h utime.h sys/utime.h)
|
||||||
|
AC_CHECK_HEADERS(sys/select.h sys/utsname.h pwd.h signal.h)
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Return type of signal-handlers
|
||||||
|
dnl
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check for struct utimbuf
|
||||||
|
WGET_STRUCT_UTIMBUF
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Checks for library functions.
|
||||||
|
dnl
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_CHECK_FUNCS(strdup strstr strcasecmp strncasecmp)
|
||||||
|
AC_CHECK_FUNCS(gettimeofday mktime strptime)
|
||||||
|
AC_CHECK_FUNCS(strerror vsnprintf select signal symlink access isatty)
|
||||||
|
AC_CHECK_FUNCS(uname gethostname)
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS(gethostbyname, [], [
|
||||||
|
AC_CHECK_LIB(nsl, gethostbyname)
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Checks for libraries.
|
||||||
|
dnl
|
||||||
|
|
||||||
|
AC_CHECK_LIB(socket, socket)
|
||||||
|
|
||||||
|
dnl #### This appears to be deficient with later versions of SOCKS.
|
||||||
|
if test "x${with_socks}" = xyes
|
||||||
|
then
|
||||||
|
AC_CHECK_LIB(resolv, main)
|
||||||
|
AC_CHECK_LIB(socks, Rconnect)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Set of available languages.
|
||||||
|
dnl
|
||||||
|
dnl #### This kind of sucks. Shouldn't the configure process
|
||||||
|
dnl determine this automagically by scanning `.po' files in `po/'
|
||||||
|
dnl subdirectory?
|
||||||
|
ALL_LINGUAS="cs de hr no it pt_BR"
|
||||||
|
|
||||||
|
dnl internationalization macros
|
||||||
|
WGET_WITH_NLS
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Find makeinfo. If makeinfo is not found, look for Emacs. If
|
||||||
|
dnl Emacs cannot be found, look for XEmacs.
|
||||||
|
dnl
|
||||||
|
|
||||||
|
AC_CHECK_PROGS(MAKEINFO, makeinfo emacs xemacs)
|
||||||
|
|
||||||
|
case "${MAKEINFO}" in
|
||||||
|
*makeinfo) MAKEINFO="${MAKEINFO} \$(srcdir)/wget.texi" ;;
|
||||||
|
*emacs | *xemacs) MAKEINFO="${MAKEINFO} -batch -q -no-site-file -eval '(find-file \"\$(srcdir)/wget.texi\")' -l texinfmt -f texinfo-format-buffer -f save-buffer" ;;
|
||||||
|
*) MAKEINFO="makeinfo \$(srcdir)/wget.texi" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Create output
|
||||||
|
dnl
|
||||||
|
AC_OUTPUT([Makefile src/Makefile doc/Makefile util/Makefile po/Makefile.in],
|
||||||
|
[WGET_PROCESS_PO
|
||||||
|
test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h])
|
245
doc/ChangeLog
Normal file
245
doc/ChangeLog
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
1998-09-10 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (HTTP Options): Warn against masquerading as Mozilla.
|
||||||
|
|
||||||
|
1998-05-24 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (clean): Remove HTML files.
|
||||||
|
|
||||||
|
1998-05-13 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Various updates.
|
||||||
|
(Proxies): New node.
|
||||||
|
|
||||||
|
1998-05-09 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* texinfo.tex: New file.
|
||||||
|
|
||||||
|
1998-05-08 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (dvi): New target.
|
||||||
|
|
||||||
|
1998-05-02 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Recursive Retrieval): Fix typo. Suggested by
|
||||||
|
Francois Pinard.
|
||||||
|
|
||||||
|
1998-04-18 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Fixed @dircategory, courtesy Karl Eichwalder.
|
||||||
|
|
||||||
|
1998-03-31 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in: Don't attempt to (un)install the man-page.
|
||||||
|
|
||||||
|
1998-03-30 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.1: Removed it.
|
||||||
|
|
||||||
|
1998-03-29 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Invoking): Split into more sections, analogous to
|
||||||
|
output of `wget --help'.
|
||||||
|
(HTTP Options): Document --user-agent.
|
||||||
|
|
||||||
|
1998-03-16 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Contributors): Updated with oodles of new names.
|
||||||
|
|
||||||
|
1998-02-22 Karl Eichwalder <ke@suse.de>
|
||||||
|
|
||||||
|
* Makefile.in (install.info): only info files (no *info.orig,
|
||||||
|
etc.).
|
||||||
|
|
||||||
|
1998-01-31 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (install.wgetrc): Don't use `!'.
|
||||||
|
|
||||||
|
1998-01-28 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Expanded.
|
||||||
|
|
||||||
|
1998-01-25 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document `--cache'.
|
||||||
|
(Contributors): Added Brian.
|
||||||
|
|
||||||
|
1997-07-26 Francois Pinard <pinard@iro.umontreal.ca>
|
||||||
|
|
||||||
|
* Makefile.in (install.wgetrc): Print the sample.wgetrc warning
|
||||||
|
only if the files actually differ.
|
||||||
|
|
||||||
|
1998-01-23 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in: Use `test ...' rather than `[ ... ]'.
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Explained suffices.
|
||||||
|
|
||||||
|
1998-01-23 Karl Heuer <kwzh@gnu.org>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Updated.
|
||||||
|
|
||||||
|
1997-12-18 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Mailing List): Update.
|
||||||
|
|
||||||
|
1997-04-23 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document `--follow-ftp'.
|
||||||
|
|
||||||
|
1997-02-17 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document --proxy-user and
|
||||||
|
--proxy-passwd.
|
||||||
|
|
||||||
|
1997-02-14 Karl Eichwalder <ke@ke.Central.DE>
|
||||||
|
|
||||||
|
* Makefile.in (install.wgetrc): Never ever nuke an existing rc file.
|
||||||
|
|
||||||
|
1997-02-02 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Updated and revised.
|
||||||
|
|
||||||
|
* wget.texi (Contributors): Update.
|
||||||
|
(Advanced Options): Removed bogus **/* example.
|
||||||
|
|
||||||
|
* wget.texi: Use ``...'' instead of "...".
|
||||||
|
|
||||||
|
1997-02-01 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Domain Acceptance): Document --exclude-domains.
|
||||||
|
|
||||||
|
1997-01-21 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document --ignore-length.
|
||||||
|
|
||||||
|
1997-01-20 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Time-Stamping): New node.
|
||||||
|
|
||||||
|
1997-01-12 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* Makefile.in (distclean): Don't remove wget.info*.
|
||||||
|
|
||||||
|
1997-01-08 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Mailing List): Update archive.
|
||||||
|
(Portability): Update the Windows port by Budor.
|
||||||
|
|
||||||
|
1996-12-21 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Security Considerations): New node.
|
||||||
|
|
||||||
|
1996-12-19 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document --passive.
|
||||||
|
|
||||||
|
1996-12-12 Dieter Baron <dillo@danbala.tuwien.ac.at>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Usage): Would reference prep instead of
|
||||||
|
wuarchive.
|
||||||
|
|
||||||
|
1996-11-25 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Documented --retr-symlinks.
|
||||||
|
|
||||||
|
1996-11-23 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document --delete-after.
|
||||||
|
|
||||||
|
1996-11-22 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Portability): Add IRIX and FreeBSD as the "regular"
|
||||||
|
platforms.
|
||||||
|
|
||||||
|
1996-11-20 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Usage): Document dot-style.
|
||||||
|
|
||||||
|
1996-11-18 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Usage): Dot customization example.
|
||||||
|
(Sample Wgetrc): Likewise.
|
||||||
|
|
||||||
|
1996-11-16 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Wgetrc Syntax): Explained emptying lists.
|
||||||
|
|
||||||
|
1996-11-13 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document includes/excludes.
|
||||||
|
(Wgetrc Commands): Likewise.
|
||||||
|
|
||||||
|
1996-11-10 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Options): Document headers.
|
||||||
|
|
||||||
|
1996-11-07 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* sample.wgetrc: Added header examples.
|
||||||
|
|
||||||
|
1996-11-06 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* sample.wgetrc: Rewritten.
|
||||||
|
|
||||||
|
* Makefile.in (install.wgetrc): Install sample.wgetrc.
|
||||||
|
(uninstall.info): Use $(RM).
|
||||||
|
|
||||||
|
1996-11-06 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Docfixes.
|
||||||
|
|
||||||
|
1996-11-03 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Proofread; *many* docfixes.
|
||||||
|
|
||||||
|
1996-11-02 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Introduction): Updated robots mailing list address.
|
||||||
|
|
||||||
|
1996-11-01 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi: Minor docfixes.
|
||||||
|
|
||||||
|
1996-10-26 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* wget.texi (Advanced Usage): Document passwords better.
|
||||||
|
|
||||||
|
* Makefile.in (distclean): Remove wget.1 on make distclean.
|
||||||
|
|
||||||
|
* wget.texi (Option Syntax): Explain --.
|
||||||
|
|
||||||
|
1996-10-21 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* fetch.texi (No Parent): update.
|
||||||
|
|
||||||
|
1996-10-18 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* fetch.texi (Advanced Options): Docfix.
|
||||||
|
|
||||||
|
1996-10-17 Tage Stabell-Kulo <tage@acm.org>
|
||||||
|
|
||||||
|
* geturl.texi (Advanced Options): Sort alphabetically.
|
||||||
|
|
||||||
|
1996-10-16 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* geturl.texi (Advanced Options): Describe -nr.
|
||||||
|
(Advanced Usage): Moved -O pipelines to Guru Usage.
|
||||||
|
(Simple Usage): Update.
|
||||||
|
(Advanced Options): Docfix.
|
||||||
|
|
||||||
|
* Makefile.in (RM): RM = rm -f.
|
||||||
|
|
||||||
|
1996-10-15 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* geturl.texi (Guru Usage): Add proxy-filling example.
|
||||||
|
|
||||||
|
1996-10-12 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* geturl.texi (Advanced Options): Added --spider.
|
||||||
|
|
||||||
|
1996-10-08 Hrvoje Niksic <hniksic@srce.hr>
|
||||||
|
|
||||||
|
* geturl.texi (Advanced Options): Added -X.
|
||||||
|
|
||||||
|
* Makefile.in: Added $(srcdir) where appropriate (I hope).
|
145
doc/Makefile.in
Normal file
145
doc/Makefile.in
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# Makefile for `wget' utility
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Version: @VERSION@
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
# Program to format Texinfo source into Info files.
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
# Program to format Texinfo source into DVI files.
|
||||||
|
TEXI2DVI = texi2dvi
|
||||||
|
# Program to convert DVI files to PostScript
|
||||||
|
DVIPS = dvips -D 300
|
||||||
|
# Program to convert texinfo files to html
|
||||||
|
TEXI2HTML = texi2html -expandinfo -split_chapter
|
||||||
|
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
infodir = @infodir@
|
||||||
|
mandir = @mandir@
|
||||||
|
manext = 1
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
MAN = wget.$(manext)
|
||||||
|
WGETRC = $(sysconfdir)/wgetrc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for building
|
||||||
|
#
|
||||||
|
|
||||||
|
all: wget.info # wget.cat
|
||||||
|
|
||||||
|
everything: all wget_us.ps wget_a4.ps wget_toc.html
|
||||||
|
|
||||||
|
wget.info: wget.texi
|
||||||
|
-$(MAKEINFO)
|
||||||
|
|
||||||
|
#wget.cat: $(MAN)
|
||||||
|
# nroff -man $(srcdir)/$(MAN) > wget.cat
|
||||||
|
|
||||||
|
dvi: wget.dvi
|
||||||
|
|
||||||
|
wget.dvi: wget.texi
|
||||||
|
$(TEXI2DVI) $(srcdir)/wget.texi
|
||||||
|
|
||||||
|
wget_us.ps: wget.dvi
|
||||||
|
$(DVIPS) -t letter -o $@ wget.dvi
|
||||||
|
|
||||||
|
wget_a4.ps: wget.dvi
|
||||||
|
$(DVIPS) -t a4 -o $@ wget.dvi
|
||||||
|
|
||||||
|
wget_toc.html: wget.texi
|
||||||
|
$(TEXI2HTML) $(srcdir)/wget.texi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for installing
|
||||||
|
#
|
||||||
|
|
||||||
|
# install all the documentation
|
||||||
|
install: install.info install.wgetrc # install.man
|
||||||
|
|
||||||
|
# uninstall all the documentation
|
||||||
|
uninstall: uninstall.info # uninstall.man
|
||||||
|
|
||||||
|
# install info pages, creating install directory if necessary
|
||||||
|
install.info: wget.info
|
||||||
|
$(top_srcdir)/mkinstalldirs $(infodir)
|
||||||
|
-for file in $(srcdir)/wget.info $(srcdir)/wget.info-*[0-9]; do \
|
||||||
|
test -f "$$file" && $(INSTALL_DATA) $$file $(infodir) ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# install man page, creating install directory if necessary
|
||||||
|
#install.man:
|
||||||
|
# $(top_srcdir)/mkinstalldirs $(mandir)/man$(manext)
|
||||||
|
# $(INSTALL_DATA) $(srcdir)/$(MAN) $(mandir)/man$(manext)/$(MAN)
|
||||||
|
|
||||||
|
# install sample.wgetrc
|
||||||
|
install.wgetrc:
|
||||||
|
$(top_srcdir)/mkinstalldirs $(sysconfdir)
|
||||||
|
@if test -f $(WGETRC); then \
|
||||||
|
if cmp -s $(srcdir)/sample.wgetrc $(WGETRC); then echo ""; \
|
||||||
|
else \
|
||||||
|
echo ' $(INSTALL_DATA) $(srcdir)/sample.wgetrc $(WGETRC).new'; \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/sample.wgetrc $(WGETRC).new; \
|
||||||
|
echo "WARNING: File \`$(WGETRC)' already exists and is spared."; \
|
||||||
|
echo " You might want to consider \`$(WGETRC).new',"; \
|
||||||
|
echo " and merge both into \`$(WGETRC)', for the best."; \
|
||||||
|
fi; \
|
||||||
|
else \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/sample.wgetrc $(WGETRC); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# uninstall info pages
|
||||||
|
uninstall.info:
|
||||||
|
$(RM) $(infodir)/wget.info*
|
||||||
|
|
||||||
|
# uninstall man page
|
||||||
|
#uninstall.man:
|
||||||
|
# $(RM) $(mandir)/man$(manext)/$(MAN)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for cleanup
|
||||||
|
#
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *~ *.bak *.cat *.html
|
||||||
|
$(RM) *.dvi *.aux *.cp *.cps *.fn *.toc *.tp *.vr *.ps *.ky *.pg *.log
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) Makefile
|
||||||
|
|
||||||
|
realclean: distclean
|
||||||
|
$(RM) wget.info*
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for maintenance
|
||||||
|
#
|
||||||
|
|
||||||
|
subdir = doc
|
||||||
|
|
||||||
|
Makefile: Makefile.in ../config.status
|
||||||
|
cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
|
19
doc/ansi2knr.1
Normal file
19
doc/ansi2knr.1
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.TH ANSI2KNR 1 "31 December 1990"
|
||||||
|
.SH NAME
|
||||||
|
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.I ansi2knr
|
||||||
|
input_file output_file
|
||||||
|
.SH DESCRIPTION
|
||||||
|
If no output_file is supplied, output goes to stdout.
|
||||||
|
.br
|
||||||
|
There are no error messages.
|
||||||
|
.sp
|
||||||
|
.I ansi2knr
|
||||||
|
recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line.
|
||||||
|
.sp
|
||||||
|
The following constructs will confuse it:
|
||||||
|
.br
|
||||||
|
- Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call).
|
||||||
|
.br
|
||||||
|
- Macros that tinker with the syntax of the function header.
|
95
doc/sample.wgetrc
Normal file
95
doc/sample.wgetrc
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
###
|
||||||
|
### Sample Wget initialization file .wgetrc
|
||||||
|
###
|
||||||
|
|
||||||
|
## You can use this file to change the default behaviour of wget or to
|
||||||
|
## avoid having to type many many command-line options. This file does
|
||||||
|
## not contain a comprehensive list of commands -- look at the manual
|
||||||
|
## to find out what you can put into this file.
|
||||||
|
##
|
||||||
|
## Wget initialization file can reside in /usr/local/etc/wgetrc
|
||||||
|
## (global, for all users) or $HOME/.wgetrc (for a single user).
|
||||||
|
##
|
||||||
|
## To use any of the settings in this file, you will have to uncomment
|
||||||
|
## them (and probably change them).
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Global settings (useful for setting up in /usr/local/etc/wgetrc).
|
||||||
|
## Think well before you change them, since they may reduce wget's
|
||||||
|
## functionality, and make it behave contrary to the documentation:
|
||||||
|
##
|
||||||
|
|
||||||
|
# You can set retrieve quota for beginners by specifying a value
|
||||||
|
# optionally followed by 'K' (kilobytes) or 'M' (megabytes). The
|
||||||
|
# default quota is unlimited.
|
||||||
|
#quota = inf
|
||||||
|
|
||||||
|
# You can lower (or raise) the default number of retries when
|
||||||
|
# downloading a file (default is 20).
|
||||||
|
#tries = 20
|
||||||
|
|
||||||
|
# Lowering the maximum depth of the recursive retrieval is handy to
|
||||||
|
# prevent newbies from going too "deep" when they unwittingly start
|
||||||
|
# the recursive retrieval. The default is 5.
|
||||||
|
#reclevel = 5
|
||||||
|
|
||||||
|
# Many sites are behind firewalls that do not allow initiation of
|
||||||
|
# connections from the outside. On these sites you have to use the
|
||||||
|
# `passive' feature of FTP. If you are behind such a firewall, you
|
||||||
|
# can turn this on to make Wget use passive FTP by default.
|
||||||
|
#passive_ftp = off
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Local settings (for a user to set in his $HOME/.wgetrc). It is
|
||||||
|
## *highly* undesirable to put these settings in the global file, since
|
||||||
|
## they are potentially dangerous to "normal" users.
|
||||||
|
##
|
||||||
|
## Even when setting up your own ~/.wgetrc, you should know what you
|
||||||
|
## are doing before doing so.
|
||||||
|
##
|
||||||
|
|
||||||
|
# Set this to on to use timestamping by default:
|
||||||
|
#timestamping = off
|
||||||
|
|
||||||
|
# It is a good idea to make Wget send your email address in a `From:'
|
||||||
|
# header with your request (so that server administrators can contact
|
||||||
|
# you in case of errors). Wget does *not* send `From:' by default.
|
||||||
|
#header = From: Your Name <username@site.domain>
|
||||||
|
|
||||||
|
# You can set up other headers, like Accept-Language. Accept-Language
|
||||||
|
# is *not* sent by default.
|
||||||
|
#header = Accept-Language: en
|
||||||
|
|
||||||
|
# You can set the default proxy for Wget to use. It will override the
|
||||||
|
# value in the environment.
|
||||||
|
#http_proxy = http://proxy.yoyodyne.com:18023/
|
||||||
|
|
||||||
|
# If you do not want to use proxy at all, set this to off.
|
||||||
|
#use_proxy = on
|
||||||
|
|
||||||
|
# You can customize the retrieval outlook. Valid options are default,
|
||||||
|
# binary, mega and micro.
|
||||||
|
#dot_style = default
|
||||||
|
|
||||||
|
# Setting this to off makes Wget not download /robots.txt. Be sure to
|
||||||
|
# know *exactly* what /robots.txt is and how it is used before changing
|
||||||
|
# the default!
|
||||||
|
#robots = on
|
||||||
|
|
||||||
|
# It can be useful to make Wget wait between connections. Set this to
|
||||||
|
# the number of seconds you want Wget to wait.
|
||||||
|
#wait = 0
|
||||||
|
|
||||||
|
# You can force creating directory structure, even if a single is being
|
||||||
|
# retrieved, by setting this to on.
|
||||||
|
#dirstruct = off
|
||||||
|
|
||||||
|
# You can turn on recursive retrieving by default (don't do this if
|
||||||
|
# you are not sure you know what it means) by setting this to on.
|
||||||
|
#recursive = off
|
||||||
|
|
||||||
|
# To have Wget follow FTP links from HTML files by default, set this
|
||||||
|
# to on:
|
||||||
|
#follow_ftp = off
|
5039
doc/texinfo.tex
Normal file
5039
doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
88
doc/wget.info
Normal file
88
doc/wget.info
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
This is Info file wget.info, produced by Makeinfo version 1.67 from the
|
||||||
|
input file ./wget.texi.
|
||||||
|
|
||||||
|
INFO-DIR-SECTION Net Utilities
|
||||||
|
INFO-DIR-SECTION World Wide Web
|
||||||
|
START-INFO-DIR-ENTRY
|
||||||
|
* Wget: (wget). The non-interactive network downloader.
|
||||||
|
END-INFO-DIR-ENTRY
|
||||||
|
|
||||||
|
This file documents the the GNU Wget utility for downloading network
|
||||||
|
data.
|
||||||
|
|
||||||
|
Copyright (C) 1996, 1997, 1998 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.
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute modified versions of
|
||||||
|
this manual under the conditions for verbatim copying, provided also
|
||||||
|
that the sections entitled "Copying" and "GNU General Public License"
|
||||||
|
are included exactly as in the original, and provided that the entire
|
||||||
|
resulting derived work is distributed under the terms of a permission
|
||||||
|
notice identical to this one.
|
||||||
|
|
||||||
|
|
||||||
|
Indirect:
|
||||||
|
wget.info-1: 955
|
||||||
|
wget.info-2: 50818
|
||||||
|
wget.info-3: 88475
|
||||||
|
|
||||||
|
Tag Table:
|
||||||
|
(Indirect)
|
||||||
|
Node: Top955
|
||||||
|
Node: Overview1832
|
||||||
|
Node: Invoking5006
|
||||||
|
Node: URL Format5815
|
||||||
|
Node: Option Syntax8147
|
||||||
|
Node: Basic Startup Options9571
|
||||||
|
Node: Logging and Input File Options10271
|
||||||
|
Node: Download Options12665
|
||||||
|
Node: Directory Options18450
|
||||||
|
Node: HTTP Options20928
|
||||||
|
Node: FTP Options24524
|
||||||
|
Node: Recursive Retrieval Options25717
|
||||||
|
Node: Recursive Accept/Reject Options27493
|
||||||
|
Node: Recursive Retrieval29575
|
||||||
|
Node: Following Links31871
|
||||||
|
Node: Relative Links32903
|
||||||
|
Node: Host Checking33417
|
||||||
|
Node: Domain Acceptance35450
|
||||||
|
Node: All Hosts37120
|
||||||
|
Node: Types of Files37547
|
||||||
|
Node: Directory-Based Limits39997
|
||||||
|
Node: FTP Links42637
|
||||||
|
Node: Time-Stamping43507
|
||||||
|
Node: Time-Stamping Usage45144
|
||||||
|
Node: HTTP Time-Stamping Internals46713
|
||||||
|
Node: FTP Time-Stamping Internals47922
|
||||||
|
Node: Startup File49130
|
||||||
|
Node: Wgetrc Location50003
|
||||||
|
Node: Wgetrc Syntax50818
|
||||||
|
Node: Wgetrc Commands51533
|
||||||
|
Node: Sample Wgetrc58229
|
||||||
|
Node: Examples62521
|
||||||
|
Node: Simple Usage63128
|
||||||
|
Node: Advanced Usage65522
|
||||||
|
Node: Guru Usage68273
|
||||||
|
Node: Various69935
|
||||||
|
Node: Proxies70459
|
||||||
|
Node: Distribution73224
|
||||||
|
Node: Mailing List73566
|
||||||
|
Node: Reporting Bugs74265
|
||||||
|
Node: Portability76050
|
||||||
|
Node: Signals77425
|
||||||
|
Node: Appendices78079
|
||||||
|
Node: Robots78494
|
||||||
|
Node: Introduction to RES79641
|
||||||
|
Node: RES Format81534
|
||||||
|
Node: User-Agent Field82638
|
||||||
|
Node: Disallow Field83402
|
||||||
|
Node: Norobots Examples84013
|
||||||
|
Node: Security Considerations84967
|
||||||
|
Node: Contributors85963
|
||||||
|
Node: Copying88475
|
||||||
|
Node: Concept Index107638
|
||||||
|
|
||||||
|
End Tag Table
|
1283
doc/wget.info-1
Normal file
1283
doc/wget.info-1
Normal file
File diff suppressed because it is too large
Load Diff
1079
doc/wget.info-2
Normal file
1079
doc/wget.info-2
Normal file
File diff suppressed because it is too large
Load Diff
534
doc/wget.info-3
Normal file
534
doc/wget.info-3
Normal file
@ -0,0 +1,534 @@
|
|||||||
|
This is Info file wget.info, produced by Makeinfo version 1.67 from the
|
||||||
|
input file ./wget.texi.
|
||||||
|
|
||||||
|
INFO-DIR-SECTION Net Utilities
|
||||||
|
INFO-DIR-SECTION World Wide Web
|
||||||
|
START-INFO-DIR-ENTRY
|
||||||
|
* Wget: (wget). The non-interactive network downloader.
|
||||||
|
END-INFO-DIR-ENTRY
|
||||||
|
|
||||||
|
This file documents the the GNU Wget utility for downloading network
|
||||||
|
data.
|
||||||
|
|
||||||
|
Copyright (C) 1996, 1997, 1998 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.
|
||||||
|
|
||||||
|
Permission is granted to copy and distribute modified versions of
|
||||||
|
this manual under the conditions for verbatim copying, provided also
|
||||||
|
that the sections entitled "Copying" and "GNU General Public License"
|
||||||
|
are included exactly as in the original, and provided that the entire
|
||||||
|
resulting derived work is distributed under the terms of a permission
|
||||||
|
notice identical to this one.
|
||||||
|
|
||||||
|
|
||||||
|
File: wget.info, Node: Copying, Next: Concept Index, Prev: Appendices, Up: Top
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
**************************
|
||||||
|
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
========
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it in
|
||||||
|
new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software,
|
||||||
|
and (2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
1. This License applies to any program or other work which contains a
|
||||||
|
notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program",
|
||||||
|
below, refers to any such program or work, and a "work based on
|
||||||
|
the Program" means either the Program or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Program or a
|
||||||
|
portion of it, either verbatim or with modifications and/or
|
||||||
|
translated into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".) Each
|
||||||
|
licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are
|
||||||
|
not covered by this License; they are outside its scope. The act
|
||||||
|
of running the Program is not restricted, and the output from the
|
||||||
|
Program is covered only if its contents constitute a work based on
|
||||||
|
the Program (independent of having been made by running the
|
||||||
|
Program). Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
2. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any
|
||||||
|
warranty; and give any other recipients of the Program a copy of
|
||||||
|
this License along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange
|
||||||
|
for a fee.
|
||||||
|
|
||||||
|
3. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a. You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b. You must cause any work that you distribute or publish, that
|
||||||
|
in whole or in part contains or is derived from the Program
|
||||||
|
or any part thereof, to be licensed as a whole at no charge
|
||||||
|
to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
c. If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display
|
||||||
|
an announcement including an appropriate copyright notice and
|
||||||
|
a notice that there is no warranty (or else, saying that you
|
||||||
|
provide a warranty) and that users may redistribute the
|
||||||
|
program under these conditions, and telling the user how to
|
||||||
|
view a copy of this License. (Exception: if the Program
|
||||||
|
itself is interactive but does not normally print such an
|
||||||
|
announcement, your work based on the Program is not required
|
||||||
|
to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the
|
||||||
|
Program, and can be reasonably considered independent and separate
|
||||||
|
works in themselves, then this License, and its terms, do not
|
||||||
|
apply to those sections when you distribute them as separate
|
||||||
|
works. But when you distribute the same sections as part of a
|
||||||
|
whole which is a work based on the Program, the distribution of
|
||||||
|
the whole must be on the terms of this License, whose permissions
|
||||||
|
for other licensees extend to the entire whole, and thus to each
|
||||||
|
and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or
|
||||||
|
contest your rights to work written entirely by you; rather, the
|
||||||
|
intent is to exercise the right to control the distribution of
|
||||||
|
derivative or collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the
|
||||||
|
Program with the Program (or with a work based on the Program) on
|
||||||
|
a volume of a storage or distribution medium does not bring the
|
||||||
|
other work under the scope of this License.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms
|
||||||
|
of Sections 1 and 2 above provided that you also do one of the
|
||||||
|
following:
|
||||||
|
|
||||||
|
a. Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of
|
||||||
|
Sections 1 and 2 above on a medium customarily used for
|
||||||
|
software interchange; or,
|
||||||
|
|
||||||
|
b. Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c. Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with
|
||||||
|
such an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete
|
||||||
|
source code means all the source code for all modules it contains,
|
||||||
|
plus any associated interface definition files, plus the scripts
|
||||||
|
used to control compilation and installation of the executable.
|
||||||
|
However, as a special exception, the source code distributed need
|
||||||
|
not include anything that is normally distributed (in either
|
||||||
|
source or binary form) with the major components (compiler,
|
||||||
|
kernel, and so on) of the operating system on which the executable
|
||||||
|
runs, unless that component itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this
|
||||||
|
License. However, parties who have received copies, or rights,
|
||||||
|
from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
6. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify
|
||||||
|
or distribute the Program or its derivative works. These actions
|
||||||
|
are prohibited by law if you do not accept this License.
|
||||||
|
Therefore, by modifying or distributing the Program (or any work
|
||||||
|
based on the Program), you indicate your acceptance of this
|
||||||
|
License to do so, and all its terms and conditions for copying,
|
||||||
|
distributing or modifying the Program or works based on it.
|
||||||
|
|
||||||
|
7. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program
|
||||||
|
subject to these terms and conditions. You may not impose any
|
||||||
|
further restrictions on the recipients' exercise of the rights
|
||||||
|
granted herein. You are not responsible for enforcing compliance
|
||||||
|
by third parties to this License.
|
||||||
|
|
||||||
|
8. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent
|
||||||
|
issues), conditions are imposed on you (whether by court order,
|
||||||
|
agreement or otherwise) that contradict the conditions of this
|
||||||
|
License, they do not excuse you from the conditions of this
|
||||||
|
License. If you cannot distribute so as to satisfy simultaneously
|
||||||
|
your obligations under this License and any other pertinent
|
||||||
|
obligations, then as a consequence you may not distribute the
|
||||||
|
Program at all. For example, if a patent license would not permit
|
||||||
|
royalty-free redistribution of the Program by all those who
|
||||||
|
receive copies directly or indirectly through you, then the only
|
||||||
|
way you could satisfy both it and this License would be to refrain
|
||||||
|
entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable
|
||||||
|
under any particular circumstance, the balance of the section is
|
||||||
|
intended to apply and the section as a whole is intended to apply
|
||||||
|
in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of
|
||||||
|
any such claims; this section has the sole purpose of protecting
|
||||||
|
the integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is
|
||||||
|
willing to distribute software through any other system and a
|
||||||
|
licensee cannot impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed
|
||||||
|
to be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
9. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces,
|
||||||
|
the original copyright holder who places the Program under this
|
||||||
|
License may add an explicit geographical distribution limitation
|
||||||
|
excluding those countries, so that distribution is permitted only
|
||||||
|
in or among countries not thus excluded. In such case, this
|
||||||
|
License incorporates the limitation as if written in the body of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
10. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the General Public License from time to time. Such
|
||||||
|
new versions will be similar in spirit to the present version, but
|
||||||
|
may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies a version number of this License which applies
|
||||||
|
to it and "any later version", you have the option of following
|
||||||
|
the terms and conditions either of that version or of any later
|
||||||
|
version published by the Free Software Foundation. If the Program
|
||||||
|
does not specify a version number of this License, you may choose
|
||||||
|
any version ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
11. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the
|
||||||
|
author to ask for permission. For software which is copyrighted
|
||||||
|
by the Free Software Foundation, write to the Free Software
|
||||||
|
Foundation; we sometimes make exceptions for this. Our decision
|
||||||
|
will be guided by the two goals of preserving the free status of
|
||||||
|
all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
||||||
|
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
||||||
|
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
|
||||||
|
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
|
||||||
|
SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
|
||||||
|
MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
|
||||||
|
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
|
||||||
|
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU
|
||||||
|
OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY
|
||||||
|
OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these
|
||||||
|
terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
|
||||||
|
Copyright (C) 19YY NAME OF AUTHOR
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 comes with ABSOLUTELY NO WARRANTY; for details
|
||||||
|
type `show w'. This is free software, and you are welcome
|
||||||
|
to redistribute it under certain conditions; type `show c'
|
||||||
|
for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the
|
||||||
|
appropriate parts of the General Public License. Of course, the
|
||||||
|
commands you use may be called something other than `show w' and `show
|
||||||
|
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||||
|
program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or
|
||||||
|
your school, if any, to sign a "copyright disclaimer" for the program,
|
||||||
|
if necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright
|
||||||
|
interest in the program `Gnomovision'
|
||||||
|
(which makes passes at compilers) written
|
||||||
|
by James Hacker.
|
||||||
|
|
||||||
|
SIGNATURE OF TY COON, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your
|
||||||
|
program into proprietary programs. If your program is a subroutine
|
||||||
|
library, you may consider it more useful to permit linking proprietary
|
||||||
|
applications with the library. If this is what you want to do, use the
|
||||||
|
GNU Library General Public License instead of this License.
|
||||||
|
|
||||||
|
|
||||||
|
File: wget.info, Node: Concept Index, Prev: Copying, Up: Top
|
||||||
|
|
||||||
|
Concept Index
|
||||||
|
*************
|
||||||
|
|
||||||
|
* Menu:
|
||||||
|
|
||||||
|
* .netrc: Startup File.
|
||||||
|
* .wgetrc: Startup File.
|
||||||
|
* accept directories: Directory-Based Limits.
|
||||||
|
* accept suffixes: Types of Files.
|
||||||
|
* accept wildcards: Types of Files.
|
||||||
|
* all hosts: All Hosts.
|
||||||
|
* append to log: Logging and Input File Options.
|
||||||
|
* arguments: Invoking.
|
||||||
|
* authentication: HTTP Options.
|
||||||
|
* bug reports: Reporting Bugs.
|
||||||
|
* bugs: Reporting Bugs.
|
||||||
|
* cache: HTTP Options.
|
||||||
|
* command line: Invoking.
|
||||||
|
* Content-Length, ignore: HTTP Options.
|
||||||
|
* continue retrieval: Download Options.
|
||||||
|
* contributors: Contributors.
|
||||||
|
* conversion of links: Recursive Retrieval Options.
|
||||||
|
* copying: Copying.
|
||||||
|
* cut directories: Directory Options.
|
||||||
|
* debug: Logging and Input File Options.
|
||||||
|
* delete after retrieval: Recursive Retrieval Options.
|
||||||
|
* directories: Directory-Based Limits.
|
||||||
|
* directories, exclude: Directory-Based Limits.
|
||||||
|
* directories, include: Directory-Based Limits.
|
||||||
|
* directory limits: Directory-Based Limits.
|
||||||
|
* directory prefix: Directory Options.
|
||||||
|
* DNS lookup: Host Checking.
|
||||||
|
* dot style: Download Options.
|
||||||
|
* examples: Examples.
|
||||||
|
* exclude directories: Directory-Based Limits.
|
||||||
|
* execute wgetrc command: Basic Startup Options.
|
||||||
|
* features: Overview.
|
||||||
|
* filling proxy cache: Recursive Retrieval Options.
|
||||||
|
* follow FTP links: Recursive Accept/Reject Options.
|
||||||
|
* following ftp links: FTP Links.
|
||||||
|
* following links: Following Links.
|
||||||
|
* force html: Logging and Input File Options.
|
||||||
|
* ftp time-stamping: FTP Time-Stamping Internals.
|
||||||
|
* globbing, toggle: FTP Options.
|
||||||
|
* GPL: Copying.
|
||||||
|
* hangup: Signals.
|
||||||
|
* header, add: HTTP Options.
|
||||||
|
* host checking: Host Checking.
|
||||||
|
* host lookup: Host Checking.
|
||||||
|
* http password: HTTP Options.
|
||||||
|
* http time-stamping: HTTP Time-Stamping Internals.
|
||||||
|
* http user: HTTP Options.
|
||||||
|
* ignore length: HTTP Options.
|
||||||
|
* include directories: Directory-Based Limits.
|
||||||
|
* incremental updating: Time-Stamping.
|
||||||
|
* input-file: Logging and Input File Options.
|
||||||
|
* invoking: Invoking.
|
||||||
|
* latest version: Distribution.
|
||||||
|
* links: Following Links.
|
||||||
|
* links conversion: Recursive Retrieval Options.
|
||||||
|
* list: Mailing List.
|
||||||
|
* location of wgetrc: Wgetrc Location.
|
||||||
|
* log file: Logging and Input File Options.
|
||||||
|
* mailing list: Mailing List.
|
||||||
|
* mirroring: Guru Usage.
|
||||||
|
* no parent: Directory-Based Limits.
|
||||||
|
* no warranty: Copying.
|
||||||
|
* no-clobber: Download Options.
|
||||||
|
* nohup: Invoking.
|
||||||
|
* norobots disallow: Disallow Field.
|
||||||
|
* norobots examples: Norobots Examples.
|
||||||
|
* norobots format: RES Format.
|
||||||
|
* norobots introduction: Introduction to RES.
|
||||||
|
* norobots user-agent: User-Agent Field.
|
||||||
|
* number of retries: Download Options.
|
||||||
|
* operating systems: Portability.
|
||||||
|
* option syntax: Option Syntax.
|
||||||
|
* output file: Logging and Input File Options.
|
||||||
|
* overview: Overview.
|
||||||
|
* passive ftp: FTP Options.
|
||||||
|
* pause: Download Options.
|
||||||
|
* portability: Portability.
|
||||||
|
* proxies: Proxies.
|
||||||
|
* proxy <1>: Download Options.
|
||||||
|
* proxy: HTTP Options.
|
||||||
|
* proxy authentication: HTTP Options.
|
||||||
|
* proxy filling: Recursive Retrieval Options.
|
||||||
|
* proxy password: HTTP Options.
|
||||||
|
* proxy user: HTTP Options.
|
||||||
|
* quiet: Logging and Input File Options.
|
||||||
|
* quota: Download Options.
|
||||||
|
* recursion: Recursive Retrieval.
|
||||||
|
* recursive retrieval: Recursive Retrieval.
|
||||||
|
* redirecting output: Guru Usage.
|
||||||
|
* reject directories: Directory-Based Limits.
|
||||||
|
* reject suffixes: Types of Files.
|
||||||
|
* reject wildcards: Types of Files.
|
||||||
|
* relative links: Relative Links.
|
||||||
|
* reporting bugs: Reporting Bugs.
|
||||||
|
* retries: Download Options.
|
||||||
|
* retrieval tracing style: Download Options.
|
||||||
|
* retrieve symbolic links: FTP Options.
|
||||||
|
* retrieving: Recursive Retrieval.
|
||||||
|
* robots: Robots.
|
||||||
|
* robots.txt: Robots.
|
||||||
|
* sample wgetrc: Sample Wgetrc.
|
||||||
|
* security: Security Considerations.
|
||||||
|
* server maintenance: Robots.
|
||||||
|
* server response, print: Download Options.
|
||||||
|
* server response, save: HTTP Options.
|
||||||
|
* signal handling: Signals.
|
||||||
|
* span hosts: All Hosts.
|
||||||
|
* spider: Download Options.
|
||||||
|
* startup: Startup File.
|
||||||
|
* startup file: Startup File.
|
||||||
|
* suffixes, accept: Types of Files.
|
||||||
|
* suffixes, reject: Types of Files.
|
||||||
|
* syntax of options: Option Syntax.
|
||||||
|
* syntax of wgetrc: Wgetrc Syntax.
|
||||||
|
* time-stamping: Time-Stamping.
|
||||||
|
* time-stamping usage: Time-Stamping Usage.
|
||||||
|
* timeout: Download Options.
|
||||||
|
* timestamping: Time-Stamping.
|
||||||
|
* tries: Download Options.
|
||||||
|
* types of files: Types of Files.
|
||||||
|
* updating the archives: Time-Stamping.
|
||||||
|
* URL: URL Format.
|
||||||
|
* URL syntax: URL Format.
|
||||||
|
* usage, time-stamping: Time-Stamping Usage.
|
||||||
|
* user-agent: HTTP Options.
|
||||||
|
* various: Various.
|
||||||
|
* verbose: Logging and Input File Options.
|
||||||
|
* wait: Download Options.
|
||||||
|
* Wget as spider: Download Options.
|
||||||
|
* wgetrc: Startup File.
|
||||||
|
* wgetrc commands: Wgetrc Commands.
|
||||||
|
* wgetrc location: Wgetrc Location.
|
||||||
|
* wgetrc syntax: Wgetrc Syntax.
|
||||||
|
* wildcards, accept: Types of Files.
|
||||||
|
* wildcards, reject: Types of Files.
|
||||||
|
|
||||||
|
|
3118
doc/wget.texi
Normal file
3118
doc/wget.texi
Normal file
File diff suppressed because it is too large
Load Diff
250
install-sh
Executable file
250
install-sh
Executable file
@ -0,0 +1,250 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
#
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||||
|
#
|
||||||
|
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
# documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
# the above copyright notice appear in all copies and that both that
|
||||||
|
# copyright notice and this permission notice appear in supporting
|
||||||
|
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||||
|
# publicity pertaining to distribution of the software without specific,
|
||||||
|
# written prior permission. M.I.T. makes no representations about the
|
||||||
|
# suitability of this software for any purpose. It is provided "as is"
|
||||||
|
# without express or implied warranty.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
transformbasename=""
|
||||||
|
transform_arg=""
|
||||||
|
instcmd="$mvprog"
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=""
|
||||||
|
chgrpcmd=""
|
||||||
|
stripcmd=""
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=""
|
||||||
|
dst=""
|
||||||
|
dir_arg=""
|
||||||
|
|
||||||
|
while [ x"$1" != x ]; do
|
||||||
|
case $1 in
|
||||||
|
-c) instcmd="$cpprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd="$stripprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
*) if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
src=$1
|
||||||
|
else
|
||||||
|
# this colon is to work around a 386BSD /bin/sh bug
|
||||||
|
:
|
||||||
|
dst=$1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no input file specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]; then
|
||||||
|
dst=$src
|
||||||
|
src=""
|
||||||
|
|
||||||
|
if [ -d $dst ]; then
|
||||||
|
instcmd=:
|
||||||
|
else
|
||||||
|
instcmd=mkdir
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
|
||||||
|
if [ -f $src -o -d $src ]
|
||||||
|
then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
echo "install: $src does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dst" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no destination specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; if your system
|
||||||
|
# does not like double slashes in filenames, you may need to add some logic
|
||||||
|
|
||||||
|
if [ -d $dst ]
|
||||||
|
then
|
||||||
|
dst="$dst"/`basename $src`
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## this sed command emulates the dirname command
|
||||||
|
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if [ ! -d "$dstdir" ]; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-${defaultIFS}}"
|
||||||
|
|
||||||
|
oIFS="${IFS}"
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
IFS="${oIFS}"
|
||||||
|
|
||||||
|
pathcomp=''
|
||||||
|
|
||||||
|
while [ $# -ne 0 ] ; do
|
||||||
|
pathcomp="${pathcomp}${1}"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ ! -d "${pathcomp}" ] ;
|
||||||
|
then
|
||||||
|
$mkdirprog "${pathcomp}"
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
pathcomp="${pathcomp}/"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]
|
||||||
|
then
|
||||||
|
$doit $instcmd $dst &&
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
|
||||||
|
if [ x"$transformarg" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
dstfile=`basename $dst $transformbasename |
|
||||||
|
sed $transformarg`$transformbasename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't allow the sed command to completely eliminate the filename
|
||||||
|
|
||||||
|
if [ x"$dstfile" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make a temp file name in the proper directory.
|
||||||
|
|
||||||
|
dsttmp=$dstdir/#inst.$$#
|
||||||
|
|
||||||
|
# Move or copy the file name to the temp name
|
||||||
|
|
||||||
|
$doit $instcmd $src $dsttmp &&
|
||||||
|
|
||||||
|
trap "rm -f ${dsttmp}" 0 &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits
|
||||||
|
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
|
||||||
|
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||||
|
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||||
|
|
||||||
|
fi &&
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
40
mkinstalldirs
Executable file
40
mkinstalldirs
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# mkinstalldirs --- make directory hierarchy
|
||||||
|
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||||
|
# Created: 1993-05-16
|
||||||
|
# Public domain
|
||||||
|
|
||||||
|
# $Id: mkinstalldirs 2 1999-12-02 07:42:23Z kwget $
|
||||||
|
|
||||||
|
errstatus=0
|
||||||
|
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||||
|
shift
|
||||||
|
|
||||||
|
pathcomp=
|
||||||
|
for d
|
||||||
|
do
|
||||||
|
pathcomp="$pathcomp$d"
|
||||||
|
case "$pathcomp" in
|
||||||
|
-* ) pathcomp=./$pathcomp ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
echo "mkdir $pathcomp" 1>&2
|
||||||
|
|
||||||
|
mkdir "$pathcomp" || lasterr=$?
|
||||||
|
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
errstatus=$lasterr
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
pathcomp="$pathcomp/"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $errstatus
|
||||||
|
|
||||||
|
# mkinstalldirs ends here
|
212
po/Makefile.in.in
Normal file
212
po/Makefile.in.in
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
# Makefile for program source directory in GNU NLS utilities package.
|
||||||
|
# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
|
||||||
|
#
|
||||||
|
# This file file be copied and used freely without restrictions. It can
|
||||||
|
# be used in projects which are not available under the GNU Public License
|
||||||
|
# but which still want to provide support for the GNU gettext functionality.
|
||||||
|
# Please note that the actual code is *not* freely available.
|
||||||
|
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
datadir = $(prefix)/@DATADIRNAME@
|
||||||
|
localedir = $(datadir)/locale
|
||||||
|
gnulocaledir = $(prefix)/share/locale
|
||||||
|
gettextsrcdir = $(prefix)/share/gettext/po
|
||||||
|
subdir = po
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
|
||||||
|
MSGFMT = @MSGFMT@
|
||||||
|
XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
|
||||||
|
MSGMERGE = PATH=../src:$$PATH msgmerge
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
|
INCLUDES = -I.. -I$(top_srcdir)/intl
|
||||||
|
|
||||||
|
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
|
||||||
|
|
||||||
|
POFILES = @POFILES@
|
||||||
|
GMOFILES = @GMOFILES@
|
||||||
|
DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
|
||||||
|
$(POFILES) $(GMOFILES) $(SOURCES)
|
||||||
|
|
||||||
|
POTFILES = \
|
||||||
|
|
||||||
|
CATALOGS = @CATALOGS@
|
||||||
|
CATOBJEXT = @CATOBJEXT@
|
||||||
|
INSTOBJEXT = @INSTOBJEXT@
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .o .po .pox .gmo .mo .msg
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) $<
|
||||||
|
|
||||||
|
.po.pox:
|
||||||
|
$(MAKE) $(PACKAGE).pot
|
||||||
|
$(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
|
||||||
|
|
||||||
|
.po.mo:
|
||||||
|
$(MSGFMT) -o $@ $<
|
||||||
|
|
||||||
|
.po.gmo:
|
||||||
|
file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
|
||||||
|
&& rm -f $$file && $(GMSGFMT) -o $$file $<
|
||||||
|
|
||||||
|
|
||||||
|
all: all-@USE_NLS@
|
||||||
|
|
||||||
|
all-yes: $(CATALOGS)
|
||||||
|
all-no:
|
||||||
|
|
||||||
|
$(srcdir)/$(PACKAGE).pot: $(POTFILES)
|
||||||
|
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
|
||||||
|
--add-comments --keyword=_ --keyword=N_ \
|
||||||
|
--files-from=$(srcdir)/POTFILES.in
|
||||||
|
rm -f $(srcdir)/$(PACKAGE).pot
|
||||||
|
mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
|
||||||
|
|
||||||
|
install.mo: install
|
||||||
|
install: install-exec install-data
|
||||||
|
install-exec:
|
||||||
|
install-data: install-data-@USE_NLS@
|
||||||
|
install-data-no: all
|
||||||
|
install-data-yes: all
|
||||||
|
@catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
case "$$cat" in \
|
||||||
|
*.gmo) destdir=$(gnulocaledir);; \
|
||||||
|
*) destdir=$(localedir);; \
|
||||||
|
esac; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
dir=$$destdir/$$lang/LC_MESSAGES; \
|
||||||
|
$(top_srcdir)/mkinstalldirs $$dir; \
|
||||||
|
if test -r $$cat; then \
|
||||||
|
$(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
|
||||||
|
else \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
echo "installing $(srcdir)/$$cat as" \
|
||||||
|
"$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
|
||||||
|
fi; \
|
||||||
|
if test -r $$cat.m; then \
|
||||||
|
$(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
|
||||||
|
else \
|
||||||
|
if test -r $(srcdir)/$$cat.m ; then \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/$$cat.m \
|
||||||
|
$$dir/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
echo "installing $(srcdir)/$$cat as" \
|
||||||
|
"$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
|
||||||
|
else \
|
||||||
|
true; \
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
if test "$(PACKAGE)" = "gettext"; then \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/Makefile.in.in \
|
||||||
|
$(gettextsrcdir)/Makefile.in.in; \
|
||||||
|
else \
|
||||||
|
: ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define this as empty until I found a useful application.
|
||||||
|
installcheck:
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
done
|
||||||
|
rm -f $(gettextsrcdir)/po-Makefile.in.in
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
cat-id-tbl.o: ../intl/libgettext.h
|
||||||
|
|
||||||
|
dvi info tags TAGS ID:
|
||||||
|
|
||||||
|
mostlyclean:
|
||||||
|
rm -f core core.* *.pox $(PACKAGE).po *.old.po
|
||||||
|
rm -fr *.o
|
||||||
|
|
||||||
|
clean: mostlyclean
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile Makefile.in POTFILES *.mo *.msg
|
||||||
|
|
||||||
|
maintainer-clean: distclean
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
rm -f $(GMOFILES)
|
||||||
|
|
||||||
|
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
||||||
|
dist distdir: update-po $(DISTFILES)
|
||||||
|
dists="$(DISTFILES)"; \
|
||||||
|
for file in $$dists; do \
|
||||||
|
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|
||||||
|
|| cp -p $(srcdir)/$$file $(distdir); \
|
||||||
|
done
|
||||||
|
|
||||||
|
update-po: Makefile
|
||||||
|
$(MAKE) $(PACKAGE).pot
|
||||||
|
PATH=`pwd`/../src:$$PATH; \
|
||||||
|
cd $(srcdir); \
|
||||||
|
catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
mv $$lang.po $$lang.old.po; \
|
||||||
|
echo "$$lang:"; \
|
||||||
|
if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
|
||||||
|
rm -f $$lang.old.po; \
|
||||||
|
else \
|
||||||
|
echo "msgmerge for $$cat failed!"; \
|
||||||
|
rm -f $$lang.po; \
|
||||||
|
mv $$lang.old.po $$lang.po; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
POTFILES: POTFILES.in
|
||||||
|
( if test 'x$(srcdir)' != 'x.'; then \
|
||||||
|
posrcprefix='$(top_srcdir)/'; \
|
||||||
|
else \
|
||||||
|
posrcprefix="../"; \
|
||||||
|
fi; \
|
||||||
|
rm -f $@-t $@ \
|
||||||
|
&& (sed -e '/^#/d' -e '/^[ ]*$$/d' \
|
||||||
|
-e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
|
||||||
|
| sed -e '$$s/\\$$//') > $@-t \
|
||||||
|
&& chmod a-w $@-t \
|
||||||
|
&& mv $@-t $@ )
|
||||||
|
|
||||||
|
Makefile: Makefile.in.in ../config.status POTFILES
|
||||||
|
cd .. \
|
||||||
|
&& CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
|
||||||
|
$(SHELL) ./config.status
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make not to export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
26
po/POTFILES.in
Normal file
26
po/POTFILES.in
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# List of files which containing translatable strings.
|
||||||
|
# Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# Package source files
|
||||||
|
src/cmpt.c
|
||||||
|
src/connect.c
|
||||||
|
src/fnmatch.c
|
||||||
|
src/ftp-basic.c
|
||||||
|
src/ftp-ls.c
|
||||||
|
src/ftp-opie.c
|
||||||
|
src/ftp.c
|
||||||
|
src/getopt.c
|
||||||
|
src/headers.c
|
||||||
|
src/host.c
|
||||||
|
src/html.c
|
||||||
|
src/http.c
|
||||||
|
src/init.c
|
||||||
|
src/log.c
|
||||||
|
src/main.c
|
||||||
|
src/mswindows.c
|
||||||
|
src/netrc.c
|
||||||
|
src/rbuf.c
|
||||||
|
src/recur.c
|
||||||
|
src/retr.c
|
||||||
|
src/url.c
|
||||||
|
src/utils.c
|
BIN
po/pt_BR.gmo
Normal file
BIN
po/pt_BR.gmo
Normal file
Binary file not shown.
1168
po/pt_BR.po
Normal file
1168
po/pt_BR.po
Normal file
File diff suppressed because it is too large
Load Diff
921
po/wget.pot
Normal file
921
po/wget.pot
Normal file
@ -0,0 +1,921 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR Free Software Foundation, Inc.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"POT-Creation-Date: 1998-09-21 19:08+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
|
"Content-Transfer-Encoding: ENCODING\n"
|
||||||
|
|
||||||
|
#. Login to the server:
|
||||||
|
#. First: Establish the control connection.
|
||||||
|
#: src/ftp.c:147 src/http.c:346
|
||||||
|
#, c-format
|
||||||
|
msgid "Connecting to %s:%hu... "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:169 src/ftp.c:411 src/http.c:363
|
||||||
|
#, c-format
|
||||||
|
msgid "Connection to %s:%hu refused.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Second: Login with proper USER/PASS sequence.
|
||||||
|
#: src/ftp.c:190 src/http.c:374
|
||||||
|
msgid "connected!\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:191
|
||||||
|
#, c-format
|
||||||
|
msgid "Logging in as %s ... "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:200 src/ftp.c:253 src/ftp.c:301 src/ftp.c:353 src/ftp.c:447
|
||||||
|
#: src/ftp.c:520 src/ftp.c:568 src/ftp.c:616
|
||||||
|
msgid "Error in server response, closing control connection.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:208
|
||||||
|
msgid "Error in server greeting.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:216 src/ftp.c:262 src/ftp.c:310 src/ftp.c:362 src/ftp.c:457
|
||||||
|
#: src/ftp.c:530 src/ftp.c:578 src/ftp.c:626
|
||||||
|
msgid "Write failed, closing control connection.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:223
|
||||||
|
msgid "The server refuses login.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:230
|
||||||
|
msgid "Login incorrect.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:237
|
||||||
|
msgid "Logged in!\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:270
|
||||||
|
#, c-format
|
||||||
|
msgid "Unknown type `%c', closing control connection.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:283
|
||||||
|
msgid "done. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:289
|
||||||
|
msgid "==> CWD not needed.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:317
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"No such directory `%s'.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:331 src/ftp.c:599 src/ftp.c:647 src/url.c:1431
|
||||||
|
msgid "done.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. do not CWD
|
||||||
|
#: src/ftp.c:335
|
||||||
|
msgid "==> CWD not required.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:369
|
||||||
|
msgid "Cannot initiate PASV transfer.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:373
|
||||||
|
msgid "Cannot parse PASV response.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:387
|
||||||
|
#, c-format
|
||||||
|
msgid "Will try connecting to %s:%hu.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:432 src/ftp.c:504 src/ftp.c:548
|
||||||
|
msgid "done. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:474
|
||||||
|
#, c-format
|
||||||
|
msgid "Bind error (%s).\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:490
|
||||||
|
msgid "Invalid PORT.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:537
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"REST failed, starting from scratch.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:586
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"No such file `%s'.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:634
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"No such file or directory `%s'.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:692 src/ftp.c:699
|
||||||
|
#, c-format
|
||||||
|
msgid "Length: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:694 src/ftp.c:701
|
||||||
|
#, c-format
|
||||||
|
msgid " [%s to go]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:703
|
||||||
|
msgid " (unauthoritative)\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:721
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s, closing control connection.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:729
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (%s) - Data connection: %s; "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:746
|
||||||
|
msgid "Control connection closed.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:764
|
||||||
|
msgid "Data transfer aborted.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:830
|
||||||
|
#, c-format
|
||||||
|
msgid "File `%s' already there, not retrieving.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:896 src/http.c:922
|
||||||
|
#, c-format
|
||||||
|
msgid "(try:%2d)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:955 src/http.c:1116
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"%s (%s) - `%s' saved [%ld]\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1001
|
||||||
|
#, c-format
|
||||||
|
msgid "Using `%s' as listing tmp file.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1013
|
||||||
|
#, c-format
|
||||||
|
msgid "Removed `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1049
|
||||||
|
#, c-format
|
||||||
|
msgid "Recursion depth %d exceeded max. depth %d.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1096 src/http.c:1054
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"Local file `%s' is more recent, not retrieving.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1102 src/http.c:1060
|
||||||
|
#, c-format
|
||||||
|
msgid "The sizes do not match (local %ld), retrieving.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1119
|
||||||
|
msgid "Invalid name of the symlink, skipping.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1136
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"Already have correct symlink %s -> %s\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1144
|
||||||
|
#, c-format
|
||||||
|
msgid "Creating symlink %s -> %s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1155
|
||||||
|
#, c-format
|
||||||
|
msgid "Symlinks not supported, skipping symlink `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1167
|
||||||
|
#, c-format
|
||||||
|
msgid "Skipping directory `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1176
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: unknown/unsupported file type.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1193
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: corrupt time-stamp.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1213
|
||||||
|
#, c-format
|
||||||
|
msgid "Will not retrieve dirs since depth is %d (max %d).\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1252
|
||||||
|
#, c-format
|
||||||
|
msgid "Not descending to `%s' as it is excluded/not-included.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1297
|
||||||
|
#, c-format
|
||||||
|
msgid "Rejecting `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. No luck.
|
||||||
|
#. #### This message SUCKS. We should see what was the
|
||||||
|
#. reason that nothing was retrieved.
|
||||||
|
#: src/ftp.c:1344
|
||||||
|
#, c-format
|
||||||
|
msgid "No matches on pattern `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1404
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrote HTML-ized index to `%s' [%ld].\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ftp.c:1409
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrote HTML-ized index to `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/getopt.c:454
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: option `%s' is ambiguous\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/getopt.c:478
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: option `--%s' doesn't allow an argument\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/getopt.c:483
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: option `%c%s' doesn't allow an argument\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/getopt.c:498
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: option `%s' requires an argument\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. --option
|
||||||
|
#: src/getopt.c:528
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: unrecognized option `--%s'\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. +option or -option
|
||||||
|
#: src/getopt.c:532
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: unrecognized option `%c%s'\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. 1003.2 specifies the format of this message.
|
||||||
|
#: src/getopt.c:563
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: illegal option -- %c\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. 1003.2 specifies the format of this message.
|
||||||
|
#: src/getopt.c:602
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: option requires an argument -- %c\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:432
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Cannot determine user-id.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:444
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: uname failed: %s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:456
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: gethostname failed\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:484
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: cannot determine local IP address.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:498
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: cannot reverse-lookup local IP address.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. This gets ticked pretty often. Karl Berry reports
|
||||||
|
#. that there can be valid reasons for the local host
|
||||||
|
#. name not to be an FQDN, so I've decided to remove the
|
||||||
|
#. annoying warning.
|
||||||
|
#: src/host.c:511
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: reverse-lookup of local address did not yield FQDN!\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:539
|
||||||
|
msgid "Host not found"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/host.c:541
|
||||||
|
msgid "Unknown error"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:439 src/html.c:441
|
||||||
|
#, c-format
|
||||||
|
msgid "Index of /%s on %s:%d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:463
|
||||||
|
msgid "time unknown "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:467
|
||||||
|
msgid "File "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:470
|
||||||
|
msgid "Directory "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:473
|
||||||
|
msgid "Link "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:476
|
||||||
|
msgid "Not sure "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/html.c:494
|
||||||
|
#, c-format
|
||||||
|
msgid " (%s bytes)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:492
|
||||||
|
msgid "Failed writing HTTP request.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:497
|
||||||
|
#, c-format
|
||||||
|
msgid "%s request sent, awaiting response... "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:536
|
||||||
|
msgid "End of file while parsing headers.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:547
|
||||||
|
#, c-format
|
||||||
|
msgid "Read error (%s) in headers.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:587
|
||||||
|
msgid "No data received"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:589
|
||||||
|
msgid "Malformed status line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:594
|
||||||
|
msgid "(no description)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. If we have tried it already, then there is not point
|
||||||
|
#. retrying it.
|
||||||
|
#: src/http.c:678
|
||||||
|
msgid "Authorization failed.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:685
|
||||||
|
msgid "Unknown authentication scheme.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:748
|
||||||
|
#, c-format
|
||||||
|
msgid "Location: %s%s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:749 src/http.c:774
|
||||||
|
msgid "unspecified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:750
|
||||||
|
msgid " [following]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. No need to print this output if the body won't be
|
||||||
|
#. downloaded at all, or if the original server response is
|
||||||
|
#. printed.
|
||||||
|
#: src/http.c:764
|
||||||
|
msgid "Length: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:769
|
||||||
|
#, c-format
|
||||||
|
msgid " (%s to go)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:774
|
||||||
|
msgid "ignored"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:857
|
||||||
|
msgid "Warning: wildcards not supported in HTTP.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. If opt.noclobber is turned on and file already exists, do not
|
||||||
|
#. retrieve the file
|
||||||
|
#: src/http.c:872
|
||||||
|
#, c-format
|
||||||
|
msgid "File `%s' already there, will not retrieve.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:978
|
||||||
|
#, c-format
|
||||||
|
msgid "Cannot write to `%s' (%s).\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:988
|
||||||
|
#, c-format
|
||||||
|
msgid "ERROR: Redirection (%d) without location.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1011
|
||||||
|
#, c-format
|
||||||
|
msgid "%s ERROR %d: %s.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1023
|
||||||
|
msgid "Last-modified header missing -- time-stamps turned off.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1031
|
||||||
|
msgid "Last-modified header invalid -- time-stamp ignored.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1064
|
||||||
|
msgid "Remote file is newer, retrieving.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1098
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"%s (%s) - `%s' saved [%ld/%ld]\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1130
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (%s) - Connection closed at byte %ld. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1138
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"%s (%s) - `%s' saved [%ld/%ld])\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1150
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (%s) - Connection closed at byte %ld/%ld. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1161
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (%s) - Read error at byte %ld (%s)."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/http.c:1169
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (%s) - Read error at byte %ld/%ld (%s). "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:312 src/netrc.c:250
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Cannot read %s (%s).\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:333 src/init.c:339
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Error in %s at line %d.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:370
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Warning: Both system and user wgetrc point to `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:458
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: BUG: unknown command `%s', value `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:485
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s: Please specify on or off.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:503 src/init.c:760 src/init.c:782 src/init.c:855
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s: Invalid specification `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/init.c:616 src/init.c:638 src/init.c:660 src/init.c:686
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Invalid specification `%s'\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:101
|
||||||
|
#, c-format
|
||||||
|
msgid "Usage: %s [OPTION]... [URL]...\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:109
|
||||||
|
#, c-format
|
||||||
|
msgid "GNU Wget %s, a non-interactive network retriever.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Had to split this in parts, so the #@@#%# Ultrix compiler and cpp
|
||||||
|
#. don't bitch. Also, it makes translation much easier.
|
||||||
|
#: src/main.c:114
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"Mandatory arguments to long options are mandatory for short options too.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:117
|
||||||
|
msgid ""
|
||||||
|
"Startup:\n"
|
||||||
|
" -V, --version display the version of Wget and exit.\n"
|
||||||
|
" -h, --help print this help.\n"
|
||||||
|
" -b, --background go to background after startup.\n"
|
||||||
|
" -e, --execute=COMMAND execute a `.wgetrc' command.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:123
|
||||||
|
msgid ""
|
||||||
|
"Logging and input file:\n"
|
||||||
|
" -o, --output-file=FILE log messages to FILE.\n"
|
||||||
|
" -a, --append-output=FILE append messages to FILE.\n"
|
||||||
|
" -d, --debug print debug output.\n"
|
||||||
|
" -q, --quiet quiet (no output).\n"
|
||||||
|
" -v, --verbose be verbose (this is the default).\n"
|
||||||
|
" -nv, --non-verbose turn off verboseness, without being quiet.\n"
|
||||||
|
" -i, --input-file=FILE read URL-s from file.\n"
|
||||||
|
" -F, --force-html treat input file as HTML.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:133
|
||||||
|
msgid ""
|
||||||
|
"Download:\n"
|
||||||
|
" -t, --tries=NUMBER set number of retries to NUMBER (0 "
|
||||||
|
"unlimits).\n"
|
||||||
|
" -O --output-document=FILE write documents to FILE.\n"
|
||||||
|
" -nc, --no-clobber don't clobber existing files.\n"
|
||||||
|
" -c, --continue restart getting an existing file.\n"
|
||||||
|
" --dot-style=STYLE set retrieval display style.\n"
|
||||||
|
" -N, --timestamping don't retrieve files if older than local.\n"
|
||||||
|
" -S, --server-response print server response.\n"
|
||||||
|
" --spider don't download anything.\n"
|
||||||
|
" -T, --timeout=SECONDS set the read timeout to SECONDS.\n"
|
||||||
|
" -w, --wait=SECONDS wait SECONDS between retrievals.\n"
|
||||||
|
" -Y, --proxy=on/off turn proxy on or off.\n"
|
||||||
|
" -Q, --quota=NUMBER set retrieval quota to NUMBER.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:147
|
||||||
|
msgid ""
|
||||||
|
"Directories:\n"
|
||||||
|
" -nd --no-directories don't create directories.\n"
|
||||||
|
" -x, --force-directories force creation of directories.\n"
|
||||||
|
" -nH, --no-host-directories don't create host directories.\n"
|
||||||
|
" -P, --directory-prefix=PREFIX save files to PREFIX/...\n"
|
||||||
|
" --cut-dirs=NUMBER ignore NUMBER remote directory "
|
||||||
|
"components.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:154
|
||||||
|
msgid ""
|
||||||
|
"HTTP options:\n"
|
||||||
|
" --http-user=USER set http user to USER.\n"
|
||||||
|
" --http-passwd=PASS set http password to PASS.\n"
|
||||||
|
" -C, --cache=on/off (dis)allow server-cached data (normally "
|
||||||
|
"allowed).\n"
|
||||||
|
" --ignore-length ignore `Content-Length' header field.\n"
|
||||||
|
" --header=STRING insert STRING among the headers.\n"
|
||||||
|
" --proxy-user=USER set USER as proxy username.\n"
|
||||||
|
" --proxy-passwd=PASS set PASS as proxy password.\n"
|
||||||
|
" -s, --save-headers save the HTTP headers to file.\n"
|
||||||
|
" -U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:165
|
||||||
|
msgid ""
|
||||||
|
"FTP options:\n"
|
||||||
|
" --retr-symlinks retrieve FTP symbolic links.\n"
|
||||||
|
" -g, --glob=on/off turn file name globbing on or off.\n"
|
||||||
|
" --passive-ftp use the \"passive\" transfer mode.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:170
|
||||||
|
msgid ""
|
||||||
|
"Recursive retrieval:\n"
|
||||||
|
" -r, --recursive recursive web-suck -- use with care!.\n"
|
||||||
|
" -l, --level=NUMBER maximum recursion depth (0 to unlimit).\n"
|
||||||
|
" --delete-after delete downloaded files.\n"
|
||||||
|
" -k, --convert-links convert non-relative links to relative.\n"
|
||||||
|
" -m, --mirror turn on options suitable for mirroring.\n"
|
||||||
|
" -nr, --dont-remove-listing don't remove `.listing' files.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:178
|
||||||
|
msgid ""
|
||||||
|
"Recursive accept/reject:\n"
|
||||||
|
" -A, --accept=LIST list of accepted extensions.\n"
|
||||||
|
" -R, --reject=LIST list of rejected extensions.\n"
|
||||||
|
" -D, --domains=LIST list of accepted domains.\n"
|
||||||
|
" --exclude-domains=LIST comma-separated list of rejected "
|
||||||
|
"domains.\n"
|
||||||
|
" -L, --relative follow relative links only.\n"
|
||||||
|
" --follow-ftp follow FTP links from HTML documents.\n"
|
||||||
|
" -H, --span-hosts go to foreign hosts when recursive.\n"
|
||||||
|
" -I, --include-directories=LIST list of allowed directories.\n"
|
||||||
|
" -X, --exclude-directories=LIST list of excluded directories.\n"
|
||||||
|
" -nh, --no-host-lookup don't DNS-lookup hosts.\n"
|
||||||
|
" -np, --no-parent don't ascend to the parent directory.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:191
|
||||||
|
msgid "Mail bug reports and suggestions to <bug-wget@gnu.org>.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:347
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: debug support not compiled in.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:395
|
||||||
|
msgid ""
|
||||||
|
"Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\n"
|
||||||
|
"This program 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"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:401
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"Written by Hrvoje Niksic <hniksic@srce.hr>.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:465
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s: invalid command\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:515
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: illegal option -- `-n%c'\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. #### Something nicer should be printed here -- similar to the
|
||||||
|
#. pre-1.5 `--help' page.
|
||||||
|
#: src/main.c:518 src/main.c:560 src/main.c:591
|
||||||
|
#, c-format
|
||||||
|
msgid "Try `%s --help' for more options.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:571
|
||||||
|
msgid "Can't be verbose and quiet at the same time.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:577
|
||||||
|
msgid "Can't timestamp and not clobber old files at the same time.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. No URL specified.
|
||||||
|
#: src/main.c:586
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: missing URL\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:674
|
||||||
|
#, c-format
|
||||||
|
msgid "No URLs found in %s.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:683
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"FINISHED --%s--\n"
|
||||||
|
"Downloaded: %s bytes in %d files\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/main.c:688
|
||||||
|
#, c-format
|
||||||
|
msgid "Download quota (%s bytes) EXCEEDED!\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Please note that the double `%' in `%%s' is intentional, because
|
||||||
|
#. redirect_output passes tmp through printf.
|
||||||
|
#: src/main.c:715
|
||||||
|
msgid "%s received, redirecting output to `%%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/mswindows.c:118
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
"CTRL+Break received, redirecting output to `%s'.\n"
|
||||||
|
"Execution continued in background.\n"
|
||||||
|
"You may stop Wget by pressing CTRL+ALT+DELETE.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. parent, no error
|
||||||
|
#: src/mswindows.c:135 src/utils.c:268
|
||||||
|
msgid "Continuing in background.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/mswindows.c:137 src/utils.c:270
|
||||||
|
#, c-format
|
||||||
|
msgid "Output will be written to `%s'.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/mswindows.c:227
|
||||||
|
#, c-format
|
||||||
|
msgid "Starting WinHelp %s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/mswindows.c:254 src/mswindows.c:262
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Couldn't find usable socket driver.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/netrc.c:334
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s:%d: warning: \"%s\" token appears before any machine name\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/netrc.c:365
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s:%d: unknown token \"%s\"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/netrc.c:429
|
||||||
|
#, c-format
|
||||||
|
msgid "Usage: %s NETRC [HOSTNAME]\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/netrc.c:439
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: cannot stat %s: %s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/recur.c:449 src/retr.c:462
|
||||||
|
#, c-format
|
||||||
|
msgid "Removing %s.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/recur.c:450
|
||||||
|
#, c-format
|
||||||
|
msgid "Removing %s since it should be rejected.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/recur.c:609
|
||||||
|
msgid "Loading robots.txt; please ignore errors.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:193
|
||||||
|
#, c-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" [ skipping %dK ]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:344
|
||||||
|
msgid "Could not find proxy host.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:355
|
||||||
|
#, c-format
|
||||||
|
msgid "Proxy %s: Must be HTTP.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:398
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: Redirection to itself.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:483
|
||||||
|
msgid ""
|
||||||
|
"Giving up.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/retr.c:483
|
||||||
|
msgid ""
|
||||||
|
"Retrying.\n"
|
||||||
|
"\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/url.c:940
|
||||||
|
#, c-format
|
||||||
|
msgid "Error (%s): Link %s without a base provided.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/url.c:955
|
||||||
|
#, c-format
|
||||||
|
msgid "Error (%s): Base %s relative, without referer URL.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/url.c:1373
|
||||||
|
#, c-format
|
||||||
|
msgid "Converting %s... "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/url.c:1378 src/url.c:1389
|
||||||
|
#, c-format
|
||||||
|
msgid "Cannot convert links in %s: %s\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/utils.c:71
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s: Not enough memory.\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/utils.c:203
|
||||||
|
msgid "Unknown/unsupported protocol"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/utils.c:206
|
||||||
|
msgid "Invalid port specification"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/utils.c:209
|
||||||
|
msgid "Invalid host name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/utils.c:430
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unlink symlink `%s': %s\n"
|
||||||
|
msgstr ""
|
3206
src/ChangeLog
Normal file
3206
src/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
158
src/Makefile.in
Normal file
158
src/Makefile.in
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
# Makefile for `wget' utility
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Version: @VERSION@
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
ANSI2KNR = @ANSI2KNR@
|
||||||
|
o = .@U@o
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = @bindir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
localedir = $(prefix)/share/locale
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
# The following line is losing on some versions of make!
|
||||||
|
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
exeext = @exeext@
|
||||||
|
|
||||||
|
INCLUDES = -I. -I$(srcdir)
|
||||||
|
|
||||||
|
COMPILE = $(CC) $(INCLUDES) $(CPPFLAGS) $(DEFS) $(CFLAGS)
|
||||||
|
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
RM = rm -f
|
||||||
|
ETAGS = etags
|
||||||
|
|
||||||
|
# Conditional compiles
|
||||||
|
ALLOCA = @ALLOCA@
|
||||||
|
MD5_OBJ = @MD5_OBJ@
|
||||||
|
OPIE_OBJ = @OPIE_OBJ@
|
||||||
|
|
||||||
|
OBJ = $(ALLOCA) cmpt$o connect$o fnmatch$o ftp$o ftp-basic$o \
|
||||||
|
ftp-ls$o $(OPIE_OBJ) getopt$o headers$o host$o html$o \
|
||||||
|
http$o init$o log$o main$o $(MD5_OBJ) netrc$o rbuf$o \
|
||||||
|
recur$o retr$o url$o utils$o version$o
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .o ._c ._o
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
.c._c: $(ANSI2KNR)
|
||||||
|
$(ANSI2KNR) $< > $*.tmp && mv $*.tmp $@
|
||||||
|
|
||||||
|
._c._o:
|
||||||
|
@echo $(COMPILE) -c $<
|
||||||
|
@rm -f _$*.c
|
||||||
|
@ln $< _$*.c && $(COMPILE) -c _$*.c && mv _$*.o $@ && rm _$*.c
|
||||||
|
|
||||||
|
.c._o: $(ANSI2KNR)
|
||||||
|
$(ANSI2KNR) $< > $*.tmp && mv $*.tmp $*._c
|
||||||
|
@echo $(COMPILE) -c $*._c
|
||||||
|
@rm -f _$*.c
|
||||||
|
@ln $*._c _$*.c && $(COMPILE) -c _$*.c && mv _$*.o $@ && rm _$*.c
|
||||||
|
|
||||||
|
# Dependencies for building
|
||||||
|
|
||||||
|
wget$(exeext): $(OBJ)
|
||||||
|
$(LINK) $(OBJ) $(LIBS)
|
||||||
|
|
||||||
|
ansi2knr: ansi2knr.o
|
||||||
|
$(CC) -o ansi2knr ansi2knr.o $(LIBS)
|
||||||
|
|
||||||
|
$(OBJ): $(ANSI2KNR)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for installing
|
||||||
|
#
|
||||||
|
|
||||||
|
install: install.bin
|
||||||
|
|
||||||
|
uninstall: uninstall.bin
|
||||||
|
|
||||||
|
install.bin: wget$(exeext)
|
||||||
|
$(top_srcdir)/mkinstalldirs $(bindir)
|
||||||
|
$(INSTALL_PROGRAM) wget$(exeext) $(bindir)/wget$(exeext)
|
||||||
|
|
||||||
|
uninstall.bin:
|
||||||
|
$(RM) $(bindir)/wget$(exeext)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for cleanup
|
||||||
|
#
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.o wget$(exeext) *~ *.bak core $(ANSI2KNR) *._o *._c
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) Makefile config.h
|
||||||
|
|
||||||
|
realclean: distclean
|
||||||
|
$(RM) TAGS
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for maintenance
|
||||||
|
#
|
||||||
|
|
||||||
|
subdir = src
|
||||||
|
|
||||||
|
Makefile: Makefile.in ../config.status
|
||||||
|
cd .. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
|
||||||
|
|
||||||
|
TAGS: *.c *.h
|
||||||
|
-$(ETAGS) *.c *.h
|
||||||
|
|
||||||
|
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||||
|
|
||||||
|
cmpt$o: config.h wget.h sysdep.h options.h
|
||||||
|
connect$o: config.h wget.h sysdep.h options.h connect.h host.h
|
||||||
|
fnmatch$o: config.h wget.h sysdep.h options.h fnmatch.h
|
||||||
|
ftp-basic$o: config.h wget.h sysdep.h options.h utils.h rbuf.h connect.h host.h
|
||||||
|
ftp-ls$o: config.h wget.h sysdep.h options.h utils.h ftp.h rbuf.h
|
||||||
|
ftp-opie$o: config.h wget.h sysdep.h options.h md5.h
|
||||||
|
ftp$o: config.h wget.h sysdep.h options.h utils.h url.h rbuf.h retr.h ftp.h html.h connect.h host.h fnmatch.h netrc.h
|
||||||
|
getopt$o: wget.h sysdep.h options.h
|
||||||
|
headers$o: config.h wget.h sysdep.h options.h connect.h rbuf.h headers.h
|
||||||
|
host$o: config.h wget.h sysdep.h options.h utils.h host.h url.h
|
||||||
|
html$o: config.h wget.h sysdep.h options.h url.h utils.h ftp.h rbuf.h html.h
|
||||||
|
http$o: config.h wget.h sysdep.h options.h utils.h url.h host.h rbuf.h retr.h headers.h connect.h fnmatch.h netrc.h
|
||||||
|
init$o: config.h wget.h sysdep.h options.h utils.h init.h host.h recur.h netrc.h
|
||||||
|
log$o: config.h wget.h sysdep.h options.h utils.h
|
||||||
|
main$o: config.h wget.h sysdep.h options.h utils.h getopt.h init.h retr.h rbuf.h recur.h host.h
|
||||||
|
md5$o: wget.h sysdep.h options.h md5.h
|
||||||
|
mswindows$o: config.h winsock.h wget.h sysdep.h options.h url.h
|
||||||
|
netrc$o: wget.h sysdep.h options.h utils.h netrc.h init.h
|
||||||
|
rbuf$o: config.h wget.h sysdep.h options.h rbuf.h connect.h
|
||||||
|
recur$o: config.h wget.h sysdep.h options.h url.h recur.h utils.h retr.h rbuf.h ftp.h fnmatch.h host.h
|
||||||
|
retr$o: config.h wget.h sysdep.h options.h utils.h retr.h rbuf.h url.h recur.h ftp.h host.h connect.h
|
||||||
|
url$o: config.h wget.h sysdep.h options.h utils.h url.h host.h html.h
|
||||||
|
utils$o: config.h wget.h sysdep.h options.h utils.h fnmatch.h
|
504
src/alloca.c
Normal file
504
src/alloca.c
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
/* alloca.c -- allocate automatically reclaimed memory
|
||||||
|
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||||
|
|
||||||
|
This implementation of the PWB library alloca function,
|
||||||
|
which is used to allocate space off the run-time stack so
|
||||||
|
that it is automatically reclaimed upon procedure exit,
|
||||||
|
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||||
|
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||||
|
|
||||||
|
There are some preprocessor constants that can
|
||||||
|
be defined when compiling for your specific system, for
|
||||||
|
improved efficiency; however, the defaults should be okay.
|
||||||
|
|
||||||
|
The general concept of this implementation is to keep
|
||||||
|
track of all alloca-allocated blocks, and reclaim any
|
||||||
|
that are found to be deeper in the stack than the current
|
||||||
|
invocation. This heuristic does not reclaim storage as
|
||||||
|
soon as it becomes invalid, but it will do so eventually.
|
||||||
|
|
||||||
|
As a special case, alloca(0) reclaims storage without
|
||||||
|
allocating any. It is a good idea to use alloca(0) in
|
||||||
|
your main control loop, etc. to force garbage collection. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STDLIB_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef emacs
|
||||||
|
#include "blockinput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If compiling with GCC 2, this file's not needed. */
|
||||||
|
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||||
|
|
||||||
|
/* If someone has defined alloca as a macro,
|
||||||
|
there must be some other way alloca is supposed to work. */
|
||||||
|
#ifndef alloca
|
||||||
|
|
||||||
|
#ifdef emacs
|
||||||
|
#ifdef static
|
||||||
|
/* actually, only want this if static is defined as ""
|
||||||
|
-- this is for usg, in which emacs must undefine static
|
||||||
|
in order to make unexec workable
|
||||||
|
*/
|
||||||
|
#ifndef STACK_DIRECTION
|
||||||
|
you
|
||||||
|
lose
|
||||||
|
-- must know STACK_DIRECTION at compile-time
|
||||||
|
#endif /* STACK_DIRECTION undefined */
|
||||||
|
#endif /* static */
|
||||||
|
#endif /* emacs */
|
||||||
|
|
||||||
|
/* If your stack is a linked list of frames, you have to
|
||||||
|
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||||
|
|
||||||
|
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
long i00afunc ();
|
||||||
|
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||||
|
#else
|
||||||
|
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
typedef void *pointer;
|
||||||
|
#else
|
||||||
|
typedef char *pointer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Different portions of Emacs need to call different versions of
|
||||||
|
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||||
|
ordinary malloc isn't protected from input signals. On the other
|
||||||
|
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||||
|
them are very simple, and don't have an xmalloc routine.
|
||||||
|
|
||||||
|
Non-Emacs programs expect this to call xmalloc.
|
||||||
|
|
||||||
|
Callers below should use malloc. */
|
||||||
|
|
||||||
|
#ifndef emacs
|
||||||
|
#define malloc xmalloc
|
||||||
|
#endif
|
||||||
|
extern pointer malloc ();
|
||||||
|
|
||||||
|
/* Define STACK_DIRECTION if you know the direction of stack
|
||||||
|
growth for your system; otherwise it will be automatically
|
||||||
|
deduced at run-time.
|
||||||
|
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
|
||||||
|
#ifndef STACK_DIRECTION
|
||||||
|
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STACK_DIRECTION != 0
|
||||||
|
|
||||||
|
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||||
|
|
||||||
|
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||||
|
|
||||||
|
static int stack_dir; /* 1 or -1 once known. */
|
||||||
|
#define STACK_DIR stack_dir
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_stack_direction ()
|
||||||
|
{
|
||||||
|
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||||
|
auto char dummy; /* To get stack address. */
|
||||||
|
|
||||||
|
if (addr == NULL)
|
||||||
|
{ /* Initial entry. */
|
||||||
|
addr = ADDRESS_FUNCTION (dummy);
|
||||||
|
|
||||||
|
find_stack_direction (); /* Recurse once. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Second entry. */
|
||||||
|
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||||
|
stack_dir = 1; /* Stack grew upward. */
|
||||||
|
else
|
||||||
|
stack_dir = -1; /* Stack grew downward. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* STACK_DIRECTION == 0 */
|
||||||
|
|
||||||
|
/* An "alloca header" is used to:
|
||||||
|
(a) chain together all alloca'ed blocks;
|
||||||
|
(b) keep track of stack depth.
|
||||||
|
|
||||||
|
It is very important that sizeof(header) agree with malloc
|
||||||
|
alignment chunk size. The following default should work okay. */
|
||||||
|
|
||||||
|
#ifndef ALIGN_SIZE
|
||||||
|
#define ALIGN_SIZE sizeof(double)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef union hdr
|
||||||
|
{
|
||||||
|
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
union hdr *next; /* For chaining headers. */
|
||||||
|
char *deep; /* For stack depth measure. */
|
||||||
|
} h;
|
||||||
|
} header;
|
||||||
|
|
||||||
|
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||||
|
|
||||||
|
/* Return a pointer to at least SIZE bytes of storage,
|
||||||
|
which will be automatically reclaimed upon exit from
|
||||||
|
the procedure that called alloca. Originally, this space
|
||||||
|
was supposed to be taken from the current stack frame of the
|
||||||
|
caller, but that method cannot be made to work for some
|
||||||
|
implementations of C, for example under Gould's UTX/32. */
|
||||||
|
|
||||||
|
pointer
|
||||||
|
alloca (size)
|
||||||
|
unsigned size;
|
||||||
|
{
|
||||||
|
auto char probe; /* Probes stack depth: */
|
||||||
|
register char *depth = ADDRESS_FUNCTION (probe);
|
||||||
|
|
||||||
|
#if STACK_DIRECTION == 0
|
||||||
|
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||||
|
find_stack_direction ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reclaim garbage, defined as all alloca'd storage that
|
||||||
|
was allocated from deeper in the stack than currently. */
|
||||||
|
|
||||||
|
{
|
||||||
|
register header *hp; /* Traverses linked list. */
|
||||||
|
|
||||||
|
#ifdef emacs
|
||||||
|
BLOCK_INPUT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (hp = last_alloca_header; hp != NULL;)
|
||||||
|
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||||
|
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||||
|
{
|
||||||
|
register header *np = hp->h.next;
|
||||||
|
|
||||||
|
free ((pointer) hp); /* Collect garbage. */
|
||||||
|
|
||||||
|
hp = np; /* -> next header. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break; /* Rest are not deeper. */
|
||||||
|
|
||||||
|
last_alloca_header = hp; /* -> last valid storage. */
|
||||||
|
|
||||||
|
#ifdef emacs
|
||||||
|
UNBLOCK_INPUT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return NULL; /* No allocation required. */
|
||||||
|
|
||||||
|
/* Allocate combined header + user data storage. */
|
||||||
|
|
||||||
|
{
|
||||||
|
register pointer new = malloc (sizeof (header) + size);
|
||||||
|
/* Address of header. */
|
||||||
|
|
||||||
|
if (new == 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
((header *) new)->h.next = last_alloca_header;
|
||||||
|
((header *) new)->h.deep = depth;
|
||||||
|
|
||||||
|
last_alloca_header = (header *) new;
|
||||||
|
|
||||||
|
/* User storage begins just after header. */
|
||||||
|
|
||||||
|
return (pointer) ((char *) new + sizeof (header));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRAY_STACK
|
||||||
|
#define CRAY_STACK
|
||||||
|
#ifndef CRAY2
|
||||||
|
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||||
|
struct stack_control_header
|
||||||
|
{
|
||||||
|
long shgrow:32; /* Number of times stack has grown. */
|
||||||
|
long shaseg:32; /* Size of increments to stack. */
|
||||||
|
long shhwm:32; /* High water mark of stack. */
|
||||||
|
long shsize:32; /* Current size of stack (all segments). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The stack segment linkage control information occurs at
|
||||||
|
the high-address end of a stack segment. (The stack
|
||||||
|
grows from low addresses to high addresses.) The initial
|
||||||
|
part of the stack segment linkage control information is
|
||||||
|
0200 (octal) words. This provides for register storage
|
||||||
|
for the routine which overflows the stack. */
|
||||||
|
|
||||||
|
struct stack_segment_linkage
|
||||||
|
{
|
||||||
|
long ss[0200]; /* 0200 overflow words. */
|
||||||
|
long sssize:32; /* Number of words in this segment. */
|
||||||
|
long ssbase:32; /* Offset to stack base. */
|
||||||
|
long:32;
|
||||||
|
long sspseg:32; /* Offset to linkage control of previous
|
||||||
|
segment of stack. */
|
||||||
|
long:32;
|
||||||
|
long sstcpt:32; /* Pointer to task common address block. */
|
||||||
|
long sscsnm; /* Private control structure number for
|
||||||
|
microtasking. */
|
||||||
|
long ssusr1; /* Reserved for user. */
|
||||||
|
long ssusr2; /* Reserved for user. */
|
||||||
|
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||||
|
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||||
|
long sscray[7]; /* Reserved for Cray Research. */
|
||||||
|
long ssa0;
|
||||||
|
long ssa1;
|
||||||
|
long ssa2;
|
||||||
|
long ssa3;
|
||||||
|
long ssa4;
|
||||||
|
long ssa5;
|
||||||
|
long ssa6;
|
||||||
|
long ssa7;
|
||||||
|
long sss0;
|
||||||
|
long sss1;
|
||||||
|
long sss2;
|
||||||
|
long sss3;
|
||||||
|
long sss4;
|
||||||
|
long sss5;
|
||||||
|
long sss6;
|
||||||
|
long sss7;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* CRAY2 */
|
||||||
|
/* The following structure defines the vector of words
|
||||||
|
returned by the STKSTAT library routine. */
|
||||||
|
struct stk_stat
|
||||||
|
{
|
||||||
|
long now; /* Current total stack size. */
|
||||||
|
long maxc; /* Amount of contiguous space which would
|
||||||
|
be required to satisfy the maximum
|
||||||
|
stack demand to date. */
|
||||||
|
long high_water; /* Stack high-water mark. */
|
||||||
|
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||||
|
long hits; /* Number of internal buffer hits. */
|
||||||
|
long extends; /* Number of block extensions. */
|
||||||
|
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||||
|
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||||
|
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||||
|
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||||
|
long segments; /* Current number of stack segments. */
|
||||||
|
long maxs; /* Maximum number of stack segments so far. */
|
||||||
|
long pad_size; /* Stack pad size. */
|
||||||
|
long current_address; /* Current stack segment address. */
|
||||||
|
long current_size; /* Current stack segment size. This
|
||||||
|
number is actually corrupted by STKSTAT to
|
||||||
|
include the fifteen word trailer area. */
|
||||||
|
long initial_address; /* Address of initial segment. */
|
||||||
|
long initial_size; /* Size of initial segment. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following structure describes the data structure which trails
|
||||||
|
any stack segment. I think that the description in 'asdef' is
|
||||||
|
out of date. I only describe the parts that I am sure about. */
|
||||||
|
|
||||||
|
struct stk_trailer
|
||||||
|
{
|
||||||
|
long this_address; /* Address of this block. */
|
||||||
|
long this_size; /* Size of this block (does not include
|
||||||
|
this trailer). */
|
||||||
|
long unknown2;
|
||||||
|
long unknown3;
|
||||||
|
long link; /* Address of trailer block of previous
|
||||||
|
segment. */
|
||||||
|
long unknown5;
|
||||||
|
long unknown6;
|
||||||
|
long unknown7;
|
||||||
|
long unknown8;
|
||||||
|
long unknown9;
|
||||||
|
long unknown10;
|
||||||
|
long unknown11;
|
||||||
|
long unknown12;
|
||||||
|
long unknown13;
|
||||||
|
long unknown14;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CRAY2 */
|
||||||
|
#endif /* not CRAY_STACK */
|
||||||
|
|
||||||
|
#ifdef CRAY2
|
||||||
|
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||||
|
I doubt that "lint" will like this much. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long *address)
|
||||||
|
{
|
||||||
|
struct stk_stat status;
|
||||||
|
struct stk_trailer *trailer;
|
||||||
|
long *block, size;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
/* We want to iterate through all of the segments. The first
|
||||||
|
step is to get the stack status structure. We could do this
|
||||||
|
more quickly and more directly, perhaps, by referencing the
|
||||||
|
$LM00 common block, but I know that this works. */
|
||||||
|
|
||||||
|
STKSTAT (&status);
|
||||||
|
|
||||||
|
/* Set up the iteration. */
|
||||||
|
|
||||||
|
trailer = (struct stk_trailer *) (status.current_address
|
||||||
|
+ status.current_size
|
||||||
|
- 15);
|
||||||
|
|
||||||
|
/* There must be at least one stack segment. Therefore it is
|
||||||
|
a fatal error if "trailer" is null. */
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Discard segments that do not contain our argument address. */
|
||||||
|
|
||||||
|
while (trailer != 0)
|
||||||
|
{
|
||||||
|
block = (long *) trailer->this_address;
|
||||||
|
size = trailer->this_size;
|
||||||
|
if (block == 0 || size == 0)
|
||||||
|
abort ();
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
if ((block <= address) && (address < (block + size)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the result to the offset in this segment and add the sizes
|
||||||
|
of all predecessor segments. */
|
||||||
|
|
||||||
|
result = address - block;
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (trailer->this_size <= 0)
|
||||||
|
abort ();
|
||||||
|
result += trailer->this_size;
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
}
|
||||||
|
while (trailer != 0);
|
||||||
|
|
||||||
|
/* We are done. Note that if you present a bogus address (one
|
||||||
|
not in any segment), you will get a different number back, formed
|
||||||
|
from subtracting the address of the first block. This is probably
|
||||||
|
not what you want. */
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* not CRAY2 */
|
||||||
|
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||||
|
Determine the number of the cell within the stack,
|
||||||
|
given the address of the cell. The purpose of this
|
||||||
|
routine is to linearize, in some sense, stack addresses
|
||||||
|
for alloca. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long address)
|
||||||
|
{
|
||||||
|
long stkl = 0;
|
||||||
|
|
||||||
|
long size, pseg, this_segment, stack;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
struct stack_segment_linkage *ssptr;
|
||||||
|
|
||||||
|
/* Register B67 contains the address of the end of the
|
||||||
|
current stack segment. If you (as a subprogram) store
|
||||||
|
your registers on the stack and find that you are past
|
||||||
|
the contents of B67, you have overflowed the segment.
|
||||||
|
|
||||||
|
B67 also points to the stack segment linkage control
|
||||||
|
area, which is what we are really interested in. */
|
||||||
|
|
||||||
|
stkl = CRAY_STACKSEG_END ();
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
|
||||||
|
/* If one subtracts 'size' from the end of the segment,
|
||||||
|
one has the address of the first word of the segment.
|
||||||
|
|
||||||
|
If this is not the first segment, 'pseg' will be
|
||||||
|
nonzero. */
|
||||||
|
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
|
||||||
|
this_segment = stkl - size;
|
||||||
|
|
||||||
|
/* It is possible that calling this routine itself caused
|
||||||
|
a stack overflow. Discard stack segments which do not
|
||||||
|
contain the target address. */
|
||||||
|
|
||||||
|
while (!(this_segment <= address && address <= stkl))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||||
|
#endif
|
||||||
|
if (pseg == 0)
|
||||||
|
break;
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
this_segment = stkl - size;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = address - this_segment;
|
||||||
|
|
||||||
|
/* If you subtract pseg from the current end of the stack,
|
||||||
|
you get the address of the previous stack segment's end.
|
||||||
|
This seems a little convoluted to me, but I'll bet you save
|
||||||
|
a cycle somewhere. */
|
||||||
|
|
||||||
|
while (pseg != 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||||
|
#endif
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
result += size;
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* not CRAY2 */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
#endif /* no alloca */
|
||||||
|
#endif /* not GCC version 2 */
|
550
src/ansi2knr.c
Normal file
550
src/ansi2knr.c
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/* ansi2knr.c */
|
||||||
|
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
|
||||||
|
|
||||||
|
/*
|
||||||
|
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY. No author or distributor accepts responsibility to anyone for the
|
||||||
|
consequences of using it or for whether it serves any particular purpose or
|
||||||
|
works at all, unless he says so in writing. Refer to the GNU General Public
|
||||||
|
License (the "GPL") for full details.
|
||||||
|
|
||||||
|
Everyone is granted permission to copy, modify and redistribute ansi2knr,
|
||||||
|
but only under the conditions described in the GPL. A copy of this license
|
||||||
|
is supposed to have been given to you along with ansi2knr so you can know
|
||||||
|
your rights and responsibilities. It should be in a file named COPYLEFT.
|
||||||
|
Among other things, the copyright notice and this notice must be preserved
|
||||||
|
on all copies.
|
||||||
|
|
||||||
|
We explicitly state here what we believe is already implied by the GPL: if
|
||||||
|
the ansi2knr program is distributed as a separate set of sources and a
|
||||||
|
separate executable file which are aggregated on a storage medium together
|
||||||
|
with another program, this in itself does not bring the other program under
|
||||||
|
the GPL, nor does the mere fact that such a program or the procedures for
|
||||||
|
constructing it invoke the ansi2knr executable bring any other part of the
|
||||||
|
program under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usage:
|
||||||
|
ansi2knr input_file [output_file]
|
||||||
|
* If no output_file is supplied, output goes to stdout.
|
||||||
|
* There are no error messages.
|
||||||
|
*
|
||||||
|
* ansi2knr recognizes function definitions by seeing a non-keyword
|
||||||
|
* identifier at the left margin, followed by a left parenthesis,
|
||||||
|
* with a right parenthesis as the last character on the line,
|
||||||
|
* and with a left brace as the first token on the following line
|
||||||
|
* (ignoring possible intervening comments).
|
||||||
|
* It will recognize a multi-line header provided that no intervening
|
||||||
|
* line ends with a left or right brace or a semicolon.
|
||||||
|
* These algorithms ignore whitespace and comments, except that
|
||||||
|
* the function name must be the first thing on the line.
|
||||||
|
* The following constructs will confuse it:
|
||||||
|
* - Any other construct that starts at the left margin and
|
||||||
|
* follows the above syntax (such as a macro or function call).
|
||||||
|
* - Some macros that tinker with the syntax of the function header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The original and principal author of ansi2knr is L. Peter Deutsch
|
||||||
|
* <ghost@aladdin.com>. Other authors are noted in the change history
|
||||||
|
* that follows (in reverse chronological order):
|
||||||
|
lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
|
||||||
|
compilers that don't understand void, as suggested by
|
||||||
|
Tom Lane
|
||||||
|
lpd 96-01-15 changed to require that the first non-comment token
|
||||||
|
on the line following a function header be a left brace,
|
||||||
|
to reduce sensitivity to macros, as suggested by Tom Lane
|
||||||
|
<tgl@sss.pgh.pa.us>
|
||||||
|
lpd 95-06-22 removed #ifndefs whose sole purpose was to define
|
||||||
|
undefined preprocessor symbols as 0; changed all #ifdefs
|
||||||
|
for configuration symbols to #ifs
|
||||||
|
lpd 95-04-05 changed copyright notice to make it clear that
|
||||||
|
including ansi2knr in a program does not bring the entire
|
||||||
|
program under the GPL
|
||||||
|
lpd 94-12-18 added conditionals for systems where ctype macros
|
||||||
|
don't handle 8-bit characters properly, suggested by
|
||||||
|
Francois Pinard <pinard@iro.umontreal.ca>;
|
||||||
|
removed --varargs switch (this is now the default)
|
||||||
|
lpd 94-10-10 removed CONFIG_BROKETS conditional
|
||||||
|
lpd 94-07-16 added some conditionals to help GNU `configure',
|
||||||
|
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
|
||||||
|
properly erase prototype args in function parameters,
|
||||||
|
contributed by Jim Avera <jima@netcom.com>;
|
||||||
|
correct error in writeblanks (it shouldn't erase EOLs)
|
||||||
|
lpd 89-xx-xx original version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Most of the conditionals here are to make ansi2knr work with */
|
||||||
|
/* or without the GNU configure machinery. */
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
|
||||||
|
This will define HAVE_CONFIG_H and so, activate the following lines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# if STDC_HEADERS || HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
# else
|
||||||
|
# include <strings.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else /* not HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
/* Otherwise do it the hard way */
|
||||||
|
|
||||||
|
# ifdef BSD
|
||||||
|
# include <strings.h>
|
||||||
|
# else
|
||||||
|
# ifdef VMS
|
||||||
|
extern int strlen(), strncmp();
|
||||||
|
# else
|
||||||
|
# include <string.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif /* not HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#if STDC_HEADERS
|
||||||
|
# include <stdlib.h>
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
malloc and free should be declared in stdlib.h,
|
||||||
|
but if you've got a K&R compiler, they probably aren't.
|
||||||
|
*/
|
||||||
|
# ifdef MSDOS
|
||||||
|
# include <malloc.h>
|
||||||
|
# else
|
||||||
|
# ifdef VMS
|
||||||
|
extern char *malloc();
|
||||||
|
extern void free();
|
||||||
|
# else
|
||||||
|
extern char *malloc();
|
||||||
|
extern int free();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ctype macros don't always handle 8-bit characters correctly.
|
||||||
|
* Compensate for this here.
|
||||||
|
*/
|
||||||
|
#ifdef isascii
|
||||||
|
# undef HAVE_ISASCII /* just in case */
|
||||||
|
# define HAVE_ISASCII 1
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#if STDC_HEADERS || !HAVE_ISASCII
|
||||||
|
# define is_ascii(c) 1
|
||||||
|
#else
|
||||||
|
# define is_ascii(c) isascii(c)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define is_space(c) (is_ascii(c) && isspace(c))
|
||||||
|
#define is_alpha(c) (is_ascii(c) && isalpha(c))
|
||||||
|
#define is_alnum(c) (is_ascii(c) && isalnum(c))
|
||||||
|
|
||||||
|
/* Scanning macros */
|
||||||
|
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
|
||||||
|
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
|
||||||
|
|
||||||
|
/* Forward references */
|
||||||
|
char *skipspace();
|
||||||
|
int writeblanks();
|
||||||
|
int test1();
|
||||||
|
int convert1();
|
||||||
|
|
||||||
|
/* The main program */
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{ FILE *in, *out;
|
||||||
|
#define bufsize 5000 /* arbitrary size */
|
||||||
|
char *buf;
|
||||||
|
char *line;
|
||||||
|
char *more;
|
||||||
|
/*
|
||||||
|
* In previous versions, ansi2knr recognized a --varargs switch.
|
||||||
|
* If this switch was supplied, ansi2knr would attempt to convert
|
||||||
|
* a ... argument to va_alist and va_dcl; if this switch was not
|
||||||
|
* supplied, ansi2knr would simply drop any such arguments.
|
||||||
|
* Now, ansi2knr always does this conversion, and we only
|
||||||
|
* check for this switch for backward compatibility.
|
||||||
|
*/
|
||||||
|
int convert_varargs = 1;
|
||||||
|
|
||||||
|
if ( argc > 1 && argv[1][0] == '-' )
|
||||||
|
{ if ( !strcmp(argv[1], "--varargs") )
|
||||||
|
{ convert_varargs = 1;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argc < 2 || argc > 3)
|
||||||
|
{
|
||||||
|
printf("Usage: ansi2knr input_file [output_file]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
in = fopen(argv[1], "r");
|
||||||
|
if ( in == NULL )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot open input file %s\n", argv[1]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (argc == 3)
|
||||||
|
{
|
||||||
|
out = fopen(argv[2], "w");
|
||||||
|
if ( out == NULL )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot open output file %s\n", argv[2]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out = stdout;
|
||||||
|
}
|
||||||
|
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
|
||||||
|
buf = malloc(bufsize);
|
||||||
|
line = buf;
|
||||||
|
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
|
||||||
|
{
|
||||||
|
test: line += strlen(line);
|
||||||
|
switch ( test1(buf) )
|
||||||
|
{
|
||||||
|
case 2: /* a function header */
|
||||||
|
convert1(buf, out, 1, convert_varargs);
|
||||||
|
break;
|
||||||
|
case 1: /* a function */
|
||||||
|
/* Check for a { at the start of the next line. */
|
||||||
|
more = ++line;
|
||||||
|
f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
|
||||||
|
goto wl;
|
||||||
|
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
|
||||||
|
goto wl;
|
||||||
|
switch ( *skipspace(more, 1) )
|
||||||
|
{
|
||||||
|
case '{':
|
||||||
|
/* Definitely a function header. */
|
||||||
|
convert1(buf, out, 0, convert_varargs);
|
||||||
|
fputs(more, out);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* The next line was blank or a comment: */
|
||||||
|
/* keep scanning for a non-comment. */
|
||||||
|
line += strlen(line);
|
||||||
|
goto f;
|
||||||
|
default:
|
||||||
|
/* buf isn't a function header, but */
|
||||||
|
/* more might be. */
|
||||||
|
fputs(buf, out);
|
||||||
|
strcpy(buf, more);
|
||||||
|
line = buf;
|
||||||
|
goto test;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case -1: /* maybe the start of a function */
|
||||||
|
if ( line != buf + (bufsize - 1) ) /* overflow check */
|
||||||
|
continue;
|
||||||
|
/* falls through */
|
||||||
|
default: /* not a function */
|
||||||
|
wl: fputs(buf, out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line = buf;
|
||||||
|
}
|
||||||
|
if ( line != buf )
|
||||||
|
fputs(buf, out);
|
||||||
|
free(buf);
|
||||||
|
fclose(out);
|
||||||
|
fclose(in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip over space and comments, in either direction. */
|
||||||
|
char *
|
||||||
|
skipspace(p, dir)
|
||||||
|
register char *p;
|
||||||
|
register int dir; /* 1 for forward, -1 for backward */
|
||||||
|
{ for ( ; ; )
|
||||||
|
{ while ( is_space(*p) )
|
||||||
|
p += dir;
|
||||||
|
if ( !(*p == '/' && p[dir] == '*') )
|
||||||
|
break;
|
||||||
|
p += dir; p += dir;
|
||||||
|
while ( !(*p == '*' && p[dir] == '/') )
|
||||||
|
{ if ( *p == 0 )
|
||||||
|
return p; /* multi-line comment?? */
|
||||||
|
p += dir;
|
||||||
|
}
|
||||||
|
p += dir; p += dir;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write blanks over part of a string.
|
||||||
|
* Don't overwrite end-of-line characters.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
writeblanks(start, end)
|
||||||
|
char *start;
|
||||||
|
char *end;
|
||||||
|
{ char *p;
|
||||||
|
for ( p = start; p < end; p++ )
|
||||||
|
if ( *p != '\r' && *p != '\n' )
|
||||||
|
*p = ' ';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test whether the string in buf is a function definition.
|
||||||
|
* The string may contain and/or end with a newline.
|
||||||
|
* Return as follows:
|
||||||
|
* 0 - definitely not a function definition;
|
||||||
|
* 1 - definitely a function definition;
|
||||||
|
* 2 - definitely a function prototype (NOT USED);
|
||||||
|
* -1 - may be the beginning of a function definition,
|
||||||
|
* append another line and look again.
|
||||||
|
* The reason we don't attempt to convert function prototypes is that
|
||||||
|
* Ghostscript's declaration-generating macros look too much like
|
||||||
|
* prototypes, and confuse the algorithms.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
test1(buf)
|
||||||
|
char *buf;
|
||||||
|
{ register char *p = buf;
|
||||||
|
char *bend;
|
||||||
|
char *endfn;
|
||||||
|
int contin;
|
||||||
|
|
||||||
|
if ( !isidfirstchar(*p) )
|
||||||
|
return 0; /* no name at left margin */
|
||||||
|
bend = skipspace(buf + strlen(buf) - 1, -1);
|
||||||
|
switch ( *bend )
|
||||||
|
{
|
||||||
|
case ';': contin = 0 /*2*/; break;
|
||||||
|
case ')': contin = 1; break;
|
||||||
|
case '{': return 0; /* not a function */
|
||||||
|
case '}': return 0; /* not a function */
|
||||||
|
default: contin = -1;
|
||||||
|
}
|
||||||
|
while ( isidchar(*p) )
|
||||||
|
p++;
|
||||||
|
endfn = p;
|
||||||
|
p = skipspace(p, 1);
|
||||||
|
if ( *p++ != '(' )
|
||||||
|
return 0; /* not a function */
|
||||||
|
p = skipspace(p, 1);
|
||||||
|
if ( *p == ')' )
|
||||||
|
return 0; /* no parameters */
|
||||||
|
/* Check that the apparent function name isn't a keyword. */
|
||||||
|
/* We only need to check for keywords that could be followed */
|
||||||
|
/* by a left parenthesis (which, unfortunately, is most of them). */
|
||||||
|
{ static char *words[] =
|
||||||
|
{ "asm", "auto", "case", "char", "const", "double",
|
||||||
|
"extern", "float", "for", "if", "int", "long",
|
||||||
|
"register", "return", "short", "signed", "sizeof",
|
||||||
|
"static", "switch", "typedef", "unsigned",
|
||||||
|
"void", "volatile", "while", 0
|
||||||
|
};
|
||||||
|
char **key = words;
|
||||||
|
char *kp;
|
||||||
|
int len = endfn - buf;
|
||||||
|
|
||||||
|
while ( (kp = *key) != 0 )
|
||||||
|
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
|
||||||
|
return 0; /* name is a keyword */
|
||||||
|
key++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert a recognized function definition or header to K&R syntax. */
|
||||||
|
int
|
||||||
|
convert1(buf, out, header, convert_varargs)
|
||||||
|
char *buf;
|
||||||
|
FILE *out;
|
||||||
|
int header; /* Boolean */
|
||||||
|
int convert_varargs; /* Boolean */
|
||||||
|
{ char *endfn;
|
||||||
|
register char *p;
|
||||||
|
/*
|
||||||
|
* The breaks table contains pointers to the beginning and end
|
||||||
|
* of each argument.
|
||||||
|
*/
|
||||||
|
char **breaks;
|
||||||
|
unsigned num_breaks = 2; /* for testing */
|
||||||
|
char **btop;
|
||||||
|
char **bp;
|
||||||
|
char **ap;
|
||||||
|
char *vararg = 0;
|
||||||
|
|
||||||
|
/* Pre-ANSI implementations don't agree on whether strchr */
|
||||||
|
/* is called strchr or index, so we open-code it here. */
|
||||||
|
for ( endfn = buf; *(endfn++) != '('; )
|
||||||
|
;
|
||||||
|
top: p = endfn;
|
||||||
|
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
|
||||||
|
if ( breaks == 0 )
|
||||||
|
{ /* Couldn't allocate break table, give up */
|
||||||
|
fprintf(stderr, "Unable to allocate break table!\n");
|
||||||
|
fputs(buf, out);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
btop = breaks + num_breaks * 2 - 2;
|
||||||
|
bp = breaks;
|
||||||
|
/* Parse the argument list */
|
||||||
|
do
|
||||||
|
{ int level = 0;
|
||||||
|
char *lp = NULL;
|
||||||
|
char *rp;
|
||||||
|
char *end = NULL;
|
||||||
|
|
||||||
|
if ( bp >= btop )
|
||||||
|
{ /* Filled up break table. */
|
||||||
|
/* Allocate a bigger one and start over. */
|
||||||
|
free((char *)breaks);
|
||||||
|
num_breaks <<= 1;
|
||||||
|
goto top;
|
||||||
|
}
|
||||||
|
*bp++ = p;
|
||||||
|
/* Find the end of the argument */
|
||||||
|
for ( ; end == NULL; p++ )
|
||||||
|
{ switch(*p)
|
||||||
|
{
|
||||||
|
case ',':
|
||||||
|
if ( !level ) end = p;
|
||||||
|
break;
|
||||||
|
case '(':
|
||||||
|
if ( !level ) lp = p;
|
||||||
|
level++;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
if ( --level < 0 ) end = p;
|
||||||
|
else rp = p;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
p = skipspace(p, 1) - 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Erase any embedded prototype parameters. */
|
||||||
|
if ( lp )
|
||||||
|
writeblanks(lp + 1, rp);
|
||||||
|
p--; /* back up over terminator */
|
||||||
|
/* Find the name being declared. */
|
||||||
|
/* This is complicated because of procedure and */
|
||||||
|
/* array modifiers. */
|
||||||
|
for ( ; ; )
|
||||||
|
{ p = skipspace(p - 1, -1);
|
||||||
|
switch ( *p )
|
||||||
|
{
|
||||||
|
case ']': /* skip array dimension(s) */
|
||||||
|
case ')': /* skip procedure args OR name */
|
||||||
|
{ int level = 1;
|
||||||
|
while ( level )
|
||||||
|
switch ( *--p )
|
||||||
|
{
|
||||||
|
case ']': case ')': level++; break;
|
||||||
|
case '[': case '(': level--; break;
|
||||||
|
case '/': p = skipspace(p, -1) + 1; break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
|
||||||
|
{ /* We found the name being declared */
|
||||||
|
while ( !isidfirstchar(*p) )
|
||||||
|
p = skipspace(p, 1) + 1;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
|
||||||
|
{ if ( convert_varargs )
|
||||||
|
{ *bp++ = "va_alist";
|
||||||
|
vararg = p-2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ p++;
|
||||||
|
if ( bp == breaks + 1 ) /* sole argument */
|
||||||
|
writeblanks(breaks[0], p);
|
||||||
|
else
|
||||||
|
writeblanks(bp[-1] - 1, p);
|
||||||
|
bp--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ while ( isidchar(*p) ) p--;
|
||||||
|
*bp++ = p+1;
|
||||||
|
}
|
||||||
|
p = end;
|
||||||
|
}
|
||||||
|
while ( *p++ == ',' );
|
||||||
|
*bp = p;
|
||||||
|
/* Make a special check for 'void' arglist */
|
||||||
|
if ( bp == breaks+2 )
|
||||||
|
{ p = skipspace(breaks[0], 1);
|
||||||
|
if ( !strncmp(p, "void", 4) )
|
||||||
|
{ p = skipspace(p+4, 1);
|
||||||
|
if ( p == breaks[2] - 1 )
|
||||||
|
{ bp = breaks; /* yup, pretend arglist is empty */
|
||||||
|
writeblanks(breaks[0], p + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Put out the function name and left parenthesis. */
|
||||||
|
p = buf;
|
||||||
|
while ( p != endfn ) putc(*p, out), p++;
|
||||||
|
/* Put out the declaration. */
|
||||||
|
if ( header )
|
||||||
|
{ fputs(");", out);
|
||||||
|
for ( p = breaks[0]; *p; p++ )
|
||||||
|
if ( *p == '\r' || *p == '\n' )
|
||||||
|
putc(*p, out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ for ( ap = breaks+1; ap < bp; ap += 2 )
|
||||||
|
{ p = *ap;
|
||||||
|
while ( isidchar(*p) )
|
||||||
|
putc(*p, out), p++;
|
||||||
|
if ( ap < bp - 1 )
|
||||||
|
fputs(", ", out);
|
||||||
|
}
|
||||||
|
fputs(") ", out);
|
||||||
|
/* Put out the argument declarations */
|
||||||
|
for ( ap = breaks+2; ap <= bp; ap += 2 )
|
||||||
|
(*ap)[-1] = ';';
|
||||||
|
if ( vararg != 0 )
|
||||||
|
{ *vararg = 0;
|
||||||
|
fputs(breaks[0], out); /* any prior args */
|
||||||
|
fputs("va_dcl", out); /* the final arg */
|
||||||
|
fputs(bp[0], out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fputs(breaks[0], out);
|
||||||
|
}
|
||||||
|
free((char *)breaks);
|
||||||
|
return 0;
|
||||||
|
}
|
1191
src/cmpt.c
Normal file
1191
src/cmpt.c
Normal file
File diff suppressed because it is too large
Load Diff
183
src/config.h.in
Normal file
183
src/config.h.in
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/* Configuration header file.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
/* Define if you have the <alloca.h> header file. */
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* AIX requires this to be the first thing in the file. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define alloca __builtin_alloca
|
||||||
|
#else
|
||||||
|
# if HAVE_ALLOCA_H
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
# else
|
||||||
|
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||||
|
char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define if on AIX 3.
|
||||||
|
System headers sometimes define this.
|
||||||
|
We just want to avoid a redefinition error message. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
#undef _ALL_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define to empty if the keyword does not work. */
|
||||||
|
#undef const
|
||||||
|
|
||||||
|
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* Define if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (int or void). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* Define if your architecture is big endian (with the most
|
||||||
|
significant byte first). */
|
||||||
|
#undef WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
/* Define this if you want the NLS support. */
|
||||||
|
#undef HAVE_NLS
|
||||||
|
|
||||||
|
/* Define if you want the FTP support for Opie compiled in. */
|
||||||
|
#undef USE_OPIE
|
||||||
|
|
||||||
|
/* Define if you want the HTTP Digest Authorization compiled in. */
|
||||||
|
#undef USE_DIGEST
|
||||||
|
|
||||||
|
/* Define if you want the debug output support compiled in. */
|
||||||
|
#undef DEBUG
|
||||||
|
|
||||||
|
/* Define if you have sys/time.h header. */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
|
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
|
#undef TIME_WITH_SYS_TIME
|
||||||
|
|
||||||
|
/* Define if you have struct utimbuf. */
|
||||||
|
#undef HAVE_STRUCT_UTIMBUF
|
||||||
|
|
||||||
|
/* Define if you have the uname function. */
|
||||||
|
#undef HAVE_UNAME
|
||||||
|
|
||||||
|
/* Define if you have the gethostname function. */
|
||||||
|
#undef HAVE_GETHOSTNAME
|
||||||
|
|
||||||
|
/* Define if you have the select function. */
|
||||||
|
#undef HAVE_SELECT
|
||||||
|
|
||||||
|
/* Define if you have the gettimeofday function. */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
/* Define if you have the strdup function. */
|
||||||
|
#undef HAVE_STRDUP
|
||||||
|
|
||||||
|
/* Define if you have the sys/utsname.h header. */
|
||||||
|
#undef HAVE_SYS_UTSNAME_H
|
||||||
|
|
||||||
|
/* Define if you have the strerror function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define if you have the vsnprintf function. */
|
||||||
|
#undef HAVE_VSNPRINTF
|
||||||
|
|
||||||
|
/* Define if you have the strstr function. */
|
||||||
|
#undef HAVE_STRSTR
|
||||||
|
|
||||||
|
/* Define if you have the strcasecmp function. */
|
||||||
|
#undef HAVE_STRCASECMP
|
||||||
|
|
||||||
|
/* Define if you have the strncasecmp function. */
|
||||||
|
#undef HAVE_STRNCASECMP
|
||||||
|
|
||||||
|
/* Define if you have the strptime function. */
|
||||||
|
#undef HAVE_STRPTIME
|
||||||
|
|
||||||
|
/* Define if you have the mktime function. */
|
||||||
|
#undef HAVE_MKTIME
|
||||||
|
|
||||||
|
/* Define if you have the symlink function. */
|
||||||
|
#undef HAVE_SYMLINK
|
||||||
|
|
||||||
|
/* Define if you have the access function. */
|
||||||
|
#undef HAVE_ACCESS
|
||||||
|
|
||||||
|
/* Define if you have the isatty function. */
|
||||||
|
#undef HAVE_ISATTY
|
||||||
|
|
||||||
|
/* Define if you have the signal function. */
|
||||||
|
#undef HAVE_SIGNAL
|
||||||
|
|
||||||
|
/* Define if you have the gettext function. */
|
||||||
|
#undef HAVE_GETTEXT
|
||||||
|
|
||||||
|
/* Define if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define if you have the <stdarg.h> header file. */
|
||||||
|
#undef HAVE_STDARG_H
|
||||||
|
|
||||||
|
/* Define if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define if you have the <utime.h> header file. */
|
||||||
|
#undef HAVE_UTIME_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/utime.h> header file. */
|
||||||
|
#undef HAVE_SYS_UTIME_H
|
||||||
|
|
||||||
|
/* Define if you have the <sys/select.h> header file. */
|
||||||
|
#undef HAVE_SYS_SELECT_H
|
||||||
|
|
||||||
|
/* Define if you have the <pwd.h> header file. */
|
||||||
|
#undef HAVE_PWD_H
|
||||||
|
|
||||||
|
/* Define if you have the <signal.h> header file. */
|
||||||
|
#undef HAVE_SIGNAL_H
|
||||||
|
|
||||||
|
/* Define if you have the <libintl.h> header file. */
|
||||||
|
#undef HAVE_LIBINTL_H
|
||||||
|
|
||||||
|
/* Define if you have the <locale.h> header file. */
|
||||||
|
#undef HAVE_LOCALE_H
|
||||||
|
|
||||||
|
/* Define to be the name of the operating system. */
|
||||||
|
#undef OS_TYPE
|
||||||
|
|
||||||
|
/* Define if you wish to compile with socks support. */
|
||||||
|
#undef HAVE_SOCKS
|
||||||
|
|
||||||
|
/* Define to 1 if ANSI function prototypes are usable. */
|
||||||
|
#undef PROTOTYPES
|
||||||
|
|
||||||
|
#endif /* CONFIG_H */
|
308
src/connect.c
Normal file
308
src/connect.c
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/* Establishing and handling network connections.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
# include <winsock.h>
|
||||||
|
#else
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# include <netdb.h>
|
||||||
|
# include <netinet/in.h>
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
# include <sys/select.h>
|
||||||
|
#endif /* HAVE_SYS_SELECT_H */
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "connect.h"
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Variables shared by bindport and acceptport: */
|
||||||
|
static int msock = -1;
|
||||||
|
static struct sockaddr *addr;
|
||||||
|
|
||||||
|
|
||||||
|
/* Create an internet connection to HOSTNAME on PORT. The created
|
||||||
|
socket will be stored to *SOCK. */
|
||||||
|
uerr_t
|
||||||
|
make_connection (int *sock, char *hostname, unsigned short port)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sock_name;
|
||||||
|
/* struct hostent *hptr; */
|
||||||
|
|
||||||
|
/* Get internet address of the host. We can do it either by calling
|
||||||
|
ngethostbyname, or by calling store_hostaddress, from host.c.
|
||||||
|
storehostaddress is better since it caches calls to
|
||||||
|
gethostbyname. */
|
||||||
|
#if 1
|
||||||
|
if (!store_hostaddress ((unsigned char *)&sock_name.sin_addr, hostname))
|
||||||
|
return HOSTERR;
|
||||||
|
#else /* never */
|
||||||
|
if (!(hptr = ngethostbyname (hostname)))
|
||||||
|
return HOSTERR;
|
||||||
|
/* Copy the address of the host to socket description. */
|
||||||
|
memcpy (&sock_name.sin_addr, hptr->h_addr, hptr->h_length);
|
||||||
|
#endif /* never */
|
||||||
|
|
||||||
|
/* Set port and protocol */
|
||||||
|
sock_name.sin_family = AF_INET;
|
||||||
|
sock_name.sin_port = htons (port);
|
||||||
|
|
||||||
|
/* Make an internet socket, stream type. */
|
||||||
|
if ((*sock = socket (AF_INET, SOCK_STREAM, 0)) == -1)
|
||||||
|
return CONSOCKERR;
|
||||||
|
|
||||||
|
/* Connect the socket to the remote host. */
|
||||||
|
if (connect (*sock, (struct sockaddr *) &sock_name, sizeof (sock_name)))
|
||||||
|
{
|
||||||
|
if (errno == ECONNREFUSED)
|
||||||
|
return CONREFUSED;
|
||||||
|
else
|
||||||
|
return CONERROR;
|
||||||
|
}
|
||||||
|
DEBUGP (("Created fd %d.\n", *sock));
|
||||||
|
return NOCONERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bind the local port PORT. This does all the necessary work, which
|
||||||
|
is creating a socket, setting SO_REUSEADDR option on it, then
|
||||||
|
calling bind() and listen(). If *PORT is 0, a random port is
|
||||||
|
chosen by the system, and its value is stored to *PORT. The
|
||||||
|
internal variable MPORT is set to the value of the ensuing master
|
||||||
|
socket. Call acceptport() to block for and accept a connection. */
|
||||||
|
uerr_t
|
||||||
|
bindport (unsigned short *port)
|
||||||
|
{
|
||||||
|
int optval = 1;
|
||||||
|
static struct sockaddr_in srv;
|
||||||
|
|
||||||
|
msock = -1;
|
||||||
|
addr = (struct sockaddr *) &srv;
|
||||||
|
if ((msock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
return CONSOCKERR;
|
||||||
|
if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(char *)&optval, sizeof (optval)) < 0)
|
||||||
|
return CONSOCKERR;
|
||||||
|
srv.sin_family = AF_INET;
|
||||||
|
srv.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
srv.sin_port = htons (*port);
|
||||||
|
if (bind (msock, addr, sizeof (struct sockaddr_in)) < 0)
|
||||||
|
{
|
||||||
|
CLOSE (msock);
|
||||||
|
msock = -1;
|
||||||
|
return BINDERR;
|
||||||
|
}
|
||||||
|
DEBUGP (("Master socket fd %d bound.\n", msock));
|
||||||
|
if (!*port)
|
||||||
|
{
|
||||||
|
size_t addrlen = sizeof (struct sockaddr_in);
|
||||||
|
if (getsockname (msock, addr, (int *)&addrlen) < 0)
|
||||||
|
{
|
||||||
|
CLOSE (msock);
|
||||||
|
msock = -1;
|
||||||
|
return CONPORTERR;
|
||||||
|
}
|
||||||
|
*port = ntohs (srv.sin_port);
|
||||||
|
}
|
||||||
|
if (listen (msock, 1) < 0)
|
||||||
|
{
|
||||||
|
CLOSE (msock);
|
||||||
|
msock = -1;
|
||||||
|
return LISTENERR;
|
||||||
|
}
|
||||||
|
return BINDOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
/* Wait for file descriptor FD to be readable, MAXTIME being the
|
||||||
|
timeout in seconds. If WRITEP is non-zero, checks for FD being
|
||||||
|
writable instead.
|
||||||
|
|
||||||
|
Returns 1 if FD is accessible, 0 for timeout and -1 for error in
|
||||||
|
select(). */
|
||||||
|
static int
|
||||||
|
select_fd (int fd, int maxtime, int writep)
|
||||||
|
{
|
||||||
|
fd_set fds, exceptfds;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
FD_ZERO (&fds);
|
||||||
|
FD_SET (fd, &fds);
|
||||||
|
FD_ZERO (&exceptfds);
|
||||||
|
FD_SET (fd, &exceptfds);
|
||||||
|
timeout.tv_sec = maxtime;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
/* HPUX reportedly warns here. What is the correct incantation? */
|
||||||
|
return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
|
||||||
|
&exceptfds, &timeout);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SELECT */
|
||||||
|
|
||||||
|
/* Call accept() on MSOCK and store the result to *SOCK. This assumes
|
||||||
|
that bindport() has been used to initialize MSOCK to a correct
|
||||||
|
value. It blocks the caller until a connection is established. If
|
||||||
|
no connection is established for OPT.TIMEOUT seconds, the function
|
||||||
|
exits with an error status. */
|
||||||
|
uerr_t
|
||||||
|
acceptport (int *sock)
|
||||||
|
{
|
||||||
|
int addrlen = sizeof (struct sockaddr_in);
|
||||||
|
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
if (select_fd (msock, opt.timeout, 0) <= 0)
|
||||||
|
return ACCEPTERR;
|
||||||
|
#endif
|
||||||
|
if ((*sock = accept (msock, addr, &addrlen)) < 0)
|
||||||
|
return ACCEPTERR;
|
||||||
|
DEBUGP (("Created socket fd %d.\n", *sock));
|
||||||
|
return ACCEPTOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close SOCK, as well as the most recently remembered MSOCK, created
|
||||||
|
via bindport(). If SOCK is -1, close MSOCK only. */
|
||||||
|
void
|
||||||
|
closeport (int sock)
|
||||||
|
{
|
||||||
|
/*shutdown (sock, 2);*/
|
||||||
|
if (sock != -1)
|
||||||
|
CLOSE (sock);
|
||||||
|
if (msock != -1)
|
||||||
|
CLOSE (msock);
|
||||||
|
msock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the local IP address associated with the connection on FD.
|
||||||
|
It is returned in a static buffer. */
|
||||||
|
unsigned char *
|
||||||
|
conaddr (int fd)
|
||||||
|
{
|
||||||
|
static unsigned char res[4];
|
||||||
|
struct sockaddr_in mysrv;
|
||||||
|
struct sockaddr *myaddr;
|
||||||
|
size_t addrlen = sizeof (mysrv);
|
||||||
|
|
||||||
|
myaddr = (struct sockaddr *) (&mysrv);
|
||||||
|
if (getsockname (fd, myaddr, (int *)&addrlen) < 0)
|
||||||
|
return NULL;
|
||||||
|
memcpy (res, &mysrv.sin_addr, 4);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read at most LEN bytes from FD, storing them to BUF. This is
|
||||||
|
virtually the same as read(), but takes care of EINTR braindamage
|
||||||
|
and uses select() to timeout the stale connections (a connection is
|
||||||
|
stale if more than OPT.TIMEOUT time is spent in select() or
|
||||||
|
read()). */
|
||||||
|
int
|
||||||
|
iread (int fd, char *buf, int len)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
if (opt.timeout)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
res = select_fd (fd, opt.timeout, 0);
|
||||||
|
}
|
||||||
|
while (res == -1 && errno == EINTR);
|
||||||
|
if (res <= 0)
|
||||||
|
{
|
||||||
|
/* Set errno to ETIMEDOUT on timeout. */
|
||||||
|
if (res == 0)
|
||||||
|
/* #### Potentially evil! */
|
||||||
|
errno = ETIMEDOUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
res = READ (fd, buf, len);
|
||||||
|
}
|
||||||
|
while (res == -1 && errno == EINTR);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write LEN bytes from BUF to FD. This is similar to iread(), but
|
||||||
|
doesn't bother with select(). Unlike iread(), it makes sure that
|
||||||
|
all of BUF is actually written to FD, so callers needn't bother
|
||||||
|
with checking that the return value equals to LEN. Instead, you
|
||||||
|
should simply check for -1. */
|
||||||
|
int
|
||||||
|
iwrite (int fd, char *buf, int len)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
/* `write' may write less than LEN bytes, thus the outward loop
|
||||||
|
keeps trying it until all was written, or an error occurred. The
|
||||||
|
inner loop is reserved for the usual EINTR f*kage, and the
|
||||||
|
innermost loop deals with the same during select(). */
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
if (opt.timeout)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
res = select_fd (fd, opt.timeout, 1);
|
||||||
|
}
|
||||||
|
while (res == -1 && errno == EINTR);
|
||||||
|
if (res <= 0)
|
||||||
|
{
|
||||||
|
/* Set errno to ETIMEDOUT on timeout. */
|
||||||
|
if (res == 0)
|
||||||
|
/* #### Potentially evil! */
|
||||||
|
errno = ETIMEDOUT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
res = WRITE (fd, buf, len);
|
||||||
|
}
|
||||||
|
while (res == -1 && errno == EINTR);
|
||||||
|
if (res <= 0)
|
||||||
|
break;
|
||||||
|
buf += res;
|
||||||
|
len -= res;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
33
src/connect.h
Normal file
33
src/connect.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* Declarations for connect.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef CONNECT_H
|
||||||
|
#define CONNECT_H
|
||||||
|
|
||||||
|
/* Function declarations */
|
||||||
|
uerr_t make_connection PARAMS ((int *, char *, unsigned short));
|
||||||
|
uerr_t bindport PARAMS ((unsigned short *));
|
||||||
|
uerr_t acceptport PARAMS ((int *));
|
||||||
|
void closeport PARAMS ((int));
|
||||||
|
unsigned char *conaddr PARAMS ((int));
|
||||||
|
|
||||||
|
int iread PARAMS ((int, char *, int));
|
||||||
|
int iwrite PARAMS ((int, char *, int));
|
||||||
|
|
||||||
|
#endif /* CONNECT_H */
|
200
src/fnmatch.c
Normal file
200
src/fnmatch.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/* Pattern matching (globbing).
|
||||||
|
Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* NOTE: Some Un*xes have their own fnmatch() -- yet, they are
|
||||||
|
reportedly unreliable and buggy. Thus I chose never to use it;
|
||||||
|
this version (from GNU Bash) is used unconditionally. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "wget.h"
|
||||||
|
#include "fnmatch.h"
|
||||||
|
|
||||||
|
/* Match STRING against the filename pattern PATTERN, returning zero
|
||||||
|
if it matches, FNM_NOMATCH if not. */
|
||||||
|
int
|
||||||
|
fnmatch (const char *pattern, const char *string, int flags)
|
||||||
|
{
|
||||||
|
register const char *p = pattern, *n = string;
|
||||||
|
register char c;
|
||||||
|
|
||||||
|
if ((flags & ~__FNM_FLAGS) != 0)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((c = *p++) != '\0')
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '?':
|
||||||
|
if (*n == '\0')
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
else if ((flags & FNM_PATHNAME) && *n == '/')
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||||
|
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (!(flags & FNM_NOESCAPE))
|
||||||
|
c = *p++;
|
||||||
|
if (*n != c)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||||
|
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||||
|
if (((flags & FNM_PATHNAME) && *n == '/') ||
|
||||||
|
(c == '?' && *n == '\0'))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
if (c == '\0')
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
{
|
||||||
|
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||||
|
for (--p; *n != '\0'; ++n)
|
||||||
|
if ((c == '[' || *n == c1) &&
|
||||||
|
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||||
|
return (0);
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
/* Nonzero if the sense of the character class is
|
||||||
|
inverted. */
|
||||||
|
register int not;
|
||||||
|
|
||||||
|
if (*n == '\0')
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||||
|
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
/* Make sure there is a closing `]'. If there isn't,
|
||||||
|
the `[' is just a character to be matched. */
|
||||||
|
{
|
||||||
|
register const char *np;
|
||||||
|
|
||||||
|
for (np = p; np && *np && *np != ']'; np++);
|
||||||
|
|
||||||
|
if (np && !*np)
|
||||||
|
{
|
||||||
|
if (*n != '[')
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
goto next_char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
not = (*p == '!' || *p == '^');
|
||||||
|
if (not)
|
||||||
|
++p;
|
||||||
|
|
||||||
|
c = *p++;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
register char cstart = c, cend = c;
|
||||||
|
|
||||||
|
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||||
|
cstart = cend = *p++;
|
||||||
|
|
||||||
|
if (c == '\0')
|
||||||
|
/* [ (unterminated) loses. */
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
c = *p++;
|
||||||
|
|
||||||
|
if ((flags & FNM_PATHNAME) && c == '/')
|
||||||
|
/* [/] can never match. */
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
if (c == '-' && *p != ']')
|
||||||
|
{
|
||||||
|
cend = *p++;
|
||||||
|
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||||
|
cend = *p++;
|
||||||
|
if (cend == '\0')
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
c = *p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*n >= cstart && *n <= cend)
|
||||||
|
goto matched;
|
||||||
|
|
||||||
|
if (c == ']')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!not)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
next_char:
|
||||||
|
break;
|
||||||
|
|
||||||
|
matched:
|
||||||
|
/* Skip the rest of the [...] that already matched. */
|
||||||
|
while (c != ']')
|
||||||
|
{
|
||||||
|
if (c == '\0')
|
||||||
|
/* [... (unterminated) loses. */
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
c = *p++;
|
||||||
|
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||||
|
/* 1003.2d11 is unclear if this is right. %%% */
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
if (not)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (c != *n)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*n == '\0')
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return non-zero if S contains globbing wildcards (`*', `?', `[' or
|
||||||
|
`]'). */
|
||||||
|
int
|
||||||
|
has_wildcards_p (const char *s)
|
||||||
|
{
|
||||||
|
for (; *s; s++)
|
||||||
|
if (*s == '*' || *s == '?' || *s == '[' || *s == ']')
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
35
src/fnmatch.h
Normal file
35
src/fnmatch.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Declarations for fnmatch.c.
|
||||||
|
Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef MTCH_H
|
||||||
|
#define MTCH_H
|
||||||
|
|
||||||
|
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||||
|
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||||
|
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||||
|
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||||
|
#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD)
|
||||||
|
|
||||||
|
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||||
|
#define FNM_NOMATCH 1
|
||||||
|
|
||||||
|
int fnmatch PARAMS ((const char *, const char *, int));
|
||||||
|
int has_wildcards_p PARAMS ((const char *));
|
||||||
|
|
||||||
|
#endif /* MTCH_H */
|
539
src/ftp-basic.c
Normal file
539
src/ftp-basic.c
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
/* Basic FTP routines.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
# include <winsock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "rbuf.h"
|
||||||
|
#include "connect.h"
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
#ifndef h_errno
|
||||||
|
extern int h_errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char ftp_last_respline[128];
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the response of FTP server and allocate enough room to handle
|
||||||
|
it. <CR> and <LF> characters are stripped from the line, and the
|
||||||
|
line is 0-terminated. All the response lines but the last one are
|
||||||
|
skipped. The last line is determined as described in RFC959. */
|
||||||
|
uerr_t
|
||||||
|
ftp_response (struct rbuf *rbuf, char **line)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int bufsize = 40;
|
||||||
|
|
||||||
|
*line = (char *)xmalloc (bufsize);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
for (i = 0; 1; i++)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
if (i > bufsize - 1)
|
||||||
|
*line = (char *)xrealloc (*line, (bufsize <<= 1));
|
||||||
|
res = RBUF_READCHAR (rbuf, *line + i);
|
||||||
|
/* RES is number of bytes read. */
|
||||||
|
if (res == 1)
|
||||||
|
{
|
||||||
|
if ((*line)[i] == '\n')
|
||||||
|
{
|
||||||
|
(*line)[i] = '\0';
|
||||||
|
/* Get rid of \r. */
|
||||||
|
if (i > 0 && (*line)[i - 1] == '\r')
|
||||||
|
(*line)[i - 1] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FTPRERR;
|
||||||
|
}
|
||||||
|
if (opt.server_response)
|
||||||
|
logprintf (LOG_ALWAYS, "%s\n", *line);
|
||||||
|
else
|
||||||
|
DEBUGP (("%s\n", *line));
|
||||||
|
}
|
||||||
|
while (!(i >= 3 && ISDIGIT (**line) && ISDIGIT ((*line)[1]) &&
|
||||||
|
ISDIGIT ((*line)[2]) && (*line)[3] == ' '));
|
||||||
|
strncpy (ftp_last_respline, *line, sizeof (ftp_last_respline));
|
||||||
|
ftp_last_respline[sizeof (ftp_last_respline) - 1] = '\0';
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the malloc-ed FTP request, ending with <CR><LF>, printing
|
||||||
|
it if printing is required. If VALUE is NULL, just use
|
||||||
|
command<CR><LF>. */
|
||||||
|
static char *
|
||||||
|
ftp_request (const char *command, const char *value)
|
||||||
|
{
|
||||||
|
char *res = (char *)xmalloc (strlen (command)
|
||||||
|
+ (value ? (1 + strlen (value)) : 0)
|
||||||
|
+ 2 + 1);
|
||||||
|
sprintf (res, "%s%s%s\r\n", command, value ? " " : "", value ? value : "");
|
||||||
|
if (opt.server_response)
|
||||||
|
{
|
||||||
|
/* Hack: don't print out password. */
|
||||||
|
if (strncmp (res, "PASS", 4) != 0)
|
||||||
|
logprintf (LOG_ALWAYS, "--> %s\n", res);
|
||||||
|
else
|
||||||
|
logputs (LOG_ALWAYS, "--> PASS Turtle Power!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DEBUGP (("\n--> %s\n", res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OPIE
|
||||||
|
const char *calculate_skey_response PARAMS ((int, const char *, const char *));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sends the USER and PASS commands to the server, to control
|
||||||
|
connection socket csock. */
|
||||||
|
uerr_t
|
||||||
|
ftp_login (struct rbuf *rbuf, const char *acc, const char *pass)
|
||||||
|
{
|
||||||
|
uerr_t err;
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
|
||||||
|
/* Get greeting. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPSRVERR;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* Send USER username. */
|
||||||
|
request = ftp_request ("USER", acc);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
/* An unprobable possibility of logging without a password. */
|
||||||
|
if (*respline == '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
/* Else, only response 3 is appropriate. */
|
||||||
|
if (*respline != '3')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPLOGREFUSED;
|
||||||
|
}
|
||||||
|
#ifdef USE_OPIE
|
||||||
|
{
|
||||||
|
static const char *skey_head[] = {
|
||||||
|
"331 s/key ",
|
||||||
|
"331 opiekey "
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (skey_head); i++)
|
||||||
|
{
|
||||||
|
if (strncmp (skey_head[i], respline, strlen (skey_head[i])) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < ARRAY_SIZE (skey_head))
|
||||||
|
{
|
||||||
|
const char *cp;
|
||||||
|
int skey_sequence = 0;
|
||||||
|
|
||||||
|
for (cp = respline + strlen (skey_head[i]);
|
||||||
|
'0' <= *cp && *cp <= '9';
|
||||||
|
cp++)
|
||||||
|
{
|
||||||
|
skey_sequence = skey_sequence * 10 + *cp - '0';
|
||||||
|
}
|
||||||
|
if (*cp == ' ')
|
||||||
|
cp++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bad:
|
||||||
|
free (respline);
|
||||||
|
return FTPLOGREFUSED;
|
||||||
|
}
|
||||||
|
if ((cp = calculate_skey_response (skey_sequence, cp, pass)) == 0)
|
||||||
|
goto bad;
|
||||||
|
pass = cp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* USE_OPIE */
|
||||||
|
free (respline);
|
||||||
|
/* Send PASS password. */
|
||||||
|
request = ftp_request ("PASS", pass);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPLOGINC;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bind a port and send the appropriate PORT command to the FTP
|
||||||
|
server. Use acceptport after RETR, to get the socket of data
|
||||||
|
connection. */
|
||||||
|
uerr_t
|
||||||
|
ftp_port (struct rbuf *rbuf)
|
||||||
|
{
|
||||||
|
uerr_t err;
|
||||||
|
char *request, *respline, *bytes;
|
||||||
|
unsigned char *in_addr;
|
||||||
|
int nwritten;
|
||||||
|
unsigned short port;
|
||||||
|
|
||||||
|
/* Setting port to 0 lets the system choose a free port. */
|
||||||
|
port = 0;
|
||||||
|
/* Bind the port. */
|
||||||
|
err = bindport (&port);
|
||||||
|
if (err != BINDOK)
|
||||||
|
return err;
|
||||||
|
/* Get the address of this side of the connection. */
|
||||||
|
if (!(in_addr = conaddr (RBUF_FD (rbuf))))
|
||||||
|
return HOSTERR;
|
||||||
|
/* Construct the argument of PORT (of the form a,b,c,d,e,f). */
|
||||||
|
bytes = (char *)alloca (6 * 4 + 1);
|
||||||
|
sprintf (bytes, "%d,%d,%d,%d,%d,%d", in_addr[0], in_addr[1],
|
||||||
|
in_addr[2], in_addr[3], (unsigned) (port & 0xff00) >> 8,
|
||||||
|
port & 0xff);
|
||||||
|
/* Send PORT request. */
|
||||||
|
request = ftp_request ("PORT", bytes);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPPORTERR;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to ftp_port, but uses `PASV' to initiate the passive FTP
|
||||||
|
transfer. Reads the response from server and parses it. Reads the
|
||||||
|
host and port addresses and returns them. */
|
||||||
|
uerr_t
|
||||||
|
ftp_pasv (struct rbuf *rbuf, unsigned char *addr)
|
||||||
|
{
|
||||||
|
char *request, *respline, *s;
|
||||||
|
int nwritten, i;
|
||||||
|
uerr_t err;
|
||||||
|
|
||||||
|
/* Form the request. */
|
||||||
|
request = ftp_request ("PASV", NULL);
|
||||||
|
/* And send it. */
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get the server response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPNOPASV;
|
||||||
|
}
|
||||||
|
/* Parse the request. */
|
||||||
|
s = respline;
|
||||||
|
for (s += 4; *s && !ISDIGIT (*s); s++);
|
||||||
|
if (!*s)
|
||||||
|
return FTPINVPASV;
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
addr[i] = 0;
|
||||||
|
for (; ISDIGIT (*s); s++)
|
||||||
|
addr[i] = (*s - '0') + 10 * addr[i];
|
||||||
|
if (*s == ',')
|
||||||
|
s++;
|
||||||
|
else if (i < 5)
|
||||||
|
{
|
||||||
|
/* When on the last number, anything can be a terminator. */
|
||||||
|
free (respline);
|
||||||
|
return FTPINVPASV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sends the TYPE request to the server. */
|
||||||
|
uerr_t
|
||||||
|
ftp_type (struct rbuf *rbuf, int type)
|
||||||
|
{
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
uerr_t err;
|
||||||
|
char stype[2];
|
||||||
|
|
||||||
|
/* Construct argument. */
|
||||||
|
stype[0] = type;
|
||||||
|
stype[1] = 0;
|
||||||
|
/* Send TYPE request. */
|
||||||
|
request = ftp_request ("TYPE", stype);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPUNKNOWNTYPE;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Changes the working directory by issuing a CWD command to the
|
||||||
|
server. */
|
||||||
|
uerr_t
|
||||||
|
ftp_cwd (struct rbuf *rbuf, const char *dir)
|
||||||
|
{
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
uerr_t err;
|
||||||
|
|
||||||
|
/* Send CWD request. */
|
||||||
|
request = ftp_request ("CWD", dir);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline == '5')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPNSFOD;
|
||||||
|
}
|
||||||
|
if (*respline != '2')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPRERR;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sends REST command to the FTP server. */
|
||||||
|
uerr_t
|
||||||
|
ftp_rest (struct rbuf *rbuf, long offset)
|
||||||
|
{
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
uerr_t err;
|
||||||
|
static char numbuf[20]; /* Buffer for the number */
|
||||||
|
|
||||||
|
long_to_string (numbuf, offset);
|
||||||
|
request = ftp_request ("REST", numbuf);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline != '3')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPRESTFAIL;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sends RETR command to the FTP server. */
|
||||||
|
uerr_t
|
||||||
|
ftp_retr (struct rbuf *rbuf, const char *file)
|
||||||
|
{
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
uerr_t err;
|
||||||
|
|
||||||
|
/* Send RETR request. */
|
||||||
|
request = ftp_request ("RETR", file);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate response. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline == '5')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPNSFOD;
|
||||||
|
}
|
||||||
|
if (*respline != '1')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPRERR;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sends the LIST command to the server. If FILE is NULL, send just
|
||||||
|
`LIST' (no space). */
|
||||||
|
uerr_t
|
||||||
|
ftp_list (struct rbuf *rbuf, const char *file)
|
||||||
|
{
|
||||||
|
char *request, *respline;
|
||||||
|
int nwritten;
|
||||||
|
uerr_t err;
|
||||||
|
|
||||||
|
/* Send LIST request. */
|
||||||
|
request = ftp_request ("LIST", file);
|
||||||
|
nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
free (request);
|
||||||
|
return WRITEFAILED;
|
||||||
|
}
|
||||||
|
free (request);
|
||||||
|
/* Get appropriate respone. */
|
||||||
|
err = ftp_response (rbuf, &respline);
|
||||||
|
if (err != FTPOK)
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (*respline == '5')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPNSFOD;
|
||||||
|
}
|
||||||
|
if (*respline != '1')
|
||||||
|
{
|
||||||
|
free (respline);
|
||||||
|
return FTPRERR;
|
||||||
|
}
|
||||||
|
free (respline);
|
||||||
|
/* All OK. */
|
||||||
|
return FTPOK;
|
||||||
|
}
|
388
src/ftp-ls.c
Normal file
388
src/ftp-ls.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/* Parsing FTP `ls' output.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "ftp.h"
|
||||||
|
|
||||||
|
/* Converts symbolic permissions to number-style ones, e.g. string
|
||||||
|
rwxr-xr-x to 755. For now, it knows nothing of
|
||||||
|
setuid/setgid/sticky. ACLs are ignored. */
|
||||||
|
static int
|
||||||
|
symperms (const char *s)
|
||||||
|
{
|
||||||
|
int perms = 0, i;
|
||||||
|
|
||||||
|
if (strlen (s) < 9)
|
||||||
|
return 0;
|
||||||
|
for (i = 0; i < 3; i++, s += 3)
|
||||||
|
{
|
||||||
|
perms <<= 3;
|
||||||
|
perms += (((s[0] == 'r') << 2) + ((s[1] == 'w') << 1) +
|
||||||
|
(s[2] == 'x' || s[2] == 's'));
|
||||||
|
}
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert the Un*x-ish style directory listing stored in FILE to a
|
||||||
|
linked list of fileinfo (system-independent) entries. The contents
|
||||||
|
of FILE are considered to be produced by the standard Unix `ls -la'
|
||||||
|
output (whatever that might be). BSD (no group) and SYSV (with
|
||||||
|
group) listings are handled.
|
||||||
|
|
||||||
|
The time stamps are stored in a separate variable, time_t
|
||||||
|
compatible (I hope). The timezones are ignored. */
|
||||||
|
static struct fileinfo *
|
||||||
|
ftp_parse_unix_ls (const char *file)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
static const char *months[] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
int next, len, i, error, ignore;
|
||||||
|
int year, month, day; /* for time analysis */
|
||||||
|
int hour, min, sec;
|
||||||
|
struct tm timestruct, *tnow;
|
||||||
|
time_t timenow;
|
||||||
|
|
||||||
|
char *line, *tok; /* tokenizer */
|
||||||
|
struct fileinfo *dir, *l, cur; /* list creation */
|
||||||
|
|
||||||
|
fp = fopen (file, "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dir = l = NULL;
|
||||||
|
|
||||||
|
/* Line loop to end of file: */
|
||||||
|
while ((line = read_whole_line (fp)))
|
||||||
|
{
|
||||||
|
DEBUGP (("%s\n", line));
|
||||||
|
len = strlen (line);
|
||||||
|
/* Destroy <CR> if there is one. */
|
||||||
|
if (len && line[len - 1] == '\r')
|
||||||
|
line[--len] = '\0';
|
||||||
|
|
||||||
|
/* Skip if total... */
|
||||||
|
if (!strncasecmp (line, "total", 5))
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Get the first token (permissions). */
|
||||||
|
tok = strtok (line, " ");
|
||||||
|
if (!tok)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.name = NULL;
|
||||||
|
cur.linkto = NULL;
|
||||||
|
|
||||||
|
/* Decide whether we deal with a file or a directory. */
|
||||||
|
switch (*tok)
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
cur.type = FT_PLAINFILE;
|
||||||
|
DEBUGP (("PLAINFILE; "));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
cur.type = FT_DIRECTORY;
|
||||||
|
DEBUGP (("DIRECTORY; "));
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
cur.type = FT_SYMLINK;
|
||||||
|
DEBUGP (("SYMLINK; "));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cur.type = FT_UNKNOWN;
|
||||||
|
DEBUGP (("UNKOWN; "));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.perms = symperms (tok + 1);
|
||||||
|
DEBUGP (("perms %0o; ", cur.perms));
|
||||||
|
|
||||||
|
error = ignore = 0; /* Errnoeous and ignoring entries are
|
||||||
|
treated equally for now. */
|
||||||
|
year = hour = min = sec = 0; /* Silence the compiler. */
|
||||||
|
month = day = 0;
|
||||||
|
next = -1;
|
||||||
|
/* While there are tokens on the line, parse them. Next is the
|
||||||
|
number of tokens left until the filename.
|
||||||
|
|
||||||
|
Use the month-name token as the "anchor" (the place where the
|
||||||
|
position wrt the file name is "known"). When a month name is
|
||||||
|
encountered, `next' is set to 5. Also, the preceding
|
||||||
|
characters are parsed to get the file size.
|
||||||
|
|
||||||
|
This tactic is quite dubious when it comes to
|
||||||
|
internationalization issues (non-English month names), but it
|
||||||
|
works for now. */
|
||||||
|
while ((tok = strtok (NULL, " ")))
|
||||||
|
{
|
||||||
|
--next;
|
||||||
|
if (next < 0) /* a month name was not encountered */
|
||||||
|
{
|
||||||
|
for (i = 0; i < 12; i++)
|
||||||
|
if (!strcmp (tok, months[i]))
|
||||||
|
break;
|
||||||
|
/* If we got a month, it means the token before it is the
|
||||||
|
size, and the filename is three tokens away. */
|
||||||
|
if (i != 12)
|
||||||
|
{
|
||||||
|
char *t = tok - 2;
|
||||||
|
long mul = 1;
|
||||||
|
|
||||||
|
for (cur.size = 0; t > line && ISDIGIT (*t); mul *= 10, t--)
|
||||||
|
cur.size += mul * (*t - '0');
|
||||||
|
if (t == line)
|
||||||
|
{
|
||||||
|
/* Something is seriously wrong. */
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
month = i;
|
||||||
|
next = 5;
|
||||||
|
DEBUGP (("month: %s; ", months[month]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (next == 4) /* days */
|
||||||
|
{
|
||||||
|
if (tok[1]) /* two-digit... */
|
||||||
|
day = 10 * (*tok - '0') + tok[1] - '0';
|
||||||
|
else /* ...or one-digit */
|
||||||
|
day = *tok - '0';
|
||||||
|
DEBUGP (("day: %d; ", day));
|
||||||
|
}
|
||||||
|
else if (next == 3)
|
||||||
|
{
|
||||||
|
/* This ought to be either the time, or the year. Let's
|
||||||
|
be flexible!
|
||||||
|
|
||||||
|
If we have a number x, it's a year. If we have x:y,
|
||||||
|
it's hours and minutes. If we have x:y:z, z are
|
||||||
|
seconds. */
|
||||||
|
year = 0;
|
||||||
|
min = hour = sec = 0;
|
||||||
|
/* We must deal with digits. */
|
||||||
|
if (ISDIGIT (*tok))
|
||||||
|
{
|
||||||
|
/* Suppose it's year. */
|
||||||
|
for (; ISDIGIT (*tok); tok++)
|
||||||
|
year = (*tok - '0') + 10 * year;
|
||||||
|
if (*tok == ':')
|
||||||
|
{
|
||||||
|
/* This means these were hours! */
|
||||||
|
hour = year;
|
||||||
|
year = 0;
|
||||||
|
++tok;
|
||||||
|
/* Get the minutes... */
|
||||||
|
for (; ISDIGIT (*tok); tok++)
|
||||||
|
min = (*tok - '0') + 10 * min;
|
||||||
|
if (*tok == ':')
|
||||||
|
{
|
||||||
|
/* ...and the seconds. */
|
||||||
|
++tok;
|
||||||
|
for (; ISDIGIT (*tok); tok++)
|
||||||
|
sec = (*tok - '0') + 10 * sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (year)
|
||||||
|
DEBUGP (("year: %d (no tm); ", year));
|
||||||
|
else
|
||||||
|
DEBUGP (("time: %02d:%02d:%02d (no yr); ", hour, min, sec));
|
||||||
|
}
|
||||||
|
else if (next == 2) /* The file name */
|
||||||
|
{
|
||||||
|
int fnlen;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* Since the file name may contain a SPC, it is possible
|
||||||
|
for strtok to handle it wrong. */
|
||||||
|
fnlen = strlen (tok);
|
||||||
|
if (fnlen < len - (tok - line))
|
||||||
|
{
|
||||||
|
/* So we have a SPC in the file name. Restore the
|
||||||
|
original. */
|
||||||
|
tok[fnlen] = ' ';
|
||||||
|
/* If the file is a symbolic link, it should have a
|
||||||
|
` -> ' somewhere. */
|
||||||
|
if (cur.type == FT_SYMLINK)
|
||||||
|
{
|
||||||
|
p = strstr (tok, " -> ");
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur.linkto = xstrdup (p + 4);
|
||||||
|
DEBUGP (("link to: %s\n", cur.linkto));
|
||||||
|
/* And separate it from the file name. */
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If we have the filename, add it to the list of files or
|
||||||
|
directories. */
|
||||||
|
/* "." and ".." are an exception! */
|
||||||
|
if (!strcmp (tok, ".") || !strcmp (tok, ".."))
|
||||||
|
{
|
||||||
|
DEBUGP (("\nIgnoring `.' and `..'; "));
|
||||||
|
ignore = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Some FTP sites choose to have ls -F as their default
|
||||||
|
LIST output, which marks the symlinks with a trailing
|
||||||
|
`@', directory names with a trailing `/' and
|
||||||
|
executables with a trailing `*'. This is no problem
|
||||||
|
unless encountering a symbolic link ending with `@',
|
||||||
|
or an executable ending with `*' on a server without
|
||||||
|
default -F output. I believe these cases are very
|
||||||
|
rare. */
|
||||||
|
fnlen = strlen (tok); /* re-calculate `fnlen' */
|
||||||
|
cur.name = (char *)xmalloc (fnlen + 1);
|
||||||
|
memcpy (cur.name, tok, fnlen + 1);
|
||||||
|
if (fnlen)
|
||||||
|
{
|
||||||
|
if (cur.type == FT_DIRECTORY && cur.name[fnlen - 1] == '/')
|
||||||
|
{
|
||||||
|
cur.name[fnlen - 1] = '\0';
|
||||||
|
DEBUGP (("trailing `/' on dir.\n"));
|
||||||
|
}
|
||||||
|
else if (cur.type == FT_SYMLINK && cur.name[fnlen - 1] == '@')
|
||||||
|
{
|
||||||
|
cur.name[fnlen - 1] = '\0';
|
||||||
|
DEBUGP (("trailing `@' on link.\n"));
|
||||||
|
}
|
||||||
|
else if (cur.type == FT_PLAINFILE
|
||||||
|
&& (cur.perms & 0111)
|
||||||
|
&& cur.name[fnlen - 1] == '*')
|
||||||
|
{
|
||||||
|
cur.name[fnlen - 1] = '\0';
|
||||||
|
DEBUGP (("trailing `*' on exec.\n"));
|
||||||
|
}
|
||||||
|
} /* if (fnlen) */
|
||||||
|
else
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
if (!cur.name || (cur.type == FT_SYMLINK && !cur.linkto))
|
||||||
|
error = 1;
|
||||||
|
|
||||||
|
DEBUGP (("\n"));
|
||||||
|
|
||||||
|
if (error || ignore)
|
||||||
|
{
|
||||||
|
DEBUGP (("Skipping.\n"));
|
||||||
|
FREE_MAYBE (cur.name);
|
||||||
|
FREE_MAYBE (cur.linkto);
|
||||||
|
free (line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
l = dir = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
|
||||||
|
memcpy (l, &cur, sizeof (cur));
|
||||||
|
l->prev = l->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur.prev = l;
|
||||||
|
l->next = (struct fileinfo *)xmalloc (sizeof (struct fileinfo));
|
||||||
|
l = l->next;
|
||||||
|
memcpy (l, &cur, sizeof (cur));
|
||||||
|
l->next = NULL;
|
||||||
|
}
|
||||||
|
/* Get the current time. */
|
||||||
|
timenow = time (NULL);
|
||||||
|
tnow = localtime (&timenow);
|
||||||
|
/* Build the time-stamp (the idea by zaga@fly.cc.fer.hr). */
|
||||||
|
timestruct.tm_sec = sec;
|
||||||
|
timestruct.tm_min = min;
|
||||||
|
timestruct.tm_hour = hour;
|
||||||
|
timestruct.tm_mday = day;
|
||||||
|
timestruct.tm_mon = month;
|
||||||
|
if (year == 0)
|
||||||
|
{
|
||||||
|
/* Some listings will not specify the year if it is "obvious"
|
||||||
|
that the file was from the previous year. E.g. if today
|
||||||
|
is 97-01-12, and you see a file of Dec 15th, its year is
|
||||||
|
1996, not 1997. Thanks to Vladimir Volovich for
|
||||||
|
mentioning this! */
|
||||||
|
if (month > tnow->tm_mon)
|
||||||
|
timestruct.tm_year = tnow->tm_year - 1;
|
||||||
|
else
|
||||||
|
timestruct.tm_year = tnow->tm_year;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
timestruct.tm_year = year;
|
||||||
|
if (timestruct.tm_year >= 1900)
|
||||||
|
timestruct.tm_year -= 1900;
|
||||||
|
timestruct.tm_wday = 0;
|
||||||
|
timestruct.tm_yday = 0;
|
||||||
|
timestruct.tm_isdst = -1;
|
||||||
|
l->tstamp = mktime (×truct); /* store the time-stamp */
|
||||||
|
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (fp);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is just a stub. It should actually accept some kind
|
||||||
|
of information what system it is running on -- e.g. FPL_UNIX,
|
||||||
|
FPL_DOS, FPL_NT, FPL_VMS, etc. and a "guess-me" value, like
|
||||||
|
FPL_GUESS. Then it would call the appropriate parsers to fill up
|
||||||
|
fileinfos.
|
||||||
|
|
||||||
|
Since we currently support only the Unix FTP servers, this function
|
||||||
|
simply returns the result of ftp_parse_unix_ls(). */
|
||||||
|
struct fileinfo *
|
||||||
|
ftp_parse_ls (const char *file)
|
||||||
|
{
|
||||||
|
return ftp_parse_unix_ls (file);
|
||||||
|
}
|
2179
src/ftp-opie.c
Normal file
2179
src/ftp-opie.c
Normal file
File diff suppressed because it is too large
Load Diff
95
src/ftp.h
Normal file
95
src/ftp.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* Declarations for FTP support.
|
||||||
|
Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef FTP_H
|
||||||
|
#define FTP_H
|
||||||
|
|
||||||
|
/* Need it for struct rbuf. */
|
||||||
|
#include "rbuf.h"
|
||||||
|
|
||||||
|
uerr_t ftp_response PARAMS ((struct rbuf *, char **));
|
||||||
|
uerr_t ftp_login PARAMS ((struct rbuf *, const char *, const char *));
|
||||||
|
uerr_t ftp_port PARAMS ((struct rbuf *));
|
||||||
|
uerr_t ftp_pasv PARAMS ((struct rbuf *, unsigned char *));
|
||||||
|
uerr_t ftp_type PARAMS ((struct rbuf *, int));
|
||||||
|
uerr_t ftp_cwd PARAMS ((struct rbuf *, const char *));
|
||||||
|
uerr_t ftp_retr PARAMS ((struct rbuf *, const char *));
|
||||||
|
uerr_t ftp_rest PARAMS ((struct rbuf *, long));
|
||||||
|
uerr_t ftp_list PARAMS ((struct rbuf *, const char *));
|
||||||
|
|
||||||
|
struct urlinfo;
|
||||||
|
|
||||||
|
/* File types. */
|
||||||
|
enum ftype
|
||||||
|
{
|
||||||
|
FT_PLAINFILE,
|
||||||
|
FT_DIRECTORY,
|
||||||
|
FT_SYMLINK,
|
||||||
|
FT_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Globbing (used by ftp_retrieve_glob). */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GLOBALL, GETALL, GETONE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Information about one filename in a linked list. */
|
||||||
|
struct fileinfo
|
||||||
|
{
|
||||||
|
enum ftype type; /* file type */
|
||||||
|
char *name; /* file name */
|
||||||
|
long size; /* file size */
|
||||||
|
long tstamp; /* time-stamp */
|
||||||
|
int perms; /* file permissions */
|
||||||
|
char *linkto; /* link to which file points */
|
||||||
|
struct fileinfo *prev; /* previous... */
|
||||||
|
struct fileinfo *next; /* ...and next structure. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Commands for FTP functions. */
|
||||||
|
enum command
|
||||||
|
{
|
||||||
|
DO_LOGIN = 0x0001, /* Connect and login to the server. */
|
||||||
|
DO_CWD = 0x0002, /* Change current directory. */
|
||||||
|
DO_RETR = 0x0004, /* Retrieve the file. */
|
||||||
|
DO_LIST = 0x0008, /* Retrieve the directory list. */
|
||||||
|
LEAVE_PENDING = 0x0010 /* Do not close the socket. */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fstatus
|
||||||
|
{
|
||||||
|
NOTHING = 0x0000, /* Nothing done yet. */
|
||||||
|
ON_YOUR_OWN = 0x0001, /* The ftp_loop_internal sets the
|
||||||
|
defaults. */
|
||||||
|
DONE_CWD = 0x0002 /* The current working directory is
|
||||||
|
correct. */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int st; /* connection status */
|
||||||
|
int cmd; /* command code */
|
||||||
|
struct rbuf rbuf; /* control connection buffer */
|
||||||
|
long dltime; /* time of the download */
|
||||||
|
} ccon;
|
||||||
|
|
||||||
|
struct fileinfo *ftp_parse_ls PARAMS ((const char *));
|
||||||
|
uerr_t ftp_loop PARAMS ((struct urlinfo *, int *));
|
||||||
|
|
||||||
|
#endif /* FTP_H */
|
712
src/getopt.c
Normal file
712
src/getopt.c
Normal file
@ -0,0 +1,712 @@
|
|||||||
|
/* Getopt for GNU.
|
||||||
|
NOTE: getopt is now part of the C library, so if you don't know what
|
||||||
|
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||||
|
before changing it!
|
||||||
|
|
||||||
|
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||||
|
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* NOTE!!! AIX requires this to be the first thing in the file.
|
||||||
|
Do not put ANYTHING before it! */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
#include "wget.h"
|
||||||
|
|
||||||
|
#if !__STDC__ && !defined(const) && IN_GCC
|
||||||
|
#define const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||||
|
#ifndef _NO_PROTO
|
||||||
|
#define _NO_PROTO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||||
|
actually compiling the library itself. This code is part of the GNU C
|
||||||
|
Library, but also included in many other GNU distributions. Compiling
|
||||||
|
and linking in this code is a waste when using the GNU C library
|
||||||
|
(especially if it is a shared library). Rather than having every GNU
|
||||||
|
program understand `configure --with-gnu-libc' and omit the object files,
|
||||||
|
it is simpler to just do this in the source for each such file. */
|
||||||
|
|
||||||
|
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||||
|
long-named option. Because this is not POSIX.2 compliant, it is
|
||||||
|
being phased out. */
|
||||||
|
/* #define GETOPT_COMPAT */
|
||||||
|
|
||||||
|
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||||
|
but it behaves differently for the user, since it allows the user
|
||||||
|
to intersperse the options with the other arguments.
|
||||||
|
|
||||||
|
As `getopt' works, it permutes the elements of ARGV so that,
|
||||||
|
when it is done, all the options precede everything else. Thus
|
||||||
|
all application programs are extended to handle flexible argument order.
|
||||||
|
|
||||||
|
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||||
|
Then the behavior is completely standard.
|
||||||
|
|
||||||
|
GNU application programs can use a third alternative mode in which
|
||||||
|
they can distinguish the relative order of options and other arguments. */
|
||||||
|
|
||||||
|
#include "getopt.h"
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
char *optarg = 0;
|
||||||
|
|
||||||
|
/* 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 EOF, 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. */
|
||||||
|
|
||||||
|
/* XXX 1003.2 says this must be 1 before any call. */
|
||||||
|
int optind = 0;
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
static char *nextchar;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
int opterr = 1;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized.
|
||||||
|
This must be initialized on some systems to avoid linking in the
|
||||||
|
system's own getopt implementation. */
|
||||||
|
|
||||||
|
int optopt = '?';
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
|
||||||
|
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 EOF with `optind' != ARGC. */
|
||||||
|
|
||||||
|
static enum
|
||||||
|
{
|
||||||
|
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||||
|
} ordering;
|
||||||
|
|
||||||
|
#ifdef __GNU_LIBRARY__
|
||||||
|
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||||
|
because there are many ways it can cause trouble.
|
||||||
|
On some systems, it contains special magic macros that don't work
|
||||||
|
in GCC. */
|
||||||
|
#include <string.h>
|
||||||
|
#define my_index strchr
|
||||||
|
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Avoid depending on library functions or files
|
||||||
|
whose names are inconsistent. */
|
||||||
|
|
||||||
|
char *getenv ();
|
||||||
|
|
||||||
|
static char *
|
||||||
|
my_index (const char *str, int chr)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
if (*str == chr)
|
||||||
|
return (char *) str;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_bcopy (const char *from, char *to, int size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
to[i] = from[i];
|
||||||
|
}
|
||||||
|
#endif /* GNU C library. */
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
static int first_nonopt;
|
||||||
|
static int last_nonopt;
|
||||||
|
|
||||||
|
/* Exchange two adjacent subsequences of ARGV.
|
||||||
|
One subsequence is elements [first_nonopt,last_nonopt)
|
||||||
|
which contains all the non-options that have been skipped so far.
|
||||||
|
The other is elements [last_nonopt,optind), which contains all
|
||||||
|
the options processed since those non-options were skipped.
|
||||||
|
|
||||||
|
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||||
|
the new indices of the non-options in ARGV after they are moved. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
exchange (char **argv)
|
||||||
|
{
|
||||||
|
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||||
|
char **temp = (char **) alloca (nonopts_size);
|
||||||
|
|
||||||
|
/* Interchange the two blocks of data in ARGV. */
|
||||||
|
|
||||||
|
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||||
|
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||||
|
(optind - last_nonopt) * sizeof (char *));
|
||||||
|
my_bcopy ((char *) temp,
|
||||||
|
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||||
|
nonopts_size);
|
||||||
|
|
||||||
|
/* Update records for the slots the non-options now occupy. */
|
||||||
|
|
||||||
|
first_nonopt += (optind - last_nonopt);
|
||||||
|
last_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||||
|
given in OPTSTRING.
|
||||||
|
|
||||||
|
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||||
|
then it is an option element. The characters of this element
|
||||||
|
(aside from the initial '-') are option characters. If `getopt'
|
||||||
|
is called repeatedly, it returns successively each of the option characters
|
||||||
|
from each of the option elements.
|
||||||
|
|
||||||
|
If `getopt' finds another option character, it returns that character,
|
||||||
|
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||||
|
resume the scan with the following option character or ARGV-element.
|
||||||
|
|
||||||
|
If there are no more option characters, `getopt' returns `EOF'.
|
||||||
|
Then `optind' is the index in ARGV of the first ARGV-element
|
||||||
|
that is not an option. (The ARGV-elements have been permuted
|
||||||
|
so that those that are not options now come last.)
|
||||||
|
|
||||||
|
OPTSTRING is a string containing the legitimate option characters.
|
||||||
|
If an option character is seen that is not listed in OPTSTRING,
|
||||||
|
return '?' after printing an error message. If you set `opterr' to
|
||||||
|
zero, the error message is suppressed but we still return '?'.
|
||||||
|
|
||||||
|
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||||
|
so the following text in the same ARGV-element, or the text of the following
|
||||||
|
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||||
|
wants an optional arg; if there is text in the current ARGV-element,
|
||||||
|
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||||
|
|
||||||
|
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||||
|
handling the non-option ARGV-elements.
|
||||||
|
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||||
|
|
||||||
|
Long-named options begin with `--' instead of `-'.
|
||||||
|
Their names may be abbreviated as long as the abbreviation is unique
|
||||||
|
or is an exact match for some defined option. If they have an
|
||||||
|
argument, it follows the option name in the same ARGV-element, separated
|
||||||
|
from the option name by a `=', or else the in next ARGV-element.
|
||||||
|
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||||
|
`flag' field is nonzero, the value of the option's `val' field
|
||||||
|
if the `flag' field is zero.
|
||||||
|
|
||||||
|
The elements of ARGV aren't really const, because we permute them.
|
||||||
|
But we pretend they're const in the prototype to be compatible
|
||||||
|
with other systems.
|
||||||
|
|
||||||
|
LONGOPTS is a vector of `struct option' terminated by an
|
||||||
|
element containing a name which is zero.
|
||||||
|
|
||||||
|
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||||
|
It is only valid when a long-named option has been found by the most
|
||||||
|
recent call.
|
||||||
|
|
||||||
|
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||||
|
long-named options. */
|
||||||
|
|
||||||
|
int
|
||||||
|
_getopt_internal (int argc, char *const *argv, const char *optstring,
|
||||||
|
const struct option *longopts, int *longind, int long_only)
|
||||||
|
{
|
||||||
|
int option_index;
|
||||||
|
|
||||||
|
optarg = 0;
|
||||||
|
|
||||||
|
/* Initialize the internal data when the first call is made.
|
||||||
|
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||||
|
is the program name); the sequence of previously skipped
|
||||||
|
non-option ARGV-elements is empty. */
|
||||||
|
|
||||||
|
if (optind == 0)
|
||||||
|
{
|
||||||
|
first_nonopt = last_nonopt = optind = 1;
|
||||||
|
|
||||||
|
nextchar = NULL;
|
||||||
|
|
||||||
|
/* Determine how to handle the ordering of options and nonoptions. */
|
||||||
|
|
||||||
|
if (optstring[0] == '-')
|
||||||
|
{
|
||||||
|
ordering = RETURN_IN_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (optstring[0] == '+')
|
||||||
|
{
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
else
|
||||||
|
ordering = PERMUTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextchar == NULL || *nextchar == '\0')
|
||||||
|
{
|
||||||
|
if (ordering == PERMUTE)
|
||||||
|
{
|
||||||
|
/* If we have just processed some options following some non-options,
|
||||||
|
exchange them so that the options come first. */
|
||||||
|
|
||||||
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
|
exchange ((char **) argv);
|
||||||
|
else if (last_nonopt != optind)
|
||||||
|
first_nonopt = optind;
|
||||||
|
|
||||||
|
/* Now skip any additional non-options
|
||||||
|
and extend the range of non-options previously skipped. */
|
||||||
|
|
||||||
|
while (optind < argc
|
||||||
|
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
&& (longopts == NULL
|
||||||
|
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
)
|
||||||
|
optind++;
|
||||||
|
last_nonopt = optind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special ARGV-element `--' means premature end of options.
|
||||||
|
Skip it like a null option,
|
||||||
|
then exchange with previous non-options as if it were an option,
|
||||||
|
then skip everything else like a non-option. */
|
||||||
|
|
||||||
|
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||||
|
{
|
||||||
|
optind++;
|
||||||
|
|
||||||
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
|
exchange ((char **) argv);
|
||||||
|
else if (first_nonopt == last_nonopt)
|
||||||
|
first_nonopt = optind;
|
||||||
|
last_nonopt = argc;
|
||||||
|
|
||||||
|
optind = argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have done all the ARGV-elements, stop the scan
|
||||||
|
and back over any non-options that we skipped and permuted. */
|
||||||
|
|
||||||
|
if (optind == argc)
|
||||||
|
{
|
||||||
|
/* Set the next-arg-index to point at the non-options
|
||||||
|
that we previously skipped, so the caller will digest them. */
|
||||||
|
if (first_nonopt != last_nonopt)
|
||||||
|
optind = first_nonopt;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have come to a non-option and did not permute it,
|
||||||
|
either stop the scan or describe it to the caller and pass it by. */
|
||||||
|
|
||||||
|
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
&& (longopts == NULL
|
||||||
|
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (ordering == REQUIRE_ORDER)
|
||||||
|
return EOF;
|
||||||
|
optarg = argv[optind++];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have found another option-ARGV-element.
|
||||||
|
Start decoding its characters. */
|
||||||
|
|
||||||
|
nextchar = (argv[optind] + 1
|
||||||
|
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longopts != NULL
|
||||||
|
&& ((argv[optind][0] == '-'
|
||||||
|
&& (argv[optind][1] == '-' || long_only))
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
|| argv[optind][0] == '+'
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
))
|
||||||
|
{
|
||||||
|
const struct option *p;
|
||||||
|
char *s = nextchar;
|
||||||
|
int exact = 0;
|
||||||
|
int ambig = 0;
|
||||||
|
const struct option *pfound = NULL;
|
||||||
|
int indfound;
|
||||||
|
|
||||||
|
indfound = 0; /* To silence the compiler. */
|
||||||
|
|
||||||
|
while (*s && *s != '=')
|
||||||
|
s++;
|
||||||
|
|
||||||
|
/* Test all options for either exact match or abbreviated matches. */
|
||||||
|
for (p = longopts, option_index = 0; p->name;
|
||||||
|
p++, option_index++)
|
||||||
|
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||||
|
{
|
||||||
|
if (s - nextchar == strlen (p->name))
|
||||||
|
{
|
||||||
|
/* Exact match found. */
|
||||||
|
pfound = p;
|
||||||
|
indfound = option_index;
|
||||||
|
exact = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (pfound == NULL)
|
||||||
|
{
|
||||||
|
/* First nonexact match found. */
|
||||||
|
pfound = p;
|
||||||
|
indfound = option_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Second nonexact match found. */
|
||||||
|
ambig = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ambig && !exact)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
|
||||||
|
exec_name, argv[optind]);
|
||||||
|
nextchar += strlen (nextchar);
|
||||||
|
optind++;
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfound != NULL)
|
||||||
|
{
|
||||||
|
option_index = indfound;
|
||||||
|
optind++;
|
||||||
|
if (*s)
|
||||||
|
{
|
||||||
|
/* Don't test has_arg with >, because some C compilers don't
|
||||||
|
allow it to be used on enums. */
|
||||||
|
if (pfound->has_arg)
|
||||||
|
optarg = s + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
if (argv[optind - 1][1] == '-')
|
||||||
|
/* --option */
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: option `--%s' doesn't allow an argument\n"),
|
||||||
|
exec_name, pfound->name);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: option `%c%s' doesn't allow an argument\n"),
|
||||||
|
exec_name, argv[optind - 1][0], pfound->name);
|
||||||
|
}
|
||||||
|
nextchar += strlen (nextchar);
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pfound->has_arg == 1)
|
||||||
|
{
|
||||||
|
if (optind < argc)
|
||||||
|
optarg = argv[optind++];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: option `%s' requires an argument\n"),
|
||||||
|
exec_name, argv[optind - 1]);
|
||||||
|
nextchar += strlen (nextchar);
|
||||||
|
return optstring[0] == ':' ? ':' : '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextchar += strlen (nextchar);
|
||||||
|
if (longind != NULL)
|
||||||
|
*longind = option_index;
|
||||||
|
if (pfound->flag)
|
||||||
|
{
|
||||||
|
*(pfound->flag) = pfound->val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pfound->val;
|
||||||
|
}
|
||||||
|
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||||
|
or the option starts with '--' or is not a valid short
|
||||||
|
option, then it's an error.
|
||||||
|
Otherwise interpret it as a short option. */
|
||||||
|
if (!long_only || argv[optind][1] == '-'
|
||||||
|
#ifdef GETOPT_COMPAT
|
||||||
|
|| argv[optind][0] == '+'
|
||||||
|
#endif /* GETOPT_COMPAT */
|
||||||
|
|| my_index (optstring, *nextchar) == NULL)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
if (argv[optind][1] == '-')
|
||||||
|
/* --option */
|
||||||
|
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
|
||||||
|
exec_name, nextchar);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
|
||||||
|
exec_name, argv[optind][0], nextchar);
|
||||||
|
}
|
||||||
|
nextchar = (char *) "";
|
||||||
|
optind++;
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look at and handle the next option-character. */
|
||||||
|
|
||||||
|
{
|
||||||
|
char c = *nextchar++;
|
||||||
|
char *temp = my_index (optstring, c);
|
||||||
|
|
||||||
|
/* Increment `optind' when we start to process its last character. */
|
||||||
|
if (*nextchar == '\0')
|
||||||
|
++optind;
|
||||||
|
|
||||||
|
if (temp == NULL || c == ':')
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (c < 040 || c >= 0177)
|
||||||
|
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||||
|
exec_name, c);
|
||||||
|
else
|
||||||
|
fprintf (stderr, "%s: unrecognized option `-%c'\n", exec_name, c);
|
||||||
|
#else
|
||||||
|
/* 1003.2 specifies the format of this message. */
|
||||||
|
fprintf (stderr, _("%s: illegal option -- %c\n"), exec_name, c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
optopt = c;
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
if (temp[1] == ':')
|
||||||
|
{
|
||||||
|
if (temp[2] == ':')
|
||||||
|
{
|
||||||
|
/* This is an option that accepts an argument optionally. */
|
||||||
|
if (*nextchar != '\0')
|
||||||
|
{
|
||||||
|
optarg = nextchar;
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
optarg = 0;
|
||||||
|
nextchar = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is an option that requires an argument. */
|
||||||
|
if (*nextchar != '\0')
|
||||||
|
{
|
||||||
|
optarg = nextchar;
|
||||||
|
/* If we end this ARGV-element by taking the rest as an arg,
|
||||||
|
we must advance to the next element now. */
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
else if (optind == argc)
|
||||||
|
{
|
||||||
|
if (opterr)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||||
|
exec_name, c);
|
||||||
|
#else
|
||||||
|
/* 1003.2 specifies the format of this message. */
|
||||||
|
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
|
||||||
|
exec_name, c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
optopt = c;
|
||||||
|
if (optstring[0] == ':')
|
||||||
|
c = ':';
|
||||||
|
else
|
||||||
|
c = '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* We already incremented `optind' once;
|
||||||
|
increment it again when taking next ARGV-elt as argument. */
|
||||||
|
optarg = argv[optind++];
|
||||||
|
nextchar = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calls internal getopt function to enable long option names. */
|
||||||
|
int
|
||||||
|
getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind)
|
||||||
|
{
|
||||||
|
return _getopt_internal (argc, argv, shortopts, longopts, longind, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getopt (int argc, char *const *argv, const char *optstring)
|
||||||
|
{
|
||||||
|
return _getopt_internal (argc, argv, optstring,
|
||||||
|
(const struct option *) 0,
|
||||||
|
(int *) 0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
/* Compile with -DTEST to make an executable for use in testing
|
||||||
|
the above definition of `getopt'. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int digit_optind = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int this_option_optind = optind ? optind : 1;
|
||||||
|
|
||||||
|
c = getopt (argc, argv, "abc:d:0123456789");
|
||||||
|
if (c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
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 '?':
|
||||||
|
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 */
|
129
src/getopt.h
Normal file
129
src/getopt.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* Declarations for getopt.
|
||||||
|
Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef _GETOPT_H
|
||||||
|
#define _GETOPT_H 1
|
||||||
|
|
||||||
|
#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 EOF, 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;
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
|
#if __STDC__
|
||||||
|
const char *name;
|
||||||
|
#else
|
||||||
|
char *name;
|
||||||
|
#endif
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
#if defined(__GNU_LIBRARY__)
|
||||||
|
/* Many other libraries have conflicting prototypes for getopt, with
|
||||||
|
differences in the consts, in stdlib.h. To avoid compilation
|
||||||
|
errors, only prototype getopt for the GNU C library. */
|
||||||
|
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||||
|
#else /* not __GNU_LIBRARY__ */
|
||||||
|
extern int getopt ();
|
||||||
|
#endif /* not __GNU_LIBRARY__ */
|
||||||
|
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
extern int getopt_long_only (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
|
||||||
|
/* Internal only. Users should not call this directly. */
|
||||||
|
extern int _getopt_internal (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind,
|
||||||
|
int long_only);
|
||||||
|
#else /* not __STDC__ */
|
||||||
|
extern int getopt ();
|
||||||
|
extern int getopt_long ();
|
||||||
|
extern int getopt_long_only ();
|
||||||
|
|
||||||
|
extern int _getopt_internal ();
|
||||||
|
#endif /* not __STDC__ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _GETOPT_H */
|
178
src/headers.c
Normal file
178
src/headers.c
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/* Generic support for headers.
|
||||||
|
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "connect.h"
|
||||||
|
#include "rbuf.h"
|
||||||
|
#include "headers.h"
|
||||||
|
|
||||||
|
/* This file contains the generic routines for work with headers.
|
||||||
|
Currently they are used only by HTTP in http.c, but they can be
|
||||||
|
used by anything that cares about RFC822-style headers.
|
||||||
|
|
||||||
|
Header is defined in RFC2068, as quoted below. Note that this
|
||||||
|
definition is not HTTP-specific -- it is virtually
|
||||||
|
indistinguishable from the one given in RFC822 or RFC1036.
|
||||||
|
|
||||||
|
message-header = field-name ":" [ field-value ] CRLF
|
||||||
|
|
||||||
|
field-name = token
|
||||||
|
field-value = *( field-content | LWS )
|
||||||
|
|
||||||
|
field-content = <the OCTETs making up the field-value
|
||||||
|
and consisting of either *TEXT or combinations
|
||||||
|
of token, tspecials, and quoted-string>
|
||||||
|
|
||||||
|
The public functions are header_get() and header_process(), which
|
||||||
|
see. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Get a header from read-buffer RBUF and return it in *HDR.
|
||||||
|
|
||||||
|
As defined in RFC2068 and elsewhere, a header can be folded into
|
||||||
|
multiple lines if the continuation line begins with a space or
|
||||||
|
horizontal TAB. Also, this function will accept a header ending
|
||||||
|
with just LF instead of CRLF.
|
||||||
|
|
||||||
|
The header may be of arbitrary length; the function will allocate
|
||||||
|
as much memory as necessary for it to fit. It need not contain a
|
||||||
|
`:', thus you can use it to retrieve, say, HTTP status line.
|
||||||
|
|
||||||
|
The trailing CRLF or LF are stripped from the header, and it is
|
||||||
|
zero-terminated. #### Is this well-behaved? */
|
||||||
|
int
|
||||||
|
header_get (struct rbuf *rbuf, char **hdr, enum header_get_flags flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int bufsize = 80;
|
||||||
|
|
||||||
|
*hdr = (char *)xmalloc (bufsize);
|
||||||
|
for (i = 0; 1; i++)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
/* #### Use DO_REALLOC? */
|
||||||
|
if (i > bufsize - 1)
|
||||||
|
*hdr = (char *)xrealloc (*hdr, (bufsize <<= 1));
|
||||||
|
res = RBUF_READCHAR (rbuf, *hdr + i);
|
||||||
|
if (res == 1)
|
||||||
|
{
|
||||||
|
if ((*hdr)[i] == '\n')
|
||||||
|
{
|
||||||
|
if (!((flags & HG_NO_CONTINUATIONS)
|
||||||
|
|| i == 0
|
||||||
|
|| (i == 1 && (*hdr)[0] == '\r')))
|
||||||
|
{
|
||||||
|
char next;
|
||||||
|
/* If the header is non-empty, we need to check if
|
||||||
|
it continues on to the other line. We do that by
|
||||||
|
peeking at the next character. */
|
||||||
|
res = rbuf_peek (rbuf, &next);
|
||||||
|
if (res == 0)
|
||||||
|
return HG_EOF;
|
||||||
|
else if (res == -1)
|
||||||
|
return HG_ERROR;
|
||||||
|
/* If the next character is HT or SP, just continue. */
|
||||||
|
if (next == '\t' || next == ' ')
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* The header ends. */
|
||||||
|
(*hdr)[i] = '\0';
|
||||||
|
/* Get rid of '\r'. */
|
||||||
|
if (i > 0 && (*hdr)[i - 1] == '\r')
|
||||||
|
(*hdr)[i - 1] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (res == 0)
|
||||||
|
return HG_EOF;
|
||||||
|
else
|
||||||
|
return HG_ERROR;
|
||||||
|
}
|
||||||
|
DEBUGP (("%s\n", *hdr));
|
||||||
|
return HG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether HEADER begins with NAME and, if yes, skip the `:' and
|
||||||
|
the whitespace, and call PROCFUN with the arguments of HEADER's
|
||||||
|
contents (after the `:' and space) and ARG. Otherwise, return 0. */
|
||||||
|
int
|
||||||
|
header_process (const char *header, const char *name,
|
||||||
|
int (*procfun) (const char *, void *),
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
/* Check whether HEADER matches NAME. */
|
||||||
|
while (*name && (tolower (*name) == tolower (*header)))
|
||||||
|
++name, ++header;
|
||||||
|
if (*name || *header++ != ':')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
header += skip_lws (header);
|
||||||
|
|
||||||
|
return ((*procfun) (header, arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper functions for use with header_process(). */
|
||||||
|
|
||||||
|
/* Extract a long integer from HEADER and store it to CLOSURE. If an
|
||||||
|
error is encountered, return 0, else 1. */
|
||||||
|
int
|
||||||
|
header_extract_number (const char *header, void *closure)
|
||||||
|
{
|
||||||
|
const char *p = header;
|
||||||
|
long result;
|
||||||
|
|
||||||
|
for (result = 0; ISDIGIT (*p); p++)
|
||||||
|
result = 10 * result + (*p - '0');
|
||||||
|
if (*p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*(long *)closure = result;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strdup HEADER, and place the pointer to CLOSURE. */
|
||||||
|
int
|
||||||
|
header_strdup (const char *header, void *closure)
|
||||||
|
{
|
||||||
|
*(char **)closure = xstrdup (header);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip LWS (linear white space), if present. Returns number of
|
||||||
|
characters to skip. */
|
||||||
|
int
|
||||||
|
skip_lws (const char *string)
|
||||||
|
{
|
||||||
|
const char *p = string;
|
||||||
|
|
||||||
|
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||||
|
++p;
|
||||||
|
return p - string;
|
||||||
|
}
|
35
src/headers.h
Normal file
35
src/headers.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Declarations for `headers.c'.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HG_OK, HG_ERROR, HG_EOF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum header_get_flags { HG_NONE = 0,
|
||||||
|
HG_NO_CONTINUATIONS = 0x2 };
|
||||||
|
|
||||||
|
int header_get PARAMS ((struct rbuf *, char **, enum header_get_flags));
|
||||||
|
int header_process PARAMS ((const char *, const char *,
|
||||||
|
int (*) (const char *, void *),
|
||||||
|
void *));
|
||||||
|
|
||||||
|
int header_extract_number PARAMS ((const char *, void *));
|
||||||
|
int header_strdup PARAMS ((const char *, void *));
|
||||||
|
|
||||||
|
int skip_lws PARAMS ((const char *));
|
560
src/host.c
Normal file
560
src/host.c
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
/* Dealing with host names.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
# include <winsock.h>
|
||||||
|
#else
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# include <netinet/in.h>
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
# include <netdb.h>
|
||||||
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_UTSNAME_H
|
||||||
|
# include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "host.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Host list entry */
|
||||||
|
struct host
|
||||||
|
{
|
||||||
|
/* Host's symbolical name, as encountered at the time of first
|
||||||
|
inclusion, e.g. "fly.cc.fer.hr". */
|
||||||
|
char *hostname;
|
||||||
|
/* Host's "real" name, i.e. its IP address, written out in ASCII
|
||||||
|
form of N.N.N.N, e.g. "161.53.70.130". */
|
||||||
|
char *realname;
|
||||||
|
/* More than one HOSTNAME can correspond to the same REALNAME. For
|
||||||
|
our purposes, the canonical name of the host is its HOSTNAME when
|
||||||
|
it was first encountered. This entry is said to have QUALITY. */
|
||||||
|
int quality;
|
||||||
|
/* Next entry in the list. */
|
||||||
|
struct host *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct host *hlist;
|
||||||
|
|
||||||
|
static struct host *add_hlist PARAMS ((struct host *, const char *,
|
||||||
|
const char *, int));
|
||||||
|
|
||||||
|
/* The same as gethostbyname, but supports internet addresses of the
|
||||||
|
form `N.N.N.N'. */
|
||||||
|
struct hostent *
|
||||||
|
ngethostbyname (const char *name)
|
||||||
|
{
|
||||||
|
struct hostent *hp;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
addr = (unsigned long)inet_addr (name);
|
||||||
|
if ((int)addr != -1)
|
||||||
|
hp = gethostbyaddr ((char *)&addr, sizeof (addr), AF_INET);
|
||||||
|
else
|
||||||
|
hp = gethostbyname (name);
|
||||||
|
return hp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search for HOST in the linked list L, by hostname. Return the
|
||||||
|
entry, if found, or NULL. The search is case-insensitive. */
|
||||||
|
static struct host *
|
||||||
|
search_host (struct host *l, const char *host)
|
||||||
|
{
|
||||||
|
for (; l; l = l->next)
|
||||||
|
if (strcasecmp (l->hostname, host) == 0)
|
||||||
|
return l;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like search_host, but searches by address. */
|
||||||
|
static struct host *
|
||||||
|
search_address (struct host *l, const char *address)
|
||||||
|
{
|
||||||
|
for (; l; l = l->next)
|
||||||
|
{
|
||||||
|
int cmp = strcmp (l->realname, address);
|
||||||
|
if (cmp == 0)
|
||||||
|
return l;
|
||||||
|
else if (cmp > 0)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the address of HOSTNAME, internet-style, to WHERE. First
|
||||||
|
check for it in the host list, and (if not found), use
|
||||||
|
ngethostbyname to get it.
|
||||||
|
|
||||||
|
Return 1 on successful finding of the hostname, 0 otherwise. */
|
||||||
|
int
|
||||||
|
store_hostaddress (unsigned char *where, const char *hostname)
|
||||||
|
{
|
||||||
|
struct host *t;
|
||||||
|
unsigned long addr;
|
||||||
|
struct hostent *hptr;
|
||||||
|
struct in_addr in;
|
||||||
|
char *inet_s;
|
||||||
|
|
||||||
|
/* If the address is of the form d.d.d.d, there will be no trouble
|
||||||
|
with it. */
|
||||||
|
addr = (unsigned long)inet_addr (hostname);
|
||||||
|
if ((int)addr == -1)
|
||||||
|
{
|
||||||
|
/* If it is not of that form, try to find it in the cache. */
|
||||||
|
t = search_host (hlist, hostname);
|
||||||
|
if (t)
|
||||||
|
addr = (unsigned long)inet_addr (t->realname);
|
||||||
|
}
|
||||||
|
/* If we have the numeric address, just store it. */
|
||||||
|
if ((int)addr != -1)
|
||||||
|
{
|
||||||
|
/* This works on both little and big endian architecture, as
|
||||||
|
inet_addr returns the address in the proper order. It
|
||||||
|
appears to work on 64-bit machines too. */
|
||||||
|
memcpy (where, &addr, 4);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Since all else has failed, let's try gethostbyname(). Note that
|
||||||
|
we use gethostbyname() rather than ngethostbyname(), because we
|
||||||
|
*know* the address is not numerical. */
|
||||||
|
hptr = gethostbyname (hostname);
|
||||||
|
if (!hptr)
|
||||||
|
return 0;
|
||||||
|
/* Copy the address of the host to socket description. */
|
||||||
|
memcpy (where, hptr->h_addr_list[0], hptr->h_length);
|
||||||
|
/* Now that we're here, we could as well cache the hostname for
|
||||||
|
future use, as in realhost(). First, we have to look for it by
|
||||||
|
address to know if it's already in the cache by another name. */
|
||||||
|
|
||||||
|
/* Originally, we copied to in.s_addr, but it appears to be missing
|
||||||
|
on some systems. */
|
||||||
|
memcpy (&in, *hptr->h_addr_list, sizeof (in));
|
||||||
|
STRDUP_ALLOCA (inet_s, inet_ntoa (in));
|
||||||
|
t = search_address (hlist, inet_s);
|
||||||
|
if (t) /* Found in the list, as realname. */
|
||||||
|
{
|
||||||
|
/* Set the default, 0 quality. */
|
||||||
|
hlist = add_hlist (hlist, hostname, inet_s, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Since this is really the first time this host is encountered,
|
||||||
|
set quality to 1. */
|
||||||
|
hlist = add_hlist (hlist, hostname, inet_s, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a host to the host list. The list is sorted by addresses. For
|
||||||
|
equal addresses, the entries with quality should bubble towards the
|
||||||
|
beginning of the list. */
|
||||||
|
static struct host *
|
||||||
|
add_hlist (struct host *l, const char *nhost, const char *nreal, int quality)
|
||||||
|
{
|
||||||
|
struct host *t, *old, *beg;
|
||||||
|
|
||||||
|
/* The entry goes to the beginning of the list if the list is empty
|
||||||
|
or the order requires it. */
|
||||||
|
if (!l || (strcmp (nreal, l->realname) < 0))
|
||||||
|
{
|
||||||
|
t = (struct host *)xmalloc (sizeof (struct host));
|
||||||
|
t->hostname = xstrdup (nhost);
|
||||||
|
t->realname = xstrdup (nreal);
|
||||||
|
t->quality = quality;
|
||||||
|
t->next = l;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
beg = l;
|
||||||
|
/* Second two one-before-the-last element. */
|
||||||
|
while (l->next)
|
||||||
|
{
|
||||||
|
int cmp;
|
||||||
|
old = l;
|
||||||
|
l = l->next;
|
||||||
|
cmp = strcmp (nreal, l->realname);
|
||||||
|
if (cmp >= 0)
|
||||||
|
continue;
|
||||||
|
/* If the next list element is greater than s, put s between the
|
||||||
|
current and the next list element. */
|
||||||
|
t = (struct host *)xmalloc (sizeof (struct host));
|
||||||
|
old->next = t;
|
||||||
|
t->next = l;
|
||||||
|
t->hostname = xstrdup (nhost);
|
||||||
|
t->realname = xstrdup (nreal);
|
||||||
|
t->quality = quality;
|
||||||
|
return beg;
|
||||||
|
}
|
||||||
|
t = (struct host *)xmalloc (sizeof (struct host));
|
||||||
|
t->hostname = xstrdup (nhost);
|
||||||
|
t->realname = xstrdup (nreal);
|
||||||
|
t->quality = quality;
|
||||||
|
/* Insert the new element after the last element. */
|
||||||
|
l->next = t;
|
||||||
|
t->next = NULL;
|
||||||
|
return beg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the "real" name of HOST, as perceived by Wget. If HOST
|
||||||
|
is referenced by more than one name, "real" name is considered to
|
||||||
|
be the first one encountered in the past.
|
||||||
|
|
||||||
|
If the host cannot be found in the list of already dealt-with
|
||||||
|
hosts, try with its INET address. If this fails too, add it to the
|
||||||
|
list. The routine does not call gethostbyname twice for the same
|
||||||
|
host if it can possibly avoid it. */
|
||||||
|
char *
|
||||||
|
realhost (const char *host)
|
||||||
|
{
|
||||||
|
struct host *l;
|
||||||
|
struct in_addr in;
|
||||||
|
struct hostent *hptr;
|
||||||
|
char *inet_s;
|
||||||
|
|
||||||
|
DEBUGP (("Checking for %s.\n", host));
|
||||||
|
/* Look for the host, looking by the host name. */
|
||||||
|
l = search_host (hlist, host);
|
||||||
|
if (l && l->quality) /* Found it with quality */
|
||||||
|
{
|
||||||
|
DEBUGP (("%s was already used, by that name.\n", host));
|
||||||
|
/* Here we return l->hostname, not host, because of the possible
|
||||||
|
case differences (e.g. jaGOR.srce.hr and jagor.srce.hr are
|
||||||
|
the same, but we want the one that was first. */
|
||||||
|
return xstrdup (l->hostname);
|
||||||
|
}
|
||||||
|
else if (!l) /* Not found, with or without quality */
|
||||||
|
{
|
||||||
|
/* The fact that gethostbyname will get called makes it
|
||||||
|
necessary to store it to the list, to ensure that
|
||||||
|
gethostbyname will not be called twice for the same string.
|
||||||
|
However, the quality argument must be set appropriately.
|
||||||
|
|
||||||
|
Note that add_hlist must be called *after* the realname
|
||||||
|
search, or the quality would be always set to 0 */
|
||||||
|
DEBUGP (("This is the first time I hear about host %s by that name.\n",
|
||||||
|
host));
|
||||||
|
hptr = ngethostbyname (host);
|
||||||
|
if (!hptr)
|
||||||
|
return xstrdup (host);
|
||||||
|
/* Originally, we copied to in.s_addr, but it appears to be
|
||||||
|
missing on some systems. */
|
||||||
|
memcpy (&in, *hptr->h_addr_list, sizeof (in));
|
||||||
|
STRDUP_ALLOCA (inet_s, inet_ntoa (in));
|
||||||
|
}
|
||||||
|
else /* Found, without quality */
|
||||||
|
{
|
||||||
|
/* This case happens when host is on the list,
|
||||||
|
but not as first entry (the one with quality).
|
||||||
|
Then we just get its INET address and pick
|
||||||
|
up the first entry with quality. */
|
||||||
|
DEBUGP (("We've dealt with host %s, but under the name %s.\n",
|
||||||
|
host, l->realname));
|
||||||
|
STRDUP_ALLOCA (inet_s, l->realname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we certainly have the INET address. The following loop is
|
||||||
|
guaranteed to pick either an entry with quality (because it is
|
||||||
|
the first one), or none at all. */
|
||||||
|
l = search_address (hlist, inet_s);
|
||||||
|
if (l) /* Found in the list, as realname. */
|
||||||
|
{
|
||||||
|
/* Set the default, 0 quality. */
|
||||||
|
hlist = add_hlist (hlist, host, inet_s, 0);
|
||||||
|
return xstrdup (l->hostname);
|
||||||
|
}
|
||||||
|
/* Since this is really the first time this host is encountered,
|
||||||
|
set quality to 1. */
|
||||||
|
hlist = add_hlist (hlist, host, inet_s, 1);
|
||||||
|
return xstrdup (host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare two hostnames (out of URL-s if the arguments are URL-s),
|
||||||
|
taking care of aliases. It uses realhost() to determine a unique
|
||||||
|
hostname for each of two hosts. If simple_check is non-zero, only
|
||||||
|
strcmp() is used for comparison. */
|
||||||
|
int
|
||||||
|
same_host (const char *u1, const char *u2)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
char *p1, *p2;
|
||||||
|
char *real1, *real2;
|
||||||
|
|
||||||
|
/* Skip protocol, if present. */
|
||||||
|
u1 += skip_url (u1);
|
||||||
|
u2 += skip_url (u2);
|
||||||
|
u1 += skip_proto (u1);
|
||||||
|
u2 += skip_proto (u2);
|
||||||
|
|
||||||
|
/* Skip username ans password, if present. */
|
||||||
|
u1 += skip_uname (u1);
|
||||||
|
u2 += skip_uname (u2);
|
||||||
|
|
||||||
|
for (s = u1; *u1 && *u1 != '/' && *u1 != ':'; u1++);
|
||||||
|
p1 = strdupdelim (s, u1);
|
||||||
|
for (s = u2; *u2 && *u2 != '/' && *u2 != ':'; u2++);
|
||||||
|
p2 = strdupdelim (s, u2);
|
||||||
|
DEBUGP (("Comparing hosts %s and %s...\n", p1, p2));
|
||||||
|
if (strcasecmp (p1, p2) == 0)
|
||||||
|
{
|
||||||
|
free (p1);
|
||||||
|
free (p2);
|
||||||
|
DEBUGP (("They are quite alike.\n"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (opt.simple_check)
|
||||||
|
{
|
||||||
|
free (p1);
|
||||||
|
free (p2);
|
||||||
|
DEBUGP (("Since checking is simple, I'd say they are not the same.\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
real1 = realhost (p1);
|
||||||
|
real2 = realhost (p2);
|
||||||
|
free (p1);
|
||||||
|
free (p2);
|
||||||
|
if (strcasecmp (real1, real2) == 0)
|
||||||
|
{
|
||||||
|
DEBUGP (("They are alike, after realhost()->%s.\n", real1));
|
||||||
|
free (real1);
|
||||||
|
free (real2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUGP (("They are not the same (%s, %s).\n", real1, real2));
|
||||||
|
free (real1);
|
||||||
|
free (real2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine whether a URL is acceptable to be followed, according to
|
||||||
|
a list of domains to accept. */
|
||||||
|
int
|
||||||
|
accept_domain (struct urlinfo *u)
|
||||||
|
{
|
||||||
|
assert (u->host != NULL);
|
||||||
|
if (opt.domains)
|
||||||
|
{
|
||||||
|
if (!sufmatch ((const char **)opt.domains, u->host))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (opt.exclude_domains)
|
||||||
|
{
|
||||||
|
if (sufmatch ((const char **)opt.exclude_domains, u->host))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether WHAT is matched in LIST, each element of LIST being a
|
||||||
|
pattern to match WHAT against, using backward matching (see
|
||||||
|
match_backwards() in utils.c).
|
||||||
|
|
||||||
|
If an element of LIST matched, 1 is returned, 0 otherwise. */
|
||||||
|
int
|
||||||
|
sufmatch (const char **list, const char *what)
|
||||||
|
{
|
||||||
|
int i, j, k, lw;
|
||||||
|
|
||||||
|
lw = strlen (what);
|
||||||
|
for (i = 0; list[i]; i++)
|
||||||
|
{
|
||||||
|
for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--)
|
||||||
|
if (tolower (list[i][j]) != tolower (what[k]))
|
||||||
|
break;
|
||||||
|
/* The domain must be first to reach to beginning. */
|
||||||
|
if (j == -1)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return email address of the form username@FQDN suitable for
|
||||||
|
anonymous FTP passwords. This process is error-prone, and the
|
||||||
|
escape hatch is the MY_HOST preprocessor constant, which can be
|
||||||
|
used to hard-code either your hostname or FQDN at compile-time.
|
||||||
|
|
||||||
|
If the FQDN cannot be determined, a warning is printed, and the
|
||||||
|
function returns a short `username@' form, accepted by most
|
||||||
|
anonymous servers.
|
||||||
|
|
||||||
|
If not even the username cannot be divined, it means things are
|
||||||
|
seriously fucked up, and Wget exits. */
|
||||||
|
char *
|
||||||
|
ftp_getaddress (void)
|
||||||
|
{
|
||||||
|
static char *address;
|
||||||
|
|
||||||
|
/* Do the drill only the first time, as it won't change. */
|
||||||
|
if (!address)
|
||||||
|
{
|
||||||
|
char userid[32]; /* 9 should be enough for Unix, but
|
||||||
|
I'd rather be on the safe side. */
|
||||||
|
char *host, *fqdn;
|
||||||
|
|
||||||
|
if (!pwd_cuserid (userid))
|
||||||
|
{
|
||||||
|
logprintf (LOG_ALWAYS, _("%s: Cannot determine user-id.\n"),
|
||||||
|
exec_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
#ifdef MY_HOST
|
||||||
|
STRDUP_ALLOCA (host, MY_HOST);
|
||||||
|
#else /* not MY_HOST */
|
||||||
|
#ifdef HAVE_UNAME
|
||||||
|
{
|
||||||
|
struct utsname ubuf;
|
||||||
|
if (uname (&ubuf) < 0)
|
||||||
|
{
|
||||||
|
logprintf (LOG_ALWAYS, _("%s: Warning: uname failed: %s\n"),
|
||||||
|
exec_name, strerror (errno));
|
||||||
|
fqdn = "";
|
||||||
|
goto giveup;
|
||||||
|
}
|
||||||
|
STRDUP_ALLOCA (host, ubuf.nodename);
|
||||||
|
}
|
||||||
|
#else /* not HAVE_UNAME */
|
||||||
|
#ifdef HAVE_GETHOSTNAME
|
||||||
|
host = alloca (256);
|
||||||
|
if (gethostname (host, 256) < 0)
|
||||||
|
{
|
||||||
|
logprintf (LOG_ALWAYS, _("%s: Warning: gethostname failed\n"),
|
||||||
|
exec_name);
|
||||||
|
fqdn = "";
|
||||||
|
goto giveup;
|
||||||
|
}
|
||||||
|
#else /* not HAVE_GETHOSTNAME */
|
||||||
|
#error Cannot determine host name.
|
||||||
|
#endif /* not HAVE_GETHOSTNAME */
|
||||||
|
#endif /* not HAVE_UNAME */
|
||||||
|
#endif /* not MY_HOST */
|
||||||
|
/* If the address we got so far contains a period, don't bother
|
||||||
|
anymore. */
|
||||||
|
if (strchr (host, '.'))
|
||||||
|
fqdn = host;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* #### I've seen the following scheme fail on at least one
|
||||||
|
system! Do we care? */
|
||||||
|
char *tmpstore;
|
||||||
|
/* According to Richard Stevens, the correct way to find the
|
||||||
|
FQDN is to (1) find the host name, (2) find its IP
|
||||||
|
address using gethostbyname(), and (3) get the FQDN using
|
||||||
|
gethostbyaddr(). So that's what we'll do. Step one has
|
||||||
|
been done above. */
|
||||||
|
/* (2) */
|
||||||
|
struct hostent *hp = gethostbyname (host);
|
||||||
|
if (!hp || !hp->h_addr_list)
|
||||||
|
{
|
||||||
|
logprintf (LOG_ALWAYS, _("\
|
||||||
|
%s: Warning: cannot determine local IP address.\n"),
|
||||||
|
exec_name);
|
||||||
|
fqdn = "";
|
||||||
|
goto giveup;
|
||||||
|
}
|
||||||
|
/* Copy the argument, so the call to gethostbyaddr doesn't
|
||||||
|
clobber it -- just in case. */
|
||||||
|
tmpstore = (char *)alloca (hp->h_length);
|
||||||
|
memcpy (tmpstore, *hp->h_addr_list, hp->h_length);
|
||||||
|
/* (3) */
|
||||||
|
hp = gethostbyaddr (tmpstore, hp->h_length, hp->h_addrtype);
|
||||||
|
if (!hp || !hp->h_name)
|
||||||
|
{
|
||||||
|
logprintf (LOG_ALWAYS, _("\
|
||||||
|
%s: Warning: cannot reverse-lookup local IP address.\n"),
|
||||||
|
exec_name);
|
||||||
|
fqdn = "";
|
||||||
|
goto giveup;
|
||||||
|
}
|
||||||
|
if (!strchr (hp->h_name, '.'))
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
/* This gets ticked pretty often. Karl Berry reports
|
||||||
|
that there can be valid reasons for the local host
|
||||||
|
name not to be an FQDN, so I've decided to remove the
|
||||||
|
annoying warning. */
|
||||||
|
logprintf (LOG_ALWAYS, _("\
|
||||||
|
%s: Warning: reverse-lookup of local address did not yield FQDN!\n"),
|
||||||
|
exec_name);
|
||||||
|
#endif
|
||||||
|
fqdn = "";
|
||||||
|
goto giveup;
|
||||||
|
}
|
||||||
|
/* Once we're here, hp->h_name contains the correct FQDN. */
|
||||||
|
STRDUP_ALLOCA (fqdn, hp->h_name);
|
||||||
|
}
|
||||||
|
giveup:
|
||||||
|
address = (char *)xmalloc (strlen (userid) + 1 + strlen (fqdn) + 1);
|
||||||
|
sprintf (address, "%s@%s", userid, fqdn);
|
||||||
|
}
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print error messages for host errors. */
|
||||||
|
char *
|
||||||
|
herrmsg (int error)
|
||||||
|
{
|
||||||
|
/* Can't use switch since some constants are equal (at least on my
|
||||||
|
system), and the compiler signals "duplicate case value". */
|
||||||
|
if (error == HOST_NOT_FOUND
|
||||||
|
|| error == NO_RECOVERY
|
||||||
|
|| error == NO_DATA
|
||||||
|
|| error == NO_ADDRESS
|
||||||
|
|| error == TRY_AGAIN)
|
||||||
|
return _("Host not found");
|
||||||
|
else
|
||||||
|
return _("Unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean the host list. This is a separate function, so we needn't
|
||||||
|
export HLIST and its implementation. Ha! */
|
||||||
|
void
|
||||||
|
clean_hosts (void)
|
||||||
|
{
|
||||||
|
struct host *l = hlist;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
struct host *p = l->next;
|
||||||
|
free (l->hostname);
|
||||||
|
free (l->realname);
|
||||||
|
free (l);
|
||||||
|
l = p;
|
||||||
|
}
|
||||||
|
hlist = NULL;
|
||||||
|
}
|
41
src/host.h
Normal file
41
src/host.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* Declarations for host.c
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef HOST_H
|
||||||
|
#define HOST_H
|
||||||
|
|
||||||
|
struct urlinfo;
|
||||||
|
|
||||||
|
/* Function declarations */
|
||||||
|
|
||||||
|
struct hostent *ngethostbyname PARAMS ((const char *));
|
||||||
|
int store_hostaddress PARAMS ((unsigned char *, const char *));
|
||||||
|
|
||||||
|
void clean_hosts PARAMS ((void));
|
||||||
|
|
||||||
|
char *realhost PARAMS ((const char *));
|
||||||
|
int same_host PARAMS ((const char *, const char *));
|
||||||
|
int accept_domain PARAMS ((struct urlinfo *));
|
||||||
|
int sufmatch PARAMS ((const char **, const char *));
|
||||||
|
|
||||||
|
char *ftp_getaddress PARAMS ((void));
|
||||||
|
|
||||||
|
char *herrmsg PARAMS ((int));
|
||||||
|
|
||||||
|
#endif /* HOST_H */
|
508
src/html.c
Normal file
508
src/html.c
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
/* A simple HTML parser.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "url.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "ftp.h"
|
||||||
|
#include "html.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static state_t global_state;
|
||||||
|
|
||||||
|
struct tag_attr {
|
||||||
|
char *tag;
|
||||||
|
char *attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Match a string against a null-terminated list of identifiers. */
|
||||||
|
static int
|
||||||
|
idmatch (struct tag_attr *tags, const char *tag, const char *attr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!tag || !attr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; tags[i].tag; i++)
|
||||||
|
if (!strcasecmp (tags[i].tag, tag) && !strcasecmp (tags[i].attr, attr))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse BUF (a buffer of BUFSIZE characters) searching for HTML tags
|
||||||
|
describing URLs to follow. When a tag is encountered, extract its
|
||||||
|
components (as described by html_allow[] array), and return the
|
||||||
|
address and the length of the string. Return NULL if no URL is
|
||||||
|
found. */
|
||||||
|
const char *
|
||||||
|
htmlfindurl (const char *buf, int bufsize, int *size, int init)
|
||||||
|
{
|
||||||
|
const char *p, *ph;
|
||||||
|
state_t *s;
|
||||||
|
/* NULL-terminated list of tags and modifiers someone would want to
|
||||||
|
follow -- feel free to edit to suit your needs: */
|
||||||
|
static struct tag_attr html_allow[] = {
|
||||||
|
{ "a", "href" },
|
||||||
|
{ "img", "src" },
|
||||||
|
{ "img", "href" },
|
||||||
|
{ "body", "background" },
|
||||||
|
{ "frame", "src" },
|
||||||
|
{ "iframe", "src" },
|
||||||
|
{ "fig", "src" },
|
||||||
|
{ "overlay", "src" },
|
||||||
|
{ "applet", "code" },
|
||||||
|
{ "script", "src" },
|
||||||
|
{ "embed", "src" },
|
||||||
|
{ "bgsound", "src" },
|
||||||
|
{ "area", "href" },
|
||||||
|
{ "img", "lowsrc" },
|
||||||
|
{ "input", "src" },
|
||||||
|
{ "layer", "src" },
|
||||||
|
{ "table", "background"},
|
||||||
|
{ "th", "background"},
|
||||||
|
{ "td", "background"},
|
||||||
|
/* Tags below this line are treated specially. */
|
||||||
|
{ "base", "href" },
|
||||||
|
{ "meta", "content" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
s = &global_state;
|
||||||
|
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
DEBUGP (("Resetting a parser state.\n"));
|
||||||
|
memset (s, 0, sizeof (*s));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
/* Let's look for a tag, if we are not already in one. */
|
||||||
|
if (!s->at_value)
|
||||||
|
{
|
||||||
|
/* Find '<'. */
|
||||||
|
if (*buf != '<')
|
||||||
|
for (; bufsize && *buf != '<'; ++buf, --bufsize);
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
/* Skip spaces. */
|
||||||
|
for (++buf, --bufsize; bufsize && ISSPACE (*buf) && *buf != '>';
|
||||||
|
++buf, --bufsize);
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
p = buf;
|
||||||
|
/* Find the tag end. */
|
||||||
|
for (; bufsize && !ISSPACE (*buf) && *buf != '>' && *buf != '=';
|
||||||
|
++buf, --bufsize);
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
if (*buf == '=')
|
||||||
|
{
|
||||||
|
/* <tag=something> is illegal. Just skip it. */
|
||||||
|
++buf, --bufsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (p == buf)
|
||||||
|
{
|
||||||
|
/* *buf == '>'. */
|
||||||
|
++buf, --bufsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s->tag = strdupdelim (p, buf);
|
||||||
|
if (*buf == '>')
|
||||||
|
{
|
||||||
|
free (s->tag);
|
||||||
|
s->tag = NULL;
|
||||||
|
++buf, --bufsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* s->at_value */
|
||||||
|
{
|
||||||
|
/* Reset AT_VALUE. */
|
||||||
|
s->at_value = 0;
|
||||||
|
/* If in quotes, just skip out of them and continue living. */
|
||||||
|
if (s->in_quote)
|
||||||
|
{
|
||||||
|
s->in_quote = 0;
|
||||||
|
for (; bufsize && *buf != s->quote_char; ++buf, --bufsize);
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
++buf, --bufsize;
|
||||||
|
}
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
if (*buf == '>')
|
||||||
|
{
|
||||||
|
FREE_MAYBE (s->tag);
|
||||||
|
FREE_MAYBE (s->attr);
|
||||||
|
s->tag = s->attr = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Find the attributes. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
FREE_MAYBE (s->attr);
|
||||||
|
s->attr = NULL;
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
/* Skip the spaces if we have them. We don't have them at
|
||||||
|
places like <img alt="something"src="something-else">.
|
||||||
|
^ no spaces here */
|
||||||
|
if (ISSPACE (*buf))
|
||||||
|
for (++buf, --bufsize; bufsize && ISSPACE (*buf) && *buf != '>';
|
||||||
|
++buf, --bufsize);
|
||||||
|
if (!bufsize || *buf == '>')
|
||||||
|
break;
|
||||||
|
if (*buf == '=')
|
||||||
|
{
|
||||||
|
/* This is the case of <tag = something>, which is
|
||||||
|
illegal. Just skip it. */
|
||||||
|
++buf, --bufsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p = buf;
|
||||||
|
/* Find the attribute end. */
|
||||||
|
for (; bufsize && !ISSPACE (*buf) && *buf != '>' && *buf != '=';
|
||||||
|
++buf, --bufsize);
|
||||||
|
if (!bufsize || *buf == '>')
|
||||||
|
break;
|
||||||
|
/* Construct the attribute. */
|
||||||
|
s->attr = strdupdelim (p, buf);
|
||||||
|
/* Now we must skip the spaces to find '='. */
|
||||||
|
if (*buf != '=')
|
||||||
|
{
|
||||||
|
for (; bufsize && ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize);
|
||||||
|
if (!bufsize || *buf == '>')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If we still don't have '=', something is amiss. */
|
||||||
|
if (*buf != '=')
|
||||||
|
continue;
|
||||||
|
/* Find the beginning of attribute value by skipping the
|
||||||
|
spaces. */
|
||||||
|
++buf, --bufsize;
|
||||||
|
for (; bufsize && ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize);
|
||||||
|
if (!bufsize || *buf == '>')
|
||||||
|
break;
|
||||||
|
ph = NULL;
|
||||||
|
/* The value of an attribute can, but does not have to be
|
||||||
|
quoted. */
|
||||||
|
if (*buf == '\"' || *buf == '\'')
|
||||||
|
{
|
||||||
|
s->in_quote = 1;
|
||||||
|
s->quote_char = *buf;
|
||||||
|
p = buf + 1;
|
||||||
|
for (++buf, --bufsize;
|
||||||
|
bufsize && *buf != s->quote_char && *buf != '\n';
|
||||||
|
++buf, --bufsize)
|
||||||
|
if (*buf == '#')
|
||||||
|
ph = buf;
|
||||||
|
if (!bufsize)
|
||||||
|
{
|
||||||
|
s->in_quote = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*buf == '\n')
|
||||||
|
{
|
||||||
|
/* #### Is the following logic good?
|
||||||
|
|
||||||
|
Obviously no longer in quote. It might be well
|
||||||
|
to check whether '>' was encountered, but that
|
||||||
|
would be encouraging writers of invalid HTMLs,
|
||||||
|
and we don't want that, now do we? */
|
||||||
|
s->in_quote = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = buf;
|
||||||
|
for (; bufsize && !ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize)
|
||||||
|
if (*buf == '#')
|
||||||
|
ph = buf;
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If '#' was found unprotected in a URI, it is probably an
|
||||||
|
HTML marker, or color spec. */
|
||||||
|
*size = (ph ? ph : buf) - p;
|
||||||
|
/* The URI is liable to be returned if:
|
||||||
|
1) *size != 0;
|
||||||
|
2) its tag and attribute are found in html_allow. */
|
||||||
|
if (*size && idmatch (html_allow, s->tag, s->attr))
|
||||||
|
{
|
||||||
|
if (!strcasecmp (s->tag, "base") && !strcasecmp (s->attr, "href"))
|
||||||
|
{
|
||||||
|
FREE_MAYBE (s->base);
|
||||||
|
s->base = strdupdelim (p, buf);
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (s->tag, "meta") && !strcasecmp (s->attr, "content"))
|
||||||
|
{
|
||||||
|
/* Some pages use a META tag to specify that the page
|
||||||
|
be refreshed by a new page after a given number of
|
||||||
|
seconds. We need to attempt to extract an URL for
|
||||||
|
the new page from the other garbage present. The
|
||||||
|
general format for this is:
|
||||||
|
<META HTTP-EQUIV=Refresh CONTENT="0; URL=index2.html">
|
||||||
|
|
||||||
|
So we just need to skip past the "0; URL="
|
||||||
|
garbage to get to the URL. META tags are also
|
||||||
|
used for specifying random things like the page
|
||||||
|
author's name and what editor was used to create
|
||||||
|
it. So we need to be careful to ignore them and
|
||||||
|
not assume that an URL will be present at all. */
|
||||||
|
for (; *size && ISDIGIT (*p); p++, *size -= 1);
|
||||||
|
if (*p == ';')
|
||||||
|
{
|
||||||
|
for (p++, *size -= 1; *size && ISSPACE (*p); p++, *size -= 1) ;
|
||||||
|
if (!strncasecmp (p, "URL=", 4))
|
||||||
|
{
|
||||||
|
p += 4, *size -= 4;
|
||||||
|
s->at_value = 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->at_value = 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Exit from quote. */
|
||||||
|
if (*buf == s->quote_char)
|
||||||
|
{
|
||||||
|
s->in_quote = 0;
|
||||||
|
++buf, --bufsize;
|
||||||
|
}
|
||||||
|
} while (*buf != '>');
|
||||||
|
FREE_MAYBE (s->tag);
|
||||||
|
FREE_MAYBE (s->attr);
|
||||||
|
s->tag = s->attr = NULL;
|
||||||
|
if (!bufsize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_MAYBE (s->tag);
|
||||||
|
FREE_MAYBE (s->attr);
|
||||||
|
FREE_MAYBE (s->base);
|
||||||
|
memset (s, 0, sizeof (*s)); /* just to be sure */
|
||||||
|
DEBUGP (("HTML parser ends here (state destroyed).\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function returns the base reference of HTML buffer id, or NULL
|
||||||
|
if one wasn't defined for that buffer. */
|
||||||
|
const char *
|
||||||
|
html_base (void)
|
||||||
|
{
|
||||||
|
return global_state.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function returns the pointer to the malloc-ed quoted version of
|
||||||
|
string s. It will recognize and quote numeric and special graphic
|
||||||
|
entities, as per RFC1866:
|
||||||
|
|
||||||
|
`&' -> `&'
|
||||||
|
`<' -> `<'
|
||||||
|
`>' -> `>'
|
||||||
|
`"' -> `"'
|
||||||
|
|
||||||
|
No other entities are recognized or replaced. */
|
||||||
|
static char *
|
||||||
|
html_quote_string (const char *s)
|
||||||
|
{
|
||||||
|
const char *b = s;
|
||||||
|
char *p, *res;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Pass through the string, and count the new size. */
|
||||||
|
for (i = 0; *s; s++, i++)
|
||||||
|
{
|
||||||
|
if (*s == '&')
|
||||||
|
i += 4; /* `amp;' */
|
||||||
|
else if (*s == '<' || *s == '>')
|
||||||
|
i += 3; /* `lt;' and `gt;' */
|
||||||
|
else if (*s == '\"')
|
||||||
|
i += 5; /* `quot;' */
|
||||||
|
}
|
||||||
|
res = (char *)xmalloc (i + 1);
|
||||||
|
s = b;
|
||||||
|
for (p = res; *s; s++)
|
||||||
|
{
|
||||||
|
switch (*s)
|
||||||
|
{
|
||||||
|
case '&':
|
||||||
|
*p++ = '&';
|
||||||
|
*p++ = 'a';
|
||||||
|
*p++ = 'm';
|
||||||
|
*p++ = 'p';
|
||||||
|
*p++ = ';';
|
||||||
|
break;
|
||||||
|
case '<': case '>':
|
||||||
|
*p++ = '&';
|
||||||
|
*p++ = (*s == '<' ? 'l' : 'g');
|
||||||
|
*p++ = 't';
|
||||||
|
*p++ = ';';
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
*p++ = '&';
|
||||||
|
*p++ = 'q';
|
||||||
|
*p++ = 'u';
|
||||||
|
*p++ = 'o';
|
||||||
|
*p++ = 't';
|
||||||
|
*p++ = ';';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*p++ = *s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function creates an HTML index containing references to given
|
||||||
|
directories and files on the appropriate host. The references are
|
||||||
|
FTP. */
|
||||||
|
uerr_t
|
||||||
|
ftp_index (const char *file, struct urlinfo *u, struct fileinfo *f)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *upwd;
|
||||||
|
char *htclfile; /* HTML-clean file name */
|
||||||
|
|
||||||
|
if (!opt.dfp)
|
||||||
|
{
|
||||||
|
fp = fopen (file, "wb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
|
||||||
|
return FOPENERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fp = opt.dfp;
|
||||||
|
if (u->user)
|
||||||
|
{
|
||||||
|
char *tmpu, *tmpp; /* temporary, clean user and passwd */
|
||||||
|
|
||||||
|
tmpu = CLEANDUP (u->user);
|
||||||
|
tmpp = u->passwd ? CLEANDUP (u->passwd) : NULL;
|
||||||
|
upwd = (char *)xmalloc (strlen (tmpu)
|
||||||
|
+ (tmpp ? (1 + strlen (tmpp)) : 0) + 2);
|
||||||
|
sprintf (upwd, "%s%s%s@", tmpu, tmpp ? ":" : "", tmpp ? tmpp : "");
|
||||||
|
free (tmpu);
|
||||||
|
FREE_MAYBE (tmpp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
upwd = xstrdup ("");
|
||||||
|
fprintf (fp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
|
||||||
|
fprintf (fp, "<html>\n<head>\n<title>");
|
||||||
|
fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
|
||||||
|
fprintf (fp, "</title>\n</head>\n<body>\n<h1>");
|
||||||
|
fprintf (fp, _("Index of /%s on %s:%d"), u->dir, u->host, u->port);
|
||||||
|
fprintf (fp, "</h1>\n<hr>\n<pre>\n");
|
||||||
|
while (f)
|
||||||
|
{
|
||||||
|
fprintf (fp, " ");
|
||||||
|
if (f->tstamp != -1)
|
||||||
|
{
|
||||||
|
/* #### Should we translate the months? */
|
||||||
|
static char *months[] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
struct tm *ptm = localtime ((time_t *)&f->tstamp);
|
||||||
|
|
||||||
|
fprintf (fp, "%d %s %02d ", ptm->tm_year + 1900, months[ptm->tm_mon],
|
||||||
|
ptm->tm_mday);
|
||||||
|
if (ptm->tm_hour)
|
||||||
|
fprintf (fp, "%02d:%02d ", ptm->tm_hour, ptm->tm_min);
|
||||||
|
else
|
||||||
|
fprintf (fp, " ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (fp, _("time unknown "));
|
||||||
|
switch (f->type)
|
||||||
|
{
|
||||||
|
case FT_PLAINFILE:
|
||||||
|
fprintf (fp, _("File "));
|
||||||
|
break;
|
||||||
|
case FT_DIRECTORY:
|
||||||
|
fprintf (fp, _("Directory "));
|
||||||
|
break;
|
||||||
|
case FT_SYMLINK:
|
||||||
|
fprintf (fp, _("Link "));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf (fp, _("Not sure "));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
htclfile = html_quote_string (f->name);
|
||||||
|
fprintf (fp, "<a href=\"ftp://%s%s:%hu", upwd, u->host, u->port);
|
||||||
|
if (*u->dir != '/')
|
||||||
|
putc ('/', fp);
|
||||||
|
fprintf (fp, "%s", u->dir);
|
||||||
|
if (*u->dir)
|
||||||
|
putc ('/', fp);
|
||||||
|
fprintf (fp, "%s", htclfile);
|
||||||
|
if (f->type == FT_DIRECTORY)
|
||||||
|
putc ('/', fp);
|
||||||
|
fprintf (fp, "\">%s", htclfile);
|
||||||
|
if (f->type == FT_DIRECTORY)
|
||||||
|
putc ('/', fp);
|
||||||
|
fprintf (fp, "</a> ");
|
||||||
|
if (f->type == FT_PLAINFILE)
|
||||||
|
fprintf (fp, _(" (%s bytes)"), legible (f->size));
|
||||||
|
else if (f->type == FT_SYMLINK)
|
||||||
|
fprintf (fp, "-> %s", f->linkto ? f->linkto : "(nil)");
|
||||||
|
putc ('\n', fp);
|
||||||
|
free (htclfile);
|
||||||
|
f = f->next;
|
||||||
|
}
|
||||||
|
fprintf (fp, "</pre>\n</body>\n</html>\n");
|
||||||
|
free (upwd);
|
||||||
|
if (!opt.dfp)
|
||||||
|
fclose (fp);
|
||||||
|
else
|
||||||
|
fflush (fp);
|
||||||
|
return FTPOK;
|
||||||
|
}
|
39
src/html.h
Normal file
39
src/html.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* HTML parser declarations.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef HTML_H
|
||||||
|
#define HTML_H
|
||||||
|
|
||||||
|
/* Structure of a parser state */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int at_value, in_quote;
|
||||||
|
char quote_char;
|
||||||
|
char *tag, *attr;
|
||||||
|
char *base;
|
||||||
|
} state_t;
|
||||||
|
|
||||||
|
struct fileinfo;
|
||||||
|
|
||||||
|
/* Function declarations */
|
||||||
|
const char *htmlfindurl PARAMS ((const char *, int, int *, int));
|
||||||
|
const char *html_base PARAMS ((void));
|
||||||
|
uerr_t ftp_index PARAMS ((const char *, struct urlinfo *, struct fileinfo *));
|
||||||
|
|
||||||
|
#endif /* HTML_H */
|
1589
src/http.c
Normal file
1589
src/http.c
Normal file
File diff suppressed because it is too large
Load Diff
928
src/init.c
Normal file
928
src/init.c
Normal file
@ -0,0 +1,928 @@
|
|||||||
|
/* Reading/parsing the initialization file.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "host.h"
|
||||||
|
#include "recur.h"
|
||||||
|
#include "netrc.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define CMD_DECLARE(func) static int func \
|
||||||
|
PARAMS ((const char *, const char *, void *))
|
||||||
|
|
||||||
|
CMD_DECLARE (cmd_boolean);
|
||||||
|
CMD_DECLARE (cmd_boolean);
|
||||||
|
CMD_DECLARE (cmd_number);
|
||||||
|
CMD_DECLARE (cmd_number_inf);
|
||||||
|
CMD_DECLARE (cmd_string);
|
||||||
|
CMD_DECLARE (cmd_vector);
|
||||||
|
CMD_DECLARE (cmd_directory_vector);
|
||||||
|
CMD_DECLARE (cmd_bytes);
|
||||||
|
CMD_DECLARE (cmd_time);
|
||||||
|
|
||||||
|
CMD_DECLARE (cmd_spec_dirstruct);
|
||||||
|
CMD_DECLARE (cmd_spec_dotstyle);
|
||||||
|
CMD_DECLARE (cmd_spec_header);
|
||||||
|
CMD_DECLARE (cmd_spec_htmlify);
|
||||||
|
CMD_DECLARE (cmd_spec_mirror);
|
||||||
|
CMD_DECLARE (cmd_spec_outputdocument);
|
||||||
|
CMD_DECLARE (cmd_spec_recursive);
|
||||||
|
CMD_DECLARE (cmd_spec_useragent);
|
||||||
|
|
||||||
|
/* List of recognized commands, each consisting of name, closure and
|
||||||
|
function. When adding a new command, simply add it to the list,
|
||||||
|
but be sure to keep the list sorted alphabetically, as comind()
|
||||||
|
depends on it. */
|
||||||
|
static struct {
|
||||||
|
char *name;
|
||||||
|
void *closure;
|
||||||
|
int (*action) PARAMS ((const char *, const char *, void *));
|
||||||
|
} commands[] = {
|
||||||
|
{ "accept", &opt.accepts, cmd_vector },
|
||||||
|
{ "addhostdir", &opt.add_hostdir, cmd_boolean },
|
||||||
|
{ "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */
|
||||||
|
{ "background", &opt.background, cmd_boolean },
|
||||||
|
{ "backups", &opt.backups, cmd_number },
|
||||||
|
{ "base", &opt.base_href, cmd_string },
|
||||||
|
{ "cache", &opt.proxy_cache, cmd_boolean },
|
||||||
|
{ "continue", &opt.always_rest, cmd_boolean },
|
||||||
|
{ "convertlinks", &opt.convert_links, cmd_boolean },
|
||||||
|
{ "cutdirs", &opt.cut_dirs, cmd_number },
|
||||||
|
#ifdef DEBUG
|
||||||
|
{ "debug", &opt.debug, cmd_boolean },
|
||||||
|
#endif
|
||||||
|
{ "deleteafter", &opt.delete_after, cmd_boolean },
|
||||||
|
{ "dirprefix", &opt.dir_prefix, cmd_string },
|
||||||
|
{ "dirstruct", NULL, cmd_spec_dirstruct },
|
||||||
|
{ "domains", &opt.domains, cmd_vector },
|
||||||
|
{ "dotbytes", &opt.dot_bytes, cmd_bytes },
|
||||||
|
{ "dotsinline", &opt.dots_in_line, cmd_number },
|
||||||
|
{ "dotspacing", &opt.dot_spacing, cmd_number },
|
||||||
|
{ "dotstyle", NULL, cmd_spec_dotstyle },
|
||||||
|
{ "excludedirectories", &opt.excludes, cmd_directory_vector },
|
||||||
|
{ "excludedomains", &opt.exclude_domains, cmd_vector },
|
||||||
|
{ "followftp", &opt.follow_ftp, cmd_boolean },
|
||||||
|
{ "forcehtml", &opt.force_html, cmd_boolean },
|
||||||
|
{ "ftpproxy", &opt.ftp_proxy, cmd_string },
|
||||||
|
{ "glob", &opt.ftp_glob, cmd_boolean },
|
||||||
|
{ "header", NULL, cmd_spec_header },
|
||||||
|
{ "htmlify", NULL, cmd_spec_htmlify },
|
||||||
|
{ "httppasswd", &opt.http_passwd, cmd_string },
|
||||||
|
{ "httpproxy", &opt.http_proxy, cmd_string },
|
||||||
|
{ "httpuser", &opt.http_user, cmd_string },
|
||||||
|
{ "ignorelength", &opt.ignore_length, cmd_boolean },
|
||||||
|
{ "includedirectories", &opt.includes, cmd_directory_vector },
|
||||||
|
{ "input", &opt.input_filename, cmd_string },
|
||||||
|
{ "killlonger", &opt.kill_longer, cmd_boolean },
|
||||||
|
{ "logfile", &opt.lfilename, cmd_string },
|
||||||
|
{ "login", &opt.ftp_acc, cmd_string },
|
||||||
|
{ "mirror", NULL, cmd_spec_mirror },
|
||||||
|
{ "netrc", &opt.netrc, cmd_boolean },
|
||||||
|
{ "noclobber", &opt.noclobber, cmd_boolean },
|
||||||
|
{ "noparent", &opt.no_parent, cmd_boolean },
|
||||||
|
{ "noproxy", &opt.no_proxy, cmd_vector },
|
||||||
|
{ "numtries", &opt.ntry, cmd_number_inf }, /* deprecated */
|
||||||
|
{ "outputdocument", NULL, cmd_spec_outputdocument },
|
||||||
|
{ "passiveftp", &opt.ftp_pasv, cmd_boolean },
|
||||||
|
{ "passwd", &opt.ftp_pass, cmd_string },
|
||||||
|
{ "proxypasswd", &opt.proxy_passwd, cmd_string },
|
||||||
|
{ "proxyuser", &opt.proxy_user, cmd_string },
|
||||||
|
{ "quiet", &opt.quiet, cmd_boolean },
|
||||||
|
{ "quota", &opt.quota, cmd_bytes },
|
||||||
|
{ "reclevel", &opt.reclevel, cmd_number_inf },
|
||||||
|
{ "recursive", NULL, cmd_spec_recursive },
|
||||||
|
{ "reject", &opt.rejects, cmd_vector },
|
||||||
|
{ "relativeonly", &opt.relative_only, cmd_boolean },
|
||||||
|
{ "removelisting", &opt.remove_listing, cmd_boolean },
|
||||||
|
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
|
||||||
|
{ "robots", &opt.use_robots, cmd_boolean },
|
||||||
|
{ "saveheaders", &opt.save_headers, cmd_boolean },
|
||||||
|
{ "serverresponse", &opt.server_response, cmd_boolean },
|
||||||
|
{ "simplehostcheck", &opt.simple_check, cmd_boolean },
|
||||||
|
{ "spanhosts", &opt.spanhost, cmd_boolean },
|
||||||
|
{ "spider", &opt.spider, cmd_boolean },
|
||||||
|
{ "timeout", &opt.timeout, cmd_time },
|
||||||
|
{ "timestamping", &opt.timestamping, cmd_boolean },
|
||||||
|
{ "tries", &opt.ntry, cmd_number_inf },
|
||||||
|
{ "useproxy", &opt.use_proxy, cmd_boolean },
|
||||||
|
{ "useragent", NULL, cmd_spec_useragent },
|
||||||
|
{ "verbose", &opt.verbose, cmd_boolean },
|
||||||
|
{ "wait", &opt.wait, cmd_time }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return index of COM if it is a valid command, or -1 otherwise. COM
|
||||||
|
is looked up in `commands' using binary search algorithm. */
|
||||||
|
static int
|
||||||
|
comind (const char *com)
|
||||||
|
{
|
||||||
|
int min = 0, max = ARRAY_SIZE (commands);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int i = (min + max) / 2;
|
||||||
|
int cmp = strcasecmp (com, commands[i].name);
|
||||||
|
if (cmp == 0)
|
||||||
|
return i;
|
||||||
|
else if (cmp < 0)
|
||||||
|
max = i - 1;
|
||||||
|
else
|
||||||
|
min = i + 1;
|
||||||
|
}
|
||||||
|
while (min <= max);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the variables to default values. */
|
||||||
|
static void
|
||||||
|
defaults (void)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
/* Most of the default values are 0. Just reset everything, and
|
||||||
|
fill in the non-zero values. Note that initializing pointers to
|
||||||
|
NULL this way is technically illegal, but porting Wget to a
|
||||||
|
machine where NULL is not all-zero bit pattern will be the least
|
||||||
|
of the implementors' worries. */
|
||||||
|
memset (&opt, 0, sizeof (opt));
|
||||||
|
|
||||||
|
opt.verbose = -1;
|
||||||
|
opt.dir_prefix = xstrdup (".");
|
||||||
|
opt.ntry = 20;
|
||||||
|
opt.reclevel = 5;
|
||||||
|
opt.add_hostdir = 1;
|
||||||
|
opt.ftp_acc = xstrdup ("anonymous");
|
||||||
|
/*opt.ftp_pass = xstrdup (ftp_getaddress ());*/
|
||||||
|
opt.netrc = 1;
|
||||||
|
opt.ftp_glob = 1;
|
||||||
|
opt.htmlify = 1;
|
||||||
|
opt.use_proxy = 1;
|
||||||
|
tmp = getenv ("no_proxy");
|
||||||
|
if (tmp)
|
||||||
|
opt.no_proxy = sepstring (tmp);
|
||||||
|
opt.proxy_cache = 1;
|
||||||
|
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
opt.timeout = 900;
|
||||||
|
#endif
|
||||||
|
opt.use_robots = 1;
|
||||||
|
|
||||||
|
opt.remove_listing = 1;
|
||||||
|
|
||||||
|
opt.dot_bytes = 1024;
|
||||||
|
opt.dot_spacing = 10;
|
||||||
|
opt.dots_in_line = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the user's home directory (strdup-ed), or NULL if none is
|
||||||
|
found. */
|
||||||
|
char *
|
||||||
|
home_dir (void)
|
||||||
|
{
|
||||||
|
char *home = getenv ("HOME");
|
||||||
|
|
||||||
|
if (!home)
|
||||||
|
{
|
||||||
|
#ifndef WINDOWS
|
||||||
|
/* If HOME is not defined, try getting it from the password
|
||||||
|
file. */
|
||||||
|
struct passwd *pwd = getpwuid (getuid ());
|
||||||
|
if (!pwd || !pwd->pw_dir)
|
||||||
|
return NULL;
|
||||||
|
home = pwd->pw_dir;
|
||||||
|
#else /* WINDOWS */
|
||||||
|
home = "C:\\";
|
||||||
|
/* #### Maybe I should grab home_dir from registry, but the best
|
||||||
|
that I could get from there is user's Start menu. It sucks! */
|
||||||
|
#endif /* WINDOWS */
|
||||||
|
}
|
||||||
|
|
||||||
|
return home ? xstrdup (home) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the path to the user's .wgetrc. This is either the value of
|
||||||
|
`WGETRC' environment variable, or `$HOME/.wgetrc'.
|
||||||
|
|
||||||
|
If the `WGETRC' variable exists but the file does not exist, the
|
||||||
|
function will exit(). */
|
||||||
|
static char *
|
||||||
|
wgetrc_file_name (void)
|
||||||
|
{
|
||||||
|
char *env, *home;
|
||||||
|
char *file = NULL;
|
||||||
|
|
||||||
|
/* Try the environment. */
|
||||||
|
env = getenv ("WGETRC");
|
||||||
|
if (env && *env)
|
||||||
|
{
|
||||||
|
if (!file_exists_p (env))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: %s: %s.\n", exec_name, file, strerror (errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
return xstrdup (env);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WINDOWS
|
||||||
|
/* If that failed, try $HOME/.wgetrc. */
|
||||||
|
home = home_dir ();
|
||||||
|
if (home)
|
||||||
|
{
|
||||||
|
file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1);
|
||||||
|
sprintf (file, "%s/.wgetrc", home);
|
||||||
|
}
|
||||||
|
#else /* WINDOWS */
|
||||||
|
/* Under Windows, "home" is (for the purposes of this function) the
|
||||||
|
directory where `wget.exe' resides, and `wget.ini' will be used
|
||||||
|
as file name. SYSTEM_WGETRC should not be defined under WINDOWS.
|
||||||
|
|
||||||
|
It is not as trivial as I assumed, because on 95 argv[0] is full
|
||||||
|
path, but on NT you get what you typed in command line. --dbudor */
|
||||||
|
home = ws_mypath ();
|
||||||
|
if (home)
|
||||||
|
{
|
||||||
|
file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1);
|
||||||
|
sprintf (file, "%swget.ini", home);
|
||||||
|
}
|
||||||
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
|
FREE_MAYBE (home);
|
||||||
|
if (!file)
|
||||||
|
return NULL;
|
||||||
|
if (!file_exists_p (file))
|
||||||
|
{
|
||||||
|
free (file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize variables from a wgetrc file */
|
||||||
|
static void
|
||||||
|
run_wgetrc (const char *file)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *line;
|
||||||
|
int ln;
|
||||||
|
|
||||||
|
fp = fopen (file, "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
|
||||||
|
file, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Reset line number. */
|
||||||
|
ln = 1;
|
||||||
|
while ((line = read_whole_line (fp)))
|
||||||
|
{
|
||||||
|
char *com, *val;
|
||||||
|
int status;
|
||||||
|
int length = strlen (line);
|
||||||
|
|
||||||
|
if (length && line[length - 1] == '\r')
|
||||||
|
line[length - 1] = '\0';
|
||||||
|
/* Parse the line. */
|
||||||
|
status = parse_line (line, &com, &val);
|
||||||
|
free (line);
|
||||||
|
/* If everything is OK, set the value. */
|
||||||
|
if (status == 1)
|
||||||
|
{
|
||||||
|
if (!setval (com, val))
|
||||||
|
fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
|
||||||
|
file, ln);
|
||||||
|
free (com);
|
||||||
|
free (val);
|
||||||
|
}
|
||||||
|
else if (status == 0)
|
||||||
|
fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name,
|
||||||
|
file, ln);
|
||||||
|
++ln;
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the defaults and run the system wgetrc and user's own
|
||||||
|
wgetrc. */
|
||||||
|
void
|
||||||
|
initialize (void)
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
/* Load the hard-coded defaults. */
|
||||||
|
defaults ();
|
||||||
|
|
||||||
|
/* If SYSTEM_WGETRC is defined, use it. */
|
||||||
|
#ifdef SYSTEM_WGETRC
|
||||||
|
if (file_exists_p (SYSTEM_WGETRC))
|
||||||
|
run_wgetrc (SYSTEM_WGETRC);
|
||||||
|
#endif
|
||||||
|
/* Override it with your own, if one exists. */
|
||||||
|
file = wgetrc_file_name ();
|
||||||
|
if (!file)
|
||||||
|
return;
|
||||||
|
/* #### We should somehow canonicalize `file' and SYSTEM_WGETRC,
|
||||||
|
really. */
|
||||||
|
#ifdef SYSTEM_WGETRC
|
||||||
|
if (!strcmp (file, SYSTEM_WGETRC))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("\
|
||||||
|
%s: Warning: Both system and user wgetrc point to `%s'.\n"),
|
||||||
|
exec_name, file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
run_wgetrc (file);
|
||||||
|
free (file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the line pointed by line, with the syntax:
|
||||||
|
<sp>* command <sp>* = <sp>* value <newline>
|
||||||
|
Uses malloc to allocate space for command and value.
|
||||||
|
If the line is invalid, data is freed and 0 is returned.
|
||||||
|
|
||||||
|
Return values:
|
||||||
|
1 - success
|
||||||
|
0 - failure
|
||||||
|
-1 - empty */
|
||||||
|
int
|
||||||
|
parse_line (const char *line, char **com, char **val)
|
||||||
|
{
|
||||||
|
const char *p = line;
|
||||||
|
const char *orig_comptr, *end;
|
||||||
|
char *new_comptr;
|
||||||
|
|
||||||
|
/* Skip spaces. */
|
||||||
|
while (*p == ' ' || *p == '\t')
|
||||||
|
++p;
|
||||||
|
|
||||||
|
/* Don't process empty lines. */
|
||||||
|
if (!*p || *p == '\n' || *p == '#')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (orig_comptr = p; ISALPHA (*p) || *p == '_' || *p == '-'; p++)
|
||||||
|
;
|
||||||
|
/* The next char should be space or '='. */
|
||||||
|
if (!ISSPACE (*p) && (*p != '='))
|
||||||
|
return 0;
|
||||||
|
*com = (char *)xmalloc (p - orig_comptr + 1);
|
||||||
|
for (new_comptr = *com; orig_comptr < p; orig_comptr++)
|
||||||
|
{
|
||||||
|
if (*orig_comptr == '_' || *orig_comptr == '-')
|
||||||
|
continue;
|
||||||
|
*new_comptr++ = *orig_comptr;
|
||||||
|
}
|
||||||
|
*new_comptr = '\0';
|
||||||
|
/* If the command is invalid, exit now. */
|
||||||
|
if (comind (*com) == -1)
|
||||||
|
{
|
||||||
|
free (*com);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip spaces before '='. */
|
||||||
|
for (; ISSPACE (*p); p++);
|
||||||
|
/* If '=' not found, bail out. */
|
||||||
|
if (*p != '=')
|
||||||
|
{
|
||||||
|
free (*com);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Skip spaces after '='. */
|
||||||
|
for (++p; ISSPACE (*p); p++);
|
||||||
|
/* Get the ending position. */
|
||||||
|
for (end = p; *end && *end != '\n'; end++);
|
||||||
|
/* Allocate *val, and copy from line. */
|
||||||
|
*val = strdupdelim (p, end);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set COM to VAL. This is the meat behind processing `.wgetrc'. No
|
||||||
|
fatals -- error signal prints a warning and resets to default
|
||||||
|
value. All error messages are printed to stderr, *not* to
|
||||||
|
opt.lfile, since opt.lfile wasn't even generated yet. */
|
||||||
|
int
|
||||||
|
setval (const char *com, const char *val)
|
||||||
|
{
|
||||||
|
int ind;
|
||||||
|
|
||||||
|
if (!com || !val)
|
||||||
|
return 0;
|
||||||
|
ind = comind (com);
|
||||||
|
if (ind == -1)
|
||||||
|
{
|
||||||
|
/* #### Should I just abort()? */
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, _("%s: BUG: unknown command `%s', value `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((*commands[ind].action) (com, val, commands[ind].closure));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic helper functions, for use with `commands'. */
|
||||||
|
|
||||||
|
static int myatoi PARAMS ((const char *s));
|
||||||
|
|
||||||
|
/* Store the boolean value from VAL to CLOSURE. COM is ignored,
|
||||||
|
except for error messages. */
|
||||||
|
static int
|
||||||
|
cmd_boolean (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
int bool_value;
|
||||||
|
|
||||||
|
if (!strcasecmp (val, "on")
|
||||||
|
|| (*val == '1' && !*(val + 1)))
|
||||||
|
bool_value = 1;
|
||||||
|
else if (!strcasecmp (val, "off")
|
||||||
|
|| (*val == '0' && !*(val + 1)))
|
||||||
|
bool_value = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Please specify on or off.\n"),
|
||||||
|
exec_name, com);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(int *)closure = bool_value;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the non-negative integer value from VAL to CLOSURE. With
|
||||||
|
incorrect specification, the number remains unchanged. */
|
||||||
|
static int
|
||||||
|
cmd_number (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
int num = myatoi (val);
|
||||||
|
|
||||||
|
if (num == -1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*(int *)closure = num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to cmd_number(), only accepts `inf' as a synonym for 0. */
|
||||||
|
static int
|
||||||
|
cmd_number_inf (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
if (!strcasecmp (val, "inf"))
|
||||||
|
{
|
||||||
|
*(int *)closure = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return cmd_number (com, val, closure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy (strdup) the string at COM to a new location and place a
|
||||||
|
pointer to *CLOSURE. */
|
||||||
|
static int
|
||||||
|
cmd_string (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
char **pstring = (char **)closure;
|
||||||
|
|
||||||
|
FREE_MAYBE (*pstring);
|
||||||
|
*pstring = xstrdup (val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge the vector (array of strings separated with `,') in COM with
|
||||||
|
the vector (NULL-terminated array of strings) pointed to by
|
||||||
|
CLOSURE. */
|
||||||
|
static int
|
||||||
|
cmd_vector (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
char ***pvec = (char ***)closure;
|
||||||
|
|
||||||
|
if (*val)
|
||||||
|
*pvec = merge_vecs (*pvec, sepstring (val));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free_vec (*pvec);
|
||||||
|
*pvec = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_directory_vector (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
char ***pvec = (char ***)closure;
|
||||||
|
|
||||||
|
if (*val)
|
||||||
|
{
|
||||||
|
/* Strip the trailing slashes from directories. */
|
||||||
|
char **t, **seps;
|
||||||
|
|
||||||
|
seps = sepstring (val);
|
||||||
|
for (t = seps; t && *t; t++)
|
||||||
|
{
|
||||||
|
int len = strlen (*t);
|
||||||
|
/* Skip degenerate case of root directory. */
|
||||||
|
if (len > 1)
|
||||||
|
{
|
||||||
|
if ((*t)[len - 1] == '/')
|
||||||
|
(*t)[len - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pvec = merge_vecs (*pvec, seps);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free_vec (*pvec);
|
||||||
|
*pvec = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the value stored in VAL to CLOSURE (which should point to a
|
||||||
|
long int), allowing several postfixes, with the following syntax
|
||||||
|
(regexp):
|
||||||
|
|
||||||
|
[0-9]+ -> bytes
|
||||||
|
[0-9]+[kK] -> bytes * 1024
|
||||||
|
[0-9]+[mM] -> bytes * 1024 * 1024
|
||||||
|
inf -> 0
|
||||||
|
|
||||||
|
Anything else is flagged as incorrect, and CLOSURE is unchanged. */
|
||||||
|
static int
|
||||||
|
cmd_bytes (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
long *out = (long *)closure;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
p = val;
|
||||||
|
/* Check for "inf". */
|
||||||
|
if (p[0] == 'i' && p[1] == 'n' && p[2] == 'f' && p[3] == '\0')
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Search for digits and construct result. */
|
||||||
|
for (; *p && ISDIGIT (*p); p++)
|
||||||
|
result = (10 * result) + (*p - '0');
|
||||||
|
/* If no digits were found, or more than one character is following
|
||||||
|
them, bail out. */
|
||||||
|
if (p == val || (*p != '\0' && *(p + 1) != '\0'))
|
||||||
|
{
|
||||||
|
printf (_("%s: Invalid specification `%s'\n"), com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Search for a designator. */
|
||||||
|
switch (tolower (*p))
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
/* None */
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
/* Kilobytes */
|
||||||
|
result *= 1024;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
/* Megabytes */
|
||||||
|
result *= (long)1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
/* Gigabytes */
|
||||||
|
result *= (long)1024 * 1024 * 1024;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf (_("%s: Invalid specification `%s'\n"), com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*out = result;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the value of VAL to *OUT, allowing suffixes for minutes and
|
||||||
|
hours. */
|
||||||
|
static int
|
||||||
|
cmd_time (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
long result = 0;
|
||||||
|
const char *p = val;
|
||||||
|
|
||||||
|
/* Search for digits and construct result. */
|
||||||
|
for (; *p && ISDIGIT (*p); p++)
|
||||||
|
result = (10 * result) + (*p - '0');
|
||||||
|
/* If no digits were found, or more than one character is following
|
||||||
|
them, bail out. */
|
||||||
|
if (p == val || (*p != '\0' && *(p + 1) != '\0'))
|
||||||
|
{
|
||||||
|
printf (_("%s: Invalid specification `%s'\n"), com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Search for a suffix. */
|
||||||
|
switch (tolower (*p))
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
/* None */
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
/* Minutes */
|
||||||
|
result *= 60;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
/* Seconds */
|
||||||
|
result *= 3600;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
/* Days (overflow on 16bit machines) */
|
||||||
|
result *= 86400L;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
/* Weeks :-) */
|
||||||
|
result *= 604800L;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf (_("%s: Invalid specification `%s'\n"), com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*(long *)closure = result;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specialized helper functions, used by `commands' to handle some
|
||||||
|
options specially. */
|
||||||
|
|
||||||
|
static int check_user_specified_header PARAMS ((const char *));
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_dirstruct (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
if (!cmd_boolean (com, val, &opt.dirstruct))
|
||||||
|
return 0;
|
||||||
|
/* Since dirstruct behaviour is explicitly changed, no_dirstruct
|
||||||
|
must be affected inversely. */
|
||||||
|
if (opt.dirstruct)
|
||||||
|
opt.no_dirstruct = 0;
|
||||||
|
else
|
||||||
|
opt.no_dirstruct = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_dotstyle (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
/* Retrieval styles. */
|
||||||
|
if (!strcasecmp (val, "default"))
|
||||||
|
{
|
||||||
|
/* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
|
||||||
|
line. */
|
||||||
|
opt.dot_bytes = 1024;
|
||||||
|
opt.dot_spacing = 10;
|
||||||
|
opt.dots_in_line = 50;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (val, "binary"))
|
||||||
|
{
|
||||||
|
/* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
|
||||||
|
(384K) in a line. */
|
||||||
|
opt.dot_bytes = 8192;
|
||||||
|
opt.dot_spacing = 16;
|
||||||
|
opt.dots_in_line = 48;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (val, "mega"))
|
||||||
|
{
|
||||||
|
/* "Mega" retrieval, for retrieving very long files; each dot is
|
||||||
|
64K, 8 dots in a cluster, 6 clusters (3M) in a line. */
|
||||||
|
opt.dot_bytes = 65536L;
|
||||||
|
opt.dot_spacing = 8;
|
||||||
|
opt.dots_in_line = 48;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (val, "giga"))
|
||||||
|
{
|
||||||
|
/* "Giga" retrieval, for retrieving very very *very* long files;
|
||||||
|
each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
|
||||||
|
line. */
|
||||||
|
opt.dot_bytes = (1L << 20);
|
||||||
|
opt.dot_spacing = 8;
|
||||||
|
opt.dots_in_line = 32;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (val, "micro"))
|
||||||
|
{
|
||||||
|
/* "Micro" retrieval, for retrieving very small files (and/or
|
||||||
|
slow connections); each dot is 128 bytes, 8 dots in a
|
||||||
|
cluster, 6 clusters (6K) in a line. */
|
||||||
|
opt.dot_bytes = 128;
|
||||||
|
opt.dot_spacing = 8;
|
||||||
|
opt.dots_in_line = 48;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_header (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
if (!*val)
|
||||||
|
{
|
||||||
|
/* Empty header means reset headers. */
|
||||||
|
FREE_MAYBE (opt.user_header);
|
||||||
|
opt.user_header = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!check_user_specified_header (val))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
i = opt.user_header ? strlen (opt.user_header) : 0;
|
||||||
|
opt.user_header = (char *)xrealloc (opt.user_header, i + strlen (val)
|
||||||
|
+ 2 + 1);
|
||||||
|
strcpy (opt.user_header + i, val);
|
||||||
|
i += strlen (val);
|
||||||
|
opt.user_header[i++] = '\r';
|
||||||
|
opt.user_header[i++] = '\n';
|
||||||
|
opt.user_header[i] = '\0';
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_htmlify (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
int flag = cmd_boolean (com, val, &opt.htmlify);
|
||||||
|
if (flag && !opt.htmlify)
|
||||||
|
opt.remove_listing = 0;
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_mirror (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
int mirror;
|
||||||
|
|
||||||
|
if (!cmd_boolean (com, val, &mirror))
|
||||||
|
return 0;
|
||||||
|
if (mirror)
|
||||||
|
{
|
||||||
|
opt.recursive = 1;
|
||||||
|
if (!opt.no_dirstruct)
|
||||||
|
opt.dirstruct = 1;
|
||||||
|
opt.timestamping = 1;
|
||||||
|
opt.reclevel = 0;
|
||||||
|
opt.remove_listing = 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_outputdocument (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
FREE_MAYBE (opt.output_document);
|
||||||
|
opt.output_document = xstrdup (val);
|
||||||
|
opt.ntry = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_recursive (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
if (!cmd_boolean (com, val, &opt.recursive))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opt.recursive && !opt.no_dirstruct)
|
||||||
|
opt.dirstruct = 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_spec_useragent (const char *com, const char *val, void *closure)
|
||||||
|
{
|
||||||
|
/* Just check for empty string and newline, so we don't throw total
|
||||||
|
junk to the server. */
|
||||||
|
if (!*val || strchr (val, '\n'))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: Invalid specification `%s'.\n"),
|
||||||
|
exec_name, com, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opt.useragent = xstrdup (val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Miscellaneous useful routines. */
|
||||||
|
|
||||||
|
/* Return the integer value of a positive integer written in S, or -1
|
||||||
|
if an error was encountered. */
|
||||||
|
static int
|
||||||
|
myatoi (const char *s)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
const char *orig = s;
|
||||||
|
|
||||||
|
for (res = 0; *s && ISDIGIT (*s); s++)
|
||||||
|
res = 10 * res + (*s - '0');
|
||||||
|
if (*s || orig == s)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ISODIGIT(x) ((x) >= '0' && (x) <= '7')
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_user_specified_header (const char *s)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
for (p = s; *p && *p != ':' && !ISSPACE (*p); p++);
|
||||||
|
/* The header MUST contain `:' preceded by at least one
|
||||||
|
non-whitespace character. */
|
||||||
|
if (*p != ':' || p == s)
|
||||||
|
return 0;
|
||||||
|
/* The header MUST NOT contain newlines. */
|
||||||
|
if (strchr (s, '\n'))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the memory allocated by global variables. */
|
||||||
|
void
|
||||||
|
cleanup (void)
|
||||||
|
{
|
||||||
|
extern acc_t *netrc_list;
|
||||||
|
|
||||||
|
recursive_cleanup ();
|
||||||
|
clean_hosts ();
|
||||||
|
free_netrc (netrc_list);
|
||||||
|
if (opt.dfp)
|
||||||
|
fclose (opt.dfp);
|
||||||
|
FREE_MAYBE (opt.lfilename);
|
||||||
|
free (opt.dir_prefix);
|
||||||
|
FREE_MAYBE (opt.input_filename);
|
||||||
|
FREE_MAYBE (opt.output_document);
|
||||||
|
free_vec (opt.accepts);
|
||||||
|
free_vec (opt.rejects);
|
||||||
|
free_vec (opt.excludes);
|
||||||
|
free_vec (opt.includes);
|
||||||
|
free_vec (opt.domains);
|
||||||
|
free (opt.ftp_acc);
|
||||||
|
free (opt.ftp_pass);
|
||||||
|
FREE_MAYBE (opt.ftp_proxy);
|
||||||
|
FREE_MAYBE (opt.http_proxy);
|
||||||
|
free_vec (opt.no_proxy);
|
||||||
|
FREE_MAYBE (opt.useragent);
|
||||||
|
FREE_MAYBE (opt.http_user);
|
||||||
|
FREE_MAYBE (opt.http_passwd);
|
||||||
|
FREE_MAYBE (opt.user_header);
|
||||||
|
}
|
29
src/init.h
Normal file
29
src/init.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* Declarations for init.c.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef INIT_H
|
||||||
|
#define INIT_H
|
||||||
|
|
||||||
|
void initialize PARAMS ((void));
|
||||||
|
int parse_line PARAMS ((const char *, char **, char **));
|
||||||
|
int setval PARAMS ((const char *, const char *));
|
||||||
|
char *home_dir PARAMS ((void));
|
||||||
|
void cleanup PARAMS ((void));
|
||||||
|
|
||||||
|
#endif /* INIT_H */
|
317
src/log.c
Normal file
317
src/log.c
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
/* Messages logging.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#if defined(__STDC__) && defined(HAVE_STDARG_H)
|
||||||
|
/* If we have __STDC__ and stdarg.h, we'll assume it's an ANSI system. */
|
||||||
|
# define USE_STDARG
|
||||||
|
# include <stdarg.h>
|
||||||
|
#else
|
||||||
|
# include <varargs.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We expect no message passed to logprintf() to be bigger than this.
|
||||||
|
Before a message is printed, we make sure that at least this much
|
||||||
|
room is left for printing it. */
|
||||||
|
#define SAVED_LOG_MAXMSG 32768
|
||||||
|
|
||||||
|
/* Maximum allowed growing size. */
|
||||||
|
#define SAVED_LOG_MAXSIZE (10 * 1L << 20)
|
||||||
|
|
||||||
|
static char *saved_log;
|
||||||
|
/* Size of the current log. */
|
||||||
|
static long saved_log_size;
|
||||||
|
/* Offset into the log where we are about to print (size of the
|
||||||
|
used-up part of SAVED_LOG). */
|
||||||
|
static long saved_log_offset;
|
||||||
|
/* Whether logging is saved at all. */
|
||||||
|
int save_log_p;
|
||||||
|
|
||||||
|
static FILE *logfp;
|
||||||
|
|
||||||
|
/* Check X against opt.verbose and opt.quiet. The semantics is as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
* LOG_ALWAYS - print the message unconditionally;
|
||||||
|
|
||||||
|
* LOG_NOTQUIET - print the message if opt.quiet is non-zero;
|
||||||
|
|
||||||
|
* LOG_NONVERBOSE - print the message if opt.verbose is zero;
|
||||||
|
|
||||||
|
* LOG_VERBOSE - print the message if opt.verbose is non-zero. */
|
||||||
|
#define CHECK_VERBOSE(x) \
|
||||||
|
switch (x) \
|
||||||
|
{ \
|
||||||
|
case LOG_ALWAYS: \
|
||||||
|
break; \
|
||||||
|
case LOG_NOTQUIET: \
|
||||||
|
if (opt.quiet) \
|
||||||
|
return; \
|
||||||
|
break; \
|
||||||
|
case LOG_NONVERBOSE: \
|
||||||
|
if (opt.verbose || opt.quiet) \
|
||||||
|
return; \
|
||||||
|
break; \
|
||||||
|
case LOG_VERBOSE: \
|
||||||
|
if (!opt.verbose) \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CANONICALIZE_LOGFP_OR_RETURN do { \
|
||||||
|
if (logfp == stdin) \
|
||||||
|
return; \
|
||||||
|
else if (!logfp) \
|
||||||
|
/* #### Should this ever happen? */ \
|
||||||
|
logfp = stderr; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
logputs (enum log_options o, const char *s)
|
||||||
|
{
|
||||||
|
CHECK_VERBOSE (o);
|
||||||
|
CANONICALIZE_LOGFP_OR_RETURN;
|
||||||
|
|
||||||
|
fputs (s, logfp);
|
||||||
|
if (!opt.no_flush)
|
||||||
|
fflush (logfp);
|
||||||
|
|
||||||
|
if (save_log_p && saved_log_size < SAVED_LOG_MAXSIZE)
|
||||||
|
{
|
||||||
|
int len = strlen (s);
|
||||||
|
|
||||||
|
/* Increase size of SAVED_LOG exponentially. */
|
||||||
|
DO_REALLOC (saved_log, saved_log_size,
|
||||||
|
saved_log_offset + len + 1, char);
|
||||||
|
memcpy (saved_log + saved_log_offset, s, len + 1);
|
||||||
|
saved_log_offset += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a message to the log file logfp. If logfp is NULL, print to
|
||||||
|
stderr. If logfp is stdin, don't print at all. A copy of message
|
||||||
|
will be saved to saved_log, for later reusal by dump_log(). */
|
||||||
|
static void
|
||||||
|
logvprintf (enum log_options o, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
CHECK_VERBOSE (o);
|
||||||
|
CANONICALIZE_LOGFP_OR_RETURN;
|
||||||
|
|
||||||
|
/* Originally, we first used vfprintf(), and then checked whether
|
||||||
|
the message needs to be stored with vsprintf(). However, Watcom
|
||||||
|
C didn't like ARGS being used twice, so now we first vsprintf()
|
||||||
|
the message, and then fwrite() it to LOGFP. */
|
||||||
|
if (save_log_p && saved_log_size < SAVED_LOG_MAXSIZE)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
/* Increase size of `saved_log' exponentially. */
|
||||||
|
DO_REALLOC (saved_log, saved_log_size,
|
||||||
|
saved_log_offset + SAVED_LOG_MAXMSG, char);
|
||||||
|
/* Print the message to the log saver... */
|
||||||
|
#ifdef HAVE_VSNPRINTF
|
||||||
|
vsnprintf (saved_log + saved_log_offset, SAVED_LOG_MAXMSG, fmt, args);
|
||||||
|
#else /* not HAVE_VSNPRINTF */
|
||||||
|
vsprintf (saved_log + saved_log_offset, fmt, args);
|
||||||
|
#endif /* not HAVE_VSNPRINTF */
|
||||||
|
/* ...and then dump it to LOGFP. */
|
||||||
|
len = strlen (saved_log + saved_log_offset);
|
||||||
|
fwrite (saved_log + saved_log_offset, len, 1, logfp);
|
||||||
|
saved_log_offset += len;
|
||||||
|
/* If we ran off the limits and corrupted something, bail out
|
||||||
|
immediately. */
|
||||||
|
assert (saved_log_size >= saved_log_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vfprintf (logfp, fmt, args);
|
||||||
|
|
||||||
|
if (!opt.no_flush)
|
||||||
|
fflush (logfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush LOGFP. */
|
||||||
|
void
|
||||||
|
logflush (void)
|
||||||
|
{
|
||||||
|
CANONICALIZE_LOGFP_OR_RETURN;
|
||||||
|
fflush (logfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Portability makes these two functions look like @#%#@$@#$. */
|
||||||
|
|
||||||
|
#ifdef USE_STDARG
|
||||||
|
void
|
||||||
|
logprintf (enum log_options o, const char *fmt, ...)
|
||||||
|
#else /* not USE_STDARG */
|
||||||
|
void
|
||||||
|
logprintf (va_alist)
|
||||||
|
va_dcl
|
||||||
|
#endif /* not USE_STDARG */
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
#ifndef USE_STDARG
|
||||||
|
enum log_options o;
|
||||||
|
const char *fmt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_STDARG
|
||||||
|
va_start (args, fmt);
|
||||||
|
#else
|
||||||
|
va_start (args);
|
||||||
|
o = va_arg (args, enum log_options);
|
||||||
|
fmt = va_arg (args, char *);
|
||||||
|
#endif
|
||||||
|
logvprintf (o, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* The same as logprintf(), but does anything only if opt.debug is
|
||||||
|
non-zero. */
|
||||||
|
#ifdef USE_STDARG
|
||||||
|
void
|
||||||
|
debug_logprintf (const char *fmt, ...)
|
||||||
|
#else /* not USE_STDARG */
|
||||||
|
void
|
||||||
|
debug_logprintf (va_alist)
|
||||||
|
va_dcl
|
||||||
|
#endif /* not USE_STDARG */
|
||||||
|
{
|
||||||
|
if (opt.debug)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
#ifndef USE_STDARG
|
||||||
|
const char *fmt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_STDARG
|
||||||
|
va_start (args, fmt);
|
||||||
|
#else
|
||||||
|
va_start (args);
|
||||||
|
fmt = va_arg (args, char *);
|
||||||
|
#endif
|
||||||
|
logvprintf (LOG_ALWAYS, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
/* Open FILE and set up a logging stream. If FILE cannot be opened,
|
||||||
|
exit with status of 1. */
|
||||||
|
void
|
||||||
|
log_init (const char *file, int appendp)
|
||||||
|
{
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
logfp = fopen (file, appendp ? "a" : "w");
|
||||||
|
if (!logfp)
|
||||||
|
{
|
||||||
|
perror (opt.lfilename);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logfp = stderr;
|
||||||
|
/* If the output is a TTY, enable logging, which will make Wget
|
||||||
|
remember all the printed messages, to be able to dump them to
|
||||||
|
a log file in case SIGHUP or SIGUSR1 is received (or
|
||||||
|
Ctrl+Break is pressed under Windows). */
|
||||||
|
if (1
|
||||||
|
#ifdef HAVE_ISATTY
|
||||||
|
&& isatty (fileno (logfp))
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
save_log_p = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close LOGFP, inhibit further logging and free the memory associated
|
||||||
|
with it. */
|
||||||
|
void
|
||||||
|
log_close (void)
|
||||||
|
{
|
||||||
|
fclose (logfp);
|
||||||
|
save_log_p = 0;
|
||||||
|
FREE_MAYBE (saved_log);
|
||||||
|
saved_log = NULL;
|
||||||
|
saved_log_size = saved_log_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dump SAVED_LOG using logprintf(), but quit further logging to memory.
|
||||||
|
Also, free the memory occupied by saved_log. */
|
||||||
|
static void
|
||||||
|
log_dump (void)
|
||||||
|
{
|
||||||
|
save_log_p = 0;
|
||||||
|
if (!saved_log)
|
||||||
|
return;
|
||||||
|
logputs (LOG_ALWAYS, saved_log);
|
||||||
|
free (saved_log);
|
||||||
|
saved_log = NULL;
|
||||||
|
saved_log_size = saved_log_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Redirect output to `wget-log' if opt.lfile is stdout. MESSIJ is
|
||||||
|
printed on stdout, and should contain *exactly one* `%s', which
|
||||||
|
will be replaced by the log file name.
|
||||||
|
|
||||||
|
If logging was not enabled, MESSIJ will not be printed. */
|
||||||
|
void
|
||||||
|
redirect_output (const char *messij)
|
||||||
|
{
|
||||||
|
char *logfile;
|
||||||
|
|
||||||
|
if (!save_log_p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
logfile = unique_name (DEFAULT_LOGFILE);
|
||||||
|
logfp = fopen (logfile, "w");
|
||||||
|
if (!logfp)
|
||||||
|
{
|
||||||
|
printf ("%s: %s: %s\n", exec_name, logfile, strerror (errno));
|
||||||
|
/* `stdin' is magic to not print anything. */
|
||||||
|
logfp = stdin;
|
||||||
|
}
|
||||||
|
printf (messij, logfile);
|
||||||
|
free (logfile);
|
||||||
|
/* Dump all the previous messages to LOGFILE. */
|
||||||
|
log_dump ();
|
||||||
|
}
|
721
src/main.c
Normal file
721
src/main.c
Normal file
@ -0,0 +1,721 @@
|
|||||||
|
/* Command line parsing.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#ifdef HAVE_SIGNAL_H
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NLS
|
||||||
|
#ifdef HAVE_LOCALE_H
|
||||||
|
# include <locale.h>
|
||||||
|
#endif /* HAVE_LOCALE_H */
|
||||||
|
#endif /* HAVE_NLS */
|
||||||
|
|
||||||
|
#define OPTIONS_DEFINED_HERE /* for options.h */
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "getopt.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "retr.h"
|
||||||
|
#include "recur.h"
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
#ifndef PATH_SEPARATOR
|
||||||
|
# define PATH_SEPARATOR '/'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern char *version_string;
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct options opt;
|
||||||
|
|
||||||
|
/* From log.c. */
|
||||||
|
void log_init PARAMS ((const char *, int));
|
||||||
|
void log_close PARAMS ((void));
|
||||||
|
void redirect_output PARAMS ((const char *));
|
||||||
|
|
||||||
|
static RETSIGTYPE redirect_output_signal PARAMS ((int));
|
||||||
|
|
||||||
|
const char *exec_name;
|
||||||
|
|
||||||
|
/* Initialize I18N. The initialization amounts to invoking
|
||||||
|
setlocale(), bindtextdomain() and textdomain().
|
||||||
|
Does nothing if NLS is disabled or missing. */
|
||||||
|
static void
|
||||||
|
i18n_initialize (void)
|
||||||
|
{
|
||||||
|
/* If HAVE_NLS is defined, assume the existence of the three
|
||||||
|
functions invoked here. */
|
||||||
|
#ifdef HAVE_NLS
|
||||||
|
/* Set the current locale. */
|
||||||
|
/* Here we use LC_MESSAGES instead of LC_ALL, for two reasons.
|
||||||
|
First, message catalogs are all of I18N Wget uses anyway.
|
||||||
|
Second, setting LC_ALL has a dangerous potential of messing
|
||||||
|
things up. For example, when in a foreign locale, Solaris
|
||||||
|
strptime() fails to handle international dates correctly, which
|
||||||
|
makes http_atotm() malfunction. */
|
||||||
|
setlocale (LC_MESSAGES, "");
|
||||||
|
/* Set the text message domain. */
|
||||||
|
bindtextdomain ("wget", LOCALEDIR);
|
||||||
|
textdomain ("wget");
|
||||||
|
#endif /* HAVE_NLS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the usage message. */
|
||||||
|
static void
|
||||||
|
print_usage (void)
|
||||||
|
{
|
||||||
|
printf (_("Usage: %s [OPTION]... [URL]...\n"), exec_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the help message, describing all the available options. If
|
||||||
|
you add an option, be sure to update this list. */
|
||||||
|
static void
|
||||||
|
print_help (void)
|
||||||
|
{
|
||||||
|
printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
|
||||||
|
version_string);
|
||||||
|
print_usage ();
|
||||||
|
/* Had to split this in parts, so the #@@#%# Ultrix compiler and cpp
|
||||||
|
don't bitch. Also, it makes translation much easier. */
|
||||||
|
printf ("%s%s%s%s%s%s%s%s%s%s", _("\
|
||||||
|
\n\
|
||||||
|
Mandatory arguments to long options are mandatory for short options too.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Startup:\n\
|
||||||
|
-V, --version display the version of Wget and exit.\n\
|
||||||
|
-h, --help print this help.\n\
|
||||||
|
-b, --background go to background after startup.\n\
|
||||||
|
-e, --execute=COMMAND execute a `.wgetrc\' command.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Logging and input file:\n\
|
||||||
|
-o, --output-file=FILE log messages to FILE.\n\
|
||||||
|
-a, --append-output=FILE append messages to FILE.\n\
|
||||||
|
-d, --debug print debug output.\n\
|
||||||
|
-q, --quiet quiet (no output).\n\
|
||||||
|
-v, --verbose be verbose (this is the default).\n\
|
||||||
|
-nv, --non-verbose turn off verboseness, without being quiet.\n\
|
||||||
|
-i, --input-file=FILE read URL-s from file.\n\
|
||||||
|
-F, --force-html treat input file as HTML.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Download:\n\
|
||||||
|
-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits).\n\
|
||||||
|
-O --output-document=FILE write documents to FILE.\n\
|
||||||
|
-nc, --no-clobber don\'t clobber existing files.\n\
|
||||||
|
-c, --continue restart getting an existing file.\n\
|
||||||
|
--dot-style=STYLE set retrieval display style.\n\
|
||||||
|
-N, --timestamping don\'t retrieve files if older than local.\n\
|
||||||
|
-S, --server-response print server response.\n\
|
||||||
|
--spider don\'t download anything.\n\
|
||||||
|
-T, --timeout=SECONDS set the read timeout to SECONDS.\n\
|
||||||
|
-w, --wait=SECONDS wait SECONDS between retrievals.\n\
|
||||||
|
-Y, --proxy=on/off turn proxy on or off.\n\
|
||||||
|
-Q, --quota=NUMBER set retrieval quota to NUMBER.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Directories:\n\
|
||||||
|
-nd --no-directories don\'t create directories.\n\
|
||||||
|
-x, --force-directories force creation of directories.\n\
|
||||||
|
-nH, --no-host-directories don\'t create host directories.\n\
|
||||||
|
-P, --directory-prefix=PREFIX save files to PREFIX/...\n\
|
||||||
|
--cut-dirs=NUMBER ignore NUMBER remote directory components.\n\
|
||||||
|
\n"), _("\
|
||||||
|
HTTP options:\n\
|
||||||
|
--http-user=USER set http user to USER.\n\
|
||||||
|
--http-passwd=PASS set http password to PASS.\n\
|
||||||
|
-C, --cache=on/off (dis)allow server-cached data (normally allowed).\n\
|
||||||
|
--ignore-length ignore `Content-Length\' header field.\n\
|
||||||
|
--header=STRING insert STRING among the headers.\n\
|
||||||
|
--proxy-user=USER set USER as proxy username.\n\
|
||||||
|
--proxy-passwd=PASS set PASS as proxy password.\n\
|
||||||
|
-s, --save-headers save the HTTP headers to file.\n\
|
||||||
|
-U, --user-agent=AGENT identify as AGENT instead of Wget/VERSION.\n\
|
||||||
|
\n"), _("\
|
||||||
|
FTP options:\n\
|
||||||
|
--retr-symlinks retrieve FTP symbolic links.\n\
|
||||||
|
-g, --glob=on/off turn file name globbing on or off.\n\
|
||||||
|
--passive-ftp use the \"passive\" transfer mode.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Recursive retrieval:\n\
|
||||||
|
-r, --recursive recursive web-suck -- use with care!.\n\
|
||||||
|
-l, --level=NUMBER maximum recursion depth (0 to unlimit).\n\
|
||||||
|
--delete-after delete downloaded files.\n\
|
||||||
|
-k, --convert-links convert non-relative links to relative.\n\
|
||||||
|
-m, --mirror turn on options suitable for mirroring.\n\
|
||||||
|
-nr, --dont-remove-listing don\'t remove `.listing\' files.\n\
|
||||||
|
\n"), _("\
|
||||||
|
Recursive accept/reject:\n\
|
||||||
|
-A, --accept=LIST list of accepted extensions.\n\
|
||||||
|
-R, --reject=LIST list of rejected extensions.\n\
|
||||||
|
-D, --domains=LIST list of accepted domains.\n\
|
||||||
|
--exclude-domains=LIST comma-separated list of rejected domains.\n\
|
||||||
|
-L, --relative follow relative links only.\n\
|
||||||
|
--follow-ftp follow FTP links from HTML documents.\n\
|
||||||
|
-H, --span-hosts go to foreign hosts when recursive.\n\
|
||||||
|
-I, --include-directories=LIST list of allowed directories.\n\
|
||||||
|
-X, --exclude-directories=LIST list of excluded directories.\n\
|
||||||
|
-nh, --no-host-lookup don\'t DNS-lookup hosts.\n\
|
||||||
|
-np, --no-parent don\'t ascend to the parent directory.\n\
|
||||||
|
\n"), _("Mail bug reports and suggestions to <bug-wget@gnu.org>.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *const *argv)
|
||||||
|
{
|
||||||
|
char **url, **t;
|
||||||
|
int i, c, nurl, status, append_to_log;
|
||||||
|
|
||||||
|
static struct option long_options[] =
|
||||||
|
{
|
||||||
|
{ "background", no_argument, NULL, 'b' },
|
||||||
|
{ "continue", no_argument, NULL, 'c' },
|
||||||
|
{ "convert-links", no_argument, NULL, 'k' },
|
||||||
|
{ "debug", no_argument, NULL, 'd' },
|
||||||
|
{ "dont-remove-listing", no_argument, NULL, 21 },
|
||||||
|
{ "email-address", no_argument, NULL, 'E' }, /* undocumented (debug) */
|
||||||
|
{ "follow-ftp", no_argument, NULL, 14 },
|
||||||
|
{ "force-directories", no_argument, NULL, 'x' },
|
||||||
|
{ "force-hier", no_argument, NULL, 'x' }, /* obsolete */
|
||||||
|
{ "force-html", no_argument, NULL, 'F'},
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "ignore-length", no_argument, NULL, 10 },
|
||||||
|
{ "mirror", no_argument, NULL, 'm' },
|
||||||
|
{ "no-clobber", no_argument, NULL, 13 },
|
||||||
|
{ "no-directories", no_argument, NULL, 19 },
|
||||||
|
{ "no-host-directories", no_argument, NULL, 20 },
|
||||||
|
{ "no-host-lookup", no_argument, NULL, 22 },
|
||||||
|
{ "no-parent", no_argument, NULL, 5 },
|
||||||
|
{ "non-verbose", no_argument, NULL, 18 },
|
||||||
|
{ "passive-ftp", no_argument, NULL, 11 },
|
||||||
|
{ "quiet", no_argument, NULL, 'q' },
|
||||||
|
{ "recursive", no_argument, NULL, 'r' },
|
||||||
|
{ "relative", no_argument, NULL, 'L' },
|
||||||
|
{ "retr-symlinks", no_argument, NULL, 9 },
|
||||||
|
{ "save-headers", no_argument, NULL, 's' },
|
||||||
|
{ "server-response", no_argument, NULL, 'S' },
|
||||||
|
{ "span-hosts", no_argument, NULL, 'H' },
|
||||||
|
{ "spider", no_argument, NULL, 4 },
|
||||||
|
{ "timestamping", no_argument, NULL, 'N' },
|
||||||
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
|
{ "version", no_argument, NULL, 'V' },
|
||||||
|
|
||||||
|
{ "accept", required_argument, NULL, 'A' },
|
||||||
|
{ "append-output", required_argument, NULL, 'a' },
|
||||||
|
{ "backups", required_argument, NULL, 23 }, /* undocumented */
|
||||||
|
{ "base", required_argument, NULL, 'B' },
|
||||||
|
{ "cache", required_argument, NULL, 'C' },
|
||||||
|
{ "cut-dirs", required_argument, NULL, 17 },
|
||||||
|
{ "delete-after", no_argument, NULL, 8 },
|
||||||
|
{ "directory-prefix", required_argument, NULL, 'P' },
|
||||||
|
{ "domains", required_argument, NULL, 'D' },
|
||||||
|
{ "dot-style", required_argument, NULL, 6 },
|
||||||
|
{ "execute", required_argument, NULL, 'e' },
|
||||||
|
{ "exclude-directories", required_argument, NULL, 'X' },
|
||||||
|
{ "exclude-domains", required_argument, NULL, 12 },
|
||||||
|
{ "glob", required_argument, NULL, 'g' },
|
||||||
|
{ "header", required_argument, NULL, 3 },
|
||||||
|
{ "htmlify", required_argument, NULL, 7 },
|
||||||
|
{ "http-passwd", required_argument, NULL, 2 },
|
||||||
|
{ "http-user", required_argument, NULL, 1 },
|
||||||
|
{ "include-directories", required_argument, NULL, 'I' },
|
||||||
|
{ "input-file", required_argument, NULL, 'i' },
|
||||||
|
{ "level", required_argument, NULL, 'l' },
|
||||||
|
{ "no", required_argument, NULL, 'n' },
|
||||||
|
{ "output-document", required_argument, NULL, 'O' },
|
||||||
|
{ "output-file", required_argument, NULL, 'o' },
|
||||||
|
{ "proxy", required_argument, NULL, 'Y' },
|
||||||
|
{ "proxy-passwd", required_argument, NULL, 16 },
|
||||||
|
{ "proxy-user", required_argument, NULL, 15 },
|
||||||
|
{ "quota", required_argument, NULL, 'Q' },
|
||||||
|
{ "reject", required_argument, NULL, 'R' },
|
||||||
|
{ "timeout", required_argument, NULL, 'T' },
|
||||||
|
{ "tries", required_argument, NULL, 't' },
|
||||||
|
{ "user-agent", required_argument, NULL, 'U' },
|
||||||
|
{ "use-proxy", required_argument, NULL, 'Y' },
|
||||||
|
{ "wait", required_argument, NULL, 'w' },
|
||||||
|
{ 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
i18n_initialize ();
|
||||||
|
|
||||||
|
append_to_log = 0;
|
||||||
|
|
||||||
|
/* Construct the name of the executable, without the directory part. */
|
||||||
|
exec_name = strrchr (argv[0], PATH_SEPARATOR);
|
||||||
|
if (!exec_name)
|
||||||
|
exec_name = argv[0];
|
||||||
|
else
|
||||||
|
++exec_name;
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
windows_main_junk (&argc, (char **) argv, (char **) &exec_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
initialize ();
|
||||||
|
|
||||||
|
while ((c = getopt_long (argc, argv, "\
|
||||||
|
hVqvdksxmNWrHSLcFbEY:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:",
|
||||||
|
long_options, (int *)0)) != EOF)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
/* Options without arguments: */
|
||||||
|
case 4:
|
||||||
|
setval ("spider", "on");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
setval ("noparent", "on");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
setval ("deleteafter", "on");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
setval ("retrsymlinks", "on");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
setval ("ignorelength", "on");
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
setval ("passiveftp", "on");
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
setval ("noclobber", "on");
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
setval ("followftp", "on");
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
setval ("cutdirs", optarg);
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
setval ("verbose", "off");
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
setval ("dirstruct", "off");
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
setval ("addhostdir", "off");
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
setval ("removelisting", "off");
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
setval ("simplehostcheck", "on");
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
setval ("background", "on");
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
setval ("continue", "on");
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
#ifdef DEBUG
|
||||||
|
setval ("debug", "on");
|
||||||
|
#else /* not DEBUG */
|
||||||
|
fprintf (stderr, _("%s: debug support not compiled in.\n"),
|
||||||
|
exec_name);
|
||||||
|
#endif /* not DEBUG */
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
/* For debugging purposes. */
|
||||||
|
printf ("%s\n", ftp_getaddress ());
|
||||||
|
exit (0);
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
setval ("forcehtml", "on");
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
setval ("spanhosts", "on");
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_help ();
|
||||||
|
#ifdef WINDOWS
|
||||||
|
ws_help (exec_name);
|
||||||
|
#endif
|
||||||
|
exit (0);
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
setval ("convertlinks", "on");
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
setval ("relativeonly", "on");
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
setval ("mirror", "on");
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
setval ("timestamping", "on");
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
setval ("serverresponse", "on");
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
setval ("saveheaders", "on");
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
setval ("quiet", "on");
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
setval ("recursive", "on");
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
printf ("GNU Wget %s\n\n", version_string);
|
||||||
|
printf ("%s", _("\
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\n\
|
||||||
|
This program 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"));
|
||||||
|
printf (_("\nWritten by Hrvoje Niksic <hniksic@srce.hr>.\n"));
|
||||||
|
exit (0);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
setval ("verbose", "on");
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
setval ("dirstruct", "on");
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Options accepting an argument: */
|
||||||
|
case 1:
|
||||||
|
setval ("httpuser", optarg);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setval ("httppasswd", optarg);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
setval ("header", optarg);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
setval ("dotstyle", optarg);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
setval ("htmlify", optarg);
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
setval ("excludedomains", optarg);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
setval ("proxyuser", optarg);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
setval ("proxypasswd", optarg);
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
setval ("backups", optarg);
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
setval ("accept", optarg);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
setval ("logfile", optarg);
|
||||||
|
append_to_log = 1;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
setval ("base", optarg);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
setval ("cache", optarg);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
setval ("domains", optarg);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
{
|
||||||
|
char *com, *val;
|
||||||
|
if (parse_line (optarg, &com, &val))
|
||||||
|
{
|
||||||
|
if (!setval (com, val))
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: %s: invalid command\n"), exec_name,
|
||||||
|
optarg);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
free (com);
|
||||||
|
free (val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
setval ("glob", optarg);
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
setval ("includedirectories", optarg);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
setval ("input", optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
setval ("reclevel", optarg);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
{
|
||||||
|
/* #### The n? options are utter crock! */
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
for (p = optarg; *p; p++)
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
setval ("verbose", "off");
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
setval ("simplehostcheck", "on");
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
setval ("addhostdir", "off");
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
setval ("dirstruct", "off");
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
setval ("noclobber", "on");
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
setval ("removelisting", "off");
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
setval ("noparent", "on");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p);
|
||||||
|
print_usage ();
|
||||||
|
printf ("\n");
|
||||||
|
printf (_("Try `%s --help\' for more options.\n"), exec_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'O':
|
||||||
|
setval ("outputdocument", optarg);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
setval ("logfile", optarg);
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
setval ("dirprefix", optarg);
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
setval ("quota", optarg);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
setval ("reject", optarg);
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
setval ("timeout", optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
setval ("tries", optarg);
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
setval ("useragent", optarg);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
setval ("wait", optarg);
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
setval ("excludedirectories", optarg);
|
||||||
|
break;
|
||||||
|
case 'Y':
|
||||||
|
setval ("useproxy", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
print_usage ();
|
||||||
|
printf ("\n");
|
||||||
|
printf (_("Try `%s --help' for more options.\n"), exec_name);
|
||||||
|
exit (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opt.verbose == -1)
|
||||||
|
opt.verbose = !opt.quiet;
|
||||||
|
|
||||||
|
/* Sanity checks. */
|
||||||
|
if (opt.verbose && opt.quiet)
|
||||||
|
{
|
||||||
|
printf (_("Can't be verbose and quiet at the same time.\n"));
|
||||||
|
print_usage ();
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (opt.timestamping && opt.noclobber)
|
||||||
|
{
|
||||||
|
printf (_("\
|
||||||
|
Can't timestamp and not clobber old files at the same time.\n"));
|
||||||
|
print_usage ();
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
nurl = argc - optind;
|
||||||
|
if (!nurl && !opt.input_filename)
|
||||||
|
{
|
||||||
|
/* No URL specified. */
|
||||||
|
printf (_("%s: missing URL\n"), exec_name);
|
||||||
|
print_usage ();
|
||||||
|
printf ("\n");
|
||||||
|
/* #### Something nicer should be printed here -- similar to the
|
||||||
|
pre-1.5 `--help' page. */
|
||||||
|
printf (_("Try `%s --help' for more options.\n"), exec_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.background)
|
||||||
|
fork_to_background ();
|
||||||
|
|
||||||
|
/* Allocate basic pointer. */
|
||||||
|
url = ALLOCA_ARRAY (char *, nurl + 1);
|
||||||
|
/* Fill in the arguments. */
|
||||||
|
for (i = 0; i < nurl; i++, optind++)
|
||||||
|
{
|
||||||
|
char *irix4_cc_needs_this;
|
||||||
|
STRDUP_ALLOCA (irix4_cc_needs_this, argv[optind]);
|
||||||
|
url[i] = irix4_cc_needs_this;
|
||||||
|
}
|
||||||
|
url[i] = NULL;
|
||||||
|
|
||||||
|
/* Change the title of console window on Windows. #### I think this
|
||||||
|
statement should belong to retrieve_url(). --hniksic. */
|
||||||
|
#ifdef WINDOWS
|
||||||
|
ws_changetitle (*url, nurl);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize logging. */
|
||||||
|
log_init (opt.lfilename, append_to_log);
|
||||||
|
|
||||||
|
DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", version_string,
|
||||||
|
OS_TYPE));
|
||||||
|
/* Open the output filename if necessary. */
|
||||||
|
if (opt.output_document)
|
||||||
|
{
|
||||||
|
if (HYPHENP (opt.output_document))
|
||||||
|
opt.dfp = stdout;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opt.dfp = fopen (opt.output_document, "wb");
|
||||||
|
if (opt.dfp == NULL)
|
||||||
|
{
|
||||||
|
perror (opt.output_document);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
ws_startup ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Setup the signal handler to redirect output when hangup is
|
||||||
|
received. */
|
||||||
|
#ifdef HAVE_SIGNAL
|
||||||
|
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
||||||
|
signal(SIGHUP, redirect_output_signal);
|
||||||
|
/* ...and do the same for SIGUSR1. */
|
||||||
|
signal (SIGUSR1, redirect_output_signal);
|
||||||
|
/* Writing to a closed socket normally signals SIGPIPE, and the
|
||||||
|
process exits. What we want is to ignore SIGPIPE and just check
|
||||||
|
for the return value of write(). */
|
||||||
|
signal (SIGPIPE, SIG_IGN);
|
||||||
|
#endif /* HAVE_SIGNAL */
|
||||||
|
|
||||||
|
status = RETROK; /* initialize it, just-in-case */
|
||||||
|
recursive_reset ();
|
||||||
|
/* Retrieve the URLs from argument list. */
|
||||||
|
for (t = url; *t; t++)
|
||||||
|
{
|
||||||
|
char *filename, *new_file;
|
||||||
|
int dt;
|
||||||
|
|
||||||
|
status = retrieve_url (*t, &filename, &new_file, NULL, &dt);
|
||||||
|
if (opt.recursive && status == RETROK && (dt & TEXTHTML))
|
||||||
|
status = recursive_retrieve (filename, new_file ? new_file : *t);
|
||||||
|
FREE_MAYBE (new_file);
|
||||||
|
FREE_MAYBE (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And then from the input file, if any. */
|
||||||
|
if (opt.input_filename)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
|
||||||
|
if (!count)
|
||||||
|
logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
|
||||||
|
opt.input_filename);
|
||||||
|
}
|
||||||
|
/* Print the downloaded sum. */
|
||||||
|
if (opt.recursive
|
||||||
|
|| nurl > 1
|
||||||
|
|| (opt.input_filename && opt.downloaded != 0))
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET,
|
||||||
|
_("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
|
||||||
|
time_str (NULL), legible (opt.downloaded), opt.numurls);
|
||||||
|
/* Print quota warning, if exceeded. */
|
||||||
|
if (opt.quota && opt.downloaded > opt.quota)
|
||||||
|
logprintf (LOG_NOTQUIET,
|
||||||
|
_("Download quota (%s bytes) EXCEEDED!\n"),
|
||||||
|
legible (opt.quota));
|
||||||
|
}
|
||||||
|
if (opt.convert_links)
|
||||||
|
{
|
||||||
|
convert_all_links ();
|
||||||
|
}
|
||||||
|
log_close ();
|
||||||
|
cleanup ();
|
||||||
|
if (status == RETROK)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hangup signal handler. When wget receives SIGHUP or SIGUSR1, it
|
||||||
|
will proceed operation as usual, trying to write into a log file.
|
||||||
|
If that is impossible, the output will be turned off. */
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGNAL
|
||||||
|
static RETSIGTYPE
|
||||||
|
redirect_output_signal (int sig)
|
||||||
|
{
|
||||||
|
char tmp[100];
|
||||||
|
signal (sig, redirect_output_signal);
|
||||||
|
/* Please note that the double `%' in `%%s' is intentional, because
|
||||||
|
redirect_output passes tmp through printf. */
|
||||||
|
sprintf (tmp, _("%s received, redirecting output to `%%s'.\n"),
|
||||||
|
(sig == SIGHUP ? "SIGHUP" :
|
||||||
|
(sig == SIGUSR1 ? "SIGUSR1" :
|
||||||
|
"WTF?!")));
|
||||||
|
redirect_output (tmp);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SIGNAL */
|
410
src/md5.c
Normal file
410
src/md5.c
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
/* md5.c - Functions to compute MD5 message digest of files or memory blocks
|
||||||
|
according to the definition of MD5 in RFC 1321 from April 1992.
|
||||||
|
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||||
|
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 the GNU C 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. */
|
||||||
|
|
||||||
|
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wget */
|
||||||
|
/*#if STDC_HEADERS || defined _LIBC*/
|
||||||
|
# include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
/*#else*/
|
||||||
|
/*# ifndef HAVE_MEMCPY*/
|
||||||
|
/*# define memcpy(d, s, n) bcopy ((s), (d), (n))*/
|
||||||
|
/*# endif*/
|
||||||
|
/*#endif*/
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <endian.h>
|
||||||
|
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
# define WORDS_BIGENDIAN 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
# define SWAP(n) \
|
||||||
|
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
|
||||||
|
#else
|
||||||
|
# define SWAP(n) (n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This array contains the bytes used to pad the buffer to the next
|
||||||
|
64-byte boundary. (RFC 1321, 3.1: Step 1) */
|
||||||
|
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize structure containing state of computation.
|
||||||
|
(RFC 1321, 3.3: Step 3) */
|
||||||
|
void
|
||||||
|
md5_init_ctx (struct md5_ctx *ctx)
|
||||||
|
{
|
||||||
|
ctx->A = 0x67452301;
|
||||||
|
ctx->B = 0xefcdab89;
|
||||||
|
ctx->C = 0x98badcfe;
|
||||||
|
ctx->D = 0x10325476;
|
||||||
|
|
||||||
|
ctx->total[0] = ctx->total[1] = 0;
|
||||||
|
ctx->buflen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put result from CTX in first 16 bytes following RESBUF. The result
|
||||||
|
must be in little endian byte order.
|
||||||
|
|
||||||
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
|
aligned for a 32 bits value. */
|
||||||
|
void *
|
||||||
|
md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
|
||||||
|
{
|
||||||
|
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
|
||||||
|
((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
|
||||||
|
((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
|
||||||
|
((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
|
||||||
|
|
||||||
|
return resbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the remaining bytes in the internal buffer and the usual
|
||||||
|
prolog according to the standard and write the result to RESBUF.
|
||||||
|
|
||||||
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
|
aligned for a 32 bits value. */
|
||||||
|
void *
|
||||||
|
md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
|
||||||
|
{
|
||||||
|
/* Take yet unprocessed bytes into account. */
|
||||||
|
md5_uint32 bytes = ctx->buflen;
|
||||||
|
size_t pad;
|
||||||
|
|
||||||
|
/* Now count remaining bytes. */
|
||||||
|
ctx->total[0] += bytes;
|
||||||
|
if (ctx->total[0] < bytes)
|
||||||
|
++ctx->total[1];
|
||||||
|
|
||||||
|
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
|
||||||
|
memcpy (&ctx->buffer[bytes], fillbuf, pad);
|
||||||
|
|
||||||
|
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||||
|
*(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
|
||||||
|
*(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
|
||||||
|
(ctx->total[0] >> 29));
|
||||||
|
|
||||||
|
/* Process last bytes. */
|
||||||
|
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||||
|
|
||||||
|
return md5_read_ctx (ctx, resbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unused in Wget */
|
||||||
|
#if 0
|
||||||
|
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||||
|
resulting message digest number will be written into the 16 bytes
|
||||||
|
beginning at RESBLOCK. */
|
||||||
|
int
|
||||||
|
md5_stream (FILE *stream, void *resblock)
|
||||||
|
{
|
||||||
|
/* Important: BLOCKSIZE must be a multiple of 64. */
|
||||||
|
#define BLOCKSIZE 4096
|
||||||
|
struct md5_ctx ctx;
|
||||||
|
char buffer[BLOCKSIZE + 72];
|
||||||
|
size_t sum;
|
||||||
|
|
||||||
|
/* Initialize the computation context. */
|
||||||
|
md5_init_ctx (&ctx);
|
||||||
|
|
||||||
|
/* Iterate over full file contents. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* We read the file in blocks of BLOCKSIZE bytes. One call of the
|
||||||
|
computation function processes the whole buffer so that with the
|
||||||
|
next round of the loop another block can be read. */
|
||||||
|
size_t n;
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
/* Read block. Take care for partial reads. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
|
||||||
|
|
||||||
|
sum += n;
|
||||||
|
}
|
||||||
|
while (sum < BLOCKSIZE && n != 0);
|
||||||
|
if (n == 0 && ferror (stream))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* If end of file is reached, end the loop. */
|
||||||
|
if (n == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Process buffer with BLOCKSIZE bytes. Note that
|
||||||
|
BLOCKSIZE % 64 == 0
|
||||||
|
*/
|
||||||
|
md5_process_block (buffer, BLOCKSIZE, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the last bytes if necessary. */
|
||||||
|
if (sum > 0)
|
||||||
|
md5_process_bytes (buffer, sum, &ctx);
|
||||||
|
|
||||||
|
/* Construct result in desired memory. */
|
||||||
|
md5_finish_ctx (&ctx, resblock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||||
|
result is always in little endian byte order, so that a byte-wise
|
||||||
|
output yields to the wanted ASCII representation of the message
|
||||||
|
digest. */
|
||||||
|
void *
|
||||||
|
md5_buffer (const char *buffer, size_t len, void *resblock)
|
||||||
|
{
|
||||||
|
struct md5_ctx ctx;
|
||||||
|
|
||||||
|
/* Initialize the computation context. */
|
||||||
|
md5_init_ctx (&ctx);
|
||||||
|
|
||||||
|
/* Process whole buffer but last len % 64 bytes. */
|
||||||
|
md5_process_bytes (buffer, len, &ctx);
|
||||||
|
|
||||||
|
/* Put result in desired memory area. */
|
||||||
|
return md5_finish_ctx (&ctx, resblock);
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
|
||||||
|
{
|
||||||
|
/* When we already have some bits in our internal buffer concatenate
|
||||||
|
both inputs first. */
|
||||||
|
if (ctx->buflen != 0)
|
||||||
|
{
|
||||||
|
size_t left_over = ctx->buflen;
|
||||||
|
size_t add = 128 - left_over > len ? len : 128 - left_over;
|
||||||
|
|
||||||
|
memcpy (&ctx->buffer[left_over], buffer, add);
|
||||||
|
ctx->buflen += add;
|
||||||
|
|
||||||
|
if (left_over + add > 64)
|
||||||
|
{
|
||||||
|
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx);
|
||||||
|
/* The regions in the following copy operation cannot overlap. */
|
||||||
|
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
|
||||||
|
(left_over + add) & 63);
|
||||||
|
ctx->buflen = (left_over + add) & 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = (const char *) buffer + add;
|
||||||
|
len -= add;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process available complete blocks. */
|
||||||
|
if (len > 64)
|
||||||
|
{
|
||||||
|
md5_process_block (buffer, len & ~63, ctx);
|
||||||
|
buffer = (const char *) buffer + (len & ~63);
|
||||||
|
len &= 63;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move remaining bytes in internal buffer. */
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
memcpy (ctx->buffer, buffer, len);
|
||||||
|
ctx->buflen = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* These are the four functions used in the four steps of the MD5 algorithm
|
||||||
|
and defined in the RFC 1321. The first function is a little bit optimized
|
||||||
|
(as found in Colin Plumbs public domain implementation). */
|
||||||
|
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
|
||||||
|
#define FF(b, c, d) (d ^ (b & (c ^ d)))
|
||||||
|
#define FG(b, c, d) FF (d, b, c)
|
||||||
|
#define FH(b, c, d) (b ^ c ^ d)
|
||||||
|
#define FI(b, c, d) (c ^ (b | ~d))
|
||||||
|
|
||||||
|
/* Process LEN bytes of BUFFER, accumulating context into CTX.
|
||||||
|
It is assumed that LEN % 64 == 0. */
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
|
||||||
|
{
|
||||||
|
md5_uint32 correct_words[16];
|
||||||
|
const md5_uint32 *words = (md5_uint32 *)buffer;
|
||||||
|
size_t nwords = len / sizeof (md5_uint32);
|
||||||
|
const md5_uint32 *endp = words + nwords;
|
||||||
|
md5_uint32 A = ctx->A;
|
||||||
|
md5_uint32 B = ctx->B;
|
||||||
|
md5_uint32 C = ctx->C;
|
||||||
|
md5_uint32 D = ctx->D;
|
||||||
|
|
||||||
|
/* First increment the byte count. RFC 1321 specifies the possible
|
||||||
|
length of the file up to 2^64 bits. Here we only compute the
|
||||||
|
number of bytes. Do a double word increment. */
|
||||||
|
ctx->total[0] += len;
|
||||||
|
if (ctx->total[0] < len)
|
||||||
|
++ctx->total[1];
|
||||||
|
|
||||||
|
/* Process all bytes in the buffer with 64 bytes in each round of
|
||||||
|
the loop. */
|
||||||
|
while (words < endp)
|
||||||
|
{
|
||||||
|
md5_uint32 *cwp = correct_words;
|
||||||
|
md5_uint32 A_save = A;
|
||||||
|
md5_uint32 B_save = B;
|
||||||
|
md5_uint32 C_save = C;
|
||||||
|
md5_uint32 D_save = D;
|
||||||
|
|
||||||
|
/* First round: using the given function, the context and a constant
|
||||||
|
the next context is computed. Because the algorithms processing
|
||||||
|
unit is a 32-bit word and it is determined to work on words in
|
||||||
|
little endian byte order we perhaps have to change the byte order
|
||||||
|
before the computation. To reduce the work for the next steps
|
||||||
|
we store the swapped words in the array CORRECT_WORDS. */
|
||||||
|
|
||||||
|
#define OP(a, b, c, d, s, T) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
|
||||||
|
++words; \
|
||||||
|
CYCLIC (a, s); \
|
||||||
|
a += b; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* It is unfortunate that C does not provide an operator for
|
||||||
|
cyclic rotation. Hope the C compiler is smart enough. */
|
||||||
|
#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
|
||||||
|
|
||||||
|
/* Before we start, one word to the strange constants.
|
||||||
|
They are defined in RFC 1321 as
|
||||||
|
|
||||||
|
T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Round 1. */
|
||||||
|
OP (A, B, C, D, 7, 0xd76aa478);
|
||||||
|
OP (D, A, B, C, 12, 0xe8c7b756);
|
||||||
|
OP (C, D, A, B, 17, 0x242070db);
|
||||||
|
OP (B, C, D, A, 22, 0xc1bdceee);
|
||||||
|
OP (A, B, C, D, 7, 0xf57c0faf);
|
||||||
|
OP (D, A, B, C, 12, 0x4787c62a);
|
||||||
|
OP (C, D, A, B, 17, 0xa8304613);
|
||||||
|
OP (B, C, D, A, 22, 0xfd469501);
|
||||||
|
OP (A, B, C, D, 7, 0x698098d8);
|
||||||
|
OP (D, A, B, C, 12, 0x8b44f7af);
|
||||||
|
OP (C, D, A, B, 17, 0xffff5bb1);
|
||||||
|
OP (B, C, D, A, 22, 0x895cd7be);
|
||||||
|
OP (A, B, C, D, 7, 0x6b901122);
|
||||||
|
OP (D, A, B, C, 12, 0xfd987193);
|
||||||
|
OP (C, D, A, B, 17, 0xa679438e);
|
||||||
|
OP (B, C, D, A, 22, 0x49b40821);
|
||||||
|
|
||||||
|
/* For the second to fourth round we have the possibly swapped words
|
||||||
|
in CORRECT_WORDS. Redefine the macro to take an additional first
|
||||||
|
argument specifying the function to use. */
|
||||||
|
#undef OP
|
||||||
|
#define OP(f, a, b, c, d, k, s, T) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
a += f (b, c, d) + correct_words[k] + T; \
|
||||||
|
CYCLIC (a, s); \
|
||||||
|
a += b; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Round 2. */
|
||||||
|
OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
|
||||||
|
OP (FG, D, A, B, C, 6, 9, 0xc040b340);
|
||||||
|
OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
|
||||||
|
OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
|
||||||
|
OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
|
||||||
|
OP (FG, D, A, B, C, 10, 9, 0x02441453);
|
||||||
|
OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
|
||||||
|
OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
|
||||||
|
OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
|
||||||
|
OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
|
||||||
|
OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
|
||||||
|
OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
|
||||||
|
OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
|
||||||
|
OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
|
||||||
|
OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
|
||||||
|
OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
|
||||||
|
|
||||||
|
/* Round 3. */
|
||||||
|
OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
|
||||||
|
OP (FH, D, A, B, C, 8, 11, 0x8771f681);
|
||||||
|
OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
|
||||||
|
OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
|
||||||
|
OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
|
||||||
|
OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
|
||||||
|
OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
|
||||||
|
OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
|
||||||
|
OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
|
||||||
|
OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
|
||||||
|
OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
|
||||||
|
OP (FH, B, C, D, A, 6, 23, 0x04881d05);
|
||||||
|
OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
|
||||||
|
OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
|
||||||
|
OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
|
||||||
|
OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
|
||||||
|
|
||||||
|
/* Round 4. */
|
||||||
|
OP (FI, A, B, C, D, 0, 6, 0xf4292244);
|
||||||
|
OP (FI, D, A, B, C, 7, 10, 0x432aff97);
|
||||||
|
OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
|
||||||
|
OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
|
||||||
|
OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
|
||||||
|
OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
|
||||||
|
OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
|
||||||
|
OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
|
||||||
|
OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
|
||||||
|
OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
|
||||||
|
OP (FI, C, D, A, B, 6, 15, 0xa3014314);
|
||||||
|
OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
|
||||||
|
OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
|
||||||
|
OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
|
||||||
|
OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
|
||||||
|
OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
|
||||||
|
|
||||||
|
/* Add the starting values of the context. */
|
||||||
|
A += A_save;
|
||||||
|
B += B_save;
|
||||||
|
C += C_save;
|
||||||
|
D += D_save;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put checksum in context given as argument. */
|
||||||
|
ctx->A = A;
|
||||||
|
ctx->B = B;
|
||||||
|
ctx->C = C;
|
||||||
|
ctx->D = D;
|
||||||
|
}
|
140
src/md5.h
Normal file
140
src/md5.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* md5.h - Declaration of functions and data types used for MD5 sum
|
||||||
|
computing library functions.
|
||||||
|
Copyright (C) 1995, 1996 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. */
|
||||||
|
|
||||||
|
#ifndef _MD5_H
|
||||||
|
#define _MD5_H 1
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined HAVE_LIMITS_H || _LIBC
|
||||||
|
# include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following contortions are an attempt to use the C preprocessor
|
||||||
|
to determine an unsigned integral type that is 32 bits wide. An
|
||||||
|
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||||
|
doing that would require that the configure script compile and *run*
|
||||||
|
the resulting executable. Locally running cross-compiled executables
|
||||||
|
is usually not possible. */
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <sys/types.h>
|
||||||
|
typedef u_int32_t md5_uint32;
|
||||||
|
#else
|
||||||
|
# if defined __STDC__ && __STDC__
|
||||||
|
# define UINT_MAX_32_BITS 4294967295U
|
||||||
|
# else
|
||||||
|
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||||
|
This should be valid for all systems GNU cares about because
|
||||||
|
that doesn't include 16-bit systems, and only modern systems
|
||||||
|
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||||
|
|
||||||
|
# ifndef UINT_MAX
|
||||||
|
# define UINT_MAX UINT_MAX_32_BITS
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if UINT_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned int md5_uint32;
|
||||||
|
# else
|
||||||
|
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned short md5_uint32;
|
||||||
|
# else
|
||||||
|
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned long md5_uint32;
|
||||||
|
# else
|
||||||
|
/* The following line is intended to evoke an error.
|
||||||
|
Using #error is not portable enough. */
|
||||||
|
"Cannot determine unsigned 32-bit data type."
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Structure to save state of computation between the single steps. */
|
||||||
|
struct md5_ctx
|
||||||
|
{
|
||||||
|
md5_uint32 A;
|
||||||
|
md5_uint32 B;
|
||||||
|
md5_uint32 C;
|
||||||
|
md5_uint32 D;
|
||||||
|
|
||||||
|
md5_uint32 total[2];
|
||||||
|
md5_uint32 buflen;
|
||||||
|
char buffer[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following three functions are build up the low level used in
|
||||||
|
* the functions `md5_stream' and `md5_buffer'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Initialize structure containing state of computation.
|
||||||
|
(RFC 1321, 3.3: Step 3) */
|
||||||
|
extern void md5_init_ctx PARAMS ((struct md5_ctx *ctx));
|
||||||
|
|
||||||
|
/* Starting with the result of former calls of this function (or the
|
||||||
|
initialization function update the context for the next LEN bytes
|
||||||
|
starting at BUFFER.
|
||||||
|
It is necessary that LEN is a multiple of 64!!! */
|
||||||
|
extern void md5_process_block PARAMS ((const void *buffer, size_t len,
|
||||||
|
struct md5_ctx *ctx));
|
||||||
|
|
||||||
|
/* Starting with the result of former calls of this function (or the
|
||||||
|
initialization function update the context for the next LEN bytes
|
||||||
|
starting at BUFFER.
|
||||||
|
It is NOT required that LEN is a multiple of 64. */
|
||||||
|
extern void md5_process_bytes PARAMS ((const void *buffer, size_t len,
|
||||||
|
struct md5_ctx *ctx));
|
||||||
|
|
||||||
|
/* Process the remaining bytes in the buffer and put result from CTX
|
||||||
|
in first 16 bytes following RESBUF. The result is always in little
|
||||||
|
endian byte order, so that a byte-wise output yields to the wanted
|
||||||
|
ASCII representation of the message digest.
|
||||||
|
|
||||||
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
|
aligned for a 32 bits value. */
|
||||||
|
extern void *md5_finish_ctx PARAMS ((struct md5_ctx *ctx, void *resbuf));
|
||||||
|
|
||||||
|
|
||||||
|
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||||
|
always in little endian byte order, so that a byte-wise output yields
|
||||||
|
to the wanted ASCII representation of the message digest.
|
||||||
|
|
||||||
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
|
aligned for a 32 bits value. */
|
||||||
|
extern void *md5_read_ctx PARAMS ((const struct md5_ctx *ctx, void *resbuf));
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute MD5 message digest for bytes read from STREAM. The
|
||||||
|
resulting message digest number will be written into the 16 bytes
|
||||||
|
beginning at RESBLOCK. */
|
||||||
|
extern int md5_stream PARAMS ((FILE *stream, void *resblock));
|
||||||
|
|
||||||
|
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
|
||||||
|
result is always in little endian byte order, so that a byte-wise
|
||||||
|
output yields to the wanted ASCII representation of the message
|
||||||
|
digest. */
|
||||||
|
extern void *md5_buffer PARAMS ((const char *buffer, size_t len,
|
||||||
|
void *resblock));
|
||||||
|
|
||||||
|
#endif
|
269
src/mswindows.c
Normal file
269
src/mswindows.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/* mswindows.c -- Windows-specific support
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* #### Someone document these functions! */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <winsock.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
|
char *argv0;
|
||||||
|
|
||||||
|
/* Defined in log.c. */
|
||||||
|
void redirect_output (const char *);
|
||||||
|
|
||||||
|
static int windows_nt_p;
|
||||||
|
|
||||||
|
|
||||||
|
/* Emulation of Unix sleep. */
|
||||||
|
unsigned int
|
||||||
|
sleep (unsigned seconds)
|
||||||
|
{
|
||||||
|
Sleep (1000 * seconds);
|
||||||
|
/* Unix sleep() is interruptible. To make it semi-usable, it
|
||||||
|
returns a value that says how much it "really" slept, or some
|
||||||
|
junk like that. Ignore it. */
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_registry (HKEY hkey, char *subkey, char *valuename, char *buf, int *len)
|
||||||
|
{
|
||||||
|
HKEY result;
|
||||||
|
DWORD size = *len;
|
||||||
|
DWORD type = REG_SZ;
|
||||||
|
if (RegOpenKeyEx (hkey, subkey, NULL, KEY_READ, &result) != ERROR_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
if (RegQueryValueEx (result, valuename, NULL, &type, buf, &size) != ERROR_SUCCESS)
|
||||||
|
buf = NULL;
|
||||||
|
*len = size;
|
||||||
|
RegCloseKey (result);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
pwd_cuserid (char *where)
|
||||||
|
{
|
||||||
|
char buf[32], *ptr;
|
||||||
|
int len = sizeof (buf);
|
||||||
|
if (GetUserName (buf, (LPDWORD) &len) == TRUE)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if (!!(ptr = getenv ("USERNAME")))
|
||||||
|
{
|
||||||
|
strcpy (buf, ptr);
|
||||||
|
}
|
||||||
|
else if (!read_registry (HKEY_LOCAL_MACHINE, "Network\\Logon",
|
||||||
|
"username", buf, &len))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (where)
|
||||||
|
{
|
||||||
|
strncpy (where, buf, len);
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
return xstrdup (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
windows_main_junk (int *argc, char **argv, char **exec_name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
argv0 = argv[0];
|
||||||
|
|
||||||
|
/* Remove .EXE from filename if it has one. */
|
||||||
|
*exec_name = xstrdup (*exec_name);
|
||||||
|
p = strrchr (*exec_name, '.');
|
||||||
|
if (p)
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Winsock stuff. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ws_cleanup (void)
|
||||||
|
{
|
||||||
|
WSACleanup ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ws_hangup (void)
|
||||||
|
{
|
||||||
|
redirect_output (_("\n\
|
||||||
|
CTRL+Break received, redirecting output to `%s'.\n\
|
||||||
|
Execution continued in background.\n\
|
||||||
|
You may stop Wget by pressing CTRL+ALT+DELETE.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fork_to_background (void)
|
||||||
|
{
|
||||||
|
/* Whether we arrange our own version of opt.lfilename here. */
|
||||||
|
int changedp = 0;
|
||||||
|
|
||||||
|
if (!opt.lfilename)
|
||||||
|
{
|
||||||
|
opt.lfilename = unique_name (DEFAULT_LOGFILE);
|
||||||
|
changedp = 1;
|
||||||
|
}
|
||||||
|
printf (_("Continuing in background.\n"));
|
||||||
|
if (changedp)
|
||||||
|
printf (_("Output will be written to `%s'.\n"), opt.lfilename);
|
||||||
|
|
||||||
|
ws_hangup ();
|
||||||
|
if (!windows_nt_p)
|
||||||
|
FreeConsole ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI
|
||||||
|
ws_handler (DWORD dwEvent)
|
||||||
|
{
|
||||||
|
switch (dwEvent)
|
||||||
|
{
|
||||||
|
#ifdef CTRLC_BACKGND
|
||||||
|
case CTRL_C_EVENT:
|
||||||
|
#endif
|
||||||
|
#ifdef CTRLBREAK_BACKGND
|
||||||
|
case CTRL_BREAK_EVENT:
|
||||||
|
#endif
|
||||||
|
fork_to_background ();
|
||||||
|
break;
|
||||||
|
case CTRL_SHUTDOWN_EVENT:
|
||||||
|
case CTRL_CLOSE_EVENT:
|
||||||
|
case CTRL_LOGOFF_EVENT:
|
||||||
|
default:
|
||||||
|
WSACleanup ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ws_changetitle (char *url, int nurl)
|
||||||
|
{
|
||||||
|
char *title_buf;
|
||||||
|
if (!nurl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
title_buf = (char *)xmalloc (strlen (url) + 20);
|
||||||
|
sprintf (title_buf, "Wget %s%s", url, nurl == 1 ? "" : " ...");
|
||||||
|
/* #### What are the semantics of SetConsoleTitle? Will it free the
|
||||||
|
given memory later? */
|
||||||
|
SetConsoleTitle (title_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ws_mypath (void)
|
||||||
|
{
|
||||||
|
static char *wspathsave;
|
||||||
|
char *buffer;
|
||||||
|
int rrr;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if (wspathsave)
|
||||||
|
{
|
||||||
|
return wspathsave;
|
||||||
|
}
|
||||||
|
ptr = strrchr (argv0, '\\');
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
*(ptr + 1) = '\0';
|
||||||
|
wspathsave = (char*) xmalloc (strlen(argv0)+1);
|
||||||
|
strcpy (wspathsave, argv0);
|
||||||
|
return wspathsave;
|
||||||
|
}
|
||||||
|
buffer = (char*) xmalloc (256);
|
||||||
|
rrr = SearchPath (NULL, argv0, strchr (argv0, '.') ? NULL : ".EXE",
|
||||||
|
256, buffer, &ptr);
|
||||||
|
if (rrr && rrr <= 256)
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
wspathsave = (char*) xmalloc (strlen(buffer)+1);
|
||||||
|
strcpy (wspathsave, buffer);
|
||||||
|
return wspathsave;
|
||||||
|
}
|
||||||
|
free (buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ws_help (const char *name)
|
||||||
|
{
|
||||||
|
char *mypath = ws_mypath ();
|
||||||
|
|
||||||
|
if (mypath)
|
||||||
|
{
|
||||||
|
struct stat sbuf;
|
||||||
|
char *buf = (char *)alloca (strlen (mypath) + strlen (name) + 4 + 1);
|
||||||
|
sprintf (buf, "%s%s.HLP", mypath, name);
|
||||||
|
if (stat (buf, &sbuf) == 0)
|
||||||
|
{
|
||||||
|
printf (_("Starting WinHelp %s\n"), buf);
|
||||||
|
WinHelp (NULL, buf, HELP_INDEX, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("%s: %s\n", buf, strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ws_startup (void)
|
||||||
|
{
|
||||||
|
WORD requested;
|
||||||
|
WSADATA data;
|
||||||
|
int err;
|
||||||
|
OSVERSIONINFO os;
|
||||||
|
|
||||||
|
if (GetVersionEx (&os) == TRUE
|
||||||
|
&& os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
|
||||||
|
windows_nt_p = 1;
|
||||||
|
|
||||||
|
requested = MAKEWORD (1, 1);
|
||||||
|
err = WSAStartup (requested, &data);
|
||||||
|
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
|
||||||
|
exec_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOBYTE (requested) < 1 || (LOBYTE (requested) == 1 &&
|
||||||
|
HIBYTE (requested) < 1))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: Couldn't find usable socket driver.\n"),
|
||||||
|
exec_name);
|
||||||
|
WSACleanup ();
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
atexit (ws_cleanup);
|
||||||
|
SetConsoleCtrlHandler (ws_handler, TRUE);
|
||||||
|
}
|
109
src/mswindows.h
Normal file
109
src/mswindows.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* Declarations for windows
|
||||||
|
Copyright (C) 1995, 1997, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef MSWINDOWS_H
|
||||||
|
#define MSWINDOWS_H
|
||||||
|
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
# define S_ISDIR(m) (((m) & (_S_IFMT)) == (_S_IFDIR))
|
||||||
|
#endif
|
||||||
|
#ifndef S_ISLNK
|
||||||
|
# define S_ISLNK(a) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We have strcasecmp and strncasecmp, just under a different name. */
|
||||||
|
#define strcasecmp stricmp
|
||||||
|
#define strncasecmp strnicmp
|
||||||
|
|
||||||
|
/* No stat on Windows. */
|
||||||
|
#define lstat stat
|
||||||
|
|
||||||
|
#define PATH_SEPARATOR '\\'
|
||||||
|
|
||||||
|
/* Microsoft says stat is _stat, Borland doesn't */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define stat _stat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REALCLOSE(x) closesocket (x)
|
||||||
|
|
||||||
|
/* read & write don't work with sockets on Windows 95. */
|
||||||
|
#define READ(fd, buf, cnt) recv ((fd), (buf), (cnt), 0)
|
||||||
|
#define WRITE(fd, buf, cnt) send ((fd), (buf), (cnt), 0)
|
||||||
|
|
||||||
|
/* #### Do we need this? */
|
||||||
|
#include <direct.h>
|
||||||
|
|
||||||
|
/* Windows compilers accept only one arg to mkdir. */
|
||||||
|
#ifndef __BORLANDC__
|
||||||
|
# define mkdir(a, b) _mkdir(a)
|
||||||
|
#else /* __BORLANDC__ */
|
||||||
|
# define mkdir(a, b) mkdir(a)
|
||||||
|
#endif /* __BORLANDC__ */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
/* Declarations of various socket errors: */
|
||||||
|
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define EINPROGRESS WSAEINPROGRESS
|
||||||
|
#define EALREADY WSAEALREADY
|
||||||
|
#define ENOTSOCK WSAENOTSOCK
|
||||||
|
#define EDESTADDRREQ WSAEDESTADDRREQ
|
||||||
|
#define EMSGSIZE WSAEMSGSIZE
|
||||||
|
#define EPROTOTYPE WSAEPROTOTYPE
|
||||||
|
#define ENOPROTOOPT WSAENOPROTOOPT
|
||||||
|
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
|
||||||
|
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
|
||||||
|
#define EOPNOTSUPP WSAEOPNOTSUPP
|
||||||
|
#define EPFNOSUPPORT WSAEPFNOSUPPORT
|
||||||
|
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||||
|
#define EADDRINUSE WSAEADDRINUSE
|
||||||
|
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
||||||
|
#define ENETDOWN WSAENETDOWN
|
||||||
|
#define ENETUNREACH WSAENETUNREACH
|
||||||
|
#define ENETRESET WSAENETRESET
|
||||||
|
#define ECONNABORTED WSAECONNABORTED
|
||||||
|
#define ECONNRESET WSAECONNRESET
|
||||||
|
#define ENOBUFS WSAENOBUFS
|
||||||
|
#define EISCONN WSAEISCONN
|
||||||
|
#define ENOTCONN WSAENOTCONN
|
||||||
|
#define ESHUTDOWN WSAESHUTDOWN
|
||||||
|
#define ETOOMANYREFS WSAETOOMANYREFS
|
||||||
|
#define ETIMEDOUT WSAETIMEDOUT
|
||||||
|
#define ECONNREFUSED WSAECONNREFUSED
|
||||||
|
#define ELOOP WSAELOOP
|
||||||
|
#define EHOSTDOWN WSAEHOSTDOWN
|
||||||
|
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||||
|
#define EPROCLIM WSAEPROCLIM
|
||||||
|
#define EUSERS WSAEUSERS
|
||||||
|
#define EDQUOT WSAEDQUOT
|
||||||
|
#define ESTALE WSAESTALE
|
||||||
|
#define EREMOTE WSAEREMOTE
|
||||||
|
|
||||||
|
/* Public functions. */
|
||||||
|
|
||||||
|
unsigned int sleep (unsigned);
|
||||||
|
void ws_startup (void);
|
||||||
|
void ws_changetitle (char*, int);
|
||||||
|
char *ws_mypath (void);
|
||||||
|
void ws_help (const char *);
|
||||||
|
void windows_main_junk (int *, char **, char **);
|
||||||
|
|
||||||
|
#endif /* MSWINDOWS_H */
|
490
src/netrc.c
Normal file
490
src/netrc.c
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
/* Read and parse the .netrc file to get hosts, accounts, and passwords.
|
||||||
|
Copyright (C) 1996, Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* This file used to be kept in synch with the code in Fetchmail, but
|
||||||
|
the latter has diverged since. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "netrc.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NETRC_FILE_NAME ".netrc"
|
||||||
|
|
||||||
|
acc_t *netrc_list;
|
||||||
|
|
||||||
|
static acc_t *parse_netrc PARAMS ((const char *));
|
||||||
|
|
||||||
|
/* Return the correct user and password, given the host, user (as
|
||||||
|
given in the URL), and password (as given in the URL). May return
|
||||||
|
NULL.
|
||||||
|
|
||||||
|
If SLACK_DEFAULT is set, allow looking for a "default" account.
|
||||||
|
You will typically turn it off for HTTP. */
|
||||||
|
void
|
||||||
|
search_netrc (const char *host, const char **acc, const char **passwd,
|
||||||
|
int slack_default)
|
||||||
|
{
|
||||||
|
acc_t *l;
|
||||||
|
static int processed_netrc;
|
||||||
|
|
||||||
|
if (!opt.netrc)
|
||||||
|
return;
|
||||||
|
/* Find ~/.netrc. */
|
||||||
|
if (!processed_netrc)
|
||||||
|
{
|
||||||
|
char *home = home_dir();
|
||||||
|
|
||||||
|
netrc_list = NULL;
|
||||||
|
processed_netrc = 1;
|
||||||
|
if (home)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct stat buf;
|
||||||
|
char *path = (char *)alloca (strlen (home) + 1
|
||||||
|
+ strlen (NETRC_FILE_NAME) + 1);
|
||||||
|
sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
|
||||||
|
free (home);
|
||||||
|
err = stat (path, &buf);
|
||||||
|
if (err == 0)
|
||||||
|
netrc_list = parse_netrc (path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If nothing to do... */
|
||||||
|
if (!netrc_list)
|
||||||
|
return;
|
||||||
|
/* Acc and password found; all OK. */
|
||||||
|
if (*acc && *passwd)
|
||||||
|
return;
|
||||||
|
if (!*acc && !slack_default)
|
||||||
|
return;
|
||||||
|
/* Some data not given -- try finding the host. */
|
||||||
|
for (l = netrc_list; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (!l->host)
|
||||||
|
continue;
|
||||||
|
else if (!strcasecmp (l->host, host))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l)
|
||||||
|
{
|
||||||
|
if (*acc)
|
||||||
|
{
|
||||||
|
/* Looking for password in .netrc. */
|
||||||
|
if (!strcmp (l->acc, *acc))
|
||||||
|
*passwd = l->passwd; /* usernames match; password OK */
|
||||||
|
else
|
||||||
|
*passwd = NULL; /* usernames don't match */
|
||||||
|
}
|
||||||
|
else /* NOT *acc */
|
||||||
|
{
|
||||||
|
/* If password was given, use it. The account is l->acc. */
|
||||||
|
*acc = l->acc;
|
||||||
|
if (l->passwd)
|
||||||
|
*passwd = l->passwd;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!slack_default)
|
||||||
|
return;
|
||||||
|
if (*acc)
|
||||||
|
return;
|
||||||
|
/* Try looking for the default account. */
|
||||||
|
for (l = netrc_list; l; l = l->next)
|
||||||
|
if (!l->host)
|
||||||
|
break;
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
*acc = l->acc;
|
||||||
|
if (!*passwd)
|
||||||
|
*passwd = l->passwd;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef STANDALONE
|
||||||
|
/* Normally, these functions would be defined by your package. */
|
||||||
|
# define xmalloc malloc
|
||||||
|
# define xstrdup strdup
|
||||||
|
|
||||||
|
/* The function reads a whole line. It reads the line realloc-ing the
|
||||||
|
storage exponentially, doubling the storage after each overflow to
|
||||||
|
minimize the number of calls to realloc().
|
||||||
|
|
||||||
|
It is not an exemplary of correctness, since it kills off the
|
||||||
|
newline (and no, there is no way to know if there was a newline at
|
||||||
|
EOF). */
|
||||||
|
# define xrealloc realloc
|
||||||
|
# define DYNAMIC_LINE_BUFFER 40
|
||||||
|
|
||||||
|
char *
|
||||||
|
read_whole_line (FILE *fp)
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
int i, bufsize, c;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
bufsize = DYNAMIC_LINE_BUFFER;
|
||||||
|
line = xmalloc(bufsize);
|
||||||
|
/* Construct the line. */
|
||||||
|
while ((c = getc(fp)) != EOF && c != '\n')
|
||||||
|
{
|
||||||
|
if (i > bufsize - 1)
|
||||||
|
line = (char *)xrealloc(line, (bufsize <<= 1));
|
||||||
|
line[i++] = c;
|
||||||
|
}
|
||||||
|
if (c == EOF && !i)
|
||||||
|
{
|
||||||
|
free(line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for overflow at zero-termination (no need to double the
|
||||||
|
buffer in this case. */
|
||||||
|
if (i == bufsize)
|
||||||
|
line = (char *)xrealloc(line, i + 1);
|
||||||
|
line[i] = '\0';
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* STANDALONE */
|
||||||
|
|
||||||
|
/* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is
|
||||||
|
set to a ready-to-use acc_t, in any event. */
|
||||||
|
static void
|
||||||
|
maybe_add_to_list (acc_t **newentry, acc_t **list)
|
||||||
|
{
|
||||||
|
acc_t *a, *l;
|
||||||
|
a = *newentry;
|
||||||
|
l = *list;
|
||||||
|
|
||||||
|
/* We need an account name in order to add the entry to the list. */
|
||||||
|
if (a && ! a->acc)
|
||||||
|
{
|
||||||
|
/* Free any allocated space. */
|
||||||
|
free (a->host);
|
||||||
|
free (a->acc);
|
||||||
|
free (a->passwd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
/* Add the current machine into our list. */
|
||||||
|
a->next = l;
|
||||||
|
l = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new acc_t structure. */
|
||||||
|
a = (acc_t *)xmalloc (sizeof (acc_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero the structure, so that it is ready to use. */
|
||||||
|
memset (a, 0, sizeof(*a));
|
||||||
|
|
||||||
|
/* Return the new pointers. */
|
||||||
|
*newentry = a;
|
||||||
|
*list = l;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse a .netrc file (as described in the ftp(1) manual page). */
|
||||||
|
static acc_t *
|
||||||
|
parse_netrc (const char *path)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *line, *p, *tok, *premature_token;
|
||||||
|
acc_t *current, *retval;
|
||||||
|
int ln;
|
||||||
|
|
||||||
|
/* The latest token we've seen in the file. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
tok_nothing, tok_account, tok_login, tok_macdef, tok_machine, tok_password
|
||||||
|
} last_token = tok_nothing;
|
||||||
|
|
||||||
|
current = retval = NULL;
|
||||||
|
|
||||||
|
fp = fopen (path, "r");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
|
||||||
|
path, strerror (errno));
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the file data. */
|
||||||
|
ln = 0;
|
||||||
|
premature_token = NULL;
|
||||||
|
|
||||||
|
/* While there are lines in the file... */
|
||||||
|
while ((line = read_whole_line (fp)))
|
||||||
|
{
|
||||||
|
ln ++;
|
||||||
|
|
||||||
|
/* Parse the line. */
|
||||||
|
p = line;
|
||||||
|
|
||||||
|
/* If the line is empty, then end any macro definition. */
|
||||||
|
if (last_token == tok_macdef && !*p)
|
||||||
|
/* End of macro if the line is empty. */
|
||||||
|
last_token = tok_nothing;
|
||||||
|
|
||||||
|
/* If we are defining macros, then skip parsing the line. */
|
||||||
|
while (*p && last_token != tok_macdef)
|
||||||
|
{
|
||||||
|
/* Skip any whitespace. */
|
||||||
|
while (*p && ISSPACE (*p))
|
||||||
|
p ++;
|
||||||
|
|
||||||
|
/* Discard end-of-line comments. */
|
||||||
|
if (*p == '#')
|
||||||
|
break;
|
||||||
|
|
||||||
|
tok = p;
|
||||||
|
|
||||||
|
/* Find the end of the token. */
|
||||||
|
while (*p && !ISSPACE (*p))
|
||||||
|
p ++;
|
||||||
|
|
||||||
|
/* Null-terminate the token, if it isn't already. */
|
||||||
|
if (*p)
|
||||||
|
*p ++ = '\0';
|
||||||
|
|
||||||
|
switch (last_token)
|
||||||
|
{
|
||||||
|
case tok_login:
|
||||||
|
if (current)
|
||||||
|
current->acc = xstrdup (tok);
|
||||||
|
else
|
||||||
|
premature_token = "login";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tok_machine:
|
||||||
|
/* Start a new machine entry. */
|
||||||
|
maybe_add_to_list (¤t, &retval);
|
||||||
|
current->host = xstrdup (tok);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tok_password:
|
||||||
|
if (current)
|
||||||
|
current->passwd = xstrdup (tok);
|
||||||
|
else
|
||||||
|
premature_token = "password";
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We handle most of tok_macdef above. */
|
||||||
|
case tok_macdef:
|
||||||
|
if (!current)
|
||||||
|
premature_token = "macdef";
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We don't handle the account keyword at all. */
|
||||||
|
case tok_account:
|
||||||
|
if (!current)
|
||||||
|
premature_token = "account";
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* We handle tok_nothing below this switch. */
|
||||||
|
case tok_nothing:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (premature_token)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("\
|
||||||
|
%s: %s:%d: warning: \"%s\" token appears before any machine name\n"),
|
||||||
|
exec_name, path, ln, premature_token);
|
||||||
|
premature_token = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_token != tok_nothing)
|
||||||
|
/* We got a value, so reset the token state. */
|
||||||
|
last_token = tok_nothing;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fetch the next token. */
|
||||||
|
if (!strcmp (tok, "account"))
|
||||||
|
last_token = tok_account;
|
||||||
|
else if (!strcmp (tok, "default"))
|
||||||
|
{
|
||||||
|
maybe_add_to_list (¤t, &retval);
|
||||||
|
}
|
||||||
|
else if (!strcmp (tok, "login"))
|
||||||
|
last_token = tok_login;
|
||||||
|
|
||||||
|
else if (!strcmp (tok, "macdef"))
|
||||||
|
last_token = tok_macdef;
|
||||||
|
|
||||||
|
else if (!strcmp (tok, "machine"))
|
||||||
|
last_token = tok_machine;
|
||||||
|
|
||||||
|
else if (!strcmp (tok, "password"))
|
||||||
|
last_token = tok_password;
|
||||||
|
|
||||||
|
else
|
||||||
|
fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
|
||||||
|
exec_name, path, ln, tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (fp);
|
||||||
|
|
||||||
|
/* Finalize the last machine entry we found. */
|
||||||
|
maybe_add_to_list (¤t, &retval);
|
||||||
|
free (current);
|
||||||
|
|
||||||
|
/* Reverse the order of the list so that it appears in file order. */
|
||||||
|
current = retval;
|
||||||
|
retval = NULL;
|
||||||
|
while (current)
|
||||||
|
{
|
||||||
|
acc_t *saved_reference;
|
||||||
|
|
||||||
|
/* Change the direction of the pointers. */
|
||||||
|
saved_reference = current->next;
|
||||||
|
current->next = retval;
|
||||||
|
|
||||||
|
/* Advance to the next node. */
|
||||||
|
retval = current;
|
||||||
|
current = saved_reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Free a netrc list. */
|
||||||
|
void
|
||||||
|
free_netrc(acc_t *l)
|
||||||
|
{
|
||||||
|
acc_t *t;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
t = l->next;
|
||||||
|
FREE_MAYBE (l->acc);
|
||||||
|
FREE_MAYBE (l->passwd);
|
||||||
|
FREE_MAYBE (l->host);
|
||||||
|
free(l);
|
||||||
|
l = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef STANDALONE
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
char *program_name, *file, *target;
|
||||||
|
acc_t *head, *a;
|
||||||
|
|
||||||
|
if (argc < 2 || argc > 3)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("Usage: %s NETRC [HOSTNAME]\n"), argv[0]);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
program_name = argv[0];
|
||||||
|
file = argv[1];
|
||||||
|
target = argv[2];
|
||||||
|
|
||||||
|
if (stat (file, &sb))
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("%s: cannot stat %s: %s\n"), argv[0], file,
|
||||||
|
strerror (errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
head = parse_netrc (file);
|
||||||
|
a = head;
|
||||||
|
while (a)
|
||||||
|
{
|
||||||
|
/* Skip if we have a target and this isn't it. */
|
||||||
|
if (target && a->host && strcmp (target, a->host))
|
||||||
|
{
|
||||||
|
a = a->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
/* Print the host name if we have no target. */
|
||||||
|
if (a->host)
|
||||||
|
fputs (a->host, stdout);
|
||||||
|
else
|
||||||
|
fputs ("DEFAULT", stdout);
|
||||||
|
|
||||||
|
fputc (' ', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the account name. */
|
||||||
|
fputs (a->acc, stdout);
|
||||||
|
|
||||||
|
if (a->passwd)
|
||||||
|
{
|
||||||
|
/* Print the password, if there is any. */
|
||||||
|
fputc (' ', stdout);
|
||||||
|
fputs (a->passwd, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc ('\n', stdout);
|
||||||
|
|
||||||
|
/* Exit if we found the target. */
|
||||||
|
if (target)
|
||||||
|
exit (0);
|
||||||
|
a = a->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit with failure if we had a target, success otherwise. */
|
||||||
|
if (target)
|
||||||
|
exit (1);
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
#endif /* STANDALONE */
|
30
src/netrc.h
Normal file
30
src/netrc.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* Declarations for netrc.c
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
typedef struct _acc_t
|
||||||
|
{
|
||||||
|
char *host; /* NULL if this is the default machine
|
||||||
|
entry. */
|
||||||
|
char *acc;
|
||||||
|
char *passwd; /* NULL if there is no password. */
|
||||||
|
struct _acc_t *next;
|
||||||
|
} acc_t;
|
||||||
|
|
||||||
|
void search_netrc PARAMS((const char *, const char **, const char **, int));
|
||||||
|
void free_netrc PARAMS((acc_t *l));
|
139
src/options.h
Normal file
139
src/options.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/* struct options.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* Needed for FDP. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct options
|
||||||
|
{
|
||||||
|
int verbose; /* Are we verbose? */
|
||||||
|
int quiet; /* Are we quiet? */
|
||||||
|
int ntry; /* Number of tries per URL */
|
||||||
|
int background; /* Whether we should work in background. */
|
||||||
|
int kill_longer; /* Do we reject messages with *more*
|
||||||
|
data than specified in
|
||||||
|
content-length? */
|
||||||
|
int ignore_length; /* Do we heed content-length at all? */
|
||||||
|
int recursive; /* Are we recursive? */
|
||||||
|
int spanhost; /* Do we span across hosts in
|
||||||
|
recursion? */
|
||||||
|
int relative_only; /* Follow only relative links. */
|
||||||
|
int no_parent; /* Restrict access to the parent
|
||||||
|
directory. */
|
||||||
|
int simple_check; /* Should we use simple checking
|
||||||
|
(strcmp) or do we create a host
|
||||||
|
hash and call gethostbyname? */
|
||||||
|
int reclevel; /* Maximum level of recursion */
|
||||||
|
int dirstruct; /* Do we build the directory structure
|
||||||
|
as we go along? */
|
||||||
|
int no_dirstruct; /* Do we hate dirstruct? */
|
||||||
|
int cut_dirs; /* Number of directory components to cut. */
|
||||||
|
int add_hostdir; /* Do we add hostname directory? */
|
||||||
|
int noclobber; /* Disables clobbering of existing
|
||||||
|
data. */
|
||||||
|
char *dir_prefix; /* The top of directory tree */
|
||||||
|
char *lfilename; /* Log filename */
|
||||||
|
int no_flush; /* If non-zero, inhibit flushing log. */
|
||||||
|
char *input_filename; /* Input filename */
|
||||||
|
int force_html; /* Is the input file an HTML file? */
|
||||||
|
|
||||||
|
int spider; /* Is Wget in spider mode? */
|
||||||
|
|
||||||
|
char **accepts; /* List of patterns to accept. */
|
||||||
|
char **rejects; /* List of patterns to reject. */
|
||||||
|
char **excludes; /* List of excluded FTP directories. */
|
||||||
|
char **includes; /* List of FTP directories to
|
||||||
|
follow. */
|
||||||
|
|
||||||
|
char **domains; /* See host.c */
|
||||||
|
char **exclude_domains;
|
||||||
|
|
||||||
|
int follow_ftp; /* Are FTP URL-s followed in recursive
|
||||||
|
retrieving? */
|
||||||
|
int retr_symlinks; /* Whether we retrieve symlinks in
|
||||||
|
FTP. */
|
||||||
|
char *output_document; /* The output file to which the
|
||||||
|
documents will be printed. */
|
||||||
|
FILE *dfp; /* The file pointer to the output
|
||||||
|
document. */
|
||||||
|
|
||||||
|
int always_rest; /* Always use REST. */
|
||||||
|
char *ftp_acc; /* FTP username */
|
||||||
|
char *ftp_pass; /* FTP password */
|
||||||
|
int netrc; /* Whether to read .netrc. */
|
||||||
|
int ftp_glob; /* FTP globbing */
|
||||||
|
int ftp_pasv; /* Passive FTP. */
|
||||||
|
|
||||||
|
char *http_user; /* HTTP user. */
|
||||||
|
char *http_passwd; /* HTTP password. */
|
||||||
|
char *user_header; /* User-defined header(s). */
|
||||||
|
|
||||||
|
int use_proxy; /* Do we use proxy? */
|
||||||
|
int proxy_cache; /* Do we load from proxy cache? */
|
||||||
|
char *http_proxy, *ftp_proxy;
|
||||||
|
char **no_proxy;
|
||||||
|
char *base_href;
|
||||||
|
char *proxy_user; /*oli*/
|
||||||
|
char *proxy_passwd;
|
||||||
|
#ifdef HAVE_SELECT
|
||||||
|
long timeout; /* The value of read timeout in
|
||||||
|
seconds. */
|
||||||
|
#endif
|
||||||
|
long wait; /* The wait period between retries. */
|
||||||
|
int use_robots; /* Do we heed robots.txt? */
|
||||||
|
|
||||||
|
long quota; /* Maximum number of bytes to
|
||||||
|
retrieve. */
|
||||||
|
long downloaded; /* How much we downloaded already. */
|
||||||
|
int numurls; /* Number of successfully downloaded
|
||||||
|
URLs */
|
||||||
|
|
||||||
|
int server_response; /* Do we print server response? */
|
||||||
|
int save_headers; /* Do we save headers together with
|
||||||
|
file? */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
int debug; /* Debugging on/off */
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
int timestamping; /* Whether to use time-stamping. */
|
||||||
|
int backups; /* Are backups made? */
|
||||||
|
|
||||||
|
char *useragent; /* Naughty User-Agent, which can be
|
||||||
|
set to something other than
|
||||||
|
Wget. */
|
||||||
|
int convert_links; /* Will the links be converted
|
||||||
|
locally? */
|
||||||
|
int remove_listing; /* Do we remove .listing files
|
||||||
|
generated by FTP? */
|
||||||
|
int htmlify; /* Do we HTML-ify the OS-dependent
|
||||||
|
listings? */
|
||||||
|
|
||||||
|
long dot_bytes; /* How many bytes in a printing
|
||||||
|
dot. */
|
||||||
|
int dots_in_line; /* How many dots in one line. */
|
||||||
|
int dot_spacing; /* How many dots between spacings. */
|
||||||
|
|
||||||
|
int delete_after; /* Whether the files will be deleted
|
||||||
|
after download. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef OPTIONS_DEFINED_HERE
|
||||||
|
extern struct options opt;
|
||||||
|
#endif
|
102
src/rbuf.c
Normal file
102
src/rbuf.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/* Buffering read.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 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 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* This is a simple implementation of buffering IO-read functions. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "rbuf.h"
|
||||||
|
#include "connect.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
rbuf_initialize (struct rbuf *rbuf, int fd)
|
||||||
|
{
|
||||||
|
rbuf->fd = fd;
|
||||||
|
rbuf->buffer_pos = rbuf->buffer;
|
||||||
|
rbuf->buffer_left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rbuf_initialized_p (struct rbuf *rbuf)
|
||||||
|
{
|
||||||
|
return rbuf->fd != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rbuf_uninitialize (struct rbuf *rbuf)
|
||||||
|
{
|
||||||
|
rbuf->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Currently unused -- see RBUF_READCHAR. */
|
||||||
|
#if 0
|
||||||
|
/* Function version of RBUF_READCHAR. */
|
||||||
|
int
|
||||||
|
rbuf_readchar (struct rbuf *rbuf, char *store)
|
||||||
|
{
|
||||||
|
return RBUF_READCHAR (rbuf, store);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Like rbuf_readchar(), only don't move the buffer position. */
|
||||||
|
int
|
||||||
|
rbuf_peek (struct rbuf *rbuf, char *store)
|
||||||
|
{
|
||||||
|
if (!rbuf->buffer_left)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
rbuf->buffer_pos = rbuf->buffer;
|
||||||
|
rbuf->buffer_left = 0;
|
||||||
|
res = iread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer));
|
||||||
|
if (res <= 0)
|
||||||
|
return res;
|
||||||
|
rbuf->buffer_left = res;
|
||||||
|
}
|
||||||
|
*store = *rbuf->buffer_pos;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush RBUF's buffer to WHERE. Flush MAXSIZE bytes at most.
|
||||||
|
Returns the number of bytes actually copied. If the buffer is
|
||||||
|
empty, 0 is returned. */
|
||||||
|
int
|
||||||
|
rbuf_flush (struct rbuf *rbuf, char *where, int maxsize)
|
||||||
|
{
|
||||||
|
if (!rbuf->buffer_left)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int howmuch = MINVAL (rbuf->buffer_left, maxsize);
|
||||||
|
|
||||||
|
if (where)
|
||||||
|
memcpy (where, rbuf->buffer_pos, howmuch);
|
||||||
|
rbuf->buffer_left -= howmuch;
|
||||||
|
rbuf->buffer_pos += howmuch;
|
||||||
|
return howmuch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Discard any cached data in RBUF. */
|
||||||
|
void
|
||||||
|
rbuf_discard (struct rbuf *rbuf)
|
||||||
|
{
|
||||||
|
rbuf->buffer_left = 0;
|
||||||
|
rbuf->buffer_pos = rbuf->buffer;
|
||||||
|
}
|
70
src/rbuf.h
Normal file
70
src/rbuf.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* Declarations for rbuf.c.
|
||||||
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef RBUF_H
|
||||||
|
#define RBUF_H
|
||||||
|
|
||||||
|
/* Retrieval stream */
|
||||||
|
struct rbuf
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buffer[4096]; /* the input buffer */
|
||||||
|
char *buffer_pos; /* current position in the buffer */
|
||||||
|
size_t buffer_left; /* number of bytes left in the buffer:
|
||||||
|
buffer_left = buffer_end - buffer_pos */
|
||||||
|
int internal_dont_touch_this; /* used by RBUF_READCHAR macro */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Read a character from RBUF. If there is anything in the buffer,
|
||||||
|
the character is returned from the buffer. Otherwise, refill the
|
||||||
|
buffer and return the first character.
|
||||||
|
|
||||||
|
The return value is the same as with read(2). On buffered read,
|
||||||
|
the function returns 1.
|
||||||
|
|
||||||
|
#### That return value is totally screwed up, and is a direct
|
||||||
|
result of historical implementation of header code. The macro
|
||||||
|
should return the character or EOF, and in case of error store it
|
||||||
|
to rbuf->err or something. */
|
||||||
|
#define RBUF_READCHAR(rbuf, store) \
|
||||||
|
((rbuf)->buffer_left \
|
||||||
|
? (--(rbuf)->buffer_left, \
|
||||||
|
*((char *) (store)) = *(rbuf)->buffer_pos++, 1) \
|
||||||
|
: ((rbuf)->buffer_pos = (rbuf)->buffer, \
|
||||||
|
((((rbuf)->internal_dont_touch_this \
|
||||||
|
= iread ((rbuf)->fd, (rbuf)->buffer, \
|
||||||
|
sizeof ((rbuf)->buffer))) <= 0) \
|
||||||
|
? (rbuf)->internal_dont_touch_this \
|
||||||
|
: ((rbuf)->buffer_left = (rbuf)->internal_dont_touch_this - 1, \
|
||||||
|
*((char *) (store)) = *(rbuf)->buffer_pos++, \
|
||||||
|
1))))
|
||||||
|
|
||||||
|
/* Return the file descriptor of RBUF. */
|
||||||
|
#define RBUF_FD(rbuf) ((rbuf)->fd)
|
||||||
|
|
||||||
|
/* Function declarations */
|
||||||
|
void rbuf_initialize PARAMS ((struct rbuf *, int));
|
||||||
|
int rbuf_initialized_p PARAMS ((struct rbuf *));
|
||||||
|
void rbuf_uninitialize PARAMS ((struct rbuf *));
|
||||||
|
int rbuf_readchar PARAMS ((struct rbuf *, char *));
|
||||||
|
int rbuf_peek PARAMS ((struct rbuf *, char *));
|
||||||
|
int rbuf_flush PARAMS ((struct rbuf *, char *, int));
|
||||||
|
void rbuf_discard PARAMS ((struct rbuf *));
|
||||||
|
|
||||||
|
#endif /* RBUF_H */
|
820
src/recur.c
Normal file
820
src/recur.c
Normal file
@ -0,0 +1,820 @@
|
|||||||
|
/* Handling of recursive HTTP retrieving.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "url.h"
|
||||||
|
#include "recur.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "retr.h"
|
||||||
|
#include "ftp.h"
|
||||||
|
#include "fnmatch.h"
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
extern char *version_string;
|
||||||
|
|
||||||
|
#define ROBOTS_FILENAME "robots.txt"
|
||||||
|
|
||||||
|
/* #### Many of these lists should really be hashtables! */
|
||||||
|
|
||||||
|
/* List of downloaded URLs. */
|
||||||
|
static urlpos *urls_downloaded;
|
||||||
|
|
||||||
|
/* List of HTML URLs. */
|
||||||
|
static slist *urls_html;
|
||||||
|
|
||||||
|
/* List of undesirable-to-load URLs. */
|
||||||
|
static slist *ulist;
|
||||||
|
|
||||||
|
/* List of forbidden locations. */
|
||||||
|
static char **forbidden = NULL;
|
||||||
|
|
||||||
|
/* Current recursion depth. */
|
||||||
|
static int depth;
|
||||||
|
|
||||||
|
/* Base directory we're recursing from (used by no_parent). */
|
||||||
|
static char *base_dir;
|
||||||
|
|
||||||
|
/* The host name for which we last checked robots. */
|
||||||
|
static char *robots_host;
|
||||||
|
|
||||||
|
static int first_time = 1;
|
||||||
|
|
||||||
|
/* Construct the robots URL. */
|
||||||
|
static struct urlinfo *robots_url PARAMS ((const char *, const char *));
|
||||||
|
static uerr_t retrieve_robots PARAMS ((const char *, const char *));
|
||||||
|
static char **parse_robots PARAMS ((const char *));
|
||||||
|
static int robots_match PARAMS ((struct urlinfo *, char **));
|
||||||
|
|
||||||
|
|
||||||
|
/* Cleanup the data structures associated with recursive retrieving
|
||||||
|
(the variables above). */
|
||||||
|
void
|
||||||
|
recursive_cleanup (void)
|
||||||
|
{
|
||||||
|
free_slist (ulist);
|
||||||
|
ulist = NULL;
|
||||||
|
free_vec (forbidden);
|
||||||
|
forbidden = NULL;
|
||||||
|
free_slist (urls_html);
|
||||||
|
urls_html = NULL;
|
||||||
|
free_urlpos (urls_downloaded);
|
||||||
|
urls_downloaded = NULL;
|
||||||
|
FREE_MAYBE (base_dir);
|
||||||
|
FREE_MAYBE (robots_host);
|
||||||
|
first_time = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset FIRST_TIME to 1, so that some action can be taken in
|
||||||
|
recursive_retrieve(). */
|
||||||
|
void
|
||||||
|
recursive_reset (void)
|
||||||
|
{
|
||||||
|
first_time = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The core of recursive retrieving. Endless recursion is avoided by
|
||||||
|
having all URL-s stored to a linked list of URL-s, which is checked
|
||||||
|
before loading any URL. That way no URL can get loaded twice.
|
||||||
|
|
||||||
|
The function also supports specification of maximum recursion depth
|
||||||
|
and a number of other goodies. */
|
||||||
|
uerr_t
|
||||||
|
recursive_retrieve (const char *file, const char *this_url)
|
||||||
|
{
|
||||||
|
char *constr, *filename, *newloc;
|
||||||
|
char *canon_this_url = NULL;
|
||||||
|
int dt, inl;
|
||||||
|
int this_url_ftp; /* See below the explanation */
|
||||||
|
uerr_t err;
|
||||||
|
struct urlinfo *rurl;
|
||||||
|
urlpos *url_list, *cur_url;
|
||||||
|
char *rfile; /* For robots */
|
||||||
|
struct urlinfo *u;
|
||||||
|
|
||||||
|
assert (this_url != NULL);
|
||||||
|
assert (file != NULL);
|
||||||
|
/* If quota was exceeded earlier, bail out. */
|
||||||
|
if (opt.quota && (opt.downloaded > opt.quota))
|
||||||
|
return QUOTEXC;
|
||||||
|
/* Cache the current URL in the list. */
|
||||||
|
if (first_time)
|
||||||
|
{
|
||||||
|
ulist = add_slist (ulist, this_url, 0);
|
||||||
|
urls_downloaded = NULL;
|
||||||
|
urls_html = NULL;
|
||||||
|
/* Enter this_url to the slist, in original and "enhanced" form. */
|
||||||
|
u = newurl ();
|
||||||
|
err = parseurl (this_url, u, 0);
|
||||||
|
if (err == URLOK)
|
||||||
|
{
|
||||||
|
ulist = add_slist (ulist, u->url, 0);
|
||||||
|
urls_downloaded = add_url (urls_downloaded, u->url, file);
|
||||||
|
urls_html = add_slist (urls_html, file, NOSORT);
|
||||||
|
if (opt.no_parent)
|
||||||
|
base_dir = xstrdup (u->dir); /* Set the base dir. */
|
||||||
|
/* Set the canonical this_url to be sent as referer. This
|
||||||
|
problem exists only when running the first time. */
|
||||||
|
canon_this_url = xstrdup (u->url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUGP (("Double yuck! The *base* URL is broken.\n"));
|
||||||
|
base_dir = NULL;
|
||||||
|
}
|
||||||
|
freeurl (u, 1);
|
||||||
|
depth = 1;
|
||||||
|
robots_host = NULL;
|
||||||
|
forbidden = NULL;
|
||||||
|
first_time = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++depth;
|
||||||
|
|
||||||
|
/* Bail out if opt.reclevel is exceeded. */
|
||||||
|
if ((opt.reclevel != 0) && (depth > opt.reclevel))
|
||||||
|
{
|
||||||
|
DEBUGP (("Recursion depth %d exceeded max. depth %d.\n",
|
||||||
|
depth, opt.reclevel));
|
||||||
|
--depth;
|
||||||
|
return RECLEVELEXC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine whether this_url is an FTP URL. If it is, it means
|
||||||
|
that the retrieval is done through proxy. In that case, FTP
|
||||||
|
links will be followed by default and recursion will not be
|
||||||
|
turned off when following them. */
|
||||||
|
this_url_ftp = (urlproto (this_url) == URLFTP);
|
||||||
|
|
||||||
|
/* Get the URL-s from an HTML file: */
|
||||||
|
url_list = get_urls_html (file,
|
||||||
|
canon_this_url ? canon_this_url : this_url, 0);
|
||||||
|
|
||||||
|
/* Decide what to do with each of the URLs. A URL will be loaded if
|
||||||
|
it meets several requirements, discussed later. */
|
||||||
|
for (cur_url = url_list; cur_url; cur_url = cur_url->next)
|
||||||
|
{
|
||||||
|
/* If quota was exceeded earlier, bail out. */
|
||||||
|
if (opt.quota && (opt.downloaded > opt.quota))
|
||||||
|
break;
|
||||||
|
/* Parse the URL for convenient use in other functions, as well
|
||||||
|
as to get the optimized form. It also checks URL integrity. */
|
||||||
|
u = newurl ();
|
||||||
|
if (parseurl (cur_url->url, u, 0) != URLOK)
|
||||||
|
{
|
||||||
|
DEBUGP (("Yuck! A bad URL.\n"));
|
||||||
|
freeurl (u, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (u->proto == URLFILE)
|
||||||
|
{
|
||||||
|
DEBUGP (("Nothing to do with file:// around here.\n"));
|
||||||
|
freeurl (u, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert (u->url != NULL);
|
||||||
|
constr = xstrdup (u->url);
|
||||||
|
|
||||||
|
/* Several checkings whether a file is acceptable to load:
|
||||||
|
1. check if URL is ftp, and we don't load it
|
||||||
|
2. check for relative links (if relative_only is set)
|
||||||
|
3. check for domain
|
||||||
|
4. check for no-parent
|
||||||
|
5. check for excludes && includes
|
||||||
|
6. check for suffix
|
||||||
|
7. check for same host (if spanhost is unset), with possible
|
||||||
|
gethostbyname baggage
|
||||||
|
8. check for robots.txt
|
||||||
|
|
||||||
|
Addendum: If the URL is FTP, and it is to be loaded, only the
|
||||||
|
domain and suffix settings are "stronger".
|
||||||
|
|
||||||
|
Note that .html and (yuck) .htm will get loaded
|
||||||
|
regardless of suffix rules (but that is remedied later with
|
||||||
|
unlink).
|
||||||
|
|
||||||
|
More time- and memory- consuming tests should be put later on
|
||||||
|
the list. */
|
||||||
|
|
||||||
|
/* inl is set if the URL we are working on (constr) is stored in
|
||||||
|
ulist. Using it is crucial to avoid the incessant calls to
|
||||||
|
in_slist, which is quite slow. */
|
||||||
|
inl = in_slist (ulist, constr);
|
||||||
|
|
||||||
|
/* If it is FTP, and FTP is not followed, chuck it out. */
|
||||||
|
if (!inl)
|
||||||
|
if (u->proto == URLFTP && !opt.follow_ftp && !this_url_ftp)
|
||||||
|
{
|
||||||
|
DEBUGP (("Uh, it is FTP but i'm not in the mood to follow FTP.\n"));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
/* If it is absolute link and they are not followed, chuck it
|
||||||
|
out. */
|
||||||
|
if (!inl && u->proto != URLFTP)
|
||||||
|
if (opt.relative_only && !(cur_url->flags & URELATIVE))
|
||||||
|
{
|
||||||
|
DEBUGP (("It doesn't really look like a relative link.\n"));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
/* If its domain is not to be accepted/looked-up, chuck it out. */
|
||||||
|
if (!inl)
|
||||||
|
if (!accept_domain (u))
|
||||||
|
{
|
||||||
|
DEBUGP (("I don't like the smell of that domain.\n"));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
/* Check for parent directory. */
|
||||||
|
if (!inl && opt.no_parent
|
||||||
|
/* If the new URL is FTP and the old was not, ignore
|
||||||
|
opt.no_parent. */
|
||||||
|
&& !(!this_url_ftp && u->proto == URLFTP))
|
||||||
|
{
|
||||||
|
/* Check for base_dir first. */
|
||||||
|
if (!(base_dir && frontcmp (base_dir, u->dir)))
|
||||||
|
{
|
||||||
|
/* Failing that, check for parent dir. */
|
||||||
|
struct urlinfo *ut = newurl ();
|
||||||
|
if (parseurl (this_url, ut, 0) != URLOK)
|
||||||
|
DEBUGP (("Double yuck! The *base* URL is broken.\n"));
|
||||||
|
else if (!frontcmp (ut->dir, u->dir))
|
||||||
|
{
|
||||||
|
/* Failing that too, kill the URL. */
|
||||||
|
DEBUGP (("Trying to escape parental guidance with no_parent on.\n"));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
freeurl (ut, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If the file does not match the acceptance list, or is on the
|
||||||
|
rejection list, chuck it out. The same goes for the
|
||||||
|
directory exclude- and include- lists. */
|
||||||
|
if (!inl && (opt.includes || opt.excludes))
|
||||||
|
{
|
||||||
|
if (!accdir (u->dir, ALLABS))
|
||||||
|
{
|
||||||
|
DEBUGP (("%s (%s) is excluded/not-included.\n", constr, u->dir));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inl)
|
||||||
|
{
|
||||||
|
char *suf = NULL;
|
||||||
|
/* We check for acceptance/rejection rules only for non-HTML
|
||||||
|
documents. Since we don't know whether they really are
|
||||||
|
HTML, it will be deduced from (an OR-ed list):
|
||||||
|
|
||||||
|
1) u->file is "" (meaning it is a directory)
|
||||||
|
2) suffix exists, AND:
|
||||||
|
a) it is "html", OR
|
||||||
|
b) it is "htm"
|
||||||
|
|
||||||
|
If the file *is* supposed to be HTML, it will *not* be
|
||||||
|
subject to acc/rej rules. That's why the `!'. */
|
||||||
|
if (!
|
||||||
|
(!*u->file
|
||||||
|
|| (((suf = suffix (constr)) != NULL)
|
||||||
|
&& (!strcmp (suf, "html") || !strcmp (suf, "htm")))))
|
||||||
|
{
|
||||||
|
if (!acceptable (u->file))
|
||||||
|
{
|
||||||
|
DEBUGP (("%s (%s) does not match acc/rej rules.\n",
|
||||||
|
constr, u->file));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FREE_MAYBE (suf);
|
||||||
|
}
|
||||||
|
/* Optimize the URL (which includes possible DNS lookup) only
|
||||||
|
after all other possibilities have been exhausted. */
|
||||||
|
if (!inl)
|
||||||
|
{
|
||||||
|
if (!opt.simple_check)
|
||||||
|
opt_url (u);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
/* Just lowercase the hostname. */
|
||||||
|
for (p = u->host; *p; p++)
|
||||||
|
*p = tolower (*p);
|
||||||
|
free (u->url);
|
||||||
|
u->url = str_url (u, 0);
|
||||||
|
}
|
||||||
|
free (constr);
|
||||||
|
constr = xstrdup (u->url);
|
||||||
|
inl = in_slist (ulist, constr);
|
||||||
|
if (!inl && !((u->proto == URLFTP) && !this_url_ftp))
|
||||||
|
if (!opt.spanhost && this_url && !same_host (this_url, constr))
|
||||||
|
{
|
||||||
|
DEBUGP (("This is not the same hostname as the parent's.\n"));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* What about robots.txt? */
|
||||||
|
if (!inl && opt.use_robots && u->proto == URLHTTP)
|
||||||
|
{
|
||||||
|
/* Since Wget knows about only one set of robot rules at a
|
||||||
|
time, /robots.txt must be reloaded whenever a new host is
|
||||||
|
accessed.
|
||||||
|
|
||||||
|
robots_host holds the host the current `forbid' variable
|
||||||
|
is assigned to. */
|
||||||
|
if (!robots_host || !same_host (robots_host, u->host))
|
||||||
|
{
|
||||||
|
FREE_MAYBE (robots_host);
|
||||||
|
/* Now make robots_host the new host, no matter what the
|
||||||
|
result will be. So if there is no /robots.txt on the
|
||||||
|
site, Wget will not retry getting robots all the
|
||||||
|
time. */
|
||||||
|
robots_host = xstrdup (u->host);
|
||||||
|
free_vec (forbidden);
|
||||||
|
forbidden = NULL;
|
||||||
|
err = retrieve_robots (constr, ROBOTS_FILENAME);
|
||||||
|
if (err == ROBOTSOK)
|
||||||
|
{
|
||||||
|
rurl = robots_url (constr, ROBOTS_FILENAME);
|
||||||
|
rfile = url_filename (rurl);
|
||||||
|
forbidden = parse_robots (rfile);
|
||||||
|
freeurl (rurl, 1);
|
||||||
|
free (rfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now that we have (or don't have) robots, we can check for
|
||||||
|
them. */
|
||||||
|
if (!robots_match (u, forbidden))
|
||||||
|
{
|
||||||
|
DEBUGP (("Stuffing %s because %s forbids it.\n", this_url,
|
||||||
|
ROBOTS_FILENAME));
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
inl = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = NULL;
|
||||||
|
/* If it wasn't chucked out, do something with it. */
|
||||||
|
if (!inl)
|
||||||
|
{
|
||||||
|
DEBUGP (("I've decided to load it -> "));
|
||||||
|
/* Add it to the list of already-loaded URL-s. */
|
||||||
|
ulist = add_slist (ulist, constr, 0);
|
||||||
|
/* Automatically followed FTPs will *not* be downloaded
|
||||||
|
recursively. */
|
||||||
|
if (u->proto == URLFTP)
|
||||||
|
{
|
||||||
|
/* Don't you adore side-effects? */
|
||||||
|
opt.recursive = 0;
|
||||||
|
}
|
||||||
|
/* Reset its type. */
|
||||||
|
dt = 0;
|
||||||
|
/* Retrieve it. */
|
||||||
|
retrieve_url (constr, &filename, &newloc,
|
||||||
|
canon_this_url ? canon_this_url : this_url, &dt);
|
||||||
|
if (u->proto == URLFTP)
|
||||||
|
{
|
||||||
|
/* Restore... */
|
||||||
|
opt.recursive = 1;
|
||||||
|
}
|
||||||
|
if (newloc)
|
||||||
|
{
|
||||||
|
free (constr);
|
||||||
|
constr = newloc;
|
||||||
|
}
|
||||||
|
/* In case of convert_links: If there was no error, add it to
|
||||||
|
the list of downloaded URLs. We might need it for
|
||||||
|
conversion. */
|
||||||
|
if (opt.convert_links && filename)
|
||||||
|
{
|
||||||
|
if (dt & RETROKF)
|
||||||
|
{
|
||||||
|
urls_downloaded = add_url (urls_downloaded, constr, filename);
|
||||||
|
/* If the URL is HTML, note it. */
|
||||||
|
if (dt & TEXTHTML)
|
||||||
|
urls_html = add_slist (urls_html, filename, NOSORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If there was no error, and the type is text/html, parse
|
||||||
|
it recursively. */
|
||||||
|
if (dt & TEXTHTML)
|
||||||
|
{
|
||||||
|
if (dt & RETROKF)
|
||||||
|
recursive_retrieve (filename, constr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DEBUGP (("%s is not text/html so we don't chase.\n",
|
||||||
|
filename ? filename: "(null)"));
|
||||||
|
/* If an suffix-rejected file was loaded only because it was HTML,
|
||||||
|
undo the error now */
|
||||||
|
if (opt.delete_after || (filename && !acceptable (filename)))
|
||||||
|
{
|
||||||
|
logprintf (LOG_VERBOSE,
|
||||||
|
(opt.delete_after ? _("Removing %s.\n")
|
||||||
|
: _("Removing %s since it should be rejected.\n")),
|
||||||
|
filename);
|
||||||
|
if (unlink (filename))
|
||||||
|
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||||
|
dt &= ~RETROKF;
|
||||||
|
}
|
||||||
|
/* If everything was OK, and links are to be converted, let's
|
||||||
|
store the local filename. */
|
||||||
|
if (opt.convert_links && (dt & RETROKF) && (filename != NULL))
|
||||||
|
{
|
||||||
|
cur_url->flags |= UABS2REL;
|
||||||
|
cur_url->local_name = xstrdup (filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUGP (("%s already in list, so we don't load.\n", constr));
|
||||||
|
/* Free filename and constr. */
|
||||||
|
FREE_MAYBE (filename);
|
||||||
|
FREE_MAYBE (constr);
|
||||||
|
freeurl (u, 1);
|
||||||
|
/* Increment the pbuf for the appropriate size. */
|
||||||
|
}
|
||||||
|
if (opt.convert_links)
|
||||||
|
convert_links (file, url_list);
|
||||||
|
/* Free the linked list of URL-s. */
|
||||||
|
free_urlpos (url_list);
|
||||||
|
/* Free the canonical this_url. */
|
||||||
|
FREE_MAYBE (canon_this_url);
|
||||||
|
/* Decrement the recursion depth. */
|
||||||
|
--depth;
|
||||||
|
if (opt.quota && (opt.downloaded > opt.quota))
|
||||||
|
return QUOTEXC;
|
||||||
|
else
|
||||||
|
return RETROK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simple calls to convert_links will often fail because only the
|
||||||
|
downloaded files are converted, and Wget cannot know which files
|
||||||
|
will be converted in the future. So, if we have file fileone.html
|
||||||
|
with:
|
||||||
|
|
||||||
|
<a href=/c/something.gif>
|
||||||
|
|
||||||
|
and /c/something.gif was not downloaded because it exceeded the
|
||||||
|
recursion depth, the reference will *not* be changed.
|
||||||
|
|
||||||
|
However, later we can encounter /c/something.gif from an "upper"
|
||||||
|
level HTML (let's call it filetwo.html), and it gets downloaded.
|
||||||
|
|
||||||
|
But now we have a problem because /c/something.gif will be
|
||||||
|
correctly transformed in filetwo.html, but not in fileone.html,
|
||||||
|
since Wget could not have known that /c/something.gif will be
|
||||||
|
downloaded in the future.
|
||||||
|
|
||||||
|
This is why Wget must, after the whole retrieval, call
|
||||||
|
convert_all_links to go once more through the entire list of
|
||||||
|
retrieved HTML-s, and re-convert them.
|
||||||
|
|
||||||
|
All the downloaded HTMLs are kept in urls_html, and downloaded URLs
|
||||||
|
in urls_downloaded. From these two lists information is
|
||||||
|
extracted. */
|
||||||
|
void
|
||||||
|
convert_all_links (void)
|
||||||
|
{
|
||||||
|
uerr_t res;
|
||||||
|
urlpos *l1, *l2, *urls;
|
||||||
|
struct urlinfo *u;
|
||||||
|
slist *html;
|
||||||
|
urlpos *urlhtml;
|
||||||
|
|
||||||
|
for (html = urls_html; html; html = html->next)
|
||||||
|
{
|
||||||
|
DEBUGP (("Rescanning %s\n", html->string));
|
||||||
|
/* Determine the URL of the HTML file. get_urls_html will need
|
||||||
|
it. */
|
||||||
|
for (urlhtml = urls_downloaded; urlhtml; urlhtml = urlhtml->next)
|
||||||
|
if (!strcmp (urlhtml->local_name, html->string))
|
||||||
|
break;
|
||||||
|
if (urlhtml)
|
||||||
|
DEBUGP (("It should correspond to %s.\n", urlhtml->url));
|
||||||
|
else
|
||||||
|
DEBUGP (("I cannot find the corresponding URL.\n"));
|
||||||
|
/* Parse the HTML file... */
|
||||||
|
urls = get_urls_html (html->string, urlhtml ? urlhtml->url : NULL, 1);
|
||||||
|
if (!urls)
|
||||||
|
continue;
|
||||||
|
for (l1 = urls; l1; l1 = l1->next)
|
||||||
|
{
|
||||||
|
/* The URL must be in canonical form to be compared. */
|
||||||
|
u = newurl ();
|
||||||
|
res = parseurl (l1->url, u, 0);
|
||||||
|
if (res != URLOK)
|
||||||
|
{
|
||||||
|
freeurl (u, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* We decide the direction of conversion according to whether
|
||||||
|
a URL was downloaded. Downloaded URLs will be converted
|
||||||
|
ABS2REL, whereas non-downloaded will be converted REL2ABS.
|
||||||
|
Note: not yet implemented; only ABS2REL works. */
|
||||||
|
for (l2 = urls_downloaded; l2; l2 = l2->next)
|
||||||
|
if (!strcmp (l2->url, u->url))
|
||||||
|
{
|
||||||
|
DEBUGP (("%s flagged for conversion, local %s\n",
|
||||||
|
l2->url, l2->local_name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Clear the flags. */
|
||||||
|
l1->flags &= ~ (UABS2REL | UREL2ABS);
|
||||||
|
/* Decide on the conversion direction. */
|
||||||
|
if (l2)
|
||||||
|
{
|
||||||
|
l1->flags |= UABS2REL;
|
||||||
|
l1->local_name = xstrdup (l2->local_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l1->flags |= UREL2ABS;
|
||||||
|
l1->local_name = NULL;
|
||||||
|
}
|
||||||
|
freeurl (u, 1);
|
||||||
|
}
|
||||||
|
/* Convert the links in the file. */
|
||||||
|
convert_links (html->string, urls);
|
||||||
|
/* Free the data. */
|
||||||
|
free_urlpos (urls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Robots support. */
|
||||||
|
|
||||||
|
/* Construct the robots URL. */
|
||||||
|
static struct urlinfo *
|
||||||
|
robots_url (const char *url, const char *robots_filename)
|
||||||
|
{
|
||||||
|
struct urlinfo *u = newurl ();
|
||||||
|
uerr_t err;
|
||||||
|
|
||||||
|
err = parseurl (url, u, 0);
|
||||||
|
assert (err == URLOK && u->proto == URLHTTP);
|
||||||
|
free (u->file);
|
||||||
|
free (u->dir);
|
||||||
|
free (u->url);
|
||||||
|
u->dir = xstrdup ("");
|
||||||
|
u->file = xstrdup (robots_filename);
|
||||||
|
u->url = str_url (u, 0);
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieves the robots_filename from the root server directory, if
|
||||||
|
possible. Returns ROBOTSOK if robots were retrieved OK, and
|
||||||
|
NOROBOTS if robots could not be retrieved for any reason. */
|
||||||
|
static uerr_t
|
||||||
|
retrieve_robots (const char *url, const char *robots_filename)
|
||||||
|
{
|
||||||
|
int dt;
|
||||||
|
uerr_t err;
|
||||||
|
struct urlinfo *u;
|
||||||
|
|
||||||
|
u = robots_url (url, robots_filename);
|
||||||
|
logputs (LOG_VERBOSE, _("Loading robots.txt; please ignore errors.\n"));
|
||||||
|
err = retrieve_url (u->url, NULL, NULL, NULL, &dt);
|
||||||
|
freeurl (u, 1);
|
||||||
|
if (err == RETROK)
|
||||||
|
return ROBOTSOK;
|
||||||
|
else
|
||||||
|
return NOROBOTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the robots_filename and return the disallowed path components
|
||||||
|
in a malloc-ed vector of character pointers.
|
||||||
|
|
||||||
|
It should be fully compliant with the syntax as described in the
|
||||||
|
file norobots.txt, adopted by the robots mailing list
|
||||||
|
(robots@webcrawler.com). */
|
||||||
|
static char **
|
||||||
|
parse_robots (const char *robots_filename)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char **entries;
|
||||||
|
char *line, *cmd, *str, *p;
|
||||||
|
char *base_version, *version;
|
||||||
|
int len, num, i;
|
||||||
|
int wget_matched; /* is the part meant for Wget? */
|
||||||
|
|
||||||
|
entries = NULL;
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
fp = fopen (robots_filename, "rb");
|
||||||
|
if (!fp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Kill version number. */
|
||||||
|
if (opt.useragent)
|
||||||
|
{
|
||||||
|
STRDUP_ALLOCA (base_version, opt.useragent);
|
||||||
|
STRDUP_ALLOCA (version, opt.useragent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int len = 10 + strlen (version_string);
|
||||||
|
base_version = (char *)alloca (len);
|
||||||
|
sprintf (base_version, "Wget/%s", version_string);
|
||||||
|
version = (char *)alloca (len);
|
||||||
|
sprintf (version, "Wget/%s", version_string);
|
||||||
|
}
|
||||||
|
for (p = version; *p; p++)
|
||||||
|
*p = tolower (*p);
|
||||||
|
for (p = base_version; *p && *p != '/'; p++)
|
||||||
|
*p = tolower (*p);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
/* Setting this to 1 means that Wget considers itself under
|
||||||
|
restrictions by default, even if the User-Agent field is not
|
||||||
|
present. However, if it finds the user-agent set to anything
|
||||||
|
other than Wget, the rest will be ignored (up to the following
|
||||||
|
User-Agent field). Thus you may have something like:
|
||||||
|
|
||||||
|
Disallow: 1
|
||||||
|
Disallow: 2
|
||||||
|
User-Agent: stupid-robot
|
||||||
|
Disallow: 3
|
||||||
|
Disallow: 4
|
||||||
|
User-Agent: Wget*
|
||||||
|
Disallow: 5
|
||||||
|
Disallow: 6
|
||||||
|
User-Agent: *
|
||||||
|
Disallow: 7
|
||||||
|
|
||||||
|
In this case the 1, 2, 5, 6 and 7 disallow lines will be
|
||||||
|
stored. */
|
||||||
|
wget_matched = 1;
|
||||||
|
while ((line = read_whole_line (fp)))
|
||||||
|
{
|
||||||
|
len = strlen (line);
|
||||||
|
/* Destroy <CR> if there is one. */
|
||||||
|
if (len && line[len - 1] == '\r')
|
||||||
|
line[len - 1] = '\0';
|
||||||
|
/* According to specifications, optional space may be at the
|
||||||
|
end... */
|
||||||
|
DEBUGP (("Line: %s\n", line));
|
||||||
|
/* Skip spaces. */
|
||||||
|
for (cmd = line; *cmd && ISSPACE (*cmd); cmd++);
|
||||||
|
if (!*cmd)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
DEBUGP (("(chucked out)\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Look for ':'. */
|
||||||
|
for (str = cmd; *str && *str != ':'; str++);
|
||||||
|
if (!*str)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
DEBUGP (("(chucked out)\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Zero-terminate the command. */
|
||||||
|
*str++ = '\0';
|
||||||
|
/* Look for the string beginning... */
|
||||||
|
for (; *str && ISSPACE (*str); str++);
|
||||||
|
/* Look for comments and kill them off. */
|
||||||
|
for (p = str; *p; p++)
|
||||||
|
if (*p && ISSPACE (*p) && *(p + 1) == '#')
|
||||||
|
{
|
||||||
|
/* We have found a shell-style comment `<sp>+ #'. Now
|
||||||
|
rewind to the beginning of the spaces and place '\0'
|
||||||
|
there. */
|
||||||
|
while (p > str && ISSPACE (*p))
|
||||||
|
--p;
|
||||||
|
if (p == str)
|
||||||
|
*p = '\0';
|
||||||
|
else
|
||||||
|
*(p + 1) = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strcasecmp (cmd, "User-agent"))
|
||||||
|
{
|
||||||
|
int match = 0;
|
||||||
|
/* Lowercase the agent string. */
|
||||||
|
for (p = str; *p; p++)
|
||||||
|
*p = tolower (*p);
|
||||||
|
/* If the string is `*', it matches. */
|
||||||
|
if (*str == '*' && !*(str + 1))
|
||||||
|
match = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If the string contains wildcards, we'll run it through
|
||||||
|
fnmatch(). */
|
||||||
|
if (has_wildcards_p (str))
|
||||||
|
{
|
||||||
|
/* If the string contains '/', compare with the full
|
||||||
|
version. Else, compare it to base_version. */
|
||||||
|
if (strchr (str, '/'))
|
||||||
|
match = !fnmatch (str, version, 0);
|
||||||
|
else
|
||||||
|
match = !fnmatch (str, base_version, 0);
|
||||||
|
}
|
||||||
|
else /* Substring search */
|
||||||
|
{
|
||||||
|
if (strstr (version, str))
|
||||||
|
match = 1;
|
||||||
|
else
|
||||||
|
match = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If Wget is not matched, skip all the entries up to the
|
||||||
|
next User-agent field. */
|
||||||
|
wget_matched = match;
|
||||||
|
}
|
||||||
|
else if (!wget_matched)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
DEBUGP (("(chucking out since it is not applicable for Wget)\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp (cmd, "Disallow"))
|
||||||
|
{
|
||||||
|
/* If "Disallow" is empty, the robot is welcome. */
|
||||||
|
if (!*str)
|
||||||
|
{
|
||||||
|
free_vec (entries);
|
||||||
|
entries = (char **)xmalloc (sizeof (char *));
|
||||||
|
*entries = NULL;
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entries = (char **)xrealloc (entries, (num + 2)* sizeof (char *));
|
||||||
|
entries[num] = xstrdup (str);
|
||||||
|
entries[++num] = NULL;
|
||||||
|
/* Strip trailing spaces, according to specifications. */
|
||||||
|
for (i = strlen (str); i >= 0 && ISSPACE (str[i]); i--)
|
||||||
|
if (ISSPACE (str[i]))
|
||||||
|
str[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unknown command */
|
||||||
|
DEBUGP (("(chucked out)\n"));
|
||||||
|
}
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* May the URL url be loaded according to disallowing rules stored in
|
||||||
|
forbidden? */
|
||||||
|
static int
|
||||||
|
robots_match (struct urlinfo *u, char **forbidden)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
if (!forbidden)
|
||||||
|
return 1;
|
||||||
|
DEBUGP (("Matching %s against: ", u->path));
|
||||||
|
for (; *forbidden; forbidden++)
|
||||||
|
{
|
||||||
|
DEBUGP (("%s ", *forbidden));
|
||||||
|
l = strlen (*forbidden);
|
||||||
|
/* If dir is forbidden, we may not load the file. */
|
||||||
|
if (strncmp (u->path, *forbidden, l) == 0)
|
||||||
|
{
|
||||||
|
DEBUGP (("matched.\n"));
|
||||||
|
return 0; /* Matches, i.e. does not load... */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUGP (("not matched.\n"));
|
||||||
|
return 1;
|
||||||
|
}
|
29
src/recur.h
Normal file
29
src/recur.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* Declarations for recur.c.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef RECUR_H
|
||||||
|
#define RECUR_H
|
||||||
|
|
||||||
|
void recursive_cleanup PARAMS ((void));
|
||||||
|
void recursive_reset PARAMS ((void));
|
||||||
|
uerr_t recursive_retrieve PARAMS ((const char *, const char *));
|
||||||
|
|
||||||
|
void convert_all_links PARAMS ((void));
|
||||||
|
|
||||||
|
#endif /* RECUR_H */
|
484
src/retr.c
Normal file
484
src/retr.c
Normal file
@ -0,0 +1,484 @@
|
|||||||
|
/* File retrieval.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "retr.h"
|
||||||
|
#include "url.h"
|
||||||
|
#include "recur.h"
|
||||||
|
#include "ftp.h"
|
||||||
|
#include "host.h"
|
||||||
|
#include "connect.h"
|
||||||
|
|
||||||
|
/* Internal variables used by the timer. */
|
||||||
|
static long internal_secs, internal_msecs;
|
||||||
|
|
||||||
|
void logflush PARAMS ((void));
|
||||||
|
|
||||||
|
/* From http.c. */
|
||||||
|
uerr_t http_loop PARAMS ((struct urlinfo *, char **, int *));
|
||||||
|
|
||||||
|
/* Flags for show_progress(). */
|
||||||
|
enum spflags { SP_NONE, SP_INIT, SP_FINISH };
|
||||||
|
|
||||||
|
static int show_progress PARAMS ((long, long, enum spflags));
|
||||||
|
|
||||||
|
/* Reads the contents of file descriptor FD, until it is closed, or a
|
||||||
|
read error occurs. The data is read in 8K chunks, and stored to
|
||||||
|
stream fp, which should have been open for writing. If BUF is
|
||||||
|
non-NULL and its file descriptor is equal to FD, flush RBUF first.
|
||||||
|
This function will *not* use the rbuf_* functions!
|
||||||
|
|
||||||
|
The EXPECTED argument is passed to show_progress() unchanged, but
|
||||||
|
otherwise ignored.
|
||||||
|
|
||||||
|
If opt.verbose is set, the progress is also shown. RESTVAL
|
||||||
|
represents a value from which to start downloading (which will be
|
||||||
|
shown accordingly). If RESTVAL is non-zero, the stream should have
|
||||||
|
been open for appending.
|
||||||
|
|
||||||
|
The function exits and returns codes of 0, -1 and -2 if the
|
||||||
|
connection was closed, there was a read error, or if it could not
|
||||||
|
write to the output stream, respectively.
|
||||||
|
|
||||||
|
IMPORTANT: The function flushes the contents of the buffer in
|
||||||
|
rbuf_flush() before actually reading from fd. If you wish to read
|
||||||
|
from fd immediately, flush or discard the buffer. */
|
||||||
|
int
|
||||||
|
get_contents (int fd, FILE *fp, long *len, long restval, long expected,
|
||||||
|
struct rbuf *rbuf)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
static char c[8192];
|
||||||
|
|
||||||
|
*len = restval;
|
||||||
|
if (opt.verbose)
|
||||||
|
show_progress (restval, expected, SP_INIT);
|
||||||
|
if (rbuf && RBUF_FD (rbuf) == fd)
|
||||||
|
{
|
||||||
|
while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
|
||||||
|
{
|
||||||
|
if (fwrite (c, sizeof (char), res, fp) < res)
|
||||||
|
return -2;
|
||||||
|
if (opt.verbose)
|
||||||
|
{
|
||||||
|
if (show_progress (res, expected, SP_NONE))
|
||||||
|
fflush (fp);
|
||||||
|
}
|
||||||
|
*len += res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read from fd while there is available data. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
res = iread (fd, c, sizeof (c));
|
||||||
|
if (res > 0)
|
||||||
|
{
|
||||||
|
if (fwrite (c, sizeof (char), res, fp) < res)
|
||||||
|
return -2;
|
||||||
|
if (opt.verbose)
|
||||||
|
{
|
||||||
|
if (show_progress (res, expected, SP_NONE))
|
||||||
|
fflush (fp);
|
||||||
|
}
|
||||||
|
*len += res;
|
||||||
|
}
|
||||||
|
} while (res > 0);
|
||||||
|
if (res < -1)
|
||||||
|
res = -1;
|
||||||
|
if (opt.verbose)
|
||||||
|
show_progress (0, expected, SP_FINISH);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_percentage (long bytes, long expected)
|
||||||
|
{
|
||||||
|
int percentage = (int)(100.0 * bytes / expected);
|
||||||
|
logprintf (LOG_VERBOSE, " [%3d%%]", percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show the dotted progress report of file loading. Called with
|
||||||
|
length and a flag to tell it whether to reset or not. It keeps the
|
||||||
|
offset information in static local variables.
|
||||||
|
|
||||||
|
Return value: 1 or 0, designating whether any dots have been drawn.
|
||||||
|
|
||||||
|
If the init argument is set, the routine will initialize.
|
||||||
|
|
||||||
|
If the res is non-zero, res/line_bytes lines are skipped
|
||||||
|
(meaning the appropriate number ok kilobytes), and the number of
|
||||||
|
"dots" fitting on the first line are drawn as ','. */
|
||||||
|
static int
|
||||||
|
show_progress (long res, long expected, enum spflags flags)
|
||||||
|
{
|
||||||
|
static long line_bytes;
|
||||||
|
static long offs;
|
||||||
|
static int ndot, nrow;
|
||||||
|
int any_output = 0;
|
||||||
|
|
||||||
|
if (flags == SP_FINISH)
|
||||||
|
{
|
||||||
|
if (expected)
|
||||||
|
{
|
||||||
|
int dot = ndot;
|
||||||
|
char *tmpstr = (char *)alloca (2 * opt.dots_in_line + 1);
|
||||||
|
char *tmpp = tmpstr;
|
||||||
|
for (; dot < opt.dots_in_line; dot++)
|
||||||
|
{
|
||||||
|
if (!(dot % opt.dot_spacing))
|
||||||
|
*tmpp++ = ' ';
|
||||||
|
*tmpp++ = ' ';
|
||||||
|
}
|
||||||
|
*tmpp = '\0';
|
||||||
|
logputs (LOG_VERBOSE, tmpstr);
|
||||||
|
print_percentage (nrow * line_bytes + ndot * opt.dot_bytes + offs,
|
||||||
|
expected);
|
||||||
|
}
|
||||||
|
logputs (LOG_VERBOSE, "\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Temporarily disable flushing. */
|
||||||
|
opt.no_flush = 1;
|
||||||
|
/* init set means initialization. If res is set, it also means that
|
||||||
|
the retrieval is *not* done from the beginning. The part that
|
||||||
|
was already retrieved is not shown again. */
|
||||||
|
if (flags == SP_INIT)
|
||||||
|
{
|
||||||
|
/* Generic initialization of static variables. */
|
||||||
|
offs = 0L;
|
||||||
|
ndot = nrow = 0;
|
||||||
|
line_bytes = (long)opt.dots_in_line * opt.dot_bytes;
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (res >= line_bytes)
|
||||||
|
{
|
||||||
|
nrow = res / line_bytes;
|
||||||
|
res %= line_bytes;
|
||||||
|
logprintf (LOG_VERBOSE,
|
||||||
|
_("\n [ skipping %dK ]"),
|
||||||
|
(int) ((nrow * line_bytes) / 1024));
|
||||||
|
ndot = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logprintf (LOG_VERBOSE, "\n%5ldK ->", nrow * line_bytes / 1024);
|
||||||
|
}
|
||||||
|
/* Offset gets incremented by current value. */
|
||||||
|
offs += res;
|
||||||
|
/* While offset is >= opt.dot_bytes, print dots, taking care to
|
||||||
|
precede every 50th dot with a status message. */
|
||||||
|
for (; offs >= opt.dot_bytes; offs -= opt.dot_bytes)
|
||||||
|
{
|
||||||
|
if (!(ndot % opt.dot_spacing))
|
||||||
|
logputs (LOG_VERBOSE, " ");
|
||||||
|
any_output = 1;
|
||||||
|
logputs (LOG_VERBOSE, flags == SP_INIT ? "," : ".");
|
||||||
|
++ndot;
|
||||||
|
if (ndot == opt.dots_in_line)
|
||||||
|
{
|
||||||
|
ndot = 0;
|
||||||
|
++nrow;
|
||||||
|
if (expected)
|
||||||
|
print_percentage (nrow * line_bytes, expected);
|
||||||
|
logprintf (LOG_VERBOSE, "\n%5ldK ->", nrow * line_bytes / 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Reenable flushing. */
|
||||||
|
opt.no_flush = 0;
|
||||||
|
if (any_output)
|
||||||
|
/* Force flush. #### Oh, what a kludge! */
|
||||||
|
logflush ();
|
||||||
|
return any_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the internal timer. */
|
||||||
|
void
|
||||||
|
reset_timer (void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
|
struct timeval t;
|
||||||
|
gettimeofday (&t, NULL);
|
||||||
|
internal_secs = t.tv_sec;
|
||||||
|
internal_msecs = t.tv_usec / 1000;
|
||||||
|
#else
|
||||||
|
internal_secs = time (NULL);
|
||||||
|
internal_msecs = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the time elapsed from the last call to reset_timer(), in
|
||||||
|
milliseconds. */
|
||||||
|
long
|
||||||
|
elapsed_time (void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
|
struct timeval t;
|
||||||
|
gettimeofday (&t, NULL);
|
||||||
|
return ((t.tv_sec - internal_secs) * 1000
|
||||||
|
+ (t.tv_usec / 1000 - internal_msecs));
|
||||||
|
#else
|
||||||
|
return 1000 * ((long)time (NULL) - internal_secs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out the appropriate download rate. Appropriate means that if
|
||||||
|
rate is > 1024 bytes per second, kilobytes are used, and if rate >
|
||||||
|
1024 * 1024 bps, megabytes are used. */
|
||||||
|
char *
|
||||||
|
rate (long bytes, long msecs)
|
||||||
|
{
|
||||||
|
static char res[15];
|
||||||
|
double dlrate;
|
||||||
|
|
||||||
|
if (!msecs)
|
||||||
|
++msecs;
|
||||||
|
dlrate = (double)1000 * bytes / msecs;
|
||||||
|
/* #### Should these strings be translatable? */
|
||||||
|
if (dlrate < 1024.0)
|
||||||
|
sprintf (res, "%.2f B/s", dlrate);
|
||||||
|
else if (dlrate < 1024.0 * 1024.0)
|
||||||
|
sprintf (res, "%.2f KB/s", dlrate / 1024.0);
|
||||||
|
else
|
||||||
|
sprintf (res, "%.2f MB/s", dlrate / (1024.0 * 1024.0));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USE_PROXY_P(u) (opt.use_proxy && getproxy((u)->proto) \
|
||||||
|
&& no_proxy_match((u)->host, \
|
||||||
|
(const char **)opt.no_proxy))
|
||||||
|
|
||||||
|
/* Retrieve the given URL. Decides which loop to call -- HTTP, FTP,
|
||||||
|
or simply copy it with file:// (#### the latter not yet
|
||||||
|
implemented!). */
|
||||||
|
uerr_t
|
||||||
|
retrieve_url (const char *origurl, char **file, char **newloc,
|
||||||
|
const char *refurl, int *dt)
|
||||||
|
{
|
||||||
|
uerr_t result;
|
||||||
|
char *url;
|
||||||
|
int location_changed, already_redirected, dummy;
|
||||||
|
int local_use_proxy;
|
||||||
|
char *mynewloc, *proxy;
|
||||||
|
struct urlinfo *u;
|
||||||
|
|
||||||
|
|
||||||
|
/* If dt is NULL, just ignore it. */
|
||||||
|
if (!dt)
|
||||||
|
dt = &dummy;
|
||||||
|
url = xstrdup (origurl);
|
||||||
|
if (newloc)
|
||||||
|
*newloc = NULL;
|
||||||
|
if (file)
|
||||||
|
*file = NULL;
|
||||||
|
already_redirected = 0;
|
||||||
|
|
||||||
|
again:
|
||||||
|
u = newurl ();
|
||||||
|
/* Parse the URL. RFC2068 requires `Location' to contain an
|
||||||
|
absoluteURI, but many sites break this requirement. #### We
|
||||||
|
should be liberal and accept a relative location, too. */
|
||||||
|
result = parseurl (url, u, already_redirected);
|
||||||
|
if (result != URLOK)
|
||||||
|
{
|
||||||
|
freeurl (u, 1);
|
||||||
|
logprintf (LOG_NOTQUIET, "%s: %s.\n", url, uerrmsg (result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the referer. */
|
||||||
|
if (refurl)
|
||||||
|
u->referer = xstrdup (refurl);
|
||||||
|
else
|
||||||
|
u->referer = NULL;
|
||||||
|
|
||||||
|
local_use_proxy = USE_PROXY_P (u);
|
||||||
|
if (local_use_proxy)
|
||||||
|
{
|
||||||
|
struct urlinfo *pu = newurl ();
|
||||||
|
|
||||||
|
/* Copy the original URL to new location. */
|
||||||
|
memcpy (pu, u, sizeof (*u));
|
||||||
|
pu->proxy = NULL; /* A minor correction :) */
|
||||||
|
/* Initialize u to nil. */
|
||||||
|
memset (u, 0, sizeof (*u));
|
||||||
|
u->proxy = pu;
|
||||||
|
/* Get the appropriate proxy server, appropriate for the
|
||||||
|
current protocol. */
|
||||||
|
proxy = getproxy (pu->proto);
|
||||||
|
if (!proxy)
|
||||||
|
{
|
||||||
|
logputs (LOG_NOTQUIET, _("Could not find proxy host.\n"));
|
||||||
|
freeurl (u, 1);
|
||||||
|
return PROXERR;
|
||||||
|
}
|
||||||
|
/* Parse the proxy URL. */
|
||||||
|
result = parseurl (proxy, u, 0);
|
||||||
|
if (result != URLOK || u->proto != URLHTTP)
|
||||||
|
{
|
||||||
|
if (u->proto == URLHTTP)
|
||||||
|
logprintf (LOG_NOTQUIET, "Proxy %s: %s.\n", proxy, uerrmsg (result));
|
||||||
|
else
|
||||||
|
logprintf (LOG_NOTQUIET, _("Proxy %s: Must be HTTP.\n"), proxy);
|
||||||
|
freeurl (u, 1);
|
||||||
|
return PROXERR;
|
||||||
|
}
|
||||||
|
u->proto = URLHTTP;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (u->proto != URLFILE); /* #### Implement me! */
|
||||||
|
mynewloc = NULL;
|
||||||
|
|
||||||
|
if (u->proto == URLHTTP)
|
||||||
|
result = http_loop (u, &mynewloc, dt);
|
||||||
|
else if (u->proto == URLFTP)
|
||||||
|
{
|
||||||
|
/* If this is a redirection, we must not allow recursive FTP
|
||||||
|
retrieval, so we save recursion to oldrec, and restore it
|
||||||
|
later. */
|
||||||
|
int oldrec = opt.recursive;
|
||||||
|
if (already_redirected)
|
||||||
|
opt.recursive = 0;
|
||||||
|
result = ftp_loop (u, dt);
|
||||||
|
opt.recursive = oldrec;
|
||||||
|
/* There is a possibility of having HTTP being redirected to
|
||||||
|
FTP. In these cases we must decide whether the text is HTML
|
||||||
|
according to the suffix. The HTML suffixes are `.html' and
|
||||||
|
`.htm', case-insensitive.
|
||||||
|
|
||||||
|
#### All of this is, of course, crap. These types should be
|
||||||
|
determined through mailcap. */
|
||||||
|
if (already_redirected && u->local && (u->proto == URLFTP ))
|
||||||
|
{
|
||||||
|
char *suf = suffix (u->local);
|
||||||
|
if (suf && (!strcasecmp (suf, "html") || !strcasecmp (suf, "htm")))
|
||||||
|
*dt |= TEXTHTML;
|
||||||
|
FREE_MAYBE (suf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
location_changed = (result == NEWLOCATION);
|
||||||
|
if (location_changed)
|
||||||
|
{
|
||||||
|
/* Check for redirection to oneself. */
|
||||||
|
if (url_equal (url, mynewloc))
|
||||||
|
{
|
||||||
|
logprintf (LOG_NOTQUIET, _("%s: Redirection to itself.\n"),
|
||||||
|
mynewloc);
|
||||||
|
return WRONGCODE;
|
||||||
|
}
|
||||||
|
if (mynewloc)
|
||||||
|
{
|
||||||
|
free (url);
|
||||||
|
url = mynewloc;
|
||||||
|
}
|
||||||
|
freeurl (u, 1);
|
||||||
|
already_redirected = 1;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
if (u->local)
|
||||||
|
*file = xstrdup (u->local);
|
||||||
|
else
|
||||||
|
*file = NULL;
|
||||||
|
}
|
||||||
|
freeurl (u, 1);
|
||||||
|
|
||||||
|
if (newloc)
|
||||||
|
*newloc = url;
|
||||||
|
else
|
||||||
|
free (url);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the URL-s in the file and call retrieve_url() for each of
|
||||||
|
them. If HTML is non-zero, treat the file as HTML, and construct
|
||||||
|
the URL-s accordingly.
|
||||||
|
|
||||||
|
If opt.recursive is set, call recursive_retrieve() for each file. */
|
||||||
|
uerr_t
|
||||||
|
retrieve_from_file (const char *file, int html, int *count)
|
||||||
|
{
|
||||||
|
uerr_t status;
|
||||||
|
urlpos *url_list, *cur_url;
|
||||||
|
|
||||||
|
/* If spider-mode is on, we do not want get_urls_html barfing
|
||||||
|
errors on baseless links. */
|
||||||
|
url_list = (html ? get_urls_html (file, NULL, opt.spider)
|
||||||
|
: get_urls_file (file));
|
||||||
|
status = RETROK; /* Suppose everything is OK. */
|
||||||
|
*count = 0; /* Reset the URL count. */
|
||||||
|
recursive_reset ();
|
||||||
|
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
|
||||||
|
{
|
||||||
|
char *filename, *new_file;
|
||||||
|
int dt;
|
||||||
|
|
||||||
|
if (opt.quota && opt.downloaded > opt.quota)
|
||||||
|
{
|
||||||
|
status = QUOTEXC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
status = retrieve_url (cur_url->url, &filename, &new_file, NULL, &dt);
|
||||||
|
if (opt.recursive && status == RETROK && (dt & TEXTHTML))
|
||||||
|
status = recursive_retrieve (filename, new_file ? new_file : cur_url->url);
|
||||||
|
|
||||||
|
if (filename && opt.delete_after && file_exists_p (filename))
|
||||||
|
{
|
||||||
|
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
|
||||||
|
if (unlink (filename))
|
||||||
|
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
|
||||||
|
dt &= ~RETROKF;
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_MAYBE (new_file);
|
||||||
|
FREE_MAYBE (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the linked list of URL-s. */
|
||||||
|
free_urlpos (url_list);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print `giving up', or `retrying', depending on the impending
|
||||||
|
action. N1 and N2 are the attempt number and the attempt limit. */
|
||||||
|
void
|
||||||
|
printwhat (int n1, int n2)
|
||||||
|
{
|
||||||
|
logputs (LOG_VERBOSE, (n1 == n2) ? _("Giving up.\n\n") : _("Retrying.\n\n"));
|
||||||
|
}
|
37
src/retr.h
Normal file
37
src/retr.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* Declarations for retr.c.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef RETR_H
|
||||||
|
#define RETR_H
|
||||||
|
|
||||||
|
#include "rbuf.h"
|
||||||
|
|
||||||
|
int get_contents PARAMS ((int, FILE *, long *, long, long, struct rbuf *));
|
||||||
|
|
||||||
|
uerr_t retrieve_url PARAMS ((const char *, char **, char **,
|
||||||
|
const char *, int *));
|
||||||
|
uerr_t retrieve_from_file PARAMS ((const char *, int, int *));
|
||||||
|
|
||||||
|
void reset_timer PARAMS ((void));
|
||||||
|
long elapsed_time PARAMS ((void));
|
||||||
|
char *rate PARAMS ((long, long));
|
||||||
|
|
||||||
|
void printwhat PARAMS ((int, int));
|
||||||
|
|
||||||
|
#endif /* RETR_H */
|
155
src/sysdep.h
Normal file
155
src/sysdep.h
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/* Dirty system-dependent hacks.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* This file is included by wget.h. Random .c files need not include
|
||||||
|
it. */
|
||||||
|
|
||||||
|
#ifndef SYSDEP_H
|
||||||
|
#define SYSDEP_H
|
||||||
|
|
||||||
|
/* We need these to be playing with various stuff. */
|
||||||
|
#ifdef TIME_WITH_SYS_TIME
|
||||||
|
# include <sys/time.h>
|
||||||
|
# include <time.h>
|
||||||
|
#else /* not TIME_WITH_SYS_TIME_H */
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
# include <sys/time.h>
|
||||||
|
#else /* not HAVE_SYS_TIME_H */
|
||||||
|
# include <time.h>
|
||||||
|
#endif /* HAVE_SYS_TIME_H */
|
||||||
|
#endif /* TIME_WITH_SYS_TIME_H */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
/* Windows doesn't have some functions. Include mswindows.h so we get
|
||||||
|
their declarations, as well as some additional declarations and
|
||||||
|
macros. This must come first, so it can set things up. */
|
||||||
|
#include <mswindows.h>
|
||||||
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
|
/* Allegedly needed for compilation under OS/2: */
|
||||||
|
#ifdef EMXOS2
|
||||||
|
#ifndef S_ISLNK
|
||||||
|
# define S_ISLNK(m) 0
|
||||||
|
#endif
|
||||||
|
#ifndef lstat
|
||||||
|
# define lstat stat
|
||||||
|
#endif
|
||||||
|
#endif /* EMXOS2 */
|
||||||
|
|
||||||
|
/* Reportedly, stat() macros are broken on some old systems. Those
|
||||||
|
systems will have to fend for themselves, as I will not introduce
|
||||||
|
new code to handle it.
|
||||||
|
|
||||||
|
However, I will add code for *missing* macros, and the following
|
||||||
|
are missing from many systems. */
|
||||||
|
#ifndef S_ISLNK
|
||||||
|
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||||
|
#endif
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
# define S_ISDIR(m) (((m) & (_S_IFMT)) == (_S_IFDIR))
|
||||||
|
#endif
|
||||||
|
#ifndef S_ISREG
|
||||||
|
# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Bletch! SPARC compiler doesn't define sparc (needed by
|
||||||
|
arpa/nameser.h) when in -Xc mode. Luckily, it always defines
|
||||||
|
__sparc. */
|
||||||
|
#ifdef __sparc
|
||||||
|
#ifndef sparc
|
||||||
|
#define sparc
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mswindows.h defines these. */
|
||||||
|
#ifndef READ
|
||||||
|
# define READ(fd, buf, cnt) read ((fd), (buf), (cnt))
|
||||||
|
#endif
|
||||||
|
#ifndef WRITE
|
||||||
|
# define WRITE(fd, buf, cnt) write ((fd), (buf), (cnt))
|
||||||
|
#endif
|
||||||
|
#ifndef REALCLOSE
|
||||||
|
# define REALCLOSE(x) close (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CLOSE(x) \
|
||||||
|
do { \
|
||||||
|
REALCLOSE (x); \
|
||||||
|
DEBUGP (("Closing fd %d\n", x)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* OK, now define a decent interface to ctype macros. The regular
|
||||||
|
ones misfire when you feed them chars >= 127, as they understand
|
||||||
|
them as "negative", which results in out-of-bound access at
|
||||||
|
table-lookup, yielding random results. This is, of course, totally
|
||||||
|
bogus. One way to "solve" this is to use `unsigned char'
|
||||||
|
everywhere, but it is nearly impossible to do that cleanly, because
|
||||||
|
all of the library functions and system calls accept `char'.
|
||||||
|
|
||||||
|
Thus we define our wrapper macros which simply cast the argument to
|
||||||
|
unsigned char before passing it to the <ctype.h> macro. These
|
||||||
|
versions are used consistently across the code. */
|
||||||
|
#define ISASCII(x) isascii ((unsigned char)(x))
|
||||||
|
#define ISALPHA(x) isalpha ((unsigned char)(x))
|
||||||
|
#define ISSPACE(x) isspace ((unsigned char)(x))
|
||||||
|
#define ISDIGIT(x) isdigit ((unsigned char)(x))
|
||||||
|
#define ISXDIGIT(x) isxdigit ((unsigned char)(x))
|
||||||
|
|
||||||
|
/* Defined in cmpt.c: */
|
||||||
|
#ifndef HAVE_STRERROR
|
||||||
|
char *strerror ();
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRCASECMP
|
||||||
|
int strcasecmp ();
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRNCASECMP
|
||||||
|
int strncasecmp ();
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRSTR
|
||||||
|
char *strstr ();
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRPTIME
|
||||||
|
char *strptime ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SunOS brain damage -- for some reason, SunOS header files fail to
|
||||||
|
declare the functions below, which causes all kinds of problems
|
||||||
|
(compiling errors) with pointer arithmetic and similar.
|
||||||
|
|
||||||
|
This used to be only within `#ifdef STDC_HEADERS', but it got
|
||||||
|
tripped on other systems (AIX), thus causing havoc. Fortunately,
|
||||||
|
SunOS appears to be the only system braindamaged that badly, so I
|
||||||
|
added an extra `#ifdef sun' guard. */
|
||||||
|
#ifndef STDC_HEADERS
|
||||||
|
#ifdef sun
|
||||||
|
#ifndef __cplusplus
|
||||||
|
char *strstr ();
|
||||||
|
char *strchr ();
|
||||||
|
char *strrchr ();
|
||||||
|
char *strtok ();
|
||||||
|
char *strdup ();
|
||||||
|
void *memcpy ();
|
||||||
|
#endif /* not __cplusplus */
|
||||||
|
#endif /* sun */
|
||||||
|
#endif /* STDC_HEADERS */
|
||||||
|
|
||||||
|
#endif /* SYSDEP_H */
|
98
src/url.h
Normal file
98
src/url.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* Declarations for url.c.
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef URL_H
|
||||||
|
#define URL_H
|
||||||
|
|
||||||
|
/* If the string contains unsafe characters, duplicate it with
|
||||||
|
encode_string, otherwise just copy it with strdup. */
|
||||||
|
#define CLEANDUP(x) (contains_unsafe (x) ? encode_string (x) : xstrdup (x))
|
||||||
|
|
||||||
|
/* Structure containing info on a URL. */
|
||||||
|
struct urlinfo
|
||||||
|
{
|
||||||
|
char *url; /* Unchanged URL */
|
||||||
|
uerr_t proto; /* URL protocol */
|
||||||
|
char *host; /* Extracted hostname */
|
||||||
|
unsigned short port;
|
||||||
|
char ftp_type;
|
||||||
|
char *path, *dir, *file; /* Path, as well as dir and file
|
||||||
|
(properly decoded) */
|
||||||
|
char *user, *passwd; /* Username and password */
|
||||||
|
struct urlinfo *proxy; /* The exact string to pass to proxy
|
||||||
|
server */
|
||||||
|
char *referer; /* The source from which the request
|
||||||
|
URI was obtained */
|
||||||
|
char *local; /* The local filename of the URL
|
||||||
|
document */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum uflags
|
||||||
|
{
|
||||||
|
URELATIVE = 0x0001, /* Is URL relative? */
|
||||||
|
UNOPROTO = 0x0002, /* Is URL without a protocol? */
|
||||||
|
UABS2REL = 0x0004, /* Convert absolute to relative? */
|
||||||
|
UREL2ABS = 0x0008 /* Convert relative to absolute? */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A structure that defines the whereabouts of a URL, i.e. its
|
||||||
|
position in an HTML document, etc. */
|
||||||
|
typedef struct _urlpos
|
||||||
|
{
|
||||||
|
char *url; /* URL */
|
||||||
|
char *local_name; /* Local file to which it was saved */
|
||||||
|
enum uflags flags; /* Various flags */
|
||||||
|
int pos, size; /* Rekative position in the buffer */
|
||||||
|
struct _urlpos *next; /* Next struct in list */
|
||||||
|
} urlpos;
|
||||||
|
|
||||||
|
|
||||||
|
/* Function declarations */
|
||||||
|
|
||||||
|
int skip_url PARAMS ((const char *));
|
||||||
|
|
||||||
|
int contains_unsafe PARAMS ((const char *));
|
||||||
|
char *encode_string PARAMS ((const char *));
|
||||||
|
|
||||||
|
struct urlinfo *newurl PARAMS ((void));
|
||||||
|
void freeurl PARAMS ((struct urlinfo *, int));
|
||||||
|
uerr_t urlproto PARAMS ((const char *));
|
||||||
|
int skip_proto PARAMS ((const char *));
|
||||||
|
int skip_uname PARAMS ((const char *));
|
||||||
|
|
||||||
|
uerr_t parseurl PARAMS ((const char *, struct urlinfo *, int));
|
||||||
|
char *str_url PARAMS ((const struct urlinfo *, int));
|
||||||
|
int url_equal PARAMS ((const char *, const char *));
|
||||||
|
|
||||||
|
urlpos *get_urls_file PARAMS ((const char *));
|
||||||
|
urlpos *get_urls_html PARAMS ((const char *, const char *, int));
|
||||||
|
void free_urlpos PARAMS ((urlpos *));
|
||||||
|
|
||||||
|
void rotate_backups PARAMS ((const char *));
|
||||||
|
int mkalldirs PARAMS ((const char *));
|
||||||
|
char *url_filename PARAMS ((const struct urlinfo *));
|
||||||
|
void opt_url PARAMS ((struct urlinfo *));
|
||||||
|
|
||||||
|
char *getproxy PARAMS ((uerr_t));
|
||||||
|
int no_proxy_match PARAMS ((const char *, const char **));
|
||||||
|
|
||||||
|
void convert_links PARAMS ((const char *, urlpos *));
|
||||||
|
urlpos *add_url PARAMS ((urlpos *, const char *, const char *));
|
||||||
|
|
||||||
|
#endif /* URL_H */
|
978
src/utils.c
Normal file
978
src/utils.c
Normal file
@ -0,0 +1,978 @@
|
|||||||
|
/* Various functions of utilitarian nature.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#else /* not HAVE_STRING_H */
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* not HAVE_STRING_H */
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
# include <pwd.h>
|
||||||
|
#endif
|
||||||
|
#include <limits.h>
|
||||||
|
#ifdef HAVE_UTIME_H
|
||||||
|
# include <utime.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_UTIME_H
|
||||||
|
# include <sys/utime.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef NeXT
|
||||||
|
# include <libc.h> /* for access() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wget.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "fnmatch.h"
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Croak the fatal memory error and bail out with non-zero exit
|
||||||
|
status. */
|
||||||
|
static void
|
||||||
|
memfatal (const char *s)
|
||||||
|
{
|
||||||
|
/* HACK: expose save_log_p from log.c, so we can turn it off in
|
||||||
|
order to prevent saving the log. Saving the log is dangerous
|
||||||
|
because logprintf() and logputs() can call malloc(), so this
|
||||||
|
could infloop. When logging is turned off, infloop can no longer
|
||||||
|
happen. */
|
||||||
|
extern int save_log_p;
|
||||||
|
|
||||||
|
save_log_p = 0;
|
||||||
|
logprintf (LOG_ALWAYS, _("%s: %s: Not enough memory.\n"), exec_name, s);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xmalloc, xrealloc and xstrdup exit the program if there is not
|
||||||
|
enough memory. xstrdup also implements strdup on systems that do
|
||||||
|
not have it. */
|
||||||
|
void *
|
||||||
|
xmalloc (size_t size)
|
||||||
|
{
|
||||||
|
void *res;
|
||||||
|
|
||||||
|
res = malloc (size);
|
||||||
|
if (!res)
|
||||||
|
memfatal ("malloc");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xrealloc (void *obj, size_t size)
|
||||||
|
{
|
||||||
|
void *res;
|
||||||
|
|
||||||
|
/* Not all Un*xes have the feature of realloc() that calling it with
|
||||||
|
a NULL-pointer is the same as malloc(), but it is easy to
|
||||||
|
simulate. */
|
||||||
|
if (obj)
|
||||||
|
res = realloc (obj, size);
|
||||||
|
else
|
||||||
|
res = malloc (size);
|
||||||
|
if (!res)
|
||||||
|
memfatal ("realloc");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
xstrdup (const char *s)
|
||||||
|
{
|
||||||
|
#ifndef HAVE_STRDUP
|
||||||
|
int l = strlen (s);
|
||||||
|
char *s1 = malloc (l + 1);
|
||||||
|
if (!s1)
|
||||||
|
memfatal ("strdup");
|
||||||
|
memcpy (s1, s, l + 1);
|
||||||
|
return s1;
|
||||||
|
#else /* HAVE_STRDUP */
|
||||||
|
char *s1 = strdup (s);
|
||||||
|
if (!s1)
|
||||||
|
memfatal ("strdup");
|
||||||
|
return s1;
|
||||||
|
#endif /* HAVE_STRDUP */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the string formed by two pointers (one on the beginning, other
|
||||||
|
on the char after the last char) to a new, malloc-ed location.
|
||||||
|
0-terminate it. */
|
||||||
|
char *
|
||||||
|
strdupdelim (const char *beg, const char *end)
|
||||||
|
{
|
||||||
|
char *res = (char *)xmalloc (end - beg + 1);
|
||||||
|
memcpy (res, beg, end - beg);
|
||||||
|
res[end - beg] = '\0';
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a string containing comma-separated elements, and return a
|
||||||
|
vector of char pointers with the elements. Spaces following the
|
||||||
|
commas are ignored. */
|
||||||
|
char **
|
||||||
|
sepstring (const char *s)
|
||||||
|
{
|
||||||
|
char **res;
|
||||||
|
const char *p;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!s || !*s)
|
||||||
|
return NULL;
|
||||||
|
res = NULL;
|
||||||
|
p = s;
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
if (*s == ',')
|
||||||
|
{
|
||||||
|
res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
|
||||||
|
res[i] = strdupdelim (p, s);
|
||||||
|
res[++i] = NULL;
|
||||||
|
++s;
|
||||||
|
/* Skip the blanks following the ','. */
|
||||||
|
while (ISSPACE (*s))
|
||||||
|
++s;
|
||||||
|
p = s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
res = (char **)xrealloc (res, (i + 2) * sizeof (char *));
|
||||||
|
res[i] = strdupdelim (p, s);
|
||||||
|
res[i + 1] = NULL;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return pointer to a static char[] buffer in which zero-terminated
|
||||||
|
string-representation of TM (in form hh:mm:ss) is printed. It is
|
||||||
|
shamelessly non-reentrant, but it doesn't matter, really.
|
||||||
|
|
||||||
|
If TM is non-NULL, the time_t of the current time will be stored
|
||||||
|
there. */
|
||||||
|
char *
|
||||||
|
time_str (time_t *tm)
|
||||||
|
{
|
||||||
|
static char tms[15];
|
||||||
|
struct tm *ptm;
|
||||||
|
time_t tim;
|
||||||
|
|
||||||
|
*tms = '\0';
|
||||||
|
tim = time (tm);
|
||||||
|
if (tim == -1)
|
||||||
|
return tms;
|
||||||
|
ptm = localtime (&tim);
|
||||||
|
sprintf (tms, "%02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
|
||||||
|
return tms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns an error message for ERRNUM. #### This requires more work.
|
||||||
|
This function, as well as the whole error system, is very
|
||||||
|
ill-conceived. */
|
||||||
|
const char *
|
||||||
|
uerrmsg (uerr_t errnum)
|
||||||
|
{
|
||||||
|
switch (errnum)
|
||||||
|
{
|
||||||
|
case URLUNKNOWN:
|
||||||
|
return _("Unknown/unsupported protocol");
|
||||||
|
break;
|
||||||
|
case URLBADPORT:
|
||||||
|
return _("Invalid port specification");
|
||||||
|
break;
|
||||||
|
case URLBADHOST:
|
||||||
|
return _("Invalid host name");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
/* $@#@#$ compiler. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Windows versions of the following two functions are defined in
|
||||||
|
mswindows.c. */
|
||||||
|
|
||||||
|
/* A cuserid() immitation using getpwuid(), to avoid hassling with
|
||||||
|
utmp. Besides, not all systems have cuesrid(). Under Windows, it
|
||||||
|
is defined in mswindows.c.
|
||||||
|
|
||||||
|
If WHERE is non-NULL, the username will be stored there.
|
||||||
|
Otherwise, it will be returned as a static buffer (as returned by
|
||||||
|
getpwuid()). In the latter case, the buffer should be copied
|
||||||
|
before calling getpwuid() or pwd_cuserid() again. */
|
||||||
|
#ifndef WINDOWS
|
||||||
|
char *
|
||||||
|
pwd_cuserid (char *where)
|
||||||
|
{
|
||||||
|
struct passwd *pwd;
|
||||||
|
|
||||||
|
if (!(pwd = getpwuid (getuid ())) || !pwd->pw_name)
|
||||||
|
return NULL;
|
||||||
|
if (where)
|
||||||
|
{
|
||||||
|
strcpy (where, pwd->pw_name);
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return pwd->pw_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fork_to_background (void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
/* Whether we arrange our own version of opt.lfilename here. */
|
||||||
|
int changedp = 0;
|
||||||
|
|
||||||
|
if (!opt.lfilename)
|
||||||
|
{
|
||||||
|
opt.lfilename = unique_name (DEFAULT_LOGFILE);
|
||||||
|
changedp = 1;
|
||||||
|
}
|
||||||
|
pid = fork ();
|
||||||
|
if (pid < 0)
|
||||||
|
{
|
||||||
|
/* parent, error */
|
||||||
|
perror ("fork");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else if (pid != 0)
|
||||||
|
{
|
||||||
|
/* parent, no error */
|
||||||
|
printf (_("Continuing in background.\n"));
|
||||||
|
if (changedp)
|
||||||
|
printf (_("Output will be written to `%s'.\n"), opt.lfilename);
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
/* child: keep running */
|
||||||
|
}
|
||||||
|
#endif /* not WINDOWS */
|
||||||
|
|
||||||
|
/* Canonicalize PATH, and return a new path. The new path differs from PATH
|
||||||
|
in that:
|
||||||
|
Multple `/'s are collapsed to a single `/'.
|
||||||
|
Leading `./'s and trailing `/.'s are removed.
|
||||||
|
Trailing `/'s are removed.
|
||||||
|
Non-leading `../'s and trailing `..'s are handled by removing
|
||||||
|
portions of the path.
|
||||||
|
|
||||||
|
E.g. "a/b/c/./../d/.." will yield "a/b". This function originates
|
||||||
|
from GNU Bash.
|
||||||
|
|
||||||
|
Changes for Wget:
|
||||||
|
Always use '/' as stub_char.
|
||||||
|
Don't check for local things using canon_stat.
|
||||||
|
Change the original string instead of strdup-ing.
|
||||||
|
React correctly when beginning with `./' and `../'. */
|
||||||
|
void
|
||||||
|
path_simplify (char *path)
|
||||||
|
{
|
||||||
|
register int i, start, ddot;
|
||||||
|
char stub_char;
|
||||||
|
|
||||||
|
if (!*path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*stub_char = (*path == '/') ? '/' : '.';*/
|
||||||
|
stub_char = '/';
|
||||||
|
|
||||||
|
/* Addition: Remove all `./'-s preceding the string. If `../'-s
|
||||||
|
precede, put `/' in front and remove them too. */
|
||||||
|
i = 0;
|
||||||
|
ddot = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (path[i] == '.' && path[i + 1] == '/')
|
||||||
|
i += 2;
|
||||||
|
else if (path[i] == '.' && path[i + 1] == '.' && path[i + 2] == '/')
|
||||||
|
{
|
||||||
|
i += 3;
|
||||||
|
ddot = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i)
|
||||||
|
strcpy (path, path + i - ddot);
|
||||||
|
|
||||||
|
/* Replace single `.' or `..' with `/'. */
|
||||||
|
if ((path[0] == '.' && path[1] == '\0')
|
||||||
|
|| (path[0] == '.' && path[1] == '.' && path[2] == '\0'))
|
||||||
|
{
|
||||||
|
path[0] = stub_char;
|
||||||
|
path[1] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Walk along PATH looking for things to compact. */
|
||||||
|
i = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!path[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
while (path[i] && path[i] != '/')
|
||||||
|
i++;
|
||||||
|
|
||||||
|
start = i++;
|
||||||
|
|
||||||
|
/* If we didn't find any slashes, then there is nothing left to do. */
|
||||||
|
if (!path[start])
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Handle multiple `/'s in a row. */
|
||||||
|
while (path[i] == '/')
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if ((start + 1) != i)
|
||||||
|
{
|
||||||
|
strcpy (path + start + 1, path + i);
|
||||||
|
i = start + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for trailing `/'. */
|
||||||
|
if (start && !path[i])
|
||||||
|
{
|
||||||
|
zero_last:
|
||||||
|
path[--i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for `../', `./' or trailing `.' by itself. */
|
||||||
|
if (path[i] == '.')
|
||||||
|
{
|
||||||
|
/* Handle trailing `.' by itself. */
|
||||||
|
if (!path[i + 1])
|
||||||
|
goto zero_last;
|
||||||
|
|
||||||
|
/* Handle `./'. */
|
||||||
|
if (path[i + 1] == '/')
|
||||||
|
{
|
||||||
|
strcpy (path + i, path + i + 1);
|
||||||
|
i = (start < 0) ? 0 : start;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle `../' or trailing `..' by itself. */
|
||||||
|
if (path[i + 1] == '.' &&
|
||||||
|
(path[i + 2] == '/' || !path[i + 2]))
|
||||||
|
{
|
||||||
|
while (--start > -1 && path[start] != '/');
|
||||||
|
strcpy (path + start + 1, path + i + 2);
|
||||||
|
i = (start < 0) ? 0 : start;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} /* path == '.' */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
if (!*path)
|
||||||
|
{
|
||||||
|
*path = stub_char;
|
||||||
|
path[1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "Touch" FILE, i.e. make its atime and mtime equal to the time
|
||||||
|
specified with TM. */
|
||||||
|
void
|
||||||
|
touch (const char *file, time_t tm)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_STRUCT_UTIMBUF
|
||||||
|
struct utimbuf times;
|
||||||
|
times.actime = times.modtime = tm;
|
||||||
|
#else
|
||||||
|
time_t times[2];
|
||||||
|
times[0] = times[1] = tm;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (utime (file, ×) == -1)
|
||||||
|
logprintf (LOG_NOTQUIET, "utime: %s\n", strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks if FILE is a symbolic link, and removes it if it is. Does
|
||||||
|
nothing under MS-Windows. */
|
||||||
|
int
|
||||||
|
remove_link (const char *file)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (lstat (file, &st) == 0 && S_ISLNK (st.st_mode))
|
||||||
|
{
|
||||||
|
DEBUGP (("Unlinking %s (symlink).\n", file));
|
||||||
|
err = unlink (file);
|
||||||
|
if (err != 0)
|
||||||
|
logprintf (LOG_VERBOSE, _("Failed to unlink symlink `%s': %s\n"),
|
||||||
|
file, strerror (errno));
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does FILENAME exist? This is quite a lousy implementation, since
|
||||||
|
it supplies no error codes -- only a yes-or-no answer. Thus it
|
||||||
|
will return that a file does not exist if, e.g., the directory is
|
||||||
|
unreadable. I don't mind it too much currently, though. The
|
||||||
|
proper way should, of course, be to have a third, error state,
|
||||||
|
other than true/false, but that would introduce uncalled-for
|
||||||
|
additional complexity to the callers. */
|
||||||
|
int
|
||||||
|
file_exists_p (const char *filename)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ACCESS
|
||||||
|
return access (filename, F_OK) >= 0;
|
||||||
|
#else
|
||||||
|
struct stat buf;
|
||||||
|
return stat (filename, &buf) >= 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 if PATH is a directory, 1 otherwise (any kind of file).
|
||||||
|
Returns 0 on error. */
|
||||||
|
int
|
||||||
|
file_non_directory_p (const char *path)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
/* Use lstat() rather than stat() so that symbolic links pointing to
|
||||||
|
directories can be identified correctly. */
|
||||||
|
if (lstat (path, &buf) != 0)
|
||||||
|
return 0;
|
||||||
|
return S_ISDIR (buf.st_mode) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a unique filename, given a prefix and count */
|
||||||
|
static char *
|
||||||
|
unique_name_1 (const char *fileprefix, int count)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
{
|
||||||
|
filename = (char *)xmalloc (strlen (fileprefix) + numdigit (count) + 2);
|
||||||
|
sprintf (filename, "%s.%d", fileprefix, count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
filename = xstrdup (fileprefix);
|
||||||
|
|
||||||
|
if (!file_exists_p (filename))
|
||||||
|
return filename;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a unique file name, based on PREFIX. */
|
||||||
|
char *
|
||||||
|
unique_name (const char *prefix)
|
||||||
|
{
|
||||||
|
char *file = NULL;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while (!file)
|
||||||
|
file = unique_name_1 (prefix, count++);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create DIRECTORY. If some of the pathname components of DIRECTORY
|
||||||
|
are missing, create them first. In case any mkdir() call fails,
|
||||||
|
return its error status. Returns 0 on successful completion.
|
||||||
|
|
||||||
|
The behaviour of this function should be identical to the behaviour
|
||||||
|
of `mkdir -p' on systems where mkdir supports the `-p' option. */
|
||||||
|
int
|
||||||
|
make_directory (const char *directory)
|
||||||
|
{
|
||||||
|
int quit = 0;
|
||||||
|
int i;
|
||||||
|
char *dir;
|
||||||
|
|
||||||
|
/* Make a copy of dir, to be able to write to it. Otherwise, the
|
||||||
|
function is unsafe if called with a read-only char *argument. */
|
||||||
|
STRDUP_ALLOCA (dir, directory);
|
||||||
|
|
||||||
|
/* If the first character of dir is '/', skip it (and thus enable
|
||||||
|
creation of absolute-pathname directories. */
|
||||||
|
for (i = (*dir == '/'); 1; ++i)
|
||||||
|
{
|
||||||
|
for (; dir[i] && dir[i] != '/'; i++)
|
||||||
|
;
|
||||||
|
if (!dir[i])
|
||||||
|
quit = 1;
|
||||||
|
dir[i] = '\0';
|
||||||
|
/* Check whether the directory already exists. */
|
||||||
|
if (!file_exists_p (dir))
|
||||||
|
{
|
||||||
|
if (mkdir (dir, 0777) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (quit)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
dir[i] = '/';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int in_acclist PARAMS ((const char *const *, const char *, int));
|
||||||
|
|
||||||
|
/* Determine whether a file is acceptable to be followed, according to
|
||||||
|
lists of patterns to accept/reject. */
|
||||||
|
int
|
||||||
|
acceptable (const char *s)
|
||||||
|
{
|
||||||
|
int l = strlen (s);
|
||||||
|
|
||||||
|
while (l && s[l] != '/')
|
||||||
|
--l;
|
||||||
|
if (s[l] == '/')
|
||||||
|
s += (l + 1);
|
||||||
|
if (opt.accepts)
|
||||||
|
{
|
||||||
|
if (opt.rejects)
|
||||||
|
return (in_acclist ((const char *const *)opt.accepts, s, 1)
|
||||||
|
&& !in_acclist ((const char *const *)opt.rejects, s, 1));
|
||||||
|
else
|
||||||
|
return in_acclist ((const char *const *)opt.accepts, s, 1);
|
||||||
|
}
|
||||||
|
else if (opt.rejects)
|
||||||
|
return !in_acclist ((const char *const *)opt.rejects, s, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare S1 and S2 frontally; S2 must begin with S1. E.g. if S1 is
|
||||||
|
`/something', frontcmp() will return 1 only if S2 begins with
|
||||||
|
`/something'. Otherwise, 0 is returned. */
|
||||||
|
int
|
||||||
|
frontcmp (const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
for (; *s1 && *s2 && (*s1 == *s2); ++s1, ++s2);
|
||||||
|
return !*s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate through STRLIST, and return the first element that matches
|
||||||
|
S, through wildcards or front comparison (as appropriate). */
|
||||||
|
static char *
|
||||||
|
proclist (char **strlist, const char *s, enum accd flags)
|
||||||
|
{
|
||||||
|
char **x;
|
||||||
|
|
||||||
|
for (x = strlist; *x; x++)
|
||||||
|
if (has_wildcards_p (*x))
|
||||||
|
{
|
||||||
|
if (fnmatch (*x, s, FNM_PATHNAME) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *p = *x + ((flags & ALLABS) && (**x == '/')); /* Remove '/' */
|
||||||
|
if (frontcmp (p, s))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns whether DIRECTORY is acceptable for download, wrt the
|
||||||
|
include/exclude lists.
|
||||||
|
|
||||||
|
If FLAGS is ALLABS, the leading `/' is ignored in paths; relative
|
||||||
|
and absolute paths may be freely intermixed. */
|
||||||
|
int
|
||||||
|
accdir (const char *directory, enum accd flags)
|
||||||
|
{
|
||||||
|
/* Remove starting '/'. */
|
||||||
|
if (flags & ALLABS && *directory == '/')
|
||||||
|
++directory;
|
||||||
|
if (opt.includes)
|
||||||
|
{
|
||||||
|
if (!proclist (opt.includes, directory, flags))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (opt.excludes)
|
||||||
|
{
|
||||||
|
if (proclist (opt.excludes, directory, flags))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Match the end of STRING against PATTERN. For instance:
|
||||||
|
|
||||||
|
match_backwards ("abc", "bc") -> 1
|
||||||
|
match_backwards ("abc", "ab") -> 0
|
||||||
|
match_backwards ("abc", "abc") -> 1 */
|
||||||
|
static int
|
||||||
|
match_backwards (const char *string, const char *pattern)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = strlen (string), j = strlen (pattern); i >= 0 && j >= 0; i--, j--)
|
||||||
|
if (string[i] != pattern[j])
|
||||||
|
break;
|
||||||
|
/* If the pattern was exhausted, the match was succesful. */
|
||||||
|
if (j == -1)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks whether string S matches each element of ACCEPTS. A list
|
||||||
|
element are matched either with fnmatch() or match_backwards(),
|
||||||
|
according to whether the element contains wildcards or not.
|
||||||
|
|
||||||
|
If the BACKWARD is 0, don't do backward comparison -- just compare
|
||||||
|
them normally. */
|
||||||
|
static int
|
||||||
|
in_acclist (const char *const *accepts, const char *s, int backward)
|
||||||
|
{
|
||||||
|
for (; *accepts; accepts++)
|
||||||
|
{
|
||||||
|
if (has_wildcards_p (*accepts))
|
||||||
|
{
|
||||||
|
/* fnmatch returns 0 if the pattern *does* match the
|
||||||
|
string. */
|
||||||
|
if (fnmatch (*accepts, s, 0) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (backward)
|
||||||
|
{
|
||||||
|
if (match_backwards (s, *accepts))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!strcmp (s, *accepts))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the malloc-ed suffix of STR. For instance:
|
||||||
|
suffix ("foo.bar") -> "bar"
|
||||||
|
suffix ("foo.bar.baz") -> "baz"
|
||||||
|
suffix ("/foo/bar") -> NULL
|
||||||
|
suffix ("/foo.bar/baz") -> NULL */
|
||||||
|
char *
|
||||||
|
suffix (const char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = strlen (str); i && str[i] != '/' && str[i] != '.'; i--);
|
||||||
|
if (str[i++] == '.')
|
||||||
|
return xstrdup (str + i);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a line from FP. The function reallocs the storage as needed
|
||||||
|
to accomodate for any length of the line. Reallocs are done
|
||||||
|
storage exponentially, doubling the storage after each overflow to
|
||||||
|
minimize the number of calls to realloc().
|
||||||
|
|
||||||
|
It is not an exemplary of correctness, since it kills off the
|
||||||
|
newline (and no, there is no way to know if there was a newline at
|
||||||
|
EOF). */
|
||||||
|
char *
|
||||||
|
read_whole_line (FILE *fp)
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
int i, bufsize, c;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
bufsize = 40;
|
||||||
|
line = (char *)xmalloc (bufsize);
|
||||||
|
/* Construct the line. */
|
||||||
|
while ((c = getc (fp)) != EOF && c != '\n')
|
||||||
|
{
|
||||||
|
if (i > bufsize - 1)
|
||||||
|
line = (char *)xrealloc (line, (bufsize <<= 1));
|
||||||
|
line[i++] = c;
|
||||||
|
}
|
||||||
|
if (c == EOF && !i)
|
||||||
|
{
|
||||||
|
free (line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Check for overflow at zero-termination (no need to double the
|
||||||
|
buffer in this case. */
|
||||||
|
if (i == bufsize)
|
||||||
|
line = (char *)xrealloc (line, i + 1);
|
||||||
|
line[i] = '\0';
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load file pointed to by FP to memory and return the malloc-ed
|
||||||
|
buffer with the contents. *NREAD will contain the number of read
|
||||||
|
bytes. The file is loaded in chunks, allocated exponentially,
|
||||||
|
starting with FILE_BUFFER_SIZE bytes. */
|
||||||
|
void
|
||||||
|
load_file (FILE *fp, char **buf, long *nread)
|
||||||
|
{
|
||||||
|
long bufsize;
|
||||||
|
|
||||||
|
bufsize = 512;
|
||||||
|
*nread = 0;
|
||||||
|
*buf = NULL;
|
||||||
|
while (!feof (fp) && !ferror (fp))
|
||||||
|
{
|
||||||
|
*buf = (char *)xrealloc (*buf, bufsize + *nread);
|
||||||
|
*nread += fread (*buf + *nread, sizeof (char), bufsize, fp);
|
||||||
|
bufsize <<= 1;
|
||||||
|
}
|
||||||
|
/* #### No indication of encountered error?? */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the pointers in a NULL-terminated vector of pointers, then
|
||||||
|
free the pointer itself. */
|
||||||
|
void
|
||||||
|
free_vec (char **vec)
|
||||||
|
{
|
||||||
|
if (vec)
|
||||||
|
{
|
||||||
|
char **p = vec;
|
||||||
|
while (*p)
|
||||||
|
free (*p++);
|
||||||
|
free (vec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append vector V2 to vector V1. The function frees V2 and
|
||||||
|
reallocates V1 (thus you may not use the contents of neither
|
||||||
|
pointer after the call). If V1 is NULL, V2 is returned. */
|
||||||
|
char **
|
||||||
|
merge_vecs (char **v1, char **v2)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (!v1)
|
||||||
|
return v2;
|
||||||
|
if (!v2)
|
||||||
|
return v1;
|
||||||
|
if (!*v2)
|
||||||
|
{
|
||||||
|
/* To avoid j == 0 */
|
||||||
|
free (v2);
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
/* Count v1. */
|
||||||
|
for (i = 0; v1[i]; i++);
|
||||||
|
/* Count v2. */
|
||||||
|
for (j = 0; v2[j]; j++);
|
||||||
|
/* Reallocate v1. */
|
||||||
|
v1 = (char **)xrealloc (v1, (i + j + 1) * sizeof (char **));
|
||||||
|
memcpy (v1 + i, v2, (j + 1) * sizeof (char *));
|
||||||
|
free (v2);
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A set of simple-minded routines to store and search for strings in
|
||||||
|
a linked list. You may add a string to the slist, and peek whether
|
||||||
|
it's still in there at any time later. */
|
||||||
|
|
||||||
|
/* Add an element to the list. If flags is NOSORT, the list will not
|
||||||
|
be sorted. */
|
||||||
|
slist *
|
||||||
|
add_slist (slist *l, const char *s, int flags)
|
||||||
|
{
|
||||||
|
slist *t, *old, *beg;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
if (flags & NOSORT)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
{
|
||||||
|
t = (slist *)xmalloc (sizeof (slist));
|
||||||
|
t->string = xstrdup (s);
|
||||||
|
t->next = NULL;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
beg = l;
|
||||||
|
/* Find the last element. */
|
||||||
|
while (l->next)
|
||||||
|
l = l->next;
|
||||||
|
t = (slist *)xmalloc (sizeof (slist));
|
||||||
|
l->next = t;
|
||||||
|
t->string = xstrdup (s);
|
||||||
|
t->next = NULL;
|
||||||
|
return beg;
|
||||||
|
}
|
||||||
|
/* Empty list or changing the first element. */
|
||||||
|
if (!l || (cmp = strcmp (l->string, s)) > 0)
|
||||||
|
{
|
||||||
|
t = (slist *)xmalloc (sizeof (slist));
|
||||||
|
t->string = xstrdup (s);
|
||||||
|
t->next = l;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
beg = l;
|
||||||
|
if (cmp == 0)
|
||||||
|
return beg;
|
||||||
|
|
||||||
|
/* Second two one-before-the-last element. */
|
||||||
|
while (l->next)
|
||||||
|
{
|
||||||
|
old = l;
|
||||||
|
l = l->next;
|
||||||
|
cmp = strcmp (s, l->string);
|
||||||
|
if (cmp == 0) /* no repeating in the list */
|
||||||
|
return beg;
|
||||||
|
else if (cmp > 0)
|
||||||
|
continue;
|
||||||
|
/* If the next list element is greater than s, put s between the
|
||||||
|
current and the next list element. */
|
||||||
|
t = (slist *)xmalloc (sizeof (slist));
|
||||||
|
old->next = t;
|
||||||
|
t->next = l;
|
||||||
|
t->string = xstrdup (s);
|
||||||
|
return beg;
|
||||||
|
}
|
||||||
|
t = (slist *)xmalloc (sizeof (slist));
|
||||||
|
t->string = xstrdup (s);
|
||||||
|
/* Insert the new element after the last element. */
|
||||||
|
l->next = t;
|
||||||
|
t->next = NULL;
|
||||||
|
return beg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there a specific entry in the list? */
|
||||||
|
int
|
||||||
|
in_slist (slist *l, const char *s)
|
||||||
|
{
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
cmp = strcmp (l->string, s);
|
||||||
|
if (cmp == 0)
|
||||||
|
return 1;
|
||||||
|
else if (cmp > 0) /* the list is ordered! */
|
||||||
|
return 0;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the whole slist. */
|
||||||
|
void
|
||||||
|
free_slist (slist *l)
|
||||||
|
{
|
||||||
|
slist *n;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
n = l->next;
|
||||||
|
free (l->string);
|
||||||
|
free (l);
|
||||||
|
l = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Legible -- return a static pointer to the legibly printed long. */
|
||||||
|
char *
|
||||||
|
legible (long l)
|
||||||
|
{
|
||||||
|
static char outbuf[20];
|
||||||
|
char inbuf[20];
|
||||||
|
int i, i1, mod;
|
||||||
|
char *outptr, *inptr;
|
||||||
|
|
||||||
|
/* Print the number into the buffer. */
|
||||||
|
long_to_string (inbuf, l);
|
||||||
|
/* Reset the pointers. */
|
||||||
|
outptr = outbuf;
|
||||||
|
inptr = inbuf;
|
||||||
|
/* If the number is negative, shift the pointers. */
|
||||||
|
if (*inptr == '-')
|
||||||
|
{
|
||||||
|
*outptr++ = '-';
|
||||||
|
++inptr;
|
||||||
|
}
|
||||||
|
/* How many digits before the first separator? */
|
||||||
|
mod = strlen (inptr) % 3;
|
||||||
|
/* Insert them. */
|
||||||
|
for (i = 0; i < mod; i++)
|
||||||
|
*outptr++ = inptr[i];
|
||||||
|
/* Now insert the rest of them, putting separator before every
|
||||||
|
third digit. */
|
||||||
|
for (i1 = i, i = 0; inptr[i1]; i++, i1++)
|
||||||
|
{
|
||||||
|
if (i % 3 == 0 && i1 != 0)
|
||||||
|
*outptr++ = ',';
|
||||||
|
*outptr++ = inptr[i1];
|
||||||
|
}
|
||||||
|
/* Zero-terminate the string. */
|
||||||
|
*outptr = '\0';
|
||||||
|
return outbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count the digits in a (long) integer. */
|
||||||
|
int
|
||||||
|
numdigit (long a)
|
||||||
|
{
|
||||||
|
int res = 1;
|
||||||
|
while ((a /= 10) != 0)
|
||||||
|
++res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print NUMBER to BUFFER. The digits are first written in reverse
|
||||||
|
order (the least significant digit first), and are then reversed. */
|
||||||
|
void
|
||||||
|
long_to_string (char *buffer, long number)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int i, l;
|
||||||
|
|
||||||
|
if (number < 0)
|
||||||
|
{
|
||||||
|
*buffer++ = '-';
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
p = buffer;
|
||||||
|
/* Print the digits to the string. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*p++ = number % 10 + '0';
|
||||||
|
number /= 10;
|
||||||
|
}
|
||||||
|
while (number);
|
||||||
|
/* And reverse them. */
|
||||||
|
l = p - buffer - 1;
|
||||||
|
for (i = l/2; i >= 0; i--)
|
||||||
|
{
|
||||||
|
char c = buffer[i];
|
||||||
|
buffer[i] = buffer[l - i];
|
||||||
|
buffer[l - i] = c;
|
||||||
|
}
|
||||||
|
buffer[l + 1] = '\0';
|
||||||
|
}
|
73
src/utils.h
Normal file
73
src/utils.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* Declarations for utils.c.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
/* Flags for slist. */
|
||||||
|
enum {
|
||||||
|
NOSORT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum accd {
|
||||||
|
ALLABS = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A linked list of strings. The list is ordered alphabetically. */
|
||||||
|
typedef struct _slist
|
||||||
|
{
|
||||||
|
char *string;
|
||||||
|
struct _slist *next;
|
||||||
|
} slist;
|
||||||
|
|
||||||
|
char *time_str PARAMS ((time_t *));
|
||||||
|
const char *uerrmsg PARAMS ((uerr_t));
|
||||||
|
|
||||||
|
char *strdupdelim PARAMS ((const char *, const char *));
|
||||||
|
char **sepstring PARAMS ((const char *));
|
||||||
|
int frontcmp PARAMS ((const char *, const char *));
|
||||||
|
char *pwd_cuserid PARAMS ((char *));
|
||||||
|
void fork_to_background PARAMS ((void));
|
||||||
|
void path_simplify PARAMS ((char *));
|
||||||
|
|
||||||
|
void touch PARAMS ((const char *, time_t));
|
||||||
|
int remove_link PARAMS ((const char *));
|
||||||
|
int file_exists_p PARAMS ((const char *));
|
||||||
|
int file_non_directory_p PARAMS ((const char *));
|
||||||
|
int make_directory PARAMS ((const char *));
|
||||||
|
char *unique_name PARAMS ((const char *));
|
||||||
|
|
||||||
|
int acceptable PARAMS ((const char *));
|
||||||
|
int accdir PARAMS ((const char *s, enum accd));
|
||||||
|
char *suffix PARAMS ((const char *s));
|
||||||
|
|
||||||
|
char *read_whole_line PARAMS ((FILE *));
|
||||||
|
void load_file PARAMS ((FILE *, char **, long *));
|
||||||
|
|
||||||
|
void free_vec PARAMS ((char **));
|
||||||
|
char **merge_vecs PARAMS ((char **, char **));
|
||||||
|
slist *add_slist PARAMS ((slist *, const char *, int));
|
||||||
|
int in_slist PARAMS ((slist *, const char *));
|
||||||
|
void free_slist PARAMS ((slist *));
|
||||||
|
|
||||||
|
char *legible PARAMS ((long));
|
||||||
|
int numdigit PARAMS ((long));
|
||||||
|
void long_to_string PARAMS ((char *, long));
|
||||||
|
|
||||||
|
#endif /* UTILS_H */
|
1
src/version.c
Normal file
1
src/version.c
Normal file
@ -0,0 +1 @@
|
|||||||
|
char *version_string = "1.5.3";
|
201
src/wget.h
Normal file
201
src/wget.h
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/* Miscellaneous declarations.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Wget.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
/* This file contains some declarations that don't fit anywhere else.
|
||||||
|
It also contains some useful includes, like the obnoxious TIME_H
|
||||||
|
inclusion. */
|
||||||
|
|
||||||
|
#ifndef WGET_H
|
||||||
|
#define WGET_H
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
# define NDEBUG /* To kill off assertions */
|
||||||
|
#endif /* not DEBUG */
|
||||||
|
|
||||||
|
#ifndef PARAMS
|
||||||
|
# if PROTOTYPES
|
||||||
|
# define PARAMS(args) args
|
||||||
|
# else
|
||||||
|
# define PARAMS(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* `gettext (FOO)' is long to write, so we use `_(FOO)'. If NLS is
|
||||||
|
unavailable, _(STRING) simply returns STRING. */
|
||||||
|
#ifdef HAVE_NLS
|
||||||
|
# define _(string) gettext (string)
|
||||||
|
# ifdef HAVE_LIBINTL_H
|
||||||
|
# include <libintl.h>
|
||||||
|
# endif /* HAVE_LIBINTL_H */
|
||||||
|
#else /* not HAVE_NLS */
|
||||||
|
# define _(string) string
|
||||||
|
#endif /* not HAVE_NLS */
|
||||||
|
|
||||||
|
/* I18N NOTE: You will notice that none of the DEBUG messages are
|
||||||
|
marked as translatable. This is intentional, for a few reasons:
|
||||||
|
|
||||||
|
1) The debug messages are not meant for the users to look at, but
|
||||||
|
for the developers; as such, they should be considered more like
|
||||||
|
source comments than real program output.
|
||||||
|
|
||||||
|
2) The messages are numerous, and yet they are random and frivolous
|
||||||
|
("double yuck!" and such). There would be a lot of work with no
|
||||||
|
gain.
|
||||||
|
|
||||||
|
3) Finally, the debug messages are meant to be a clue for me to
|
||||||
|
debug problems with Wget. If I get them in a language I don't
|
||||||
|
understand, debugging will become a new challenge of its own! :-) */
|
||||||
|
|
||||||
|
|
||||||
|
/* Include these, so random files need not include them. */
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#define DO_NOTHING do {} while (0)
|
||||||
|
|
||||||
|
/* Print X if debugging is enabled; a no-op otherwise. */
|
||||||
|
#ifdef DEBUG
|
||||||
|
# define DEBUGP(x) do { debug_logprintf x; } while (0)
|
||||||
|
#else /* not DEBUG */
|
||||||
|
# define DEBUGP(x) DO_NOTHING
|
||||||
|
#endif /* not DEBUG */
|
||||||
|
|
||||||
|
/* Make gcc check for the format of logmsg() and debug_logmsg(). */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define GCC_FORMAT_ATTR(a, b) __attribute__ ((format (printf, a, b)))
|
||||||
|
#else /* not __GNUC__ */
|
||||||
|
# define GCC_FORMAT_ATTR(a, b)
|
||||||
|
#endif /* not __GNUC__ */
|
||||||
|
|
||||||
|
/* These are from log.c, but they are used everywhere, so we declare
|
||||||
|
them here. */
|
||||||
|
enum log_options { LOG_VERBOSE, LOG_NOTQUIET, LOG_NONVERBOSE, LOG_ALWAYS };
|
||||||
|
|
||||||
|
void logprintf PARAMS ((enum log_options, const char *, ...))
|
||||||
|
GCC_FORMAT_ATTR (2, 3);
|
||||||
|
void debug_logprintf PARAMS ((const char *, ...)) GCC_FORMAT_ATTR (1, 2);
|
||||||
|
void logputs PARAMS ((enum log_options, const char *));
|
||||||
|
|
||||||
|
/* Defined in `utils.c', but used literally everywhere. */
|
||||||
|
void *xmalloc PARAMS ((size_t));
|
||||||
|
void *xrealloc PARAMS ((void *, size_t));
|
||||||
|
char *xstrdup PARAMS ((const char *));
|
||||||
|
|
||||||
|
/* #### Find a better place for this. */
|
||||||
|
/* The log file to which Wget writes to after HUP. */
|
||||||
|
#define DEFAULT_LOGFILE "wget-log"
|
||||||
|
|
||||||
|
#define MD5_HASHLEN 16
|
||||||
|
|
||||||
|
/* Useful macros used across the code: */
|
||||||
|
|
||||||
|
/* Is the string a hpyhen-only? */
|
||||||
|
#define HYPHENP(x) (*(x) == '-' && !*((x) + 1))
|
||||||
|
|
||||||
|
/* The smaller value of the two. */
|
||||||
|
#define MINVAL(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
/* ASCII char -> HEX digit */
|
||||||
|
#define ASC2HEXD(x) (((x) >= '0' && (x) <= '9') ? \
|
||||||
|
((x) - '0') : (toupper(x) - 'A' + 10))
|
||||||
|
|
||||||
|
/* HEX digit -> ASCII char */
|
||||||
|
#define HEXD2ASC(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'A'))
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(array) (sizeof (array) / sizeof (*(array)))
|
||||||
|
|
||||||
|
/* Note that this much more elegant definition cannot be used:
|
||||||
|
|
||||||
|
#define STRDUP_ALLOCA(str) (strcpy ((char *)alloca (strlen (str) + 1), str))
|
||||||
|
|
||||||
|
This is because some compilers don't handle alloca() as argument to
|
||||||
|
function correctly. Gcc under Intel has been reported to offend in
|
||||||
|
this case. */
|
||||||
|
|
||||||
|
#define STRDUP_ALLOCA(ptr, str) do { \
|
||||||
|
(ptr) = (char *)alloca (strlen (str) + 1); \
|
||||||
|
strcpy (ptr, str); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ALLOCA_ARRAY(type, len) ((type *) alloca ((len) * sizeof (type)))
|
||||||
|
|
||||||
|
#define XREALLOC_ARRAY(ptr, type, len) \
|
||||||
|
((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
|
||||||
|
|
||||||
|
/* Generally useful if you want to avoid arbitrary size limits but
|
||||||
|
don't need a full dynamic array. Assumes that BASEVAR points to a
|
||||||
|
malloced array of TYPE objects (or possibly a NULL pointer, if
|
||||||
|
SIZEVAR is 0), with the total size stored in SIZEVAR. This macro
|
||||||
|
will realloc BASEVAR as necessary so that it can hold at least
|
||||||
|
NEEDED_SIZE objects. The reallocing is done by doubling, which
|
||||||
|
ensures constant amortized time per element. */
|
||||||
|
#define DO_REALLOC(basevar, sizevar, needed_size, type) do \
|
||||||
|
{ \
|
||||||
|
/* Avoid side-effectualness. */ \
|
||||||
|
long do_realloc_needed_size = (needed_size); \
|
||||||
|
long do_realloc_newsize = 0; \
|
||||||
|
while ((sizevar) < (do_realloc_needed_size)) { \
|
||||||
|
do_realloc_newsize = 2*(sizevar); \
|
||||||
|
if (do_realloc_newsize < 32) \
|
||||||
|
do_realloc_newsize = 32; \
|
||||||
|
(sizevar) = do_realloc_newsize; \
|
||||||
|
} \
|
||||||
|
if (do_realloc_newsize) \
|
||||||
|
XREALLOC_ARRAY (basevar, type, do_realloc_newsize); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Free FOO if it is non-NULL. */
|
||||||
|
#define FREE_MAYBE(foo) do { if (foo) free (foo); } while (0)
|
||||||
|
|
||||||
|
/* #### Hack: OPTIONS_DEFINED_HERE is defined in main.c. */
|
||||||
|
#ifndef OPTIONS_DEFINED_HERE
|
||||||
|
extern const char *exec_name;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Document-type flags */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TEXTHTML = 0x0001, /* document is of type text/html */
|
||||||
|
RETROKF = 0x0002, /* retrieval was OK */
|
||||||
|
HEAD_ONLY = 0x0004, /* only send the HEAD request */
|
||||||
|
SEND_NOCACHE = 0x0008, /* send Pragma: no-cache directive */
|
||||||
|
ACCEPTRANGES = 0x0010 /* Accept-ranges header was found */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Universal error type -- used almost everywhere.
|
||||||
|
This is, of course, utter crock. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NOCONERROR, HOSTERR, CONSOCKERR, CONERROR,
|
||||||
|
CONREFUSED, NEWLOCATION, NOTENOUGHMEM, CONPORTERR,
|
||||||
|
BINDERR, BINDOK, LISTENERR, ACCEPTERR, ACCEPTOK,
|
||||||
|
CONCLOSED, FTPOK, FTPLOGINC, FTPLOGREFUSED, FTPPORTERR,
|
||||||
|
FTPNSFOD, FTPRETROK, FTPUNKNOWNTYPE, FTPRERR,
|
||||||
|
FTPREXC, FTPSRVERR, FTPRETRINT, FTPRESTFAIL,
|
||||||
|
URLOK, URLHTTP, URLFTP, URLFILE, URLUNKNOWN, URLBADPORT,
|
||||||
|
URLBADHOST, FOPENERR, FWRITEERR, HOK, HLEXC, HEOF,
|
||||||
|
HERR, RETROK, RECLEVELEXC, FTPACCDENIED, WRONGCODE,
|
||||||
|
FTPINVPASV, FTPNOPASV,
|
||||||
|
RETRFINISHED, READERR, TRYLIMEXC, URLBADPATTERN,
|
||||||
|
FILEBADFILE, RANGEERR, RETRBADPATTERN, RETNOTSUP,
|
||||||
|
ROBOTSOK, NOROBOTS, PROXERR, AUTHFAILED, QUOTEXC, WRITEFAILED
|
||||||
|
} uerr_t;
|
||||||
|
|
||||||
|
#endif /* WGET_H */
|
1
stamp-h.in
Normal file
1
stamp-h.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
timestamp
|
37
util/Makefile.in
Normal file
37
util/Makefile.in
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Makefile for `wget' utility
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Version: @VERSION@
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
||||||
|
clean:
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) Makefile
|
||||||
|
|
||||||
|
realclean: distclean
|
||||||
|
|
28
util/README
Normal file
28
util/README
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-*- text -*-
|
||||||
|
|
||||||
|
This directory contains various optional utilities to help you use
|
||||||
|
Wget.
|
||||||
|
|
||||||
|
|
||||||
|
Socks:
|
||||||
|
======
|
||||||
|
Antonio Rosella <antonio.rosella@agip.it> has written a sample HTML
|
||||||
|
frontend and a Perl script to demonstrate usage of socksified Wget as
|
||||||
|
web retriever.
|
||||||
|
|
||||||
|
To configure Wget to use socks, do a
|
||||||
|
$ ./configure --with-sox.
|
||||||
|
|
||||||
|
download.html and download-netscape.html are examples of how you can
|
||||||
|
use socksified Wget to schedule the WWW requests. wget.cgi is a
|
||||||
|
CGI Perl script used in conjunction with download.html, which
|
||||||
|
schedules request using the "at" command.
|
||||||
|
|
||||||
|
To get the script, contact Antonino.
|
||||||
|
|
||||||
|
rmold.pl
|
||||||
|
========
|
||||||
|
This Perl script is used to check which local files are no longer on
|
||||||
|
the remote server. You can use it to get the list of files, or
|
||||||
|
$ rmold.pl [dir] | xargs rm
|
||||||
|
|
114
util/download-netscape.html
Normal file
114
util/download-netscape.html
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Wget Gateway</title>
|
||||||
|
<link rev="made" href="mailto:Antonio.Rosella@agip.it">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<center>
|
||||||
|
<h1>Wget Gateway</h1>
|
||||||
|
</center>
|
||||||
|
<p>
|
||||||
|
Welcome to Wget Gateway, a simple page showing the usage of
|
||||||
|
socksified wget behind a firewall. In my configuration it is
|
||||||
|
very useful because:
|
||||||
|
<ul>
|
||||||
|
<li>Only few users can exit from firewall
|
||||||
|
<li>A lot of users need information that can be reached in Internet
|
||||||
|
<li>I cannot dowload big files during my job time, so, I
|
||||||
|
have to schedule the requests after the normal work time
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
With the combination of a socksified wget and a simple cgi
|
||||||
|
that schedules the requests can I reach the aim. All you need
|
||||||
|
is:
|
||||||
|
<ul>
|
||||||
|
<li> A socksified copy of
|
||||||
|
<a href="ftp://gnjilux.cc.fer.hr/pub/unix/util/wget/wget.tar.gz">
|
||||||
|
wget</a>
|
||||||
|
<li> Perl (available on all the GNU mirroring sites)
|
||||||
|
<li> cgi-lib.pl (available at
|
||||||
|
<a href="ftp://ftp.switch.ch/mirror/CPAN/ROADMAP.html">CPAN</a>)
|
||||||
|
<li> A customized copy of this html
|
||||||
|
<li> A customized copy of socks.cgi
|
||||||
|
</ul>
|
||||||
|
This is my h/s configuration:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
+----------+ +----------------------------------+ +---------------------+
|
||||||
|
| Firewall | | Host that can exit from firewall | | Intranet www server |
|
||||||
|
+----------+ | htceff | +---------------------+
|
||||||
|
+----------------------------------+ | Wget.html |
|
||||||
|
| socksified wget | +---------------------+
|
||||||
|
| cgi-lib.pl |
|
||||||
|
| perl |
|
||||||
|
| wget.cgi |
|
||||||
|
+----------------------------------+
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
wget.cgi, wget and cgi-lib.pl are located in the usual
|
||||||
|
cgi-bin directory. The customization of wget.cgi and
|
||||||
|
wget.html has to reflect you installation, i.e.:
|
||||||
|
<ul>
|
||||||
|
<li> download-netscape.html requires wget.cgi
|
||||||
|
<li> wget.cgi requires Perl, cgi-lib.pl and wget
|
||||||
|
<li>
|
||||||
|
wget.cgi has to download the files to a directory writable
|
||||||
|
by the user submitting the request. At the moment I have an
|
||||||
|
anonymous ftp installed on <em>htceff</em>, and wget puts
|
||||||
|
dowloaded files to /pub/incoming directory (if you look at
|
||||||
|
wget.cgi, it sets the destdir to "/u/ftp/pub/incoming" if
|
||||||
|
the user leaves it blank).
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
You can also add other parameters that you want to pass to wget,
|
||||||
|
but in this case you will also have to modify wget.cgi
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<form method="get" action="http://localhost/cgi-bin/wget.cgi">
|
||||||
|
<center>
|
||||||
|
<table border=1>
|
||||||
|
<td>Recursive Download
|
||||||
|
<td><select name=Recursion>
|
||||||
|
<Option selected value=N>No</Option>
|
||||||
|
<Option value=Y>Yes</Option>
|
||||||
|
</select>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<table border=1>
|
||||||
|
<td>Depth
|
||||||
|
<td><input type="radio" name=depth value=1 checked> 1
|
||||||
|
<td><input type="radio" name=depth value=2 > 2
|
||||||
|
<td><input type="radio" name=depth value=3 > 3
|
||||||
|
<td><input type="radio" name=depth value=4 > 4
|
||||||
|
<td><input type="radio" name=depth value=5 > 5
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<table>
|
||||||
|
<td>Url to download: <td><input name="url" size=50><TR>
|
||||||
|
<td>Destination directory: <td><input name="destdir" size=50><TR>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
Now you can
|
||||||
|
<font color=yellow><input type="submit" value="download"></font>
|
||||||
|
the requested URL or
|
||||||
|
<font color=yellow><input type="reset" value="reset"></font>
|
||||||
|
the form.
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
Feedback is always useful! Please contact me at
|
||||||
|
<address>
|
||||||
|
<a href="mailto:Antonio.Rosella@agip.it">Antonio Rosella<Antonio.Rosella@agip.it></a>.
|
||||||
|
</address>
|
||||||
|
You can send your suggestions or bug reports for Wget to
|
||||||
|
<address>
|
||||||
|
<a href="mailto:hniksic@srce.hr">Hrvoje Niksic <hniksic@srce.hr></a>.
|
||||||
|
</address>
|
||||||
|
<!-- hhmts start -->
|
||||||
|
Last modified: Thu Mar 26 16:26:36 MET 1998
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
106
util/download.html
Normal file
106
util/download.html
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Wget Gateway</title>
|
||||||
|
<link rev="made" href="mailto:Antonio.Rosella@agip.it">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Wget Gateway</h1>
|
||||||
|
<p>
|
||||||
|
Welcome to Wget Gateway, a simple page showing the usage of
|
||||||
|
socksified wget behind a firewall. In my configuration it is
|
||||||
|
very useful because:
|
||||||
|
<ul>
|
||||||
|
<li>Only few users can exit from firewall
|
||||||
|
<li>A lot of users need information that can be reached in Internet
|
||||||
|
<li>I cannot dowload big files during my job time, so, I
|
||||||
|
have to schedule the requests after the normal work time
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
With the combination of a socksified wget and a simple cgi
|
||||||
|
that schedules the requests can I reach the aim. All you need
|
||||||
|
is:
|
||||||
|
<ul>
|
||||||
|
<li> A socksified copy of
|
||||||
|
<a href="ftp://gnjilux.cc.fer.hr/pub/unix/util/wget/wget.tar.gz">
|
||||||
|
wget</a>
|
||||||
|
<li> Perl (available on all the GNU mirroring sites)
|
||||||
|
<li> cgi-lib.pl (available at
|
||||||
|
<a href="ftp://ftp.switch.ch/mirror/CPAN/ROADMAP.html">CPAN</a>)
|
||||||
|
<li> A customized copy of this html
|
||||||
|
<li> A customized copy of socks.cgi
|
||||||
|
</ul>
|
||||||
|
This is my h/s configuration:
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
+----------+ +----------------------------------+ +---------------------+
|
||||||
|
| Firewall | | Host that can exit from firewall | | Intranet www server |
|
||||||
|
+----------+ | htceff | +---------------------+
|
||||||
|
+----------------------------------+ | Wget.html |
|
||||||
|
| socksified wget | +---------------------+
|
||||||
|
| cgi-lib.pl |
|
||||||
|
| perl |
|
||||||
|
| wget.cgi |
|
||||||
|
+----------------------------------+
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
wget.cgi, wget and cgi-lib.pl are located in the usual
|
||||||
|
cgi-bin directory. The customization of wget.cgi and
|
||||||
|
wget.html has to reflect you installation, i.e.:
|
||||||
|
<ul>
|
||||||
|
<li> download.html requires wget.cgi
|
||||||
|
<li> wget.cgi requires Perl, cgi-lib.pl and wget
|
||||||
|
<li>
|
||||||
|
wget.cgi has to download the files to a directory writable
|
||||||
|
by the user submitting the request. At the moment I have an
|
||||||
|
anonymous ftp installed on <em>htceff</em>, and wget puts
|
||||||
|
dowloaded files to /pub/incoming directory (if you look at
|
||||||
|
wget.cgi, it sets the destdir to "/u/ftp/pub/incoming" if
|
||||||
|
the user leaves it blank).
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
You can also add other parameters that you want to pass to wget,
|
||||||
|
but in this case you will also have to modify wget.cgi
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<form method="get" action="http://localhost/cgi-bin/wget.cgi">
|
||||||
|
<h3>Downloading (optionally recursive)</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Recursion:
|
||||||
|
<Select name=Recursion>
|
||||||
|
<Option selected value=N>No</Option>
|
||||||
|
<Option value=Y>Yes</Option>
|
||||||
|
</Select>
|
||||||
|
<li>
|
||||||
|
Depth:
|
||||||
|
<input type="radio" name=depth value=1 checked>1
|
||||||
|
<input type="radio" name=depth value=2 >2
|
||||||
|
<input type="radio" name=depth value=3 >3
|
||||||
|
<input type="radio" name=depth value=4 >4
|
||||||
|
<input type="radio" name=depth value=5 >5
|
||||||
|
<li>
|
||||||
|
Url to download: <input name="url" size=50>
|
||||||
|
<li>
|
||||||
|
Destination directory: <input name="destdir" size=50>
|
||||||
|
</ul>
|
||||||
|
Now you can <input type="submit" value="download"> the
|
||||||
|
requested URL or <input type="reset" value="reset"> the form.
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
Feedback is always useful! Please contact me at
|
||||||
|
<address>
|
||||||
|
<a href="mailto:Antonio.Rosella@agip.it">Antonio Rosella<Antonio.Rosella@agip.it></a>.
|
||||||
|
</address>
|
||||||
|
You can send your suggestions or bug reports for Wget to
|
||||||
|
<address>
|
||||||
|
<a href="mailto:hniksic@srce.hr">Hrvoje Niksic <hniksic@srce.hr></a>.
|
||||||
|
</address>
|
||||||
|
<!-- hhmts start -->
|
||||||
|
Last modified: Thu Mar 26 16:26:39 MET 1998
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
92
util/rmold.pl
Executable file
92
util/rmold.pl
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#! /usr/bin/perl -w
|
||||||
|
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
|
||||||
|
# This script is a very lame hack to remove local files, until the
|
||||||
|
# time when Wget proper will have this functionality.
|
||||||
|
# Use with utmost care!
|
||||||
|
|
||||||
|
# If the remote server supports BSD-style listings, set this to 0.
|
||||||
|
$sysvlisting = 1;
|
||||||
|
|
||||||
|
$verbose = 0;
|
||||||
|
|
||||||
|
if (@ARGV && ($ARGV[0] eq '-v')) {
|
||||||
|
shift;
|
||||||
|
$verbose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
defined($dirs[0] = shift) || ($dirs[0] = '.');
|
||||||
|
while (defined($_ = shift)) {
|
||||||
|
@dirs = (@dirs, $_);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach $_ (@dirs) {
|
||||||
|
&procdir($_);
|
||||||
|
}
|
||||||
|
|
||||||
|
# End here
|
||||||
|
|
||||||
|
sub procdir
|
||||||
|
{
|
||||||
|
local($dir = $_[0]);
|
||||||
|
local(@lcfiles, @lcdirs, %files, @fl);
|
||||||
|
|
||||||
|
print STDERR "Processing directory '$dir':\n" if $verbose;
|
||||||
|
|
||||||
|
opendir(DH, $dir) || die("Cannot open $dir: $!\n");
|
||||||
|
@lcfiles = ();
|
||||||
|
@lcdirs = ();
|
||||||
|
# Read local files and directories.
|
||||||
|
foreach $_ (readdir(DH)) {
|
||||||
|
/^(\.listing|\.\.?)$/ && next;
|
||||||
|
if (-d "$dir/$_" || -l "$dir/$_") {
|
||||||
|
@lcdirs = (@lcdirs, $_);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@lcfiles = (@lcfiles, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(DH);
|
||||||
|
# Parse .listing
|
||||||
|
if (open(FD, "<$dir/.listing")) {
|
||||||
|
@files = ();
|
||||||
|
while (<FD>)
|
||||||
|
{
|
||||||
|
# Weed out the line beginning with 'total'
|
||||||
|
/^total/ && next;
|
||||||
|
# Weed out everything but plain files and symlinks.
|
||||||
|
/^[-l]/ || next;
|
||||||
|
@fl = split;
|
||||||
|
$files{$fl[7 + $sysvlisting]} = 1;
|
||||||
|
}
|
||||||
|
close FD;
|
||||||
|
foreach $_ (@lcfiles) {
|
||||||
|
if (!$files{$_}) {
|
||||||
|
print "$dir/$_\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print STDERR "Warning: $dir/.listing: $!\n";
|
||||||
|
}
|
||||||
|
foreach $_ (@lcdirs) {
|
||||||
|
&procdir("$dir/$_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
57
util/wget.spec
Normal file
57
util/wget.spec
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
Summary: A command-line client to download WWW/FTP documents with optional recursion.
|
||||||
|
Name: wget
|
||||||
|
%define version 1.4.5
|
||||||
|
Version: %{version}
|
||||||
|
Release: 3
|
||||||
|
Source: ftp://prep.ai.mit.edu/pub/gnu/wget-1.4.5.tar.gz
|
||||||
|
Group: Applications/Networking
|
||||||
|
Copyright: GPL
|
||||||
|
Buildroot: /var/tmp/wget-root
|
||||||
|
Packager: Jeff Johnson <jbj@jbj.org>
|
||||||
|
|
||||||
|
%description
|
||||||
|
GNU Wget is a freely available network utility to retrieve files from
|
||||||
|
the World Wide Web, using HTTP (Hyper Text Transfer Protocol) and
|
||||||
|
FTP (File Transfer Protocol), the two most widely used Internet
|
||||||
|
protocols.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup
|
||||||
|
|
||||||
|
%build
|
||||||
|
./configure --prefix=/usr --sysconfdir=/etc
|
||||||
|
make
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
make prefix=$RPM_BUILD_ROOT/usr sysconfdir=$RPM_BUILD_ROOT/etc INSTALL_PROGRAM="install -s" install
|
||||||
|
|
||||||
|
gzip -9nf $RPM_BUILD_ROOT/usr/info/wget*
|
||||||
|
|
||||||
|
%post
|
||||||
|
|
||||||
|
/sbin/install-info /usr/info/wget.info.gz /usr/info/dir --entry="* wget: (wget). GNU Wget Manual."
|
||||||
|
|
||||||
|
%preun
|
||||||
|
|
||||||
|
if [ $1 = 0 ]; then
|
||||||
|
/sbin/install-info --delete /usr/info/wget.info.gz /usr/info/dir --entry="* wget: (wget). GNU Wget Manual."
|
||||||
|
fi
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%files
|
||||||
|
%doc README NEWS AUTHORS COPYING INSTALL MACHINES MAILING-LIST
|
||||||
|
/usr/bin/wget
|
||||||
|
/etc/wgetrc
|
||||||
|
/usr/info/wget*
|
||||||
|
/usr/man/man1/wget.1
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
|
||||||
|
* Thu Feb 26 1998 Jeff Johnson <jbj@jbj.org>
|
||||||
|
|
||||||
|
- Simplify previous contrib version.
|
||||||
|
|
42
windows/Makefile.doc
Normal file
42
windows/Makefile.doc
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Makefile for `wget' utility
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
RM = del
|
||||||
|
|
||||||
|
all: wget.hlp
|
||||||
|
|
||||||
|
# You probably need makeinfo utility
|
||||||
|
# wget it from URL:http://www.sunsite.auc.dk/wget/makeinfo.zip
|
||||||
|
|
||||||
|
.IGNORE:
|
||||||
|
wget.hlp: wget.texi
|
||||||
|
makeinfo --no-validate --no-warn --force \
|
||||||
|
--hpj wget.hpj --output wget.rtf wget.texi
|
||||||
|
hcrtf -xn wget.hpj
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.bak
|
||||||
|
$(RM) *.hpj
|
||||||
|
$(RM) *.rtf
|
||||||
|
$(RM) *.ph
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) wget.hlp
|
||||||
|
$(RM) Makefile
|
||||||
|
|
||||||
|
realclean: distclean
|
||||||
|
|
91
windows/Makefile.src
Normal file
91
windows/Makefile.src
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# Makefile for `wget' utility for MSVC 4.0
|
||||||
|
# Copyright (C) 1995, 1996, 1997 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 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Version: 1.4.4
|
||||||
|
#
|
||||||
|
|
||||||
|
SHELL = command
|
||||||
|
|
||||||
|
VPATH = .
|
||||||
|
o = .obj
|
||||||
|
OUTDIR = .
|
||||||
|
|
||||||
|
CC = cl
|
||||||
|
LD = link
|
||||||
|
|
||||||
|
CFLAGS = /nologo /MT /W0 /O2
|
||||||
|
#DEBUGCF = /DDEBUG /Zi /Od #/Fd /FR
|
||||||
|
CPPFLAGS =
|
||||||
|
DEFS = /DWINDOWS /D_CONSOLE /DHAVE_CONFIG_H /DSYSTEM_WGETRC=\"wgetrc\"
|
||||||
|
LDFLAGS = /subsystem:console /incremental:no /warn:3
|
||||||
|
#DEBUGLF = /pdb:wget.pdb /debug /debugtype:cv /map:wget.map /opt:noref
|
||||||
|
LIBS = kernel32.lib advapi32.lib wsock32.lib user32.lib
|
||||||
|
|
||||||
|
INCLUDES = /I.
|
||||||
|
|
||||||
|
COMPILE = $(CC) $(INCLUDES) $(CPPFLAGS) $(DEBUGCF) $(DEFS) $(CFLAGS)
|
||||||
|
LINK = $(LD) $(LDFLAGS) $(DEBUGLF) /out:$@
|
||||||
|
|
||||||
|
#INSTALL = @INSTALL@
|
||||||
|
#INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
|
||||||
|
RM = del
|
||||||
|
|
||||||
|
SRC = alloca.c cmpt.c connect.c host.c http.c netrc.c ftp-basic.c ftp.c ftp-ls.c \
|
||||||
|
ftp-opie.c getopt.c headers.c html.c retr.c recur.c url.c init.c utils.c main.c \
|
||||||
|
version.c mswindows.c fnmatch.c md5.c rbuf.c log.c
|
||||||
|
|
||||||
|
OBJ = alloca$o cmpt$o connect$o host$o http$o netrc$o ftp-basic$o ftp$o ftp-ls$o \
|
||||||
|
ftp-opie$o headers$o html$o retr$o recur$o url$o init$o utils$o main$o \
|
||||||
|
getopt$o version$o mswindows$o fnmatch$o md5$o rbuf$o log$o
|
||||||
|
|
||||||
|
.SUFFIXES: .c .obj
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(COMPILE) /c $<
|
||||||
|
|
||||||
|
# Dependencies for building
|
||||||
|
|
||||||
|
wget: wget.exe
|
||||||
|
|
||||||
|
wget.exe: $(OBJ)
|
||||||
|
$(LD) @<< $(LDFLAGS) $(DEBUGLF) /out:$@ $(LIBS) $(OBJ)
|
||||||
|
<<
|
||||||
|
ren wget.exe WGET.EXE
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dependencies for cleanup
|
||||||
|
#
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.obj
|
||||||
|
$(RM) *.exe
|
||||||
|
$(RM) *.bak
|
||||||
|
$(RM) *.pdb
|
||||||
|
$(RM) *.map
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) Makefile
|
||||||
|
|
||||||
|
realclean: distclean
|
||||||
|
$(RM) TAGS
|
||||||
|
|
||||||
|
# Dependencies:
|
||||||
|
|
||||||
|
!include "..\windows\wget.dep"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user