From d646d455e2655be59f6d5bcc56710ac70548ca37 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 26 Sep 2010 02:33:01 -0400 Subject: Changed the language system to use gettext --- src/botserv.cpp | 20 +- src/channels.cpp | 19 +- src/chanserv.cpp | 5 +- src/commands.cpp | 25 +- src/config.cpp | 15 +- src/hostserv.cpp | 5 +- src/init.cpp | 4 +- src/language.cpp | 5698 ++++++++++++++++++++++++++++++++++++++++++++++--- src/mail.cpp | 21 +- src/memoserv.cpp | 58 +- src/messages.cpp | 14 +- src/misc.cpp | 42 +- src/module.cpp | 20 +- src/modulemanager.cpp | 9 +- src/modules.cpp | 118 +- src/nickserv.cpp | 17 +- src/operserv.cpp | 41 +- src/regchannel.cpp | 5 +- src/send.cpp | 72 - src/sessions.cpp | 10 +- src/users.cpp | 30 +- 21 files changed, 5598 insertions(+), 650 deletions(-) (limited to 'src') diff --git a/src/botserv.cpp b/src/botserv.cpp index 4cfd42e5b..cf5d6fa10 100644 --- a/src/botserv.cpp +++ b/src/botserv.cpp @@ -13,12 +13,11 @@ #include "services.h" #include "modules.h" -#include "language.h" static UserData *get_user_data(Channel *c, User *u); static void check_ban(ChannelInfo *ci, User *u, int ttbtype); -static void bot_kick(ChannelInfo *ci, User *u, int message, ...); +static void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...); E void moduleAddBotServCmds(); @@ -488,20 +487,19 @@ static void check_ban(ChannelInfo *ci, User *u, int ttbtype) /* This makes a bot kick an user. Works somewhat like notice_lang in fact ;) */ -static void bot_kick(ChannelInfo *ci, User *u, int message, ...) +static void bot_kick(ChannelInfo *ci, User *u, LanguageString message, ...) { va_list args; char buf[1024]; - const char *fmt; if (!ci || !ci->bi || !ci->c || !u) return; + Anope::string fmt = GetString(u, message); va_start(args, message); - fmt = getstring(u, message); - if (!fmt) + if (fmt.empty()) return; - vsnprintf(buf, sizeof(buf), fmt, args); + vsnprintf(buf, sizeof(buf), fmt.c_str(), args); va_end(args); ci->c->Kick(ci->bi, u, "%s", buf); @@ -521,7 +519,7 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, co if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); + ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", GetString(requester, ACCESS_DENIED).c_str()); return; } @@ -530,7 +528,7 @@ void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, co if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u) == 1) { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(BOT_EXCEPT)); + ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", GetString(requester, BOT_EXCEPT).c_str()); return; } @@ -558,7 +556,7 @@ void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, c if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && requester != u) { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); + ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", GetString(requester, ACCESS_DENIED).c_str()); return; } @@ -589,7 +587,7 @@ void bot_raw_mode(User *requester, ChannelInfo *ci, const Anope::string &mode, c if (ModeManager::FindUserModeByName(UMODE_PROTECTED) && u->IsProtected() && mode[0] == '-' && requester != u) { - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); + ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", GetString(requester, ACCESS_DENIED).c_str()); return; } diff --git a/src/channels.cpp b/src/channels.cpp index 8a500d759..84870b1e9 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -10,7 +10,6 @@ */ #include "services.h" -#include "language.h" #include "modules.h" channel_map ChannelList; @@ -145,9 +144,9 @@ void Channel::JoinUser(User *user) if (this->ci && check_access(user, this->ci, CA_MEMO) && this->ci->memos.memos.size() > 0) { if (this->ci->memos.memos.size() == 1) - notice_lang(Config->s_MemoServ, user, MEMO_X_ONE_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); + user->SendMessage(MemoServ, MEMO_X_ONE_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); else - notice_lang(Config->s_MemoServ, user, MEMO_X_MANY_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); + user->SendMessage(MemoServ, MEMO_X_MANY_NOTICE, this->ci->memos.memos.size(), this->ci->name.c_str()); } /* Added channelname to entrymsg - 30.03.2004, Certus */ /* Also, don't send the entrymsg when bursting -GD */ @@ -453,13 +452,6 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string ¶m, bo bi = findbot(param); User *u = bi ? bi : finduser(param); - /* Reset modes on bots if we're supposed to */ - if (bi) - { - if (std::find(Config->BotModeList.begin(), Config->BotModeList.end(), cm) != Config->BotModeList.end()) - this->SetMode(bi, cm, bi->nick); - } - if (!u) { Log() << "Channel::RemoveModeInternal() MODE " << this->name << "-" << cm->ModeChar << " for nonexistant user " << param; @@ -473,6 +465,13 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const Anope::string ¶m, bo if (cc) cc->Status->UnsetFlag(cm->Name); + /* Reset modes on bots if we're supposed to */ + if (bi) + { + if (std::find(Config->BotModeList.begin(), Config->BotModeList.end(), cm) != Config->BotModeList.end()) + this->SetMode(bi, cm, bi->nick); + } + return; } /* Setting b/e/I etc */ diff --git a/src/chanserv.cpp b/src/chanserv.cpp index b2dffcfd2..25c0cbf36 100644 --- a/src/chanserv.cpp +++ b/src/chanserv.cpp @@ -13,7 +13,6 @@ #include "services.h" #include "modules.h" -#include "language.h" registered_channel_map RegisteredChannelList; @@ -354,7 +353,7 @@ int check_valid_admin(User *user, Channel *chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOPROTECT)) { - notice_lang(Config->s_ChanServ, user, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); + user->SendMessage(ChanServ, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); chan->RemoveMode(NULL, CMODE_PROTECT, user->nick); return 0; } @@ -390,7 +389,7 @@ int check_valid_op(User *user, Channel *chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOOP)) { - notice_lang(Config->s_ChanServ, user, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); + user->SendMessage(ChanServ, CHAN_IS_REGISTERED, Config->s_ChanServ.c_str()); if (owner) chan->RemoveMode(NULL, CMODE_OWNER, user->nick); diff --git a/src/commands.cpp b/src/commands.cpp index bbf2a5233..3dc9ea177 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -11,7 +11,6 @@ #include "services.h" #include "modules.h" -#include "language.h" #include "hashcomp.h" Command *FindCommand(BotInfo *bi, const Anope::string &name) @@ -50,14 +49,14 @@ void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, if (!c) { - notice_lang(bi->nick, u, UNKNOWN_COMMAND_HELP, command.c_str(), bi->nick.c_str()); + u->SendMessage(bi, UNKNOWN_COMMAND_HELP, command.c_str(), bi->nick.c_str()); return; } // Command requires registered users only if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) { - notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config->s_NickServ.c_str()); + u->SendMessage(bi, NICK_IDENTIFY_REQUIRED, Config->s_NickServ.c_str()); Log(LOG_COMMAND, "denied", bi) << "Access denied for unregistered user " << u->GetMask() << " with command " << command; return; } @@ -102,27 +101,27 @@ void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, { if (ci->HasFlag(CI_FORBIDDEN) && !c->HasFlag(CFLAG_ALLOW_FORBIDDEN)) { - notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); + u->SendMessage(bi, CHAN_X_FORBIDDEN, ci->name.c_str()); Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command << " because of FORBIDDEN channel " << ci->name; return; } else if (ci->HasFlag(CI_SUSPENDED) && !c->HasFlag(CFLAG_ALLOW_SUSPENDED)) { - notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); + u->SendMessage(bi, CHAN_X_FORBIDDEN, ci->name.c_str()); Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command << " because of SUSPENDED channel " << ci->name; return; } } else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL)) { - notice_lang(bi->nick, u, CHAN_X_NOT_REGISTERED, params[0].c_str()); + u->SendMessage(bi, CHAN_X_NOT_REGISTERED, params[0].c_str()); return; } } /* A user not giving a channel name for a param that should be a channel */ else { - notice_lang(bi->nick, u, CHAN_X_INVALID, params[0].c_str()); + u->SendMessage(bi, CHAN_X_INVALID, params[0].c_str()); return; } } @@ -130,7 +129,7 @@ void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, // If the command requires a permission, and they aren't registered or don't have the required perm, DENIED if (!c->permission.empty() && !u->Account()->HasCommand(c->permission)) { - notice_lang(bi->nick, u, ACCESS_DENIED); + u->SendMessage(bi, ACCESS_DENIED); Log(LOG_COMMAND, "denied", bi) << "Access denied for user " << u->GetMask() << " with command " << command; return; } @@ -165,23 +164,23 @@ void mod_help_cmd(BotInfo *bi, User *u, const Anope::string &cmd) Anope::string subcommand = tokens.StreamEnd() ? "" : tokens.GetRemaining(); if (!c || (Config->HidePrivilegedCommands && !c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) || !c->OnHelp(u, subcommand)) - notice_lang(bi->nick, u, NO_HELP_AVAILABLE, cmd.c_str()); + u->SendMessage(bi, NO_HELP_AVAILABLE, cmd.c_str()); else { u->SendMessage(bi->nick, " "); /* Inform the user what permission is required to use the command */ if (!c->permission.empty()) - notice_lang(bi->nick, u, COMMAND_REQUIRES_PERM, c->permission.c_str()); + u->SendMessage(bi, COMMAND_REQUIRES_PERM, c->permission.c_str()); /* User isn't identified and needs to be to use this command */ if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) - notice_lang(bi->nick, u, COMMAND_IDENTIFY_REQUIRED); + u->SendMessage(bi, COMMAND_IDENTIFY_REQUIRED); /* User doesn't have the proper permission to use this command */ else if (!c->permission.empty() && (!u->Account() || !u->Account()->HasCommand(c->permission))) - notice_lang(bi->nick, u, COMMAND_CANNOT_USE); + u->SendMessage(bi, COMMAND_CANNOT_USE); /* User can use this command */ else - notice_lang(bi->nick, u, COMMAND_CAN_USE); + u->SendMessage(bi, COMMAND_CAN_USE); } } diff --git a/src/config.cpp b/src/config.cpp index 63141be0b..fda4d3881 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -101,9 +101,6 @@ ServerConfig::ServerConfig() : errstr(""), config_data() } } - if ((this->NSDefLanguage = langlist[this->NSDefLanguage]) < 0) - this->NSDefLanguage = DEF_LANGUAGE; - if (this->CSDefBantype < 0 || this->CSDefBantype > 3) { throw ConfigException("Value of CSDefBantype must be between 0 and 3 included"); @@ -530,15 +527,6 @@ bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string return true; } -bool ValidateLanguage(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data) -{ - int language = data.GetInteger(); - if (language < 1 || language > USED_LANGS) - throw ConfigException("The value for must be between 1 and " + stringify(USED_LANGS) + "!"); - data.Set(--language); - return true; -} - bool ValidateGuestPrefix(ServerConfig *conf, const Anope::string &tag, const Anope::string &value, ValueItem &data) { ValidateNotEmpty(conf, tag, value, data); @@ -1059,7 +1047,8 @@ void ServerConfig::Read() {"nickserv", "modules", "", new ValueContainerString(&NickCoreModules), DT_STRING, NoValidation}, {"nickserv", "forceemail", "no", new ValueContainerBool(&this->NSForceEmail), DT_BOOLEAN, ValidateEmailReg}, {"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation}, - {"nickserv", "defaultlanguage", "0", new ValueContainerUInt(&this->NSDefLanguage), DT_UINTEGER, ValidateLanguage}, + {"nickserv", "languages", "", new ValueContainerString(&this->Languages), DT_STRING, NoValidation}, + {"nickserv", "defaultlanguage", "0", new ValueContainerString(&this->NSDefLanguage), DT_STRING, NoValidation}, {"nickserv", "regdelay", "0", new ValueContainerTime(&this->NSRegDelay), DT_TIME, NoValidation}, {"nickserv", "resenddelay", "0", new ValueContainerTime(&this->NSResendDelay), DT_TIME, NoValidation}, {"nickserv", "expire", "21d", new ValueContainerTime(&this->NSExpire), DT_TIME, NoValidation}, diff --git a/src/hostserv.cpp b/src/hostserv.cpp index 31ff713f8..e8f4686cb 100644 --- a/src/hostserv.cpp +++ b/src/hostserv.cpp @@ -11,7 +11,6 @@ #include "services.h" #include "modules.h" -#include "language.h" E void moduleAddHostServCmds(); @@ -170,8 +169,8 @@ void do_on_id(User *u) u->UpdateHost(); if (!na->hostinfo.GetIdent().empty()) - notice_lang(Config->s_HostServ, u, HOST_IDENT_ACTIVATED, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str()); + u->SendMessage(HostServ, HOST_IDENT_ACTIVATED, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str()); else - notice_lang(Config->s_HostServ, u, HOST_ACTIVATED, na->hostinfo.GetHost().c_str()); + u->SendMessage(HostServ, HOST_ACTIVATED, na->hostinfo.GetHost().c_str()); } } diff --git a/src/init.cpp b/src/init.cpp index d882f34be..544dcbd7c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -431,8 +431,8 @@ void Init(int ac, char **av) signal(SIGINT, sighandler); /* Initialize multi-language support */ - lang_init(); - Log(LOG_DEBUG) << "Loaded languages"; + Log(LOG_DEBUG) << "Loading Languages..."; + InitLanguages(); /* Initialize subservices */ ns_init(); diff --git a/src/language.cpp b/src/language.cpp index 9d629f599..71dabcf46 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -1,353 +1,5421 @@ -/* Multi-language support. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - #include "services.h" -#include "language.h" - -/*************************************************************************/ - -/* The list of lists of messages. */ -char **langtexts[NUM_LANGS]; - -/* The list of names of languages. */ -char *langnames[NUM_LANGS]; - -/* Indexes of available languages: */ -int langlist[NUM_LANGS]; - -/* Order in which languages should be displayed: (alphabetical) */ -static int langorder[NUM_LANGS] = { - LANG_EN_US, /* English (US) */ - LANG_FR, /* French */ - LANG_DE, /* German */ - LANG_IT, /* Italian */ - LANG_JA_JIS, /* Japanese (JIS encoding) */ - LANG_JA_EUC, /* Japanese (EUC encoding) */ - LANG_JA_SJIS, /* Japanese (SJIS encoding) */ - LANG_PT, /* Portugese */ - LANG_ES, /* Spanish */ - LANG_TR, /* Turkish */ - LANG_CAT, /* Catalan */ - LANG_GR, /* Greek */ - LANG_NL, /* Dutch */ - LANG_RU, /* Russian */ - LANG_HUN, /* Hungarian */ - LANG_PL, /* Polish */ -}; - -/*************************************************************************/ - -/* Load a language file. */ -static int read_int32(int32 *ptr, FILE *f) -{ - int a = fgetc(f); - int b = fgetc(f); - int c = fgetc(f); - int d = fgetc(f); - if (a == EOF || b == EOF || c == EOF || d == EOF) - return -1; - *ptr = a << 24 | b << 16 | c << 8 | d; - return 0; -} - -static void load_lang(int index, const char *filename) -{ - char buf[256]; - FILE *f; - int32 num, i; - - Log(LOG_DEBUG) << "Loading language " << index << " from file `languages/" << filename << "'"; - snprintf(buf, sizeof(buf), "languages/%s", filename); -#ifndef _WIN32 - const char *mode = "r"; +#if HAVE_GETTEXT +# include #else - const char *mode = "rb"; +# define gettext(x) x #endif - if (!(f = fopen(buf, mode))) - { - throw CoreException("Failed to load language " + stringify(index) + " (" + stringify(filename) + ")"); - } - else if (read_int32(&num, f) < 0) - { - Log() << "Failed to read number of strings for language " << index << "(" << filename << ")"; - return; - } - else if (num != NUM_STRINGS) - Log() << "Warning: Bad number of strings (" << num << " , wanted " << NUM_STRINGS << ") for language " << index << " (" << filename << ")"; - langtexts[index] = static_cast(scalloc(sizeof(char *), NUM_STRINGS)); - if (num > NUM_STRINGS) - num = NUM_STRINGS; - for (i = 0; i < num; ++i) - { - int32 pos, len; - fseek(f, i * 8 + 4, SEEK_SET); - if (read_int32(&pos, f) < 0 || read_int32(&len, f) < 0) - { - Log() << "Failed to read entry " << i << " in language " << index << " (" << filename << ") TOC"; - while (--i >= 0) - { - if (langtexts[index][i]) - free(langtexts[index][i]); // XXX - } - free(langtexts[index]); - langtexts[index] = NULL; - return; - } - if (!len) - langtexts[index][i] = NULL; - else if (len >= 65536) - { - Log() << "Entry " << i << " in language " << index << " (" << filename << ") is too long (over 64k) -- corrupt TOC?"; - while (--i >= 0) - { - if (langtexts[index][i]) - free(langtexts[index][i]); // XXX - } - free(langtexts[index]); - langtexts[index] = NULL; - return; - } - else if (len < 0) - { - Log() << "Entry " << i << " in language " << index << " (" << filename << ") has negative length -- corrupt TOC?"; - while (--i >= 0) - { - if (langtexts[index][i]) - free(langtexts[index][i]); // XXX - } - free(langtexts[index]); - langtexts[index] = NULL; - return; - } - else - { - langtexts[index][i] = static_cast(malloc(len + 1)); - fseek(f, pos, SEEK_SET); - if (fread(langtexts[index][i], 1, len, f) != len) - { - Log() << "Failed to read string " << i << " in language " << index << "(" << filename << ")"; - while (--i >= 0) - { - if (langtexts[index][i]) - free(langtexts[index][i]); - } - free(langtexts[index]); - langtexts[index] = NULL; - return; - } - langtexts[index][i][len] = 0; - } - } - fclose(f); -} -/*************************************************************************/ +std::vector languages; -/* Replace all %M's with "/msg " or "/" */ -void lang_sanitize() +void InitLanguages() { - int i = 0, j = 0; - int len = 0; - char tmp[2000]; - char *newstr = NULL; - for (i = 0; i < NUM_LANGS; ++i) +#if HAVE_GETTEXT + languages.clear(); + spacesepstream sep(Config->Languages); + Anope::string language; + + while (sep.GetToken(language)) { - for (j = 0; j < NUM_STRINGS; ++j) + if (!IsFile("languages/" + language + "/LC_MESSAGES/anope.mo")) { - if (strstr(langtexts[i][j], "%R")) - { - len = strlen(langtexts[i][j]); - strscpy(tmp, langtexts[i][j], sizeof(tmp)); - if (Config->UseStrictPrivMsg) - strnrepl(tmp, sizeof(tmp), "%R", "/"); - else - strnrepl(tmp, sizeof(tmp), "%R", "/msg "); - newstr = strdup(tmp); - free(langtexts[i][j]); // XXX - langtexts[i][j] = newstr; - } + Log() << "Error loading language " << language << ", file does not exist!"; } - } -} - - -/* Initialize list of lists. */ - -void lang_init() -{ - int i, j, n = 0; - - load_lang(LANG_CAT, "cat"); - load_lang(LANG_DE, "de"); - load_lang(LANG_EN_US, "en_us"); - load_lang(LANG_ES, "es"); - load_lang(LANG_FR, "fr"); - load_lang(LANG_GR, "gr"); - load_lang(LANG_PT, "pt"); - load_lang(LANG_TR, "tr"); - load_lang(LANG_IT, "it"); - load_lang(LANG_NL, "nl"); - load_lang(LANG_RU, "ru"); - load_lang(LANG_HUN, "hun"); - load_lang(LANG_PL, "pl"); - - for (i = 0; i < NUM_LANGS; ++i) - { - if (langtexts[langorder[i]] != NULL) + else { - langnames[langorder[i]] = langtexts[langorder[i]][LANG_NAME]; - langlist[n++] = langorder[i]; - for (j = 0; j < NUM_STRINGS; ++j) - { - if (!langtexts[langorder[i]][j]) - langtexts[langorder[i]][j] = langtexts[DEF_LANGUAGE][j]; - if (!langtexts[langorder[i]][j]) - langtexts[langorder[i]][j] = langtexts[LANG_EN_US][j]; - } + Log(LOG_DEBUG) << "Found language file " << language; + languages.push_back(language); } } - while (n < NUM_LANGS) - langlist[n++] = -1; - - /* Not what I intended to do, but these services are so archaïc - * that it's difficult to do more. */ - if ((Config->NSDefLanguage = langlist[Config->NSDefLanguage]) < 0) - Config->NSDefLanguage = DEF_LANGUAGE; - if (!langtexts[DEF_LANGUAGE]) - throw CoreException("Unable to load default language"); - for (i = 0; i < NUM_LANGS; ++i) + if (!bindtextdomain("anope", (services_dir + "/languages/").c_str())) { - if (!langtexts[i]) - langtexts[i] = langtexts[DEF_LANGUAGE]; + Log() << "Error calling bindtextdomain, " << Anope::LastError(); } - lang_sanitize(); +#else + Log() << "Can not load languages, gettext is not installed"; +#endif } -/*************************************************************************/ -/*************************************************************************/ - -/* Format a string in a strftime()-like way, but heed the user's language - * setting for month and day names. The string stored in the buffer will - * always be null-terminated, even if the actual string was longer than the - * buffer size. - * Assumption: No month or day name has a length (including trailing null) - * greater than BUFSIZE. - */ - -int strftime_lang(char *buf, int size, User *u, int format, struct tm *tm) +const Anope::string GetString(Anope::string language, LanguageString string) { - int language = u && u->Account() ? u->Account()->language : Config->NSDefLanguage; - char tmpbuf[BUFSIZE], buf2[BUFSIZE]; - char *s; - int i, ret; +#if HAVE_GETTEXT + /* For older databases */ + if (language == "en") + language.clear(); - if (!tm) - return 0; + /* Apply def language */ + if (language.empty() && !Config->NSDefLanguage.empty()) + language = Config->NSDefLanguage; - strscpy(tmpbuf, langtexts[language][format], sizeof(tmpbuf)); - if ((s = langtexts[language][STRFTIME_DAYS_SHORT])) - { - for (i = 0; i < tm->tm_wday; ++i) - s += strcspn(s, "\n") + 1; - i = strcspn(s, "\n"); - strncpy(buf2, s, i); - buf2[i] = 0; - strnrepl(tmpbuf, sizeof(tmpbuf), "%a", buf2); - } - if ((s = langtexts[language][STRFTIME_DAYS_LONG])) - { - for (i = 0; i < tm->tm_wday; ++i) - s += strcspn(s, "\n") + 1; - i = strcspn(s, "\n"); - strncpy(buf2, s, i); - buf2[i] = 0; - strnrepl(tmpbuf, sizeof(tmpbuf), "%A", buf2); - } - if ((s = langtexts[language][STRFTIME_MONTHS_SHORT])) - { - for (i = 0; i < tm->tm_mon; ++i) - s += strcspn(s, "\n") + 1; - i = strcspn(s, "\n"); - strncpy(buf2, s, i); - buf2[i] = 0; - strnrepl(tmpbuf, sizeof(tmpbuf), "%b", buf2); - } - if ((s = langtexts[language][STRFTIME_MONTHS_LONG])) - { - for (i = 0; i < tm->tm_mon; ++i) - s += strcspn(s, "\n") + 1; - i = strcspn(s, "\n"); - strncpy(buf2, s, i); - buf2[i] = 0; - strnrepl(tmpbuf, sizeof(tmpbuf), "%B", buf2); - } - ret = strftime(buf, size, tmpbuf, tm); - if (ret == size) - buf[size - 1] = 0; - return ret; -} - -/*************************************************************************/ -/*************************************************************************/ - -/* Send a syntax-error message to the user. */ - -void syntax_error(const Anope::string &service, User *u, const Anope::string &command, int msgnum) -{ - const char *str; + if (language.empty()) +#endif + return language_strings[string]; - if (!u) - return; +#if HAVE_GETTEXT + setlocale(LC_ALL, language.c_str()); + const char *ret = dgettext("anope", language_strings[string].c_str()); + setlocale(LC_ALL, ""); - str = getstring(u, msgnum); - notice_lang(service, u, SYNTAX_ERROR, str); - notice_lang(service, u, MORE_INFO, service.c_str(), command.c_str()); + return ret ? ret : ""; +#endif } -const char *getstring(NickAlias *na, int index) +const Anope::string GetString(LanguageString string) { - // Default to config - int langidx = Config->NSDefLanguage; - - // If they are registered (na->nc), and NOT forbidden - if (na && na->nc && !na->HasFlag(NS_FORBIDDEN)) - langidx = na->nc->language; // set language to their nickcore's language - - return langtexts[langidx][index]; + return GetString("", string); } -const char *getstring(const NickCore *nc, int index) +const Anope::string GetString(const NickCore *nc, LanguageString string) { - // Default to config - int langidx = Config->NSDefLanguage; - - if (nc) - langidx = nc->language; - - return langtexts[langidx][index]; + return GetString(nc ? nc->language : "", string); } -const char *getstring(const User *u, int index) +const Anope::string GetString(const User *u, LanguageString string) { - return getstring(u->Account(), index); + if (!u) + return GetString(string); + const NickCore *nc = u->Account(); + NickAlias *na = NULL; + if (!nc) + na = findnick(u->nick); + return GetString(nc ? nc : (na ? na->nc : NULL), string); } -const char *getstring(int index) +void SyntaxError(BotInfo *bi, User *u, const Anope::string &command, LanguageString message) { - // Default to config - int langidx = Config->NSDefLanguage; + if (!bi || !u || command.empty()) + return; - return langtexts[langidx][index]; + Anope::string str = GetString(u, message); + u->SendMessage(bi, SYNTAX_ERROR, str.c_str()); + u->SendMessage(bi, MORE_INFO, bi->nick.c_str(), command.c_str()); } -/*************************************************************************/ +Anope::string language_strings[LANG_STRING_COUNT] = { + /* LANG_NAME */ + gettext("English"), + /* COMMAND_REQUIRES_PERM */ + gettext("Access to this command requires the permission %s to be present in your opertype."), + /* COMMAND_IDENTIFY_REQUIRED */ + gettext("You need to be identified to use this command."), + /* COMMAND_CANNOT_USE */ + gettext("You cannot use this command."), + /* COMMAND_CAN_USE */ + gettext("You can use this command."), + /* USER_RECORD_NOT_FOUND */ + gettext("Internal error - unable to process request."), + /* UNKNOWN_COMMAND */ + gettext("Unknown command %s."), + /* UNKNOWN_COMMAND_HELP */ + gettext("Unknown command %s. \"%R%s HELP\" for help."), + /* SYNTAX_ERROR */ + gettext("Syntax: %s"), + /* MORE_INFO */ + gettext("%R%s HELP %s for more information."), + /* NO_HELP_AVAILABLE */ + gettext("No help available for %s."), + /* OBSOLETE_COMMAND */ + gettext("This command is obsolete; use %s instead."), + /* BAD_USERHOST_MASK */ + gettext("Mask must be in the form user@host."), + /* BAD_EXPIRY_TIME */ + gettext("Invalid expiry time."), + /* USERHOST_MASK_TOO_WIDE */ + gettext("%s coverage is too wide; Please use a more specific mask."), + /* SERVICE_OFFLINE */ + gettext("%s is currently offline."), + /* READ_ONLY_MODE */ + gettext("Notice: Services is in read-only mode; changes will not be saved!"), + /* PASSWORD_INCORRECT */ + gettext("Password incorrect."), + /* INVALID_TARGET */ + gettext("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), + /* ACCESS_DENIED */ + gettext("Access denied."), + /* MORE_OBSCURE_PASSWORD */ + gettext("Please try again with a more obscure password. Passwords should be at least five characters long, should not be something easily guessed (e.g. your real name or your nick), and cannot contain the space or tab characters."), + /* PASSWORD_TOO_LONG */ + gettext("Your password is too long. Please try again with a shorter password."), + /* NICK_NOT_REGISTERED */ + gettext("Your nick isn't registered."), + /* NICK_NOT_REGISTERED_HELP */ + gettext("Your nick isn't registered. Type %R%s HELP for information on registering your nickname."), + /* NICK_X_IS_SERVICES */ + gettext("Nick %s is part of this Network's Services."), + /* NICK_X_NOT_REGISTERED */ + gettext("Nick %s isn't registered."), + /* NICK_X_IN_USE */ + gettext("Nick %s is currently in use."), + /* NICK_X_NOT_IN_USE */ + gettext("Nick %s isn't currently in use."), + /* NICK_X_NOT_ON_CHAN */ + gettext("%s is not currently on channel %s."), + /* NICK_X_FORBIDDEN */ + gettext("Nick %s may not be registered or used."), + /* NICK_X_FORBIDDEN_OPER */ + gettext("Nick %s has been forbidden by %s:\n" + "%s"), + /* NICK_X_ILLEGAL */ + gettext("Nick %s is an illegal nickname and cannot be used."), + /* NICK_X_TRUNCATED */ + gettext("Nick %s was truncated to %d characters."), + /* NICK_X_SUSPENDED */ + gettext("Nick %s is currently suspended."), + /* CHAN_X_NOT_REGISTERED */ + gettext("Channel %s isn't registered."), + /* CHAN_X_NOT_IN_USE */ + gettext("Channel %s doesn't exist."), + /* CHAN_X_FORBIDDEN */ + gettext("Channel %s may not be registered or used."), + /* CHAN_X_FORBIDDEN_OPER */ + gettext("Channel %s has been forbidden by %s:\n" + "%s"), + /* CHAN_X_SUSPENDED */ + gettext(" Suspended: [%s] %s"), + /* NICK_IDENTIFY_REQUIRED */ + gettext("Password authentication required for that command.\n" + "Retry after typing %R%s IDENTIFY password."), + /* CHAN_IDENTIFY_REQUIRED */ + gettext("Password authentication required for that command.\n" + "Retry after typing %R%s IDENTIFY %s password."), + /* MAIL_DISABLED */ + gettext("Services have been configured to not send mail."), + /* MAIL_INVALID */ + gettext("E-mail for %s is invalid."), + /* MAIL_X_INVALID */ + gettext("%s is not a valid e-mail address."), + /* MAIL_LATER */ + gettext("Cannot send mail now; please retry a little later."), + /* MAIL_DELAYED */ + gettext("Please wait %d seconds and retry."), + /* NO_REASON */ + gettext("No reason"), + /* UNKNOWN */ + gettext(""), + /* DURATION_DAY */ + gettext("1 day"), + /* DURATION_DAYS */ + gettext("%d days"), + /* DURATION_HOUR */ + gettext("1 hour"), + /* DURATION_HOURS */ + gettext("%d hours"), + /* DURATION_MINUTE */ + gettext("1 minute"), + /* DURATION_MINUTES */ + gettext("%d minutes"), + /* DURATION_SECOND */ + gettext("1 second"), + /* DURATION_SECONDS */ + gettext("%d seconds"), + /* NO_EXPIRE */ + gettext("does not expire"), + /* EXPIRES_SOON */ + gettext("expires at next database update"), + /* EXPIRES_M */ + gettext("expires in %d minutes"), + /* EXPIRES_1M */ + gettext("expires in %d minute"), + /* EXPIRES_HM */ + gettext("expires in %d hours, %d minutes"), + /* EXPIRES_H1M */ + gettext("expires in %d hours, %d minute"), + /* EXPIRES_1HM */ + gettext("expires in %d hour, %d minutes"), + /* EXPIRES_1H1M */ + gettext("expires in %d hour, %d minute"), + /* EXPIRES_D */ + gettext("expires in %d days"), + /* EXPIRES_1D */ + gettext("expires in %d day"), + /* END_OF_ANY_LIST */ + gettext("End of %s list."), + /* LIST_INCORRECT_RANGE */ + gettext("Incorrect range specified. The correct syntax is #from-to."), + /* CS_LIST_INCORRECT_RANGE */ + gettext("To search for channels starting with #, search for the channel\n" + "name without the #-sign prepended (anope instead of #anope)."), + /* NICK_IS_REGISTERED */ + gettext("This nick is owned by someone else. Please choose another.\n" + "(If this is your nick, type %R%s IDENTIFY password.)"), + /* NICK_IS_SECURE */ + gettext("This nickname is registered and protected. If it is your\n" + "nick, type %R%s IDENTIFY password. Otherwise,\n" + "please choose a different nick."), + /* NICK_MAY_NOT_BE_USED */ + gettext("This nickname may not be used. Please choose another one."), + /* FORCENICKCHANGE_IN_1_MINUTE */ + gettext("If you do not change within one minute, I will change your nick."), + /* FORCENICKCHANGE_IN_20_SECONDS */ + gettext("If you do not change within 20 seconds, I will change your nick."), + /* FORCENICKCHANGE_NOW */ + gettext("This nickname has been registered; you may not use it."), + /* FORCENICKCHANGE_CHANGING */ + gettext("Your nickname is now being changed to %s"), + /* NICK_REGISTER_SYNTAX */ + gettext("REGISTER password [email]"), + /* NICK_REGISTER_SYNTAX_EMAIL */ + gettext("REGISTER password email"), + /* NICK_REGISTRATION_DISABLED */ + gettext("Sorry, nickname registration is temporarily disabled."), + /* NICK_REGISTRATION_FAILED */ + gettext("Sorry, registration failed."), + /* NICK_REG_PLEASE_WAIT */ + gettext("Please wait %d seconds before using the REGISTER command again."), + /* NICK_CANNOT_BE_REGISTERED */ + gettext("Nickname %s may not be registered."), + /* NICK_ALREADY_REGISTERED */ + gettext("Nickname %s is already registered!"), + /* NICK_REGISTERED */ + gettext("Nickname %s registered under your account: %s"), + /* NICK_REGISTERED_NO_MASK */ + gettext("Nickname %s registered."), + /* NICK_PASSWORD_IS */ + gettext("Your password is %s - remember this for later use."), + /* NICK_REG_DELAY */ + gettext("You must have been using this nick for at least %d seconds to register."), + /* NICK_GROUP_SYNTAX */ + gettext("GROUP target password"), + /* NICK_GROUP_DISABLED */ + gettext("Sorry, nickname grouping is temporarily disabled."), + /* NICK_GROUP_FAILED */ + gettext("Sorry, grouping failed."), + /* NICK_GROUP_PLEASE_WAIT */ + gettext("Please wait %d seconds before using the GROUP command again."), + /* NICK_GROUP_CHANGE_DISABLED */ + gettext("Your nick is already registered; type %R%s DROP first."), + /* NICK_GROUP_SAME */ + gettext("You are already a member of the group of %s."), + /* NICK_GROUP_TOO_MANY */ + gettext("There are too many nicks in %s's group; list them and drop some.\n" + "Type %R%s HELP GLIST and %R%s HELP DROP\n" + "for more information."), + /* NICK_GROUP_JOINED */ + gettext("You are now in the group of %s."), + /* NICK_UNGROUP_ONE_NICK */ + gettext("Your nick is not grouped to anything, you can't ungroup it."), + /* NICK_UNGROUP_NOT_IN_GROUP */ + gettext("The nick %s is not in your group."), + /* NICK_UNGROUP_SUCCESSFUL */ + gettext("Nick %s has been ungrouped from %s."), + /* NICK_IDENTIFY_SYNTAX */ + gettext("IDENTIFY [account] password"), + /* NICK_IDENTIFY_FAILED */ + gettext("Sorry, identification failed."), + /* NICK_IDENTIFY_SUCCEEDED */ + gettext("Password accepted - you are now recognized."), + /* NICK_IDENTIFY_EMAIL_REQUIRED */ + gettext("You must now supply an e-mail for your nick.\n" + "This e-mail will allow you to retrieve your password in\n" + "case you forget it."), + /* NICK_IDENTIFY_EMAIL_HOWTO */ + gettext("Type %R%S SET EMAIL e-mail in order to set your e-mail.\n" + "Your privacy is respected; this e-mail won't be given to\n" + "any third-party person."), + /* NICK_ALREADY_IDENTIFIED */ + gettext("You are already identified."), + /* NICK_UPDATE_SUCCESS */ + gettext("Status updated (memos, vhost, chmodes, flags)."), + /* NICK_LOGOUT_SYNTAX */ + gettext("LOGOUT"), + /* NICK_LOGOUT_SUCCEEDED */ + gettext("Your nick has been logged out."), + /* NICK_LOGOUT_X_SUCCEEDED */ + gettext("Nick %s has been logged out."), + /* NICK_LOGOUT_SERVICESADMIN */ + gettext("Can't logout %s because he's a Services Operator."), + /* NICK_DROP_DISABLED */ + gettext("Sorry, nickname de-registration is temporarily disabled."), + /* NICK_DROPPED */ + gettext("Your nickname has been dropped."), + /* NICK_X_DROPPED */ + gettext("Nickname %s has been dropped."), + /* NICK_SET_SYNTAX */ + gettext("SET option parameters"), + /* NICK_SET_SERVADMIN_SYNTAX */ + gettext("SET [nick] option parameters"), + /* NICK_SET_DISABLED */ + gettext("Sorry, nickname option setting is temporarily disabled."), + /* NICK_SET_UNKNOWN_OPTION */ + gettext("Unknown SET option %s."), + /* NICK_SET_OPTION_DISABLED */ + gettext("Option %s cannot be set on this network."), + /* NICK_SET_DISPLAY_INVALID */ + gettext("The new display MUST be a nickname of your nickname group!"), + /* NICK_SET_DISPLAY_CHANGED */ + gettext("The new display is now %s."), + /* NICK_SET_PASSWORD_FAILED */ + gettext("Sorry, couldn't change password."), + /* NICK_SET_PASSWORD_CHANGED */ + gettext("Password changed."), + /* NICK_SET_PASSWORD_CHANGED_TO */ + gettext("Password changed to %s."), + /* NICK_SET_LANGUAGE_SYNTAX */ + gettext("SET LANGUAGE language"), + /* NICK_SET_LANGUAGE_UNKNOWN */ + gettext("Unknown language number %d. Type %R%s HELP SET LANGUAGE for a list of languages."), + /* NICK_SET_LANGUAGE_CHANGED */ + gettext("Language changed to English."), + /* NICK_SET_EMAIL_CHANGED */ + gettext("E-mail address changed to %s."), + /* NICK_SET_EMAIL_UNSET */ + gettext("E-mail address unset."), + /* NICK_SET_EMAIL_UNSET_IMPOSSIBLE */ + gettext("You cannot unset the e-mail on this network."), + /* NICK_SET_GREET_CHANGED */ + gettext("Greet message changed to %s."), + /* NICK_SET_GREET_UNSET */ + gettext("Greet message unset."), + /* NICK_SET_KILL_SYNTAX */ + gettext("SET KILL {ON | QUICK | OFF}"), + /* NICK_SET_KILL_IMMED_SYNTAX */ + gettext("SET KILL {ON | QUICK | IMMED | OFF}"), + /* NICK_SET_KILL_ON */ + gettext("Protection is now ON."), + /* NICK_SET_KILL_QUICK */ + gettext("Protection is now ON, with a reduced delay."), + /* NICK_SET_KILL_IMMED */ + gettext("Protection is now ON, with no delay."), + /* NICK_SET_KILL_IMMED_DISABLED */ + gettext("The IMMED option is not available on this network."), + /* NICK_SET_KILL_OFF */ + gettext("Protection is now OFF."), + /* NICK_SET_SECURE_SYNTAX */ + gettext("SET SECURE {ON | OFF}"), + /* NICK_SET_SECURE_ON */ + gettext("Secure option is now ON."), + /* NICK_SET_SECURE_OFF */ + gettext("Secure option is now OFF."), + /* NICK_SET_PRIVATE_SYNTAX */ + gettext("SET PRIVATE {ON | OFF}"), + /* NICK_SET_PRIVATE_ON */ + gettext("Private option is now ON."), + /* NICK_SET_PRIVATE_OFF */ + gettext("Private option is now OFF."), + /* NICK_SET_HIDE_SYNTAX */ + gettext("SET HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"), + /* NICK_SET_HIDE_EMAIL_ON */ + gettext("Your E-mail address will now be hidden from %s INFO displays."), + /* NICK_SET_HIDE_EMAIL_OFF */ + gettext("Your E-mail address will now be shown in %s INFO displays."), + /* NICK_SET_HIDE_MASK_ON */ + gettext("Your last seen user@host mask will now be hidden from %s INFO displays."), + /* NICK_SET_HIDE_MASK_OFF */ + gettext("Your last seen user@host mask will now be shown in %s INFO displays."), + /* NICK_SET_HIDE_QUIT_ON */ + gettext("Your last quit message will now be hidden from %s INFO displays."), + /* NICK_SET_HIDE_QUIT_OFF */ + gettext("Your last quit message will now be shown in %s INFO displays."), + /* NICK_SET_HIDE_STATUS_ON */ + gettext("Your services access status will now be hidden from %s INFO displays."), + /* NICK_SET_HIDE_STATUS_OFF */ + gettext("Your services access status will now be shown in %s INFO displays."), + /* NICK_SET_MSG_SYNTAX */ + gettext("SET MSG {ON | OFF}"), + /* NICK_SET_MSG_ON */ + gettext("Services will now reply to you with messages."), + /* NICK_SET_MSG_OFF */ + gettext("Services will now reply to you with notices."), + /* NICK_SET_AUTOOP_SYNTAX */ + gettext("SET AUTOOP {ON | OFF}"), + /* NICK_SET_AUTOOP_ON */ + gettext("Services will now autoop you in channels."), + /* NICK_SET_AUTOOP_OFF */ + gettext("Services will no longer autoop you in channels."), + /* NICK_SASET_SYNTAX */ + gettext("SASET nickname option parameters"), + /* NICK_SASET_UNKNOWN_OPTION */ + gettext("Unknown SASET option %s."), + /* NICK_SASET_BAD_NICK */ + gettext("Nickname %s not registered."), + /* NICK_SASET_DISPLAY_INVALID */ + gettext("The new display for %s MUST be a nickname of the nickname group!"), + /* NICK_SASET_PASSWORD_FAILED */ + gettext("Sorry, couldn't change password for %s."), + /* NICK_SASET_PASSWORD_CHANGED */ + gettext("Password for %s changed."), + /* NICK_SASET_PASSWORD_CHANGED_TO */ + gettext("Password for %s changed to %s."), + /* NICK_SASET_EMAIL_CHANGED */ + gettext("E-mail address for %s changed to %s."), + /* NICK_SASET_EMAIL_UNSET */ + gettext("E-mail address for %s unset."), + /* NICK_SASET_GREET_CHANGED */ + gettext("Greet message for %s changed to %s."), + /* NICK_SASET_GREET_UNSET */ + gettext("Greet message for %s unset."), + /* NICK_SASET_KILL_SYNTAX */ + gettext("SASET nickname KILL {ON | QUICK | OFF}"), + /* NICK_SASET_KILL_IMMED_SYNTAX */ + gettext("SASET nickname KILL {ON | QUICK | IMMED | OFF}"), + /* NICK_SASET_KILL_ON */ + gettext("Protection is now ON for %s."), + /* NICK_SASET_KILL_QUICK */ + gettext("Protection is now ON for %s, with a reduced delay."), + /* NICK_SASET_KILL_IMMED */ + gettext("Protection is now ON for %s, with no delay."), + /* NICK_SASET_KILL_OFF */ + gettext("Protection is now OFF for %s."), + /* NICK_SASET_SECURE_SYNTAX */ + gettext("SASET nickname SECURE {ON | OFF}"), + /* NICK_SASET_SECURE_ON */ + gettext("Secure option is now ON for %s."), + /* NICK_SASET_SECURE_OFF */ + gettext("Secure option is now OFF for %s."), + /* NICK_SASET_PRIVATE_SYNTAX */ + gettext("SASET nickname PRIVATE {ON | OFF}"), + /* NICK_SASET_PRIVATE_ON */ + gettext("Private option is now ON for %s."), + /* NICK_SASET_PRIVATE_OFF */ + gettext("Private option is now OFF for %s."), + /* NICK_SASET_HIDE_SYNTAX */ + gettext("SASET nickname HIDE {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"), + /* NICK_SASET_HIDE_EMAIL_ON */ + gettext("The E-mail address of %s will now be hidden from %s INFO displays."), + /* NICK_SASET_HIDE_EMAIL_OFF */ + gettext("The E-mail address of %s will now be shown in %s INFO displays."), + /* NICK_SASET_HIDE_MASK_ON */ + gettext("The last seen user@host mask of %s will now be hidden from %s INFO displays."), + /* NICK_SASET_HIDE_MASK_OFF */ + gettext("The last seen user@host mask of %s will now be shown in %s INFO displays."), + /* NICK_SASET_HIDE_QUIT_ON */ + gettext("The last quit message of %s will now be hidden from %s INFO displays."), + /* NICK_SASET_HIDE_QUIT_OFF */ + gettext("The last quit message of %s will now be shown in %s INFO displays."), + /* NICK_SASET_HIDE_STATUS_ON */ + gettext("The services access status of %s will now be hidden from %s INFO displays."), + /* NICK_SASET_HIDE_STATUS_OFF */ + gettext("The services access status of %s will now be shown in %s INFO displays."), + /* NICK_SASET_MSG_SYNTAX */ + gettext("SASAET nickname PRIVATE {ON | OFF}"), + /* NICK_SASET_MSG_ON */ + gettext("Services will now reply to %s with messages."), + /* NICK_SASET_MSG_OFF */ + gettext("Services will now reply to %s with notices."), + /* NICK_SASET_NOEXPIRE_SYNTAX */ + gettext("SASET nickname NOEXPIRE {ON | OFF}"), + /* NICK_SASET_NOEXPIRE_ON */ + gettext("Nick %s will not expire."), + /* NICK_SASET_NOEXPIRE_OFF */ + gettext("Nick %s will expire."), + /* NICK_SASET_AUTOOP_SYNTAX */ + gettext("SASET nickname AUTOOP {ON | OFF}"), + /* NICK_SASET_AUTOOP_ON */ + gettext("Services will now autoop %s in channels."), + /* NICK_SASET_AUTOOP_OFF */ + gettext("Services will no longer autoop %s in channels."), + /* NICK_SASET_LANGUAGE_SYNTAX */ + gettext("SASET nickname LANGUAGE number"), + /* NICK_ACCESS_SYNTAX */ + gettext("ACCESS {ADD | DEL | LIST} [mask]"), + /* NICK_ACCESS_ALREADY_PRESENT */ + gettext("Mask %s already present on your access list."), + /* NICK_ACCESS_REACHED_LIMIT */ + gettext("Sorry, you can only have %d access entries for a nickname."), + /* NICK_ACCESS_ADDED */ + gettext("%s added to your access list."), + /* NICK_ACCESS_NOT_FOUND */ + gettext("%s not found on your access list."), + /* NICK_ACCESS_DELETED */ + gettext("%s deleted from your access list."), + /* NICK_ACCESS_LIST */ + gettext("Access list:"), + /* NICK_ACCESS_LIST_X */ + gettext("Access list for %s:"), + /* NICK_ACCESS_LIST_EMPTY */ + gettext("Your access list is empty."), + /* NICK_ACCESS_LIST_X_EMPTY */ + gettext("Access list for %s is empty."), + /* NICK_STATUS_REPLY */ + gettext("STATUS %s %d %s"), + /* NICK_INFO_SYNTAX */ + gettext("INFO nick"), + /* NICK_INFO_REALNAME */ + gettext("%s is %s"), + /* NICK_INFO_SERVICES_OPERTYPE */ + gettext("%s is a services operator of type %s."), + /* NICK_INFO_ADDRESS */ + gettext("Last seen address: %s"), + /* NICK_INFO_ADDRESS_ONLINE */ + gettext(" Is online from: %s"), + /* NICK_INFO_ADDRESS_ONLINE_NOHOST */ + gettext("%s is currently online."), + /* NICK_INFO_TIME_REGGED */ + gettext(" Time registered: %s"), + /* NICK_INFO_LAST_SEEN */ + gettext(" Last seen time: %s"), + /* NICK_INFO_LAST_QUIT */ + gettext("Last quit message: %s"), + /* NICK_INFO_URL */ + gettext(" URL: %s"), + /* NICK_INFO_EMAIL */ + gettext(" E-mail address: %s"), + /* NICK_INFO_VHOST */ + gettext(" vhost: %s"), + /* NICK_INFO_VHOST2 */ + gettext(" vhost: %s@%s"), + /* NICK_INFO_GREET */ + gettext(" Greet message: %s"), + /* NICK_INFO_OPTIONS */ + gettext(" Options: %s"), + /* NICK_INFO_EXPIRE */ + gettext("Expires on: %s"), + /* NICK_INFO_OPT_KILL */ + gettext("Protection"), + /* NICK_INFO_OPT_SECURE */ + gettext("Security"), + /* NICK_INFO_OPT_PRIVATE */ + gettext("Private"), + /* NICK_INFO_OPT_MSG */ + gettext("Message mode"), + /* NICK_INFO_OPT_AUTOOP */ + gettext("Auto-op"), + /* NICK_INFO_OPT_NONE */ + gettext("None"), + /* NICK_INFO_NO_EXPIRE */ + gettext("This nickname will not expire."), + /* NICK_INFO_SUSPENDED */ + gettext("This nickname is currently suspended, reason: %s"), + /* NICK_INFO_SUSPENDED_NO_REASON */ + gettext("This nickname is currently suspended"), + /* NICK_LIST_SYNTAX */ + gettext("LIST pattern"), + /* NICK_LIST_SERVADMIN_SYNTAX */ + gettext("LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"), + /* NICK_LIST_HEADER */ + gettext("List of entries matching %s:"), + /* NICK_LIST_RESULTS */ + gettext("End of list - %d/%d matches shown."), + /* NICK_ALIST_SYNTAX */ + gettext("ALIST nickname"), + /* NICK_ALIST_HEADER */ + gettext("Channels that you have access on:\n" + " Num Channel Level Description"), + /* NICK_ALIST_HEADER_X */ + gettext("Channels that %s has access on:\n" + " Num Channel Level Description"), + /* NICK_ALIST_XOP_FORMAT */ + gettext(" %3d %c%-20s %-8s %s"), + /* NICK_ALIST_ACCESS_FORMAT */ + gettext(" %3d %c%-20s %-8d %s"), + /* NICK_ALIST_FOOTER */ + gettext("End of list - %d/%d channels shown."), + /* NICK_GLIST_HEADER */ + gettext("List of nicknames in your group:"), + /* NICK_GLIST_HEADER_X */ + gettext("List of nicknames in the group of %s:"), + /* NICK_GLIST_FOOTER */ + gettext("%d nicknames in the group."), + /* NICK_GLIST_REPLY */ + gettext(" %s (expires in %s)"), + /* NICK_GLIST_REPLY_NOEXPIRE */ + gettext(" %s (does not expire)"), + /* NICK_RECOVER_SYNTAX */ + gettext("RECOVER nickname [password]"), + /* NICK_NO_RECOVER_SELF */ + gettext("You can't recover yourself!"), + /* NICK_RECOVERED */ + gettext("User claiming your nick has been killed.\n" + "%R%s RELEASE %s to get it back before %s timeout."), + /* NICK_RELEASE_SYNTAX */ + gettext("RELEASE nickname [password]"), + /* NICK_RELEASE_NOT_HELD */ + gettext("Nick %s isn't being held."), + /* NICK_RELEASED */ + gettext("Services' hold on your nick has been released."), + /* NICK_GHOST_SYNTAX */ + gettext("GHOST nickname [password]"), + /* NICK_NO_GHOST_SELF */ + gettext("You can't ghost yourself!"), + /* NICK_GHOST_KILLED */ + gettext("Ghost with your nick has been killed."), + /* NICK_GETPASS_SYNTAX */ + gettext("GETPASS nickname"), + /* NICK_GETPASS_UNAVAILABLE */ + gettext("GETPASS command unavailable because encryption is in use."), + /* NICK_GETPASS_PASSWORD_IS */ + gettext("Password for %s is %s."), + /* NICK_GETEMAIL_SYNTAX */ + gettext("GETEMAIL user@email-host No WildCards!!"), + /* NICK_GETEMAIL_EMAILS_ARE */ + gettext("Emails Match %s to %s."), + /* NICK_GETEMAIL_NOT_USED */ + gettext("No Emails listed for %s."), + /* NICK_SENDPASS_SYNTAX */ + gettext("SENDPASS nickname"), + /* NICK_SENDPASS_UNAVAILABLE */ + gettext("SENDPASS command unavailable because encryption is in use."), + /* NICK_SENDPASS_SUBJECT */ + gettext("Nickname password (%s)"), + /* NICK_SENDPASS */ + gettext("Hi,\n" + " \n" + "You have requested to receive the password of nickname %s by e-mail.\n" + "The password is %s. For security purposes, you should change it as soon as you receive this mail.\n" + " \n" + "If you don't know why this mail was sent to you, please ignore it silently.\n" + " \n" + "%s administrators."), + /* NICK_SENDPASS_OK */ + gettext("Password of %s has been sent."), + /* NICK_RESETPASS_SYNTAX */ + gettext("RESETPASS nickname"), + /* NICK_RESETPASS_SUBJECT */ + gettext("Reset password request for %s"), + /* NICK_RESETPASS_MESSAGE */ + gettext("Hi,\n" + " \n" + "You have requested to have the password for %s reset.\n" + "To reset your password, type %R%s CONFIRM %s\n" + " \n" + "If you don't know why this mail was sent to you, please ignore it silently.\n" + " \n" + "%s administrators."), + /* NICK_RESETPASS_COMPLETE */ + gettext("Password reset email for %s has been sent."), + /* NICK_SUSPEND_SYNTAX */ + gettext("SUSPEND nickname reason"), + /* NICK_SUSPEND_SUCCEEDED */ + gettext("Nick %s is now suspended."), + /* NICK_SUSPEND_FAILED */ + gettext("Couldn't suspend nick %s!"), + /* NICK_UNSUSPEND_SYNTAX */ + gettext("UNSUSPEND nickname"), + /* NICK_UNSUSPEND_SUCCEEDED */ + gettext("Nick %s is now released."), + /* NICK_UNSUSPEND_FAILED */ + gettext("Couldn't release nick %s!"), + /* NICK_FORBID_SYNTAX */ + gettext("FORBID nickname [reason]"), + /* NICK_FORBID_SYNTAX_REASON */ + gettext("FORBID nickname reason"), + /* NICK_FORBID_SUCCEEDED */ + gettext("Nick %s is now forbidden."), + /* NICK_FORBID_FAILED */ + gettext("Couldn't forbid nick %s!"), + /* NICK_REQUESTED */ + gettext("This nick has already been requested, please check your e-mail address for the pass code"), + /* NICK_REG_RESENT */ + gettext("Your passcode has been re-sent to %s."), + /* NICK_REG_UNABLE */ + gettext("Nick NOT registered, please try again later."), + /* NICK_IS_PREREG */ + gettext("This nick is awaiting an e-mail verification code before completing registration."), + /* NICK_ENTER_REG_CODE */ + gettext("A passcode has been sent to %s, please type %R%s confirm to complete registration"), + /* NICK_GETPASS_PASSCODE_IS */ + gettext("Passcode for %s is %s."), + /* NICK_FORCE_REG */ + gettext("Nickname %s confirmed"), + /* NICK_REG_MAIL_SUBJECT */ + gettext("Nickname Registration (%s)"), + /* NICK_REG_MAIL */ + gettext("Hi,\n" + " \n" + "You have requested to register the nickname %s on %s.\n" + "Please type \" %R%s confirm %s \" to complete registration.\n" + " \n" + "If you don't know why this mail was sent to you, please ignore it silently.\n" + " \n" + "%s administrators."), + /* NICK_CONFIRM_NOT_FOUND */ + gettext("Registration step 1 may have expired, please use \"%R%s register \" first."), + /* NICK_CONFIRM_INVALID */ + gettext("Invalid passcode has been entered, please check the e-mail again, and retry"), + /* NICK_CONFIRM_EXPIRED */ + gettext("Your password reset request has expired."), + /* NICK_CONFIRM_SUCCESS */ + gettext("You are now identified for your nick. Change your password using \"%R%s SET PASSWORD newpassword\" now."), + /* CHAN_LEVEL_AUTOOP */ + gettext("Automatic channel operator status"), + /* CHAN_LEVEL_AUTOVOICE */ + gettext("Automatic mode +v"), + /* CHAN_LEVEL_AUTOHALFOP */ + gettext("Automatic mode +h"), + /* CHAN_LEVEL_AUTOPROTECT */ + gettext("Automatic mode +a"), + /* CHAN_LEVEL_AUTODEOP */ + gettext("Channel operator status disallowed"), + /* CHAN_LEVEL_NOJOIN */ + gettext("Not allowed to join channel"), + /* CHAN_LEVEL_INVITE */ + gettext("Allowed to use INVITE command"), + /* CHAN_LEVEL_AKICK */ + gettext("Allowed to use AKICK command"), + /* CHAN_LEVEL_SET */ + gettext("Allowed to use SET command (not FOUNDER/PASSWORD)"), + /* CHAN_LEVEL_CLEAR */ + gettext("Allowed to use CLEAR command"), + /* CHAN_LEVEL_UNBAN */ + gettext("Allowed to use UNBAN command"), + /* CHAN_LEVEL_OPDEOP */ + gettext("Allowed to use OP/DEOP commands"), + /* CHAN_LEVEL_ACCESS_LIST */ + gettext("Allowed to view the access list"), + /* CHAN_LEVEL_ACCESS_CHANGE */ + gettext("Allowed to modify the access list"), + /* CHAN_LEVEL_MEMO */ + gettext("Allowed to list/read channel memos"), + /* CHAN_LEVEL_ASSIGN */ + gettext("Allowed to assign/unassign a bot"), + /* CHAN_LEVEL_BADWORDS */ + gettext("Allowed to use BADWORDS command"), + /* CHAN_LEVEL_NOKICK */ + gettext("Never kicked by the bot's kickers"), + /* CHAN_LEVEL_FANTASIA */ + gettext("Allowed to use fantaisist commands"), + /* CHAN_LEVEL_SAY */ + gettext("Allowed to use SAY and ACT commands"), + /* CHAN_LEVEL_GREET */ + gettext("Greet message displayed"), + /* CHAN_LEVEL_VOICEME */ + gettext("Allowed to (de)voice him/herself"), + /* CHAN_LEVEL_VOICE */ + gettext("Allowed to use VOICE/DEVOICE commands"), + /* CHAN_LEVEL_GETKEY */ + gettext("Allowed to use GETKEY command"), + /* CHAN_LEVEL_OPDEOPME */ + gettext("Allowed to (de)op him/herself"), + /* CHAN_LEVEL_HALFOPME */ + gettext("Allowed to (de)halfop him/herself"), + /* CHAN_LEVEL_HALFOP */ + gettext("Allowed to use HALFOP/DEHALFOP commands"), + /* CHAN_LEVEL_PROTECTME */ + gettext("Allowed to (de)protect him/herself"), + /* CHAN_LEVEL_PROTECT */ + gettext("Allowed to use PROTECT/DEPROTECT commands"), + /* CHAN_LEVEL_KICKME */ + gettext("Allowed to kick him/herself"), + /* CHAN_LEVEL_KICK */ + gettext("Allowed to use KICK command"), + /* CHAN_LEVEL_SIGNKICK */ + gettext("No signed kick when SIGNKICK LEVEL is used"), + /* CHAN_LEVEL_BANME */ + gettext("Allowed to ban him/herself"), + /* CHAN_LEVEL_BAN */ + gettext("Allowed to use BAN command"), + /* CHAN_LEVEL_TOPIC */ + gettext("Allowed to use TOPIC command"), + /* CHAN_LEVEL_INFO */ + gettext("Allowed to use INFO command with ALL option"), + /* CHAN_LEVEL_AUTOOWNER */ + gettext("Automatic mode +q"), + /* CHAN_LEVEL_OWNER */ + gettext("Allowed to use OWNER command"), + /* CHAN_LEVEL_OWNERME */ + gettext("Allowed to (de)owner him/herself"), + /* CHAN_LEVEL_FOUNDER */ + gettext("Allowed to issue commands restricted to channel founders"), + /* CHAN_IS_REGISTERED */ + gettext("This channel has been registered with %s."), + /* CHAN_NOT_ALLOWED_OP */ + gettext("You are not allowed chanop status on channel %s."), + /* CHAN_MAY_NOT_BE_USED */ + gettext("This channel may not be used."), + /* CHAN_NOT_ALLOWED_TO_JOIN */ + gettext("You are not permitted to be on this channel."), + /* CHAN_X_INVALID */ + gettext("Channel %s is not a valid channel."), + /* CHAN_REGISTER_SYNTAX */ + gettext("REGISTER channel description"), + /* CHAN_REGISTER_DISABLED */ + gettext("Sorry, channel registration is temporarily disabled."), + /* CHAN_REGISTER_NOT_LOCAL */ + gettext("Local channels cannot be registered."), + /* CHAN_MAY_NOT_BE_REGISTERED */ + gettext("Channel %s may not be registered."), + /* CHAN_ALREADY_REGISTERED */ + gettext("Channel %s is already registered!"), + /* CHAN_MUST_BE_CHANOP */ + gettext("You must be a channel operator to register the channel."), + /* CHAN_REACHED_CHANNEL_LIMIT */ + gettext("Sorry, you have already reached your limit of %d channels."), + /* CHAN_EXCEEDED_CHANNEL_LIMIT */ + gettext("Sorry, you have already exceeded your limit of %d channels."), + /* CHAN_REGISTERED */ + gettext("Channel %s registered under your nickname: %s"), + /* CHAN_REGISTER_NONE_CHANNEL */ + gettext("You have attempted to register a nonexistent channel %s"), + /* CHAN_SYMBOL_REQUIRED */ + gettext("Please use the symbol of # when attempting to register"), + /* CHAN_DROP_SYNTAX */ + gettext("DROP channel"), + /* CHAN_DROP_DISABLED */ + gettext("Sorry, channel de-registration is temporarily disabled."), + /* CHAN_DROPPED */ + gettext("Channel %s has been dropped."), + /* CHAN_SASET_SYNTAX */ + gettext("SASET channel option parameters"), + /* CHAN_SASET_KEEPTOPIC_SYNTAX */ + gettext("SASET channel KEEPTOPIC {ON | OFF}"), + /* CHAN_SASET_OPNOTICE_SYNTAX */ + gettext("SASET channel OPNOTICE {ON | OFF}"), + /* CHAN_SASET_PEACE_SYNTAX */ + gettext("SASET channel PEACE {ON | OFF}"), + /* CHAN_SASET_PERSIST_SYNTAX */ + gettext("SASET channel PERSIST {ON | OFF}"), + /* CHAN_SASET_PRIVATE_SYNTAX */ + gettext("SASET channel PRIVATE {ON | OFF}"), + /* CHAN_SASET_RESTRICTED_SYNTAX */ + gettext("SASET channel RESTRICTED {ON | OFF}"), + /* CHAN_SASET_SECURE_SYNTAX */ + gettext("SASET channel SECURE {ON | OFF}"), + /* CHAN_SASET_SECUREFOUNDER_SYNTAX */ + gettext("SASET channel SECUREFOUNDER {ON | OFF}"), + /* CHAN_SASET_SECUREOPS_SYNTAX */ + gettext("SASET channel SECUREOPS {ON | OFF}"), + /* CHAN_SASET_SIGNKICK_SYNTAX */ + gettext("SASET channel SIGNKICK {ON | OFF}"), + /* CHAN_SASET_TOPICLOCK_SYNTAX */ + gettext("SASET channel TOPICLOCK {ON | OFF}"), + /* CHAN_SASET_XOP_SYNTAX */ + gettext("SASET channel XOP {ON | OFF}"), + /* CHAN_SET_SYNTAX */ + gettext("SET channel option parameters"), + /* CHAN_SET_DISABLED */ + gettext("Sorry, channel option setting is temporarily disabled."), + /* CHAN_SETTING_CHANGED */ + gettext("%s for %s set to %s."), + /* CHAN_SETTING_UNSET */ + gettext("%s for %s unset."), + /* CHAN_SET_FOUNDER_TOO_MANY_CHANS */ + gettext("%s has too many channels registered."), + /* CHAN_FOUNDER_CHANGED */ + gettext("Founder of %s changed to %s."), + /* CHAN_SUCCESSOR_CHANGED */ + gettext("Successor for %s changed to %s."), + /* CHAN_SUCCESSOR_UNSET */ + gettext("Successor for %s unset."), + /* CHAN_SUCCESSOR_IS_FOUNDER */ + gettext("%s cannot be the successor on channel %s because he is its founder."), + /* CHAN_DESC_CHANGED */ + gettext("Description of %s changed to %s."), + /* CHAN_EMAIL_CHANGED */ + gettext("E-mail address for %s changed to %s."), + /* CHAN_EMAIL_UNSET */ + gettext("E-mail address for %s unset."), + /* CHAN_ENTRY_MSG_CHANGED */ + gettext("Entry message for %s changed."), + /* CHAN_ENTRY_MSG_UNSET */ + gettext("Entry message for %s unset."), + /* CHAN_SET_BANTYPE_INVALID */ + gettext("%s is not a valid ban type."), + /* CHAN_SET_BANTYPE_CHANGED */ + gettext("Ban type for channel %s is now #%d."), + /* CHAN_SET_MLOCK_UNKNOWN_CHAR */ + gettext("Unknown mode character %c ignored."), + /* CHAN_SET_MLOCK_IMPOSSIBLE_CHAR */ + gettext("Mode %c ignored because you can't lock it."), + /* CHAN_SET_MLOCK_L_REQUIRED */ + gettext("You must lock mode +l as well to lock mode +L."), + /* CHAN_SET_MLOCK_K_REQUIRED */ + gettext("You must lock mode +i as well to lock mode +K."), + /* CHAN_MLOCK_CHANGED */ + gettext("Mode lock on channel %s changed to %s."), + /* CHAN_SET_KEEPTOPIC_SYNTAX */ + gettext("SET channel KEEPTOPIC {ON | OFF}"), + /* CHAN_SET_KEEPTOPIC_ON */ + gettext("Topic retention option for %s is now ON."), + /* CHAN_SET_KEEPTOPIC_OFF */ + gettext("Topic retention option for %s is now OFF."), + /* CHAN_SET_TOPICLOCK_SYNTAX */ + gettext("SET channel TOPICLOCK {ON | OFF}"), + /* CHAN_SET_TOPICLOCK_ON */ + gettext("Topic lock option for %s is now ON."), + /* CHAN_SET_TOPICLOCK_OFF */ + gettext("Topic lock option for %s is now OFF."), + /* CHAN_SET_PEACE_SYNTAX */ + gettext("SET channel PEACE {ON | OFF}"), + /* CHAN_SET_PEACE_ON */ + gettext("Peace option for %s is now ON."), + /* CHAN_SET_PEACE_OFF */ + gettext("Peace option for %s is now OFF."), + /* CHAN_SET_PRIVATE_SYNTAX */ + gettext("SET channel PRIVATE {ON | OFF}"), + /* CHAN_SET_PRIVATE_ON */ + gettext("Private option for %s is now ON."), + /* CHAN_SET_PRIVATE_OFF */ + gettext("Private option for %s is now OFF."), + /* CHAN_SET_SECUREOPS_SYNTAX */ + gettext("SET channel SECUREOPS {ON | OFF}"), + /* CHAN_SET_SECUREOPS_ON */ + gettext("Secure ops option for %s is now ON."), + /* CHAN_SET_SECUREOPS_OFF */ + gettext("Secure ops option for %s is now OFF."), + /* CHAN_SET_SECUREFOUNDER_SYNTAX */ + gettext("SET channel SECUREFOUNDER {ON | OFF}"), + /* CHAN_SET_SECUREFOUNDER_ON */ + gettext("Secure founder option for %s is now ON."), + /* CHAN_SET_SECUREFOUNDER_OFF */ + gettext("Secure founder option for %s is now OFF."), + /* CHAN_SET_RESTRICTED_SYNTAX */ + gettext("SET channel RESTRICTED {ON | OFF}"), + /* CHAN_SET_RESTRICTED_ON */ + gettext("Restricted access option for %s is now ON."), + /* CHAN_SET_RESTRICTED_OFF */ + gettext("Restricted access option for %s is now OFF."), + /* CHAN_SET_SECURE_SYNTAX */ + gettext("SET channel SECURE {ON | OFF}"), + /* CHAN_SET_SECURE_ON */ + gettext("Secure option for %s is now ON."), + /* CHAN_SET_SECURE_OFF */ + gettext("Secure option for %s is now OFF."), + /* CHAN_SET_SIGNKICK_SYNTAX */ + gettext("SET channel SIGNKICK {ON | LEVEL | OFF}"), + /* CHAN_SET_SIGNKICK_ON */ + gettext("Signed kick option for %s is now ON."), + /* CHAN_SET_SIGNKICK_LEVEL */ + gettext("Signed kick option for %s is now ON, but depends of the\n" + "level of the user that is using the command."), + /* CHAN_SET_SIGNKICK_OFF */ + gettext("Signed kick option for %s is now OFF."), + /* CHAN_SET_OPNOTICE_SYNTAX */ + gettext("SET channel OPNOTICE {ON | OFF}"), + /* CHAN_SET_OPNOTICE_ON */ + gettext("Op-notice option for %s is now ON."), + /* CHAN_SET_OPNOTICE_OFF */ + gettext("Op-notice option for %s is now OFF."), + /* CHAN_SET_XOP_SYNTAX */ + gettext("SET channel XOP {ON | OFF}"), + /* CHAN_SET_XOP_ON */ + gettext("xOP lists system for %s is now ON."), + /* CHAN_SET_XOP_OFF */ + gettext("xOP lists system for %s is now OFF."), + /* CHAN_SET_PERSIST_SYNTAX */ + gettext("SET channel PERSIST {ON | OFF}"), + /* CHAN_SET_PERSIST_ON */ + gettext("Channel %s is now persistant."), + /* CHAN_SET_PERSIST_OFF */ + gettext("Channel %s is no longer persistant."), + /* CHAN_SET_NOEXPIRE_SYNTAX */ + gettext("SET channel NOEXPIRE {ON | OFF}"), + /* CHAN_SET_NOEXPIRE_ON */ + gettext("Channel %s will not expire."), + /* CHAN_SET_NOEXPIRE_OFF */ + gettext("Channel %s will expire."), + /* CHAN_XOP_REACHED_LIMIT */ + gettext("Sorry, you can only have %d AOP/SOP/VOP entries on a channel."), + /* CHAN_XOP_LIST_FORMAT */ + gettext(" %3d %s"), + /* CHAN_XOP_ACCESS */ + gettext("You can't use this command. Use the ACCESS command instead.\n" + "Type %R%s HELP ACCESS for more information."), + /* CHAN_XOP_NOT_AVAILABLE */ + gettext("xOP system is not available."), + /* CHAN_QOP_SYNTAX */ + gettext("QOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"), + /* CHAN_QOP_DISABLED */ + gettext("Sorry, channel QOP list modification is temporarily disabled."), + /* CHAN_QOP_NICKS_ONLY */ + gettext("Channel QOP lists may only contain registered nicknames."), + /* CHAN_QOP_ADDED */ + gettext("%s added to %s QOP list."), + /* CHAN_QOP_MOVED */ + gettext("%s moved to %s QOP list."), + /* CHAN_QOP_NO_SUCH_ENTRY */ + gettext("No such entry (#%d) on %s QOP list."), + /* CHAN_QOP_NOT_FOUND */ + gettext("%s not found on %s QOP list."), + /* CHAN_QOP_NO_MATCH */ + gettext("No matching entries on %s QOP list."), + /* CHAN_QOP_DELETED */ + gettext("%s deleted from %s QOP list."), + /* CHAN_QOP_DELETED_ONE */ + gettext("Deleted 1 entry from %s QOP list."), + /* CHAN_QOP_DELETED_SEVERAL */ + gettext("Deleted %d entries from %s QOP list."), + /* CHAN_QOP_LIST_EMPTY */ + gettext("%s QOP list is empty."), + /* CHAN_QOP_LIST_HEADER */ + gettext("QOP list for %s:\n" + " Num Nick"), + /* CHAN_QOP_CLEAR */ + gettext("Channel %s QOP list has been cleared."), + /* CHAN_AOP_SYNTAX */ + gettext("AOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"), + /* CHAN_AOP_DISABLED */ + gettext("Sorry, channel AOP list modification is temporarily disabled."), + /* CHAN_AOP_NICKS_ONLY */ + gettext("Channel AOP lists may only contain registered nicknames."), + /* CHAN_AOP_ADDED */ + gettext("%s added to %s AOP list."), + /* CHAN_AOP_MOVED */ + gettext("%s moved to %s AOP list."), + /* CHAN_AOP_NO_SUCH_ENTRY */ + gettext("No such entry (#%d) on %s AOP list."), + /* CHAN_AOP_NOT_FOUND */ + gettext("%s not found on %s AOP list."), + /* CHAN_AOP_NO_MATCH */ + gettext("No matching entries on %s AOP list."), + /* CHAN_AOP_DELETED */ + gettext("%s deleted from %s AOP list."), + /* CHAN_AOP_DELETED_ONE */ + gettext("Deleted 1 entry from %s AOP list."), + /* CHAN_AOP_DELETED_SEVERAL */ + gettext("Deleted %d entries from %s AOP list."), + /* CHAN_AOP_LIST_EMPTY */ + gettext("%s AOP list is empty."), + /* CHAN_AOP_LIST_HEADER */ + gettext("AOP list for %s:\n" + " Num Nick"), + /* CHAN_AOP_CLEAR */ + gettext("Channel %s AOP list has been cleared."), + /* CHAN_HOP_SYNTAX */ + gettext("HOP channel {ADD|DEL|LIST|CLEAR} [nick | entry-list]"), + /* CHAN_HOP_DISABLED */ + gettext("Sorry, channel HOP list modification is temporarily disabled."), + /* CHAN_HOP_NICKS_ONLY */ + gettext("Channel HOP lists may only contain registered nicknam