ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/numeric.c
Revision: 69
Committed: Tue Oct 4 16:09:51 2005 UTC (19 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 5849 byte(s)
Log Message:
- splitted ircd/libio, all headers connected with libio sources have been
  moved for internal use only. To use libio interface, include "libio.h"
  (which is already done in "stdinc.h")


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

Properties

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