summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 15:45:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 15:45:37 +0000
commite0801e6bd6cc1241afafea33ba8ef701fec2e5c5 (patch)
treeb5cf84f45181b3dbc14d58833d88683fb7f3465e
parentInitial commit. (diff)
downloadwhois-e0801e6bd6cc1241afafea33ba8ef701fec2e5c5.tar.xz
whois-e0801e6bd6cc1241afafea33ba8ef701fec2e5c5.zip
Adding upstream version 5.5.17.upstream/5.5.17upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--COPYING339
-rw-r--r--Makefile168
-rw-r--r--README26
-rw-r--r--as32_del_list19
-rw-r--r--as_del_list97
-rw-r--r--config.h131
-rw-r--r--data.h169
-rw-r--r--ip6_del_list47
-rw-r--r--ip_del_list253
-rw-r--r--ip_del_recovered.h489
-rwxr-xr-xmake_as32_del.pl27
-rwxr-xr-xmake_as_del.pl28
-rwxr-xr-xmake_ip6_del.pl39
-rwxr-xr-xmake_ip_del.pl29
-rwxr-xr-xmake_ip_del_recovered.pl34
-rwxr-xr-xmake_new_gtlds.pl16
-rwxr-xr-xmake_nic_handles.pl17
-rwxr-xr-xmake_servers_charset.pl21
-rwxr-xr-xmake_tld_serv.pl25
-rwxr-xr-xmake_version_h.pl29
-rw-r--r--mkpasswd.193
-rw-r--r--mkpasswd.bash33
-rw-r--r--mkpasswd.c580
-rw-r--r--new_gtlds_list1153
-rw-r--r--nic_handles_list23
-rw-r--r--po/Makefile57
-rw-r--r--po/cs.po363
-rw-r--r--po/da.po357
-rw-r--r--po/de.po375
-rw-r--r--po/el.po367
-rw-r--r--po/es.po387
-rw-r--r--po/eu.po384
-rw-r--r--po/fi.po360
-rw-r--r--po/fr.po371
-rw-r--r--po/it.po354
-rw-r--r--po/ja.po346
-rw-r--r--po/ka.po371
-rw-r--r--po/pl.po369
-rw-r--r--po/pt_BR.po376
-rw-r--r--po/ru.po366
-rw-r--r--po/tr.po357
-rw-r--r--po/zh_CN.po353
-rw-r--r--ripe-mail90
-rw-r--r--servers_charset_list76
-rw-r--r--simple_recode.c182
-rw-r--r--simple_recode.h14
-rw-r--r--tld_serv_list432
-rw-r--r--utils.c97
-rw-r--r--utils.h63
-rw-r--r--whois.1308
-rw-r--r--whois.bash86
-rw-r--r--whois.c1549
-rw-r--r--whois.conf11
-rw-r--r--whois.conf.549
-rw-r--r--whois.h47
55 files changed, 12802 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4843c16
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,168 @@
+prefix = /usr
+
+ifdef DESTDIR
+BASEDIR := $(DESTDIR)
+endif
+
+CFLAGS ?= -g -O2
+
+PKG_CONFIG ?= pkg-config
+PERL ?= perl
+INSTALL ?= install
+
+whois_OBJECTS := whois.o utils.o
+mkpasswd_OBJECTS := mkpasswd.o utils.o
+
+##############################################################################
+# Solaris
+#whois_LDADD += -lnsl -lsocket -liconv
+
+# FreeBSD
+#whois_LDADD += -liconv
+#LIBS += -L/usr/local/lib -lintl
+#DEFS += -I/usr/local/include
+
+# OS/2 EMX
+#whois_LDADD += -lsocket
+#LDFLAGS += -Zexe -Dstrncasecmp=strnicmp
+
+# OS X
+#whois_LDADD += -liconv
+
+ifdef CONFIG_FILE
+DEFS += -DCONFIG_FILE=\"$(CONFIG_FILE)\"
+endif
+
+ifdef LOCALEDIR
+DEFS += -DLOCALEDIR=\"$(BASEDIR)$(prefix)/share/locale\"
+endif
+
+# libidn support has been autodetected since 5.2.18
+ifdef HAVE_LIBIDN
+$(error Please fix your build system to stop defining HAVE_LIBIDN!)
+endif
+
+ifeq ($(shell $(PKG_CONFIG) --exists 'libidn2 >= 2.0.3' || echo NO),)
+whois_LDADD += $(shell $(PKG_CONFIG) --libs libidn2)
+DEFS += -DHAVE_LIBIDN2 $(shell $(PKG_CONFIG) --cflags libidn2)
+else ifeq ($(shell $(PKG_CONFIG) --exists 'libidn' || echo NO),)
+whois_LDADD += $(shell $(PKG_CONFIG) --libs libidn)
+DEFS += -DHAVE_LIBIDN $(shell $(PKG_CONFIG) --cflags libidn)
+endif
+
+ifdef HAVE_ICONV
+whois_OBJECTS += simple_recode.o
+DEFS += -DHAVE_ICONV
+endif
+
+ifeq ($(shell $(PKG_CONFIG) --exists 'libxcrypt >= 4.1' || echo NO),)
+DEFS += -DHAVE_CRYPT_H -DHAVE_LINUX_CRYPT_GENSALT $(shell $(PKG_CONFIG) --cflags libcrypt)
+mkpasswd_LDADD += $(shell $(PKG_CONFIG) --libs libcrypt)
+else ifdef HAVE_XCRYPT
+DEFS += -DHAVE_XCRYPT_H -DHAVE_LINUX_CRYPT_GENSALT
+mkpasswd_LDADD += -lxcrypt
+else ifdef HAVE_LIBOWCRYPT
+# owl and openSUSE have crypt_gensalt(3) in libowcrypt
+DEFS += -DHAVE_CRYPT_H -DHAVE_LINUX_CRYPT_GENSALT -D_OW_SOURCE
+mkpasswd_LDADD += -lcrypt -lowcrypt
+else
+mkpasswd_LDADD += -lcrypt
+endif
+
+CPPFLAGS += $(DEFS) $(INCLUDES)
+
+BASHCOMPDIR ?= $(shell $(PKG_CONFIG) --variable=completionsdir bash-completion 2>/dev/null || echo /etc/bash_completion.d)
+
+##############################################################################
+all: Makefile.depend whois mkpasswd pos
+
+##############################################################################
+%.o: %.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
+
+whois: $(whois_OBJECTS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(whois_LDADD) $(LIBS)
+
+mkpasswd: $(mkpasswd_OBJECTS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(mkpasswd_LDADD) $(LIBS)
+
+##############################################################################
+version.h: debian/changelog make_version_h.pl
+ $(PERL) make_version_h.pl $< > $@
+
+as_del.h: as_del_list make_as_del.pl
+ $(PERL) make_as_del.pl < $< > $@
+
+as32_del.h: as32_del_list make_as32_del.pl
+ $(PERL) make_as32_del.pl < $< > $@
+
+ip_del.h: ip_del_list make_ip_del.pl
+ $(PERL) make_ip_del.pl < $< > $@
+
+ip6_del.h: ip6_del_list make_ip6_del.pl
+ $(PERL) make_ip6_del.pl < $< > $@
+
+new_gtlds.h: new_gtlds_list make_new_gtlds.pl
+ $(PERL) make_new_gtlds.pl < $< > $@
+
+nic_handles.h: nic_handles_list make_nic_handles.pl
+ $(PERL) make_nic_handles.pl < $< > $@
+
+tld_serv.h: tld_serv_list make_tld_serv.pl
+ $(PERL) make_tld_serv.pl < $< > $@
+
+servers_charset.h: servers_charset_list make_servers_charset.pl
+ $(PERL) make_servers_charset.pl < $< > $@
+
+##############################################################################
+afl:
+ -rm -f Makefile.depend
+ DEFS=-DAFL_MODE=1 AFL_HARDEN=1 $(MAKE) whois CC=afl-gcc HAVE_ICONV=1
+
+afl-run:
+ nice afl-fuzz -i ../afl_in -o ../afl_out -- ./whois
+
+##############################################################################
+install: install-whois install-mkpasswd install-pos install-bashcomp
+
+install-whois: whois
+ $(INSTALL) -d $(BASEDIR)$(prefix)/bin/
+ $(INSTALL) -d $(BASEDIR)$(prefix)/share/man/man1/
+ $(INSTALL) -d $(BASEDIR)$(prefix)/share/man/man5/
+ $(INSTALL) -m 0755 whois $(BASEDIR)$(prefix)/bin/
+ $(INSTALL) -m 0644 whois.1 $(BASEDIR)$(prefix)/share/man/man1/
+ $(INSTALL) -m 0644 whois.conf.5 $(BASEDIR)$(prefix)/share/man/man5/
+
+install-mkpasswd: mkpasswd
+ $(INSTALL) -d $(BASEDIR)$(prefix)/bin/
+ $(INSTALL) -d $(BASEDIR)$(prefix)/share/man/man1/
+ $(INSTALL) -m 0755 mkpasswd $(BASEDIR)$(prefix)/bin/
+ $(INSTALL) -m 0644 mkpasswd.1 $(BASEDIR)$(prefix)/share/man/man1/
+
+install-pos:
+ cd po && $(MAKE) install
+
+install-bashcomp:
+ $(INSTALL) -d $(BASEDIR)$(BASHCOMPDIR)
+ $(INSTALL) -m 0644 mkpasswd.bash $(BASEDIR)$(BASHCOMPDIR)/mkpasswd
+ $(INSTALL) -m 0644 whois.bash $(BASEDIR)$(BASHCOMPDIR)/whois
+
+distclean: clean
+ rm -f version.h po/whois.pot
+
+clean:
+ rm -f Makefile.depend as_del.h as32_del.h ip_del.h ip6_del.h \
+ nic_handles.h new_gtlds.h tld_serv.h servers_charset.h \
+ *.o whois mkpasswd
+ rm -f po/*.mo
+
+pos:
+ cd po && $(MAKE)
+
+depend: Makefile.depend
+Makefile.depend:
+ $(CC) $(CPPFLAGS) $(CFLAGS) -MM -MG *.c > $@
+
+-include Makefile.depend
+
+.DELETE_ON_ERROR:
diff --git a/README b/README
new file mode 100644
index 0000000..c795553
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+In 1999 I wrote this Whois client from scratch because the alternatives
+were obsolete or bloated.
+
+This client is intelligent and can automatically select the appropriate
+whois server for most queries.
+
+The internal database is often more accurate than IANA's published one,
+but please send me any information you have regarding domains and network
+resources which are not correctly handled by the program.
+
+Because of historical reasons this package also contains the mkpasswd
+program, which can be used to encrypt a password with crypt(3).
+
+
+The canonical distribution point for releases of the program is
+http://ftp.debian.org/debian/pool/main/w/whois/ .
+
+
+Useful information sources:
+- http://www.ripe.net/ripe/docs/current-ripe-documents/ripe-database-documents
+- http://www.iana.org/domains/root/db/
+- http://www.icann.org/en/resources/idn/fast-track/string-evaluation-completion
+- http://www.aftld.org/
+
+Marco d'Itri <md@linux.it>
+
diff --git a/as32_del_list b/as32_del_list
new file mode 100644
index 0000000..ab99059
--- /dev/null
+++ b/as32_del_list
@@ -0,0 +1,19 @@
+# http://www.iana.org/assignments/as-numbers
+
+# actually I listed here also the unallocated space reserved for each RIR
+
+131077 131086 whois.nic.ad.jp
+131092 131101 whois.nic.or.kr
+131152 131161 whois.nic.ad.jp
+131791 131890 whois.nic.or.kr
+131893 131992 whois.nic.ad.jp
+
+2.0 2.65535 apnic
+3.0 3.65535 ripe
+4.0 4.65535 lacnic
+5.0 5.65535 afrinic
+6.0 6.65535 arin
+
+# private ASN block
+4200000000 4294967294 ripe
+
diff --git a/as_del_list b/as_del_list
new file mode 100644
index 0000000..96a3756
--- /dev/null
+++ b/as_del_list
@@ -0,0 +1,97 @@
+# http://www.iana.org/assignments/as-numbers
+
+248 251 ripe
+306 371 whois.nic.mil
+379 508 whois.nic.mil
+1101 1200 ripe
+1267 1275 ripe
+1877 1901 ripe
+2043 2043 ripe
+2047 2047 ripe
+2057 2136 ripe
+2387 2488 ripe
+2497 2528 whois.nic.ad.jp
+2585 2614 ripe
+2773 2822 ripe
+2830 2879 ripe
+3154 3353 ripe
+4608 4864 apnic
+5120 5376 whois.nic.mil
+5377 5631 ripe
+5800 6055 whois.nic.mil
+6656 6911 ripe
+7467 7722 apnic
+8192 9215 ripe
+9591 9622 whois.nic.ad.jp
+9628 9647 whois.nic.or.kr
+9683 9712 whois.nic.or.kr
+9753 9784 whois.nic.or.kr
+9840 9871 whois.nic.or.kr
+9943 9982 whois.nic.or.kr
+9990 10021 whois.nic.ad.jp
+10034 10073 whois.nic.or.kr
+10154 10198 whois.nic.or.kr
+9216 10239 apnic
+12288 13311 ripe
+15360 16383 ripe
+17503 17534 whois.nic.ad.jp
+17567 17616 whois.nic.or.kr
+17673 17704 whois.nic.ad.jp
+17832 17881 whois.nic.or.kr
+17930 17961 whois.nic.ad.jp
+18067 18098 whois.nic.ad.jp
+18121 18152 whois.nic.ad.jp
+18259 18290 whois.nic.ad.jp
+18294 18343 whois.nic.or.kr
+17408 18431 apnic
+20480 21503 ripe
+23552 23601 whois.nic.or.kr
+23612 23643 whois.nic.ad.jp
+23773 23836 whois.nic.ad.jp
+24248 24297 whois.nic.ad.jp
+23552 24575 apnic
+24576 25599 ripe
+26592 26623 lacnic
+27648 28671 lacnic
+28672 29695 ripe
+30980 30999 afrinic
+30720 31743 ripe
+34515 34519 afrinic
+33792 35839 ripe
+36864 37887 afrinic
+37888 37927 whois.nic.ad.jp
+38086 38135 whois.nic.or.kr
+38387 38436 whois.nic.or.kr
+38627 38656 whois.nic.ad.jp
+38660 38709 whois.nic.or.kr
+37888 38911 apnic
+38912 39935 ripe
+40960 45055 ripe
+45360 45409 whois.nic.or.kr
+45672 45691 whois.nic.ad.jp
+45963 46012 whois.nic.or.kr
+45056 46079 apnic
+47104 52223 ripe
+52224 53247 lacnic
+55372 55396 whois.nic.ad.jp
+55584 55633 whois.nic.or.kr
+55888 55912 whois.nic.ad.jp
+55296 56319 apnic
+56320 58367 ripe
+58645 58654 whois.nic.ad.jp
+58784 58793 whois.nic.ad.jp
+59091 59130 whois.nic.ad.jp
+58368 59391 apnic
+59392 61439 ripe
+61440 61951 lacnic
+61952 62463 ripe
+63488 64098 apnic
+64099 64197 lacnic
+# catch all: everything else comes from ARIN
+1 64296 arin
+64297 64395 apnic
+64396 64495 ripe
+
+# documentation and private ASN block
+64496 65534 ripe
+
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..82ec4f6
--- /dev/null
+++ b/config.h
@@ -0,0 +1,131 @@
+/* Configurable features */
+
+/* Always hide legal disclaimers */
+#undef ALWAYS_HIDE_DISCL
+
+/* Default server */
+#define DEFAULTSERVER "whois.arin.net"
+
+/* Configuration file */
+/*
+#define CONFIG_FILE "/etc/whois.conf"
+*/
+
+
+/* autoconf in cpp macros */
+#if defined __NetBSD__ || __OpenBSD__
+# include <sys/param.h>
+#endif
+
+#if defined __GLIBC__ && !defined __UCLIBC__
+# define ENABLE_NLS
+#endif
+
+#ifdef __FreeBSD__
+/* which versions? */
+# define HAVE_GETOPT_LONG
+# define HAVE_GETADDRINFO
+# define ENABLE_NLS
+# ifndef LOCALEDIR
+# define LOCALEDIR "/usr/local/share/locale"
+# endif
+#endif
+
+/* needs unistd.h */
+#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L
+# define HAVE_GETADDRINFO
+# define HAVE_REGEXEC
+#endif
+
+#if defined __APPLE__ && defined __MACH__
+# define HAVE_GETOPT_LONG
+# define HAVE_GETADDRINFO
+# define HAVE_BSDICRYPT
+#endif
+
+#if defined __midipix__
+# define HAVE_GETOPT_LONG
+# define HAVE_GETADDRINFO
+# define HAVE_SHA_CRYPT
+#endif
+
+#if defined __GLIBC__
+# define HAVE_GETOPT_LONG
+# if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
+# define HAVE_GETADDRINFO
+# endif
+# if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 7
+# define HAVE_SHA_CRYPT
+# endif
+#endif
+
+#if defined OpenBSD && OpenBSD < 201405
+# define HAVE_BCRYPT_OBSOLETE
+#elif defined OpenBSD || defined __FreeBSD__ || (defined __SVR4 && defined __sun) || defined _OW_SOURCE
+# define HAVE_BCRYPT
+#endif
+
+#if defined OpenBSD || defined __FreeBSD__ || defined __NetBSD__
+# define HAVE_BSDICRYPT
+#endif
+
+/* Unknown versions of Solaris */
+#if defined __SVR4 && defined __sun
+# define HAVE_SHA_CRYPT
+# define HAVE_CRYPT_H
+# define HAVE_SOLARIS_CRYPT_GENSALT
+# define CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
+#endif
+
+/* FIXME: which systems lack this? */
+#define HAVE_GETTIMEOFDAY
+
+/*
+ * Please send patches to correctly ignore old releases which lack a RNG
+ * and add more systems which have one.
+ */
+#ifdef RANDOM_DEVICE
+#elif defined linux \
+ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
+ /* AIX >= 5.2? */ \
+ || defined _AIX52 \
+ /* HP-UX >= B.11.11.09? */ \
+ || defined __hpux \
+ /* OS X: */ \
+ || (defined __APPLE__ && defined __MACH__) \
+ /* Solaris >= 9 (this is >= 7): */ \
+ || (defined __SVR4 && defined __sun && defined SUSv2) \
+ /* Tru64 UNIX >= 5.1B? */ \
+ || defined __osf
+# define RANDOM_DEVICE "/dev/urandom"
+#endif
+
+/* use arc4random_buf instead if it is available */
+#if (defined __FreeBSD__ && __FreeBSD__ >= 9) || \
+ (defined __NetBSD__ && __NetBSD_Version__ >= 600000000) || \
+ (defined OpenBSD && OpenBSD >= 200805) || \
+ (defined __APPLE__ && defined __MACH__ && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+# define HAVE_ARC4RANDOM_BUF
+#endif
+
+/* or else getentropy(2) on Linux */
+#if defined __GLIBC__ && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 25 || defined __midipix__
+# define HAVE_GETENTROPY
+#endif
+
+/* some versions of crypt(3) set errno on error */
+#if defined __GLIBC__ || (defined __SVR4 && defined __sun) || defined OpenBSD || AIX
+# define CRYPT_SETS_ERRNO 1
+#else
+# define CRYPT_SETS_ERRNO 0
+#endif
+
+#ifdef ENABLE_NLS
+# ifndef NLS_CAT_NAME
+# define NLS_CAT_NAME "whois"
+# endif
+# ifndef LOCALEDIR
+# define LOCALEDIR "/usr/share/locale"
+# endif
+#endif
+
diff --git a/data.h b/data.h
new file mode 100644
index 0000000..cb3ccd8
--- /dev/null
+++ b/data.h
@@ -0,0 +1,169 @@
+/*
+ * RIPE-like servers.
+ * All of them do not understand -V2.0Md with the exception of RA and RIPN.
+ */
+
+/* servers which accept the new syntax (-V XXn.n) */
+const char *ripe_servers[] = {
+ "whois.ripe.net",
+ "whois.apnic.net",
+ "whois.afrinic.net",
+ "rr.arin.net", /* does not accept the old syntax */
+ "rr.level3.net", /* 3.0.0a13 */
+ "rr.ntt.net",
+ "whois.tcinet.ru",
+ "whois.ripn.net",
+ "whois.register.si",
+ "whois.nic.ir",
+ "whois.ra.net",
+ NULL
+};
+
+const char *hide_strings[] = {
+ "The data in Networksolutions.com's WHOIS database", NULL,
+ /* Some registrars like .wang copied the first paragraph of this
+ * disclaimer, so the detection here needs to be split in two parts. */
+ "TERMS OF USE: You are not authorized", NULL, /* crsnic */
+ "The data in Register.com's WHOIS database", NULL,
+ "The Data in the Tucows Registrar WHOIS database", NULL,
+ "TERMS OF USE: The Data in Gabia' WHOIS", NULL,
+ "The data contained in GoDaddy.com", NULL,
+ "Personal data access and use are governed by French", NULL, /* GANDI */
+ "The data in this whois database is provided to you", NULL, /* enom */
+ "Please register your domains at; http://www.", NULL, /* key-systems.net */
+ "%% NOTICE: Access to this information is provided", NULL, /* bookmyname.com */
+ "NOTICE: Access to the domain name's information", NULL, /* CORE */
+ "The Data in MarkMonitor.com's", NULL, /* MarkMonitor */
+ "Corporation Service Company(c) (CSC) The Trusted Partner", "Register your domain name at", /* CSC */
+ "The data in Networksolutions.com's", NULL, /* Networksolutions */
+ "# Welcome to the OVH WHOIS Server", "", /* ovh */
+ "TERMS OF USE OF MELBOURNE IT WHOIS DATABASE", NULL,
+ "The data contained in this Registrar's Whois", NULL, /* wildwestdomains.com */
+ "The data in the FastDomain Inc. WHOIS database", NULL,
+
+ /* gTLDs */
+ "Access to WHOIS information is provided", NULL,
+ "This Registry database contains ONLY .EDU", "domain names.", /* edu */
+ "Access to AFILIAS WHOIS information is provided", NULL, /* .info */
+ "Access to Public Interest Registry WHOIS information", NULL, /* .org */
+ "Telnames Limited, the Registry Operator for", NULL,
+ "Tralliance, Inc., the Registry Operator for .travel", NULL,
+ "The data in this record is provided by", NULL, /* .xxx */
+
+ /* new gTLDs */
+ "Terms of Use: Donuts Inc. provides", NULL,
+ "Access to WHOIS information is provided", NULL, /* Afilias */
+ "TERMS OF USE: You are not authorized", NULL, /* uniregistry.net */
+ "The Whois and RDAP services are provided by CentralNic", "",
+ ".Club Domains, LLC, the Registry Operator", NULL,
+ "% Except for agreed Internet operational purposes", NULL, /* .berlin */
+ "TERMS OF USE: The information in the Whois database", NULL, /* .wang */
+ "The WHOIS service offered by Neustar, Inc, on behalf", NULL,
+ "The WHOIS service offered by the Registry Operator", NULL, /* .science */
+
+ /* ccTLDs */
+ "Access to CCTLD WHOIS information is provided", "", /* Afilias */
+ "This WHOIS information is provided", NULL, /* as */
+ "% The WHOIS service offered by DNS Belgium", "", /* be */
+ ".CO Internet, S.A.S., the Administrator", NULL, /* co */
+ "% *The information provided",
+ "% https://www.nic.cr/iniciar-sesion/?next=/mi-cuenta/",/* cr */
+ "% The WHOIS service offered by EURid", "% of the database", /* eu */
+ "Access to .IN WHOIS information", NULL, /* in */
+ "access to .in whois information", NULL, /* in registar */
+ "% Use of CIRA's WHOIS service is governed by the Terms of Use in its Legal", NULL, /* sx */
+ "The Service is provided so that you may look", "We may discontinue",/*vu*/
+ "NeuStar, Inc., the Registry Administrator for .US", NULL,
+
+ NULL, NULL
+};
+
+const char *nic_handles[] = {
+ "net-", "whois.arin.net",
+ "netblk-", "whois.arin.net",
+ "poem-", "whois.ripe.net",
+ "form-", "whois.ripe.net",
+ "pgpkey-", "whois.ripe.net",
+ "denic-", "whois.denic.de",
+ /* RPSL objects */
+ "as-", "whois.ripe.net",
+ "rs-", "whois.ripe.net",
+ "rtrs-", "whois.ripe.net",
+ "fltr-", "whois.ripe.net",
+ "prng-", "whois.ripe.net",
+ NULL, NULL
+};
+
+struct ip_del {
+ const unsigned long net;
+ const unsigned long mask;
+ const char *serv;
+};
+
+const struct ip_del ip_assign[] = {
+#include "ip_del_recovered.h"
+#include "ip_del.h"
+ { 0, 0, NULL }
+};
+
+struct ip6_del {
+ const unsigned long net;
+ const unsigned short masklen;
+ const char *serv;
+};
+
+const struct ip6_del ip6_assign[] = {
+#include "ip6_del.h"
+ { 0, 0, NULL }
+};
+
+struct as_del {
+ const unsigned short first;
+ const unsigned short last;
+ const char *serv;
+};
+
+const struct as_del as_assign[] = {
+#include "as_del.h"
+ { 0, 0, NULL }
+};
+
+struct as32_del {
+ const unsigned long first;
+ const unsigned long last;
+ const char *serv;
+};
+
+const struct as32_del as32_assign[] = {
+#include "as32_del.h"
+ { 0, 0, NULL }
+};
+
+const char *new_gtlds[] = {
+#include "new_gtlds.h"
+ NULL
+};
+
+const char *tld_serv[] = {
+#include "tld_serv.h"
+ NULL, NULL
+};
+
+const char *nic_handles_post[] = {
+#include "nic_handles.h"
+ NULL, NULL
+};
+
+#ifdef HAVE_ICONV
+struct server_charset {
+ const char *name;
+ const char *charset;
+ const char *options;
+};
+
+const struct server_charset servers_charset[] = {
+#include "servers_charset.h"
+ { NULL, NULL, NULL }
+};
+#endif
+
diff --git a/ip6_del_list b/ip6_del_list
new file mode 100644
index 0000000..a9ab644
--- /dev/null
+++ b/ip6_del_list
@@ -0,0 +1,47 @@
+# http://www.iana.org/assignments/ipv6-unicast-address-assignments
+# The parser is very simple-minded and wants the two first components of
+# addresses. It does not deal with networks == 0 or > 24 bit.
+
+2001:0000::/32 teredo
+2001:0200::/23 apnic
+2001:0400::/23 arin
+2001:0600::/23 ripe
+2001:0800::/22 ripe
+2001:0C00::/22 apnic
+# contains 2001:1000::/23, not allocated
+2001:1000::/22 lacnic
+2001:1400::/22 ripe
+2001:1800::/23 arin
+2001:1A00::/23 ripe
+2001:1C00::/22 ripe
+# contains 2001:3C00::/22, reserved for RIPE but not allocated
+2001:2000::/19 ripe
+2001:4000::/23 ripe
+2001:4200::/23 afrinic
+2001:4400::/23 apnic
+2001:4600::/23 ripe
+2001:4800::/23 arin
+2001:4A00::/23 ripe
+# contains 2001:4E00::/23, not allocated
+2001:4C00::/22 ripe
+
+2001:5000::/20 ripe
+
+2001:8000::/18 apnic
+
+# 6to4 is special-cased
+2002:0000::/16 6to4
+
+2003:0000::/18 ripe
+
+2400:0000::/20 whois.nic.or.kr
+2400:0000::/12 apnic
+2600:0000::/12 arin
+2610:0000::/23 arin
+2620:0000::/23 arin
+2630:0000::/12 arin
+2800:0000::/12 lacnic
+2A00:0000::/12 ripe
+2A10:0000::/12 ripe
+2C00:0000::/12 afrinic
+
diff --git a/ip_del_list b/ip_del_list
new file mode 100644
index 0000000..0425203
--- /dev/null
+++ b/ip_del_list
@@ -0,0 +1,253 @@
+# WARNING! Netblocks 128.0.0.0/2, 192.0.0.0/8, 196.0.0.0/8 and 198.0.0.0/8
+# contain historical allocations now scattered among all the RIRs.
+# Do not even try submitting such networks for inclusion in this list
+# unless they are very big and contains multiple assignments to different
+# customers documented in the whois database.
+#
+# http://www.iana.org/assignments/ipv4-address-space
+#
+0.0.0.0/8 UNKNOWN
+1.0.0.0/8 apnic
+2.0.0.0/8 ripe
+5.0.0.0/8 ripe
+14.0.0.0/8 apnic
+24.132.0.0/14 ripe
+27.0.0.0/8 apnic
+31.0.0.0/8 ripe
+36.0.0.0/8 apnic
+37.0.0.0/8 ripe
+39.0.0.0/8 apnic
+41.0.0.0/8 afrinic
+42.0.0.0/8 apnic
+43.224.0.0/11 apnic
+43.0.0.0/8 whois.nic.ad.jp
+46.0.0.0/8 ripe
+49.0.0.0/8 apnic
+51.0.0.0/8 ripe
+# whois -r -K -h whois.apnic.net -i admin-c IM76-AP
+59.0.0.0/11 whois.nic.or.kr
+58.0.0.0/7 apnic
+61.72.0.0/13 whois.nic.or.kr
+61.80.0.0/14 whois.nic.or.kr
+61.84.0.0/15 whois.nic.or.kr
+61.112.0.0/12 whois.nic.ad.jp
+61.192.0.0/12 whois.nic.ad.jp # => 61.207.255.255
+61.208.0.0/13 whois.nic.ad.jp # => 61.215.255.255
+60.0.0.0/7 apnic
+62.0.0.0/8 ripe
+77.0.0.0/8 ripe
+78.0.0.0/7 ripe
+80.0.0.0/4 ripe # => 95.255.255.255
+101.0.0.0/8 apnic
+102.0.0.0/8 afrinic
+103.0.0.0/8 apnic
+105.0.0.0/8 afrinic
+106.0.0.0/8 apnic
+109.0.0.0/8 ripe
+110.0.0.0/7 apnic
+112.160.0.0/11 whois.nic.or.kr
+115.0.0.0/12 whois.nic.or.kr
+115.16.0.0/13 whois.nic.or.kr
+118.32.0.0/11 whois.nic.or.kr
+119.192.0.0/11 whois.nic.or.kr
+112.0.0.0/5 apnic
+121.128.0.0/10 whois.nic.or.kr
+125.128.0.0/11 whois.nic.or.kr
+120.0.0.0/6 apnic
+124.0.0.0/7 apnic
+126.0.0.0/8 apnic
+0.0.0.0/1 arin # all other A class addresses are managed by ARIN
+133.0.0.0/8 whois.nic.ad.jp
+139.20.0.0/14 ripe
+139.24.0.0/14 ripe
+139.28.0.0/15 ripe
+141.0.0.0/10 ripe
+141.86.0.0/16 arin
+141.64.0.0/11 ripe
+141.96.0.0/14 ripe
+141.100.0.0/16 ripe
+145.0.0.0/8 ripe
+146.48.0.0/16 ripe
+149.202.0.0/15 ripe
+149.204.0.0/16 ripe
+149.206.0.0/15 ripe
+149.208.0.0/12 ripe
+149.224.0.0/12 ripe
+149.240.0.0/13 ripe
+149.248.0.0/14 ripe
+150.183.0.0/16 whois.nic.or.kr
+150.254.0.0/16 ripe
+150.0.0.0/8 apnic
+151.0.0.0/10 ripe
+151.64.0.0/11 ripe
+151.96.0.0/14 ripe
+151.100.0.0/16 ripe
+153.128.0.0/9 whois.nic.ad.jp
+153.0.0.0/8 apnic
+154.0.0.0/8 afrinic
+155.232.0.0/13 afrinic
+155.240.0.0/16 afrinic
+160.216.0.0/14 ripe
+160.220.0.0/16 ripe
+160.44.0.0/14 ripe
+160.48.0.0/12 ripe
+160.115.0.0/16 afrinic
+160.116.0.0/14 afrinic
+160.120.0.0/14 afrinic
+160.124.0.0/16 afrinic
+163.156.0.0/14 ripe
+163.160.0.0/12 ripe
+163.195.0.0/16 afrinic
+163.196.0.0/14 afrinic
+163.200.0.0/14 afrinic
+163.0.0.0/8 apnic
+164.0.0.0/11 ripe
+164.32.0.0/13 ripe
+164.40.0.0/16 ripe
+164.128.0.0/12 ripe
+164.146.0.0/15 afrinic
+164.148.0.0/14 afrinic
+165.143.0.0/16 afrinic
+165.144.0.0/14 afrinic
+165.148.0.0/15 afrinic
+169.208.0.0/12 apnic
+171.16.0.0/12 ripe
+171.32.0.0/15 ripe
+171.0.0.0/8 apnic
+175.192.0.0/10 whois.nic.or.kr
+175.0.0.0/8 apnic
+176.0.0.0/8 ripe
+177.0.0.0/8 lacnic
+178.0.0.0/8 ripe
+179.0.0.0/8 lacnic
+180.0.0.0/8 apnic
+181.0.0.0/8 lacnic
+183.96.0.0/11 whois.nic.or.kr
+182.0.0.0/7 apnic
+185.0.0.0/8 ripe
+186.0.0.0/7 lacnic
+188.0.0.0/8 ripe # transferred from ARIN to to RIPE
+189.0.0.0/8 lacnic
+190.0.0.0/7 lacnic
+## All other B class addresses are supposed to be allocated by ARIN
+## We know that many of them are not, but they can't all be listed here
+128.0.0.0/2 arin
+
+## The C classes space is cleanly delegated and the data here should be complete
+192.71.0.0/16 ripe
+192.72.253.0/24 arin
+192.72.254.0/24 arin # how annoying...
+192.72.0.0/16 apnic
+192.106.0.0/16 ripe
+192.114.0.0/15 ripe
+192.116.0.0/15 ripe
+192.118.0.0/16 ripe
+192.162.0.0/16 ripe
+192.164.0.0/14 ripe
+192.0.0.0/8 arin # the swamp
+193.0.0.0/8 ripe
+194.0.0.0/7 ripe
+196.0.0.0/7 afrinic
+198.0.0.0/7 arin
+
+200.0.0.0/7 lacnic
+202.11.0.0/16 whois.nic.ad.jp
+202.13.0.0/16 whois.nic.ad.jp
+202.15.0.0/16 whois.nic.ad.jp
+202.16.0.0/14 whois.nic.ad.jp
+202.20.128.0/17 whois.nic.or.kr
+202.23.0.0/16 whois.nic.ad.jp
+202.24.0.0/15 whois.nic.ad.jp
+202.26.0.0/16 whois.nic.ad.jp
+202.30.0.0/15 whois.nic.or.kr
+202.32.0.0/14 whois.nic.ad.jp
+202.48.0.0/16 whois.nic.ad.jp
+202.39.128.0/17 twnic
+202.208.0.0/12 whois.nic.ad.jp
+202.224.0.0/11 whois.nic.ad.jp # => 202.255.255.255
+203.0.0.0/10 apnic
+203.66.0.0/16 twnic
+203.69.0.0/16 twnic
+203.74.0.0/15 twnic
+203.136.0.0/14 whois.nic.ad.jp
+203.140.0.0/15 whois.nic.ad.jp
+203.178.0.0/15 whois.nic.ad.jp
+203.180.0.0/14 whois.nic.ad.jp
+203.224.0.0/11 whois.nic.or.kr # => 203.255.255.255
+202.0.0.0/7 apnic
+204.0.0.0/14 rwhois.gin.ntt.net # rwhois too
+204.0.0.0/6 arin
+208.0.0.0/7 arin
+209.94.192.0/19 lacnic
+210.59.128.0/17 twnic
+210.61.0.0/16 twnic
+210.62.252.0/22 twnic
+210.65.0.0/16 twnic
+210.71.128.0/17 twnic
+210.90.0.0/15 whois.nic.or.kr
+210.92.0.0/14 whois.nic.or.kr
+210.96.0.0/11 whois.nic.or.kr # => 210.127.255.255
+210.128.0.0/11 whois.nic.ad.jp
+210.160.0.0/12 whois.nic.ad.jp
+210.178.0.0/15 whois.nic.or.kr
+210.180.0.0/14 whois.nic.or.kr
+210.188.0.0/14 whois.nic.ad.jp
+210.196.0.0/14 whois.nic.ad.jp
+210.204.0.0/14 whois.nic.or.kr
+210.216.0.0/13 whois.nic.or.kr # => 210.223.255.255
+210.224.0.0/12 whois.nic.ad.jp # => 210.239.255.255
+# some more TWNIC blocks are scattered here
+210.240.0.0/16 twnic
+210.241.0.0/18 twnic
+210.241.224.0/19 twnic
+210.242.0.0/15 twnic
+210.248.0.0/13 whois.nic.ad.jp
+211.0.0.0/12 whois.nic.ad.jp
+211.16.0.0/14 whois.nic.ad.jp
+211.20.0.0/15 twnic
+211.22.0.0/16 twnic
+211.32.0.0/11 whois.nic.or.kr # => 211.63.255.255
+211.75.0.0/16 twnic
+211.72.0.0/16 twnic
+211.104.0.0/13 whois.nic.or.kr
+211.112.0.0/13 whois.nic.or.kr # => 211.119.255.255
+211.120.0.0/13 whois.nic.ad.jp
+211.128.0.0/13 whois.nic.ad.jp
+211.168.0.0/13 whois.nic.or.kr
+211.176.0.0/12 whois.nic.or.kr
+211.192.0.0/10 whois.nic.or.kr # => 211.255.255.255
+210.0.0.0/7 apnic
+213.154.32.0/19 afrinic
+213.154.64.0/19 afrinic
+212.0.0.0/7 ripe
+214.0.0.0/7 arin # DoD
+216.0.0.0/8 arin
+217.0.0.0/8 ripe
+218.36.0.0/14 whois.nic.or.kr
+218.40.0.0/13 whois.nic.ad.jp
+218.48.0.0/13 whois.nic.or.kr
+219.96.0.0/11 whois.nic.ad.jp
+218.144.0.0/12 whois.nic.or.kr
+218.160.0.0/12 twnic
+218.216.0.0/13 whois.nic.ad.jp
+218.224.0.0/13 whois.nic.ad.jp
+218.232.0.0/13 whois.nic.or.kr
+219.240.0.0/15 whois.nic.or.kr
+219.248.0.0/13 whois.nic.or.kr
+218.0.0.0/7 apnic
+220.64.0.0/11 whois.nic.or.kr
+220.96.0.0/14 whois.nic.ad.jp
+220.103.0.0/16 whois.nic.or.kr
+220.104.0.0/13 whois.nic.ad.jp
+220.149.0.0/16 whois.nic.or.kr
+221.138.0.0/15 whois.nic.or.kr
+221.140.0.0/14 whois.nic.or.kr
+221.144.0.0/12 whois.nic.or.kr
+221.160.0.0/13 whois.nic.or.kr
+222.96.0.0/12 whois.nic.or.kr
+222.112.0.0/13 whois.nic.or.kr
+222.120.0.0/15 whois.nic.or.kr
+222.122.0.0/16 whois.nic.or.kr
+222.232.0.0/13 whois.nic.or.kr
+220.0.0.0/6 apnic
+# that's all... here starts the multicast space
diff --git a/ip_del_recovered.h b/ip_del_recovered.h
new file mode 100644
index 0000000..40471e6
--- /dev/null
+++ b/ip_del_recovered.h
@@ -0,0 +1,489 @@
+/* 43.224.0.0 - 43.231.255.255 */
+{ 736100352UL, 4294443008UL, "whois.apnic.net" },
+/* 43.236.0.0 - 43.243.255.255 */
+{ 736886784UL, 4294705152UL, "whois.apnic.net" },
+{ 737148928UL, 4294705152UL, "whois.apnic.net" },
+/* 43.245.0.0 - 43.252.255.255 */
+{ 737476608UL, 4294901760UL, "whois.apnic.net" },
+{ 737542144UL, 4294836224UL, "whois.apnic.net" },
+{ 737673216UL, 4294705152UL, "whois.apnic.net" },
+{ 737935360UL, 4294901760UL, "whois.apnic.net" },
+/* 43.254.0.0 - 43.255.255.255 */
+{ 738066432UL, 4294836224UL, "whois.apnic.net" },
+/* 45.2.0.0 - 45.3.255.255 */
+{ 755105792UL, 4294836224UL, "whois.arin.net" },
+/* 45.4.0.0 - 45.7.255.255 */
+{ 755236864UL, 4294705152UL, "whois.lacnic.net" },
+/* 45.8.0.0 - 45.15.255.255 */
+{ 755499008UL, 4294443008UL, "whois.ripe.net" },
+/* 45.16.0.0 - 45.31.255.255 */
+{ 756023296UL, 4293918720UL, "whois.arin.net" },
+/* 45.32.0.0 - 45.63.255.255 */
+{ 757071872UL, 4292870144UL, "whois.arin.net" },
+/* 45.64.0.0 - 45.65.15.255 */
+{ 759234560UL, 4294963200UL, "whois.apnic.net" },
+{ 759169024UL, 4294901760UL, "whois.apnic.net" },
+/* 45.65.16.0 - 45.65.63.255 */
+{ 759238656UL, 4294963200UL, "whois.apnic.net" },
+{ 759242752UL, 4294959104UL, "whois.apnic.net" },
+/* 45.65.64.0 - 45.65.127.255 */
+{ 759250944UL, 4294950912UL, "whois.ripe.net" },
+/* 45.65.128.0 - 45.65.255.255 */
+{ 759267328UL, 4294934528UL, "whois.lacnic.net" },
+/* 45.66.0.0 - 45.67.255.255 */
+{ 759300096UL, 4294836224UL, "whois.ripe.net" },
+/* 45.68.0.0 - 45.71.255.255 */
+{ 759431168UL, 4294705152UL, "whois.lacnic.net" },
+/* 45.72.0.0 - 45.79.255.255 */
+{ 759693312UL, 4294443008UL, "whois.arin.net" },
+/* 45.80.0.0 - 45.95.255.255 */
+{ 760217600UL, 4293918720UL, "whois.ripe.net" },
+/* 45.96.0.0 - 45.111.255.255 */
+{ 761266176UL, 4293918720UL, "whois.afrinic.net" },
+/* 45.112.0.0 - 45.127.255.255 */
+{ 762314752UL, 4293918720UL, "whois.apnic.net" },
+/* 45.128.0.0 - 45.159.255.255 */
+{ 763363328UL, 4292870144UL, "whois.ripe.net" },
+/* 45.160.0.0 - 45.191.255.255 */
+{ 765460480UL, 4292870144UL, "whois.lacnic.net" },
+/* 45.192.0.0 - 45.222.255.255 */
+{ 767557632UL, 4293918720UL, "whois.afrinic.net" },
+{ 768606208UL, 4294443008UL, "whois.afrinic.net" },
+{ 769130496UL, 4294705152UL, "whois.afrinic.net" },
+{ 769392640UL, 4294836224UL, "whois.afrinic.net" },
+{ 769523712UL, 4294901760UL, "whois.afrinic.net" },
+/* 45.223.0.0 - 45.223.255.255 */
+{ 769589248UL, 4294901760UL, "whois.arin.net" },
+/* 45.224.0.0 - 45.239.255.255 */
+{ 769654784UL, 4293918720UL, "whois.lacnic.net" },
+/* 45.240.0.0 - 45.247.255.255 */
+{ 770703360UL, 4294443008UL, "whois.afrinic.net" },
+/* 45.248.0.0 - 45.255.255.255 */
+{ 771227648UL, 4294443008UL, "whois.apnic.net" },
+/* 66.218.132.0 - 66.218.133.255 */
+{ 1121616896UL, 4294966784UL, "whois.arin.net" },
+/* 66.251.128.0 - 66.251.191.255 */
+{ 1123778560UL, 4294950912UL, "whois.afrinic.net" },
+/* 72.44.16.0 - 72.44.31.255 */
+{ 1210847232UL, 4294963200UL, "whois.lacnic.net" },
+/* 74.91.48.0 - 74.91.63.255 */
+{ 1247490048UL, 4294963200UL, "whois.arin.net" },
+/* 128.201.0.0 - 128.201.255.255 */
+{ 2160656384UL, 4294901760UL, "whois.lacnic.net" },
+/* 131.196.0.0 - 131.196.255.255 */
+{ 2210660352UL, 4294901760UL, "whois.lacnic.net" },
+/* 137.59.0.0 - 137.59.255.255 */
+{ 2302345216UL, 4294901760UL, "whois.apnic.net" },
+/* 139.5.0.0 - 139.5.255.255 */
+{ 2332360704UL, 4294901760UL, "whois.apnic.net" },
+/* 139.26.0.0 - 139.26.255.255 */
+{ 2333736960UL, 4294901760UL, "whois.afrinic.net" },
+/* 139.28.0.0 - 139.28.255.255 */
+{ 2333868032UL, 4294901760UL, "whois.ripe.net" },
+/* 144.48.0.0 - 144.48.255.255 */
+{ 2419064832UL, 4294901760UL, "whois.apnic.net" },
+/* 144.168.0.0 - 144.168.255.255 */
+{ 2426929152UL, 4294901760UL, "whois.arin.net" },
+/* 146.196.32.0 - 146.196.127.255 */
+{ 2462326784UL, 4294959104UL, "whois.apnic.net" },
+{ 2462334976UL, 4294950912UL, "whois.apnic.net" },
+/* 146.196.128.0 - 146.196.255.255 */
+{ 2462351360UL, 4294934528UL, "whois.afrinic.net" },
+/* 147.78.0.0 - 147.78.255.255 */
+{ 2471362560UL, 4294901760UL, "whois.ripe.net" },
+/* 149.248.0.0 - 149.248.255.255 */
+{ 2516058112UL, 4294901760UL, "whois.arin.net" },
+/* 150.107.0.0 - 150.107.255.255 */
+{ 2523594752UL, 4294901760UL, "whois.apnic.net" },
+/* 150.129.0.0 - 150.129.255.255 */
+{ 2525036544UL, 4294901760UL, "whois.apnic.net" },
+/* 150.242.0.0 - 150.242.255.255 */
+{ 2532442112UL, 4294901760UL, "whois.apnic.net" },
+/* 152.89.0.0 - 152.89.255.255 */
+{ 2555969536UL, 4294901760UL, "whois.ripe.net" },
+/* 154.16.0.0 - 154.16.255.255 */
+{ 2584739840UL, 4294901760UL, "whois.afrinic.net" },
+/* 157.119.0.0 - 157.119.255.255 */
+{ 2641821696UL, 4294901760UL, "whois.apnic.net" },
+/* 160.19.0.0 - 160.19.15.255 */
+{ 2685599744UL, 4294963200UL, "whois.arin.net" },
+/* 160.19.20.0 - 160.19.23.255 */
+{ 2685604864UL, 4294966272UL, "whois.apnic.net" },
+/* 160.19.24.0 - 160.19.31.255 */
+{ 2685605888UL, 4294965248UL, "whois.arin.net" },
+/* 160.19.36.0 - 160.19.39.255 */
+{ 2685608960UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.19.44.0 - 160.19.47.255 */
+{ 2685611008UL, 4294966272UL, "whois.lacnic.net" },
+/* 160.19.48.0 - 160.19.55.255 */
+{ 2685612032UL, 4294965248UL, "whois.apnic.net" },
+/* 160.19.60.0 - 160.19.63.255 */
+{ 2685615104UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.19.64.0 - 160.19.67.255 */
+{ 2685616128UL, 4294966272UL, "whois.apnic.net" },
+/* 160.19.92.0 - 160.19.95.255 */
+{ 2685623296UL, 4294966272UL, "whois.ripe.net" },
+/* 160.19.96.0 - 160.19.103.255 */
+{ 2685624320UL, 4294965248UL, "whois.afrinic.net" },
+/* 160.19.104.0 - 160.19.107.255 */
+{ 2685626368UL, 4294966272UL, "whois.arin.net" },
+/* 160.19.112.0 - 160.19.143.255 */
+{ 2685628416UL, 4294963200UL, "whois.afrinic.net" },
+{ 2685632512UL, 4294963200UL, "whois.afrinic.net" },
+/* 160.19.152.0 - 160.19.155.255 */
+{ 2685638656UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.19.160.0 - 160.19.163.255 */
+{ 2685640704UL, 4294966272UL, "whois.arin.net" },
+/* 160.19.168.0 - 160.19.175.255 */
+{ 2685642752UL, 4294965248UL, "whois.lacnic.net" },
+/* 160.19.180.0 - 160.19.183.255 */
+{ 2685645824UL, 4294966272UL, "whois.ripe.net" },
+/* 160.19.188.0 - 160.19.191.255 */
+{ 2685647872UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.19.192.0 - 160.19.199.255 */
+{ 2685648896UL, 4294965248UL, "whois.afrinic.net" },
+/* 160.19.200.0 - 160.19.203.255 */
+{ 2685650944UL, 4294966272UL, "whois.lacnic.net" },
+/* 160.19.208.0 - 160.19.223.255 */
+{ 2685652992UL, 4294963200UL, "whois.apnic.net" },
+/* 160.19.224.0 - 160.19.227.255 */
+{ 2685657088UL, 4294966272UL, "whois.apnic.net" },
+/* 160.19.232.0 - 160.19.239.255 */
+{ 2685659136UL, 4294965248UL, "whois.afrinic.net" },
+/* 160.19.240.0 - 160.19.255.255 */
+{ 2685661184UL, 4294963200UL, "whois.lacnic.net" },
+/* 160.20.0.0 - 160.20.15.255 */
+{ 2685665280UL, 4294963200UL, "whois.apnic.net" },
+/* 160.20.20.0 - 160.20.23.255 */
+{ 2685670400UL, 4294966272UL, "whois.lacnic.net" },
+/* 160.20.24.0 - 160.20.31.255 */
+{ 2685671424UL, 4294965248UL, "whois.afrinic.net" },
+/* 160.20.32.0 - 160.20.35.255 */
+{ 2685673472UL, 4294966272UL, "whois.lacnic.net" },
+/* 160.20.40.0 - 160.20.47.255 */
+{ 2685675520UL, 4294965248UL, "whois.apnic.net" },
+/* 160.20.48.0 - 160.20.63.255 */
+{ 2685677568UL, 4294963200UL, "whois.apnic.net" },
+/* 160.20.64.0 - 160.20.71.255 */
+{ 2685681664UL, 4294965248UL, "whois.lacnic.net" },
+/* 160.20.72.0 - 160.20.75.255 */
+{ 2685683712UL, 4294966272UL, "whois.apnic.net" },
+/* 160.20.80.0 - 160.20.95.255 */
+{ 2685685760UL, 4294963200UL, "whois.lacnic.net" },
+/* 160.20.96.0 - 160.20.103.255 */
+{ 2685689856UL, 4294965248UL, "whois.ripe.net" },
+/* 160.20.108.0 - 160.20.111.255 */
+{ 2685692928UL, 4294966272UL, "whois.ripe.net" },
+/* 160.20.112.0 - 160.20.115.255 */
+{ 2685693952UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.20.144.0 - 160.20.159.255 */
+{ 2685702144UL, 4294963200UL, "whois.ripe.net" },
+/* 160.20.160.0 - 160.20.207.255 */
+{ 2685706240UL, 4294959104UL, "whois.lacnic.net" },
+{ 2685714432UL, 4294963200UL, "whois.lacnic.net" },
+/* 160.20.208.0 - 160.20.211.255 */
+{ 2685718528UL, 4294966272UL, "whois.arin.net" },
+/* 160.20.213.0 - 160.20.213.255 */
+{ 2685719808UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.20.214.0 - 160.20.215.255 */
+{ 2685720064UL, 4294966784UL, "whois.ripe.net" },
+/* 160.20.217.0 - 160.20.217.255 */
+{ 2685720832UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.20.218.0 - 160.20.219.255 */
+{ 2685721088UL, 4294966784UL, "whois.lacnic.net" },
+/* 160.20.221.0 - 160.20.221.255 */
+{ 2685721856UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.20.222.0 - 160.20.223.255 */
+{ 2685722112UL, 4294966784UL, "whois.apnic.net" },
+/* 160.20.225.0 - 160.20.225.255 */
+{ 2685722880UL, 4294967040UL, "whois.lacnic.net" },
+/* 160.20.226.0 - 160.20.227.255 */
+{ 2685723136UL, 4294966784UL, "whois.afrinic.net" },
+/* 160.20.229.0 - 160.20.229.255 */
+{ 2685723904UL, 4294967040UL, "whois.ripe.net" },
+/* 160.20.230.0 - 160.20.231.255 */
+{ 2685724160UL, 4294966784UL, "whois.arin.net" },
+/* 160.20.232.0 - 160.20.239.255 */
+{ 2685724672UL, 4294965248UL, "whois.arin.net" },
+/* 160.20.242.0 - 160.20.243.255 */
+{ 2685727232UL, 4294966784UL, "whois.lacnic.net" },
+/* 160.20.246.0 - 160.20.247.255 */
+{ 2685728256UL, 4294966784UL, "whois.lacnic.net" },
+/* 160.20.248.0 - 160.20.249.255 */
+{ 2685728768UL, 4294966784UL, "whois.ripe.net" },
+/* 160.20.251.0 - 160.20.251.255 */
+{ 2685729536UL, 4294967040UL, "whois.arin.net" },
+/* 160.20.252.0 - 160.20.255.255 */
+{ 2685729792UL, 4294966272UL, "whois.afrinic.net" },
+/* 160.202.8.0 - 160.202.15.255 */
+{ 2697594880UL, 4294965248UL, "whois.apnic.net" },
+/* 160.202.16.0 - 160.202.31.255 */
+{ 2697596928UL, 4294963200UL, "whois.ripe.net" },
+/* 160.202.32.0 - 160.202.63.255 */
+{ 2697601024UL, 4294959104UL, "whois.apnic.net" },
+/* 160.202.64.0 - 160.202.127.255 */
+{ 2697609216UL, 4294950912UL, "whois.arin.net" },
+/* 160.202.128.0 - 160.202.255.255 */
+{ 2697625600UL, 4294934528UL, "whois.apnic.net" },
+/* 160.238.0.0 - 160.238.0.255 */
+{ 2699952128UL, 4294967040UL, "whois.apnic.net" },
+/* 160.238.11.0 - 160.238.11.255 */
+{ 2699954944UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.238.12.0 - 160.238.19.255 */
+{ 2699955200UL, 4294966272UL, "whois.apnic.net" },
+{ 2699956224UL, 4294966272UL, "whois.apnic.net" },
+/* 160.238.21.0 - 160.238.21.255 */
+{ 2699957504UL, 4294967040UL, "whois.ripe.net" },
+/* 160.238.22.0 - 160.238.23.255 */
+{ 2699957760UL, 4294966784UL, "whois.arin.net" },
+/* 160.238.24.0 - 160.238.29.255 */
+{ 2699958272UL, 4294966272UL, "whois.lacnic.net" },
+{ 2699959296UL, 4294966784UL, "whois.lacnic.net" },
+/* 160.238.31.0 - 160.238.31.255 */
+{ 2699960064UL, 4294967040UL, "whois.arin.net" },
+/* 160.238.33.0 - 160.238.33.255 */
+{ 2699960576UL, 4294967040UL, "whois.apnic.net" },
+/* 160.238.34.0 - 160.238.35.255 */
+{ 2699960832UL, 4294966784UL, "whois.apnic.net" },
+/* 160.238.36.0 - 160.238.39.255 */
+{ 2699961344UL, 4294966272UL, "whois.ripe.net" },
+/* 160.238.41.0 - 160.238.41.255 */
+{ 2699962624UL, 4294967040UL, "whois.arin.net" },
+/* 160.238.42.0 - 160.238.47.255 */
+{ 2699962880UL, 4294966784UL, "whois.arin.net" },
+{ 2699963392UL, 4294966272UL, "whois.arin.net" },
+/* 160.238.48.0 - 160.238.49.255 */
+{ 2699964416UL, 4294966784UL, "whois.afrinic.net" },
+/* 160.238.50.0 - 160.238.50.255 */
+{ 2699964928UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.238.52.0 - 160.238.55.255 */
+{ 2699965440UL, 4294966272UL, "whois.ripe.net" },
+/* 160.238.57.0 - 160.238.57.255 */
+{ 2699966720UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.238.58.0 - 160.238.59.255 */
+{ 2699966976UL, 4294966784UL, "whois.apnic.net" },
+/* 160.238.60.0 - 160.238.61.255 */
+{ 2699967488UL, 4294966784UL, "whois.ripe.net" },
+/* 160.238.63.0 - 160.238.63.255 */
+{ 2699968256UL, 4294967040UL, "whois.lacnic.net" },
+/* 160.238.64.0 - 160.238.95.255 */
+{ 2699968512UL, 4294959104UL, "whois.apnic.net" },
+/* 160.238.96.0 - 160.238.99.255 */
+{ 2699976704UL, 4294966272UL, "whois.ripe.net" },
+/* 160.238.101.0 - 160.238.101.255 */
+{ 2699977984UL, 4294967040UL, "whois.afrinic.net" },
+/* 160.238.102.0 - 160.238.103.255 */
+{ 2699978240UL, 4294966784UL, "whois.arin.net" },
+/* 160.238.104.0 - 160.238.111.255 */
+{ 2699978752UL, 4294965248UL, "whois.lacnic.net" },
+/* 160.238.112.0 - 160.238.127.255 */
+{ 2699980800UL, 4294963200UL, "whois.ripe.net" },
+/* 160.238.128.0 - 160.238.255.255 */
+{ 2699984896UL, 4294934528UL, "whois.lacnic.net" },
+/* 161.123.0.0 - 161.123.255.255 */
+{ 2709192704UL, 4294901760UL, "whois.afrinic.net" },
+/* 162.12.196.0 - 162.12.199.255 */
+{ 2718745600UL, 4294966272UL, "whois.lacnic.net" },
+/* 162.12.200.0 - 162.12.207.255 */
+{ 2718746624UL, 4294965248UL, "whois.ripe.net" },
+/* 162.12.208.0 - 162.12.215.255 */
+{ 2718748672UL, 4294965248UL, "whois.apnic.net" },
+/* 162.12.216.0 - 162.12.219.255 */
+{ 2718750720UL, 4294966272UL, "whois.arin.net" },
+/* 162.12.224.0 - 162.12.235.255 */
+{ 2718752768UL, 4294965248UL, "whois.arin.net" },
+{ 2718754816UL, 4294966272UL, "whois.arin.net" },
+/* 162.12.240.0 - 162.12.247.255 */
+{ 2718756864UL, 4294965248UL, "whois.apnic.net" },
+/* 163.47.4.0 - 163.47.18.255 */
+{ 2737767424UL, 4294966272UL, "whois.apnic.net" },
+{ 2737768448UL, 4294965248UL, "whois.apnic.net" },
+{ 2737770496UL, 4294966784UL, "whois.apnic.net" },
+{ 2737771008UL, 4294967040UL, "whois.apnic.net" },
+/* 163.47.20.0 - 163.47.21.255 */
+{ 2737771520UL, 4294966784UL, "whois.apnic.net" },
+/* 163.47.32.0 - 163.47.45.255 */
+{ 2737774592UL, 4294965248UL, "whois.apnic.net" },
+{ 2737776640UL, 4294966272UL, "whois.apnic.net" },
+{ 2737777664UL, 4294966784UL, "whois.apnic.net" },
+/* 163.47.47.0 - 163.47.255.255 */
+{ 2737778432UL, 4294967040UL, "whois.apnic.net" },
+{ 2737778688UL, 4294963200UL, "whois.apnic.net" },
+{ 2737782784UL, 4294950912UL, "whois.apnic.net" },
+{ 2737799168UL, 4294934528UL, "whois.apnic.net" },
+/* 163.53.0.0 - 163.53.255.255 */
+{ 2738159616UL, 4294901760UL, "whois.apnic.net" },
+/* 164.160.0.0 - 164.160.255.255 */
+{ 2761949184UL, 4294901760UL, "whois.afrinic.net" },
+/* 164.163.0.0 - 164.163.255.255 */
+{ 2762145792UL, 4294901760UL, "whois.lacnic.net" },
+/* 192.12.109.0 - 192.12.109.255 */
+{ 3222039808UL, 4294967040UL, "whois.apnic.net" },
+/* 192.12.110.0 - 192.12.111.255 */
+{ 3222040064UL, 4294966784UL, "whois.afrinic.net" },
+/* 192.12.112.0 - 192.12.115.255 */
+{ 3222040576UL, 4294966272UL, "whois.lacnic.net" },
+/* 192.12.116.0 - 192.12.117.255 */
+{ 3222041600UL, 4294966784UL, "whois.afrinic.net" },
+/* 192.12.118.0 - 192.12.118.255 */
+{ 3222042112UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.26.110.0 - 192.26.110.255 */
+{ 3222957568UL, 4294967040UL, "whois.apnic.net" },
+/* 192.42.65.0 - 192.42.65.255 */
+{ 3223994624UL, 4294967040UL, "whois.ripe.net" },
+/* 192.47.36.0 - 192.47.36.255 */
+{ 3224314880UL, 4294967040UL, "whois.afrinic.net" },
+/* 192.51.188.0 - 192.51.188.255 */
+{ 3224615936UL, 4294967040UL, "whois.apnic.net" },
+/* 192.51.240.0 - 192.51.240.255 */
+{ 3224629248UL, 4294967040UL, "whois.afrinic.net" },
+/* 192.54.244.0 - 192.54.244.255 */
+{ 3224826880UL, 4294967040UL, "whois.ripe.net" },
+/* 192.67.23.0 - 192.67.23.255 */
+{ 3225622272UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.68.185.0 - 192.68.185.255 */
+{ 3225729280UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.70.192.0 - 192.70.199.255 */
+{ 3225862144UL, 4294965248UL, "whois.ripe.net" },
+/* 192.70.200.0 - 192.70.201.255 */
+{ 3225864192UL, 4294966784UL, "whois.afrinic.net" },
+/* 192.75.4.0 - 192.75.4.255 */
+{ 3226141696UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.75.137.0 - 192.75.137.255 */
+{ 3226175744UL, 4294967040UL, "whois.apnic.net" },
+/* 192.75.236.0 - 192.75.236.255 */
+{ 3226201088UL, 4294967040UL, "whois.afrinic.net" },
+/* 192.83.207.0 - 192.83.207.255 */
+{ 3226717952UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.83.208.0 - 192.83.215.255 */
+{ 3226718208UL, 4294965248UL, "whois.afrinic.net" },
+/* 192.83.216.0 - 192.83.216.255 */
+{ 3226720256UL, 4294967040UL, "whois.ripe.net" },
+/* 192.91.200.0 - 192.91.200.255 */
+{ 3227240448UL, 4294967040UL, "whois.afrinic.net" },
+/* 192.91.254.0 - 192.91.254.255 */
+{ 3227254272UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.92.154.0 - 192.92.154.255 */
+{ 3227294208UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.94.77.0 - 192.94.77.255 */
+{ 3227405568UL, 4294967040UL, "whois.arin.net" },
+/* 192.94.78.0 - 192.94.78.255 */
+{ 3227405824UL, 4294967040UL, "whois.ripe.net" },
+/* 192.107.1.0 - 192.107.1.255 */
+{ 3228238080UL, 4294967040UL, "whois.arin.net" },
+/* 192.133.103.0 - 192.133.103.255 */
+{ 3229968128UL, 4294967040UL, "whois.arin.net" },
+/* 192.135.90.0 - 192.135.91.255 */
+{ 3230095872UL, 4294966784UL, "whois.apnic.net" },
+/* 192.135.95.0 - 192.135.95.255 */
+{ 3230097152UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.135.99.0 - 192.135.99.255 */
+{ 3230098176UL, 4294967040UL, "whois.apnic.net" },
+/* 192.135.100.0 - 192.135.100.255 */
+{ 3230098432UL, 4294967040UL, "whois.ripe.net" },
+/* 192.135.185.0 - 192.135.185.255 */
+{ 3230120192UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.140.1.0 - 192.140.1.255 */
+{ 3230400768UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.140.2.0 - 192.140.3.255 */
+{ 3230401024UL, 4294966784UL, "whois.ripe.net" },
+/* 192.140.4.0 - 192.140.7.255 */
+{ 3230401536UL, 4294966272UL, "whois.arin.net" },
+/* 192.140.8.0 - 192.140.15.255 */
+{ 3230402560UL, 4294965248UL, "whois.lacnic.net" },
+/* 192.140.16.0 - 192.140.127.255 */
+{ 3230404608UL, 4294963200UL, "whois.lacnic.net" },
+{ 3230408704UL, 4294959104UL, "whois.lacnic.net" },
+{ 3230416896UL, 4294950912UL, "whois.lacnic.net" },
+/* 192.140.128.0 - 192.140.255.255 */
+{ 3230433280UL, 4294934528UL, "whois.apnic.net" },
+/* 192.141.0.0 - 192.141.255.255 */
+{ 3230466048UL, 4294901760UL, "whois.lacnic.net" },
+/* 192.142.0.0 - 192.143.255.255 */
+{ 3230531584UL, 4294836224UL, "whois.afrinic.net" },
+/* 192.144.0.0 - 192.144.63.255 */
+{ 3230662656UL, 4294950912UL, "whois.ripe.net" },
+/* 192.144.64.0 - 192.144.71.255 */
+{ 3230679040UL, 4294965248UL, "whois.lacnic.net" },
+/* 192.144.72.0 - 192.144.73.255 */
+{ 3230681088UL, 4294966784UL, "whois.lacnic.net" },
+/* 192.144.75.0 - 192.144.75.255 */
+{ 3230681856UL, 4294967040UL, "whois.ripe.net" },
+/* 192.144.78.0 - 192.144.79.255 */
+{ 3230682624UL, 4294966784UL, "whois.apnic.net" },
+/* 192.144.80.0 - 192.144.95.255 */
+{ 3230683136UL, 4294963200UL, "whois.apnic.net" },
+/* 192.144.96.0 - 192.144.127.255 */
+{ 3230687232UL, 4294959104UL, "whois.lacnic.net" },
+/* 192.144.128.0 - 192.144.255.255 */
+{ 3230695424UL, 4294934528UL, "whois.arin.net" },
+/* 192.145.0.0 - 192.145.127.255 */
+{ 3230728192UL, 4294934528UL, "whois.ripe.net" },
+/* 192.145.128.0 - 192.145.191.255 */
+{ 3230760960UL, 4294950912UL, "whois.afrinic.net" },
+/* 192.145.192.0 - 192.145.223.255 */
+{ 3230777344UL, 4294959104UL, "whois.lacnic.net" },
+/* 192.145.224.0 - 192.145.227.255 */
+{ 3230785536UL, 4294966272UL, "whois.ripe.net" },
+/* 192.145.228.0 - 192.145.229.255 */
+{ 3230786560UL, 4294966784UL, "whois.apnic.net" },
+/* 192.145.230.0 - 192.145.230.255 */
+{ 3230787072UL, 4294967040UL, "whois.afrinic.net" },
+/* 192.147.11.0 - 192.147.11.255 */
+{ 3230862080UL, 4294967040UL, "whois.arin.net" },
+/* 192.153.12.0 - 192.153.12.255 */
+{ 3231255552UL, 4294967040UL, "whois.lacnic.net" },
+/* 192.156.144.0 - 192.156.144.255 */
+{ 3231485952UL, 4294967040UL, "whois.apnic.net" },
+/* 192.156.202.0 - 192.156.202.255 */
+{ 3231500800UL, 4294967040UL, "whois.arin.net" },
+/* 192.156.220.0 - 192.156.220.255 */
+{ 3231505408UL, 4294967040UL, "whois.apnic.net" },
+/* 192.172.232.0 - 192.172.232.255 */
+{ 3232557056UL, 4294967040UL, "whois.ripe.net" },
+/* 192.172.244.0 - 192.172.244.255 */
+{ 3232560128UL, 4294967040UL, "whois.arin.net" },
+/* 192.188.81.0 - 192.188.81.255 */
+{ 3233566976UL, 4294967040UL, "whois.arin.net" },
+/* 192.188.82.0 - 192.188.83.255 */
+{ 3233567232UL, 4294966784UL, "whois.apnic.net" },
+/* 192.188.248.0 - 192.188.248.255 */
+{ 3233609728UL, 4294967040UL, "whois.ripe.net" },
+/* 192.197.113.0 - 192.197.113.255 */
+{ 3234164992UL, 4294967040UL, "whois.apnic.net" },
+/* 192.231.238.0 - 192.231.238.255 */
+{ 3236425216UL, 4294967040UL, "whois.arin.net" },
+/* 192.251.230.0 - 192.251.230.255 */
+{ 3237733888UL, 4294967040UL, "whois.ripe.net" },
+/* 198.17.79.0 - 198.17.79.255 */
+{ 3323023104UL, 4294967040UL, "whois.arin.net" },
+/* 198.97.38.0 - 198.97.38.255 */
+{ 3328255488UL, 4294967040UL, "whois.lacnic.net" },
+/* 199.21.172.0 - 199.21.175.255 */
+{ 3340086272UL, 4294966272UL, "whois.apnic.net" },
+/* 199.212.57.0 - 199.212.57.255 */
+{ 3352574208UL, 4294967040UL, "whois.apnic.net" },
+/* 204.8.204.0 - 204.8.207.255 */
+{ 3423128576UL, 4294966272UL, "whois.afrinic.net" },
+/* 204.11.0.0 - 204.11.3.255 */
+{ 3423272960UL, 4294966272UL, "whois.ripe.net" },
+/* 204.48.32.0 - 204.48.33.255 */
+{ 3425705984UL, 4294966784UL, "whois.ripe.net" },
+/* 204.52.191.0 - 204.52.191.255 */
+{ 3426008832UL, 4294967040UL, "whois.apnic.net" },
+/* 204.225.42.0 - 204.225.43.255 */
+{ 3437308416UL, 4294966784UL, "whois.lacnic.net" },
+/* 205.211.83.0 - 205.211.83.255 */
+{ 3453178624UL, 4294967040UL, "whois.ripe.net" },
+/* 207.115.112.0 - 207.115.127.255 */
+{ 3480449024UL, 4294963200UL, "whois.arin.net" },
+/* 208.73.240.0 - 208.73.243.255 */
+{ 3494506496UL, 4294966272UL, "whois.arin.net" },
+/* 208.85.156.0 - 208.85.159.255 */
+{ 3495271424UL, 4294966272UL, "whois.afrinic.net" },
+/* 209.107.128.0 - 209.107.191.255 */
+{ 3513483264UL, 4294950912UL, "whois.arin.net" },
+/* 216.98.208.0 - 216.98.223.255 */
+{ 3630354432UL, 4294963200UL, "whois.lacnic.net" },
+/* 216.250.96.0 - 216.250.111.255 */
+{ 3640287232UL, 4294963200UL, "whois.apnic.net" },
diff --git a/make_as32_del.pl b/make_as32_del.pl
new file mode 100755
index 0000000..6382679
--- /dev/null
+++ b/make_as32_del.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ my ($fh, $fl, $lh, $ll, $s, $f, $l);
+ if (($fh, $fl, $lh, $ll, $s) =
+ /^(\d+)\.(\d+)\s+(\d+)\.(\d+)\s+([\w\.-]+)$/) {
+ $f = ($fh << 16) + $fl;
+ $l = ($lh << 16) + $ll;
+
+ my $server = ($s =~ /\./) ? $s : "whois.$s.net";
+ print qq|{ ${f}u, ${l}u,\t"$server" },\t/* $fh.$fl $lh.$ll */\n|;
+ } elsif (($f, $l, $s) = /^(\d+)\s+(\d+)\s+([\w\.-]+)$/) {
+ my $server = ($s =~ /\./) ? $s : "whois.$s.net";
+ print qq|{ ${f}u, ${l}u,\t"$server" },\n|;
+ } else {
+ die "format error: $_";
+ }
+}
+
diff --git a/make_as_del.pl b/make_as_del.pl
new file mode 100755
index 0000000..10ab071
--- /dev/null
+++ b/make_as_del.pl
@@ -0,0 +1,28 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+my $last_l = 0;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not (/^([\d\.]+)\s+([\d\.]+)\s+([\w\.]+)$/);
+ my $f = $1; my $l = $2; my $s = $3;
+
+ die "constraint violated: $l < $last_l" if $l < $last_l;
+ $last_l = $l;
+
+ print "{ ${f}, ${l}, \"";
+ if ($s =~ /\./) {
+ print "$s";
+ } else {
+ print "whois.$s.net";
+ }
+ print qq(" },\n);
+}
+
diff --git a/make_ip6_del.pl b/make_ip6_del.pl
new file mode 100755
index 0000000..80f0b0c
--- /dev/null
+++ b/make_ip6_del.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error:\n$_\n"
+ if not m#^([\da-fA-F]{4}):([\da-fA-F]{1,4})::/(\d+)\s+([\w\.]+)$#;
+ my $len = $3; my $s = $4;
+ my $i1 = $1; my $i2 = $2;
+ my $net = (hex($i1) << 16) + hex $i2;
+
+ if (0) { # just some code to help me visually aggregate networks
+ my $bs = unpack('B32', pack('N', $net));
+ $bs =~ s/(.{8})/$1 /g;
+ print "${i1}:${i2}::/$len\t$bs $s\n";
+ next;
+ }
+
+ print qq|{ ${net}UL, $len, "|;
+ if ($s =~ /\./) {
+ print $s;
+ } elsif ($s eq '6to4') {
+ print "\\x0A";
+ } elsif ($s eq 'teredo') {
+ print "\\x0B";
+ } elsif ($s eq 'UNALLOCATED') {
+ print "\\006";
+ } else {
+ print $s =~ /\./ ? $s : "whois.$s.net";
+ }
+ print qq|" },\n|;
+}
+
diff --git a/make_ip_del.pl b/make_ip_del.pl
new file mode 100755
index 0000000..7ed5c93
--- /dev/null
+++ b/make_ip_del.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not /^([\d\.]+)\/(\d+)\s+([\w\.]+)$/;
+ my $m = $2; my $s = $3;
+
+ my ($i1, $i2, $i3, $i4) = split(/\./, $1);
+ print '{ ' . (($i1 << 24) + ($i2 << 16) + ($i3 << 8) + $i4) . 'UL, '.
+ ((~(0xffffffff >> $m)) & 0xffffffff) . 'UL, "';
+ if ($s =~ /\./) {
+ print $s;
+ } elsif ($s eq 'UNKNOWN') {
+ print "\\005";
+ } elsif ($s eq 'UNALLOCATED') {
+ print "\\006";
+ } else {
+ print "whois.$s.net";
+ }
+ print qq|" },\n|;
+}
+
diff --git a/make_ip_del_recovered.pl b/make_ip_del_recovered.pl
new file mode 100755
index 0000000..65e9112
--- /dev/null
+++ b/make_ip_del_recovered.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+# https://www.iana.org/assignments/ipv4-recovered-address-space/ipv4-recovered-address-space-2.csv
+
+use warnings;
+use strict;
+use autodie;
+
+use Text::CSV;
+use Net::CIDR;
+use Net::IP;
+
+my $csv = Text::CSV->new;
+
+open(my $in, '<', 'ipv4-recovered-address-space-2.csv');
+open(my $out, '>', 'ip_del_recovered.h');
+
+while (my $row = $csv->getline($in)) {
+ next if $row->[0] eq 'Start address';
+ next if $row->[5] ne 'ALLOCATED';
+
+ print $out '/* ' . $row->[0] . ' - ' . $row->[1] . " */\n";
+ my @networks =
+ map { Net::IP->new($_) }
+ Net::CIDR::range2cidr($row->[0] . '-' . $row->[1]);
+ print $out sprintf(qq|{ %sUL, %sUL, "%s" },\n|,
+ $_->intip,
+ ((~(0xffffffff >> $_->prefixlen)) & 0xffffffff),
+ $row->[4]
+ ) foreach @networks;
+}
+
+close($in);
+close($out);
+
diff --git a/make_new_gtlds.pl b/make_new_gtlds.pl
new file mode 100755
index 0000000..dc7110e
--- /dev/null
+++ b/make_new_gtlds.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not /^(xn--[a-z0-9-]+|[a-z]+)$/;
+
+ print qq| "$_",\n|;
+}
+
diff --git a/make_nic_handles.pl b/make_nic_handles.pl
new file mode 100755
index 0000000..6b031c2
--- /dev/null
+++ b/make_nic_handles.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not
+ (my ($a, $b) = /^(-\w+)\s+([\w\d\.:-]+)$/);
+
+ print qq| "$a",\t"$b",\n|;
+}
+
diff --git a/make_servers_charset.pl b/make_servers_charset.pl
new file mode 100755
index 0000000..2f83a09
--- /dev/null
+++ b/make_servers_charset.pl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not
+ (my ($a, $b, $c) = /^([a-z0-9.-]+)\s+([a-z0-9-]+)(?:\s+(.+))?$/);
+
+ if ($c) {
+ print qq| { "$a",\t"$b",\t"$c" },\n|;
+ } else {
+ print qq| { "$a",\t"$b",\tNULL },\n|;
+ }
+}
+
diff --git a/make_tld_serv.pl b/make_tld_serv.pl
new file mode 100755
index 0000000..66af45c
--- /dev/null
+++ b/make_tld_serv.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+while (<>) {
+ chomp;
+ s/#.*$//;
+ s/^\s+//; s/\s+$//;
+ next if /^$/;
+
+ die "format error: $_" if not
+ (my ($a, $b) = /^\.(\w[\w\d\.-]+)\s+([\w\d\.:-]+|[A-Z]+\s+.*)$/);
+
+ $b =~ s/^W(?:EB)?\s+/\\x01/;
+ $b =~ s/^VERISIGN\s+/\\x04" "/;
+ $b = "\\x03" if $b eq 'NONE';
+ $b =~ s/^RECURSIVE\s+/\\x08" "/;
+ $b = "\\x08$b" if $b eq 'whois.flexireg.net';
+ $b = "\\x08$b" if $b eq 'whois.registry.in';
+ $b = "\\x0C" if $b eq 'ARPA';
+ $b = "\\x0D" if $b eq 'IP6';
+ print qq| "$a",\t"$b",\n|;
+}
+
diff --git a/make_version_h.pl b/make_version_h.pl
new file mode 100755
index 0000000..ae4a69b
--- /dev/null
+++ b/make_version_h.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+use autodie;
+
+my $changelog = $ARGV[0] or die "Usage: $0 debian/changelog\n";
+
+open(my $fh, '<', $changelog);
+my $line = <$fh>;
+close($fh);
+
+my ($ver) = $line =~ /^whois \s+ \( ( [^\)]+ ) \) \s+ \S+/x;
+die "Version number not found in $changelog!\n" if not $ver;
+
+$ver =~ s/ ( ~bpo\d+\+\d+ | \+b\d+ | ~deb\d+.* | ubuntu\d+ | build\d+ | \+dyson\d+ ) $//x;
+
+# The version number must not deviate from this format or the -V option
+# to RIPE-like servers will break. If needed, update the previous regexp.
+# This may not be true anymore in 2019.
+die "Invalid version number in $changelog!\n"
+ unless $ver =~ /^ \d+\.\d+ ( \.\d+ )? $/x;
+
+# This is the version number used in the help messages.
+print qq|#define VERSION "$ver"\n|;
+
+# This is the string sent to RIPE-like servers as the argument of -V.
+print qq|#define IDSTRING "Md$ver"\n|;
+
diff --git a/mkpasswd.1 b/mkpasswd.1
new file mode 100644
index 0000000..f5e5775
--- /dev/null
+++ b/mkpasswd.1
@@ -0,0 +1,93 @@
+.TH MKPASSWD 1 "2019-12-30" "Marco d'Itri" "Debian GNU/Linux"
+.SH NAME
+mkpasswd \- Overfeatured front end to crypt(3)
+.SH SYNOPSIS
+.B mkpasswd
+.I PASSWORD
+.RI [ SALT ]
+.SH DESCRIPTION
+.B mkpasswd
+encrypts the given password with the
+.BR crypt (3)
+libc function, using the given salt.
+.SH OPTIONS
+.TP
+.BR \-S ", "\c
+.BI \-\-salt= STRING
+Use the
+.I STRING
+as salt. If it begins with
+.I $
+then it will be passed straight to
+.BR crypt (3)
+without any checks.
+.TP
+.BR \-R ", "\c
+.BI \-\-rounds= NUMBER
+Use
+.I NUMBER
+rounds. This argument is ignored if the method chosen
+does not support variable rounds. For the OpenBSD Blowfish method this is
+the logarithm of the number of rounds.
+The behavior is undefined if this option is used without
+.IR \-\-method .
+.TP
+.BR \-m ", "\c
+.BI \-\-method= TYPE
+Compute the password using the
+.I TYPE
+method.
+If
+.I TYPE
+is
+.I help
+then the list of available methods is printed.
+If
+.I TYPE
+begins and end with
+.I $
+characters then the string is passed to
+.IR crypt_gensalt (3)
+as-is.
+.TP
+.B -5
+Like
+.IR \-\-method=md5crypt .
+.TP
+.B \-P \c
+.IR NUM ", "\c
+.BI \-\-password-fd= NUM
+Read the password from file descriptor
+.I NUM
+instead of using
+.IR getpass (3).
+If the file descriptor is not connected to a tty then no other text
+than the hashed password is printed on stdout.
+.TP
+.BR \-s ", " \-\-stdin
+Like
+.IR \-\-password-fd=0 .
+.SH ENVIRONMENT
+.IP "MKPASSWD_OPTIONS"
+A list of options which will be evaluated before the ones specified on the
+command line.
+.SH BUGS
+If the
+.I \-\-stdin
+option is used then passwords containing some control
+characters may not be read correctly.
+.P
+This program suffers of a bad case of featuritis.
+.SH "SEE ALSO"
+.IR passwd (1),
+.IR passwd (5),
+.IR crypt (3),
+.IR crypt (5),
+.IR crypt_gensalt (3),
+.IR getpass (3).
+.SH AUTHOR
+.B mkpasswd
+and this man page were written by Marco d'Itri
+.RI < md@linux.it >
+and are licensed under the terms of the GNU General Public License,
+version 2 or higher.
diff --git a/mkpasswd.bash b/mkpasswd.bash
new file mode 100644
index 0000000..2d0b9a6
--- /dev/null
+++ b/mkpasswd.bash
@@ -0,0 +1,33 @@
+_mkpasswd() {
+
+ case $3 in
+ --help | --version | --salt | --rounds | --password-fd | -[hVSRP])
+ return 0
+ ;;
+ --method | -m)
+ COMPREPLY=($(compgen -W '$(
+ LC_ALL=C "$1" --method=help 2>/dev/null |
+ while read -r method _; do
+ [[ $method == Available ]] ||
+ printf "%s\n" "$method"
+ done
+ )'))
+ return 0
+ ;;
+ esac
+
+ if [[ $2 == -* ]]; then
+ COMPREPLY=($(compgen -W '
+ --method
+ -5
+ --salt
+ --rounds
+ --password-fd
+ --stdin
+ --help
+ --version
+ ' -- "$2"))
+ return 0
+ fi
+
+} && complete -F _mkpasswd mkpasswd
diff --git a/mkpasswd.c b/mkpasswd.c
new file mode 100644
index 0000000..1d35329
--- /dev/null
+++ b/mkpasswd.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2001-2021 Marco d'Itri <md@linux.it>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* for crypt, snprintf and strcasecmp */
+#define _XOPEN_SOURCE 500
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#define __EXTENSIONS__ 1
+
+/* System library */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "config.h"
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <sys/types.h>
+#ifdef HAVE_XCRYPT_H
+#include <xcrypt.h>
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+/* Application-specific */
+#include "version.h"
+#include "utils.h"
+
+/* Global variables */
+#ifdef HAVE_GETOPT_LONG
+static const struct option longopts[] = {
+ {"method", optional_argument, NULL, 'm'},
+ /* for backward compatibility with versions < 4.7.25 (< 20080321): */
+ {"hash", optional_argument, NULL, 'H'},
+ {"help", no_argument, NULL, 'h'},
+ {"password-fd", required_argument, NULL, 'P'},
+ {"stdin", no_argument, NULL, 's'},
+ {"salt", required_argument, NULL, 'S'},
+ {"rounds", required_argument, NULL, 'R'},
+ {"version", no_argument, NULL, 'V'},
+ {NULL, 0, NULL, 0 }
+};
+#else
+extern char *optarg;
+extern int optind;
+#endif
+
+static const char valid_salts[] = "abcdefghijklmnopqrstuvwxyz"
+"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+
+struct crypt_method {
+ const char *method; /* short name used by the command line option */
+ const char *prefix; /* salt prefix */
+ const unsigned int minlen; /* minimum salt length */
+ const unsigned int maxlen; /* maximum salt length */
+ const unsigned int rounds; /* supports a variable number of rounds */
+ const char *desc; /* long description for the methods list */
+};
+
+/* XCRYPT_VERSION_NUM is defined in crypt.h from libxcrypt */
+#if defined XCRYPT_VERSION_NUM
+# define HAVE_SHA_CRYPT
+# define HAVE_BCRYPT
+# define HAVE_BSDICRYPT
+#endif
+
+static const struct crypt_method methods[] = {
+ /* method prefix minlen, maxlen rounds description */
+#ifdef CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
+ { "auto", NULL, 0, 0, 0, NULL },
+#endif
+ /* compatibility aliases for mkpasswd versions < 5.4.0 */
+ { "des", "", 2, 2, 0, NULL },
+ { "md5", "$1$", 8, 8, 0, NULL },
+#if defined XCRYPT_VERSION_NUM
+ { "yescrypt", "$y$", 0, 0, 1, "Yescrypt" },
+#if XCRYPT_VERSION_NUM >= ((4 << 16) | 4)
+ { "gost-yescrypt", "$gy$", 0, 0, 1, "GOST Yescrypt" },
+#endif
+ { "scrypt", "$7$", 0, 0, 1, "scrypt" },
+#endif
+#ifdef HAVE_BCRYPT_OBSOLETE
+ /* http://marc.info/?l=openbsd-misc&m=139320023202696 */
+ { "bf", "$2a$", 22, 22, 2, "bcrypt" },
+#endif
+#ifdef HAVE_BCRYPT
+ { "bcrypt", "$2b$", 22, 22, 2, "bcrypt" },
+ { "bcrypt-a", "$2a$", 22, 22, 2, "bcrypt (obsolete $2a$ version)" },
+#endif
+#if defined HAVE_SHA_CRYPT
+ /* http://people.redhat.com/drepper/SHA-crypt.txt */
+ { "sha512crypt", "$6$", 8, 16, 1, "SHA-512" },
+ { "sha256crypt", "$5$", 8, 16, 1, "SHA-256" },
+ /* compatibility aliases for mkpasswd versions < 5.4.0 */
+ { "sha-256", "$5$", 8, 16, 1, NULL },
+ { "sha-512", "$6$", 8, 16, 1, NULL },
+#endif
+#if (defined __SVR4 && defined __sun) || defined XCRYPT_VERSION_NUM
+ /* http://www.crypticide.com/dropsafe/article/1389 */
+ /*
+ * Actually the maximum salt length is arbitrary, but Solaris by default
+ * always uses 8 characters:
+ * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/ \
+ * usr/src/lib/crypt_modules/sunmd5/sunmd5.c#crypt_gensalt_impl
+ */
+ { "sunmd5", "$md5$", 8, 8, 1, "SunMD5" },
+#endif
+ { "md5crypt", "$1$", 8, 8, 0, "MD5" },
+#ifdef HAVE_BSDICRYPT
+ { "bsdicrypt", "_", 0, 0, 0,
+ N_("BSDI extended DES-based crypt(3)") },
+#endif
+ { "descrypt", "", 2, 2, 0,
+ N_("standard 56 bit DES-based crypt(3)") },
+#if defined FreeBSD || defined XCRYPT_VERSION_NUM
+ { "nt", "$3$", 0, 0, 0, "NT-Hash" },
+#endif
+ { NULL, NULL, 0, 0, 0, NULL }
+};
+
+void generate_salt(char *const buf, const unsigned int len);
+void *get_random_bytes(const unsigned int len);
+void NORETURN display_help(int error);
+void display_version(void);
+void display_methods(void);
+char *read_line(FILE *fp);
+
+int main(int argc, char *argv[])
+{
+ int ch, i;
+ int password_fd = -1;
+ unsigned int salt_minlen = 0;
+ unsigned int salt_maxlen = 0;
+ unsigned int rounds_support = 0;
+ const char *salt_prefix = NULL;
+ const char *salt_arg = NULL;
+ unsigned int rounds = 0;
+ char *salt = NULL;
+ char rounds_str[30];
+ char *password = NULL;
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
+ textdomain(NLS_CAT_NAME);
+#endif
+
+ /* prepend options from environment */
+ argv = merge_args(getenv("MKPASSWD_OPTIONS"), argv, &argc);
+
+ while ((ch = GETOPT_LONGISH(argc, argv, "hH:m:5P:R:sS:V", longopts, NULL))
+ > 0) {
+ switch (ch) {
+ case '5':
+ optarg = (char *) "md5crypt";
+ /* fall through */
+ case 'm':
+ case 'H':
+ if (!optarg || strcaseeq("help", optarg)) {
+ display_methods();
+ exit(0);
+ }
+#if defined HAVE_LINUX_CRYPT_GENSALT || defined HAVE_SOLARIS_CRYPT_GENSALT
+ if (optarg[0] == '$'
+ && strlen(optarg) > 2
+ && *(optarg + strlen(optarg) - 1) == '$') {
+ salt_prefix = NOFAIL(strdup(optarg));
+ salt_minlen = 0;
+ salt_maxlen = 0;
+ rounds_support = 0;
+ break;
+ }
+#endif
+ for (i = 0; methods[i].method != NULL; i++)
+ if (strcaseeq(methods[i].method, optarg)) {
+ salt_prefix = methods[i].prefix;
+ salt_minlen = methods[i].minlen;
+ salt_maxlen = methods[i].maxlen;
+ rounds_support = methods[i].rounds;
+ break;
+ }
+ if (!salt_prefix) {
+ fprintf(stderr, _("Invalid method '%s'.\n"), optarg);
+ exit(1);
+ }
+ break;
+ case 'P':
+ {
+ char *p;
+ password_fd = strtol(optarg, &p, 10);
+ if (p == NULL || *p != '\0' || password_fd < 0) {
+ fprintf(stderr, _("Invalid number '%s'.\n"), optarg);
+ exit(1);
+ }
+ }
+ break;
+ case 'R':
+ {
+ char *p;
+ long r;
+
+ r = strtol(optarg, &p, 10);
+ if (p == NULL || *p != '\0' || r < 0) {
+ fprintf(stderr, _("Invalid number '%s'.\n"), optarg);
+ exit(1);
+ }
+ rounds = r;
+ }
+ break;
+ case 's':
+ password_fd = 0;
+ break;
+ case 'S':
+ salt_arg = optarg;
+ break;
+ case 'V':
+ display_version();
+ exit(0);
+ case 'h':
+ display_help(EXIT_SUCCESS);
+ default:
+ fprintf(stderr, _("Try '%s --help' for more information.\n"),
+ argv[0]);
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 2 && !salt_arg) {
+ password = argv[0];
+ salt_arg = argv[1];
+ } else if (argc == 1) {
+ password = argv[0];
+ } else if (argc == 0) {
+ } else {
+ display_help(EXIT_FAILURE);
+ }
+
+ /* default: DES password, or else whatever crypt_gensalt chooses */
+ if (!salt_prefix) {
+ salt_minlen = methods[0].minlen;
+ salt_maxlen = methods[0].maxlen;
+ salt_prefix = methods[0].prefix;
+ rounds_support = methods[0].rounds;
+ }
+
+ if (!salt_prefix) {
+ /* NULL means that crypt_gensalt will choose one later */
+ } else if (rounds_support == 2) {
+ /* bcrypt strings always contain the rounds number */
+ if (rounds <= 5)
+ rounds = 5;
+ /* actually it is the logarithm of the number of rounds */
+ snprintf(rounds_str, sizeof(rounds_str), "%02u$", rounds);
+ } else if (rounds_support && rounds)
+ snprintf(rounds_str, sizeof(rounds_str), "rounds=%u$", rounds);
+ else
+ rounds_str[0] = '\0';
+
+ if (salt_arg && salt_arg[0] == '$')
+ /* the salt begins with the prefix which specifies the method */
+ salt = NOFAIL(strdup(salt_arg));
+ else if (salt_prefix && salt_arg && strchr(salt_arg, '$')) {
+ /* looks like a salt, but with no initial method prefix */
+ salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
+ + strlen(salt_arg) + 1));
+ *salt = '\0';
+ strcat(salt, salt_prefix);
+ strcat(salt, rounds_str);
+ strcat(salt, salt_arg);
+ } else if (salt_arg && salt_arg[0] != '\0') {
+ /* just the salt string with no metadata */
+ unsigned int c = strlen(salt_arg);
+ if (c < salt_minlen || c > salt_maxlen) {
+ if (salt_minlen == salt_maxlen)
+ fprintf(stderr, ngettext(
+ "Wrong salt length: %d byte when %d expected.\n",
+ "Wrong salt length: %d bytes when %d expected.\n", c),
+ c, salt_maxlen);
+ else
+ fprintf(stderr, ngettext(
+ "Wrong salt length: %d byte when %d <= n <= %d"
+ " expected.\n",
+ "Wrong salt length: %d bytes when %d <= n <= %d"
+ " expected.\n", c),
+ c, salt_minlen, salt_maxlen);
+ exit(1);
+ }
+ while (c-- > 0) {
+ if (strchr(valid_salts, salt_arg[c]) == NULL) {
+ fprintf(stderr, _("Illegal salt character '%c'.\n"),
+ salt_arg[c]);
+ exit(1);
+ }
+ }
+
+ /*
+ * Build the actual argument to crypt(3) by concatenating the
+ * method prefix, the rounds metadata (if any) and the salt string.
+ */
+ salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
+ + strlen(salt_arg) + 1));
+ *salt = '\0';
+ strcat(salt, salt_prefix);
+ strcat(salt, rounds_str);
+ strcat(salt, salt_arg);
+ } else {
+ /* no salt was specified by the user, so generate one */
+#ifdef HAVE_SOLARIS_CRYPT_GENSALT
+ salt = crypt_gensalt(salt_prefix, NULL);
+ if (!salt) {
+ perror("crypt_gensalt");
+ exit(2);
+ }
+#elif defined HAVE_LINUX_CRYPT_GENSALT
+ void *entropy = get_random_bytes(64);
+
+ salt = crypt_gensalt(salt_prefix, rounds, entropy, 64);
+ if (!salt) {
+ perror("crypt_gensalt");
+ exit(2);
+ }
+ if (entropy)
+ free(entropy);
+#else
+ unsigned int salt_len = salt_maxlen;
+
+ if (salt_minlen != salt_maxlen) { /* salt length can vary */
+ srand(time(NULL) + getpid());
+ salt_len = rand() % (salt_maxlen - salt_minlen + 1) + salt_minlen;
+ }
+
+ salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
+ + salt_len + 1));
+ *salt = '\0';
+ strcat(salt, salt_prefix);
+ strcat(salt, rounds_str);
+ generate_salt(salt + strlen(salt), salt_len);
+#endif
+ }
+
+ if (password) {
+ } else if (password_fd != -1) {
+ FILE *fp;
+
+ if (isatty(password_fd))
+ fprintf(stderr, _("Password: "));
+ fp = fdopen(password_fd, "r");
+ if (!fp) {
+ perror("fdopen");
+ exit(2);
+ }
+
+ password = read_line(fp);
+ if (!password) {
+ perror("fgetc");
+ exit(2);
+ }
+ } else {
+ password = getpass(_("Password: "));
+ if (!password) {
+ perror("getpass");
+ exit(2);
+ }
+ }
+
+ {
+ const char *result;
+ result = crypt(password, salt);
+ /* xcrypt returns "*0" on errors */
+ if (!result || result[0] == '*') {
+ if (CRYPT_SETS_ERRNO)
+ perror("crypt");
+ else
+ fprintf(stderr, "crypt failed.\n");
+ exit(2);
+ }
+ if (!strneq(result, salt, strlen(salt))) {
+ fprintf(stderr, _("Method not supported by crypt(3).\n"));
+ exit(2);
+ }
+ printf("%s\n", result);
+ }
+
+ exit(0);
+}
+
+#ifdef CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY
+
+/*
+ * If NULL is passed to the libxcrypt version of crypt_gensalt() instead of
+ * the buffer of random bytes then the function will obtain by itself the
+ * required randomness.
+ */
+inline void *get_random_bytes(const unsigned int count)
+{
+ return NULL;
+}
+
+#elif defined HAVE_SOLARIS_CRYPT_GENSALT
+
+/*
+ * The Solaris version of crypt_gensalt() gathers the random data by itself.
+ */
+
+#elif defined RANDOM_DEVICE || defined HAVE_ARC4RANDOM_BUF || defined HAVE_GETENTROPY
+
+void *get_random_bytes(const unsigned int count)
+{
+ char *buf = NOFAIL(malloc(count));
+
+#if defined HAVE_ARC4RANDOM_BUF
+ arc4random_buf(buf, count);
+#elif defined HAVE_GETENTROPY
+ if (getentropy(buf, count) < 0)
+ perror("getentropy");
+#else
+ int fd;
+ ssize_t bytes_read;
+
+ fd = open(RANDOM_DEVICE, O_RDONLY);
+ if (fd < 0) {
+ perror("open(" RANDOM_DEVICE ")");
+ exit(2);
+ }
+ bytes_read = read(fd, buf, count);
+ if (bytes_read < 0) {
+ perror("read(" RANDOM_DEVICE ")");
+ exit(2);
+ }
+ if (bytes_read != count) {
+ fprintf(stderr, "Short read of %s.\n", RANDOM_DEVICE);
+ exit(2);
+ }
+ close(fd);
+#endif
+
+ return buf;
+}
+
+void generate_salt(char *const buf, const unsigned int len)
+{
+ unsigned int i;
+ unsigned char *entropy;
+
+ entropy = get_random_bytes(len);
+
+ for (i = 0; i < len; i++)
+ buf[i] = valid_salts[entropy[i] % (sizeof valid_salts - 1)];
+ buf[i] = '\0';
+ free(entropy);
+}
+
+#else /* RANDOM_DEVICE || HAVE_ARC4RANDOM_BUF || HAVE_GETENTROPY */
+
+void generate_salt(char *const buf, const unsigned int len)
+{
+ unsigned int i;
+
+# ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ srand(tv.tv_sec ^ tv.tv_usec);
+
+# else /* HAVE_GETTIMEOFDAY */
+# warning "This system lacks a strong enough random numbers generator!"
+
+ /*
+ * The possible values of time over one year are 31536000, which is
+ * two orders of magnitude less than the allowed entropy range (2^32).
+ */
+ srand(time(NULL) + getpid());
+
+# endif /* HAVE_GETTIMEOFDAY */
+
+ for (i = 0; i < len; i++)
+ buf[i] = valid_salts[rand() % (sizeof valid_salts - 1)];
+ buf[i] = '\0';
+}
+
+#endif /* RANDOM_DEVICE || HAVE_ARC4RANDOM_BUF || HAVE_GETENTROPY*/
+
+void NORETURN display_help(int error)
+{
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr,
+ _("Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+ "Crypts the PASSWORD using crypt(3).\n\n"));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"), "<md+whois@linux.it>");
+ exit(error);
+}
+
+void display_version(void)
+{
+ printf("mkpasswd %s\n\n", VERSION);
+ puts("Copyright (C) 2001-2021 Marco d'Itri\n"
+"This is free software; see the source for copying conditions. There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
+}
+
+void display_methods(void)
+{
+ unsigned int i;
+
+ printf(_("Available methods:\n"));
+ for (i = 0; methods[i].method != NULL; i++)
+ if (methods[i].desc)
+ printf("%-15s %s\n", methods[i].method, methods[i].desc);
+}
+
+char *read_line(FILE *fp) {
+ size_t size = 128;
+ int ch;
+ size_t pos = 0;
+ char *password;
+
+ password = NOFAIL(malloc(size));
+
+ while ((ch = fgetc(fp)) != EOF) {
+ if (ch == '\n' || ch == '\r')
+ break;
+ password[pos++] = ch;
+ if (pos == size) {
+ size += 128;
+ password = NOFAIL(realloc(password, size));
+ }
+ }
+ password[pos] = '\0';
+
+ if (ferror(fp)) {
+ free(password);
+ return NULL;
+ }
+ return password;
+}
+
diff --git a/new_gtlds_list b/new_gtlds_list
new file mode 100644
index 0000000..12ff5b8
--- /dev/null
+++ b/new_gtlds_list
@@ -0,0 +1,1153 @@
+# If a TLD is listed in this file then queries will go to whois.nic.$TLD.
+# All "new" gTLDs are mandated by the ICANN contract to provide port 43 and
+# web-based whois service on this standard domain.
+# Any exceptions can be handled in tld_serv_list as usual, since it will
+# be checked first.
+
+aaa
+aarp
+abarth
+abb
+abbott
+abbvie
+abc
+able
+abogado
+abudhabi
+academy
+accenture
+accountant
+accountants
+aco
+actor
+ads
+adult
+aeg
+aetna
+afl
+africa
+agakhan
+agency
+aig
+airbus
+airforce
+airtel
+akdn
+alfaromeo
+alibaba
+alipay
+allfinanz
+allstate
+ally
+alsace
+alstom
+amazon
+americanexpress
+americanfamily
+amex
+amfam
+amica
+amsterdam
+analytics
+android
+anquan
+anz
+aol
+apartments
+app
+apple
+aquarelle
+arab
+aramco
+archi
+army
+art
+arte
+asda
+associates
+athleta
+attorney
+auction
+audi
+audible
+audio
+auspost
+author
+auto
+autos
+avianca
+aws
+axa
+azure
+baby
+baidu
+banamex
+bananarepublic
+band
+bank
+bar
+barcelona
+barclaycard
+barclays
+barefoot
+bargains
+baseball
+basketball
+bauhaus
+bayern
+bbc
+bbt
+bbva
+bcg
+bcn
+beats
+beauty
+beer
+bentley
+berlin
+best
+bestbuy
+bet
+bharti
+bible
+bid
+bike
+bing
+bingo
+bio
+black
+blackfriday
+blockbuster
+blog
+bloomberg
+blue
+bms
+bmw
+bnpparibas
+boats
+boehringer
+bofa
+bom
+bond
+boo
+book
+booking
+bosch
+bostik
+boston
+bot
+boutique
+box
+bradesco
+bridgestone
+broadway
+broker
+brother
+brussels
+build
+builders
+business
+buy
+buzz
+bzh
+cab
+cafe
+cal
+call
+calvinklein
+cam
+camera
+camp
+canon
+capetown
+capital
+capitalone
+car
+caravan
+cards
+care
+career
+careers
+cars
+casa
+case
+cash
+casino
+catering
+catholic
+cba
+cbn
+cbre
+cbs
+center
+ceo
+cern
+cfa
+cfd
+chanel
+channel
+charity
+chase
+chat
+cheap
+chintai
+christmas
+chrome
+church
+cipriani
+circle
+cisco
+citadel
+citi
+citic
+city
+cityeats
+claims
+cleaning
+click
+clinic
+clinique
+clothing
+cloud
+club
+clubmed
+coach
+codes
+coffee
+college
+cologne
+comcast
+commbank
+community
+company
+compare
+computer
+comsec
+condos
+construction
+consulting
+contact
+contractors
+cooking
+cookingchannel
+cool
+corsica
+country
+coupon
+coupons
+courses
+cpa
+credit
+creditcard
+creditunion
+cricket
+crown
+crs
+cruise
+cruises
+cuisinella
+cymru
+cyou
+dabur
+dad
+dance
+data
+date
+dating
+datsun
+day
+dclk
+dds
+deal
+dealer
+deals
+degree
+delivery
+dell
+deloitte
+delta
+democrat
+dental
+dentist
+desi
+design
+dev
+dhl
+diamonds
+diet
+digital
+direct
+directory
+discount
+discover
+dish
+diy
+dnp
+docs
+doctor
+dog
+domains
+dot
+download
+drive
+dtv
+dubai
+dunlop
+dupont
+durban
+dvag
+dvr
+earth
+eat
+eco
+edeka
+education
+email
+emerck
+energy
+engineer
+engineering
+enterprises
+epson
+equipment
+ericsson
+erni
+esq
+estate
+etisalat
+eurovision
+eus
+events
+exchange
+expert
+exposed
+express
+extraspace
+fage
+fail
+fairwinds
+faith
+family
+fan
+fans
+farm
+farmers
+fashion
+fast
+fedex
+feedback
+ferrari
+ferrero
+fiat
+fidelity
+fido
+film
+final
+finance
+financial
+fire
+firestone
+firmdale
+fish
+fishing
+fit
+fitness
+flickr
+flights
+flir
+florist
+flowers
+fly
+foo
+food
+foodnetwork
+football
+ford
+forex
+forsale
+forum
+foundation
+fox
+free
+fresenius
+frl
+frogans
+frontdoor
+frontier
+ftr
+fujitsu
+fun
+fund
+furniture
+futbol
+fyi
+gal
+gallery
+gallo
+gallup
+game
+games
+gap
+garden
+gay
+gbiz
+gdn
+gea
+gent
+genting
+george
+ggee
+gift
+gifts
+gives
+giving
+glass
+gle
+global
+globo
+gmail
+gmbh
+gmo
+gmx
+godaddy
+gold
+goldpoint
+golf
+goo
+goodyear
+goog
+google
+gop
+got
+grainger
+graphics
+gratis
+green
+gripe
+grocery
+group
+guardian
+gucci
+guge
+guide
+guitars
+guru
+hair
+hamburg
+hangout
+haus
+hbo
+hdfc
+hdfcbank
+health
+healthcare
+help
+helsinki
+here
+hermes
+hgtv
+hiphop
+hisamitsu
+hitachi
+hiv
+hkt
+hockey
+holdings
+holiday
+homedepot
+homegoods
+homes
+homesense
+honda
+horse
+hospital
+host
+hosting
+hot
+hoteles
+hotels
+hotmail
+house
+how
+hsbc
+hughes
+hyatt
+hyundai
+ibm
+icbc
+ice
+icu
+ieee
+ifm
+ikano
+imamat
+imdb
+immo
+immobilien
+inc
+industries
+infiniti
+ing
+ink
+institute
+insurance
+insure
+international
+intuit
+investments
+ipiranga
+irish
+ismaili
+ist
+istanbul
+itau
+itv
+jaguar
+java
+jcb
+jeep
+jetzt
+jewelry
+jio
+jll
+jmp
+jnj
+joburg
+jot
+joy
+jpmorgan
+jprs
+juegos
+juniper
+kaufen
+kddi
+kerryhotels
+kerrylogistics
+kerryproperties
+kfh
+kia
+kids
+kim
+kinder
+kindle
+kitchen
+kiwi
+koeln
+komatsu
+kosher
+kpmg
+kpn
+krd
+kred
+kuokgroup
+kyoto
+lacaixa
+lamborghini
+lamer
+lancaster
+lancia
+land
+landrover
+lanxess
+lasalle
+lat
+latino
+latrobe
+law
+lawyer
+lds
+lease
+leclerc
+lefrak
+legal
+lego
+lexus
+lgbt
+lidl
+life
+lifeinsurance
+lifestyle
+lighting
+like
+lilly
+limited
+limo
+lincoln
+link
+lipsy
+live
+living
+llc
+llp
+loan
+loans
+locker
+locus
+lol
+london
+lotte
+lotto
+love
+lpl
+lplfinancial
+ltd
+ltda
+lundbeck
+luxe
+luxury
+madrid
+maif
+maison
+makeup
+man
+management
+mango
+map
+market
+marketing
+markets
+marriott
+marshalls
+maserati
+mattel
+mba
+mckinsey
+med
+media
+meet
+melbourne
+meme
+memorial
+men
+menu
+merckmsd
+miami
+microsoft
+mini
+mint
+mit
+mitsubishi
+mlb
+mls
+mma
+mobile
+moda
+moe
+moi
+mom
+monash
+money
+monster
+mormon
+mortgage
+moscow
+moto
+motorcycles
+mov
+movie
+msd
+mtn
+mtr
+music
+mutual
+nab
+nagoya
+natura
+navy
+nba
+nec
+netbank
+netflix
+network
+neustar
+new
+news
+next
+nextdirect
+nexus
+nfl
+ngo
+nhk
+nico
+nike
+nikon
+ninja
+nissan
+nissay
+nokia
+northwesternmutual
+norton
+now
+nowruz
+nowtv
+nra
+nrw
+ntt
+nyc
+obi
+observer
+office
+okinawa
+olayan
+olayangroup
+oldnavy
+ollo
+omega
+one
+ong
+onl
+online
+ooo
+open
+oracle
+orange
+organic
+origins
+osaka
+otsuka
+ott
+ovh
+page
+panasonic
+paris
+pars
+partners
+parts
+party
+passagens
+pay
+pccw
+pet
+pfizer
+pharmacy
+phd
+philips
+phone
+photo
+photography
+photos
+physio
+pics
+pictet
+pictures
+pid
+pin
+ping
+pink
+pioneer
+pizza
+place
+play
+playstation
+plumbing
+plus
+pnc
+pohl
+poker
+politie
+porn
+pramerica
+praxi
+press
+prime
+prod
+productions
+prof
+progressive
+promo
+properties
+property
+protection
+pru
+prudential
+pub
+pwc
+qpon
+quebec
+quest
+racing
+radio
+read
+realestate
+realtor
+realty
+recipes
+red
+redstone
+redumbrella
+rehab
+reise
+reisen
+reit
+reliance
+ren
+rent
+rentals
+repair
+report
+republican
+rest
+restaurant
+review
+reviews
+rexroth
+rich
+richardli
+ricoh
+ril
+rio
+rip
+rocher
+rocks
+rodeo
+rogers
+room
+rsvp
+rugby
+ruhr
+run
+rwe
+ryukyu
+saarland
+safe
+safety
+sakura
+sale
+salon
+samsclub
+samsung
+sandvik
+sandvikcoromant
+sanofi
+sap
+sarl
+sas
+save
+saxo
+sbi
+sbs
+sca
+scb
+schaeffler
+schmidt
+scholarships
+school
+schule
+schwarz
+science
+scot
+search
+seat
+secure
+security
+seek
+select
+sener
+services
+seven
+sew
+sex
+sexy
+sfr
+shangrila
+sharp
+shaw
+shell
+shia
+shiksha
+shoes
+shop
+shopping
+shouji
+show
+showtime
+silk
+sina
+singles
+site
+ski
+skin
+sky
+skype
+sling
+smart
+smile
+sncf
+soccer
+social
+softbank
+software
+sohu
+solar
+solutions
+song
+sony
+soy
+spa
+space
+sport
+spot
+srl
+stada
+staples
+star
+statebank
+statefarm
+stc
+stcgroup
+stockholm
+storage
+store
+stream
+studio
+study
+style
+sucks
+supplies
+supply
+support
+surf
+surgery
+suzuki
+swatch
+swiss
+sydney
+systems
+tab
+taipei
+talk
+taobao
+target
+tatamotors
+tatar
+tattoo
+tax
+taxi
+tci
+tdk
+team
+tech
+technology
+temasek
+tennis
+teva
+thd
+theater
+theatre
+tiaa
+tickets
+tienda
+tiffany
+tips
+tires
+tirol
+tjmaxx
+tjx
+tkmaxx
+tmall
+today
+tokyo
+tools
+top
+toray
+toshiba
+total
+tours
+town
+toyota
+toys
+trade
+trading
+training
+travelchannel
+travelers
+travelersinsurance
+trust
+trv
+tube
+tui
+tunes
+tushu
+tvs
+ubank
+ubs
+unicom
+university
+uno
+uol
+ups
+vacations
+vana
+vanguard
+vegas
+ventures
+verisign
+versicherung
+vet
+viajes
+video
+vig
+viking
+villas
+vin
+vip
+virgin
+visa
+vision
+viva
+vivo
+vlaanderen
+vodka
+volkswagen
+volvo
+vote
+voting
+voto
+voyage
+vuelos
+wales
+walmart
+walter
+wang
+wanggou
+watch
+watches
+weather
+weatherchannel
+webcam
+weber
+website
+wed
+wedding
+weibo
+weir
+whoswho
+wien
+wiki
+williamhill
+win
+windows
+wine
+winners
+wme
+wolterskluwer
+woodside
+work
+works
+world
+wow
+wtc
+wtf
+xbox
+xerox
+xfinity
+xihuan
+xin
+xn--11b4c3d
+xn--1ck2e1b
+xn--1qqw23a
+xn--30rr7y
+xn--3bst00m
+xn--3ds443g
+xn--3pxu8k
+xn--42c2d9a
+xn--45q11c
+xn--4gbrim
+xn--55qw42g
+xn--55qx5d
+xn--5su34j936bgsg
+xn--5tzm5g
+xn--6frz82g
+xn--6qq986b3xl
+xn--80adxhks
+xn--80aqecdr1a
+xn--80asehdb
+xn--80aswg
+xn--8y0a063a
+xn--9dbq2a
+xn--9et52u
+xn--9krt00a
+xn--b4w605ferd
+xn--bck1b9a5dre4c
+xn--c1avg
+xn--c2br7g
+xn--cck2b3b
+xn--cckwcxetd
+xn--cg4bki
+xn--czr694b
+xn--czrs0t
+xn--czru2d
+xn--d1acj3b
+xn--eckvdtc9d
+xn--efvy88h
+xn--fct429k
+xn--fhbei
+xn--fiq228c5hs
+xn--fiq64b
+xn--fjq720a
+xn--flw351e
+xn--fzys8d69uvgm
+xn--g2xx48c
+xn--gckr3f0f
+xn--gk3at1e
+xn--hxt814e
+xn--i1b6b1a6a2e
+xn--imr513n
+xn--io0a7i
+xn--j1aef
+xn--jlq480n2rg
+xn--jvr189m
+xn--kcrx77d1x4a
+xn--kput3i
+xn--mgba3a3ejt
+xn--mgba7c0bbn0a
+xn--mgbaakc7dvf
+xn--mgbab2bd
+xn--mgbca7dzdo
+xn--mgbi4ecexp
+xn--mgbt3dhd
+xn--mk1bu44c
+xn--mxtq1m
+xn--ngbc5azd
+xn--ngbe9e0a
+xn--ngbrx
+xn--nqv7f
+xn--nqv7fs00ema
+xn--nyqy26a
+xn--otu796d
+xn--p1acf
+xn--pssy2u
+xn--q9jyb4c
+xn--qcka1pmc
+xn--rhqv96g
+xn--rovu88b
+xn--ses554g
+xn--t60b56a
+xn--tckwe
+xn--tiq49xqyj
+xn--unup4y
+xn--vermgensberater-ctb
+xn--vermgensberatung-pwb
+xn--vhquv
+xn--vuq861b
+xn--w4r85el8fhu5dnra
+xn--w4rs40l
+xn--xhq521b
+xn--zfr164b
+xyz
+yachts
+yahoo
+yamaxun
+yandex
+yodobashi
+yoga
+yokohama
+you
+youtube
+yun
+zappos
+zara
+zero
+zip
+zone
+zuerich
diff --git a/nic_handles_list b/nic_handles_list
new file mode 100644
index 0000000..3fae1dd
--- /dev/null
+++ b/nic_handles_list
@@ -0,0 +1,23 @@
+-arin whois.arin.net
+-ripe whois.ripe.net
+-mnt whois.ripe.net
+-lacnic whois.lacnic.net
+-afrinic whois.afrinic.net
+-ap whois.apnic.net
+-cznic whois.nic.cz
+-dk whois.dk-hostmaster.dk
+-il whois.isoc.org.il
+-is whois.isnic.is
+-kg whois.kg
+-coop whois.nic.coop
+-frnic whois.nic.fr
+-lrms whois.afilias.info
+-nicat whois.nic.at
+-nicci whois.nic.ci
+-irnic whois.nic.ir
+-norid whois.norid.no
+-tel whois.nic.tel
+-adnic whois.nic.org.uy
+-sixxs whois.sixxs.net
+-uanic whois.ua
+-bzh whois.nic.bzh
diff --git a/po/Makefile b/po/Makefile
new file mode 100644
index 0000000..641fe3d
--- /dev/null
+++ b/po/Makefile
@@ -0,0 +1,57 @@
+prefix = /usr
+
+ifdef DESTDIR
+BASEDIR := $(DESTDIR)
+endif
+
+INSTALL= install
+
+INSTALLNLSDIR=$(BASEDIR)$(prefix)/share/locale
+
+PACKAGE = whois
+
+CATALOGS = cs.mo da.mo de.mo el.mo es.mo eu.mo fi.mo fr.mo it.mo ja.mo ka.mo pl.mo pt_BR.mo ru.mo tr.mo zh_CN.mo
+
+POTFILES=../whois.c ../mkpasswd.c
+
+all: $(PACKAGE).pot $(CATALOGS)
+
+$(PACKAGE).pot: $(POTFILES)
+ xgettext --default-domain=$(PACKAGE) \
+ --add-comments --keyword=_ --keyword=N_ $(POTFILES)
+ if cmp -s $(PACKAGE).po $(PACKAGE).pot; then \
+ rm -f $(PACKAGE).po; \
+ else \
+ mv $(PACKAGE).po $(PACKAGE).pot; \
+ fi
+
+update-po: $(PACKAGE).pot
+ for cat in $(CATALOGS); do \
+ lang=`echo $$cat | sed 's/.mo$$//'`; \
+ 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
+
+%.mo: %.po
+ msgfmt --statistics --check --verbose --output-file=$@ $<
+
+clean:
+ rm -f *.mo
+
+distclean: clean
+ rm -f whois.pot
+
+install: $(CATALOGS)
+ for n in $(CATALOGS); do \
+ l=`basename $$n .mo`; \
+ $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l; \
+ $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l/LC_MESSAGES; \
+ $(INSTALL) -m 644 $$n $(INSTALLNLSDIR)/$$l/LC_MESSAGES/$(PACKAGE).mo; \
+ done
+
diff --git a/po/cs.po b/po/cs.po
new file mode 100644
index 0000000..89f05fa
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,363 @@
+# Czech translation for whois
+# Petr Pisar <petr.pisar@atlas.cz>, 2008, 2009, 2010, 2012, 2013, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.4.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2019-06-28 06:05+02:00\n"
+"Last-Translator: Petr Pisar <petr.pisar@atlas.cz>\n"
+"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Verze %s.\n"
+"\n"
+"Chyby programu hlaste na %s (anglicky), chyby překladu na\n"
+"<translation-team-cs@lists.sourceforge.net> (česky).\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Tato TLD nemá žádný whoisový server, ale k whoisové databázi se lze dostat na"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Tato TLD nemá žádný whoisový server."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Pro tento druh objektu není znám žádný whoisový server."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr ""
+"Neznámé číslo AS nebo neznámá IP síť.\n"
+"Prosím, pořiďte si novou verzi tohoto programu."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Používá se server %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Dotazuji se na IPv4 konec %s příslušející 6to4 IPv6 adrese.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Dotazuji se na IPv4 konec %s příslušející Teredo IPv6 adrese.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Znění dotazu: „%s“\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Nalezen odkaz na %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Tento řádek nemohu rozebrat: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Varování: RIPE příznak použit s tradičním serverem."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Katastrofální chyba: text prohlášení byl pozměněn.\n"
+"Prosím, pořiďte si novou verzi tohoto programu.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Jméno počítače %s nenalezeno."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/TCP: neznámá služba"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Čas vypršel."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Přerušeno signálem %d…"
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Použití: whois [PŘEPÍNAČ]… OBJEKT…\n"
+"\n"
+"-h STROJ, --host STROJ připojí se na server STROJ\n"
+"-p PORT, --port PORT připojí se na PORT\n"
+"-I dotáže se whois.iana.org a následuje tamní odkazy\n"
+"-H skryje právní prohlášení\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose vysvětlí, co se právě provádí\n"
+" --help zobrazí tuto nápovědu a skončí\n"
+" --version vypíše informace o verzi a skončí\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Tyto přepínače jsou podporovány serverem whois.ripe.net a některými\n"
+"podobnými jemu:\n"
+"-l nalezne o jednu úroveň širší shodu\n"
+"-L nalezne všechny širší shody\n"
+"-m nalezne všechny nejbližší užší shody\n"
+"-M nalezne všechny užší shody\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c nalezne nejužší shodu obsahující atribut mnt-irt\n"
+"-x přesná shoda\n"
+"-b vrátí stručný rozsah IP adres s kontaktem na "
+"stížnosti\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B vypne filtrování objektů (zobrazuje e-mailové "
+"adresy)\n"
+"-G vypne seskupování přidružených objektů\n"
+"-d vrací též objekty delegace reverzního DNS\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATR[,ATR]… provede inverzní dotaz k zadaným ATRIBUTŮM\n"
+"-T TYP[,TYP]… dotáže se jen na objekty zadaného TYPU\n"
+"-K vrátí pouze primární klíče\n"
+"-r vypne rekurzivní dohledávání kontaktů\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R vynutí zobrazení místní kopie doménového objektu,\n"
+" i když obsahuje odkaz\n"
+"-a prohledá rovněž všechny zrcadlené databáze\n"
+"-s ZDROJ[,ZDROJ]… prohledá databázi zrcadlenou ze ZDROJE\n"
+"-g ZDROJ:PRVNÍ-POSLEDNÍ nalezne aktualizace ze ZDROJE se sériovým číslem\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+" PRVNÍ až POSLEDNÍ\n"
+"-t TYP požaduje šablonu pro objekt druhu TYP\n"
+"-v TYP požaduje podrobnou šablonu pro objekt druhu TYP\n"
+"-q [version|sources|types]\n"
+" dotáže se na zadané informace o serveru („version“ "
+"–\n"
+" verze, „sources“ – zdroje, „types“ – typy)\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "rozšířený BSDI crypt(3) založený na šifře DES"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "standardní crypt(3) založený na 56bitové šifře DES"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Neplatná metoda „%s“.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Neplatné číslo „%s“.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Pro podrobnosti zkuste příkaz „%s --help“.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Chybná délka soli: %d bajt, zatímco očekáváno %d.\n"
+msgstr[1] "Chybná délka soli: %d bajty, zatímco očekáváno %d.\n"
+msgstr[2] "Chybná délka soli: %d bajtů, zatímco očekáváno %d.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Chybná délka soli: %d bajt, zatímco očekáváno %d <= n <= %d.\n"
+msgstr[1] "Chybná délka soli: %d bajty, zatímco očekáváno %d <= n <= %d.\n"
+msgstr[2] "Chybná délka soli: %d bajtů, zatímco očekáváno %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Neplatný znak v soli „%c“.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Heslo: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Metoda není podporována funkcí crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Použití: mkpasswd [VOLBY]… [HESLO [SŮL]]\n"
+"Zašifruje HESLO pomocí funkce crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=DRUH vybere DRUH metody\n"
+" -5 stejné jako --method=md5crypt\n"
+" -S, --salt=SŮL použije zadanou SŮL\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=POČET použije zadaný POČET kol\n"
+" -P, --password-fd=Č přečte heslo z deskriptoru souboru Č\n"
+" místo z /dev/tty\n"
+" -s, --stdin jako --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help zobrazí tuto nápovědu a skončí\n"
+" -V, --version vypíše informace o verzi a skončí\n"
+"\n"
+"Chybí-li HESLO, bude o něj požádáno interaktivně.\n"
+"Nebude-li zadána SŮL, vygeneruje se náhodná.\n"
+"Bude-li DRUH „help“, vypíšou se dostupné metody.\n"
+"\n"
+"Chyby programu hlaste na %s (anglicky), chyby překladu na\n"
+"<translation-team-cs@lists.sourceforge.net> (česky).\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Dostupné metody:\n"
diff --git a/po/da.po b/po/da.po
new file mode 100644
index 0000000..0a7fe6b
--- /dev/null
+++ b/po/da.po
@@ -0,0 +1,357 @@
+# Translation of whois to Danish.
+# Copyright (C) 2001 Simon Richter <Simon.Richter@in.tum.de>, 2004 Adrian
+# Bunk <bunk@fs.tum.de>, 2010 Chris Leick <c.leick@vollbio.de>.
+# This file is distributed under the same license as the whois package.
+# Joe Hansen <joedalton2@yahoo.dk>, 2011, 2013, 2020.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.5.6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2020-03-08 17:30+01:00\n"
+"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
+"Language-Team: Danish <debian-l10n-danish@lists.debian.org>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Version %s.\n"
+"\n"
+"Rapporter fejl til %s (på engelsk).\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr "Denne TLD har ingen whois-server, men du kan tilgå whois-databasen på"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Denne TLD har ingen whois-server."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Ingen whois-server er kendt for denne type af objekt."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Ukendt AS- eller IP-netværksnummer. Opgrader venligst dette program."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Bruger server %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Forespørger efter IPv4-slutpunktet %s for en 6to4 IPv6-adresse.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Forespørger efter IPv4-slutpunktet %s for en Teredo IPv6-adresse.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Forespørgelsesstreng: »%s«\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Fandt en henvisning til %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Kan ikke fortolke denne linje: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Advarsel: RIPE-flag brugt med en traditionel server."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Katastrofal fejl: Teksten for ansvarsfraskrivelse er blevet ændret.\n"
+"Opgrader venligst dette program.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Vært %s er ikke fundet."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: Ukendt tjeneste"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Tidsudløb."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Afbrudt af signal %d ..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Brug: whois [TILVALG]... OBJEKT...\n"
+"\n"
+"-h VÆRT, --host VÆRT forbind til server-VÆRT\n"
+"-p PORT, --port PORT forbind til PORT\n"
+"-I forespørg whois.iana.org og følg henvisningen\n"
+"-H skjul juridisk ansvarsfraskrivelse\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose forklar hvad der sker\n"
+" --help vis denne hjælpetekst og afslut\n"
+" --version vis versionsinformation og afslut\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Disse flag er understøttet af whois.ripe.net og nogle RIPE-lignende "
+"servere:\n"
+"-l et niveau mindre specifik opslag\n"
+"-L find alle mindre specifikke resultater\n"
+"-m find første niveau mere specifikke resultater\n"
+"-M find alle mere specifikke resultater\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c find det mindste resultat der indeholder attributten\n"
+" mnt-irt\n"
+"-x præcis match\n"
+"-b returner korte IP-adresseintervaller med "
+"misbrugskontakt\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B sluk for objektfiltrering (vis e-post-adresser)\n"
+"-G sluk for gruppering af associerede objekter\n"
+"-d returner også DNS-omvendte delegationsobjekter\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... foretag et omvendt opslag for angivne ATTRibutter\n"
+"-T TYPE[,TYPE]... kig kun efter objekter i form af TYPE\n"
+"-K kun primære nøgler returneres\n"
+"-r deaktiver omvendte opslag for kontaktinformation\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R fremtving visning af lokal kopi af domæneobjektet "
+"selv\n"
+" hvis det indeholder henvisning\n"
+"-a søg i alle databaser\n"
+"-s KILDE[,KILDE]... søg databasen fra KILDE\n"
+"-g KILDE:FØRST-SIDST find opdateringer fra KILDE fra seriel FØRST til "
+"SIDST\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE anmod om skabelon for objekttypen TYPE\n"
+"-v TYPE anmod om uddybende skabelon for objekttypen TYPE\n"
+"-q [version|kilder|typer] forespørg angivet serverinfo\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDI-udvidet DES-baseret Crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "standard 56-bit DES-baseret Crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Ugyldig metode »%s«\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Ugyldigt tal »%s«.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Prøv »%s --help« for yderligere information.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Forkert salt-længde: %d byte men %d var forventet.\n"
+msgstr[1] "Forkert salt-længde: %d byte men %d var forventet.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Forkert salt-længde: %d byte men %d <= n <= %d var forventet.\n"
+msgstr[1] "Forkert salt-længde: %d byte men %d <= n <= %d var forventet.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Ugyldigt salt-tegn »%c«.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Adgangskode: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Metoden er ikke understøttet af crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Brug: mkpasswd [TILVALG] ... [ADGANGSKODE] [SALT]]\n"
+"Krypterer ADGANGSKODEN med crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYPE vælg metoden TYPE\n"
+" -5 som --method=md5crypt\n"
+" -S, --salt=SALT brug den angivne SALT\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=ANTAL brug det angivne ANTAL af runder\n"
+" -P, --password-fd=NUM læs adgangskoden fra filbeskriveren NUM\n"
+" i steden for /dev/tty\n"
+" -s, --stdin som --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help vis denne hjælpetekst og afslut\n"
+" -V, --version vis versionsinformation og afslut\n"
+"\n"
+"Hvis ADGANGSKODE mangler, så spørges der efter den interaktivt.\n"
+"Hvis ingen SALT er angivet, så oprettes en vilkårlig.\n"
+"Hvis TYPE er »help«, så udskrives tilgængelige metoder.\n"
+"\n"
+"Rapporter fejl til %s (på engelsk).\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Tilgængelige metoder:\n"
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..898e443
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,375 @@
+# Translation of whois to German
+# Copyright (C) 2001 Simon Richter <Simon.Richter@in.tum.de>
+# Copyright (C) 2004 Adrian Bunk <bunk@fs.tum.de>
+# Copyright (C) 2010, 2013, 2019 Chris Leick <c.leick@vollbio.de>
+# Copyright (C) 2021 Helge Kreutzmann <debian@helgefjell.de>
+#
+# This file is distributed under the same license as the whois package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.5.11\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2022-01-12 12:11+0100\n"
+"Last-Translator: Helge Kreutzmann <debian@helgefjell.de>\n"
+"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Version %s.\n"
+"\n"
+"Berichten Sie Fehler auf Englisch an %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Diese TLD hat keinen Whois-Server, kann aber auf eine Whois-Datenbank "
+"zugreifen unter"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Diese TLD hat keinen Whois-Server."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Für diese Art von Objekten ist kein Whois-Server bekannt."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr ""
+"Unbekannte AS-Nummer oder unbekanntes IP-Netzwerk. Bitte führen Sie ein "
+"Upgrade dieses Programms durch."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Server %s wird benutzt.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Abfrage des IPv4-Endpunkts %s einer 6to4-IPv6-Adresse.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Abfrage des IPv4-Endpunkts %s einer Teredo-IPv6-Adresse.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Abfragezeichenkette: »%s«\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Verweis auf %s gefunden.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Diese Zeile kann nicht ausgewertet werden: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr ""
+"Warnung: RIPE-Flags wurden mit einem »traditionellen« Server verwendet."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Katastrophaler Fehler: Haftungsausschlusstext wurde geändert.\n"
+"Bitte führen Sie ein Upgrade dieses Programms durch.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Host %s nicht gefunden."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: unbekannter Dienst"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Zeitüberschreitung"
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Durch Signal %d unterbrochen …"
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Aufruf: whois [OPTION] … OBJEKT …\n"
+"\n"
+"-h HOST, --host HOST verbindet sich mit Server HOST.\n"
+"-p PORT, --port PORT verbindet sich mit PORT.\n"
+"-I fragt whois.iana.org ab und folgt dessen Verweis.\n"
+"-H versteckt Haftungsausschlussklauseln.\n"
+
+#: ../whois.c:1506
+#, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose erklärt, was getan wird.\n"
+" --no-recursion deaktiviert Rekursion vom Register zu Registrar-Servern\n"
+" --help zeigt diese Hilfe und beendet sich.\n"
+" --version gibt Versionsinformationen aus und beendet sich.\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Diese Schalter werden von whois.ripe.net und einigen RIPE ähnlichen Servern\n"
+"unterstützt:\n"
+"-l sucht den um eine Stufe weniger spezifischen "
+"Treffer.\n"
+"-L sucht alle Stufen weniger spezifischer Treffer.\n"
+"-m sucht alle um eine Stufe spezifischeren Treffer.\n"
+"-M sucht alle Stufen der spezifischeren Treffer.\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c sucht die kleinste Übereinstimmung eines\n"
+" »mnt-irt«-Attributs.\n"
+"-x exakte Übereinstimmung\n"
+"-b gibt einen kurzen IP-Adressbereich mit "
+"Beschwerdekontakt\n"
+" zurück.\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B schaltet die Objektfilterung aus (zeigt E-Mail-"
+"Adressen)\n"
+"-G schaltet die Gruppierung verbundener Objekte aus.\n"
+"-d gibt auch DNS-Reverse-Delegation-Objekte zurück.\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR] … schlägt angegebene ATTRibute in umgekehrter Richtung\n"
+" nach.\n"
+"-T TYP[,TYP] … beachtet nur Objekte dieses TYPs.\n"
+"-K gibt nur Primärschlüssel zurück.\n"
+"-r schaltet das rekursive Nachschlagen von\n"
+" Kontaktinformationen aus.\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R erzwingt die Anzeige einer lokalen Kopie des\n"
+" Domain-Objekts, selbst wenn es einen Verweis "
+"enthält.\n"
+"-a durchsucht auch die gespiegelten Datenbanken.\n"
+"-s QUELLE[,QUELLE] … durchsucht die von QUELLE gespiegelte Datenbank.\n"
+"-g QUELLE:ANFANG-ENDE sucht Aktualisierungen der QUELLE aufeinanderfolgend "
+"von\n"
+" ANFANG bis ENDE\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYP fragt die Schablone des Objekts des TYPs ab.\n"
+"-v TYP fragt die Schablone des Objekts des TYPs ausführlich "
+"ab.\n"
+"-q [version|sources|types] fragt die angegebene Server-Information ab.\n"
+
+# https://en.wikipedia.org/wiki/Crypt_%28C%29#BSDi_extended_DES-based_scheme
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDi-erweitertes DES-basiertes Crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "Standard-56-Bit-DES-basiertes Crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Ungültige Methode »%s«\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Falsche Nummer »%s«.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Versuchen Sie »%s --help«, um weitere Informationen zu erhalten.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Falsche Salt-Länge: %d Byte, aber %d wurden erwartet.\n"
+msgstr[1] "Falsche Salt-Länge: %d Byte, aber %d wurden erwartet.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Falsche Salt-Länge: %d Byte, aber %d <= n <= %d wurden erwartet.\n"
+msgstr[1] "Falsche Salt-Länge: %d Byte, aber %d <= n <= %d wurden erwartet.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Illegales Salt-Zeichen »%c«.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Passwort: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Methode nicht von »crypt(3)« unterstützt.\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Aufruf: mkpasswd [OPTIONEN]... [PASSWORT] [SALT]]\n"
+"Verschlüsselt das PASSWORT mit »crypt(3)«.\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYP wählt die Methode TYP aus.\n"
+" -5 wie --method=md5crypt\n"
+" -S, --salt=SALT benutzt angegebenes SALT.\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=ANZAHL benutzt angegebene ANZAHL von Runden.\n"
+" -P, --password-fd=NUM liest das Passwort vom Dateideskriptor NUM "
+"anstatt\n"
+" von /dev/tty\n"
+" -s, --stdin wie --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help zeigt diese Hilfe an und beendet sich.\n"
+" -V, --version zeigt Versionsinformationen an und beendet "
+"sich.\n"
+"\n"
+"Falls das PASSWORT fehlt, wird es interaktiv erfragt.\n"
+"Falls SALT nicht angegeben wurde, wird ein zufälliges erzeugt.\n"
+"Wenn der TYP »help« ist, werden die verfügbaren Methoden ausgegeben.\n"
+"\n"
+"Berichten Sie Fehler auf Englisch an %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Verfügbare Methoden:\n"
diff --git a/po/el.po b/po/el.po
new file mode 100644
index 0000000..3a8c1d8
--- /dev/null
+++ b/po/el.po
@@ -0,0 +1,367 @@
+# Greek translation of the whois 4.6.9 command.
+# Copyright (C) 1999-2003 Simos Xenitellis, Velonis Petros
+# Simos Xenitellis <simos@hellug.gr>
+# Velonis Petros <velonis@freemail.gr>
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 4.6.9\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2003-12-10 08:51+0200\n"
+"Last-Translator: Velonis Petros\n"
+"Language-Team: \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Έκδοση %s.\n"
+"\n"
+"Αναφέρατε σφάλματα στο %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Αυτό το TLD δεν έχει εξυπηρετητή whois, ωστόσο μπορείτε να προσπελάσετε την "
+"βάση whois στο"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Αυτό το TLD δεν έχει εξυπηρετητή whois."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr ""
+"Κανένας εξυπηρετητής whois δεν είναι γνωστός για αυτού του είδους το "
+"αντικείμενο."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr ""
+"Άγνωστος αριθμός AS ή IP δικτύου. Παρακαλώ αναβαθμίστε αυτό το πρόγραμμα."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Γίνεται χρήση του εξυπηρετητή %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Άντληση πληροφοριών για το σημείο τέλους IPv4 %s μιας διεύθυνσης 6to4 IPv6.\n"
+"\n"
+
+#: ../whois.c:369
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Άντληση πληροφοριών για το σημείο τέλους IPv4 %s μιας διεύθυνσης 6to4 IPv6.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Αλφαριθμητικό ερώτησης: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Βρέθηκε αναφορά στο %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Αδύνατη η ανάλυση αυτής της γραμμής: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr ""
+"Προειδοποίηση: Η σημαίες του RIPE χρησιμοποιούνται σε έναν παραδοσιακό "
+"εξυπηρετητή."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Καταστροφικό σφάλμα: το κείμενο της αποποίησης ευθυνών έχει τροποποιηθεί.\n"
+"Παρακαλώ αναβαθμίστε το πρόγραμμα.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Το σύστημα %s δε βρέθηκε."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: άγνωστη υπηρεσία"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Διάλειμμα."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Διακοπή από το σήμα %d..."
+
+#: ../whois.c:1499
+#, fuzzy, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Χρήση: whois [ΕΠΙΛΟΓΕΣ]... ΑΝΤΙΚΕΙΜΕΝΟ...\n"
+"\n"
+"-h ΣΥΣΤΗΜΑ σύνδεση στον εξυπηρετητή ΣΎΣΤΗΜΑ\n"
+"-p ΘΥΡΑ σύνδεση στη ΘΥΡΑ\n"
+"-H απόκρυψη του νομικού εγγράφου αποποίησης ευθύνης\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose εξήγηση του τί συμβαίνει\n"
+" --help εμφάνιση αυτής της βοήθειας και έξοδος\n"
+" --version εμφάνιση της έκδοσης και έξοδος\n"
+
+#: ../whois.c:1513
+#, fuzzy, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"-l ένα επίπεδο λιγότερο συγκεκριμένη αναζήτηση [μόνο "
+"RPSL]\n"
+"-L εύρεση όλων των Λιγότερο συγκεκριμένων ταιριασμάτων\n"
+"-m εύρεση όλων των πρώτου επιπέδου περισσότερο "
+"συγκεκριμένων ταιριασμάτων\n"
+"-M εύρεση όλων των Περισσότερο συγκεκριμένων "
+"ταιριασμάτων\n"
+
+#: ../whois.c:1520
+#, fuzzy, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c εύρεση του μικρότερου ταιριάσματος που να περιέχει "
+"μια ένα χαρακτηριστικό mnt-irt \n"
+"-x ακριβές ταίριασμα\n"
+
+#: ../whois.c:1525
+#, fuzzy, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-d επιστροφή και των αντίστροφων αντικειμένων DNS [μόνο "
+"RPSL]\n"
+
+#: ../whois.c:1530
+#, fuzzy, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ΧΑΡΑΚ[,ΧΑΡΑΚ]... να γίνει μια αντίστροφη αναζήτηση για τα καθορισμένα "
+"ΧΑΡΑΚτηριστικά\n"
+"-T ΕΙΔΟΣ[,ΕΊΔΟΣ]... αναζήτηση μόνο αντικειμένου του ΕΙΔΟΥΣ\n"
+"-K επιστροφή μόνο των πρωταρχικών κλειδιών [μόνο RPSL]\n"
+"-r απενεργοποίηση των αναδρομικών αναζητήσεων για "
+"πληροφορίες επικοινωνίας\n"
+
+#: ../whois.c:1536
+#, fuzzy, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R επιβολή εμφάνισης τοπικού αντιγράφου του αντικειμένου "
+"επιθήματος ακόμα και αν περιέχει αναφορές\n"
+"-a αναζήτηση σε όλες τις βάσεις δεδομένων\n"
+"-s ΠΗΓΗ[,ΠΗΓΉ]... αναζήτηση της βάσης δεδομένων από την ΠΗΓΗ\n"
+"-g ΠΗΓΗ:ΠΡΩΤΟ:ΤΕΛΕΥΤΑΙΟ εμφάνιση αναβαθμίσεων από την ΠΗΓΗ από το σειριακό "
+"ΠΡΏΤΟ ως ΤΕΛΕΥΤΑΙΟ\n"
+
+#: ../whois.c:1543
+#, fuzzy, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t ΕΙΔΟΣ αναζήτηση προτύπου για το αντικείμενο του ΕΊΔΟΥΣ "
+"('all' για εμφάνιση λίστας)\n"
+"-v ΕΙΔΟΣ αναζήτηση περιφραστικού προτύπου για το αντικείμενο "
+"του ΕΙΔΟΥΣ\n"
+"-q [έκδοση|πηγές|τύποι] συγκεκριμένο ερώτημα πληροφοριών εξυπηρετητή [μόνο "
+"RPSL]\n"
+
+#: ../mkpasswd.c:135
+#, fuzzy
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "\tκαθεριερωμένη 56 bit με βάση το DES crypt(3)"
+
+#: ../mkpasswd.c:138
+#, fuzzy
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "\tκαθεριερωμένη 56 bit με βάση το DES crypt(3)"
+
+#: ../mkpasswd.c:207
+#, fuzzy, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Μη αποδεκτό νούμερο '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Μη αποδεκτό νούμερο '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Προσπάθησε '%s --help' για περισσότερες πληροφορίες.\n"
+
+#: ../mkpasswd.c:292
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Εσφαλμένο μήκος salt : %d byte(s) όταν αναμένεται %d .\n"
+msgstr[1] "Εσφαλμένο μήκος salt : %d byte(s) όταν αναμένεται %d .\n"
+
+#: ../mkpasswd.c:297
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Εσφαλμένο μήκος salt : %d byte(s) όταν αναμένεται %d .\n"
+msgstr[1] "Εσφαλμένο μήκος salt : %d byte(s) όταν αναμένεται %d .\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Μη αποδεκτός χαρακτήρας salt '%c'.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Συνθηματικό: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr ""
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Χρήση: mkpasswd [ΕΠΙΛΟΓΕΣ]... [ΣΥΝΘΗΜΑΤΙΚΟ [SALT]]\n"
+"Κρυπτογραφεί το ΣΥΝΘΗΜΑΤΙΚΟ χρησιμοποιώντας το crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, fuzzy, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr " -S, --salt=SALT χρήση του συγκεκριμένου SALT\n"
+
+#: ../mkpasswd.c:505
+#, fuzzy, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -P, --password-fd=NUM ανάγνωση του συνθηματικού από αρχείο περιγραφής "
+"NUM\n"
+" αντί από το /dev/tty\n"
+" -s, --stdin σαν το --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, fuzzy, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help εμφάνιση αυτής της βοήθειας και έξοδος\n"
+" -V, --version εμφάνιση πληροφοριών έκδοσης και έξοδος\n"
+"\n"
+"Αν λείπει το ΣΥΝΘΗΜΑΤΙΚΟ τότε γίνεται αλληλεπιδραστική ερώτηση.\n"
+"Αν κανένα SALT δεν έχει προσδιοριστεί, τότε δημιουργείται ένα τυχαίο.\n"
+"Αν λείπει ο ΤΥΠΟΣ τότε τυπώνονται διαθέσιμοι αλγόριθμοι.\n"
+"\n"
+"Αναφέρατε σφάλματα στο %s.\n"
+
+#: ../mkpasswd.c:534
+#, fuzzy, c-format
+msgid "Available methods:\n"
+msgstr "Διαθέσιμοι αλγόριθμοι:\n"
+
+#~ msgid "Illegal password character '0x%hhx'.\n"
+#~ msgstr "Μη αποδεκτός χαρακτήρας συνθηματικού '0x%hhx'.\n"
+
+#~ msgid "Invalid hash type '%s'.\n"
+#~ msgstr "Άκυρος τύπος hash '%s'.\n"
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..24d15ee
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,387 @@
+# whois po-debconf translation to Spanish
+# Copyright (C) 2001, 2010 Software in the Public Interest
+# This file is distributed under the same license as the whois whois.
+#
+# Changes:
+# - Initial translation
+# Francisco Monteagudo <francisco@monteagudo.net>, 2001
+#
+# - Updates
+# Francisco Javier Cuadrado <fcocuadrado@gmail.com>, 2010
+# Matías A. Bellone <matiasbellone+debian@gmail.com>, 2014, 2019
+#
+# Traductores, si no conocen el formato PO, merece la pena leer la
+# documentación de gettext, especialmente las secciones dedicadas a este
+# formato, por ejemplo ejecutando:
+# info -n '(gettext)PO Files'
+# info -n '(gettext)Header Entry'
+#
+# Equipo de traducción al español, por favor lean antes de traducir
+# los siguientes documentos:
+#
+# - El proyecto de traducción de Debian al español
+# http://www.debian.org/intl/spanish/
+# especialmente las notas y normas de traducción en
+# http://www.debian.org/intl/spanish/notas
+#
+# - La guía de traducción de po's de debconf:
+# /usr/share/doc/po-debconf/README-trans
+# o http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2019-07-02 02:30-0300\n"
+"Last-Translator: Matías A. Bellone <matiasbellone+debian@gmail.com>\n"
+"Language-Team: Debian l10n Spanish <debian-l10n-spanish@lists.debian.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Versión %s.\n"
+"\n"
+"Informar de fallos a %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Este TLD no dispone de servidor whois, pero puede acceder a la base de datos "
+"de whois en"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Este TLD no dispone de servidor whois."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "No se conoce ningún servidor de whois para esta clase de objeto."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Numero AS o red IP desconocida. Por favor, actualice este programa."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Usando el servidor %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Consultando el punto final IPv4 de %s de una dirección IPv6 6a4.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Consultando el punto final IPv4 de %s de una dirección IPv6 Teredo.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Cadena de la consulta: «%s»\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Se ha encontrado una referencia a %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "No se pudo procesar esta línea: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Atención: Se han usado opciones de RIPE con un servidor tradicional."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Error catastrófico: el texto de las condiciones de uso ha sido cambiado.\n"
+"Por favor, actualice este programa.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "No se ha encontrado el servidor %s."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: servicio desconocido"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Se ha agotado el tiempo de espera."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Interrumpido por la señal %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Utilización: whois [OPCION]... OBJETO...\n"
+"\n"
+"-h EQUIPO, --host EQUIPO conectar con el servidor EQUIPO\n"
+"-p PUERTO, --port PUERTO conectar al PUERTO\n"
+"-I consultar whois.iana.org y seguir su redirección\n"
+"-H no mostrar avisos legales\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose mostrar lo que está haciendo\n"
+" --help mostrar este mensaje de ayuda y finalizar\n"
+" --version mostrar información de la versión y finalizar\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Estas opciones son compatibles con whois.ripe.net y algunos servidores\n"
+"similares a RIPE:\n"
+"-l buscar la coincidencia un nivel menos específica\n"
+"-L buscar coincidencias de niveles menos específicos\n"
+"-m buscar coincidencias del primer nivel más específico\n"
+"-M buscar coincidencias de niveles más específicos\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c buscar la coincidencia más pequeña que contenga\n"
+" un atributo «mnt-irt»\n"
+"-x coincidencia exacta\n"
+"-b mostrar rangos IP breves y contacto en caso de abuso\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B no filtrar objetos (mostrar direcciones de correo)\n"
+"-G no agrupar objetos asociados\n"
+"-d mostrar objetos de delegación de DNS reverso también\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATRIB[,ATRIB]... búsqueda inversa del ATRIButo indicado\n"
+"-T TIPO[,TIPO]... sólo buscar objetos del TIPO indicado\n"
+"-K mostrar sólo claves primarias\n"
+"-r no buscar información de contacto de forma recursiva\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R mostrar la copia local del objeto del dominio "
+"incluso\n"
+" si contiene una referencia\n"
+"-a buscar también en todas las réplicas de base de "
+"datos\n"
+"-s ORIGEN[,ORIGEN]... buscar en la base de datos replicada desde ORIGEN\n"
+"-g ORIGEN:PRIMERO-ÚLTIMO buscar actualizaciones desde ORIGEN en la serie\n"
+" PRIMERO a ÚLTIMO\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TIPO solicitar plantilla para el objeto del TIPO indicado\n"
+"-v TIPO solicitar plantilla detallada para el objeto del "
+"TIPO\n"
+" indicado\n"
+"-q [versión|orígenes|tipos] consultar información con el servidor indicado\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "crypt(3) extendido BSDI basado en DES"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "crypt(3) estándar basado en DES de 56 bits"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Método «%s» inválido.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "El número «%s» no es válido.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Pruebe «%s --help» para más información.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Longitud de sal («salt») incorrecta: %d byte en lugar de %d.\n"
+msgstr[1] "Longitud de sal («salt») incorrecta: %d bytes en lugar de %d.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] ""
+"Longitud del «salt» incorrecta: %d byte cuando se esperaba %d <= n <= %d.\n"
+msgstr[1] ""
+"Longitud del «salt» incorrecta: %d bytes cuando se esperaba %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "El carácter «%c» no es válido en el «salt».\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Contraseña: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "crypt(3) no admite este método.\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Uso: mkpasswd [OPCIONES]... [CONTRASEÑA [SALT]]\n"
+"Cifra la CONTRASEÑA utilizando crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TIPO selecciona el TIPO de método\n"
+" -5 igual que --method=md5crypt\n"
+" -S, --salt=SALT usa el SALT indicado\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=NÚMERO usa el NÚMERO indicado de rondas\n"
+" -P, --password-fd=NUM lee la contraseña del descriptor de archivo NUM\n"
+" en lugar de «/dev/tty»\n"
+" -s, --stdin igual que --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help muestra este mensaje de ayuda y finaliza\n"
+" -V, --version muestra la información de la versión y finaliza\n"
+"\n"
+"Si no se indica la CONTRASEÑA, se pedirá una de forma interactiva.\n"
+"Si no se indica el SALT, se generará uno de forma aleatoria.\n"
+"Si el TIPO es «help», se mostrarán los métodos disponibles.\n"
+"\n"
+"Informar de fallos a %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Métodos disponibles:\n"
diff --git a/po/eu.po b/po/eu.po
new file mode 100644
index 0000000..6c462b7
--- /dev/null
+++ b/po/eu.po
@@ -0,0 +1,384 @@
+# translation of whois to Euskara
+# Aitor Ibaez <aitiba@gmail.com>,2007
+# Copyright (C) 2009 Marco d'Itri
+# This file is distributed under the same license as the whois package.
+# Aitor Ibaez <aitiba@gmail.com>, 2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 4.5.29\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2002-08-24 16:22+0200\n"
+"Last-Translator: Aitor Ibaez <aitiba@gmail.com>\n"
+"Language-Team: \n"
+"Language: eu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"%s bertsioa.\n"
+"\n"
+"Bug berri baten jakinarazpena: %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"TLD honek ez du whois zerbitzaririk, baina whois databasera sarbidea "
+"daukazu..."
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "TLD honek ez du whois zerbitzaririk."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Objetu mota horrentzako, ez da whois zerbitzaririk ezagutzen."
+
+#: ../whois.c:340
+#, fuzzy
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "AS zenbaki edo IP sarea ezezaguna. Mesedez, programa eguneratu."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "%s zerbitzaria erabiltzen.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Kontsula 6to4 IPv6 helbidean dagoen %s IPv4 endpoint-entzat.\n"
+"\n"
+
+#: ../whois.c:369
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Kontsula 6to4 IPv6 helbidean dagoen %s IPv4 endpoint-entzat.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Kontsulta: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, fuzzy, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"$s-ra erreferentzia aurkituta.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Lerro hau, %s , ezin da prozesatu."
+
+#: ../whois.c:650
+#, fuzzy
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Oharra: RIPE flags-ak ohiko zerbitzariengatik ezikusiak izaten dira."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Hondamen arriskua: erabilpen balditzen textua aldatu egin da.\n"
+"Programa eguneratu.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "%s Host-a ez da aurkitu."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: zerbitzu ezezaguna"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Denbora muga."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "%d seinalearengatik etena..."
+
+#: ../whois.c:1499
+#, fuzzy, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Erabilpena: whois [AUKERAK]... OBJETUA...\n"
+"\n"
+"-h HOST HOST zerbitzarira konektatzen da\n"
+"-p PORTUA PORTUA konektatzen du\n"
+"-H abisu-legala ezkutatzen du\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose egiten ari dena bakarrik, eraskusten du\n"
+" --help laguntza pantaila hau erakusten du eta amaitzen du\n"
+" --version programaren bertsioa erakusten du eta amaitzen du\n"
+
+#: ../whois.c:1513
+#, fuzzy, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"-l adierazitako [RPSL] bilaketarentzat, maila bat jeisten "
+"du\n"
+"-L mapeketa gutxien espezifikoenak bilatzen ditu\n"
+"-M mapeketa espezifikoenak bilatzen ditu\n"
+"-m lehen maila espezifikoena bilatzen du\n"
+
+#: ../whois.c:1520
+#, fuzzy, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr "-x bilaketa zehatza\n"
+
+#: ../whois.c:1525
+#, fuzzy, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr "-d alderantizko DNSaren ordezkaritza itzultzen du\n"
+
+#: ../whois.c:1530
+#, fuzzy, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... adierazitako ATTRibute-arentzat alderantzizko bilaketa "
+"egin du\n"
+"-T TIPO[,TIPO]... TIPO objektu motak bakarrik bilatzen ditu\n"
+"-K oinarrizko-gakoak bakarrik\n"
+"-r alderantzizko bilaketa ezgaitzen du\n"
+
+#: ../whois.c:1536
+#, fuzzy, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R Objektu zehatzaren kopia lokala eraskuten du,\n"
+" erreferentzia bat eduki ere\n"
+"-a data base guztietan bilatzen du\n"
+"-s SOURCE[,SOURCE]... SOURCE data basea bilatzen du\n"
+"-g SOURCE:HASIERA-BUKAERA H eta B tarteko serietan,SOURCE-ren agerraldiak "
+"bilatzen ditu\n"
+
+#: ../whois.c:1543
+#, fuzzy, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TIPO TIPO objektu mota batentzako, txantiloiak "
+"lortzen ditu ('all' lista batentzako)\n"
+"-v TIPO TIPO objektu baten txantiloi zehatza lortzen du\n"
+"-q [bertsioa|sources] zerbitzariaren informazioa kontsultatzen du\n"
+
+#: ../mkpasswd.c:135
+#, fuzzy
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "56 bits-etako DESan oinarritutako \tcrypt(3)-a"
+
+#: ../mkpasswd.c:138
+#, fuzzy
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "56 bits-etako DESan oinarritutako \tcrypt(3)-a"
+
+#: ../mkpasswd.c:207
+#, fuzzy, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "'%s' zenbakia ez da baliozkoa.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "'%s' zenbakia ez da baliozkoa.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "%s --help informazio gehiagorako.\n"
+
+#: ../mkpasswd.c:292
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Hazi tamain desegokia:%d byte %d-en ordez.\n"
+msgstr[1] "Hazi tamain desegokia:%d byte %d-en ordez.\n"
+
+#: ../mkpasswd.c:297
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Hazi tamain desegokia:%d byte %d-en ordez.\n"
+msgstr[1] "Hazi tamain desegokia:%d byte %d-en ordez.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "'%c' karakterea, hazian, ilegala da.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Pasahitza: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr ""
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Erabilpena: mkpasswd [AUKERAK]... [PASAHITZA [HAZIA]]\n"
+"PASAHITZA crypt(3) erabiliz enkriptatu.\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, fuzzy, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -H, --hash=MOTA Hash MOTA funtzioa aukeratu\n"
+" -S, --salt=HAZI HAZI egokia erabili\n"
+
+#: ../mkpasswd.c:505
+#, fuzzy, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -P, --password-fd=NUM /dev/tty-ak irakurri ordez, NUM deskriptore-"
+"gakoa irakurtzen du\n"
+" -s, --stdin /dev/tty-ak irakurri ordez, stdin-gakoa "
+"irakurtzen du\n"
+
+#: ../mkpasswd.c:511
+#, fuzzy, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help laguntza pantaila erakusten du\n"
+" -v, --version programaren bertsioa erakusten du\n"
+"\n"
+"GAKOA zehazten ez bada, modu interaktiboan eskatuko da.\n"
+"HAZIa zehazten ez bada, aleatorioki bat sortuko da.\n"
+"MOTA zehazten ez bada, erabilgarri dauden algoritmoak inprimituko dira.\n"
+"\n"
+"Bug berri baten jakinarazpena: %s.\n"
+
+#: ../mkpasswd.c:534
+#, fuzzy, c-format
+msgid "Available methods:\n"
+msgstr "Algoritmo erabilgarriak:\n"
+
+#~ msgid "Illegal password character '0x%hhx'.\n"
+#~ msgstr "'0x%hhx' password karakterea ilegala da.\n"
+
+#~ msgid "Invalid hash type '%s'.\n"
+#~ msgstr "'%s' hash funtzioa ez da baliozkoa.\n"
+
+#~ msgid "Using default server %s.\n"
+#~ msgstr "Aurredefinitutako %s zerbitzaria erabiltzen.\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "\n"
+#~ "Found referral to %s.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "crsnic-en %s-ri, erreferentzi bat aurkitu zaio.\n"
+#~ "\n"
+
+#~ msgid "Detected referral to %s on %s.\n"
+#~ msgstr "%s-en %s-ri erreferentzia detektatua.\n"
+
+#~ msgid ""
+#~ "I don't know where this IP has been delegated.\n"
+#~ "I'll try ARIN and hope for the best..."
+#~ msgstr ""
+#~ "Ez dakit zeineri delegatua izan zaion IP helbidea hori.\n"
+#~ "ARIN-ekin porbatuko dut, zorte gehiagoren bila..."
+
+#~ msgid "I guess it's a netblock name but I don't know where to look it up."
+#~ msgstr "netblock-en izen bat dirudi, baina ez dakit, non bilatu dezakedan."
+
+#~ msgid "I guess it's a domain but I don't know where to look it up."
+#~ msgstr "Domeinu izen bat dirudi, baina ez dakit, non bilatu dezakedan."
diff --git a/po/fi.po b/po/fi.po
new file mode 100644
index 0000000..d543c65
--- /dev/null
+++ b/po/fi.po
@@ -0,0 +1,360 @@
+# Finnish translation for whois.
+# Copyright (C) 2008- Sami Kerola <kerolasa@iki.fi>
+# Copyright (C) 2022 Lauri Nurmi <lanurmi@iki.fi>
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.5.14\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-10-29 11:48+0300\n"
+"PO-Revision-Date: 2022-10-30 00:27+0300\n"
+"Last-Translator: Lauri Nurmi <lanurmi@iki.fi>\n"
+"Language-Team: \n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 3.2\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Versio %s.\n"
+"\n"
+"Lähetä bugiraportit osoitteeseen %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Tällä TLD:llä ei ole whois-palvelinta, mutta voit käyttää whois-tietokantaa "
+"osoitteessa"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Tällä TLD:llä ei ole whois-palvelinta."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Tällaiselle objektille ei ole tiedossa whois-palvelinta."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Tuntematon AS-numero tai IP-verkko. Päivitä tämä ohjelma."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Käytetään palvelinta %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Kysellään IPv4-päätetepistettä %s 6to4-IPv6-osoitteelle.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Kysellään IPv4-päätetepistettä %s Teredo-IPv6-osoitteelle.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Kysely: ”%s”\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Löytyi viittaus %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Tätä riviä ei voi jäsentää: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Varoitus: RIPE-valitsimia käytetään perinteiseen palvelimeen."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Katastrofaalinen virhe: vastuuvapauslausekkeen teksti\n"
+"on muuttunut.\n"
+"Päivitä tämä ohjelma.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Palvelinta %s ei löydy."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: tuntematon palvelu"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Aikakatkaisu."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Ohjelma keskeytyi signaaliin %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Käyttö: whois [VALITSIN]... OBJEKTI...\n"
+"\n"
+"-h PALV, --host PALV ota yhteys PALVelimeen\n"
+"-p PORT, --port PORT käytä PORTtia\n"
+"-I kysele whois.iana.org:ilta ja seuraa viittausta\n"
+"-H piilota vastuuvapauslausekkeet\n"
+
+#: ../whois.c:1506
+#, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar "
+"servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose kerro mitä on tekeillä\n"
+" --no-recursion älä käytä rekursiota rekisteristä\n"
+" verkkotunnusvälittäjän palvelimille\n"
+" --help näytä tämä ohje ja poistu\n"
+" --version näytä versiotiedot ja poistu\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Seuraavat liput toimivat whois.ripe.net- ja joillakin RIPEn\n"
+"kaltaisilla palvelimilla:\n"
+"-l etsi yhden tason vähemmän tarkka osuma\n"
+"-L etsi kaikkien tasojen vähemmän tarkat osumat\n"
+"-m etsi kaikki yhden tason tarkemmat osumat\n"
+"-M etsi kaikkien tasojen tarkemmat osumat\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c etsi vähin osuma, jolla on mnt-irt-attribuutti\n"
+"-x täysosuma\n"
+"-b palauta lyhyesti IP-osoiteavaruudet ja abuse-tieto\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B poista objektisuodatus (näytä sähköpostiosoitteet)\n"
+"-G poista objektien ryhmittely\n"
+"-d palauta myös DNS-delegointiobjektit\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... tee käänteishaku käyttäen ATTRibuutteja\n"
+"-T TYYP[,TYYP]... hae ainoastaan tietyn TYYPpisiä objekteja\n"
+"-K vain pääavaimet palautetaan\n"
+"-r älä käytä rekursiivisia hakuja yhteystiedoille\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R pakota näyttämään paikallinen objekti vaikka se\n"
+" sisältäisi viitteen\n"
+"-a etsi myös kaikista peilatuista tietokannoista\n"
+"-s LÄHDE[,LÄHDE]... käytä LÄHTEestä peilattua tietokantaa\n"
+"-g LÄHDE:ALKU-LOPPU hae päivityksiä LÄHTEestä sarjasta ALKU-LOPPU\n"
+
+# version|sources|types ovat kirjaimellisesti sitä mitä käyttäjän kuuluu syöttää, niitä ei saa suomentaa.
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYYPPI hae malline TYYPPIä olevalle objektille\n"
+"-v TYYPPI hae laaja malline TYYPPIä olevalle objektille\n"
+"-q [version|sources|types] kysele annettua palvelintietoa\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDI-laajennettu DES-salaus, crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "standardi 56-bittinen DES-salaus, crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Kelvoton menetelmä ”%s”.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Kelvoton lukuarvo ”%s”.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Komento ”%s --help” antaa lisää tietoa.\n"
+
+#: ../mkpasswd.c:302
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Väärä suolan pituus: %d tavu, odotettiin %d.\n"
+msgstr[1] "Väärä suolan pituus: %d tavua, odotettiin %d.\n"
+
+#: ../mkpasswd.c:307
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Väärä suolan pituus: %d tavu, odotettiin %d <= n <= %d.\n"
+msgstr[1] "Väärä suolan pituus: %d tavua, odotettiin kun %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:316
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Kielletty suolamerkki ’%c’.\n"
+
+#: ../mkpasswd.c:372 ../mkpasswd.c:385
+#, c-format
+msgid "Password: "
+msgstr "Salasana: "
+
+#: ../mkpasswd.c:404
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "crypt(3)-funktio ei tue menetelmää.\n"
+
+#: ../mkpasswd.c:512
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Käyttö: mkpasswd [VALITSIMET] ... [SALASANA] [SUOLA]]\n"
+"Salaa SALASANAn crypt(3)-funktiolla.\n"
+"\n"
+
+#: ../mkpasswd.c:515
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYYPPI valitse menetelmä TYYPPI\n"
+" -5 sama kuin --method=md5crypt\n"
+" -S, --salt=SUOLA suolan valinta\n"
+
+#: ../mkpasswd.c:520
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=MÄÄRÄ käytä annettua kierrosMÄÄRÄä\n"
+" -P, --password-fd=NUM lue salasana tiedostokahvasta NUM\n"
+" eikä terminaalista /dev/tty\n"
+" -s, --stdin sama kuin --password-fd=0\n"
+
+#: ../mkpasswd.c:526
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help näytä tämä ohje ja poistu\n"
+" -V, --version tulosta versiotiedot ja poistu\n"
+"\n"
+"Jos SALASANA puuttuu, sitä kysytään vuorovaikutteisesti.\n"
+"Jos SUOLAa ei anneta, luodaan satunnainen.\n"
+"Jos TYYPPI on ”help”, käytettävissä olevat menetelmät\n"
+"tulostetaan.\n"
+"\n"
+"Lähetä bugiraportit osoitteeseen %s.\n"
+
+#: ../mkpasswd.c:549
+#, c-format
+msgid "Available methods:\n"
+msgstr "Käytettävissä olevat menetelmät:\n"
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..716cbd4
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,371 @@
+# Translation of whois to French
+# Copyright © 2003-2009 Debian French l10n team <debian-l10n-french@lists.debian.org>
+# This file is distributed under the same license as the whois package.
+# -2003: William Steve Applegate <wsapplegate@est.un.goret.info>
+# -2008: Mohammed Adnène Trojette <adn+deb@diwi.org>
+# 2013: Steve Petruzzello <dlist@bluewin.ch>
+# 2019: Steve Petruzzello <dlist@bluewin.ch>
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.4.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2019-06-28 17:47+0200\n"
+"Last-Translator: Steve Petruzzello <dlist@bluewin.ch>\n"
+"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Version %s.\n"
+"\n"
+"Veuillez signaler les bogues à %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Ce TLD n'a pas de serveur whois, mais vous pouvez accéder à la base de "
+"données à"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Ce TLD n'a pas de serveur whois."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Aucun serveur whois n'est connu pour ce type d'objet."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Numéro d'AS ou réseau IP inconnu. Veuillez mettre à jour ce programme."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Le serveur %s est sélectionné.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Requête faite pour l'extrémité IPv4 %s d'une adresse IPv6 6to4.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Requête faite pour l'extrémité IPv4 %s d'une adresse IPv6 Teredo.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Requête : \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Renvoi trouvé vers %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Impossible d'interpréter la ligne : %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr ""
+"Avertissement : des options RIPE ont été utilisées avec un serveur classique."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Erreur catastrophique : le texte d'avertissement a changé.\n"
+"Veuillez mettre à jour ce programme.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "L'hôte %s est introuvable."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp : service inconnu"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Temps limite dépassé."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Interruption par le signal %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Usage: whois [OPTION]... OBJET...\n"
+"\n"
+"-h HÔTE, --host HÔTE se connecter au serveur HÔTE\n"
+"-p PORT, --port PORT se connecter sur le port PORT\n"
+"-I interroger whois.iana.org et suivre son référent-"
+"H cacher les mentions légales\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose mode verbeux\n"
+" --help afficher cette aide et sortir\n"
+" --version afficher la version et sortir\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Ces drapeaux sont gérés par le serveur whois.ripe.net et quelques serveurs "
+"de type RIPE :\n"
+"-l réduire d'un niveau la spécificité de la recherche\n"
+"-L trouver toutes les occurrences moins spécifiques\n"
+"-m trouver les occurrences de premier niveau plus "
+"spécifiques\n"
+"-M trouver toutes les occurrences plus spécifiques\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c trouver l'occurrence la plus spécifique contenant un "
+"attribut mnt-irt\n"
+"-x occurrence exacte\n"
+"-b afficher la plage des adresses IP avec l'information "
+"d'abus\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B désactiver le filtrage d'objet (montrer les adresses "
+"électroniques)\n"
+"-G désactiver le groupement des objets associés\n"
+"-d afficher aussi les objets de délégation DNS inverse\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... effectuer une recherche inverse pour les ATTRibuts "
+"spécifiés\n"
+"-T TYPE[,TYPE]... chercher seulement les objets de ce TYPE\n"
+"-K seules les clés primaires sont renvoyées\n"
+"-r désactiver la recherche récursive des informations de "
+"contact\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R forcer l'affichage de la copie locale de l'objet de "
+"domaine même\n"
+" s'il contient un renvoi\n"
+"-a rechercher aussi dans toutes les bases de données "
+"miroir\n"
+"-s SOURCE[,SOURCE]... rechercher dans la base de données miroir de SOURCE\n"
+"-g SOURCE:PREM-DERN trouver les mises à jour de la SOURCE ayant des "
+"numéros\n"
+" de série entre PREM et DERN\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE demander la syntaxe pour les objets de ce TYPE\n"
+"-v TYPE demander la syntaxe détaillée pour les objets de ce "
+"TYPE\n"
+"-q [version|sources|types] demander les informations spécifiées au serveur\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "chiffrement à base DES étendu par BSDI"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "fonction crypt(3) standard, chiffrement DES à 56 bits"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "La méthode « %s » est invalide.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Le nombre « %s » est invalide.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Veuillez taper « %s --help » pour plus d'informations.\n"
+
+# : ../mkpasswd.c:152
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Mauvaise taille d'aléa : %d octet au lieu de %d.\n"
+msgstr[1] "Mauvaise taille d'aléa : %d octets au lieu de %d.\n"
+
+# : ../mkpasswd.c:152
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Mauvaise taille d'aléa : %d octet, non comprise entre %d et %d.\n"
+msgstr[1] "Mauvaise taille d'aléa : %d octets, non comprise entre %d et %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Le caractère « %c » est invalide dans l'aléa.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Mot de passe : "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Méthode non prise en charge par crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Usage : mkpasswd [OPTIONS]... [MOT DE PASSE [ALÉA]]\n"
+"Chiffre le MOT DE PASSE à l'aide de la fonction crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYPE sélectionner ce TYPE de méthode\n"
+" -5 équivalent à --method=md5crypt\n"
+" -S, --salt=ALÉA utiliser cet ALÉA\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=NOMBRE utiliser le NOMBRE de passages indiqué\n"
+" -P, --password-fd=NUM lire le mot de passe depuis le descripteur de\n"
+" fichier NUM\n"
+" au lieu de /dev/tty\n"
+" -s, --stdin équivalent à --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help afficher cette page d'aide et sortir\n"
+" -V, --version afficher les informations de version et sortir\n"
+"\n"
+"Si le MOT DE PASSE est manquant, il est demandé interactivement.\n"
+"Si aucun ALÉA n'est spécifié, un aléa aléatoire est généré.\n"
+"Si le TYPE est « help », les méthodes disponibles sont affichées.\n"
+"\n"
+"Veuillez signaler les bogues à %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Méthodes disponibles :\n"
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 0000000..740ac82
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,354 @@
+# Traduzione di whois.pot.
+# Copyright (C) 1999-2021 Marco d'Itri
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.0.24\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2022-01-03 18:13+0200\n"
+"Last-Translator: Marco d'Itri <md@linux.it>\n"
+"Language-Team: Italian <tp@lists.linux.it>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Versione %s.\n"
+"\n"
+"Segnalare i bug a %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Questo TLD non ha un server whois, ma si può accedere al database tramite"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Non esiste un server whois per questo TLD."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Non è noto alcun server whois per questo tipo di oggetto."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr ""
+"Numero dell'AS o della rete IP sconosciuto. Per favore aggiorna il programma."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Uso il server %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Cerco l'endpoint IPv4 %s di un indirizzo IPv6 6to4.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Cerco l'endpoint IPv4 %s di un indirizzo IPv6 Teredo.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Richiesta: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Trovato un riferimento a %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Impossibile interpretare questa riga: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Attenzione: sono stati usati dei flag RIPE con un server tradizionale."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Errore catastrofico: il testo di avvertenze è cambiato.\n"
+"Aggiorna questo programma.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Host %s non trovato."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: servizio sconosciuto"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Tempo scaduto."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Interrotto dal segnale %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Uso: whois [OPZIONE]... OGGETTO...\n"
+"\n"
+"-h HOST, --host HOST si connette al server HOST\n"
+"-p PORTA, --port PORTA si connette alla PORTA\n"
+"-I chiede a whois.iana.org e segue il rinvio\n"
+"-H nasconde le avvertenze legali\n"
+
+#: ../whois.c:1506
+#, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose spiega cosa sta facendo\n"
+" --no-recursion disattiva la ricorsione dal registry al registrar\n"
+" --help mostra questo aiuto ed esce\n"
+" --version stampa le informazioni sulla versione ed esce\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Le seguenti opzioni sono gestite da whois.ripe.net e alcuni server simili:\n"
+"-l trova la corrispondenza un livello meno specifica\n"
+"-L trova le corrispondenze meno specifiche a tutti i "
+"livelli\n"
+"-m trova le corrispondenze di primo livello più specifiche\n"
+"-M trova le corrispondenze più specifiche a tutti i livelli\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c trova la corrispondenza più specifica contenente un\n"
+" attributo mnt-irt\n"
+"-x trova solo la corrispondenza esatta\n"
+"-b mostra solo la rete IP con il contatto per gli abusi\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B non filtra gli oggetti (mostra gli indirizzi di e-mail)\n"
+"-G non raggruppa gli oggetti collegati\n"
+"-d restituisce anche gli oggetti della delega del DNS\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... fa una ricerca inversa per l'ATTRibuto specificato\n"
+"-T TIPO[,TIPO]... cerca solo oggetti del TIPO\n"
+"-K restituisce solo le chiavi primarie\n"
+"-r disabilita le ricerche ricorsive per i contatti\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R mostra la copia locale dell'oggetto domain anche se\n"
+" contiene un riferimento\n"
+"-a cerca anche in tutti i database replicati\n"
+"-s SOURCE[,SOURCE]... cerca il database replicato da SOURCE\n"
+"-g SOURCE:FIRST-LAST trova gli aggiornamenti di SOURCE dal seriale F a L\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TIPO chiede il template per un oggetto del TIPO\n"
+"-v TIPO chiede il template prolisso per un oggetto del TIPO\n"
+"-q [version|sources|types] chiede al server le informazioni indicate\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "crypt(3) estesa di BSDI basata su DES"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "crypt(3) standard a 56 bit basata su DES"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Il metodo '%s' non è valido.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Il numero '%s' non è valido.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Per maggior informazioni prova '%s --help'.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Lunghezza del sale sbagliata: %d byte invece di %d.\n"
+msgstr[1] "Lunghezza del sale sbagliata: %d byte invece di %d.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Lunghezza del sale sbagliata: %d byte invece di %d <= n <= %d.\n"
+msgstr[1] "Lunghezza del sale sbagliata: %d byte invece di %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Il carattere '%c' non è valido in un sale.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Password: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Metodo non gestito da crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Uso: mkpasswd [OPZIONI]... [PASSWORD [SALE]]\n"
+"Cifra la PASSWORD usando crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TIPO seleziona il TIPO di metodo\n"
+" -5 come --method=md5crypt\n"
+" -S, --salt=SALE usa il SALE specificato\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=NUMBER usa il NUMERO indicato di iterazioni\n"
+" -P, --password-fd=NUM legge la password dal file descriptor NUM\n"
+" invece che da /dev/tty\n"
+" -s, --stdin come --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help mostra questo aiuto ed esce\n"
+" -v, --version mostra le informazioni sulla versione ed esce\n"
+"\n"
+"Se la PASSWORD non è specificata viene chiesta interattivamente.\n"
+"Se il SALE non è specificato ne viene generato uno casuale.\n"
+"Se il TIPO è 'help' viene stampata la lista degli algoritmi disponibili.\n"
+"\n"
+"Segnalare i bug a %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Metodi disponibili:\n"
diff --git a/po/ja.po b/po/ja.po
new file mode 100644
index 0000000..9e7c060
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,346 @@
+# ja.po for whois
+# Copyright (C) 2005 Marco d'Itri <md@linux.it>
+# This file is distributed under the same license as the whois package.
+# Satoru SATOH <ss@gnome.gr.jp>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 4.7.2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2005-04-26 00:20+0900\n"
+"Last-Translator: Satoru SATOH\n"
+"Language-Team: Japanese\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"バージョン %s.\n"
+"\n"
+"バグ報告は %s へ.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"この TLD には whois サーバーがありませんが、次のサーバーで whois データベース"
+"にアクセスできます"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "この TLD には whois サーバーがありません"
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "この種のオブジェクトに対する既知の whois サーバーはありません"
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "不明な AS 番号または IP ネットワーク. アップグレードして下さい"
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "サーバー %s を使用\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"6to4 IPv6 アドレスの IPv4 終端 %s を問い合わせ中\n"
+"\n"
+
+#: ../whois.c:369
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"6to4 IPv6 アドレスの IPv4 終端 %s を問い合わせ中\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"問い合わせ文字列: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"%s への照会をみつけました\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "この行を解析できません: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "警告: 旧来のサーバーについて RIPE フラグが使用されています"
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"破滅的なエラー: 免責条項テキストが変更されました\n"
+"このプログラムをアップグレードして下さい\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "ホスト %s はみつかりませんでした"
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: 不明なサービス"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "時間切れ"
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "シグナル %d が割込み..."
+
+#: ../whois.c:1499
+#, fuzzy, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"-h HOST サーバー HOST に接続\n"
+"-p PORT PORT に接続\n"
+"-H 法的責任棄却声明を表示しない\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose 進捗について詳細に説明\n"
+" --help このヘルプを表示して終了\n"
+" --version バージョン情報を表示して終了\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+
+#: ../whois.c:1520
+#, fuzzy, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr "-x 厳密にマッチ\n"
+
+#: ../whois.c:1525
+#, fuzzy, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr "-d DNS 逆向き移譲オブジェクトも返す\n"
+
+#: ../whois.c:1530
+#, fuzzy, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... 指定属性 ATTR について逆引き\n"
+"-T TYPE[,TYPE]... TYPE オブジェクトのみについて検索\n"
+"-K 主キーのみ返す\n"
+"-r コンタクト情報について再帰検索しない\n"
+
+#: ../whois.c:1536
+#, fuzzy, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R 照会が含まれていても強制的にドメインオブジェクトの\n"
+" ローカルコピーを表示\n"
+"-a すべてのデータベースを検索\n"
+"-s SOURCE[,SOURCE]... SOURCE からデータベースを検索\n"
+"-g SOURCE:FIRST-LAST SOURCE (シリアル FIRST から LAST まで)から更新を検索\n"
+
+#: ../whois.c:1543
+#, fuzzy, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE TYPE オブジェクトについてテンプレートを要求 (リストは "
+"'all')\n"
+"-v TYPE TYPE オブジェクトについて冗長なテンプレートを要求\n"
+"-q [version|sources|types] 指定サーバー情報を問い合わせ\n"
+
+#: ../mkpasswd.c:135
+#, fuzzy
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "\t標準 56 ビット DES ベース暗号(3)"
+
+#: ../mkpasswd.c:138
+#, fuzzy
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "\t標準 56 ビット DES ベース暗号(3)"
+
+#: ../mkpasswd.c:207
+#, fuzzy, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "不正な数字 '%s'\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "不正な数字 '%s'\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "さらなる詳細については '%s --help' を実行\n"
+
+#: ../mkpasswd.c:292
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "間違ったソルト長: %d バイト(s) (%d を期待)\n"
+msgstr[1] "間違ったソルト長: %d バイト(s) (%d を期待)\n"
+
+#: ../mkpasswd.c:297
+#, fuzzy, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "間違ったソルト長: %d バイト(s) (%d を期待)\n"
+msgstr[1] "間違ったソルト長: %d バイト(s) (%d を期待)\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "不正なソルト文字 '%c'\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "パスワード: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr ""
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"使い方: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"PASSWORD を crypt(3) で暗号化\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, fuzzy, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -H, --hash=TYPE ハッシュ TYPE を選択\n"
+" -S, --salt=SALT 指定の SALT を選択\n"
+
+#: ../mkpasswd.c:505
+#, fuzzy, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -P, --password-fd=NUM /dev/tty の代わりにファイルディスクリプタ\n"
+" NUM からパスワードを読み込む\n"
+" -s, --stdin --password-fd=0 と同様\n"
+
+#: ../mkpasswd.c:511
+#, fuzzy, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help このヘルプを表示して終了\n"
+" -V, --version バージョン情報を出力して終了\n"
+"\n"
+"PASSWORD が未指定なら対話的に尋ねられます.\n"
+"SALT が未指定ならランダムに生成されたものが用いられます.\n"
+"TYPE が 'help' なら利用可能なアルゴリズムを表示します.\n"
+"\n"
+"バグ報告は %s へ.\n"
+
+#: ../mkpasswd.c:534
+#, fuzzy, c-format
+msgid "Available methods:\n"
+msgstr "利用可能なアルゴリズム:\n"
+
+#~ msgid "Illegal password character '0x%hhx'.\n"
+#~ msgstr "不正なパスワード文字 '0x%hhx'\n"
+
+#~ msgid "Invalid hash type '%s'.\n"
+#~ msgstr "不正なハッシュタイプ '%s'\n"
diff --git a/po/ka.po b/po/ka.po
new file mode 100644
index 0000000..c2822a2
--- /dev/null
+++ b/po/ka.po
@@ -0,0 +1,371 @@
+# Georgian translation for whois.
+# Copyright (C) 2022 whois authors
+# This file is distributed under the same license as the whois package.
+# Temuri Doghonadze <temuri.doghonadze@gmail.com>, 2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-10-20 04:31+0200\n"
+"PO-Revision-Date: 2022-10-20 05:41+0200\n"
+"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
+"Language-Team: \n"
+"Language: ka\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.1.1\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"ვერსია %s\n"
+"\n"
+"შეცდომები მიიწერეთ მისამართზე %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"ამ TLD-ს whois სერვერი არ გააჩნია. მაგრამ whois-ის ბაზასთან წვდომა გაქვთ "
+"მისამართზე"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "ამ TLD-ს whois სერვერი არ გააჩნია."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "ამ ტიპის ობიექტისთვის whois სერვერი ცნობილი არაა."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "უცნობი AS რიცხვი ან IP ქსელი. განაახლეთ ეს პროგრამა."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "ვიყენებ სერვერს: %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"6to4 IPv6 მისამართის IPv4 ბოლო წერტილის (%s) გამოთხოვა.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Teredo IPv6 მისამართის IPv4 ბოლო წერტილის (%s) გამოთხოვა.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"მოთხოვნის სტრიქონი: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"ნაპოვნია მიმართვა %s-ზე.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "ამ ხაზის დამუშავება შეუძლებელია: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "გაფრთხილება. RIPE-ის ალმები ტრადიციულ სერვერთან ერთად გამოიყენება."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"კატასტროფული შეცდომა: შეიცვალა პასუხისმგებლობების ტექსტი.\n"
+"საჭიროა ამ პროგრამის განახლება.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "ჰოსტი %s ვერ ვიპოვე."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: უცნობი სერვისი"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "ლოდინის ვადა გავიდა."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "შეწყდა სიგნალით %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"გამოყენება: whois [პარამეტრები]... ობიექტი...\n"
+"\n"
+"-h ჰოსტი, --host ჰოსტი მითითებულ ჰოსტთან მიერთება\n"
+"-p პორტი, --port პორტი მითითებულ პორტზე მიერთება\n"
+"-I whois.iana.org-ის მოთხოვნა და პასუხის მიყოლა\n"
+"-H იურიდიული ტექსტების დამალვა\n"
+
+#: ../whois.c:1506
+#, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar "
+"servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose ქმედებების ახსნა მიმდინარე დროში\n"
+" --no-recursion რეკურსიის გამორთვა რეესტრის სერვერბს შორის\n"
+" --help ამ დახმარების ჩვენება და გასვლა\n"
+" --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"ეს ალმები მხარდაჭერილია whois.ripe.net-ის და ზოგიერთი RIPE-ის მსგავსი "
+"სერვერების მიერ:\n"
+"-l ერთდონიანი მინიმალური ძებნა\n"
+"-L ყველაფრის მოძებნა მინიმალური დამთხვევებით\n"
+"-m მაქსიმალური მითითებული დამთხვევების პირველი დონის "
+"მოძებნა\n"
+"-M ყველაფრის მოძებნა მაქსიმალური დამთხვევებით\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c mnt-irt ატრიბუტის შემცველი უმცირესი დამთხვევის "
+"მოძებნა\n"
+"-x ზუსტი დამთხვევა\n"
+"-b კანონდარღვევს კონტაქტთან ერთად IP მისამართების "
+"დიაპაზონების მოკლე სიის დაბრუნება\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B ობიექტების ფილტრაციის გამორთვა (ელფოსტის "
+"მისამართების ჩვენება)\n"
+"-G ასოცირებული ობიექტების დაჯგუფების გამორთვა\n"
+"-d დაბრუნდება DNS სევერსის დელეგაციის ობექტებიც\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... მითითებული ატრბუტების ინვერსიული ძებნა\n"
+"-T TYPE[,TYPE]... მხოლოდ მითითებული ტიპის ობიექტების ძებნა\n"
+"-K მხოლოდ ძირითადი გასაღებები დაბრუნდება\n"
+"-r საკონტაქტო ინფორმაციის რეკურსიული ძებნის გამორთვა\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R დომენის ობიექტის ლოკალური ასლის ჩვენება მაშინაც კი,\n"
+" როცა ის ბმებს შეიცავს\n"
+"-a ძებნა სარკულ ბაზებშიაც\n"
+"-s SOURCE[,SOURCE]... მითითებული წყაროდან კოპირებულ ბაზაში ძებნა\n"
+"-g SOURCE:FIRST-LAST განახლებების ძებნა წყაროდან სერიულად პირველიდან "
+"ჩანაწერიდან, ბოლომდე\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE მითითებული ტიპის ობიექტისთვის შაბლონს მოთხოვნა\n"
+"-v TYPE მითითებული ტიპის ობიექტისთვის დამატებითი შაბლონის "
+"მოთხოვნა\n"
+"-q [version(ვერსია)|sources(წყაროები)|types(ტიპები)] სერვერის მითითებული "
+"ინფორმაციის მოთხოვნა\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDI გაფართოებული DES-ზე ბაზირებული crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "სტანდარტული 56 ბიტიანი DES-ზე ბაზირებული crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "არასწორი მეტოდი '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "არასწორი რიცხვი '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "მეტი ინფორმაციისთვის სცადეთ '%s --help'\n"
+
+#: ../mkpasswd.c:302
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] ""
+"მარილის არასწორი სიგრძე: %d ბაიტი მაშინ, როცა მოსალოდნელი იყო %d ბაიტი.\n"
+msgstr[1] ""
+"მარილის არასწორი სიგრძე: %d ბაიტი მაშინ, როცა მოსალოდნელი იყო %d ბაიტი.\n"
+
+#: ../mkpasswd.c:307
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] ""
+"მარილის არასწორი სიგრძე: %d ბაიტი მაშინ, როცა მოსალოდნელი იყო %d <= n <= %d "
+"ბაიტი.\n"
+msgstr[1] ""
+"მარილის არასწორი სიგრძე: %d ბაიტი მაშინ, როცა მოსალოდნელი იყო %d <= n <= %d "
+"ბაიტი.\n"
+
+#: ../mkpasswd.c:316
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "მარილიას დაუშვებელი სიმბოლო: '%c'.\n"
+
+#: ../mkpasswd.c:372 ../mkpasswd.c:385
+#, c-format
+msgid "Password: "
+msgstr "პაროლი: "
+
+#: ../mkpasswd.c:404
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "მეთოდი crypt(3)-ის მიერ მხარდაუჭერელია.\n"
+
+#: ../mkpasswd.c:512
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"გამოყენება: mkpasswd [პარამეტრები]... [პაროლი [მარილი]]\n"
+"მითითებული პაროლის crypt(3)-ით დაშიფვრა.\n"
+"\n"
+
+#: ../mkpasswd.c:515
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=ტიპი მითითებული ტიპის მეთოდის გამოყენება\n"
+" -5 იგივე, რაც --method=md5crypt\n"
+" -S, --salt=მარილი მითითებული მარილის გამოყენება\n"
+
+#: ../mkpasswd.c:520
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=რიცხვი მითითებული რაოდენობის რაუნდების გამოყენება\n"
+" -P, --password-fd=რცხვ პაროლების /dev/tty-ის მაგიერ მითითებული "
+"ფაილის\n"
+" დესკრიპტორიდან წაკითხვა\n"
+" -s, --stdin იგივე, რაც --password-fd=0\n"
+
+#: ../mkpasswd.c:526
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help ამ დახმარების გამოტანა და გასვლა\n"
+" -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n"
+"\n"
+"თუ პაროლი მითითებული არაა, მას ინტერაქტიურად გკითხავთ.\n"
+"თუ მარილი მითითებული არაა, ის შემთხვევითობის წესით დაგენერირდება.\n"
+" თუ ტიპი 'help'-ა, ეკრანზე იქნება ნაჩვენები ხელმისაწვდომი მეთოდები.\n"
+"\n"
+"შეცდომების შესახებ მიწერეთ: %s.\n"
+
+#: ../mkpasswd.c:549
+#, c-format
+msgid "Available methods:\n"
+msgstr "ხელმისაწვდომი მეთოდები:\n"
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 0000000..4dd737c
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,369 @@
+# Polish translation for whois.
+# Michał 'CeFeK' Nazarewicz <cefek@career.pl>, 1999
+# Przemysław Knycz <djrzulf@pld.org.pl>, 2003
+# Jakub Bogusz <qboosh@pld-linux.org>, 2003-2019
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.5.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2019-08-28 18:02+0200\n"
+"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
+"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Wersja %s.\n"
+"\n"
+"Błędy proszę zgłaszać na adres %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Ta główna domena nie ma serwera whois, ale można użyć bazy danych whois pod"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Ta główna domena nie ma serwera whois."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Dla tego rodzaju obiektu nie jest znany żaden serwer whois."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Nieznany numer AS lub sieć IP. Proszę uaktualnić ten program."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Użycie serwera %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Pytanie o zakończenie IPv4 %s adresu IPv6 typu 6to4.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Pytanie o zakończenie IPv4 %s adresu IPv6 Teredo.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Zapytanie: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Znaleziono odniesienie do %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Nie można przeanalizować tej linii: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Uwaga: użyto flag RIPE ze starszym serwerem."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Katastrofa! Tekst oświadczenia został zmieniony.\n"
+"Proszę uaktualnić ten program.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Serwer %s nie został znaleziony."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: usługa nieznana"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Upłynął limit czasu."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Przerwano sygnałem %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Składnia: whois [OPCJA]... OBIEKT...\n"
+"\n"
+"-h HOST, --host HOST łączenie z serwerem HOST\n"
+"-p PORT, --port PORT łączenie z portem PORT\n"
+"-I odpytanie whois.iana.org i podążanie za odwołaniami\n"
+"-H ukrycie oświadczeń prawnych\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose wyjaśnianie, co się dzieje\n"
+" --help wyświetlenie tego opisu i zakończenie działania\n"
+" --version wyświetlenie informacji o wersji i zakończenie "
+"działania\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Następujące flagi są obsługiwane przez serwery whois.ripe.net i podobne:\n"
+"-l zapytanie o jeden poziom mniej szczegółowe\n"
+"-L wyszukanie wszystkich mniej szczegółowych dopasowań\n"
+"-m wyszukanie pierwszego bardziej szczegółowego "
+"dopasowania\n"
+"-M wyszukanie wszystkich bardziej szczegółowych "
+"dopasowań\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c wyszukanie najmniejszego dopasowania z atrybutem mnt-"
+"irt\n"
+"-x dokładne dopasowanie\n"
+"-b wypisanie zwięźle przedziałów adresów IP i kontaktu "
+"abuse\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B bez filtrowania abiektów (wyświetlanie adresów e-"
+"mail)\n"
+"-G bez grupowania powiązanych obiektów\n"
+"-d także obiekty odwrotnej delegacji DNS\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-T TYP[,TYP]... szukanie tylko obiektów podanego TYPU\n"
+"-K zwrócenie tylko podstawowych kluczy\n"
+"-r bez rekursywnego poszukiwania informacji "
+"kontaktowych\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R wymuszenie pokazania lokalnej kopii obiektu domeny "
+"nawet\n"
+" jeśli zawiera odwołanie\n"
+"-a przeszukanie wszystkich baz danych z kopii "
+"lustrzanej\n"
+"-s ŹRÓDŁO[,ŹRÓDŁO]... przeszukanie odbicia lustrzanego bazy danych ze "
+"ŹRÓDŁA\n"
+"-g ŹRÓDŁO:PIERW.-OST. szukanie uaktualnień ze ŹRÓDŁA od numeru PIERW. do "
+"OST.\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYP żądanie szablonu dla obiektu podanego TYPU\n"
+"-v TYP żądanie szczegółowego szablonu dla obiektu podanego "
+"TYPU\n"
+"-q [version|sources|types] zapytanie serwera o podane informacje\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "oparta o DES rozszerzona funkcja crypt(3) BSDI"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "standardowa 56-bitowa, oparta o DES funkcja crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Nieprawidłowa metoda '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Nieprawidłowa liczba '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "'%s --help' poda więcej informacji.\n"
+
+# : ../mkpasswd.c:152
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Błędna długość zarodka: %d bajt kiedy oczekiwano %d.\n"
+msgstr[1] "Błędna długość zarodka: %d bajty kiedy oczekiwano %d.\n"
+msgstr[2] "Błędna długość zarodka: %d bajtów kiedy oczekiwano %d.\n"
+
+# : ../mkpasswd.c:152
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Błędna długość zarodka: %d bajt kiedy oczekiwano %d <= n <= %d.\n"
+msgstr[1] "Błędna długość zarodka: %d bajty kiedy oczekiwano %d <= n <= %d.\n"
+msgstr[2] "Błędna długość zarodka: %d bajtów kiedy oczekiwano %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Błędny znak zarodka '%c'.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Hasło: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Metoda nie obsługiwana przez crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Składnia: mkpasswd [OPCJE]... [HASŁO [ZARODEK]]\n"
+"Koduje HASŁO przy użyciu funkcji crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYP wybór metody TYP\n"
+" -5 to samo, co --method=md5crypt\n"
+" -S, --salt=ZARODEK użycie podanego ZARODKA\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=LICZBA użycie podanej LICZBY cykli\n"
+" -P, --password-fd=NUM odczyt hasła z deskryptora pliku NUM zamiast\n"
+" z /dev/tty\n"
+" -s, --stdin to samo co --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help wyświetlenie tego opisu i zakończenie działania\n"
+" -V, --version wyświetlenie informacji o wersji i zakończenie "
+"działania\n"
+"\n"
+"Jeśli nie podano HASŁA, pobierane jest interaktywnie.\n"
+"Jeśli nie podano ZARODKA, generowany jest losowy.\n"
+"Jeśli podano TYP 'help', wypisywane są dostępne metody.\n"
+"\n"
+"Błędy proszę zgłaszać na adres %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Dostępne metody:\n"
diff --git a/po/pt_BR.po b/po/pt_BR.po
new file mode 100644
index 0000000..b77f23b
--- /dev/null
+++ b/po/pt_BR.po
@@ -0,0 +1,376 @@
+# Portuguese/Brazil translation of whois.
+# Copyright (C) 2006 Marco d'Itri
+# This file is distributed under the same license as the whois package.
+# Anderson Goulart <globalx@gmail.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.5.6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2020-02-17 10:30+0000\n"
+"Last-Translator: Anderson Goulart <globalx@gmail.com>\n"
+"Language-Team: Portuguese/Brazil\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Versão %s.\n"
+"\n"
+"Reporte falhas(bugs) para %s \n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Este TLD não possui servidor whois, mas você pode acessar a base de dados do "
+"whois em"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Não existe servidor whois para este TLD."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Nenhum servidor whois é conhecido para este tipo de objeto."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Número AS ou rede IP desconhecidos. Por favor, atualize este programa."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Utilizando servidor %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Procurando pelo endereço IPv4 %s a partir de um endereço 6to4 IPv6.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Procurando pelo endereço IPv4 %s a partir de um endereço Teredo IPv6.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Texto de consulta: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Referência encontrada para %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Não conseguiu processar esta linha: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Aviso: RIPE flags utilizados com um servidor tradicional."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Erro catastrófico: o texto das condições de uso foi alterado.\n"
+"Por favor, atualize este programa.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Hospedeiro %s não encontrado."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: serviço desconhecido"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Tempo esgotado."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Interrompido pelo sinal %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Uso: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST conecta no servidor(HOST)\n"
+"-p PORT conecta na porta(PORT)\n"
+"-H esconde o aviso legal\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose exibe detalhes de execução\n"
+" --help exibe esta ajuda e termina\n"
+" --version exibe informações sobre a versão e termina\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Estas opções(flags) são suportadas pelo servider whois.ripe.net e alguns "
+"servidores RIPE compatíveis:\n"
+"-l encontre a correspondência menos específica de nível "
+"um\n"
+"-L encontra todos os níveis de correspondências menos "
+"específicas\n"
+"-m encontra todas as correspondências mais específicas "
+"do nível um\n"
+"-M encontra todos os níveis de correspondências mais "
+"específicas\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c busca a correspondência menos específica que contém o "
+"atributo mnt-irt\n"
+"-x busca exata\n"
+"-b retorna o resumo de faixas de endereços IP com o "
+"contato de abuso\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B desliga o filtro de objetos (exibe o endereço de "
+"email)\n"
+"-G desliga o agrupamento de objectos associados\n"
+"-d retorna também os objetos de delegação de DNS "
+"reverso\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... efetua uma busca inversa para os atributtos(ATTR) "
+"especificados\n"
+"-T TYPE[,TYPE]... busca somente por objetos do tipo(TYPE) "
+"especificados\n"
+"-K somente chaves primárias são retornadas\n"
+"-r desabilita buscas recursivas para informações de "
+"contatos\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R força a exibição da cópia local do objeto de domínio "
+"mesmo que\n"
+" ele contenha referência\n"
+"-a busca em todas as bases de dados espelhadas\n"
+"-s SOURCE[,SOURCE]... busca na base de dados espelhada a partir das "
+"fontes(SOURCE) especificadas\n"
+"-g SOURCE:FIRST-LAST encontra atualizações a partir da fonte(SOURCE) entre "
+"o serial primeiro(FIRST) e último(LAST)\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE obtém o modelo para objeto do tipo(TYPE) "
+"especificado\n"
+"-v TYPE obtém o modelo detalhado para objeto do tipo(TYPE) "
+"especificado\n"
+"-q [version|sources|types] consulta informações especificadas do servidor\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDI extendido baseado em DES crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "padrão 56 bit baseado em DES crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Método inválido '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Número inválido '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Tente '%s --help para maiores informações.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Tamanho do sal(salt) incorreto: %d byte enquanto %d era esperado.\n"
+msgstr[1] ""
+"Tamanho do sal(salt) incorreto: %d bytes enquanto %d era esperado.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] ""
+"Tamanho do sal(salt) incorreto: %d byte enquanto %d <= n <= %d era "
+"esperado.\n"
+msgstr[1] ""
+"Tamanho do sal(salt) incorreto: %d bytes enquanto %d <= n <= %d era "
+"esperado.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Caractere sal(salt) ilegal '%c'.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Senha: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Método não suportado por crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Uso: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Encripta a senha(PASSWORD) utilizando crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYPE seleciona o método do tipo(TYPE) especificado\n"
+" -5 igual a --method=md5crypt\n"
+" -S, --salt=SALT usa o sal(SALT) especificado\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=NUMBER utiliza o número(NUMBER) de rodadas "
+"especificado\n"
+" -P, --password-fd=NUM lê a senha do descritor de arquivo NUM\n"
+" ao invés do /dev/tty\n"
+" -s, --stdin igual a --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help exibe essa ajuda(help) e sai\n"
+" -V, --version exibe informações sobre a versão(version) e sai\n"
+"\n"
+"Se a senha(PASSWORD) estiver faltando, esta será requisitada "
+"interativamente.\n"
+"Se nenhum sal(SALT) for especificado, um sal randômico é gerado.\n"
+"Se o tipo(TYPE) é igual a 'help', os métodos disponíveis são exibidos.\n"
+"\n"
+"Reporte falhas(bugs) para %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Métodos disponíveis:\n"
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..407798b
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,366 @@
+# translation of ru.po to Russian
+# Copyright (C) Marco d'Itri
+# This file is distributed under the same license as the whois package.
+#
+# Andy Shevchenko <andy@smile.org.ua>, 2005.
+# Yuri Kozlov <yuray@komyakino.ru>, 2009, 2010, 2012, 2013, 2019.
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 5.4.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2019-06-29 09:55+0300\n"
+"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
+"Language-Team: Russian <debian-l10n-russian@lists.debian.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 2.0\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Версия %s.\n"
+"\n"
+"Сообщения об ошибках отправляйте на %s.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Данный TLD не имеет whois-сервера, но можно получить доступ к базе whois на"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Данный TLD не имеет whois-сервера."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Нет whois-сервера для объектов данного вида."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Неизвестный номер AS или IP-сеть. Пожалуйста, обновите программу."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Используется сервер %s.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Запрашивается конечная IPv4-точка %s для IPv6-адреса 6-в-4.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Запрашивается конечная IPv4-точка %s для IPv6-адреса Teredo.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Строка запроса: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Найдено перенаправление на %s.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Невозможно разобрать строку: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Предупреждение: флаги RIPE используются с традиционным сервером."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Катастрофическая ошибка: текст правовой оговорки был изменён.\n"
+"Пожалуйста, обновите программу.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "Узел %s не найден."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: неизвестный сервис"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Задержка."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Прервано по сигналу %d..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Использование: whois [ПАРАМЕТР]… ОБЪЕКТ…\n"
+"\n"
+"-h УЗЕЛ, --host УЗЕЛ подключиться к серверному УЗЛУ\n"
+"-p ПОРТ, --port ПОРТ подключаться по ПОРТУ\n"
+"-I запросить whois.iana.org и следовать результатам\n"
+"-H скрыть уведомление о правах\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose разъяснять, что происходит\n"
+" --help показать эту справку и закончить работу\n"
+" --version показать информацию о версии и закончить работу\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Эти флаги поддерживаются whois.ripe.net и некоторыми RIPE-подобными "
+"серверами:\n"
+"-l одноуровневый минимальный поиск\n"
+"-L найти всё при минимуме указанных совпадений\n"
+"-m найти первый уровень при максимуме указанных "
+"совпадений\n"
+"-M найти всё при максимуме указанных совпадений\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c найти наименьшее совпадение, содержащее атрибут mnt-"
+"irt\n"
+"-x точное совпадение\n"
+"-b вернуть краткий диапазон IP-адресов\n"
+" с контактом для жалоб\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B выключить объектную фильтрацию (показ адресов эл. "
+"почты)\n"
+"-G выключить группировку связанных объектов\n"
+"-d возвращать также реверсные делегированные объекты "
+"DNS\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i АТР[,АТР]… выполнить инверсный поиск для указанных АТРибутов\n"
+"-T ТИП[,ТИП]… поиск только объектов с типом ТИП\n"
+"-K возвращать только основные ключи\n"
+"-r выключить рекурсивный поиск контактной информации\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R всегда показывать локальную копию объекта домена "
+"даже\n"
+" если она содержит перенаправление\n"
+"-a искать на всех зеркалах базы\n"
+"-s ИСТОЧНИК[,ИСТ]… искать в базе-зеркале ИСТОЧНИКА\n"
+"-g ИСТОЧНИК:ПЕРВЫЙ-ПОСЛЕДНИЙ\n"
+" найти обновления ИСТОЧНИКА от ПЕРВОГО до ПОСЛЕДНЕГО\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t ТИП запросить шаблон для объекта с типом ТИП\n"
+"-v ТИП запросить расширенный шаблон для объекта с типом ТИП\n"
+"-q [version|sources|types]\n"
+" запросить указанную информацию о сервере\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "основанный на DES crypt(3), расширенный BSDI"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "основанный на стандартном 56-битном DES crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Неверный метод '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Неверный номер '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Доп. информацию можно получить, запустив '%s --help'.\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Неверная длина соли: %d байт при ожидаемой %d.\n"
+msgstr[1] "Неверная длина соли: %d байта при ожидаемой %d.\n"
+msgstr[2] "Неверная длина соли: %d байт при ожидаемой %d.\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Неверная длина соли: %d байт при ожидаемой %d <= n <= %d.\n"
+msgstr[1] "Неверная длина соли: %d байта при ожидаемой %d <= n <= %d.\n"
+msgstr[2] "Неверная длина соли: %d байт при ожидаемой %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Недопустимый для соли символ '%c'.\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "Пароль: "
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Данный метод не поддерживается crypt(3).\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Использование: mkpasswd [ПАРАМЕТРЫ]... [ПАРОЛЬ [СОЛЬ]]\n"
+"Шифрует ПАРОЛЬ, используя crypt(3).\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=ТИП использовать метод ТИП\n"
+" -5 аналогично --method=md5crypt\n"
+" -S, --salt=СОЛЬ использовать указанную СОЛЬ\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=ЧИСЛО использовать указанное ЧИСЛО округлений\n"
+" -P, --password-fd=НОМЕР прочитать пароль из дескриптора файла\n"
+" с НОМЕРом вместо /dev/tty\n"
+" -s, --stdin аналогично --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help показать эту справку и закончить работу\n"
+" -V, --version показать версию и закончить работу\n"
+"\n"
+"Если ПАРОЛЬ не задан, то он будет затребован интерактивно.\n"
+"Если не указана СОЛЬ, то будет сгенерировано произвольное значение.\n"
+"Если значение ТИП равно 'help', то будет показан список доступных методов.\n"
+"\n"
+"Сообщения об ошибках отправляйте на %s.\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "Доступные методы:\n"
diff --git a/po/tr.po b/po/tr.po
new file mode 100644
index 0000000..0577473
--- /dev/null
+++ b/po/tr.po
@@ -0,0 +1,357 @@
+# translation of whois to Turkish
+# Copyright (C) 2022
+# This file is distributed under the same license as the whois package.
+# Oğuz Ersen <oguz@ersen.moe>, 2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-04-01 22:10+0300\n"
+"PO-Revision-Date: 2022-04-01 23:06+0300\n"
+"Last-Translator: Oğuz Ersen <oguz@ersen.moe>\n"
+"Language-Team: \n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"Sürüm %s.\n"
+"\n"
+"Hataları %s adresine bildirin.\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr ""
+"Bu TLD'nin whois sunucusu yok, ancak whois veri tabanına şu adresten "
+"erişebilirsiniz"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "Bu TLD'nin whois sunucusu yok."
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "Bu tür nesneler için bilinen bir whois sunucusu yok."
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "Bilinmeyen AS numarası veya IP ağı. Lütfen bu programı güncelleyin."
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "%s sunucusu kullanılıyor.\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"6to4 IPv6 adresinin IPv4 uç noktası %s sorgulanıyor.\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"Teredo IPv6 adresinin IPv4 uç noktası %s sorgulanıyor.\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Sorgu dizgesi: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"%s için bir yönlendirme bulundu.\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "Bu satır ayrıştırılamıyor: %s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "Uyarı: Geleneksel bir sunucuyla RIPE bayrakları kullanıldı."
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Önemli hata: sorumluluk reddi metni değiştirildi.\n"
+"Lütfen bu programı güncelleyin.\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "%s sunucusu bulunamadı."
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: bilinmeyen hizmet"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "Zaman aşımı."
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "%d sinyali tarafından kesildi..."
+
+#: ../whois.c:1499
+#, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"Kullanım: whois [SEÇENEK]... NESNE...\n"
+"\n"
+"-h HOST, --host HOST HOST sunucusuna bağlan\n"
+"-p PORT, --port PORT PORT bağlantı noktasına bağlan\n"
+"-I whois.iana.org'u sorgula ve yönlendirmesini takip et\n"
+"-H yasal uyarıları gizle\n"
+
+#: ../whois.c:1506
+#, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose ne yapıldığını açıkla\n"
+" --no-recursion kayıt defterinden kayıt sunucularına özyinelemeyi "
+"devre dışı bırak\n"
+" --help bu yardımı görüntüle ve çık\n"
+" --version sürüm bilgisini yazdır ve çık\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"Bu bayraklar whois.ripe.net ve bazı RIPE benzeri sunucular tarafından "
+"desteklenmektedir:\n"
+"-l bir seviye daha az özel eşleşmeyi bul\n"
+"-L tüm seviyelerde daha az özel eşleşmeleri bul\n"
+"-m tüm bir seviye daha özel eşleşmeleri bul\n"
+"-M tüm seviyelerde daha özel eşleşmeleri bul\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c mnt-irt özniteliği içeren en küçük eşleşmeyi bul\n"
+"-x tam olarak eşleş\n"
+"-b kötüye kullanım irtibatıyla kısa IP adresi "
+"aralıklarını döndür\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B nesne filtrelemeyi kapat (e-posta adreslerini "
+"göster)\n"
+"-G ilişkili nesnelerin gruplandırılmasını kapat\n"
+"-d DNS ters yetki nesnelerini de döndür\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ÖZNİ[,ÖZNİ]... belirtilen ÖZNİtelikler için ters arama yap\n"
+"-T TÜR[,TÜR]... yalnızca TÜR nesnelerini ara\n"
+"-K yalnızca birincil anahtarları döndür\n"
+"-r iletişim bilgileri için özyinelemeli aramaları kapat\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R yönlendirme içerse bile etki alanı nesnesinin yerel\n"
+" kopyasını göstermeye zorla\n"
+"-a ayrıca tüm yansıtılmış veri tabanlarında arama yap\n"
+"-s KAYNAK[,KAYNAK]... KAYNAK'tan yansıtılan veri tabanında arama yap\n"
+"-g KAYNAK:İLK-SON KAYNAK'tan İLK'ten SON'a kadar olan güncellemeleri "
+"bul\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TÜR TÜR nesnesi için şablon iste\n"
+"-v TÜR TÜR nesnesi için ayrıntılı şablon iste\n"
+"-q [version|sources|types] belirtilen sunucu bilgilerini sorgula\n"
+
+#: ../mkpasswd.c:135
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "BSDI genişletilmiş DES tabanlı crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "standart 56 bit DES tabanlı crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "Geçersiz yöntem '%s'.\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "Geçersiz sayı '%s'.\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "Daha fazla bilgi için '%s --help' komutunu deneyin.\n"
+
+#: ../mkpasswd.c:302
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] "Yanlış salt uzunluğu: %d bayt, beklenen: %d.\n"
+
+#: ../mkpasswd.c:307
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] "Yanlış salt uzunluğu: %d bayt, beklenen: %d <= n <= %d.\n"
+
+#: ../mkpasswd.c:316
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "Geçersiz salt karakteri '%c'.\n"
+
+#: ../mkpasswd.c:372 ../mkpasswd.c:385
+#, c-format
+msgid "Password: "
+msgstr "Parola: "
+
+#: ../mkpasswd.c:404
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "Yöntem crypt(3) tarafından desteklenmiyor.\n"
+
+#: ../mkpasswd.c:512
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"Kullanım: mkpasswd [SEÇENEKLER]... [PAROLA [SALT]]\n"
+"PAROLA değerini crypt(3) kullanarak şifreler.\n"
+"\n"
+
+#: ../mkpasswd.c:515
+#, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TÜR TÜR yöntemini seç\n"
+" -5 --method=md5crypt ile aynı\n"
+" -S, --salt=SALT belirtilen SALT değerini kullan\n"
+
+#: ../mkpasswd.c:520
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=SAYI belirtilen SAYI kadar tur kullan\n"
+" -P, --password-fd=NUM parolayı /dev/tty yerine NUM dosya\n"
+" tanıtıcısından oku\n"
+" -s, --stdin --password-fd=0 ile aynı\n"
+
+#: ../mkpasswd.c:526
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help bu yardımı görüntüle ve çık\n"
+" -V, --version sürüm bilgisini yazdır ve çık\n"
+"\n"
+"PAROLA eksikse etkileşimli olarak sorulur.\n"
+"SALT belirtilmezse, rastgele bir tane oluşturulur.\n"
+"TÜR 'help' ise kullanılabilir yöntemler yazdırılır.\n"
+"\n"
+"Hataları %s adresine bildirin.\n"
+
+#: ../mkpasswd.c:549
+#, c-format
+msgid "Available methods:\n"
+msgstr "Kullanılabilir yöntemler:\n"
diff --git a/po/zh_CN.po b/po/zh_CN.po
new file mode 100644
index 0000000..68d8237
--- /dev/null
+++ b/po/zh_CN.po
@@ -0,0 +1,353 @@
+# Chinese (China) translation for whois
+# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006
+# This file is distributed under the same license as the whois package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-03 17:52+0100\n"
+"PO-Revision-Date: 2013-12-25 17:40+0800\n"
+"Last-Translator: Terence Ng <pheotiman@gmail.com>\n"
+"Language-Team: \n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2009-11-10 02:44+0000\n"
+"X-Generator: Poedit 1.5.7\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: ../whois.c:240
+#, c-format
+msgid ""
+"Version %s.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+"版本 %s。\n"
+"\n"
+"向 %s 报告漏洞。\n"
+
+#: ../whois.c:329
+msgid "This TLD has no whois server, but you can access the whois database at"
+msgstr "此顶级域名没有 whois 服务器,但您可在这里访问 whois 数据库:"
+
+#: ../whois.c:334
+msgid "This TLD has no whois server."
+msgstr "此顶级域名没有对应的 whois 服务器。"
+
+#: ../whois.c:337
+msgid "No whois server is known for this kind of object."
+msgstr "无针对此类对象的 whois 服务器。"
+
+#: ../whois.c:340
+msgid "Unknown AS number or IP network. Please upgrade this program."
+msgstr "未知的 AS 号码或 IP 地址。请升级此程序。"
+
+#: ../whois.c:344 ../whois.c:353 ../whois.c:388 ../whois.c:405
+#, c-format
+msgid "Using server %s.\n"
+msgstr "使用服务器 %s。\n"
+
+#: ../whois.c:362
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"查询和一个6to4 IPv6 地址相对应的 IPv4 终端 %s。\n"
+"\n"
+
+#: ../whois.c:369
+#, c-format
+msgid ""
+"\n"
+"Querying for the IPv4 endpoint %s of a Teredo IPv6 address.\n"
+"\n"
+msgstr ""
+"\n"
+"查询一个Teredo IPv6 地址相对应的 IPv4 终端 %s。\n"
+"\n"
+
+#: ../whois.c:406
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"查询字符串: \"%s\"\n"
+"\n"
+
+#: ../whois.c:416
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Found a referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"发现一个到 %s 的引用。\n"
+"\n"
+
+#: ../whois.c:458 ../whois.c:461
+#, c-format
+msgid "Cannot parse this line: %s"
+msgstr "不能分析该行:%s"
+
+#: ../whois.c:650
+msgid "Warning: RIPE flags used with a traditional server."
+msgstr "警告: 对传统服务器使用了 RIPE 标志。"
+
+#: ../whois.c:823 ../whois.c:939
+msgid ""
+"Catastrophic error: disclaimer text has been changed.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"严重错误: 声明(disclaimer)文本已经被改变。\n"
+"请升级此程序。\n"
+
+#: ../whois.c:1040
+#, c-format
+msgid "Host %s not found."
+msgstr "没有找到主机 %s。"
+
+#: ../whois.c:1050
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: 未知服务"
+
+#: ../whois.c:1125
+msgid "Timeout."
+msgstr "超时。"
+
+#: ../whois.c:1131
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "被信号 %d 中断..."
+
+#: ../whois.c:1499
+#, fuzzy, c-format
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+msgstr ""
+"用法: whois 【选项】 …… 对象 ……\n"
+"\n"
+"-h HOST, --host HOST 连接到服务器 HOST\n"
+"-p PORT, --port PORT 连接到端口 PORT\n"
+"-H 隐藏法律声明\n"
+
+#: ../whois.c:1506
+#, fuzzy, c-format
+msgid ""
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+msgstr ""
+" --verbose 解释正在做什么\n"
+" --help 显示帮助并退出\n"
+" --version 输出版本信息并退出\n"
+"\n"
+
+#: ../whois.c:1513
+#, c-format
+msgid ""
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+msgstr ""
+"这些标志是由 whois.ripe.net 和 RIPE-like 服务器支持的:\n"
+" -l 寻找有更少具体匹配的一个级别\n"
+"-L 寻找所有更少具体匹配的级别\n"
+"-m 寻找有更加具体匹配的一个级别\n"
+"-M 寻找有更加具体的匹配的所有级别\n"
+
+#: ../whois.c:1520
+#, c-format
+msgid ""
+"-c find the smallest match containing a mnt-irt "
+"attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+msgstr ""
+"-c 寻找包含 mnt-irt 属性的最小匹配\n"
+"-x 精确匹配\n"
+"-b return brief IP address ranges with abuse contact\n"
+
+#: ../whois.c:1525
+#, c-format
+msgid ""
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+msgstr ""
+"-B 关闭对象过滤(显示 email 地址)\n"
+"-G 关闭相关联对象的分组\n"
+"-d 返回 DNS 反解授权对象\n"
+
+#: ../whois.c:1530
+#, c-format
+msgid ""
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+msgstr ""
+"-i ATTR[,ATTR]... 对特定的属性( ATTR )进行逆向查询\n"
+"-T TYPE[,TYPE]... 只寻找 TYPE 的对象\n"
+"-K 只返回主键\n"
+"-r 关闭联系信息的递归查询\n"
+
+#: ../whois.c:1536
+#, c-format
+msgid ""
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+msgstr ""
+"-R 强制显示域对象的本地副本,即使\n"
+" 它包含引用\n"
+"-a 一并搜索所有的数据库镜像\n"
+"-s SOURCE[,SOURCE]... 从 SOURCE 中搜索数据库镜像\n"
+"-g SOURCE:FIRST-LAST 从串行的 FIRST 到 LAST 的 SOURCE 中查找更新\n"
+
+#: ../whois.c:1543
+#, c-format
+msgid ""
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+msgstr ""
+"-t TYPE 请求 TYPE 对象的模板\n"
+"-v TYPE 请求 TYPE 对象的详细模板\n"
+"-q [version|sources|types] 询问制定服务器信息\n"
+
+#: ../mkpasswd.c:135
+#, fuzzy
+msgid "BSDI extended DES-based crypt(3)"
+msgstr "以标准56位DES为基础的 crypt(3)"
+
+#: ../mkpasswd.c:138
+msgid "standard 56 bit DES-based crypt(3)"
+msgstr "以标准56位DES为基础的 crypt(3)"
+
+#: ../mkpasswd.c:207
+#, c-format
+msgid "Invalid method '%s'.\n"
+msgstr "无效方式 '%s'。\n"
+
+#: ../mkpasswd.c:216 ../mkpasswd.c:228
+#, c-format
+msgid "Invalid number '%s'.\n"
+msgstr "无效的数字 '%s'。\n"
+
+#: ../mkpasswd.c:246
+#, c-format
+msgid "Try '%s --help' for more information.\n"
+msgstr "尝试用 '%s --help' 获取更多的信息。\n"
+
+#: ../mkpasswd.c:292
+#, c-format
+msgid "Wrong salt length: %d byte when %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d expected.\n"
+msgstr[0] ""
+"错误的随即字符 ( salt ) 长度:当前为 %d 字节,预期长度为 %d 字节。\n"
+
+#: ../mkpasswd.c:297
+#, c-format
+msgid "Wrong salt length: %d byte when %d <= n <= %d expected.\n"
+msgid_plural "Wrong salt length: %d bytes when %d <= n <= %d expected.\n"
+msgstr[0] ""
+"错误的随机字符(salt) 长度: 当前为 %d 字节,预期长度范围为 %d <= n <= %d 字"
+"节。\n"
+
+#: ../mkpasswd.c:306
+#, c-format
+msgid "Illegal salt character '%c'.\n"
+msgstr "非法的随机数字符 '%c'。\n"
+
+#: ../mkpasswd.c:357 ../mkpasswd.c:370
+#, c-format
+msgid "Password: "
+msgstr "密码:"
+
+#: ../mkpasswd.c:389
+#, c-format
+msgid "Method not supported by crypt(3).\n"
+msgstr "不被 crypt(3) 支持的方法。\n"
+
+#: ../mkpasswd.c:497
+#, c-format
+msgid ""
+"Usage: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"Crypts the PASSWORD using crypt(3).\n"
+"\n"
+msgstr ""
+"用法: mkpasswd [OPTIONS]... [PASSWORD [SALT]]\n"
+"用 crypt(3) 加密 PASSWORD。\n"
+"\n"
+
+#: ../mkpasswd.c:500
+#, fuzzy, c-format
+msgid ""
+" -m, --method=TYPE select method TYPE\n"
+" -5 like --method=md5crypt\n"
+" -S, --salt=SALT use the specified SALT\n"
+msgstr ""
+" -m, --method=TYPE \t选择使用 TYPE 的方法\n"
+" -S, --salt=SALT \t\t使用指定随机字符\n"
+
+#: ../mkpasswd.c:505
+#, c-format
+msgid ""
+" -R, --rounds=NUMBER use the specified NUMBER of rounds\n"
+" -P, --password-fd=NUM read the password from file descriptor NUM\n"
+" instead of /dev/tty\n"
+" -s, --stdin like --password-fd=0\n"
+msgstr ""
+" -R, --rounds=NUMBER \t使用指定的循环次数 NUMBER\n"
+" -P, --password-fd=NUM \t从文件描述符 NUM 中读取密码来\n"
+"\t\t\t\t替代从 /dev/tty 中获取密码\n"
+" -s, --stdin \t\t同 --password-fd=0\n"
+
+#: ../mkpasswd.c:511
+#, c-format
+msgid ""
+" -h, --help display this help and exit\n"
+" -V, --version output version information and exit\n"
+"\n"
+"If PASSWORD is missing then it is asked interactively.\n"
+"If no SALT is specified, a random one is generated.\n"
+"If TYPE is 'help', available methods are printed.\n"
+"\n"
+"Report bugs to %s.\n"
+msgstr ""
+" -h, --help \t\t显示帮助信息并退出\n"
+" -V, --version \t\t输出版本信息并退出\n"
+"\n"
+"如果密码不存在,将会要求输入密码。\n"
+"如果未指定,将会随机生成一个SALT。\n"
+"如果类型是 'help',显示所有可用的方式。\n"
+"\n"
+"请将BUGS提交给 %s。\n"
+
+#: ../mkpasswd.c:534
+#, c-format
+msgid "Available methods:\n"
+msgstr "可用方式:\n"
diff --git a/ripe-mail b/ripe-mail
new file mode 100644
index 0000000..f1f40d0
--- /dev/null
+++ b/ripe-mail
@@ -0,0 +1,90 @@
+From ripe-dbm@ripe.net Mon Jan 27 10:09:59 2003
+Return-Path: <ripe-dbm@ripe.net>
+Delivered-To: md@wonderland.linux.it
+Received: from attila.bofh.it (localhost [127.0.0.1])
+ by wonderland.linux.it (Postfix/Md) with ESMTP id 582BA33CD5
+ for <md@wonderland.linux.it>; Mon, 27 Jan 2003 10:09:59 +0100 (CET)
+Received: from picard.linux.it (picard.linux.it [::ffff:62.177.1.107])
+ by attila.bofh.it (Postfix) with ESMTP id 46AE15F966
+ for <md@wonderland.linux.it>; Mon, 27 Jan 2003 09:03:25 +0100 (CET)
+Received: from birch.ripe.net (birch.ripe.net [::ffff:193.0.1.96])
+ by picard.linux.it (Postfix) with ESMTP id 4A76942B2
+ for <md@Linux.IT>; Mon, 27 Jan 2003 09:05:01 +0100 (CET)
+Received: from x24.ripe.net (x24.ripe.net [193.0.1.24])
+ by birch.ripe.net (8.12.5/8.11.6) with ESMTP id h0R83NAq030231;
+ Mon, 27 Jan 2003 09:03:23 +0100
+Received: (from ripe-dbm@localhost)
+ by x24.ripe.net (8.12.4/8.12.6) id h0R83M5k002263;
+ Mon, 27 Jan 2003 09:03:22 +0100
+Message-Id: <200301270803.h0R83M5k002263@x24.ripe.net>
+From: RIPE Database Administration <ripe-dbm@ripe.net>
+Cc: Can Bican <can@ripe.net>
+To: md@Linux.IT
+FCC: cur
+Subject: Re: NCC#2003013332 Re: [db-wg] IPv6 Whois update
+Reply-To: ripe-dbm@ripe.net
+X-Organization: RIPE Network Coordination Centre
+X-Phone: +31 20 535 4444
+X-Fax: +31 20 535 4341
+X-Mailer: BaT/0.67
+Sender: RIPE Database Manager <ripe-dbm@ripe.net>
+Date: Mon, 27 Jan 2003 09:03:21 +0100
+MIME-Version: 1.0
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+X-Spam-Status: No, hits=0.6 required=5.0
+ tests=DEAR_SOMEBODY,QUOTED_EMAIL_TEXT,SIGNATURE_SHORT_DENSE,
+ SPAM_PHRASE_05_08
+ version=2.43
+X-Spam-Level:
+Status: RO
+Content-Length: 1239
+Lines: 46
+
+
+Dear Marco d'Itri,
+
+For the month October, 2002:
+We had 55 milion queries, 4.3 milion done with your client.
+
+This number is probably not the best indicator as some IPs do a lot of
+queries so here are also the statistics for different IP addresses using
+your client:
+31364 (of 853385) different IP addresses used your client.
+
+If you have any more questions, please contact <ripe-dbm@ripe.net>.
+
+Regards,
+
+Tiago Antao
+____________________________
+RIPE Database Administration.
+
+
+
+Original message follows:
+------------------------
+
+On Thursday 23 January 2003 18:52, Marco d'Itri wrote:
+> On Jan 23, Can Bican <can@ripe.net> wrote:
+> >This is a feature we supported, and we'll keep supporting it. It's a
+> > mistake on our side that we'll change promptly, so please don't change
+> > the behaviour. We'll make the proxy accept -V switches of these types.
+>
+> Thank you for your prompt reply.
+> BTW, is any statistics about -V arguments available? I wonder how many
+> queries are made with my client (i.e. the -V argument matches /^Md/).
+
+ I have forwarded your request to ripe-dbm@ripe.net. You can contact that
+address if you'd like more/less specific requirements about the counts.
+
+ Regards,
+
+--
+Can Bican
+DB Group
+RIPE NCC
+
+
+
+
diff --git a/servers_charset_list b/servers_charset_list
new file mode 100644
index 0000000..fa85e4e
--- /dev/null
+++ b/servers_charset_list
@@ -0,0 +1,76 @@
+# server name charset optional parameters
+whois.cat utf-8 -C UTF-8
+whois.conac.cn utf-8
+whois.corenic.net utf-8 -C UTF-8
+whois.online.rs.corenic.net utf-8 -C UTF-8
+whois.site.rs.corenic.net utf-8 -C UTF-8
+whois.lacnic.net utf-8
+whois.museum utf-8 -C UTF-8
+whois.ripe.net iso-8859-1
+
+whois.nic.llyw.cymru utf-8
+whois.nic.gov.scot utf-8
+whois.nic.gov.wales utf-8
+
+whois.aeda.net.ae utf-8
+whois.nic.ar utf-8
+whois.ax utf-8
+whois.registro.br iso-8859-1
+whois.cira.ca utf-8
+whois.nic.ch utf-8
+whois.nic.cl utf-8
+whois.cnnic.cn utf-8
+cwhois.cnnic.cn utf-8
+whois.nic.cz utf-8
+whois.denic.de utf-8
+whois.enum.denic.de utf-8
+whois.dk-hostmaster.dk utf-8 --charset=utf-8
+whois.tld.ee utf-8
+whois.eu utf-8
+whois.fi iso-8859-1
+whois.nic.fo utf-8
+whois.nic.fr utf-8
+whois.hkirc.hk utf-8
+whois.nic.hr utf-8
+whois.nic.hu iso-8859-1
+whois.nic.ir utf-8
+whois.isnic.is iso-8859-1
+whois.nic.it utf-8
+whois.jprs.jp iso-2022-jp
+whois.nic.ad.jp iso-2022-jp
+whois.kg cp1251
+whois.nic.or.kr utf-8
+whois.kr utf-8
+whois.nic.kz utf-8
+whois.nic.li utf-8
+whois.domreg.lt utf-8
+whois.dns.lu iso-8859-1
+whois.marnet.mk utf-8
+whois.nic.mu utf-8
+whois.norid.no iso-8859-1
+whois.iis.nu utf-8
+whois.registry.om utf-8
+whois.registry.pf utf-8
+whois.dns.pt utf-8
+whois.registry.qa utf-8
+whois.nic.re utf-8
+whois.rnids.rs utf-8
+whois.nic.net.sa utf-8
+whois.iis.se utf-8
+whois.sgnic.sg utf-8
+whois.tld.sy utf-8
+whois.thains.co.th utf-8
+whois.ati.tn utf-8
+whois.trabis.gov.tr utf-8
+whois.twnic.net.tw utf-8
+whois.nic.ac.uk utf-8
+whois.gov.uk utf-8
+whois.biz.ua utf-8
+whois.co.ua utf-8
+whois.pp.ua utf-8
+whois.ua utf-8
+whois.nic.org.uy utf-8
+whois.nic.wf utf-8
+whois.nic.yt utf-8
+whois.nic.xn--otu796d utf-8
+
diff --git a/simple_recode.c b/simple_recode.c
new file mode 100644
index 0000000..5989bef
--- /dev/null
+++ b/simple_recode.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2009 by Marco d'Itri <md@linux.it>.
+ *
+ * simple_recode was inspired by a similar function found in Simon
+ * Josefsson's libidn.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <iconv.h>
+#include <langinfo.h>
+
+#include "utils.h"
+
+#include "simple_recode.h"
+
+/* Global variables */
+iconv_t simple_recode_iconv_handle;
+const char *simple_recode_input_charset;
+
+/*
+ * These value should be tuned to an acceptable compromise between memory
+ * usage and calling iconv(3) as few times as possible.
+ */
+#define SIMPLE_RECODE_BUFFER_SIZE_1 256
+#define SIMPLE_RECODE_BUFFER_SIZE_2 1024
+#define SIMPLE_RECODE_BUFFER_INCREMENT 1
+
+/*
+ * Convert a NULL-terminated string accordingly to the provided iconv(3)
+ * handle. The returned string is allocated using malloc(3) and needs to be
+ * deallocated by the caller.
+ * Incomplete, invalid and impossible to recode sequences are copied as-is.
+ * On failure, NULL is returned and errno is set.
+ */
+char *simple_recode(const iconv_t handle, const char *str)
+{
+ char *inp = (char *) str;
+ char *outp, *result;
+ size_t inbytes_remaining, outbytes_remaining, outbuf_size;
+
+ inbytes_remaining = strlen(inp);
+ if (inbytes_remaining + 1 <= SIMPLE_RECODE_BUFFER_SIZE_1
+ - (SIMPLE_RECODE_BUFFER_SIZE_1 >> SIMPLE_RECODE_BUFFER_INCREMENT))
+ outbuf_size = SIMPLE_RECODE_BUFFER_SIZE_1;
+ else
+ outbuf_size = inbytes_remaining + 1
+ + (inbytes_remaining >> SIMPLE_RECODE_BUFFER_INCREMENT);
+
+ outp = result = malloc(outbuf_size);
+ if (!result)
+ return NULL;
+ outbytes_remaining = outbuf_size - 1;
+
+ do {
+ size_t err = iconv(handle, &inp, &inbytes_remaining, &outp,
+ &outbytes_remaining);
+
+ if (err != (size_t) -1)
+ break; /* success */
+
+ switch (errno) {
+ case EINVAL: /* incomplete multibyte sequence */
+ case EILSEQ: /* invalid multibyte sequence */
+#ifdef SIMPLE_RECODE_SKIP_INVALID_SEQUENCES
+ /* recover from invalid input by replacing it with a '?' */
+ inp++;
+ *outp++ = '?'; /* use U+FFFD for unicode output? how? */
+#else
+ /* garbage in, garbage out */
+ *outp++ = *inp++;
+#endif
+ inbytes_remaining--;
+ outbytes_remaining--;
+ continue;
+
+ case E2BIG:
+ {
+ size_t used = outp - result;
+ size_t newsize;
+ char *new_result;
+
+ if (outbuf_size < SIMPLE_RECODE_BUFFER_SIZE_2)
+ newsize = SIMPLE_RECODE_BUFFER_SIZE_2;
+ else
+ newsize = outbuf_size
+ + (outbuf_size >> SIMPLE_RECODE_BUFFER_INCREMENT);
+
+ /* check if the newsize variable has overflowed */
+ if (newsize <= outbuf_size) {
+ free(result);
+ errno = ENOMEM;
+ return NULL;
+ }
+ outbuf_size = newsize;
+ new_result = realloc(result, outbuf_size);
+ if (!new_result) {
+ free(result);
+ return NULL;
+ }
+ result = new_result;
+
+ /* update the position in the new output stream */
+ outp = result + used;
+ outbytes_remaining = outbuf_size - used - 1;
+
+ continue;
+ }
+
+ default:
+ free(result);
+ return NULL;
+ }
+ } while (inbytes_remaining > 0);
+
+ *outp = '\0';
+
+ return result;
+}
+
+/*
+ * Like fputs(3), but transparently recodes s using the global variable
+ * simple_recode_input_charset as the input charset and the current locale
+ * as the output charset.
+ * If simple_recode_input_charset is NULL it just calls fputs(3).
+ * Exits with an error if iconv(3) or iconv_open(3) fail.
+ *
+ * Assumes that setlocale(3) has already been called.
+ *
+ * If appropriate, the iconv object referenced by the global variable
+ * simple_recode_iconv_handle should be deallocated with iconv_close(3).
+ */
+int recode_fputs(const char *s, FILE *stream)
+{
+ char *out;
+ int result;
+
+ if (simple_recode_input_charset == NULL) /* no conversion is needed */
+ return fputs(s, stream);
+
+ if (simple_recode_iconv_handle == NULL) {
+ simple_recode_iconv_handle = iconv_open(nl_langinfo(CODESET),
+ simple_recode_input_charset);
+ if (simple_recode_iconv_handle == (iconv_t) - 1)
+ err_sys("iconv_open");
+ }
+
+ out = simple_recode(simple_recode_iconv_handle, s);
+ if (!out)
+ err_sys("iconv");
+ result = fputs(out, stream);
+ free(out);
+
+ return result;
+}
+
+void simple_recode_iconv_close(void)
+{
+ if (simple_recode_iconv_handle == NULL)
+ return;
+
+ iconv_close(simple_recode_iconv_handle);
+ simple_recode_iconv_handle = NULL;
+ simple_recode_input_charset = NULL;
+}
+
diff --git a/simple_recode.h b/simple_recode.h
new file mode 100644
index 0000000..5fc95b0
--- /dev/null
+++ b/simple_recode.h
@@ -0,0 +1,14 @@
+#ifndef SIMPLE_RECODE_H
+#define SIMPLE_RECODE_H
+
+#include <iconv.h>
+#include <stdio.h>
+
+extern iconv_t simple_recode_iconv_handle;
+extern const char *simple_recode_input_charset;
+
+char *simple_recode(const iconv_t handle, const char *str);
+int recode_fputs(const char *s, FILE* stream);
+void simple_recode_iconv_close(void);
+
+#endif
diff --git a/tld_serv_list b/tld_serv_list
new file mode 100644
index 0000000..cb480da
--- /dev/null
+++ b/tld_serv_list
@@ -0,0 +1,432 @@
+# http://www.iana.org/domains/root/db/
+#
+# Domain names MUST be lowercase and MUST begin with "." or "-".
+# First match wins.
+# Elements in this list are matched against the end of the query.
+# "NIC?" means that I have not been able to find the registry.
+
+.br.com whois.centralnic.net
+.cn.com whois.centralnic.net
+.de.com whois.centralnic.net
+.eu.com whois.centralnic.net
+.gb.com whois.centralnic.net
+.gb.net whois.centralnic.net
+.gr.com whois.centralnic.net
+.hu.com whois.centralnic.net
+.in.net whois.centralnic.net
+.no.com whois.centralnic.net
+.qc.com whois.centralnic.net
+.ru.com whois.centralnic.net
+.sa.com whois.centralnic.net
+.se.com whois.centralnic.net
+.se.net whois.centralnic.net
+.uk.com whois.centralnic.net
+.uk.net whois.centralnic.net
+.us.com whois.centralnic.net
+.uy.com whois.centralnic.net
+.za.com whois.centralnic.net
+.jpn.com whois.centralnic.net
+.web.com whois.centralnic.net
+
+.com VERISIGN whois.verisign-grs.com
+
+.za.net whois.za.net
+.net VERISIGN whois.verisign-grs.com
+
+.eu.org whois.eu.org
+.za.org whois.za.org
+.org whois.pir.org
+
+# Technically these are SLDs of new gTLDs (hence listed in new_gtlds_list),
+# but the registrar (JISC) asked to add the servers for these
+# government-related domains.
+.llyw.cymru whois.nic.llyw.cymru
+.gov.scot whois.nic.gov.scot
+.gov.wales whois.nic.gov.wales
+
+.edu whois.educause.edu
+.gov whois.dotgov.gov
+.int whois.iana.org
+.mil NONE
+
+.e164.arpa whois.ripe.net
+.in-addr.arpa ARPA
+.ip6.arpa IP6
+.arpa whois.iana.org
+
+.aero whois.aero
+.asia whois.nic.asia
+.biz whois.nic.biz
+.cat whois.nic.cat
+.coop whois.nic.coop
+.info whois.afilias.net
+.jobs whois.nic.jobs
+.mobi whois.afilias.net
+.museum whois.nic.museum
+.name whois.nic.name
+.post whois.dotpostregistry.net
+.pro whois.nic.pro
+.tel whois.nic.tel
+.travel whois.nic.travel
+.xxx whois.nic.xxx
+
+.ac whois.nic.ac
+.ad NONE # www.nic.ad
+.ae whois.aeda.net.ae
+.af whois.nic.af
+.ag whois.nic.ag
+.ai whois.nic.ai
+.al NONE # www.akep.al
+.am whois.amnic.net
+.ao WEB https://www.dns.ao/ao/gca/index.php?id=19 # www.dns.ao
+.aq NONE # 2day.com
+.ar whois.nic.ar
+.as whois.nic.as
+.priv.at whois.nic.priv.at # "unofficial" SLD
+.at whois.nic.at
+.au whois.auda.org.au
+.aw whois.nic.aw
+.ax whois.ax # www.ax
+.gov.az WEB https://www.gov.az/
+.az WEB http://whois.az/
+.ba WEB http://www.nic.ba/stream/whois/
+.bb WEB http://whois.telecoms.gov.bb/search_domain.php
+.bd WEB https://bdia.btcl.com.bd/
+.be whois.dns.be
+.bf whois.registre.bf # http://www.arcep.bf/noms-de-domaine/
+.bg whois.register.bg
+.bh whois.nic.bh
+.bi whois1.nic.bi
+.bj whois.nic.bj
+#.bl
+.bm whois.afilias-srs.net
+.bn whois.bnnic.bn
+.bo whois.nic.bo
+#.bq
+.br whois.registro.br
+.bs NONE # http://www.register.bs/
+.bt WEB http://www.nic.bt/
+.bv NONE # http://www.norid.no/domenenavnbaser/bv-sj.html
+.by whois.cctld.by
+.bw whois.nic.net.bw
+.bz RECURSIVE whois.afilias-grs.info
+.co.ca whois.co.ca
+.ca whois.cira.ca
+.cc VERISIGN ccwhois.verisign-grs.com
+.cd whois.nic.cd
+.cf NONE
+.cg NONE # www.nic.cg
+.ch whois.nic.ch
+.ci whois.nic.ci
+.ck NONE
+.cl whois.nic.cl
+.cm whois.netcom.cm
+.edu.cn whois.edu.cn
+.cn whois.cnnic.cn
+.uk.co whois.uk.co
+.co whois.nic.co
+.cr whois.nic.cr
+.cu WEB http://www.nic.cu/
+.cv WEB http://www.dns.cv/
+.cw NONE # https://www.uoc.cw/cw-registry
+.cx whois.nic.cx
+.cy WEB https://www.nic.cy/cy-ui/home
+.cz whois.nic.cz
+.de whois.denic.de
+.dj NONE # http://www.dj/
+.dk whois.dk-hostmaster.dk
+.dm whois.dmdomains.dm
+.do whois.nic.do
+.dz whois.nic.dz
+.ec whois.nic.ec
+.ee whois.tld.ee
+.eg NONE # http://lookup.egregistry.eg/english.aspx
+#.eh
+.er NONE # http://www.afridns.org/er/tld_er.txt
+.es WEB https://www.nic.es/
+.et NONE # http://www.ethionet.et/
+.eu whois.eu
+.fi whois.fi
+.fj www.whois.fj
+.fk NONE # http://www.fidc.co.fk/
+.fm whois.nic.fm
+.fo whois.nic.fo
+.fr whois.nic.fr
+.ga WEB http://www.my.ga/en/whois.html
+.gb NONE
+.gd whois.nic.gd
+.ge whois.nic.ge
+.gf whois.mediaserv.net
+.gg whois.gg
+.gh whois.nic.gh
+.gi whois2.afilias-grs.net
+.gl whois.nic.gl
+.gm WEB http://www.nic.gm/htmlpages/whois.htm
+.gn NONE # http://www.psg.com/dns/gn/
+.gp whois.nic.gp
+.gq whois.dominio.gq
+.gr WEB https://grweb.ics.forth.gr/public/whois
+.gs whois.nic.gs
+.gt WEB http://www.gt/
+.gu NONE
+.gw WEB http://nic.gw/en/whois/
+.gy whois.registry.gy
+.hk whois.hkirc.hk
+.hm whois.registry.hm
+.hn whois.nic.hn
+.hr whois.dns.hr
+.ht whois.nic.ht
+.hu whois.nic.hu
+.id whois.id
+.ie whois.weare.ie
+.il whois.isoc.org.il
+.im whois.nic.im
+.in whois.registry.in
+.io whois.nic.io
+.iq whois.cmc.iq # http://www.cmc.iq/en/iq.html
+.ir whois.nic.ir
+.is whois.isnic.is
+.it whois.nic.it
+.je whois.je
+.jm NONE # http://myspot.mona.uwi.edu/mits/
+.jo WEB https://www.dns.jo/en.aspx
+.jp whois.jprs.jp
+.ke whois.kenic.or.ke
+.kg whois.kg
+.kh NONE # https://www.trc.gov.kh/en/offline-services/dns-registration/
+.ki whois.nic.ki
+.km NONE # www.domaine.km
+.kn whois.nic.kn
+.kp NONE # NIC? http://www.star.co.kp/
+.kr whois.kr
+.kw whois.nic.kw
+.ky whois.kyregistry.ky
+.kz whois.nic.kz
+.la whois.nic.la
+.lb whois.lbdr.org.lb
+.lc whois2.afilias-grs.net
+.li whois.nic.li
+.lk whois.nic.lk
+.lr NONE # http://www.psg.com/dns/lr/
+.ls whois.nic.ls
+.lt whois.domreg.lt
+.lu whois.dns.lu
+.lv whois.nic.lv
+.ly whois.nic.ly
+.ma whois.registre.ma
+.mc NONE # www.nic.mc
+.md whois.nic.md
+.me whois.nic.me # afilias
+#.mf
+.mg whois.nic.mg
+.mh NONE # www.nic.net.mh
+.mk whois.marnet.mk
+.ml whois.dot.ml # www.point.ml
+.mm whois.registry.gov.mm
+.mn whois.nic.mn
+.mo WEB http://www.monic.mo/ # whois.monic.mo is restricted
+.mp NONE # get.mp
+.mq whois.mediaserv.net
+.mr whois.nic.mr
+.ms whois.nic.ms
+.mt whois.nic.org.mt
+.mu whois.nic.mu
+.mv NONE # NIC? www.dhiraagu.com.mv
+.mw whois.nic.mw
+.mx whois.mx
+.my whois.mynic.my
+.mz whois.nic.mz
+.na whois.na-nic.com.na
+.nc whois.nc
+.ne NONE # NIC? http://www.intnet.ne
+.nf whois.nic.nf
+.ng whois.nic.net.ng
+.ni WEB http://www.nic.ni/
+.nl whois.domain-registry.nl
+.no whois.norid.no
+.np WEB https://register.com.np/whois-lookup
+.nr WEB http://www.cenpac.net.nr/dns/whois.html
+.nu whois.iis.nu
+.nz whois.irs.net.nz
+.om whois.registry.om
+.pa WEB http://www.nic.pa/
+.pe kero.yachay.pe
+.pf whois.registry.pf
+.pg NONE # http://www.unitech.ac.pg/
+.edu.ph WEB http://services.ph.net/dns/query.pl
+.gov.ph NONE # http://dns.gov.ph/
+.ph WEB https://whois.dot.ph/
+.pk whois.pknic.net.pk
+.co.pl whois.co.pl # "unofficial" SLD
+.pl whois.dns.pl
+.pm whois.nic.pm
+.pn WEB http://www.pitcairn.pn/PnRegistry/
+.pr whois.afilias-srs.net
+.ps whois.pnina.ps
+.pt whois.dns.pt
+.pw whois.nic.pw
+.py WEB https://www.nic.py/consultdompy.php
+.qa whois.registry.qa
+.re whois.nic.re
+.ro whois.rotld.ro
+.rs whois.rnids.rs
+.ac.ru whois.free.net
+.edu.ru whois.informika.ru
+.com.ru whois.flexireg.net
+.msk.ru whois.flexireg.net
+.net.ru whois.nic.net.ru
+.nov.ru whois.flexireg.net
+.org.ru whois.nic.net.ru
+.pp.ru whois.nic.net.ru
+.spb.ru whois.flexireg.net
+.ru whois.tcinet.ru
+.rw whois.ricta.org.rw # http://www.ricta.org.rw/
+.sa whois.nic.net.sa
+.sb whois.nic.net.sb
+.sc whois2.afilias-grs.net # www.nic.sc
+.sd whois.sdnic.sd
+.se whois.iis.se
+.sg whois.sgnic.sg
+.sh whois.nic.sh
+.si whois.register.si
+.sj NONE # http://www.norid.no/domenenavnbaser/bv-sj.html
+.sk whois.sk-nic.sk
+.sl whois.nic.sl
+.sm whois.nic.sm
+.sn whois.nic.sn
+.so whois.nic.so
+.sr NONE # www.register.sr
+.ss whois.nic.ss
+.st whois.nic.st
+.msk.su whois.flexireg.net
+.nov.su whois.flexireg.net
+.spb.su whois.flexireg.net
+.su whois.tcinet.ru
+.sv WEB http://www.svnet.org.sv/
+.sx whois.sx
+.sy whois.tld.sy
+.sz NONE # http://www.sispa.org.sz/
+.tc whois.nic.tc
+.td whois.nic.td
+.tf whois.nic.tf
+.tg whois.nic.tg
+.th whois.thnic.co.th
+.tj WEB http://www.nic.tj/whois.html
+.tk whois.dot.tk
+.tl whois.nic.tl
+.tm whois.nic.tm
+.tn whois.ati.tn
+.to whois.tonic.to
+.tr whois.trabis.gov.tr
+.tt WEB http://www.nic.tt/cgi-bin/search.pl
+.tv RECURSIVE whois.nic.tv
+.tw whois.twnic.net.tw
+.tz whois.tznic.or.tz
+.biz.ua whois.biz.ua
+.co.ua whois.co.ua
+.pp.ua whois.pp.ua
+.ua whois.ua
+.ug whois.co.ug
+.ac.uk whois.nic.ac.uk
+.bl.uk NONE
+.british-library.uk NONE
+.gov.uk whois.gov.uk
+.icnet.uk NONE
+.jet.uk NONE
+.mod.uk NONE
+.nhs.uk NONE
+.nls.uk NONE
+.parliament.uk NONE
+.police.uk NONE
+.uk whois.nic.uk
+#.um
+.fed.us whois.nic.gov
+.us whois.nic.us
+.com.uy WEB https://nic.com.uy/public/consulta-whois/acceder.action
+.uy whois.nic.org.uy
+.uz whois.cctld.uz
+.va NONE
+.vc whois2.afilias-grs.net
+.ve whois.nic.ve
+.vg whois.nic.vg
+.vi WEB https://secure.nic.vi/whois-lookup/
+.vn WEB http://www.vnnic.vn/en
+.vu whois.dnrs.vu
+.wf whois.nic.wf
+.ws whois.website.ws
+.ye NONE # NIC? http://www.y.net.ye/services/domain_name.htm
+.yt whois.nic.yt
+.ac.za whois.ac.za
+.alt.za whois.alt.za
+.co.za whois.registry.net.za
+.gov.za whois.gov.za
+.net.za net-whois.registry.net.za
+.org.za org-whois.registry.net.za
+.web.za web-whois.registry.net.za
+.za NONE # http://www.zadna.org.za/content/page/domain-information
+.zm whois.zicta.zm
+.zw NONE # http://www.zispa.co.zw/
+
+# AW means that I had to guess the whois server name, but I was not able
+# to find any registered subdomains to verify it.
+.xn--2scrj9c whois.registry.in # India
+.xn--3e0b707e whois.kr # Korea, Republic of
+.xn--3hcrj9c whois.registry.in # India
+.xn--45br5cyl whois.registry.in # India
+.xn--45brj9c whois.registry.in # India, Bengali
+.xn--4dbrk0ce whois.isoc.org.il # Israel
+.xn--54b7fta0cc NONE # Bangladesh
+.xn--80ao21a whois.nic.kz # Kazakhstan
+.xn--90a3ac whois.rnids.rs # Serbia
+.xn--90ae whois.imena.bg # Bulgaria
+.xn--90ais whois.cctld.by # Belarus
+.xn--clchc0ea0b2g2a9gcd whois.sgnic.sg # Singapore, Tamil
+.xn--d1alf whois.marnet.mk # Macedonia
+.xn--e1a4c whois.eu # European Union, Cyrillic
+.xn--fiqs8s cwhois.cnnic.cn # China, Simplified Chinese
+.xn--fiqz9s cwhois.cnnic.cn # China, Traditional Chinese
+.xn--fpcrj9c3d whois.registry.in # India, Telugu
+.xn--fzc2c9e2c whois.nic.lk # Sri Lanka, Sinhala
+.xn--gecrj9c whois.registry.in # India, Gujarati
+.xn--h2breg3eve whois.registry.in # India
+.xn--h2brj9c8c whois.registry.in # India
+.xn--h2brj9c whois.registry.in # India, Hindi
+.xn--j1amh whois.dotukr.com # Ukraine
+.xn--j6w193g whois.hkirc.hk # Hong Kong
+.xn--kprw13d whois.twnic.net.tw # Taiwan, Simplified Chinese
+.xn--kpry57d whois.twnic.net.tw # Taiwan, Traditional Chinese
+.xn--l1acc NONE # Mongolia
+.xn--lgbbat1ad8j whois.nic.dz # Algeria
+.xn--mgb9awbf whois.registry.om # Oman
+.xn--mgba3a4f16a whois.nic.ir # Iran
+.xn--mgbaam7a8h whois.aeda.net.ae # United Arab Emirates
+.xn--mgbah1a3hjkrd whois.nic.mr # Mauritania
+.xn--mgbai9azgqp6j NONE # Pakistan
+.xn--mgbayh7gpa WEB https://www.dns.jo/en.aspx # Jordan
+.xn--mgbbh1a71e whois.registry.in # India, Urdu
+.xn--mgbbh1a whois.registry.in # India
+.xn--mgbc0a9azcg NONE # Morocco
+.xn--mgbcpq6gpa1a NONE # Bahrain
+.xn--mgberp4a5d4ar whois.nic.net.sa # Saudi Arabia
+.xn--mgbgu82a whois.registry.in # India
+.xn--mgbpl2fh NONE # Sudan
+.xn--mgbtx2b whois.cmc.iq # Iraq
+.xn--mgbx4cd0ab whois.mynic.my # Malaysia AW
+.xn--mix891f WEB http://www.monic.mo/ # Macao
+.xn--node whois.itdc.ge # Georgia
+.xn--o3cw4h whois.thnic.co.th # Thailand
+.xn--ogbpf8fl whois.tld.sy # Syria
+.xn--p1ai whois.tcinet.ru # Russian Federation
+.xn--pgbs0dh whois.ati.tn # Tunisia
+.xn--q7ce6a whois.nic.la # Lao
+.xn--qxa6a whois.eu # European Union, Greek
+.xn--qxam WEB https://grweb.ics.forth.gr/public/whois # Greece
+.xn--rvc1e0am3e whois.registry.in # India
+.xn--s9brj9c whois.registry.in # India, Punjabi
+.xn--wgbh1c whois.dotmasr.eg # Egypt
+.xn--wgbl6a whois.registry.qa # Qatar
+.xn--xkc2al3hye2a whois.nic.lk # Sri Lanka, Tamil
+.xn--xkc2dl3a5ee0h whois.registry.in # India, Tamil
+.xn--y9a3aq whois.amnic.net # Armenia
+.xn--yfro4i67o whois.sgnic.sg # Singapore, Chinese
+.xn--ygbi2ammx whois.pnina.ps # Palestinian Territory
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..4ade650
--- /dev/null
+++ b/utils.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2008 by Marco d'Itri <md@linux.it>.
+ *
+ * do_nofail and merge_args come from the module-init-tools package.
+ * Copyright 2001 by Rusty Russell.
+ * Copyright 2002, 2003 by Rusty Russell, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* for strdup */
+#define _XOPEN_SOURCE 500
+
+/* System library */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+/* Application-specific */
+#include "utils.h"
+
+void *do_nofail(void *ptr, const char *file, const int line)
+{
+ if (ptr)
+ return ptr;
+
+ err_quit("Memory allocation failure at %s:%d.", file, line);
+}
+
+/* Prepend options from a string. */
+char **merge_args(char *args, char *argv[], int *argc)
+{
+ char *arg, *argstring;
+ char **newargs = NULL;
+ int i;
+ unsigned int num_env = 0;
+
+ if (!args)
+ return argv;
+
+ argstring = NOFAIL(strdup(args));
+ for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) {
+ num_env++;
+ newargs = NOFAIL(realloc(newargs,
+ sizeof(newargs[0]) * (num_env + *argc + 1)));
+ newargs[num_env] = arg;
+ }
+
+ if (!newargs)
+ return argv;
+
+ /* Append commandline args */
+ newargs[0] = argv[0];
+ for (i = 1; i <= *argc; i++)
+ newargs[num_env + i] = argv[i];
+
+ *argc += num_env;
+ return newargs;
+}
+
+/* Error routines */
+void NORETURN err_sys(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(errno));
+ va_end(ap);
+ exit(2);
+}
+
+void NORETURN err_quit(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ va_end(ap);
+ exit(2);
+}
+
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..32055b3
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,63 @@
+#ifndef WHOIS_UTILS_H
+#define WHOIS_UTILS_H
+
+/* Convenience macros */
+#define streq(a, b) (strcmp(a, b) == 0)
+#define strcaseeq(a, b) (strcasecmp(a, b) == 0)
+#define strneq(a, b, n) (strncmp(a, b, n) == 0)
+#define strncaseeq(a, b, n) (strncasecmp(a, b, n) == 0)
+
+#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__)
+
+#ifndef AFL_MODE
+# define AFL_MODE 0
+#endif
+
+/* Portability macros */
+#ifdef __GNUC__
+# define NORETURN __attribute__((noreturn))
+#else
+# define NORETURN
+#endif
+
+#ifndef AI_IDN
+# define AI_IDN 0
+#endif
+
+#ifndef AI_ADDRCONFIG
+# define AI_ADDRCONFIG 0
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+# define GETOPT_LONGISH(c, v, o, l, i) getopt_long(c, v, o, l, i)
+#else
+# define GETOPT_LONGISH(c, v, o, l, i) getopt(c, v, o)
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# include <locale.h>
+# define _(a) (gettext(a))
+# ifdef gettext_noop
+# define N_(a) gettext_noop(a)
+# else
+# define N_(a) (a)
+# endif
+#else
+# define _(a) (a)
+# define N_(a) (a)
+# define ngettext(a, b, c) ((c==1) ? (a) : (b))
+#endif
+
+#if defined IDN2_VERSION_NUMBER && IDN2_VERSION_NUMBER < 0x00140000
+# define IDN2_NONTRANSITIONAL IDN2_NFC_INPUT
+#endif
+
+/* Prototypes */
+void *do_nofail(void *ptr, const char *file, const int line);
+char **merge_args(char *args, char *argv[], int *argc);
+
+void NORETURN err_quit(const char *fmt, ...);
+void NORETURN err_sys(const char *fmt, ...);
+
+#endif
diff --git a/whois.1 b/whois.1
new file mode 100644
index 0000000..47119b8
--- /dev/null
+++ b/whois.1
@@ -0,0 +1,308 @@
+.TH "WHOIS" "1" "2019-12-30" "Marco d'Itri" "Debian GNU/Linux"
+.SH NAME
+whois \- client for the whois directory service
+.SH SYNOPSIS
+.B whois
+[
+.RB {\~ \-h \~|\~ \-\-host \~}
+.I HOST
+] [
+.RB {\~ \-p \~|\~ \-\-port \~}
+.I PORT
+] [\~\c
+.B \-abBcdGHIKlLmMrRx
+] [\~\c
+.BI \-g \~SOURCE:FIRST\-LAST
+] [\~\c
+.BR \-i \~
+.IR ATTR [, ATTR ]...\~]
+[\~\c
+.BR \-s \~
+.IR SOURCE [, SOURCE ]...\~]
+[\~\c
+.BR \-T \~
+.IR TYPE [, TYPE ]...\~]
+.RB [\~ \-\-verbose \~]
+.RB [\~ \-\-no-recursion \~]
+.I OBJECT
+
+.B whois
+.B \-q
+.I KEYWORD
+
+.B whois
+.B \-t
+.I TYPE
+
+.B whois
+.B \-v
+.I TYPE
+
+.B whois \-\-help
+
+.B whois \-\-version
+
+.PP
+.SH DESCRIPTION
+.B whois
+searches for an object in a
+.I RFC 3912
+database.
+.P
+This version of the whois client tries to guess the right server to
+ask for the specified object. If no guess can be made it will connect to
+.I whois.networksolutions.com
+for NIC handles or
+.I whois.arin.net
+for IPv4 addresses and network names.
+.PP
+.SH OPTIONS
+.TP 8
+.B \-h \c
+.IR HOST ", "\c
+.BI \-\-host= HOST
+Connect to
+.IR HOST .
+.TP 8
+.B \-H
+Do not display the legal disclaimers that some registries like to show you.
+.TP 8
+.B \-p \c
+.IR PORT ", "\c
+.BI \-\-port= PORT
+Connect to
+.IR PORT .
+.TP 8
+.B \-I
+First query
+.I whois.iana.org
+and then follow its referral to the
+whois server authoritative for that request. This works for IP addresses,
+AS numbers and domains.
+.BR BEWARE :
+this implies that the IANA server will receive your complete query.
+.TP 8
+.B \-\-no-recursion
+Disable recursion from registry to registrar servers.
+.TP 8
+.B \-\-verbose
+Be verbose.
+.TP 8
+.B \-\-help
+Display online help.
+.TP 8
+.B \-\-version
+Display the program version.
+.P
+Other options are flags understood by
+.I whois.ripe.net
+and some other
+RIPE-like servers:
+.TP 8
+.B \-a
+Also search all the mirrored databases.
+.TP 8
+.B \-b
+Return brief IP address ranges with abuse contact.
+.TP 8
+.B \-B
+Disable objects filtering. (Show the e-mail addresses.)
+.TP 8
+.B \-c
+Return the smallest IP address range with a reference to an irt object.
+.TP 8
+.B \-d
+Return the reverse DNS delegation object too.
+.TP 8
+.B \-g \c
+.I SOURCE:FIRST\-LAST
+Search updates from
+.I SOURCE
+database between
+.I FIRST
+and
+.I LAST
+update serial number. It is useful to obtain Near Real Time Mirroring stream.
+.TP 8
+.B \-G
+Disable grouping of associated objects.
+.TP 8
+.B \-i \c
+.I ATTR[,ATTR]...
+Inverse-search objects having associated attributes.
+.I ATTR
+is the attribute name, while the positional
+.I OBJECT
+argument is the attribute value.
+.TP 8
+.B \-K
+Return primary key attributes only. An exception is the
+.I members
+attribute of
+.I set
+objects, which is always returned. Another exception are all
+attributes of the objects
+.IR organisation ,
+.I person
+and
+.IR role ,
+that are never returned.
+.TP 8
+.B \-l
+Return the one level less specific object.
+.TP 8
+.B \-L
+Return all levels of less specific objects.
+.TP 8
+.B \-m
+Return all one level more specific objects.
+.TP 8
+.B \-M
+Return all levels of more specific objects.
+.TP 8
+.B \-q \c
+.I KEYWORD
+Return information about the server.
+.I KEYWORD
+can be
+.I version
+for the server version,
+.I sources
+for the list of database sources or
+.I types
+for the list of supported object types.
+.TP 8
+.B \-r
+Disable recursive lookups for contact information.
+.TP 8
+.B \-R
+Disable following referrals and force showing the object from the local copy
+in the server.
+.TP 8
+.B \-s \c
+.I SOURCE[,SOURCE]...
+Request the server to search for objects mirrored from
+.IR SOURCE .
+Sources are delimited by comma, and the order is significant.
+Use the
+.I -q sources
+parameter to obtain a list of valid sources.
+.TP 8
+.B \-t \c
+.I TYPE
+Return the template for a object of
+.IR TYPE .
+.TP 8
+.B \-T \c
+.I TYPE[,TYPE]...
+Restrict the search to objects of
+.IR TYPE .
+Multiple types are separated by a comma.
+.TP 8
+.B \-v \c
+.I TYPE
+Return the verbose template for a object of
+.IR TYPE .
+.TP 8
+.B \-x
+Search for only exact match on network address prefix.
+.SH NOTES
+When querying the Verisign gTLDs (e.g. .com, .net...) thin registry servers
+for a domain, the program will automatically prepend the
+.I domain
+keyword to only show domain records. The
+.I nameserver
+or
+.I registrar
+keywords must be used to show other kinds of records.
+.P
+When querying
+.I whois.arin.net
+for IPv4 or IPv6 networks, the CIDR
+netmask length will be automatically removed from the query string.
+.P
+When querying
+.I whois.nic.ad.jp
+for AS numbers, the program will automatically convert the request
+in the appropriate format, inserting a space after the string
+.IR AS .
+.P
+When querying
+.I whois.denic.de
+for domain names and no other
+flags have been specified, the program will automatically add the flag
+.IR "-T dn" .
+.P
+When querying
+.I whois.dk\-hostmaster.dk
+for domain names and no other
+flags have been specified, the program will automatically add the flag
+.IR "\-\-show\-handles" .
+.P
+RIPE-specific command line options are ignored when querying non-RIPE
+servers. This may or may not be the behaviour intended by the user.
+When using non-standard query parameters then the command line options
+which are not to be interpreted by the client must follow the
+.I \-\-
+separator (which marks the beginning of the query string).
+.P
+If the
+.I /etc/whois.conf
+configuration file exists, it will be consulted
+to find a server before applying the normal rules. Each line of the
+file should contain a regular expression to be matched against the query
+text and the whois server to use, separated by white space.
+IDN domains must use the ACE format.
+.P
+The whois protocol does not specify an encoding for characters which
+cannot be represented by ASCII and implementations vary wildly.
+If the program knows that a specific server uses a certain encoding,
+if needed it will transcode the server output to the encoding specified
+by the current system locale.
+.P
+Command line arguments will always be interpreted accordingly to the
+current system locale and converted to the IDN ASCII Compatible Encoding.
+.SH "FILES"
+/etc/whois.conf
+.SH "ENVIRONMENT"
+.IP LANG
+When querying
+.I whois.nic.ad.jp
+and
+.I whois.jprs.jp
+English text is requested unless the
+.I LANG
+or
+.I LC_MESSAGES
+environment variables specify a Japanese locale.
+.IP "WHOIS_OPTIONS"
+A list of options which will be evaluated before the ones specified on the
+command line.
+.IP "WHOIS_SERVER"
+This server will be queried if the program cannot guess where some kind
+of objects are located. If the variable does not exist then
+.I whois.arin.net
+will be queried.
+.SH "SEE ALSO"
+.IR whois.conf (5).
+.P
+.IR "RFC 3912" :
+WHOIS Protocol Specification.
+.P
+.IR "RIPE Database Query Reference Manual" :
+.RI < http://www.ripe.net/data\-tools/support/documentation/ripe\-database\-query\-reference\-manual >
+.SH BUGS
+The program may have buffer overflows in the command line parser:
+be sure to not pass untrusted data to it.
+It should be rewritten to use a dynamic strings library.
+.SH HISTORY
+This program closely tracks the user interface of the whois client
+developed at RIPE by Ambrose Magee and others on the base of the
+original BSD client.
+.SH AUTHOR
+.B Whois
+and this man page were written by Marco d'Itri
+.RI < md@linux.it >
+and are licensed under the terms of the GNU General Public License,
+version 2 or higher.
+
diff --git a/whois.bash b/whois.bash
new file mode 100644
index 0000000..1f7291f
--- /dev/null
+++ b/whois.bash
@@ -0,0 +1,86 @@
+_whois_query() {
+ "$1" -q "$2" 2>/dev/null | while read -r item _; do
+ [[ $item == %* ]] && continue
+ printf "%s\n" "${item%%:*}"
+ done
+}
+
+_whois_hosts() {
+ # _known_hosts_real from github.com/scop/bash-completion if available
+ if declare -f _known_hosts_real &>/dev/null; then
+ _known_hosts_real -- "$1"
+ return 0
+ fi
+ COMPREPLY=($(compgen -A hostname -- "$1"))
+}
+
+_whois() {
+
+ case $3 in
+ --help | --version | -p | --port | -i)
+ return 0
+ ;;
+ -h | --host)
+ _whois_hosts "$2"
+ return 0
+ ;;
+ -T | -t | -v)
+ [[ ${_whois_types-} ]] ||
+ _whois_types=" $(_whois_query "$1" types)"
+ COMPREPLY=($(compgen -W '$_whois_types' -- "$2"))
+ return 0
+ ;;
+ -s | -g)
+ [[ ${_whois_sources-} ]] ||
+ _whois_sources=" $(_whois_query "$1" sources)"
+ COMPREPLY=($(compgen -W '$_whois_sources' -- "$2"))
+ if [[ $3 == -g ]]; then
+ [[ ${#COMPREPLY[*]} -eq 1 ]] && COMPREPLY[0]+=:
+ compopt -o nospace
+ fi
+ return 0
+ ;;
+ -q)
+ COMPREPLY=($(compgen -W 'version sources types' -- "$2"))
+ return 0
+ ;;
+ esac
+
+ if [[ $2 == -* ]]; then
+ COMPREPLY=($(compgen -W '
+ -h --host
+ -p --port
+ -I
+ -H
+ --verbose
+ --no-recursion
+ --help
+ --version
+ -l
+ -L
+ -m
+ -M
+ -c
+ -x
+ -b
+ -B
+ -G
+ -d
+ -i
+ -T
+ -K
+ -r
+ -R
+ -a
+ -s
+ -g
+ -t
+ -v
+ -q
+ ' -- "$2"))
+ return 0
+ fi
+
+ _whois_hosts "$2"
+
+} && complete -F _whois whois
diff --git a/whois.c b/whois.c
new file mode 100644
index 0000000..cb9d4d0
--- /dev/null
+++ b/whois.c
@@ -0,0 +1,1549 @@
+/*
+ * Copyright (C) 1999-2022 Marco d'Itri <md@linux.it>.
+ *
+ * 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.
+ */
+
+/* for AI_IDN */
+#define _GNU_SOURCE
+
+/* System library */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include "config.h"
+#include <string.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#endif
+#ifdef HAVE_REGEXEC
+#include <regex.h>
+#endif
+#ifdef HAVE_LIBIDN2
+#include <idn2.h>
+#elif defined HAVE_LIBIDN
+#include <idna.h>
+#endif
+
+/* Application-specific */
+#include "version.h"
+#include "data.h"
+#include "whois.h"
+#include "utils.h"
+
+#ifdef HAVE_ICONV
+#include "simple_recode.h"
+#else
+#define recode_fputs(a, b) fputs(a, b)
+#endif
+
+/* hack */
+#define malloc(s) NOFAIL(malloc(s))
+#define realloc(p, s) NOFAIL(realloc(p, s))
+#ifdef strdup
+#undef strdup
+#define strdup(s) NOFAIL(__strdup(s))
+#else
+#define strdup(s) NOFAIL(strdup(s))
+#endif
+
+/* Global variables */
+int sockfd, verb = 0, no_recursion = 0;
+
+#ifdef ALWAYS_HIDE_DISCL
+int hide_discl = HIDE_NOT_STARTED;
+#else
+int hide_discl = HIDE_DISABLED;
+#endif
+
+const char *client_tag = IDSTRING;
+
+#ifndef HAVE_GETOPT_LONG
+extern char *optarg;
+extern int optind;
+#endif
+
+int main(int argc, char *argv[])
+{
+#ifdef HAVE_GETOPT_LONG
+ const struct option longopts[] = {
+ /* program flags */
+ {"version", no_argument, NULL, 1 },
+ {"verbose", no_argument, NULL, 2 },
+ {"help", no_argument, NULL, 3 },
+ {"no-recursion", no_argument, NULL, 4 },
+ {"server", required_argument, NULL, 'h'},
+ {"host", required_argument, NULL, 'h'},
+ {"port", required_argument, NULL, 'p'},
+ /* long RIPE flags */
+ {"exact", required_argument, NULL, 'x'},
+ {"all-more", required_argument, NULL, 'M'},
+ {"one-more", required_argument, NULL, 'm'},
+ {"all-less", required_argument, NULL, 'L'},
+ {"one-less", required_argument, NULL, 'l'},
+ {"reverse-domain", required_argument, NULL, 'd'},
+ {"irt", required_argument, NULL, 'c'},
+ {"abuse-contact", no_argument, NULL, 'b'},
+ {"brief", no_argument, NULL, 'F'},
+ {"primary-keys", no_argument, NULL, 'K'},
+ {"persistent-connection", no_argument, NULL, 'k'},
+ {"no-referenced", no_argument, NULL, 'r'},
+ {"no-filtering", no_argument, NULL, 'B'},
+ {"no-grouping", no_argument, NULL, 'G'},
+ {"select-types", required_argument, NULL, 'T'},
+ {"all-sources", no_argument, NULL, 'a'},
+ {"sources", required_argument, NULL, 's'},
+ {"types", no_argument, NULL, 12 }, /* -q */
+ {"ripe-version", no_argument, NULL, 12 }, /* -q */
+ {"list-sources", no_argument, NULL, 12 }, /* -q */
+ {"template", required_argument, NULL, 't'},
+ {"ripe-verbose", required_argument, NULL, 'v'},
+ /* long RIPE flags with no short equivalent */
+ {"list-versions", no_argument, NULL, 10 },
+ {"diff-versions", required_argument, NULL, 11 },
+ {"show-version", required_argument, NULL, 11 },
+ {"resource", no_argument, NULL, 10 },
+ {"show-personal", no_argument, NULL, 10 },
+ {"no-personal", no_argument, NULL, 10 },
+ {"show-tag-info", no_argument, NULL, 10 },
+ {"no-tag-info", no_argument, NULL, 10 },
+ {"filter-tag-include", required_argument, NULL, 11 },
+ {"filter-tag-exclude", required_argument, NULL, 11 },
+ {NULL, 0, NULL, 0 }
+ };
+ int longindex;
+#endif
+
+ int ch, nopar = 0;
+ size_t fstringlen = 64;
+ const char *server = NULL, *port = NULL;
+ char *qstring, *fstring;
+ int ret;
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
+ textdomain(NLS_CAT_NAME);
+#endif
+
+ fstring = malloc(fstringlen + 1);
+ *fstring = '\0';
+
+ /* interface for American Fuzzy Lop */
+ if (AFL_MODE) {
+ FILE *fp = fdopen(0, "r");
+ char *buf = NULL;
+ size_t len = 0;
+
+ /* read one line from stdin */
+ if (getline(&buf, &len, fp) < 0)
+ err_sys("getline");
+ fflush(fp);
+ /* and use it as command line arguments */
+ argv = merge_args(buf, argv, &argc);
+ }
+
+ /* prepend options from environment */
+ argv = merge_args(getenv("WHOIS_OPTIONS"), argv, &argc);
+
+ while ((ch = GETOPT_LONGISH(argc, argv,
+ "abBcdFg:Gh:Hi:IKlLmMp:q:rRs:t:T:v:V:x",
+ longopts, &longindex)) > 0) {
+ /* RIPE flags */
+ if (strchr(ripeflags, ch)) {
+ if (strlen(fstring) + 3 > fstringlen) {
+ fstringlen += 3;
+ fstring = realloc(fstring, fstringlen + 1);
+ }
+ sprintf(fstring + strlen(fstring), "-%c ", ch);
+ continue;
+ }
+ if (strchr(ripeflagsp, ch)) {
+ int flaglen = 3 + strlen(optarg) + 1;
+ if (strlen(fstring) + flaglen > fstringlen) {
+ fstringlen += flaglen;
+ fstring = realloc(fstring, fstringlen + 1);
+ }
+ sprintf(fstring + strlen(fstring), "-%c %s ", ch, optarg);
+ if (ch == 't' || ch == 'v' || ch == 'q')
+ nopar = 1;
+ continue;
+ }
+ switch (ch) {
+#ifdef HAVE_GETOPT_LONG
+ /* long RIPE flags with no short equivalent */
+ case 12:
+ nopar = 1;
+ /* fall through */
+ case 10:
+ {
+ int flaglen = 2 + strlen(longopts[longindex].name) + 1;
+ if (strlen(fstring) + flaglen > fstringlen) {
+ fstringlen += flaglen;
+ fstring = realloc(fstring, fstringlen + 1);
+ }
+ sprintf(fstring + strlen(fstring), "--%s ",
+ longopts[longindex].name);
+ }
+ break;
+ case 11:
+ {
+ int flaglen = 2 + strlen(longopts[longindex].name) + 1
+ + strlen(optarg) + 1;
+ if (strlen(fstring) + flaglen > fstringlen) {
+ fstringlen += flaglen;
+ fstring = realloc(fstring, fstringlen + 1);
+ }
+ sprintf(fstring + strlen(fstring), "--%s %s ",
+ longopts[longindex].name, optarg);
+ }
+ break;
+#endif
+ /* program flags */
+ case 'h':
+ server = strdup(optarg);
+ break;
+ case 'V':
+ client_tag = optarg;
+ break;
+ case 'H':
+ hide_discl = HIDE_NOT_STARTED; /* enable disclaimers hiding */
+ break;
+ case 'I':
+ server = strdup("\x0E");
+ break;
+ case 'p':
+ port = strdup(optarg);
+ break;
+ case 4:
+ no_recursion = 1;
+ break;
+ case 3:
+ usage(EXIT_SUCCESS);
+ case 2:
+ verb = 1;
+ break;
+ case 1:
+ fprintf(stdout, _("Version %s.\n\nReport bugs to %s.\n"),
+ VERSION, "<md+whois@linux.it>");
+ exit(EXIT_SUCCESS);
+ default:
+ usage(EXIT_FAILURE);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0 && !nopar) /* there is no parameter */
+ usage(EXIT_FAILURE);
+
+ /* On some systems realloc only works on non-NULL buffers */
+ /* I wish I could remember which ones they are... */
+ qstring = malloc(64);
+ *qstring = '\0';
+
+ /* parse other parameters, if any */
+ if (!nopar) {
+ int qstringlen = 0;
+
+ while (1) {
+ qstringlen += strlen(*argv) + 1;
+ qstring = realloc(qstring, qstringlen + 1);
+ strcat(qstring, *argv++);
+ if (argc == 1)
+ break;
+ strcat(qstring, " ");
+ argc--;
+ }
+ }
+
+ signal(SIGTERM, sighandler);
+ signal(SIGINT, sighandler);
+ signal(SIGALRM, alarm_handler);
+
+ if (getenv("WHOIS_HIDE"))
+ hide_discl = HIDE_NOT_STARTED;
+
+ /* -v or -t or long flags have been used */
+ if (!server && (!*qstring || *fstring))
+ server = strdup("whois.ripe.net");
+
+ if (*qstring) {
+ char *tmp = normalize_domain(qstring);
+ free(qstring);
+ qstring = tmp;
+ }
+
+#ifdef CONFIG_FILE
+ if (!server)
+ server = match_config_file(qstring);
+#endif
+
+ if (!server)
+ server = guess_server(qstring);
+
+ ret = handle_query(server, port, qstring, fstring);
+
+ exit(ret);
+}
+
+/*
+ * Server may be a server name from the command line, a server name got
+ * from guess_server or an encoded command/message from guess_server.
+ * This function has multiple memory leaks.
+ */
+int handle_query(const char *hserver, const char *hport,
+ const char *query, const char *flags)
+{
+ char *server = NULL, *port = NULL;
+ char *p, *query_string;
+
+ if (hport) {
+ server = strdup(hserver);
+ port = strdup(hport);
+ } else if (hserver[0] < ' ')
+ server = strdup(hserver);
+ else
+ split_server_port(hserver, &server, &port);
+
+ retry:
+ switch (server[0]) {
+ case 0:
+ if (!(server = getenv("WHOIS_SERVER")))
+ server = strdup(DEFAULTSERVER);
+ break;
+ case 1:
+ puts(_("This TLD has no whois server, but you can access the "
+ "whois database at"));
+ puts(server + 1);
+ return 1;
+ case 3:
+ puts(_("This TLD has no whois server."));
+ return 1;
+ case 5:
+ puts(_("No whois server is known for this kind of object."));
+ return 1;
+ case 6:
+ puts(_("Unknown AS number or IP network. Please upgrade this program."));
+ return 1;
+ case 4:
+ if (verb)
+ printf(_("Using server %s.\n"), server + 1);
+ sockfd = openconn(server + 1, NULL);
+ free(server);
+ server = query_crsnic(sockfd, query);
+ if (no_recursion)
+ server[0] = '\0';
+ break;
+ case 8:
+ if (verb)
+ printf(_("Using server %s.\n"), server + 1);
+ sockfd = openconn(server + 1, NULL);
+ free(server);
+ server = query_afilias(sockfd, query);
+ if (no_recursion)
+ server[0] = '\0';
+ break;
+ case 0x0A:
+ p = convert_6to4(query);
+ printf(_("\nQuerying for the IPv4 endpoint %s of a 6to4 IPv6 address.\n\n"), p);
+ free(server);
+ server = guess_server(p);
+ query = p;
+ goto retry;
+ case 0x0B:
+ p = convert_teredo(query);
+ printf(_("\nQuerying for the IPv4 endpoint %s of a Teredo IPv6 address.\n\n"), p);
+ free(server);
+ server = guess_server(p);
+ query = p;
+ goto retry;
+ case 0x0C:
+ p = convert_inaddr(query);
+ free(server);
+ server = guess_server(p);
+ free(p);
+ goto retry;
+ case 0x0D:
+ p = convert_in6arpa(query);
+ free(server);
+ server = guess_server(p);
+ free(p);
+ goto retry;
+ case 0x0E:
+ if (verb)
+ printf(_("Using server %s.\n"), "whois.iana.org");
+ sockfd = openconn("whois.iana.org", NULL);
+ free(server);
+ server = query_iana(sockfd, query);
+ break;
+ default:
+ break;
+ }
+
+ if (!server)
+ return 1;
+
+ if (*server == '\0')
+ return 0;
+
+ query_string = queryformat(server, flags, query);
+ if (verb) {
+ printf(_("Using server %s.\n"), server);
+ printf(_("Query string: \"%s\"\n\n"), query_string);
+ }
+
+ sockfd = openconn(server, port);
+
+ server = do_query(sockfd, query_string);
+ free(query_string);
+
+ /* recursion is fun */
+ if (!no_recursion && server && !strchr(query, ' ')) {
+ printf(_("\n\nFound a referral to %s.\n\n"), server);
+ handle_query(server, NULL, query, flags);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_FILE
+const char *match_config_file(const char *s)
+{
+ FILE *fp;
+ char buf[512];
+ static const char delim[] = " \t";
+
+ if ((fp = fopen(CONFIG_FILE, "r")) == NULL) {
+ if (errno != ENOENT)
+ err_sys("Cannot open " CONFIG_FILE);
+ return NULL;
+ }
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ char *p;
+ const char *pattern, *server;
+#ifdef HAVE_REGEXEC
+ int i;
+ regex_t re;
+#endif
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+
+ p = buf;
+ while (*p == ' ' || *p == '\t') /* eat leading blanks */
+ p++;
+ if (!*p)
+ continue; /* skip empty lines */
+ if (*p == '#')
+ continue; /* skip comments */
+
+ pattern = strtok(p, delim);
+ server = strtok(NULL, delim);
+ if (!pattern || !server)
+ err_quit(_("Cannot parse this line: %s"), p);
+ p = strtok(NULL, delim);
+ if (p)
+ err_quit(_("Cannot parse this line: %s"), p);
+
+#ifdef HAVE_REGEXEC
+ i = regcomp(&re, pattern, REG_EXTENDED | REG_ICASE | REG_NOSUB);
+ if (i != 0) {
+ char m[1024];
+ regerror(i, &re, m, sizeof(m));
+ err_quit("Invalid regular expression '%s': %s", pattern, m);
+ }
+
+ i = regexec(&re, s, 0, NULL, 0);
+ if (i == 0) {
+ regfree(&re);
+ fclose(fp);
+ return strdup(server);
+ }
+ if (i != REG_NOMATCH) {
+ char m[1024];
+ regerror(i, &re, m, sizeof(m));
+ err_quit("regexec: %s", m);
+ }
+ regfree(&re);
+#else
+ if (endstrcaseeq(s, pattern)) {
+ fclose(fp);
+ return strdup(server);
+ }
+#endif
+ }
+ fclose(fp);
+ return NULL;
+}
+#endif
+
+/* Parses an user-supplied string and tries to guess the right whois server.
+ * Returns a dynamically allocated buffer.
+ */
+char *guess_server(const char *s)
+{
+ unsigned long ip, as32;
+ unsigned int i;
+ const char *colon, *tld;
+
+ /* IPv6 address */
+ if ((colon = strchr(s, ':'))) {
+ unsigned long v6prefix, v6net;
+
+ /* RPSL hierarchical objects */
+ if (strncaseeq(s, "as", 2)) {
+ if (isasciidigit(s[2]))
+ return strdup(whereas(atol(s + 2)));
+ else
+ return strdup("");
+ }
+
+ v6prefix = strtol(s, NULL, 16);
+
+ if (v6prefix == 0)
+ return strdup("\x05"); /* unknown */
+
+ v6net = (v6prefix << 16) + strtol(colon + 1, NULL, 16);/* second u16 */
+
+ for (i = 0; ip6_assign[i].serv; i++) {
+ if ((v6net & (~0UL << (32 - ip6_assign[i].masklen)))
+ == ip6_assign[i].net)
+ return strdup(ip6_assign[i].serv);
+ }
+
+ return strdup("\x06"); /* unknown allocation */
+ }
+
+ /* email address */
+ if (strchr(s, '@'))
+ return strdup("\x05");
+
+ if (!strpbrk(s, ".")) {
+ /* if it is a TLD or a new gTLD then ask IANA */
+ for (i = 0; tld_serv[i]; i += 2)
+ if (strcaseeq(s, tld_serv[i]))
+ return strdup("whois.iana.org");
+
+ for (i = 0; new_gtlds[i]; i++)
+ if (strcaseeq(s, new_gtlds[i]))
+ return strdup("whois.iana.org");
+ }
+
+ /* no dot and no hyphen means it's a NSI NIC handle or ASN (?) */
+ if (!strpbrk(s, ".-")) {
+ if (strncaseeq(s, "as", 2) && /* it's an AS */
+ (isasciidigit(s[2]) || s[2] == ' '))
+ return strdup(whereas(atol(s + 2)));
+ if (*s == '!') /* NSI NIC handle */
+ return strdup("whois.networksolutions.com");
+ else
+ return strdup("\x05"); /* probably a unknown kind of nic handle */
+ }
+
+ /* ASN32? */
+ if (strncaseeq(s, "as", 2) && s[2] && (as32 = asn32_to_long(s + 2)) != 0)
+ return strdup(whereas32(as32));
+
+ /* smells like an IP? */
+ if ((ip = myinet_aton(s))) {
+ for (i = 0; ip_assign[i].serv; i++)
+ if ((ip & ip_assign[i].mask) == ip_assign[i].net)
+ return strdup(ip_assign[i].serv);
+ return strdup("\x05"); /* not in the unicast IPv4 space */
+ }
+
+ /* check the TLDs list */
+ for (i = 0; tld_serv[i]; i += 2)
+ if (in_domain(s, tld_serv[i]))
+ return strdup(tld_serv[i + 1]);
+
+ /* use the default server name for "new" gTLDs */
+ if ((tld = is_new_gtld(s))) {
+ char *server = malloc(strlen("whois.nic.") + strlen(tld) + 1);
+ strcpy(server, "whois.nic.");
+ strcat(server, tld);
+ return server;
+ }
+
+ /* no dot but hyphen */
+ if (!strchr(s, '.')) {
+ /* search for strings at the start of the word */
+ for (i = 0; nic_handles[i]; i += 2)
+ if (strncaseeq(s, nic_handles[i], strlen(nic_handles[i])))
+ return strdup(nic_handles[i + 1]);
+
+ /* search for strings at the end of the word */
+ for (i = 0; nic_handles_post[i]; i += 2)
+ if (endstrcaseeq(s, nic_handles_post[i]))
+ return strdup(nic_handles_post[i + 1]);
+
+ /* it's probably a network name */
+ return strdup("");
+ }
+
+ /* has dot and maybe a hyphen and it's not in tld_serv[], WTF is it? */
+ /* either a TLD or a NIC handle we don't know about yet */
+ return strdup("\x05");
+}
+
+const char *whereas32(const unsigned long asn)
+{
+ int i;
+
+ for (i = 0; as32_assign[i].serv; i++)
+ if (asn >= as32_assign[i].first && asn <= as32_assign[i].last)
+ return as32_assign[i].serv;
+ return "\x06";
+}
+
+const char *whereas(const unsigned long asn)
+{
+ int i;
+
+ if (asn > 65535)
+ return whereas32(asn);
+
+ for (i = 0; as_assign[i].serv; i++)
+ if (asn >= as_assign[i].first && asn <= as_assign[i].last)
+ return as_assign[i].serv;
+ return "\x06";
+}
+
+/*
+ * Construct the query string.
+ * Determines the server character set as a side effect.
+ * Returns a malloc'ed string which needs to be freed by the caller.
+ */
+char *queryformat(const char *server, const char *flags, const char *query)
+{
+ char *buf;
+ int i, isripe = 0;
+
+ /* 64 bytes reserved for server-specific flags added later */
+ buf = malloc(strlen(flags) + strlen(query) + strlen(client_tag) + 64);
+ *buf = '\0';
+
+ for (i = 0; ripe_servers[i]; i++)
+ if (streq(server, ripe_servers[i])) {
+ sprintf(buf + strlen(buf), "-V %s ", client_tag);
+ isripe = 1;
+ break;
+ }
+
+ if (*flags) {
+ if (!isripe)
+ puts(_("Warning: RIPE flags used with a traditional server."));
+ strcat(buf, flags);
+ }
+
+#ifdef HAVE_ICONV
+ simple_recode_iconv_close();
+ for (i = 0; servers_charset[i].name; i++)
+ if (streq(server, servers_charset[i].name)) {
+ simple_recode_input_charset = servers_charset[i].charset;
+ if (servers_charset[i].options) {
+ strcat(buf, servers_charset[i].options);
+ strcat(buf, " ");
+ }
+ break;
+ }
+
+ /* Use UTF-8 by default for "new" gTLDs */
+ if (!simple_recode_input_charset && /* was not in the database */
+ !strchr(query, ' ') && /* and has no parameters */
+ is_new_gtld(query)) /* and is a "new" gTLD: */
+ simple_recode_input_charset = "utf-8"; /* then try UTF-8 */
+#endif
+
+#if defined HAVE_LIBIDN || defined HAVE_LIBIDN2
+# define DENIC_PARAM_ACE ",ace"
+#else
+# define DENIC_PARAM_ACE ""
+#endif
+#ifdef HAVE_ICONV
+# define DENIC_PARAM_CHARSET ""
+#else
+# define DENIC_PARAM_CHARSET " -C US-ASCII"
+#endif
+
+ /* add useful default flags if there are no flags or multiple arguments */
+ if (isripe) { }
+ else if (strchr(query, ' ') || *flags) { }
+ else if (streq(server, "whois.denic.de") && in_domain(query, "de"))
+ strcat(buf, "-T dn" DENIC_PARAM_ACE DENIC_PARAM_CHARSET " ");
+ else if (streq(server, "whois.dk-hostmaster.dk") && in_domain(query, "dk"))
+ strcat(buf, "--show-handles ");
+
+ /* mangle and add the query string */
+ if (!isripe && streq(server, "whois.nic.ad.jp") &&
+ strncaseeq(query, "AS", 2) && isasciidigit(query[2])) {
+ strcat(buf, "AS ");
+ strcat(buf, query + 2);
+ }
+ else if (!isripe && streq(server, "whois.arin.net") &&
+ !strrchr(query, ' ')) {
+ if (strncaseeq(query, "AS", 2) && isasciidigit(query[2])) {
+ strcat(buf, "a ");
+ strcat(buf, query + 2);
+ } else if (myinet_aton(query) || strchr(query, ':')) {
+ if (strchr(query, '/'))
+ strcat(buf, "r + = ");
+ else
+ strcat(buf, "n + ");
+ strcat(buf, query);
+ } else
+ strcat(buf, query);
+ }
+ else
+ strcat(buf, query);
+
+ /* ask for english text */
+ if (!isripe && (streq(server, "whois.nic.ad.jp") ||
+ streq(server, "whois.jprs.jp")) && japanese_locale())
+ strcat(buf, "/e");
+
+ return buf;
+}
+
+/* the first parameter contains the state of this simple state machine:
+ * HIDE_DISABLED: hidden text finished
+ * HIDE_NOT_STARTED: hidden text not seen yet
+ * >= 0: currently hiding message hide_strings[*hiding]
+ */
+int hide_line(int *hiding, const char *const line)
+{
+ int i;
+
+ if (*hiding == HIDE_TO_THE_END) {
+ return 1;
+ } else if (*hiding == HIDE_DISABLED) {
+ return 0;
+ } else if (*hiding == HIDE_NOT_STARTED) { /* looking for smtng to hide */
+ for (i = 0; hide_strings[i] != NULL; i += 2) {
+ if (strneq(line, hide_strings[i], strlen(hide_strings[i]))) {
+ if (hide_strings[i + 1] == NULL)
+ *hiding = HIDE_TO_THE_END; /* all the remaining output */
+ else
+ *hiding = i; /* start hiding */
+ return 1; /* and hide this line */
+ }
+ }
+ return 0; /* don't hide this line */
+ } else if (*hiding > HIDE_NOT_STARTED) { /* hiding something */
+ if (*hide_strings[*hiding + 1] == '\0') { /*look for a blank line?*/
+ if (*line == '\n' || *line == '\r' || *line == '\0') {
+ *hiding = HIDE_NOT_STARTED; /* stop hiding */
+ return 0; /* but do not hide the blank line */
+ }
+ } else { /*look for a matching string*/
+ if (strneq(line, hide_strings[*hiding + 1],
+ strlen(hide_strings[*hiding + 1]))) {
+ *hiding = HIDE_NOT_STARTED; /* stop hiding */
+ return 1; /* but hide the last line */
+ }
+ }
+ return 1; /* we are hiding, so do it */
+ } else
+ return 0;
+}
+
+/* returns a string which should be freed by the caller, or NULL */
+char *do_query(const int sock, const char *query)
+{
+ char *temp, *p, buf[2000];
+ FILE *fi;
+ int hide = hide_discl;
+ char *referral_server = NULL;
+
+ temp = malloc(strlen(query) + 2 + 1);
+ strcpy(temp, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ free(temp);
+
+ while (fgets(buf, sizeof(buf), fi)) {
+ /* 6bone-style referral:
+ * % referto: whois -h whois.arin.net -p 43 as 1
+ */
+ if (!referral_server && strneq(buf, "% referto:", 10)) {
+ char nh[256], np[16], nq[1024];
+
+ if (sscanf(buf, REFERTO_FORMAT, nh, np, nq) == 3) {
+ /* XXX we are ignoring the new query string */
+ referral_server = malloc(strlen(nh) + 1 + strlen(np) + 1);
+ sprintf(referral_server, "%s:%s", nh, np);
+ }
+ }
+
+ /* ARIN referrals:
+ * ReferralServer: rwhois://rwhois.fuse.net:4321/
+ * ReferralServer: whois://whois.ripe.net
+ */
+ if (!referral_server && strneq(buf, "ReferralServer:", 15)) {
+ if ((p = strstr(buf, "rwhois://")))
+ referral_server = strdup(p + 9);
+ else if ((p = strstr(buf, "whois://")))
+ referral_server = strdup(p + 8);
+ if (referral_server && (p = strpbrk(referral_server, "/\r\n")))
+ *p = '\0';
+ }
+
+ if (hide_line(&hide, buf))
+ continue;
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+ recode_fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+
+ if (ferror(fi))
+ err_sys("fgets");
+ fclose(fi);
+
+ if (hide > HIDE_NOT_STARTED && hide != HIDE_TO_THE_END)
+ err_quit(_("Catastrophic error: disclaimer text has been changed.\n"
+ "Please upgrade this program.\n"));
+
+ return referral_server;
+}
+
+char *query_crsnic(const int sock, const char *query)
+{
+ char *temp, *p, buf[2000];
+ FILE *fi;
+ int hide = hide_discl;
+ char *referral_server = NULL;
+ int state = 0;
+ int dotscount = 0;
+
+ temp = malloc(strlen("domain ") + strlen(query) + 2 + 1);
+ *temp = '\0';
+
+ /* if this has more than one dot then it is a name server */
+ for (p = (char *) query; *p != '\0'; p++)
+ if (*p == '.')
+ dotscount++;
+
+ if (dotscount == 1 && !strpbrk(query, "=~ "))
+ strcpy(temp, "domain ");
+ strcat(temp, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ free(temp);
+
+ while (fgets(buf, sizeof(buf), fi)) {
+ /* If there are multiple matches only the server of the first record
+ is queried */
+ if (state == 0 && strneq(buf, " Domain Name:", 15))
+ state = 1;
+ if (state == 0 && strneq(buf, " Server Name:", 15)) {
+ referral_server = strdup("");
+ state = 2;
+ }
+ if (state == 1 && strneq(buf, " Registrar WHOIS Server:", 26)) {
+ for (p = buf; *p != ':'; p++); /* skip until the colon */
+ for (p++; *p == ' '; p++); /* skip the spaces */
+ referral_server = strdup(p);
+ if ((p = strpbrk(referral_server, "\r\n ")))
+ *p = '\0';
+ state = 2;
+ }
+
+ /* the output must not be hidden or no data will be shown for
+ host records and not-existing domains */
+ if (hide_line(&hide, buf))
+ continue;
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+ recode_fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+
+ if (ferror(fi))
+ err_sys("fgets");
+ fclose(fi);
+
+ return referral_server;
+}
+
+char *query_afilias(const int sock, const char *query)
+{
+ char *temp, *p, buf[2000];
+ FILE *fi;
+ int hide = hide_discl;
+ char *referral_server = NULL;
+ int state = 0;
+
+ temp = malloc(strlen(query) + 2 + 1);
+ strcpy(temp, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ free(temp);
+
+ while (fgets(buf, sizeof(buf), fi)) {
+ /* If multiple attributes are returned then use the first result.
+ This is not supposed to happen. */
+ if (state == 0 && strneq(buf, "Domain Name:", 12))
+ state = 1;
+ if (state == 1 && strneq(buf, "Registrar WHOIS Server:", 23)) {
+ for (p = buf; *p != ':'; p++); /* skip until colon */
+ for (p++; *p == ' '; p++); /* skip colon and spaces */
+ referral_server = strdup(p);
+ if ((p = strpbrk(referral_server, "\r\n ")))
+ *p = '\0';
+ state = 2;
+ }
+
+ /* the output must not be hidden or no data will be shown for
+ host records and not-existing domains */
+ if (hide_line(&hide, buf))
+ continue;
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+ recode_fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+
+ if (ferror(fi))
+ err_sys("fgets");
+ fclose(fi);
+
+ if (hide > HIDE_NOT_STARTED && hide != HIDE_TO_THE_END)
+ err_quit(_("Catastrophic error: disclaimer text has been changed.\n"
+ "Please upgrade this program.\n"));
+
+ return referral_server;
+}
+
+char *query_iana(const int sock, const char *query)
+{
+ char *temp, *p, buf[2000];
+ FILE *fi;
+ char *referral_server = NULL;
+ int state = 0;
+
+ temp = malloc(strlen(query) + 2 + 1);
+ strcpy(temp, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ free(temp);
+
+ while (fgets(buf, sizeof(buf), fi)) {
+ /* If multiple attributes are returned then use the first result.
+ This is not supposed to happen. */
+ if (state == 0 && strneq(buf, "refer:", 6)) {
+ for (p = buf; *p != ':'; p++); /* skip until colon */
+ for (p++; *p == ' '; p++); /* skip colon and spaces */
+ referral_server = strdup(p);
+ if ((p = strpbrk(referral_server, "\r\n ")))
+ *p = '\0';
+ state = 2;
+ }
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+ recode_fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+
+ if (ferror(fi))
+ err_sys("fgets");
+ fclose(fi);
+
+ return referral_server;
+}
+
+int openconn(const char *server, const char *port)
+{
+ int fd = -1;
+ int timeout = 10;
+#ifdef HAVE_GETADDRINFO
+ int err;
+ struct addrinfo hints, *res, *ai;
+#else
+ struct hostent *hostinfo;
+ struct servent *servinfo;
+ struct sockaddr_in saddr;
+#endif
+
+ /*
+ * When using American Fuzzy Lop get the data from it using stdin
+ * instead of connecting to the actual whois server.
+ */
+ if (AFL_MODE)
+ return dup(0);
+
+ alarm(60);
+
+#ifdef HAVE_GETADDRINFO
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_ADDRCONFIG;
+ hints.ai_flags |= AI_IDN;
+
+ if ((err = getaddrinfo(server, port ? port : "nicname", &hints, &res))
+ != 0) {
+ if (err == EAI_SYSTEM)
+ err_sys("getaddrinfo(%s)", server);
+ else
+ err_quit("getaddrinfo(%s): %s", server, gai_strerror(err));
+ }
+
+ for (ai = res; ai; ai = ai->ai_next) {
+ /* no timeout for the last address. is this a good idea? */
+ if (!ai->ai_next)
+ timeout = 0;
+ if ((fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
+ continue; /* ignore */
+ if (connect_with_timeout(fd, (struct sockaddr *)ai->ai_addr,
+ ai->ai_addrlen, timeout) == 0)
+ break; /* success */
+ close(fd);
+ }
+ freeaddrinfo(res);
+
+ if (!ai)
+ err_sys("connect");
+#else
+ if ((hostinfo = gethostbyname(server)) == NULL)
+ err_quit(_("Host %s not found."), server);
+ if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
+ err_sys("socket");
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
+ saddr.sin_family = AF_INET;
+ if (!port) {
+ saddr.sin_port = htons(43);
+ } else if ((saddr.sin_port = htons(atoi(port))) == 0) {
+ if ((servinfo = getservbyname(port, "tcp")) == NULL)
+ err_quit(_("%s/tcp: unknown service"), port);
+ saddr.sin_port = servinfo->s_port;
+ }
+ if (connect_with_timeout(fd, (struct sockaddr *)&saddr, sizeof(saddr),
+ timeout) < 0)
+ err_sys("connect");
+#endif
+
+ return fd;
+}
+
+int connect_with_timeout(int fd, const struct sockaddr *addr,
+ socklen_t addrlen, int timeout)
+{
+ int savedflags, rc, connect_errno, opt;
+ unsigned int len;
+ fd_set fd_w;
+ struct timeval tv;
+
+ if (timeout <= 0)
+ return connect(fd, addr, addrlen);
+
+ if ((savedflags = fcntl(fd, F_GETFL, 0)) < 0)
+ return -1;
+
+ /* set the socket non-blocking, so connect(2) will return immediately */
+ if (fcntl(fd, F_SETFL, savedflags | O_NONBLOCK) < 0)
+ return -1;
+
+ rc = connect(fd, addr, addrlen);
+
+ /* set the socket to block again */
+ connect_errno = errno;
+ if (fcntl(fd, F_SETFL, savedflags) < 0)
+ return -1;
+ errno = connect_errno;
+
+ if (rc == 0 || errno != EINPROGRESS)
+ return rc;
+
+ FD_ZERO(&fd_w);
+ FD_SET(fd, &fd_w);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ /* loop until an error or the timeout has expired */
+ do {
+ rc = select(fd + 1, NULL, &fd_w, NULL, &tv);
+ } while (rc == -1 && errno == EINTR);
+
+ if (rc == 0) { /* timed out */
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (rc < 0 || rc > 1) /* select failed */
+ return rc;
+
+ /* rc == 1: success. check for errors */
+ len = sizeof(opt);
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &len) < 0)
+ return -1;
+
+ /* and report them */
+ if (opt != 0) {
+ errno = opt;
+ return -1;
+ }
+
+ return 0;
+}
+
+void NORETURN alarm_handler(int signum)
+{
+ close(sockfd);
+ err_quit(_("Timeout."));
+}
+
+void NORETURN sighandler(int signum)
+{
+ close(sockfd);
+ err_quit(_("Interrupted by signal %d..."), signum);
+}
+
+int japanese_locale(void)
+{
+ char *lang;
+
+ lang = getenv("LC_MESSAGES");
+ if (lang) {
+ if (strneq(lang, "ja", 2))
+ return 0;
+ return 1;
+ }
+
+ lang = getenv("LANG");
+ if (lang && strneq(lang, "ja", 2))
+ return 0;
+ return 1;
+}
+
+/* check if dom ends with tld */
+int endstrcaseeq(const char *dom, const char *tld)
+{
+ size_t dom_len, tld_len;
+ const char *p = NULL;
+
+ if ((dom_len = strlen(dom)) == 0)
+ return 0;
+
+ if ((tld_len = strlen(tld)) == 0)
+ return 0;
+
+ /* dom cannot be shorter than what we are looking for */
+ if (tld_len > dom_len)
+ return 0;
+
+ p = dom + dom_len - tld_len;
+
+ return strcaseeq(p, tld);
+}
+
+/* check if dom is a subdomain of tld */
+int in_domain(const char *dom, const char *tld)
+{
+ size_t dom_len, tld_len;
+ const char *p = NULL;
+
+ if ((dom_len = strlen(dom)) == 0)
+ return 0;
+
+ if ((tld_len = strlen(tld)) == 0)
+ return 0;
+
+ /* dom cannot be shorter than what we are looking for */
+ /* -1 to ignore dom containing just a dot and tld */
+ if (tld_len >= dom_len - 1)
+ return 0;
+
+ p = dom + dom_len - tld_len;
+
+ /* fail if the character before tld is not a dot */
+ if (*(p - 1) != '.')
+ return 0;
+
+ return strcaseeq(p, tld);
+}
+
+const char *is_new_gtld(const char *s)
+{
+ int i;
+
+ for (i = 0; new_gtlds[i]; i++)
+ if (in_domain(s, new_gtlds[i]))
+ return new_gtlds[i];
+
+ return NULL;
+}
+
+/*
+ * Attempt to normalize a query by removing trailing dots and whitespace,
+ * then convert the domain to punycode.
+ * The function assumes that the domain is the last token of the query.
+ * Returns a malloc'ed string which needs to be freed by the caller.
+ */
+char *normalize_domain(const char *dom)
+{
+ char *p, *ret;
+#if defined HAVE_LIBIDN || defined HAVE_LIBIDN2
+ char *domain_start = NULL;
+#endif
+
+ ret = strdup(dom);
+ /* start from the last character */
+ p = ret + strlen(ret) - 1;
+ /* and then eat trailing dots and blanks */
+ while (p > ret) {
+ if (!(*p == '.' || *p == ' ' || *p == '\t'))
+ break;
+ *p = '\0';
+ p--;
+ }
+
+#if defined HAVE_LIBIDN || defined HAVE_LIBIDN2
+ /* find the start of the last word if there are spaces in the query */
+ for (p = ret; *p; p++)
+ if (*p == ' ')
+ domain_start = p + 1;
+
+ if (domain_start) {
+ char *q, *r;
+ int prefix_len;
+
+#ifdef HAVE_LIBIDN2
+ if (idn2_lookup_ul(domain_start, &q, IDN2_NONTRANSITIONAL) != IDN2_OK)
+ return ret;
+#else
+ if (idna_to_ascii_lz(domain_start, &q, 0) != IDNA_SUCCESS)
+ return ret;
+#endif
+
+ /* reassemble the original query in a new buffer */
+ prefix_len = domain_start - ret;
+ r = malloc(prefix_len + strlen(q) + 1);
+ strncpy(r, ret, prefix_len);
+ r[prefix_len] = '\0';
+ strcat(r, q);
+
+ free(q);
+ free(ret);
+ return r;
+ } else {
+ char *q;
+
+#ifdef HAVE_LIBIDN2
+ if (idn2_lookup_ul(ret, &q, IDN2_NONTRANSITIONAL) != IDN2_OK)
+ return ret;
+#else
+ if (idna_to_ascii_lz(ret, &q, 0) != IDNA_SUCCESS)
+ return ret;
+#endif
+
+ free(ret);
+ return q;
+ }
+#else
+ return ret;
+#endif
+}
+
+/* server and port have to be freed by the caller */
+void split_server_port(const char *const input,
+ char **server, char **port)
+{
+ char *p;
+
+ if (*input == '[' && (p = strchr(input, ']'))) { /* IPv6 */
+ char *s;
+ int len = p - input - 1;
+
+ *server = s = malloc(len + 1);
+ memcpy(s, input + 1, len);
+ *(s + len) = '\0';
+
+ p = strchr(p, ':');
+ if (p && *(p + 1) != '\0')
+ *port = strdup(p + 1); /* IPv6 + port */
+ } else if ((p = strchr(input, ':')) && /* IPv6, no port */
+ strchr(p + 1, ':')) { /* and no brackets */
+ *server = strdup(input);
+ } else if ((p = strchr(input, ':'))) { /* IPv4 + port */
+ char *s;
+ int len = p - input;
+
+ *server = s = malloc(len + 1);
+ memcpy(s, input, len);
+ *(s + len) = '\0';
+
+ p++;
+ if (*p != '\0')
+ *port = strdup(p);
+ } else { /* IPv4, no port */
+ *server = strdup(input);
+ }
+
+ /* change the server name to lower case */
+ for (p = (char *) *server; *p; p++)
+ *p = tolower(*p);
+}
+
+char *convert_6to4(const char *s)
+{
+ char *new;
+ int items;
+ unsigned int a, b;
+ char c;
+
+ items = sscanf(s, "2002:%x:%x%c", &a, &b, &c);
+
+ if (items <= 0 || items == 2 || (items == 3 && c != ':'))
+ return strdup("0.0.0.0");
+
+ if (items == 1) {
+ items = sscanf(s, "2002:%x:%c", &a, &c);
+ if (items != 2 || c != ':')
+ return strdup("0.0.0.0");
+ b = 0;
+ }
+
+ new = malloc(sizeof("255.255.255.255"));
+ sprintf(new, "%u.%u.%u.%u", a >> 8, a & 0xff, b >> 8, b & 0xff);
+
+ return new;
+}
+
+char *convert_teredo(const char *s)
+{
+ char *new;
+ unsigned int a, b;
+
+ if (sscanf(s, "2001:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%x:%x", &a, &b) != 2)
+ return strdup("0.0.0.0");
+
+ a ^= 0xffff;
+ b ^= 0xffff;
+ new = malloc(sizeof("255.255.255.255"));
+ sprintf(new, "%u.%u.%u.%u", a >> 8, a & 0xff, b >> 8, b & 0xff);
+
+ return new;
+}
+
+char *convert_inaddr(const char *s)
+{
+ char *new;
+ char *endptr;
+ long int a, b = 0, c = 0;
+
+ errno = 0;
+
+ a = strtol(s, &endptr, 10);
+ if (errno || a < 0 || a > 255 || *endptr != '.')
+ return strdup("0.0.0.0");
+
+ if (in_domain(endptr + 1, "in-addr.arpa")) {
+ b = strtol(endptr + 1, &endptr, 10); /* 1.2. */
+ if (errno || b < 0 || b > 255 || *endptr != '.')
+ return strdup("0.0.0.0");
+
+ if (in_domain(endptr + 1, "in-addr.arpa")) {
+ c = strtol(endptr + 1, &endptr, 10); /* 1.2.3. */
+ if (errno || c < 0 || c > 255 || *endptr != '.')
+ return strdup("0.0.0.0");
+
+ if (in_domain(endptr + 1, "in-addr.arpa"))
+ return strdup("0.0.0.0");
+ } else {
+ c = b; b = a; a = 0;
+ }
+ } else {
+ c = a; a = 0;
+ }
+
+ new = malloc(sizeof("255.255.255.255"));
+ sprintf(new, "%ld.%ld.%ld.0", c, b, a);
+ return new;
+}
+
+char *convert_in6arpa(const char *s)
+{
+ char *ip, *p;
+ int character = 0;
+ int digits = 1;
+
+ ip = malloc(40);
+
+ p = strstr(s, ".ip6.arpa");
+ if (!p || p == s) {
+ ip[character] = '\0';
+ return ip;
+ }
+
+ /* start from the first character before ".ip6.arpa" */
+ p--;
+
+ while (1) {
+ /* check that this is a valid digit for an IPv6 address */
+ if (!((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') ||
+ (*p >= 'A' && *p <= 'F'))) {
+ ip[character] = '\0';
+ return ip;
+ }
+
+ /* copy the digit to the IP address */
+ ip[character++] = *p;
+
+ /* stop if we have reached the beginning of the string */
+ if (p == s)
+ break;
+
+ /* stop if we have parsed a complete address */
+ if (character == 39)
+ break;
+
+ /* add the colon separator every four digits */
+ if ((digits++ % 4) == 0)
+ ip[character++] = ':';
+
+ /* go to the precedent character and abort if it is not a dot */
+ p--;
+ if (*p != '.') {
+ ip[character] = '\0';
+ return ip;
+ }
+
+ /* abort if the string starts with the dot */
+ if (p == s) {
+ ip[character] = '\0';
+ return ip;
+ }
+
+ /* go to the precedent character and continue */
+ p--;
+ }
+
+ /* terminate the string */
+ ip[character] = '\0';
+ return ip;
+}
+
+unsigned long myinet_aton(const char *s)
+{
+ unsigned long a, b, c, d;
+ int elements;
+ char junk;
+
+ if (!s)
+ return 0;
+ elements = sscanf(s, "%lu.%lu.%lu.%lu%c", &a, &b, &c, &d, &junk);
+ if (!(elements == 4 || (elements == 5 && junk == '/')))
+ return 0;
+ if (a > 255 || b > 255 || c > 255 || d > 255)
+ return 0;
+ return (a << 24) + (b << 16) + (c << 8) + d;
+}
+
+unsigned long asn32_to_long(const char *s)
+{
+ unsigned long a, b;
+ char junk;
+
+ if (!s)
+ return 0;
+ if (sscanf(s, "%lu.%lu%c", &a, &b, &junk) != 2)
+ return 0;
+ if (a > 65535 || b > 65535)
+ return 0;
+ return (a << 16) + b;
+}
+
+int isasciidigit(const char c)
+{
+ return (c >= '0' && c <= '9') ? 1 : 0;
+}
+
+/* http://www.ripe.net/ripe/docs/databaseref-manual.html */
+
+void NORETURN usage(int error)
+{
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"Usage: whois [OPTION]... OBJECT...\n\n"
+"-h HOST, --host HOST connect to server HOST\n"
+"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
+"-H hide legal disclaimers\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+" --verbose explain what is being done\n"
+" --no-recursion disable recursion from registry to registrar servers\n"
+" --help display this help and exit\n"
+" --version output version information and exit\n"
+"\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"These flags are supported by whois.ripe.net and some RIPE-like servers:\n"
+"-l find the one level less specific match\n"
+"-L find all levels less specific matches\n"
+"-m find all one level more specific matches\n"
+"-M find all levels of more specific matches\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"-c find the smallest match containing a mnt-irt attribute\n"
+"-x exact match\n"
+"-b return brief IP address ranges with abuse contact\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"-B turn off object filtering (show email addresses)\n"
+"-G turn off grouping of associated objects\n"
+"-d return DNS reverse delegation objects too\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"-i ATTR[,ATTR]... do an inverse look-up for specified ATTRibutes\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-K only primary keys are returned\n"
+"-r turn off recursive look-ups for contact information\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-a also search all the mirrored databases\n"
+"-s SOURCE[,SOURCE]... search the database mirrored from SOURCE\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+ ));
+ fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
+"-t TYPE request template for object of TYPE\n"
+"-v TYPE request verbose template for object of TYPE\n"
+"-q [version|sources|types] query specified server info\n"
+));
+ exit(error);
+}
+
diff --git a/whois.conf b/whois.conf
new file mode 100644
index 0000000..620894c
--- /dev/null
+++ b/whois.conf
@@ -0,0 +1,11 @@
+# whois configuration file
+#
+# This file can contain details of alternative whois servers to use if
+# the compiled in servers are not suitable. Each entry is a single
+# text line and consists of a regular expression pattern to match and
+# the whois server to be used for it, separated by blank space.
+# IDN domains must use the ACE format.
+#
+# Eg:
+# \.nz$ nz.whois-servers.net
+#
diff --git a/whois.conf.5 b/whois.conf.5
new file mode 100644
index 0000000..7ec1b50
--- /dev/null
+++ b/whois.conf.5
@@ -0,0 +1,49 @@
+.TH "WHOIS.CONF" "5" "2019-12-30" "Petr Písař" "Debian GNU/Linux"
+
+.SH NAME
+whois.conf \- alternative WHOIS servers list for whois client
+
+.SH SYNOPSIS
+.B /etc/whois.conf
+
+.SH DESCRIPTION
+This file contains a list of WHOIS servers which can augment or override
+the built-in list of the client.
+
+It's a plain text file in ASCII encoding. Each line consists of two fields:
+a pattern to match WHOIS object identifier and a corresponding WHOIS server
+domain name.
+
+Fields are separated by non-empty sequence of space or a tabular characters.
+A line starting with a hash character is a free comment and it's not
+considered.
+
+The pattern is case-insensitive extended regular expression if whois client
+has been compiled with POSIX regular expressions support. Otherwise, simple
+case-insensitive suffix comparison against WHOIS object identifier is used.
+
+Internationalized domain names (IDN) must be specified in ascii-compatible
+encoding (ACE) format.
+
+.SH EXAMPLE
+\\.nz$ nz.whois-servers.net
+.br
+# Hangul Korean TLD
+.br
+\\.xn--3e0b707e$ whois.kr
+.br
+# Private ASNs
+.br
+^as645(1[2-9]|2[0-9]|3[0-4])$ whois.example.net
+
+.SH FILES
+/etc/whois.conf
+
+.SH "SEE ALSO"
+.IR whois (1)
+
+.SH AUTHOR
+This manual page was written by Petr Písař
+.RI < ppisar@redhat.com >
+and is licensed under the terms of the GNU General Public License,
+version 2 or higher.
diff --git a/whois.h b/whois.h
new file mode 100644
index 0000000..bb910e5
--- /dev/null
+++ b/whois.h
@@ -0,0 +1,47 @@
+#include "utils.h"
+
+/* 6bone referto: extension */
+#define REFERTO_FORMAT "%% referto: whois -h %255s -p %15s %1021[^\n\r]"
+
+#define HIDE_TO_THE_END -3
+#define HIDE_DISABLED -2
+#define HIDE_NOT_STARTED -1
+
+/* prototypes */
+char *guess_server(const char *);
+const char *match_config_file(const char *);
+const char *whereas(const unsigned long);
+const char *whereas32(const unsigned long);
+char *queryformat(const char *, const char *, const char *);
+int hide_line(int *hiding, const char *const line);
+char *do_query(const int, const char *);
+char *query_crsnic(const int, const char *);
+char *query_afilias(const int, const char *);
+char *query_iana(const int, const char *);
+int openconn(const char *, const char *);
+int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
+void NORETURN usage(int error);
+void NORETURN alarm_handler(int);
+void NORETURN sighandler(int);
+int japanese_locale(void);
+unsigned long myinet_aton(const char *);
+unsigned long asn32_to_long(const char *);
+int isasciidigit(const char);
+int endstrcaseeq(const char *, const char *);
+int in_domain(const char *, const char *);
+const char *is_new_gtld(const char *);
+int domfind(const char *, const char *[]);
+char *normalize_domain(const char *);
+char *convert_6to4(const char *);
+char *convert_teredo(const char *);
+char *convert_inaddr(const char *);
+char *convert_in6arpa(const char *);
+int handle_query(const char *server, const char *port,
+ const char *qstring, const char *fstring);
+void split_server_port(const char *const input, char **server, char **port);
+
+
+/* flags for RIPE-like servers */
+const char *ripeflags="abBcdFGKlLmMrRx";
+const char *ripeflagsp="gisTtvq";
+