Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/source/funny.c
1069 views
1
/*
2
* funny.c: Well, I put some stuff here and called it funny. So sue me.
3
*
4
* written by michael sandrof
5
*
6
* copyright(c) 1990
7
*
8
* see the copyright file, or do a help ircii copyright
9
*/
10
11
12
#include "irc.h"
13
static char cvsrevision[] = "$Id: funny.c 130 2011-05-16 13:16:25Z keaston $";
14
CVS_REVISION(funny_c)
15
#include "struct.h"
16
17
#include "ircaux.h"
18
#include "hook.h"
19
#include "vars.h"
20
#include "funny.h"
21
#include "names.h"
22
#include "server.h"
23
#include "lastlog.h"
24
#include "ircterm.h"
25
#include "output.h"
26
#include "numbers.h"
27
#include "parse.h"
28
#include "status.h"
29
#include "misc.h"
30
#include "screen.h"
31
#define MAIN_SOURCE
32
#include "modval.h"
33
34
static char *match_str = NULL;
35
36
static int funny_min;
37
static int funny_max;
38
static int funny_flags;
39
40
void funny_match(char *stuff)
41
{
42
malloc_strcpy(&match_str, stuff);
43
}
44
45
void set_funny_flags(int min, int max, int flags)
46
{
47
funny_min = min;
48
funny_max = max;
49
funny_flags = flags;
50
}
51
52
struct WideListInfoStru
53
{
54
char *channel;
55
int users;
56
};
57
58
typedef struct WideListInfoStru WideList;
59
60
static WideList **wide_list = NULL;
61
static int wl_size = 0;
62
static int wl_elements = 0;
63
64
static int funny_widelist_users (WideList **, WideList **);
65
static int funny_widelist_names (WideList **, WideList **);
66
67
static int funny_widelist_users(WideList **left, WideList **right)
68
{
69
if ((**left).users > (**right).users)
70
return -1;
71
else if ((**right).users > (**left).users)
72
return 1;
73
else
74
return my_stricmp((**left).channel, (**right).channel);
75
}
76
77
static int funny_widelist_names(WideList **left, WideList **right)
78
{
79
int comp;
80
81
if (!(comp = my_stricmp((**left).channel, (**right).channel)))
82
return comp;
83
else if ((**left).users > (**right).users)
84
return -1;
85
else if ((**right).users > (**left).users)
86
return 1;
87
else
88
return 0;
89
}
90
91
92
void funny_print_widelist(void)
93
{
94
int i;
95
char buffer1[BIG_BUFFER_SIZE];
96
char buffer2[BIG_BUFFER_SIZE];
97
char *ptr;
98
99
if (!wide_list)
100
return;
101
102
if (funny_flags & FUNNY_NAME)
103
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
104
(int (*) (const void *, const void *)) funny_widelist_names);
105
else if (funny_flags & FUNNY_USERS)
106
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
107
(int (*) (const void *, const void *)) funny_widelist_users);
108
109
set_display_target(NULL, LOG_CRAP);
110
*buffer1 = '\0';
111
for (i = 1; i < wl_elements; i++)
112
{
113
sprintf(buffer2, "%s(%d) ", wide_list[i]->channel,
114
wide_list[i]->users);
115
ptr = strchr(buffer1, '\0');
116
if (strlen(buffer1) + strlen(buffer2) > current_term->TI_cols - 5)
117
{
118
if (do_hook(WIDELIST_LIST, "%s", buffer1))
119
put_it("%s", convert_output_format(fget_string_var(FORMAT_WIDELIST_FSET), "%s %s", update_clock(GET_TIME), buffer1));
120
*buffer1 = 0;
121
strcat(buffer1, buffer2);
122
}
123
else
124
strcpy(ptr, buffer2);
125
}
126
if (*buffer1 && do_hook(WIDELIST_LIST, "%s", buffer1))
127
put_it("%s", convert_output_format(fget_string_var(FORMAT_WIDELIST_FSET), "%s %s", update_clock(GET_TIME), buffer1));
128
129
reset_display_target();
130
for (i = 0; i < wl_elements; i++)
131
{
132
new_free(&wide_list[i]->channel);
133
new_free((char **)&wide_list[i]);
134
}
135
new_free((char **)&wide_list);
136
wl_elements = wl_size = 0;
137
}
138
139
void funny_list(char *from, char **ArgList)
140
{
141
char *channel,
142
*user_cnt,
143
*line;
144
WideList **new_list;
145
int cnt;
146
static char format[30];
147
static int last_width = -1;
148
149
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
150
{
151
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
152
snprintf(format, 25, "%%s %%-%u.%us %%-5s %%s", /*thing_ansi,*/
153
(unsigned char) last_width,
154
(unsigned char) last_width);
155
else
156
snprintf(format, 25, "%%s %%s %%-5s %%s"/*, thing_ansi*/);
157
}
158
channel = ArgList[0];
159
user_cnt = ArgList[1];
160
line = PasteArgs(ArgList, 2);
161
if (funny_flags & FUNNY_TOPIC && !(line && *line))
162
return;
163
cnt = my_atol(user_cnt);
164
if (funny_min && (cnt < funny_min))
165
return;
166
if (funny_max && (cnt > funny_max))
167
return;
168
if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*'))
169
return;
170
if ((funny_flags & FUNNY_PUBLIC) && ((*channel == '*') || (*channel == '@')))
171
return;
172
if (match_str)
173
{
174
if (wild_match(match_str, channel) == 0)
175
return;
176
}
177
if (funny_flags & FUNNY_WIDE)
178
{
179
if (wl_elements >= wl_size)
180
{
181
new_list = (WideList **) new_malloc(sizeof(WideList *) *
182
(wl_size + 50));
183
memset(new_list, 0, sizeof(WideList *) * (wl_size + 50));
184
if (wl_size)
185
memcpy(new_list, wide_list, sizeof(WideList *) * wl_size);
186
wl_size += 50;
187
new_free((char **)&wide_list);
188
wide_list = new_list;
189
}
190
wide_list[wl_elements] = (WideList *)
191
new_malloc(sizeof(WideList));
192
wide_list[wl_elements]->channel = NULL;
193
wide_list[wl_elements]->users = cnt;
194
malloc_strcpy(&wide_list[wl_elements]->channel,
195
(*channel != '*') ? channel : "Prv");
196
wl_elements++;
197
return;
198
}
199
set_display_target(channel, LOG_CRAP);
200
if (do_hook(current_numeric, "%s %s %s %s", from, channel, user_cnt,
201
line) && do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line))
202
{
203
if (channel && user_cnt)
204
put_it("%s", convert_output_format(fget_string_var(FORMAT_LIST_FSET),"%s %s %s %s", update_clock(GET_TIME), *channel == '*'?"Prv":channel, user_cnt, line));
205
}
206
reset_display_target();
207
}
208
209
/* print_funny_names
210
*
211
* This handles presenting the output of a NAMES reply. It is a cut-down
212
* version of the /SCAN output formatting.
213
*/
214
void print_funny_names(char *line)
215
{
216
char *t;
217
int count = 0;
218
char buffer[BIG_BUFFER_SIZE];
219
int cols = get_int_var(NAMES_COLUMNS_VAR);
220
221
if (!cols)
222
cols = 1;
223
224
if (line && *line)
225
{
226
*buffer = 0;
227
228
while ((t = next_arg(line, &line))) {
229
char *nick;
230
char *nick_format;
231
char nick_buffer[BIG_BUFFER_SIZE];
232
233
if (!count && fget_string_var(FORMAT_NAMES_BANNER_FSET))
234
strlcat(buffer, convert_output_format(
235
fget_string_var(FORMAT_NAMES_BANNER_FSET), NULL, NULL),
236
sizeof buffer);
237
238
/* Seperate the nick and the possible status presets that might
239
* preceede it. */
240
nick = t + strspn(t, "@%+~-");
241
nick_format = fget_string_var(isme(nick) ?
242
FORMAT_NAMES_NICK_ME_FSET : FORMAT_NAMES_NICK_FSET);
243
strlcpy(nick_buffer,
244
convert_output_format(nick_format, "%s", nick),
245
sizeof nick_buffer);
246
247
if (nick != t)
248
{
249
char special = *t;
250
251
if (special == '+')
252
strlcat(buffer,
253
convert_output_format(
254
fget_string_var(FORMAT_NAMES_USER_VOICE_FSET),
255
"%c %s", special, nick_buffer), sizeof buffer);
256
else
257
strlcat(buffer,
258
convert_output_format(
259
fget_string_var(FORMAT_NAMES_USER_CHANOP_FSET),
260
"%c %s", special, nick_buffer), sizeof buffer);
261
}
262
else
263
strlcat(buffer,
264
convert_output_format(
265
fget_string_var(FORMAT_NAMES_USER_FSET), ". %s",
266
nick_buffer), sizeof buffer);
267
268
strlcat(buffer, space, sizeof buffer);
269
270
if (++count >= cols)
271
{
272
put_it("%s", buffer);
273
*buffer = 0;
274
count = 0;
275
}
276
}
277
278
if (count)
279
put_it("%s", buffer);
280
}
281
}
282
283
void funny_namreply(char *from, char **Args)
284
{
285
char *type,
286
*channel;
287
static char format[40];
288
static int last_width = -1;
289
register char *ptr;
290
register char *line;
291
int user_count = 0;
292
293
PasteArgs(Args, 2);
294
type = Args[0];
295
channel = Args[1];
296
line = Args[2];
297
298
/* protocol violation by server */
299
if (!channel || !line)
300
return;
301
302
ptr = line;
303
while (*ptr)
304
{
305
while (*ptr && (*ptr != ' '))
306
ptr++;
307
user_count++;
308
while (*ptr && (*ptr == ' '))
309
ptr++;
310
}
311
312
if (in_join_list(channel, from_server))
313
{
314
set_display_target(channel, LOG_CRAP);
315
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel,line)
316
&& do_hook(NAMES_LIST, "%s %s", channel, line)
317
&& get_int_var(SHOW_CHANNEL_NAMES_VAR))
318
{
319
put_it("%s", convert_output_format(fget_string_var(FORMAT_NAMES_FSET), "%s %s %d %d",update_clock(GET_TIME), channel, user_count, user_count));
320
print_funny_names(line);
321
}
322
if ((user_count == 1) && (*line == '@'))
323
{
324
ChannelList *chan;
325
if ((chan = lookup_channel(channel, from_server, CHAN_NOUNLINK)))
326
if ((ptr = get_cset_str_var(chan->csets, CHANMODE_CSET)))
327
my_send_to_server(from_server, "MODE %s %s", channel, ptr);
328
}
329
got_info(channel, from_server, GOTNAMES);
330
reset_display_target();
331
return;
332
}
333
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
334
{
335
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
336
sprintf(format, "%%s: %%-%u.%us %%s",
337
(unsigned char) last_width,
338
(unsigned char) last_width);
339
else
340
strcpy(format, "%s: %s\t%s");
341
}
342
if (funny_min && (user_count < funny_min))
343
return;
344
else if (funny_max && (user_count > funny_max))
345
return;
346
if ((funny_flags & FUNNY_PRIVATE) && (*type == '='))
347
return;
348
if ((funny_flags & FUNNY_PUBLIC) && ((*type == '*') || (*type == '@')))
349
return;
350
if (type && channel)
351
{
352
if (match_str)
353
{
354
if (wild_match(match_str, channel) == 0)
355
return;
356
}
357
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel, line) && do_hook(NAMES_LIST, "%s %s", channel, line))
358
{
359
set_display_target(channel, LOG_CRAP);
360
if (fget_string_var(FORMAT_NAMES_FSET))
361
{
362
put_it("%s", convert_output_format(fget_string_var(FORMAT_NAMES_FSET), "%s %s %d %d", update_clock(GET_TIME), channel, user_count, user_count));
363
print_funny_names(line);
364
}
365
else
366
{
367
switch (*type)
368
{
369
case '=':
370
if (last_width &&(strlen(channel) > last_width))
371
{
372
channel[last_width-1] = '>';
373
channel[last_width] = (char) 0;
374
}
375
put_it(format, "Pub", channel, line);
376
break;
377
case '*':
378
put_it(format, "Prv", channel, line);
379
break;
380
case '@':
381
put_it(format, "Sec", channel, line);
382
break;
383
}
384
}
385
reset_display_target();
386
}
387
}
388
}
389
390
void funny_mode(char *from, char **ArgList)
391
{
392
char *mode, *channel;
393
ChannelList *chan = NULL;
394
395
if (!ArgList[0]) return;
396
397
channel = ArgList[0];
398
mode = ArgList[1];
399
PasteArgs(ArgList, 1);
400
401
if (in_join_list(channel, from_server))
402
{
403
update_channel_mode(from, channel, from_server, mode, chan);
404
update_all_status(current_window, NULL, 0);
405
got_info(channel, from_server, GOTMODE);
406
}
407
else
408
{
409
set_display_target(channel, LOG_CRAP);
410
if (do_hook(current_numeric, "%s %s %s", from, channel, mode))
411
put_it("%s", convert_output_format(fget_string_var(FORMAT_MODE_CHANNEL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, *FromUserHost ? FromUserHost:"�", channel, mode));
412
reset_display_target();
413
}
414
}
415
416
void update_user_mode(char *modes)
417
{
418
int onoff = 1;
419
char *p_umodes = get_possible_umodes(from_server);
420
421
for (; *modes; modes++)
422
{
423
if (*modes == '-')
424
onoff = 0;
425
else if (*modes == '+')
426
onoff = 1;
427
428
else if ((*modes >= 'a' && *modes <= 'z')
429
|| (*modes >= 'A' && *modes <= 'Z'))
430
{
431
size_t idx;
432
int c = *modes;
433
434
idx = ccspan(p_umodes, c);
435
if (p_umodes[idx] == 0)
436
ircpanic("Invalid user mode referenced");
437
set_server_flag(from_server, idx, onoff);
438
439
if (c == 'o' || c == 'O')
440
set_server_operator(from_server, onoff);
441
#if 0
442
char c = tolower(*modes);
443
size_t idx = (size_t) (strchr(umodes, c) - umodes);
444
445
set_server_flag(from_server, USER_MODE << idx, onoff);
446
447
if (c == 'o' || c == 'O')
448
set_server_operator(from_server, onoff);
449
#endif
450
}
451
}
452
}
453
454
void reinstate_user_modes (void)
455
{
456
char *modes = get_umode(from_server);
457
if (modes && *modes)
458
send_to_server("MODE %s +%s", get_server_nickname(from_server), modes);
459
}
460
461