ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/numeric.c
Revision: 1834
Committed: Fri Apr 19 19:50:27 2013 UTC (10 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 5920 byte(s)
Log Message:
- Revert to -r1831

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * numeric.c: Numeric handling functions.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26
27 #include "numeric.h"
28 #include "irc_string.h"
29 #include "memory.h"
30 #include "log.h"
31 #include "send.h"
32 #include "client.h"
33 #include "messages.tab"
34
35 static char used_locale[LOCALE_LENGTH] = "standard";
36
37 /*
38 * form_str
39 *
40 * inputs - numeric
41 * output - corresponding string
42 * side effects - NONE
43 */
44 const char* form_str(int numeric)
45 {
46 assert(-1 < numeric);
47 assert(numeric < ERR_LAST_ERR_MSG);
48
49 if (numeric > ERR_LAST_ERR_MSG)
50 numeric = ERR_LAST_ERR_MSG;
51 if (numeric < 0)
52 numeric = ERR_LAST_ERR_MSG;
53
54 assert(replies[numeric].standard != NULL);
55
56 return (replies[numeric].translated != NULL ? replies[numeric].translated :
57 replies[numeric].standard);
58 }
59
60 /* Attempts to change a numeric with index "reply" to "new_reply".
61 * Returns 1 if ok, 0 otherwise.
62 */
63 static int
64 change_reply(const char *locale, int linecnt, int reply, char *new_reply)
65 {
66 int found;
67 char *new = new_reply;
68 const char *old = replies[reply].standard;
69
70 for (; *new; new++)
71 {
72 if (*new == '%')
73 {
74 if (!*++new) break;
75 if (*new != '%')
76 {
77 /* We've just found a format symbol. Check if it is the next format
78 * symbol in the original reply.
79 */
80 for (; *new >= '0' && *new <= '9'; new++); /* skip size prefix */
81 found = 0;
82 for (; *old; old++)
83 {
84 if (*old == '%')
85 {
86 if (!*++old) break; /* shouldn't happen */
87 if (*old != '%')
88 {
89 for (; *old >= '0' && *old <= '9'; old++); /* skip size prefix */
90 if (*new != *old++)
91 {
92 ilog(LOG_TYPE_IRCD, "Incompatible format symbols (%s.lang, %d)",
93 locale, linecnt);
94 return 0;
95 }
96 found = 1;
97 break;
98 }
99 }
100 }
101 if (!found)
102 {
103 ilog(LOG_TYPE_IRCD, "Too many format symbols (%s.lang, %d)", locale, linecnt);
104 return(0);
105 }
106 }
107 }
108 }
109
110 MyFree(replies[reply].translated);
111 replies[reply].translated = xstrdup(new_reply);
112 return(1);
113 }
114
115 /* Loads a language file. Errors are logged into the log file. */
116 void
117 set_locale(const char *locale)
118 {
119 int i, res = 1, linecnt = 0;
120 char buffer[IRCD_BUFSIZE + 1];
121 char *ident, *reply;
122 FILE *f;
123
124 /* Restore standard replies */
125 for (i = 0; i <= ERR_LAST_ERR_MSG; i++) /* 0 isn't a magic number! ;> */
126 {
127 if (replies[i].translated != NULL)
128 {
129 MyFree(replies[i].translated);
130 replies[i].translated = NULL;
131 }
132 }
133
134 if (strchr(locale, '/') != NULL)
135 {
136 strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX paranoid */
137 return;
138 }
139
140 /* yes, I know - the slash isn't necessary. But I have to be sure
141 * that it'll work even if some lame admin won't put "/" at the end
142 * of MSGPATH.
143 */
144 snprintf(buffer, sizeof(buffer), "%s/%s.lang", MSGPATH, locale);
145 if ((f = fopen(buffer, "r")) == NULL)
146 {
147 strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX */
148 return;
149 }
150
151 /* Process the language file */
152 while (fgets(buffer, sizeof(buffer), f))
153 {
154 ++linecnt;
155 if (buffer[0] == ';')
156 continue; /* that's a comment */
157
158 if ((ident = strpbrk(buffer, "\r\n")) != NULL)
159 *ident = '\0';
160
161 /* skip spaces if there are any */
162 for (ident = buffer; *ident == ' ' || *ident == '\t'; ident++)/* null */;
163 if (*ident == '\0')
164 continue; /* empty line */
165
166 /* skip after the reply identificator */
167 for (reply = ident; *reply != ' ' && *reply != '\t' && *reply != ':';
168 reply++)
169 if (*reply == '\0') goto error;
170
171 if (*reply == ' ' || *reply == '\t')
172 {
173 for (*reply++ = '\0'; *reply == ' ' || *reply == '\t'; reply++);
174 if (*reply != ':')
175 {
176 error:
177 ilog(LOG_TYPE_IRCD, "Invalid line in language file (%s.lang, %d)",
178 locale, linecnt);
179 res = 0;
180 continue;
181 }
182 }
183 else
184 *reply++ = '\0';
185 if (*ident == '\0')
186 goto error;
187
188 /* skip to the beginning of reply */
189 while (*reply == ' ' || *reply == '\t') reply++;
190 if (*reply == '\0')
191 goto error;
192
193 for (i = 0; i <= ERR_LAST_ERR_MSG; i++)
194 {
195 if (replies[i].name != NULL)
196 {
197 if (irccmp(replies[i].name, ident) == 0)
198 {
199 if (!change_reply(locale, linecnt, i, reply)) res = 0;
200 i = -1;
201 break;
202 }
203 }
204 }
205 if (i != -1)
206 {
207 ilog(LOG_TYPE_IRCD,
208 "Unknown numeric %s (%s.lang, %d)", ident, locale, linecnt);
209 res = 0;
210 }
211 }
212 fclose(f);
213
214 strlcpy(used_locale, locale, sizeof(used_locale));
215 if (!res)
216 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
217 "Language file [%s] contains "
218 "errors, check server log file for more details",
219 used_locale);
220 }
221
222 /* Returns the name of current locale. */
223 const char *
224 get_locale(void)
225 {
226 return used_locale;
227 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision