Internationalization of tinc.
This commit is contained in:
parent
61e71ab74a
commit
9fd02ffcb0
34 changed files with 5517 additions and 192 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = gnu
|
AUTOMAKE_OPTIONS = gnu
|
||||||
|
|
||||||
SUBDIRS = m4 lib cipher src doc redhat debian
|
SUBDIRS = m4 lib cipher src doc po redhat debian
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS =
|
ACLOCAL_AMFLAGS =
|
||||||
|
|
||||||
|
|
12
configure.in
12
configure.in
|
@ -9,8 +9,9 @@ AM_ACLOCAL_INCLUDE(m4)
|
||||||
# Enable GNU extensions.
|
# Enable GNU extensions.
|
||||||
# Define this here, not in acconfig's @TOP@ section, since definitions
|
# Define this here, not in acconfig's @TOP@ section, since definitions
|
||||||
# in the latter don't make it into the configure-time tests.
|
# in the latter don't make it into the configure-time tests.
|
||||||
AC_DEFINE([_GNU_SOURCE])
|
AC_DEFINE([_GNU_SOURCE], [__USE_BSD])
|
||||||
AC_DEFINE([__USE_BSD])
|
|
||||||
|
ALL_LINGUAS="nl"
|
||||||
|
|
||||||
dnl Checks for programs.
|
dnl Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
@ -23,6 +24,8 @@ AC_PROG_MAKE_SET
|
||||||
jm_PERL
|
jm_PERL
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
|
AC_ISC_POSIX
|
||||||
|
|
||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
|
@ -68,5 +71,6 @@ AC_CHECK_LIB(dl, dlopen, [
|
||||||
LIBS="$LIBS -ldl"
|
LIBS="$LIBS -ldl"
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_OUTPUT([Makefile src/Makefile cipher/Makefile cipher/blowfish/Makefile
|
AC_OUTPUT([Makefile src/Makefile cipher/Makefile
|
||||||
doc/Makefile lib/Makefile m4/Makefile redhat/Makefile debian/Makefile])
|
cipher/blowfish/Makefile doc/Makefile intl/Makefile lib/Makefile
|
||||||
|
m4/Makefile po/Makefile.in redhat/Makefile debian/Makefile])
|
||||||
|
|
1086
intl/ChangeLog
Normal file
1086
intl/ChangeLog
Normal file
File diff suppressed because it is too large
Load diff
214
intl/Makefile.in
Normal file
214
intl/Makefile.in
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
# Makefile for directory with message catalog handling in GNU NLS Utilities.
|
||||||
|
# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
top_builddir = ..
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
transform = @program_transform_name@
|
||||||
|
libdir = $(exec_prefix)/lib
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
datadir = $(prefix)/@DATADIRNAME@
|
||||||
|
localedir = $(datadir)/locale
|
||||||
|
gnulocaledir = $(prefix)/share/locale
|
||||||
|
gettextsrcdir = @datadir@/gettext/intl
|
||||||
|
aliaspath = $(localedir):.
|
||||||
|
subdir = intl
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||||
|
|
||||||
|
l = @l@
|
||||||
|
|
||||||
|
AR = ar
|
||||||
|
CC = @CC@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
|
||||||
|
DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \
|
||||||
|
-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
|
||||||
|
|
||||||
|
HEADERS = $(COMHDRS) libgettext.h loadinfo.h
|
||||||
|
COMHDRS = gettext.h gettextP.h hash-string.h
|
||||||
|
SOURCES = $(COMSRCS) intl-compat.c cat-compat.c
|
||||||
|
COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \
|
||||||
|
finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
|
||||||
|
explodename.c
|
||||||
|
OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \
|
||||||
|
finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \
|
||||||
|
explodename.$lo
|
||||||
|
CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo
|
||||||
|
GETTOBJS = intl-compat.$lo
|
||||||
|
DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \
|
||||||
|
xopen-msg.sed $(HEADERS) $(SOURCES)
|
||||||
|
DISTFILES.normal = VERSION
|
||||||
|
DISTFILES.gettext = libintl.glibc intlh.inst.in
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .o .lo
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) $<
|
||||||
|
.c.lo:
|
||||||
|
$(LIBTOOL) --mode=compile $(COMPILE) $<
|
||||||
|
|
||||||
|
INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib
|
||||||
|
|
||||||
|
all: all-@USE_INCLUDED_LIBINTL@
|
||||||
|
|
||||||
|
all-yes: libintl.$la intlh.inst
|
||||||
|
all-no:
|
||||||
|
|
||||||
|
libintl.a: $(OBJECTS)
|
||||||
|
rm -f $@
|
||||||
|
$(AR) cru $@ $(OBJECTS)
|
||||||
|
$(RANLIB) $@
|
||||||
|
|
||||||
|
libintl.la: $(OBJECTS)
|
||||||
|
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \
|
||||||
|
-version-info 1:0 -rpath $(libdir)
|
||||||
|
|
||||||
|
../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot
|
||||||
|
cd ../po && $(MAKE) cat-id-tbl.$lo
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
# This installation goal is only used in GNU gettext. Packages which
|
||||||
|
# only use the library should use install instead.
|
||||||
|
|
||||||
|
# We must not install the libintl.h/libintl.a files if we are on a
|
||||||
|
# system which has the gettext() function in its C library or in a
|
||||||
|
# separate library or use the catgets interface. A special case is
|
||||||
|
# where configure found a previously installed GNU gettext library.
|
||||||
|
# If you want to use the one which comes with this version of the
|
||||||
|
# package, you have to use `configure --with-included-gettext'.
|
||||||
|
install: install-exec install-data
|
||||||
|
install-exec: all
|
||||||
|
if test "$(PACKAGE)" = "gettext" \
|
||||||
|
&& test '@INTLOBJS@' = '$(GETTOBJS)'; then \
|
||||||
|
if test -r $(MKINSTALLDIRS); then \
|
||||||
|
$(MKINSTALLDIRS) $(libdir) $(includedir); \
|
||||||
|
else \
|
||||||
|
$(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \
|
||||||
|
fi; \
|
||||||
|
$(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \
|
||||||
|
$(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
|
||||||
|
else \
|
||||||
|
: ; \
|
||||||
|
fi
|
||||||
|
install-data: all
|
||||||
|
if test "$(PACKAGE)" = "gettext"; then \
|
||||||
|
if test -r $(MKINSTALLDIRS); then \
|
||||||
|
$(MKINSTALLDIRS) $(gettextsrcdir); \
|
||||||
|
else \
|
||||||
|
$(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
|
||||||
|
fi; \
|
||||||
|
$(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \
|
||||||
|
dists="$(DISTFILES.common)"; \
|
||||||
|
for file in $$dists; do \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \
|
||||||
|
done; \
|
||||||
|
else \
|
||||||
|
: ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define this as empty until I found a useful application.
|
||||||
|
installcheck:
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
dists="$(DISTFILES.common)"; \
|
||||||
|
for file in $$dists; do \
|
||||||
|
rm -f $(gettextsrcdir)/$$file; \
|
||||||
|
done
|
||||||
|
|
||||||
|
info dvi:
|
||||||
|
|
||||||
|
$(OBJECTS): ../config.h libgettext.h
|
||||||
|
bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
|
||||||
|
dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES)
|
||||||
|
here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES)
|
||||||
|
|
||||||
|
id: ID
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES)
|
||||||
|
here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES)
|
||||||
|
|
||||||
|
|
||||||
|
mostlyclean:
|
||||||
|
rm -f *.a *.o *.lo core core.*
|
||||||
|
|
||||||
|
clean: mostlyclean
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile ID TAGS po2msg.sed po2tbl.sed
|
||||||
|
|
||||||
|
maintainer-clean: distclean
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
|
||||||
|
|
||||||
|
# GNU gettext needs not contain the file `VERSION' but contains some
|
||||||
|
# other files which should not be distributed in other packages.
|
||||||
|
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
||||||
|
dist distdir: Makefile $(DISTFILES)
|
||||||
|
if test "$(PACKAGE)" = gettext; then \
|
||||||
|
additional="$(DISTFILES.gettext)"; \
|
||||||
|
else \
|
||||||
|
additional="$(DISTFILES.normal)"; \
|
||||||
|
fi; \
|
||||||
|
for file in $(DISTFILES.common) $$additional; do \
|
||||||
|
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|
||||||
|
|| cp -p $(srcdir)/$$file $(distdir); \
|
||||||
|
done
|
||||||
|
|
||||||
|
dist-libc:
|
||||||
|
tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc
|
||||||
|
|
||||||
|
Makefile: Makefile.in ../config.status
|
||||||
|
cd .. \
|
||||||
|
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||||
|
|
||||||
|
# The dependency for intlh.inst is different in gettext and all other
|
||||||
|
# packages. Because we cannot you GNU make features we have to solve
|
||||||
|
# the problem while rewriting Makefile.in.
|
||||||
|
@GT_YES@intlh.inst: intlh.inst.in ../config.status
|
||||||
|
@GT_YES@ cd .. \
|
||||||
|
@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \
|
||||||
|
@GT_YES@ $(SHELL) ./config.status
|
||||||
|
@GT_NO@.PHONY: intlh.inst
|
||||||
|
@GT_NO@intlh.inst:
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make not to export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
1
intl/VERSION
Normal file
1
intl/VERSION
Normal file
|
@ -0,0 +1 @@
|
||||||
|
GNU gettext library from gettext-0.10.35
|
203
intl/bindtextdom.c
Normal file
203
intl/bindtextdom.c
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/* Implementation of the bindtextdomain(3) function
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
# else
|
||||||
|
void free ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
# ifndef memcpy
|
||||||
|
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "gettextP.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* Contains the default location of the message catalogs. */
|
||||||
|
extern const char _nl_default_dirname[];
|
||||||
|
|
||||||
|
/* List with bindings of specific domains. */
|
||||||
|
extern struct binding *_nl_domain_bindings;
|
||||||
|
|
||||||
|
|
||||||
|
/* Names for the libintl functions are a problem. They must not clash
|
||||||
|
with existing names and they should follow ANSI C. But this source
|
||||||
|
code is also used in GNU C Library where the names have a __
|
||||||
|
prefix. So we have to make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define BINDTEXTDOMAIN __bindtextdomain
|
||||||
|
# ifndef strdup
|
||||||
|
# define strdup(str) __strdup (str)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define BINDTEXTDOMAIN bindtextdomain__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Specify that the DOMAINNAME message catalog will be found
|
||||||
|
in DIRNAME rather than in the system locale data base. */
|
||||||
|
char *
|
||||||
|
BINDTEXTDOMAIN (domainname, dirname)
|
||||||
|
const char *domainname;
|
||||||
|
const char *dirname;
|
||||||
|
{
|
||||||
|
struct binding *binding;
|
||||||
|
|
||||||
|
/* Some sanity checks. */
|
||||||
|
if (domainname == NULL || domainname[0] == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
|
||||||
|
{
|
||||||
|
int compare = strcmp (domainname, binding->domainname);
|
||||||
|
if (compare == 0)
|
||||||
|
/* We found it! */
|
||||||
|
break;
|
||||||
|
if (compare < 0)
|
||||||
|
{
|
||||||
|
/* It is not in the list. */
|
||||||
|
binding = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirname == NULL)
|
||||||
|
/* The current binding has be to returned. */
|
||||||
|
return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
|
||||||
|
|
||||||
|
if (binding != NULL)
|
||||||
|
{
|
||||||
|
/* The domain is already bound. If the new value and the old
|
||||||
|
one are equal we simply do nothing. Otherwise replace the
|
||||||
|
old binding. */
|
||||||
|
if (strcmp (dirname, binding->dirname) != 0)
|
||||||
|
{
|
||||||
|
char *new_dirname;
|
||||||
|
|
||||||
|
if (strcmp (dirname, _nl_default_dirname) == 0)
|
||||||
|
new_dirname = (char *) _nl_default_dirname;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined _LIBC || defined HAVE_STRDUP
|
||||||
|
new_dirname = strdup (dirname);
|
||||||
|
if (new_dirname == NULL)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
size_t len = strlen (dirname) + 1;
|
||||||
|
new_dirname = (char *) malloc (len);
|
||||||
|
if (new_dirname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy (new_dirname, dirname, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding->dirname != _nl_default_dirname)
|
||||||
|
free (binding->dirname);
|
||||||
|
|
||||||
|
binding->dirname = new_dirname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have to create a new binding. */
|
||||||
|
#if !defined _LIBC && !defined HAVE_STRDUP
|
||||||
|
size_t len;
|
||||||
|
#endif
|
||||||
|
struct binding *new_binding =
|
||||||
|
(struct binding *) malloc (sizeof (*new_binding));
|
||||||
|
|
||||||
|
if (new_binding == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if defined _LIBC || defined HAVE_STRDUP
|
||||||
|
new_binding->domainname = strdup (domainname);
|
||||||
|
if (new_binding->domainname == NULL)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
len = strlen (domainname) + 1;
|
||||||
|
new_binding->domainname = (char *) malloc (len);
|
||||||
|
if (new_binding->domainname == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy (new_binding->domainname, domainname, len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strcmp (dirname, _nl_default_dirname) == 0)
|
||||||
|
new_binding->dirname = (char *) _nl_default_dirname;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined _LIBC || defined HAVE_STRDUP
|
||||||
|
new_binding->dirname = strdup (dirname);
|
||||||
|
if (new_binding->dirname == NULL)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
len = strlen (dirname) + 1;
|
||||||
|
new_binding->dirname = (char *) malloc (len);
|
||||||
|
if (new_binding->dirname == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy (new_binding->dirname, dirname, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now enqueue it. */
|
||||||
|
if (_nl_domain_bindings == NULL
|
||||||
|
|| strcmp (domainname, _nl_domain_bindings->domainname) < 0)
|
||||||
|
{
|
||||||
|
new_binding->next = _nl_domain_bindings;
|
||||||
|
_nl_domain_bindings = new_binding;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
binding = _nl_domain_bindings;
|
||||||
|
while (binding->next != NULL
|
||||||
|
&& strcmp (domainname, binding->next->domainname) > 0)
|
||||||
|
binding = binding->next;
|
||||||
|
|
||||||
|
new_binding->next = binding->next;
|
||||||
|
binding->next = new_binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding = new_binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return binding->dirname;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Alias for function name in GNU C Library. */
|
||||||
|
weak_alias (__bindtextdomain, bindtextdomain);
|
||||||
|
#endif
|
262
intl/cat-compat.c
Normal file
262
intl/cat-compat.c
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
/* Compatibility code for gettext-using-catgets interface.
|
||||||
|
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef STDC_HEADERS
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
char *getenv ();
|
||||||
|
# ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_NL_TYPES_H
|
||||||
|
# include <nl_types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libgettext.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* XPG3 defines the result of `setlocale (category, NULL)' as:
|
||||||
|
``Directs `setlocale()' to query `category' and return the current
|
||||||
|
setting of `local'.''
|
||||||
|
However it does not specify the exact format. And even worse: POSIX
|
||||||
|
defines this not at all. So we can use this feature only on selected
|
||||||
|
system (e.g. those using GNU C Library). */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define HAVE_LOCALE_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The catalog descriptor. */
|
||||||
|
static nl_catd catalog = (nl_catd) -1;
|
||||||
|
|
||||||
|
/* Name of the default catalog. */
|
||||||
|
static const char default_catalog_name[] = "messages";
|
||||||
|
|
||||||
|
/* Name of currently used catalog. */
|
||||||
|
static const char *catalog_name = default_catalog_name;
|
||||||
|
|
||||||
|
/* Get ID for given string. If not found return -1. */
|
||||||
|
static int msg_to_cat_id PARAMS ((const char *msg));
|
||||||
|
|
||||||
|
/* Substitution for systems lacking this function in their C library. */
|
||||||
|
#if !_LIBC && !HAVE_STPCPY
|
||||||
|
static char *stpcpy PARAMS ((char *dest, const char *src));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Set currently used domain/catalog. */
|
||||||
|
char *
|
||||||
|
textdomain (domainname)
|
||||||
|
const char *domainname;
|
||||||
|
{
|
||||||
|
nl_catd new_catalog;
|
||||||
|
char *new_name;
|
||||||
|
size_t new_name_len;
|
||||||
|
char *lang;
|
||||||
|
|
||||||
|
#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \
|
||||||
|
&& defined HAVE_LOCALE_NULL
|
||||||
|
lang = setlocale (LC_MESSAGES, NULL);
|
||||||
|
#else
|
||||||
|
lang = getenv ("LC_ALL");
|
||||||
|
if (lang == NULL || lang[0] == '\0')
|
||||||
|
{
|
||||||
|
lang = getenv ("LC_MESSAGES");
|
||||||
|
if (lang == NULL || lang[0] == '\0')
|
||||||
|
lang = getenv ("LANG");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (lang == NULL || lang[0] == '\0')
|
||||||
|
lang = "C";
|
||||||
|
|
||||||
|
/* See whether name of currently used domain is asked. */
|
||||||
|
if (domainname == NULL)
|
||||||
|
return (char *) catalog_name;
|
||||||
|
|
||||||
|
if (domainname[0] == '\0')
|
||||||
|
domainname = default_catalog_name;
|
||||||
|
|
||||||
|
/* Compute length of added path element. */
|
||||||
|
new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang)
|
||||||
|
+ sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1
|
||||||
|
+ sizeof (".cat");
|
||||||
|
|
||||||
|
new_name = (char *) malloc (new_name_len);
|
||||||
|
if (new_name == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
strcpy (new_name, PACKAGE);
|
||||||
|
new_catalog = catopen (new_name, 0);
|
||||||
|
|
||||||
|
if (new_catalog == (nl_catd) -1)
|
||||||
|
{
|
||||||
|
/* NLSPATH search didn't work, try absolute path */
|
||||||
|
sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang,
|
||||||
|
PACKAGE);
|
||||||
|
new_catalog = catopen (new_name, 0);
|
||||||
|
|
||||||
|
if (new_catalog == (nl_catd) -1)
|
||||||
|
{
|
||||||
|
free (new_name);
|
||||||
|
return (char *) catalog_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close old catalog. */
|
||||||
|
if (catalog != (nl_catd) -1)
|
||||||
|
catclose (catalog);
|
||||||
|
if (catalog_name != default_catalog_name)
|
||||||
|
free ((char *) catalog_name);
|
||||||
|
|
||||||
|
catalog = new_catalog;
|
||||||
|
catalog_name = new_name;
|
||||||
|
|
||||||
|
return (char *) catalog_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
bindtextdomain (domainname, dirname)
|
||||||
|
const char *domainname;
|
||||||
|
const char *dirname;
|
||||||
|
{
|
||||||
|
#if HAVE_SETENV || HAVE_PUTENV
|
||||||
|
char *old_val, *new_val, *cp;
|
||||||
|
size_t new_val_len;
|
||||||
|
|
||||||
|
/* This does not make much sense here but to be compatible do it. */
|
||||||
|
if (domainname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Compute length of added path element. If we use setenv we don't need
|
||||||
|
the first byts for NLSPATH=, but why complicate the code for this
|
||||||
|
peanuts. */
|
||||||
|
new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname)
|
||||||
|
+ sizeof ("/%L/LC_MESSAGES/%N.cat");
|
||||||
|
|
||||||
|
old_val = getenv ("NLSPATH");
|
||||||
|
if (old_val == NULL || old_val[0] == '\0')
|
||||||
|
{
|
||||||
|
old_val = NULL;
|
||||||
|
new_val_len += 1 + sizeof (LOCALEDIR) - 1
|
||||||
|
+ sizeof ("/%L/LC_MESSAGES/%N.cat");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_val_len += strlen (old_val);
|
||||||
|
|
||||||
|
new_val = (char *) malloc (new_val_len);
|
||||||
|
if (new_val == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
# if HAVE_SETENV
|
||||||
|
cp = new_val;
|
||||||
|
# else
|
||||||
|
cp = stpcpy (new_val, "NLSPATH=");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
cp = stpcpy (cp, dirname);
|
||||||
|
cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:");
|
||||||
|
|
||||||
|
if (old_val == NULL)
|
||||||
|
{
|
||||||
|
# if __STDC__
|
||||||
|
stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat");
|
||||||
|
# else
|
||||||
|
|
||||||
|
cp = stpcpy (cp, LOCALEDIR);
|
||||||
|
stpcpy (cp, "/%L/LC_MESSAGES/%N.cat");
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stpcpy (cp, old_val);
|
||||||
|
|
||||||
|
# if HAVE_SETENV
|
||||||
|
setenv ("NLSPATH", new_val, 1);
|
||||||
|
free (new_val);
|
||||||
|
# else
|
||||||
|
putenv (new_val);
|
||||||
|
/* Do *not* free the environment entry we just entered. It is used
|
||||||
|
from now on. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (char *) domainname;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef gettext
|
||||||
|
char *
|
||||||
|
gettext (msg)
|
||||||
|
const char *msg;
|
||||||
|
{
|
||||||
|
int msgid;
|
||||||
|
|
||||||
|
if (msg == NULL || catalog == (nl_catd) -1)
|
||||||
|
return (char *) msg;
|
||||||
|
|
||||||
|
/* Get the message from the catalog. We always use set number 1.
|
||||||
|
The message ID is computed by the function `msg_to_cat_id'
|
||||||
|
which works on the table generated by `po-to-tbl'. */
|
||||||
|
msgid = msg_to_cat_id (msg);
|
||||||
|
if (msgid == -1)
|
||||||
|
return (char *) msg;
|
||||||
|
|
||||||
|
return catgets (catalog, 1, msgid, (char *) msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries
|
||||||
|
for the one equal to msg. If it is found return the ID. In case when
|
||||||
|
the string is not found return -1. */
|
||||||
|
static int
|
||||||
|
msg_to_cat_id (msg)
|
||||||
|
const char *msg;
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < _msg_tbl_length; ++cnt)
|
||||||
|
if (strcmp (msg, _msg_tbl[cnt]._msg) == 0)
|
||||||
|
return _msg_tbl[cnt]._msg_number;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
/* We don't want libintl.a to depend on any other library. So we
|
||||||
|
avoid the non-standard function stpcpy. In GNU C Library this
|
||||||
|
function is available, though. Also allow the symbol HAVE_STPCPY
|
||||||
|
to be defined. */
|
||||||
|
#if !_LIBC && !HAVE_STPCPY
|
||||||
|
static char *
|
||||||
|
stpcpy (dest, src)
|
||||||
|
char *dest;
|
||||||
|
const char *src;
|
||||||
|
{
|
||||||
|
while ((*dest++ = *src++) != '\0')
|
||||||
|
/* Do nothing. */ ;
|
||||||
|
return dest - 1;
|
||||||
|
}
|
||||||
|
#endif
|
655
intl/dcgettext.c
Normal file
655
intl/dcgettext.c
Normal file
|
@ -0,0 +1,655 @@
|
||||||
|
/* Implementation of the dcgettext(3) function.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined __GNUC__ && !defined C_ALLOCA
|
||||||
|
# define alloca __builtin_alloca
|
||||||
|
# define HAVE_ALLOCA 1
|
||||||
|
#else
|
||||||
|
# if (defined HAVE_ALLOCA_H || defined _LIBC) && !defined C_ALLOCA
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
# else
|
||||||
|
# ifndef alloca
|
||||||
|
char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
#ifndef __set_errno
|
||||||
|
# define __set_errno(val) errno = (val)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#else
|
||||||
|
char *getenv ();
|
||||||
|
# ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
# else
|
||||||
|
void free ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE 1
|
||||||
|
# endif
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#if !HAVE_STRCHR && !defined _LIBC
|
||||||
|
# ifndef strchr
|
||||||
|
# define strchr index
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_UNISTD_H || defined _LIBC
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "gettextP.h"
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
#include "hash-string.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Rename the non ANSI C functions. This is required by the standard
|
||||||
|
because some ANSI C functions will require linking with this object
|
||||||
|
file and the name space must not be polluted. */
|
||||||
|
# define getcwd __getcwd
|
||||||
|
# ifndef stpcpy
|
||||||
|
# define stpcpy __stpcpy
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if !defined HAVE_GETCWD
|
||||||
|
char *getwd ();
|
||||||
|
# define getcwd(buf, max) getwd (buf)
|
||||||
|
# else
|
||||||
|
char *getcwd ();
|
||||||
|
# endif
|
||||||
|
# ifndef HAVE_STPCPY
|
||||||
|
static char *stpcpy PARAMS ((char *dest, const char *src));
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Amount to increase buffer size by in each try. */
|
||||||
|
#define PATH_INCR 32
|
||||||
|
|
||||||
|
/* The following is from pathmax.h. */
|
||||||
|
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
|
||||||
|
PATH_MAX but might cause redefinition warnings when sys/param.h is
|
||||||
|
later included (as on MORE/BSD 4.3). */
|
||||||
|
#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
|
||||||
|
# include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _POSIX_PATH_MAX
|
||||||
|
# define _POSIX_PATH_MAX 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
|
||||||
|
# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Don't include sys/param.h if it already has been. */
|
||||||
|
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
|
||||||
|
# include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(PATH_MAX) && defined(MAXPATHLEN)
|
||||||
|
# define PATH_MAX MAXPATHLEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
# define PATH_MAX _POSIX_PATH_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XPG3 defines the result of `setlocale (category, NULL)' as:
|
||||||
|
``Directs `setlocale()' to query `category' and return the current
|
||||||
|
setting of `local'.''
|
||||||
|
However it does not specify the exact format. And even worse: POSIX
|
||||||
|
defines this not at all. So we can use this feature only on selected
|
||||||
|
system (e.g. those using GNU C Library). */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define HAVE_LOCALE_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Name of the default domain used for gettext(3) prior any call to
|
||||||
|
textdomain(3). The default value for this is "messages". */
|
||||||
|
const char _nl_default_default_domain[] = "messages";
|
||||||
|
|
||||||
|
/* Value used as the default domain for gettext(3). */
|
||||||
|
const char *_nl_current_default_domain = _nl_default_default_domain;
|
||||||
|
|
||||||
|
/* Contains the default location of the message catalogs. */
|
||||||
|
const char _nl_default_dirname[] = GNULOCALEDIR;
|
||||||
|
|
||||||
|
/* List with bindings of specific domains created by bindtextdomain()
|
||||||
|
calls. */
|
||||||
|
struct binding *_nl_domain_bindings;
|
||||||
|
|
||||||
|
/* Prototypes for local functions. */
|
||||||
|
static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
|
||||||
|
const char *msgid)) internal_function;
|
||||||
|
static const char *category_to_name PARAMS ((int category)) internal_function;
|
||||||
|
static const char *guess_category_value PARAMS ((int category,
|
||||||
|
const char *categoryname))
|
||||||
|
internal_function;
|
||||||
|
|
||||||
|
|
||||||
|
/* For those loosing systems which don't have `alloca' we have to add
|
||||||
|
some additional code emulating it. */
|
||||||
|
#ifdef HAVE_ALLOCA
|
||||||
|
/* Nothing has to be done. */
|
||||||
|
# define ADD_BLOCK(list, address) /* nothing */
|
||||||
|
# define FREE_BLOCKS(list) /* nothing */
|
||||||
|
#else
|
||||||
|
struct block_list
|
||||||
|
{
|
||||||
|
void *address;
|
||||||
|
struct block_list *next;
|
||||||
|
};
|
||||||
|
# define ADD_BLOCK(list, addr) \
|
||||||
|
do { \
|
||||||
|
struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
|
||||||
|
/* If we cannot get a free block we cannot add the new element to \
|
||||||
|
the list. */ \
|
||||||
|
if (newp != NULL) { \
|
||||||
|
newp->address = (addr); \
|
||||||
|
newp->next = (list); \
|
||||||
|
(list) = newp; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
# define FREE_BLOCKS(list) \
|
||||||
|
do { \
|
||||||
|
while (list != NULL) { \
|
||||||
|
struct block_list *old = list; \
|
||||||
|
list = list->next; \
|
||||||
|
free (old); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
# undef alloca
|
||||||
|
# define alloca(size) (malloc (size))
|
||||||
|
#endif /* have alloca */
|
||||||
|
|
||||||
|
|
||||||
|
/* Names for the libintl functions are a problem. They must not clash
|
||||||
|
with existing names and they should follow ANSI C. But this source
|
||||||
|
code is also used in GNU C Library where the names have a __
|
||||||
|
prefix. So we have to make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define DCGETTEXT __dcgettext
|
||||||
|
#else
|
||||||
|
# define DCGETTEXT dcgettext__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Checking whether the binaries runs SUID must be done and glibc provides
|
||||||
|
easier methods therefore we make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define ENABLE_SECURE __libc_enable_secure
|
||||||
|
# define DETERMINE_SECURE
|
||||||
|
#else
|
||||||
|
static int enable_secure;
|
||||||
|
# define ENABLE_SECURE (enable_secure == 1)
|
||||||
|
# define DETERMINE_SECURE \
|
||||||
|
if (enable_secure == 0) \
|
||||||
|
{ \
|
||||||
|
if (getuid () != geteuid () || getgid () != getegid ()) \
|
||||||
|
enable_secure = 1; \
|
||||||
|
else \
|
||||||
|
enable_secure = -1; \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||||
|
locale. */
|
||||||
|
char *
|
||||||
|
DCGETTEXT (domainname, msgid, category)
|
||||||
|
const char *domainname;
|
||||||
|
const char *msgid;
|
||||||
|
int category;
|
||||||
|
{
|
||||||
|
#ifndef HAVE_ALLOCA
|
||||||
|
struct block_list *block_list = NULL;
|
||||||
|
#endif
|
||||||
|
struct loaded_l10nfile *domain;
|
||||||
|
struct binding *binding;
|
||||||
|
const char *categoryname;
|
||||||
|
const char *categoryvalue;
|
||||||
|
char *dirname, *xdomainname;
|
||||||
|
char *single_locale;
|
||||||
|
char *retval;
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
/* If no real MSGID is given return NULL. */
|
||||||
|
if (msgid == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* See whether this is a SUID binary or not. */
|
||||||
|
DETERMINE_SECURE;
|
||||||
|
|
||||||
|
/* If DOMAINNAME is NULL, we are interested in the default domain. If
|
||||||
|
CATEGORY is not LC_MESSAGES this might not make much sense but the
|
||||||
|
definition left this undefined. */
|
||||||
|
if (domainname == NULL)
|
||||||
|
domainname = _nl_current_default_domain;
|
||||||
|
|
||||||
|
/* First find matching binding. */
|
||||||
|
for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
|
||||||
|
{
|
||||||
|
int compare = strcmp (domainname, binding->domainname);
|
||||||
|
if (compare == 0)
|
||||||
|
/* We found it! */
|
||||||
|
break;
|
||||||
|
if (compare < 0)
|
||||||
|
{
|
||||||
|
/* It is not in the list. */
|
||||||
|
binding = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding == NULL)
|
||||||
|
dirname = (char *) _nl_default_dirname;
|
||||||
|
else if (binding->dirname[0] == '/')
|
||||||
|
dirname = binding->dirname;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have a relative path. Make it absolute now. */
|
||||||
|
size_t dirname_len = strlen (binding->dirname) + 1;
|
||||||
|
size_t path_max;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
path_max = (unsigned int) PATH_MAX;
|
||||||
|
path_max += 2; /* The getcwd docs say to do this. */
|
||||||
|
|
||||||
|
dirname = (char *) alloca (path_max + dirname_len);
|
||||||
|
ADD_BLOCK (block_list, dirname);
|
||||||
|
|
||||||
|
__set_errno (0);
|
||||||
|
while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
|
||||||
|
{
|
||||||
|
path_max += PATH_INCR;
|
||||||
|
dirname = (char *) alloca (path_max + dirname_len);
|
||||||
|
ADD_BLOCK (block_list, dirname);
|
||||||
|
__set_errno (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
/* We cannot get the current working directory. Don't signal an
|
||||||
|
error but simply return the default string. */
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
__set_errno (saved_errno);
|
||||||
|
return (char *) msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now determine the symbolic name of CATEGORY and its value. */
|
||||||
|
categoryname = category_to_name (category);
|
||||||
|
categoryvalue = guess_category_value (category, categoryname);
|
||||||
|
|
||||||
|
xdomainname = (char *) alloca (strlen (categoryname)
|
||||||
|
+ strlen (domainname) + 5);
|
||||||
|
ADD_BLOCK (block_list, xdomainname);
|
||||||
|
|
||||||
|
stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
|
||||||
|
domainname),
|
||||||
|
".mo");
|
||||||
|
|
||||||
|
/* Creating working area. */
|
||||||
|
single_locale = (char *) alloca (strlen (categoryvalue) + 1);
|
||||||
|
ADD_BLOCK (block_list, single_locale);
|
||||||
|
|
||||||
|
|
||||||
|
/* Search for the given string. This is a loop because we perhaps
|
||||||
|
got an ordered list of languages to consider for the translation. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Make CATEGORYVALUE point to the next element of the list. */
|
||||||
|
while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
|
||||||
|
++categoryvalue;
|
||||||
|
if (categoryvalue[0] == '\0')
|
||||||
|
{
|
||||||
|
/* The whole contents of CATEGORYVALUE has been searched but
|
||||||
|
no valid entry has been found. We solve this situation
|
||||||
|
by implicitly appending a "C" entry, i.e. no translation
|
||||||
|
will take place. */
|
||||||
|
single_locale[0] = 'C';
|
||||||
|
single_locale[1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *cp = single_locale;
|
||||||
|
while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
|
||||||
|
*cp++ = *categoryvalue++;
|
||||||
|
*cp = '\0';
|
||||||
|
|
||||||
|
/* When this is a SUID binary we must not allow accessing files
|
||||||
|
outside the dedicated directories. */
|
||||||
|
if (ENABLE_SECURE
|
||||||
|
&& (memchr (single_locale, '/',
|
||||||
|
_nl_find_language (single_locale) - single_locale)
|
||||||
|
!= NULL))
|
||||||
|
/* Ingore this entry. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the current locale value is C (or POSIX) we don't load a
|
||||||
|
domain. Return the MSGID. */
|
||||||
|
if (strcmp (single_locale, "C") == 0
|
||||||
|
|| strcmp (single_locale, "POSIX") == 0)
|
||||||
|
{
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
__set_errno (saved_errno);
|
||||||
|
return (char *) msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Find structure describing the message catalog matching the
|
||||||
|
DOMAINNAME and CATEGORY. */
|
||||||
|
domain = _nl_find_domain (dirname, single_locale, xdomainname);
|
||||||
|
|
||||||
|
if (domain != NULL)
|
||||||
|
{
|
||||||
|
retval = find_msg (domain, msgid);
|
||||||
|
|
||||||
|
if (retval == NULL)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
|
||||||
|
{
|
||||||
|
retval = find_msg (domain->successor[cnt], msgid);
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
__set_errno (saved_errno);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Alias for function name in GNU C Library. */
|
||||||
|
weak_alias (__dcgettext, dcgettext);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
internal_function
|
||||||
|
find_msg (domain_file, msgid)
|
||||||
|
struct loaded_l10nfile *domain_file;
|
||||||
|
const char *msgid;
|
||||||
|
{
|
||||||
|
size_t act = 0;
|
||||||
|
size_t top, bottom;
|
||||||
|
struct loaded_domain *domain;
|
||||||
|
|
||||||
|
if (domain_file->decided == 0)
|
||||||
|
_nl_load_domain (domain_file);
|
||||||
|
|
||||||
|
if (domain_file->data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
domain = (struct loaded_domain *) domain_file->data;
|
||||||
|
|
||||||
|
/* Locate the MSGID and its translation. */
|
||||||
|
if (domain->hash_size > 2 && domain->hash_tab != NULL)
|
||||||
|
{
|
||||||
|
/* Use the hashing table. */
|
||||||
|
nls_uint32 len = strlen (msgid);
|
||||||
|
nls_uint32 hash_val = hash_string (msgid);
|
||||||
|
nls_uint32 idx = hash_val % domain->hash_size;
|
||||||
|
nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
|
||||||
|
nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
|
||||||
|
|
||||||
|
if (nstr == 0)
|
||||||
|
/* Hash table entry is empty. */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
|
||||||
|
&& strcmp (msgid,
|
||||||
|
domain->data + W (domain->must_swap,
|
||||||
|
domain->orig_tab[nstr - 1].offset)) == 0)
|
||||||
|
return (char *) domain->data + W (domain->must_swap,
|
||||||
|
domain->trans_tab[nstr - 1].offset);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (idx >= domain->hash_size - incr)
|
||||||
|
idx -= domain->hash_size - incr;
|
||||||
|
else
|
||||||
|
idx += incr;
|
||||||
|
|
||||||
|
nstr = W (domain->must_swap, domain->hash_tab[idx]);
|
||||||
|
if (nstr == 0)
|
||||||
|
/* Hash table entry is empty. */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
|
||||||
|
&& strcmp (msgid,
|
||||||
|
domain->data + W (domain->must_swap,
|
||||||
|
domain->orig_tab[nstr - 1].offset))
|
||||||
|
== 0)
|
||||||
|
return (char *) domain->data
|
||||||
|
+ W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we try the default method: binary search in the sorted
|
||||||
|
array of messages. */
|
||||||
|
bottom = 0;
|
||||||
|
top = domain->nstrings;
|
||||||
|
while (bottom < top)
|
||||||
|
{
|
||||||
|
int cmp_val;
|
||||||
|
|
||||||
|
act = (bottom + top) / 2;
|
||||||
|
cmp_val = strcmp (msgid, domain->data
|
||||||
|
+ W (domain->must_swap,
|
||||||
|
domain->orig_tab[act].offset));
|
||||||
|
if (cmp_val < 0)
|
||||||
|
top = act;
|
||||||
|
else if (cmp_val > 0)
|
||||||
|
bottom = act + 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If an translation is found return this. */
|
||||||
|
return bottom >= top ? NULL : (char *) domain->data
|
||||||
|
+ W (domain->must_swap,
|
||||||
|
domain->trans_tab[act].offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return string representation of locale CATEGORY. */
|
||||||
|
static const char *
|
||||||
|
internal_function
|
||||||
|
category_to_name (category)
|
||||||
|
int category;
|
||||||
|
{
|
||||||
|
const char *retval;
|
||||||
|
|
||||||
|
switch (category)
|
||||||
|
{
|
||||||
|
#ifdef LC_COLLATE
|
||||||
|
case LC_COLLATE:
|
||||||
|
retval = "LC_COLLATE";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_CTYPE
|
||||||
|
case LC_CTYPE:
|
||||||
|
retval = "LC_CTYPE";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_MONETARY
|
||||||
|
case LC_MONETARY:
|
||||||
|
retval = "LC_MONETARY";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_NUMERIC
|
||||||
|
case LC_NUMERIC:
|
||||||
|
retval = "LC_NUMERIC";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_TIME
|
||||||
|
case LC_TIME:
|
||||||
|
retval = "LC_TIME";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_MESSAGES
|
||||||
|
case LC_MESSAGES:
|
||||||
|
retval = "LC_MESSAGES";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_RESPONSE
|
||||||
|
case LC_RESPONSE:
|
||||||
|
retval = "LC_RESPONSE";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef LC_ALL
|
||||||
|
case LC_ALL:
|
||||||
|
/* This might not make sense but is perhaps better than any other
|
||||||
|
value. */
|
||||||
|
retval = "LC_ALL";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
/* If you have a better idea for a default value let me know. */
|
||||||
|
retval = "LC_XXX";
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Guess value of current locale from value of the environment variables. */
|
||||||
|
static const char *
|
||||||
|
internal_function
|
||||||
|
guess_category_value (category, categoryname)
|
||||||
|
int category;
|
||||||
|
const char *categoryname;
|
||||||
|
{
|
||||||
|
const char *retval;
|
||||||
|
|
||||||
|
/* The highest priority value is the `LANGUAGE' environment
|
||||||
|
variable. This is a GNU extension. */
|
||||||
|
retval = getenv ("LANGUAGE");
|
||||||
|
if (retval != NULL && retval[0] != '\0')
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* `LANGUAGE' is not set. So we have to proceed with the POSIX
|
||||||
|
methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some
|
||||||
|
systems this can be done by the `setlocale' function itself. */
|
||||||
|
#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
|
||||||
|
return setlocale (category, NULL);
|
||||||
|
#else
|
||||||
|
/* Setting of LC_ALL overwrites all other. */
|
||||||
|
retval = getenv ("LC_ALL");
|
||||||
|
if (retval != NULL && retval[0] != '\0')
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* Next comes the name of the desired category. */
|
||||||
|
retval = getenv (categoryname);
|
||||||
|
if (retval != NULL && retval[0] != '\0')
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* Last possibility is the LANG environment variable. */
|
||||||
|
retval = getenv ("LANG");
|
||||||
|
if (retval != NULL && retval[0] != '\0')
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
/* We use C as the default domain. POSIX says this is implementation
|
||||||
|
defined. */
|
||||||
|
return "C";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
/* We don't want libintl.a to depend on any other library. So we
|
||||||
|
avoid the non-standard function stpcpy. In GNU C Library this
|
||||||
|
function is available, though. Also allow the symbol HAVE_STPCPY
|
||||||
|
to be defined. */
|
||||||
|
#if !_LIBC && !HAVE_STPCPY
|
||||||
|
static char *
|
||||||
|
stpcpy (dest, src)
|
||||||
|
char *dest;
|
||||||
|
const char *src;
|
||||||
|
{
|
||||||
|
while ((*dest++ = *src++) != '\0')
|
||||||
|
/* Do nothing. */ ;
|
||||||
|
return dest - 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* If we want to free all resources we have to do some work at
|
||||||
|
program's end. */
|
||||||
|
static void __attribute__ ((unused))
|
||||||
|
free_mem (void)
|
||||||
|
{
|
||||||
|
struct binding *runp;
|
||||||
|
|
||||||
|
for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
|
||||||
|
{
|
||||||
|
free (runp->domainname);
|
||||||
|
if (runp->dirname != _nl_default_dirname)
|
||||||
|
/* Yes, this is a pointer comparison. */
|
||||||
|
free (runp->dirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_nl_current_default_domain != _nl_default_default_domain)
|
||||||
|
/* Yes, again a pointer comparison. */
|
||||||
|
free ((char *) _nl_current_default_domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
text_set_element (__libc_subfreeres, free_mem);
|
||||||
|
#endif
|
59
intl/dgettext.c
Normal file
59
intl/dgettext.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* Implementation of the dgettext(3) function
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_LOCALE_H || defined _LIBC
|
||||||
|
# include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* Names for the libintl functions are a problem. They must not clash
|
||||||
|
with existing names and they should follow ANSI C. But this source
|
||||||
|
code is also used in GNU C Library where the names have a __
|
||||||
|
prefix. So we have to make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define DGETTEXT __dgettext
|
||||||
|
# define DCGETTEXT __dcgettext
|
||||||
|
#else
|
||||||
|
# define DGETTEXT dgettext__
|
||||||
|
# define DCGETTEXT dcgettext__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Look up MSGID in the DOMAINNAME message catalog of the current
|
||||||
|
LC_MESSAGES locale. */
|
||||||
|
char *
|
||||||
|
DGETTEXT (domainname, msgid)
|
||||||
|
const char *domainname;
|
||||||
|
const char *msgid;
|
||||||
|
{
|
||||||
|
return DCGETTEXT (domainname, msgid, LC_MESSAGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Alias for function name in GNU C Library. */
|
||||||
|
weak_alias (__dgettext, dgettext);
|
||||||
|
#endif
|
197
intl/explodename.c
Normal file
197
intl/explodename.c
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "loadinfo.h"
|
||||||
|
|
||||||
|
/* On some strange systems still no definition of NULL is found. Sigh! */
|
||||||
|
#ifndef NULL
|
||||||
|
# if defined __STDC__ && __STDC__
|
||||||
|
# define NULL ((void *) 0)
|
||||||
|
# else
|
||||||
|
# define NULL 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
char *
|
||||||
|
_nl_find_language (const char *name)
|
||||||
|
{
|
||||||
|
while (name[0] != '\0' && name[0] != '_' && name[0] != '@'
|
||||||
|
&& name[0] != '+' && name[0] != ',')
|
||||||
|
++name;
|
||||||
|
|
||||||
|
return (char *) name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_nl_explode_name (name, language, modifier, territory, codeset,
|
||||||
|
normalized_codeset, special, sponsor, revision)
|
||||||
|
char *name;
|
||||||
|
const char **language;
|
||||||
|
const char **modifier;
|
||||||
|
const char **territory;
|
||||||
|
const char **codeset;
|
||||||
|
const char **normalized_codeset;
|
||||||
|
const char **special;
|
||||||
|
const char **sponsor;
|
||||||
|
const char **revision;
|
||||||
|
{
|
||||||
|
enum { undecided, xpg, cen } syntax;
|
||||||
|
char *cp;
|
||||||
|
int mask;
|
||||||
|
|
||||||
|
*modifier = NULL;
|
||||||
|
*territory = NULL;
|
||||||
|
*codeset = NULL;
|
||||||
|
*normalized_codeset = NULL;
|
||||||
|
*special = NULL;
|
||||||
|
*sponsor = NULL;
|
||||||
|
*revision = NULL;
|
||||||
|
|
||||||
|
/* Now we determine the single parts of the locale name. First
|
||||||
|
look for the language. Termination symbols are `_' and `@' if
|
||||||
|
we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
|
||||||
|
mask = 0;
|
||||||
|
syntax = undecided;
|
||||||
|
*language = cp = name;
|
||||||
|
cp = _nl_find_language (*language);
|
||||||
|
|
||||||
|
if (*language == cp)
|
||||||
|
/* This does not make sense: language has to be specified. Use
|
||||||
|
this entry as it is without exploding. Perhaps it is an alias. */
|
||||||
|
cp = strchr (*language, '\0');
|
||||||
|
else if (cp[0] == '_')
|
||||||
|
{
|
||||||
|
/* Next is the territory. */
|
||||||
|
cp[0] = '\0';
|
||||||
|
*territory = ++cp;
|
||||||
|
|
||||||
|
while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
|
||||||
|
&& cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
mask |= TERRITORY;
|
||||||
|
|
||||||
|
if (cp[0] == '.')
|
||||||
|
{
|
||||||
|
/* Next is the codeset. */
|
||||||
|
syntax = xpg;
|
||||||
|
cp[0] = '\0';
|
||||||
|
*codeset = ++cp;
|
||||||
|
|
||||||
|
while (cp[0] != '\0' && cp[0] != '@')
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
mask |= XPG_CODESET;
|
||||||
|
|
||||||
|
if (*codeset != cp && (*codeset)[0] != '\0')
|
||||||
|
{
|
||||||
|
*normalized_codeset = _nl_normalize_codeset (*codeset,
|
||||||
|
cp - *codeset);
|
||||||
|
if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||||
|
free ((char *) *normalized_codeset);
|
||||||
|
else
|
||||||
|
mask |= XPG_NORM_CODESET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
|
||||||
|
{
|
||||||
|
/* Next is the modifier. */
|
||||||
|
syntax = cp[0] == '@' ? xpg : cen;
|
||||||
|
cp[0] = '\0';
|
||||||
|
*modifier = ++cp;
|
||||||
|
|
||||||
|
while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
|
||||||
|
&& cp[0] != ',' && cp[0] != '_')
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
mask |= XPG_MODIFIER | CEN_AUDIENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
|
||||||
|
{
|
||||||
|
syntax = cen;
|
||||||
|
|
||||||
|
if (cp[0] == '+')
|
||||||
|
{
|
||||||
|
/* Next is special application (CEN syntax). */
|
||||||
|
cp[0] = '\0';
|
||||||
|
*special = ++cp;
|
||||||
|
|
||||||
|
while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
mask |= CEN_SPECIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp[0] == ',')
|
||||||
|
{
|
||||||
|
/* Next is sponsor (CEN syntax). */
|
||||||
|
cp[0] = '\0';
|
||||||
|
*sponsor = ++cp;
|
||||||
|
|
||||||
|
while (cp[0] != '\0' && cp[0] != '_')
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
mask |= CEN_SPONSOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp[0] == '_')
|
||||||
|
{
|
||||||
|
/* Next is revision (CEN syntax). */
|
||||||
|
cp[0] = '\0';
|
||||||
|
*revision = ++cp;
|
||||||
|
|
||||||
|
mask |= CEN_REVISION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For CEN syntax values it might be important to have the
|
||||||
|
separator character in the file name, not for XPG syntax. */
|
||||||
|
if (syntax == xpg)
|
||||||
|
{
|
||||||
|
if (*territory != NULL && (*territory)[0] == '\0')
|
||||||
|
mask &= ~TERRITORY;
|
||||||
|
|
||||||
|
if (*codeset != NULL && (*codeset)[0] == '\0')
|
||||||
|
mask &= ~XPG_CODESET;
|
||||||
|
|
||||||
|
if (*modifier != NULL && (*modifier)[0] == '\0')
|
||||||
|
mask &= ~XPG_MODIFIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
216
intl/finddomain.c
Normal file
216
intl/finddomain.c
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
/* Handle list of needed message catalogs
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
# else
|
||||||
|
void free ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
# ifndef memcpy
|
||||||
|
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !HAVE_STRCHR && !defined _LIBC
|
||||||
|
# ifndef strchr
|
||||||
|
# define strchr index
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_UNISTD_H || defined _LIBC
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "gettextP.h"
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
/* List of already loaded domains. */
|
||||||
|
static struct loaded_l10nfile *_nl_loaded_domains;
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a data structure describing the message catalog described by
|
||||||
|
the DOMAINNAME and CATEGORY parameters with respect to the currently
|
||||||
|
established bindings. */
|
||||||
|
struct loaded_l10nfile *
|
||||||
|
internal_function
|
||||||
|
_nl_find_domain (dirname, locale, domainname)
|
||||||
|
const char *dirname;
|
||||||
|
char *locale;
|
||||||
|
const char *domainname;
|
||||||
|
{
|
||||||
|
struct loaded_l10nfile *retval;
|
||||||
|
const char *language;
|
||||||
|
const char *modifier;
|
||||||
|
const char *territory;
|
||||||
|
const char *codeset;
|
||||||
|
const char *normalized_codeset;
|
||||||
|
const char *special;
|
||||||
|
const char *sponsor;
|
||||||
|
const char *revision;
|
||||||
|
const char *alias_value;
|
||||||
|
int mask;
|
||||||
|
|
||||||
|
/* LOCALE can consist of up to four recognized parts for the XPG syntax:
|
||||||
|
|
||||||
|
language[_territory[.codeset]][@modifier]
|
||||||
|
|
||||||
|
and six parts for the CEN syntax:
|
||||||
|
|
||||||
|
language[_territory][+audience][+special][,[sponsor][_revision]]
|
||||||
|
|
||||||
|
Beside the first part all of them are allowed to be missing. If
|
||||||
|
the full specified locale is not found, the less specific one are
|
||||||
|
looked for. The various parts will be stripped off according to
|
||||||
|
the following order:
|
||||||
|
(1) revision
|
||||||
|
(2) sponsor
|
||||||
|
(3) special
|
||||||
|
(4) codeset
|
||||||
|
(5) normalized codeset
|
||||||
|
(6) territory
|
||||||
|
(7) audience/modifier
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If we have already tested for this locale entry there has to
|
||||||
|
be one data set in the list of loaded domains. */
|
||||||
|
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||||
|
strlen (dirname) + 1, 0, locale, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, domainname, 0);
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
/* We know something about this locale. */
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
if (retval->decided == 0)
|
||||||
|
_nl_load_domain (retval);
|
||||||
|
|
||||||
|
if (retval->data != NULL)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
|
||||||
|
{
|
||||||
|
if (retval->successor[cnt]->decided == 0)
|
||||||
|
_nl_load_domain (retval->successor[cnt]);
|
||||||
|
|
||||||
|
if (retval->successor[cnt]->data != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cnt >= 0 ? retval : NULL;
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See whether the locale value is an alias. If yes its value
|
||||||
|
*overwrites* the alias name. No test for the original value is
|
||||||
|
done. */
|
||||||
|
alias_value = _nl_expand_alias (locale);
|
||||||
|
if (alias_value != NULL)
|
||||||
|
{
|
||||||
|
#if defined _LIBC || defined HAVE_STRDUP
|
||||||
|
locale = strdup (alias_value);
|
||||||
|
if (locale == NULL)
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
size_t len = strlen (alias_value) + 1;
|
||||||
|
locale = (char *) malloc (len);
|
||||||
|
if (locale == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy (locale, alias_value, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we determine the single parts of the locale name. First
|
||||||
|
look for the language. Termination symbols are `_' and `@' if
|
||||||
|
we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
|
||||||
|
mask = _nl_explode_name (locale, &language, &modifier, &territory,
|
||||||
|
&codeset, &normalized_codeset, &special,
|
||||||
|
&sponsor, &revision);
|
||||||
|
|
||||||
|
/* Create all possible locale entries which might be interested in
|
||||||
|
generalization. */
|
||||||
|
retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
|
||||||
|
strlen (dirname) + 1, mask, language, territory,
|
||||||
|
codeset, normalized_codeset, modifier, special,
|
||||||
|
sponsor, revision, domainname, 1);
|
||||||
|
if (retval == NULL)
|
||||||
|
/* This means we are out of core. */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (retval->decided == 0)
|
||||||
|
_nl_load_domain (retval);
|
||||||
|
if (retval->data == NULL)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
|
||||||
|
{
|
||||||
|
if (retval->successor[cnt]->decided == 0)
|
||||||
|
_nl_load_domain (retval->successor[cnt]);
|
||||||
|
if (retval->successor[cnt]->data != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The room for an alias was dynamically allocated. Free it now. */
|
||||||
|
if (alias_value != NULL)
|
||||||
|
free (locale);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
static void __attribute__ ((unused))
|
||||||
|
free_mem (void)
|
||||||
|
{
|
||||||
|
struct loaded_l10nfile *runp = _nl_loaded_domains;
|
||||||
|
|
||||||
|
while (runp != NULL)
|
||||||
|
{
|
||||||
|
struct loaded_l10nfile *here = runp;
|
||||||
|
if (runp->data != NULL)
|
||||||
|
_nl_unload_domain ((struct loaded_domain *) runp->data);
|
||||||
|
runp = runp->next;
|
||||||
|
free (here);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text_set_element (__libc_subfreeres, free_mem);
|
||||||
|
#endif
|
70
intl/gettext.c
Normal file
70
intl/gettext.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* Implementation of gettext(3) function.
|
||||||
|
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define __need_NULL
|
||||||
|
# include <stddef.h>
|
||||||
|
#else
|
||||||
|
# ifdef STDC_HEADERS
|
||||||
|
# include <stdlib.h> /* Just for NULL. */
|
||||||
|
# else
|
||||||
|
# ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
# else
|
||||||
|
# define NULL ((void *) 0)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* Names for the libintl functions are a problem. They must not clash
|
||||||
|
with existing names and they should follow ANSI C. But this source
|
||||||
|
code is also used in GNU C Library where the names have a __
|
||||||
|
prefix. So we have to make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define GETTEXT __gettext
|
||||||
|
# define DGETTEXT __dgettext
|
||||||
|
#else
|
||||||
|
# define GETTEXT gettext__
|
||||||
|
# define DGETTEXT dgettext__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Look up MSGID in the current default message catalog for the current
|
||||||
|
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||||
|
text). */
|
||||||
|
char *
|
||||||
|
GETTEXT (msgid)
|
||||||
|
const char *msgid;
|
||||||
|
{
|
||||||
|
return DGETTEXT (NULL, msgid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Alias for function name in GNU C Library. */
|
||||||
|
weak_alias (__gettext, gettext);
|
||||||
|
#endif
|
105
intl/gettext.h
Normal file
105
intl/gettext.h
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/* Internal header for GNU gettext internationalization functions.
|
||||||
|
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, 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 Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef _GETTEXT_H
|
||||||
|
#define _GETTEXT_H 1
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if HAVE_LIMITS_H || _LIBC
|
||||||
|
# include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* The magic number of the GNU message catalog format. */
|
||||||
|
#define _MAGIC 0x950412de
|
||||||
|
#define _MAGIC_SWAPPED 0xde120495
|
||||||
|
|
||||||
|
/* Revision number of the currently used .mo (binary) file format. */
|
||||||
|
#define MO_REVISION_NUMBER 0
|
||||||
|
|
||||||
|
/* The following contortions are an attempt to use the C preprocessor
|
||||||
|
to determine an unsigned integral type that is 32 bits wide. An
|
||||||
|
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
|
||||||
|
doing that would require that the configure script compile and *run*
|
||||||
|
the resulting executable. Locally running cross-compiled executables
|
||||||
|
is usually not possible. */
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
# define UINT_MAX_32_BITS 4294967295U
|
||||||
|
#else
|
||||||
|
# define UINT_MAX_32_BITS 0xFFFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If UINT_MAX isn't defined, assume it's a 32-bit type.
|
||||||
|
This should be valid for all systems GNU cares about because
|
||||||
|
that doesn't include 16-bit systems, and only modern systems
|
||||||
|
(that certainly have <limits.h>) have 64+-bit integral types. */
|
||||||
|
|
||||||
|
#ifndef UINT_MAX
|
||||||
|
# define UINT_MAX UINT_MAX_32_BITS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UINT_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned nls_uint32;
|
||||||
|
#else
|
||||||
|
# if USHRT_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned short nls_uint32;
|
||||||
|
# else
|
||||||
|
# if ULONG_MAX == UINT_MAX_32_BITS
|
||||||
|
typedef unsigned long nls_uint32;
|
||||||
|
# else
|
||||||
|
/* The following line is intended to throw an error. Using #error is
|
||||||
|
not portable enough. */
|
||||||
|
"Cannot determine unsigned 32-bit data type."
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Header for binary .mo file format. */
|
||||||
|
struct mo_file_header
|
||||||
|
{
|
||||||
|
/* The magic number. */
|
||||||
|
nls_uint32 magic;
|
||||||
|
/* The revision number of the file format. */
|
||||||
|
nls_uint32 revision;
|
||||||
|
/* The number of strings pairs. */
|
||||||
|
nls_uint32 nstrings;
|
||||||
|
/* Offset of table with start offsets of original strings. */
|
||||||
|
nls_uint32 orig_tab_offset;
|
||||||
|
/* Offset of table with start offsets of translation strings. */
|
||||||
|
nls_uint32 trans_tab_offset;
|
||||||
|
/* Size of hashing table. */
|
||||||
|
nls_uint32 hash_tab_size;
|
||||||
|
/* Offset of first hashing entry. */
|
||||||
|
nls_uint32 hash_tab_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_desc
|
||||||
|
{
|
||||||
|
/* Length of addressed string. */
|
||||||
|
nls_uint32 length;
|
||||||
|
/* Offset of string in file. */
|
||||||
|
nls_uint32 offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
#endif /* gettext.h */
|
89
intl/gettextP.h
Normal file
89
intl/gettextP.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/* Header describing internals of gettext library
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef _GETTEXTP_H
|
||||||
|
#define _GETTEXTP_H
|
||||||
|
|
||||||
|
#include "loadinfo.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifndef PARAMS
|
||||||
|
# if __STDC__
|
||||||
|
# define PARAMS(args) args
|
||||||
|
# else
|
||||||
|
# define PARAMS(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef internal_function
|
||||||
|
# define internal_function
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef W
|
||||||
|
# define W(flag, data) ((flag) ? SWAP (data) : (data))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <byteswap.h>
|
||||||
|
# define SWAP(i) bswap_32 (i)
|
||||||
|
#else
|
||||||
|
static nls_uint32 SWAP PARAMS ((nls_uint32 i));
|
||||||
|
|
||||||
|
static inline nls_uint32
|
||||||
|
SWAP (i)
|
||||||
|
nls_uint32 i;
|
||||||
|
{
|
||||||
|
return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct loaded_domain
|
||||||
|
{
|
||||||
|
const char *data;
|
||||||
|
int use_mmap;
|
||||||
|
size_t mmap_size;
|
||||||
|
int must_swap;
|
||||||
|
nls_uint32 nstrings;
|
||||||
|
struct string_desc *orig_tab;
|
||||||
|
struct string_desc *trans_tab;
|
||||||
|
nls_uint32 hash_size;
|
||||||
|
nls_uint32 *hash_tab;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct binding
|
||||||
|
{
|
||||||
|
struct binding *next;
|
||||||
|
char *domainname;
|
||||||
|
char *dirname;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
|
||||||
|
char *__locale,
|
||||||
|
const char *__domainname))
|
||||||
|
internal_function;
|
||||||
|
void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain))
|
||||||
|
internal_function;
|
||||||
|
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain))
|
||||||
|
internal_function;
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
#endif /* gettextP.h */
|
59
intl/hash-string.h
Normal file
59
intl/hash-string.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* Implements a string hashing function.
|
||||||
|
Copyright (C) 1995, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, 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 Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifndef PARAMS
|
||||||
|
# if __STDC__
|
||||||
|
# define PARAMS(Args) Args
|
||||||
|
# else
|
||||||
|
# define PARAMS(Args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We assume to have `unsigned long int' value with at least 32 bits. */
|
||||||
|
#define HASHWORDBITS 32
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines the so called `hashpjw' function by P.J. Weinberger
|
||||||
|
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
|
||||||
|
1986, 1987 Bell Telephone Laboratories, Inc.] */
|
||||||
|
static unsigned long int hash_string PARAMS ((const char *__str_param));
|
||||||
|
|
||||||
|
static inline unsigned long int
|
||||||
|
hash_string (str_param)
|
||||||
|
const char *str_param;
|
||||||
|
{
|
||||||
|
unsigned long int hval, g;
|
||||||
|
const char *str = str_param;
|
||||||
|
|
||||||
|
/* Compute the hash value for the given string. */
|
||||||
|
hval = 0;
|
||||||
|
while (*str != '\0')
|
||||||
|
{
|
||||||
|
hval <<= 4;
|
||||||
|
hval += (unsigned long int) *str++;
|
||||||
|
g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
|
||||||
|
if (g != 0)
|
||||||
|
{
|
||||||
|
hval ^= g >> (HASHWORDBITS - 8);
|
||||||
|
hval ^= g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hval;
|
||||||
|
}
|
76
intl/intl-compat.c
Normal file
76
intl/intl-compat.c
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* intl-compat.c - Stub functions to call gettext functions from GNU gettext
|
||||||
|
Library.
|
||||||
|
Copyright (C) 1995 Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libgettext.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
|
||||||
|
#undef gettext
|
||||||
|
#undef dgettext
|
||||||
|
#undef dcgettext
|
||||||
|
#undef textdomain
|
||||||
|
#undef bindtextdomain
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
bindtextdomain (domainname, dirname)
|
||||||
|
const char *domainname;
|
||||||
|
const char *dirname;
|
||||||
|
{
|
||||||
|
return bindtextdomain__ (domainname, dirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
dcgettext (domainname, msgid, category)
|
||||||
|
const char *domainname;
|
||||||
|
const char *msgid;
|
||||||
|
int category;
|
||||||
|
{
|
||||||
|
return dcgettext__ (domainname, msgid, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
dgettext (domainname, msgid)
|
||||||
|
const char *domainname;
|
||||||
|
const char *msgid;
|
||||||
|
{
|
||||||
|
return dgettext__ (domainname, msgid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
gettext (msgid)
|
||||||
|
const char *msgid;
|
||||||
|
{
|
||||||
|
return gettext__ (msgid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
textdomain (domainname)
|
||||||
|
const char *domainname;
|
||||||
|
{
|
||||||
|
return textdomain__ (domainname);
|
||||||
|
}
|
411
intl/l10nflist.c
Normal file
411
intl/l10nflist.c
Normal file
|
@ -0,0 +1,411 @@
|
||||||
|
/* Handle list of needed message catalogs
|
||||||
|
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE 1
|
||||||
|
# endif
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
# ifndef memcpy
|
||||||
|
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !HAVE_STRCHR && !defined _LIBC
|
||||||
|
# ifndef strchr
|
||||||
|
# define strchr index
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _LIBC || defined HAVE_ARGZ_H
|
||||||
|
# include <argz.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "loadinfo.h"
|
||||||
|
|
||||||
|
/* On some strange systems still no definition of NULL is found. Sigh! */
|
||||||
|
#ifndef NULL
|
||||||
|
# if defined __STDC__ && __STDC__
|
||||||
|
# define NULL ((void *) 0)
|
||||||
|
# else
|
||||||
|
# define NULL 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Rename the non ANSI C functions. This is required by the standard
|
||||||
|
because some ANSI C functions will require linking with this object
|
||||||
|
file and the name space must not be polluted. */
|
||||||
|
# ifndef stpcpy
|
||||||
|
# define stpcpy(dest, src) __stpcpy(dest, src)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# ifndef HAVE_STPCPY
|
||||||
|
static char *stpcpy PARAMS ((char *dest, const char *src));
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define function which are usually not available. */
|
||||||
|
|
||||||
|
#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
|
||||||
|
/* Returns the number of strings in ARGZ. */
|
||||||
|
static size_t argz_count__ PARAMS ((const char *argz, size_t len));
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
argz_count__ (argz, len)
|
||||||
|
const char *argz;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
size_t part_len = strlen (argz);
|
||||||
|
argz += part_len + 1;
|
||||||
|
len -= part_len + 1;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
# undef __argz_count
|
||||||
|
# define __argz_count(argz, len) argz_count__ (argz, len)
|
||||||
|
#endif /* !_LIBC && !HAVE___ARGZ_COUNT */
|
||||||
|
|
||||||
|
#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
|
||||||
|
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
|
||||||
|
except the last into the character SEP. */
|
||||||
|
static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
|
||||||
|
|
||||||
|
static void
|
||||||
|
argz_stringify__ (argz, len, sep)
|
||||||
|
char *argz;
|
||||||
|
size_t len;
|
||||||
|
int sep;
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
size_t part_len = strlen (argz);
|
||||||
|
argz += part_len;
|
||||||
|
len -= part_len + 1;
|
||||||
|
if (len > 0)
|
||||||
|
*argz++ = sep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# undef __argz_stringify
|
||||||
|
# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
|
||||||
|
#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
|
||||||
|
|
||||||
|
#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
|
||||||
|
static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
|
||||||
|
const char *entry));
|
||||||
|
|
||||||
|
static char *
|
||||||
|
argz_next__ (argz, argz_len, entry)
|
||||||
|
char *argz;
|
||||||
|
size_t argz_len;
|
||||||
|
const char *entry;
|
||||||
|
{
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
if (entry < argz + argz_len)
|
||||||
|
entry = strchr (entry, '\0') + 1;
|
||||||
|
|
||||||
|
return entry >= argz + argz_len ? NULL : (char *) entry;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (argz_len > 0)
|
||||||
|
return argz;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
# undef __argz_next
|
||||||
|
# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
|
||||||
|
#endif /* !_LIBC && !HAVE___ARGZ_NEXT */
|
||||||
|
|
||||||
|
|
||||||
|
/* Return number of bits set in X. */
|
||||||
|
static int pop PARAMS ((int x));
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
pop (x)
|
||||||
|
int x;
|
||||||
|
{
|
||||||
|
/* We assume that no more than 16 bits are used. */
|
||||||
|
x = ((x & ~0x5555) >> 1) + (x & 0x5555);
|
||||||
|
x = ((x & ~0x3333) >> 2) + (x & 0x3333);
|
||||||
|
x = ((x >> 4) + x) & 0x0f0f;
|
||||||
|
x = ((x >> 8) + x) & 0xff;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct loaded_l10nfile *
|
||||||
|
_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
|
||||||
|
territory, codeset, normalized_codeset, modifier, special,
|
||||||
|
sponsor, revision, filename, do_allocate)
|
||||||
|
struct loaded_l10nfile **l10nfile_list;
|
||||||
|
const char *dirlist;
|
||||||
|
size_t dirlist_len;
|
||||||
|
int mask;
|
||||||
|
const char *language;
|
||||||
|
const char *territory;
|
||||||
|
const char *codeset;
|
||||||
|
const char *normalized_codeset;
|
||||||
|
const char *modifier;
|
||||||
|
const char *special;
|
||||||
|
const char *sponsor;
|
||||||
|
const char *revision;
|
||||||
|
const char *filename;
|
||||||
|
int do_allocate;
|
||||||
|
{
|
||||||
|
char *abs_filename;
|
||||||
|
struct loaded_l10nfile *last = NULL;
|
||||||
|
struct loaded_l10nfile *retval;
|
||||||
|
char *cp;
|
||||||
|
size_t entries;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
/* Allocate room for the full file name. */
|
||||||
|
abs_filename = (char *) malloc (dirlist_len
|
||||||
|
+ strlen (language)
|
||||||
|
+ ((mask & TERRITORY) != 0
|
||||||
|
? strlen (territory) + 1 : 0)
|
||||||
|
+ ((mask & XPG_CODESET) != 0
|
||||||
|
? strlen (codeset) + 1 : 0)
|
||||||
|
+ ((mask & XPG_NORM_CODESET) != 0
|
||||||
|
? strlen (normalized_codeset) + 1 : 0)
|
||||||
|
+ (((mask & XPG_MODIFIER) != 0
|
||||||
|
|| (mask & CEN_AUDIENCE) != 0)
|
||||||
|
? strlen (modifier) + 1 : 0)
|
||||||
|
+ ((mask & CEN_SPECIAL) != 0
|
||||||
|
? strlen (special) + 1 : 0)
|
||||||
|
+ (((mask & CEN_SPONSOR) != 0
|
||||||
|
|| (mask & CEN_REVISION) != 0)
|
||||||
|
? (1 + ((mask & CEN_SPONSOR) != 0
|
||||||
|
? strlen (sponsor) + 1 : 0)
|
||||||
|
+ ((mask & CEN_REVISION) != 0
|
||||||
|
? strlen (revision) + 1 : 0)) : 0)
|
||||||
|
+ 1 + strlen (filename) + 1);
|
||||||
|
|
||||||
|
if (abs_filename == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retval = NULL;
|
||||||
|
last = NULL;
|
||||||
|
|
||||||
|
/* Construct file name. */
|
||||||
|
memcpy (abs_filename, dirlist, dirlist_len);
|
||||||
|
__argz_stringify (abs_filename, dirlist_len, ':');
|
||||||
|
cp = abs_filename + (dirlist_len - 1);
|
||||||
|
*cp++ = '/';
|
||||||
|
cp = stpcpy (cp, language);
|
||||||
|
|
||||||
|
if ((mask & TERRITORY) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = '_';
|
||||||
|
cp = stpcpy (cp, territory);
|
||||||
|
}
|
||||||
|
if ((mask & XPG_CODESET) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = '.';
|
||||||
|
cp = stpcpy (cp, codeset);
|
||||||
|
}
|
||||||
|
if ((mask & XPG_NORM_CODESET) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = '.';
|
||||||
|
cp = stpcpy (cp, normalized_codeset);
|
||||||
|
}
|
||||||
|
if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
|
||||||
|
{
|
||||||
|
/* This component can be part of both syntaces but has different
|
||||||
|
leading characters. For CEN we use `+', else `@'. */
|
||||||
|
*cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
|
||||||
|
cp = stpcpy (cp, modifier);
|
||||||
|
}
|
||||||
|
if ((mask & CEN_SPECIAL) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = '+';
|
||||||
|
cp = stpcpy (cp, special);
|
||||||
|
}
|
||||||
|
if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = ',';
|
||||||
|
if ((mask & CEN_SPONSOR) != 0)
|
||||||
|
cp = stpcpy (cp, sponsor);
|
||||||
|
if ((mask & CEN_REVISION) != 0)
|
||||||
|
{
|
||||||
|
*cp++ = '_';
|
||||||
|
cp = stpcpy (cp, revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*cp++ = '/';
|
||||||
|
stpcpy (cp, filename);
|
||||||
|
|
||||||
|
/* Look in list of already loaded domains whether it is already
|
||||||
|
available. */
|
||||||
|
last = NULL;
|
||||||
|
for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
|
||||||
|
if (retval->filename != NULL)
|
||||||
|
{
|
||||||
|
int compare = strcmp (retval->filename, abs_filename);
|
||||||
|
if (compare == 0)
|
||||||
|
/* We found it! */
|
||||||
|
break;
|
||||||
|
if (compare < 0)
|
||||||
|
{
|
||||||
|
/* It's not in the list. */
|
||||||
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval != NULL || do_allocate == 0)
|
||||||
|
{
|
||||||
|
free (abs_filename);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = (struct loaded_l10nfile *)
|
||||||
|
malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
|
||||||
|
* (1 << pop (mask))
|
||||||
|
* sizeof (struct loaded_l10nfile *)));
|
||||||
|
if (retval == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retval->filename = abs_filename;
|
||||||
|
retval->decided = (__argz_count (dirlist, dirlist_len) != 1
|
||||||
|
|| ((mask & XPG_CODESET) != 0
|
||||||
|
&& (mask & XPG_NORM_CODESET) != 0));
|
||||||
|
retval->data = NULL;
|
||||||
|
|
||||||
|
if (last == NULL)
|
||||||
|
{
|
||||||
|
retval->next = *l10nfile_list;
|
||||||
|
*l10nfile_list = retval;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retval->next = last->next;
|
||||||
|
last->next = retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries = 0;
|
||||||
|
/* If the DIRLIST is a real list the RETVAL entry corresponds not to
|
||||||
|
a real file. So we have to use the DIRLIST separation mechanism
|
||||||
|
of the inner loop. */
|
||||||
|
cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
|
||||||
|
for (; cnt >= 0; --cnt)
|
||||||
|
if ((cnt & ~mask) == 0
|
||||||
|
&& ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
|
||||||
|
&& ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
|
||||||
|
{
|
||||||
|
/* Iterate over all elements of the DIRLIST. */
|
||||||
|
char *dir = NULL;
|
||||||
|
|
||||||
|
while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
|
||||||
|
!= NULL)
|
||||||
|
retval->successor[entries++]
|
||||||
|
= _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
|
||||||
|
language, territory, codeset,
|
||||||
|
normalized_codeset, modifier, special,
|
||||||
|
sponsor, revision, filename, 1);
|
||||||
|
}
|
||||||
|
retval->successor[entries] = NULL;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normalize codeset name. There is no standard for the codeset
|
||||||
|
names. Normalization allows the user to use any of the common
|
||||||
|
names. */
|
||||||
|
const char *
|
||||||
|
_nl_normalize_codeset (codeset, name_len)
|
||||||
|
const char *codeset;
|
||||||
|
size_t name_len;
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int only_digit = 1;
|
||||||
|
char *retval;
|
||||||
|
char *wp;
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < name_len; ++cnt)
|
||||||
|
if (isalnum (codeset[cnt]))
|
||||||
|
{
|
||||||
|
++len;
|
||||||
|
|
||||||
|
if (isalpha (codeset[cnt]))
|
||||||
|
only_digit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (only_digit)
|
||||||
|
wp = stpcpy (retval, "iso");
|
||||||
|
else
|
||||||
|
wp = retval;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < name_len; ++cnt)
|
||||||
|
if (isalpha (codeset[cnt]))
|
||||||
|
*wp++ = tolower (codeset[cnt]);
|
||||||
|
else if (isdigit (codeset[cnt]))
|
||||||
|
*wp++ = codeset[cnt];
|
||||||
|
|
||||||
|
*wp = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (const char *) retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
/* We don't want libintl.a to depend on any other library. So we
|
||||||
|
avoid the non-standard function stpcpy. In GNU C Library this
|
||||||
|
function is available, though. Also allow the symbol HAVE_STPCPY
|
||||||
|
to be defined. */
|
||||||
|
#if !_LIBC && !HAVE_STPCPY
|
||||||
|
static char *
|
||||||
|
stpcpy (dest, src)
|
||||||
|
char *dest;
|
||||||
|
const char *src;
|
||||||
|
{
|
||||||
|
while ((*dest++ = *src++) != '\0')
|
||||||
|
/* Do nothing. */ ;
|
||||||
|
return dest - 1;
|
||||||
|
}
|
||||||
|
#endif
|
182
intl/libgettext.h
Normal file
182
intl/libgettext.h
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/* Message catalogs for internationalization.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* Because on some systems (e.g. Solaris) we sometimes have to include
|
||||||
|
the systems libintl.h as well as this file we have more complex
|
||||||
|
include protection above. But the systems header might perhaps also
|
||||||
|
define _LIBINTL_H and therefore we have to protect the definition here. */
|
||||||
|
|
||||||
|
#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H
|
||||||
|
#ifndef _LIBINTL_H
|
||||||
|
# define _LIBINTL_H 1
|
||||||
|
#endif
|
||||||
|
#define _LIBGETTEXT_H 1
|
||||||
|
|
||||||
|
/* We define an additional symbol to signal that we use the GNU
|
||||||
|
implementation of gettext. */
|
||||||
|
#define __USE_GNU_GETTEXT 1
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if HAVE_LOCALE_H
|
||||||
|
# include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifndef PARAMS
|
||||||
|
# if __STDC__ || defined __cplusplus
|
||||||
|
# define PARAMS(args) args
|
||||||
|
# else
|
||||||
|
# define PARAMS(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
# if !defined __cplusplus || defined __GNUC__
|
||||||
|
# define NULL ((void *) 0)
|
||||||
|
# else
|
||||||
|
# define NULL (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_LC_MESSAGES
|
||||||
|
/* This value determines the behaviour of the gettext() and dgettext()
|
||||||
|
function. But some system does not have this defined. Define it
|
||||||
|
to a default value. */
|
||||||
|
# define LC_MESSAGES (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Declarations for gettext-using-catgets interface. Derived from
|
||||||
|
Jim Meyering's libintl.h. */
|
||||||
|
struct _msg_ent
|
||||||
|
{
|
||||||
|
const char *_msg;
|
||||||
|
int _msg_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_CATGETS
|
||||||
|
/* These two variables are defined in the automatically by po-to-tbl.sed
|
||||||
|
generated file `cat-id-tbl.c'. */
|
||||||
|
extern const struct _msg_ent _msg_tbl[];
|
||||||
|
extern int _msg_tbl_length;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* For automatical extraction of messages sometimes no real
|
||||||
|
translation is needed. Instead the string itself is the result. */
|
||||||
|
#define gettext_noop(Str) (Str)
|
||||||
|
|
||||||
|
/* Look up MSGID in the current default message catalog for the current
|
||||||
|
LC_MESSAGES locale. If not found, returns MSGID itself (the default
|
||||||
|
text). */
|
||||||
|
extern char *gettext PARAMS ((const char *__msgid));
|
||||||
|
extern char *gettext__ PARAMS ((const char *__msgid));
|
||||||
|
|
||||||
|
/* Look up MSGID in the DOMAINNAME message catalog for the current
|
||||||
|
LC_MESSAGES locale. */
|
||||||
|
extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
|
||||||
|
extern char *dgettext__ PARAMS ((const char *__domainname,
|
||||||
|
const char *__msgid));
|
||||||
|
|
||||||
|
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
|
||||||
|
locale. */
|
||||||
|
extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
|
||||||
|
int __category));
|
||||||
|
extern char *dcgettext__ PARAMS ((const char *__domainname,
|
||||||
|
const char *__msgid, int __category));
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the current default message catalog to DOMAINNAME.
|
||||||
|
If DOMAINNAME is null, return the current default.
|
||||||
|
If DOMAINNAME is "", reset to the default of "messages". */
|
||||||
|
extern char *textdomain PARAMS ((const char *__domainname));
|
||||||
|
extern char *textdomain__ PARAMS ((const char *__domainname));
|
||||||
|
|
||||||
|
/* Specify that the DOMAINNAME message catalog will be found
|
||||||
|
in DIRNAME rather than in the system locale data base. */
|
||||||
|
extern char *bindtextdomain PARAMS ((const char *__domainname,
|
||||||
|
const char *__dirname));
|
||||||
|
extern char *bindtextdomain__ PARAMS ((const char *__domainname,
|
||||||
|
const char *__dirname));
|
||||||
|
|
||||||
|
#if ENABLE_NLS
|
||||||
|
|
||||||
|
/* Solaris 2.3 has the gettext function but dcgettext is missing.
|
||||||
|
So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4
|
||||||
|
has dcgettext. */
|
||||||
|
# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT)
|
||||||
|
|
||||||
|
# define gettext(Msgid) \
|
||||||
|
dgettext (NULL, Msgid)
|
||||||
|
|
||||||
|
# define dgettext(Domainname, Msgid) \
|
||||||
|
dcgettext (Domainname, Msgid, LC_MESSAGES)
|
||||||
|
|
||||||
|
# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
|
||||||
|
/* This global variable is defined in loadmsgcat.c. We need a sign,
|
||||||
|
whether a new catalog was loaded, which can be associated with all
|
||||||
|
translations. */
|
||||||
|
extern int _nl_msg_cat_cntr;
|
||||||
|
|
||||||
|
# define dcgettext(Domainname, Msgid, Category) \
|
||||||
|
(__extension__ \
|
||||||
|
({ \
|
||||||
|
char *__result; \
|
||||||
|
if (__builtin_constant_p (Msgid)) \
|
||||||
|
{ \
|
||||||
|
static char *__translation__; \
|
||||||
|
static int __catalog_counter__; \
|
||||||
|
if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
|
||||||
|
{ \
|
||||||
|
__translation__ = \
|
||||||
|
dcgettext__ (Domainname, Msgid, Category); \
|
||||||
|
__catalog_counter__ = _nl_msg_cat_cntr; \
|
||||||
|
} \
|
||||||
|
__result = __translation__; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
__result = dcgettext__ (Domainname, Msgid, Category); \
|
||||||
|
__result; \
|
||||||
|
}))
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define gettext(Msgid) (Msgid)
|
||||||
|
# define dgettext(Domainname, Msgid) (Msgid)
|
||||||
|
# define dcgettext(Domainname, Msgid, Category) (Msgid)
|
||||||
|
# define textdomain(Domainname) ((char *) Domainname)
|
||||||
|
# define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ begin of epilog @@ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
100
intl/linux-msg.sed
Normal file
100
intl/linux-msg.sed
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file
|
||||||
|
# Copyright (C) 1995 Free Software Foundation, Inc.
|
||||||
|
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The first directive in the .msg should be the definition of the
|
||||||
|
# message set number. We use always set number 1.
|
||||||
|
#
|
||||||
|
1 {
|
||||||
|
i\
|
||||||
|
$set 1 # Automatically created by po2msg.sed
|
||||||
|
h
|
||||||
|
s/.*/0/
|
||||||
|
x
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# Mitch's old catalog format does not allow comments.
|
||||||
|
#
|
||||||
|
# We copy the original message as a comment into the .msg file.
|
||||||
|
#
|
||||||
|
/^msgid/ {
|
||||||
|
s/msgid[ ]*"//
|
||||||
|
#
|
||||||
|
# This does not work now with the new format.
|
||||||
|
# /"$/! {
|
||||||
|
# s/\\$//
|
||||||
|
# s/$/ ... (more lines following)"/
|
||||||
|
# }
|
||||||
|
x
|
||||||
|
# The following nice solution is by
|
||||||
|
# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
|
||||||
|
td
|
||||||
|
# Increment a decimal number in pattern space.
|
||||||
|
# First hide trailing `9' digits.
|
||||||
|
:d
|
||||||
|
s/9\(_*\)$/_\1/
|
||||||
|
td
|
||||||
|
# Assure at least one digit is available.
|
||||||
|
s/^\(_*\)$/0\1/
|
||||||
|
# Increment the last digit.
|
||||||
|
s/8\(_*\)$/9\1/
|
||||||
|
s/7\(_*\)$/8\1/
|
||||||
|
s/6\(_*\)$/7\1/
|
||||||
|
s/5\(_*\)$/6\1/
|
||||||
|
s/4\(_*\)$/5\1/
|
||||||
|
s/3\(_*\)$/4\1/
|
||||||
|
s/2\(_*\)$/3\1/
|
||||||
|
s/1\(_*\)$/2\1/
|
||||||
|
s/0\(_*\)$/1\1/
|
||||||
|
# Convert the hidden `9' digits to `0's.
|
||||||
|
s/_/0/g
|
||||||
|
x
|
||||||
|
G
|
||||||
|
s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# The .msg file contains, other then the .po file, only the translations
|
||||||
|
# but each given a unique ID. Starting from 1 and incrementing by 1 for
|
||||||
|
# each message we assign them to the messages.
|
||||||
|
# It is important that the .po file used to generate the cat-id-tbl.c file
|
||||||
|
# (with po-to-tbl) is the same as the one used here. (At least the order
|
||||||
|
# of declarations must not be changed.)
|
||||||
|
#
|
||||||
|
/^msgstr/ {
|
||||||
|
s/msgstr[ ]*"\(.*\)"/# \1/
|
||||||
|
# Clear substitution flag.
|
||||||
|
tb
|
||||||
|
# Append the next line.
|
||||||
|
:b
|
||||||
|
N
|
||||||
|
# Look whether second part is continuation line.
|
||||||
|
s/\(.*\n\)"\(.*\)"/\1\2/
|
||||||
|
# Yes, then branch.
|
||||||
|
ta
|
||||||
|
P
|
||||||
|
D
|
||||||
|
# Note that D includes a jump to the start!!
|
||||||
|
# We found a continuation line. But before printing insert '\'.
|
||||||
|
:a
|
||||||
|
s/\(.*\)\(\n.*\)/\1\\\2/
|
||||||
|
P
|
||||||
|
# We cannot use D here.
|
||||||
|
s/.*\n\(.*\)/\1/
|
||||||
|
tb
|
||||||
|
}
|
||||||
|
d
|
78
intl/loadinfo.h
Normal file
78
intl/loadinfo.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef PARAMS
|
||||||
|
# if __STDC__
|
||||||
|
# define PARAMS(args) args
|
||||||
|
# else
|
||||||
|
# define PARAMS(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Encoding of locale name parts. */
|
||||||
|
#define CEN_REVISION 1
|
||||||
|
#define CEN_SPONSOR 2
|
||||||
|
#define CEN_SPECIAL 4
|
||||||
|
#define XPG_NORM_CODESET 8
|
||||||
|
#define XPG_CODESET 16
|
||||||
|
#define TERRITORY 32
|
||||||
|
#define CEN_AUDIENCE 64
|
||||||
|
#define XPG_MODIFIER 128
|
||||||
|
|
||||||
|
#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
|
||||||
|
#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
|
||||||
|
|
||||||
|
|
||||||
|
struct loaded_l10nfile
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
int decided;
|
||||||
|
|
||||||
|
const void *data;
|
||||||
|
|
||||||
|
struct loaded_l10nfile *next;
|
||||||
|
struct loaded_l10nfile *successor[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
|
||||||
|
size_t name_len));
|
||||||
|
|
||||||
|
extern struct loaded_l10nfile *
|
||||||
|
_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
|
||||||
|
const char *dirlist, size_t dirlist_len, int mask,
|
||||||
|
const char *language, const char *territory,
|
||||||
|
const char *codeset,
|
||||||
|
const char *normalized_codeset,
|
||||||
|
const char *modifier, const char *special,
|
||||||
|
const char *sponsor, const char *revision,
|
||||||
|
const char *filename, int do_allocate));
|
||||||
|
|
||||||
|
|
||||||
|
extern const char *_nl_expand_alias PARAMS ((const char *name));
|
||||||
|
|
||||||
|
extern int _nl_explode_name PARAMS ((char *name, const char **language,
|
||||||
|
const char **modifier,
|
||||||
|
const char **territory,
|
||||||
|
const char **codeset,
|
||||||
|
const char **normalized_codeset,
|
||||||
|
const char **special,
|
||||||
|
const char **sponsor,
|
||||||
|
const char **revision));
|
||||||
|
|
||||||
|
extern char *_nl_find_language PARAMS ((const char *name));
|
220
intl/loadmsgcat.c
Normal file
220
intl/loadmsgcat.c
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/* Load needed message catalogs.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_UNISTD_H || defined _LIBC
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
|
||||||
|
|| (defined _LIBC && defined _POSIX_MAPPED_FILES)
|
||||||
|
# include <sys/mman.h>
|
||||||
|
# undef HAVE_MMAP
|
||||||
|
# define HAVE_MMAP 1
|
||||||
|
#else
|
||||||
|
# undef HAVE_MMAP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "gettextP.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Rename the non ISO C functions. This is required by the standard
|
||||||
|
because some ISO C functions will require linking with this object
|
||||||
|
file and the name space must not be polluted. */
|
||||||
|
# define open __open
|
||||||
|
# define close __close
|
||||||
|
# define read __read
|
||||||
|
# define mmap __mmap
|
||||||
|
# define munmap __munmap
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We need a sign, whether a new catalog was loaded, which can be associated
|
||||||
|
with all translations. This is important if the translations are
|
||||||
|
cached by one of GCC's features. */
|
||||||
|
int _nl_msg_cat_cntr = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Load the message catalogs specified by FILENAME. If it is no valid
|
||||||
|
message catalog do nothing. */
|
||||||
|
void
|
||||||
|
internal_function
|
||||||
|
_nl_load_domain (domain_file)
|
||||||
|
struct loaded_l10nfile *domain_file;
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
size_t size;
|
||||||
|
struct stat st;
|
||||||
|
struct mo_file_header *data = (struct mo_file_header *) -1;
|
||||||
|
int use_mmap = 0;
|
||||||
|
struct loaded_domain *domain;
|
||||||
|
|
||||||
|
domain_file->decided = 1;
|
||||||
|
domain_file->data = NULL;
|
||||||
|
|
||||||
|
/* If the record does not represent a valid locale the FILENAME
|
||||||
|
might be NULL. This can happen when according to the given
|
||||||
|
specification the locale file name is different for XPG and CEN
|
||||||
|
syntax. */
|
||||||
|
if (domain_file->filename == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Try to open the addressed file. */
|
||||||
|
fd = open (domain_file->filename, O_RDONLY);
|
||||||
|
if (fd == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We must know about the size of the file. */
|
||||||
|
if (fstat (fd, &st) != 0
|
||||||
|
|| (size = (size_t) st.st_size) != st.st_size
|
||||||
|
|| size < sizeof (struct mo_file_header))
|
||||||
|
{
|
||||||
|
/* Something went wrong. */
|
||||||
|
close (fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
/* Now we are ready to load the file. If mmap() is available we try
|
||||||
|
this first. If not available or it failed we try to load it. */
|
||||||
|
data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
|
||||||
|
MAP_PRIVATE, fd, 0);
|
||||||
|
|
||||||
|
if (data != (struct mo_file_header *) -1)
|
||||||
|
{
|
||||||
|
/* mmap() call was successful. */
|
||||||
|
close (fd);
|
||||||
|
use_mmap = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the data is not yet available (i.e. mmap'ed) we try to load
|
||||||
|
it manually. */
|
||||||
|
if (data == (struct mo_file_header *) -1)
|
||||||
|
{
|
||||||
|
size_t to_read;
|
||||||
|
char *read_ptr;
|
||||||
|
|
||||||
|
data = (struct mo_file_header *) malloc (size);
|
||||||
|
if (data == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
to_read = size;
|
||||||
|
read_ptr = (char *) data;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
long int nb = (long int) read (fd, read_ptr, to_read);
|
||||||
|
if (nb == -1)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_ptr += nb;
|
||||||
|
to_read -= nb;
|
||||||
|
}
|
||||||
|
while (to_read > 0);
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Using the magic number we can test whether it really is a message
|
||||||
|
catalog file. */
|
||||||
|
if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
|
||||||
|
{
|
||||||
|
/* The magic number is wrong: not a message catalog file. */
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
if (use_mmap)
|
||||||
|
munmap ((caddr_t) data, size);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
free (data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
domain_file->data
|
||||||
|
= (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
|
||||||
|
if (domain_file->data == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
domain = (struct loaded_domain *) domain_file->data;
|
||||||
|
domain->data = (char *) data;
|
||||||
|
domain->use_mmap = use_mmap;
|
||||||
|
domain->mmap_size = size;
|
||||||
|
domain->must_swap = data->magic != _MAGIC;
|
||||||
|
|
||||||
|
/* Fill in the information about the available tables. */
|
||||||
|
switch (W (domain->must_swap, data->revision))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
domain->nstrings = W (domain->must_swap, data->nstrings);
|
||||||
|
domain->orig_tab = (struct string_desc *)
|
||||||
|
((char *) data + W (domain->must_swap, data->orig_tab_offset));
|
||||||
|
domain->trans_tab = (struct string_desc *)
|
||||||
|
((char *) data + W (domain->must_swap, data->trans_tab_offset));
|
||||||
|
domain->hash_size = W (domain->must_swap, data->hash_tab_size);
|
||||||
|
domain->hash_tab = (nls_uint32 *)
|
||||||
|
((char *) data + W (domain->must_swap, data->hash_tab_offset));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* This is an invalid revision. */
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
if (use_mmap)
|
||||||
|
munmap ((caddr_t) data, size);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
free (data);
|
||||||
|
free (domain);
|
||||||
|
domain_file->data = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show that one domain is changed. This might make some cached
|
||||||
|
translations invalid. */
|
||||||
|
++_nl_msg_cat_cntr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
void
|
||||||
|
internal_function
|
||||||
|
_nl_unload_domain (domain)
|
||||||
|
struct loaded_domain *domain;
|
||||||
|
{
|
||||||
|
#ifdef _POSIX_MAPPED_FILES
|
||||||
|
if (domain->use_mmap)
|
||||||
|
munmap ((caddr_t) domain->data, domain->mmap_size);
|
||||||
|
else
|
||||||
|
#endif /* _POSIX_MAPPED_FILES */
|
||||||
|
free ((void *) domain->data);
|
||||||
|
|
||||||
|
free (domain);
|
||||||
|
}
|
||||||
|
#endif
|
438
intl/localealias.c
Normal file
438
intl/localealias.c
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
/* Handle aliases for locale names.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define alloca __builtin_alloca
|
||||||
|
# define HAVE_ALLOCA 1
|
||||||
|
#else
|
||||||
|
# if defined HAVE_ALLOCA_H || defined _LIBC
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
# else
|
||||||
|
# ifndef alloca
|
||||||
|
char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#else
|
||||||
|
char *getenv ();
|
||||||
|
# ifdef HAVE_MALLOC_H
|
||||||
|
# include <malloc.h>
|
||||||
|
# else
|
||||||
|
void free ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE 1
|
||||||
|
# endif
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
# ifndef memcpy
|
||||||
|
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !HAVE_STRCHR && !defined _LIBC
|
||||||
|
# ifndef strchr
|
||||||
|
# define strchr index
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "gettextP.h"
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Rename the non ANSI C functions. This is required by the standard
|
||||||
|
because some ANSI C functions will require linking with this object
|
||||||
|
file and the name space must not be polluted. */
|
||||||
|
# define strcasecmp __strcasecmp
|
||||||
|
|
||||||
|
# ifndef mempcpy
|
||||||
|
# define mempcpy __mempcpy
|
||||||
|
# endif
|
||||||
|
# define HAVE_MEMPCPY 1
|
||||||
|
|
||||||
|
/* We need locking here since we can be called from different places. */
|
||||||
|
# include <bits/libc-lock.h>
|
||||||
|
|
||||||
|
__libc_lock_define_initialized (static, lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef internal_function
|
||||||
|
# define internal_function
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For those loosing systems which don't have `alloca' we have to add
|
||||||
|
some additional code emulating it. */
|
||||||
|
#ifdef HAVE_ALLOCA
|
||||||
|
/* Nothing has to be done. */
|
||||||
|
# define ADD_BLOCK(list, address) /* nothing */
|
||||||
|
# define FREE_BLOCKS(list) /* nothing */
|
||||||
|
#else
|
||||||
|
struct block_list
|
||||||
|
{
|
||||||
|
void *address;
|
||||||
|
struct block_list *next;
|
||||||
|
};
|
||||||
|
# define ADD_BLOCK(list, addr) \
|
||||||
|
do { \
|
||||||
|
struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
|
||||||
|
/* If we cannot get a free block we cannot add the new element to \
|
||||||
|
the list. */ \
|
||||||
|
if (newp != NULL) { \
|
||||||
|
newp->address = (addr); \
|
||||||
|
newp->next = (list); \
|
||||||
|
(list) = newp; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
# define FREE_BLOCKS(list) \
|
||||||
|
do { \
|
||||||
|
while (list != NULL) { \
|
||||||
|
struct block_list *old = list; \
|
||||||
|
list = list->next; \
|
||||||
|
free (old); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
# undef alloca
|
||||||
|
# define alloca(size) (malloc (size))
|
||||||
|
#endif /* have alloca */
|
||||||
|
|
||||||
|
#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
|
||||||
|
# undef fgets
|
||||||
|
# define fgets(buf, len, s) fgets_unlocked (buf, len, s)
|
||||||
|
#endif
|
||||||
|
#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
|
||||||
|
# undef feof
|
||||||
|
# define feof(s) feof_unlocked (s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct alias_map
|
||||||
|
{
|
||||||
|
const char *alias;
|
||||||
|
const char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static char *string_space = NULL;
|
||||||
|
static size_t string_space_act = 0;
|
||||||
|
static size_t string_space_max = 0;
|
||||||
|
static struct alias_map *map;
|
||||||
|
static size_t nmap = 0;
|
||||||
|
static size_t maxmap = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Prototypes for local functions. */
|
||||||
|
static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
|
||||||
|
internal_function;
|
||||||
|
static void extend_alias_table PARAMS ((void));
|
||||||
|
static int alias_compare PARAMS ((const struct alias_map *map1,
|
||||||
|
const struct alias_map *map2));
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
_nl_expand_alias (name)
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
static const char *locale_alias_path = LOCALE_ALIAS_PATH;
|
||||||
|
struct alias_map *retval;
|
||||||
|
const char *result = NULL;
|
||||||
|
size_t added;
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
__libc_lock_lock (lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
struct alias_map item;
|
||||||
|
|
||||||
|
item.alias = name;
|
||||||
|
|
||||||
|
if (nmap > 0)
|
||||||
|
retval = (struct alias_map *) bsearch (&item, map, nmap,
|
||||||
|
sizeof (struct alias_map),
|
||||||
|
(int (*) PARAMS ((const void *,
|
||||||
|
const void *))
|
||||||
|
) alias_compare);
|
||||||
|
else
|
||||||
|
retval = NULL;
|
||||||
|
|
||||||
|
/* We really found an alias. Return the value. */
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
result = retval->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perhaps we can find another alias file. */
|
||||||
|
added = 0;
|
||||||
|
while (added == 0 && locale_alias_path[0] != '\0')
|
||||||
|
{
|
||||||
|
const char *start;
|
||||||
|
|
||||||
|
while (locale_alias_path[0] == ':')
|
||||||
|
++locale_alias_path;
|
||||||
|
start = locale_alias_path;
|
||||||
|
|
||||||
|
while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
|
||||||
|
++locale_alias_path;
|
||||||
|
|
||||||
|
if (start < locale_alias_path)
|
||||||
|
added = read_alias_file (start, locale_alias_path - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (added != 0);
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
__libc_lock_unlock (lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
internal_function
|
||||||
|
read_alias_file (fname, fname_len)
|
||||||
|
const char *fname;
|
||||||
|
int fname_len;
|
||||||
|
{
|
||||||
|
#ifndef HAVE_ALLOCA
|
||||||
|
struct block_list *block_list = NULL;
|
||||||
|
#endif
|
||||||
|
FILE *fp;
|
||||||
|
char *full_fname;
|
||||||
|
size_t added;
|
||||||
|
static const char aliasfile[] = "/locale.alias";
|
||||||
|
|
||||||
|
full_fname = (char *) alloca (fname_len + sizeof aliasfile);
|
||||||
|
ADD_BLOCK (block_list, full_fname);
|
||||||
|
#ifdef HAVE_MEMPCPY
|
||||||
|
mempcpy (mempcpy (full_fname, fname, fname_len),
|
||||||
|
aliasfile, sizeof aliasfile);
|
||||||
|
#else
|
||||||
|
memcpy (full_fname, fname, fname_len);
|
||||||
|
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fp = fopen (full_fname, "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
added = 0;
|
||||||
|
while (!feof (fp))
|
||||||
|
{
|
||||||
|
/* It is a reasonable approach to use a fix buffer here because
|
||||||
|
a) we are only interested in the first two fields
|
||||||
|
b) these fields must be usable as file names and so must not
|
||||||
|
be that long
|
||||||
|
*/
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
char *alias;
|
||||||
|
char *value;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (fgets (buf, sizeof buf, fp) == NULL)
|
||||||
|
/* EOF reached. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Possibly not the whole line fits into the buffer. Ignore
|
||||||
|
the rest of the line. */
|
||||||
|
if (strchr (buf, '\n') == NULL)
|
||||||
|
{
|
||||||
|
char altbuf[BUFSIZ];
|
||||||
|
do
|
||||||
|
if (fgets (altbuf, sizeof altbuf, fp) == NULL)
|
||||||
|
/* Make sure the inner loop will be left. The outer loop
|
||||||
|
will exit at the `feof' test. */
|
||||||
|
break;
|
||||||
|
while (strchr (altbuf, '\n') == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = buf;
|
||||||
|
/* Ignore leading white space. */
|
||||||
|
while (isspace (cp[0]))
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
/* A leading '#' signals a comment line. */
|
||||||
|
if (cp[0] != '\0' && cp[0] != '#')
|
||||||
|
{
|
||||||
|
alias = cp++;
|
||||||
|
while (cp[0] != '\0' && !isspace (cp[0]))
|
||||||
|
++cp;
|
||||||
|
/* Terminate alias name. */
|
||||||
|
if (cp[0] != '\0')
|
||||||
|
*cp++ = '\0';
|
||||||
|
|
||||||
|
/* Now look for the beginning of the value. */
|
||||||
|
while (isspace (cp[0]))
|
||||||
|
++cp;
|
||||||
|
|
||||||
|
if (cp[0] != '\0')
|
||||||
|
{
|
||||||
|
size_t alias_len;
|
||||||
|
size_t value_len;
|
||||||
|
|
||||||
|
value = cp++;
|
||||||
|
while (cp[0] != '\0' && !isspace (cp[0]))
|
||||||
|
++cp;
|
||||||
|
/* Terminate value. */
|
||||||
|
if (cp[0] == '\n')
|
||||||
|
{
|
||||||
|
/* This has to be done to make the following test
|
||||||
|
for the end of line possible. We are looking for
|
||||||
|
the terminating '\n' which do not overwrite here. */
|
||||||
|
*cp++ = '\0';
|
||||||
|
*cp = '\n';
|
||||||
|
}
|
||||||
|
else if (cp[0] != '\0')
|
||||||
|
*cp++ = '\0';
|
||||||
|
|
||||||
|
if (nmap >= maxmap)
|
||||||
|
extend_alias_table ();
|
||||||
|
|
||||||
|
alias_len = strlen (alias) + 1;
|
||||||
|
value_len = strlen (value) + 1;
|
||||||
|
|
||||||
|
if (string_space_act + alias_len + value_len > string_space_max)
|
||||||
|
{
|
||||||
|
/* Increase size of memory pool. */
|
||||||
|
size_t new_size = (string_space_max
|
||||||
|
+ (alias_len + value_len > 1024
|
||||||
|
? alias_len + value_len : 1024));
|
||||||
|
char *new_pool = (char *) realloc (string_space, new_size);
|
||||||
|
if (new_pool == NULL)
|
||||||
|
{
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
string_space = new_pool;
|
||||||
|
string_space_max = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
map[nmap].alias = memcpy (&string_space[string_space_act],
|
||||||
|
alias, alias_len);
|
||||||
|
string_space_act += alias_len;
|
||||||
|
|
||||||
|
map[nmap].value = memcpy (&string_space[string_space_act],
|
||||||
|
value, value_len);
|
||||||
|
string_space_act += value_len;
|
||||||
|
|
||||||
|
++nmap;
|
||||||
|
++added;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should we test for ferror()? I think we have to silently ignore
|
||||||
|
errors. --drepper */
|
||||||
|
fclose (fp);
|
||||||
|
|
||||||
|
if (added > 0)
|
||||||
|
qsort (map, nmap, sizeof (struct alias_map),
|
||||||
|
(int (*) PARAMS ((const void *, const void *))) alias_compare);
|
||||||
|
|
||||||
|
FREE_BLOCKS (block_list);
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
extend_alias_table ()
|
||||||
|
{
|
||||||
|
size_t new_size;
|
||||||
|
struct alias_map *new_map;
|
||||||
|
|
||||||
|
new_size = maxmap == 0 ? 100 : 2 * maxmap;
|
||||||
|
new_map = (struct alias_map *) realloc (map, (new_size
|
||||||
|
* sizeof (struct alias_map)));
|
||||||
|
if (new_map == NULL)
|
||||||
|
/* Simply don't extend: we don't have any more core. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
map = new_map;
|
||||||
|
maxmap = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
static void __attribute__ ((unused))
|
||||||
|
free_mem (void)
|
||||||
|
{
|
||||||
|
if (string_space != NULL)
|
||||||
|
free (string_space);
|
||||||
|
if (map != NULL)
|
||||||
|
free (map);
|
||||||
|
}
|
||||||
|
text_set_element (__libc_subfreeres, free_mem);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
alias_compare (map1, map2)
|
||||||
|
const struct alias_map *map1;
|
||||||
|
const struct alias_map *map2;
|
||||||
|
{
|
||||||
|
#if defined _LIBC || defined HAVE_STRCASECMP
|
||||||
|
return strcasecmp (map1->alias, map2->alias);
|
||||||
|
#else
|
||||||
|
const unsigned char *p1 = (const unsigned char *) map1->alias;
|
||||||
|
const unsigned char *p2 = (const unsigned char *) map2->alias;
|
||||||
|
unsigned char c1, c2;
|
||||||
|
|
||||||
|
if (p1 == p2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* I know this seems to be odd but the tolower() function in
|
||||||
|
some systems libc cannot handle nonalpha characters. */
|
||||||
|
c1 = isupper (*p1) ? tolower (*p1) : *p1;
|
||||||
|
c2 = isupper (*p2) ? tolower (*p2) : *p2;
|
||||||
|
if (c1 == '\0')
|
||||||
|
break;
|
||||||
|
++p1;
|
||||||
|
++p2;
|
||||||
|
}
|
||||||
|
while (c1 == c2);
|
||||||
|
|
||||||
|
return c1 - c2;
|
||||||
|
#endif
|
||||||
|
}
|
102
intl/po2tbl.sed.in
Normal file
102
intl/po2tbl.sed.in
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets
|
||||||
|
# Copyright (C) 1995 Free Software Foundation, Inc.
|
||||||
|
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
1 {
|
||||||
|
i\
|
||||||
|
/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\
|
||||||
|
\
|
||||||
|
#if HAVE_CONFIG_H\
|
||||||
|
# include <config.h>\
|
||||||
|
#endif\
|
||||||
|
\
|
||||||
|
#include "libgettext.h"\
|
||||||
|
\
|
||||||
|
const struct _msg_ent _msg_tbl[] = {
|
||||||
|
h
|
||||||
|
s/.*/0/
|
||||||
|
x
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# Write msgid entries in C array form.
|
||||||
|
#
|
||||||
|
/^msgid/ {
|
||||||
|
s/msgid[ ]*\(".*"\)/ {\1/
|
||||||
|
tb
|
||||||
|
# Append the next line
|
||||||
|
:b
|
||||||
|
N
|
||||||
|
# Look whether second part is continuation line.
|
||||||
|
s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/
|
||||||
|
# Yes, then branch.
|
||||||
|
ta
|
||||||
|
# Because we assume that the input file correctly formed the line
|
||||||
|
# just read cannot be again be a msgid line. So it's safe to ignore
|
||||||
|
# it.
|
||||||
|
s/\(.*\)\n.*/\1/
|
||||||
|
bc
|
||||||
|
# We found a continuation line. But before printing insert '\'.
|
||||||
|
:a
|
||||||
|
s/\(.*\)\(\n.*\)/\1\\\2/
|
||||||
|
P
|
||||||
|
# We cannot use D here.
|
||||||
|
s/.*\n\(.*\)/\1/
|
||||||
|
# Some buggy seds do not clear the `successful substitution since last ``t'''
|
||||||
|
# flag on `N', so we do a `t' here to clear it.
|
||||||
|
tb
|
||||||
|
# Not reached
|
||||||
|
:c
|
||||||
|
x
|
||||||
|
# The following nice solution is by
|
||||||
|
# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
|
||||||
|
td
|
||||||
|
# Increment a decimal number in pattern space.
|
||||||
|
# First hide trailing `9' digits.
|
||||||
|
:d
|
||||||
|
s/9\(_*\)$/_\1/
|
||||||
|
td
|
||||||
|
# Assure at least one digit is available.
|
||||||
|
s/^\(_*\)$/0\1/
|
||||||
|
# Increment the last digit.
|
||||||
|
s/8\(_*\)$/9\1/
|
||||||
|
s/7\(_*\)$/8\1/
|
||||||
|
s/6\(_*\)$/7\1/
|
||||||
|
s/5\(_*\)$/6\1/
|
||||||
|
s/4\(_*\)$/5\1/
|
||||||
|
s/3\(_*\)$/4\1/
|
||||||
|
s/2\(_*\)$/3\1/
|
||||||
|
s/1\(_*\)$/2\1/
|
||||||
|
s/0\(_*\)$/1\1/
|
||||||
|
# Convert the hidden `9' digits to `0's.
|
||||||
|
s/_/0/g
|
||||||
|
x
|
||||||
|
G
|
||||||
|
s/\(.*\)\n\([0-9]*\)/\1, \2},/
|
||||||
|
s/\(.*\)"$/\1/
|
||||||
|
p
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# Last line.
|
||||||
|
#
|
||||||
|
$ {
|
||||||
|
i\
|
||||||
|
};\
|
||||||
|
|
||||||
|
g
|
||||||
|
s/0*\(.*\)/int _msg_tbl_length = \1;/p
|
||||||
|
}
|
||||||
|
d
|
108
intl/textdomain.c
Normal file
108
intl/textdomain.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/* Implementation of the textdomain(3) function.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined _LIBC
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC
|
||||||
|
# include <string.h>
|
||||||
|
#else
|
||||||
|
# include <strings.h>
|
||||||
|
# ifndef memcpy
|
||||||
|
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
#else
|
||||||
|
# include "libgettext.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* @@ end of prolog @@ */
|
||||||
|
|
||||||
|
/* Name of the default text domain. */
|
||||||
|
extern const char _nl_default_default_domain[];
|
||||||
|
|
||||||
|
/* Default text domain in which entries for gettext(3) are to be found. */
|
||||||
|
extern const char *_nl_current_default_domain;
|
||||||
|
|
||||||
|
|
||||||
|
/* Names for the libintl functions are a problem. They must not clash
|
||||||
|
with existing names and they should follow ANSI C. But this source
|
||||||
|
code is also used in GNU C Library where the names have a __
|
||||||
|
prefix. So we have to make a difference here. */
|
||||||
|
#ifdef _LIBC
|
||||||
|
# define TEXTDOMAIN __textdomain
|
||||||
|
# ifndef strdup
|
||||||
|
# define strdup(str) __strdup (str)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define TEXTDOMAIN textdomain__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set the current default message catalog to DOMAINNAME.
|
||||||
|
If DOMAINNAME is null, return the current default.
|
||||||
|
If DOMAINNAME is "", reset to the default of "messages". */
|
||||||
|
char *
|
||||||
|
TEXTDOMAIN (domainname)
|
||||||
|
const char *domainname;
|
||||||
|
{
|
||||||
|
char *old;
|
||||||
|
|
||||||
|
/* A NULL pointer requests the current setting. */
|
||||||
|
if (domainname == NULL)
|
||||||
|
return (char *) _nl_current_default_domain;
|
||||||
|
|
||||||
|
old = (char *) _nl_current_default_domain;
|
||||||
|
|
||||||
|
/* If domain name is the null string set to default domain "messages". */
|
||||||
|
if (domainname[0] == '\0'
|
||||||
|
|| strcmp (domainname, _nl_default_default_domain) == 0)
|
||||||
|
_nl_current_default_domain = _nl_default_default_domain;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If the following malloc fails `_nl_current_default_domain'
|
||||||
|
will be NULL. This value will be returned and so signals we
|
||||||
|
are out of core. */
|
||||||
|
#if defined _LIBC || defined HAVE_STRDUP
|
||||||
|
_nl_current_default_domain = strdup (domainname);
|
||||||
|
#else
|
||||||
|
size_t len = strlen (domainname) + 1;
|
||||||
|
char *cp = (char *) malloc (len);
|
||||||
|
if (cp != NULL)
|
||||||
|
memcpy (cp, domainname, len);
|
||||||
|
_nl_current_default_domain = cp;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old != _nl_default_default_domain)
|
||||||
|
free (old);
|
||||||
|
|
||||||
|
return (char *) _nl_current_default_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
/* Alias for function name in GNU C Library. */
|
||||||
|
weak_alias (__textdomain, textdomain);
|
||||||
|
#endif
|
104
intl/xopen-msg.sed
Normal file
104
intl/xopen-msg.sed
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file
|
||||||
|
# Copyright (C) 1995 Free Software Foundation, Inc.
|
||||||
|
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The first directive in the .msg should be the definition of the
|
||||||
|
# message set number. We use always set number 1.
|
||||||
|
#
|
||||||
|
1 {
|
||||||
|
i\
|
||||||
|
$set 1 # Automatically created by po2msg.sed
|
||||||
|
h
|
||||||
|
s/.*/0/
|
||||||
|
x
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# We copy all comments into the .msg file. Perhaps they can help.
|
||||||
|
#
|
||||||
|
/^#/ s/^#[ ]*/$ /p
|
||||||
|
#
|
||||||
|
# We copy the original message as a comment into the .msg file.
|
||||||
|
#
|
||||||
|
/^msgid/ {
|
||||||
|
# Does not work now
|
||||||
|
# /"$/! {
|
||||||
|
# s/\\$//
|
||||||
|
# s/$/ ... (more lines following)"/
|
||||||
|
# }
|
||||||
|
s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/
|
||||||
|
p
|
||||||
|
}
|
||||||
|
#
|
||||||
|
# The .msg file contains, other then the .po file, only the translations
|
||||||
|
# but each given a unique ID. Starting from 1 and incrementing by 1 for
|
||||||
|
# each message we assign them to the messages.
|
||||||
|
# It is important that the .po file used to generate the cat-id-tbl.c file
|
||||||
|
# (with po-to-tbl) is the same as the one used here. (At least the order
|
||||||
|
# of declarations must not be changed.)
|
||||||
|
#
|
||||||
|
/^msgstr/ {
|
||||||
|
s/msgstr[ ]*"\(.*\)"/\1/
|
||||||
|
x
|
||||||
|
# The following nice solution is by
|
||||||
|
# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
|
||||||
|
td
|
||||||
|
# Increment a decimal number in pattern space.
|
||||||
|
# First hide trailing `9' digits.
|
||||||
|
:d
|
||||||
|
s/9\(_*\)$/_\1/
|
||||||
|
td
|
||||||
|
# Assure at least one digit is available.
|
||||||
|
s/^\(_*\)$/0\1/
|
||||||
|
# Increment the last digit.
|
||||||
|
s/8\(_*\)$/9\1/
|
||||||
|
s/7\(_*\)$/8\1/
|
||||||
|
s/6\(_*\)$/7\1/
|
||||||
|
s/5\(_*\)$/6\1/
|
||||||
|
s/4\(_*\)$/5\1/
|
||||||
|
s/3\(_*\)$/4\1/
|
||||||
|
s/2\(_*\)$/3\1/
|
||||||
|
s/1\(_*\)$/2\1/
|
||||||
|
s/0\(_*\)$/1\1/
|
||||||
|
# Convert the hidden `9' digits to `0's.
|
||||||
|
s/_/0/g
|
||||||
|
x
|
||||||
|
# Bring the line in the format `<number> <message>'
|
||||||
|
G
|
||||||
|
s/^[^\n]*$/& /
|
||||||
|
s/\(.*\)\n\([0-9]*\)/\2 \1/
|
||||||
|
# Clear flag from last substitution.
|
||||||
|
tb
|
||||||
|
# Append the next line.
|
||||||
|
:b
|
||||||
|
N
|
||||||
|
# Look whether second part is a continuation line.
|
||||||
|
s/\(.*\n\)"\(.*\)"/\1\2/
|
||||||
|
# Yes, then branch.
|
||||||
|
ta
|
||||||
|
P
|
||||||
|
D
|
||||||
|
# Note that `D' includes a jump to the start!!
|
||||||
|
# We found a continuation line. But before printing insert '\'.
|
||||||
|
:a
|
||||||
|
s/\(.*\)\(\n.*\)/\1\\\2/
|
||||||
|
P
|
||||||
|
# We cannot use the sed command `D' here
|
||||||
|
s/.*\n\(.*\)/\1/
|
||||||
|
tb
|
||||||
|
}
|
||||||
|
d
|
248
po/Makefile.in.in
Normal file
248
po/Makefile.in.in
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
# Makefile for program source directory in GNU NLS utilities package.
|
||||||
|
# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
|
||||||
|
#
|
||||||
|
# This file file be copied and used freely without restrictions. It can
|
||||||
|
# be used in projects which are not available under the GNU Public License
|
||||||
|
# but which still want to provide support for the GNU gettext functionality.
|
||||||
|
# Please note that the actual code is *not* freely available.
|
||||||
|
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
datadir = $(prefix)/@DATADIRNAME@
|
||||||
|
localedir = $(datadir)/locale
|
||||||
|
gnulocaledir = $(prefix)/share/locale
|
||||||
|
gettextsrcdir = $(prefix)/share/gettext/po
|
||||||
|
subdir = po
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
GENCAT = @GENCAT@
|
||||||
|
GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
|
||||||
|
MSGFMT = @MSGFMT@
|
||||||
|
XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
|
||||||
|
MSGMERGE = PATH=../src:$$PATH msgmerge
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
|
INCLUDES = -I.. -I$(top_srcdir)/intl
|
||||||
|
|
||||||
|
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
|
||||||
|
|
||||||
|
SOURCES = cat-id-tbl.c
|
||||||
|
POFILES = @POFILES@
|
||||||
|
GMOFILES = @GMOFILES@
|
||||||
|
DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
|
||||||
|
stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
|
||||||
|
|
||||||
|
POTFILES = \
|
||||||
|
|
||||||
|
CATALOGS = @CATALOGS@
|
||||||
|
CATOBJEXT = @CATOBJEXT@
|
||||||
|
INSTOBJEXT = @INSTOBJEXT@
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) $<
|
||||||
|
|
||||||
|
.po.pox:
|
||||||
|
$(MAKE) $(PACKAGE).pot
|
||||||
|
$(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
|
||||||
|
|
||||||
|
.po.mo:
|
||||||
|
$(MSGFMT) -o $@ $<
|
||||||
|
|
||||||
|
.po.gmo:
|
||||||
|
file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
|
||||||
|
&& rm -f $$file && $(GMSGFMT) -o $$file $<
|
||||||
|
|
||||||
|
.po.cat:
|
||||||
|
sed -f ../intl/po2msg.sed < $< > $*.msg \
|
||||||
|
&& rm -f $@ && $(GENCAT) $@ $*.msg
|
||||||
|
|
||||||
|
|
||||||
|
all: all-@USE_NLS@
|
||||||
|
|
||||||
|
all-yes: cat-id-tbl.c $(CATALOGS)
|
||||||
|
all-no:
|
||||||
|
|
||||||
|
$(srcdir)/$(PACKAGE).pot: $(POTFILES)
|
||||||
|
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
|
||||||
|
--add-comments --keyword=_ --keyword=N_ \
|
||||||
|
--files-from=$(srcdir)/POTFILES.in \
|
||||||
|
&& test ! -f $(PACKAGE).po \
|
||||||
|
|| ( rm -f $(srcdir)/$(PACKAGE).pot \
|
||||||
|
&& mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot )
|
||||||
|
|
||||||
|
$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
|
||||||
|
$(srcdir)/stamp-cat-id: $(PACKAGE).pot
|
||||||
|
rm -f cat-id-tbl.tmp
|
||||||
|
sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
|
||||||
|
| sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
|
||||||
|
if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
|
||||||
|
rm cat-id-tbl.tmp; \
|
||||||
|
else \
|
||||||
|
echo cat-id-tbl.c changed; \
|
||||||
|
rm -f $(srcdir)/cat-id-tbl.c; \
|
||||||
|
mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
|
||||||
|
fi
|
||||||
|
cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
|
||||||
|
|
||||||
|
|
||||||
|
install: install-exec install-data
|
||||||
|
install-exec:
|
||||||
|
install-data: install-data-@USE_NLS@
|
||||||
|
install-data-no: all
|
||||||
|
install-data-yes: all
|
||||||
|
if test -r "$(MKINSTALLDIRS)"; then \
|
||||||
|
$(MKINSTALLDIRS) $(datadir); \
|
||||||
|
else \
|
||||||
|
$(SHELL) $(top_srcdir)/mkinstalldirs $(datadir); \
|
||||||
|
fi
|
||||||
|
@catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
case "$$cat" in \
|
||||||
|
*.gmo) destdir=$(gnulocaledir);; \
|
||||||
|
*) destdir=$(localedir);; \
|
||||||
|
esac; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
dir=$$destdir/$$lang/LC_MESSAGES; \
|
||||||
|
if test -r "$(MKINSTALLDIRS)"; then \
|
||||||
|
$(MKINSTALLDIRS) $$dir; \
|
||||||
|
else \
|
||||||
|
$(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \
|
||||||
|
fi; \
|
||||||
|
if test -r $$cat; then \
|
||||||
|
$(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
|
||||||
|
else \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
echo "installing $(srcdir)/$$cat as" \
|
||||||
|
"$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
|
||||||
|
fi; \
|
||||||
|
if test -r $$cat.m; then \
|
||||||
|
$(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
|
||||||
|
else \
|
||||||
|
if test -r $(srcdir)/$$cat.m ; then \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/$$cat.m \
|
||||||
|
$$dir/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
echo "installing $(srcdir)/$$cat as" \
|
||||||
|
"$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
|
||||||
|
else \
|
||||||
|
true; \
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
if test "$(PACKAGE)" = "gettext"; then \
|
||||||
|
if test -r "$(MKINSTALLDIRS)"; then \
|
||||||
|
$(MKINSTALLDIRS) $(gettextsrcdir); \
|
||||||
|
else \
|
||||||
|
$(SHELL) $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
|
||||||
|
fi; \
|
||||||
|
$(INSTALL_DATA) $(srcdir)/Makefile.in.in \
|
||||||
|
$(gettextsrcdir)/Makefile.in.in; \
|
||||||
|
else \
|
||||||
|
: ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define this as empty until I found a useful application.
|
||||||
|
installcheck:
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
|
||||||
|
rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
|
||||||
|
done
|
||||||
|
rm -f $(gettextsrcdir)/po-Makefile.in.in
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
cat-id-tbl.o: ../intl/libgettext.h
|
||||||
|
|
||||||
|
dvi info tags TAGS ID:
|
||||||
|
|
||||||
|
mostlyclean:
|
||||||
|
rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
|
||||||
|
rm -fr *.o
|
||||||
|
|
||||||
|
clean: mostlyclean
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
|
||||||
|
|
||||||
|
maintainer-clean: distclean
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
rm -f $(GMOFILES)
|
||||||
|
|
||||||
|
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
||||||
|
dist distdir: update-po $(DISTFILES)
|
||||||
|
dists="$(DISTFILES)"; \
|
||||||
|
for file in $$dists; do \
|
||||||
|
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|
||||||
|
|| cp -p $(srcdir)/$$file $(distdir); \
|
||||||
|
done
|
||||||
|
|
||||||
|
update-po: Makefile
|
||||||
|
$(MAKE) $(PACKAGE).pot
|
||||||
|
PATH=`pwd`/../src:$$PATH; \
|
||||||
|
cd $(srcdir); \
|
||||||
|
catalogs='$(CATALOGS)'; \
|
||||||
|
for cat in $$catalogs; do \
|
||||||
|
cat=`basename $$cat`; \
|
||||||
|
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
|
||||||
|
mv $$lang.po $$lang.old.po; \
|
||||||
|
echo "$$lang:"; \
|
||||||
|
if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
|
||||||
|
rm -f $$lang.old.po; \
|
||||||
|
else \
|
||||||
|
echo "msgmerge for $$cat failed!"; \
|
||||||
|
rm -f $$lang.po; \
|
||||||
|
mv $$lang.old.po $$lang.po; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
POTFILES: POTFILES.in
|
||||||
|
( if test 'x$(srcdir)' != 'x.'; then \
|
||||||
|
posrcprefix='$(top_srcdir)/'; \
|
||||||
|
else \
|
||||||
|
posrcprefix="../"; \
|
||||||
|
fi; \
|
||||||
|
rm -f $@-t $@ \
|
||||||
|
&& (sed -e '/^#/d' -e '/^[ ]*$$/d' \
|
||||||
|
-e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
|
||||||
|
| sed -e '$$s/\\$$//') > $@-t \
|
||||||
|
&& chmod a-w $@-t \
|
||||||
|
&& mv $@-t $@ )
|
||||||
|
|
||||||
|
Makefile: Makefile.in.in ../config.status POTFILES
|
||||||
|
cd .. \
|
||||||
|
&& CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
|
||||||
|
$(SHELL) ./config.status
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make not to export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
13
po/POTFILES.in
Normal file
13
po/POTFILES.in
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# List of files which contain translatable strings.
|
||||||
|
# Copyright (C) 1999,2000 Ivo Timmermans
|
||||||
|
|
||||||
|
# Package source files
|
||||||
|
|
||||||
|
lib/pidfile.c
|
||||||
|
src/conf.c
|
||||||
|
src/encr.c
|
||||||
|
src/genauth.c
|
||||||
|
src/net.c
|
||||||
|
src/netutl.c
|
||||||
|
src/protocol.c
|
||||||
|
src/tincd.c
|
10
src/conf.c
10
src/conf.c
|
@ -35,6 +35,8 @@
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "netutl.h" /* for strtoip */
|
#include "netutl.h" /* for strtoip */
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
config_t *config;
|
config_t *config;
|
||||||
int debug_lvl = 0;
|
int debug_lvl = 0;
|
||||||
int timeout = 0; /* seconds before timeout */
|
int timeout = 0; /* seconds before timeout */
|
||||||
|
@ -150,14 +152,14 @@ readconfig(const char *fname, FILE *fp)
|
||||||
|
|
||||||
if(!hazahaza[i].name)
|
if(!hazahaza[i].name)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: %d: Invalid variable name `%s'.\n",
|
fprintf(stderr, _("%s: %d: Invalid variable name `%s'.\n"),
|
||||||
fname, lineno, p);
|
fname, lineno, p);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
|
if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: %d: No value given for `%s'.\n",
|
fprintf(stderr, _("%s: %d: No value given for `%s'.\n"),
|
||||||
fname, lineno, hazahaza[i].name);
|
fname, lineno, hazahaza[i].name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +167,7 @@ readconfig(const char *fname, FILE *fp)
|
||||||
cfg = add_config_val(&config, hazahaza[i].argtype, q);
|
cfg = add_config_val(&config, hazahaza[i].argtype, q);
|
||||||
if(cfg == NULL)
|
if(cfg == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: %d: Invalid value `%s' for variable `%s'.\n",
|
fprintf(stderr, _("%s: %d: Invalid value `%s' for variable `%s'.\n"),
|
||||||
fname, lineno, q, hazahaza[i].name);
|
fname, lineno, q, hazahaza[i].name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +188,7 @@ read_config_file(const char *fname)
|
||||||
|
|
||||||
if((fp = fopen (fname, "r")) == NULL)
|
if((fp = fopen (fname, "r")) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not open %s: %s\n", fname, sys_errlist[errno]);
|
fprintf(stderr, _("Could not open %s: %s\n"), fname, sys_errlist[errno]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/encr.c
12
src/encr.c
|
@ -47,6 +47,8 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
#define ENCR_GENERATOR "0xd"
|
#define ENCR_GENERATOR "0xd"
|
||||||
#define ENCR_PRIME "0x7fffffffffffffffffffffffffffffff" /* Mersenne :) */
|
#define ENCR_PRIME "0x7fffffffffffffffffffffffffffffff" /* Mersenne :) */
|
||||||
|
|
||||||
|
@ -104,14 +106,14 @@ cp
|
||||||
|
|
||||||
if((f = fopen(filename, "rb")) == NULL)
|
if((f = fopen(filename, "rb")) == NULL)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Could not open %s: %m", filename);
|
syslog(LOG_ERR, _("Could not open %s: %m"), filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fscanf(f, "%d ", &size);
|
fscanf(f, "%d ", &size);
|
||||||
if(size < 1 || size > (1<<15))
|
if(size < 1 || size > (1<<15))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Illegal passphrase in %s; size would be %d", filename, size);
|
syslog(LOG_ERR, _("Illegal passphrase in %s; size would be %d"), filename, size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
size >>= 2; /* bits->nibbles */
|
size >>= 2; /* bits->nibbles */
|
||||||
|
@ -145,11 +147,11 @@ cp
|
||||||
else
|
else
|
||||||
my_key_expiry = (time_t)(time(NULL) + cfg->data.val);
|
my_key_expiry = (time_t)(time(NULL) + cfg->data.val);
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "Generating %d bits keys.", PRIVATE_KEY_BITS);
|
syslog(LOG_NOTICE, _("Generating %d bits keys."), PRIVATE_KEY_BITS);
|
||||||
|
|
||||||
if((f = fopen("/dev/urandom", "r")) == NULL)
|
if((f = fopen("/dev/urandom", "r")) == NULL)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Opening /dev/urandom failed: %m");
|
syslog(LOG_ERR, _("Opening /dev/urandom failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +216,7 @@ cp
|
||||||
encryption_keylen = len;
|
encryption_keylen = len;
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_INFO, "Encryption key set to %s", tmp);
|
syslog(LOG_INFO, _("Encryption key set to %s"), tmp);
|
||||||
|
|
||||||
free(tmp);
|
free(tmp);
|
||||||
mpz_clear(ak);
|
mpz_clear(ak);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "encr.h"
|
#include "encr.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
unsigned char initvec[] = { 0x22, 0x7b, 0xad, 0x55, 0x41, 0xf4, 0x3e, 0xf3 };
|
unsigned char initvec[] = { 0x22, 0x7b, 0xad, 0x55, 0x41, 0xf4, 0x3e, 0xf3 };
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -37,7 +39,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if(argc > 2 || (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))))
|
if(argc > 2 || (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s bits\n", argv[0]);
|
fprintf(stderr, _("Usage: %s bits\n"), argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,17 +48,17 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if(!(bits = atol(argv[1])))
|
if(!(bits = atol(argv[1])))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Illegal number: %s\n", argv[1]);
|
fprintf(stderr, _("Illegal number: %s\n"), argv[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bits = ((bits - 1) | 63) + 1;
|
bits = ((bits - 1) | 63) + 1;
|
||||||
fprintf(stderr, "Generating %d bits number", bits);
|
fprintf(stderr, _("Generating %d bits number"), bits);
|
||||||
bytes = bits >> 3;
|
bytes = bits >> 3;
|
||||||
|
|
||||||
if((fp = fopen("/dev/urandom", "r")) == NULL)
|
if((fp = fopen("/dev/urandom", "r")) == NULL)
|
||||||
{
|
{
|
||||||
perror("Opening /dev/urandom");
|
perror(_("Opening /dev/urandom"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ int main(int argc, char **argv)
|
||||||
if(feof(fp))
|
if(feof(fp))
|
||||||
{
|
{
|
||||||
puts("");
|
puts("");
|
||||||
fprintf(stderr, "File was empty!\n");
|
fprintf(stderr, _("File was empty!\n"));
|
||||||
}
|
}
|
||||||
p[i] = c;
|
p[i] = c;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +79,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if(isatty(1))
|
if(isatty(1))
|
||||||
{
|
{
|
||||||
fprintf(stderr, ": done.\nThe following line should be ENTIRELY copied into a passphrase file:\n");
|
fprintf(stderr, _(": done.\nThe following line should be ENTIRELY copied into a passphrase file:\n"));
|
||||||
printf("%d ", bits);
|
printf("%d ", bits);
|
||||||
for(i = 0; i < bytes; i++)
|
for(i = 0; i < bytes; i++)
|
||||||
printf("%02x", p[i]);
|
printf("%02x", p[i]);
|
||||||
|
@ -89,7 +91,7 @@ int main(int argc, char **argv)
|
||||||
for(i = 0; i < bytes; i++)
|
for(i = 0; i < bytes; i++)
|
||||||
printf("%02x", p[i]);
|
printf("%02x", p[i]);
|
||||||
puts("");
|
puts("");
|
||||||
fprintf(stderr, ": done.\n");
|
fprintf(stderr, _(": done.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
128
src/net.c
128
src/net.c
|
@ -44,6 +44,8 @@
|
||||||
#include "netutl.h"
|
#include "netutl.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
int tap_fd = -1;
|
int tap_fd = -1;
|
||||||
|
|
||||||
int total_tap_in = 0;
|
int total_tap_in = 0;
|
||||||
|
@ -98,11 +100,11 @@ cp
|
||||||
rp.len = htons(rp.len);
|
rp.len = htons(rp.len);
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_ERR, "Sent %d bytes to %lx", ntohs(rp.len), cl->vpn_ip);
|
syslog(LOG_ERR, _("Sent %d bytes to %lx"), ntohs(rp.len), cl->vpn_ip);
|
||||||
|
|
||||||
if((r = send(cl->socket, (char*)&rp, ntohs(rp.len), 0)) < 0)
|
if((r = send(cl->socket, (char*)&rp, ntohs(rp.len), 0)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Error sending data: %m");
|
syslog(LOG_ERR, _("Error sending data: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +124,7 @@ cp
|
||||||
add_mac_addresses(&vp);
|
add_mac_addresses(&vp);
|
||||||
|
|
||||||
if((lenin = write(tap_fd, &vp, vp.len + sizeof(vp.len))) < 0)
|
if((lenin = write(tap_fd, &vp, vp.len + sizeof(vp.len))) < 0)
|
||||||
syslog(LOG_ERR, "Can't write to tap device: %m");
|
syslog(LOG_ERR, _("Can't write to tap device: %m"));
|
||||||
else
|
else
|
||||||
total_tap_out += lenin;
|
total_tap_out += lenin;
|
||||||
|
|
||||||
|
@ -141,7 +143,7 @@ void add_queue(packet_queue_t **q, void *packet, size_t s)
|
||||||
queue_element_t *e;
|
queue_element_t *e;
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "packet to queue: %d", s);
|
syslog(LOG_DEBUG, _("packet to queue: %d"), s);
|
||||||
|
|
||||||
e = xmalloc(sizeof(*e));
|
e = xmalloc(sizeof(*e));
|
||||||
e->packet = xmalloc(s);
|
e->packet = xmalloc(s);
|
||||||
|
@ -228,7 +230,7 @@ cp
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "queue flushed");
|
syslog(LOG_DEBUG, _("queue flushed"));
|
||||||
cp
|
cp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +245,7 @@ cp
|
||||||
if(cl->sq)
|
if(cl->sq)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_DEBUG, "Flushing send queue for " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Flushing send queue for " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
flush_queue(cl, &(cl->sq), xsend);
|
flush_queue(cl, &(cl->sq), xsend);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +253,7 @@ cp
|
||||||
if(cl->rq)
|
if(cl->rq)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_DEBUG, "Flushing receive queue for " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Flushing receive queue for " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
flush_queue(cl, &(cl->rq), xrecv);
|
flush_queue(cl, &(cl->rq), xrecv);
|
||||||
}
|
}
|
||||||
|
@ -269,14 +271,14 @@ cp
|
||||||
{
|
{
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
{
|
{
|
||||||
syslog(LOG_NOTICE, "trying to look up " IP_ADDR_S " in connection list failed.",
|
syslog(LOG_NOTICE, _("trying to look up " IP_ADDR_S " in connection list failed."),
|
||||||
IP_ADDR_V(to));
|
IP_ADDR_V(to));
|
||||||
}
|
}
|
||||||
for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
|
for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
|
||||||
if(!cl)
|
if(!cl)
|
||||||
{ /* No open outgoing connection has been found. */
|
{ /* No open outgoing connection has been found. */
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_NOTICE, "There is no remote host I can send this packet to.");
|
syslog(LOG_NOTICE, _("There is no remote host I can send this packet to."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,7 +302,7 @@ cp
|
||||||
{
|
{
|
||||||
add_queue(&(cl->sq), packet, packet->len + 2);
|
add_queue(&(cl->sq), packet, packet->len + 2);
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_INFO, _(IP_ADDR_S " is not ready, queueing packet."), IP_ADDR_V(cl->vpn_ip));
|
||||||
return 0; /* We don't want to mess up, do we? */
|
return 0; /* We don't want to mess up, do we? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +327,7 @@ cp
|
||||||
|
|
||||||
if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
|
if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Could not open %s: %m", tapfname);
|
syslog(LOG_ERR, _("Could not open %s: %m"), tapfname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,20 +348,20 @@ int setup_listen_meta_socket(int port)
|
||||||
cp
|
cp
|
||||||
if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Creating metasocket failed: %m");
|
syslog(LOG_ERR, _("Creating metasocket failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
|
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "setsockopt: %m");
|
syslog(LOG_ERR, _("setsockopt: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(nfd, F_GETFL);
|
flags = fcntl(nfd, F_GETFL);
|
||||||
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "fcntl: %m");
|
syslog(LOG_ERR, _("fcntl: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,13 +372,13 @@ cp
|
||||||
|
|
||||||
if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
|
if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
|
syslog(LOG_ERR, _("Can't bind to port %hd/tcp: %m"), port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(listen(nfd, 3))
|
if(listen(nfd, 3))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "listen: %m");
|
syslog(LOG_ERR, _("listen: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -395,20 +397,20 @@ int setup_vpn_in_socket(int port)
|
||||||
cp
|
cp
|
||||||
if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Creating socket failed: %m");
|
syslog(LOG_ERR, _("Creating socket failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
|
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "setsockopt: %m");
|
syslog(LOG_ERR, _("setsockopt: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(nfd, F_GETFL);
|
flags = fcntl(nfd, F_GETFL);
|
||||||
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "fcntl: %m");
|
syslog(LOG_ERR, _("fcntl: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +421,7 @@ cp
|
||||||
|
|
||||||
if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
|
if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
|
syslog(LOG_ERR, _("Can't bind to port %hd/udp: %m"), port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -443,7 +445,7 @@ cp
|
||||||
cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if(cl->meta_socket == -1)
|
if(cl->meta_socket == -1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Creating socket failed: %m");
|
syslog(LOG_ERR, _("Creating socket failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,20 +455,20 @@ cp
|
||||||
|
|
||||||
if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
|
if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
|
syslog(LOG_ERR, _(IP_ADDR_S ":%d: %m"), IP_ADDR_V(cl->real_ip), cl->port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(cl->meta_socket, F_GETFL);
|
flags = fcntl(cl->meta_socket, F_GETFL);
|
||||||
if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
|
if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "fcntl: %m");
|
syslog(LOG_ERR, _("fcntl: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->hostname = hostlookup(htonl(cl->real_ip));
|
cl->hostname = hostlookup(htonl(cl->real_ip));
|
||||||
|
|
||||||
syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
|
syslog(LOG_INFO, _("Connected to %s:%hd"), cl->hostname, cl->port);
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +489,7 @@ cp
|
||||||
|
|
||||||
if(setup_outgoing_meta_socket(ncn) < 0)
|
if(setup_outgoing_meta_socket(ncn) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Could not set up a meta connection.");
|
syslog(LOG_ERR, _("Could not set up a meta connection."));
|
||||||
free_conn_element(ncn);
|
free_conn_element(ncn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -511,7 +513,7 @@ cp
|
||||||
|
|
||||||
if(!(cfg = get_config_val(myvpnip)))
|
if(!(cfg = get_config_val(myvpnip)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "No value for my VPN IP given");
|
syslog(LOG_ERR, _("No value for my VPN IP given"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,20 +527,20 @@ cp
|
||||||
|
|
||||||
if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
|
if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Unable to set up a listening socket");
|
syslog(LOG_ERR, _("Unable to set up a listening socket"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
|
if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
|
syslog(LOG_ERR, _("Unable to set up an incoming vpn data socket"));
|
||||||
close(myself->meta_socket);
|
close(myself->meta_socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
myself->status.active = 1;
|
myself->status.active = 1;
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
|
syslog(LOG_NOTICE, _("Ready: listening on port %d."), myself->port);
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -561,7 +563,7 @@ cp
|
||||||
if(seconds_till_retry>300) /* Don't wait more than 5 minutes. */
|
if(seconds_till_retry>300) /* Don't wait more than 5 minutes. */
|
||||||
seconds_till_retry = 300;
|
seconds_till_retry = 300;
|
||||||
alarm(seconds_till_retry);
|
alarm(seconds_till_retry);
|
||||||
syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
|
syslog(LOG_ERR, _("Still failed to connect to other. Will retry in %d seconds."),
|
||||||
seconds_till_retry);
|
seconds_till_retry);
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -594,7 +596,7 @@ cp
|
||||||
signal(SIGALRM, sigalrm_handler);
|
signal(SIGALRM, sigalrm_handler);
|
||||||
seconds_till_retry = 300;
|
seconds_till_retry = 300;
|
||||||
alarm(seconds_till_retry);
|
alarm(seconds_till_retry);
|
||||||
syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 minutes.");
|
syslog(LOG_NOTICE, _("Try to re-establish outgoing connection in 5 minutes."));
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -632,7 +634,7 @@ cp
|
||||||
close(tap_fd);
|
close(tap_fd);
|
||||||
destroy_conn_list();
|
destroy_conn_list();
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "Terminating.");
|
syslog(LOG_NOTICE, _("Terminating."));
|
||||||
cp
|
cp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -646,12 +648,12 @@ int setup_vpn_connection(conn_list_t *cl)
|
||||||
struct sockaddr_in a;
|
struct sockaddr_in a;
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
|
syslog(LOG_DEBUG, _("Opening UDP socket to " IP_ADDR_S), IP_ADDR_V(cl->real_ip));
|
||||||
|
|
||||||
nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(nfd == -1)
|
if(nfd == -1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Creating data socket failed: %m");
|
syslog(LOG_ERR, _("Creating data socket failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,7 +663,7 @@ cp
|
||||||
|
|
||||||
if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
|
if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Connecting to " IP_ADDR_S ":%d failed: %m",
|
syslog(LOG_ERR, _("Connecting to " IP_ADDR_S ":%d failed: %m"),
|
||||||
IP_ADDR_V(cl->real_ip), cl->port);
|
IP_ADDR_V(cl->real_ip), cl->port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -669,7 +671,7 @@ cp
|
||||||
flags = fcntl(nfd, F_GETFL);
|
flags = fcntl(nfd, F_GETFL);
|
||||||
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
|
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"), __FILE__, __LINE__, nfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +695,7 @@ cp
|
||||||
|
|
||||||
if(getpeername(sfd, &ci, &len) < 0)
|
if(getpeername(sfd, &ci, &len) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Error: getpeername: %m");
|
syslog(LOG_ERR, _("Error: getpeername: %m"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,7 +707,7 @@ cp
|
||||||
p->last_ping_time = time(NULL);
|
p->last_ping_time = time(NULL);
|
||||||
p->want_ping = 0;
|
p->want_ping = 0;
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
|
syslog(LOG_NOTICE, _("Connection from %s:%d"), p->hostname, htons(ci.sin_port));
|
||||||
|
|
||||||
if(send_basic_info(p) < 0)
|
if(send_basic_info(p) < 0)
|
||||||
{
|
{
|
||||||
|
@ -753,12 +755,12 @@ int handle_incoming_vpn_data(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->socket);
|
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"), __FILE__, __LINE__, cl->socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(x)
|
if(x)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Incoming data socket error: %s", sys_errlist[x]);
|
syslog(LOG_ERR, _("Incoming data socket error: %s"), sys_errlist[x]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,7 +768,7 @@ cp
|
||||||
lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
|
lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
|
||||||
if(lenin <= 0)
|
if(lenin <= 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Receiving data failed: %m");
|
syslog(LOG_ERR, _("Receiving data failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
total_socket_in += lenin;
|
total_socket_in += lenin;
|
||||||
|
@ -779,11 +781,11 @@ cp
|
||||||
{
|
{
|
||||||
f = lookup_conn(rp.from);
|
f = lookup_conn(rp.from);
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "packet from " IP_ADDR_S " (len %d)",
|
syslog(LOG_DEBUG, _("packet from " IP_ADDR_S " (len %d)"),
|
||||||
IP_ADDR_V(rp.from), rp.len);
|
IP_ADDR_V(rp.from), rp.len);
|
||||||
if(!f)
|
if(!f)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Got packet from unknown source " IP_ADDR_S,
|
syslog(LOG_ERR, _("Got packet from unknown source " IP_ADDR_S),
|
||||||
IP_ADDR_V(rp.from));
|
IP_ADDR_V(rp.from));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -815,7 +817,7 @@ cp
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_NOTICE, "Closing connection with %s.", cl->hostname);
|
syslog(LOG_NOTICE, _("Closing connection with %s."), cl->hostname);
|
||||||
|
|
||||||
if(cl->status.timeout)
|
if(cl->status.timeout)
|
||||||
send_timeout(cl);
|
send_timeout(cl);
|
||||||
|
@ -831,7 +833,7 @@ cp
|
||||||
signal(SIGALRM, sigalrm_handler);
|
signal(SIGALRM, sigalrm_handler);
|
||||||
seconds_till_retry = 5;
|
seconds_till_retry = 5;
|
||||||
alarm(seconds_till_retry);
|
alarm(seconds_till_retry);
|
||||||
syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
|
syslog(LOG_NOTICE, _("Try to re-establish outgoing connection in 5 seconds."));
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->status.active = 0;
|
cl->status.active = 0;
|
||||||
|
@ -863,7 +865,7 @@ cp
|
||||||
{
|
{
|
||||||
if(p->status.pinged && !p->status.got_pong)
|
if(p->status.pinged && !p->status.got_pong)
|
||||||
{
|
{
|
||||||
syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
|
syslog(LOG_INFO, _("%s (" IP_ADDR_S ") didn't respond to ping"),
|
||||||
p->hostname, IP_ADDR_V(p->vpn_ip));
|
p->hostname, IP_ADDR_V(p->vpn_ip));
|
||||||
p->status.timeout = 1;
|
p->status.timeout = 1;
|
||||||
terminate_connection(p);
|
terminate_connection(p);
|
||||||
|
@ -894,7 +896,7 @@ int handle_new_meta_connection(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
|
if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Accepting a new connection failed: %m");
|
syslog(LOG_ERR, _("Accepting a new connection failed: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,7 +904,7 @@ cp
|
||||||
{
|
{
|
||||||
shutdown(nfd, 2);
|
shutdown(nfd, 2);
|
||||||
close(nfd);
|
close(nfd);
|
||||||
syslog(LOG_NOTICE, "Closed attempted connection.");
|
syslog(LOG_NOTICE, _("Closed attempted connection."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,18 +926,18 @@ int handle_incoming_meta_data(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
|
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m"), __FILE__, __LINE__, cl->meta_socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(x)
|
if(x)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
|
syslog(LOG_ERR, _("Metadata socket error: %s"), sys_errlist[x]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cl->buflen >= MAXBUFSIZE)
|
if(cl->buflen >= MAXBUFSIZE)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Metadata read buffer overflow.");
|
syslog(LOG_ERR, _("Metadata read buffer overflow."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,7 +945,7 @@ cp
|
||||||
|
|
||||||
if(lenin<=0)
|
if(lenin<=0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Metadata socket read error: %m");
|
syslog(LOG_ERR, _("Metadata socket read error: %m"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,22 +972,22 @@ cp
|
||||||
{
|
{
|
||||||
if(request_handlers[request] == NULL)
|
if(request_handlers[request] == NULL)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Unknown request: %s", cl->buffer);
|
syslog(LOG_ERR, _("Unknown request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "Got request: %s", cl->buffer);
|
syslog(LOG_DEBUG, _("Got request: %s"), cl->buffer);
|
||||||
|
|
||||||
if(request_handlers[request](cl)) /* Something went wrong. Probably scriptkiddies. Terminate. */
|
if(request_handlers[request](cl)) /* Something went wrong. Probably scriptkiddies. Terminate. */
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Error while processing request from IP_ADDR_S", IP_ADDR_V(cl->real_ip));
|
syslog(LOG_ERR, _("Error while processing request from " IP_ADDR_S), IP_ADDR_V(cl->real_ip));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Bogus data received.");
|
syslog(LOG_ERR, _("Bogus data received."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,7 +1031,7 @@ cp
|
||||||
I've once got here when it said `No route to host'.
|
I've once got here when it said `No route to host'.
|
||||||
*/
|
*/
|
||||||
getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
|
getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
|
||||||
syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
|
syslog(LOG_ERR, _("Outgoing data socket error: %s"), sys_errlist[x]);
|
||||||
terminate_connection(p);
|
terminate_connection(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1064,7 +1066,7 @@ cp
|
||||||
memset(&vp, 0, sizeof(vp));
|
memset(&vp, 0, sizeof(vp));
|
||||||
if((lenin = read(tap_fd, &vp, MTU)) <= 0)
|
if((lenin = read(tap_fd, &vp, MTU)) <= 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Error while reading from tapdevice: %m");
|
syslog(LOG_ERR, _("Error while reading from tapdevice: %m"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,7 +1076,7 @@ cp
|
||||||
if(ether_type != 0x0800)
|
if(ether_type != 0x0800)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_INFO, "Non-IP ethernet frame %04x from " MAC_ADDR_S,
|
syslog(LOG_INFO, _("Non-IP ethernet frame %04x from " MAC_ADDR_S),
|
||||||
ether_type, MAC_ADDR_V(vp.data[6]));
|
ether_type, MAC_ADDR_V(vp.data[6]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1084,7 @@ cp
|
||||||
if(lenin < 32)
|
if(lenin < 32)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_INFO, "Dropping short packet");
|
syslog(LOG_INFO, _("Dropping short packet"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,10 +1092,10 @@ cp
|
||||||
to = ntohl(*((unsigned long*)(&vp.data[30])));
|
to = ntohl(*((unsigned long*)(&vp.data[30])));
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S),
|
||||||
ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
|
ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
|
||||||
if(debug_lvl > 4)
|
if(debug_lvl > 4)
|
||||||
syslog(LOG_DEBUG, MAC_ADDR_S " to " MAC_ADDR_S,
|
syslog(LOG_DEBUG, _(MAC_ADDR_S " to " MAC_ADDR_S),
|
||||||
MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
|
MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
|
||||||
|
|
||||||
vp.len = (length_t)lenin - 2;
|
vp.len = (length_t)lenin - 2;
|
||||||
|
@ -1128,7 +1130,7 @@ cp
|
||||||
{
|
{
|
||||||
if(errno == EINTR) /* because of alarm */
|
if(errno == EINTR) /* because of alarm */
|
||||||
continue;
|
continue;
|
||||||
syslog(LOG_ERR, "Error while waiting for input: %m");
|
syslog(LOG_ERR, _("Error while waiting for input: %m"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "netutl.h"
|
#include "netutl.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
look for a connection associated with the given vpn ip,
|
look for a connection associated with the given vpn ip,
|
||||||
return its connection structure.
|
return its connection structure.
|
||||||
|
@ -203,7 +205,7 @@ cp
|
||||||
|
|
||||||
if(!(h = gethostbyname(p)))
|
if(!(h = gethostbyname(p)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error looking up `%s': %s\n", p, sys_errlist[h_errno]);
|
fprintf(stderr, _("Error looking up `%s': %s\n"), p, sys_errlist[h_errno]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +229,7 @@ void dump_conn_list(void)
|
||||||
{
|
{
|
||||||
conn_list_t *p;
|
conn_list_t *p;
|
||||||
cp
|
cp
|
||||||
syslog(LOG_DEBUG, "Connection list:");
|
syslog(LOG_DEBUG, _("Connection list:"));
|
||||||
|
|
||||||
for(p = conn_list; p != NULL; p = p->next)
|
for(p = conn_list; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
|
|
141
src/protocol.c
141
src/protocol.c
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
protocol.c -- handle the meta-protocol
|
protocol.c -- handle the meta-protocol
|
||||||
Copyright (C) 1999,2000 Ivo Timmermans <zarq@iname.com>
|
Copyright (C) 1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||||
|
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
$Id: protocol.c,v 1.26 2000/05/29 21:01:25 zarq Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -37,6 +40,8 @@
|
||||||
#include "netutl.h"
|
#include "netutl.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
char buffer[MAXBUFSIZE+1];
|
char buffer[MAXBUFSIZE+1];
|
||||||
int buflen;
|
int buflen;
|
||||||
|
|
||||||
|
@ -46,17 +51,17 @@ int send_ack(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send ACK to %s", cl->hostname);
|
syslog(LOG_DEBUG, _("Send ACK to %s"), cl->hostname);
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %d:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %d:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
|
syslog(LOG_NOTICE, _("Connection with %s activated."), cl->hostname);
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +70,7 @@ int send_termreq(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send TERMREQ to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Send TERMREQ to " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
|
||||||
|
@ -73,7 +78,7 @@ cp
|
||||||
if(write(cl->meta_socket, buffer, buflen) < 0)
|
if(write(cl->meta_socket, buffer, buflen) < 0)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -84,14 +89,14 @@ int send_timeout(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send TIMEOUT to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Send TIMEOUT to " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -102,14 +107,14 @@ int send_del_host(conn_list_t *cl, conn_list_t *new_host)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Sending delete host " IP_ADDR_S " to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Sending delete host " IP_ADDR_S " to " IP_ADDR_S),
|
||||||
IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -120,13 +125,13 @@ int send_ping(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "pinging " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_DEBUG, _("pinging " IP_ADDR_S), IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -140,7 +145,7 @@ cp
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -151,14 +156,14 @@ int send_add_host(conn_list_t *cl, conn_list_t *new_host)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Sending add host to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Sending add host to " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x\n", ADD_HOST, new_host->real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x\n", ADD_HOST, new_host->real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -169,14 +174,14 @@ int send_key_changed(conn_list_t *cl, conn_list_t *src)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Sending KEY_CHANGED to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Sending KEY_CHANGED to " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->vpn_ip));
|
IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -197,14 +202,14 @@ int send_basic_info(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send BASIC_INFO to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Send BASIC_INFO to " IP_ADDR_S),
|
||||||
IP_ADDR_V(cl->real_ip));
|
IP_ADDR_V(cl->real_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -218,14 +223,14 @@ cp
|
||||||
encrypt_passphrase(&tmp);
|
encrypt_passphrase(&tmp);
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send PASSPHRASE %s to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Send PASSPHRASE %s to " IP_ADDR_S),
|
||||||
tmp.phrase, IP_ADDR_V(cl->vpn_ip));
|
tmp.phrase, IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -236,14 +241,14 @@ int send_public_key(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Send PUBLIC_KEY %s to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Send PUBLIC_KEY %s to " IP_ADDR_S),
|
||||||
my_public_key_base36, IP_ADDR_V(cl->vpn_ip));
|
my_public_key_base36, IP_ADDR_V(cl->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -257,7 +262,7 @@ cp
|
||||||
|
|
||||||
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
if((write(cl->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -271,20 +276,20 @@ cp
|
||||||
fw = lookup_conn(to);
|
fw = lookup_conn(to);
|
||||||
if(!fw)
|
if(!fw)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Attempting to send key request to " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Attempting to send key request to " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(to));
|
IP_ADDR_V(to));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Sending out request for public key to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Sending out request for public key to " IP_ADDR_S),
|
||||||
IP_ADDR_V(fw->nexthop->vpn_ip));
|
IP_ADDR_V(fw->nexthop->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
|
||||||
|
|
||||||
if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
|
if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fw->status.waitingforkey = 1;
|
fw->status.waitingforkey = 1;
|
||||||
|
@ -301,20 +306,20 @@ cp
|
||||||
|
|
||||||
if(!fw)
|
if(!fw)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Attempting to send key answer to " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Attempting to send key answer to " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(to));
|
IP_ADDR_V(to));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Sending public key to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Sending public key to " IP_ADDR_S),
|
||||||
IP_ADDR_V(fw->nexthop->vpn_ip));
|
IP_ADDR_V(fw->nexthop->vpn_ip));
|
||||||
|
|
||||||
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
|
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
|
||||||
|
|
||||||
if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
|
if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -362,22 +367,22 @@ int basic_info_h(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port) != 4)
|
if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port) != 4)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad BASIC_INFO request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad BASIC_INFO request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cl->protocol_version != PROT_CURRENT)
|
if(cl->protocol_version != PROT_CURRENT)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Peer uses incompatible protocol version %d.",
|
syslog(LOG_ERR, _("Peer uses incompatible protocol version %d."),
|
||||||
cl->protocol_version);
|
cl->protocol_version);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got BASIC_INFO(%hd," IP_ADDR_S "," IP_ADDR_S ")", cl->port,
|
syslog(LOG_DEBUG, _("got BASIC_INFO(%hd," IP_ADDR_S "," IP_ADDR_S ")"), cl->port,
|
||||||
IP_ADDR_V(cl->vpn_ip), IP_ADDR_V(cl->vpn_mask));
|
IP_ADDR_V(cl->vpn_ip), IP_ADDR_V(cl->vpn_mask));
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_DEBUG, "Peer uses protocol version %d",
|
syslog(LOG_DEBUG, _("Peer uses protocol version %d"),
|
||||||
cl->protocol_version);
|
cl->protocol_version);
|
||||||
|
|
||||||
if(cl->status.outgoing)
|
if(cl->status.outgoing)
|
||||||
|
@ -403,13 +408,13 @@ cp
|
||||||
|
|
||||||
if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
|
if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad PASSPHRASE request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad PASSPHRASE request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cl->pp->len = strlen(cl->pp->phrase);
|
cl->pp->len = strlen(cl->pp->phrase);
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got PASSPHRASE");
|
syslog(LOG_DEBUG, _("got PASSPHRASE"));
|
||||||
|
|
||||||
if(cl->status.outgoing)
|
if(cl->status.outgoing)
|
||||||
send_passphrase(cl);
|
send_passphrase(cl);
|
||||||
|
@ -426,22 +431,22 @@ int public_key_h(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
|
if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad PUBLIC_KEY request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad PUBLIC_KEY request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got PUBLIC_KEY %s", g_n);
|
syslog(LOG_DEBUG, _("got PUBLIC_KEY %s"), g_n);
|
||||||
|
|
||||||
if(verify_passphrase(cl, g_n))
|
if(verify_passphrase(cl, g_n))
|
||||||
{
|
{
|
||||||
/* intruder! */
|
/* intruder! */
|
||||||
syslog(LOG_ERR, "Intruder: passphrase does not match.");
|
syslog(LOG_ERR, _("Intruder: passphrase does not match."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_INFO, "Passphrase OK");
|
syslog(LOG_INFO, _("Passphrase OK"));
|
||||||
|
|
||||||
if(cl->status.outgoing)
|
if(cl->status.outgoing)
|
||||||
send_public_key(cl);
|
send_public_key(cl);
|
||||||
|
@ -467,10 +472,10 @@ int ack_h(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got ACK");
|
syslog(LOG_DEBUG, _("got ACK"));
|
||||||
|
|
||||||
cl->status.active = 1;
|
cl->status.active = 1;
|
||||||
syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
|
syslog(LOG_NOTICE, _("Connection with %s activated."), cl->hostname);
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -478,7 +483,7 @@ cp
|
||||||
int termreq_h(conn_list_t *cl)
|
int termreq_h(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
syslog(LOG_NOTICE, IP_ADDR_S " wants to quit", IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_NOTICE, _(IP_ADDR_S " wants to quit"), IP_ADDR_V(cl->vpn_ip));
|
||||||
cl->status.termreq = 1;
|
cl->status.termreq = 1;
|
||||||
terminate_connection(cl);
|
terminate_connection(cl);
|
||||||
|
|
||||||
|
@ -491,7 +496,7 @@ int timeout_h(conn_list_t *cl)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
syslog(LOG_NOTICE, IP_ADDR_S " says it's gotten a timeout from us", IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_NOTICE, _(IP_ADDR_S " says it's gotten a timeout from us"), IP_ADDR_V(cl->vpn_ip));
|
||||||
cl->status.termreq = 1;
|
cl->status.termreq = 1;
|
||||||
terminate_connection(cl);
|
terminate_connection(cl);
|
||||||
cp
|
cp
|
||||||
|
@ -507,17 +512,17 @@ cp
|
||||||
|
|
||||||
if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
|
if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad DEL_HOST request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad DEL_HOST request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got DEL_HOST for " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("got DEL_HOST for " IP_ADDR_S),
|
||||||
IP_ADDR_V(vpn_ip));
|
IP_ADDR_V(vpn_ip));
|
||||||
|
|
||||||
if(!(fw = lookup_conn(vpn_ip)))
|
if(!(fw = lookup_conn(vpn_ip)))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Somebody wanted to delete " IP_ADDR_S " which does not exist?",
|
syslog(LOG_ERR, _("Somebody wanted to delete " IP_ADDR_S " which does not exist?"),
|
||||||
IP_ADDR_V(vpn_ip));
|
IP_ADDR_V(vpn_ip));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +540,7 @@ int ping_h(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "responding to ping from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_DEBUG, _("responding to ping from " IP_ADDR_S), IP_ADDR_V(cl->vpn_ip));
|
||||||
cl->status.pinged = 0;
|
cl->status.pinged = 0;
|
||||||
cl->status.got_pong = 1;
|
cl->status.got_pong = 1;
|
||||||
|
|
||||||
|
@ -549,7 +554,7 @@ int pong_h(conn_list_t *cl)
|
||||||
cp
|
cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "ok, got pong from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_DEBUG, _("ok, got pong from " IP_ADDR_S), IP_ADDR_V(cl->vpn_ip));
|
||||||
cl->status.got_pong = 1;
|
cl->status.got_pong = 1;
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -566,14 +571,14 @@ cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx", &real_ip, &vpn_ip, &vpn_mask, &port) != 4)
|
if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx", &real_ip, &vpn_ip, &vpn_mask, &port) != 4)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad ADD_HOST request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad ADD_HOST request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Add host request from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
|
syslog(LOG_DEBUG, _("Add host request from " IP_ADDR_S), IP_ADDR_V(cl->vpn_ip));
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)",
|
syslog(LOG_DEBUG, _("got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)"),
|
||||||
IP_ADDR_V(vpn_ip), IP_ADDR_V(vpn_mask), port);
|
IP_ADDR_V(vpn_ip), IP_ADDR_V(vpn_mask), port);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -609,12 +614,12 @@ cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
|
if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S),
|
||||||
IP_ADDR_V(from), IP_ADDR_V(to));
|
IP_ADDR_V(from), IP_ADDR_V(to));
|
||||||
|
|
||||||
if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
|
if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
|
||||||
|
@ -627,20 +632,20 @@ cp
|
||||||
|
|
||||||
if(!fw)
|
if(!fw)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Attempting to forward key request to " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Attempting to forward key request to " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(to));
|
IP_ADDR_V(to));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "Forwarding request for public key to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Forwarding request for public key to " IP_ADDR_S),
|
||||||
IP_ADDR_V(fw->nexthop->vpn_ip));
|
IP_ADDR_V(fw->nexthop->vpn_ip));
|
||||||
|
|
||||||
cl->buffer[cl->reqlen-1] = '\n';
|
cl->buffer[cl->reqlen-1] = '\n';
|
||||||
|
|
||||||
if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
|
if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -693,23 +698,23 @@ cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
|
if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad ANS_KEY request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad ANS_KEY request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S),
|
||||||
IP_ADDR_V(from), IP_ADDR_V(to));
|
IP_ADDR_V(from), IP_ADDR_V(to));
|
||||||
|
|
||||||
if(to == myself->vpn_ip)
|
if(to == myself->vpn_ip)
|
||||||
{ /* hey! that key's for ME! :) */
|
{ /* hey! that key's for ME! :) */
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Yeah! key arrived. Now do something with it.");
|
syslog(LOG_DEBUG, _("Yeah! key arrived. Now do something with it."));
|
||||||
gk = lookup_conn(from);
|
gk = lookup_conn(from);
|
||||||
|
|
||||||
if(!gk)
|
if(!gk)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Receiving key from " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Receiving key from " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(from));
|
IP_ADDR_V(from));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -725,20 +730,20 @@ cp
|
||||||
|
|
||||||
if(!fw)
|
if(!fw)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Attempting to forward key to " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Attempting to forward key to " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(to));
|
IP_ADDR_V(to));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "Forwarding public key to " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("Forwarding public key to " IP_ADDR_S),
|
||||||
IP_ADDR_V(fw->nexthop->vpn_ip));
|
IP_ADDR_V(fw->nexthop->vpn_ip));
|
||||||
|
|
||||||
cl->buffer[cl->reqlen-1] = '\n';
|
cl->buffer[cl->reqlen-1] = '\n';
|
||||||
|
|
||||||
if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
|
if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
|
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
|
@ -753,19 +758,19 @@ cp
|
||||||
if(!cl->status.active) return -1;
|
if(!cl->status.active) return -1;
|
||||||
if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
|
if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "got bad ANS_KEY request: %s", cl->buffer);
|
syslog(LOG_ERR, _("got bad ANS_KEY request: %s"), cl->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_lvl > 2)
|
if(debug_lvl > 2)
|
||||||
syslog(LOG_DEBUG, "got KEY_CHANGED from " IP_ADDR_S,
|
syslog(LOG_DEBUG, _("got KEY_CHANGED from " IP_ADDR_S),
|
||||||
IP_ADDR_V(from));
|
IP_ADDR_V(from));
|
||||||
|
|
||||||
ik = lookup_conn(from);
|
ik = lookup_conn(from);
|
||||||
|
|
||||||
if(!ik)
|
if(!ik)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Got changed key from " IP_ADDR_S ", which does not exist?",
|
syslog(LOG_ERR, _("Got changed key from " IP_ADDR_S ", which does not exist?"),
|
||||||
IP_ADDR_V(from));
|
IP_ADDR_V(from));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -774,7 +779,7 @@ cp
|
||||||
ik->status.waitingforkey = 0;
|
ik->status.waitingforkey = 0;
|
||||||
|
|
||||||
if(debug_lvl > 3)
|
if(debug_lvl > 3)
|
||||||
syslog(LOG_DEBUG, "Forwarding key invalidation request");
|
syslog(LOG_DEBUG, _("Forwarding key invalidation request"));
|
||||||
|
|
||||||
notify_others(cl, ik, send_key_changed);
|
notify_others(cl, ik, send_key_changed);
|
||||||
cp
|
cp
|
||||||
|
|
86
src/tincd.c
86
src/tincd.c
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: tincd.c,v $
|
* $Log: tincd.c,v $
|
||||||
|
* Revision 1.9 2000/05/29 21:01:26 zarq
|
||||||
|
* Internationalization of tinc.
|
||||||
|
*
|
||||||
* Revision 1.8 2000/05/14 12:22:42 guus
|
* Revision 1.8 2000/05/14 12:22:42 guus
|
||||||
* Cleanups.
|
* Cleanups.
|
||||||
*
|
*
|
||||||
|
@ -60,6 +63,8 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "netutl.h"
|
#include "netutl.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
/* The name this program was run with. */
|
/* The name this program was run with. */
|
||||||
char *program_name;
|
char *program_name;
|
||||||
|
|
||||||
|
@ -106,19 +111,19 @@ static void
|
||||||
usage(int status)
|
usage(int status)
|
||||||
{
|
{
|
||||||
if(status != 0)
|
if(status != 0)
|
||||||
fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
|
fprintf(stderr, _("Try `%s --help\' for more information.\n"), program_name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Usage: %s [option]...\n\n", program_name);
|
printf(_("Usage: %s [option]...\n\n"), program_name);
|
||||||
printf(" -c, --config=FILE Read configuration options from FILE.\n"
|
printf(_(" -c, --config=FILE Read configuration options from FILE.\n"
|
||||||
" -D, --no-detach Don't fork and detach.\n"
|
" -D, --no-detach Don't fork and detach.\n"
|
||||||
" -d Increase debug level.\n"
|
" -d Increase debug level.\n"
|
||||||
" -k, --kill Attempt to kill a running tincd and exit.\n"
|
" -k, --kill Attempt to kill a running tincd and exit.\n"
|
||||||
" -n, --net=NETNAME Connect to net NETNAME.\n"
|
" -n, --net=NETNAME Connect to net NETNAME.\n"
|
||||||
" -t, --timeout=TIMEOUT Seconds to wait before giving a timeout.\n");
|
" -t, --timeout=TIMEOUT Seconds to wait before giving a timeout.\n"));
|
||||||
printf(" --help Display this help and exit.\n"
|
printf(_(" --help Display this help and exit.\n"
|
||||||
" --version Output version information and exit.\n\n");
|
" --version Output version information and exit.\n\n"));
|
||||||
printf("Report bugs to tinc@nl.linux.org.\n");
|
printf(_("Report bugs to tinc@nl.linux.org.\n"));
|
||||||
}
|
}
|
||||||
exit(status);
|
exit(status);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +161,7 @@ parse_options(int argc, char **argv, char **envp)
|
||||||
case 't': /* timeout */
|
case 't': /* timeout */
|
||||||
if(!(p = add_config_val(&config, TYPE_INT, optarg)))
|
if(!(p = add_config_val(&config, TYPE_INT, optarg)))
|
||||||
{
|
{
|
||||||
printf("Invalid timeout value `%s'.\n", optarg);
|
printf(_("Invalid timeout value `%s'.\n"), optarg);
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -170,7 +175,7 @@ parse_options(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
void memory_full(int size)
|
void memory_full(int size)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "Memory exhausted (last is %s:%d) (couldn't allocate %d bytes); exiting.", cp_file, cp_line, size);
|
syslog(LOG_ERR, _("Memory exhausted (last is %s:%d) (couldn't allocate %d bytes); exiting."), cp_file, cp_line, size);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,10 +230,10 @@ int detach(void)
|
||||||
openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON);
|
openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_NOTICE, "tincd %s (%s %s) starting, debug level %d.",
|
syslog(LOG_NOTICE, _("tincd %s (%s %s) starting, debug level %d."),
|
||||||
VERSION, __DATE__, __TIME__, debug_lvl);
|
VERSION, __DATE__, __TIME__, debug_lvl);
|
||||||
else
|
else
|
||||||
syslog(LOG_NOTICE, "tincd %s starting, debug level %d.", VERSION, debug_lvl);
|
syslog(LOG_NOTICE, _("tincd %s starting, debug level %d."), VERSION, debug_lvl);
|
||||||
|
|
||||||
xalloc_fail_func = memory_full;
|
xalloc_fail_func = memory_full;
|
||||||
|
|
||||||
|
@ -243,7 +248,7 @@ void cleanup_and_exit(int c)
|
||||||
close_network_connections();
|
close_network_connections();
|
||||||
|
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_INFO, "Total bytes written: tap %d, socket %d; bytes read: tap %d, socket %d.",
|
syslog(LOG_INFO, _("Total bytes written: tap %d, socket %d; bytes read: tap %d, socket %d."),
|
||||||
total_tap_out, total_socket_out, total_tap_in, total_socket_in);
|
total_tap_out, total_socket_out, total_tap_in, total_socket_in);
|
||||||
|
|
||||||
closelog();
|
closelog();
|
||||||
|
@ -261,10 +266,10 @@ int write_pidfile(void)
|
||||||
if((pid = check_pid(pidfilename)))
|
if((pid = check_pid(pidfilename)))
|
||||||
{
|
{
|
||||||
if(netname)
|
if(netname)
|
||||||
fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n",
|
fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"),
|
||||||
netname, pid);
|
netname, pid);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "A tincd is already running with pid %d.\n", pid);
|
fprintf(stderr, _("A tincd is already running with pid %d.\n"), pid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,16 +290,16 @@ int kill_other(void)
|
||||||
if(!(pid = read_pid(pidfilename)))
|
if(!(pid = read_pid(pidfilename)))
|
||||||
{
|
{
|
||||||
if(netname)
|
if(netname)
|
||||||
fprintf(stderr, "No other tincd is running for net `%s'.\n", netname);
|
fprintf(stderr, _("No other tincd is running for net `%s'.\n"), netname);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "No other tincd is running.\n");
|
fprintf(stderr, _("No other tincd is running.\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0; /* No error, sometimes errno is only changed on error */
|
errno = 0; /* No error, sometimes errno is only changed on error */
|
||||||
/* ESRCH is returned when no process with that pid is found */
|
/* ESRCH is returned when no process with that pid is found */
|
||||||
if(kill(pid, SIGTERM) && errno == ESRCH)
|
if(kill(pid, SIGTERM) && errno == ESRCH)
|
||||||
fprintf(stderr, "Removing stale lock file.\n");
|
fprintf(stderr, _("Removing stale lock file.\n"));
|
||||||
remove_pid(pidfilename);
|
remove_pid(pidfilename);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -342,16 +347,21 @@ main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
program_name = argv[0];
|
program_name = argv[0];
|
||||||
|
|
||||||
|
setlocale (LC_ALL, "");
|
||||||
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
|
textdomain (PACKAGE);
|
||||||
|
|
||||||
parse_options(argc, argv, envp);
|
parse_options(argc, argv, envp);
|
||||||
|
|
||||||
if(show_version)
|
if(show_version)
|
||||||
{
|
{
|
||||||
printf("%s version %s\nCopyright (C) 1998,1999,2000 Ivo Timmermans and others,\n"
|
printf(_("%s version %s\n"), PACKAGE, VERSION);
|
||||||
"see the AUTHORS file for a complete list.\n\n"
|
printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans and others,\n"
|
||||||
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
|
"see the AUTHORS file for a complete list.\n\n"
|
||||||
"and you are welcome to redistribute it under certain conditions;\n"
|
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
|
||||||
"see the file COPYING for details.\n\n", PACKAGE, VERSION);
|
"and you are welcome to redistribute it under certain conditions;\n"
|
||||||
printf("This product includes software developed by Eric Young (eay@mincom.oz.au)\n");
|
"see the file COPYING for details.\n\n"));
|
||||||
|
printf(_("This product includes software developed by Eric Young (eay@mincom.oz.au)\n"));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +371,7 @@ main(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
if(geteuid())
|
if(geteuid())
|
||||||
{
|
{
|
||||||
fprintf(stderr, "You must be root to run this program. sorry.\n");
|
fprintf(stderr, _("You must be root to run this program. sorry.\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +406,7 @@ RETSIGTYPE
|
||||||
sigterm_handler(int a)
|
sigterm_handler(int a)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_NOTICE, "Got TERM signal");
|
syslog(LOG_NOTICE, _("Got TERM signal"));
|
||||||
cleanup_and_exit(0);
|
cleanup_and_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,14 +414,14 @@ RETSIGTYPE
|
||||||
sigquit_handler(int a)
|
sigquit_handler(int a)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_NOTICE, "Got QUIT signal");
|
syslog(LOG_NOTICE, _("Got QUIT signal"));
|
||||||
cleanup_and_exit(0);
|
cleanup_and_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RETSIGTYPE
|
RETSIGTYPE
|
||||||
sigsegv_square(int a)
|
sigsegv_square(int a)
|
||||||
{
|
{
|
||||||
syslog(LOG_NOTICE, "Got another SEGV signal: not restarting");
|
syslog(LOG_NOTICE, _("Got another SEGV signal: not restarting"));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,10 +429,10 @@ RETSIGTYPE
|
||||||
sigsegv_handler(int a)
|
sigsegv_handler(int a)
|
||||||
{
|
{
|
||||||
if(cp_file)
|
if(cp_file)
|
||||||
syslog(LOG_NOTICE, "Got SEGV signal after %s line %d. Trying to re-execute.",
|
syslog(LOG_NOTICE, _("Got SEGV signal after %s line %d. Trying to re-execute."),
|
||||||
cp_file, cp_line);
|
cp_file, cp_line);
|
||||||
else
|
else
|
||||||
syslog(LOG_NOTICE, "Got SEGV signal; trying to re-execute.");
|
syslog(LOG_NOTICE, _("Got SEGV signal; trying to re-execute."));
|
||||||
|
|
||||||
signal(SIGSEGV, sigsegv_square);
|
signal(SIGSEGV, sigsegv_square);
|
||||||
|
|
||||||
|
@ -435,7 +445,7 @@ RETSIGTYPE
|
||||||
sighup_handler(int a)
|
sighup_handler(int a)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_NOTICE, "Got HUP signal");
|
syslog(LOG_NOTICE, _("Got HUP signal"));
|
||||||
close_network_connections();
|
close_network_connections();
|
||||||
setup_network_connections();
|
setup_network_connections();
|
||||||
/* FIXME: read config-file and re-establish network connections */
|
/* FIXME: read config-file and re-establish network connections */
|
||||||
|
@ -445,7 +455,7 @@ RETSIGTYPE
|
||||||
sigint_handler(int a)
|
sigint_handler(int a)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 0)
|
if(debug_lvl > 0)
|
||||||
syslog(LOG_NOTICE, "Got INT signal");
|
syslog(LOG_NOTICE, _("Got INT signal"));
|
||||||
cleanup_and_exit(0);
|
cleanup_and_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +469,7 @@ RETSIGTYPE
|
||||||
sigusr2_handler(int a)
|
sigusr2_handler(int a)
|
||||||
{
|
{
|
||||||
if(debug_lvl > 1)
|
if(debug_lvl > 1)
|
||||||
syslog(LOG_NOTICE, "Forcing new keys");
|
syslog(LOG_NOTICE, _("Forcing new key generation"));
|
||||||
regenerate_keys();
|
regenerate_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,10 +477,10 @@ RETSIGTYPE
|
||||||
sighuh(int a)
|
sighuh(int a)
|
||||||
{
|
{
|
||||||
if(cp_file)
|
if(cp_file)
|
||||||
syslog(LOG_NOTICE, "Got unexpected signal (%d) after %s line %d.",
|
syslog(LOG_NOTICE, _("Got unexpected signal (%d) after %s line %d."),
|
||||||
a, cp_file, cp_line);
|
a, cp_file, cp_line);
|
||||||
else
|
else
|
||||||
syslog(LOG_NOTICE, "Got unexpected signal (%d).", a);
|
syslog(LOG_NOTICE, _("Got unexpected signal (%d)."), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue