9 changed files with 1132 additions and 0 deletions
-
BINlam/graphics/lock.gif
-
68lam/lib/example.php
-
44lam/po/Makefile
-
191lam/po/README
-
45lam/po/extract.pl
-
716lam/po/shtool
-
25lam/po/wintokoi.pl
-
4lam/po/xgettext.sh
-
39lam/templates/example.inc
After Width: 18 | Height: 18 | Size: 129 B |
@ -0,0 +1,68 @@ |
|||
<?php |
|||
// $Horde: nmslib/base.php,v 1.6 2002/06/19 02:31:26 chuck Exp $
|
|||
// modified 2002/07/13 Tilo Lutz
|
|||
/* |
|||
* NMS base inclusion file. |
|||
* |
|||
* This file brings in all of the dependencies that every NMS script |
|||
* will need, and sets up objects that all scripts use. |
|||
*/ |
|||
|
|||
// Find the base file path of Horde
|
|||
@define('HORDE_BASE', dirname(__FILE__) . '/../..'); |
|||
|
|||
// Find the base file path of VACATION
|
|||
@define('NMS_BASE', dirname(__FILE__) . '/..'); |
|||
|
|||
// Registry
|
|||
require_once HORDE_BASE . '/lib/Registry.php'; |
|||
$registry = &Registry::singleton(); |
|||
$registry->pushApp('nms'); |
|||
$conf = &$GLOBALS['conf']; |
|||
@define('NMS_TEMPLATES', $registry->getParam('templates')); |
|||
|
|||
// Horde base libraries
|
|||
require_once HORDE_BASE . '/lib/Horde.php'; |
|||
require_once HORDE_BASE . '/lib/Auth.php'; |
|||
require_once HORDE_BASE . '/lib/Secret.php'; |
|||
require_once HORDE_BASE . '/lib/Text.php'; |
|||
require_once HORDE_BASE . '/lib/Help.php'; |
|||
|
|||
// Browser detection library
|
|||
require_once HORDE_BASE . '/lib/Browser.php'; |
|||
$browser = new Browser(); |
|||
if (isset($session_control)) { |
|||
switch ($session_control) { |
|||
case 'netscape': |
|||
if ($browser->isBrowser('mozilla')) { |
|||
session_cache_limiter('private, must-revalidate'); |
|||
} |
|||
break; |
|||
|
|||
case 'cache_ssl_downloads': |
|||
header('Vary: User-Agent'); |
|||
if ($browser->hasQuirk('cache_ssl_downloads')) { |
|||
session_cache_limiter('private, must-revalidate'); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
// Notification system
|
|||
require_once HORDE_BASE . '/lib/Notification.php'; |
|||
$notification = &Notification::singleton(); |
|||
$notification->attach('status'); |
|||
|
|||
// NMS base library
|
|||
#require_once NMS_BASE . '/lib/version.php';
|
|||
define('NMS_NAME', 'Horde nms module'); |
|||
|
|||
// Don't allow access unless there is a Horde login
|
|||
// NOTE: We explicitely do not honor the guests flag here!!!
|
|||
if (!Auth::getAuth()) { |
|||
header('Location: ' . Horde::url($registry->getWebRoot("horde") . '/login.php?url=' . urlencode(Horde::selfUrl()), true)); |
|||
echo "\n"; |
|||
exit; |
|||
} |
|||
|
|||
?>
|
@ -0,0 +1,44 @@ |
|||
# Lam .mo files makefile
|
|||
#
|
|||
# $Lam: lam/po/Makefile,v 1.5 2002/04/16 12:38:24 jan Exp $
|
|||
# This file was copyied from the horde-project, www.horde.org
|
|||
#
|
|||
|
|||
APPLICATION = lam |
|||
MSGFMT = msgfmt --statistics -c -v -o |
|||
MSGFMTSOL = msgfmt -v -o |
|||
|
|||
all: install |
|||
|
|||
install: *.po |
|||
@echo "Checking for os ... ${OSTYPE}"; \
|
|||
if test "${OSTYPE}" = "solaris"; then \
|
|||
echo "You'll probably get some warnings on Solaris. This is normal."; \
|
|||
fi; \
|
|||
for LOCALE in `ls *.po | sed 's/\.[^.]*$$//g'`; do \
|
|||
if test $${LOCALE}.po = "messages.po"; then \
|
|||
continue; \
|
|||
fi; \
|
|||
echo "Compiling locale $${LOCALE}:"; \
|
|||
if ./shtool mkdir -p ../locale/$${LOCALE}/LC_MESSAGES; then \
|
|||
if test "${OSTYPE}" = "solaris"; then \
|
|||
if ${MSGFMTSOL} ../locale/$${LOCALE}/LC_MESSAGES/${APPLICATION}.mo $${LOCALE}.po; then \
|
|||
echo " ... done"; \
|
|||
echo; \
|
|||
else \
|
|||
echo " ... FAILED"; \
|
|||
echo; \
|
|||
fi \
|
|||
else \
|
|||
if ${MSGFMT} ../locale/$${LOCALE}/LC_MESSAGES/${APPLICATION}.mo $${LOCALE}.po; then \
|
|||
echo " ... done"; \
|
|||
echo; \
|
|||
else \
|
|||
echo " ... FAILED"; \
|
|||
echo; \
|
|||
fi \
|
|||
fi; \
|
|||
else \
|
|||
echo "Could not create locale directory for $${LOCALE}."; \
|
|||
fi \
|
|||
done; |
@ -0,0 +1,191 @@ |
|||
$Horde: horde/po/README,v 1.11 2002/03/24 13:35:14 jan Exp $ |
|||
|
|||
Horde Translation Guide |
|||
Copyright 2000-2002 Joris Braakman <jbraakman@yahoo.com> |
|||
Copyright 2001-2002 Chuck Hagenbuch <chuck@horde.org> |
|||
Copyright 2001-2002 Jan Schneider <jan@horde.org> |
|||
|
|||
Contents |
|||
======== |
|||
- GNU gettext, PHP and Horde |
|||
- Starting a new translation |
|||
- Example messages header |
|||
- Updating a existing translation |
|||
- Debugging |
|||
- Solaris |
|||
- Changing the English standard texts |
|||
|
|||
|
|||
GNU gettext, PHP and Horde |
|||
-------------------------- |
|||
|
|||
Horde uses GNU gettext for internationalization (i18n) and localization |
|||
(l10n). The manual at http://www.gnu.org/manual/gettext/index.html is |
|||
biased against C and using Emacs. This is more for Horde. |
|||
|
|||
There is a good explanation for PHP and gettext at: |
|||
http://www.faqts.com/knowledge-base/view.phtml/aid/2953/fid/422 |
|||
|
|||
People seem to like learning from examples better, so I have used |
|||
dutch (nl_NL) as an example everywhere. |
|||
|
|||
|
|||
Starting a new translation |
|||
-------------------------- |
|||
|
|||
- run xgettext.sh (in this directory - horde/po/), this generates a |
|||
messages.po file. |
|||
- rename it to the language you are translating to, e.g. nl_NL.po |
|||
- adjust the header of nl_NL.po, then remove the #, fuzzy line. |
|||
Emacs has support for .po files, but I used vi |
|||
- translate, the time consuming part. |
|||
- convert the nl_NL.po to horde.mo and put the file in place: |
|||
$ make install |
|||
Compiling locale nl_NL: |
|||
261 translated messages, 21 untranslated messages. |
|||
... done |
|||
|
|||
- modify the horde/config/lang.php to use nl_NL as the default language, if you |
|||
wish. |
|||
- Make sure your language exists in the horde/config/lang.php file. Also, if |
|||
the translation uses a character set that isn't ascii, make sure the |
|||
appropriate charset is defined in $nls['charsets']. You should also define |
|||
an alias for the language because some browsers only send a two letter code |
|||
in their Accept-Charset header. |
|||
|
|||
And then it works. |
|||
|
|||
|
|||
Example messages header |
|||
----------------------- |
|||
# Dutch translation for Horde. |
|||
# Joris Braakman <jbraakman@yahoo.com>, 2000. |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Horde 2.3\n" |
|||
"POT-Creation-Date: 2000-08-14 10:30+0200\n" |
|||
"PO-Revision-Date: 2000-08-14 17:17+02:00\n" |
|||
"Last-Translator: Joris Braakman <jbraakman@yahoo.com>\n" |
|||
"Language-Team: Dutch <dev@lists.horde.org>\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=ISO-8859-1\n" |
|||
"Content-Transfer-Encoding: 8-bit\n" |
|||
|
|||
|
|||
Updating a existing translation |
|||
------------------------------- |
|||
As soon as you check out a new version you have to check the translations |
|||
again, messages might have been changed after all. If you don't, you |
|||
can get strange effects. Information is cached every where so as a no |
|||
brain solutions I sometimes also restart the webbrowser and webserver |
|||
to make sure everything is fresh. msgmerge will mark translations that |
|||
have changed a bit to fuzzy. |
|||
|
|||
If you want to update an existing translation and contribute it to the Horde |
|||
project you should first contact the last translator to see if he is still |
|||
working on it, doesn't have time to further maintain it or is even unreachable. |
|||
|
|||
- run xgettext.sh again, this generates a messages.po file. |
|||
- merge it with the old .po file: |
|||
$ msgmerge nl_NL.po messages.po > nl_NL-new.po |
|||
|
|||
- translate/update the strings that are new or have become fuzzy. |
|||
- delete the '#, fuzzy' lines. |
|||
- move the nl_NL-new.po to nl_NL.po |
|||
- put the new translations in effect |
|||
$ make install |
|||
Compiling locale nl_NL: |
|||
261 translated messages, 21 untranslated messages. |
|||
... done |
|||
|
|||
|
|||
Debugging |
|||
--------- |
|||
Is this locale (nl_NL) installed at all? |
|||
$ locale -a |
|||
should list all locales installed on your system. |
|||
|
|||
On Debian not all locales may be enabled by default. Edit /etc/locale.gen and |
|||
run locale-gen if you changed the list of enabled locales. |
|||
|
|||
Do you have any .mo files? Usually in /usr/share/locale/ |
|||
e.g. /usr/share/locale/nl/LC_MESSAGES/tar.mo |
|||
|
|||
Does gettext even work? |
|||
Get a string to translate, |
|||
$ strings /bin/tar | grep Memory |
|||
Memory exhausted |
|||
$ (LANG=nl_NL; LANGUAGE=nl_NL; LC_MESSAGES=nl_NL; gettext tar "Memory exhausted" ) |
|||
Geheugen uitgeput |
|||
|
|||
Does the local Horde file work? |
|||
Assuming that you have put the translated Horde file in |
|||
/data/www/horde/locale/nl_NL/LC_MESSAGES/horde.mo |
|||
$ export TEXTDOMAINDIR=/data/www/horde/locale |
|||
$ (LANG=nl_NL; LANGUAGE=nl_NL; LC_MESSAGES=nl_NL; gettext horde "Message" ) |
|||
Bericht |
|||
|
|||
Create a file in the horde directory, langtest.php: |
|||
<?php |
|||
setlocale(LC_MESSAGES, 'nl_NL'); |
|||
putenv('LANG=nl_NL'); |
|||
putenv('LANGUAGE=nl_NL'); |
|||
// use the tar test. |
|||
echo dgettext('tar', 'Memory exhausted'); |
|||
echo '<br />'; |
|||
|
|||
// Specify location of translation tables |
|||
bindtextdomain('horde', './locale'); |
|||
|
|||
// Choose domain |
|||
textdomain('horde'); |
|||
|
|||
// Print the already tested message |
|||
echo _("Message"); |
|||
echo '<br />'; |
|||
|
|||
// this should print the same. |
|||
echo dgettext('horde', 'Message'); |
|||
|
|||
?> |
|||
|
|||
OUTPUT web browser: |
|||
Geheugen uitgeput |
|||
Bericht |
|||
Bericht |
|||
|
|||
|
|||
Solaris |
|||
------- |
|||
Since the .mo files are binary, they are platform specific. You |
|||
have to rerun make in all po directories. |
|||
|
|||
You have not installed the Supplementary Partial Locales (SUNWploc1) if |
|||
you get: |
|||
$ LANG=nl_NL |
|||
couldn't set locale correctly |
|||
|
|||
This is what it should say. |
|||
$ pkginfo | grep ploc |
|||
system SUNWploc Partial Locales |
|||
system SUNWploc1 Supplementary Partial Locales |
|||
|
|||
The stuff is installed in /usr/lib/locale |
|||
$ ls /usr/lib/locale/nl |
|||
LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME nl.so.1 |
|||
|
|||
We assume that the Solaris gettext implementation is installed when we compile |
|||
the translations. Thus the make process will fail if the installed gettext is |
|||
from GNU. If anyone knows how to determine if the installed gettext is from |
|||
Solaris or GNU on Solaris systems, please send us a note. |
|||
|
|||
|
|||
Changing the English standard texts |
|||
----------------------------------- |
|||
You can also use gettext to change some of the English texts to your own taste. |
|||
|
|||
- Create a message.po file as described in "Starting a new translation" |
|||
- Edit the msgstr entry of the strings you want to change. You can leave all |
|||
other msgstr entries empty. |
|||
- Run "make install" |
@ -0,0 +1,45 @@ |
|||
#!/usr/bin/perl |
|||
# |
|||
# $Horde: horde/po/extract.pl,v 1.6 2001/09/14 20:03:33 jon Exp $ |
|||
# |
|||
# Perl script to extract strings from all the files and print |
|||
# to stdout for use with xgettext. |
|||
|
|||
use FileHandle; |
|||
use File::Basename; |
|||
use File::Find; |
|||
use Cwd; |
|||
|
|||
use strict; |
|||
use vars qw($exts @dirs $dirs %strings); |
|||
|
|||
chdir(dirname($0)); |
|||
|
|||
@dirs = qw($ /templates /lib /config /admin /util); |
|||
|
|||
$exts = '(\.php$|\.inc$|\.dist$)'; |
|||
$dirs = '^' . cwd() . '/..(' . join('|', @dirs) . ')'; |
|||
|
|||
find(\&extract, cwd() . '/..'); |
|||
print join("\n", sort keys %strings), "\n"; |
|||
|
|||
sub extract |
|||
{ |
|||
my $file = $File::Find::name; |
|||
my $dir = $File::Find::dir; |
|||
my $fd = new FileHandle; |
|||
|
|||
if ($dir !~ /$dirs/s) { |
|||
$File::Find::prune = 1; |
|||
return; |
|||
} |
|||
|
|||
if ($file =~ /$exts/) { |
|||
open($fd, basename($file)); |
|||
my $data = join('', <$fd>); |
|||
while ($data =~ s/_\("(.*?)"\)//s) { |
|||
$strings{"_(\"$1\")"}++; |
|||
} |
|||
close($fd); |
|||
} |
|||
} |
@ -0,0 +1,716 @@ |
|||
#!/bin/sh |
|||
## |
|||
## GNU shtool -- The GNU Portable Shell Tool |
|||
## Copyright (c) 1994-2000 Ralf S. Engelschall <rse@engelschall.com> |
|||
## |
|||
## See http://www.gnu.org/software/shtool/ for more information. |
|||
## See ftp://ftp.gnu.org/gnu/shtool/ for latest version. |
|||
## |
|||
## Version 1.4.9 (16-Apr-2000) |
|||
## Ingredients: 3/17 available modules |
|||
## |
|||
|
|||
## |
|||
## This program is free software; you can redistribute it and/or modify |
|||
## it under the terms of the GNU General Public License as published by |
|||
## the Free Software Foundation; either version 2 of the License, or |
|||
## (at your option) any later version. |
|||
## |
|||
## This program is distributed in the hope that it will be useful, |
|||
## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
## General Public License for more details. |
|||
## |
|||
## You should have received a copy of the GNU General Public License |
|||
## along with this program; if not, write to the Free Software |
|||
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|||
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>. |
|||
## |
|||
## Notice: Given that you include this file verbatim into your own |
|||
## source tree, you are justified in saying that it remains separate |
|||
## from your package, and that this way you are simply just using GNU |
|||
## shtool. So, in this situation, there is no requirement that your |
|||
## package itself is licensed under the GNU General Public License in |
|||
## order to take advantage of GNU shtool. |
|||
## |
|||
|
|||
## |
|||
## Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]] |
|||
## |
|||
## Available commands: |
|||
## echo Print string with optional construct expansion |
|||
## install Install a program, script or datafile |
|||
## mkdir Make one or more directories |
|||
## |
|||
## Not available commands (because module was not built-in): |
|||
## mdate Pretty-print modification time of a file or dir |
|||
## table Pretty-print a field-separated list as a table |
|||
## prop Display progress with a running propeller |
|||
## move Move files with simultaneous substitution |
|||
## mkln Make link with calculation of relative paths |
|||
## mkshadow Make a shadow tree through symbolic links |
|||
## fixperm Fix file permissions inside a source tree |
|||
## tarball Roll distribution tarballs |
|||
## guessos Simple operating system guesser |
|||
## arx Extended archive command |
|||
## slo Separate linker options by library class |
|||
## scpp Sharing C Pre-Processor |
|||
## version Generate and maintain a version information file |
|||
## path Deal with program paths |
|||
## |
|||
|
|||
if [ $# -eq 0 ]; then |
|||
echo "$0:Error: invalid command line" 1>&2 |
|||
echo "$0:Hint: run \`$0 -h' for usage" 1>&2 |
|||
exit 1 |
|||
fi |
|||
if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then |
|||
echo "This is GNU shtool, version 1.4.9 (16-Apr-2000)" |
|||
echo "Copyright (c) 1994-2000 Ralf S. Engelschall <rse@engelschall.com>" |
|||
echo "Report bugs to <bug-shtool@gnu.org>" |
|||
echo '' |
|||
echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]" |
|||
echo '' |
|||
echo 'Available global <options>:' |
|||
echo ' -v, --version display shtool version information' |
|||
echo ' -h, --help display shtool usage help page (this one)' |
|||
echo ' -d, --debug display shell trace information' |
|||
echo '' |
|||
echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:' |
|||
echo ' echo [-n] [-e] [<str> ...]' |
|||
echo ' install [-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>]' |
|||
echo ' [-e<ext>] <file> <path>' |
|||
echo ' mkdir [-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]' |
|||
echo '' |
|||
echo 'Not available <cmd-name> (because module was not built-in):' |
|||
echo ' mdate [-n] [-z] [-s] [-d] [-f<str>] [-o<spec>] <path>' |
|||
echo ' table [-F<sep>] [-w<width>] [-c<cols>] [-s<strip>] <str><sep><str>...' |
|||
echo ' prop [-p<str>]' |
|||
echo ' move [-v] [-t] [-e] [-p] <src-file> <dst-file>' |
|||
echo ' mkln [-t] [-f] [-s] <src-path> [<src-path> ...] <dst-path>' |
|||
echo ' mkshadow [-v] [-t] [-a] <src-dir> <dst-dir>' |
|||
echo ' fixperm [-v] [-t] <path> [<path> ...]' |
|||
echo ' tarball [-t] [-v] [-o <tarball>] [-c <prog>] [-d <dir>] [-u' |
|||
echo ' <user>] [-g <group>] [-e <pattern>] <path> [<path> ...]' |
|||
echo ' guessos ' |
|||
echo ' arx [-t] [-C<cmd>] <op> <archive> [<file> ...]' |
|||
echo ' slo [-p<str>] -- -L<dir> -l<lib> [-L<dir> -l<lib> ...]' |
|||
echo ' scpp [-v] [-p] [-f<filter>] [-o<ofile>] [-t<tfile>] [-M<mark>]' |
|||
echo ' [-D<dname>] [-C<cname>] <file> [<file> ...]' |
|||
echo ' version [-l<lang>] [-n<name>] [-p<prefix>] [-s<version>] [-i<knob>]' |
|||
echo ' [-d<type>] <file>' |
|||
echo ' path [-s] [-r] [-d] [-b] [-m] [-p<path>] <str> [<str> ...]' |
|||
echo '' |
|||
exit 0 |
|||
fi |
|||
if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then |
|||
echo "GNU shtool 1.4.9 (16-Apr-2000)" |
|||
exit 0 |
|||
fi |
|||
if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then |
|||
shift |
|||
set -x |
|||
fi |
|||
name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'` |
|||
case "$name" in |
|||
echo|install|mkdir ) |
|||
# implicit tool command selection |
|||
tool="$name" |
|||
;; |
|||
* ) |
|||
# explicit tool command selection |
|||
tool="$1" |
|||
shift |
|||
;; |
|||
esac |
|||
arg_spec="" |
|||
opt_spec="" |
|||
gen_tmpfile=no |
|||
|
|||
## |
|||
## DISPATCH INTO SCRIPT PROLOG |
|||
## |
|||
|
|||
case $tool in |
|||
echo ) |
|||
str_tool="echo" |
|||
str_usage="[-n] [-e] [<str> ...]" |
|||
arg_spec="0+" |
|||
opt_spec="n.e." |
|||
opt_n=no |
|||
opt_e=no |
|||
;; |
|||
install ) |
|||
str_tool="install" |
|||
str_usage="[-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>] [-e<ext>] <file> <path>" |
|||
arg_spec="2=" |
|||
opt_spec="v.t.c.C.s.m:o:g:e:" |
|||
opt_v=no |
|||
opt_t=no |
|||
opt_c=no |
|||
opt_C=no |
|||
opt_s=no |
|||
opt_m="" |
|||
opt_o="" |
|||
opt_g="" |
|||
opt_e="" |
|||
;; |
|||
mkdir ) |
|||
str_tool="mkdir" |
|||
str_usage="[-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]" |
|||
arg_spec="1+" |
|||
opt_spec="t.f.p.m:" |
|||
opt_t=no |
|||
opt_f=no |
|||
opt_p=no |
|||
opt_m="" |
|||
;; |
|||
-* ) |
|||
echo "$0:Error: unknown option \`$tool'" 2>&1 |
|||
echo "$0:Hint: run \`$0 -h' for usage" 2>&1 |
|||
exit 1 |
|||
;; |
|||
* ) |
|||
echo "$0:Error: unknown command \`$tool'" 2>&1 |
|||
echo "$0:Hint: run \`$0 -h' for usage" 2>&1 |
|||
exit 1 |
|||
;; |
|||
esac |
|||
|
|||
## |
|||
## COMMON UTILITY CODE |
|||
## |
|||
|
|||
# determine name of tool |
|||
if [ ".$tool" != . ]; then |
|||
# used inside shtool script |
|||
toolcmd="$0 $tool" |
|||
toolcmdhelp="shtool $tool" |
|||
msgprefix="shtool:$tool" |
|||
else |
|||
# used as standalone script |
|||
toolcmd="$0" |
|||
toolcmdhelp="sh $0" |
|||
msgprefix="$str_tool" |
|||
fi |
|||
|
|||
# parse argument specification string |
|||
eval `echo $arg_spec |\ |
|||
sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` |
|||
|
|||
# parse option specification string |
|||
eval `echo h.$opt_spec |\ |
|||
sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` |
|||
|
|||
# interate over argument line |
|||
opt_PREV='' |
|||
while [ $# -gt 0 ]; do |
|||
# special option stops processing |
|||
if [ ".$1" = ".--" ]; then |
|||
shift |
|||
break |
|||
fi |
|||
|
|||
# determine option and argument |
|||
opt_ARG_OK=no |
|||
if [ ".$opt_PREV" != . ]; then |
|||
# merge previous seen option with argument |
|||
opt_OPT="$opt_PREV" |
|||
opt_ARG="$1" |
|||
opt_ARG_OK=yes |
|||
opt_PREV='' |
|||
else |
|||
# split argument into option and argument |
|||
case "$1" in |
|||
-[a-zA-Z0-9]*) |
|||
eval `echo "x$1" |\ |
|||
sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ |
|||
-e 's/";\(.*\)$/"; opt_ARG="\1"/'` |
|||
;; |
|||
-[a-zA-Z0-9]) |
|||
opt_OPT=`echo "x$1" | cut -c3-` |
|||
opt_ARG='' |
|||
;; |
|||
*) |
|||
break |
|||
;; |
|||
esac |
|||
fi |
|||
|
|||
# eat up option |
|||
shift |
|||
|
|||
# determine whether option needs an argument |
|||
eval "opt_MODE=\$opt_MODE_${opt_OPT}" |
|||
if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then |
|||
if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then |
|||
opt_PREV="$opt_OPT" |
|||
continue |
|||
fi |
|||
fi |
|||
|
|||
# process option |
|||
case $opt_MODE in |
|||
'.' ) |
|||
# boolean option |
|||
eval "opt_${opt_OPT}=yes" |
|||
;; |
|||
':' ) |
|||
# option with argument (multiple occurances override) |
|||
eval "opt_${opt_OPT}=\"\$opt_ARG\"" |
|||
;; |
|||
'+' ) |
|||
# option with argument (multiple occurances append) |
|||
eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" |
|||
;; |
|||
* ) |
|||
echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 |
|||
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 |
|||
exit 1 |
|||
;; |
|||
esac |
|||
done |
|||
if [ ".$opt_PREV" != . ]; then |
|||
echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 |
|||
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 |
|||
exit 1 |
|||
fi |
|||
|
|||
# process help option |
|||
if [ ".$opt_h" = .yes ]; then |
|||
echo "Usage: $toolcmdhelp $str_usage" |
|||
exit 0 |
|||
fi |
|||
|
|||
# complain about incorrect number of arguments |
|||
case $arg_MODE in |
|||
'=' ) |
|||
if [ $# -ne $arg_NUMS ]; then |
|||
echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 |
|||
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 |
|||
exit 1 |
|||
fi |
|||
;; |
|||
'+' ) |
|||
if [ $# -lt $arg_NUMS ]; then |
|||
echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 |
|||
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 |
|||
exit 1 |
|||
fi |
|||
;; |
|||
esac |
|||
|
|||
# establish a temporary file on request |
|||
if [ ".$gen_tmpfile" = .yes ]; then |
|||
if [ ".$TMPDIR" != . ]; then |
|||
tmpdir="$TMPDIR" |
|||
elif [ ".$TEMPDIR" != . ]; then |
|||
tmpdir="$TEMPDIR" |
|||
else |
|||
tmpdir="/tmp" |
|||
fi |
|||
tmpfile="$tmpdir/.shtool.$$" |
|||
rm -f $tmpfile >/dev/null 2>&1 |
|||
touch $tmpfile |
|||
fi |
|||
|
|||
## |
|||
## DISPATCH INTO SCRIPT BODY |
|||
## |
|||
|
|||
case $tool in |
|||
|
|||
echo ) |
|||
## |
|||
## echo -- Print string with optional construct expansion |
|||
## Copyright (c) 1998-2000 Ralf S. Engelschall <rse@engelschall.com> |
|||
## Originally written for WML as buildinfo |
|||
## |
|||
|
|||
text="$*" |
|||
|
|||
# check for broken escape sequence expansion |
|||
seo='' |
|||
bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'` |
|||
if [ ".$bytes" != .3 ]; then |
|||
bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'` |
|||
if [ ".$bytes" = .3 ]; then |
|||
seo='-E' |
|||
fi |
|||
fi |
|||
|
|||
# check for existing -n option (to suppress newline) |
|||
minusn='' |
|||
bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'` |
|||
if [ ".$bytes" = .3 ]; then |
|||
minusn='-n' |
|||
fi |
|||
|
|||
# determine terminal bold sequence |
|||
term_bold='' |
|||
term_norm='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then |
|||
case $TERM in |
|||
# for the most important terminal types we directly know the sequences |
|||
xterm|xterm*|vt220|vt220*) |
|||
term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null` |
|||
term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null` |
|||
;; |
|||
vt100|vt100*) |
|||
term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null` |
|||
term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null` |
|||
;; |
|||
# for all others, we try to use a possibly existing `tput' or `tcout' utility |
|||
* ) |
|||
paths=`echo $PATH | sed -e 's/:/ /g'` |
|||
for tool in tput tcout; do |
|||
for dir in $paths; do |
|||
if [ -r "$dir/$tool" ]; then |
|||
for seq in bold md smso; do # 'smso' is last |
|||
bold="`$dir/$tool $seq 2>/dev/null`" |
|||
if [ ".$bold" != . ]; then |
|||
term_bold="$bold" |
|||
break |
|||
fi |
|||
done |
|||
if [ ".$term_bold" != . ]; then |
|||
for seq in sgr0 me rmso reset; do # 'reset' is last |
|||
norm="`$dir/$tool $seq 2>/dev/null`" |
|||
if [ ".$norm" != . ]; then |
|||
term_norm="$norm" |
|||
break |
|||
fi |
|||
done |
|||
fi |
|||
break |
|||
fi |
|||
done |
|||
if [ ".$term_bold" != . -a ".$term_norm" != . ]; then |
|||
break; |
|||
fi |
|||
done |
|||
;; |
|||
esac |
|||
if [ ".$term_bold" = . -o ".$term_norm" = . ]; then |
|||
echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2 |
|||
fi |
|||
fi |
|||
|
|||
# determine user name |
|||
username='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uU]'`" != . ]; then |
|||
username="$LOGNAME" |
|||
if [ ".$username" = . ]; then |
|||
username="$USER" |
|||
if [ ".$username" = . ]; then |
|||
username="`(whoami) 2>/dev/null |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
if [ ".$username" = . ]; then |
|||
username="`(who am i) 2>/dev/null |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
if [ ".$username" = . ]; then |
|||
username='unknown' |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
# determine user id |
|||
userid='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then |
|||
userid="`(id -u) 2>/dev/null`" |
|||
if [ ".$userid" = . ]; then |
|||
str="`(id) 2>/dev/null`" |
|||
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then |
|||
userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*//'` |
|||
fi |
|||
if [ ".$userid" = . ]; then |
|||
userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \ |
|||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` |
|||
if [ ".$userid" = . ]; then |
|||
userid=`(ypcat passwd) 2>/dev/null | |
|||
egrep "^${username}:" | \ |
|||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` |
|||
if [ ".$userid" = . ]; then |
|||
userid='?' |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
# determine host name |
|||
hostname='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then |
|||
hostname="`(uname -n) 2>/dev/null |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
if [ ".$hostname" = . ]; then |
|||
hostname="`(hostname) 2>/dev/null |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
if [ ".$hostname" = . ]; then |
|||
hostname='unknown' |
|||
fi |
|||
fi |
|||
case $hostname in |
|||
*.* ) |
|||
domainname=".`echo $hostname | cut -d. -f2-`" |
|||
hostname="`echo $hostname | cut -d. -f1`" |
|||
;; |
|||
esac |
|||
fi |
|||
|
|||
# determine domain name |
|||
domainname='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then |
|||
if [ ".$domainname" = . ]; then |
|||
if [ -f /etc/resolv.conf ]; then |
|||
domainname="`egrep '^[ ]*domain' /etc/resolv.conf | head -1 |\ |
|||
sed -e 's/.*domain//' \ |
|||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ |
|||
-e 's/^\.//' -e 's/^/./' |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
if [ ".$domainname" = . ]; then |
|||
domainname="`egrep '^[ ]*search' /etc/resolv.conf | head -1 |\ |
|||
sed -e 's/.*search//' \ |
|||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ |
|||
-e 's/ .*//' -e 's/ .*//' \ |
|||
-e 's/^\.//' -e 's/^/./' |\ |
|||
awk '{ printf("%s", $1); }'`" |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
# determine current time |
|||
time_day='' |
|||
time_month='' |
|||
time_year='' |
|||
time_monthname='' |
|||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then |
|||
time_day=`date '+%d'` |
|||
time_month=`date '+%m'` |
|||
time_year=`date '+%Y' 2>/dev/null` |
|||
if [ ".$time_year" = . ]; then |
|||
time_year=`date '+%y'` |
|||
case $time_year in |
|||
[5-9][0-9]) time_year="19$time_year" ;; |
|||
[0-4][0-9]) time_year="20$time_year" ;; |
|||
esac |
|||
fi |
|||
case $time_month in |
|||
1|01) time_monthname='Jan' ;; |
|||
2|02) time_monthname='Feb' ;; |
|||
3|03) time_monthname='Mar' ;; |
|||
4|04) time_monthname='Apr' ;; |
|||
5|05) time_monthname='May' ;; |
|||
6|06) time_monthname='Jun' ;; |
|||
7|07) time_monthname='Jul' ;; |
|||
8|08) time_monthname='Aug' ;; |
|||
9|09) time_monthname='Sep' ;; |
|||
10) time_monthname='Oct' ;; |
|||
11) time_monthname='Nov' ;; |
|||
12) time_monthname='Dec' ;; |
|||
esac |
|||
fi |
|||
|
|||
# expand special ``%x'' constructs |
|||
if [ ".$opt_e" = .yes ]; then |
|||
text=`echo $seo "$text" |\ |
|||
sed -e "s/%B/${term_bold}/g" \ |
|||
-e "s/%b/${term_norm}/g" \ |
|||
-e "s/%u/${username}/g" \ |
|||
-e "s/%U/${userid}/g" \ |
|||
-e "s/%h/${hostname}/g" \ |
|||
-e "s/%d/${domainname}/g" \ |
|||
-e "s/%D/${time_day}/g" \ |
|||
-e "s/%M/${time_month}/g" \ |
|||
-e "s/%Y/${time_year}/g" \ |
|||
-e "s/%m/${time_monthname}/g" 2>/dev/null` |
|||
fi |
|||
|
|||
# create output |
|||
if [ .$opt_n = .no ]; then |
|||
echo $seo "$text" |
|||
else |
|||
# the harder part: echo -n is best, because |
|||
# awk may complain about some \xx sequences. |
|||
if [ ".$minusn" != . ]; then |
|||
echo $seo $minusn "$text" |
|||
else |
|||
echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text" |
|||
fi |
|||
fi |
|||
;; |
|||
|
|||
install ) |
|||
## |
|||
## install -- Install a program, script or datafile |
|||
## Copyright (c) 1997-2000 Ralf S. Engelschall <rse@engelschall.com> |
|||
## Originally written for shtool |
|||
## |
|||
|
|||
src="$1" |
|||
dst="$2" |
|||
|
|||
# If destination is a directory, append the input filename |
|||
if [ -d $dst ]; then |
|||
dst=`echo "$dst" | sed -e 's:/$::'` |
|||
dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` |
|||
dst="$dst/$dstfile" |
|||
fi |
|||
|
|||
# Add a possible extension to src and dst |
|||
if [ ".$opt_e" != . ]; then |
|||
src="$src$opt_e" |
|||
dst="$dst$opt_e" |
|||
fi |
|||
|
|||
# Check for correct arguments |
|||
if [ ".$src" = ".$dst" ]; then |
|||
echo "$msgprefix:Error: source and destination are the same" 1>&2 |
|||
exit 1 |
|||
fi |
|||
|
|||
# Make a temp file name in the destination directory |
|||
dstdir=`echo $dst | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'` |
|||
dsttmp="$dstdir/#INST@$$#" |
|||
|
|||
# Verbosity |
|||
if [ ".$opt_v" = .yes ]; then |
|||
echo "$src -> $dst" 1>&2 |
|||
fi |
|||
|
|||
# Copy or move the file name to the temp name |
|||
# (because we might be not allowed to change the source) |
|||
if [ ".$opt_C" = .yes ]; then |
|||
opt_c=yes |
|||
fi |
|||
if [ ".$opt_c" = .yes ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "cp $src $dsttmp" 1>&2 |
|||
fi |
|||
cp $src $dsttmp || exit $? |
|||
else |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "mv $src $dsttmp" 1>&2 |
|||
fi |
|||
mv $src $dsttmp || exit $? |
|||
fi |
|||
|
|||
# Adjust the target file |
|||
# (we do chmod last to preserve setuid bits) |
|||
if [ ".$opt_s" = .yes ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "strip $dsttmp" 1>&2 |
|||
fi |
|||
strip $dsttmp || exit $? |
|||
fi |
|||
if [ ".$opt_o" != . ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "chown $opt_o $dsttmp" 1>&2 |
|||
fi |
|||
chown $opt_o $dsttmp || exit $? |
|||
fi |
|||
if [ ".$opt_g" != . ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "chgrp $opt_g $dsttmp" 1>&2 |
|||
fi |
|||
chgrp $opt_g $dsttmp || exit $? |
|||
fi |
|||
if [ ".$opt_m" != . ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "chmod $opt_m $dsttmp" 1>&2 |
|||
fi |
|||
chmod $opt_m $dsttmp || exit $? |
|||
fi |
|||
|
|||
# Determine whether to do a quick install |
|||
# (has to be done _after_ the strip was already done) |
|||
quick=no |
|||
if [ ".$opt_C" = .yes ]; then |
|||
if [ -r $dst ]; then |
|||
if cmp -s $src $dst; then |
|||
quick=yes |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
# Finally install the file to the real destination |
|||
if [ $quick = yes ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "rm -f $dsttmp" 1>&2 |
|||
fi |
|||
rm -f $dsttmp |
|||
else |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "rm -f $dst && mv $dsttmp $dst" 1>&2 |
|||
fi |
|||
rm -f $dst && mv $dsttmp $dst |
|||
fi |
|||
;; |
|||
|
|||
mkdir ) |
|||
## |
|||
## mkdir -- Make one or more directories |
|||
## Copyright (c) 1996-2000 Ralf S. Engelschall <rse@engelschall.com> |
|||
## Originally written for public domain by Noah Friedman <friedman@prep.ai.mit.edu> |
|||
## Cleaned up and enhanced for shtool |
|||
## |
|||
|
|||
errstatus=0 |
|||
for p in ${1+"$@"}; do |
|||
# if the directory already exists... |
|||
if [ -d "$p" ]; then |
|||
if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then |
|||
echo "$msgprefix:Error: directory already exists: $p" 1>&2 |
|||
errstatus=1 |
|||
break |
|||
else |
|||
continue |
|||
fi |
|||
fi |
|||
# if the directory has to be created... |
|||
if [ ".$opt_p" = .no ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "mkdir $p" 1>&2 |
|||
fi |
|||
mkdir $p || errstatus=$? |
|||
else |
|||
# the smart situation |
|||
set fnord `echo ":$p" |\ |
|||
sed -e 's/^:\//%/' \ |
|||
-e 's/^://' \ |
|||
-e 's/\// /g' \ |
|||
-e 's/^%/\//'` |
|||
shift |
|||
pathcomp='' |
|||
for d in ${1+"$@"}; do |
|||
pathcomp="$pathcomp$d" |
|||
case "$pathcomp" in |
|||
-* ) pathcomp="./$pathcomp" ;; |
|||
esac |
|||
if [ ! -d "$pathcomp" ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "mkdir $pathcomp" 1>&2 |
|||
fi |
|||
mkdir $pathcomp || errstatus=$? |
|||
if [ ".$opt_m" != . ]; then |
|||
if [ ".$opt_t" = .yes ]; then |
|||
echo "chmod $opt_m $pathcomp" 1>&2 |
|||
fi |
|||
chmod $opt_m $pathcomp || errstatus=$? |
|||
fi |
|||
fi |
|||
pathcomp="$pathcomp/" |
|||
done |
|||
fi |
|||
done |
|||
exit $errstatus |
|||
;; |
|||
|
|||
esac |
|||
|
|||
exit 0 |
|||
|
|||
##EOF## |
@ -0,0 +1,25 @@ |
|||
#!/usr/bin/perl |
|||
# |
|||
# Copyright (C) 2001 Ignat Ikryanov <iignat@newmail.ru> |
|||
# |
|||
|
|||
use strict; |
|||
my @INtext; |
|||
|
|||
open (text, "ru_RU.po") || die "$!"; |
|||
open (text1,">ru_RU.KOI8-R.po") || die "$!"; |
|||
|
|||
@INtext=<text>; |
|||
close(text); |
|||
|
|||
foreach(@INtext) |
|||
{ |
|||
tr/면坼劉帳票寤浹顥涉尊陰艶�琶麟潗愁㉸爐脚稿妹합樸龐일近愷펀裳緊훽保�/J촹愾曠百珉尙墓죗碌箝鷺螺答�輓윰儒蓄蘖晤犧�殮投倧睛隘劃�樟初循/; |
|||
s/CP1251/KOI8-R/; |
|||
|
|||
# You can alternatively use the following lines to change the conversion direction. |
|||
# tr/J촹愾曠百珉尙墓죗碌箝鷺螺答�輓윰儒蓄蘖晤犧�殮投倧睛隘劃�樟初循/면坼劉帳票寤浹顥涉尊陰艶�琶麟潗愁㉸爐脚稿妹합樸龐일近愷펀裳緊훽保�/; |
|||
|
|||
print text1; |
|||
} |
|||
close (text1); |
@ -0,0 +1,4 @@ |
|||
#!/bin/sh |
|||
|
|||
cd `dirname $0`; |
|||
perl extract.pl | xgettext --keyword=_ -C --no-location - |
@ -0,0 +1,39 @@ |
|||
<!-- $Horde: nms/templates/notconfigured.inc,v 1.2 2002/06/15 05:05:30 chuck Exp $--> |
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> |
|||
<html> |
|||
<head> |
|||
<title><?php echo _("Nms module is not properly configured") ?></title> |
|||
<style type="text/css"> |
|||
<!-- |
|||
<?php include NMS_BASE . '/templates/css.inc'; ?> |
|||
--> |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<table border="0" align="center" width="500" cellpadding="2" cellspacing="4"> |
|||
<tr><td colspan="2" class="header"><b><?php echo _("Some of NMS module's configuration files are missing:") ?></b></td></tr> |
|||
|
|||
<?php if (!@is_readable('./config/conf.php')): ?> |
|||
<tr> |
|||
<td align="right" class="smallheader"><b>conf.php</b></td> |
|||
<td class="light"><?php echo _("This is the main NMS module configuration file. It contains paths and options for all NMS module scripts.") ?></td> |
|||
</tr> |
|||
<?php endif; ?> |
|||
|
|||
<?php if (!@is_readable('./config/html.php')): ?> |
|||
<tr> |
|||
<td align="right" class="smallheader"><b>html.php</b></td> |
|||
<td class="light"><?php echo _("This file controls the stylesheet that is used to set colors and fonts in addition to or overriding Horde defaults.") ?></td> |
|||
</tr> |
|||
<?php endif; ?> |
|||
|
|||
<?php if (!@is_readable('./config/prefs.php')): ?> |
|||
<tr> |
|||
<td align="right" class="smallheader"><b>prefs.php</b></td> |
|||
<td class="light"><?php echo _("This file controls the default preferences for NMS module, and also controls which preferences users can alter.") ?></td> |
|||
</tr> |
|||
<?php endif; ?> |
|||
|
|||
</table> |
|||
</body> |
|||
</html> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue