[PATCH] i18n/l10n pam_winbind. (updated for v3-3 and higher)
boyang
boyang at suse.de
Fri Oct 31 08:10:16 GMT 2008
tested with master, work as expected. Thanks!
boyang wrote:
> Hi, everybody:
> here is the patch for v3-3-test, v3-devel, master, Please review it.
> I have tested v3-3-test, v3-devel with gdm, su, passwd, and it
> worked as expected. For master, I am not sure whether it is a Makefile
> problem or I misused the compile system. When built samba3, some
> binaries ended with 4 were produced, I guess they are for samba4. Why?
> And I cannot use "make install" to install all files for samba3
> because of the error "No rule to make xxxxx4, needed by installbin",@@.
> I compiled master with the following steps: 1. ./configure; 2. make; 3.
> make install(failed). Thanks for helping me on this. :-)
> Here is the major changes:
> 1. add configuration option to set locale directory;
> 2. To make pam_winbind find the correct path to .mo files, define
> the LOCALEDIR; I didn't link it against dynconfig.c but against a new
> file localedir.c because link against dynconfig.c will cause it linking
> to param/loadparam.c(because of lp_XXX()), which is too expensive. many
> unused variables and functions will be linked into pam_winbind, which is
> a waste of memory and disk too.
> 3. add target <installmo> in makefile to install .mo files;
> 4. add one directory locale/ in source/ to hold .po files, For
> example, .po for pam_winbind goes into source[3]/locale/pam_winbind/.
> Thanks in advance!
> Best
> Regards
> BoYang
> 30th, Oct
>
> ------------------------------------------------------------------------
>
> commit 8666b84021dbb0a263d9758c1528d93307a66822
> Author: boyang <boyang at desktop.boyang.novell.com>
> Date: Thu Oct 30 17:53:52 2008 +0800
>
> i18n/l10n pam_winbind
>
> diff --git a/source3/Makefile.in b/source3/Makefile.in
> index ac9770d..05353bf 100644
> --- a/source3/Makefile.in
> +++ b/source3/Makefile.in
> @@ -139,6 +139,9 @@ PRIVATE_DIR = $(PRIVATEDIR)
> # This is where SWAT images and help files go
> SWATDIR = @swatdir@
>
> +# This is where locale(mo) files go
> +LOCALEDIR= @localedir@
> +
> # the directory where lock files go
> LOCKDIR = @lockdir@
>
> @@ -172,7 +175,8 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
> -DCONFIGDIR=\"$(CONFIGDIR)\" \
> -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \
> -DCACHEDIR=\"$(CACHEDIR)\" \
> - -DSTATEDIR=\"$(STATEDIR)\"
> + -DSTATEDIR=\"$(STATEDIR)\" \
> + -DLOCALEDIR=\"$(LOCALEDIR)\"
>
> # Note that all executable programs now provide for an optional executable suffix.
>
> @@ -797,7 +801,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
> $(LIBADS_OBJ) $(POPT_LIB_OBJ) \
> $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ)
>
> -PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
> +PAM_WINBIND_OBJ = nsswitch/pam_winbind.o localedir.o $(WBCOMMON_OBJ) \
> $(LIBREPLACE_OBJ) @BUILD_INIPARSER@
>
> LIBSMBCLIENT_OBJ0 = \
> @@ -1304,6 +1308,13 @@ dynconfig.o: dynconfig.c Makefile
> echo "$(COMPILE_CC_PATH)" 1>&2;\
> $(COMPILE_CC_PATH) >/dev/null 2>&1
>
> +localedir.o: localedir.c Makefile
> + @echo Compiling $*.c
> + @$(COMPILE_CC_PATH) && exit 0;\
> + echo "The following command failed:" 1>&2;\
> + echo "$(COMPILE_CC_PATH)" 1>&2;\
> + $(COMPILE_CC_PATH) >/dev/null 2>&1
> +
> lib/pidfile.o: lib/pidfile.c
> @echo Compiling $*.c
> @$(COMPILE_CC_PATH) && exit 0;\
> @@ -2546,7 +2557,7 @@ bin/test_lp_load at EXEEXT@: $(BINARY_PREREQS) $(TEST_LP_LOAD_OBJ) @BUILD_POPT@ @LI
>
> install:: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSUPCALL@ installman \
> installscripts installdat installmodules @SWAT_INSTALL_TARGETS@ \
> - @INSTALL_PAM_MODULES@ installlibs
> + @INSTALL_PAM_MODULES@ installlibs installmo
>
> install-everything:: install installmodules
>
> @@ -2559,7 +2570,7 @@ install-everything:: install installmodules
> # is not used
>
> installdirs::
> - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR)
> + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) $(LOCALEDIR)
>
> installservers:: all installdirs
> @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) $(SBIN_PROGS)
> @@ -2625,6 +2636,9 @@ revert::
> installman:: installdirs
> @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
>
> +installmo:: all installdirs
> + @$(SHELL) $(srcdir)/script/installmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> .PHONY: showlayout
>
> showlayout::
> @@ -2644,8 +2658,11 @@ showlayout::
> @echo " codepagedir: $(CODEPAGEDIR)"
>
>
> -uninstall:: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
> +uninstall:: uninstallmo uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
>
> +uninstallmo::
> + @$(SHELL) $(srcdir)/script/uninstallmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> uninstallman::
> @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
>
> @@ -2689,7 +2706,7 @@ uninstallpammodules::
> done
>
> # Toplevel clean files
> -TOPFILES=dynconfig.o
> +TOPFILES=dynconfig.o localedir.o
>
> cleanlibs::
> -rm -f ../lib/*/*.o ../lib/*/*/*.o \
> diff --git a/source3/configure.in b/source3/configure.in
> index cd84934..eaf2807 100644
> --- a/source3/configure.in
> +++ b/source3/configure.in
> @@ -662,7 +662,7 @@ AUTH_LIBS="${AUTH_LIBS} ${CRYPT_LIBS}"
>
> AC_CHECK_HEADERS(aio.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
> AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h memory.h alloca.h)
> -AC_CHECK_HEADERS(limits.h float.h pthread.h)
> +AC_CHECK_HEADERS(limits.h float.h pthread.h libintl.h)
> AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
> AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
> AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h)
> @@ -1055,6 +1055,7 @@ AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
> AC_CHECK_HEADERS(sys/mman.h)
> # setbuffer, shmget, shm_open are needed for smbtorture
> AC_CHECK_FUNCS(setbuffer shmget shm_open)
> +AC_CHECK_FUNCS(gettext dgettext)
>
> # Find a method of generating a stack trace
> AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h)
> diff --git a/source3/include/localedir.h b/source3/include/localedir.h
> new file mode 100644
> index 0000000..2a291d3
> --- /dev/null
> +++ b/source3/include/localedir.h
> @@ -0,0 +1,6 @@
> +#ifndef __LOCALEDIR_H__
> +#define __LOCALEDIR_H__
> +
> +extern const char *dyn_LOCALEDIR;
> +
> +#endif
> diff --git a/source3/locale/pam_winbind/genmsg b/source3/locale/pam_winbind/genmsg
> new file mode 100644
> index 0000000..5aa258a
> --- /dev/null
> +++ b/source3/locale/pam_winbind/genmsg
> @@ -0,0 +1,25 @@
> +#!/bin/sh
> +
> +FILES="../../nsswitch/pam_winbind.c ../../nsswitch/pam_winbind.h"
> +LANGS="af ar bg bn bs ca cs cy da de el en_GB en_US es et fi fr gl gu he hi hr hu id it ja ka km ko lo lt mk mr nb nl pa pl pt_BR pt ro ru si sk sl sr sv ta th tr uk vi wa xh zh_CN zh_TW zu"
> +
> +XGETTEXT=xgettext
> +MSGMERGE=msgmerge
> +
> +WIDTH=256
> +
> +$XGETTEXT --default-domain="pam_winbind" \
> + --add-comments \
> + --keyword=_ --keyword=N_ \
> + --width=${WIDTH} \
> + ${FILES}
> +
> +for lang in ${LANGS}; do
> + echo -n $lang
> + touch ${lang}.po
> + mv ${lang}.po ${lang}.po.old
> + ${MSGMERGE} --width=${WIDTH} ${lang}.po.old pam_winbind.po -o ${lang}.po
> + rm -fr ${lang}.po.old
> +done
> +
> +rm -fr pam_winbind.po
> diff --git a/source3/localedir.c b/source3/localedir.c
> new file mode 100644
> index 0000000..20f6921
> --- /dev/null
> +++ b/source3/localedir.c
> @@ -0,0 +1,3 @@
> +#include "localedir.h"
> +
> +const char *dyn_LOCALEDIR = LOCALEDIR;
> diff --git a/source3/m4/check_path.m4 b/source3/m4/check_path.m4
> index 9c99468..f61ed7c 100644
> --- a/source3/m4/check_path.m4
> +++ b/source3/m4/check_path.m4
> @@ -30,6 +30,7 @@ swatdir="\${prefix}/swat"
> codepagedir="\${MODULESDIR}"
> statedir="\${LOCKDIR}"
> cachedir="\${LOCKDIR}"
> +localedir="\${prefix}/share/locale"
>
> AC_ARG_WITH(fhs,
> [AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])],
> @@ -242,6 +243,23 @@ AC_ARG_WITH(mandir,
> ;;
> esac])
>
> +################################################
> +# set locale directory location
> +AC_ARG_WITH(localedir,
> +[ --with-localedir=DIR Where to put po files ($ac_default_prefix/share/locale)],
> +[ case "$withval" in
> + yes|no)
> + #
> + # Just in case anybody does it
> + #
> + AC_MSG_WARN([--with-localedir called without argument - will use default])
> + ;;
> + *)
> + localedir="$withval"
> + ;;
> + esac])
> +
> +
> AC_SUBST(configdir)
> AC_SUBST(lockdir)
> AC_SUBST(piddir)
> @@ -258,6 +276,7 @@ AC_SUBST(cachedir)
> AC_SUBST(rootsbindir)
> AC_SUBST(pammodulesdir)
> AC_SUBST(modulesdir)
> +AC_SUBST(localedir)
>
> #################################################
> # set prefix for 'make test'
> diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
> index 1c92725..cfbc4b0 100644
> --- a/source3/nsswitch/pam_winbind.c
> +++ b/source3/nsswitch/pam_winbind.c
> @@ -147,6 +147,21 @@ static const char *_pam_error_code_str(int err)
>
> #define MAX_PASSWD_TRIES 3
>
> +#ifdef HAVE_GETTEXT
> +static char initialized = 0;
> +
> +static inline void textdomain_init(void);
> +static inline void textdomain_init(void)
> +{
> + if (!initialized) {
> + bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
> + initialized = 1;
> + }
> + return;
> +}
> +#endif
> +
> +
> /*
> * Work around the pam API that has functions with void ** as parameters
> * These lead to strict aliasing warnings with gcc.
> @@ -515,6 +530,10 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
> {
> struct pwb_context *r = NULL;
>
> + #ifdef HAVE_GETTEXT
> + textdomain_init();
> + #endif
> +
> r = TALLOC_ZERO_P(NULL, struct pwb_context);
> if (!r) {
> return PAM_BUF_ERR;
> @@ -557,44 +576,44 @@ static const struct ntstatus_errors {
> const char *error_string;
> } ntstatus_errors[] = {
> {"NT_STATUS_OK",
> - "Success"},
> + N_("Success")},
> {"NT_STATUS_BACKUP_CONTROLLER",
> - "No primary Domain Controler available"},
> + N_("No primary Domain Controler available")},
> {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
> - "No domain controllers found"},
> + N_("No domain controllers found")},
> {"NT_STATUS_NO_LOGON_SERVERS",
> - "No logon servers"},
> + N_("No logon servers")},
> {"NT_STATUS_PWD_TOO_SHORT",
> - "Password too short"},
> + N_("Password too short")},
> {"NT_STATUS_PWD_TOO_RECENT",
> - "The password of this user is too recent to change"},
> + N_("The password of this user is too recent to change")},
> {"NT_STATUS_PWD_HISTORY_CONFLICT",
> - "Password is already in password history"},
> + N_("Password is already in password history")},
> {"NT_STATUS_PASSWORD_EXPIRED",
> - "Your password has expired"},
> + N_("Your password has expired")},
> {"NT_STATUS_PASSWORD_MUST_CHANGE",
> - "You need to change your password now"},
> + N_("You need to change your password now")},
> {"NT_STATUS_INVALID_WORKSTATION",
> - "You are not allowed to logon from this workstation"},
> + N_("You are not allowed to logon from this workstation")},
> {"NT_STATUS_INVALID_LOGON_HOURS",
> - "You are not allowed to logon at this time"},
> + N_("You are not allowed to logon at this time")},
> {"NT_STATUS_ACCOUNT_EXPIRED",
> "Your account has expired. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_DISABLED",
> "Your account is disabled. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_LOCKED_OUT",
> "Your account has been locked. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_ACCESS_DENIED",
> - "Access is denied"},
> + N_("Access is denied")},
> {NULL, NULL}
> };
>
> @@ -604,7 +623,7 @@ static const char *_get_ntstatus_error_string(const char *nt_status_string)
> for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) {
> if (!strcasecmp(ntstatus_errors[i].ntstatus_string,
> nt_status_string)) {
> - return ntstatus_errors[i].error_string;
> + return _(ntstatus_errors[i].error_string);
> }
> }
> return NULL;
> @@ -832,14 +851,14 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
>
> if (days == 0) {
> _make_remark(ctx, PAM_TEXT_INFO,
> - "Your password expires today");
> + _("Your password expires today"));
> return true;
> }
>
> if (days > 0 && days < warn_pwd_expire) {
> _make_remark_format(ctx, PAM_TEXT_INFO,
> - "Your password will expire in %d %s",
> - days, (days > 1) ? "days":"day");
> + _("Your password will expire in %d %s"),
> + days, (days > 1) ? _("days"):_("day"));
> return true;
> }
>
> @@ -1231,9 +1250,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> if (PAM_WB_GRACE_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Grace login. "
> - "Please change your password as soon you're "
> - "online again");
> + _("Grace login. "
> + "Please change your password as soon you're "
> + "online again"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using grace logon\n",
> username);
> @@ -1241,9 +1260,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> } else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Domain Controller unreachable, "
> - "using cached credentials instead. "
> - "Network resources may be unavailable");
> + _("Domain Controller unreachable, "
> + "using cached credentials instead. "
> + "Network resources may be unavailable"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using cached credentials\n",
> username);
> @@ -1266,10 +1285,10 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx,
> {
> if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Failed to establish your Kerberos Ticket cache "
> - "due time differences\n"
> - "with the domain controller. "
> - "Please verify the system time.\n");
> + _("Failed to establish your Kerberos Ticket cache "
> + "due time differences\n"
> + "with the domain controller. "
> + "Please verify the system time.\n"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s: Clock skew when getting Krb5 TGT\n",
> username);
> @@ -1334,7 +1353,7 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
> goto failed;
> }
>
> - str = talloc_asprintf(ctx, "Your password ");
> + str = talloc_asprintf(ctx, _("Your password "));
> if (!str) {
> goto failed;
> }
> @@ -1350,8 +1369,8 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
>
> if (i->password_history > 0) {
> str = talloc_asprintf_append(str,
> - "cannot repeat any of your previous %d "
> - "passwords; ",
> + _("cannot repeat any of your previous %d "
> + "passwords; "),
> i->password_history);
> if (!str) {
> goto failed;
> @@ -1360,19 +1379,19 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
>
> if (i->password_properties & WBC_DOMAIN_PASSWORD_COMPLEX) {
> str = talloc_asprintf_append(str,
> - "must contain capitals, numerals "
> - "or punctuation; "
> - "and cannot contain your account "
> - "or full name; ");
> + _("must contain capitals, numerals "
> + "or punctuation; "
> + "and cannot contain your account "
> + "or full name; "));
> if (!str) {
> goto failed;
> }
> }
>
> str = talloc_asprintf_append(str,
> - "Please type a different password. "
> - "Type a password which meets these requirements in "
> - "both text boxes.");
> + _("Please type a different password. "
> + "Type a password which meets these requirements in "
> + "both text boxes."));
> if (!str) {
> goto failed;
> }
> @@ -1851,8 +1870,8 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
> break;
> case WBC_PWD_CHANGE_REJECT_COMPLEXITY:
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Password does not meet "
> - "complexity requirements");
> + _("Password does not meet "
> + "complexity requirements"));
> break;
> default:
> _pam_log_debug(ctx, LOG_DEBUG,
> @@ -2485,7 +2504,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
> }
>
> retval = _winbind_read_password(ctx, ctx->ctrl, NULL,
> - "Password: ", NULL,
> + _("Password: "), NULL,
> &password);
>
> if (retval != PAM_SUCCESS) {
> @@ -2893,7 +2912,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
>
> /* instruct user what is happening */
>
> -#define greeting "Changing password for"
> +#define greeting _("Changing password for")
> Announce = talloc_asprintf(ctx, "%s %s", greeting, user);
> if (!Announce) {
> _pam_log(ctx, LOG_CRIT,
> @@ -2906,7 +2925,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
> lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD;
> ret = _winbind_read_password(ctx, lctrl,
> Announce,
> - "(current) NT password: ",
> + _("(current) NT password: "),
> NULL,
> (const char **) &pass_old);
> TALLOC_FREE(Announce);
> @@ -2976,8 +2995,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
>
> ret = _winbind_read_password(ctx, lctrl,
> NULL,
> - "Enter new NT password: ",
> - "Retype new NT password: ",
> + _("Enter new NT password: "),
> + _("Retype new NT password: "),
> (const char **)&pass_new);
>
> if (ret != PAM_SUCCESS) {
> diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
> index cb6f450..2d7005a 100644
> --- a/source3/nsswitch/pam_winbind.h
> +++ b/source3/nsswitch/pam_winbind.h
> @@ -9,6 +9,7 @@
> #include "system/time.h"
> #include <talloc.h>
> #include "libwbclient/wbclient.h"
> +#include "localedir.h"
>
> #define MODULE_NAME "pam_winbind"
> #define PAM_SM_AUTH
> @@ -22,6 +23,10 @@
>
> #include <iniparser.h>
>
> +#ifdef HAVE_LIBINTL_H
> +#include <libintl.h>
> +#endif
> +
> #ifndef LINUX
>
> /* Solaris always uses dynamic pam modules */
> @@ -105,8 +110,22 @@ do { \
> * here is the string to inform the user that the new passwords they
> * typed were not the same.
> */
> +
> +#if 0
> +#ifndef LOCALEDIR
> +#define LOCALEDIR "/usr/share/locale"
> +#endif
> +#endif
> +
> +#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
> +#define _(string) dgettext(MODULE_NAME, string)
> +#else
> +#define _(string) string
> +#endif
> +
> +#define N_(string) string
>
> -#define MISTYPED_PASS "Sorry, passwords do not match"
> +#define MISTYPED_PASS _("Sorry, passwords do not match")
>
> #define on(x, y) (x & y)
> #define off(x, y) (!(x & y))
> diff --git a/source3/script/installmo.sh b/source3/script/installmo.sh
> new file mode 100644
> index 0000000..0581853
> --- /dev/null
> +++ b/source3/script/installmo.sh
> @@ -0,0 +1,83 @@
> +#!/bin/sh
> +
> +DESTDIR=$1
> +LOCALEDIR=`echo $2 | sed 's/\/\//\//g'`
> +SRCDIR=$3/
> +MSGFMT=msgfmt
> +
> +case $0 in
> + *uninstall*)
> + if test ! -d "$DESTDIR/$LOCALEDIR"; then
> + echo "Directory $DESTDIR/$LOCALEDIR doesn't exist!"
> + echo "Do a \"make installmo\" or \"make install\" first."
> + exit 1
> + fi
> + mode='uninstall'
> + ;;
> + *)
> + mode='install'
> + ;;
> +esac
> +
> +for dir in $SRCDIR/locale/*; do
> + MODULE=`basename $dir`
> + for f in $SRCDIR/locale/$MODULE/*.po; do
> + BASE=`basename $f`
> + LANGUAGE=`echo $BASE | sed 's/\.po//g'`
> + FNAME="$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/$MODULE.mo"
> + if test ! -d "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"; then
> + mkdir -p "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"
> + fi
> + if test "$mode" = 'install'; then
> + echo "Installing $f as $FNAME"
> + touch "$FNAME"
> + $MSGFMT "$f" -f -o "$FNAME"
> + if test ! -f "$FNAME"; then
> + echo "Cannot install $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + chmod 0644 "$FNAME"
> + elif test "$mode" = 'uninstall'; then
> + echo "removing $FNAME"
> + rm -f "$FNAME"
> + if test -f "$FNAME"; then
> + echo "Cannot remove $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + else
> + echo "Unknown mode $mode. script called as $0."
> + exit 1
> + fi
> + done
> + if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are installed.
> +==============================================================
> +EOF
> + else
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are removed.
> +==============================================================
> +EOF
> + fi
> +done
> +
> +if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +All MO files for Samba are installed. You can use "make uninstall"
> +or "make uninstallmo" to remove them.
> +==============================================================
> +EOF
> +else
> + cat << EOF
> +==============================================================
> +All MO files for Samba are removed. you can use "make install"
> +or "make installmo" to install them.
> +==============================================================
> +EOF
> +fi
> +
> +exit 0
> diff --git a/source3/script/uninstallmo.sh b/source3/script/uninstallmo.sh
> new file mode 100644
> index 0000000..1a2cb68
> --- /dev/null
> +++ b/source3/script/uninstallmo.sh
> @@ -0,0 +1 @@
> +installmo.sh
> \ No newline at end of file
>
> ------------------------------------------------------------------------
>
> commit 95ee8c16a23f309aa736d97d4d1471f3d9ec0598
> Author: boyang <boyang at desktop.boyang.novell.com>
> Date: Thu Oct 30 13:02:41 2008 +0800
>
> i18n/l10n pam_winbind
>
> diff --git a/source/Makefile.in b/source/Makefile.in
> index e6f99f0..235adef 100644
> --- a/source/Makefile.in
> +++ b/source/Makefile.in
> @@ -137,6 +137,9 @@ PRIVATE_DIR = $(PRIVATEDIR)
> # This is where SWAT images and help files go
> SWATDIR = @swatdir@
>
> +# This is where locale(mo) files go
> +LOCALEDIR= @localedir@
> +
> # the directory where lock files go
> LOCKDIR = @lockdir@
>
> @@ -174,7 +177,8 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
> -DCONFIGDIR=\"$(CONFIGDIR)\" \
> -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \
> -DCACHEDIR=\"$(CACHEDIR)\" \
> - -DSTATEDIR=\"$(STATEDIR)\"
> + -DSTATEDIR=\"$(STATEDIR)\" \
> + -DLOCALEDIR=\"$(LOCALEDIR)\"
>
> # Note that all executable programs now provide for an optional executable suffix.
>
> @@ -777,7 +781,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
> $(LIBADS_OBJ) $(POPT_LIB_OBJ) \
> $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ)
>
> -PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
> +PAM_WINBIND_OBJ = nsswitch/pam_winbind.o localedir.o $(WBCOMMON_OBJ) \
> $(LIBREPLACE_OBJ) @BUILD_INIPARSER@
>
> LIBSMBCLIENT_OBJ0 = \
> @@ -1272,6 +1276,13 @@ dynconfig.o: dynconfig.c Makefile
> echo "$(COMPILE_CC_PATH)" 1>&2;\
> $(COMPILE_CC_PATH) >/dev/null 2>&1
>
> +localedir.o: localedir.c Makefile
> + @echo Compiling $*.c
> + @$(COMPILE_CC_PATH) && exit 0;\
> + echo "The following command failed:" 1>&2;\
> + echo "$(COMPILE_CC_PATH)" 1>&2;\
> + $(COMPILE_CC_PATH) >/dev/null 2>&1
> +
> lib/pidfile.o: lib/pidfile.c
> @echo Compiling $*.c
> @$(COMPILE_CC_PATH) && exit 0;\
> @@ -2500,7 +2511,7 @@ bin/rpc_open_tcp at EXEEXT@: $(BINARY_PREREQS) $(RPC_OPEN_TCP_OBJ) @LIBTALLOC_SHARE
>
> install:: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSUPCALL@ installman \
> installscripts installdat installmodules @SWAT_INSTALL_TARGETS@ \
> - @INSTALL_PAM_MODULES@ installlibs
> + @INSTALL_PAM_MODULES@ installlibs installmo
>
> install-everything:: install installmodules
>
> @@ -2513,7 +2524,7 @@ install-everything:: install installmodules
> # is not used
>
> installdirs::
> - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR)
> + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) $(LOCALEDIR)
>
> installservers:: all installdirs
> @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) $(SBIN_PROGS)
> @@ -2579,6 +2590,9 @@ revert::
> installman:: installdirs
> @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
>
> +installmo:: all installdirs
> + @$(SHELL) $(srcdir)/script/installmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> .PHONY: showlayout
>
> showlayout::
> @@ -2598,8 +2612,11 @@ showlayout::
> @echo " codepagedir: $(CODEPAGEDIR)"
>
>
> -uninstall:: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
> +uninstall:: uninstallmo uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
>
> +uninstallmo::
> + @$(SHELL) $(srcdir)/script/uninstallmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> uninstallman::
> @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
>
> @@ -2643,7 +2660,7 @@ uninstallpammodules::
> done
>
> # Toplevel clean files
> -TOPFILES=dynconfig.o
> +TOPFILES=dynconfig.o localedir.o
>
> clean:: cleanlibs
> -rm -f include/build_env.h
> diff --git a/source/configure.in b/source/configure.in
> index 83eef75..6db7ac7 100644
> --- a/source/configure.in
> +++ b/source/configure.in
> @@ -662,7 +662,7 @@ LIBS="${LIBS} ${LIBDL} ${LIBREPLACE_NETWORK_LIBS}"
>
> AC_CHECK_HEADERS(aio.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
> AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h memory.h alloca.h)
> -AC_CHECK_HEADERS(limits.h float.h pthread.h)
> +AC_CHECK_HEADERS(limits.h float.h pthread.h libintl.h)
> AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
> AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
> AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h)
> @@ -1055,6 +1055,7 @@ AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
> AC_CHECK_HEADERS(sys/mman.h)
> # setbuffer, shmget, shm_open are needed for smbtorture
> AC_CHECK_FUNCS(setbuffer shmget shm_open)
> +AC_CHECK_FUNCS(gettext dgettext)
>
> # Find a method of generating a stack trace
> AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h)
> diff --git a/source/include/localedir.h b/source/include/localedir.h
> new file mode 100644
> index 0000000..2a291d3
> --- /dev/null
> +++ b/source/include/localedir.h
> @@ -0,0 +1,6 @@
> +#ifndef __LOCALEDIR_H__
> +#define __LOCALEDIR_H__
> +
> +extern const char *dyn_LOCALEDIR;
> +
> +#endif
> diff --git a/source/locale/pam_winbind/genmsg b/source/locale/pam_winbind/genmsg
> new file mode 100755
> index 0000000..5aa258a
> --- /dev/null
> +++ b/source/locale/pam_winbind/genmsg
> @@ -0,0 +1,25 @@
> +#!/bin/sh
> +
> +FILES="../../nsswitch/pam_winbind.c ../../nsswitch/pam_winbind.h"
> +LANGS="af ar bg bn bs ca cs cy da de el en_GB en_US es et fi fr gl gu he hi hr hu id it ja ka km ko lo lt mk mr nb nl pa pl pt_BR pt ro ru si sk sl sr sv ta th tr uk vi wa xh zh_CN zh_TW zu"
> +
> +XGETTEXT=xgettext
> +MSGMERGE=msgmerge
> +
> +WIDTH=256
> +
> +$XGETTEXT --default-domain="pam_winbind" \
> + --add-comments \
> + --keyword=_ --keyword=N_ \
> + --width=${WIDTH} \
> + ${FILES}
> +
> +for lang in ${LANGS}; do
> + echo -n $lang
> + touch ${lang}.po
> + mv ${lang}.po ${lang}.po.old
> + ${MSGMERGE} --width=${WIDTH} ${lang}.po.old pam_winbind.po -o ${lang}.po
> + rm -fr ${lang}.po.old
> +done
> +
> +rm -fr pam_winbind.po
> diff --git a/source/localedir.c b/source/localedir.c
> new file mode 100644
> index 0000000..20f6921
> --- /dev/null
> +++ b/source/localedir.c
> @@ -0,0 +1,3 @@
> +#include "localedir.h"
> +
> +const char *dyn_LOCALEDIR = LOCALEDIR;
> diff --git a/source/m4/check_path.m4 b/source/m4/check_path.m4
> index 7aa8c21..77e571b 100644
> --- a/source/m4/check_path.m4
> +++ b/source/m4/check_path.m4
> @@ -29,6 +29,7 @@ swatdir="\${prefix}/swat"
> codepagedir="\${MODULESDIR}"
> statedir="\${LOCKDIR}"
> cachedir="\${LOCKDIR}"
> +localedir="\${prefix}/share/locale"
>
> AC_ARG_WITH(fhs,
> [AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])],
> @@ -224,6 +225,23 @@ AC_ARG_WITH(mandir,
> ;;
> esac])
>
> +################################################
> +# set locale directory location
> +AC_ARG_WITH(localedir,
> +[ --with-localedir=DIR Where to put po files ($ac_default_prefix/share/locale)],
> +[ case "$withval" in
> + yes|no)
> + #
> + # Just in case anybody does it
> + #
> + AC_MSG_WARN([--with-localedir called without argument - will use default])
> + ;;
> + *)
> + localedir="$withval"
> + ;;
> + esac])
> +
> +
> AC_SUBST(configdir)
> AC_SUBST(lockdir)
> AC_SUBST(piddir)
> @@ -239,6 +257,7 @@ AC_SUBST(cachedir)
> AC_SUBST(rootsbindir)
> AC_SUBST(pammodulesdir)
> AC_SUBST(modulesdir)
> +AC_SUBST(localedir)
>
> #################################################
> # set prefix for 'make test'
> diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
> index 5593114..1cee296 100644
> --- a/source/nsswitch/pam_winbind.c
> +++ b/source/nsswitch/pam_winbind.c
> @@ -111,6 +111,21 @@ static const char *_pam_error_code_str(int err)
>
> #define MAX_PASSWD_TRIES 3
>
> +#ifdef HAVE_GETTEXT
> +static char initialized = 0;
> +
> +static inline void textdomain_init(void);
> +static inline void textdomain_init(void)
> +{
> + if (!initialized) {
> + bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
> + initialized = 1;
> + }
> + return;
> +}
> +#endif
> +
> +
> /*
> * Work around the pam API that has functions with void ** as parameters
> * These lead to strict aliasing warnings with gcc.
> @@ -469,6 +484,10 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
> {
> struct pwb_context *r = NULL;
>
> + #ifdef HAVE_GETTEXT
> + textdomain_init();
> + #endif
> +
> r = (struct pwb_context *)malloc(sizeof(struct pwb_context));
> if (!r) {
> return PAM_BUF_ERR;
> @@ -511,44 +530,44 @@ static const struct ntstatus_errors {
> const char *error_string;
> } ntstatus_errors[] = {
> {"NT_STATUS_OK",
> - "Success"},
> + N_("Success")},
> {"NT_STATUS_BACKUP_CONTROLLER",
> - "No primary Domain Controler available"},
> + N_("No primary Domain Controler available")},
> {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
> - "No domain controllers found"},
> + N_("No domain controllers found")},
> {"NT_STATUS_NO_LOGON_SERVERS",
> - "No logon servers"},
> + N_("No logon servers")},
> {"NT_STATUS_PWD_TOO_SHORT",
> - "Password too short"},
> + N_("Password too short")},
> {"NT_STATUS_PWD_TOO_RECENT",
> - "The password of this user is too recent to change"},
> + N_("The password of this user is too recent to change")},
> {"NT_STATUS_PWD_HISTORY_CONFLICT",
> - "Password is already in password history"},
> + N_("Password is already in password history")},
> {"NT_STATUS_PASSWORD_EXPIRED",
> - "Your password has expired"},
> + N_("Your password has expired")},
> {"NT_STATUS_PASSWORD_MUST_CHANGE",
> - "You need to change your password now"},
> + N_("You need to change your password now")},
> {"NT_STATUS_INVALID_WORKSTATION",
> - "You are not allowed to logon from this workstation"},
> + N_("You are not allowed to logon from this workstation")},
> {"NT_STATUS_INVALID_LOGON_HOURS",
> - "You are not allowed to logon at this time"},
> + N_("You are not allowed to logon at this time")},
> {"NT_STATUS_ACCOUNT_EXPIRED",
> "Your account has expired. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_DISABLED",
> "Your account is disabled. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_LOCKED_OUT",
> "Your account has been locked. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_ACCESS_DENIED",
> - "Access is denied"},
> + N_("Access is denied")},
> {NULL, NULL}
> };
>
> @@ -558,7 +577,7 @@ static const char *_get_ntstatus_error_string(const char *nt_status_string)
> for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) {
> if (!strcasecmp(ntstatus_errors[i].ntstatus_string,
> nt_status_string)) {
> - return ntstatus_errors[i].error_string;
> + return _(ntstatus_errors[i].error_string);
> }
> }
> return NULL;
> @@ -823,14 +842,14 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
>
> if (days == 0) {
> _make_remark(ctx, PAM_TEXT_INFO,
> - "Your password expires today");
> + _("Your password expires today"));
> return true;
> }
>
> if (days > 0 && days < warn_pwd_expire) {
> _make_remark_format(ctx, PAM_TEXT_INFO,
> - "Your password will expire in %d %s",
> - days, (days > 1) ? "days":"day");
> + _("Your password will expire in %d %s"),
> + days, (days > 1) ? _("days"):_("day"));
> return true;
> }
>
> @@ -1171,9 +1190,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> if (PAM_WB_GRACE_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Grace login. "
> - "Please change your password as soon you're "
> - "online again");
> + _("Grace login. "
> + "Please change your password as soon you're "
> + "online again"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using grace logon\n",
> username);
> @@ -1181,9 +1200,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> } else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Domain Controller unreachable, "
> - "using cached credentials instead. "
> - "Network resources may be unavailable");
> + _("Domain Controller unreachable, "
> + "using cached credentials instead. "
> + "Network resources may be unavailable"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using cached credentials\n",
> username);
> @@ -1206,10 +1225,10 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx,
> {
> if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Failed to establish your Kerberos Ticket cache "
> - "due time differences\n"
> - "with the domain controller. "
> - "Please verify the system time.\n");
> + _("Failed to establish your Kerberos Ticket cache "
> + "due time differences\n"
> + "with the domain controller. "
> + "Please verify the system time.\n"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s: Clock skew when getting Krb5 TGT\n",
> username);
> @@ -1236,14 +1255,14 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
>
> memset(str, '\0', str_size);
>
> - offset = snprintf(str, str_size, "Your password ");
> + offset = snprintf(str, str_size, _("Your password "));
> if (offset == -1) {
> goto failed;
> }
>
> if (response->data.auth.policy.min_length_password > 0) {
> ret = snprintf(str+offset, str_size-offset,
> - "must be at least %d characters; ",
> + _("must be at least %d characters; "),
> response->data.auth.policy.min_length_password);
> if (ret == -1) {
> goto failed;
> @@ -1253,8 +1272,8 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
>
> if (response->data.auth.policy.password_history > 0) {
> ret = snprintf(str+offset, str_size-offset,
> - "cannot repeat any of your previous %d "
> - "passwords; ",
> + _("cannot repeat any of your previous %d "
> + "passwords; "),
> response->data.auth.policy.password_history);
> if (ret == -1) {
> goto failed;
> @@ -1265,10 +1284,10 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
> if (response->data.auth.policy.password_properties &
> DOMAIN_PASSWORD_COMPLEX) {
> ret = snprintf(str+offset, str_size-offset,
> - "must contain capitals, numerals "
> - "or punctuation; "
> - "and cannot contain your account "
> - "or full name; ");
> + _("must contain capitals, numerals "
> + "or punctuation; "
> + "and cannot contain your account "
> + "or full name; "));
> if (ret == -1) {
> goto failed;
> }
> @@ -1276,9 +1295,9 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
> }
>
> ret = snprintf(str+offset, str_size-offset,
> - "Please type a different password. "
> - "Type a password which meets these requirements in "
> - "both text boxes.");
> + _("Please type a different password. "
> + "Type a password which meets these requirements in "
> + "both text boxes."));
> if (ret == -1) {
> goto failed;
> }
> @@ -1578,8 +1597,8 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
> break;
> case SAMR_REJECT_COMPLEXITY:
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Password does not meet "
> - "complexity requirements");
> + _("Password does not meet "
> + "complexity requirements"));
> break;
> default:
> _pam_log_debug(ctx, LOG_DEBUG,
> @@ -1953,7 +1972,7 @@ static char winbind_get_separator(struct pwb_context *ctx)
>
> ZERO_STRUCT(request);
> ZERO_STRUCT(response);
> -
> +
> if (pam_winbind_request_log(ctx, WINBINDD_INFO,
> &request, &response, NULL)) {
> return '\0';
> @@ -2092,7 +2111,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
> }
>
> retval = _winbind_read_password(ctx, ctx->ctrl, NULL,
> - "Password: ", NULL,
> + _("Password: "), NULL,
> &password);
>
> if (retval != PAM_SUCCESS) {
> @@ -2567,7 +2586,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
> time_t pwdlastset_prelim = 0;
>
> /* instruct user what is happening */
> -#define greeting "Changing password for "
> +#define greeting _("Changing password for ")
> Announce = (char *) malloc(sizeof(greeting) + strlen(user));
> if (Announce == NULL) {
> _pam_log(ctx, LOG_CRIT,
> @@ -2582,7 +2601,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
> lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD;
> ret = _winbind_read_password(ctx, lctrl,
> Announce,
> - "(current) NT password: ",
> + _("(current) NT password: "),
> NULL,
> (const char **) &pass_old);
> if (ret != PAM_SUCCESS) {
> @@ -2650,8 +2669,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
>
> ret = _winbind_read_password(ctx, lctrl,
> NULL,
> - "Enter new NT password: ",
> - "Retype new NT password: ",
> + _("Enter new NT password: "),
> + _("Retype new NT password: "),
> (const char **)&pass_new);
>
> if (ret != PAM_SUCCESS) {
> diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
> index c8c1910..7db8718 100644
> --- a/source/nsswitch/pam_winbind.h
> +++ b/source/nsswitch/pam_winbind.h
> @@ -7,6 +7,7 @@
> #include "lib/replace/replace.h"
> #include "system/syslog.h"
> #include "system/time.h"
> +#include "localedir.h"
>
> #define MODULE_NAME "pam_winbind"
> #define PAM_SM_AUTH
> @@ -20,6 +21,10 @@
>
> #include <iniparser.h>
>
> +#ifdef HAVE_LIBINTL_H
> +#include <libintl.h>
> +#endif
> +
> #ifndef LINUX
>
> /* Solaris always uses dynamic pam modules */
> @@ -102,8 +107,22 @@ do { \
> * here is the string to inform the user that the new passwords they
> * typed were not the same.
> */
> +
> +#if 0
> +#ifndef LOCALEDIR
> +#define LOCALEDIR "/usr/share/locale"
> +#endif
> +#endif
> +
> +#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
> +#define _(string) dgettext(MODULE_NAME, string)
> +#else
> +#define _(string) string
> +#endif
> +
> +#define N_(string) string
>
> -#define MISTYPED_PASS "Sorry, passwords do not match"
> +#define MISTYPED_PASS _("Sorry, passwords do not match")
>
> #define on(x, y) (x & y)
> #define off(x, y) (!(x & y))
> diff --git a/source/script/installmo.sh b/source/script/installmo.sh
> new file mode 100644
> index 0000000..0581853
> --- /dev/null
> +++ b/source/script/installmo.sh
> @@ -0,0 +1,83 @@
> +#!/bin/sh
> +
> +DESTDIR=$1
> +LOCALEDIR=`echo $2 | sed 's/\/\//\//g'`
> +SRCDIR=$3/
> +MSGFMT=msgfmt
> +
> +case $0 in
> + *uninstall*)
> + if test ! -d "$DESTDIR/$LOCALEDIR"; then
> + echo "Directory $DESTDIR/$LOCALEDIR doesn't exist!"
> + echo "Do a \"make installmo\" or \"make install\" first."
> + exit 1
> + fi
> + mode='uninstall'
> + ;;
> + *)
> + mode='install'
> + ;;
> +esac
> +
> +for dir in $SRCDIR/locale/*; do
> + MODULE=`basename $dir`
> + for f in $SRCDIR/locale/$MODULE/*.po; do
> + BASE=`basename $f`
> + LANGUAGE=`echo $BASE | sed 's/\.po//g'`
> + FNAME="$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/$MODULE.mo"
> + if test ! -d "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"; then
> + mkdir -p "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"
> + fi
> + if test "$mode" = 'install'; then
> + echo "Installing $f as $FNAME"
> + touch "$FNAME"
> + $MSGFMT "$f" -f -o "$FNAME"
> + if test ! -f "$FNAME"; then
> + echo "Cannot install $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + chmod 0644 "$FNAME"
> + elif test "$mode" = 'uninstall'; then
> + echo "removing $FNAME"
> + rm -f "$FNAME"
> + if test -f "$FNAME"; then
> + echo "Cannot remove $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + else
> + echo "Unknown mode $mode. script called as $0."
> + exit 1
> + fi
> + done
> + if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are installed.
> +==============================================================
> +EOF
> + else
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are removed.
> +==============================================================
> +EOF
> + fi
> +done
> +
> +if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +All MO files for Samba are installed. You can use "make uninstall"
> +or "make uninstallmo" to remove them.
> +==============================================================
> +EOF
> +else
> + cat << EOF
> +==============================================================
> +All MO files for Samba are removed. you can use "make install"
> +or "make installmo" to install them.
> +==============================================================
> +EOF
> +fi
> +
> +exit 0
> diff --git a/source/script/uninstallmo.sh b/source/script/uninstallmo.sh
> new file mode 120000
> index 0000000..1a2cb68
> --- /dev/null
> +++ b/source/script/uninstallmo.sh
> @@ -0,0 +1 @@
> +installmo.sh
> \ No newline at end of file
>
> ------------------------------------------------------------------------
>
> commit 46e5ab0479818193cf51835456ed3f3efecc9a4f
> Author: boyang <boyang at desktop.boyang.novell.com>
> Date: Thu Oct 30 14:11:13 2008 +0800
>
> i18n/l10n pam_winbind
>
> diff --git a/source/Makefile.in b/source/Makefile.in
> index b67cfe8..e52346e 100644
> --- a/source/Makefile.in
> +++ b/source/Makefile.in
> @@ -137,6 +137,9 @@ PRIVATE_DIR = $(PRIVATEDIR)
> # This is where SWAT images and help files go
> SWATDIR = @swatdir@
>
> +# This is where locale(mo) files go
> +LOCALEDIR= @localedir@
> +
> # the directory where lock files go
> LOCKDIR = @lockdir@
>
> @@ -174,7 +177,8 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
> -DCONFIGDIR=\"$(CONFIGDIR)\" \
> -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \
> -DCACHEDIR=\"$(CACHEDIR)\" \
> - -DSTATEDIR=\"$(STATEDIR)\"
> + -DSTATEDIR=\"$(STATEDIR)\" \
> + -DLOCALEDIR=\"$(LOCALEDIR)\"
>
> # Note that all executable programs now provide for an optional executable suffix.
>
> @@ -775,7 +779,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
> $(LIBADS_OBJ) $(POPT_LIB_OBJ) \
> $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ)
>
> -PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
> +PAM_WINBIND_OBJ = nsswitch/pam_winbind.o localedir.o $(WBCOMMON_OBJ) \
> $(LIBREPLACE_OBJ) @BUILD_INIPARSER@
>
> LIBSMBCLIENT_OBJ0 = \
> @@ -1256,6 +1260,13 @@ dynconfig.o: dynconfig.c Makefile
> echo "$(COMPILE_CC_PATH)" 1>&2;\
> $(COMPILE_CC_PATH) >/dev/null 2>&1
>
> +localedir.o: localedir.c Makefile
> + @echo Compiling $*.c
> + @$(COMPILE_CC_PATH) && exit 0;\
> + echo "The following command failed:" 1>&2;\
> + echo "$(COMPILE_CC_PATH)" 1>&2;\
> + $(COMPILE_CC_PATH) >/dev/null 2>&1
> +
> lib/pidfile.o: lib/pidfile.c
> @echo Compiling $*.c
> @$(COMPILE_CC_PATH) && exit 0;\
> @@ -2463,7 +2474,7 @@ bin/rpc_open_tcp at EXEEXT@: $(BINARY_PREREQS) $(RPC_OPEN_TCP_OBJ) @LIBTALLOC_SHARE
>
> install:: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSUPCALL@ installman \
> installscripts installdat installmodules @SWAT_INSTALL_TARGETS@ \
> - @INSTALL_PAM_MODULES@ installlibs
> + @INSTALL_PAM_MODULES@ installlibs installmo
>
> install-everything:: install installmodules
>
> @@ -2476,7 +2487,7 @@ install-everything:: install installmodules
> # is not used
>
> installdirs::
> - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR)
> + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) $(LOCALEDIR)
>
> installservers:: all installdirs
> @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) $(SBIN_PROGS)
> @@ -2540,6 +2551,9 @@ revert::
> installman:: installdirs
> @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
>
> +installmo:: all installdirs
> + @$(SHELL) $(srcdir)/script/installmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> .PHONY: showlayout
>
> showlayout::
> @@ -2559,8 +2573,11 @@ showlayout::
> @echo " codepagedir: $(CODEPAGEDIR)"
>
>
> -uninstall:: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
> +uninstall:: uninstallmo uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
>
> +uninstallmo::
> + @$(SHELL) $(srcdir)/script/uninstallmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
> +
> uninstallman::
> @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
>
> @@ -2604,7 +2621,7 @@ uninstallpammodules::
> done
>
> # Toplevel clean files
> -TOPFILES=dynconfig.o
> +TOPFILES=dynconfig.o localedir.o
>
> clean:: cleanlibs
> -rm -f include/build_env.h
> diff --git a/source/configure.in b/source/configure.in
> index f813e87..7d8a882 100644
> --- a/source/configure.in
> +++ b/source/configure.in
> @@ -662,7 +662,7 @@ LIBS="${LIBS} ${LIBDL} ${LIBREPLACE_NETWORK_LIBS}"
>
> AC_CHECK_HEADERS(aio.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
> AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h memory.h alloca.h)
> -AC_CHECK_HEADERS(limits.h float.h pthread.h)
> +AC_CHECK_HEADERS(limits.h float.h pthread.h libintl.h)
> AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
> AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
> AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h)
> @@ -1040,6 +1040,7 @@ AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
> AC_CHECK_HEADERS(sys/mman.h)
> # setbuffer, shmget, shm_open are needed for smbtorture
> AC_CHECK_FUNCS(setbuffer shmget shm_open)
> +AC_CHECK_FUNCS(gettext dgettext)
>
> # Find a method of generating a stack trace
> AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h)
> diff --git a/source/include/localedir.h b/source/include/localedir.h
> new file mode 100644
> index 0000000..2a291d3
> --- /dev/null
> +++ b/source/include/localedir.h
> @@ -0,0 +1,6 @@
> +#ifndef __LOCALEDIR_H__
> +#define __LOCALEDIR_H__
> +
> +extern const char *dyn_LOCALEDIR;
> +
> +#endif
> diff --git a/source/locale/pam_winbind/genmsg b/source/locale/pam_winbind/genmsg
> new file mode 100644
> index 0000000..5aa258a
> --- /dev/null
> +++ b/source/locale/pam_winbind/genmsg
> @@ -0,0 +1,25 @@
> +#!/bin/sh
> +
> +FILES="../../nsswitch/pam_winbind.c ../../nsswitch/pam_winbind.h"
> +LANGS="af ar bg bn bs ca cs cy da de el en_GB en_US es et fi fr gl gu he hi hr hu id it ja ka km ko lo lt mk mr nb nl pa pl pt_BR pt ro ru si sk sl sr sv ta th tr uk vi wa xh zh_CN zh_TW zu"
> +
> +XGETTEXT=xgettext
> +MSGMERGE=msgmerge
> +
> +WIDTH=256
> +
> +$XGETTEXT --default-domain="pam_winbind" \
> + --add-comments \
> + --keyword=_ --keyword=N_ \
> + --width=${WIDTH} \
> + ${FILES}
> +
> +for lang in ${LANGS}; do
> + echo -n $lang
> + touch ${lang}.po
> + mv ${lang}.po ${lang}.po.old
> + ${MSGMERGE} --width=${WIDTH} ${lang}.po.old pam_winbind.po -o ${lang}.po
> + rm -fr ${lang}.po.old
> +done
> +
> +rm -fr pam_winbind.po
> diff --git a/source/localedir.c b/source/localedir.c
> new file mode 100644
> index 0000000..20f6921
> --- /dev/null
> +++ b/source/localedir.c
> @@ -0,0 +1,3 @@
> +#include "localedir.h"
> +
> +const char *dyn_LOCALEDIR = LOCALEDIR;
> diff --git a/source/m4/check_path.m4 b/source/m4/check_path.m4
> index 7aa8c21..77e571b 100644
> --- a/source/m4/check_path.m4
> +++ b/source/m4/check_path.m4
> @@ -29,6 +29,7 @@ swatdir="\${prefix}/swat"
> codepagedir="\${MODULESDIR}"
> statedir="\${LOCKDIR}"
> cachedir="\${LOCKDIR}"
> +localedir="\${prefix}/share/locale"
>
> AC_ARG_WITH(fhs,
> [AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])],
> @@ -224,6 +225,23 @@ AC_ARG_WITH(mandir,
> ;;
> esac])
>
> +################################################
> +# set locale directory location
> +AC_ARG_WITH(localedir,
> +[ --with-localedir=DIR Where to put po files ($ac_default_prefix/share/locale)],
> +[ case "$withval" in
> + yes|no)
> + #
> + # Just in case anybody does it
> + #
> + AC_MSG_WARN([--with-localedir called without argument - will use default])
> + ;;
> + *)
> + localedir="$withval"
> + ;;
> + esac])
> +
> +
> AC_SUBST(configdir)
> AC_SUBST(lockdir)
> AC_SUBST(piddir)
> @@ -239,6 +257,7 @@ AC_SUBST(cachedir)
> AC_SUBST(rootsbindir)
> AC_SUBST(pammodulesdir)
> AC_SUBST(modulesdir)
> +AC_SUBST(localedir)
>
> #################################################
> # set prefix for 'make test'
> diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
> index c28c5d2..a000b03 100644
> --- a/source/nsswitch/pam_winbind.c
> +++ b/source/nsswitch/pam_winbind.c
> @@ -103,6 +103,21 @@ static const char *_pam_error_code_str(int err)
>
> #define MAX_PASSWD_TRIES 3
>
> +#ifdef HAVE_GETTEXT
> +static char initialized = 0;
> +
> +static inline void textdomain_init(void);
> +static inline void textdomain_init(void)
> +{
> + if (!initialized) {
> + bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
> + initialized = 1;
> + }
> + return;
> +}
> +#endif
> +
> +
> /*
> * Work around the pam API that has functions with void ** as parameters
> * These lead to strict aliasing warnings with gcc.
> @@ -461,6 +476,10 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
> {
> struct pwb_context *r = NULL;
>
> + #ifdef HAVE_GETTEXT
> + textdomain_init();
> + #endif
> +
> r = (struct pwb_context *)malloc(sizeof(struct pwb_context));
> if (!r) {
> return PAM_BUF_ERR;
> @@ -503,44 +522,44 @@ static const struct ntstatus_errors {
> const char *error_string;
> } ntstatus_errors[] = {
> {"NT_STATUS_OK",
> - "Success"},
> + N_("Success")},
> {"NT_STATUS_BACKUP_CONTROLLER",
> - "No primary Domain Controler available"},
> + N_("No primary Domain Controler available")},
> {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
> - "No domain controllers found"},
> + N_("No domain controllers found")},
> {"NT_STATUS_NO_LOGON_SERVERS",
> - "No logon servers"},
> + N_("No logon servers")},
> {"NT_STATUS_PWD_TOO_SHORT",
> - "Password too short"},
> + N_("Password too short")},
> {"NT_STATUS_PWD_TOO_RECENT",
> - "The password of this user is too recent to change"},
> + N_("The password of this user is too recent to change")},
> {"NT_STATUS_PWD_HISTORY_CONFLICT",
> - "Password is already in password history"},
> + N_("Password is already in password history")},
> {"NT_STATUS_PASSWORD_EXPIRED",
> - "Your password has expired"},
> + N_("Your password has expired")},
> {"NT_STATUS_PASSWORD_MUST_CHANGE",
> - "You need to change your password now"},
> + N_("You need to change your password now")},
> {"NT_STATUS_INVALID_WORKSTATION",
> - "You are not allowed to logon from this workstation"},
> + N_("You are not allowed to logon from this workstation")},
> {"NT_STATUS_INVALID_LOGON_HOURS",
> - "You are not allowed to logon at this time"},
> + N_("You are not allowed to logon at this time")},
> {"NT_STATUS_ACCOUNT_EXPIRED",
> "Your account has expired. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_DISABLED",
> "Your account is disabled. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_ACCOUNT_LOCKED_OUT",
> "Your account has been locked. "
> - "Please contact your System administrator"}, /* SCNR */
> + N_("Please contact your System administrator")}, /* SCNR */
> {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
> - "Invalid Trust Account"},
> + N_("Invalid Trust Account")},
> {"NT_STATUS_ACCESS_DENIED",
> - "Access is denied"},
> + N_("Access is denied")},
> {NULL, NULL}
> };
>
> @@ -550,7 +569,7 @@ static const char *_get_ntstatus_error_string(const char *nt_status_string)
> for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) {
> if (!strcasecmp(ntstatus_errors[i].ntstatus_string,
> nt_status_string)) {
> - return ntstatus_errors[i].error_string;
> + return _(ntstatus_errors[i].error_string);
> }
> }
> return NULL;
> @@ -815,14 +834,14 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
>
> if (days == 0) {
> _make_remark(ctx, PAM_TEXT_INFO,
> - "Your password expires today");
> + _("Your password expires today"));
> return true;
> }
>
> if (days > 0 && days < warn_pwd_expire) {
> _make_remark_format(ctx, PAM_TEXT_INFO,
> - "Your password will expire in %d %s",
> - days, (days > 1) ? "days":"day");
> + _("Your password will expire in %d %s"),
> + days, (days > 1) ? _("days"):_("day"));
> return true;
> }
>
> @@ -1163,9 +1182,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> if (PAM_WB_GRACE_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Grace login. "
> - "Please change your password as soon you're "
> - "online again");
> + _("Grace login. "
> + "Please change your password as soon you're "
> + "online again"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using grace logon\n",
> username);
> @@ -1173,9 +1192,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
> } else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) {
>
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Domain Controller unreachable, "
> - "using cached credentials instead. "
> - "Network resources may be unavailable");
> + _("Domain Controller unreachable, "
> + "using cached credentials instead. "
> + "Network resources may be unavailable"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s logged on using cached credentials\n",
> username);
> @@ -1198,10 +1217,10 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx,
> {
> if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Failed to establish your Kerberos Ticket cache "
> - "due time differences\n"
> - "with the domain controller. "
> - "Please verify the system time.\n");
> + _("Failed to establish your Kerberos Ticket cache "
> + "due time differences\n"
> + "with the domain controller. "
> + "Please verify the system time.\n"));
> _pam_log_debug(ctx, LOG_DEBUG,
> "User %s: Clock skew when getting Krb5 TGT\n",
> username);
> @@ -1228,14 +1247,14 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
>
> memset(str, '\0', str_size);
>
> - offset = snprintf(str, str_size, "Your password ");
> + offset = snprintf(str, str_size, _("Your password "));
> if (offset == -1) {
> goto failed;
> }
>
> if (response->data.auth.policy.min_length_password > 0) {
> ret = snprintf(str+offset, str_size-offset,
> - "must be at least %d characters; ",
> + _("must be at least %d characters; "),
> response->data.auth.policy.min_length_password);
> if (ret == -1) {
> goto failed;
> @@ -1245,8 +1264,8 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
>
> if (response->data.auth.policy.password_history > 0) {
> ret = snprintf(str+offset, str_size-offset,
> - "cannot repeat any of your previous %d "
> - "passwords; ",
> + _("cannot repeat any of your previous %d "
> + "passwords; "),
> response->data.auth.policy.password_history);
> if (ret == -1) {
> goto failed;
> @@ -1257,10 +1276,10 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
> if (response->data.auth.policy.password_properties &
> DOMAIN_PASSWORD_COMPLEX) {
> ret = snprintf(str+offset, str_size-offset,
> - "must contain capitals, numerals "
> - "or punctuation; "
> - "and cannot contain your account "
> - "or full name; ");
> + _("must contain capitals, numerals "
> + "or punctuation; "
> + "and cannot contain your account "
> + "or full name; "));
> if (ret == -1) {
> goto failed;
> }
> @@ -1268,9 +1287,9 @@ static char *_pam_compose_pwd_restriction_string(struct winbindd_response *respo
> }
>
> ret = snprintf(str+offset, str_size-offset,
> - "Please type a different password. "
> - "Type a password which meets these requirements in "
> - "both text boxes.");
> + _("Please type a different password. "
> + "Type a password which meets these requirements in "
> + "both text boxes."));
> if (ret == -1) {
> goto failed;
> }
> @@ -1570,8 +1589,8 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
> break;
> case SAMR_REJECT_COMPLEXITY:
> _make_remark(ctx, PAM_ERROR_MSG,
> - "Password does not meet "
> - "complexity requirements");
> + _("Password does not meet "
> + "complexity requirements"));
> break;
> default:
> _pam_log_debug(ctx, LOG_DEBUG,
> @@ -1945,7 +1964,7 @@ static char winbind_get_separator(struct pwb_context *ctx)
>
> ZERO_STRUCT(request);
> ZERO_STRUCT(response);
> -
> +
> if (pam_winbind_request_log(ctx, WINBINDD_INFO,
> &request, &response, NULL)) {
> return '\0';
> @@ -2084,7 +2103,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
> }
>
> retval = _winbind_read_password(ctx, ctx->ctrl, NULL,
> - "Password: ", NULL,
> + _("Password: "), NULL,
> &password);
>
> if (retval != PAM_SUCCESS) {
> @@ -2552,7 +2571,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
> time_t pwdlastset_prelim = 0;
>
> /* instruct user what is happening */
> -#define greeting "Changing password for "
> +#define greeting _("Changing password for ")
> Announce = (char *) malloc(sizeof(greeting) + strlen(user));
> if (Announce == NULL) {
> _pam_log(ctx, LOG_CRIT,
> @@ -2567,7 +2586,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
> lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD;
> ret = _winbind_read_password(ctx, lctrl,
> Announce,
> - "(current) NT password: ",
> + _("(current) NT password: "),
> NULL,
> (const char **) &pass_old);
> if (ret != PAM_SUCCESS) {
> @@ -2635,8 +2654,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
>
> ret = _winbind_read_password(ctx, lctrl,
> NULL,
> - "Enter new NT password: ",
> - "Retype new NT password: ",
> + _("Enter new NT password: "),
> + _("Retype new NT password: "),
> (const char **)&pass_new);
>
> if (ret != PAM_SUCCESS) {
> diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
> index c8c1910..7db8718 100644
> --- a/source/nsswitch/pam_winbind.h
> +++ b/source/nsswitch/pam_winbind.h
> @@ -7,6 +7,7 @@
> #include "lib/replace/replace.h"
> #include "system/syslog.h"
> #include "system/time.h"
> +#include "localedir.h"
>
> #define MODULE_NAME "pam_winbind"
> #define PAM_SM_AUTH
> @@ -20,6 +21,10 @@
>
> #include <iniparser.h>
>
> +#ifdef HAVE_LIBINTL_H
> +#include <libintl.h>
> +#endif
> +
> #ifndef LINUX
>
> /* Solaris always uses dynamic pam modules */
> @@ -102,8 +107,22 @@ do { \
> * here is the string to inform the user that the new passwords they
> * typed were not the same.
> */
> +
> +#if 0
> +#ifndef LOCALEDIR
> +#define LOCALEDIR "/usr/share/locale"
> +#endif
> +#endif
> +
> +#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
> +#define _(string) dgettext(MODULE_NAME, string)
> +#else
> +#define _(string) string
> +#endif
> +
> +#define N_(string) string
>
> -#define MISTYPED_PASS "Sorry, passwords do not match"
> +#define MISTYPED_PASS _("Sorry, passwords do not match")
>
> #define on(x, y) (x & y)
> #define off(x, y) (!(x & y))
> diff --git a/source/script/installmo.sh b/source/script/installmo.sh
> new file mode 100644
> index 0000000..0581853
> --- /dev/null
> +++ b/source/script/installmo.sh
> @@ -0,0 +1,83 @@
> +#!/bin/sh
> +
> +DESTDIR=$1
> +LOCALEDIR=`echo $2 | sed 's/\/\//\//g'`
> +SRCDIR=$3/
> +MSGFMT=msgfmt
> +
> +case $0 in
> + *uninstall*)
> + if test ! -d "$DESTDIR/$LOCALEDIR"; then
> + echo "Directory $DESTDIR/$LOCALEDIR doesn't exist!"
> + echo "Do a \"make installmo\" or \"make install\" first."
> + exit 1
> + fi
> + mode='uninstall'
> + ;;
> + *)
> + mode='install'
> + ;;
> +esac
> +
> +for dir in $SRCDIR/locale/*; do
> + MODULE=`basename $dir`
> + for f in $SRCDIR/locale/$MODULE/*.po; do
> + BASE=`basename $f`
> + LANGUAGE=`echo $BASE | sed 's/\.po//g'`
> + FNAME="$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/$MODULE.mo"
> + if test ! -d "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"; then
> + mkdir -p "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"
> + fi
> + if test "$mode" = 'install'; then
> + echo "Installing $f as $FNAME"
> + touch "$FNAME"
> + $MSGFMT "$f" -f -o "$FNAME"
> + if test ! -f "$FNAME"; then
> + echo "Cannot install $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + chmod 0644 "$FNAME"
> + elif test "$mode" = 'uninstall'; then
> + echo "removing $FNAME"
> + rm -f "$FNAME"
> + if test -f "$FNAME"; then
> + echo "Cannot remove $FNAME. Does $USER have privileges?"
> + exit 1
> + fi
> + else
> + echo "Unknown mode $mode. script called as $0."
> + exit 1
> + fi
> + done
> + if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are installed.
> +==============================================================
> +EOF
> + else
> + cat << EOF
> +==============================================================
> +MO files for $MODULE are removed.
> +==============================================================
> +EOF
> + fi
> +done
> +
> +if test "$mode" = 'install'; then
> + cat << EOF
> +==============================================================
> +All MO files for Samba are installed. You can use "make uninstall"
> +or "make uninstallmo" to remove them.
> +==============================================================
> +EOF
> +else
> + cat << EOF
> +==============================================================
> +All MO files for Samba are removed. you can use "make install"
> +or "make installmo" to install them.
> +==============================================================
> +EOF
> +fi
> +
> +exit 0
> diff --git a/source/script/uninstallmo.sh b/source/script/uninstallmo.sh
> new file mode 120000
> index 0000000..1a2cb68
> --- /dev/null
> +++ b/source/script/uninstallmo.sh
> @@ -0,0 +1 @@
> +installmo.sh
> \ No newline at end of file
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: boyang.vcf
Type: text/x-vcard
Size: 187 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20081031/37557fa4/boyang.vcf
More information about the samba-technical
mailing list