Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/contrib/misc.c
1069 views
1
/*
2
* Copyright Colten Edwards (c) 1996
3
*/
4
#include "irc.h"
5
#include "struct.h"
6
7
#include "server.h"
8
#include "dcc.h"
9
#include "commands.h"
10
#include "crypt.h"
11
#include "vars.h"
12
#include "ircaux.h"
13
#include "lastlog.h"
14
#include "window.h"
15
#include "screen.h"
16
#include "who.h"
17
#include "hook.h"
18
#include "input.h"
19
#include "ignore.h"
20
#include "keys.h"
21
#include "names.h"
22
#include "alias.h"
23
#include "history.h"
24
#include "funny.h"
25
#include "ctcp.h"
26
#include "output.h"
27
#include "exec.h"
28
#include "notify.h"
29
#include "numbers.h"
30
#include "status.h"
31
#include "list.h"
32
#include "timer.h"
33
#include "userlist.h"
34
#include "misc.h"
35
#include "gui.h"
36
#include "flood.h"
37
#include "parse.h"
38
#include "whowas.h"
39
#include "hash2.h"
40
#include "cset.h"
41
42
#include <stdio.h>
43
#include <ctype.h>
44
45
#include <sys/types.h>
46
#include <sys/stat.h>
47
#include <signal.h>
48
49
#include <sys/time.h>
50
#include <sys/types.h>
51
#ifndef __OPENNT
52
#include <sys/resource.h>
53
#endif
54
#include <unistd.h>
55
56
#if defined(sparc) && defined(sun4c)
57
#include <sys/rusage.h>
58
#endif
59
60
#ifdef GUI
61
extern int guiipc[2];
62
extern int newscrollerpos, lastscrollerpos, lastscrollerwindow;
63
#endif
64
65
66
extern int user_count;
67
extern int shit_count;
68
extern int bot_count;
69
extern int in_server_ping;
70
71
int serv_action = 0;
72
int first_time = 0;
73
74
LastMsg last_msg[MAX_LAST_MSG+1] = { { NULL } };
75
LastMsg last_dcc[MAX_LAST_MSG+1] = { { NULL } };
76
LastMsg last_notice[MAX_LAST_MSG+1] = { { NULL } };
77
LastMsg last_servermsg[MAX_LAST_MSG+1] = { { NULL } };
78
LastMsg last_sent_msg[MAX_LAST_MSG+1] = {{ NULL }};
79
LastMsg last_sent_notice[MAX_LAST_MSG+1] = {{ NULL }};
80
LastMsg last_sent_topic[2] = {{ NULL }};
81
LastMsg last_sent_wall[2] = {{ NULL }};
82
LastMsg last_topic[2] = {{ NULL }};
83
LastMsg last_wall[MAX_LAST_MSG+1] = {{ NULL }};
84
LastMsg last_invite_channel[2] = {{ NULL }};
85
LastMsg last_ctcp[2] = {{ NULL }};
86
LastMsg last_sent_ctcp[2] = {{ NULL }};
87
LastMsg last_sent_dcc[MAX_LAST_MSG+1] = {{ NULL }};
88
89
extern int in_cparse;
90
91
#define SPLIT 1
92
93
94
ChannelList *idlechan_list = NULL;
95
96
extern NickTab *tabkey_array, *autoreply_array;
97
98
99
extern Ignore *ignored_nicks;
100
101
#ifdef REVERSE_WHITE_BLACK
102
char *color_str[] = {
103
"","","","","","","","",
104
"","","","","","","","", "",
105
"", "", "","", "","","", "",
106
"", "", "","", "","","", "",
107
"", "", "", ""};
108
109
#else
110
111
char *color_str[] = {
112
"","","","","","","","",
113
"","","","","","","","", "",
114
"", "", "","", "","","", "",
115
"", "", "","", "","","", "",
116
"", "", "", ""};
117
#endif
118
119
irc_server /**tmplink = NULL, *server_last = NULL, *split_link = NULL,*/ *map = NULL;
120
121
#define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min))
122
123
char *awaymsg = NULL;
124
125
char *convert_time (time_t ltime)
126
{
127
time_t days = 0,hours = 0,minutes = 0,seconds = 0;
128
static char buffer[40];
129
130
131
*buffer = '\0';
132
seconds = ltime % 60;
133
ltime = (ltime - seconds) / 60;
134
minutes = ltime%60;
135
ltime = (ltime - minutes) / 60;
136
hours = ltime % 24;
137
days = (ltime - hours) / 24;
138
sprintf(buffer, "%2ldd %2ldh %2ldm %2lds", days, hours, minutes, seconds);
139
return(*buffer ? buffer : empty_string);
140
}
141
142
BUILT_IN_COMMAND(do_uptime)
143
{
144
145
#ifdef ONLY_STD_CHARS
146
put_it("%s",convert_output_format("%G--[ %WBitchX%g-%wClient%g-%RStatistics %G]------------------------------------------",NULL));
147
put_it("%s",convert_output_format("%G| %CClient Version: %W$0 $1","%s %s", irc_version, internal_version));
148
put_it("%s",convert_output_format("%G| %CClient Running Since %W$0-","%s",my_ctime(start_time)));
149
put_it("%s",convert_output_format("%G| %CClient Uptime: %W$0-","%s",convert_time(now-start_time)));
150
put_it("%s",convert_output_format("%G| %CCurrent UserName: %W$0-","%s", username));
151
put_it("%s",convert_output_format("%G| %CCurrent RealName: %W$0-","%s", realname));
152
put_it("%s",convert_output_format("%G| %CLast Recv Message: %W$0-","%s",last_msg[0].last_msg?last_msg[0].last_msg:"None"));
153
put_it("%s",convert_output_format("%G| %CLast Recv Notice: %W$0-","%s",last_notice[0].last_msg?last_notice[0].last_msg:"None"));
154
put_it("%s",convert_output_format("%G| %CLast Sent Msg: %W$0-","%s",last_sent_msg[0].last_msg?last_sent_msg[0].last_msg:"None"));
155
put_it("%s",convert_output_format("%G| %CLast Sent Notice: %W$0-","%s",last_sent_notice[0].last_msg?last_sent_notice[0].last_msg:"None"));
156
put_it("%s",convert_output_format("%G| %CLast Channel invited to: %R$0-","%s",invite_channel?invite_channel:"None"));
157
put_it("%s",convert_output_format("%G| %cTotal Users on Userlist: %K[%R$0%K]","%d",user_count));
158
put_it("%s",convert_output_format("%G| %cTotal Users on Shitlist: %K[%R$0%K]","%d",shit_count));
159
160
#else
161
put_it("%s",convert_output_format("%G��[ %WBitchX%g�%wClient%g�%RStatistics %G]����---%g�--��%K-%g�����--%G�--��%K-%g�������--- %K--%g -",NULL));
162
put_it("%s",convert_output_format("%G| %CClient Version: %W$0 $1","%s %s", irc_version, internal_version));
163
put_it("%s",convert_output_format("%G� %CClient Running Since %W$0-","%s",my_ctime(start_time)));
164
put_it("%s",convert_output_format("%G| %CClient Uptime: %W$0-","%s",convert_time(now-start_time)));
165
put_it("%s",convert_output_format("%G� %CCurrent UserName: %W$0-","%s", username));
166
put_it("%s",convert_output_format("%G: %CCurrent RealName: %W$0-","%s", realname));
167
put_it("%s",convert_output_format("%G. %CLast Recv Message: %W$0-","%s",last_msg[0].last_msg?last_msg[0].last_msg:"None"));
168
put_it("%s",convert_output_format("%G: %CLast Recv Notice: %W$0-","%s",last_notice[0].last_msg?last_notice[0].last_msg:"None"));
169
put_it("%s",convert_output_format("%G. %CLast Sent Msg: %W$0-","%s",last_sent_msg[0].last_msg?last_sent_msg[0].last_msg:"None"));
170
put_it("%s",convert_output_format("%G: %CLast Sent Notice: %W$0-","%s",last_sent_notice[0].last_msg?last_sent_notice[0].last_msg:"None"));
171
put_it("%s",convert_output_format("%G� %CLast Channel invited to: %R$0-","%s",invite_channel?invite_channel:"None"));
172
put_it("%s",convert_output_format("%G| %cTotal Users on Userlist: %K[%R$0%K]","%d",user_count));
173
put_it("%s",convert_output_format("%G� %cTotal Users on Shitlist: %K[%R$0%K]","%d",shit_count));
174
175
#endif
176
}
177
178
/* extern_write -- controls whether others may write to our terminal or not. */
179
/* This is basically stolen from bsd -- so its under the bsd copyright */
180
BUILT_IN_COMMAND(extern_write)
181
{
182
char *tty;
183
struct stat sbuf;
184
const int OTHER_WRITE = 020;
185
int on = 0;
186
187
if (!(tty = ttyname(2)))
188
{
189
yell("Internal error: notify %s", "[email protected]");
190
yell("Error in ttyname()");
191
return;
192
}
193
if (stat(tty, &sbuf) < 0)
194
{
195
yell("Internal error: noTify %s", "[email protected]");
196
yell("Error in stat()");
197
return;
198
}
199
if (!args || !*args)
200
{
201
if (sbuf.st_mode & 020)
202
bitchsay("Mesg is \002On\002");
203
else
204
bitchsay("Mesg is \002Off\002");
205
return;
206
}
207
if (!my_stricmp(args, "ON") || !my_stricmp(args, "YES"))
208
on = 1;
209
else if (!my_stricmp(args, "OFF") || !my_stricmp(args, "NO"))
210
on = 0;
211
else
212
{
213
userage("Mesg", helparg);
214
return;
215
}
216
switch (on)
217
{
218
case 1 :
219
if (chmod(tty, sbuf.st_mode | OTHER_WRITE) < 0)
220
{
221
yell("Sorry, couldnt set your tty's mode");
222
return;
223
}
224
bitchsay("Mesg is \002On\002");
225
break;
226
case 0 :
227
if (chmod(tty, sbuf.st_mode &~ OTHER_WRITE) < 0)
228
{
229
yell("Sorry, couldnt set your tty's mode");
230
return;
231
}
232
bitchsay("Mesg is \002Off\002");
233
break;
234
}
235
236
}
237
238
239
int check_serverlag (void)
240
{
241
int i;
242
time_t new_t = now;
243
244
for (i = 0; i < number_of_servers; i++)
245
{
246
if (is_server_connected(i) && (new_t != server_list[i].lag_time))
247
{
248
server_list[i].lag_time = new_t;
249
my_send_to_server(i, "PING %lu %s", server_list[i].lag_time, get_server_itsname(i) ? get_server_itsname(i): get_server_name(i));
250
in_server_ping++;
251
server_list[i].lag = -1;
252
}
253
}
254
return 0;
255
}
256
257
int timer_unban (void *args)
258
{
259
char *p = (char *)args;
260
char *channel;
261
ChannelList *chan;
262
char *ban;
263
char *serv;
264
int server = from_server;
265
266
serv = next_arg(p, &p);
267
if (my_atol(serv) != server)
268
server = my_atol(serv);
269
if (server < 0 || server > number_of_servers || !server_list[server].connected)
270
server = from_server;
271
channel = next_arg(p, &p);
272
ban = next_arg(p, &p);
273
if ((chan = (ChannelList *)find_in_list((List **)&server_list[server].chan_list, channel, 0)) && ban_is_on_channel(ban, chan))
274
my_send_to_server(server, "MODE %s -b %s", channel, ban);
275
new_free(&serv);
276
return 0;
277
}
278
279
int timer_idlekick (void *args)
280
{
281
char *channel = (char *)args;
282
ChannelList *tmp = NULL;
283
int kick_count = 0;
284
UserList *user = NULL;
285
286
287
if (channel && (tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK)) && tmp->chop && tmp->max_idle && tmp->check_idle)
288
{
289
NickList *nick;
290
for (nick = next_nicklist(tmp, NULL); nick; nick = next_nicklist(tmp, nick))
291
{
292
if (!my_stricmp(nick->nick, get_server_nickname(from_server)))
293
continue;
294
if ((nick->chanop || nick->voice) && !get_cset_int_var(tmp->csets, KICK_OPS_CSET))
295
continue;
296
if ((user=nick->userlist) && check_channel_match(user->channels, channel))
297
continue;
298
if (now - nick->idle_time >= tmp->max_idle)
299
{
300
if (kick_count <= get_int_var(MAX_IDLEKICKS_VAR))
301
{
302
char *p = NULL;
303
malloc_sprintf(&p, "%s %s*!*%s", channel, nick->nick, nick->host);
304
send_to_server("MODE %s +b %s*!*%s", channel, nick->nick, nick->host);
305
send_to_server("KICK %s %s :\002%s\002: (Idle Channel User)", channel, nick->nick, version);
306
add_timer(0, "", 60, 1, timer_unban, m_sprintf("%d %s", from_server, p), NULL, current_window);
307
new_free(&p);
308
}
309
else
310
break;
311
kick_count++;
312
}
313
}
314
}
315
if (tmp && tmp->max_idle && tmp->check_idle)
316
add_timer(0, "", get_int_var(IDLE_CHECK_VAR), 1, timer_idlekick, channel, NULL, current_window);
317
else
318
new_free(&channel);
319
320
return 0;
321
}
322
323
BUILT_IN_COMMAND(addidle)
324
{
325
time_t default_idle = 10 * 60;
326
char *channel = NULL, *p;
327
time_t seconds = 0;
328
ChannelList *tmp, *new = NULL;
329
330
331
if ((p = next_arg(args, &args)))
332
{
333
malloc_strcpy(&channel, make_channel(p));
334
if (args && *args)
335
seconds = atol(args);
336
337
if (seconds < default_idle)
338
seconds = default_idle;
339
340
if (!(new = (ChannelList *)find_in_list((List **)&idlechan_list, channel, 0)))
341
{
342
new = (ChannelList *)new_malloc(sizeof(ChannelList));
343
malloc_strcpy(&new->channel, channel);
344
add_to_list((List **)&idlechan_list, (List *)new);
345
}
346
new->max_idle = seconds;
347
new->check_idle = (my_strnicmp(command, "UN", 2) == 0) ? 0: 1;
348
349
if (!new->check_idle)
350
{
351
bitchsay("Idle checking turned %s for %s",on_off(new->check_idle), channel);
352
if ((tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK)))
353
tmp->check_idle = tmp->max_idle = 0;
354
new_free(&channel);
355
new->max_idle = 0;
356
}
357
else
358
{
359
if ((tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK)))
360
{
361
if (new && new->check_idle)
362
{
363
tmp->max_idle = new->max_idle;
364
tmp->check_idle = new->check_idle;
365
add_timer(0, "", get_int_var(IDLE_CHECK_VAR), 1, timer_idlekick, channel, NULL, current_window);
366
bitchsay("Idle checking turned %s for %s %d mins",on_off(tmp->check_idle), channel, (int)(tmp->max_idle/60));
367
}
368
} else
369
new_free(&channel);
370
}
371
} else
372
userage(command, helparg);
373
}
374
375
BUILT_IN_COMMAND(showidle)
376
{
377
ChannelList *tmp;
378
char *channel = NULL;
379
int count = 0;
380
NickList *nick, *ntmp;
381
time_t ltime;
382
int server;
383
int sorted = 0;
384
while (args && *args)
385
{
386
if (!args || !*args)
387
break;
388
if ((*args == '-') && !my_strnicmp(args, "-sort", 3))
389
{
390
next_arg(args, &args);
391
sorted = NICKSORT_NONE;
392
}
393
else if (!my_strnicmp(args, "nick", 3) && sorted)
394
{
395
next_arg(args, &args);
396
sorted = NICKSORT_NICK;
397
}
398
else if (!my_strnicmp(args, "host", 3) && sorted)
399
{
400
next_arg(args, &args);
401
sorted = NICKSORT_HOST;
402
}
403
else if (!my_strnicmp(args, "time", 3) && sorted)
404
{
405
next_arg(args, &args);
406
sorted = NICKSORT_TIME;
407
}
408
else if (!my_strnicmp(args, "ip", 2) && sorted)
409
{
410
next_arg(args, &args);
411
sorted = NICKSORT_IP;
412
}
413
else
414
channel = next_arg(args, &args);
415
}
416
if (!(tmp = prepare_command(&server, channel, NO_OP)))
417
{
418
userage(command, helparg);
419
return;
420
}
421
ntmp = sorted_nicklist(tmp, sorted);
422
for (nick = ntmp; nick; nick = nick->next)
423
{
424
if (!count && do_hook(SHOWIDLE_HEADER_LIST, "%s %ld", tmp->channel, tmp->max_idle))
425
put_it("%s", convert_output_format("$G %W$a%n: Idle check for %W$0%n Max Idle Time %K[%W$1- %K]", "%s %s", tmp->channel, convert_time(tmp->max_idle)));
426
ltime = now - nick->idle_time;
427
if (do_hook(SHOWIDLE_LIST, "%s %s %d %ld", nick->nick, nick->host, find_user_level(nick->nick, nick->host, tmp->channel), ltime))
428
put_it("%s", convert_output_format("$[20]0 Idle%W: %K[%n$1- %K]", "%s %s", nick->nick, convert_time(ltime)));
429
count++;
430
}
431
if (count)
432
do_hook(SHOWIDLE_FOOTER_LIST, "%s", "End of idlelist");
433
clear_sorted_nicklist(&ntmp);
434
}
435
436
BUILT_IN_COMMAND(kickidle)
437
{
438
char *channel = NULL;
439
ChannelList *tmp;
440
int kick_count = 0;
441
int server = from_server;
442
443
444
if (args && *args)
445
channel = next_arg(args, &args);
446
447
if ((tmp = prepare_command(&server, channel, NEED_OP)) && tmp->max_idle)
448
{
449
NickList *nick;
450
for (nick = next_nicklist(tmp, NULL); nick; nick = next_nicklist(tmp, nick))
451
{
452
if (!my_stricmp(nick->nick, get_server_nickname(from_server)))
453
continue;
454
if (nick->userlist && check_channel_match(nick->userlist->channels, tmp->channel))
455
continue;
456
if (now - nick->idle_time >= tmp->max_idle)
457
{
458
if (kick_count <= get_int_var(MAX_IDLEKICKS_VAR))
459
my_send_to_server(server, "KICK %s %s :\002%s\002: (Idle Channel User)", tmp->channel, nick->nick, version);
460
else
461
bitchsay(" found idle user %-12s channel %s", nick->nick, tmp->channel);
462
kick_count++;
463
}
464
}
465
} else
466
userage(command, helparg);
467
}
468
469
void save_idle(FILE *output)
470
{
471
ChannelList *chan;
472
int count = 0;
473
474
475
if (!output)
476
return;
477
if (idlechan_list)
478
{
479
fprintf(output, "# %s Idle Channel list\n", version);
480
for (chan = idlechan_list; chan; chan = chan->next)
481
{
482
if (chan->max_idle)
483
{
484
fprintf(output, "ADDIDLE %s %d\n", chan->channel, (int)chan->max_idle);
485
count++;
486
}
487
}
488
}
489
if (count && do_hook(SAVEFILE_LIST, "Idle %d", count))
490
bitchsay("Saved %d Idle channels", count);
491
}
492
493
BUILT_IN_COMMAND(channel_stats)
494
{
495
ChannelList *new = NULL;
496
char *channel = NULL;
497
WhowasChanList *new1 = NULL;
498
int numircops = 0;
499
int usershere = 0;
500
int usersaway = 0;
501
int chanops = 0;
502
int chanunop = 0;
503
char *ircops = NULL;
504
int server = -1;
505
506
NickList *l;
507
unsigned long nick_mem = 0,
508
ban_mem = 0;
509
BanList *b;
510
511
512
513
514
if (args && *args)
515
{
516
channel = next_arg(args, &args);
517
if (my_strnicmp(channel, "-ALL", strlen(channel)))
518
{
519
channel = make_channel(channel);
520
if (!(new = prepare_command(&server, channel, 3)))
521
if ((channel && !(new1 = check_whowas_chan_buffer(channel, 0))))
522
return;
523
}
524
else
525
{
526
527
int stats_ops= 0, stats_dops = 0, stats_bans = 0, stats_unbans = 0;
528
int stats_topics = 0, stats_kicks = 0, stats_pubs = 0, stats_parts = 0;
529
int stats_signoffs = 0, stats_joins = 0;
530
int total_nicks = 0, max_nicks = 0, total_bans = 0, max_bans = 0;
531
int stats_sops = 0, stats_sdops = 0, stats_sbans = 0, stats_sunbans = 0;
532
533
NickList *l;
534
BanList *b;
535
unsigned long chan_mem = 0;
536
channel = NULL;
537
538
if (from_server != -1)
539
{
540
for (new = server_list[from_server].chan_list; new; new = new->next)
541
{
542
if (!channel)
543
malloc_strcpy(&channel, new->channel);
544
else
545
{
546
malloc_strcat(&channel, ",");
547
malloc_strcat(&channel, new->channel);
548
}
549
for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l))
550
{
551
switch(l->away)
552
{
553
case 'H':
554
usershere++;
555
break;
556
case 'G':
557
usersaway++;
558
default:
559
break;
560
}
561
if (l->ircop)
562
{
563
numircops++;
564
malloc_strcat(&ircops, " (");
565
malloc_strcat(&ircops, l->nick);
566
malloc_strcat(&ircops, ")");
567
}
568
if (l->chanop)
569
chanops++;
570
else
571
chanunop++;
572
nick_mem += sizeof(NickList);
573
}
574
for (b = new->bans; b; b = b->next)
575
ban_mem += sizeof(BanList);
576
chan_mem += sizeof(ChannelList);
577
stats_ops += new->stats_ops;
578
stats_dops += new->stats_dops;
579
stats_bans += new->stats_bans;
580
stats_unbans += new->stats_unbans;
581
stats_topics += new->stats_topics;
582
stats_kicks += new->stats_kicks;
583
stats_pubs += new->stats_pubs;
584
stats_parts += new->stats_parts;
585
stats_signoffs += new->stats_signoffs;
586
stats_joins += new->stats_joins;
587
588
total_nicks += new->totalnicks;
589
max_nicks += new->maxnicks;
590
total_bans += new->totalbans;
591
max_bans += new->maxbans;
592
stats_sops += new->stats_sops;
593
stats_sdops += new->stats_sdops;
594
stats_sbans += new->stats_sbans;
595
stats_sunbans += new->stats_sunbans;
596
}
597
}
598
if (!ircops)
599
malloc_strcat(&ircops, empty_string);
600
if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %lu %lu %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s",
601
channel, empty_string, empty_string,
602
nick_mem+chan_mem+ban_mem, nick_mem,
603
(unsigned long)sizeof(ChannelList),ban_mem,
604
stats_ops, stats_dops, stats_bans, stats_unbans,
605
stats_topics, stats_kicks, stats_pubs, stats_parts,
606
stats_signoffs, stats_joins, total_bans, max_bans,
607
stats_sops, stats_sdops,stats_sbans, stats_sunbans,
608
usershere, usersaway, chanops, chanunop,total_nicks,max_nicks,
609
numircops, ircops))
610
{
611
put_it("%s", convert_output_format("$G %CInformation for channels %K: %W$0", "%s", channel));
612
put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+chan_mem+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem));
613
put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_ops, stats_dops, stats_bans, stats_unbans));
614
put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_topics, stats_kicks, stats_pubs, stats_parts));
615
put_it("%s", convert_output_format("Signoffs %C[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_signoffs, stats_joins, total_bans, max_bans));
616
put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%d %d %d %d", stats_sops, stats_sdops,stats_sbans, stats_sunbans));
617
put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%d %d %d %d", usershere, usersaway, chanops, chanunop));
618
put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w", "%d %d", total_nicks,max_nicks));
619
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops));
620
}
621
new_free(&ircops);
622
new_free(&channel);
623
return;
624
}
625
}
626
else
627
{
628
if (!(new = prepare_command(&server, channel, 3)))
629
if ((channel && !(new1 = check_whowas_chan_buffer(channel, 0))))
630
return;
631
}
632
633
if (!new && new1)
634
new = new1->channellist;
635
if (!new)
636
{
637
bitchsay("Try joining a channel first");
638
return;
639
}
640
if (new)
641
{
642
for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l))
643
{
644
nick_mem += sizeof(NickList);
645
switch(l->away)
646
{
647
case 'H':
648
usershere++;
649
break;
650
case 'G':
651
usersaway++;
652
default:
653
break;
654
}
655
if (l->ircop)
656
{
657
numircops++;
658
malloc_strcat(&ircops, " (");
659
malloc_strcat(&ircops, l->nick);
660
malloc_strcat(&ircops, ")");
661
}
662
if (l->chanop)
663
chanops++;
664
else
665
chanunop++;
666
}
667
for (b = new->bans; b; b = b->next)
668
ban_mem += sizeof(BanList);
669
}
670
if (!ircops)
671
malloc_strcat(&ircops, empty_string);
672
if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %ld %ld %ld %ld %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s",
673
new->channel, my_ctime(new->channel_create.tv_sec), convert_time(now-new->join_time.tv_sec),
674
nick_mem+sizeof(ChannelList)+ban_mem, nick_mem,
675
(unsigned long)sizeof(ChannelList),ban_mem,
676
new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans,
677
new->stats_topics, new->stats_kicks, new->stats_pubs, new->stats_parts,
678
new->stats_signoffs, new->stats_joins, new->totalbans, new->maxbans,
679
new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans,
680
usershere, usersaway, chanops, chanunop,new->totalnicks,new->maxnicks,
681
numircops, ircops))
682
{
683
put_it("%s", convert_output_format("$G %CInformation for channel %K: %W$0", "%s", new->channel));
684
put_it("%s", convert_output_format("$G %CChannel created %K: %W$0 $1 $2 $3%n in memory %W$4-", "%s %s", convert_time(now-new->channel_create.tv_sec), my_ctime(new->join_time.tv_sec)));
685
686
put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+sizeof(ChannelList)+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem));
687
put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans));
688
put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_topics, new->stats_kicks, new->stats_pubs, new->stats_parts));
689
put_it("%s", convert_output_format("Signoffs %K[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_signoffs, new->stats_joins, new->totalbans, new->maxbans));
690
put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%d %d %d %d", new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans));
691
put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%d %d %d %d", usershere, usersaway, chanops, chanunop));
692
put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w", "%d %d", new->totalnicks,new->maxnicks));
693
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops));
694
695
put_it("%s", convert_output_format(" %CThere is %R$0%C limit and limit checking is %R$1-", "%s %s", new->limit ? ltoa(new->limit): "no", new->tog_limit?"Enabled":"Disabled"));
696
put_it("%s", convert_output_format(" %CIdle user check is %K[%R$0-%K]", "%s", new->check_idle?"Enabled":"Disabled"));
697
/*put_it("%s", convert_output_format("$G End of channel stats for $0", "%s", new->channel));*/
698
/* wtf is do_scan in the channel struct */
699
}
700
new_free(&ircops);
701
702
}
703
704
void update_stats(int what, char *channel, NickList *nick, ChannelList *chan, int splitter)
705
{
706
time_t this_time = now;
707
int t = 0;
708
709
710
if (!chan || !chan->channel)
711
return;
712
713
switch (what)
714
{
715
case KICKLIST:
716
{
717
chan->stats_kicks++;
718
chan->totalnicks--;
719
if (nick) nick->stat_kicks++;
720
break;
721
}
722
723
case LEAVELIST:
724
{
725
chan->stats_parts++;
726
chan->totalnicks--;
727
break;
728
}
729
case JOINLIST:
730
{
731
chan->stats_joins++;
732
chan->totalnicks++;
733
if (chan->totalnicks > chan->maxnicks)
734
{
735
chan->maxnicks = chan->totalnicks;
736
chan->maxnickstime = this_time;
737
}
738
if (!splitter)
739
{
740
if (chan->chop && is_other_flood(chan, nick, JOIN_FLOOD, &t))
741
{
742
if (get_cset_int_var(chan->csets, JOINFLOOD_CSET) && get_cset_int_var(chan->csets, KICK_ON_JOINFLOOD_CSET) && !nick->kickcount++)
743
{
744
send_to_server("MODE %s -o+b %s *!*%s", chan->channel, nick->nick, clear_server_flags(nick->host));
745
send_to_server("KICK %s %s :\002Join flood\002 (%d joins in %dsecs of %dsecs)", chan->channel, nick->nick, get_cset_int_var(chan->csets, KICK_ON_JOINFLOOD_CSET)/*chan->set_kick_on_joinflood*/, t, get_cset_int_var(chan->csets, JOINFLOOD_TIME_CSET));
746
if (get_int_var(AUTO_UNBAN_VAR))
747
add_timer(0, "", get_int_var(AUTO_UNBAN_VAR), 1, timer_unban, m_sprintf("%d %s *!*%s", from_server, chan->channel, clear_server_flags(nick->host)), NULL, current_window);
748
}
749
}
750
}
751
break;
752
}
753
case CHANNELSIGNOFFLIST:
754
{
755
chan->stats_signoffs++;
756
chan->totalnicks--;
757
break;
758
}
759
case PUBLICLIST:
760
case PUBLICOTHERLIST:
761
case PUBLICNOTICELIST:
762
case NOTICELIST:
763
{
764
chan->stats_pubs++;
765
if (nick)
766
{
767
nick->stat_pub++;
768
nick->idle_time = this_time;
769
}
770
break;
771
}
772
case TOPICLIST:
773
{
774
chan->stats_topics++;
775
break;
776
}
777
case MODEOPLIST:
778
if (splitter)
779
chan->stats_sops++;
780
else
781
{
782
if (nick) nick->stat_ops++;
783
chan->stats_ops++;
784
}
785
break;
786
case MODEHOPLIST:
787
if (splitter)
788
chan->stats_shops++;
789
else
790
{
791
if (nick) nick->stat_hops++;
792
chan->stats_hops++;
793
}
794
break;
795
case MODEDEHOPLIST:
796
if (splitter)
797
chan->stats_sdehops++;
798
else
799
{
800
if (nick) nick->stat_dhops++;
801
chan->stats_dhops++;
802
}
803
break;
804
case MODEDEOPLIST:
805
if (splitter)
806
chan->stats_sdops++;
807
else
808
{
809
chan->stats_dops++;
810
if (nick) nick->stat_dops++;
811
}
812
813
if (chan->chop && is_other_flood(chan, nick, DEOP_FLOOD, &t))
814
{
815
if (get_cset_int_var(chan->csets, DEOP_ON_DEOPFLOOD_CSET) < get_cset_int_var(chan->csets, KICK_ON_DEOPFLOOD_CSET))
816
send_to_server("MODE %s -o %s", chan->channel, nick->nick);
817
else if (!nick->kickcount++)
818
send_to_server("KICK %s %s :\002De-op flood\002 (%d de-ops in %dsecs of %dsecs)", chan->channel, nick->nick, get_cset_int_var(chan->csets, KICK_ON_DEOPFLOOD_CSET), t, get_cset_int_var(chan->csets, DEOPFLOOD_TIME_CSET));
819
}
820
break;
821
case MODEBANLIST:
822
if (splitter)
823
chan->stats_sbans++;
824
else
825
{
826
if (nick) nick->stat_bans++;
827
chan->stats_bans++;
828
}
829
chan->totalbans++;
830
if (chan->stats_bans > chan->maxbans)
831
{
832
chan->maxbans = chan->stats_bans;
833
chan->maxbanstime = this_time;
834
}
835
break;
836
case MODEUNBANLIST:
837
if (splitter)
838
chan->stats_sunbans++;
839
else
840
{
841
if (nick) nick->stat_unbans++;
842
chan->stats_unbans++;
843
}
844
if (chan->totalbans) chan->totalbans--;
845
break;
846
default:
847
break;
848
}
849
}
850
851
BUILT_IN_COMMAND(usage)
852
{
853
#if defined(HAVE_GETRUSAGE)
854
struct rusage r_usage;
855
856
857
if ((0 == getrusage(RUSAGE_SELF, &r_usage)))
858
{
859
/* struct timeval ru_utime; user time used
860
* struct timeval ru_stime; system time used
861
*/
862
int secs = r_usage.ru_utime.tv_sec + r_usage.ru_stime.tv_sec;
863
if (secs == 0)
864
secs =1;
865
866
#ifdef ONLY_STD_CHARS
867
put_it("%s", convert_output_format("%G--%WBitchX%G-%WUsage%G-%WStatistics%G------------------------------------", NULL));
868
put_it("%s",convert_output_format("%G| %CCPU %cUsage: Secs %W$[-2]0%n:%W$[-2]1%n %K[%CU%cser %W$[-2]2%n:%W$[-2]3 %CS%cystem %W$[-2]4%n:%W$[-2]5%K]","%d %d %d %d %d %d", secs/60,secs%60,r_usage.ru_utime.tv_sec/60, r_usage.ru_utime.tv_sec%60,r_usage.ru_stime.tv_sec/60, r_usage.ru_stime.tv_sec%60));
869
put_it("%s",convert_output_format("%G| %CMEM %cUsage: MaXRSS %W$0 %cShMem %W$1 %cData %W$2 %cStack %W$3","%l %l %l %l", r_usage.ru_maxrss, r_usage.ru_ixrss, r_usage.ru_idrss,r_usage.ru_isrss));
870
put_it("%s",convert_output_format("%G| %CSwaps %W$[-8]0 %CReclaims %W$[-8]1 %CFaults %W$[-8]2","%l %l %l", r_usage.ru_nswap, r_usage.ru_minflt, r_usage.ru_majflt));
871
put_it("%s",convert_output_format("%G| %CBlock %K[%cin %W$[-8]0 %cout %W$[-8]1%K]","%l %l", r_usage.ru_inblock, r_usage.ru_oublock));
872
put_it("%s",convert_output_format("%G| %CMsg %K[%cRcv %W$[-8]0 %cSend %W$[-8]1%K]","%l %l", r_usage.ru_msgrcv, r_usage.ru_msgsnd));
873
put_it("%s",convert_output_format("%G| %CSignals %W$[-8]0 %CContext %cVol. %W$[-8]1 %cInvol %W$[-8]2","%l %l %l", r_usage.ru_nsignals, r_usage.ru_nvcsw, r_usage.ru_nivcsw));
874
875
#else
876
put_it("%s", convert_output_format("%G��%WBitchX%G�%WUsage%G�%WStatistics%G����%g---%G�%g--%G��%g-%G������%g---%K�%g--%K��%g-%K��������", NULL));
877
put_it("%s",convert_output_format("%G| %CCPU %cUsage: Secs %W$[-2]0%n:%W$[-2]1%n %K[%CU%cser %W$[-2]2%n:%W$[-2]3 %CS%cystem %W$[-2]4%n:%W$[-2]5%K]","%d %d %d %d %d %d", secs/60,secs%60,r_usage.ru_utime.tv_sec/60, r_usage.ru_utime.tv_sec%60,r_usage.ru_stime.tv_sec/60, r_usage.ru_stime.tv_sec%60));
878
put_it("%s",convert_output_format("%g� %CMEM %cUsage: MaXRSS %W$0 %cShMem %W$1 %cData %W$2 %cStack %W$3","%l %l %l %l", r_usage.ru_maxrss, r_usage.ru_ixrss, r_usage.ru_idrss,r_usage.ru_isrss));
879
put_it("%s",convert_output_format("%g| %CSwaps %W$[-8]0 %CReclaims %W$[-8]1 %CFaults %W$[-8]2","%l %l %l", r_usage.ru_nswap, r_usage.ru_minflt, r_usage.ru_majflt));
880
put_it("%s",convert_output_format("%K� %CBlock %K[%cin %W$[-8]0 %cout %W$[-8]1%K]","%l %l", r_usage.ru_inblock, r_usage.ru_oublock));
881
put_it("%s",convert_output_format("%K: %CMsg %K[%cRcv %W$[-8]0 %cSend %W$[-8]1%K]","%l %l", r_usage.ru_msgrcv, r_usage.ru_msgsnd));
882
put_it("%s",convert_output_format("%K. %CSignals %W$[-8]0 %CContext %cVol. %W$[-8]1 %cInvol %W$[-8]2","%l %l %l", r_usage.ru_nsignals, r_usage.ru_nvcsw, r_usage.ru_nivcsw));
883
#endif
884
}
885
#else
886
bitchsay("Lack of getrusage(). This function needed to be disabled on your client");
887
#endif
888
}
889
890
char *clear_server_flags (char *userhost)
891
{
892
register char *uh = userhost;
893
while(uh && (*uh == '~' || *uh == '#' || *uh == '+' || *uh == '-' || *uh == '=' || *uh == '^'))
894
uh++;
895
return uh;
896
}
897
898
899
/*
900
* (max server send) and max mirc color change is 256
901
* so 256 * 8 should give us a safety margin for hackers.
902
* BIG_BUFFER is 1024 * 3 is 3072 whereas 256*8 is 2048
903
*/
904
905
static unsigned char newline1[BIG_BUFFER_SIZE+1];
906
907
#ifndef BITCHX_LITE1
908
char *mircansi(unsigned char *line)
909
{
910
/* mconv v1.00 (c) copyright 1996 Ananda, all rights reserved. */
911
/* ----------------------------------------------------------- */
912
/* mIRC->ansi color code convertor: 12.26.96 */
913
/* map of mIRC color values to ansi color codes */
914
/* format: ansi fg color ansi bg color */
915
/* modified Colten Edwards */
916
struct {
917
char *fg, *bg;
918
} codes[16] = {
919
920
{ "", "" }, /* white */
921
{ "", "" }, /* black (grey for us) */
922
{ "", "" }, /* blue */
923
{ "", "" }, /* green */
924
{ "", "" }, /* red */
925
{ "", "" }, /* brown */
926
927
{ "", "" }, /* magenta */
928
{ "", "" }, /* bright red */
929
{ "", "" }, /* yellow */
930
931
{ "", "" }, /* bright green */
932
{ "", "" }, /* cyan */
933
{ "", "" }, /* bright cyan */
934
{ "", "" }, /* bright blue */
935
{ "", "" }, /* bright magenta */
936
{ "", "" }, /* dark grey */
937
{ "", "" } /* grey */
938
};
939
register unsigned char *sptr = line, *dptr = newline1;
940
short code;
941
942
if (!*line)
943
return empty_string;
944
*newline1 = 0;
945
while (*sptr) {
946
if (*sptr == '' && isdigit(sptr[1]))
947
{
948
sptr++;
949
code = *sptr - '0';
950
sptr++;
951
if isdigit (*sptr) {
952
code = code * 10 + *sptr - '0';
953
sptr++;
954
}
955
if (code > 15 || code <= 0) code = code % 16;
956
strcpy(dptr, codes[code].fg);
957
while (*dptr) dptr++;
958
if (*sptr == ',')
959
{
960
sptr++;
961
code = *sptr - '0';
962
sptr++;
963
if isdigit (*sptr) {
964
code = code * 10 + *sptr - '0';
965
sptr++;
966
}
967
if (code > 15 || code <= 0) code = code % 16;
968
strcpy(dptr, codes[code].bg);
969
while (*dptr) dptr++;
970
}
971
}
972
else if (*sptr == '')
973
{
974
strcpy(dptr, "");
975
while(*dptr) dptr++;
976
sptr++;
977
}
978
else *dptr++ = *sptr++;
979
}
980
*dptr = 0;
981
return (char *)newline1;
982
}
983
#endif
984
985
/* Borrowed with permission from FLiER */
986
char *stripansicodes(const unsigned char *line)
987
{
988
register unsigned char *tstr;
989
register unsigned char *nstr;
990
int gotansi=0;
991
992
tstr=(char *)line;
993
nstr=newline1;
994
while (*tstr)
995
{
996
if (*tstr==0x1B || *tstr == 0x9b)
997
gotansi=1;
998
if (gotansi && isalpha(*tstr))
999
gotansi = 0;
1000
else if (!gotansi)
1001
{
1002
*nstr = *tstr;
1003
nstr++;
1004
}
1005
tstr++;
1006
}
1007
*nstr = 0;
1008
return (char *)newline1;
1009
}
1010
1011
char *stripansi(unsigned char *line)
1012
{
1013
register unsigned char *cp;
1014
unsigned char *newline;
1015
newline = m_strdup(line);
1016
for (cp = newline; *cp; cp++)
1017
if ((*cp < 31 && *cp > 13))
1018
if (*cp != 1 && *cp != 15 && *cp !=22 && *cp != 0x9b)
1019
*cp = (*cp & 127) | 64;
1020
return (char *)newline;
1021
}
1022
1023
1024
int check_split(char *nick, char *reason, char *chan)
1025
{
1026
char *bogus = get_string_var(FAKE_SPLIT_PATS_VAR);
1027
char *Reason = m_strdup(reason);
1028
char *tmp;
1029
1030
tmp = Reason;
1031
if (word_count(Reason) > 3)
1032
goto fail_split;
1033
if (wild_match("%.% %.%", Reason) && !strstr(Reason, "))") )
1034
{
1035
char *host1 = next_arg(Reason, &Reason);
1036
char *host2 = next_arg(Reason, &Reason);
1037
char *x = NULL;
1038
1039
if (!my_stricmp(host1, host2))
1040
goto fail_split;
1041
if (wild_match(host1, "*..*") || wild_match(host2, "*..*"))
1042
goto fail_split;
1043
if ((x = strrchr(host1, '.')))
1044
x++;
1045
if (!x || strlen(x) < 2 || strlen(x) > 3)
1046
goto fail_split;
1047
if ((x = strrchr(host2, '.')))
1048
x++;
1049
if (!x || strlen(x) < 2 || strlen(x) > 3)
1050
goto fail_split;
1051
1052
if (bogus)
1053
{
1054
char *copy = NULL;
1055
char *b_check;
1056
char *temp;
1057
malloc_strcpy(&copy, bogus);
1058
temp = copy;
1059
while((b_check = next_arg(copy, &copy)))
1060
{
1061
if (wild_match(b_check, host1) || wild_match(b_check, host2))
1062
{
1063
new_free(&temp);
1064
goto fail_split;
1065
}
1066
}
1067
new_free(&temp);
1068
}
1069
new_free(&tmp);
1070
return 1;
1071
}
1072
fail_split:
1073
new_free(&tmp);
1074
return 0;
1075
}
1076
1077
void clear_array(NickTab **tmp)
1078
{
1079
NickTab *t, *q;
1080
1081
for (t = *tmp; t; )
1082
{
1083
q = t->next;
1084
new_free(&t->nick);
1085
new_free(&t->type);
1086
new_free((char **)&t);
1087
t = q;
1088
}
1089
*tmp = NULL;
1090
}
1091
1092
BUILT_IN_COMMAND(clear_tab)
1093
{
1094
NickTab **tmp = &tabkey_array;
1095
if (command && *command && !my_stricmp(command, "CLEARAUTO"))
1096
tmp = &autoreply_array;
1097
clear_array(tmp);
1098
}
1099
1100
void userage(char *command, char *use)
1101
{
1102
if (command)
1103
{
1104
if (do_hook(USAGE_LIST, "%s %s", command, use ? use : "No Help Available for this command"))
1105
put_it("%s", convert_output_format(fget_string_var(FORMAT_USAGE_FSET), "%s %s", command, convert_output_format(use ? use : "%WNo Help available for this command", NULL, NULL)));
1106
}
1107
else
1108
put_it("Please return the command you just typed to #bitchx on efnet");
1109
}
1110
1111
char *random_str(int min, int max)
1112
{
1113
int i, ii;
1114
static char str[BIG_BUFFER_SIZE/4+1];
1115
1116
1117
1118
while ((i = getrandom(min, max)) > BIG_BUFFER_SIZE/4)
1119
;
1120
for (ii = 0; ii < i; ii++)
1121
str[ii] = (char) getrandom(97, 122);
1122
str[ii] = '\0';
1123
return str;
1124
}
1125
1126
1127
void auto_away(unsigned long value)
1128
{
1129
1130
if (get_int_var(AUTO_AWAY_VAR) && !get_server_away(from_server))
1131
{
1132
char *msg = NULL;
1133
if (awaymsg)
1134
malloc_sprintf(&msg, "%s: [%d mins]", convert_output_format(awaymsg, NULL), get_int_var(AUTO_AWAY_TIME_VAR)/60);
1135
else
1136
malloc_sprintf(&msg, "Auto-Away after %d mins", get_int_var(AUTO_AWAY_TIME_VAR)/60);
1137
away(NULL, msg, NULL, NULL);
1138
new_free(&msg);
1139
}
1140
}
1141
1142
/*char *logfile[] = { "tcl.log", "msg.log", NULL };*/
1143
1144
/* putlog(level,channel_name,format,...); */
1145
void putlog(int type, ...)
1146
{
1147
va_list va;
1148
time_t t;
1149
char *format,
1150
*chname,
1151
*logfilen = NULL,
1152
s[BIG_BUFFER_SIZE+1],
1153
s1[40],
1154
s2[BIG_BUFFER_SIZE+1];
1155
FILE *f;
1156
if (!get_int_var(BOT_LOG_VAR))
1157
return;
1158
if (!(logfilen = get_string_var(BOT_LOGFILE_VAR)))
1159
return;
1160
#ifdef PUBLIC_ACCESS
1161
return;
1162
#endif
1163
1164
va_start(va, type);
1165
t = now;
1166
strftime(s1, 30, "%I:%M%p", localtime(&t));
1167
chname=va_arg(va,char *);
1168
format=va_arg(va,char *);
1169
vsprintf(s,format,va);
1170
1171
if (!*s)
1172
strcpy(s2,empty_string);
1173
else
1174
sprintf(s2,"[%s] %s",s1,s);
1175
1176
if (chname && *chname =='*')
1177
{
1178
if ((f=fopen(logfilen, "a+")) != NULL)
1179
{
1180
fprintf(f,"%s\n",s2);
1181
fclose(f);
1182
}
1183
}
1184
}
1185
1186
int rename_file (char *old_file, char **new_file)
1187
{
1188
char *tmp = NULL;
1189
char buffer[BIG_BUFFER_SIZE+4];
1190
char *c = NULL;
1191
FILE *fp;
1192
1193
1194
1195
malloc_sprintf(&c,"%03i.",getrandom(0, 999));
1196
if (get_string_var(DCC_DLDIR_VAR))
1197
malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), &c);
1198
else
1199
malloc_sprintf(&tmp, "%s", &c);
1200
malloc_strcat(&tmp, *new_file);
1201
strmcpy(buffer, *new_file, BIG_BUFFER_SIZE);
1202
while ((fp = fopen(tmp, "r")) != NULL)
1203
{
1204
fclose(fp);
1205
new_free(&c);
1206
malloc_sprintf(&c,"%03i.",getrandom(0, 999));
1207
if (get_string_var(DCC_DLDIR_VAR))
1208
malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), &c);
1209
else
1210
malloc_sprintf(&tmp, "%s", &c);
1211
malloc_strcat(&tmp, buffer);
1212
}
1213
if (fp != NULL)
1214
fclose(fp);
1215
malloc_sprintf(new_file, "%s", c);
1216
malloc_strcat(new_file, buffer);
1217
new_free(&c);
1218
new_free(&tmp);
1219
return 0;
1220
}
1221
1222
int isme(char *nick)
1223
{
1224
return ((my_stricmp(nick, get_server_nickname(from_server)) == 0) ? 1 : 0);
1225
}
1226
1227
1228
void clear_link(irc_server **serv1)
1229
{
1230
irc_server *temp = *serv1, *hold;
1231
1232
while (temp != NULL)
1233
{
1234
hold = temp->next;
1235
new_free(&temp->name);
1236
new_free(&temp->link);
1237
new_free(&temp->time);
1238
new_free((char **) &temp);
1239
temp = hold;
1240
}
1241
*serv1 = NULL;
1242
}
1243
1244
irc_server *add_server(irc_server **serv1, char *channel, char *arg, int hops, char *time)
1245
{
1246
irc_server *serv2;
1247
serv2 = (irc_server *) new_malloc(sizeof (irc_server));
1248
serv2->next = *serv1;
1249
malloc_strcpy(&serv2->name, channel);
1250
malloc_strcpy(&serv2->link, arg);
1251
serv2->hopcount = hops;
1252
malloc_strcpy(&serv2->time, time);
1253
*serv1 = serv2;
1254
return serv2;
1255
}
1256
1257
int find_server(irc_server *serv1, char *channel)
1258
{
1259
register irc_server *temp;
1260
1261
for (temp = serv1; temp; temp = temp->next)
1262
{
1263
if (!my_stricmp(temp->name, channel))
1264
return 1;
1265
}
1266
return 0;
1267
}
1268
1269
void add_split_server(char *name, char *link, int hops)
1270
{
1271
irc_server *temp;
1272
temp = add_server(&(server_list[from_server].split_link), name, link, hops, update_clock(GET_TIME));
1273
temp->status = SPLIT;
1274
}
1275
1276
irc_server *check_split_server(char *server)
1277
{
1278
register irc_server *temp;
1279
if (!server) return NULL;
1280
for (temp = server_list[from_server].split_link; temp; temp = temp->next)
1281
if (!my_stricmp(temp->name, server))
1282
return temp;
1283
return NULL;
1284
}
1285
1286
void remove_split_server(char *server)
1287
{
1288
irc_server *temp;
1289
if ((temp = (irc_server *) remove_from_list((List **)&server_list[from_server].split_link, server)))
1290
{
1291
new_free(&temp->name);
1292
new_free(&temp->link);
1293
new_free(&temp->time);
1294
new_free((char **) &temp);
1295
}
1296
}
1297
1298
void parse_364(char *channel, char *args, char *subargs)
1299
{
1300
if (!*channel || !*args || from_server < 0)
1301
return;
1302
1303
add_server(&server_list[from_server].tmplink, channel, args, atol(subargs), update_clock(GET_TIME));
1304
}
1305
1306
void parse_365(char *channel, char *args, char *subargs)
1307
{
1308
register irc_server *serv1;
1309
1310
for (serv1 = server_list[from_server].server_last; serv1; serv1 = serv1->next)
1311
{
1312
if (!find_server(server_list[from_server].tmplink, serv1->name))
1313
{
1314
if (!(serv1->status & SPLIT))
1315
serv1->status = SPLIT;
1316
if (serv1->count)
1317
continue;
1318
malloc_strcpy(&serv1->time, update_clock(GET_TIME));
1319
if (do_hook(LLOOK_SPLIT_LIST, "%s %s %d %s", serv1->name, serv1->link, serv1->hopcount, serv1->time))
1320
put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount));
1321
serv1->count++;
1322
}
1323
else
1324
{
1325
if (serv1->status & SPLIT)
1326
{
1327
serv1->status = ~SPLIT;
1328
if (do_hook(LLOOK_JOIN_LIST, "%s %s %d %s", serv1->name, serv1->link, serv1->hopcount, serv1->time))
1329
put_it("%s", convert_output_format(fget_string_var(FORMAT_NETJOIN_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount));
1330
serv1->count = 0;
1331
}
1332
}
1333
}
1334
for (serv1 = server_list[from_server].tmplink; serv1; serv1 = serv1->next)
1335
{
1336
if (!find_server(server_list[from_server].server_last, serv1->name))
1337
{
1338
if (first_time == 1)
1339
{
1340
if (do_hook(LLOOK_ADDED_LIST, "%s %s %d", serv1->name, serv1->link, serv1->hopcount))
1341
put_it("%s", convert_output_format(fget_string_var(FORMAT_NETADD_FSET), "%s %s %s %d", serv1->time, serv1->name, serv1->link, serv1->hopcount));
1342
serv1->count = 0;
1343
}
1344
add_server(&server_list[from_server].server_last, serv1->name, serv1->link, serv1->hopcount, update_clock(GET_TIME));
1345
}
1346
}
1347
first_time = 1;
1348
clear_link(&server_list[from_server].tmplink);
1349
}
1350
1351
/*
1352
* find split servers we hope
1353
*/
1354
BUILT_IN_COMMAND(linklook)
1355
{
1356
struct server_split *serv;
1357
int count;
1358
1359
if (from_server == -1 || !(serv = server_list[from_server].server_last))
1360
{
1361
bitchsay("No active splits");
1362
return;
1363
}
1364
1365
count = 0;
1366
while (serv)
1367
{
1368
if (serv->status & SPLIT)
1369
{
1370
if (!count)
1371
put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_HEADER_FSET), "%s %s %s %s", "time","server","uplink","hops"));
1372
if (do_hook(LLOOK_SPLIT_LIST, "%s %s %d", serv->name, serv->link, serv->hopcount))
1373
put_it("%s", convert_output_format(fget_string_var(FORMAT_NETSPLIT_FSET), "%s %s %s %d", serv->time, serv->name, serv->link, serv->hopcount));
1374
count++;
1375
}
1376
serv = serv->next;
1377
}
1378
if (count)
1379
bitchsay("There %s %d split servers", (count == 1) ? "is": "are", count);
1380
else
1381
bitchsay("No split servers found");
1382
}
1383
1384
enum REDIR_TYPES { PRIVMSG = 0, KICK, TOPIC, WALL, WALLOP, NOTICE, KBOOT, KILL, DCC, LIST};
1385
void userhost_ban(UserhostItem *stuff, char *nick1, char *args);
1386
1387
int redirect_msg(char *to, enum REDIR_TYPES what, char *str, int showansi)
1388
{
1389
char *new_str;
1390
if (showansi)
1391
new_str = str;
1392
else
1393
new_str = stripansicodes(str);
1394
switch(what)
1395
{
1396
case PRIVMSG:
1397
if (is_channel(to))
1398
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_PUBLIC_FSET), "%s %s %s %s", update_clock(GET_TIME), "*", to, str));
1399
else if ((*to == '=') && dcc_activechat(to+1))
1400
;
1401
else
1402
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_MSG_FSET), "%s %s %s %s", update_clock(GET_TIME), to, "*", str));
1403
if ((*to == '=') && dcc_activechat(to+1))
1404
dcc_chat_transmit(to+1, new_str, str, "PRIVMSG", 1);
1405
else
1406
send_to_server("PRIVMSG %s :%s", to, new_str);
1407
break;
1408
case KILL:
1409
send_to_server("KILL %s :%s", to, new_str);
1410
break;
1411
case KBOOT:
1412
userhostbase(to, userhost_ban, 1, "%s %s %s", get_current_channel_by_refnum(0), to, "");
1413
case KICK:
1414
send_to_server("KICK %s %s :%s", get_current_channel_by_refnum(0), to, new_str);
1415
break;
1416
case TOPIC:
1417
send_to_server("TOPIC %s :%s", to, new_str);
1418
break;
1419
case WALL:
1420
{
1421
ChanWallOp(NULL, new_str, NULL, NULL);
1422
break;
1423
}
1424
case WALLOP:
1425
put_it("!! %s", str);
1426
send_to_server("WALLOPS :%s", new_str);
1427
break;
1428
case NOTICE:
1429
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), to, "*", str));
1430
send_to_server("NOTICE %s :%s", to, new_str);
1431
break;
1432
case LIST:
1433
default:
1434
break;
1435
}
1436
return 1;
1437
}
1438
1439
BUILT_IN_COMMAND(do_dirlasttype)
1440
{
1441
char *channel = NULL; int count = -1;
1442
LastMsg *t = NULL;
1443
char *form = NULL;
1444
char *sform;
1445
int numargs = 5;
1446
int size = 1;
1447
int len = strlen(command);
1448
int showansi = 0;
1449
enum REDIR_TYPES what = PRIVMSG;
1450
1451
if (!my_strnicmp(command, "RELCR", 5))
1452
{
1453
t = &last_ctcp[0];
1454
form = fget_string_var(FORMAT_CTCP_REPLY_FSET);
1455
sform = "%s %s %s %s %s";
1456
if (len == 6 && command[len-1] == 'T')
1457
what = TOPIC;
1458
}
1459
else if (!my_strnicmp(command, "RELC", 4))
1460
{
1461
t = &last_sent_ctcp[0];
1462
form = fget_string_var(FORMAT_SEND_CTCP_FSET);
1463
sform = "%s %s %s %s %s";
1464
if (len > 4 && command[len-1] == 'T')
1465
what = TOPIC;
1466
}
1467
else if (!my_strnicmp(command, "RELD", 4))
1468
{
1469
t = &last_dcc[0];
1470
form = fget_string_var(FORMAT_DCC_CHAT_FSET);
1471
sform = "%s %s %s %s";
1472
if (len > 4 && command[len-1] == 'T')
1473
what = TOPIC;
1474
numargs = 4;
1475
}
1476
else if (!my_strnicmp(command, "RELSD", 5))
1477
{
1478
t = &last_sent_dcc[0];
1479
form = fget_string_var(FORMAT_DCC_CHAT_FSET);
1480
sform = "%s %s %s %s";
1481
if (len > 5 && command[len-1] == 'T')
1482
what = TOPIC;
1483
numargs = 4;
1484
}
1485
else if (!my_strnicmp(command, "RELI", 4))
1486
{
1487
t = &last_invite_channel[0];
1488
form = fget_string_var(FORMAT_INVITE_FSET);
1489
numargs = 4;
1490
sform = "%s %s %s";
1491
if (len > 4 && command[len-1] == 'T')
1492
what = TOPIC;
1493
}
1494
else if (!my_strnicmp(command, "RELM", 4))
1495
{
1496
/* ??? */
1497
t = &last_msg[0]; size = MAX_LAST_MSG;
1498
form = fget_string_var(FORMAT_RELM_FSET);
1499
sform = "%s %s %s %s %s";
1500
if (len > 4 && command[len-1] == 'T')
1501
what = TOPIC;
1502
}
1503
else if (!my_strnicmp(command, "RELN", 4))
1504
{
1505
/* ??? */
1506
t = &last_notice[0]; size = MAX_LAST_MSG;
1507
form = fget_string_var(FORMAT_RELN_FSET);
1508
sform = "%s %s %s %s %s";
1509
if (len > 4 && command[len-1] == 'T')
1510
what = TOPIC;
1511
}
1512
else if (!my_strnicmp(command, "RELSM", 5))
1513
{
1514
/* ??? */
1515
t = &last_sent_msg[0]; size = MAX_LAST_MSG;
1516
form = fget_string_var(FORMAT_RELSM_FSET);
1517
sform = "%s %s %s %s %s";
1518
if (len > 5 && command[len-1] == 'T')
1519
what = TOPIC;
1520
}
1521
else if (!my_strnicmp(command, "RELSN", 5))
1522
{
1523
/* ??? */
1524
t = &last_sent_notice[0]; size = MAX_LAST_MSG;
1525
form = fget_string_var(FORMAT_SEND_NOTICE_FSET);
1526
sform = "%s %s %s %s";
1527
numargs = 4;
1528
if (len > 5 && command[len-1] == 'T')
1529
what = TOPIC;
1530
}
1531
else if (!my_strnicmp(command, "RELST", 5))
1532
{
1533
/* ??? */
1534
t = &last_sent_topic[0];
1535
form = fget_string_var(FORMAT_TOPIC_FSET);
1536
sform = "%s %s %s";
1537
numargs = 2;
1538
if (len > 5 && command[len-1] == 'T')
1539
what = TOPIC;
1540
}
1541
else if (!my_strnicmp(command, "RELSW", 5))
1542
{
1543
/* ??? */
1544
t = &last_sent_wall[0];
1545
form = fget_string_var(FORMAT_WALLOP_FSET);
1546
sform = "%s %s %s %s %s";
1547
if (len > 5 && command[len-1] == 'T')
1548
what = TOPIC;
1549
}
1550
else if (!my_strnicmp(command, "RELS", 4))
1551
{
1552
t = &last_servermsg[0]; size = MAX_LAST_MSG;
1553
form = fget_string_var(FORMAT_RELS_FSET);
1554
sform = "%s %s %s %s";
1555
numargs = 4;
1556
if (len > 4 && command[len-1] == 'T')
1557
what = TOPIC;
1558
}
1559
else if (!my_strnicmp(command, "RELT", 4))
1560
{
1561
/* ??? */
1562
t = &last_topic[0];
1563
form = fget_string_var(FORMAT_TOPIC_FSET);
1564
sform = "%s %s %s";
1565
numargs = 2;
1566
if (len > 4 && command[len-1] == 'T')
1567
what = TOPIC;
1568
}
1569
else if (!my_strnicmp(command, "RELW", 4))
1570
{
1571
/* ??? */
1572
t = &last_wall[0]; size = MAX_LAST_MSG;
1573
form = fget_string_var(FORMAT_WALLOP_FSET);
1574
sform = "%s %s %s %s";
1575
numargs = 4;
1576
if (len > 4 && command[len-1] == 'T')
1577
what = TOPIC;
1578
}
1579
else
1580
{
1581
what = LIST; size = MAX_LAST_MSG;
1582
t = &last_msg[0];
1583
for (count = size - 1; count != -1; count--)
1584
{
1585
if (t[count].last_msg)
1586
#if 0
1587
{
1588
bitchsay("No such msg #%d for /%s received", count, command);
1589
break;
1590
} else
1591
#endif
1592
put_it("%2d %s", count, convert_output_format(fget_string_var(FORMAT_RELM_FSET), "%s %s %s %s %s", t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg));
1593
}
1594
return;
1595
}
1596
1597
while (args && *args)
1598
{
1599
char *comm;
1600
if (!(comm = next_arg(args, &args)))
1601
break;
1602
if (!my_strnicmp(comm, "-list", strlen(comm)))
1603
{
1604
for (count = size - 1; count != -1; count--)
1605
{
1606
#if 0
1607
if (!count && !t[count].last_msg)
1608
{
1609
bitchsay("No such msg #%d for /%s received", count, command);
1610
break;
1611
} else if (!t[count].last_msg)
1612
break;
1613
#endif
1614
if (!t[count].last_msg)
1615
continue;
1616
switch(numargs)
1617
{
1618
case 2:
1619
put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].to, t[count].last_msg));
1620
break;
1621
case 3:
1622
put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].last_msg));
1623
break;
1624
case 4:
1625
put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].to, t[count].last_msg));
1626
break;
1627
case 5:
1628
put_it("%2d %s", count, convert_output_format(form, sform, t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg));
1629
}
1630
}
1631
return;
1632
}
1633
else if (!my_strnicmp(comm, "-kick", strlen(comm)))
1634
what = KICK;
1635
else if (!my_strnicmp(comm, "-wall", strlen(comm)))
1636
what = WALL;
1637
else if (!my_strnicmp(comm, "-wallop", strlen(comm)))
1638
what = WALLOP;
1639
else if (!my_strnicmp(comm, "-msg", strlen(comm)))
1640
what = PRIVMSG;
1641
else if (!my_strnicmp(comm, "-notice", strlen(comm)))
1642
what = NOTICE;
1643
else if (!my_strnicmp(comm, "-topic", strlen(comm)))
1644
what = TOPIC;
1645
else if (!my_strnicmp(comm, "-kboot", strlen(comm)))
1646
what = KBOOT;
1647
else if (!my_strnicmp(comm, "-kill", strlen(comm)))
1648
what = KILL;
1649
else if (!my_strnicmp(comm, "-ansi", strlen(comm)))
1650
showansi++;
1651
else if (!my_strnicmp(comm, "-help", strlen(comm)))
1652
{
1653
userage(command, helparg/*"<-list|-kick|-wall|-wallop|-msg|-notice|-topic|-kboot|-ansi|-kill|-help> <#|channel|nick> <channel|nick>"*/);
1654
return;
1655
}
1656
else
1657
{
1658
if (is_number(comm))
1659
{
1660
count = my_atol(comm);
1661
if (count < 0)
1662
count *= -1;
1663
}
1664
else
1665
channel = comm;
1666
}
1667
if (count > size)
1668
count = size;
1669
}
1670
if (count == -1)
1671
count = 0;
1672
if (!channel)
1673
channel = get_current_channel_by_refnum(0);
1674
if (channel || what == WALLOP)
1675
{
1676
char *p = NULL;
1677
if (!t[count].last_msg)
1678
{
1679
bitchsay("No such msg #%d for /%s received", count, command);
1680
return;
1681
}
1682
switch(numargs)
1683
{
1684
case 2:
1685
malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].to, t[count].last_msg));
1686
break;
1687
case 3:
1688
malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].last_msg));
1689
break;
1690
case 4:
1691
malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].to, t[count].last_msg));
1692
break;
1693
case 5:
1694
malloc_strcpy(&p, convert_output_format(form, sform, t[count].time, t[count].from, t[count].uh, t[count].to, t[count].last_msg));
1695
}
1696
redirect_msg(channel, what, p, showansi);
1697
new_free(&p);
1698
}
1699
else
1700
bitchsay("Can not %s what you requested", command);
1701
}
1702
1703
/*
1704
* Wallop Sends NOTICE to all ops of Current Channel!
1705
*/
1706
BUILT_IN_COMMAND(ChanWallOp)
1707
{
1708
char *channel = NULL;
1709
char *chops = NULL;
1710
char *include = NULL;
1711
char *exclude = NULL;
1712
ChannelList *chan;
1713
NickList *tmp;
1714
int ver = 0;
1715
int enable_all = 0;
1716
1717
char buffer[BIG_BUFFER_SIZE + 1];
1718
1719
if (!args || (args && !*args))
1720
{
1721
userage("WALLMSG", helparg);
1722
return;
1723
}
1724
if (get_current_channel_by_refnum(0))
1725
{
1726
int count = 0;
1727
int i = 0;
1728
char *nick = NULL;
1729
malloc_strcpy(&channel, get_current_channel_by_refnum(0));
1730
chan = lookup_channel(channel, current_window->server, 0);
1731
if (((ver = get_server_version(current_window->server)) == Server2_8hybrid6))
1732
enable_all = 1;
1733
else if (((ver = get_server_version(current_window->server)) < Server_u2_8))
1734
{
1735
while (args && (*args == '-' || *args == '+'))
1736
{
1737
nick = next_arg(args, &args);
1738
if (*nick == '-')
1739
{
1740
malloc_strcat(&exclude, nick+1);
1741
malloc_strcat(&exclude, " ");
1742
}
1743
else
1744
{
1745
malloc_strcat(&include, nick+1);
1746
malloc_strcat(&include, " ");
1747
}
1748
}
1749
}
1750
if (!args || !*args)
1751
{
1752
bitchsay("NO Wallmsg included");
1753
new_free(&exclude);
1754
new_free(&include);
1755
new_free(&channel);
1756
}
1757
message_from(channel, LOG_WALL);
1758
sprintf(buffer, "[\002BX-Wall\002/\002%s\002] %s", channel, args);
1759
if (ver >= Server_u2_10 || enable_all)
1760
{
1761
send_to_server(enable_all?"NOTICE @%s :%s":"WALLCHOPS %s :%s", channel, buffer);
1762
put_it("%s", convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), channel, "*", "*", args));
1763
add_last_type(&last_sent_wall[0], 1, NULL, NULL, channel, buffer);
1764
new_free(&channel);
1765
message_from(NULL, LOG_CRAP);
1766
return;
1767
}
1768
for (tmp = next_nicklist(chan, NULL); tmp; tmp = next_nicklist(chan, tmp))
1769
{
1770
if (!my_stricmp(tmp->nick, get_server_nickname(from_server)))
1771
continue;
1772
if (exclude && stristr(exclude, tmp->nick))
1773
continue;
1774
if (tmp->chanop == 1 || (include && stristr(include, tmp->nick)))
1775
{
1776
if (chops)
1777
malloc_strcat(&chops, ",");
1778
malloc_strcat(&chops, tmp->nick);
1779
count++;
1780
}
1781
if (count >= 8 && chops)
1782
{
1783
send_to_server("%s %s :%s", "NOTICE", chops, buffer);
1784
i+=count;
1785
count = 0;
1786
new_free(&chops);
1787
}
1788
}
1789
i+=count;
1790
if (chops)
1791
send_to_server("%s %s :%s", "NOTICE", chops, buffer);
1792
if (i)
1793
{
1794
put_it("%s", convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), channel, "*", "*", args));
1795
add_last_type(&last_sent_wall[0], 1, NULL, NULL, channel, buffer);
1796
if (exclude)
1797
bitchsay("Excluded <%s> from wallmsg", exclude);
1798
if (include)
1799
bitchsay("Included <%s> in wallmsg", include);
1800
}
1801
else
1802
put_it("%s", convert_output_format("$G No ops on $0", "%s", channel));
1803
message_from(NULL, LOG_CRAP);
1804
}
1805
else
1806
say("No Current Channel for this Window.");
1807
new_free(&include);
1808
new_free(&channel);
1809
new_free(&chops);
1810
new_free(&exclude);
1811
}
1812
1813
void log_toggle(int flag, ChannelList *chan)
1814
{
1815
char *logfile;
1816
1817
if (((logfile = get_string_var(MSGLOGFILE_VAR)) == NULL) || !get_string_var(CTOOLZ_DIR_VAR))
1818
{
1819
bitchsay("You must set the MSGLOGFILE and CTOOLZ_DIR variables first!");
1820
set_int_var(MSGLOG_VAR, 0);
1821
return;
1822
}
1823
logmsg(LOG_CURRENT, NULL, flag ? 1 : 2, NULL);
1824
}
1825
1826
void not_on_a_channel(Window *win)
1827
{
1828
if (win)
1829
message_to(win->refnum);
1830
bitchsay("You're not on a channel!");
1831
message_to(0);
1832
}
1833
1834
int are_you_opped(char *channel)
1835
{
1836
return is_chanop(channel, get_server_nickname(from_server));
1837
}
1838
1839
void error_not_opped(char *channel)
1840
{
1841
say("You're not opped on %s", channel);
1842
}
1843
1844
int freadln(FILE *stream, char *lin)
1845
{
1846
char *p;
1847
1848
do
1849
p = fgets(lin, BIG_BUFFER_SIZE/4, stream);
1850
while (p && (*lin == '#'));
1851
1852
if (!p)
1853
return 0;
1854
chop(lin, 1);
1855
if (!*lin)
1856
return 0;
1857
return 1;
1858
}
1859
1860
char *randreason(char *filename)
1861
{
1862
int count, min, i;
1863
FILE *bleah;
1864
static char buffer[BIG_BUFFER_SIZE/4 + 1];
1865
1866
min = 1;
1867
count = 0;
1868
1869
buffer[0] = '\0';
1870
1871
if (!filename || !(bleah = fopen(filename, "r")))
1872
return NULL;
1873
1874
while (!feof(bleah))
1875
if (freadln(bleah, buffer))
1876
count++;
1877
if (!count)
1878
{
1879
strcpy(buffer, "No Reason");
1880
return buffer;
1881
}
1882
fseek(bleah, 0, 0);
1883
i = getrandom(1, count);
1884
count = 0;
1885
1886
while (!feof(bleah) && (count < i))
1887
if (freadln(bleah, buffer))
1888
count++;
1889
fclose(bleah);
1890
1891
if (*buffer)
1892
return buffer;
1893
return NULL;
1894
}
1895
1896
char *get_reason(char *nick, char *file)
1897
{
1898
char *temp, *p;
1899
char *filename = NULL;
1900
if (file && *file)
1901
malloc_sprintf(&filename, "%s", file);
1902
else
1903
#if defined(WINNT) || defined(__EMX__)
1904
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "kck");
1905
#else
1906
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "reasons");
1907
#endif
1908
p = expand_twiddle(filename);
1909
temp = randreason(p);
1910
new_free(&filename);
1911
new_free(&p);
1912
if ((!temp || !*temp) && get_string_var(DEFAULT_REASON_VAR))
1913
temp = get_string_var(DEFAULT_REASON_VAR);
1914
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) )));
1915
}
1916
1917
char *get_realname(char *nick)
1918
{
1919
char *temp, *p;
1920
char *filename = NULL;
1921
1922
#if defined(WINNT) || defined(__EMX__)
1923
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "nam");
1924
#else
1925
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "ircnames");
1926
#endif
1927
p = expand_twiddle(filename);
1928
temp = randreason(p);
1929
new_free(&filename);
1930
new_free(&p);
1931
if ((!temp || !*temp))
1932
temp = "Who cares?";
1933
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) )));
1934
}
1935
1936
char *get_signoffreason(char *nick)
1937
{
1938
char *temp, *p;
1939
char *filename = NULL;
1940
1941
#if defined(WINNT) || defined(__EMX__)
1942
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "qt");
1943
#else
1944
malloc_sprintf(&filename, "%s/%s.%s", get_string_var(CTOOLZ_DIR_VAR), version, "quit");
1945
#endif
1946
p = expand_twiddle(filename);
1947
temp = randreason(p);
1948
new_free(&filename);
1949
new_free(&p);
1950
if (!temp || !*temp)
1951
temp = "$0 has no reason";
1952
1953
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server))));
1954
}
1955
1956
1957
#ifndef WINNT
1958
1959
/*
1960
* arlib.c (C)opyright 1993 Darren Reed. All rights reserved.
1961
* This file may not be distributed without the author's permission in any
1962
* shape or form. The author takes no responsibility for any damage or loss
1963
* of property which results from the use of this software.
1964
* heavily modified for use in a irc client.
1965
*/
1966
#include <stdio.h>
1967
#include <fcntl.h>
1968
#include <signal.h>
1969
#include <sys/types.h>
1970
#include <sys/time.h>
1971
#include <sys/socket.h>
1972
#include <netinet/in.h>
1973
#include <netdb.h>
1974
#include <arpa/nameser.h>
1975
#include <resolv.h>
1976
1977
#define HOSTLEN 100
1978
extern int h_errno;
1979
static char ar_hostbuf[HOSTLEN+1], ar_domainname[HOSTLEN+1];
1980
static char ar_dot[] = ".";
1981
static int ar_resfd = -1, ar_vc = 0;
1982
static struct reslist *ar_last = NULL, *ar_first = NULL;
1983
1984
1985
static int do_query_name(struct resinfo *, char *, register struct reslist *, char *, char *, char *, char *, int , void (*func)());
1986
static int do_query_number(struct resinfo *, char *, register struct reslist *, char *, char *, char *, char *, int , void (*func)());
1987
static int ar_resend_query(struct reslist *);
1988
1989
#define MAX_RETRIES 4
1990
1991
#ifndef HFIXEDSZ
1992
#define HFIXEDSZ 12
1993
#endif
1994
1995
#ifndef INT32SZ
1996
#define INT32SZ 4
1997
#endif
1998
1999
2000
/*
2001
* Statistics structure.
2002
*/
2003
static struct resstats {
2004
int re_errors;
2005
int re_nu_look;
2006
int re_na_look;
2007
int re_replies;
2008
int re_requests;
2009
int re_resends;
2010
int re_sent;
2011
int re_timeouts;
2012
} ar_reinfo;
2013
2014
/*
2015
* ar_init
2016
*
2017
* Initializes the various ARLIB internal varilables and related DNS
2018
* options for res_init().
2019
*
2020
* Returns 0 or the socket opened for use with talking to name servers
2021
* if 0 is passed or ARES_INITSOCK is set.
2022
*/
2023
int ar_init(int op)
2024
{
2025
int ret = 0;
2026
2027
if (op & ARES_INITLIST)
2028
{
2029
memset(&ar_reinfo, 0, sizeof(ar_reinfo));
2030
ar_first = ar_last = NULL;
2031
}
2032
2033
if (op & ARES_CALLINIT && !(_res.options & RES_INIT))
2034
{
2035
ret = res_init();
2036
(void)strcpy(ar_domainname, ar_dot);
2037
(void)strncat(ar_domainname, _res.defdname, HOSTLEN-2);
2038
if (!_res.nscount)
2039
{
2040
_res.nscount = 1;
2041
_res.nsaddr_list[0].sin_addr.s_addr = inet_addr("127.0.0.1");
2042
}
2043
}
2044
2045
if (op & ARES_INITSOCK)
2046
ret = ar_resfd = ar_open();
2047
2048
if (op & ARES_INITDEBG)
2049
_res.options |= RES_DEBUG;
2050
2051
if (op == 0)
2052
ret = ar_resfd;
2053
2054
return ret;
2055
}
2056
2057
/*
2058
* ar_open
2059
*
2060
* Open a socket to talk to a name server with.
2061
* Check _res.options to see if we use a TCP or UDP socket.
2062
*/
2063
int ar_open(void)
2064
{
2065
if (ar_resfd == -1)
2066
{
2067
if (_res.options & RES_USEVC)
2068
{
2069
struct sockaddr_in *sip;
2070
int i = 0;
2071
2072
sip = _res.nsaddr_list;
2073
ar_vc = 1;
2074
ar_resfd = socket(AF_INET, SOCK_STREAM, 0);
2075
2076
/*
2077
* Try each name server listed in sequence until we
2078
* succeed or run out.
2079
*/
2080
while (connect(ar_resfd, (struct sockaddr *)sip++,
2081
sizeof(struct sockaddr)))
2082
{
2083
(void)close(ar_resfd);
2084
ar_resfd = -1;
2085
if (i >= _res.nscount)
2086
break;
2087
ar_resfd = socket(AF_INET, SOCK_STREAM, 0);
2088
}
2089
}
2090
else
2091
{
2092
int on = 0;
2093
ar_resfd = socket(AF_INET, SOCK_DGRAM, 0);
2094
(void) setsockopt(ar_resfd, SOL_SOCKET, SO_BROADCAST,(char *)&on, sizeof(on));
2095
}
2096
}
2097
if (ar_resfd >= 0)
2098
{ /* Need one of these two here - and it MUST work!! */
2099
if (set_non_blocking(ar_resfd) < 0)
2100
{
2101
(void)close(ar_resfd);
2102
ar_resfd = -1;
2103
}
2104
}
2105
return ar_resfd;
2106
}
2107
2108
/*
2109
* ar_close
2110
*
2111
* Closes and flags the ARLIB socket as closed.
2112
*/
2113
void ar_close(void)
2114
{
2115
(void)close(ar_resfd);
2116
ar_resfd = -1;
2117
return;
2118
}
2119
2120
/*
2121
* ar_add_request
2122
*
2123
* Add a new DNS query to the end of the query list.
2124
*/
2125
static int ar_add_request(struct reslist *new)
2126
{
2127
if (!new)
2128
return -1;
2129
if (!ar_first)
2130
ar_first = ar_last = new;
2131
else
2132
{
2133
ar_last->re_next = new;
2134
ar_last = new;
2135
}
2136
new->re_next = NULL;
2137
ar_reinfo.re_requests++;
2138
return 0;
2139
}
2140
2141
/*
2142
* ar_remrequest
2143
*
2144
* Remove a request from the list. This must also free any memory that has
2145
* been allocated for temporary storage of DNS results.
2146
*
2147
* Returns -1 if there are anyy problems removing the requested structure
2148
* or 0 if the remove is successful.
2149
*/
2150
static int ar_remrequest(struct reslist *old)
2151
{
2152
struct reslist *rptr, *r2ptr;
2153
register char **s;
2154
2155
if (!old)
2156
return -1;
2157
for (rptr = ar_first, r2ptr = NULL; rptr; rptr = rptr->re_next)
2158
{
2159
if (rptr == old)
2160
break;
2161
r2ptr = rptr;
2162
}
2163
2164
if (!rptr)
2165
return -1;
2166
if (rptr == ar_first)
2167
ar_first = ar_first->re_next;
2168
else if (rptr == ar_last)
2169
{
2170
if ((ar_last = r2ptr))
2171
ar_last->re_next = NULL;
2172
}
2173
else
2174
r2ptr->re_next = rptr->re_next;
2175
2176
if (!ar_first)
2177
ar_last = ar_first;
2178
if (rptr->re_he.h_name)
2179
new_free(&rptr->re_he.h_name);
2180
if ((s = rptr->re_he.h_aliases))
2181
{
2182
for (; *s; s++)
2183
new_free(s);
2184
new_free(&rptr->re_he.h_aliases);
2185
}
2186
#if 0
2187
if ((s = rptr->re_he.h_addr_list))
2188
{
2189
/* CDE memleak detected here */
2190
for (; *s; s++)
2191
new_free(s);
2192
new_free(&rptr->re_he.h_addr_list);
2193
}
2194
#endif
2195
if (rptr->re_rinfo.ri_ptr)
2196
new_free(&rptr->re_rinfo.ri_ptr);
2197
2198
new_free(&rptr->nick);
2199
new_free(&rptr->user);
2200
new_free(&rptr->host);
2201
new_free(&rptr->channel);
2202
new_free(&rptr);
2203
2204
return 0;
2205
}
2206
2207
/*
2208
* ar_make_request
2209
*
2210
* Create a DNS query recorded for the request being made and place it on the
2211
* current list awaiting replies. Initialization of the record with set
2212
* values should also be done.
2213
*/
2214
static struct reslist *ar_make_request(register struct resinfo *resi, char *nick, char *user, char *h, char *chan, int server, void (*func)())
2215
{
2216
register struct reslist *rptr;
2217
register struct resinfo *rp;
2218
2219
rptr = (struct reslist *)new_malloc(sizeof(struct reslist));
2220
rp = &rptr->re_rinfo;
2221
2222
rptr->re_next = NULL; /* where NULL is non-zero ;) */
2223
rptr->re_sentat = now;
2224
rptr->re_retries = MAX_RETRIES;/*_res.retry + 2;*/
2225
rptr->re_sends = 1;
2226
rptr->re_resend = 1;
2227
rptr->re_timeout = rptr->re_sentat + _res.retrans;
2228
rptr->re_he.h_name = NULL;
2229
rptr->re_he.h_addrtype = AF_INET;
2230
rptr->re_he.h_aliases[0] = NULL;
2231
rp->ri_ptr = resi->ri_ptr;
2232
rp->ri_size = resi->ri_size;
2233
if (nick)
2234
malloc_strcpy(&rptr->nick, nick);
2235
if (user)
2236
malloc_strcpy(&rptr->user, user);
2237
if (h)
2238
malloc_strcpy(&rptr->host, h);
2239
if (chan)
2240
rptr->channel = m_strdup(chan);
2241
rptr->server = server;
2242
if (func)
2243
rptr->func = func;
2244
(void)ar_add_request(rptr);
2245
2246
return rptr;
2247
}
2248
2249
void ar_rename_nick(char *old_nick, char *new_nick, int server)
2250
{
2251
register struct reslist *rptr;
2252
for (rptr = ar_first; rptr; rptr = rptr->re_next)
2253
{
2254
if (!rptr->nick) continue;
2255
if (!strcmp(rptr->nick, old_nick) && rptr->server == server)
2256
malloc_strcpy(&rptr->nick, new_nick);
2257
}
2258
}
2259
2260
/*
2261
* ar_timeout
2262
*
2263
* Remove queries from the list which have been there too long without
2264
* being resolved.
2265
*/
2266
long ar_timeout(time_t now, char *info, int size, void (*func)(struct reslist *) )
2267
{
2268
register struct reslist *rptr, *r2ptr;
2269
register long next = 0;
2270
2271
for (rptr = ar_first, r2ptr = NULL; rptr; rptr = r2ptr)
2272
{
2273
r2ptr = rptr->re_next;
2274
if (now >= rptr->re_timeout)
2275
{
2276
/*
2277
* If the timeout for the query has been exceeded,
2278
* then resend the query if we still have some
2279
* 'retry credit' and reset the timeout. If we have
2280
* used it all up, then remove the request.
2281
*/
2282
if (--rptr->re_retries <= 0)
2283
{
2284
ar_reinfo.re_timeouts++;
2285
if (info && rptr->re_rinfo.ri_ptr)
2286
bcopy(rptr->re_rinfo.ri_ptr, info,
2287
MIN(rptr->re_rinfo.ri_size, size));
2288
if (rptr->func)
2289
(*rptr->func)(rptr);
2290
else if (func)
2291
(*func)(rptr);
2292
(void)ar_remrequest(rptr);
2293
return now;
2294
}
2295
else
2296
{
2297
rptr->re_sends++;
2298
rptr->re_sentat = now;
2299
rptr->re_timeout = now + _res.retrans;
2300
(void)ar_resend_query(rptr);
2301
}
2302
}
2303
if (!next || rptr->re_timeout < next)
2304
next = rptr->re_timeout;
2305
}
2306
return next;
2307
}
2308
2309
/*
2310
* ar_send_res_msg
2311
*
2312
* When sending queries to nameservers listed in the resolv.conf file,
2313
* don't send a query to every one, but increase the number sent linearly
2314
* to match the number of resends. This increase only occurs if there are
2315
* multiple nameserver entries in the resolv.conf file.
2316
* The return value is the number of messages successfully sent to
2317
* nameservers or -1 if no successful sends.
2318
*/
2319
static int ar_send_res_msg(char *msg, int len, int rcount)
2320
{
2321
register int i;
2322
int sent = 0;
2323
2324
if (!msg)
2325
return -1;
2326
2327
rcount = (_res.nscount > rcount) ? rcount : _res.nscount;
2328
if (_res.options & RES_PRIMARY)
2329
rcount = 1;
2330
if (!rcount)
2331
rcount = 1;
2332
if (ar_vc)
2333
{
2334
ar_reinfo.re_sent++;
2335
sent++;
2336
if (write(ar_resfd, msg, len) == -1)
2337
{
2338
int errtmp = errno;
2339
(void)close(ar_resfd);
2340
errno = errtmp;
2341
ar_resfd = -1;
2342
}
2343
}
2344
else
2345
for (i = 0; i < rcount; i++)
2346
{
2347
_res.nsaddr_list[i].sin_family = AF_INET;
2348
if (sendto(ar_resfd, msg, len, 0,
2349
(struct sockaddr *)&(_res.nsaddr_list[i]),
2350
sizeof(struct sockaddr_in)) == len)
2351
{
2352
ar_reinfo.re_sent++;
2353
sent++;
2354
}
2355
}
2356
return (sent) ? sent : -1;
2357
}
2358
2359
/*
2360
* ar_find_id
2361
*
2362
* find a dns query record by the id (id is determined by dn_mkquery)
2363
*/
2364
static struct reslist *ar_find_id(int id)
2365
{
2366
register struct reslist *rptr;
2367
2368
for (rptr = ar_first; rptr; rptr = rptr->re_next)
2369
if (rptr->re_id == id)
2370
return rptr;
2371
return NULL;
2372
}
2373
2374
/*
2375
* ar_delete
2376
*
2377
* Delete a request from the waiting list if it has a data pointer which
2378
* matches the one passed.
2379
*/
2380
int ar_delete(char *ptr, int size)
2381
{
2382
register struct reslist *rptr;
2383
register struct reslist *r2ptr;
2384
int removed = 0;
2385
2386
for (rptr = ar_first; rptr; rptr = r2ptr)
2387
{
2388
r2ptr = rptr->re_next;
2389
if (rptr->re_rinfo.ri_ptr && ptr && size &&
2390
memcmp(rptr->re_rinfo.ri_ptr, ptr, size) == 0)
2391
{
2392
(void)ar_remrequest(rptr);
2393
removed++;
2394
}
2395
}
2396
return removed;
2397
}
2398
2399
/*
2400
* ar_query_name
2401
*
2402
* generate a query based on class, type and name.
2403
*/
2404
static int ar_query_name(char *name, int class, int type, struct reslist *rptr)
2405
{
2406
static char buf[MAXPACKET];
2407
int r,s;
2408
HEADER *hptr;
2409
2410
memset(buf, 0, sizeof(buf));
2411
r = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
2412
buf, sizeof(buf));
2413
if (r <= 0)
2414
{
2415
h_errno = NO_RECOVERY;
2416
return r;
2417
}
2418
hptr = (HEADER *)buf;
2419
rptr->re_id = ntohs(hptr->id);
2420
2421
s = ar_send_res_msg(buf, r, rptr->re_sends);
2422
2423
if (s == -1)
2424
{
2425
h_errno = TRY_AGAIN;
2426
return -1;
2427
}
2428
else
2429
rptr->re_sent += s;
2430
return 0;
2431
}
2432
2433
/*
2434
* ar_gethostbyname
2435
*
2436
* Replacement library function call to gethostbyname(). This one, however,
2437
* doesn't return the record being looked up but just places the query in the
2438
* queue to await answers.
2439
*/
2440
int ar_gethostbyname(char *name, char *info, int size, char *nick, char *user, char *h, char *chan, int server, void (*func)())
2441
{
2442
char host[HOSTLEN+1];
2443
struct resinfo resi;
2444
register struct resinfo *rp = &resi;
2445
2446
if (size && info)
2447
{
2448
rp->ri_ptr = (char *)new_malloc(size+1);
2449
if (*info)
2450
bcopy(info, rp->ri_ptr, size);
2451
rp->ri_size = size;
2452
}
2453
else
2454
memset((char *)rp, 0, sizeof(resi));
2455
ar_reinfo.re_na_look++;
2456
(void)strncpy(host, name, 64);
2457
host[64] = '\0';
2458
2459
return (do_query_name(rp, host, NULL, nick, user, h, chan, server, func));
2460
}
2461
2462
static int do_query_name(struct resinfo *resi, char *name, register struct reslist *rptr, char *nick, char *user, char *h, char *chan, int server, void (*func)())
2463
{
2464
char hname[HOSTLEN];
2465
int len;
2466
2467
len = strlen((char *)strncpy(hname, name, sizeof(hname)-1));
2468
2469
if (rptr && (hname[len-1] != '.'))
2470
{
2471
(void)strncat(hname, ar_dot, sizeof(hname)-len-1);
2472
/*
2473
* NOTE: The logical relationship between DNSRCH and DEFNAMES
2474
* is implies. ie no DEFNAES, no DNSRCH.
2475
*/
2476
if ((_res.options & (RES_DEFNAMES|RES_DNSRCH)) ==
2477
(RES_DEFNAMES|RES_DNSRCH))
2478
{
2479
if (_res.dnsrch[(int)rptr->re_srch])
2480
(void)strncat(hname, _res.dnsrch[(int)rptr->re_srch],
2481
sizeof(hname) - ++len -1);
2482
}
2483
else if (_res.options & RES_DEFNAMES)
2484
(void)strncat(hname, ar_domainname, sizeof(hname) - len -1);
2485
}
2486
2487
/*
2488
* Store the name passed as the one to lookup and generate other host
2489
* names to pass onto the nameserver(s) for lookups.
2490
*/
2491
if (!rptr)
2492
{
2493
rptr = ar_make_request(resi, nick, user, h, chan, server, func);
2494
rptr->re_type = T_A;
2495
(void)strncpy(rptr->re_name, name, sizeof(rptr->re_name)-1);
2496
}
2497
return (ar_query_name(hname, C_IN, T_A, rptr));
2498
}
2499
2500
/*
2501
* ar_gethostbyaddr
2502
*
2503
* Generates a query for a given IP address.
2504
*/
2505
int ar_gethostbyaddr(char *addr, char *info, int size, char *nick, char *user, char *h, char *chan, int server, void (*func)())
2506
{
2507
struct resinfo resi;
2508
register struct resinfo *rp = &resi;
2509
2510
if (size && info)
2511
{
2512
rp->ri_ptr = (char *)new_malloc(size+1);
2513
if (*info)
2514
bcopy(info, rp->ri_ptr, size);
2515
rp->ri_size = size;
2516
}
2517
else
2518
memset((char *)rp, 0, sizeof(resi));
2519
ar_reinfo.re_nu_look++;
2520
return (do_query_number(rp, addr, NULL, nick, user, h, chan, server, func));
2521
}
2522
2523
/*
2524
* do_query_number
2525
*
2526
* Use this to do reverse IP# lookups.
2527
*/
2528
static int do_query_number(struct resinfo *resi, char *numb, register struct reslist *rptr, char *nick, char *user, char *h, char *chan, int server, void (*func)())
2529
{
2530
register unsigned char *cp;
2531
static char ipbuf[32];
2532
2533
/*
2534
* Generate name in the "in-addr.arpa" domain. No addings bits to this
2535
* name to get more names to query!.
2536
*/
2537
cp = (unsigned char *)numb;
2538
(void)sprintf(ipbuf,"%u.%u.%u.%u.in-addr.arpa.",
2539
(unsigned int)(cp[3]), (unsigned int)(cp[2]),
2540
(unsigned int)(cp[1]), (unsigned int)(cp[0]));
2541
2542
if (!rptr)
2543
{
2544
rptr = ar_make_request(resi, nick, user, h, chan, server, func);
2545
rptr->re_type = T_PTR;
2546
rptr->re_he.h_length = sizeof(struct in_addr);
2547
memcpy((char *)&rptr->re_addr, numb, rptr->re_he.h_length);
2548
memcpy((char *)&rptr->re_he.h_addr_list[0].s_addr, numb,
2549
rptr->re_he.h_length);
2550
}
2551
return (ar_query_name(ipbuf, C_IN, T_PTR, rptr));
2552
}
2553
2554
/*
2555
* ar_resent_query
2556
*
2557
* resends a query.
2558
*/
2559
static int ar_resend_query(struct reslist *rptr)
2560
{
2561
if (!rptr->re_resend)
2562
return -1;
2563
2564
switch(rptr->re_type)
2565
{
2566
case T_PTR:
2567
ar_reinfo.re_resends++;
2568
return do_query_number(NULL, (char *)&rptr->re_addr, rptr, NULL, NULL, NULL, NULL, -1, NULL);
2569
case T_A:
2570
ar_reinfo.re_resends++;
2571
return do_query_name(NULL, rptr->re_name, rptr, NULL, NULL, NULL, NULL, -1, NULL);
2572
default:
2573
break;
2574
}
2575
2576
return -1;
2577
}
2578
2579
/*
2580
* ar_procanswer
2581
*
2582
* process an answer received from a nameserver.
2583
*/
2584
static int ar_procanswer(struct reslist *rptr, HEADER *hptr, char *buf, char *eob)
2585
{
2586
char *cp, **alias;
2587
int class, type, dlen, len, ans = 0, n;
2588
unsigned int ttl, dr, *adr;
2589
struct hent *hp;
2590
2591
cp = buf + HFIXEDSZ;
2592
adr = (unsigned int *)rptr->re_he.h_addr_list;
2593
2594
while (*adr)
2595
adr++;
2596
2597
alias = rptr->re_he.h_aliases;
2598
while (*alias)
2599
alias++;
2600
2601
hp = &rptr->re_he;
2602
2603
2604
/*
2605
* Skip over the original question.
2606
*/
2607
while (hptr->qdcount-- > 0)
2608
cp += dn_skipname(cp, eob) + QFIXEDSZ;
2609
/*
2610
* proccess each answer sent to us. blech.
2611
*/
2612
while (hptr->ancount-- > 0 && cp < eob) {
2613
n = dn_expand(buf, eob, cp, ar_hostbuf, sizeof(ar_hostbuf)-1);
2614
cp += n;
2615
if (n <= 0)
2616
return ans;
2617
2618
ans++;
2619
/*
2620
* 'skip' past the general dns crap (ttl, class, etc) to get
2621
* the pointer to the right spot. Some of thse are actually
2622
* useful so its not a good idea to skip past in one big jump.
2623
*/
2624
type = (int)_getshort(cp);
2625
cp += sizeof(short);
2626
class = (int)_getshort(cp);
2627
cp += sizeof(short);
2628
ttl = (unsigned int)_getlong(cp);
2629
cp += INT32SZ;
2630
dlen = (int)_getshort(cp);
2631
cp += sizeof(short);
2632
rptr->re_type = type;
2633
2634
switch(type)
2635
{
2636
case T_A :
2637
rptr->re_he.h_length = dlen;
2638
if (ans == 1)
2639
rptr->re_he.h_addrtype=(class == C_IN) ?
2640
AF_INET : AF_UNSPEC;
2641
memcpy(&dr, cp, dlen);
2642
*adr++ = dr;
2643
*adr = 0;
2644
cp += dlen;
2645
len = strlen(ar_hostbuf);
2646
if (!rptr->re_he.h_name)
2647
malloc_strcpy(&rptr->re_he.h_name, ar_hostbuf);
2648
break;
2649
case T_PTR :
2650
if ((n = dn_expand(buf, eob, cp, ar_hostbuf,
2651
sizeof(ar_hostbuf)-1 )) < 0)
2652
{
2653
cp += n;
2654
continue;
2655
}
2656
ar_hostbuf[HOSTLEN] = 0;
2657
cp += n;
2658
len = strlen(ar_hostbuf)+1;
2659
/*
2660
* copy the returned hostname into the host name
2661
* or alias field if there is a known hostname
2662
* already.
2663
*/
2664
if (!rptr->re_he.h_name)
2665
malloc_strcpy(&rptr->re_he.h_name, ar_hostbuf);
2666
else
2667
{
2668
*alias = (char *)new_malloc(len);
2669
strcpy(*alias++, ar_hostbuf);
2670
*alias = NULL;
2671
}
2672
break;
2673
case T_CNAME :
2674
cp += dlen;
2675
if (alias >= &(rptr->re_he.h_aliases[MAXALIASES-1]))
2676
continue;
2677
n = strlen(ar_hostbuf)+1;
2678
*alias = (char *)new_malloc(n);
2679
(void)strcpy(*alias++, ar_hostbuf);
2680
*alias = NULL;
2681
break;
2682
default :
2683
break;
2684
}
2685
}
2686
2687
return ans;
2688
}
2689
2690
/*
2691
* ar_answer
2692
*
2693
* Get an answer from a DNS server and process it. If a query is found to
2694
* which no answer has been given to yet, copy its 'info' structure back
2695
* to where "reip" points and return a pointer to the hostent structure.
2696
*/
2697
struct hostent *ar_answer(char *reip, int size, void (*func)(struct reslist *) )
2698
{
2699
static char ar_rcvbuf[HFIXEDSZ + MAXPACKET];
2700
static struct hostent ar_host;
2701
2702
register HEADER *hptr;
2703
register struct reslist *rptr = NULL;
2704
register struct hostent *hp;
2705
register char **s;
2706
unsigned long *adr;
2707
int rc, i, n, a;
2708
2709
rc = recv(ar_resfd, ar_rcvbuf, sizeof(ar_rcvbuf), 0);
2710
if (rc <= 0)
2711
goto getres_err;
2712
2713
ar_reinfo.re_replies++;
2714
hptr = (HEADER *)ar_rcvbuf;
2715
/*
2716
* convert things to be in the right order.
2717
*/
2718
hptr->id = ntohs(hptr->id);
2719
hptr->ancount = ntohs(hptr->ancount);
2720
hptr->arcount = ntohs(hptr->arcount);
2721
hptr->nscount = ntohs(hptr->nscount);
2722
hptr->qdcount = ntohs(hptr->qdcount);
2723
/*
2724
* response for an id which we have already received an answer for
2725
* just ignore this response.
2726
*/
2727
rptr = ar_find_id(hptr->id);
2728
if (!rptr)
2729
goto getres_err;
2730
2731
if ((hptr->rcode != NOERROR) || (hptr->ancount == 0))
2732
{
2733
switch (hptr->rcode)
2734
{
2735
case NXDOMAIN:
2736
h_errno = HOST_NOT_FOUND;
2737
break;
2738
case SERVFAIL:
2739
h_errno = TRY_AGAIN;
2740
break;
2741
case NOERROR:
2742
h_errno = NO_DATA;
2743
break;
2744
case FORMERR:
2745
case NOTIMP:
2746
case REFUSED:
2747
default:
2748
h_errno = NO_RECOVERY;
2749
break;
2750
}
2751
ar_reinfo.re_errors++;
2752
/*
2753
** If a bad error was returned, we stop here and dont send
2754
** send any more (no retries granted).
2755
*/
2756
if (h_errno != TRY_AGAIN)
2757
{
2758
rptr->re_resend = 0;
2759
rptr->re_retries = 0;
2760
}
2761
goto getres_err;
2762
}
2763
2764
a = ar_procanswer(rptr, hptr, ar_rcvbuf, ar_rcvbuf+rc);
2765
2766
if ((rptr->re_type == T_PTR) && (_res.options & RES_CHECKPTR))
2767
{
2768
/*
2769
* For reverse lookups on IP#'s, lookup the name that is given
2770
* for the ip# and return with that as the official result.
2771
* -avalon
2772
*/
2773
rptr->re_type = T_A;
2774
/*
2775
* Clean out the list of addresses already set, even though
2776
* there should only be one :)
2777
*/
2778
adr = (unsigned long *)rptr->re_he.h_addr_list;
2779
while (*adr)
2780
*adr++ = 0L;
2781
/*
2782
* Lookup the name that we were given for the ip#
2783
*/
2784
ar_reinfo.re_na_look++;
2785
(void)strncpy(rptr->re_name, rptr->re_he.h_name,
2786
sizeof(rptr->re_name)-1);
2787
rptr->re_he.h_name = NULL;
2788
rptr->re_retries = MAX_RETRIES;/*_res.retry + 2;*/
2789
rptr->re_sends = 1;
2790
rptr->re_resend = 1;
2791
if (rptr->re_he.h_name)
2792
new_free(&rptr->re_he.h_name);
2793
ar_reinfo.re_na_look++;
2794
(void)ar_query_name(rptr->re_name, C_IN, T_A, rptr);
2795
return NULL;
2796
}
2797
2798
if (reip && rptr->re_rinfo.ri_ptr && size)
2799
memcpy(reip, rptr->re_rinfo.ri_ptr,
2800
MIN(rptr->re_rinfo.ri_size, size));
2801
2802
/*
2803
* Clean up structure from previous usage.
2804
*/
2805
hp = &ar_host;
2806
if (hp->h_name)
2807
new_free(&hp->h_name);
2808
if ((s = hp->h_aliases))
2809
{
2810
while (*s)
2811
{
2812
new_free(s);
2813
s++;
2814
}
2815
new_free(&hp->h_aliases);
2816
}
2817
if ((s = hp->h_addr_list))
2818
{
2819
2820
while (*s)
2821
{
2822
new_free(s);
2823
s++;
2824
}
2825
new_free(&hp->h_addr_list);
2826
hp->h_addr_list = NULL;
2827
}
2828
memset ((char *)hp, 0, sizeof(*hp));
2829
/*
2830
* Setup and copy details for the structure we return a pointer to.
2831
*/
2832
hp->h_addrtype = AF_INET;
2833
hp->h_length = sizeof(struct in_addr);
2834
malloc_strcpy(&hp->h_name, rptr->re_he.h_name);
2835
/*
2836
* Count IP#'s.
2837
*/
2838
for (i = 0, n = 0; i < MAXADDRS; i++, n++)
2839
if (!rptr->re_he.h_addr_list[i].s_addr)
2840
break;
2841
s = hp->h_addr_list = (char **)new_malloc((n + 1) * sizeof(char *));
2842
if (n)
2843
{
2844
*s = (char *)new_malloc(sizeof(struct in_addr));
2845
memcpy(*s, (char *)&rptr->re_he.h_addr_list[0].s_addr,
2846
sizeof(struct in_addr));
2847
s++;
2848
for (i = 1; i < n; i++, s++)
2849
{
2850
*s = (char *)new_malloc(sizeof(struct in_addr));
2851
memcpy(*s, (char *)&rptr->re_he.h_addr_list[i].s_addr,
2852
sizeof(struct in_addr));
2853
}
2854
}
2855
*s = NULL;
2856
/*
2857
* Count CNAMEs
2858
*/
2859
for (i = 0, n = 0; i < MAXADDRS; i++, n++)
2860
if (!rptr->re_he.h_aliases[i])
2861
break;
2862
s = hp->h_aliases = (char **)new_malloc((n + 1) * sizeof(char *));
2863
for (i = 0; i < n; i++)
2864
{
2865
*s++ = rptr->re_he.h_aliases[i];
2866
rptr->re_he.h_aliases[i] = NULL;
2867
}
2868
*s = NULL;
2869
if (rptr->func)
2870
(*rptr->func)(rptr);
2871
else if (func)
2872
(*func)(rptr);
2873
if (a > 0)
2874
(void)ar_remrequest(rptr);
2875
else
2876
if (!rptr->re_sent)
2877
(void)ar_remrequest(rptr);
2878
return hp;
2879
2880
getres_err:
2881
if (rptr)
2882
{
2883
if (reip && rptr->re_rinfo.ri_ptr && size)
2884
memcpy(reip, rptr->re_rinfo.ri_ptr,
2885
MIN(rptr->re_rinfo.ri_size, size));
2886
if ((h_errno != TRY_AGAIN) &&
2887
((_res.options & (RES_DNSRCH|RES_DEFNAMES)) ==
2888
(RES_DNSRCH|RES_DEFNAMES) ))
2889
if (_res.dnsrch[(int)rptr->re_srch])
2890
{
2891
rptr->re_retries = MAX_RETRIES; /*_res.retry + 2;*/
2892
rptr->re_sends = 1;
2893
rptr->re_resend = 1;
2894
(void)ar_resend_query(rptr);
2895
rptr->re_srch++;
2896
}
2897
return NULL;
2898
}
2899
return NULL;
2900
}
2901
2902
static int ar_seq = 0;
2903
static int ar_lookup = 0;
2904
2905
void auto_nslookup(struct reslist *rptr)
2906
{
2907
NickList *nick;
2908
ChannelList *chan;
2909
struct in_addr ip;
2910
if ((chan = lookup_channel(rptr->channel, rptr->server, 0)))
2911
{
2912
if ((nick = find_nicklist_in_channellist(rptr->nick, chan, 0)))
2913
{
2914
if (rptr->re_he.h_addr_list[0].s_addr)
2915
{
2916
bcopy(&rptr->re_he.h_addr_list[0], (char *)&ip, sizeof(ip));
2917
nick->ip = m_strdup(inet_ntoa(ip));
2918
check_auto(chan->channel, nick, chan);
2919
}
2920
else if (++nick->ip_count < 2)
2921
do_nslookup(rptr->host, rptr->nick, rptr->user, rptr->channel, rptr->server, auto_nslookup);
2922
#ifdef PANA_DEBUG
2923
else
2924
put_it("got here. nslookup failure %s!%s", nick->nick, nick->host);
2925
#endif
2926
}
2927
}
2928
return;
2929
}
2930
2931
void print_ns_succede(struct reslist *rptr)
2932
{
2933
char *u, *n, *h;
2934
u = rptr->user ? rptr->user : empty_string;
2935
h = rptr->host;
2936
n = rptr->nick ? rptr->nick : empty_string;
2937
if (do_hook(NSLOOKUP_LIST, "%s %s %s %s %s", h, rptr->re_he.h_name?rptr->re_he.h_name:"", (char *)inet_ntoa(rptr->re_he.h_addr_list[0]), n, u))
2938
{
2939
int i;
2940
char buffer[BIG_BUFFER_SIZE];
2941
struct in_addr ip;
2942
*buffer = 0;
2943
if (rptr->nick && rptr->user)
2944
bitchsay("[%s!%s@%s]: %s", n, u, h, rptr->re_he.h_name ? rptr->re_he.h_name: "invalid hostname");
2945
else
2946
bitchsay("%s is %s (%s)", h, rptr->re_he.h_name ? rptr->re_he.h_name:"invalid hostname", (char *)inet_ntoa(rptr->re_he.h_addr_list[0]));
2947
for (i = 0; rptr->re_he.h_addr_list[i].s_addr; i++)
2948
{
2949
bcopy(&rptr->re_he.h_addr_list[i], (char *)&ip, sizeof(ip));
2950
strpcat(buffer, "[%s] ", inet_ntoa(ip));
2951
if (strlen(buffer) > 490)
2952
break;
2953
}
2954
bitchsay("IPs: %s", buffer);
2955
for (i = 0; rptr->re_he.h_aliases[i]; i++)
2956
bitchsay("\talias %d = %s", i+1, rptr->re_he.h_aliases[i]);
2957
}
2958
2959
}
2960
2961
void print_ns_fail(struct reslist *rptr)
2962
{
2963
if (do_hook(NSLOOKUP_LIST, "%s %s %s", rptr->host, rptr->nick?rptr->nick:empty_string, rptr->user?rptr->user:empty_string))
2964
{
2965
if (rptr->nick && rptr->user)
2966
bitchsay("nslookup of %s!%s@%s failed.", rptr->nick, rptr->user, rptr->host);
2967
else
2968
bitchsay("nslookup of host %s failed.", rptr->host);
2969
}
2970
}
2971
2972
void set_nslookupfd(fd_set *rd)
2973
{
2974
int s;
2975
if ((s = ar_init(0)) != -1)
2976
FD_SET(s, rd);
2977
}
2978
2979
long print_nslookup(fd_set *rd)
2980
{
2981
struct hostent *hp = NULL;
2982
int ar_del = 0;
2983
int s;
2984
if ((s = ar_init(0)) == -1)
2985
return -1;
2986
if (!(FD_ISSET(s, rd)))
2987
{
2988
unsigned long when = 0;
2989
when = ar_timeout(now, (char *)&ar_del, sizeof(ar_del), print_ns_fail);
2990
if (ar_del)
2991
ar_lookup--;
2992
return when;
2993
}
2994
if ((hp = ar_answer((char *)&ar_del, sizeof(ar_del), print_ns_succede)))
2995
{
2996
char **s;
2997
ar_lookup--;
2998
new_free(&hp->h_name);
2999
if ((s = hp->h_aliases))
3000
{
3001
while (*s)
3002
{
3003
new_free(s);
3004
s++;
3005
}
3006
new_free(&hp->h_aliases);
3007
}
3008
if ((s = hp->h_addr_list))
3009
{
3010
while (*s)
3011
{
3012
new_free(s);
3013
s++;
3014
}
3015
new_free(&hp->h_addr_list);
3016
}
3017
}
3018
return -1;
3019
}
3020
#else
3021
long print_nslookup(fd_set *rd)
3022
{
3023
return -1;
3024
}
3025
void set_nslookupfd(fd_set *rd)
3026
{
3027
}
3028
3029
void auto_nslookup(struct reslist *res)
3030
{
3031
}
3032
#endif
3033
3034
void ns_init(void)
3035
{
3036
#ifndef WINNT
3037
ar_init(ARES_INITLIST|ARES_CALLINIT|ARES_INITSOCK);
3038
#endif
3039
}
3040
3041
char *do_nslookup(char *host, char *nick, char *user, char *chan, int server, void (*func)())
3042
{
3043
#ifndef WINNT
3044
struct in_addr temp1;
3045
int s;
3046
3047
if (!host)
3048
return NULL;
3049
3050
if ((s = ar_init(0)) == -1)
3051
ar_init(ARES_INITLIST|ARES_INITSOCK|ARES_CALLINIT);
3052
3053
ar_lookup++;
3054
if (isdigit(*(host + strlen(host) - 1)))
3055
{
3056
ar_seq++;
3057
temp1.s_addr = inet_addr(host);
3058
ar_gethostbyaddr((char *)&temp1.s_addr, (char *)&ar_seq, sizeof(ar_seq), nick, user, host, chan, server, func);
3059
}
3060
else
3061
{
3062
ar_seq++;
3063
ar_gethostbyname(host, (char *)&ar_seq, sizeof(ar_seq), nick, user, host, chan, server, func);
3064
}
3065
#endif
3066
return NULL;
3067
}
3068
3069
#ifndef WINNT
3070
void userhost_nsl(UserhostItem *stuff, char *nick, char *args)
3071
{
3072
char *nsl;
3073
3074
if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "<UNKNOWN>") || my_stricmp(stuff->nick, nick))
3075
{
3076
say("No information for %s", nick);
3077
return;
3078
}
3079
nsl = do_nslookup(stuff->host, stuff->nick, stuff->user, NULL, from_server, NULL);
3080
}
3081
#endif
3082
3083
BUILT_IN_COMMAND(nslookup)
3084
{
3085
#ifndef WINNT
3086
char *host, *hostname;
3087
3088
if ((host = next_arg(args, &args)))
3089
{
3090
bitchsay("Checking tables...");
3091
if (!strchr(host, '.'))
3092
userhostbase(host, userhost_nsl, 1, "%s", host);
3093
else
3094
hostname = do_nslookup(host, NULL, NULL, NULL, from_server, NULL);
3095
}
3096
else
3097
userage(command, helparg);
3098
#endif
3099
}
3100
3101
3102
char *rights(string, num)
3103
char *string;
3104
int num;
3105
{
3106
if (strlen(string) < num)
3107
return string;
3108
return (string + strlen(string) - num);
3109
}
3110
3111
int numchar(char *string, char c)
3112
{
3113
int num = 0;
3114
3115
while (*string)
3116
{
3117
if (tolower(*string) == tolower(c))
3118
num++;
3119
string++;
3120
}
3121
return num;
3122
}
3123
3124
char *cluster (char *hostname)
3125
{
3126
static char result[BIG_BUFFER_SIZE/4 + 1];
3127
char temphost[BIG_BUFFER_SIZE + 1];
3128
char *host;
3129
3130
if (!hostname)
3131
return NULL;
3132
host = temphost;
3133
*result = 0;
3134
memset(result, 0, sizeof(result));
3135
memset(temphost, 0, sizeof(temphost));
3136
if (strchr(hostname, '@'))
3137
{
3138
if (*hostname == '~')
3139
hostname++;
3140
strcpy(result, hostname);
3141
*strchr(result, '@') = '\0';
3142
if (strlen(result) > 9)
3143
{
3144
result[8] = '*';
3145
result[9] = '\0';
3146
}
3147
strcat(result, "@");
3148
if (!(hostname = strchr(hostname, '@')))
3149
return NULL;
3150
hostname++;
3151
}
3152
strcpy(host, hostname);
3153
3154
if (*host && isdigit(*(host + strlen(host) - 1)))
3155
{
3156
/* Thanks icebreak for this small patch which fixes this function */
3157
int i;
3158
char *tmp;
3159
char count=0;
3160
3161
tmp = host;
3162
while((tmp-host)<strlen(host))
3163
{
3164
if((tmp=strchr(tmp,'.'))==NULL)
3165
break;
3166
count++;
3167
tmp++;
3168
}
3169
tmp = host;
3170
for (i = 0; i < count; i++)
3171
tmp = strchr(tmp, '.') + 1;
3172
*tmp = '\0';
3173
strcat(result, host);
3174
strcat(result, "*");
3175
}
3176
else
3177
{
3178
char *tmp;
3179
int num;
3180
3181
num = 1;
3182
tmp = rights(host, 3);
3183
if (my_stricmp(tmp, "com") &&
3184
my_stricmp(tmp, "edu") &&
3185
my_stricmp(tmp, "net") &&
3186
(stristr(host, "com") ||
3187
stristr(host, "edu")))
3188
num = 2;
3189
while (host && *host && (numchar(host, '.') > num))
3190
{
3191
if ((host = strchr(host, '.')) != NULL)
3192
host++;
3193
else
3194
return (char *) NULL;
3195
}
3196
strcat(result, "*");
3197
if (my_stricmp(host, temphost))
3198
strcat(result, ".");
3199
strcat(result, host);
3200
}
3201
return result;
3202
}
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
struct _sock_manager
3216
{
3217
int init;
3218
int count;
3219
int max_fd;
3220
SocketList sockets[FD_SETSIZE];
3221
} sock_manager = {0, 0, -1, {{ 0, 0, 0, NULL, 0, 0, NULL, NULL, NULL }}};
3222
3223
#define SOCKET_TIMEOUT 120
3224
3225
3226
#ifdef GUI
3227
char *checkmenu(MenuList *check, int menuid)
3228
{
3229
MenuList *tmpml;
3230
MenuStruct *tmpms;
3231
char *tmpalias;
3232
3233
tmpml=check;
3234
while(tmpml!=NULL)
3235
{
3236
if (tmpml->menutype==GUISUBMENU || tmpml->menutype==GUISHARED || tmpml->menutype==GUIBRKSUBMENU)
3237
{
3238
tmpms = (MenuStruct *)findmenu(tmpml->submenu);
3239
if ((tmpalias=checkmenu(tmpms->menuorigin, menuid))!=NULL)
3240
return tmpalias;
3241
}
3242
if (tmpml->menuid==menuid)
3243
return tmpml->alias;
3244
tmpml=tmpml->next;
3245
}
3246
return NULL;
3247
}
3248
3249
void scan_gui(fd_set *rd)
3250
{
3251
char guicmd[3];
3252
extern MenuStruct *morigin;
3253
extern unsigned long menucmd;
3254
MenuStruct *tmpms;
3255
int newpos, cursb;
3256
char *alias;
3257
Window *scrollwin, *newfocuswindow;
3258
float bleah;
3259
Screen *newfocusscreen;
3260
3261
#ifdef __EMXPM__
3262
extern int just_resized;
3263
extern Screen *just_resized_screen;
3264
#endif
3265
3266
#ifdef __EMXPM__
3267
if(just_resized == 1)
3268
WinSendMsg(just_resized_screen->hwndFrame, 0x041e, 0, 0);
3269
#endif
3270
3271
/* Read the data from the pipe and decide what to do */
3272
if(FD_ISSET(guiipc[0], rd))
3273
{
3274
read(guiipc[0], guicmd, 2);
3275
switch(guicmd[0])
3276
{
3277
case '2':
3278
tmpms = morigin;
3279
while(tmpms!=NULL)
3280
{
3281
if((alias=checkmenu(tmpms->menuorigin, menucmd))!=NULL)
3282
{
3283
make_window_current(get_window_by_refnum((int)guicmd[1]));
3284
parse_line(NULL, alias, empty_string, 0, 0, 0);
3285
break;
3286
}
3287
tmpms=tmpms->next;
3288
}
3289
break;
3290
case '3':
3291
gui_flush();
3292
newfocuswindow=get_window_by_refnum((int)guicmd[1]);
3293
if(newfocuswindow)
3294
newfocusscreen=newfocuswindow->screen;
3295
else
3296
newfocusscreen=NULL;
3297
if (newfocusscreen && newfocusscreen->current_window)
3298
{
3299
make_window_current(newfocusscreen->current_window);
3300
output_screen=last_input_screen=newfocusscreen;
3301
set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 1);
3302
}
3303
update_input(UPDATE_ALL);
3304
break;
3305
case '4':
3306
refresh_window_screen(get_window_by_refnum((int)guicmd[1]));
3307
break;
3308
case '5':
3309
if(newscrollerpos != lastscrollerpos || lastscrollerwindow != (int)guicmd[1])
3310
{
3311
lastscrollerpos=newscrollerpos;
3312
lastscrollerwindow=(int)guicmd[1];
3313
scrollwin=get_window_by_refnum((int)guicmd[1]);
3314
bleah = get_int_var(SCROLLBACK_VAR);
3315
newpos = (int)(((bleah-newscrollerpos) / bleah) * (scrollwin->display_buffer_size));
3316
cursb = scrollwin->distance_from_display;
3317
printf("lsp = %d lsw = %d newpos = %d cursb = %d\n", lastscrollerpos, lastscrollerwindow, newpos, cursb);
3318
if (newpos > cursb)
3319
scrollback_backwards_lines(newpos-cursb);
3320
if (newpos < cursb)
3321
scrollback_forwards_lines(cursb-newpos);
3322
}
3323
break;
3324
case '6':
3325
scrollback_backwards_lines(1);
3326
break;
3327
case '7':
3328
scrollback_forwards_lines(1);
3329
break;
3330
case '8':
3331
scrollback_backwards((char)NULL, NULL);
3332
break;
3333
case '9':
3334
scrollback_forwards((char)NULL, NULL);
3335
break;
3336
case 'A':
3337
wm_process((int)guicmd[1]);
3338
break;
3339
}
3340
}
3341
}
3342
#endif
3343
3344
3345
void read_clonelist(int s)
3346
{
3347
char buffer[IRCD_BUFFER_SIZE + 1];
3348
char *str = buffer;
3349
switch(dgets(str, s, 0, IRCD_BUFFER_SIZE))
3350
{
3351
case -1:
3352
{
3353
do_hook(SOCKET_LIST, "%d %s %d", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port);
3354
close_socketread(s);
3355
break;
3356
}
3357
case 0:
3358
break;
3359
default:
3360
{
3361
if ((buffer[strlen(buffer)-1] == '\r') || (buffer[strlen(buffer)-1] == '\n'))
3362
buffer[strlen(buffer)-1] = 0;
3363
if ((buffer[strlen(buffer)-1] == '\r') || (buffer[strlen(buffer)-1] == '\n'))
3364
buffer[strlen(buffer)-1] = 0;
3365
if (*buffer)
3366
do_hook(SOCKET_LIST, "%d %s %d %s", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port, buffer);
3367
}
3368
}
3369
}
3370
3371
void read_clonenotify(int s)
3372
{
3373
unsigned long flags = 0;
3374
flags = get_socketflags(s);
3375
do_hook(SOCKET_NOTIFY_LIST, "%d %s %d %d", s, sock_manager.sockets[s].server, sock_manager.sockets[s].port, (unsigned int)flags);
3376
}
3377
3378
unsigned long set_socketflags(int s, unsigned long flags)
3379
{
3380
if (check_socket(s))
3381
{
3382
sock_manager.sockets[s].flags = flags;
3383
return sock_manager.sockets[s].flags;
3384
}
3385
return 0;
3386
}
3387
3388
unsigned long get_socketflags(int s)
3389
{
3390
if (check_socket(s))
3391
return sock_manager.sockets[s].flags;
3392
return 0;
3393
}
3394
3395
char *get_socketserver(int s)
3396
{
3397
if (check_socket(s))
3398
return sock_manager.sockets[s].server;
3399
return NULL;
3400
}
3401
3402
void *get_socketinfo(int s)
3403
{
3404
if (check_socket(s))
3405
return sock_manager.sockets[s].info;
3406
return NULL;
3407
}
3408
3409
void set_socketinfo(int s, void *info)
3410
{
3411
if (check_socket(s))
3412
sock_manager.sockets[s].info = info;
3413
}
3414
3415
int get_max_fd(void)
3416
{
3417
return sock_manager.max_fd + 1;
3418
}
3419
3420
int add_socketread(int s, int port, unsigned long flags, char *server, void (*func_read)(int), void (*func_write)(int))
3421
{
3422
if (!sock_manager.init)
3423
{
3424
fd_set rd;
3425
FD_ZERO(&rd);
3426
set_socket_read(&rd, &rd);
3427
}
3428
if (s > FD_SETSIZE)
3429
return -1;
3430
if (s > sock_manager.max_fd)
3431
sock_manager.max_fd = s;
3432
sock_manager.count++;
3433
sock_manager.sockets[s].is_read = s;
3434
sock_manager.sockets[s].port = port;
3435
sock_manager.sockets[s].flags = flags;
3436
if (server)
3437
sock_manager.sockets[s].server = m_strdup(server);
3438
sock_manager.sockets[s].func_read = func_read;
3439
sock_manager.sockets[s].func_write = func_write;
3440
new_open(s);
3441
return s;
3442
}
3443
3444
int set_socketwrite(int s)
3445
{
3446
if (s > FD_SETSIZE)
3447
return -1;
3448
if (s > sock_manager.max_fd)
3449
sock_manager.max_fd = s;
3450
sock_manager.sockets[s].is_write = s;
3451
new_open_write(s);
3452
return s;
3453
}
3454
3455
void add_sockettimeout(int s, time_t timeout)
3456
{
3457
if (timeout < 0)
3458
{
3459
timeout = get_int_var(CONNECT_TIMEOUT_VAR);
3460
if (timeout <= 0)
3461
timeout = SOCKET_TIMEOUT;
3462
}
3463
if (timeout)
3464
sock_manager.sockets[s].time = now + timeout;
3465
else
3466
sock_manager.sockets[s].time = 0;
3467
}
3468
3469
void close_socketread(int s)
3470
{
3471
if (!sock_manager.count)
3472
return;
3473
if (sock_manager.sockets[s].is_read)
3474
{
3475
new_free(&sock_manager.sockets[s].server);
3476
if (sock_manager.sockets[s].is_write)
3477
new_close_write(s);
3478
new_close(s);
3479
memset(&sock_manager.sockets[s], 0, sizeof(SocketList));
3480
sock_manager.count--;
3481
if (s == sock_manager.max_fd)
3482
{
3483
int i;
3484
sock_manager.max_fd = -1;
3485
for (i = 0; i < FD_SETSIZE; i++)
3486
if (sock_manager.sockets[i].is_read)
3487
sock_manager.max_fd = i;
3488
}
3489
}
3490
}
3491
3492
int check_socket(int s)
3493
{
3494
if (s != -1 && sock_manager.count && sock_manager.sockets[s].is_read)
3495
return 1;
3496
return 0;
3497
}
3498
3499
int check_dcc_socket(int s)
3500
{
3501
if (sock_manager.count && sock_manager.sockets[s].is_read && sock_manager.sockets[s].info)
3502
{
3503
if ( ((dcc_struct_type *)sock_manager.sockets[s].info)->struct_type == DCC_STRUCT_TYPE)
3504
return 1;
3505
}
3506
return 0;
3507
}
3508
3509
int write_sockets(int s, unsigned char *str, int len, int nl)
3510
{
3511
if (s < 1)
3512
return -1;
3513
if (nl)
3514
{
3515
unsigned char *buf;
3516
buf = alloca(strlen(str)+4);
3517
strcpy(buf, str);
3518
strcat(buf, "\r\n");
3519
len += 2;
3520
return write(s, buf, len);
3521
}
3522
return write(s, str, len);
3523
}
3524
3525
int read_sockets(int s, unsigned char *str, int len)
3526
{
3527
if (s < 1)
3528
return -1;
3529
return read(s, str, len);
3530
}
3531
3532
void set_socket_read (fd_set *rd, fd_set *wr)
3533
{
3534
register int i;
3535
static int socket_init = 0;
3536
if (!socket_init)
3537
{
3538
memset(&sock_manager, 0, sizeof(sock_manager));
3539
socket_init++;
3540
sock_manager.init++;
3541
}
3542
if (!sock_manager.count) return;
3543
for (i = 0; i < sock_manager.max_fd + 1; i++)
3544
{
3545
if (sock_manager.sockets[i].is_read)
3546
FD_SET(sock_manager.sockets[i].is_read, rd);
3547
if (sock_manager.sockets[i].is_write)
3548
FD_SET(sock_manager.sockets[i].is_write, wr);
3549
}
3550
}
3551
3552
void scan_sockets(fd_set *rd, fd_set *wr)
3553
{
3554
register int i;
3555
time_t t = now;
3556
if (!sock_manager.count) return;
3557
for (i = 0; i < sock_manager.max_fd+1; i++)
3558
{
3559
if (sock_manager.sockets[i].is_read && FD_ISSET(sock_manager.sockets[i].is_read, rd))
3560
(sock_manager.sockets[i].func_read) (sock_manager.sockets[i].is_read);
3561
if (sock_manager.sockets[i].func_write && sock_manager.sockets[i].is_write && FD_ISSET(sock_manager.sockets[i].is_write, wr))
3562
(sock_manager.sockets[i].func_write) (sock_manager.sockets[i].is_write);
3563
if (sock_manager.sockets[i].time && (t >= sock_manager.sockets[i].time))
3564
close_socketread(i);
3565
}
3566
}
3567
3568
SocketList *get_socket(int s)
3569
{
3570
if (check_socket(s))
3571
return &sock_manager.sockets[s];
3572
return NULL;
3573
}
3574
3575
extern int dgets_errno;
3576
3577
void read_netfinger(int s)
3578
{
3579
char tmpstr[BIG_BUFFER_SIZE+1];
3580
register unsigned char *p = tmpstr;
3581
*tmpstr = 0;
3582
switch(dgets(tmpstr, s, 0, BIG_BUFFER_SIZE))
3583
{
3584
case 0:
3585
break;
3586
case -1:
3587
if (do_hook(SOCKET_LIST, "%d %d %s Remote closed connection", s, sock_manager.sockets[s].port, sock_manager.sockets[s].server))
3588
{
3589
if (dgets_errno == -1)
3590
bitchsay("Remote closed connection");
3591
}
3592
close_socketread(s);
3593
break;
3594
default:
3595
{
3596
chop(tmpstr, 1);
3597
while (*p)
3598
{
3599
switch(*p)
3600
{
3601
case 0210:
3602
case 0211:
3603
case 0212:
3604
case 0214:
3605
*p -= 0200;
3606
break;
3607
case 0x9b:
3608
case '\t':
3609
break;
3610
case '\n':
3611
case '\r':
3612
*p = '\0';
3613
break;
3614
default:
3615
if (!isprint(*p))
3616
*p = (*p & 0x7f) | 0x40;
3617
break;
3618
}
3619
p++;
3620
}
3621
if (do_hook(SOCKET_LIST, "%d %d %s %s", s, sock_manager.sockets[s].port, sock_manager.sockets[s].server, tmpstr))
3622
put_it("%s", tmpstr);
3623
}
3624
}
3625
}
3626
3627
void netfinger (char *name)
3628
{
3629
char *host = NULL;
3630
unsigned short port = 79;
3631
int s;
3632
3633
if (name)
3634
{
3635
if ((host = strrchr(name, '@')))
3636
*host++ = 0;
3637
else
3638
host = name;
3639
}
3640
if (!host || !*host)
3641
{
3642
say("Invalid @host or user@host.");
3643
return;
3644
}
3645
3646
if (name && *name)
3647
{
3648
if ((s = connect_by_number(host, &port, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0)
3649
{
3650
bitchsay("Finger connect error on %s@%s", name?name:empty_string, host);
3651
return;
3652
}
3653
if ((add_socketread(s, port, 0, name, read_netfinger, NULL)) > -1)
3654
{
3655
write_sockets(s, name, strlen(name), 1);
3656
add_sockettimeout(s, 120);
3657
} else
3658
close_socketread(s);
3659
}
3660
return;
3661
}
3662
3663
void start_finger (UserhostItem *stuff, char *nick, char *args)
3664
{
3665
char *finger_userhost = NULL;
3666
char *str;
3667
if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "<UNKNOWN>") || my_stricmp(stuff->nick, nick))
3668
{
3669
say("No information for %s", nick);
3670
return;
3671
}
3672
3673
malloc_sprintf(&finger_userhost, "%s@%s", stuff->user, stuff->host);
3674
str = finger_userhost;
3675
str = clear_server_flags(finger_userhost);
3676
say("Launching finger for %s (%s)", nick, finger_userhost);
3677
netfinger(str);
3678
new_free(&finger_userhost);
3679
}
3680
3681
BUILT_IN_COMMAND(finger)
3682
{
3683
char *userhost;
3684
3685
if ((userhost = next_arg(args, &args)))
3686
{
3687
if (!strchr(userhost, '@'))
3688
{
3689
userhostbase(userhost, start_finger, 1, "%s", userhost);
3690
return;
3691
}
3692
netfinger(userhost);
3693
}
3694
else
3695
userage(command, helparg);
3696
}
3697
3698
static void handle_socket_connect(int rc)
3699
{
3700
struct servent *serv;
3701
struct sockaddr_in addr;
3702
struct hostent *host;
3703
int address_len;
3704
3705
address_len = sizeof(struct sockaddr_in);
3706
if ((getpeername(rc, (struct sockaddr *) &addr, &address_len)) != -1)
3707
{
3708
serv = getservbyport(addr.sin_port,"tcp");
3709
address_len = sizeof(addr.sin_addr);
3710
host = gethostbyaddr((char *)&addr.sin_addr, address_len, AF_INET);
3711
put_it("Hostname %s:%s port %d is running (%s)", host->h_name, inet_ntoa(addr.sin_addr), htons(addr.sin_port), serv == NULL? "UNKNOWN":serv->s_name);
3712
}
3713
close_socketread(rc);
3714
}
3715
3716
static int scan(char *remote_host, int low_port, int high_port, struct hostent *host)
3717
{
3718
unsigned short int port;
3719
int rc;
3720
if (low_port == 0) low_port = 1;
3721
for (port = low_port;port <= high_port;port++)
3722
{
3723
if ((rc = connect_by_number(remote_host, &port, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0)
3724
continue;
3725
if ((add_socketread(rc, port, 0, NULL, handle_socket_connect, NULL)) > -1)
3726
add_sockettimeout(rc, 120);
3727
else
3728
close_socketread(rc);
3729
}
3730
3731
return 1;
3732
}
3733
3734
void userhost_scanport(UserhostItem *stuff, char *nick, char *args)
3735
{
3736
char *t;
3737
int low_port = 0,
3738
high_port = 0;
3739
struct hostent *host;
3740
3741
if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "<UNKNOWN>") || my_stricmp(stuff->nick, nick))
3742
{
3743
bitchsay("No such nick [%s] found", nick);
3744
return;
3745
}
3746
next_arg(args, &args);
3747
t = next_arg(args, &args);
3748
low_port = atol(t);
3749
t = next_arg(args, &args);
3750
high_port = atol(t);
3751
if ((host = resolv(stuff->host)))
3752
{
3753
bitchsay("Scanning %s ports %d to %d", stuff->host, low_port, high_port);
3754
scan(stuff->host, low_port, high_port, host);
3755
return;
3756
}
3757
bitchsay("Cannot resolv host %s for %s", stuff->host, stuff->nick);
3758
}
3759
3760
BUILT_IN_COMMAND(findports)
3761
{
3762
char *remote_host;
3763
int low_port = 6660;
3764
int high_port = 7000;
3765
struct hostent *host;
3766
3767
3768
if (args && *args)
3769
{
3770
char *tmp = NULL;
3771
remote_host = next_arg(args, &args);
3772
if (args && *args)
3773
{
3774
tmp = next_arg(args, &args);
3775
low_port = strtoul(tmp, NULL, 10);
3776
if (args && *args)
3777
{
3778
tmp = next_arg(args, &args);
3779
high_port = strtoul(tmp, NULL, 10);
3780
}
3781
else
3782
high_port = low_port;
3783
}
3784
if (strchr(remote_host, '.'))
3785
{
3786
if ((host = resolv(remote_host)))
3787
{
3788
bitchsay("Scanning %s's tcp ports %d through %d",remote_host, low_port,high_port);
3789
scan(remote_host, low_port, high_port, host);
3790
} else
3791
bitchsay("No such host %s", remote_host);
3792
}
3793
else
3794
userhostbase(remote_host, userhost_scanport, 1, "%s %d %d", remote_host, low_port, high_port);
3795
} else
3796
userage("FPORT", helparg);
3797
return;
3798
}
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
void userhost_ignore (UserhostItem *stuff, char *nick1, char *args)
3812
{
3813
char *p, *arg;
3814
char *nick = NULL, *user = NULL, *host = NULL;
3815
int old_window_display;
3816
char ignorebuf[BIG_BUFFER_SIZE+1];
3817
Ignore *igptr, *igtmp;
3818
WhowasList *whowas;
3819
3820
arg = next_arg(args, &args);
3821
if (!stuff || !stuff->nick || !nick1 || !strcmp(stuff->user, "<UNKNOWN>") || my_stricmp(stuff->nick, nick1))
3822
{
3823
if ((whowas = check_whowas_nick_buffer(nick1, arg, 0)))
3824
{
3825
bitchsay("Using WhoWas info for %s of %s ", arg, nick1);
3826
user = host; host = strchr(host, '@'); *host++ = 0;
3827
nick = whowas->nicklist->nick;
3828
}
3829
else
3830
{
3831
say("No match for user %s", nick1);
3832
return;
3833
}
3834
}
3835
else
3836
{
3837
user = clear_server_flags(stuff->user);
3838
host = stuff->host; nick = stuff->nick;
3839
}
3840
if (!arg || !*arg || !my_stricmp(arg, "+HOST"))
3841
sprintf(ignorebuf, "*!*@%s ALL -CRAP -PUBLIC", cluster(host));
3842
else if (!my_stricmp(arg, "+USER"))
3843
sprintf(ignorebuf, "*%s@%s ALL -CRAP -PUBLIC", user, cluster(host));
3844
else if (!my_stricmp(arg, "-USER") || !my_stricmp(arg, "-HOST"))
3845
{
3846
int found = 0;
3847
if (!my_stricmp(arg, "-HOST"))
3848
sprintf(ignorebuf, "*!*@%s", cluster(host));
3849
else
3850
sprintf(ignorebuf, "%s!%s@%s", nick, user, host);
3851
igptr = ignored_nicks;
3852
while (igptr != NULL)
3853
{
3854
igtmp = igptr->next;
3855
if (wild_match(igptr->nick, ignorebuf) ||
3856
wild_match(nick, igptr->nick))
3857
{
3858
sprintf(ignorebuf, "%s NONE", igptr->nick);
3859
old_window_display = window_display;
3860
window_display = 0;
3861
ignore(NULL, ignorebuf, ignorebuf, NULL);
3862
window_display = old_window_display;
3863
bitchsay("Unignored %s!%s@%s", nick, user, host);
3864
found++;
3865
}
3866
igptr = igtmp;
3867
}
3868
if (!found)
3869
bitchsay("No Match for ignorance of %s", nick);
3870
return;
3871
}
3872
old_window_display = window_display;
3873
window_display = 0;
3874
ignore(NULL, ignorebuf, ignorebuf, NULL);
3875
if ((arg = next_arg(args, &args)))
3876
{
3877
char tmp[BIG_BUFFER_SIZE+1];
3878
sprintf(tmp, "%s ^IGNORE %s NONE", arg, ignorebuf);
3879
timercmd("TIMER", tmp, NULL, NULL);
3880
}
3881
window_display = old_window_display;
3882
if ((p = strchr(ignorebuf, ' ')))
3883
*p = 0;
3884
say("Now ignoring ALL except CRAP and PUBLIC from %s", ignorebuf);
3885
return;
3886
}
3887
3888
BUILT_IN_COMMAND(reset)
3889
{
3890
refresh_screen(0, NULL);
3891
}
3892
3893
3894
extern char *channel_key (char *);
3895
BUILT_IN_COMMAND(cycle)
3896
{
3897
char *to = NULL;
3898
int server = from_server;
3899
ChannelList *chan;
3900
3901
if (args && args)
3902
to = next_arg(args, &args);
3903
3904
if (!(chan = prepare_command(&server, to, NO_OP)))
3905
return;
3906
my_send_to_server(server, "PART %s\nJOIN %s%s%s", chan->channel, chan->channel, chan->key?" ":"", chan->key?chan->key:"");
3907
/* my_send_to_server(server, "JOIN %s%s%s", chan->channel, chan->key?" ":"", chan->key?chan->key:"");*/
3908
}
3909
3910
3911
int do_newuser(char *command, char *args, char *subargs)
3912
{
3913
char *newusername = NULL;
3914
if ((newusername = next_arg(args, &args)))
3915
{
3916
#ifdef IDENT_FAKE
3917
FILE *outfile;
3918
char *p = NULL, *q = NULL;
3919
malloc_sprintf(&p, "~/%s", get_string_var(IDENT_HACK_VAR));
3920
q = expand_twiddle(p);
3921
outfile = fopen(q,"w");
3922
#ifdef CIDENTD
3923
fprintf(outfile,"hideme\nmynameis %s\n", newusername);
3924
#else
3925
fprintf(outfile,"%s", newusername);
3926
#endif
3927
fclose(outfile);
3928
#endif
3929
strmcpy(username, newusername, NAME_LEN);
3930
if (subargs && *subargs)
3931
strmcpy(realname, subargs, REALNAME_LEN);
3932
#ifdef IDENT_FAKE
3933
new_free(&p); new_free(&q);
3934
#endif
3935
reconnect_cmd(NULL, newusername, NULL, NULL);
3936
}
3937
else
3938
return 0;
3939
return 1;
3940
}
3941
3942
BUILT_IN_COMMAND(newnick)
3943
{
3944
char *newnick, *newusername;
3945
3946
if ((newnick = next_arg(args, &args)) &&
3947
(newusername = next_arg(args, &args)))
3948
do_newuser(newnick, newusername, args);
3949
else
3950
say("You must specify a nick and username");
3951
}
3952
3953
3954
BUILT_IN_COMMAND(newuser)
3955
{
3956
char *newusername;
3957
3958
if ((newusername = next_arg(args, &args)))
3959
{
3960
if ((do_newuser(NULL, newusername, args)))
3961
say("You must specify a username.");
3962
} else
3963
userage(command, helparg);
3964
}
3965
3966
BUILT_IN_COMMAND(do_ig)
3967
{
3968
char *nick;
3969
char ignore_type[6];
3970
int got_ignore_type = 0;
3971
int need_time = 0;
3972
if (!args || !*args)
3973
goto bad_ignore;
3974
3975
while ((nick = next_arg(args, &args)))
3976
{
3977
if (!nick || !*nick)
3978
goto bad_ignore;
3979
if (*nick == '-' || *nick == '+')
3980
{
3981
if (!my_stricmp(nick, "-USER") || !my_stricmp(nick, "+HOST") || !my_stricmp(nick, "+USER") || !my_stricmp(nick, "-HOST"))
3982
strcpy(ignore_type, nick);
3983
if (!args || !*args)
3984
goto bad_ignore;
3985
got_ignore_type++;
3986
continue;
3987
}
3988
else if (!got_ignore_type)
3989
{
3990
if (command && !my_strnicmp(command, "IGH",3))
3991
strcpy(ignore_type, "+HOST");
3992
else if (command && !my_strnicmp(command, "IG",2))
3993
strcpy(ignore_type, "+USER");
3994
if (command && !my_strnicmp(command, "UNIGH", 5))
3995
strcpy(ignore_type, "-HOST");
3996
else if (command && !my_strnicmp(command, "UNIG", 4))
3997
strcpy(ignore_type, "-USER");
3998
if (command && toupper(command[strlen(command)-1]) == 'T')
3999
need_time ++;
4000
}
4001
if (need_time)
4002
userhostbase(nick, userhost_ignore, 1, "%s %d", ignore_type, get_int_var(IGNORE_TIME_VAR));
4003
else
4004
userhostbase(nick, userhost_ignore, 1, "%s", ignore_type);
4005
}
4006
return;
4007
bad_ignore:
4008
userage(command, helparg);
4009
}
4010
4011
4012
4013
BUILT_IN_COMMAND(users)
4014
{
4015
ChannelList *chan;
4016
NickList *nicks;
4017
NickList *sortl = NULL;
4018
char *to = NULL,
4019
*spec = "*!*@*",
4020
*temp1 = NULL;
4021
char modebuf[BIG_BUFFER_SIZE + 1];
4022
char msgbuf[BIG_BUFFER_SIZE +1];
4023
int count = 0,
4024
ops = 0,
4025
msg = 0,
4026
num_kicks = 0,
4027
hook = 0,
4028
not = 0,
4029
server = from_server,
4030
sorted = NICKSORT_NORMAL;
4031
4032
*msgbuf = 0;
4033
*modebuf = 0;
4034
4035
while (args && *args)
4036
{
4037
if (!args || !*args)
4038
break;
4039
temp1 = next_arg(args, &args);
4040
if (*temp1 == '-')
4041
{
4042
if (!my_strnicmp(temp1, "-ops", strlen(temp1)))
4043
ops = 1;
4044
else if (!my_strnicmp(temp1, "-nonops", strlen(temp1)))
4045
ops = 2;
4046
else if (!my_strnicmp(temp1, "-msg", strlen(temp1)))
4047
msg = 1;
4048
else if (!my_strnicmp(temp1, "-notice", strlen(temp1)))
4049
msg = 2;
4050
else if (!my_strnicmp(temp1, "-nkill", strlen(temp1)))
4051
msg = 3;
4052
else if (!my_strnicmp(temp1, "-kill", strlen(temp1)))
4053
msg = 4;
4054
else if (!my_strnicmp(temp1, "-kick", strlen(temp1)))
4055
msg = 5;
4056
else if (!my_strnicmp(temp1, "-stats", strlen(temp1)))
4057
msg = 6;
4058
else if (!my_strnicmp(temp1, "-ips", strlen(temp1)))
4059
msg = 7;
4060
else if (!my_strnicmp(temp1, "-sort", strlen(temp1)) && args && *args)
4061
{
4062
if (!my_strnicmp(args, "none", 4))
4063
sorted = NICKSORT_NONE;
4064
else if (!my_strnicmp(args, "host", 4))
4065
sorted = NICKSORT_HOST;
4066
else if (!my_strnicmp(args, "nick", 4))
4067
sorted = NICKSORT_NICK;
4068
else if (!my_strnicmp(args, "ip", 3))
4069
sorted = NICKSORT_IP;
4070
else if (!my_strnicmp(args, "time", 3))
4071
sorted = NICKSORT_TIME;
4072
if (sorted != NICKSORT_NORMAL)
4073
next_arg(args, &args);
4074
}
4075
else if (strpbrk(temp1, "*!@."))
4076
{
4077
spec = temp1+1;
4078
not = 1;
4079
}
4080
}
4081
else if (temp1 && is_channel(temp1))
4082
to = temp1;
4083
else if (strpbrk(temp1, "*!@."))
4084
spec = temp1;
4085
else
4086
{
4087
if (args && *args)
4088
temp1[strlen(temp1)] = ' ';
4089
args = temp1;
4090
break;
4091
}
4092
}
4093
if (!spec || !*spec)
4094
spec = "*!*@*";
4095
if (!(chan = prepare_command(&server, to, NO_OP)))
4096
{
4097
bitchsay(to?"Not on that channel %s":"No such channel %s", to?to:empty_string);
4098
return;
4099
}
4100
message_from(chan->channel, LOG_CRAP);
4101
if (command && !my_stricmp(command, "CHOPS"))
4102
ops = 1;
4103
if (command && !my_stricmp(command, "NOPS"))
4104
ops = 2;
4105
4106
if ((msg == 1 || msg == 2) && (!args || !*args))
4107
{
4108
say("No message given");
4109
message_from(NULL, LOG_CRAP);
4110
return;
4111
}
4112
4113
switch (msg)
4114
{
4115
case 6:
4116
if (do_hook(STAT_HEADER_LIST, "%s %s %s %s %s", "Nick", "dops", "kicks","nicks","publics"))
4117
put_it("Nick dops kicks nicks publics");
4118
break;
4119
case 0:
4120
{
4121
char *f;
4122
if ((f = fget_string_var(FORMAT_USERS_TITLE_FSET)))
4123
put_it("%s", convert_output_format(f, "%s %s", update_clock(GET_TIME), chan->channel));
4124
}
4125
default:
4126
break;
4127
}
4128
4129
sortl = sorted_nicklist(chan, sorted);
4130
for (nicks = sortl; nicks; nicks = nicks->next)
4131
{
4132
sprintf(modebuf, "%s!%s", nicks->nick,
4133
nicks->host ? nicks->host : "<UNKNOWN@UNKNOWN>");
4134
if (msg == 7 && nicks->ip)
4135
{
4136
strcat(modebuf, " ");
4137
strcat(modebuf, nicks->ip);
4138
}
4139
if (((!not && wild_match(spec, modebuf)) || (not && !wild_match(spec, modebuf))) &&
4140
(!ops ||
4141
((ops == 1) && nicks->chanop) ||
4142
((ops == 2) && !nicks->chanop) ))
4143
{
4144
switch(msg)
4145
{
4146
case 3: /* nokill */
4147
count--;
4148
break;
4149
case 4: /* kill */
4150
{
4151
if (!isme(nicks->nick))
4152
my_send_to_server(server, "KILL %s :%s (%i", nicks->nick,
4153
args && *args ? args : get_reason(nicks->nick, NULL),
4154
count + 1);
4155
else
4156
count--;
4157
break;
4158
}
4159
case 5: /* mass kick */
4160
{
4161
if (!isme(nicks->nick))
4162
{
4163
if (*msgbuf)
4164
strcat(msgbuf, ",");
4165
strcat(msgbuf, nicks->nick);
4166
num_kicks++;
4167
} else
4168
count--;
4169
if ((get_int_var(NUM_KICKS_VAR) && (num_kicks == get_int_var(NUM_KICKS_VAR))) || strlen(msgbuf) >= 450)
4170
{
4171
my_send_to_server(server, "KICK %s %s :%s", chan->channel,
4172
msgbuf, (args && *args) ? args :
4173
"-=punt=-");
4174
*msgbuf = 0;
4175
num_kicks = 0;
4176
}
4177
break;
4178
}
4179
case 6:
4180
{
4181
if (!isme(nicks->nick))
4182
{
4183
if (do_hook(STAT_LIST, "%s %d %d %d %d", nicks->nick, nicks->dopcount, nicks->kickcount,
4184
nicks->nickcount, nicks->floodcount))
4185
put_it("%-10s %4d %4d %4d %4d",
4186
nicks->nick, nicks->dopcount, nicks->kickcount,
4187
nicks->nickcount, nicks->floodcount);
4188
}
4189
break;
4190
}
4191
case 7:
4192
if (do_hook(USERS_IP_LIST, "%s %s %s", nicks->nick, nicks->host, nicks->ip?nicks->ip:"Unknown"))
4193
put_it("%s!%s = %s", nicks->nick, nicks->host, nicks->ip?nicks->ip:"Unknown");
4194
break;
4195
case 1:
4196
case 2:
4197
{
4198
if (*msgbuf)
4199
strcat(msgbuf, ",");
4200
strcat(msgbuf, nicks->nick);
4201
if (strlen(msgbuf)+strlen(args) >= 490)
4202
{
4203
put_it("%s", convert_output_format(fget_string_var((msg == 1)?FORMAT_SEND_MSG_FSET:FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME),msgbuf, get_server_nickname(from_server), args));
4204
my_send_to_server(server, "%s %s :%s", (msg == 1) ? "PRIVMSG" : "NOTICE", msgbuf, args);
4205
*msgbuf = 0;
4206
}
4207
break;
4208
}
4209
default:
4210
{
4211
if (!count && do_hook(USERS_HEADER_LIST, "%s %s %s %s %s %s %s", "Level", "aop", "prot", "Channel", "Nick", "+o", "UserHost") && fget_string_var(FORMAT_USERS_HEADER_FSET))
4212
put_it("%s", convert_output_format(fget_string_var(FORMAT_USERS_HEADER_FSET), "%s", chan->channel));
4213
4214
if ((hook = do_hook(USERS_LIST, "%lu %s %s %s %c",
4215
nicks->userlist ? nicks->userlist->flags:nicks->shitlist?nicks->shitlist->level:0,
4216
chan->channel, nicks->nick,
4217
nicks->host,
4218
nicks->chanop ? '@' : ' ')))
4219
{
4220
put_it("%s", convert_output_format(fget_string_var(nicks->userlist?FORMAT_USERS_USER_FSET:nicks->shitlist?FORMAT_USERS_SHIT_FSET:FORMAT_USERS_FSET), "%s %s %s %s %s",
4221
nicks->userlist ? convert_flags(nicks->userlist->flags) : nicks->shitlist?ltoa(nicks->shitlist->level):"n/a ",
4222
chan->channel, nicks->nick,
4223
nicks->host,
4224
nicks->chanop ? "@" : (nicks->voice? "v" : "�")));
4225
}
4226
}
4227
}
4228
count++;
4229
}
4230
else if (msg == 3)
4231
{
4232
count++;
4233
if (!isme(nicks->nick))
4234
{
4235
my_send_to_server(server, "KILL %s :%s (%i", nicks->nick,
4236
args && *args ? args : get_reason(nicks->nick, NULL),
4237
count);
4238
}
4239
else
4240
count--;
4241
}
4242
}
4243
clear_sorted_nicklist(&sortl);
4244
if (!msg && do_hook(USERS_FOOTER_LIST, "%s", "End of Users"))
4245
;
4246
else if (msg == 6 && do_hook(STAT_FOOTER_LIST, "%s", "End of stats"))
4247
;
4248
else if (!count)
4249
{
4250
if (chan)
4251
{
4252
if (!command)
4253
say("No match of %s on %s", spec, chan->channel);
4254
else
4255
say("There are no [\002%s\002] on %s", command, chan->channel);
4256
}
4257
}
4258
else if (!msg && !hook)
4259
bitchsay("End of UserList on %s %d counted", chan->channel, count);
4260
4261
if (count && *msgbuf)
4262
{
4263
switch(msg)
4264
{
4265
case 1:
4266
case 2:
4267
{
4268
put_it("%s", convert_output_format(fget_string_var((msg == 1)?FORMAT_SEND_MSG_FSET:FORMAT_SEND_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME),msgbuf, get_server_nickname(from_server), args));
4269
my_send_to_server(server, "%s %s :%s", (msg == 1) ? "PRIVMSG" : "NOTICE", msgbuf, args);
4270
break;
4271
}
4272
case 5:
4273
{
4274
if (chan)
4275
my_send_to_server(server, "KICK %s %s :%s", chan->channel,
4276
msgbuf, (args && *args) ? args : "-=punt=-");
4277
}
4278
default:
4279
break;
4280
}
4281
}
4282
message_from(NULL, LOG_CRAP);
4283
4284
}
4285
4286
int caps_fucknut (register unsigned char *crap)
4287
{
4288
int total = 0, allcaps = 0;
4289
/* removed from ComStud client */
4290
while (*crap)
4291
{
4292
if (isalpha(*crap))
4293
{
4294
total++;
4295
if (isupper(*crap))
4296
allcaps++;
4297
}
4298
crap++;
4299
}
4300
if (total > 12)
4301
{
4302
if ( ((unsigned int)(((float) allcaps / (float) total) * 100) >= 75))
4303
return (1);
4304
}
4305
return (0);
4306
}
4307
4308
int char_fucknut (register unsigned char *crap, char looking, int max)
4309
{
4310
int total = strlen(crap), allchar = 0;
4311
4312
while (*crap)
4313
{
4314
if ((*crap == looking))
4315
{
4316
crap++;
4317
while(*crap && *crap != looking)
4318
{
4319
allchar++;
4320
crap++;
4321
}
4322
}
4323
if (*crap)
4324
crap++;
4325
}
4326
if (total > 12)
4327
{
4328
if ( ((unsigned int)(((float) allchar / (float) total) * 100)) >= 75)
4329
return (1);
4330
}
4331
return (0);
4332
}
4333
4334
static int cparse_recurse = -1;
4335
#define MAX_RECURSE 5
4336
#define RECURSE_CPARSE
4337
4338
char *convert_output_format_raw(const char *format, const char *str, va_list args)
4339
{
4340
static unsigned char buffer[MAX_RECURSE*BIG_BUFFER_SIZE+1];
4341
char buffer2[3*BIG_BUFFER_SIZE+1];
4342
enum color_attributes this_color = BLACK;
4343
register unsigned char *s;
4344
char *copy = NULL;
4345
char *tmpc = NULL;
4346
register char *p;
4347
int old_who_level = who_level;
4348
int bold = 0;
4349
extern int in_chelp;
4350
/*va_list args;*/
4351
int arg_flags;
4352
char color_mod[] = "kbgcrmywKBGCRMYWn";
4353
4354
if (!format)
4355
return empty_string;
4356
copy = alloca(strlen(format)+2);
4357
strcpy(copy, format);
4358
4359
memset(buffer2, 0, BIG_BUFFER_SIZE);
4360
4361
if (cparse_recurse < MAX_RECURSE)
4362
cparse_recurse++;
4363
4364
if (str)
4365
{
4366
4367
p = (char *)str;
4368
/* va_start(args, str);*/
4369
while(p && *p)
4370
{
4371
if (*p == '%')
4372
{
4373
switch(*++p)
4374
{
4375
case 's':
4376
{
4377
char *q, *s = (char *)va_arg(args, char *);
4378
#ifdef RECURSE_CPARSE
4379
char buff[BIG_BUFFER_SIZE];
4380
q = buff;
4381
while (s && *s)
4382
{
4383
if (*s == '%')
4384
*q++ = '%';
4385
else if (*s == '$')
4386
*q++ = '$';
4387
*q++ = *s++;
4388
}
4389
*q = 0;
4390
if (*buff)
4391
strcat(buffer2, buff);
4392
#else
4393
if (s)
4394
strcat(buffer2, s);
4395
#endif
4396
break;
4397
}
4398
case 'd':
4399
{
4400
int d = (int) va_arg(args, int);
4401
strcat(buffer2, ltoa((long)d));
4402
break;
4403
}
4404
case 'c':
4405
{
4406
char c = (char )va_arg(args, int);
4407
buffer2[strlen(buffer2)] = c;
4408
break;
4409
}
4410
case 'u':
4411
{
4412
unsigned int d = (unsigned int) va_arg(args, unsigned int);
4413
strcat(buffer2, ltoa(d));
4414
break;
4415
}
4416
case 'l':
4417
{
4418
unsigned long d = (unsigned long) va_arg(args, unsigned long);
4419
strcat(buffer2, ltoa(d));
4420
break;
4421
}
4422
case '%':
4423
{
4424
buffer2[strlen(buffer2)] = '%';
4425
p++;
4426
break;
4427
}
4428
default:
4429
strcat(buffer2, "%");
4430
buffer2[strlen(buffer2)] = *p;
4431
}
4432
p++;
4433
} else
4434
{
4435
buffer2[strlen(buffer2)] = *p;
4436
p++;
4437
}
4438
}
4439
/* va_end(args);*/
4440
}
4441
else if (str)
4442
strcpy(buffer2, str);
4443
4444
s = buffer + (BIG_BUFFER_SIZE * cparse_recurse);
4445
memset(s, 0, BIG_BUFFER_SIZE);
4446
tmpc = copy;
4447
if (!tmpc)
4448
goto done;
4449
while (*tmpc)
4450
{
4451
if (*tmpc == '%')
4452
{
4453
char *cs;
4454
tmpc++;
4455
this_color = BLACK;
4456
if (*tmpc == '%')
4457
{
4458
*s++ = *tmpc++;
4459
continue;
4460
}
4461
else if (isdigit(*tmpc))
4462
{
4463
char background_mod[] = "01234567";
4464
if ((cs = strchr(background_mod, *tmpc)))
4465
{
4466
this_color = ((int)cs - (int)&background_mod) + (bold ? BACK_BBLACK : BACK_BLACK);
4467
bold = 0;
4468
}
4469
else if (*tmpc == '8')
4470
{
4471
this_color = REVERSE_COLOR;
4472
bold = 0;
4473
}
4474
else
4475
{
4476
this_color = BOLD_COLOR;
4477
bold ^= 1;
4478
}
4479
}
4480
else if ((cs = strchr(color_mod, *tmpc)))
4481
this_color = ((int)cs - (int)&color_mod);
4482
else if (*tmpc == 'F')
4483
this_color = BLINK_COLOR;
4484
else if (*tmpc == 'U')
4485
this_color = UNDERLINE_COLOR;
4486
else if (*tmpc == 'A')
4487
this_color = (int) (((float)UNDERLINE_COLOR * rand())/RAND_MAX);
4488
else if (*tmpc == 'P')
4489
this_color = MAGENTAB;
4490
else if (*tmpc == 'p')
4491
this_color = MAGENTA;
4492
else
4493
{
4494
*s++ = *tmpc;
4495
continue;
4496
}
4497
strcpy(s, color_str[this_color]);
4498
while(*s) s++;
4499
tmpc++;
4500
continue;
4501
}
4502
else if (*tmpc == '$' && !in_chelp)
4503
{
4504
char *new_str = NULL;
4505
tmpc++;
4506
if (*tmpc == '$')
4507
{
4508
*s++ = *tmpc++;
4509
continue;
4510
}
4511
in_cparse++;
4512
tmpc = alias_special_char(&new_str, tmpc, buffer2, NULL, &arg_flags);
4513
in_cparse--;
4514
if (new_str)
4515
#ifdef RECURSE_CPARSE
4516
strcat(s, convert_output_format_raw(new_str, NULL, NULL));
4517
#else
4518
strcat(s, new_str);
4519
#endif
4520
new_free(&new_str);
4521
while (*s) { if (*s == 255) *s = ' '; s++; }
4522
if (!tmpc) break;
4523
continue;
4524
} else
4525
*s = *tmpc;
4526
tmpc++; s++;
4527
}
4528
*s = 0;
4529
4530
done:
4531
s = buffer + (BIG_BUFFER_SIZE * cparse_recurse);
4532
/* if (*s) strcat(s, color_str[NO_COLOR]);*/
4533
4534
who_level = old_who_level;
4535
cparse_recurse--;
4536
4537
return s;
4538
}
4539
4540
char *convert_output_format(const char *format, const char *str, ...)
4541
{
4542
char *ret;
4543
va_list args;
4544
va_start(args, str);
4545
ret = convert_output_format_raw(format, str, args);
4546
va_end(args);
4547
if (*ret)
4548
strcat(ret, color_str[NO_COLOR]);
4549
return ret;
4550
}
4551
4552
4553
char *convert_output_format2(const char *str)
4554
{
4555
unsigned char buffer[3*BIG_BUFFER_SIZE+1];
4556
unsigned char buffer2[3*BIG_BUFFER_SIZE+1];
4557
register unsigned char *s;
4558
char *copy = NULL;
4559
char *tmpc = NULL;
4560
int arg_flags;
4561
4562
if (!str)
4563
return m_strdup(empty_string);
4564
4565
memset(buffer, 0, BIG_BUFFER_SIZE);
4566
strcpy(buffer2, str);
4567
copy = tmpc = buffer2;
4568
s = buffer;
4569
while (*tmpc)
4570
{
4571
if (*tmpc == '$')
4572
{
4573
char *new_str = NULL;
4574
tmpc++;
4575
in_cparse++;
4576
tmpc = alias_special_char(&new_str, tmpc, copy, NULL, &arg_flags);
4577
in_cparse--;
4578
if (new_str)
4579
#ifdef RECURSE_CPARSE
4580
strcat(s, convert_output_format(new_str, NULL, NULL));
4581
#else
4582
strcat(s, new_str);
4583
#endif
4584
s=s+(strlen(new_str));
4585
new_free(&new_str);
4586
if (!tmpc) break;
4587
continue;
4588
} else
4589
*s = *tmpc;
4590
tmpc++; s++;
4591
}
4592
*s = 0;
4593
return m_strdup(buffer);
4594
}
4595
4596
void add_last_type (LastMsg *array, int size, char *from, char *uh, char *to, char *str)
4597
{
4598
int i;
4599
for (i = size - 1; i > 0; i--)
4600
{
4601
4602
malloc_strcpy(&(array[i].last_msg), array[i - 1].last_msg);
4603
malloc_strcpy(&(array[i].from), array[i - 1].from);
4604
malloc_strcpy(&(array[i].uh), array[i - 1].uh);
4605
malloc_strcpy(&(array[i].to), array[i - 1].to);
4606
malloc_strcpy(&(array[i].time), array[i - 1].time);
4607
}
4608
malloc_strcpy(&array->last_msg, str);
4609
malloc_strcpy(&array->from, from);
4610
malloc_strcpy(&array->to, to);
4611
malloc_strcpy(&array->uh, uh);
4612
malloc_strcpy(&array->time, update_clock(GET_TIME));
4613
}
4614
4615
int check_last_type(LastMsg *array, int size, char *from, char *uh)
4616
{
4617
int i;
4618
for (i = 0; i < size-1; i++)
4619
{
4620
if (array[i].from && array[i].uh && !my_stricmp(from, array[i].from) && !my_stricmp(uh, array[i].uh))
4621
return 1;
4622
}
4623
return 0;
4624
}
4625
4626
int matchmcommand(char *origline,int count)
4627
{
4628
int startnum=0;
4629
int endnum=0;
4630
char *tmpstr;
4631
char tmpbuf[BIG_BUFFER_SIZE];
4632
4633
strncpy(tmpbuf,origline, BIG_BUFFER_SIZE-1);
4634
tmpstr=tmpbuf;
4635
if (*tmpstr=='*') return(1);
4636
while (tmpstr && *tmpstr)
4637
{
4638
startnum=0;
4639
endnum=0;
4640
if (tmpstr && *tmpstr && *tmpstr=='-')
4641
{
4642
while (tmpstr && *tmpstr && !isdigit(*tmpstr))
4643
tmpstr++;
4644
endnum=atoi(tmpstr);
4645
startnum=1;
4646
while (tmpstr && *tmpstr && isdigit(*tmpstr))
4647
tmpstr++;
4648
}
4649
else
4650
{
4651
while (tmpstr && *tmpstr && !isdigit(*tmpstr))
4652
tmpstr++;
4653
startnum=atoi(tmpstr);
4654
while (tmpstr && *tmpstr && isdigit(*tmpstr))
4655
tmpstr++;
4656
if (tmpstr && *tmpstr && *tmpstr=='-') {
4657
while (tmpstr && *tmpstr && !isdigit(*tmpstr))
4658
tmpstr++;
4659
endnum=atoi(tmpstr);
4660
if (!endnum)
4661
endnum=1000;
4662
while (tmpstr && *tmpstr && isdigit(*tmpstr))
4663
tmpstr++;
4664
}
4665
}
4666
if (count==startnum || (count>=startnum && count<=endnum))
4667
return(1);
4668
}
4669
if (count==startnum || (count>=startnum && count<=endnum))
4670
return(1);
4671
return(0);
4672
}
4673
4674
ChannelList *prepare_command(int *active_server, char *channel, int need_op)
4675
{
4676
int server = 0;
4677
ChannelList *chan = NULL;
4678
4679
if (!channel && !get_current_channel_by_refnum(0))
4680
{
4681
4682
if (need_op != 3)
4683
not_on_a_channel(current_window);
4684
return NULL;
4685
}
4686
server = current_window->server;
4687
*active_server = server;
4688
if (!(chan = lookup_channel(channel? channel : get_current_channel_by_refnum(0), server, 0)))
4689
{
4690
4691
if (need_op != 3)
4692
not_on_a_channel(current_window);
4693
return NULL;
4694
}
4695
if (need_op == NEED_OP && chan && !chan->chop)
4696
{
4697
4698
error_not_opped(chan->channel);
4699
return NULL;
4700
}
4701
return chan;
4702
}
4703
4704
char *make_channel (char *chan)
4705
{
4706
static char buffer[IRCD_BUFFER_SIZE+1];
4707
*buffer = 0;
4708
if (*chan != '#' && *chan != '&' && *chan != '+' && *chan != '!')
4709
snprintf(buffer, IRCD_BUFFER_SIZE-2, "#%s", chan);
4710
else
4711
strmcpy(buffer, chan, IRCD_BUFFER_SIZE-1);
4712
return buffer;
4713
}
4714
4715
BUILT_IN_COMMAND(do_map)
4716
{
4717
if (server_list[from_server].link_look == 0)
4718
{
4719
bitchsay("Generating irc server map");
4720
send_to_server("LINKS");
4721
server_list[from_server].link_look = 2;
4722
} else
4723
bitchsay("Wait until previous %s is done", server_list[from_server].link_look == 2? "MAP":"LLOOK");
4724
}
4725
4726
void add_to_irc_map(char *server1, char *distance)
4727
{
4728
irc_server *tmp, *insert, *prev;
4729
int dist = 0;
4730
if (distance)
4731
dist = atoi(distance);
4732
tmp = (irc_server *) new_malloc(sizeof(irc_server));
4733
malloc_strcpy(&tmp->name, server1);
4734
tmp->hopcount = dist;
4735
if (!map)
4736
{
4737
map = tmp;
4738
return;
4739
}
4740
for (insert = map, prev = map; insert && insert->hopcount < dist; )
4741
{
4742
prev = insert;
4743
insert = insert->next;
4744
}
4745
if (insert && insert->hopcount >= dist)
4746
{
4747
tmp->next = insert;
4748
if (insert == map)
4749
map = tmp;
4750
else
4751
prev->next = tmp;
4752
} else
4753
prev->next = tmp;
4754
}
4755
4756
void show_server_map (void)
4757
{
4758
int prevdist = 0;
4759
irc_server *tmp;
4760
char tmp1[80];
4761
char tmp2[BIG_BUFFER_SIZE+1];
4762
#ifdef ONLY_STD_CHARS
4763
char *ascii="-> ";
4764
#else
4765
char *ascii = "��> ";
4766
#endif
4767
if (map) prevdist = map->hopcount;
4768
4769
for (tmp = map; tmp; tmp = map)
4770
{
4771
map = tmp->next;
4772
if (!tmp->hopcount || tmp->hopcount != prevdist)
4773
strmcpy(tmp1, convert_output_format("%K[%G$0%K]", "%d", tmp->hopcount), 79);
4774
else
4775
*tmp1 = 0;
4776
snprintf(tmp2, BIG_BUFFER_SIZE, "$G %%W$[-%d]1%%c $0 %s", tmp->hopcount*3, tmp1);
4777
put_it("%s", convert_output_format(tmp2, "%s %s", tmp->name, prevdist!=tmp->hopcount?ascii:empty_string));
4778
prevdist = tmp->hopcount;
4779
new_free(&tmp->name);
4780
new_free((char **)&tmp);
4781
}
4782
}
4783
4784
extern int timed_server (void *);
4785
extern int in_timed_server;
4786
void check_server_connect(int server)
4787
{
4788
if (!get_int_var(AUTO_RECONNECT_VAR))
4789
return;
4790
if ((from_server == -1) || (!in_timed_server && server_list[from_server].last_msg + 50 < now))
4791
{
4792
add_timer(0, "", 10, 1, timed_server, m_strdup(zero), NULL, current_window);
4793
in_timed_server++;
4794
}
4795
}
4796
4797
char *country(char *hostname)
4798
{
4799
typedef struct _domain {
4800
char *code;
4801
char *country;
4802
} Domain;
4803
Domain domain[] = {
4804
{"AD", "Andorra" },
4805
{"AE", "United Arab Emirates" },
4806
{"AF", "Afghanistan" },
4807
{"AG", "Antigua and Barbuda" },
4808
{"AI", "Anguilla" },
4809
{"AL", "Albania" },
4810
{"AM", "Armenia" },
4811
{"AN", "Netherlands Antilles" },
4812
{"AO", "Angola" },
4813
{"AQ", "Antarctica (pHEAR)" },
4814
{"AR", "Argentina" },
4815
{"AS", "American Samoa" },
4816
{"AT", "Austria" },
4817
{"AU", "Australia" },
4818
{"AW", "Aruba" },
4819
{"AZ", "Azerbaijan" },
4820
{"BA", "Bosnia and Herzegovina" },
4821
{"BB", "Barbados" },
4822
{"BD", "Bangladesh" },
4823
{"BE", "Belgium" },
4824
{"BF", "Burkina Faso" },
4825
{"BG", "Bulgaria" },
4826
{"BH", "Bahrain" },
4827
{"BI", "Burundi" },
4828
{"BJ", "Benin" },
4829
{"BM", "Bermuda" },
4830
{"BN", "Brunei Darussalam" },
4831
{"BO", "Bolivia" },
4832
{"BR", "Brazil" },
4833
{"BS", "Bahamas" },
4834
{"BT", "Bhutan" },
4835
{"BV", "Bouvet Island" },
4836
{"BW", "Botswana" },
4837
{"BY", "Belarus" },
4838
{"BZ", "Belize" },
4839
{"CA", "Canada (pHEAR)" },
4840
{"CC", "Cocos Islands" },
4841
{"CF", "Central African Republic" },
4842
{"CG", "Congo" },
4843
{"CH", "Switzerland" },
4844
{"CI", "Cote D'ivoire" },
4845
{"CK", "Cook Islands" },
4846
{"CL", "Chile" },
4847
{"CM", "Cameroon" },
4848
{"CN", "China" },
4849
{"CO", "Colombia" },
4850
{"CR", "Costa Rica" },
4851
{"CS", "Former Czechoslovakia" },
4852
{"CU", "Cuba" },
4853
{"CV", "Cape Verde" },
4854
{"CX", "Christmas Island" },
4855
{"CY", "Cyprus" },
4856
{"CZ", "Czech Republic" },
4857
{"DE", "Germany" },
4858
{"DJ", "Djibouti" },
4859
{"DK", "Denmark" },
4860
{"DM", "Dominica" },
4861
{"DO", "Dominican Republic" },
4862
{"DZ", "Algeria" },
4863
{"EC", "Ecuador" },
4864
{"EE", "Estonia" },
4865
{"EG", "Egypt" },
4866
{"EH", "Western Sahara" },
4867
{"ER", "Eritrea" },
4868
{"ES", "Spain" },
4869
{"ET", "Ethiopia" },
4870
{"FI", "Finland" },
4871
{"FJ", "Fiji" },
4872
{"FK", "Falkland Islands" },
4873
{"FM", "Micronesia" },
4874
{"FO", "Faroe Islands" },
4875
{"FR", "France" },
4876
{"FX", "France, Metropolitan" },
4877
{"GA", "Gabon" },
4878
{"GB", "Great Britain" },
4879
{"GD", "Grenada" },
4880
{"GE", "Georgia" },
4881
{"GF", "French Guiana" },
4882
{"GH", "Ghana" },
4883
{"GI", "Gibraltar" },
4884
{"GL", "Greenland" },
4885
{"GM", "Gambia" },
4886
{"GN", "Guinea" },
4887
{"GP", "Guadeloupe" },
4888
{"GQ", "Equatorial Guinea" },
4889
{"GR", "Greece" },
4890
{"GS", "S. Georgia and S. Sandwich Isles." },
4891
{"GT", "Guatemala" },
4892
{"GU", "Guam" },
4893
{"GW", "Guinea-Bissau" },
4894
{"GY", "Guyana" },
4895
{"HK", "Hong Kong" },
4896
{"HM", "Heard and McDonald Islands" },
4897
{"HN", "Honduras" },
4898
{"HR", "Croatia" },
4899
{"HT", "Haiti" },
4900
{"HU", "Hungary" },
4901
{"ID", "Indonesia" },
4902
{"IE", "Ireland" },
4903
{"IL", "Israel" },
4904
{"IN", "India" },
4905
{"IO", "British Indian Ocean Territory" },
4906
{"IQ", "Iraq" },
4907
{"IR", "Iran" },
4908
{"IS", "Iceland" },
4909
{"IT", "Italy" },
4910
{"JM", "Jamaica" },
4911
{"JO", "Jordan" },
4912
{"JP", "Japan" },
4913
{"KE", "Kenya" },
4914
{"KG", "Kyrgyzstan" },
4915
{"KH", "Cambodia" },
4916
{"KI", "Kiribati" },
4917
{"KM", "Comoros" },
4918
{"KN", "St. Kitts and Nevis" },
4919
{"KP", "North Korea" },
4920
{"KR", "South Korea" },
4921
{"KW", "Kuwait" },
4922
{"KY", "Cayman Islands" },
4923
{"KZ", "Kazakhstan" },
4924
{"LA", "Laos" },
4925
{"LB", "Lebanon" },
4926
{"LC", "Saint Lucia" },
4927
{"LI", "Liechtenstein" },
4928
{"LK", "Sri Lanka" },
4929
{"LR", "Liberia" },
4930
{"LS", "Lesotho" },
4931
{"LT", "Lithuania" },
4932
{"LU", "Luxembourg" },
4933
{"LV", "Latvia" },
4934
{"LY", "Libya" },
4935
{"MA", "Morocco" },
4936
{"MC", "Monaco" },
4937
{"MD", "Moldova" },
4938
{"MG", "Madagascar" },
4939
{"MH", "Marshall Islands" },
4940
{"MK", "Macedonia" },
4941
{"ML", "Mali" },
4942
{"MM", "Myanmar" },
4943
{"MN", "Mongolia" },
4944
{"MO", "Macau" },
4945
{"MP", "Northern Mariana Islands" },
4946
{"MQ", "Martinique" },
4947
{"MR", "Mauritania" },
4948
{"MS", "Montserrat" },
4949
{"MT", "Malta" },
4950
{"MU", "Mauritius" },
4951
{"MV", "Maldives" },
4952
{"MW", "Malawi" },
4953
{"MX", "Mexico" },
4954
{"MY", "Malaysia" },
4955
{"MZ", "Mozambique" },
4956
{"NA", "Namibia" },
4957
{"NC", "New Caledonia" },
4958
{"NE", "Niger" },
4959
{"NF", "Norfolk Island" },
4960
{"NG", "Nigeria" },
4961
{"NI", "Nicaragua" },
4962
{"NL", "Netherlands" },
4963
{"NO", "Norway" },
4964
{"NP", "Nepal" },
4965
{"NR", "Nauru" },
4966
{"NT", "Neutral Zone (pHEAR)" },
4967
{"NU", "Niue" },
4968
{"NZ", "New Zealand" },
4969
{"OM", "Oman" },
4970
{"PA", "Panama" },
4971
{"PE", "Peru" },
4972
{"PF", "French Polynesia" },
4973
{"PG", "Papua New Guinea" },
4974
{"PH", "Philippines" },
4975
{"PK", "Pakistan" },
4976
{"PL", "Poland" },
4977
{"PM", "St. Pierre and Miquelon" },
4978
{"PN", "Pitcairn" },
4979
{"PR", "Puerto Rico" },
4980
{"PT", "Portugal" },
4981
{"PW", "Palau" },
4982
{"PY", "Paraguay" },
4983
{"QA", "Qatar" },
4984
{"RE", "Reunion" },
4985
{"RO", "Romania" },
4986
{"RU", "Russian Federation (pHEAR)" },
4987
{"RW", "Rwanda" },
4988
{"SA", "Saudi Arabia" },
4989
{"Sb", "Solomon Islands" },
4990
{"SC", "Seychelles" },
4991
{"SD", "Sudan" },
4992
{"SE", "Sweden" },
4993
{"SG", "Singapore" },
4994
{"SH", "St. Helena" },
4995
{"SI", "Slovenia" },
4996
{"SJ", "Svalbard and Jan Mayen Islands" },
4997
{"SK", "Slovak Republic" },
4998
{"SL", "Sierra Leone" },
4999
{"SM", "San Marino" },
5000
{"SN", "Senegal" },
5001
{"SO", "Somalia" },
5002
{"SR", "Suriname" },
5003
{"ST", "Sao Tome and Principe" },
5004
{"SU", "Former USSR (pHEAR)" },
5005
{"SV", "El Salvador" },
5006
{"SY", "Syria" },
5007
{"SZ", "Swaziland" },
5008
{"TC", "Turks and Caicos Islands" },
5009
{"TD", "Chad" },
5010
{"TF", "French Southern Territories" },
5011
{"TG", "Togo" },
5012
{"TH", "Thailand" },
5013
{"TJ", "Tajikistan" },
5014
{"TK", "Tokelau" },
5015
{"TM", "Turkmenistan" },
5016
{"TN", "Tunisia" },
5017
{"TO", "Tonga" },
5018
{"TP", "East Timor" },
5019
{"TR", "Turkey" },
5020
{"TT", "Trinidad and Tobago" },
5021
{"TV", "Tuvalu" },
5022
{"TW", "Taiwan" },
5023
{"TZ", "Tanzania" },
5024
{"UA", "Ukraine" },
5025
{"UG", "Uganda" },
5026
{"UK", "United Kingdom" },
5027
{"UM", "US Minor Outlying Islands" },
5028
{"US", "United States of America" },
5029
{"UY", "Uruguay" },
5030
{"UZ", "Uzbekistan" },
5031
{"VA", "Vatican City State" },
5032
{"VC", "St. Vincent and the grenadines" },
5033
{"VE", "Venezuela" },
5034
{"VG", "British Virgin Islands" },
5035
{"VI", "US Virgin Islands" },
5036
{"VN", "Vietnam" },
5037
{"VU", "Vanuatu" },
5038
{"WF", "Wallis and Futuna Islands" },
5039
{"WS", "Samoa" },
5040
{"YE", "Yemen" },
5041
{"YT", "Mayotte" },
5042
{"YU", "Yugoslavia" },
5043
{"ZA", "South Africa" },
5044
{"ZM", "Zambia" },
5045
{"ZR", "Zaire" },
5046
{"ZW", "Zimbabwe" },
5047
{"COM", "Internic Commercial" },
5048
{"EDU", "Educational Institution" },
5049
{"GOV", "Government" },
5050
{"INT", "International" },
5051
{"MIL", "Military" },
5052
{"NET", "Internic Network" },
5053
{"ORG", "Internic Non-Profit Organization" },
5054
{"RPA", "Old School ARPAnet" },
5055
{"ATO", "Nato Fiel" },
5056
{"MED", "United States Medical" },
5057
{"ARPA", "Reverse DNS" },
5058
{NULL, NULL}
5059
};
5060
char *p;
5061
int i = 0;
5062
if (!hostname || !*hostname || isdigit(hostname[strlen(hostname)-1]))
5063
return "unknown";
5064
if ((p = strrchr(hostname, '.')))
5065
p++;
5066
else
5067
p = hostname;
5068
for (i = 0; domain[i].code; i++)
5069
if (!my_stricmp(p, domain[i].code))
5070
return domain[i].country;
5071
return "unknown";
5072
}
5073
5074
5075