ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/numeric.c
Revision: 1309
Committed: Sun Mar 25 11:24:18 2012 UTC (13 years, 5 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/src/numeric.c
File size: 5908 byte(s)
Log Message:
- renaming files:

  ircd_parser.y -> conf_parser.y
  ircd_lexer.l  -> conf_lexer.l
  s_conf.c      -> conf.c
  s_conf.h      -> conf.h
  s_log.c       -> log.c
  s_log.h       -> log.h

File Contents

# User Rev Content
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 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26    
27     #include "numeric.h"
28     #include "irc_string.h"
29     #include "memory.h"
30 michael 1309 #include "log.h"
31 adx 30 #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 michael 1247 ilog(LOG_TYPE_IRCD, "Incompatible format symbols (%s.lang, %d)",
94     locale, linecnt);
95 adx 30 return 0;
96     }
97     found = 1;
98     break;
99     }
100     }
101     }
102     if (!found)
103     {
104 michael 1247 ilog(LOG_TYPE_IRCD, "Too many format symbols (%s.lang, %d)", locale, linecnt);
105 adx 30 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 michael 1247 ilog(LOG_TYPE_IRCD, "Invalid line in language file (%s.lang, %d)",
179     locale, linecnt);
180 adx 30 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 michael 1247 ilog(LOG_TYPE_IRCD,
209 adx 30 "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