ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/numeric.c
Revision: 1243
Committed: Fri Sep 30 10:47:53 2011 UTC (14 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/src/numeric.c
File size: 5890 byte(s)
Log Message:
- move content of msg.h, ircd_handler.h and handlers.h into parse.h and
  remove headers accordingly
- killed common.h
- remove m_killhost.c and m_flags.c from contrib/
- sort out unused header includes here and there

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 "s_log.h"
31 #include "fileio.h"
32 #include "send.h"
33 #include "client.h"
34 #include "messages.tab"
35
36 static char used_locale[LOCALE_LENGTH] = "standard";
37
38 /*
39 * form_str
40 *
41 * inputs - numeric
42 * output - corresponding string
43 * side effects - NONE
44 */
45 const char* form_str(int numeric)
46 {
47 assert(-1 < numeric);
48 assert(numeric < ERR_LAST_ERR_MSG);
49
50 if (numeric > ERR_LAST_ERR_MSG)
51 numeric = ERR_LAST_ERR_MSG;
52 if (numeric < 0)
53 numeric = ERR_LAST_ERR_MSG;
54
55 assert(replies[numeric].standard != NULL);
56
57 return (replies[numeric].translated != NULL ? replies[numeric].translated :
58 replies[numeric].standard);
59 }
60
61 /* Attempts to change a numeric with index "reply" to "new_reply".
62 * Returns 1 if ok, 0 otherwise.
63 */
64 static int
65 change_reply(const char *locale, int linecnt, int reply, char *new_reply)
66 {
67 int found;
68 char *new = new_reply;
69 const char *old = replies[reply].standard;
70
71 for (; *new; new++)
72 {
73 if (*new == '%')
74 {
75 if (!*++new) break;
76 if (*new != '%')
77 {
78 /* We've just found a format symbol. Check if it is the next format
79 * symbol in the original reply.
80 */
81 for (; *new >= '0' && *new <= '9'; new++); /* skip size prefix */
82 found = 0;
83 for (; *old; old++)
84 {
85 if (*old == '%')
86 {
87 if (!*++old) break; /* shouldn't happen */
88 if (*old != '%')
89 {
90 for (; *old >= '0' && *old <= '9'; old++); /* skip size prefix */
91 if (*new != *old++)
92 {
93 ilog(L_ERROR, "Incompatible format symbols (%s.lang, %d)",
94 locale, linecnt);
95 return 0;
96 }
97 found = 1;
98 break;
99 }
100 }
101 }
102 if (!found)
103 {
104 ilog(L_ERROR, "Too many format symbols (%s.lang, %d)", locale, linecnt);
105 return(0);
106 }
107 }
108 }
109 }
110
111 MyFree(replies[reply].translated);
112 DupString(replies[reply].translated, new_reply);
113 return(1);
114 }
115
116 /* Loads a language file. Errors are logged into the log file. */
117 void
118 set_locale(const char *locale)
119 {
120 int i, res = 1, linecnt = 0;
121 char buffer[IRCD_BUFSIZE + 1];
122 char *ident, *reply;
123 FBFILE *f;
124
125 /* Restore standard replies */
126 for (i = 0; i <= ERR_LAST_ERR_MSG; i++) /* 0 isn't a magic number! ;> */
127 {
128 if (replies[i].translated != NULL)
129 {
130 MyFree(replies[i].translated);
131 replies[i].translated = NULL;
132 }
133 }
134
135 if (strchr(locale, '/') != NULL)
136 {
137 strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX paranoid */
138 return;
139 }
140
141 /* yes, I know - the slash isn't necessary. But I have to be sure
142 * that it'll work even if some lame admin won't put "/" at the end
143 * of MSGPATH.
144 */
145 snprintf(buffer, sizeof(buffer), "%s/%s.lang", MSGPATH, locale);
146 if ((f = fbopen(buffer, "r")) == NULL)
147 {
148 strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX */
149 return;
150 }
151
152 /* Process the language file */
153 while (fbgets(buffer, sizeof(buffer), f))
154 {
155 ++linecnt;
156 if (buffer[0] == ';')
157 continue; /* that's a comment */
158
159 if ((ident = strpbrk(buffer, "\r\n")) != NULL)
160 *ident = '\0';
161
162 /* skip spaces if there are any */
163 for (ident = buffer; *ident == ' ' || *ident == '\t'; ident++)/* null */;
164 if (*ident == '\0')
165 continue; /* empty line */
166
167 /* skip after the reply identificator */
168 for (reply = ident; *reply != ' ' && *reply != '\t' && *reply != ':';
169 reply++)
170 if (*reply == '\0') goto error;
171
172 if (*reply == ' ' || *reply == '\t')
173 {
174 for (*reply++ = '\0'; *reply == ' ' || *reply == '\t'; reply++);
175 if (*reply != ':')
176 {
177 error:
178 ilog(L_ERROR, "Invalid line in language file (%s.lang, %d)",
179 locale, linecnt);
180 res = 0;
181 continue;
182 }
183 }
184 else
185 *reply++ = '\0';
186 if (*ident == '\0')
187 goto error;
188
189 /* skip to the beginning of reply */
190 while (*reply == ' ' || *reply == '\t') reply++;
191 if (*reply == '\0')
192 goto error;
193
194 for (i = 0; i <= ERR_LAST_ERR_MSG; i++)
195 {
196 if (replies[i].name != NULL)
197 {
198 if (irccmp(replies[i].name, ident) == 0)
199 {
200 if (!change_reply(locale, linecnt, i, reply)) res = 0;
201 i = -1;
202 break;
203 }
204 }
205 }
206 if (i != -1)
207 {
208 ilog(L_ERROR,
209 "Unknown numeric %s (%s.lang, %d)", ident, locale, linecnt);
210 res = 0;
211 }
212 }
213 fbclose(f);
214
215 strlcpy(used_locale, locale, sizeof(used_locale));
216 if (!res)
217 sendto_realops_flags(UMODE_ALL, L_ADMIN, "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