ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/numeric.c
Revision: 1618
Committed: Tue Oct 30 21:04:38 2012 UTC (12 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 5921 byte(s)
Log Message:
- Made m_globops() and ms_globops() use sendto_realops_flags()
- Added message-type parameter to sendto_realops_flags() which can be one of
  SEND_NOTICE, SEND_GLOBAL, SEND_LOCOPS
- Forward-port -r1617

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 "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 michael 1247 ilog(LOG_TYPE_IRCD, "Incompatible format symbols (%s.lang, %d)",
93     locale, linecnt);
94 adx 30 return 0;
95     }
96     found = 1;
97     break;
98     }
99     }
100     }
101     if (!found)
102     {
103 michael 1247 ilog(LOG_TYPE_IRCD, "Too many format symbols (%s.lang, %d)", locale, linecnt);
104 adx 30 return(0);
105     }
106     }
107     }
108     }
109    
110     MyFree(replies[reply].translated);
111     DupString(replies[reply].translated, 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 michael 1325 FILE *f;
123 adx 30
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 michael 1325 if ((f = fopen(buffer, "r")) == NULL)
146 adx 30 {
147     strlcpy(used_locale, "standard", sizeof(used_locale)); /* XXX */
148     return;
149     }
150    
151     /* Process the language file */
152 michael 1325 while (fgets(buffer, sizeof(buffer), f))
153 adx 30 {
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 michael 1247 ilog(LOG_TYPE_IRCD, "Invalid line in language file (%s.lang, %d)",
178     locale, linecnt);
179 adx 30 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 michael 1247 ilog(LOG_TYPE_IRCD,
208 adx 30 "Unknown numeric %s (%s.lang, %d)", ident, locale, linecnt);
209     res = 0;
210     }
211     }
212 michael 1325 fclose(f);
213 adx 30
214     strlcpy(used_locale, locale, sizeof(used_locale));
215     if (!res)
216 michael 1618 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
217     "Language file [%s] contains "
218 adx 30 "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