1 /*
2 * Written for BitchX by Colten Edwards (c) Feb 1999
3 */
4
5 #include "irc.h"
6 static char cvsrevision[] = "$Id: struct.c 110 2011-02-02 12:34:13Z keaston $";
7 CVS_REVISION(struct_c)
8 #include "struct.h"
9 #include "hash.h"
10 #include "hash2.h"
11 #include "misc.h"
12 #include "names.h"
13 #include "window.h"
14 #include "server.h"
15 #define MAIN_SOURCE
16 #include "modval.h"
17
18 extern char *after_expando(char *, int, int *);
19
20 /* the types of IrcVariables (repeated in vars.h) */
21 #define BOOL_TYPE_VAR 0
22 #define CHAR_TYPE_VAR 1
23 #define INT_TYPE_VAR 2
24 #define STR_TYPE_VAR 3
25 #define SPECIAL_TYPE_VAR 4
26
27 #define VAR_READ_WRITE 0
28 #define VAR_READ_ONLY 1
29
30 static char *struct_name[] = {"WINDOW", "CHANNEL", "NICK", "DCC", "CSET", "USERLIST", "SHITLIST", "BANS", "EXEMPTBANS", "SERVER", "" };
31
32 #define WINDOW_LOOKUP 0
33 #define CHANNEL_LOOKUP 1
34 #define NICKLIST_LOOKUP 2
35 #define DCC_LOOKUP 3
36 #define CSET_LOOKUP 4
37 #define USERLIST_LOOKUP 5
38 #define SHITLIST_LOOKUP 6
39 #define BANS_LOOKUP 7
40 #define EXEMPT_LOOKUP 8
41 #define SERVER_LOOKUP 9
42
43 typedef struct _lookup_struct
44 {
45 char *code;
46 int offset;
47 int type;
48 int readwrite;
49 } LookupStruct;
50
51 static LookupStruct server_struct[] = {
52 { "NAME", offsetof(Server, name), STR_TYPE_VAR, VAR_READ_ONLY },
53 { "ITSNAME", offsetof(Server, itsname), STR_TYPE_VAR, VAR_READ_ONLY },
54 { "PASSWORD", offsetof(Server, password), STR_TYPE_VAR, VAR_READ_WRITE },
55 { "SNETWORK", offsetof(Server, snetwork), STR_TYPE_VAR, VAR_READ_WRITE },
56 { "COOKIE", offsetof(Server, cookie), STR_TYPE_VAR, VAR_READ_ONLY },
57 { "PORT", offsetof(Server, port), INT_TYPE_VAR, VAR_READ_ONLY },
58
59 { "NICKNAME", offsetof(Server, nickname), STR_TYPE_VAR, VAR_READ_ONLY },
60 { "USERHOST", offsetof(Server, userhost), STR_TYPE_VAR, VAR_READ_WRITE },
61 { "NICKNAME_PENDING", offsetof(Server, nickname_pending), INT_TYPE_VAR, VAR_READ_ONLY },
62 { "ORIGNICK_PENDING", offsetof(Server, orignick_pending), INT_TYPE_VAR, VAR_READ_ONLY },
63
64 { "AWAY", offsetof(Server, away), STR_TYPE_VAR, VAR_READ_WRITE },
65 { "AWAYTIME", offsetof(Server, awaytime), INT_TYPE_VAR, VAR_READ_WRITE },
66 { "OPERATOR", offsetof(Server, operator), BOOL_TYPE_VAR, VAR_READ_ONLY },
67 { "SERVER2_8", offsetof(Server, server2_8), BOOL_TYPE_VAR, VAR_READ_WRITE },
68 { "VERSION", offsetof(Server, version), INT_TYPE_VAR, VAR_READ_WRITE },
69 { "VERSION_STRING", offsetof(Server, version_string), STR_TYPE_VAR, VAR_READ_ONLY },
70
71 { "UMODES", offsetof(Server, umodes), STR_TYPE_VAR, VAR_READ_ONLY },
72 { "UMODE", offsetof(Server, umode), CHAR_TYPE_VAR, VAR_READ_ONLY },
73
74 { "CONNECTED", offsetof(Server, connected), BOOL_TYPE_VAR, VAR_READ_ONLY },
75
76 { "WRITE", offsetof(Server, write), INT_TYPE_VAR, VAR_READ_ONLY },
77 { "READ", offsetof(Server, read), INT_TYPE_VAR, VAR_READ_ONLY },
78 { "EOF", offsetof(Server, eof), INT_TYPE_VAR, VAR_READ_ONLY },
79
80
81 { "CHANNEL", offsetof(Server, chan_list), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
82 { "ORIGNICK", offsetof(Server, orignick), STR_TYPE_VAR, VAR_READ_WRITE },
83 { "LAG", offsetof(Server, lag), INT_TYPE_VAR, VAR_READ_ONLY },
84 { NULL, 0, 0, 0 }
85 };
86
87 static LookupStruct channel_struct[] = {
88 { "CHANNEL", offsetof(ChannelList, channel), STR_TYPE_VAR, VAR_READ_ONLY },
89 { "SERVER", offsetof(ChannelList, server), INT_TYPE_VAR, VAR_READ_ONLY },
90 { "MODE", offsetof(ChannelList, s_mode), STR_TYPE_VAR, VAR_READ_ONLY },
91 { "TOPIC", offsetof(ChannelList, topic), STR_TYPE_VAR, VAR_READ_WRITE },
92 { "TOPIC_LOCK", offsetof(ChannelList, topic_lock), INT_TYPE_VAR, VAR_READ_WRITE },
93
94 { "LIMIT", offsetof(ChannelList, limit), INT_TYPE_VAR, VAR_READ_ONLY },
95 { "KEY", offsetof(ChannelList, key), STR_TYPE_VAR, VAR_READ_ONLY },
96 { "CHOP", offsetof(ChannelList, have_op), INT_TYPE_VAR, VAR_READ_ONLY },
97 { "HOP", offsetof(ChannelList, hop), INT_TYPE_VAR, VAR_READ_ONLY },
98 { "VOICE", offsetof(ChannelList, voice), INT_TYPE_VAR, VAR_READ_ONLY },
99 { "BOUND", offsetof(ChannelList, bound), INT_TYPE_VAR, VAR_READ_ONLY },
100 { "CHANPASS", offsetof(ChannelList, chanpass), STR_TYPE_VAR, VAR_READ_ONLY },
101 { "CONNECTED", offsetof(ChannelList, connected), INT_TYPE_VAR, VAR_READ_ONLY },
102 { "REFNUM", offsetof(ChannelList, refnum), INT_TYPE_VAR, VAR_READ_ONLY },
103 { "WINDOW", offsetof(ChannelList, window), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
104
105 { "NICK", offsetof(ChannelList, NickListTable), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
106
107 { "MAXIDLE", offsetof(ChannelList, max_idle), INT_TYPE_VAR, VAR_READ_WRITE },
108 { "TOG_LIMIT", offsetof(ChannelList, tog_limit), BOOL_TYPE_VAR, VAR_READ_WRITE },
109 { "CHECK_IDLE", offsetof(ChannelList, check_idle), BOOL_TYPE_VAR, VAR_READ_WRITE },
110 { "DO_SCAN", offsetof(ChannelList, do_scan), INT_TYPE_VAR, VAR_READ_ONLY },
111 #if 0
112 struct timeval channel_create; /* time for channel creation */
113 struct timeval join_time; /* time of last join */
114 #endif
115
116 { "STATS_OPS", offsetof(ChannelList, stats_ops), INT_TYPE_VAR, VAR_READ_WRITE },
117 { "STATS_DOPS", offsetof(ChannelList, stats_dops), INT_TYPE_VAR, VAR_READ_WRITE },
118 { "STATS_BANS", offsetof(ChannelList, stats_bans), INT_TYPE_VAR, VAR_READ_WRITE },
119 { "STATS_UNBANS", offsetof(ChannelList, stats_unbans), INT_TYPE_VAR, VAR_READ_WRITE },
120
121 { "STATS_SOPS", offsetof(ChannelList, stats_sops), INT_TYPE_VAR, VAR_READ_WRITE },
122 { "STATS_SDOPS", offsetof(ChannelList, stats_sdops), INT_TYPE_VAR, VAR_READ_WRITE },
123 { "STATS_SHOPS", offsetof(ChannelList, stats_shops), INT_TYPE_VAR, VAR_READ_WRITE },
124 { "STATS_SDEHOPS", offsetof(ChannelList, stats_sdehops), INT_TYPE_VAR, VAR_READ_WRITE },
125 { "STATS_SEBANS", offsetof(ChannelList, stats_sebans), INT_TYPE_VAR, VAR_READ_WRITE },
126 { "STATS_SUNEBANS", offsetof(ChannelList, stats_sunebans), INT_TYPE_VAR, VAR_READ_WRITE },
127 { "STATS_SBANS", offsetof(ChannelList, stats_sbans), INT_TYPE_VAR, VAR_READ_WRITE },
128 { "STATS_SUNBANS", offsetof(ChannelList, stats_sunbans), INT_TYPE_VAR, VAR_READ_WRITE },
129
130 { "STATS_TOPICS", offsetof(ChannelList, stats_topics), INT_TYPE_VAR, VAR_READ_WRITE },
131 { "STATS_KICKS", offsetof(ChannelList, stats_kicks), INT_TYPE_VAR, VAR_READ_WRITE },
132 { "STATS_PUBS", offsetof(ChannelList, stats_pubs), INT_TYPE_VAR , VAR_READ_WRITE },
133 { "STATS_PARTS", offsetof(ChannelList, stats_parts), INT_TYPE_VAR , VAR_READ_WRITE },
134 { "STATS_SIGNOFFS", offsetof(ChannelList, stats_signoffs), INT_TYPE_VAR , VAR_READ_WRITE },
135 { "STATS_JOINS", offsetof(ChannelList, stats_joins), INT_TYPE_VAR , VAR_READ_WRITE },
136 { "STATS_EBANS", offsetof(ChannelList, stats_ebans), INT_TYPE_VAR , VAR_READ_WRITE },
137 { "STATS_UNEBANS", offsetof(ChannelList, stats_unebans), INT_TYPE_VAR , VAR_READ_WRITE },
138 { "STATS_CHANPASS", offsetof(ChannelList, stats_chanpass), INT_TYPE_VAR , VAR_READ_WRITE },
139 { "STATS_HOPS", offsetof(ChannelList, stats_hops), INT_TYPE_VAR , VAR_READ_WRITE },
140 { "STATS_DHOPS", offsetof(ChannelList, stats_dhops), INT_TYPE_VAR , VAR_READ_WRITE },
141 { "CSET", offsetof(ChannelList, csets), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
142
143 { "MSGLOG", offsetof(ChannelList, msglog_on), BOOL_TYPE_VAR , VAR_READ_WRITE },
144 { "MSGLOG_FILE", offsetof(ChannelList, logfile), STR_TYPE_VAR , VAR_READ_WRITE },
145
146 { "TOTALNICKS", offsetof(ChannelList, totalnicks), INT_TYPE_VAR , VAR_READ_ONLY },
147 { "MAXNICKS", offsetof(ChannelList, maxnicks), INT_TYPE_VAR , VAR_READ_ONLY },
148 { "MAXNICKSTIME", offsetof(ChannelList, maxnickstime), INT_TYPE_VAR , VAR_READ_ONLY },
149 { "TOTALBANS", offsetof(ChannelList, totalbans), INT_TYPE_VAR , VAR_READ_ONLY },
150 { "MAXBANS", offsetof(ChannelList, maxbans), INT_TYPE_VAR , VAR_READ_ONLY },
151 { "MAXBANSTIME", offsetof(ChannelList, maxbanstime), INT_TYPE_VAR , VAR_READ_ONLY },
152 { "BANS", offsetof(ChannelList, bans), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
153 { "EXEMPTBANS", offsetof(ChannelList, exemptbans), SPECIAL_TYPE_VAR, VAR_READ_ONLY },
154 { NULL, 0, 0, 0 }
155 };
156
157 static LookupStruct user_struct[] = {
158 { "NICK", offsetof(UserList, nick), STR_TYPE_VAR , VAR_READ_WRITE },
159 { "HOST", offsetof(UserList, host), STR_TYPE_VAR , VAR_READ_WRITE },
160 { "COMMENT", offsetof(UserList, comment), STR_TYPE_VAR , VAR_READ_WRITE },
161 { "CHANNELS", offsetof(UserList, channels), STR_TYPE_VAR , VAR_READ_WRITE },
162 { "PASSWORD", offsetof(UserList, password), STR_TYPE_VAR , VAR_READ_WRITE },
163 { "FLAGS", offsetof(UserList, flags), INT_TYPE_VAR , VAR_READ_WRITE },
164 { "TIME", offsetof(UserList, time), INT_TYPE_VAR , VAR_READ_WRITE },
165 { NULL, 0, 0, 0 }
166 };
167
168 static LookupStruct shit_struct[] = {
169 { "FILTER", offsetof(ShitList, filter), STR_TYPE_VAR , VAR_READ_WRITE },
170 { "LEVEL", offsetof(ShitList, level), INT_TYPE_VAR , VAR_READ_WRITE },
171 { "CHANNELS", offsetof(ShitList, channels), STR_TYPE_VAR , VAR_READ_WRITE },
172 { "REASON", offsetof(ShitList, reason), STR_TYPE_VAR , VAR_READ_WRITE },
173 { "TIME", offsetof(ShitList, time), INT_TYPE_VAR , VAR_READ_WRITE },
174 { NULL, 0, 0, 0 }
175 };
176
177 static LookupStruct bans_struct[] = {
178 { "BAN", offsetof(BanList, ban), STR_TYPE_VAR, VAR_READ_ONLY },
179 { "SETBY", offsetof(BanList, setby), STR_TYPE_VAR, VAR_READ_WRITE },
180 { "SENT_UNBAN", offsetof(BanList, sent_unban),INT_TYPE_VAR, VAR_READ_WRITE },
181 { "SENT_UNBAN_TIME", offsetof(BanList, sent_unban_time),INT_TYPE_VAR, VAR_READ_WRITE },
182 { "TIME", offsetof(BanList, time), INT_TYPE_VAR, VAR_READ_ONLY },
183 { "COUNT", offsetof(BanList, count), INT_TYPE_VAR, VAR_READ_ONLY },
184 { NULL, 0, 0, 0 }
185 };
186
187 static LookupStruct dcc_struct[] = {
188 { "USER", offsetof(DCC_int, user), STR_TYPE_VAR , VAR_READ_WRITE },
189 { "USERHOST", offsetof(DCC_int, userhost), STR_TYPE_VAR , VAR_READ_WRITE },
190 { "SERVER", offsetof(DCC_int, server), INT_TYPE_VAR , VAR_READ_ONLY },
191 { "ENCRYPT", offsetof(DCC_int, encrypt), STR_TYPE_VAR , VAR_READ_ONLY },
192 { "FILENAME", offsetof(DCC_int, filename), STR_TYPE_VAR , VAR_READ_ONLY },
193 { "OTHERNAME", offsetof(DCC_int, othername), STR_TYPE_VAR , VAR_READ_ONLY },
194 { "BYTES_READ", offsetof(DCC_int, bytes_read), INT_TYPE_VAR , VAR_READ_ONLY },
195 { "BYTES_SENT", offsetof(DCC_int, bytes_sent), INT_TYPE_VAR , VAR_READ_ONLY },
196 { "START_OFFSET", offsetof(DCC_int, transfer_orders.byteoffset), INT_TYPE_VAR , VAR_READ_ONLY },
197 { "FILESIZE", offsetof(DCC_int, filesize), INT_TYPE_VAR , VAR_READ_ONLY },
198 { "PACKETS", offsetof(DCC_int, packets), INT_TYPE_VAR , VAR_READ_ONLY },
199 { "BLOCKSIZE", offsetof(DCC_int, blocksize), INT_TYPE_VAR , VAR_READ_ONLY },
200 { "DCC_FAST", offsetof(DCC_int, dcc_fast), INT_TYPE_VAR , VAR_READ_ONLY },
201 { "REMPORT", offsetof(DCC_int, remport), INT_TYPE_VAR , VAR_READ_ONLY },
202 { "LOCALPORT", offsetof(DCC_int, localport), INT_TYPE_VAR , VAR_READ_ONLY },
203 { "DCCNUM", offsetof(DCC_int, dccnum), INT_TYPE_VAR , VAR_READ_ONLY },
204 { NULL, 0, 0, 0}
205 };
206
207 static LookupStruct win_struct[] = {
208 { "NAME", offsetof(Window, name), STR_TYPE_VAR , VAR_READ_ONLY },
209 { "REFNUM", offsetof(Window, refnum), INT_TYPE_VAR , VAR_READ_ONLY },
210 { "SERVER", offsetof(Window, server), INT_TYPE_VAR , VAR_READ_ONLY },
211 { "TOP", offsetof(Window, top), INT_TYPE_VAR , VAR_READ_ONLY },
212 { "BOTTOM", offsetof(Window, bottom), INT_TYPE_VAR , VAR_READ_ONLY },
213 { "CURSOR", offsetof(Window, cursor), INT_TYPE_VAR , VAR_READ_ONLY },
214 { "LINE_CNT", offsetof(Window, line_cnt), INT_TYPE_VAR , VAR_READ_ONLY },
215 { "SCROLL", offsetof(Window, noscroll), BOOL_TYPE_VAR , VAR_READ_WRITE },
216 { "SCRATCH", offsetof(Window, scratch_line), BOOL_TYPE_VAR , VAR_READ_WRITE },
217 { "COLUMNS", offsetof(Window, columns), INT_TYPE_VAR , VAR_READ_ONLY },
218 { "NOTIFY_LEVEL", offsetof(Window, notify_level), INT_TYPE_VAR , VAR_READ_WRITE },
219 { "WINDOW_LEVEL", offsetof(Window, window_level), INT_TYPE_VAR , VAR_READ_WRITE },
220 { "CURRENT_CHANNEL", offsetof(Window, current_channel),STR_TYPE_VAR , VAR_READ_ONLY },
221 { "WAITING_CHANNEL", offsetof(Window, waiting_channel),STR_TYPE_VAR , VAR_READ_ONLY },
222 { "BIND_CHANNEL", offsetof(Window, bind_channel), STR_TYPE_VAR , VAR_READ_ONLY },
223 { "QUERY_NICK", offsetof(Window, query_nick), STR_TYPE_VAR , VAR_READ_WRITE },
224 { "QUERY_HOST", offsetof(Window, query_host), STR_TYPE_VAR , VAR_READ_WRITE },
225 { "QUERY_CMD", offsetof(Window, query_cmd), STR_TYPE_VAR , VAR_READ_WRITE },
226 { "LOG", offsetof(Window, log), BOOL_TYPE_VAR , VAR_READ_WRITE },
227 { "LOGFILE", offsetof(Window, logfile), STR_TYPE_VAR , VAR_READ_WRITE },
228 { "LASTLOG_LEVEL", offsetof(Window, lastlog_level),INT_TYPE_VAR , VAR_READ_WRITE },
229 { "LASTLOG_SIZE", offsetof(Window, lastlog_size), INT_TYPE_VAR , VAR_READ_WRITE },
230 { "LASTLOG_MAX", offsetof(Window, lastlog_max), INT_TYPE_VAR , VAR_READ_WRITE },
231 { "HOLD_MODE", offsetof(Window, hold_mode), BOOL_TYPE_VAR , VAR_READ_WRITE },
232 { "MANGLER", offsetof(Window, mangler), BOOL_TYPE_VAR, VAR_READ_WRITE },
233 { "PROMPT", offsetof(Window, prompt), STR_TYPE_VAR, VAR_READ_WRITE },
234 { NULL, 0, 0, 0}
235 };
236
237 static LookupStruct nicklist_struct[] = {
238 { "NICK", offsetof(NickList, nick), STR_TYPE_VAR , VAR_READ_ONLY },
239 { "HOST", offsetof(NickList, host), STR_TYPE_VAR , VAR_READ_ONLY },
240 { "IP", offsetof(NickList, ip), STR_TYPE_VAR , VAR_READ_WRITE },
241 { "SERVER", offsetof(NickList, server), STR_TYPE_VAR , VAR_READ_ONLY },
242 { "IP_COUNT", offsetof(NickList, ip_count), INT_TYPE_VAR , VAR_READ_ONLY },
243
244 { "USERLIST", offsetof(NickList, userlist), SPECIAL_TYPE_VAR , VAR_READ_ONLY },
245 { "SHITLIST", offsetof(NickList, shitlist), SPECIAL_TYPE_VAR , VAR_READ_ONLY },
246
247 { "FLAGS", offsetof(NickList, flags), INT_TYPE_VAR , VAR_READ_ONLY },
248
249 { "IDLE_TIME", offsetof(NickList, idle_time), INT_TYPE_VAR , VAR_READ_WRITE },
250
251 { "FLOODCOUNT", offsetof(NickList, floodcount), INT_TYPE_VAR , VAR_READ_WRITE },
252 { "FLOODTIME", offsetof(NickList, floodtime), INT_TYPE_VAR , VAR_READ_WRITE },
253
254 { "NICKCOUNT", offsetof(NickList, nickcount), INT_TYPE_VAR , VAR_READ_WRITE },
255 { "NICKTIME", offsetof(NickList, nicktime), INT_TYPE_VAR , VAR_READ_WRITE },
256
257 { "KICKCOUNT", offsetof(NickList, kickcount), INT_TYPE_VAR , VAR_READ_WRITE },
258 { "KICKTIME", offsetof(NickList, kicktime), INT_TYPE_VAR , VAR_READ_WRITE },
259
260 { "JOINCOUNT", offsetof(NickList, joincount), INT_TYPE_VAR , VAR_READ_WRITE },
261 { "JOINTIME", offsetof(NickList, jointime), INT_TYPE_VAR , VAR_READ_WRITE },
262
263
264 { "DOPCOUNT", offsetof(NickList, dopcount), INT_TYPE_VAR , VAR_READ_WRITE },
265 { "DOPTIME", offsetof(NickList, doptime), INT_TYPE_VAR , VAR_READ_WRITE },
266
267 { "KICKCOUNT", offsetof(NickList, bancount), INT_TYPE_VAR , VAR_READ_WRITE },
268 { "KICKTIME", offsetof(NickList, bantime), INT_TYPE_VAR , VAR_READ_WRITE },
269
270 { "CREATED", offsetof(NickList, created), INT_TYPE_VAR , VAR_READ_ONLY },
271
272
273 { "STAT_KICKS", offsetof(NickList, stat_kicks),INT_TYPE_VAR , VAR_READ_WRITE },
274 { "STAT_DOPS", offsetof(NickList, stat_dops), INT_TYPE_VAR , VAR_READ_WRITE },
275 { "STAT_OPS", offsetof(NickList, stat_ops), INT_TYPE_VAR , VAR_READ_WRITE },
276 { "STAT_HOPS", offsetof(NickList, stat_hops), INT_TYPE_VAR , VAR_READ_WRITE },
277 { "STAT_DHOPS", offsetof(NickList, stat_dhops),INT_TYPE_VAR , VAR_READ_WRITE },
278 { "STAT_EBAN", offsetof(NickList, stat_eban), INT_TYPE_VAR , VAR_READ_WRITE },
279 { "STAT_UNEBAN", offsetof(NickList, stat_uneban),INT_TYPE_VAR , VAR_READ_WRITE },
280 { "STAT_BANS", offsetof(NickList, stat_bans), INT_TYPE_VAR , VAR_READ_WRITE },
281 { "STAT_UNBANS", offsetof(NickList, stat_unbans),INT_TYPE_VAR , VAR_READ_WRITE },
282 { "STAT_NICKS", offsetof(NickList, stat_nicks),INT_TYPE_VAR , VAR_READ_WRITE },
283 { "STAT_PUB", offsetof(NickList, stat_pub), INT_TYPE_VAR , VAR_READ_WRITE },
284 { "STAT_TOPICS", offsetof(NickList, stat_topics),INT_TYPE_VAR , VAR_READ_WRITE },
285
286 { "SENT_REOP", offsetof(NickList, sent_reop), INT_TYPE_VAR , VAR_READ_WRITE },
287 { "SENT_REOP_TIME", offsetof(NickList, sent_reop_time),INT_TYPE_VAR , VAR_READ_WRITE },
288 { "SENT_VOICE", offsetof(NickList, sent_voice), INT_TYPE_VAR , VAR_READ_WRITE },
289 { "SENT_VOICE_TIME", offsetof(NickList, sent_voice_time),INT_TYPE_VAR , VAR_READ_WRITE },
290 { "SENT_DEOP", offsetof(NickList, sent_deop), INT_TYPE_VAR , VAR_READ_WRITE },
291 { "SENT_DEOP_TIME", offsetof(NickList, sent_deop_time),INT_TYPE_VAR , VAR_READ_WRITE },
292 { "NEED_USERHOST", offsetof(NickList, need_userhost), INT_TYPE_VAR , VAR_READ_ONLY },
293 { NULL, 0, 0, 0}
294 };
295
296 static LookupStruct cset_struct[] = {
297 { "AINV", offsetof(CSetList, set_ainv), INT_TYPE_VAR, VAR_READ_WRITE },
298 { "ANNOY_KICK", offsetof(CSetList, set_annoy_kick), BOOL_TYPE_VAR, VAR_READ_WRITE },
299 { "AOP", offsetof(CSetList, set_aop), BOOL_TYPE_VAR, VAR_READ_WRITE },
300 { "AUTO_JOIN_ON_INVITE",offsetof(CSetList, set_auto_join_on_invite), BOOL_TYPE_VAR, VAR_READ_WRITE },
301 { "AUTO_LIMIT", offsetof(CSetList, set_auto_limit), BOOL_TYPE_VAR, VAR_READ_WRITE },
302 { "AUTO_REJOIN", offsetof(CSetList, set_auto_rejoin), INT_TYPE_VAR, VAR_READ_WRITE },
303 { "BANTIME", offsetof(CSetList, set_bantime), INT_TYPE_VAR, VAR_READ_WRITE },
304 { "BITCH", offsetof(CSetList, bitch_mode), BOOL_TYPE_VAR, VAR_READ_WRITE },
305 { "CHANMODE", offsetof(CSetList, chanmode), STR_TYPE_VAR, VAR_READ_WRITE },
306
307 { "CHANNEL_LOG", offsetof(CSetList, channel_log), BOOL_TYPE_VAR, VAR_READ_WRITE },
308 { "CHANNEL_LOG_FILE", offsetof(CSetList, channel_log_file), STR_TYPE_VAR, VAR_READ_WRITE },
309 { "CHANNEL_LOG_LEVEL", offsetof(CSetList, log_level), INT_TYPE_VAR, VAR_READ_WRITE },
310
311 { "COMPRESS_MODES", offsetof(CSetList, compress_modes), BOOL_TYPE_VAR, VAR_READ_WRITE },
312 { "CTCP_FLOOD_BAN", offsetof(CSetList, set_ctcp_flood_ban), BOOL_TYPE_VAR, VAR_READ_WRITE },
313 { "DEOPFLOOD", offsetof(CSetList, set_deopflood), BOOL_TYPE_VAR, VAR_READ_WRITE },
314 { "DEOPFLOOD_TIME", offsetof(CSetList, set_deopflood_time), INT_TYPE_VAR, VAR_READ_WRITE },
315 { "DEOP_ON_DEOPFLOOD", offsetof(CSetList, set_deop_on_deopflood), INT_TYPE_VAR, VAR_READ_WRITE },
316 { "DEOP_ON_KICKFLOOD", offsetof(CSetList, set_deop_on_kickflood), INT_TYPE_VAR, VAR_READ_WRITE },
317 { "HACKING", offsetof(CSetList, set_hacking), INT_TYPE_VAR, VAR_READ_WRITE },
318 { "JOINFLOOD", offsetof(CSetList, set_joinflood), BOOL_TYPE_VAR, VAR_READ_WRITE },
319 { "JOINFLOOD_TIME", offsetof(CSetList, set_joinflood_time), INT_TYPE_VAR, VAR_READ_WRITE },
320 { "KICKFLOOD", offsetof(CSetList, set_kickflood), BOOL_TYPE_VAR, VAR_READ_WRITE },
321 { "KICKFLOOD_TIME", offsetof(CSetList, set_kickflood_time), INT_TYPE_VAR, VAR_READ_WRITE },
322 { "KICK_IF_BANNED", offsetof(CSetList, set_kick_if_banned), BOOL_TYPE_VAR, VAR_READ_WRITE },
323 { "KICK_ON_DEOPFLOOD", offsetof(CSetList, set_kick_on_deopflood), INT_TYPE_VAR, VAR_READ_WRITE },
324 { "KICK_ON_JOINFLOOD", offsetof(CSetList, set_kick_on_joinflood), INT_TYPE_VAR, VAR_READ_WRITE },
325 { "KICK_ON_KICKFLOOD", offsetof(CSetList, set_kick_on_kickflood), INT_TYPE_VAR, VAR_READ_WRITE },
326 { "KICK_ON_NICKFLOOD", offsetof(CSetList, set_kick_on_nickflood), INT_TYPE_VAR, VAR_READ_WRITE },
327 { "KICK_ON_PUBFLOOD", offsetof(CSetList, set_kick_on_pubflood), INT_TYPE_VAR, VAR_READ_WRITE },
328 { "KICK_OPS", offsetof(CSetList, set_kick_ops), BOOL_TYPE_VAR, VAR_READ_WRITE },
329 { "LAMEIDENT", offsetof(CSetList, set_lame_ident), BOOL_TYPE_VAR, VAR_READ_WRITE },
330 { "LAMELIST", offsetof(CSetList, set_lamelist), BOOL_TYPE_VAR, VAR_READ_WRITE },
331 { "NICKFLOOD", offsetof(CSetList, set_nickflood), BOOL_TYPE_VAR, VAR_READ_WRITE },
332 { "NICKFLOOD_TIME", offsetof(CSetList, set_nickflood_time), INT_TYPE_VAR, VAR_READ_WRITE },
333 { "PUBFLOOD", offsetof(CSetList, set_pubflood), BOOL_TYPE_VAR, VAR_READ_WRITE },
334 { "PUBFLOOD_IGNORE_TIME",offsetof(CSetList, set_pubflood_ignore), INT_TYPE_VAR, VAR_READ_WRITE },
335 { "PUBFLOOD_TIME", offsetof(CSetList, set_pubflood_time), INT_TYPE_VAR, VAR_READ_WRITE },
336 { "SHITLIST", offsetof(CSetList, set_shitlist), BOOL_TYPE_VAR, VAR_READ_WRITE },
337 { "USERLIST", offsetof(CSetList, set_userlist), BOOL_TYPE_VAR, VAR_READ_WRITE },
338 { "CHANNEL", offsetof(CSetList, channel), STR_TYPE_VAR, VAR_READ_ONLY },
339 { NULL, 0, 0, 0}
340 };
341
find_structure(char * name)342 int find_structure(char *name)
343 {
344 int i;
345 for (i = 0; *struct_name[i]; i++)
346 if (!my_stricmp(struct_name[i], name))
347 return i;
348 return -1;
349 }
350
setup_structure(char * name,char * which,Window ** win,DCC_int ** dcc,ChannelList ** chan,NickList ** nick,int * server)351 int setup_structure(char *name, char *which, Window **win, DCC_int **dcc, ChannelList **chan, NickList **nick, int *server)
352 {
353 int i;
354 int serv = -1;
355 i = find_structure(name);
356 switch (i)
357 {
358 case WINDOW_LOOKUP:
359 {
360 *win = get_window_by_desc(which);
361 if (!*win)
362 *win = current_window;
363 return WINDOW_LOOKUP;
364 }
365 case NICKLIST_LOOKUP:
366 {
367 char *ch = NULL;
368 if (!*chan)
369 {
370 if (!(ch = get_current_channel_by_refnum(0)))
371 return -1;
372 if (!(*chan = lookup_channel(ch, current_window->server, 0)))
373 return -1;
374 }
375 if (!ch && !*chan)
376 return -1;
377 *nick = find_nicklist_in_channellist(which, *chan, 0);
378 return NICKLIST_LOOKUP;
379 }
380 case DCC_LOOKUP:
381 {
382 SocketList *s;
383 DCC_int *n;
384 int l = my_atol(which);
385 s = get_socket(l);
386 if (!s || !(n = (DCC_int *)s->info))
387 break;
388 *dcc = n;
389 return DCC_LOOKUP;
390 }
391 case CHANNEL_LOOKUP:
392 {
393 char *ch = which;
394 if (!*ch)
395 {
396 if (!(ch = get_current_channel_by_refnum(0)))
397 return -1;
398 }
399 if (is_channel(ch))
400 *chan = lookup_channel(ch, current_window->server, 0);
401 else
402 {
403 if ((ch = make_channel(ch)))
404 *chan = lookup_channel(ch, current_window->server, 0);
405 }
406 return CHANNEL_LOOKUP;
407 }
408 case SERVER_LOOKUP:
409 if (*which && ((serv = my_atol(which)) != -1))
410 *server = serv;
411 return SERVER_LOOKUP;
412 default:
413 break;
414 }
415 return -1;
416 }
417
418
get_offset_int(void * tmp,int offset)419 static inline int get_offset_int(void *tmp, int offset)
420 {
421 int val = *(int *)((char *)tmp + offset);
422 return val;
423 }
424
get_offset_str(void * tmp,int offset)425 static inline char *get_offset_str(void *tmp, int offset)
426 {
427 char *s = *(char **)((char *)tmp + offset);
428 return s;
429 }
430
get_offset_char(void * tmp,int offset)431 static inline char *get_offset_char(void *tmp, int offset)
432 {
433 char *s = (char *)((char *)tmp + offset);
434 return s;
435 }
436
set_offset_int(void * tmp,int offset,int val)437 static inline void set_offset_int(void *tmp, int offset, int val)
438 {
439 int *ptr = (int *)((char *)tmp + offset);
440 *ptr = val;
441 }
442
set_offset_str(void * tmp,int offset,const char * val)443 static inline void set_offset_str(void *tmp, int offset, const char *val)
444 {
445 char **ptr = (char **)((char *)tmp + offset);
446 if (val && *val)
447 malloc_strcpy(ptr, val);
448 else
449 new_free(ptr);
450 }
451
set_offset_char(void * tmp,int offset,const char * val)452 static inline void set_offset_char(void *tmp, int offset, const char *val)
453 {
454 char *ptr = (char *)((char *)tmp + offset);
455 if (val && *val)
456 strcpy(ptr, val);
457 else
458 *ptr = 0;
459 }
460
lookup_code(LookupStruct * t,char * name)461 int lookup_code(LookupStruct *t, char *name)
462 {
463 int i;
464 for (i = 0; t[i].code; i++)
465 {
466 if (!my_stricmp(t[i].code, name))
467 break;
468 }
469 if (!t[i].code)
470 return -1;
471 return i;
472 }
473
return_structure(LookupStruct * name,void * user)474 char *return_structure(LookupStruct *name, void *user)
475 {
476 int j;
477 char *ret = NULL;
478 char *s;
479 if (!user)
480 return NULL;
481 for (j = 0; name[j].code; j++)
482 {
483 if (name[j].type == INT_TYPE_VAR)
484 m_s3cat(&ret, ",", ltoa(get_offset_int(user, name[j].offset)));
485 else if (name[j].type == STR_TYPE_VAR)
486 {
487 s = get_offset_str(user, name[j].offset);
488 m_s3cat(&ret, ",", s ? s : empty_string);
489 }
490 else if (name[j].type == BOOL_TYPE_VAR)
491 m_s3cat(&ret, ",", on_off(get_offset_int(user, name[j].offset)));
492 else if (name[j].type == CHAR_TYPE_VAR)
493 m_s3cat(&ret, ",", get_offset_char(user, name[j].offset));
494 else if (name[j].type == SPECIAL_TYPE_VAR)
495 {
496 s = LOCAL_COPY(name[j].code);
497 lower(s);
498 m_s3cat(&ret, ",", "<");
499 malloc_strcat(&ret, s);
500 malloc_strcat(&ret, ">");
501 }
502 }
503 return ret;
504 }
505
lookup_structure_item(int idx,LookupStruct * name,void * user,char * arg)506 char *lookup_structure_item(int idx, LookupStruct *name, void *user, char *arg)
507 {
508 if (!user || (idx == -1))
509 return NULL;
510 switch (name[idx].type)
511 {
512 case STR_TYPE_VAR:
513 if (arg && !name[idx].readwrite)
514 set_offset_str(user, name[idx].offset, arg);
515 return m_strdup(get_offset_str(user, name[idx].offset));
516 case CHAR_TYPE_VAR:
517 if (arg && !name[idx].readwrite)
518 set_offset_char(user, name[idx].offset, arg);
519 return m_strdup(get_offset_char(user, name[idx].offset));
520 case INT_TYPE_VAR:
521 if (arg && *arg && !name[idx].readwrite)
522 set_offset_int(user, name[idx].offset, my_atol(arg));
523 return m_strdup(ltoa(get_offset_int(user, name[idx].offset)));
524 case BOOL_TYPE_VAR:
525 if (arg && *arg && !name[idx].readwrite)
526 {
527 int val = 0;
528 if (!my_stricmp(arg, "on"))
529 val = 1;
530 else if (!my_stricmp(arg, "off"))
531 val = 0;
532 else
533 val = my_atol(arg);
534 set_offset_int(user, name[idx].offset, val);
535 }
536 return m_strdup(on_off(get_offset_int(user, name[idx].offset)));
537 default:
538 break;
539 }
540 return NULL;
541 }
542
lookup_structure_member(int type,char * name,char * rest,NickList * n,ChannelList * ch,Window * w,DCC_int * dcc,int serv)543 char *lookup_structure_member(int type, char *name, char *rest, NickList *n, ChannelList *ch, Window *w, DCC_int *dcc, int serv)
544 {
545 LookupStruct *tmp = NULL;
546 int i = -1;
547 char *ret = NULL;
548 void *user = NULL;
549 int code = -1;
550 switch (type)
551 {
552 case WINDOW_LOOKUP:
553 tmp = win_struct;
554 user = w;
555 break;
556 case NICKLIST_LOOKUP:
557 tmp = nicklist_struct;
558 user = n;
559 break;
560 case DCC_LOOKUP:
561 tmp = dcc_struct;
562 user = dcc;
563 break;
564 case CHANNEL_LOOKUP:
565 tmp = channel_struct;
566 user = ch;
567 break;
568 case CSET_LOOKUP:
569 tmp = cset_struct;
570 if (ch)
571 user = ch->csets;
572 break;
573 case SERVER_LOOKUP:
574 tmp = server_struct;
575 if (serv >= 0 && serv < server_list_size())
576 {
577 Server *slist = get_server_list();
578
579 user = &slist[serv];
580 ch = slist[serv].chan_list;
581 }
582 default:
583 break;
584 }
585 if (!tmp || !user)
586 return NULL;
587 if (!name || !*name)
588 return return_structure(tmp, user);
589 if ((i = lookup_code(tmp, name)) == -1)
590 return NULL;
591 switch(tmp[i].type)
592 {
593 case INT_TYPE_VAR:
594 case STR_TYPE_VAR:
595 case BOOL_TYPE_VAR:
596 case CHAR_TYPE_VAR:
597 {
598 char *lparen;
599 if (rest && !*rest)
600 rest = NULL;
601 #if 0
602 if ((lparen = strchr(rest+1, '[')))
603 {
604 if ((rparen = MatchingBracket(lparen+1, '[', ']')))
605 *rparen++ = 0;
606 *lparen++ = 0;
607 if (!*lparen)
608 lparen = NULL;
609 } else if (*rest)
610 #endif
611 lparen = rest;
612 ret = lookup_structure_item(i, tmp, user, lparen);
613 break;
614 }
615 case SPECIAL_TYPE_VAR:
616 {
617 code = find_structure(name);
618 switch (code)
619 {
620 case NICKLIST_LOOKUP: /* this is a special case */
621 tmp = nicklist_struct;
622 n = sorted_nicklist(ch, NICKSORT_NONE);
623 for (; n; n = n->next)
624 if (!rest || !*rest)
625 m_s3cat(&ret, ",", n->nick);
626 else if (*rest == '>' && *(rest+1) && !my_stricmp(rest+1, n->nick))
627 ret = return_structure(tmp, n);
628 clear_sorted_nicklist(&n);
629 return ret;
630 break;
631 case USERLIST_LOOKUP:
632 tmp = user_struct;
633 if (n)
634 user = n->userlist;
635 break;
636 case SHITLIST_LOOKUP:
637 tmp = shit_struct;
638 if (n)
639 user = n->shitlist;
640 break;
641 case CSET_LOOKUP:
642 tmp = cset_struct;
643 if (ch)
644 user = ch->csets;
645 break;
646 case WINDOW_LOOKUP:
647 tmp = win_struct;
648 if (ch)
649 user = ch->window;
650 break;
651 case EXEMPT_LOOKUP:
652 tmp = bans_struct;
653 if (ch)
654 user = ch->exemptbans;
655 break;
656 case BANS_LOOKUP:
657 {
658 BanList *b;
659 tmp = bans_struct;
660 if (ch)
661 user = ch->bans;
662 for (b = ch->bans; b; b= b->next)
663 if (!rest || !*rest)
664 m_s3cat(&ret, ",", b->ban);
665 else if (*rest == '>' && *(rest+1) && !my_stricmp(rest+1, b->ban))
666 ret = return_structure(tmp, b);
667 return ret;
668 break;
669 }
670 case CHANNEL_LOOKUP:
671 tmp = channel_struct;
672 ch = ((Server *)user)->chan_list;
673 for (; ch; ch = ch->next)
674 if (!rest || !*rest)
675 m_s3cat(&ret, ",", ch->channel);
676 else if (*rest == '>' && *(rest+1) && !my_stricmp(rest+1, ch->channel))
677 ret = return_structure(tmp, ch);
678 return ret;
679 break;
680 }
681 if (rest && *rest == '>' && *(rest + 1))
682 {
683 char *lparen, *rparen;
684 if ((lparen = strchr(rest+1, '[')))
685 {
686 if ((rparen = MatchingBracket(lparen+1, '[', ']')))
687 *rparen++ = 0;
688 *lparen++ = 0;
689 } else if (rest && !*rest)
690 rest = NULL;
691 i = lookup_code(tmp, rest+1);
692 ret = lookup_structure_item(i, tmp, user, lparen);
693 }
694 else
695 ret = return_structure(tmp, user);
696 }
697 default:
698 break;
699 }
700 return ret;
701 }
702
703
call_structure_internal(char * name,char * args,char * rest,char * rest1)704 char *call_structure_internal(char *name, char *args, char *rest, char *rest1)
705 {
706 Window *win = NULL;
707 ChannelList *chan = NULL;
708 DCC_int *dcc = NULL;
709 NickList *nick = NULL;
710 char *ret = NULL;
711 int type = -1;
712 int server = -1;
713 char *lparen, *rparen;
714 type = setup_structure(name, args, &win, &dcc, &chan, &nick, &server);
715 if ((lparen = strchr(rest, '[')))
716 {
717 if ((rparen = MatchingBracket(lparen+1, '[', ']')))
718 *rparen++ = 0;
719 *lparen++ = 0;
720 rest1 = lparen;
721 }
722 if (type != -1)
723 ret = lookup_structure_member(type, rest, rest1, nick, chan, win ? win : current_window, dcc, server);
724 return ret;
725 }
726