00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026
00027 #include "numeric.h"
00028 #include "irc_string.h"
00029 #include "common.h"
00030 #include "memory.h"
00031 #include "s_log.h"
00032 #include "fileio.h"
00033 #include "send.h"
00034 #include "client.h"
00035 #include "messages.tab"
00036
00037 static char used_locale[LOCALE_LENGTH] = "standard";
00038
00039
00040
00041
00042
00043
00044
00045
00046 const char* form_str(int numeric)
00047 {
00048 assert(-1 < numeric);
00049 assert(numeric < ERR_LAST_ERR_MSG);
00050
00051 if (numeric > ERR_LAST_ERR_MSG)
00052 numeric = ERR_LAST_ERR_MSG;
00053 if (numeric < 0)
00054 numeric = ERR_LAST_ERR_MSG;
00055
00056 assert(replies[numeric].standard != NULL);
00057
00058 return (replies[numeric].translated != NULL ? replies[numeric].translated :
00059 replies[numeric].standard);
00060 }
00061
00062
00063
00064
00065 static int
00066 change_reply(const char *locale, int linecnt, int reply, char *new_reply)
00067 {
00068 int found;
00069 char *new = new_reply;
00070 const char *old = replies[reply].standard;
00071
00072 for (; *new; new++)
00073 {
00074 if (*new == '%')
00075 {
00076 if (!*++new) break;
00077 if (*new != '%')
00078 {
00079
00080
00081
00082 for (; *new >= '0' && *new <= '9'; new++);
00083 found = 0;
00084 for (; *old; old++)
00085 {
00086 if (*old == '%')
00087 {
00088 if (!*++old) break;
00089 if (*old != '%')
00090 {
00091 for (; *old >= '0' && *old <= '9'; old++);
00092 if (*new != *old++)
00093 {
00094 ilog(L_ERROR, "Incompatible format symbols (%s.lang, %d)",
00095 locale, linecnt);
00096 return 0;
00097 }
00098 found = 1;
00099 break;
00100 }
00101 }
00102 }
00103 if (!found)
00104 {
00105 ilog(L_ERROR, "Too many format symbols (%s.lang, %d)", locale, linecnt);
00106 return(0);
00107 }
00108 }
00109 }
00110 }
00111
00112 MyFree(replies[reply].translated);
00113 DupString(replies[reply].translated, new_reply);
00114 return(1);
00115 }
00116
00117
00118 void
00119 set_locale(const char *locale)
00120 {
00121 int i, res = 1, linecnt = 0;
00122 char buffer[IRCD_BUFSIZE + 1];
00123 char *ident, *reply;
00124 FBFILE *f;
00125
00126
00127 for (i = 0; i <= ERR_LAST_ERR_MSG; i++)
00128 {
00129 if (replies[i].translated != NULL)
00130 {
00131 MyFree(replies[i].translated);
00132 replies[i].translated = NULL;
00133 }
00134 }
00135
00136 if (strchr(locale, '/') != NULL)
00137 {
00138 strlcpy(used_locale, "standard", sizeof(used_locale));
00139 return;
00140 }
00141
00142
00143
00144
00145
00146 snprintf(buffer, sizeof(buffer), "%s/%s.lang", MSGPATH, locale);
00147 if ((f = fbopen(buffer, "r")) == NULL)
00148 {
00149 strlcpy(used_locale, "standard", sizeof(used_locale));
00150 return;
00151 }
00152
00153
00154 while (fbgets(buffer, sizeof(buffer), f))
00155 {
00156 ++linecnt;
00157 if (buffer[0] == ';')
00158 continue;
00159
00160 if ((ident = strpbrk(buffer, "\r\n")) != NULL)
00161 *ident = '\0';
00162
00163
00164 for (ident = buffer; *ident == ' ' || *ident == '\t'; ident++);
00165 if (*ident == '\0')
00166 continue;
00167
00168
00169 for (reply = ident; *reply != ' ' && *reply != '\t' && *reply != ':';
00170 reply++)
00171 if (*reply == '\0') goto error;
00172
00173 if (*reply == ' ' || *reply == '\t')
00174 {
00175 for (*reply++ = '\0'; *reply == ' ' || *reply == '\t'; reply++);
00176 if (*reply != ':')
00177 {
00178 error:
00179 ilog(L_ERROR, "Invalid line in language file (%s.lang, %d)",
00180 locale, linecnt);
00181 res = 0;
00182 continue;
00183 }
00184 }
00185 else
00186 *reply++ = '\0';
00187 if (*ident == '\0')
00188 goto error;
00189
00190
00191 while (*reply == ' ' || *reply == '\t') reply++;
00192 if (*reply == '\0')
00193 goto error;
00194
00195 for (i = 0; i <= ERR_LAST_ERR_MSG; i++)
00196 {
00197 if (replies[i].name != NULL)
00198 {
00199 if (irccmp(replies[i].name, ident) == 0)
00200 {
00201 if (!change_reply(locale, linecnt, i, reply)) res = 0;
00202 i = -1;
00203 break;
00204 }
00205 }
00206 }
00207 if (i != -1)
00208 {
00209 ilog(L_ERROR,
00210 "Unknown numeric %s (%s.lang, %d)", ident, locale, linecnt);
00211 res = 0;
00212 }
00213 }
00214 fbclose(f);
00215
00216 strlcpy(used_locale, locale, sizeof(used_locale));
00217 if (!res)
00218 sendto_realops_flags(UMODE_ALL, L_ADMIN, "Language file [%s] contains "
00219 "errors, check server log file for more details",
00220 used_locale);
00221 }
00222
00223
00224 const char *
00225 get_locale(void)
00226 {
00227 return used_locale;
00228 }