Internationalization of tinc.

This commit is contained in:
Ivo Timmermans 2000-05-29 21:01:26 +00:00
parent 61e71ab74a
commit 9fd02ffcb0
34 changed files with 5517 additions and 192 deletions

View file

@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS = gnu
SUBDIRS = m4 lib cipher src doc redhat debian
SUBDIRS = m4 lib cipher src doc po redhat debian
ACLOCAL_AMFLAGS =

View file

@ -9,8 +9,9 @@ AM_ACLOCAL_INCLUDE(m4)
# Enable GNU extensions.
# Define this here, not in acconfig's @TOP@ section, since definitions
# in the latter don't make it into the configure-time tests.
AC_DEFINE([_GNU_SOURCE])
AC_DEFINE([__USE_BSD])
AC_DEFINE([_GNU_SOURCE], [__USE_BSD])
ALL_LINGUAS="nl"
dnl Checks for programs.
AC_PROG_CC
@ -23,6 +24,8 @@ AC_PROG_MAKE_SET
jm_PERL
AM_PROG_LIBTOOL
AC_ISC_POSIX
dnl Checks for libraries.
dnl Checks for header files.
@ -68,5 +71,6 @@ AC_CHECK_LIB(dl, dlopen, [
LIBS="$LIBS -ldl"
])
AC_OUTPUT([Makefile src/Makefile cipher/Makefile cipher/blowfish/Makefile
doc/Makefile lib/Makefile m4/Makefile redhat/Makefile debian/Makefile])
AC_OUTPUT([Makefile src/Makefile cipher/Makefile
cipher/blowfish/Makefile doc/Makefile intl/Makefile lib/Makefile
m4/Makefile po/Makefile.in redhat/Makefile debian/Makefile])

1086
intl/ChangeLog Normal file

File diff suppressed because it is too large Load diff

214
intl/Makefile.in Normal file
View 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
View file

@ -0,0 +1 @@
GNU gettext library from gettext-0.10.35

203
intl/bindtextdom.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View file

@ -35,6 +35,8 @@
#include "conf.h"
#include "netutl.h" /* for strtoip */
#include "system.h"
config_t *config;
int debug_lvl = 0;
int timeout = 0; /* seconds before timeout */
@ -150,14 +152,14 @@ readconfig(const char *fname, FILE *fp)
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);
return -1;
}
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);
return -1;
}
@ -165,7 +167,7 @@ readconfig(const char *fname, FILE *fp)
cfg = add_config_val(&config, hazahaza[i].argtype, q);
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);
return -1;
}
@ -186,7 +188,7 @@ read_config_file(const char *fname)
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;
}

View file

@ -47,6 +47,8 @@
#include "net.h"
#include "protocol.h"
#include "system.h"
#define ENCR_GENERATOR "0xd"
#define ENCR_PRIME "0x7fffffffffffffffffffffffffffffff" /* Mersenne :) */
@ -104,14 +106,14 @@ cp
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;
}
fscanf(f, "%d ", &size);
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;
}
size >>= 2; /* bits->nibbles */
@ -145,11 +147,11 @@ cp
else
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)
{
syslog(LOG_ERR, "Opening /dev/urandom failed: %m");
syslog(LOG_ERR, _("Opening /dev/urandom failed: %m"));
return -1;
}
@ -214,7 +216,7 @@ cp
encryption_keylen = len;
if(debug_lvl > 2)
syslog(LOG_INFO, "Encryption key set to %s", tmp);
syslog(LOG_INFO, _("Encryption key set to %s"), tmp);
free(tmp);
mpz_clear(ak);

View file

@ -27,6 +27,8 @@
#include "encr.h"
#include "system.h"
unsigned char initvec[] = { 0x22, 0x7b, 0xad, 0x55, 0x41, 0xf4, 0x3e, 0xf3 };
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"))))
{
fprintf(stderr, "Usage: %s bits\n", argv[0]);
fprintf(stderr, _("Usage: %s bits\n"), argv[0]);
return 1;
}
@ -46,17 +48,17 @@ int main(int argc, char **argv)
if(!(bits = atol(argv[1])))
{
fprintf(stderr, "Illegal number: %s\n", argv[1]);
fprintf(stderr, _("Illegal number: %s\n"), argv[1]);
return 1;
}
bits = ((bits - 1) | 63) + 1;
fprintf(stderr, "Generating %d bits number", bits);
fprintf(stderr, _("Generating %d bits number"), bits);
bytes = bits >> 3;
if((fp = fopen("/dev/urandom", "r")) == NULL)
{
perror("Opening /dev/urandom");
perror(_("Opening /dev/urandom"));
return 1;
}
@ -69,7 +71,7 @@ int main(int argc, char **argv)
if(feof(fp))
{
puts("");
fprintf(stderr, "File was empty!\n");
fprintf(stderr, _("File was empty!\n"));
}
p[i] = c;
}
@ -77,7 +79,7 @@ int main(int argc, char **argv)
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);
for(i = 0; i < bytes; i++)
printf("%02x", p[i]);
@ -89,7 +91,7 @@ int main(int argc, char **argv)
for(i = 0; i < bytes; i++)
printf("%02x", p[i]);
puts("");
fprintf(stderr, ": done.\n");
fprintf(stderr, _(": done.\n"));
}
return 0;

128
src/net.c
View file

@ -44,6 +44,8 @@
#include "netutl.h"
#include "protocol.h"
#include "system.h"
int tap_fd = -1;
int total_tap_in = 0;
@ -98,11 +100,11 @@ cp
rp.len = htons(rp.len);
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)
{
syslog(LOG_ERR, "Error sending data: %m");
syslog(LOG_ERR, _("Error sending data: %m"));
return -1;
}
@ -122,7 +124,7 @@ cp
add_mac_addresses(&vp);
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
total_tap_out += lenin;
@ -141,7 +143,7 @@ void add_queue(packet_queue_t **q, void *packet, size_t s)
queue_element_t *e;
cp
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->packet = xmalloc(s);
@ -228,7 +230,7 @@ cp
}
if(debug_lvl > 3)
syslog(LOG_DEBUG, "queue flushed");
syslog(LOG_DEBUG, _("queue flushed"));
cp
}
@ -243,7 +245,7 @@ cp
if(cl->sq)
{
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));
flush_queue(cl, &(cl->sq), xsend);
}
@ -251,7 +253,7 @@ cp
if(cl->rq)
{
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));
flush_queue(cl, &(cl->rq), xrecv);
}
@ -269,14 +271,14 @@ cp
{
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));
}
for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
if(!cl)
{ /* No open outgoing connection has been found. */
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;
}
}
@ -300,7 +302,7 @@ cp
{
add_queue(&(cl->sq), packet, packet->len + 2);
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? */
}
@ -325,7 +327,7 @@ cp
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;
}
@ -346,20 +348,20 @@ int setup_listen_meta_socket(int port)
cp
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;
}
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
{
syslog(LOG_ERR, "setsockopt: %m");
syslog(LOG_ERR, _("setsockopt: %m"));
return -1;
}
flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
syslog(LOG_ERR, "fcntl: %m");
syslog(LOG_ERR, _("fcntl: %m"));
return -1;
}
@ -370,13 +372,13 @@ cp
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;
}
if(listen(nfd, 3))
{
syslog(LOG_ERR, "listen: %m");
syslog(LOG_ERR, _("listen: %m"));
return -1;
}
cp
@ -395,20 +397,20 @@ int setup_vpn_in_socket(int port)
cp
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;
}
if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
{
syslog(LOG_ERR, "setsockopt: %m");
syslog(LOG_ERR, _("setsockopt: %m"));
return -1;
}
flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
syslog(LOG_ERR, "fcntl: %m");
syslog(LOG_ERR, _("fcntl: %m"));
return -1;
}
@ -419,7 +421,7 @@ cp
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;
}
cp
@ -443,7 +445,7 @@ cp
cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(cl->meta_socket == -1)
{
syslog(LOG_ERR, "Creating socket failed: %m");
syslog(LOG_ERR, _("Creating socket failed: %m"));
return -1;
}
@ -453,20 +455,20 @@ cp
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;
}
flags = fcntl(cl->meta_socket, F_GETFL);
if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
{
syslog(LOG_ERR, "fcntl: %m");
syslog(LOG_ERR, _("fcntl: %m"));
return -1;
}
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
return 0;
}
@ -487,7 +489,7 @@ cp
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);
return -1;
}
@ -511,7 +513,7 @@ cp
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;
}
@ -525,20 +527,20 @@ cp
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;
}
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);
return -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
return 0;
}
@ -561,7 +563,7 @@ cp
if(seconds_till_retry>300) /* Don't wait more than 5 minutes. */
seconds_till_retry = 300;
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);
}
cp
@ -594,7 +596,7 @@ cp
signal(SIGALRM, sigalrm_handler);
seconds_till_retry = 300;
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
return 0;
@ -632,7 +634,7 @@ cp
close(tap_fd);
destroy_conn_list();
syslog(LOG_NOTICE, "Terminating.");
syslog(LOG_NOTICE, _("Terminating."));
cp
return;
}
@ -646,12 +648,12 @@ int setup_vpn_connection(conn_list_t *cl)
struct sockaddr_in a;
cp
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);
if(nfd == -1)
{
syslog(LOG_ERR, "Creating data socket failed: %m");
syslog(LOG_ERR, _("Creating data socket failed: %m"));
return -1;
}
@ -661,7 +663,7 @@ cp
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);
return -1;
}
@ -669,7 +671,7 @@ cp
flags = fcntl(nfd, F_GETFL);
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;
}
@ -693,7 +695,7 @@ cp
if(getpeername(sfd, &ci, &len) < 0)
{
syslog(LOG_ERR, "Error: getpeername: %m");
syslog(LOG_ERR, _("Error: getpeername: %m"));
return NULL;
}
@ -705,7 +707,7 @@ cp
p->last_ping_time = time(NULL);
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)
{
@ -753,12 +755,12 @@ int handle_incoming_vpn_data(conn_list_t *cl)
cp
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;
}
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;
}
@ -766,7 +768,7 @@ cp
lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
if(lenin <= 0)
{
syslog(LOG_ERR, "Receiving data failed: %m");
syslog(LOG_ERR, _("Receiving data failed: %m"));
return -1;
}
total_socket_in += lenin;
@ -779,11 +781,11 @@ cp
{
f = lookup_conn(rp.from);
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);
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));
return -1;
}
@ -815,7 +817,7 @@ cp
return;
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)
send_timeout(cl);
@ -831,7 +833,7 @@ cp
signal(SIGALRM, sigalrm_handler);
seconds_till_retry = 5;
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;
@ -863,7 +865,7 @@ cp
{
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->status.timeout = 1;
terminate_connection(p);
@ -894,7 +896,7 @@ int handle_new_meta_connection(conn_list_t *cl)
cp
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;
}
@ -902,7 +904,7 @@ cp
{
shutdown(nfd, 2);
close(nfd);
syslog(LOG_NOTICE, "Closed attempted connection.");
syslog(LOG_NOTICE, _("Closed attempted connection."));
return 0;
}
@ -924,18 +926,18 @@ int handle_incoming_meta_data(conn_list_t *cl)
cp
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;
}
if(x)
{
syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
syslog(LOG_ERR, _("Metadata socket error: %s"), sys_errlist[x]);
return -1;
}
if(cl->buflen >= MAXBUFSIZE)
{
syslog(LOG_ERR, "Metadata read buffer overflow.");
syslog(LOG_ERR, _("Metadata read buffer overflow."));
return -1;
}
@ -943,7 +945,7 @@ cp
if(lenin<=0)
{
syslog(LOG_ERR, "Metadata socket read error: %m");
syslog(LOG_ERR, _("Metadata socket read error: %m"));
return -1;
}
@ -970,22 +972,22 @@ cp
{
if(request_handlers[request] == NULL)
{
syslog(LOG_ERR, "Unknown request: %s", cl->buffer);
syslog(LOG_ERR, _("Unknown request: %s"), cl->buffer);
return -1;
}
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. */
{
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;
}
}
else
{
syslog(LOG_ERR, "Bogus data received.");
syslog(LOG_ERR, _("Bogus data received."));
return -1;
}
@ -1029,7 +1031,7 @@ cp
I've once got here when it said `No route to host'.
*/
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);
return;
}
@ -1064,7 +1066,7 @@ cp
memset(&vp, 0, sizeof(vp));
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;
}
@ -1074,7 +1076,7 @@ cp
if(ether_type != 0x0800)
{
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]));
return;
}
@ -1082,7 +1084,7 @@ cp
if(lenin < 32)
{
if(debug_lvl > 0)
syslog(LOG_INFO, "Dropping short packet");
syslog(LOG_INFO, _("Dropping short packet"));
return;
}
@ -1090,10 +1092,10 @@ cp
to = ntohl(*((unsigned long*)(&vp.data[30])));
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));
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]));
vp.len = (length_t)lenin - 2;
@ -1128,7 +1130,7 @@ cp
{
if(errno == EINTR) /* because of alarm */
continue;
syslog(LOG_ERR, "Error while waiting for input: %m");
syslog(LOG_ERR, _("Error while waiting for input: %m"));
return;
}

View file

@ -35,6 +35,8 @@
#include "net.h"
#include "netutl.h"
#include "system.h"
/*
look for a connection associated with the given vpn ip,
return its connection structure.
@ -203,7 +205,7 @@ cp
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;
}
@ -227,7 +229,7 @@ void dump_conn_list(void)
{
conn_list_t *p;
cp
syslog(LOG_DEBUG, "Connection list:");
syslog(LOG_DEBUG, _("Connection list:"));
for(p = conn_list; p != NULL; p = p->next)
{

View file

@ -1,6 +1,7 @@
/*
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
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
along with this program; if not, write to the Free Software
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"
@ -37,6 +40,8 @@
#include "netutl.h"
#include "protocol.h"
#include "system.h"
char buffer[MAXBUFSIZE+1];
int buflen;
@ -46,17 +51,17 @@ int send_ack(conn_list_t *cl)
{
cp
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);
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;
}
syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
syslog(LOG_NOTICE, _("Connection with %s activated."), cl->hostname);
cp
return 0;
}
@ -65,7 +70,7 @@ int send_termreq(conn_list_t *cl)
{
cp
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));
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(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;
}
cp
@ -84,14 +89,14 @@ int send_timeout(conn_list_t *cl)
{
cp
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
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;
}
cp
@ -102,14 +107,14 @@ int send_del_host(conn_list_t *cl, conn_list_t *new_host)
{
cp
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
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;
}
cp
@ -120,13 +125,13 @@ int send_ping(conn_list_t *cl)
{
cp
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);
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;
}
cp
@ -140,7 +145,7 @@ cp
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;
}
cp
@ -151,14 +156,14 @@ int send_add_host(conn_list_t *cl, conn_list_t *new_host)
{
cp
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));
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)
{
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
return -1;
}
cp
@ -169,14 +174,14 @@ int send_key_changed(conn_list_t *cl, conn_list_t *src)
{
cp
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
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;
}
cp
@ -197,14 +202,14 @@ int send_basic_info(conn_list_t *cl)
{
cp
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));
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)
{
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
return -1;
}
cp
@ -218,14 +223,14 @@ cp
encrypt_passphrase(&tmp);
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
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;
}
cp
@ -236,14 +241,14 @@ int send_public_key(conn_list_t *cl)
{
cp
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
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;
}
cp
@ -257,7 +262,7 @@ cp
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;
}
cp
@ -271,20 +276,20 @@ cp
fw = lookup_conn(to);
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));
return -1;
}
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));
buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
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;
}
fw->status.waitingforkey = 1;
@ -301,20 +306,20 @@ cp
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));
return -1;
}
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));
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)
{
syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
return -1;
}
cp
@ -362,22 +367,22 @@ int basic_info_h(conn_list_t *cl)
cp
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;
}
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);
return -1;
}
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));
if(debug_lvl > 1)
syslog(LOG_DEBUG, "Peer uses protocol version %d",
syslog(LOG_DEBUG, _("Peer uses protocol version %d"),
cl->protocol_version);
if(cl->status.outgoing)
@ -403,13 +408,13 @@ cp
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;
}
cl->pp->len = strlen(cl->pp->phrase);
if(debug_lvl > 2)
syslog(LOG_DEBUG, "got PASSPHRASE");
syslog(LOG_DEBUG, _("got PASSPHRASE"));
if(cl->status.outgoing)
send_passphrase(cl);
@ -426,22 +431,22 @@ int public_key_h(conn_list_t *cl)
cp
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;
}
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))
{
/* intruder! */
syslog(LOG_ERR, "Intruder: passphrase does not match.");
syslog(LOG_ERR, _("Intruder: passphrase does not match."));
return -1;
}
if(debug_lvl > 2)
syslog(LOG_INFO, "Passphrase OK");
syslog(LOG_INFO, _("Passphrase OK"));
if(cl->status.outgoing)
send_public_key(cl);
@ -467,10 +472,10 @@ int ack_h(conn_list_t *cl)
{
cp
if(debug_lvl > 2)
syslog(LOG_DEBUG, "got ACK");
syslog(LOG_DEBUG, _("got ACK"));
cl->status.active = 1;
syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
syslog(LOG_NOTICE, _("Connection with %s activated."), cl->hostname);
cp
return 0;
}
@ -478,7 +483,7 @@ cp
int termreq_h(conn_list_t *cl)
{
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;
terminate_connection(cl);
@ -491,7 +496,7 @@ int timeout_h(conn_list_t *cl)
{
cp
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;
terminate_connection(cl);
cp
@ -507,17 +512,17 @@ cp
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;
}
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));
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));
return 0;
}
@ -535,7 +540,7 @@ int ping_h(conn_list_t *cl)
cp
if(!cl->status.active) return -1;
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.got_pong = 1;
@ -549,7 +554,7 @@ int pong_h(conn_list_t *cl)
cp
if(!cl->status.active) return -1;
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;
cp
return 0;
@ -566,14 +571,14 @@ cp
if(!cl->status.active) return -1;
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;
}
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)
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);
/*
@ -609,12 +614,12 @@ cp
if(!cl->status.active) return -1;
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;
}
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));
if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
@ -627,20 +632,20 @@ cp
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));
return -1;
}
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));
cl->buffer[cl->reqlen-1] = '\n';
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;
}
cp
@ -693,23 +698,23 @@ cp
if(!cl->status.active) return -1;
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;
}
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));
if(to == myself->vpn_ip)
{ /* hey! that key's for ME! :) */
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);
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));
return -1;
}
@ -725,20 +730,20 @@ cp
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));
return -1;
}
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));
cl->buffer[cl->reqlen-1] = '\n';
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;
}
cp
@ -753,19 +758,19 @@ cp
if(!cl->status.active) return -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;
}
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));
ik = lookup_conn(from);
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));
return -1;
}
@ -774,7 +779,7 @@ cp
ik->status.waitingforkey = 0;
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);
cp

View file

@ -19,6 +19,9 @@
/*
* $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
* Cleanups.
*
@ -60,6 +63,8 @@
#include "net.h"
#include "netutl.h"
#include "system.h"
/* The name this program was run with. */
char *program_name;
@ -106,19 +111,19 @@ static void
usage(int status)
{
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
{
printf("Usage: %s [option]...\n\n", program_name);
printf(" -c, --config=FILE Read configuration options from FILE.\n"
" -D, --no-detach Don't fork and detach.\n"
" -d Increase debug level.\n"
" -k, --kill Attempt to kill a running tincd and exit.\n"
" -n, --net=NETNAME Connect to net NETNAME.\n"
" -t, --timeout=TIMEOUT Seconds to wait before giving a timeout.\n");
printf(" --help Display this help and exit.\n"
" --version Output version information and exit.\n\n");
printf("Report bugs to tinc@nl.linux.org.\n");
printf(_("Usage: %s [option]...\n\n"), program_name);
printf(_(" -c, --config=FILE Read configuration options from FILE.\n"
" -D, --no-detach Don't fork and detach.\n"
" -d Increase debug level.\n"
" -k, --kill Attempt to kill a running tincd and exit.\n"
" -n, --net=NETNAME Connect to net NETNAME.\n"
" -t, --timeout=TIMEOUT Seconds to wait before giving a timeout.\n"));
printf(_(" --help Display this help and exit.\n"
" --version Output version information and exit.\n\n"));
printf(_("Report bugs to tinc@nl.linux.org.\n"));
}
exit(status);
}
@ -156,7 +161,7 @@ parse_options(int argc, char **argv, char **envp)
case 't': /* timeout */
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);
}
break;
@ -170,7 +175,7 @@ parse_options(int argc, char **argv, char **envp)
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);
}
@ -225,10 +230,10 @@ int detach(void)
openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON);
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);
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;
@ -243,7 +248,7 @@ void cleanup_and_exit(int c)
close_network_connections();
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);
closelog();
@ -261,10 +266,10 @@ int write_pidfile(void)
if((pid = check_pid(pidfilename)))
{
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);
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;
}
@ -285,16 +290,16 @@ int kill_other(void)
if(!(pid = read_pid(pidfilename)))
{
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
fprintf(stderr, "No other tincd is running.\n");
fprintf(stderr, _("No other tincd is running.\n"));
return 1;
}
errno = 0; /* No error, sometimes errno is only changed on error */
/* ESRCH is returned when no process with that pid is found */
if(kill(pid, SIGTERM) && errno == ESRCH)
fprintf(stderr, "Removing stale lock file.\n");
fprintf(stderr, _("Removing stale lock file.\n"));
remove_pid(pidfilename);
return 0;
@ -342,16 +347,21 @@ main(int argc, char **argv, char **envp)
{
program_name = argv[0];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
parse_options(argc, argv, envp);
if(show_version)
{
printf("%s version %s\nCopyright (C) 1998,1999,2000 Ivo Timmermans and others,\n"
"see the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"
"see the file COPYING for details.\n\n", PACKAGE, VERSION);
printf("This product includes software developed by Eric Young (eay@mincom.oz.au)\n");
printf(_("%s version %s\n"), PACKAGE, VERSION);
printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans and others,\n"
"see the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\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;
}
@ -361,7 +371,7 @@ main(int argc, char **argv, char **envp)
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;
}
@ -396,7 +406,7 @@ RETSIGTYPE
sigterm_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, "Got TERM signal");
syslog(LOG_NOTICE, _("Got TERM signal"));
cleanup_and_exit(0);
}
@ -404,14 +414,14 @@ RETSIGTYPE
sigquit_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, "Got QUIT signal");
syslog(LOG_NOTICE, _("Got QUIT signal"));
cleanup_and_exit(0);
}
RETSIGTYPE
sigsegv_square(int a)
{
syslog(LOG_NOTICE, "Got another SEGV signal: not restarting");
syslog(LOG_NOTICE, _("Got another SEGV signal: not restarting"));
exit(0);
}
@ -419,10 +429,10 @@ RETSIGTYPE
sigsegv_handler(int a)
{
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);
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);
@ -435,7 +445,7 @@ RETSIGTYPE
sighup_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, "Got HUP signal");
syslog(LOG_NOTICE, _("Got HUP signal"));
close_network_connections();
setup_network_connections();
/* FIXME: read config-file and re-establish network connections */
@ -445,7 +455,7 @@ RETSIGTYPE
sigint_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, "Got INT signal");
syslog(LOG_NOTICE, _("Got INT signal"));
cleanup_and_exit(0);
}
@ -459,7 +469,7 @@ RETSIGTYPE
sigusr2_handler(int a)
{
if(debug_lvl > 1)
syslog(LOG_NOTICE, "Forcing new keys");
syslog(LOG_NOTICE, _("Forcing new key generation"));
regenerate_keys();
}
@ -467,10 +477,10 @@ RETSIGTYPE
sighuh(int a)
{
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);
else
syslog(LOG_NOTICE, "Got unexpected signal (%d).", a);
syslog(LOG_NOTICE, _("Got unexpected signal (%d)."), a);
}
void