diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2014-08-25 19:13:37 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2014-08-25 19:20:00 +0300 |
commit | e26cb120ffe5f7303ddd8b514246ac6874e83f9f (patch) | |
tree | 64ca646b34103a5e8934b42fbbd9ca732a14e034 | |
parent | 713bc0ca4b4ea3114d33f06c57c117de7f9fef11 (diff) | |
download | direvent-e26cb120ffe5f7303ddd8b514246ac6874e83f9f.tar.gz direvent-e26cb120ffe5f7303ddd8b514246ac6874e83f9f.tar.bz2 |
I18N
* .gitignore: Add am
* bootstrap: Create am, unless exists.
* Makefile.am (SUBDIRS): Add po
* acinclude.m4: New file.
* configure.ac: Use gettext
* doc/direvent.texi: Update
* po/.gitignore: New file
* po/POTFILES.in: New file.
* po/Makevars: New file.
* src/Makefile.am (LDADD): Add @LIBINTL@
(noinst_HEADERS): Add gettext.h
* src/config.c: gettextize
* src/direvent.c: Likewise.
* src/environ.c: Likewise.
* src/hashtab.c: Likewise.
* src/progman.c: Likewise.
* src/watcher.c: Likewise.
* src/gettext.h: New file.
* src/direvent.h: Add missing prototypes.
* tests/re05.at: Remove superfluous quoting.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | acinclude.m4 | 44 | ||||
-rwxr-xr-x | bootstrap | 1 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | doc/direvent.texi | 12 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | po/.gitignore | 20 | ||||
-rw-r--r-- | po/Makevars | 41 | ||||
-rw-r--r-- | po/POTFILES.in | 9 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/config.c | 103 | ||||
-rw-r--r-- | src/direvent.c | 16 | ||||
-rw-r--r-- | src/direvent.h | 13 | ||||
-rw-r--r-- | src/environ.c | 3 | ||||
-rw-r--r-- | src/gettext.h | 280 | ||||
-rw-r--r-- | src/hashtab.c | 6 | ||||
-rw-r--r-- | src/progman.c | 32 | ||||
-rw-r--r-- | src/watcher.c | 28 | ||||
-rw-r--r-- | tests/re05.at | 2 |
20 files changed, 524 insertions, 105 deletions
@@ -11,12 +11,13 @@ ABOUT-NLS ChangeLog INSTALL Makefile Makefile.in TAGS aclocal.m4 +am autom4te.cache build-aux config.h config.h.in config.log config.status diff --git a/Makefile.am b/Makefile.am index ea87088..9b13324 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,17 +11,19 @@ # 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 Direvent. If not, see <http://www.gnu.org/licenses/>. -ACLOCAL_AMFLAGS = -I grecs/am +ACLOCAL_AMFLAGS = -I am -I grecs/am -SUBDIRS=grecs src tests doc +SUBDIRS= grecs src tests doc po .PHONY: ChangeLog ChangeLog: $(AM_V_GEN)if test -d .git; then \ git log --pretty='format:%ct %an <%ae>%n%n%s%n%n%b%n' | \ awk -f $(top_builddir)/grecs/build-aux/git2chg.awk > ChangeLog; \ fi + +EXTRA_DIST = build-aux/config.rpath diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..31651bc --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,44 @@ +# This file is part of Direvent -*- autoconf -*- +# Copyright (C) 2012-2014 Sergey Poznyakoff +# +# Direvent 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 3, or (at your option) +# any later version. +# +# Direvent 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 Direvent. If not, see <http://www.gnu.org/licenses/>. + +AC_DEFUN([DEVT_CC_OPT],[ + m4_pushdef([devt_optname],translit($1,[-],[_])) + AC_MSG_CHECKING(whether $CC accepts $1) + devt_save_cc="$CC" + CC="$CC $1" + AC_TRY_RUN([int main() { return 0; }], + [devt_cv_cc_]devt_optname=yes, + [devt_cv_cc_]devt_optname=no, + [devt_cv_cc_]devt_optname=no) + CC="$devt_save_cc" + AC_MSG_RESULT($[devt_cv_cc_]devt_optname) + + if test $[devt_cv_cc_]devt_optname = yes; then + ifelse([$2],,:,[$2]) + ifelse([$3],,,else + [$3]) + fi + m4_popdef([devt_optname]) + ]) + +AC_DEFUN([DEVT_CC_OPT_CFLAGS],[ + DEVT_CC_OPT([$1],[CFLAGS="$CFLAGS $1"]) +]) + +AC_DEFUN([DEVT_CC_PAREN_QUIRK],[ + DEVT_CC_OPT_CFLAGS([-Wno-parentheses]) +]) + @@ -1,5 +1,6 @@ #! /bin/sh set -e +test -d am || mkdir am git submodule init git submodule update autoreconf -f -i -s diff --git a/configure.ac b/configure.ac index c4060d8..57cda4b 100644 --- a/configure.ac +++ b/configure.ac @@ -25,12 +25,13 @@ AM_INIT_AUTOMAKE([1.11.5 gnits tar-ustar silent-rules]) # Enable silent rules by default: AM_SILENT_RULES([yes]) # Checks for programs. AC_PROG_AWK AC_PROG_CC +DEVT_CC_PAREN_QUIRK AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_MAKE_SET # Checks for libraries. @@ -62,16 +63,22 @@ AH_TOP([ #define IFACE_KQUEUE 1 /* kqueue - BSD */ ]) # Grecs subsystem GRECS_SETUP([grecs],[tree-api git2chg no-preproc getopt tests]) +GRECS_HOST_PROJECT_INCLUDES='-I$(top_srcdir)/src' + +# Gettext. +AM_ICONV +AM_GNU_GETTEXT([external], [need-formatstring-macros]) +AM_GNU_GETTEXT_VERSION([0.18]) # Initialize the test suite. AC_CONFIG_TESTDIR(tests) -AC_CONFIG_FILES([tests/Makefile tests/atlocal]) +AC_CONFIG_FILES([tests/Makefile tests/atlocal po/Makefile.in]) AM_MISSING_PROG([AUTOM4TE], [autom4te]) AC_CONFIG_COMMANDS([status],[ cat <<EOT Selected interface: $iface diff --git a/doc/direvent.texi b/doc/direvent.texi index 46b9a35..104ced0 100644 --- a/doc/direvent.texi +++ b/doc/direvent.texi @@ -1,13 +1,13 @@ \input texinfo @c -*-texinfo-*- @smallbook @c %**start of header @setfilename direvent.info @settitle GNU Direvent @c %**end of header -@setchapternewpage odd +@c @setchapternewpage odd @defcodeindex pr @defcodeindex op @defcodeindex kw @defcodeindex fl @@ -109,13 +109,13 @@ and system-independent command-level interface. As of version @node Overview @chapter Overview @GNUDIREVENT{} monitors a set of directories on the file system and reacts when a file system event occurs in any of them. Directories and events to monitor are specified in the configuration file. When -an event occurs the utility reacts by invoking an external command +an event occurs, the program reacts by invoking an external command configured for that event. @cindex events @cindex file system events File system events can be divided into two major groups. The @dfn{system-dependent events} are specific for each particular kernel @@ -143,13 +143,13 @@ A file was written to; File attributes have changed. This includes changes in the file ownership, mode, link count, etc. @end table @cindex watcher, introduced @cindex handler, introduced -A @dfn{watcher} is a configuration entity which associates a set of +A @dfn{watcher} is a configuration entity that associates a set of directories with a set of events and instructs @command{direvent} to run a specified external command when any of these events occur in any of these directories. This external command (called a @dfn{handler}) can obtain information about the event that triggered it from the environment variables, or from its command line. @@ -178,22 +178,24 @@ any amount of whitespace and is terminated with a semicolon. A block statement is a collection of statements enclosed in curly braces. @cindex watcher declaration, summary The following block statement declares a watcher: @example +@group watcher @{ path @var{pathname} [recursive [@var{level}]]; + file @var{pattern-list}; event @var{event-list}; command @var{command-line}; - file @var{pattern-list}; user @var{name}; timeout @var{number}; environ @var{env-spec}; option @var{string-list}; @} +@end group @end example Each @code{watcher} statement instructs @command{direvent} to monitor events listed in @var{event-list} occurring in the directories specified by @var{pathname}s in @code{path} statements (any number of @code{path} statements can be given). When any such event is detected, @@ -233,13 +235,13 @@ watcher @{ path /home/ftp/incoming; event create; # @r{more statements follow...} @end example On this event, the watcher is to invoke @file{/usr/bin/upload} -with the name of created file as an argument. To make it +with the name of the created file as an argument. To make it possible, the @command{direvent} configuration file provides @dfn{macro variables}, which can be used in the @code{command} argument at configuration time and which are expanded to the actual values before the command is executed. Macro variables are referred to using the same syntax as shell variables: a dollar sign followed by the variable name, optionally enclosed in curly braces. The @samp{file} variable diff --git a/grecs b/grecs -Subproject 57a00b140954a2c22ba2fdebc93e8e6eda41b2a +Subproject 477701c059d73e47aa1bac97e96d801542f2bd8 diff --git a/po/.gitignore b/po/.gitignore new file mode 100644 index 0000000..32545fd --- /dev/null +++ b/po/.gitignore @@ -0,0 +1,20 @@ +*.gmo +*.po +*.po~ +.pot +.reference/ +LINGUAS +Makefile.in.in +Makevars.template +POTFILES +Rules-quot +boldquot.sed +en@boldquot.header +en@quot.header +insert-header.sed +insert-header.sin +direvent.pot +quot.sed +remove-potcdate.sed +remove-potcdate.sin +stamp-po diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 0000000..33b0663 --- /dev/null +++ b/po/Makevars @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Sergey Poznyakoff + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = bug-direvent@gnu.org.ua + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..5029ee6 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,9 @@ +# List of source files which contain translatable strings. + +src/cmdline.h +src/config.c +src/direvent.c +src/environ.c +src/hashtab.c +src/progman.c +src/watcher.c diff --git a/src/Makefile.am b/src/Makefile.am index c7f1439..8bdf610 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,16 +38,17 @@ if DIREVENT_RFORK direvent_SOURCES += detach-bsd.c else direvent_SOURCES += detach-darwin.c endif endif -LDADD=@GRECS_LDADD@ +LDADD=@GRECS_LDADD@ @LIBINTL@ AM_CPPFLAGS=-I$(top_srcdir)/grecs/src/ BUILT_SOURCES=cmdline.h EXTRA_DIST=cmdline.opt +noinst_HEADERS=gettext.h SUFFIXES=.opt .c .h .opt.h: $(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@ diff --git a/src/config.c b/src/config.c index 9c17124..82262a8 100644 --- a/src/config.c +++ b/src/config.c @@ -57,13 +57,13 @@ get_facility(const char *arg) errno = 0; f = strtoul (arg, &p, 0); if (*p == 0 && errno == 0) return f; if (trans_strtotok(kwfac, arg, &f)) { - diag(LOG_CRIT, "unknown syslog facility: %s", arg); + diag(LOG_CRIT, _("unknown syslog facility: %s"), arg); exit(1); } return f; } int @@ -74,35 +74,35 @@ get_priority(const char *arg) errno = 0; f = strtoul (arg, &p, 0); if (*p == 0 && errno == 0) return f; if (trans_strtotok(kwpri, arg, &f)) { - diag(LOG_CRIT, "unknown syslog priority: %s", arg); + diag(LOG_CRIT, _("unknown syslog priority: %s"), arg); exit(1); } return f; } #define ASSERT_SCALAR(cmd, locus) \ if ((cmd) != grecs_callback_set_value) { \ - grecs_error(locus, 0, "Unexpected block statement"); \ + grecs_error(locus, 0, _("unexpected block statement")); \ return 1; \ } int assert_grecs_value_type(grecs_locus_t *locus, const grecs_value_t *value, int type) { if (GRECS_VALUE_EMPTY_P(value)) { - grecs_error(locus, 0, "expected %s", + grecs_error(locus, 0, _("expected %s"), grecs_data_type_string(type)); return 1; } if (value->type != type) { - grecs_error(locus, 0, "expected %s, but found %s", + grecs_error(locus, 0, _("expected %s, but found %s"), grecs_data_type_string(type), grecs_data_type_string(value->type)); return 1; } return 0; } @@ -118,32 +118,32 @@ cb_syslog_facility(enum grecs_callback_command cmd, grecs_node_t *node, ASSERT_SCALAR(cmd, locus); if (assert_grecs_value_type(&value->locus, value, GRECS_TYPE_STRING)) return 1; if (trans_strtotok(kwfac, value->v.string, &fac)) grecs_error(&value->locus, 0, - "Unknown syslog facility `%s'", + _("unknown syslog facility `%s'"), value->v.string); else *(int*)varptr = fac; return 0; } static struct grecs_keyword syslog_kw[] = { { "facility", - "name", - "Set syslog facility. Arg is one of the following: user, daemon, " - "auth, authpriv, mail, cron, local0 through local7 " - "(case-insensitive), or a facility number.", + N_("name"), + N_("Set syslog facility. Arg is one of the following: user, daemon, " + "auth, authpriv, mail, cron, local0 through local7 " + "(case-insensitive), or a facility number."), grecs_type_string, GRECS_DFLT, &facility, 0, cb_syslog_facility }, - { "tag", "string", "Tag syslog messages with this string", + { "tag", N_("string"), N_("Tag syslog messages with this string"), grecs_type_string, GRECS_DFLT, &tag }, - { "print-priority", "arg", - "Prefix each message with its priority", + { "print-priority", N_("arg"), + N_("Prefix each message with its priority"), grecs_type_bool, GRECS_DFLT, &syslog_include_prio }, { NULL }, }; struct eventconf { @@ -204,13 +204,13 @@ eventconf_flush(grecs_locus_t *loc) if (!dwp) abort(); dwp->depth = pe->depth; for (hp = dwp->handler_list; hp; prev = hp, hp = hp->next) { if (strcmp(dwp->dirname, pe->path) == 0) { grecs_error(loc, 0, - "ignoring duplicate definition"); + _("ignoring duplicate definition")); return; } } hp = emalloc(sizeof(*hp)); hp->next = NULL; @@ -238,32 +238,34 @@ cb_watcher(enum grecs_callback_command cmd, grecs_node_t *node, void *varptr, void *cb_data) { int err = 0; switch (cmd) { case grecs_callback_section_begin: - eventconf_init(&node->locus); + eventconf_init(); break; case grecs_callback_section_end: if (!eventconf.pathlist) { - grecs_error(&node->locus, 0, "no paths configured"); + grecs_error(&node->locus, 0, _("no paths configured")); ++err; } if (!eventconf.command) { - grecs_error(&node->locus, 0, "no command configured"); + grecs_error(&node->locus, 0, + _("no command configured")); ++err; } if (evtnullp(&eventconf.eventmask)) evtsetall(&eventconf.eventmask); if (err == 0) eventconf_flush(&node->locus); else eventconf_free(); break; case grecs_callback_set_value: - grecs_error(&node->locus, 0, "invalid use of block statement"); + grecs_error(&node->locus, 0, + _("invalid use of block statement")); } return 0; } static struct pathent * pathent_alloc(char *s, long depth) @@ -302,13 +304,13 @@ cb_path(enum grecs_callback_command cmd, grecs_node_t *node, if (assert_grecs_value_type(&val->v.arg.v[1]->locus, val->v.arg.v[1], GRECS_TYPE_STRING)) return 1; if (strcmp(val->v.arg.v[1]->v.string, "recursive")) { grecs_error(&val->v.arg.v[1]->locus, 0, - "expected \"recursive\" or end of statement"); + _("expected \"recursive\" or end of statement")); return 1; } switch (val->v.arg.c) { case 2: depth = -1; break; @@ -317,19 +319,19 @@ cb_path(enum grecs_callback_command cmd, grecs_node_t *node, val->v.arg.v[2]->v.string, &val->v.arg.v[2]->locus)) return 1; break; default: grecs_error(&val->v.arg.v[3]->locus, 0, - "surplus argument"); + _("surplus argument")); return 1; } s = val->v.arg.v[0]->v.string; break; case GRECS_TYPE_LIST: - grecs_error(locus, 0, "unexpected list"); + grecs_error(locus, 0, _("unexpected list")); return 1; } pe = pathent_alloc(s, depth); if (*lpp) lp = *lpp; else { @@ -354,13 +356,13 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node, ASSERT_SCALAR(cmd, locus); switch (val->type) { case GRECS_TYPE_STRING: if (getevt(val->v.string, &m)) { grecs_error(&val->locus, 0, - "unrecognized event code"); + _("unrecognized event code")); return 1; } mask->gen_mask |= m.gen_mask; mask->sys_mask |= m.sys_mask; break; @@ -369,13 +371,13 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node, if (assert_grecs_value_type(&val->v.arg.v[i]->locus, val->v.arg.v[i], GRECS_TYPE_STRING)) return 1; if (getevt(val->v.arg.v[i]->v.string, &m)) { grecs_error(&val->v.arg.v[i]->locus, 0, - "unrecognized event code"); + _("unrecognized event code")); return 1; } mask->gen_mask |= m.gen_mask; mask->sys_mask |= m.sys_mask; } break; @@ -384,13 +386,13 @@ cb_eventlist(enum grecs_callback_command cmd, grecs_node_t *node, grecs_value_t *vp = ep->data; if (assert_grecs_value_type(&vp->locus, vp, GRECS_TYPE_STRING)) return 1; if (getevt(vp->v.string, &m)) { grecs_error(&vp->locus, 0, - "unrecognized event code"); + _("unrecognized event code")); return 1; } mask->gen_mask |= m.gen_mask; mask->sys_mask |= m.sys_mask; } break; @@ -466,34 +468,34 @@ cb_user(enum grecs_callback_command cmd, grecs_node_t *node, GRECS_TYPE_STRING)) return 1; if (val->v.arg.c > 2) { grecs_locus_t loc; loc.beg = val->v.arg.v[2]->locus.beg; loc.end = val->v.arg.v[val->v.arg.c - 1]->locus.end; - grecs_error(&loc, 0, "surplus arguments"); + grecs_error(&loc, 0, _("surplus arguments")); return 1; } uv = val->v.arg.v[0]; gv = val->v.arg.v[1]; break; case GRECS_TYPE_LIST: - grecs_error(locus, 0, "unexpected list"); + grecs_error(locus, 0, _("unexpected list")); return 1; } pw = getpwnam(uv->v.string); if (!pw) { - grecs_error(&uv->locus, 0, "no such user"); + grecs_error(&uv->locus, 0, _("no such user")); return 1; } if (gv) { gr = getgrnam(gv->v.string); if (!gr) { - grecs_error(&gv->locus, 0, "no such group"); + grecs_error(&gv->locus, 0, _("no such group")); return 1; } gid = gr->gr_gid; } else gid = pw->pw_gid; @@ -526,13 +528,13 @@ cb_option(enum grecs_callback_command cmd, grecs_node_t *node, eventconf.flags &= ~HF_NOWAIT; else if (strcmp(vp->v.string, "stdout") == 0) eventconf.flags |= HF_STDOUT; else if (strcmp(vp->v.string, "stderr") == 0) eventconf.flags |= HF_STDERR; else - grecs_error(&vp->locus, 0, "unrecognized flag"); + grecs_error(&vp->locus, 0, _("unrecognized flag")); } return 0; } static int cb_environ(enum grecs_callback_command cmd, grecs_node_t *node, @@ -604,13 +606,13 @@ file_name_pattern(struct grecs_list *lp, grecs_value_t *val) char *q, *p; pat->type = PAT_REGEX; p = strchr(arg+1, '/'); if (!p) { - grecs_error(&val->locus, 0, "Unterminated regexp"); + grecs_error(&val->locus, 0, _("unterminated regexp")); free(pat); return 1; } for (q = p + 1; *q; q++) { switch (*q) { case 'b': @@ -618,13 +620,13 @@ file_name_pattern(struct grecs_list *lp, grecs_value_t *val) break; case 'i': flags |= REG_ICASE; break; default: grecs_error(&val->locus, 0, - "Unrecognized flag: %c", *q); + _("unrecognized flag: %c"), *q); free(pat); return 1; } } *p = 0; @@ -686,71 +688,66 @@ cb_file_pattern(enum grecs_callback_command cmd, grecs_node_t *node, } return 0; } static struct grecs_keyword watcher_kw[] = { - { "path", NULL, "Pathname to watch", + { "path", NULL, N_("Pathname to watch"), grecs_type_string, GRECS_DFLT, &eventconf.pathlist, 0, cb_path }, - { "event", NULL, "Events to watch for", + { "event", NULL, N_("Events to watch for"), grecs_type_string, GRECS_LIST, &eventconf.eventmask, 0, cb_eventlist }, - { "file", "regexp", "Files to watch for", + { "file", N_("regexp"), N_("Files to watch for"), grecs_type_string, GRECS_LIST, &eventconf.fnames, 0, cb_file_pattern }, - { "command", NULL, "Command to execute on event", + { "command", NULL, N_("Command to execute on event"), grecs_type_string, GRECS_DFLT, &eventconf.command }, - { "user", "name", "Run command as this user", + { "user", N_("name"), N_("Run command as this user"), grecs_type_string, GRECS_DFLT, NULL, 0, cb_user }, - { "timeout", "seconds", "Timeout for the command", + { "timeout", N_("seconds"), N_("Timeout for the command"), grecs_type_uint, GRECS_DFLT, &eventconf.timeout }, - { "option", NULL, "List of additional options", + { "option", NULL, N_("List of additional options"), grecs_type_string, GRECS_LIST, NULL, 0, cb_option }, - { "environ", "<arg: string> <arg: string>...", "Modify environment", + { "environ", N_("<arg: string> <arg: string>..."), + N_("Modify environment"), grecs_type_string, GRECS_DFLT, NULL, 0, cb_environ }, { NULL } }; static struct grecs_keyword direvent_kw[] = { - { "user", NULL, "Run as this user", + { "user", NULL, N_("Run as this user"), grecs_type_string, GRECS_DFLT, &user }, - { "foreground", NULL, "Run in foreground", + { "foreground", NULL, N_("Run in foreground"), grecs_type_bool, GRECS_DFLT, &foreground }, - { "pidfile", "file", "Set pid file name", + { "pidfile", N_("file"), N_("Set pid file name"), grecs_type_string, GRECS_DFLT, &pidfile }, - { "syslog", NULL, "Configure syslog logging", + { "syslog", NULL, N_("Configure syslog logging"), grecs_type_section, GRECS_DFLT, NULL, 0, NULL, NULL, syslog_kw }, - { "debug", "level", "Set debug level", + { "debug", N_("level"), N_("Set debug level"), grecs_type_int, GRECS_DFLT, &debug_level }, - { "watcher", NULL, "Configure event watcher", + { "watcher", NULL, N_("Configure event watcher"), grecs_type_section, GRECS_DFLT, NULL, 0, cb_watcher, NULL, watcher_kw }, { NULL } }; void config_help() { static char docstring[] = - "Configuration file structure for direvent.\n" - "For more information, use `info direvent configuration'."; + N_("Configuration file structure for direvent.\n" + "For more information, use `info direvent configuration'."); grecs_print_docstring(docstring, 0, stdout); grecs_print_statement_array(direvent_kw, 1, 0, stdout); } void -config_init() -{ - grecs_log_to_stderr = 1; -} - -void config_finish(struct grecs_node *tree) { if (grecs_tree_process(tree, direvent_kw)) exit(1); } diff --git a/src/direvent.c b/src/direvent.c index 7cdd2c1..9dca000 100644 --- a/src/direvent.c +++ b/src/direvent.c @@ -135,13 +135,13 @@ debugprt(const char *fmt, ...) /* Memory allocation with error checking */ void * emalloc(size_t size) { void *p = malloc(size); if (!p) { - diag(LOG_CRIT, "not enough memory"); + diag(LOG_CRIT, _("not enough memory")); exit(2); } return p; } void * @@ -157,13 +157,13 @@ ecalloc(size_t nmemb, size_t size) void * erealloc(void *ptr, size_t size) { void *p = realloc(ptr, size); if (!p) { - diag(LOG_CRIT, "not enough memory"); + diag(LOG_CRIT, _("not enough memory")); exit(2); } return p; } char * @@ -265,13 +265,13 @@ signal_setup(void (*sf) (int)) void storepid(const char *pidfile) { FILE *fp = fopen(pidfile, "w"); if (!fp) { - diag(LOG_ERR, "cannot open pidfile %s for writing: %s", + diag(LOG_ERR, _("cannot open pidfile %s for writing: %s"), pidfile, strerror(errno)); } else { fprintf(fp, "%lu\n", (unsigned long) getpid()); fclose(fp); } } @@ -293,13 +293,13 @@ get_user_groups(uid_t uid, size_t *pgidc, gid_t **pgidv) gid_t *gidv = NULL; struct passwd *pw; struct group *gr; pw = getpwuid(uid); if (!pw) { - diag(LOG_ERR, 0, "no used with UID %lu", + diag(LOG_ERR, 0, _("no used with UID %lu"), (unsigned long)uid); exit(2); } n = 32; gidv = ecalloc(n, sizeof(gidv[0])); @@ -420,13 +420,13 @@ self_test() exit(2); } pid = fork(); if (pid == (pid_t)-1) { diag(LOG_CRIT, - "cannot run `%s': fork failed: %s", + _("cannot run `%s': fork failed: %s"), self_test_prog, strerror(errno)); exit(2); } if (pid != 0) { self_test_pid = pid; @@ -470,13 +470,13 @@ main(int argc, char **argv) argc -= i; argv += i; switch (argc) { default: - diag(LOG_CRIT, "too many arguments"); + diag(LOG_CRIT, _("too many arguments")); exit(1); case 1: conffile = argv[0]; break; case 0: break; @@ -516,13 +516,13 @@ main(int argc, char **argv) diag(LOG_CRIT, "daemon: %s", strerror(errno)); exit(1); } log_to_stderr = -1; } - diag(LOG_INFO, "%s %s started", program_name, VERSION); + diag(LOG_INFO, _("%s %s started"), program_name, VERSION); /* Write pidfile */ if (pidfile) storepid(pidfile); /* Relinquish superuser privileges */ @@ -537,13 +537,13 @@ main(int argc, char **argv) /* Main loop */ while (!stop && sysev_select() == 0) { process_timeouts(); process_cleanup(0); } - diag(LOG_INFO, "%s %s stopped", program_name, VERSION); + diag(LOG_INFO, _("%s %s stopped"), program_name, VERSION); if (pidfile) unlink(pidfile); return exit_code; } diff --git a/src/direvent.h b/src/direvent.h index 33fa768..069d3d8 100644 --- a/src/direvent.h +++ b/src/direvent.h @@ -22,12 +22,17 @@ #include <errno.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <regex.h> +#include "gettext.h" + +#define _(s) gettext(s) +#define N_(s) s + /* Generic (system-independent) event codes */ #define GENEV_CREATE 0x01 #define GENEV_WRITE 0x02 #define GENEV_ATTRIB 0x04 #define GENEV_DELETE 0x08 @@ -186,13 +191,16 @@ unsigned hash_string(const char *name, unsigned long hashsize); struct pathent { long depth; size_t len; char path[1]; }; - + +void config_help(void); +struct grecs_node; +void config_finish(struct grecs_node *tree); void config_parse(const char *file); int get_facility(const char *arg); int get_priority(const char *arg); void setup_watchers(void); @@ -204,12 +212,15 @@ void dirwatcher_destroy(struct dirwatcher *dwp); int watch_pathname(struct dirwatcher *parent, const char *dirname, int isdir, int notify); char *split_pathname(struct dirwatcher *dp, char **dirname); void unsplit_pathname(struct dirwatcher *dp); void ev_log(int flags, struct dirwatcher *dp); +void deliver_ev_create(struct dirwatcher *dp, const char *name); +int subwatcher_create(struct dirwatcher *parent, const char *dirname, + int isdir, int notify); struct process *process_lookup(pid_t pid); void process_cleanup(int expect_term); void process_timeouts(void); int run_handler(struct handler *hp, event_mask *event, const char *dir, const char *file); diff --git a/src/environ.c b/src/environ.c index 5fbd0ac..f0fcce7 100644 --- a/src/environ.c +++ b/src/environ.c @@ -13,18 +13,19 @@ You should have received a copy of the GNU General Public License along with direvent. If not, see <http://www.gnu.org/licenses/>. */ #include "direvent.h" #include "wordsplit.h" +#include <ctype.h> extern char **environ; /* Environment */ #define DEBUG_ENVIRON(l,env) do { \ if (debug_level >= (l)) { \ - diag(LOG_DEBUG, "environment: "); \ + diag(LOG_DEBUG, _("environment: ")); \ for (i = 0; (env)[i]; i++) \ diag(LOG_DEBUG, "%s ", (env)[i]); \ diag(LOG_DEBUG, "\n"); \ } \ } while (0) diff --git a/src/gettext.h b |