/[svn]/ircd-hybrid/src/numeric.c
ViewVC logotype

Annotation of /ircd-hybrid/src/numeric.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations)
Sun Oct 2 20:03:27 2005 UTC (14 years, 6 months ago) by adx
File MIME type: text/x-chdr
File size: 5983 byte(s)
- imported sources
- can be moved later according to the directory/branching scheme,
  but we need the svn up

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

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26