1 /**
2 * Darkbot - Internet Relay Chat Help Robot, darkbot.c
3 *
4 * Copyright (C) 2000 Jason Hamilton <jason@darkbot.net>
5 * http://darkbot.net
6 *
7 *
8 * This program is provided free for non-commercial use only. Any
9 * commercial use of this source code or binaries compiled thereof
10 * requires the prior written consent of the author. Contact
11 * jason@darkbot.net with any questions regarding commercial use.
12 * Distriubution of modified source code or binaries compiled from
13 * modified source code is expressly forbidden.
14
15 Darkbot Revision: 6f6-r6
16
17 */
18
19 /*********************************************************
20 * ATTENTION: If you are looking for the DEFINES that are
21 * usually located here, please be aware as of 6.x versions
22 * of darkbot, they are all located in "defines.h". You
23 * should not need to edit darkbot.c anymore.
24 *********************************************************/
25
26 #define ON 1
27 #define OFF 0
28 #define R return
29
30 #define STRING_SHORT 512
31 #define STRING_LONG 2048
32
33 #define LEGAL_TEXT "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
34 #define SAFE_LIST "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
35 #define NUMBER_LIST "1234567890"
36
37 #ifndef LANG /* If not defined, default to english */
38 #define LANG 1
39 #endif
40
41 #include "defines.h"
42
43 /* ------------ Below are function declarations --------------- */
44 #if STATUS == 1
45 void parse_252 (char *s), parse_251 (char *s), parse_255 (char *s);
46 #endif
47
48 #ifndef WIN32
49 inline size_t min (const size_t a, const size_t b);
50 #endif
51 char *db_strndup (const char *dupMe, size_t maxBytes);
52 char **tokenize (char *theString, size_t * numTokens);
53
54 void show_seen (char *nick, char *source, char *target),
55 count_seen (char *source, char *target),
56 show_info2 (const char *target, const char *source);
57 long save_seen (char *nick, char *uh, char *chan);
58 void do_randomtopic (char *target, char *file, char *nick,
59 char *topic);
60 #ifdef RANDOM_STUFF
61 void do_random_stuff (), get_rand_stuff_time (),
62 del_autotopic (const char *chan), add_randomstuff (char *source,
63 char *target,
64 char *data),
65 do_autotopics ();
66 #endif
67 void datasearch (const char *nick, char *topic, char *target),
68 display_url (char *, char *, char *), set_pass (char *nick, char *uh,
69 char *pass,
70 char *newpass),
71 do_modes (char *source, char *data), process_nick (char *nick,
72 char *newnick);
73 long verify_pass (char *nick, char *chan, char *uh, char *pass),
74 ifexist_autotopic (char *chan);
75 #if DO_CHANBOT_CRAP == 1
76 void save_permbans ();
77 #endif
78 void do_quit (const char *nick, long);
79 #ifdef DO_MATH_STUFF
80 void do_math (const char *who, char *target, char *math);
81 #endif
82 void parse_who (char *data);
83 void set_autotopic (char *source, char *target, char *topic);
84 void delete_user_ram (char *source, char *uh), get_s (),
85 delete_url (const char *nick, char *topic, char *target),
86 update_setinfo (const char *new_uh, const char *new_greetz,
87 const char *nick);
88 #if DO_CHANBOT_CRAP == 1
89 void add_permban (const char *uh, size_t counter, const char *reason);
90 int del_permban (const char *nick, const char *uh);
91 #endif
92 int check_existing_url (const char *source, char *topic,
93 char *target);
94 void show_helper_list (const char *nick, long level),
95 show_banlist (const char *nick), chanserv (char *source, char *target,
96 char *buf),
97 raw_now (char *type), find_url (const char *nick, char *topic,
98 char *target), save_changes (),
99 show_url (char *nick, char *topic, char *target, long, long, char *uh,
100 long);
101 char *strlwr (char *buf), *rand_reply (const char *nick), *date (),
102 *get_multiword_topic (char *first), *revert_topic (char *input),
103 *get_rand_nick (const char *chan), *get_word (long number,
104 char *text);
105
106 void info (const char *source, char *target), load_helpers (),
107 scan_chan_users (char *chan, char *nick, char *banned),
108 do_login (char *nick, char *pass);
109 int stricmp (const char *s1, const char *s2);
110 long do_lastcomm (char *nick, char *target, char *rest),
111 setinfo_lastcomm (char *rest);
112 void parse (char *), add_helper (const char *chan, const char *uh,
113 long level, size_t num_join,
114 const char *greetz,
115 const char *pass);
116 int get_connection (const char *hostname, const char *vhostname,
117 int port), readln (), writeln (const char *);
118 bool check_permban (const char *uh, const char *chan,
119 const char *nick);
120 long cf (char *host, char *nick, char *chan), f_f (char *host),
121 get_passwd (char *data);
122 time_t return_useridle (const char *chan, const char *who,
123 int toggle);
124 void a_f (char *host), reset_ (), delete_user (const char *nick,
125 char *chan),
126 add_user (char *chan, char *nick, char *uh, long);
127 void set_fds (), sig_hup (int), sig_segv (int), save_setup ();
128 void stripline (char *), init_bot (), sig_alrm (int);
129 void parse_server_msg (fd_set * read_fds);
130 void trailing_blanks (char *),
131 log (const char *, const char *, ...),
132 gs26 (), add_s25 (char *server, long port),
133 add_banned_server (char *server, char *reason), S (const char *format,
134 ...),
135 del_sendq (long), clear_sendq (long, long);
136 char L[524], *random_word (char **);
137 int socketfd, alarmed, check_access (char *uh, char *chan, int toggle,
138 char *nick),
139 match_wild (const char *pattern, const char *str), Send (),
140 get_sendq_count (long);
141 void check_dbtimers ();
142
143 /* ------------ Below are global vars -------------- */
144 long QUESTIONS = 0, ADDITIONS = 0, DELETIONS = 0, uptime, NO_FLOOD,
145 NUM_SERV = 0, L_CLIENTS = 0, IRCOPS = 0, xtried = 0, G_USERS =
146 0, rt = 120, fc, spr = 0, snr = 0, BP = 6667, CHECKED =
147 1, SEND_DELAY = 1, send_tog = 0, NUM_HELPER = 0, NUMLINESSEEN = 0;
148 #ifdef RANDOM_STUFF
149 long Rand_Stuff = 0, Rand_Idle = 0;
150 #endif
151 long AIL4 = 0, Sleep_Toggle = 0, AIL3 = 0, AIL2 = 0, AIL5 = 0,
152 JOINs = 0, PERMBAN_counter = 0, ram_load_time = 0, AIL9 =
153 0, AIL666 = 0, AIL8 = 0, LastInput = 0, AIL10 = 0, MARK_CHANGE =
154 0, html_counter = 0;
155 char NICK_COMMA[32], COLON_NICK[33], pass_data[512],
156 pass_pass[STRING_SHORT], rword[STRING_SHORT];
157 char lc1[STRING_SHORT] = "0", lc2[STRING_SHORT] = "0",
158 lc4[STRING_SHORT] = "0", lc3[STRING_SHORT] = "0";
159 long lcn1 = 0, lcn2 = 0, lcn4 = 0, lcn3 = 0, SeeN = 0, DebuG = 0;
160 char slc1[STRING_SHORT] = "0", slc2[STRING_SHORT] = "0",
161 slc4[STRING_SHORT] = "0", slc3[STRING_SHORT] = "0";
162 long slcn1 = 0, slcn2 = 0, slcn4 = 0, slcn3 = 0;
163 #ifdef WIN32
164 char *rp391 = "niW-6r.6f6tobkraD";
165 #else
166 char *rp391 = "6r.6f6tobkraD";
167 #endif
168 char BCOLON_NICK[STRING_SHORT], DARKBOT_BIN[STRING_SHORT] = "",
169 r_reply[STRING_SHORT] = "", data[STRING_SHORT] = "",
170 g_chan[STRING_SHORT], dbVersion[STRING_SHORT],
171 strbuff[STRING_SHORT], f_tmp[STRING_LONG], UID[STRING_SHORT] =
172 "database", BS[STRING_SHORT] = "204.127.145.17", CMDCHAR[2] =
173 "!", CHAN[STRING_SHORT] = "#irc_help", s_Mynick[STRING_SHORT] =
174 "bot", g_host[STRING_SHORT], Mynick[STRING_SHORT] =
175 "bot", sleep_chan[STRING_SHORT], VHOST[STRING_SHORT] =
176 "0", REALNAME[STRING_SHORT] = "http://darkbot.net",
177 privmsg_log[STRING_SHORT];
178 #define PBOT "ArchFiend"
179
180 /* ------------ Below are structs ------------------ */
181
182 struct rusage r_usage;
183
184 struct sendq
185 {
186 char data[STRING_SHORT];
187 struct sendq *next;
188 }
189 *sendqhead = NULL, *sendqtail = NULL;
190
191 struct userlist
192 { /* internal userlist */
193 char chan[STRING_SHORT];
194 char nick[STRING_SHORT];
195 char uh[STRING_SHORT];
196 long level; /* auth */
197 short global; /* Global user? */
198 long idle;
199 struct userlist *next;
200 }
201 *userhead = NULL;
202
203 struct helperlist
204 {
205 char chan[STRING_SHORT];
206 char uh[STRING_SHORT];
207 char nick[STRING_SHORT];
208 long level;
209 size_t num_join;
210 char greetz[STRING_SHORT];
211 char pass[STRING_SHORT];
212 struct helperlist *next;
213 }
214 *helperhead = NULL;
215
216 /**
217 * 6/23/00 Dan
218 * - Changed permbanlist to have dynamically allocated
219 * userhost and reason fields.
220 * - Changed type of counter to size_t, this should be an
221 * unsigned type.
222 */
223 struct permbanlist
224 {
225 char *uh;
226 char *reason;
227 size_t counter;
228
229 struct permbanlist *next;
230 }
231 *permbanhead = NULL;
232
233 struct old
234 {
235 char host[200];
236 long time;
237 int count;
238 int value;
239 int kick;
240 }
241 ood[STRING_SHORT];
242
243 struct sl124
244 {
245 char name[STRING_SHORT];
246 long port;
247 struct sl124 *next;
248 }
249 *sh124 = NULL;
250
251 /* ------------ Begin function source -------------- */
252
253 #ifndef WIN32
254 const char *
run_program(const char * input)255 run_program (const char *input)
256 {
257 FILE *read_fp;
258 long chars_read;
259
260 read_fp = popen (input, "r");
261 if (read_fp != NULL) {
262 chars_read = fread (f_tmp, sizeof (char), STRING_LONG, read_fp);
263 pclose (read_fp);
264 if (chars_read > 0) {
265 R f_tmp;
266 }
267 R "No match";
268 }
269 return NULL;
270 }
271 #endif
272
273 void
check_dbtimers()274 check_dbtimers ()
275 {
276 DIR *dp;
277 long i = 0;
278 char filename[STRING_SHORT];
279 struct dirent *entry;
280 struct stat statbuf;
281 FILE *fp;
282 char b[STRING_LONG], output[STRING_LONG];
283
284 if ((dp = opendir (DBTIMERS_PATH)) == NULL) {
285 R;
286 }
287 while ((entry = readdir (dp)) != NULL) {
288 stat (entry->d_name, &statbuf);
289 if (S_ISDIR (statbuf.st_mode) && *entry->d_name == '.') {
290 continue; /* it's a dir, ignore it */
291 }
292 i = time (NULL);
293 if (i >= atoi (entry->d_name)) {
294 #ifdef WIN32
295 sprintf (filename, "%s/%s",
296 DBTIMERS_PATH, entry->d_name);
297 #else
298 snprintf (filename, sizeof(filename), "%s/%s",
299 DBTIMERS_PATH, entry->d_name);
300 #endif
301 if ((fp = fopen (filename, "r")) == NULL) {
302 R;
303 }
304 while (fgets (b, STRING_LONG, fp)) {
305 stripline (b);
306 #ifdef WIN32
307 sprintf (output, "%s\n", b);
308 #else
309 snprintf (output, sizeof(output), "%s\n", b);
310 #endif
311 S (output);
312 }
313 fclose (fp);
314 unlink (filename);
315 }
316 }
317 closedir (dp);
318 }
319
320 char *
get_word(long number,char * string)321 get_word (long number, char *string)
322 { /* gets a specific word requested */
323 long i = 0;
324 char *ptr;
325
326 number = number - 49;
327
328 ptr = strtok (string, "+");
329
330 strncpy (f_tmp, ptr, sizeof(f_tmp));
331 if (ptr != NULL) {
332 while (ptr != NULL) {
333 i++; /* word number */
334 ptr = strtok (NULL, "+");
335 if (ptr != NULL) {
336 if (i == number) {
337 #ifdef WIN32
338 sprintf (f_tmp,"%s", ptr);
339 #else
340 snprintf (f_tmp, sizeof(f_tmp), "%s", ptr);
341 #endif
342
343 R f_tmp;
344 }
345 }
346 }
347 R f_tmp;
348 }
349 else { /* only one word */
350 if (number == 1) {
351 R f_tmp;
352 }
353 else
354 R ""; /* no match */
355 }
356 }
357
358 char **
tokenize(char * theString,size_t * numTokens)359 tokenize (char *theString, size_t * numTokens)
360 {
361 static char *tokens[STRING_SHORT];
362
363 assert (numTokens != NULL && theString != NULL);
364 memset (tokens, 0, STRING_SHORT * sizeof (char *));
365
366 tokens[(*numTokens = 0)] = strtok (theString, " ");
367 if (NULL == tokens[0]) {
368 /* 0 tokens */
369 return tokens;
370 }
371
372 while ((tokens[++(*numTokens)] = strtok (NULL, " ")) != NULL) {
373 /* NO-OP */ ;
374 }
375 tokens[*numTokens] = 0;
376
377 return tokens;
378 }
379
380 int
check_access(char * uh,char * chan,int toggle,char * nick)381 check_access (char *uh, char *chan, int toggle, char *nick)
382 {
383 long i = 0, length = 0, A = 0, X = 0, Y = 0;
384 struct helperlist *c;
385 struct userlist *c2;
386 char temp[STRING_LONG] = "";
387 c = helperhead;
388 c2 = userhead;
389 strlwr (uh);
390 if (toggle == 0) { /* get access level */
391 while (c2) {
392 if (stricmp (c2->uh, uh) == 0) {
393 if (stricmp (c2->chan, chan) == 0) {
394 if (stricmp (c2->nick, nick) == 0) {
395 R c2->level;
396 }
397 }
398 }
399 c2 = c2->next;
400 }
401 return 0; /* no matches? */
402 }
403 else
404 while (c != NULL) {
405 if (!match_wild (c->uh, uh) == 0) {
406 if (*c->pass == '0') {
407 L001 (nick, Mynick);
408 R 0;
409 }
410 if (c->chan[1] != '*')
411 if (stricmp (c->chan, chan) != 0)
412 R 0;
413 c->num_join++;
414 if (*c->greetz == '+')
415 A = 1;
416 strncpy (data, "", sizeof(data));
417 length = Y = strlen (c->greetz);
418 if (length > 1) {
419 while (length > 0) {
420 length--;
421 X++;
422 if (c->greetz[length] == '^') {
423 i++;
424 #ifdef WIN32
425 sprintf (temp,"%s%s", nick, data);
426 #else
427 snprintf (temp, sizeof(temp), "%s%s", nick, data);
428 #endif
429 }
430 else if (c->greetz[length] == '%') {
431 i++;
432 #ifdef WIN32
433 sprintf (temp, "%ul%s", c->num_join, data);
434 #else
435 snprintf (temp, sizeof(temp), "%ul%s", c->num_join, data);
436 #endif
437 }
438 else if (c->greetz[length] == '$') {
439 i++;
440 #ifdef WIN32
441 sprintf (temp, "%s%s", uh, data);
442 #else
443 snprintf (temp, sizeof(temp), "%s%s", uh, data);
444 #endif
445 }
446 else if (c->greetz[length] == '&') {
447 i++;
448 #ifdef WIN32
449 sprintf (temp, "%s%s", chan, data);
450 #else
451 snprintf (temp, sizeof(temp), "%s%s", chan, data);
452 #endif
453 }
454 else
455 #ifdef WIN32
456 sprintf (temp, "%c%s",c->greetz[length], data);
457 #else
458 snprintf (temp, sizeof(temp), "%c%s",c->greetz[length], data);
459 #endif
460 if (X == Y && A == 1)
461 continue;
462 strncpy (data, temp, sizeof(data));
463 } /* While */
464 #if JOIN_GREET == 1
465 if (i == 0) {
466 if (setinfo_lastcomm (uh) == 0) {
467 S ("PRIVMSG %s :%ld\2!\2\37(\37%s\37)\37\2:\2 %s\n",
468 chan, c->num_join, nick, c->greetz);
469 }
470 }
471 else if (A == 1) {
472 if (setinfo_lastcomm (uh) == 0) {
473 S ("PRIVMSG %s :\1ACTION %s\1\n", chan, data);
474 }
475 }
476 else {
477 if (setinfo_lastcomm (uh) == 0) {
478 S ("PRIVMSG %s :%s\n", chan, data);
479 }
480 }
481 #endif
482 R c->level;
483 }
484 }
485 c = c->next;
486 }
487 R 0;
488 }
489
490 void
parse_who(char * data)491 parse_who (char *data)
492 {
493 char *chan, *nick, *ptr, b[STRING_SHORT];
494 nick = strtok (data, " "); /* botnick */
495 strncpy (Mynick, nick, sizeof(Mynick));
496 chan = strtok (NULL, " ");
497 ptr = strtok (NULL, " ");
498 #ifdef WIN32
499 sprintf (b, "%s@%s", ptr, strtok (NULL, " "));
500 #else
501 snprintf (b, sizeof(b), "%s@%s", ptr, strtok (NULL, " "));
502 #endif
503 nick = strtok (NULL, " "); /* server */
504 nick = strtok (NULL, " ");
505 add_user (chan, nick, b, 1);
506 }
507
508 void
delete_user(const char * nick,char * chan)509 delete_user (const char *nick, char *chan)
510 {
511 struct userlist *pNode, *pPrev;
512
513 pNode = userhead;
514 pPrev = NULL;
515
516 while (pNode) {
517 if (stricmp (pNode->nick, nick) == 0
518 && stricmp (pNode->chan, chan) == 0) {
519 save_seen (pNode->nick, pNode->uh, pNode->chan);
520 if (pPrev != NULL) {
521 pPrev->next = pNode->next;
522 }
523 else {
524 userhead = pNode->next;
525 }
526 free (pNode);
527 pNode = NULL;
528 break;
529 }
530 pPrev = pNode;
531 pNode = pNode->next;
532 }
533 }
534
535 void
do_modes(char * source,char * data)536 do_modes (char *source, char *data)
537 {
538 char *chan, *mode, *nick, *ptr;
539 long PM = 0, j = 0, i = 0;
540
541 chan = strtok (data, " ");
542 mode = strtok (NULL, " ");
543
544 if ((ptr = strchr (source, '!')) != NULL)
545 *ptr++ = '\0';
546 j = strlen (mode);
547 i = -1; /* i needs to start at 0 */
548 while (j > 0) {
549 j--;
550 i++;
551 if (mode[i] == '+')
552 PM = 1;
553 if (mode[i] == '-')
554 PM = 0;
555 if (mode[i] == 'o') {
556 nick = strtok (NULL, " ");
557 continue;
558 }
559 if (mode[i] == 'v') { /* voice sucks, ignore it */
560 nick = strtok (NULL, " ");
561 continue;
562 }
563 if (mode[i] == 'k' || mode[i] == 'b') {
564 nick = strtok (NULL, " ");
565 if (nick[0] == '*' && nick[1] == '!') {
566 nick += 2;
567 }
568 strlwr (nick);
569 if (PM == 1)
570 scan_chan_users (chan, source, nick);
571 continue;
572 }
573 if (mode[i] == 'l' && PM == 1) { /* don't parse if -limit
574 * since no parms */
575 nick = strtok (NULL, " ");
576 continue;
577 }
578 }
579
580 }
581
582 /**
583 * do_quit
584 *
585 * Purpose:
586 * 1) delete all instances when a nick matches (nick)
587 * 2) delete all users off a given channel
588 * 2) delete everything (i.e., when the bot is disconnected from irc)
589 *
590 * toggle 1 = delete user.
591 * toggle 2 = delete chan
592 * toggle 3 = everything (when I'm killed).
593 */
594 void
do_quit(const char * nick,long toggle)595 do_quit (const char *nick, long toggle)
596 {
597
598 struct userlist *pNode = userhead;
599 struct userlist *pPrev = NULL;
600
601 if (toggle == 1) {
602 /* delete user */
603 while (pNode) {
604 if (stricmp (pNode->nick, nick) == 0) {
605 /* found a match, remove it */
606 save_seen (pNode->nick, pNode->uh, pNode->chan);
607 if (pPrev != NULL) {
608 pPrev->next = pNode->next;
609 free (pNode);
610 pNode = pPrev->next;
611 }
612 else {
613 /* first node in the list */
614 userhead = pNode->next;
615 free (pNode);
616 pNode = userhead;
617 }
618 }
619 else {
620 /* No match, continue to next node */
621 pPrev = pNode;
622 pNode = pNode->next;
623 }
624 }
625 }
626 else if (toggle == 2) {
627 /* delete channel */
628 while (pNode) {
629 if (stricmp (pNode->chan, nick) == 0) {
630 /* found a match, remove it */
631 save_seen (pNode->nick, pNode->uh, pNode->chan);
632 if (pPrev != NULL) {
633 pPrev->next = pNode->next;
634 free (pNode);
635 pNode = pPrev->next;
636 }
637 else {
638 /* first node in the list */
639 userhead = pNode->next;
640 free (pNode);
641 pNode = userhead;
642 }
643 }
644 else {
645 /* No match, continue to next node */
646 pPrev = pNode;
647 pNode = pNode->next;
648 }
649 }
650 }
651 else if (toggle == 3) {
652 struct userlist *tempPtr = userhead;
653 while (pNode) {
654 tempPtr = pNode->next;
655 free (pNode);
656 pNode = tempPtr;
657 }
658 }
659 }
660
661 void
do_login(char * nick,char * pass)662 do_login (char *nick, char *pass)
663 {
664 long i = 0, x = 0, D = 0;
665 char Data[STRING_SHORT] = "", b[STRING_SHORT];
666 struct userlist *c;
667 c = userhead;
668 while (c) {
669 if (stricmp (nick, c->nick) == 0) {
670 x = verify_pass (c->nick, c->chan, c->uh, pass);
671 if (x > 0) {
672 i++;
673 if (c->level == 0 && x >= 2) {
674 /* only if not already authed */
675 S ("MODE %s +ov %s %s\n", c->chan, c->nick, c->nick);
676 D = 1;
677 }
678 c->level = x;
679 #ifdef WIN32
680 sprintf (b, "%s[%d] %s",c->chan, (int) c->level, Data);
681 #else
682 snprintf (b, sizeof(b), "%s[%d] %s",c->chan, (int) c->level, Data);
683 #endif
684 strncpy (Data, b, sizeof(Data));
685 }
686 }
687 c = c->next;
688 }
689 if (i != 0) {
690 if (!D) {
691 S ("NOTICE %s :Already authed on %s\n", nick, Data);
692 }
693 else
694 S ("NOTICE %s :Verified: %s\n", nick, Data);
695 }
696 }
697
698 void
process_nick(char * nick,char * newnick)699 process_nick (char *nick, char *newnick)
700 {
701 struct userlist *c;
702 c = userhead;
703 newnick++;
704 while (c) {
705 if (stricmp (nick, c->nick) == 0) {
706 strncpy (c->nick, newnick, sizeof(c->nick));
707 }
708 c = c->next;
709 }
710 }
711
712 void
scan_chan_users(char * chan,char * nick,char * banned)713 scan_chan_users (char *chan, char *nick, char *banned)
714 {
715 struct userlist *c;
716 c = userhead;
717 if (banned[0] == '*' && banned[1] == '!' && banned[2] == '*'
718 && banned[3] == '\0') {
719 S ("MODE %s -ob %s %s\n", chan, nick, banned);
720 R;
721 }
722 #if KICK_ON_BAN == 1
723 while (c) {
724 if (!match_wild (banned, c->uh) == 0) {
725 if (stricmp (c->nick, Mynick) != 0) {
726 S ("KICK %s %s :BANNED\n", chan, c->nick);
727 }
728 else {
729 S ("MODE %s -ob %s %s\n", chan, nick, banned);
730 R;
731 }
732 }
733 c = c->next;
734 }
735 #endif
736 }
737
738 /**
739 * 6/23/00 Dan:
740 * - All method arguments are now pointer to const
741 * - Return type is now time_t
742 * - A for loop is now used instead of a while loop
743 */
return_useridle(const char * chan,const char * who,int toggle)744 time_t return_useridle (const char *chan, const char *who, int toggle)
745 { /* toggle=0 is for idle time, toggle=1 is to check if user
746 is in the chan */
747 const struct userlist *c = userhead;
748
749 for (; c != NULL; c = c->next) {
750 if (!stricmp (who, c->nick) && !stricmp (chan, c->chan)) {
751 if (toggle == 1) {
752 /* If we only care if user is present or not.. */
753 return 1;
754 }
755 else
756 return c->idle;
757 } /* if */
758 } /* for */
759 return 0;
760 }
761
762 /**
763 * 6/23/00 Dan:
764 * - All method arguments are now pointer to const
765 * - A for loop is now used instead of a while loop
766 */
767 void
show_chaninfo(const char * nick,const char * chan)768 show_chaninfo (const char *nick, const char *chan)
769 {
770 size_t totalUsers = 0, foundUsers = 0;
771 const struct userlist *c = userhead;
772
773 for (; c != NULL; c = c->next) {
774 ++totalUsers;
775 if (!stricmp (chan, c->chan))
776 ++foundUsers;
777 }
778 S ("PRIVMSG %s :%s, I see %d users in %s (%d users total in ram)\n",
779 chan, nick, foundUsers, chan, totalUsers);
780 }
781
782 /**
783 * 6/22/00 Dan
784 * - Removed srand(), should only be done once, in main()
785 * - Changed while to for loop
786 */
787 char *
get_rand_nick(const char * chan)788 get_rand_nick (const char *chan)
789 {
790 size_t x = 0;
791 size_t i = 0;
792 const struct userlist *c = userhead;
793
794 /* Iterate through the userlist */
795 for (; c != NULL; c = c->next) {
796 /* Check if this user is on the channel */
797 if (stricmp (chan, c->chan) == 0) {
798 if (stricmp (Mynick, c->nick) != 0) {
799 strncpy (f_tmp, c->nick, sizeof(f_tmp));
800 i++;
801 }
802 }
803 }
804
805 x = rand () % i + 2;
806 i = 0; /* reinit! */
807
808 for (c = userhead; c != NULL; c = c->next) {
809 if (stricmp (chan, c->chan) == 0) {
810 i++;
811 if (i == x) {
812 if (*c->nick == '0') {
813 return f_tmp;
814 }
815 if (stricmp (Mynick, c->nick) != 0) {
816 strncpy (f_tmp, c->nick, sizeof(f_tmp));
817 return f_tmp;
818 }
819 }
820 }
821 }
822 return f_tmp;
823 }
824
825 void
add_user(char * chan,char * nick,char * uh,long tog)826 add_user (char *chan, char *nick, char *uh, long tog)
827 {
828 /* toggle of 0 means to unidle the client */
829 struct userlist *n, *c;
830 c = userhead;
831 if (strlen (uh) > 399)
832 uh[399] = '\0';
833 while (c) { /* don't readd data that already exists */
834 if (tog == 0) {
835 if (stricmp (c->nick, nick) == 0
836 && stricmp (c->chan, chan) == 0) {
837 c->idle = time (NULL);
838 }
839 }
840 if (tog == 1) {
841 if (stricmp (c->nick, nick) == 0
842 && stricmp (c->chan, chan) == 0) {
843 /* If user is somehow already here, just update his data instead
844 of readding */
845 strncpy (c->chan, chan, sizeof(c->chan));
846 strncpy (c->uh, uh, sizeof(c->uh));
847 strlwr (c->uh);
848 strncpy (c->nick, nick,sizeof(c->nick));
849 c->idle = time (NULL);
850 c->level = 0;
851 R;
852 }
853 }
854 c = c->next;
855 }
856 if (tog == 0) {
857 /* all we wanted to do was unidle, so we can quit now */
858 R;
859 }
860 n = (struct userlist *) malloc (sizeof (struct userlist));
861 if (n == NULL) {
862 log ("error.log", "AHHH! No ram left! in add_user!\n");
863 R;
864 }
865 memset (n, 0, sizeof (struct userlist));
866 if (n != NULL) {
867 strncpy (n->chan, chan, sizeof(n->chan));
868 strncpy (n->uh, uh, sizeof(n->uh));
869 strlwr (n->uh);
870 strncpy (n->nick, nick, sizeof(n->nick));
871 n->idle = time (NULL);
872 n->level = 0;
873
874 n->next = userhead;
875 userhead = n;
876 }
877 }
878
879 #if DO_CHANBOT_CRAP == 1
880 /**
881 * Remove a permban based on nickname and user@host.
882 * 6/23/00 Dan:
883 * - Both arguments are now pointers to const data
884 * - Added free() for both pNode->uh and pNode->reason now
885 * that the permbanlist has dynamically allocated fields
886 * - Changed type of toggle from long to bool
887 * - Changed name of toggle variable to (foundBan)
888 * - permbanlist pointers are now initialized when declared
889 * - Added if statement at end of method, this will only save
890 * the bans if a ban was removed
891 */
892 int
del_permban(const char * nick,const char * uh)893 del_permban (const char *nick, const char *uh)
894 {
895
896 bool foundBan = false;
897 struct permbanlist *pNode = permbanhead, *pPrev = 0;
898
899 while (pNode) {
900 if (stricmp (pNode->uh, uh) == 0) {
901 L002 (nick, PERMBAN_counter, uh);
902 PERMBAN_counter--;
903 if (pPrev != NULL) {
904 pPrev->next = pNode->next;
905 }
906 else {
907 permbanhead = pNode->next;
908 }
909
910 free (pNode->uh);
911 free (pNode->reason);
912 free (pNode);
913 foundBan = true;
914 pNode = NULL;
915 break;
916 }
917 pPrev = pNode;
918 pNode = pNode->next;
919 }
920
921 if (foundBan) {
922 /* Only need to save bans if ban list has changed */
923 save_permbans ();
924 }
925 return foundBan;
926 }
927 #endif
928
929 char *
revert_topic(char * input)930 revert_topic (char *input)
931 {
932 char *ptr, b[STRING_SHORT];
933
934 ptr = strtok (input, "+");
935 strncpy (f_tmp, ptr, sizeof(f_tmp));
936 if (ptr != NULL) {
937 while (ptr != NULL) {
938 ptr = strtok (NULL, "+");
939 if (ptr != NULL) {
940 #ifdef WIN32
941 sprintf (b, "%s %s", f_tmp, ptr);
942 #else
943 snprintf (b, sizeof(b), "%s %s", f_tmp, ptr);
944 #endif
945 strncpy (f_tmp, b, sizeof(f_tmp));
946 }
947 }
948 R f_tmp;
949 }
950 else
951 R f_tmp;
952 }
953
954 char *
get_multiword_topic(char * first)955 get_multiword_topic (char *first)
956 {
957 char *tmp2;
958
959 tmp2 = strtok (NULL, " ");
960 if (tmp2 != NULL) {
961 sprintf (f_tmp, "%s", first);
962 while (tmp2 != NULL) {
963 sprintf (f_tmp, "%s+%s", f_tmp, tmp2);
964 tmp2 = strtok (NULL, " ");
965 }
966 R f_tmp;
967 }
968 else
969 R first;
970 }
971
972 /**
973 * Delete one or more elements from the sendq
974 * 1 = delete all pri/not's
975 * 0 = delete first in queue
976 * 6/23/00 Dan
977 * - Updated to use head and tail pointer queue
978 * - All variables now initialized when declared
979 * - Optimized the main while loop a bit, reduced amount of code
980 */
981 void
del_sendq(long toggle)982 del_sendq (long toggle)
983 {
984 struct sendq *pNode = sendqhead, *pPrev = 0;
985
986 if (NULL == sendqhead) {
987 return;
988 }
989
990 if (toggle == 0) {
991 /* Just delete the head */
992 pNode = sendqhead;
993 sendqhead = sendqhead->next;
994
995 free (pNode);
996 }
997 else {
998 /* Iterate through the queue and delete each element which is
999 * a PRIVMSG or NOTICE
1000 */
1001 for (; pNode != NULL; pPrev = pNode, pNode = pNode->next) {
1002 if (0 == strncmp (pNode->data, "PRI", 3)
1003 || 0 == strncmp (pNode->data, "NOT", 3)) {
1004 /* Found one, let's delete it */
1005 if (pPrev != NULL) {
1006 pPrev->next = pNode->next;
1007 }
1008 else {
1009 sendqhead = pNode->next;
1010 }
1011 free (pNode);
1012 pNode = NULL;
1013 break;
1014 }
1015 } /* for */
1016 } /* else */
1017
1018 /* Update the tail pointer if needed */
1019 if (NULL == sendqhead) {
1020 sendqtail = NULL;
1021 }
1022 }
1023
1024 /**
1025 * 6/23/00 Dan
1026 * - Changed method argument to be pointer to const data
1027 * - Initialized b
1028 */
1029 int
Snow(const char * format,...)1030 Snow (const char *format, ...)
1031 {
1032 va_list arglist;
1033 char b[STRING_LONG] = { 0 };
1034
1035 va_start (arglist, format);
1036 vsprintf (b, format, arglist);
1037 va_end (arglist);
1038 if (DebuG == 1)
1039 printf ("OUT: %s\n", b);
1040 R (writeln (b));
1041 }
1042
1043 /**
1044 * 6/23/00 Dan
1045 * - Changed method argument to be pointer to const data
1046 * - Initialized variables when declared
1047 * - Changed b to a power of 2
1048 */
1049 void
S(const char * format,...)1050 S (const char *format, ...)
1051 {
1052 va_list arglist;
1053 char b[STRING_LONG] = { 0 };
1054 struct sendq *n = 0;
1055
1056 va_start (arglist, format);
1057 vsprintf (b, format, arglist);
1058 va_end (arglist);
1059
1060 if (send_tog == 0) {
1061 send_tog = 1;
1062 if (DebuG == 1) {
1063 printf ("OUT: %s\n", b);
1064 }
1065 writeln (b);
1066 R;
1067 }
1068
1069 n = (struct sendq *) malloc (sizeof (struct sendq));
1070 if (n == NULL) {
1071 log ("error.log", "AHH! no ram left! in S!\n");
1072 R;
1073 }
1074
1075 memset (n, 0, sizeof (struct sendq));
1076 strncpy (n->data, b, sizeof(n->data));
1077
1078 if (sendqhead == NULL) {
1079 sendqhead = sendqtail = n;
1080 }
1081 else {
1082 sendqtail->next = n;
1083 sendqtail = sendqtail->next;
1084 }
1085 }
1086
1087 void
count_seen(char * source,char * target)1088 count_seen (char *source, char *target)
1089 {
1090 FILE *fp;
1091 char temp[STRING_LONG] = "";
1092 long i = 0;
1093 if ((fp = fopen (SEEN_FILE, "r")) == NULL) {
1094 L003 (source, SEEN_FILE);
1095 R;
1096 }
1097 while (fgets (temp, STRING_LONG, fp)) {
1098 i++;
1099 }
1100 fclose (fp);
1101 L004 (target, source, i);
1102 }
1103
1104 void
show_seen(char * nick,char * source,char * target)1105 show_seen (char *nick, char *source, char *target)
1106 {
1107 FILE *fp;
1108 char temp[STRING_LONG] = "", *intime, *r_nick, *uh, *chan, *ptr;
1109 long unixtime = 0;
1110
1111 if (nick == NULL)
1112 R;
1113 if (strlen (nick) > 30)
1114 R;
1115 if (stricmp (nick, source) == 0) {
1116 L005 (target, source);
1117 R;
1118 }
1119 if ((ptr = strchr (nick, '?')) != NULL)
1120 memmove (ptr, ptr + 1, strlen (ptr + 1) + 1);
1121 if ((fp = fopen (SEEN_FILE, "r")) == NULL) {
1122 L003 (source, SEEN_FILE);
1123 R;
1124 }
1125 while (fgets (temp, STRING_LONG, fp)) {
1126 stripline (temp);
1127 r_nick = strtok (temp, " ");
1128 if (stricmp (nick, r_nick) == 0) {
1129 uh = strtok (NULL, " ");
1130 chan = strtok (NULL, " ");
1131 if (uh == NULL || chan == NULL)
1132 continue;
1133 intime = strtok (NULL, " ");
1134 if (intime == NULL)
1135 continue;
1136 unixtime = time (NULL) - atoi (intime);
1137 if (unixtime > 86400)
1138 S
1139 ("PRIVMSG %s :%s, I last saw %s (%s) %d day%s, %02d:%02d ago in %s\n",
1140 target, source, r_nick, uh, unixtime / 86400,
1141 (unixtime / 86400 == 1) ? "" : "s", (unixtime / 3600) % 24,
1142 (unixtime / 60) % 60, chan);
1143 else if (unixtime > 3600)
1144 S
1145 ("PRIVMSG %s :%s, I last saw %s (%s) %d hour%s, %d min%s ago in %s\n",
1146 target, source, r_nick, uh, unixtime / 3600,
1147 unixtime / 3600 == 1 ? "" : "s", (unixtime / 60) % 60,
1148 (unixtime / 60) % 60 == 1 ? "" : "s", chan);
1149 else
1150 S
1151 ("PRIVMSG %s :%s, I last saw %s (%s) %d minute%s, %d sec%s ago in %s\n",
1152 target, source, r_nick, uh, unixtime / 60,
1153 unixtime / 60 == 1 ? "" : "s", unixtime % 60,
1154 unixtime % 60 == 1 ? "" : "s", chan);
1155 fclose (fp);
1156 R;
1157 }
1158 }
1159 fclose (fp);
1160 L006 (target, source, nick, SEEN_REPLY);
1161 }
1162
1163 long
save_seen(char * nick,char * uh,char * chan)1164 save_seen (char *nick, char *uh, char *chan)
1165 {
1166 FILE *fp;
1167 char temp[STRING_LONG] = "", *r_nick, *r_chan, *r_uh, *r_time;
1168 long toggle = 0, unixtime = 0;
1169
1170 #ifdef WIN32
1171 printf ("*** Writing seen file: %s (%s)\n", CHAN, SEEN_FILE,
1172 date ());
1173 #endif
1174 unlink (TMP_FILE);
1175 if ((fp = fopen (SEEN_FILE, "r")) == NULL) {
1176 log (SEEN_FILE, "%s %s %s %d\n", nick, uh, chan, time (NULL));
1177 R - 1;
1178 }
1179 while (fgets (temp, STRING_LONG, fp)) {
1180 stripline (temp);
1181 r_nick = strtok (temp, " ");
1182 if (stricmp (nick, r_nick) == 0) {
1183 toggle = 1;
1184 log (TMP_FILE, "%s %s %s %d\n", nick, uh, chan, time (NULL));
1185 }
1186 else {
1187 r_uh = strtok (NULL, " ");
1188 r_chan = strtok (NULL, " ");
1189 r_time = strtok (NULL, " ");
1190 if (r_uh == NULL || r_chan == NULL || r_time == NULL)
1191 continue;
1192 unixtime = time (NULL) - atoi (r_time);
1193 if (unixtime < MAX_LASTSEEN)
1194 log (TMP_FILE, "%s %s %s %s\n", r_nick, r_uh, r_chan, r_time);
1195 }
1196 }
1197 fclose (fp);
1198 if (toggle == 0) {
1199 log (TMP_FILE, "%s %s %s %d\n", nick, uh, chan, time (NULL));
1200 }
1201 rename (TMP_FILE, SEEN_FILE);
1202 return toggle;
1203 }
1204
1205 #if DO_CHANBOT_CRAP == 1
1206 /**
1207 * Save the permban list to file.
1208 * 6/23/00 Dan:
1209 * - the permbanlist pointer (c) is now pointer to const, because
1210 * this is a read only method, and that is a read only variable
1211 * - Initialized c when it is declared
1212 */
1213 void
save_permbans()1214 save_permbans ()
1215 {
1216
1217 const struct permbanlist *c = permbanhead;
1218
1219 unlink (TMP_FILE);
1220
1221 #ifdef WIN32
1222 printf ("*** Writing permbans: %s (%s)\n", PERMBAN, date ());
1223 #endif
1224
1225 for (; c != NULL; c = c->next) {
1226 log (TMP_FILE, "%s %d %s\n", c->uh, c->counter, c->reason);
1227 }
1228 rename (TMP_FILE, PERMBAN);
1229
1230 if (PERMBAN_counter == 0)
1231 unlink (PERMBAN);
1232 }
1233 #endif
1234
1235 /**
1236 * Remove the autotopic for a particular channel.
1237 * 6/23/00 Dan:
1238 * - Method argument is now pointer to const data
1239 * - All variables are now initialized when declared
1240 * - Changed size of b to be power of 2
1241 * - Changed variable types of toggle and x in accordance
1242 * with their use
1243 */
1244 void
del_autotopic(const char * chan)1245 del_autotopic (const char *chan)
1246 {
1247 FILE *fp = 0;
1248 char b[STRING_LONG] = { 0 }, *r_chan = 0, *r_data = 0;
1249 bool toggle = false;
1250 size_t x = 0;
1251
1252 unlink (TMP_FILE);
1253 fp = fopen (AUTOTOPIC_F, "r");
1254 if (NULL == fp) {
1255 return;
1256 }
1257
1258 while (fgets (b, STRING_LONG, fp)) {
1259 x++;
1260 stripline (b);
1261
1262 r_chan = strtok (b, " ");
1263 r_data = strtok (NULL, "");
1264
1265 if (stricmp (r_chan, chan) == 0) {
1266 /* Found the channel */
1267 toggle = true;
1268 }
1269 else {
1270 log (TMP_FILE, "%s %s\n", r_chan, r_data);
1271 }
1272 }
1273
1274 fclose (fp);
1275 if (x == 1 && toggle) {
1276 /* The autotopic file is now empty */
1277 unlink (AUTOTOPIC_F);
1278 unlink (TMP_FILE);
1279 R;
1280 }
1281
1282 if (toggle) {
1283 /* We found the topic, change the temp file to the
1284 * the name of the autotopic file */
1285 rename (TMP_FILE, AUTOTOPIC_F);
1286 }
1287 else {
1288 /* We were unable to find the channel, just
1289 * return */
1290 unlink (TMP_FILE);
1291 }
1292 }
1293
1294 void
do_autotopics()1295 do_autotopics ()
1296 {
1297 FILE *fp;
1298 char b[STRING_LONG], *r_chan, *r_data;
1299
1300 if ((fp = fopen (AUTOTOPIC_F, "r")) == NULL)
1301 R;
1302 while (fgets (b, STRING_LONG, fp)) {
1303 stripline (b);
1304 r_chan = strtok (b, " ");
1305 r_data = strtok (NULL, "");
1306 if (*r_data != '0') {
1307 db_sleep (1);
1308 S ("TOPIC %s :%s\n", r_chan, r_data);
1309 }
1310 }
1311 fclose (fp);
1312 }
1313
1314 long
ifexist_autotopic(char * chan)1315 ifexist_autotopic (char *chan)
1316 {
1317 FILE *fp;
1318 char b[STRING_LONG], *r_chan;
1319
1320 if ((fp = fopen (AUTOTOPIC_F, "r")) == NULL)
1321 R - 1;
1322 while (fgets (b, STRING_LONG, fp)) {
1323 stripline (b);
1324 if (*b == '/')
1325 continue;
1326 r_chan = strtok (b, " ");
1327 if (stricmp (r_chan, chan) == 0) {
1328 fclose (fp);
1329 R 1; /* exists */
1330 }
1331 }
1332 fclose (fp);
1333 R 0; /* doesn't exist */
1334 }
1335
1336 void
set_autotopic(char * source,char * target,char * topic)1337 set_autotopic (char *source, char *target, char *topic)
1338 {
1339 long exist = 0;
1340
1341 exist = ifexist_autotopic (target);
1342 if (exist == 0 && *topic == '0') { /* never existed, lets humor
1343 * the guy */
1344 L007 (source, target);
1345 R;
1346 }
1347 else if (exist == 1 && *topic == '0') { /* delete it! */
1348 L008 (source, target);
1349 S ("TOPIC %s :\n", target);
1350 del_autotopic (target);
1351 R;
1352 }
1353 if (strlen (topic) >= 400) /* make sure no overflow */
1354 topic[400] = '\0';
1355 if (exist == 0) { /* no such autotopic, so add it */
1356 L009 (source, target, topic);
1357 log (AUTOTOPIC_F, "%s %s\n", target, topic);
1358 R;
1359 }
1360 /* only thing left is if topic exists and you want to update it */
1361 del_autotopic (target);
1362 L010 (source, target, topic);
1363 S ("TOPIC %s :%s\n", target, topic);
1364 log (AUTOTOPIC_F, "%s %s\n", target, topic);
1365 }
1366
1367 #ifdef RANDOM_STUFF
1368 void
add_randomstuff(char * source,char * target,char * data)1369 add_randomstuff (char *source, char *target, char *data)
1370 {
1371 FILE *fp;
1372 char b[STRING_LONG], file2[STRING_SHORT], *ptr;
1373 long int i = 0, x = 0;
1374 long TOG = 0;
1375
1376 if (*data == '~') {
1377 data++;
1378 TOG = 1;
1379 ptr = strtok (data, " ");
1380 if (ptr != NULL)
1381 strlwr (ptr);
1382
1383 if (strspn (ptr, LEGAL_TEXT) != strlen (ptr)) {
1384 S
1385 ("PRIVMSG %s :%s, rdb file must be made up of letters and or numbers, no other text is accepted.\n",
1386 target, source);
1387 R;
1388 }
1389 #ifdef WIN32
1390 sprintf (file2, "dat/%s.rdb", ptr);
1391 #else
1392 snprintf(file2,sizeof(file2),"dat/%s.rdb",ptr);
1393 #endif
1394 data = strtok (NULL, "");
1395 }
1396 else
1397 #ifdef WIN32
1398 sprintf (file2, "%s", RAND_FILE);
1399 #else
1400 snprintf(file2,sizeof(file2), "%s", RAND_FILE);
1401 #endif
1402 if ((fp = fopen (file2, "r")) == NULL) {
1403 if (TOG == 1) {
1404 log (file2, "1\n%s\n", data);
1405 S ("PRIVMSG %s :Done, there is 1 topic under %s\n", target,
1406 file2);
1407 }
1408 R;
1409 }
1410 unlink (TMP_FILE);
1411 while (fgets (b, STRING_LONG, fp)) {
1412 stripline (b);
1413 i++;
1414 if (*b == '/')
1415 continue;
1416 if (i == 1) {
1417 if (b != NULL) {
1418 x = atol (strtok (b, " "));
1419 log (TMP_FILE, "%ld\n", x + 1);
1420 }
1421 }
1422 else {
1423 log (TMP_FILE, "%s\n", b);
1424 }
1425 }
1426 log (TMP_FILE, "%s\n", data);
1427 L011 (target, source, i);
1428 fclose (fp);
1429 rename (TMP_FILE, file2);
1430 }
1431 #endif
1432
1433 #ifdef RANDOM_STUFF
1434 void
get_rand_stuff_time()1435 get_rand_stuff_time ()
1436 {
1437 Rand_Stuff = rand () % RAND_STUFF_TIME + 2;
1438 if (Rand_Stuff < RAND_STUFF_TIME / 2)
1439 Rand_Stuff = RAND_STUFF_TIME;
1440 }
1441 #endif
1442
1443 #ifdef RANDOM_STUFF
1444 /**
1445 * 6/23/00 Dan:
1446 * - Removed an unused variable
1447 * - Changed initialization of temp
1448 * - Changed size of b to be power of 2, and initialized
1449 * - Initialized all other variables
1450 */
1451 void
do_random_stuff()1452 do_random_stuff ()
1453 {
1454 FILE *fp = 0;
1455 char temp[STRING_SHORT] = { 0 }, b[STRING_LONG] =
1456 {
1457 0}
1458 , *b2 = 0;
1459 bool A = false;
1460 size_t i = 0;
1461 size_t length = 0;
1462 size_t x = 0, y = 0;
1463 srand (time (0)); /* this makes things more random! */
1464
1465
1466 fp = fopen (RAND_FILE, "r");
1467 if (NULL == fp) {
1468 return;
1469 }
1470
1471 while (fgets (b, STRING_LONG, fp)) {
1472 if (*b == '/') {
1473 continue;
1474 }
1475 i++;
1476 stripline (b);
1477
1478 if (i == 1) {
1479 y = atoi (b);
1480 x = rand () % y + 2;
1481 }
1482 if (i == x) {
1483 if (*b == '+') {
1484 A = true;
1485 }
1486 length = strlen (b);
1487 i = 0;
1488
1489 memset (data, 0, sizeof (data));
1490 while (length > 0) {
1491 i++;
1492 length--;
1493 if (b[length] == '~') {
1494 /* $chan */
1495 #ifdef WIN32
1496 sprintf (temp, "%s%s", CHAN, data);
1497 #else
1498 snprintf(temp, sizeof(temp), "%s%s", CHAN, data);
1499 #endif
1500 }
1501 else {
1502 #ifdef WIN32
1503 sprintf (temp, "%c%s", b[length], data);
1504 #else
1505 snprintf(temp, sizeof(temp), "%c%s", b[length], data);
1506 #endif
1507 }
1508 strncpy (data, temp, sizeof(data));
1509 }
1510 if (!A) {
1511 S ("PRIVMSG %s :%s\n", CHAN, data);
1512 fclose (fp);
1513 R;
1514 }
1515 else {
1516 b2 = data;
1517 b2++;
1518 S ("PRIVMSG %s :\1ACTION %s\1\n", CHAN, b2);
1519 fclose (fp);
1520 R;
1521 }
1522 }
1523 } /* while() */
1524
1525 /* fclose(fp); */
1526 }
1527 #endif
1528
1529
1530 void
do_randomtopic(char * target,char * file,char * nick,char * topic)1531 do_randomtopic (char *target, char *file, char *nick, char *topic)
1532 {
1533 FILE *fp = 0;
1534
1535 char temp[STRING_SHORT] = { 0 };
1536 char b2[STRING_LONG] = { 0 };
1537 char *b = 0;
1538 char file2[STRING_SHORT] = { 0 };
1539 char Data[STRING_LONG] = { 0 };
1540
1541 long x = 0;
1542 long y = 0;
1543 long A = 0;
1544
1545 size_t i = 0;
1546 size_t length = 0;
1547
1548 bool Tog = false;
1549
1550 if (file != NULL)
1551 #ifdef WIN32
1552 sprintf (file2, "dat/%s.rdb", file);
1553 #else
1554 snprintf (file2, sizeof(file2), "dat/%s.rdb", file);
1555 #endif
1556 if ((fp = fopen (file2, "r")) == NULL) {
1557 S ("PRIVMSG %s :Sorry, I cannot answer that topic because "
1558 "darkbot random text file (rdb) \"%s\" was not found.\n",
1559 target, file2);
1560 R;
1561 }
1562 db_sleep (1);
1563 while (fgets (b2, STRING_LONG, fp)) {
1564 i++;
1565 stripline (b2);
1566 if (i == 1) {
1567 y = atoi (b2);
1568 x = rand () % y + 2;
1569 }
1570 if (i == x) {
1571 i = 0;
1572 b = b2;
1573 if (*b == '+') {
1574 b++;
1575 A = 1;
1576 }
1577 length = strlen (b);
1578 while (length > 0) {
1579 length--;
1580 if (Tog) {
1581 Tog = false;
1582 #ifdef WIN32
1583 if (b[length] == 'N') { /* nick */
1584 sprintf (temp, "%s%s", nick, Data);
1585 }
1586 else if (b[length] == 'C') { /* chan */
1587 sprintf (temp, "%s%s", target, Data);
1588 }
1589 else if (b[length] == 'T') { /* time */
1590 sprintf (temp, "%s%s", date (), Data);
1591 }
1592 else if (b[length] == 'R') { /* rand */
1593 sprintf (temp, "%s%s", get_rand_nick (target),
1594 Data);
1595 }
1596 else if (b[length] == 'S') { /* serv */
1597 sprintf (temp, "%s%s", BS, Data);
1598 }
1599 else if (b[length] == 'P') { /* port */
1600 sprintf (temp, "%d%s", (int) BP, Data);
1601 }
1602 else if (b[length] == 'Q') { /* question */
1603 sprintf (temp, "%s%s", revert_topic (topic),
1604 Data);
1605 }
1606 else if (b[length] == 'W') { /* WWW page */
1607 sprintf (temp,"http://darkbot.net%s", Data);
1608 }
1609 else if (b[length] == '!') { /* cmdchar */
1610 sprintf (temp,"%c%s", *CMDCHAR, Data);
1611 }
1612 else if (b[length] == 'V') { /* version */
1613 sprintf (temp,"%s%s", dbVersion, Data);
1614 }
1615 else if (b[length] == 'B') { /* mynick */
1616 sprintf (temp,"%s%s", Mynick, Data);
1617 }
1618 else {
1619 sprintf (temp,"%c~%s", b[length], Data);
1620 }
1621 }
1622 else if (b[length] == '~') {
1623 Tog = true;
1624 }
1625 else {
1626 sprintf (temp,"%c%s", b[length], Data);
1627 }
1628 strncpy (Data, temp, sizeof(Data));
1629 } /* While */
1630 #else
1631 if (b[length] == 'N') { /* nick */
1632 snprintf (temp, sizeof(temp), "%s%s", nick, Data);
1633 }
1634 else if (b[length] == 'C') { /* chan */
1635 snprintf (temp, sizeof(temp), "%s%s", target, Data);
1636 }
1637 else if (b[length] == 'T') { /* time */
1638 snprintf (temp, sizeof(temp), "%s%s", date (), Data);
1639 }
1640 else if (b[length] == 'R') { /* rand */
1641 snprintf (temp, sizeof(temp), "%s%s", get_rand_nick (target),
1642 Data);
1643 }
1644 else if (b[length] == 'S') { /* serv */
1645 snprintf (temp, sizeof(temp), "%s%s", BS, Data);
1646 }
1647 else if (b[length] == 'P') { /* port */
1648 snprintf (temp, sizeof(temp), "%d%s", (int) BP, Data);
1649 }
1650 else if (b[length] == 'Q') { /* question */
1651 snprintf (temp,sizeof(temp), "%s%s", revert_topic (topic),
1652 Data);
1653 }
1654 else if (b[length] == 'W') { /* WWW page */
1655 snprintf (temp,sizeof(temp), "http://darkbot.net%s", Data);
1656 }
1657 else if (b[length] == '!') { /* cmdchar */
1658 snprintf (temp, sizeof(temp), "%c%s", *CMDCHAR, Data);
1659 }
1660 else if (b[length] == 'V') { /* version */
1661 snprintf (temp,sizeof(temp), "%s%s", dbVersion, Data);
1662 }
1663 else if (b[length] == 'B') { /* mynick */
1664 snprintf (temp, sizeof(temp),"%s%s", Mynick, Data);
1665 }
1666 else {
1667 snprintf (temp,sizeof(temp), "%c~%s", b[length], Data);
1668 }
1669 }
1670 else if (b[length] == '~') {
1671 Tog = true;
1672 }
1673 else {
1674 snprintf (temp, sizeof(temp),"%c%s", b[length], Data);
1675 }
1676 strncpy (Data, temp, sizeof(Data));
1677 } /* While */
1678 #endif
1679 if (A == 0) {
1680 S ("PRIVMSG %s :%s\n", target, Data);
1681 }
1682 else {
1683 S ("PRIVMSG %s :\1ACTION %s\1\n", target, Data);
1684 }
1685 fclose (fp);
1686 R;
1687 }
1688 }
1689 fclose (fp);
1690 }
1691
1692
1693 /**
1694 * Add a permban to the permban list.
1695 * 6/23/00 Dan:
1696 * - Both pointer variables are now received as pointer to const data
1697 * - Changed counter to type size_t, this should be an unsigned type
1698 * - Initialiazed n to 0 on declaration
1699 * - Added support for dynamically allocated uh and reason fields
1700 * in the struct permban list
1701 * - Did some extra memory leak prevention
1702 */
1703 void
add_permban(const char * uh,size_t counter,const char * reason)1704 add_permban (const char *uh, size_t counter, const char *reason)
1705 {
1706
1707 struct permbanlist *n = 0;
1708 n = (struct permbanlist *)
1709 malloc (sizeof (struct permbanlist));
1710 if (n == NULL) {
1711 log ("error.log", "AHHH! no ram left! in add_permban!\n");
1712 R;
1713 }
1714
1715 memset (n, 0, sizeof (struct permbanlist));
1716 n->uh = db_strndup (uh, STRING_SHORT);
1717 if (NULL == n->uh) {
1718 log ("error.log", "add_permban> Memory allocation failure\n");
1719 /* Prevent memory leaks */
1720 free (n);
1721 return;
1722 }
1723
1724 n->reason = db_strndup (reason, STRING_SHORT);
1725 if (NULL == n->reason) {
1726 log ("error.log", "add_permban> Memory allocation failure\n");
1727 /* Prevent memory leaks */
1728 free (n->uh);
1729 free (n);
1730 return;
1731 }
1732
1733 strlwr (n->uh);
1734 n->counter = counter;
1735 PERMBAN_counter++;
1736 n->next = permbanhead;
1737 permbanhead = n;
1738 }
1739
1740 /**
1741 * Check if a permban exists for a given uh/channel/nick set.
1742 * 6/23/00 Dan:
1743 * - Changed all method arguments to be pointers to const data
1744 * - Return type is now bool, returns true if ban is found,
1745 * false otherwise
1746 */
1747 bool
check_permban(const char * uh,const char * chan,const char * nick)1748 check_permban (const char *uh, const char *chan, const char *nick)
1749 {
1750 static char tmpBuf[STRING_SHORT + 1];
1751 struct permbanlist *c = permbanhead;
1752 strncpy (tmpBuf, uh, min (STRING_SHORT, strlen (uh)));
1753 strlwr (tmpBuf);
1754 for (; c != NULL; c = c->next) {
1755 if (!match_wild (c->uh, tmpBuf) == 0) {
1756 c->counter++;
1757 S ("MODE %s +b %s\n", chan, c->uh);
1758 S ("KICK %s %s :\2[\2%d\2]\2: %s\n",
1759 chan, nick, c->counter, c->reason);
1760 R true;
1761 }
1762 }
1763 R false;
1764 }
1765
1766 #ifndef WIN32
min(const size_t a,const size_t b)1767 size_t min (const size_t a, const size_t b)
1768 {
1769 return ((a < b) ? a : b);
1770 }
1771 #endif
1772
1773 long
get_pass(char * data)1774 get_pass (char *data)
1775 {
1776 /* returns 0 for no data */
1777 /* returns 1 for just pass */
1778 /* returns 2 for pass and data */
1779 char b[STRING_SHORT], b2[STRING_SHORT], *temp;
1780 long i = 0;
1781 strncpy (pass_data, "0", sizeof(pass_data)); /* init */
1782 strncpy (pass_pass, "0", sizeof(pass_pass));
1783 if (data == NULL)
1784 R 0;
1785 strncpy (b2, data, sizeof(b2));
1786 temp = strtok (data, " ");
1787 if (temp == NULL)
1788 R - 1;
1789 strncpy (b, temp, sizeof(b));
1790 while (temp != NULL) {
1791 i++;
1792 strncpy (pass_pass, temp, sizeof(pass_pass));
1793 temp = strtok (NULL, " ");
1794 if (temp == NULL)
1795 break;
1796 #ifdef WIN32
1797 sprintf (b,"%s %s", b, temp);
1798 #else
1799 snprintf (b, sizeof(b),"%s %s", b, temp);
1800 #endif
1801 }
1802 strncpy (b, "", sizeof(b)); /* reinit */
1803 temp = strtok (b2, " ");
1804 strncpy (b, temp, sizeof(b));
1805 while (i > 2) {
1806 i--;
1807 temp = strtok (NULL, " ");
1808 #ifdef WIN32
1809 sprintf (b,"%s %s", b, temp);
1810 #else
1811 snprintf (b, sizeof(b),"%s %s", b, temp);
1812 #endif
1813 }
1814 if (stricmp (b, pass_pass) == 0) {
1815 strncpy (pass_data, "0", sizeof(pass_data));
1816 R 1;
1817 }
1818 strncpy (pass_data, b, sizeof(pass_data));
1819 R 2;
1820 }
1821
1822 void
set_pass(char * nick,char * uh,char * pass,char * newpass)1823 set_pass (char *nick, char *uh, char *pass, char *newpass)
1824 {
1825 struct helperlist *c;
1826 c = helperhead;
1827 strlwr (uh);
1828 while (c) {
1829 if (!match_wild (c->uh, uh) == 0) {
1830 if (strcmp (c->pass, pass) == 0) {
1831 strncpy (c->pass, newpass, sizeof(c->pass));
1832 L012 (nick, uh);
1833 save_changes ();
1834 R;
1835 }
1836 else {
1837 L013 (nick);
1838 R;
1839 }
1840 }
1841 c = c->next;
1842 }
1843 L014 (nick);
1844 }
1845
1846 long
verify_pass(char * nick,char * chan,char * uh,char * pass)1847 verify_pass (char *nick, char *chan, char *uh, char *pass)
1848 {
1849 struct helperlist *c;
1850 c = helperhead;
1851 strlwr (uh);
1852 while (c) {
1853 if (!match_wild (c->uh, uh) == 0) {
1854 if (*c->pass == '0')
1855 R 0; /* no pass set */
1856 if (strcmp (c->pass, pass) == 0) {
1857 if (c->chan[0] == '#' && c->chan[1] == '*')
1858 R c->level;
1859 if (*chan == '*')
1860 R c->level;
1861 if (stricmp (c->chan, chan) == 0)
1862 R c->level;
1863 R 0; /* don't match chan access */
1864 }
1865 }
1866 c = c->next;
1867 }
1868 R 0;
1869 }
1870
1871 void
delete_user_ram(char * source,char * uh)1872 delete_user_ram (char *source, char *uh)
1873 {
1874 struct helperlist *pNode, *pPrev;
1875 pNode = helperhead;
1876 pPrev = NULL;
1877 while (pNode) {
1878 if (stricmp (pNode->uh, uh) == 0) {
1879 L015 (source, pNode->uh, pNode->level, pNode->num_join);
1880 if (pPrev != NULL) {
1881 pPrev->next = pNode->next;
1882 }
1883 else
1884 helperhead = pNode->next;
1885 free (pNode);
1886 pNode = NULL;
1887 break;
1888 }
1889 pPrev = pNode;
1890 pNode = pNode->next;
1891 }
1892 save_changes ();
1893 }
1894
1895 #ifdef DO_MATH_STUFF
1896 void
do_math(const char * who,char * target,char * math)1897 do_math (const char *who, char *target, char *math)
1898 {
1899 char input[STRING_SHORT];
1900 char number_string[STRING_SHORT];
1901 char op = 0;
1902 unsigned int index = 0;
1903 unsigned int to = 0;
1904 unsigned int input_length = 0;
1905 unsigned int number_length = 0;
1906 double result = 0.0;
1907 double number = 0.0;
1908 strncpy (input, math, sizeof(input));
1909 input_length = strlen (input);
1910 for (to = 0, index = 0; index <= input_length; index++)
1911 if (*(input + index) != ' ')
1912 *(input + to++) = *(input + index);
1913 input_length = strlen (input);
1914 index = 0;
1915 if (input[index] == '=')
1916 index++;
1917 else {
1918 number_length = 0;
1919 if (input[index] == '+' || input[index] == '-')
1920 *(number_string + number_length++) = *(input + index++);
1921 for (; isdigit (*(input + index)); index++)
1922 *(number_string + number_length++) = *(input + index);
1923 if (*(input + index) == '.') {
1924 *(number_string + number_length++) = *(input + index++);
1925 for (; isdigit (*(input + index)); index++)
1926 *(number_string + number_length++) = *(input + index);
1927 }
1928 *(number_string + number_length) = '\0';
1929 if (number_length > 0)
1930 result = atof (number_string);
1931 }
1932 for (; index < input_length;) {
1933 op = *(input + index++);
1934 number_length = 0;
1935 if (input[index] == '+' || input[index] == '-')
1936 *(number_string + number_length++) = *(input + index++);
1937 for (; isdigit (*(input + index)); index++)
1938 *(number_string + number_length++) = *(input + index);
1939 if (*(input + index) == '.') {
1940 *(number_string + number_length++) = *(input + index++);
1941 for (; isdigit (*(input + index)); index++)
1942 *(number_string + number_length++) = *(input + index);
1943 }
1944 *(number_string + number_length) = '\0';
1945 number = atof (number_string);
1946 switch (op) {
1947 case '+':
1948 result += number;
1949 break;
1950 case '-':
1951 result -= number;
1952 break;
1953 case '*':
1954 result *= number;
1955 break;
1956 case '/':
1957 if (number == 0) {
1958 L016 (target, who);
1959 R;
1960 }
1961 else
1962 result /= number;
1963 break;
1964 case '%':
1965 if ((long) number == 0) {
1966 L016 (target, who);
1967 R;
1968 }
1969 else
1970 result = (double) ((long) result % (long) number);
1971 break;
1972 default:
1973 L017 (target, who);
1974 R;
1975 }
1976 }
1977 S ("PRIVMSG %s :%s\2:\2 %f\n", target, who, result);
1978 }
1979 #endif
1980
1981 long
cf(char * host,char * nick,char * chan)1982 cf (char *host, char *nick, char *chan)
1983 {
1984 int f_n;
1985 if (check_access (host, chan, 0, nick)
1986 >= 3)
1987 R 0;
1988 f_n = f_f (host);
1989 if (f_n == -1) {
1990 a_f (host);
1991 R 0;
1992 }
1993 if (ood[f_n].value)
1994 R 1;
1995 ood[f_n].count++;
1996 if ((time (NULL) - ood[f_n].time) > ft)
1997 ood[f_n].count = 0;
1998 else if ((time (NULL) - ood[f_n].time) <= ft
1999 && ood[f_n].count >= fr) {
2000 ood[f_n].value = true;
2001 if (!ood[f_n].kick) {
2002 ood[f_n].kick = 1;
2003 #ifdef FLOOD_KICK
2004 if (*chan == '#' || *chan == '&') {
2005 L018 (chan, nick, FLOOD_REASON, fc, host);
2006 }
2007 else
2008 L019 (CHAN, fc, host);
2009 #else
2010 if (*chan == '#' || *chan == '&') {
2011 L019 (CHAN, fc, host);
2012 }
2013 else
2014 L019 (CHAN, fc, host);
2015 #endif
2016 }
2017 R 1;
2018 }
2019 ood[f_n].time = time (NULL);
2020 R 0;
2021 }
2022
2023 /**
2024 * 6/23/00 Dan:
2025 * - Initialized all variables
2026 */
2027 void
raw_now(char * type)2028 raw_now (char *type)
2029 {
2030 FILE *fp = 0;
2031 long i = 0, counter = 0;
2032 char str[STRING_LONG] = {
2033 0
2034 }
2035 , *dat = 0, *ptr = 0, *tmp1 = 0, *tmp2 = 0, *tmp3 = 0;
2036 if (stricmp (type, "PERFORM") == 0)
2037 if ((fp = fopen (PERFORM, "r")) == NULL)
2038 R;
2039 if (stricmp (type, "PERMBAN") == 0)
2040 if ((fp = fopen (PERMBAN, "r")) == NULL)
2041 R;
2042 if (stricmp (type, "DEOP") == 0)
2043 if ((fp = fopen (DEOP, "r")) == NULL)
2044 R;
2045 if (stricmp (type, "SERVERS") == 0)
2046 if ((fp = fopen (SERVERS, "r")) == NULL) {
2047 printf
2048 ("%s not found. You must create the file with format:\n",
2049 SERVERS);
2050 printf
2051 ("server port ...this list can be as long as you want.\n");
2052 exit (0);
2053 }
2054 if (stricmp (type, "SETUP") == 0)
2055 if ((fp = fopen (SETUP, "r")) == NULL) {
2056 printf ("Unable to locate %s! You must run configure!.\n",
2057 SETUP);
2058 exit (0);
2059 }
2060 while (!feof (fp)) {
2061 if (stricmp (type, "SETUP") == 0) {
2062 printf ("Loading %s data...\n", SETUP);
2063 SeeN = 1;
2064 while (fgets (str, STRING_LONG, fp)) {
2065 if (*str == '/')
2066 continue;
2067 stripline (str);
2068 dat = strtok (str, "");
2069 if ((ptr = strchr (dat, '=')) != NULL)
2070 *ptr++ = '\0';
2071 if (stricmp (dat, "NICK") == 0) {
2072 strncpy (Mynick, ptr, sizeof(Mynick));
2073 strncpy (s_Mynick, ptr, sizeof(s_Mynick));
2074 #if LOG_PRIVMSG == 1
2075 #ifdef WIN32
2076 sprintf (privmsg_log,"%s%s-privmsg.log",
2077 LOG_DIR, Mynick);
2078 #else
2079 snprintf (privmsg_log,sizeof(privmsg_log), "%s%s-privmsg.log",
2080 LOG_DIR, Mynick);
2081 #endif
2082 #endif
2083 }
2084 else if (stricmp (dat, "USERID") == 0) {
2085 strncpy (UID, ptr, sizeof(UID));
2086 }
2087 else if (stricmp (dat, "CHAN") == 0) {
2088 strncpy (CHAN, ptr, sizeof(CHAN));
2089 }
2090 else if (stricmp (dat, "SEEN") == 0) {
2091 SeeN = atoi (ptr);
2092 }
2093 else if (stricmp (dat, "VHOST") == 0) {
2094 strncpy (VHOST, ptr, sizeof(VHOST));
2095 }
2096 else if (stricmp (dat, "REALNAME") == 0) {
2097 strncpy (REALNAME, ptr, sizeof(REALNAME));
2098 }
2099 else if (stricmp (dat, "CMDCHAR") == 0) {
2100 *CMDCHAR = *ptr;
2101 }
2102 }
2103 #ifdef VERB
2104 printf (" - botnick(%s),", Mynick);
2105 printf ("userid(%s),", UID);
2106 printf ("channel(%s)\n", CHAN);
2107 printf (" - cmdchar(%c),", *CMDCHAR);
2108 printf ("vhost(%s),", VHOST);
2109 printf ("seen(%s)\n", SeeN == 1 ? "On" : "Off");
2110 printf (" - realname(%s)\n", REALNAME);
2111 #endif
2112 }
2113 else if (stricmp (type, "PERMBAN") == 0) {
2114 while (fgets (str, STRING_LONG, fp)) {
2115 stripline (str);
2116 tmp1 = strtok (str, " ");
2117 if (tmp1 == NULL)
2118 continue;
2119 tmp2 = strtok (NULL, " ");
2120 if (tmp2 == NULL)
2121 tmp2 = "0";
2122 tmp3 = strtok (NULL, "");
2123 if (tmp3 == NULL)
2124 tmp3 = "Permbanned!";
2125 strlwr (tmp1);
2126 counter = atoi (tmp2);
2127 add_permban (tmp1, counter, tmp3);
2128 }
2129 }
2130 else if (stricmp (type, "SERVERS") == 0) {
2131 #ifndef WIN32
2132 printf ("Loading %s file ", SERVERS);
2133 #endif
2134 while (fgets (str, STRING_LONG, fp)) {
2135 i++;
2136 printf (".");
2137 fflush (stdout);
2138 stripline (str);
2139 tmp1 = strtok (str, " ");
2140 if (tmp1 == NULL) {
2141 printf
2142 ("Found error in %s! Aboring! please re-run configure!\n",
2143 SERVERS); exit (0);
2144 }
2145 else
2146 tmp2 = strtok (NULL, " ");
2147 if (tmp2 == NULL) {
2148 printf ("%s has no matching port in %s!\n", tmp1, SERVERS);
2149 exit (0);
2150 }
2151 add_s25 (tmp1, atoi (tmp2));
2152 }
2153 printf ("done(%d).\n", (int) i);
2154 }
2155 else if (fgets (str, STRING_LONG, fp))
2156 S ("%s\n", str);
2157 }
2158 fclose (fp);
2159 }
2160
2161 /**
2162 * 6/22/00 Dan
2163 * - Function argument is now pointer to const
2164 * - Fixed a problem where the file was never closed
2165 * - All variables are now initialized when declared
2166 * - Removed an unused variable
2167 * - Changed long variables to type size_t, they should be
2168 * unsigned
2169 * - Changed reinitialization of data
2170 * - Moved the big if/else structure to a switch
2171 */
2172 char *
rand_reply(const char * nick)2173 rand_reply (const char *nick)
2174 {
2175
2176 FILE *fp = 0;
2177 char temp[STRING_SHORT] = {
2178 0
2179 };
2180 size_t i = 0, x = 0, y = 0, length = 0;
2181 fp = fopen (RAND_SAY, "r");
2182 if (NULL == fp) {
2183 return 0;
2184 }
2185
2186 while (fgets (r_reply, STRING_SHORT, fp)) {
2187 if (*r_reply == '/') {
2188 continue;
2189 }
2190 i++;
2191 stripline (r_reply);
2192 if (i == 1) {
2193 /* Read in random # from top line of * random.ini */
2194 y = atoi (r_reply);
2195 x = rand () % y + 2;
2196 }
2197 if (i != x) {
2198 continue;
2199 }
2200
2201 /* Found it */
2202 fclose (fp);
2203 length = strlen (r_reply);
2204 i = 0;
2205 data[0] = 0;
2206 while (length > 0) {
2207 i++;
2208 length--;
2209 switch (r_reply[length]) {
2210 case '^':
2211 #ifdef WIN32
2212 sprintf (temp,"%s%s", nick, data);
2213 break;
2214 case '%':
2215 /* Bold */
2216 sprintf (temp,"\2%s", data);
2217 break;
2218 case '&':
2219 /* Underline */
2220 sprintf (temp,"\37%s", data);
2221 break;
2222 case '~':
2223 /* Inverse */
2224 sprintf (temp,"\26%s", data);
2225 break;
2226 default:
2227 sprintf (temp,"%c%s", r_reply[length], data);
2228 break;
2229 #else
2230 snprintf (temp,sizeof(temp), "%s%s", nick, data);
2231 break;
2232 case '%':
2233 /* Bold */
2234 snprintf (temp,sizeof(temp), "\2%s", data);
2235 break;
2236 case '&':
2237 /* Underline */
2238 snprintf (temp,sizeof(temp), "\37%s", data);
2239 break;
2240 case '~':
2241 /* Inverse */
2242 snprintf (temp,sizeof(temp), "\26%s", data);
2243 break;
2244 default:
2245 snprintf (temp,sizeof(temp), "%c%s", r_reply[length], data);
2246 break;
2247 #endif
2248 } /* switch */
2249 strncpy (data, temp, sizeof(data));
2250 } /* while( length > 0 ) */
2251
2252 return data; /* Found random line */
2253 } /* while(fgets()) */
2254
2255 /* Unable to find match */
2256 fclose (fp);
2257 /* A space is returned to prevent crashing */
2258 return " ";
2259 }
2260
2261 /**
2262 * Update a nick's channel greeting and user@host.
2263 * 6/23/00 Dan:
2264 * - All method arguments are now pointers to const data
2265 * - Rewrote to use a for loop, and fewer variables
2266 * - Info is only saved to disk if changes are made
2267 */
2268 void
update_setinfo(const char * new_uh,const char * new_greetz,const char * nick)2269 update_setinfo (const char *new_uh,
2270 const char *new_greetz, const char *nick)
2271 {
2272 struct helperlist *c = helperhead;
2273 bool madeChange = false;
2274 size_t i = 0;
2275 for (; c != NULL; c = c->next) {
2276 ++i;
2277 if (!match_wild (c->uh, new_uh) == 0) {
2278 strncpy (c->greetz, new_greetz, sizeof(c->greetz));
2279 strlwr (c->uh);
2280 L020 (nick, i, c->uh, new_greetz);
2281 madeChange = true;
2282 }
2283 }
2284 if (madeChange) {
2285 save_changes ();
2286 }
2287 }
2288
2289 void
save_setup()2290 save_setup ()
2291 {
2292 #ifdef WIN32
2293 printf ("*** Writing setup file: %s (%s)\n", SETUP, date ());
2294 #endif
2295 unlink (TMP_FILE);
2296 log (TMP_FILE, "NICK=%s\n", s_Mynick);
2297 log (TMP_FILE, "USERID=%s\n", UID);
2298 log (TMP_FILE, "CHAN=%s\n", CHAN);
2299 log (TMP_FILE, "VHOST=%s\n", VHOST);
2300 log (TMP_FILE, "REALNAME=%s\n", REALNAME);
2301 log (TMP_FILE, "CMDCHAR=%c\n", *CMDCHAR);
2302 log (TMP_FILE, "SEEN=%d\n", SeeN);
2303 rename (TMP_FILE, SETUP);
2304 }
2305
2306 void
save_changes()2307 save_changes ()
2308 {
2309 long i = 0;
2310 struct helperlist *c;
2311 c = helperhead;
2312 unlink (TMP_FILE);
2313 while (c != NULL) {
2314 i++;
2315 log (TMP_FILE, "%s %s %d %d %s %s\n",
2316 c->chan, c->uh, c->level, c->num_join, c->pass, c->greetz);
2317 c = c->next;
2318 }
2319 rename (TMP_FILE, HELPER_LIST);
2320 }
2321
2322 void
datasearch(const char * nick,char * topic,char * target)2323 datasearch (const char *nick, char *topic, char *target)
2324 {
2325 FILE *fp;
2326 long i = 0, FOUND = 0, x = 0;
2327 char b[STRING_LONG], *dorf, *subj, *ptr2, DATA[STRING_SHORT] = "";
2328 if (strlen (topic) > MAX_TOPIC_SIZE)
2329 topic[MAX_TOPIC_SIZE] = '\0';
2330 strlwr (topic);
2331 if ((fp = fopen (URL2, "r")) == NULL) {
2332 L003 (nick, URL2);
2333 R;
2334 }
2335 while (fgets (b, STRING_LONG, fp)) {
2336 x++;
2337 stripline (b);
2338 strlwr (b);
2339 subj = strtok (b, " ");
2340 dorf = strtok (NULL, "");
2341 ptr2 = strstr (dorf, topic);
2342 if (ptr2 != NULL) {
2343 i++;
2344 FOUND = 1;
2345 sprintf (DATA, "%s %s", DATA, subj);
2346 if (strlen (DATA) >= MAX_SEARCH_LENGTH)
2347 break;
2348 }
2349 }
2350 fclose (fp);
2351 if (FOUND == 0) {
2352 L021 (target, NO_TOPIC, topic, x);
2353 }
2354 else if (i > 19) {
2355 L022 (target, i, DATA);
2356 }
2357 else if (i == 1) {
2358 L023 (target, nick, DATA);
2359 }
2360 else
2361 L024 (target, i, nick, DATA);
2362 }
2363
2364 /**
2365 * 6/23/00 Dan:
2366 * - All variables now initialized when declared
2367 * - Altered variable types to reflect usage
2368 */
2369 void
info(const char * source,char * target)2370 info (const char *source, char *target)
2371 {
2372 FILE *fp = 0;
2373 clock_t starttime = 0;
2374 char b[STRING_LONG] = {
2375 0
2376 };
2377 size_t topics = 0, dup = 0;
2378 time_t t2time = 0, c_uptime = 0;
2379 #ifdef FIND_DUPS
2380 char *ptr = 0, *subj = 0;
2381 size_t last = 0, last2 = 0;
2382 #endif
2383 t2time = time (NULL);
2384 unlink (TMP_URL);
2385 starttime = clock ();
2386 fp = fopen (URL2, "r");
2387 if (NULL == fp) {
2388 L003 (source, URL2);
2389 R;
2390 }
2391 while (fgets (b, STRING_LONG, fp)) {
2392 topics++;
2393 #ifdef FIND_DUPS
2394 stripline (b);
2395 subj = strtok (b, " ");
2396 ptr = strtok (NULL, "");
2397 strlwr (subj);
2398 if (stricmp (last, subj) == 0) {
2399 dup++;
2400 #ifdef SAVE_DUPS
2401 log (BACKUP_DUP, "%s %s\n", subj, ptr);
2402 #endif
2403 }
2404 else {
2405 log (TMP_URL, "%s %s\n", subj, ptr);
2406 }
2407 strncpy (last2, subj, sizeof(last2));
2408 last = last2;
2409 #endif
2410 }
2411
2412 fclose (fp);
2413 rename (TMP_URL, URL2);
2414 #ifdef FIND_DUPS
2415 if (dup > 0) {
2416 L025 (target, dup);
2417 }
2418 #endif
2419 c_uptime = time (NULL) - uptime;
2420 topics -= dup;
2421 if (c_uptime > 86400) {
2422 L026 (target,
2423 dbVersion,
2424 topics,
2425 c_uptime / 86400,
2426 (c_uptime / 86400 ==
2427 1) ? "" : "s",
2428 (c_uptime / 3600) % 24,
2429 (c_uptime / 60) % 60, QUESTIONS,
2430 ADDITIONS, DELETIONS,
2431 (double) (clock () -
2432 starttime) /
2433 CLOCKS_PER_SEC,
2434 (((double)
2435 (clock () - starttime) / CLOCKS_PER_SEC) ==
2436 1) ? "" : "s");
2437 }
2438 else if (c_uptime > 3600) {
2439 L027 (target,
2440 dbVersion,
2441 topics,
2442 c_uptime / 3600,
2443 c_uptime / 3600 == 1 ? "" : "s",
2444 (c_uptime / 60) % 60,
2445 (c_uptime / 60) % 60 ==
2446 1 ? "" : "s", QUESTIONS,
2447 ADDITIONS, DELETIONS,
2448 (double) (clock () -
2449 starttime) /
2450 CLOCKS_PER_SEC,
2451 (((double)
2452 (clock () - starttime) / CLOCKS_PER_SEC) ==
2453 1) ? "" : "s");
2454 }
2455 else {
2456 L028 (target,
2457 dbVersion,
2458 topics,
2459 c_uptime / 60,
2460 c_uptime / 60 == 1 ? "" : "s",
2461 c_uptime % 60,
2462 c_uptime % 60 == 1 ? "" : "s",
2463 QUESTIONS, ADDITIONS, DELETIONS,
2464 (double) (clock () - starttime) / CLOCKS_PER_SEC, (((double)
2465
2466 (clock
2467 () -
2468 starttime)
2469 /
2470 CLOCKS_PER_SEC)
2471 ==
2472 1) ? "" :
2473 "s");
2474 }
2475 }
2476
2477 int
check_existing_url(const char * source,char * topic,char * target)2478 check_existing_url (const char *source, char *topic, char *target)
2479 {
2480 FILE *fp;
2481 char b[STRING_LONG], *subj;
2482 if ((fp = fopen (URL2, "r")) == NULL) {
2483 L003 (source, URL2);
2484 R 0;
2485 }
2486 while (fgets (b, STRING_LONG, fp)) {
2487 stripline (b);
2488 subj = strtok (b, " ");
2489 if (stricmp (subj, topic) == 0) {
2490 fclose (fp);
2491 R 1;
2492 }
2493 }
2494 fclose (fp);
2495 R 0;
2496 }
2497
2498 void
find_url(const char * nick,char * topic,char * target)2499 find_url (const char *nick, char *topic, char *target)
2500 {
2501 FILE *fp;
2502 long i = 0, FOUND = 0, x = 0;
2503 char b[STRING_LONG], *subj, *ptr2, DATA[STRING_SHORT] = "";
2504 if (strlen (topic) > MAX_TOPIC_SIZE)
2505 topic[MAX_TOPIC_SIZE] = '\0';
2506 strlwr (topic);
2507 if ((fp = fopen (URL2, "r")) == NULL) {
2508 L003 (nick, URL2);
2509 R;
2510 }
2511 while (fgets (b, STRING_LONG, fp)) {
2512 x++;
2513 stripline (b);
2514 subj = strtok (b, " ");
2515 strlwr (subj);
2516 ptr2 = strstr (subj, topic);
2517 if (ptr2 != NULL) {
2518 i++;
2519 FOUND = 1;
2520 sprintf (DATA, "%s %s", DATA, subj);
2521 if (strlen (DATA) >= MAX_SEARCH_LENGTH)
2522 break;
2523 }
2524 }
2525 fclose (fp);
2526 if (FOUND == 0) {
2527 L021 (target, NO_TOPIC, topic, x);
2528 }
2529 else if (i > 19) {
2530 L022 (target, i, DATA);
2531 }
2532 else if (i == 1) {
2533 L023 (target, nick, DATA);
2534 }
2535 else
2536 L024 (target, i, nick, DATA);
2537 }
2538
2539 void
display_url(char * target,char * nick,char * topic)2540 display_url (char *target, char *nick, char *topic)
2541 {
2542 FILE *fp;
2543 long x = 0;
2544 char b[STRING_LONG], *subj, *ptr;
2545 strlwr (topic);
2546 if ((fp = fopen (URL2, "r")) == NULL) {
2547 R;
2548 }
2549 while (fgets (b, STRING_LONG, fp)) {
2550 x++;
2551 stripline (b);
2552 subj = strtok (b, " ");
2553 ptr = strtok (NULL, "");
2554 if (stricmp (subj, topic) == 0 || !match_wild (subj, topic) == 0) {
2555 QUESTIONS++;
2556 S ("PRIVMSG %s :Raw data for %s is: %s\n", target, topic, ptr);
2557 fclose (fp);
2558 R;
2559 } /* Subject match */
2560 }
2561 fclose (fp);
2562 S
2563 ("PRIVMSG %s :%s, I do not know of any topic named %s\n",
2564 target, nick, topic);}
2565
2566 void
delete_url(const char * nick,char * topic,char * target)2567 delete_url (const char *nick, char *topic, char *target)
2568 {
2569 FILE *fp;
2570 long i = 0, FOUND = 0;
2571 char b[STRING_LONG], *subj, *ptr, DATA[STRING_SHORT] = "";
2572 if (*topic == '~') {
2573 topic++;
2574 if (topic != NULL)
2575 strlwr (topic);
2576 #ifdef WIN32
2577 sprintf (DATA,"dat/%s.rdb", topic);
2578 #else
2579 snprintf (DATA,sizeof(DATA), "dat/%s.rdb", topic);
2580 #endif
2581 if (strspn (topic, LEGAL_TEXT) != strlen (topic)) {
2582 S
2583 ("PRIVMSG %s :%s, rdb files are made up of letters and or numbers, no other text is accepted.\n",
2584 target, nick);
2585 R;
2586 }
2587
2588 if ((fp = fopen (DATA, "r")) == NULL) {
2589 S
2590 ("PRIVMSG %s :%s, %s.rdb does not exist.\n",
2591 target, nick, topic); R;}
2592 fclose (fp);
2593 unlink (DATA);
2594 S ("PRIVMSG %s :I have unlinked %s.\n", target, DATA);
2595 R;
2596 }
2597
2598 if ((fp = fopen (URL2, "r")) == NULL) {
2599 L003 (nick, URL2);
2600 R;
2601 }
2602 unlink (TMP_URL);
2603 while (fgets (b, STRING_LONG, fp)) {
2604 stripline (b);
2605 subj = strtok (b, " ");
2606 ptr = strtok (NULL, "");
2607 i++;
2608 if (stricmp (subj, topic) == 0) {
2609 FOUND = 1;
2610 DELETIONS++;
2611 L029 (target, nick, i, topic);
2612 }
2613 else if (strstr (subj, " ") == NULL)
2614 log (TMP_URL, "%s %s\n", subj, ptr);
2615 }
2616 fclose (fp);
2617 rename (TMP_URL, URL2);
2618 if (FOUND == 0)
2619 L030 (target, nick, topic);
2620 }
2621
2622 void
chanserv(char * source,char * target,char * buf)2623 chanserv (char *source, char *target, char *buf)
2624 {
2625 char *cmd, *s, *s2, *s3, *s4, *s5, *ptr3, temp[1024], *userhost;
2626 long sn2 = 0, sn = 0, i = 0, unixtime = 0;
2627 #ifdef RANDOM_STUFF
2628 if (stricmp (target, CHAN) == 0)
2629 Rand_Idle = 0;
2630 #endif
2631 stripline (buf);
2632 stripline (source);
2633 if (buf == NULL || target == NULL || source == NULL)
2634 R;
2635 cmd = strtok (buf, " ");
2636 if (cmd == NULL)
2637 R;
2638 if (*cmd == ':')
2639 cmd++;
2640 if ((userhost = strchr (source, '!')) != NULL) {
2641 *userhost++ = '\0';
2642 }
2643 /* ------ commands that require a privmsg ------ */
2644 if (*target != '#' && *target != '&' && *target != '+') {
2645 if (stricmp (cmd, "PASS") == 0
2646 || stricmp (cmd, "PASSWORD") == 0
2647 || stricmp (cmd, "PASSWD") == 0) {
2648 s = strtok (NULL, " ");
2649 s2 = strtok (NULL, " ");
2650 if (s == NULL || s2 == NULL) {
2651 L031 (source, Mynick);
2652 R;
2653 }
2654 if (strlen (s2) > 25)
2655 s2[25] = '\0';
2656 set_pass (source, userhost, s, s2);
2657 R;
2658 }
2659 else if (stricmp (cmd, "RAW") == 0) {
2660 if (check_access (userhost, target, 0, source) >= 3) {
2661 s = strtok (NULL, "");
2662 if (s != NULL)
2663 S ("%s\n", s);
2664 }
2665 }
2666 else if (stricmp (cmd, "ADDUSER") == 0) {
2667 if (check_access (userhost, "#*", 0, source)
2668 >= 3) {
2669 s4 = strtok (NULL, " ");
2670 s = strtok (NULL, " ");
2671 s2 = strtok (NULL, " ");
2672 s5 = strtok (NULL, " ");
2673 if (s == NULL || s4 == NULL || s2 == NULL || s5 == NULL) {
2674 L055 (source);
2675 R;
2676 }
2677 sn = atoi (s2);
2678 if (sn > 10 || sn <= 0)
2679 R;
2680 if (strlen (s) < 7)
2681 R;
2682 L056 (*CMDCHAR);
2683 add_helper (s4, s, sn, 0, temp, s5);
2684 L057 (source, s, sn);
2685 save_changes ();
2686 }
2687 }
2688 else if (stricmp (cmd, "DIE") == 0 || stricmp (cmd, "QUIT") == 0) {
2689 s = strtok (NULL, "");
2690 if (check_access (userhost, target, 0, source) >= 3) {
2691 if (s == NULL) {
2692 L032 (source);
2693 }
2694 else
2695 Snow ("QUIT :K\2\2illed (%s (%s))\n", source, s);
2696 db_sleep (1);
2697 #ifdef WIN32
2698 printf ("\n\nGood-bye! %s (c) Jason Hamilton\n\n", dbVersion);
2699 uptime = time (NULL) - uptime;
2700 printf
2701 ("Time elapsed: %d hour%s, %d min%s\n\n",
2702 uptime / 3600,
2703 uptime / 3600 == 1 ? "" : "s",
2704 (uptime / 60) % 60, (uptime / 60) % 60 == 1 ? "" : "s");
2705 db_sleep (5);
2706 #endif
2707 exit (0);
2708 }
2709 #if CTCP == 1
2710 }
2711 else if (stricmp (cmd, "\1VERSION\1") == 0) {
2712 if (cf (userhost, source, target))
2713 R;
2714 if (cf (userhost, source, target))
2715 R;
2716 S ("NOTICE %s :\1VERSION %s\1\n", source, VERSION_REPLY);
2717 }
2718 else if (stricmp (cmd, "\1PING") == 0) {
2719 if (cf (userhost, source, target))
2720 R;
2721 if (cf (userhost, source, target))
2722 R;
2723 s2 = strtok (NULL, "");
2724 if (s2 != NULL) {
2725 if (strlen (s2) > 21)
2726 s2[21] = '\0';
2727 S ("NOTICE %s :\1PING %s\n", source, s2);
2728 }
2729 #endif
2730 }
2731 else if (stricmp (cmd, "LOGIN") == 0) {
2732 s = strtok (NULL, " ");
2733 if (s == NULL)
2734 R;
2735 do_login (source, s);
2736 }
2737 R;
2738 }
2739 add_user (target, source, userhost, 0); /* Unidle */
2740 /* ------ Commands that require a CMDCHAR to activate ------ */
2741 if (*cmd == *CMDCHAR) {
2742 if (Sleep_Toggle == 1)
2743 R;
2744 cmd++;
2745 if (cf (userhost, source, target))
2746 R;
2747 if (stricmp (cmd, "USERLIST") == 0
2748 || stricmp (cmd, "HLIST") == 0
2749 || stricmp (cmd, "ACCESS") == 0) {
2750 if (check_access (userhost, target, 0, source) == 0)
2751 R;
2752 s = strtok (NULL, " ");
2753 if (s != NULL) {
2754 show_helper_list (source, atoi (s));
2755 }
2756 else
2757 show_helper_list (source, 0);
2758 }
2759 else if (stricmp (cmd, "BANLIST") == 0) {
2760 if (check_access (userhost, target, 0, source) == 0)
2761 R;
2762 show_banlist (source);
2763 }
2764 else
2765 if (stricmp (cmd, "LANG") == 0
2766 || stricmp (cmd, "LANGUAGE") == 0) {
2767 S ("PRIVMSG %s :%s, %s\n", target, source, I_SPEAK);
2768 }
2769 else if (stricmp (cmd, "CHANINFO") == 0) {
2770 show_chaninfo (source, target);
2771 }
2772 else if (stricmp (cmd, "IDLE") == 0) {
2773 s2 = strtok (NULL, " ");
2774 if (s2 == NULL)
2775 R;
2776 if (stricmp (s2, source) == 0) {
2777 S ("PRIVMSG %s :%s, don't be lame.\n", target, source);
2778 R;
2779 }
2780 unixtime = return_useridle (target, s2, 0);
2781 if (unixtime == 0) {
2782 S
2783 ("PRIVMSG %s :%s, I do not see %s in %s.\n",
2784 target, source, s2, target); return;
2785 }
2786 unixtime = time (NULL) - unixtime;
2787 if (unixtime > 86400)
2788 S
2789 ("PRIVMSG %s :%s, %s has been idle %d day%s, %02d:%02d\n",
2790 target, source, s2, unixtime / 86400,
2791 (unixtime / 86400 == 1) ? "" : "s",
2792 (unixtime / 3600) % 24, (unixtime / 60) % 60);
2793 else if (unixtime > 3600)
2794 S
2795 ("PRIVMSG %s :%s, %s has been idle %d hour%s, %d min%s\n",
2796 target, source, s2, unixtime / 3600,
2797 unixtime / 3600 == 1 ? "" : "s",
2798 (unixtime / 60) % 60,
2799 (unixtime / 60) % 60 == 1 ? "" : "s");
2800 else
2801 S ("PRIVMSG %s :%s, %s has been idle %d minute%s, %d sec%s\n",
2802 target, source, s2, unixtime / 60,
2803 unixtime / 60 == 1 ? "" : "s", unixtime % 60,
2804 unixtime % 60 == 1 ? "" : "s");
2805 }
2806 else if (stricmp (cmd, "N") == 0 || stricmp (cmd, "NICK") == 0) {
2807 if (check_access (userhost, target, 0, source) >= 3) {
2808 s = strtok (NULL, " ");
2809 if (s == NULL) {
2810 L036 (source);
2811 R;
2812 }
2813 strncpy (Mynick, s, sizeof(Mynick));
2814 #ifdef WIN32
2815 sprintf (NICK_COMMA,"%s,", Mynick);
2816 sprintf (COLON_NICK,"%s:", Mynick);
2817 sprintf (BCOLON_NICK,"%s\2:\2", Mynick);
2818 #else
2819 snprintf (NICK_COMMA,sizeof(NICK_COMMA), "%s,", Mynick);
2820 snprintf (COLON_NICK,sizeof(COLON_NICK), "%s:", Mynick);
2821 snprintf (BCOLON_NICK,sizeof(BCOLON_NICK), "%s\2:\2", Mynick);
2822 #endif
2823 L037 (source, Mynick);
2824 S ("NICK %s\n", Mynick);
2825 }
2826 else
2827 L038 (source, source);
2828 }
2829 else
2830 if (stricmp (cmd, "L") == 0
2831 || stricmp (cmd, "PART") == 0
2832 || stricmp (cmd, "LEAVE") == 0 || stricmp (cmd, "P") == 0) {
2833 if (check_access (userhost, target, 0, source) >= 2) {
2834 s = strtok (NULL, "");
2835 if (s == NULL) {
2836 S ("PART %s\n", target);
2837 }
2838 else {
2839 S ("PART %s\n", s);
2840 L039 (target, s);
2841 }
2842 }
2843 }
2844 else if (stricmp (cmd, "VARIABLES") == 0) {
2845 S ("PRIVMSG %s :%s, %s\n", target, source, myVariables);
2846 }
2847 else if (stricmp (cmd, "JOIN") == 0 || stricmp (cmd, "J") == 0) {
2848 if (check_access (userhost, target, 0, source) >= 2) {
2849 s = strtok (NULL, "");
2850 if (s == NULL) {
2851 S ("JOIN %s\n", target);
2852 }
2853 else {
2854 S ("JOIN %s\n", s);
2855 L040 (target, s);
2856 }
2857 }
2858 #if DO_CHANBOT_CRAP == 1
2859 }
2860 else if (stricmp (cmd, "OP") == 0) {
2861 if (check_access (userhost, target, 0, source) >= 2) {
2862 s = strtok (NULL, "");
2863 if (s == NULL) {
2864 S ("PRIVMSG %s :Specify a nick!\n", target);
2865 return;
2866 }
2867 else {
2868 S ("MODE %s +oooooo %s\n", target, s);
2869 }
2870 }
2871 }
2872 else if (stricmp (cmd, "DEOP") == 0) {
2873 if (check_access (userhost, target, 0, source) >= 2) {
2874 s = strtok (NULL, "");
2875 if (s == NULL) {
2876 S ("PRIVMSG %s :Specify a nick!\n", target);
2877 return;
2878 }
2879 else {
2880 S ("MODE %s -oooooo %s\n", target, s);
2881 }
2882 }
2883 }
2884 else if (stricmp (cmd, "DOWN") == 0) {
2885 if (check_access (userhost, target, 0, source) >= 2)
2886 S ("MODE %s -o %s\n", target, source);
2887 }
2888 else if (stricmp (cmd, "UP") == 0) {
2889 if (check_access (userhost, target, 0, source) >= 2)
2890 S ("MODE %s +o %s\n", target, source);
2891 }
2892 else
2893 if (
2894 (stricmp (cmd, "KICK") == 0
2895 || stricmp (cmd, "WACK") == 0
2896 || stricmp (cmd, "K") == 0 || stricmp (cmd, "NAIL") == 0)) {
2897 if (check_access (userhost, target, 0, source) >= 2) {
2898 s = strtok (NULL, " ");
2899 if (s == NULL) {
2900 S ("PRIVMSG %s :Specify a nick/chan!\n", target);
2901 return;
2902 }
2903 else {
2904 if (*s != '#' && *s != '&') {
2905 s2 = strtok (NULL, "");
2906 if (s2 == NULL) {
2907 if (stricmp (s, Mynick) == 0) {
2908 S ("KICK %s %s :hah! As *IF*\n", target, source);
2909 }
2910 else
2911 S ("KICK %s %s :\2%s\2'ed: %s\n",
2912 target, s, cmd, DEFAULT_KICK);}
2913 else if (stricmp (s, Mynick) == 0) {
2914 S ("KICK %s %s :%s\n", target, s, s2);
2915 }
2916 else
2917 S ("KICK %s %s :\2%s\2'ed: %s\n", target, s, cmd, s2);
2918 }
2919 else {
2920 s2 = strtok (NULL, " ");
2921 if (s2 == NULL) {
2922 S
2923 ("NOTICE %s :You must specify a nick to kick from %s!\n",
2924 source, s);
2925 }
2926 else {
2927 s3 = strtok (NULL, "");
2928 if (s3 == NULL) {
2929 if (stricmp (s2, Mynick) == 0) {
2930 S ("KICK %s %s :hah! As *IF*\n", s, source);
2931 }
2932 else
2933 S ("KICK %s %s :\2%s\2ed: %s\n", s, s2,
2934 cmd, DEFAULT_KICK);}
2935 else {
2936
2937 if (stricmp (s2, Mynick) == 0) {
2938 S ("KICK %s %s :hah! As *IF* (%s)\n", s, source);
2939 }
2940 else
2941 S ("KICK %s %s :\2%s\2ed: %s\n", s, s2, cmd, s3);
2942 }
2943 }
2944 }
2945 }
2946 }
2947 #endif
2948 }
2949 else if (stricmp (cmd, "CYC") == 0 || stricmp (cmd, "CYCLE") == 0) {
2950 if (check_access (userhost, target, 0, source) >= 2) {
2951 s = strtok (NULL, "");
2952 if (s == NULL) {
2953 S ("PART %s\n", target);
2954 S ("JOIN %s\n", target);
2955 }
2956 else {
2957 S ("PART %s\n", s);
2958 S ("JOIN %s\n", s);
2959 S ("PRIVMSG %s :Cycling %s\n", target, s);
2960 }
2961 }
2962 }
2963 else if (stricmp (cmd, "DIE") == 0 || stricmp (cmd, "QUIT") == 0) {
2964 s = strtok (NULL, "");
2965 if (check_access (userhost, target, 0, source) >= 3) {
2966 if (s == NULL) {
2967 L032 (source);
2968 }
2969 else
2970 Snow ("QUIT :K\2\2illed (%s (%s))\n", source, s);
2971 db_sleep (1);
2972 #ifdef WIN32
2973 printf ("\n\nGood-bye! %s (c) Jason Hamilton\n\n", dbVersion);
2974 uptime = time (NULL) - uptime;
2975 printf
2976 ("Time elapsed: %d hour%s, %d min%s\n\n",
2977 uptime / 3600,
2978 uptime / 3600 == 1 ? "" : "s",
2979 (uptime / 60) % 60, (uptime / 60) % 60 == 1 ? "" : "s");
2980 db_sleep (5);
2981 #endif
2982 exit (0);
2983 }
2984 #if DO_CHANBOT_CRAP == 1
2985 }
2986 else
2987 if (stricmp (cmd, "DEV") == 0
2988 || stricmp (cmd, "DV") == 0
2989 || stricmp (cmd, "DEVOICE") == 0
2990 || stricmp (cmd, "DVOICE") == 0) {
2991 if (check_access (userhost, target, 0, source) >= 1) {
2992 s = strtok (NULL, "");
2993 if (s == NULL) {
2994 L041 (target);
2995 R;
2996 }
2997 else
2998 S ("MODE %s -vvvvvvv %s\n", target, s);
2999 }
3000 }
3001 else if (stricmp (cmd, "VOICE") == 0 || stricmp (cmd, "V") == 0) {
3002 if (check_access (userhost, target, 0, source) >= 1) {
3003 s = strtok (NULL, "");
3004 if (s == NULL) {
3005 L041 (target);
3006 R;
3007 }
3008 else
3009 S ("MODE %s +vvvvvvv %s\n", target, s);
3010 }
3011 }
3012 else if (stricmp (cmd, "T") == 0 || stricmp (cmd, "TOPIC") == 0) {
3013 if (check_access (userhost, target, 0, source) >= 2) {
3014 s = strtok (NULL, "");
3015 if (s == NULL) {
3016 S ("TOPIC %s :\n", target);
3017 R;
3018 }
3019 else {
3020 S ("TOPIC %s :%s\n", target, s);
3021 }
3022 }
3023 #endif
3024 }
3025 else if (stricmp (cmd, "JUMP") == 0
3026 || stricmp (cmd, "SERVER") == 0) {
3027 if (check_access (userhost, target, 0, source) >= 3) {
3028 s = strtok (NULL, " ");
3029 if (s == NULL) {
3030 S ("NOTICE %s :Syntax: JUMP <server> [port]\n", source);
3031 R;
3032 }
3033 s2 = strtok (NULL, " ");
3034 if (s2 == NULL) {
3035 sn = 6667;
3036 }
3037 else
3038 sn = atoi (s2);
3039 S ("QUIT :Jumping to %s:%d\n", s, sn);
3040 db_sleep (1);
3041 socketfd = get_connection (s, VHOST, sn);
3042 init_bot ();
3043 }
3044 #if DO_CHANBOT_CRAP == 1
3045 }
3046 else if (stricmp (cmd, "DELBAN") == 0) {
3047 if (check_access (userhost, target, 0, source) >= 3) {
3048 s = strtok (NULL, " ");
3049 if (s == NULL) {
3050 L042 (source);
3051 R;
3052 }
3053 if (del_permban (source, s) == 1)
3054 S ("MODE %s -b %s\n", target, s);
3055 else
3056 L043 (source);
3057 }
3058 #endif
3059 }
3060 else if (stricmp (cmd, "DELUSER") == 0) {
3061 if (check_access (userhost, target, 0, source) >= 3) {
3062 s = strtok (NULL, " ");
3063 if (s == NULL) {
3064 L044 (source);
3065 R;
3066 }
3067 delete_user_ram (source, s);
3068 }
3069 #if DO_CHANBOT_CRAP == 1
3070 }
3071 else if (stricmp (cmd, "TEASEOP") == 0
3072 || stricmp (cmd, "TO") == 0) {
3073 if (check_access (userhost, target, 0, source) >= 2) {
3074 s = strtok (NULL, " ");
3075 if (s == NULL) {
3076 L036 (target);
3077 R;
3078 }
3079 if (stricmp (s, Mynick) == 0) {
3080 L045 (source);
3081 }
3082 else
3083 S
3084 ("MODE %s +o-o+o-o+o-o %s %s %s %s %s %s\n",
3085 target, s, s, s, s, s, s);
3086 }
3087 #endif
3088 #ifndef WIN32
3089 }
3090 else if (stricmp (cmd, "BACKUP") == 0) {
3091 if (check_access (userhost, target, 0, source) >= 3) {
3092 #ifdef WIN32
3093 sprintf (temp,"/bin/cp -rf %s \"%s.bak @ `date`\"\n",
3094 #else
3095 snprintf (temp,sizeof(temp),
3096 "/bin/cp -rf %s \"%s.bak @ `date`\"\n",
3097 #endif
3098 URL2, URL2); system (temp);
3099 L046 (target);
3100 }
3101 #endif
3102 }
3103 else if (stricmp (cmd, "AUTOTOPIC") == 0) {
3104 if (check_access (userhost, target, 0, source) >= 3) {
3105 s = strtok (NULL, "");
3106 if (s == NULL) {
3107 L047 (source, *CMDCHAR);
3108 R;
3109 }
3110 set_autotopic (source, target, s);
3111 }
3112 }
3113 else if (stricmp (cmd, "SETCHAN") == 0) {
3114 if (check_access (userhost, target, 0, source) >= 3) {
3115 s = strtok (NULL, " ");
3116 if (s == NULL) {
3117 L048 (source);
3118 R;
3119 }
3120 strncpy (CHAN, s, sizeof(CHAN));
3121 L049 (source, CHAN);
3122 save_setup ();
3123 }
3124 }
3125 else if (stricmp (cmd, "SETCHAR") == 0) {
3126 if (check_access (userhost, target, 0, source) >= 3) {
3127 s = strtok (NULL, " ");
3128 if (s == NULL) {
3129 L050 (source);
3130 R;
3131 }
3132 *CMDCHAR = *s;
3133 L051 (source, *CMDCHAR);
3134 save_setup ();
3135 }
3136 }
3137 else if (stricmp (cmd, "SETUSER") == 0) {
3138 if (check_access (userhost, target, 0, source) >= 3) {
3139 s = strtok (NULL, " ");
3140 if (s == NULL) {
3141 L052 (source);
3142 R;
3143 }
3144 strncpy (UID, s, sizeof(UID));
3145 L053 (source, UID);
3146 save_setup ();
3147 }
3148 }
3149 else if (stricmp (cmd, "VHOST") == 0) {
3150 if (check_access (userhost, target, 0, source) >= 3) {
3151 s = strtok (NULL, " ");
3152 if (s == NULL) {
3153 L091 (source);
3154 R;
3155 }
3156 strncpy (VHOST, s, sizeof(VHOST));
3157 L092 (source, VHOST);
3158 save_setup ();
3159 }
3160 }
3161 else if (stricmp (cmd, "SETNICK") == 0) {
3162 if (check_access (userhost, target, 0, source) >= 3) {
3163 s = strtok (NULL, " ");
3164 if (s == NULL) {
3165 L054 (source);
3166 R;
3167 }
3168 S ("NICK %s\n", s);
3169 strncpy (s_Mynick, s, sizeof(s_Mynick));
3170 strncpy (Mynick, s, sizeof(Mynick));
3171 #ifdef WIN32
3172 sprintf (NICK_COMMA,"%s,", Mynick);
3173 sprintf (COLON_NICK,"%s:", Mynick);
3174 sprintf (BCOLON_NICK,"%s\2:\2", Mynick);
3175 #else
3176 snprintf (NICK_COMMA,sizeof(NICK_COMMA), "%s,", Mynick);
3177 snprintf (COLON_NICK,sizeof(COLON_NICK), "%s:", Mynick);
3178 snprintf (BCOLON_NICK,sizeof(BCOLON_NICK), "%s\2:\2", Mynick);
3179 #endif
3180 save_setup ();
3181 }
3182 }
3183 else if (stricmp (cmd, "RAW") == 0) {
3184 if (check_access (userhost, target, 0, source) >= 3) {
3185 s = strtok (NULL, "");
3186 if (s != NULL)
3187 S ("%s\n", s);
3188 }
3189 }
3190 else if (stricmp (cmd, "SEEN") == 0 && SeeN == 1) {
3191 s = strtok (NULL, " ");
3192 if (s == NULL) {
3193 count_seen (source, target);
3194 R;
3195 }
3196 if (return_useridle (target, s, 1) == 1) {
3197 S ("PRIVMSG %s :%s is right here in the channel!\n", target,
3198 s);
3199 R;
3200 }
3201 show_seen (s, source, target);
3202 #if STATUS == 1
3203 }
3204 else if (stricmp (cmd, "LUSERS") == 0) {
3205 if (check_access (userhost, target, 0, source) >= 1)
3206 S ("LUSERS\n");
3207 #endif
3208 }
3209 else if (stricmp (cmd, "ADDUSER") == 0) {
3210 if (check_access (userhost, target, 0, source) >= 3) {
3211 s4 = strtok (NULL, " ");
3212 s = strtok (NULL, " ");
3213 s2 = strtok (NULL, " ");
3214 s5 = strtok (NULL, " ");
3215 if (s == NULL || s4 == NULL || s2 == NULL || s5 == NULL) {
3216 L055 (source);
3217 R;
3218 }
3219 sn = atoi (s2);
3220 if (sn > 10 || sn <= 0)
3221 R;
3222 if (strlen (s) < 7)
3223 R;
3224 L056 (*CMDCHAR);
3225 add_helper (s4, s, sn, 0, temp, s5);
3226 L057 (source, s, sn);
3227 save_changes ();
3228 }
3229 #if DO_CHANBOT_CRAP == 1
3230 }
3231 else
3232 if (stricmp (cmd, "PERMBAN") == 0
3233 || stricmp (cmd, "SHITLIST") == 0) {
3234 if (check_access (userhost, target, 0, source) >= 3) {
3235 s = strtok (NULL, " ");
3236 if (s == NULL) {
3237 L058 (source, *CMDCHAR, cmd);
3238 R;
3239 }
3240 s2 = strtok (NULL, "");
3241 if (s2 == NULL)
3242 s2 = "Permbanned!";
3243 add_permban (s, 0, s2);
3244 L059 (source, PERMBAN_counter, s, s2);
3245 save_permbans ();
3246 S ("MODE %s +b %s\n", target, s);
3247 }
3248 #endif
3249 }
3250 else
3251 if (stricmp (cmd, "ALARM") == 0
3252 || stricmp (cmd, "ALARMCLOCK") == 0) {
3253 if (check_access (userhost, target, 0, source) >= 2) {
3254 s = strtok (NULL, " ");
3255 s2 = strtok (NULL, "");
3256 if (s == NULL || s2 == NULL) {
3257 S
3258 ("NOTICE %s :Syntax: <time type: d/h/m><time> <text to say>\n",
3259 source); R;
3260 }
3261 if (strlen (s) < 2) {
3262 S
3263 ("NOTICE %s :Syntax: <time type: d/h/m><time> <text to say>\n",
3264 source); R;
3265 }
3266 if (*s == 'd') {
3267 sn = 86400;
3268 s++;
3269 }
3270 else if (*s == 'h') {
3271 sn = 3600;
3272 s++;
3273 }
3274 else if (*s == 'm') {
3275 sn = 60;
3276 s++;
3277 }
3278 else {
3279 S
3280 ("NOTICE %s :Syntax: <time type: \2d/h/m\2><time> <text to say>\n",
3281 source); R;
3282 }
3283 if (strspn (s, NUMBER_LIST) != strlen (s)) {
3284 S ("NOTICE %s :Time must be a number.\n", source);
3285 R;
3286 }
3287 i = (atoi (s) * sn) + time (NULL);
3288 #ifdef WIN32
3289 sprintf (temp,"%s/%d", DBTIMERS_PATH, (int) i);
3290 #else
3291 snprintf (temp,sizeof(temp), "%s/%d", DBTIMERS_PATH, (int) i);
3292 #endif
3293 log (temp,
3294 "PRIVMSG %s :\2ALARMCLOCK\2 by %s!%s: %s\n",
3295 target, source, userhost, s2);
3296 unixtime = atoi (s) * sn;
3297 if (unixtime > 86400)
3298 S
3299 ("PRIVMSG %s :%s, alarmclock set to go off in %d day%s, %02d:%02d\n",
3300 target, source, unixtime / 86400,
3301 (unixtime / 86400 == 1) ? "" : "s",
3302 (unixtime / 3600) % 24, (unixtime / 60) % 60);
3303 else if (unixtime > 3600)
3304 S
3305 ("PRIVMSG %s :%s, alarmclock set to go off in %d hour%s, %d min%s\n",
3306 target, source, unixtime / 3600,
3307 unixtime / 3600 == 1 ? "" : "s",
3308 (unixtime / 60) % 60,
3309 (unixtime / 60) % 60 == 1 ? "" : "s");
3310 else
3311 S
3312 ("PRIVMSG %s :%s, alarmclock set to go off in %d minute%s, %d sec%s\n",
3313 target, source, unixtime / 60,
3314 unixtime / 60 == 1 ? "" : "s",
3315 unixtime % 60, unixtime % 60 == 1 ? "" : "s");
3316 }
3317 }
3318 else
3319 if (stricmp (cmd, "REPEAT") == 0
3320 || stricmp (cmd, "TIMER") == 0) {
3321 if (check_access (userhost, target, 0, source) >= 3) {
3322 s = strtok (NULL, " ");
3323 s2 = strtok (NULL, " ");
3324 s3 = strtok (NULL, "");
3325 if (s == NULL || s2 == NULL || s3 == NULL) {
3326 L060 (source);
3327 R;
3328 }
3329 sn = atoi (s);
3330 sn2 = atoi (s2);
3331 while (sn > 0) {
3332 S ("%s\n", s3);
3333 sn--;
3334 db_sleep (sn2);
3335 }
3336 }
3337 #ifndef WIN32
3338 }
3339 else
3340 if (stricmp (cmd, "REHASH") == 0
3341 || stricmp (cmd, "RESTART") == 0) {
3342 if (check_access (userhost, target, 0, source) >= 3) {
3343 L062 (dbVersion);
3344 #ifdef WIN32
3345 sprintf (temp,"sleep 2; %s", DARKBOT_BIN);
3346 #else
3347 snprintf (temp,sizeof(temp), "sleep 2; %s", DARKBOT_BIN);
3348 #endif
3349 system (temp);
3350 db_sleep (1);
3351 exit (0);
3352 }
3353 #endif
3354 }
3355 else if (stricmp (cmd, "PING") == 0) {
3356 if (check_access (userhost, target, 0, source) == 0) {
3357 S ("NOTICE %s PONG!\n", source);
3358 }
3359 else
3360 S ("PRIVMSG %s :PONG!\n", target);
3361 }
3362 else if (stricmp (cmd, "HELP") == 0) {
3363 L100 (source, NICK_COMMA, COLON_NICK,
3364 BCOLON_NICK, Mynick, NICK_COMMA, NICK_COMMA);
3365 db_sleep (3);
3366 if (cf (userhost, source, target))
3367 R;
3368 L101 (source, NICK_COMMA, NICK_COMMA, NICK_COMMA);
3369 db_sleep (2);
3370 }
3371 else if (stricmp (cmd, "SETINFO") == 0) {
3372 if (check_access (userhost, target, 0, source) >= 1) {
3373 s = strtok (NULL, "");
3374 if (s == NULL) {
3375 S ("NOTICE %s :%s\n", source, mySetinfo);
3376 R;
3377 }
3378 update_setinfo (userhost, s, source);
3379 save_changes ();
3380 }
3381 }
3382 #if CTCP == 1
3383 }
3384 else if (stricmp (cmd, "\1VERSION\1") == 0) { /* these are #chan
3385 * ctcp's */
3386 if (cf (userhost, source, target))
3387 R;
3388 if (cf (userhost, source, target))
3389 R;
3390 S ("NOTICE %s :\1VERSION %s\1\n", source, VERSION_REPLY);
3391 }
3392 else if (stricmp (cmd, "\1PING") == 0) {
3393 if (cf (userhost, source, target))
3394 R;
3395 if (cf (userhost, source, target))
3396 R;
3397 s2 = strtok (NULL, "");
3398 if (s2 != NULL) {
3399 if (strlen (s2) > 21)
3400 s2[21] = '\0';
3401 S ("NOTICE %s :\1PING %s\n", source, s2);
3402 }
3403 #endif
3404 }
3405 else if (stricmp (cmd, "\2\2DARKBOT") == 0) {
3406 if (Sleep_Toggle == 1)
3407 R;
3408 if (cf (userhost, source, target))
3409 R;
3410 S
3411 ("PRIVMSG %s :%s reporting! My cmdchar is %c\n",
3412 target, dbVersion, *CMDCHAR);}
3413 else
3414 if (stricmp (cmd, NICK_COMMA) == 0
3415 || stricmp (cmd, COLON_NICK) == 0
3416 || stricmp (cmd, BCOLON_NICK) == 0
3417 || stricmp (cmd, Mynick) == 0) {
3418 s = strtok (NULL, " ");
3419 if (s != NULL) {
3420 if (stricmp (s, "WAKEUP") == 0) {
3421 if (Sleep_Toggle == 0)
3422 R;
3423 if (check_access (userhost, target, 0, source) >= SLEEP_LEVEL) {
3424 Sleep_Toggle = 0;
3425 AIL4 = 0;
3426 S ("PRIVMSG %s :%s\n", target, WAKEUP_ACTION);
3427 if (stricmp (sleep_chan, target) != 0)
3428 S ("PRIVMSG %s :%s\n", sleep_chan, WAKEUP_ACTION);
3429 R;
3430 }
3431 }
3432 }
3433 if (Sleep_Toggle == 1)
3434 R;
3435 if (cf (userhost, source, target))
3436 R;
3437 if (s != NULL) {
3438 #ifdef RANDOM_STUFF
3439 if (stricmp (s, "RANDOMSTUFF") == 0
3440 || stricmp (s, "RANDSTUFF") == 0) {
3441 if (check_access (userhost, target, 0, source) >= RAND_LEVEL) {
3442 s2 = strtok (NULL, "");
3443 if (s2 == NULL) {
3444 L064 (target, source);
3445 R;
3446 }
3447 add_randomstuff (source, target, s2);
3448 }
3449 }
3450 else
3451 #endif
3452 if (stricmp (s, "ADD") == 0
3453 || stricmp (s, "REMEMBER") == 0
3454 || stricmp (s, "SAVE") == 0 || stricmp (s, "STORE") == 0) {
3455 #ifdef REQ_ACCESS_ADD
3456 if (check_access (userhost, target, 0, source) >= 1) {
3457 #endif
3458 s2 = strtok (NULL, " ");
3459 if (s2 == NULL) {
3460 L065 (target, source);
3461 R;
3462 }
3463 if (strlen (s2) > MAX_TOPIC_SIZE) {
3464 s2[MAX_TOPIC_SIZE] = '\0';
3465 S
3466 ("PRIVMSG %s :%s, topic is over the limit, and has characters truncated.\n",
3467 target, source);
3468 }
3469 s3 = strtok (NULL, "");
3470 if (s3 == NULL) {
3471 L066 (target, source, s2);
3472 R;
3473 }
3474 if (strlen (s3) > MAX_DATA_SIZE)
3475 s3[MAX_DATA_SIZE] = '\0';
3476 strlwr (s2);
3477 if (*s2 == '~') {
3478 S
3479 ("PRIVMSG %s :%s, rdb files can only be called from the data of a topic, they cannot be used in the topic itself.\n",
3480 target, source);
3481 R;
3482 }
3483 if (check_existing_url (source, s2, target) == 1) {
3484 S ("PRIVMSG %s :%s \37%s\37\n", target, EXISTING_ENTRY,
3485 s2);
3486 R;
3487 }
3488 #ifdef LOG_ADD_DELETES
3489 log (ADD_DELETES,
3490 "[%s] %s!%s ADD %s %s\n", date (), source, userhost,
3491 s2, s3);
3492 #endif
3493 ADDITIONS++;
3494 if (s2[0] == 'i' && s2[1] == 'l' && s2[2] == 'c') {
3495 log (URL2, "%s ([%s] %s!%s): %s\n", s2,
3496 date (), source, userhost, s3);
3497 }
3498 else
3499 log (URL2, "%s %s\n", s2, s3);
3500 L067 (target, source);
3501 #ifdef REQ_ACCESS_ADD
3502 }
3503 #endif
3504 }
3505 else if (stricmp (s, "DATE") == 0 || stricmp (s, "TIME") == 0) {
3506 S ("PRIVMSG %s :%s, %s\n", target, source, date ());
3507 }
3508 else if (stricmp (s, "REPLACE") == 0) {
3509 #ifdef REQ_ACCESS_ADD
3510 if (check_access (userhost, target, 0, source) >= 1) {
3511 #endif
3512 s2 = strtok (NULL, " ");
3513 if (s2 == NULL) {
3514 L068 (target, source);
3515 R;
3516 }
3517 if (strlen (s2) > MAX_TOPIC_SIZE)
3518 s2[MAX_TOPIC_SIZE] = '\0';
3519 s3 = strtok (NULL, "");
3520 if (s3 == NULL) {
3521 L069 (target, source, s2);
3522 R;
3523 }
3524 if (strlen (s3) > MAX_DATA_SIZE)
3525 s3[MAX_DATA_SIZE] = '\0';
3526 strlwr (s2);
3527 if (check_existing_url (source, s2, target) != 1) {
3528 S ("PRIVMSG %s :%s \37%s\37\n", target, NO_ENTRY, s2);
3529 R;
3530 }
3531 delete_url (source, s2, target);
3532 #ifdef LOG_ADD_DELETES
3533 log (ADD_DELETES,
3534 "[%s] %s!%s REPLACE %s %s\n",
3535 date (), source, userhost, s2, s3);
3536 #endif
3537 ADDITIONS++;
3538 log (URL2, "%s %s\n", s2, s3);
3539 L070 (target, source, s2);
3540 #ifdef REQ_ACCESS_ADD
3541 }
3542 #endif
3543 #if DO_CHANBOT_CRAP == 1
3544 }
3545 else if (stricmp (s, "PERMBANS?") == 0) {
3546 L071 (target,
3547 (PERMBAN_counter ==
3548 1) ? "is" : "are",
3549 PERMBAN_counter, (PERMBAN_counter == 1) ? "" : "s");
3550 #endif
3551 #ifdef RANDOM_STUFF
3552 }
3553 else
3554 if (stricmp (s, "RANDOMSTUFF?") == 0
3555 || stricmp (s, "RANDSTUFF?") == 0) {
3556 L073 (target, source, Rand_Stuff);
3557 #endif
3558 }
3559 else if (stricmp (s, "LENGTH") == 0) {
3560 s2 = strtok (NULL, "");
3561 if (s2 == NULL)
3562 R;
3563 L074 (target, source, strlen (s2));
3564 }
3565 else if (stricmp (s, "CHAR") == 0) {
3566 s2 = strtok (NULL, " ");
3567 if (s2 == NULL)
3568 R;
3569 S ("PRIVMSG %s :%s, %c -> %d\n", target, source, s2[0],
3570 s2[0]);
3571 }
3572 else if (stricmp (s, "SEEN") == 0 && SeeN == 1) {
3573 s2 = strtok (NULL, " ");
3574 if (s2 == NULL)
3575 R;
3576 show_seen (s2, source, target);
3577 }
3578 else if (stricmp (s, "SENDQ?") == 0 || stricmp (s, "QUE?") == 0) {
3579 L075 (target, source,
3580 get_sendq_count (2),
3581 (get_sendq_count (2) == 1) ? "" : "s");
3582 }
3583 else if (stricmp (s, "JOINS?") == 0) {
3584 L076 (target, JOINs);
3585 }
3586 else if (stricmp (s, "LOCATION?") == 0) {
3587 L077 (target, (snr == 1) ? "is" : "are",
3588 snr, (snr == 1) ? "" : "s", spr);
3589 }
3590 else if (stricmp (s, "CMDCHAR?") == 0) {
3591 L078 (target, source, *CMDCHAR);
3592 }
3593 else
3594 if (stricmp (s, "DATASEARCH") == 0
3595 || stricmp (s, "DSEARCH") == 0 ||
3596 stricmp (s, "DFIND") == 0) {
3597 s2 = strtok (NULL, "");
3598 if (s2 == NULL) {
3599 L079 (target, s, source);
3600 R;
3601 }
3602 datasearch (source, s2, target);
3603 }
3604 else
3605 if (stricmp (s, "SEARCH") == 0
3606 || stricmp (s, "LOOK") == 0 || stricmp (s, "FIND") == 0) {
3607 s2 = strtok (NULL, " ");
3608 if (s2 == NULL) {
3609 if (stricmp (s, "FIND") == 0) {
3610 S ("PRIVMSG %s :%s, %s?\n", target, TRY_FIND, source);
3611 }
3612 else
3613 L079 (target, s, source);
3614 R;
3615 }
3616 find_url (source, s2, target);
3617 }
3618 else if (stricmp (s, "INFO2") == 0) {
3619 show_info2 (target, source);
3620 }
3621 else if (stricmp (s, "INFO") == 0) {
3622 info (source, target);
3623 #ifdef DO_MATH_STUFF
3624 }
3625 else if (stricmp (s, "CALC") == 0 || stricmp (s, "MATH") == 0) {
3626 s2 = strtok (NULL, "");
3627 if (s2 == NULL)
3628 R;
3629 if (strlen (s2) > 200)
3630 s2[200] = '\0';
3631 do_math (source, target, s2);
3632 #endif
3633 }
3634 else if (stricmp (s, "SLEEP") == 0 || stricmp (s, "HUSH") == 0) {
3635 if (check_access (userhost, target, 0, source) >= SLEEP_LEVEL) {
3636 Sleep_Toggle = 1;
3637 S ("PRIVMSG %s :%s\n", target, GOSLEEP_ACTION);
3638 strncpy (sleep_chan, target, sizeof(sleep_chan));
3639 }
3640 }
3641 else if (stricmp (s, "UNIXTIME") == 0) {
3642 s2 = strtok (NULL, " ");
3643 if (s2 == NULL)
3644 R;
3645 unixtime = atoi (s2) - time (NULL);
3646 if (unixtime > 86400)
3647 S
3648 ("PRIVMSG %s :%s, %d day%s, %02d:%02d\n",
3649 target, source, unixtime / 86400,
3650 (unixtime / 86400 == 1) ? "" : "s",
3651 (unixtime / 3600) % 24, (unixtime / 60) % 60);
3652 else if (unixtime > 3600)
3653 S
3654 ("PRIVMSG %s :%s, %d hour%s, %d min%s\n",
3655 target, source, unixtime / 3600,
3656 unixtime / 3600 == 1 ? "" : "s",
3657 (unixtime / 60) % 60,
3658 (unixtime / 60) % 60 == 1 ? "" : "s");
3659 else
3660 S
3661 ("PRIVMSG %s :%s, %d minute%s, %d sec%s\n",
3662 target, source, unixtime / 60,
3663 unixtime / 60 == 1 ? "" : "s",
3664 unixtime % 60, unixtime % 60 == 1 ? "" : "s");
3665 }
3666 else if (stricmp (s, "CPU?") == 0) {
3667 getrusage (RUSAGE_SELF, &r_usage);
3668 S
3669 ("PRIVMSG %s :CPU usage: %ld.%06ld, System = %ld.%06ld\n",
3670 target, r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec);
3671 }
3672 else if (stricmp (s, "DISPLAY") == 0) {
3673 s2 = strtok (NULL, " ");
3674 if (s2 == NULL)
3675 R;
3676 display_url (target, source, s2);
3677 #ifndef WIN32
3678 }
3679 else if (stricmp (s, "UPTIME") == 0) {
3680 snprintf (temp,sizeof(temp), "uptime\n");
3681 S ("PRIVMSG %s :Uptime: %s\n", target, run_program (temp));
3682 }
3683 else if (stricmp (s, "OS") == 0) {
3684 snprintf (temp,sizeof(temp), "uname\n");
3685 S ("PRIVMSG %s :I am running %s\n", target,
3686 run_program (temp));
3687 }
3688 else if (stricmp (s, "MEM") == 0 || stricmp (s, "RAM") == 0) {
3689 snprintf (temp, sizeof(temp),"ps -ux | grep %s\n", DARKBOT_BIN);
3690 S ("PRIVMSG %s :ps: %s\n", target, run_program (temp));
3691 }
3692 else if (stricmp (s, "RDB") == 0) {
3693 s2 = strtok (NULL, "");
3694 if (s2 == NULL) {
3695 snprintf (temp,sizeof(temp), "ls dat/*.rdb | wc\n");
3696 S ("PRIVMSG %s :RDB: %s\n", target, run_program (temp));
3697 }
3698 else {
3699 if (strspn (s2, SAFE_LIST) != strlen (s2)) {
3700 S
3701 ("PRIVMSG %s :%s, rdb files are made up of letters and or numbers, no other text is accepted.\n",
3702 target, source);
3703 R;
3704 }
3705 snprintf (temp,sizeof(temp),"ls -la dat/*.rdb | grep %s | tail 3\n", s2);
3706 S ("PRIVMSG %s :%s\n", target, run_program (temp));
3707 }
3708 #endif
3709 }
3710 else
3711 if (stricmp (s, "DELETE") == 0
3712 || stricmp (s, "REMOVE") == 0
3713 || stricmp (s, "FORGET") == 0 || stricmp (s, "DEL") == 0) {
3714 #ifdef REQ_ACCESS_DEL
3715 if (check_access (userhost, target, 0, source) >= 1) {
3716 #endif
3717 s2 = strtok (NULL, " ");
3718 if (s2 == NULL) {
3719 S ("PRIVMSG %s :%s what, %s?\n", target, s, source);
3720 R;
3721 }
3722 if (strlen (s2) > MAX_TOPIC_SIZE)
3723 s2[MAX_TOPIC_SIZE] = '\0';
3724 #ifdef LOG_ADD_DELETES
3725 log (ADD_DELETES, "[%s] %s!%s DEL %s\n",
3726 date (), source, userhost, s2);
3727 #endif
3728 if (*s2 == '~') { /* need level 2 to delete .rdb files */
3729 if (check_access (userhost, target, 0, source) >= 2) {
3730 delete_url (source, s2, target);
3731 }
3732 R;
3733 }
3734 delete_url (source, s2, target);
3735 #ifdef REQ_ACCESS_DEL
3736 }
3737 #endif
3738 }
3739 else if (stricmp (s, "TELL") == 0) {
3740 s2 = strtok (NULL, " ");
3741 if (s2 == NULL) {
3742 L085 (target, source);
3743 R;
3744 }
3745 s3 = strtok (NULL, " ");
3746 if (s3 == NULL) {
3747 L083 (target, source, s2);
3748 R;
3749 }
3750 if (stricmp (s3, Mynick) == 0)
3751 R; /* don't bother telling
3752 * myself about stuff */
3753 if (stricmp (s3, "ABOUT") == 0) {
3754 s4 = strtok (NULL, " ");
3755 if (s4 == NULL) {
3756 L084 (target, source, s2);
3757 R;
3758 }
3759 strlwr (s4);
3760 show_url (s2, get_multiword_topic (s4), target, 1, 0,
3761 userhost, 1);
3762 }
3763 else {
3764 strlwr (s3);
3765 show_url (s2, get_multiword_topic (s3), target, 1, 0,
3766 userhost, 1);
3767 }
3768 }
3769 else
3770 if (stricmp (s, "WHERE") == 0
3771 || stricmp (s, "WHO") == 0 || stricmp (s, "WHAT") == 0) {
3772 s2 = strtok (NULL, " ");
3773 if (s2 == NULL) {
3774 L086 (target, source);
3775 R;
3776 }
3777 s3 = strtok (NULL, " ");
3778 if (s3 == NULL)
3779 R;
3780 strlwr (s3);
3781 ptr3 = strchr (s3, '?');
3782 if (ptr3 != NULL)
3783 memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
3784 ptr3 = strchr (s3, '!');
3785 if (ptr3 != NULL)
3786 memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
3787 if (stricmp (s3, "A") == 0 || stricmp (s3, "AN") == 0) {
3788 s4 = strtok (NULL, " ");
3789 if (s4 == NULL) {
3790 L087 (target, s, s2, s3, *CMDCHAR);
3791 R;
3792 }
3793 show_url (source,
3794 get_multiword_topic (s4), target, 1, 0, userhost,
3795 0);
3796 }
3797 else
3798 show_url (source,
3799 get_multiword_topic (s3), target, 1, 0, userhost,
3800 0);
3801 }
3802 else
3803 show_url (source,
3804 get_multiword_topic (s), target, 1, 0, userhost, 0);
3805 }
3806 else
3807 S ("PRIVMSG %s :%s\n", target, WHUT);
3808 #if GENERAL_QUESTIONS == 1
3809 }
3810 else {
3811 if (Sleep_Toggle == 1)
3812 R;
3813 show_url (source, get_multiword_topic (cmd), target, 0, 1,
3814 userhost, 0);
3815 #endif
3816 i = 0;
3817 }
3818 }
3819
3820 void
gs26()3821 gs26 ()
3822 {
3823 long i = 0;
3824 struct sl124 *c;
3825 c = sh124;
3826 spr++;
3827 if (spr > snr)
3828 spr = 1;
3829 while (c != NULL) {
3830 i++;
3831 if (i == spr) {
3832 strncpy (BS, c->name, sizeof(BS));
3833 BP = c->port;
3834 }
3835 c = c->next;
3836 }
3837 }
3838
3839 void
add_s25(char * server,long port)3840 add_s25 (char *server, long port)
3841 {
3842 struct sl124 *n;
3843 n = (struct sl124 *)
3844 malloc (sizeof (struct sl124));
3845 if (n == NULL) {
3846 log ("error.log", "AHHH! No ram left! in add_s25!\n");
3847 R;
3848 }
3849 memset (n, 0, sizeof (struct sl124));
3850 snr++;
3851 if (n != NULL) {
3852 strncpy (n->name, server, sizeof(n->name));
3853 n->port = port;
3854 n->next = sh124;
3855 sh124 = n;
3856 }
3857 }
3858
3859 void
show_url(char * nick,char * topic,char * target,long donno,long floodpro,char * uh,long no_pipe)3860 show_url (char *nick, char *topic,
3861 char *target, long donno,
3862 long floodpro, char *uh, long no_pipe)
3863 {
3864 FILE *fp;
3865 long x = 0, length = 0, toggle = 0, A =
3866 0, gotit = 0, D = 0, F = 0, Tog = 0;
3867 char b[STRING_LONG], *subj, *ptr,
3868 temp[STRING_LONG] = "", Data[STRING_LONG] = "", *ptr8 = "";
3869 char crm1[STRING_LONG], crm2[STRING_LONG], bFirst = 1;
3870
3871 strlwr (topic);
3872
3873 /* removes the question mark */
3874 if ((ptr = strchr (topic, '?')) != NULL)
3875 memmove (ptr, ptr + 1, strlen (ptr + 1) + 1);
3876
3877 if ((fp = fopen (URL2, "r")) == NULL) {
3878 if (donno == 1)
3879 L003 (nick, URL2);
3880 R;
3881 }
3882 while (fgets (b, STRING_LONG, fp)) {
3883 x++;
3884 stripline (b);
3885 subj = strtok (b, " ");
3886 if (subj == NULL)
3887 continue;
3888 ptr = strtok (NULL, "");
3889 if (ptr == NULL)
3890 continue;
3891 if (stricmp (subj, topic) == 0 || !match_wild (subj, topic) == 0) {
3892 QUESTIONS++;
3893 if (floodpro == 1)
3894 if (cf (uh, nick, nick)) {
3895 fclose (fp);
3896 R;
3897 }
3898 gotit = 1;
3899 if (*ptr == '+') {
3900 ptr++;
3901 A = 1;
3902 }
3903 else if (*ptr == '-') {
3904 if (strstr (nick, "|") != NULL)
3905 R;
3906 if (no_pipe == 1) {
3907 fclose (fp);
3908 R;
3909 }
3910 ptr++;
3911 D = 1;
3912 }
3913 else if (*ptr == '~') {
3914 ptr++;
3915 fclose (fp);
3916 do_randomtopic (target, ptr, nick, topic);
3917 return;
3918 }
3919 length = strlen (ptr);
3920 if (length > 3) {
3921 if (ptr[0] == 'i' && ptr[1] == 'l' && ptr[2] == 'c') {
3922 toggle++;
3923 }
3924 }
3925 while (length > 0) {
3926 length--;
3927 if (Tog == 1) {
3928 Tog = 0;
3929 if (ptr[length] == 'N') { /* nick */
3930 toggle++;
3931 #ifdef WIN32
3932 sprintf (temp,"%s%s", nick, Data);
3933 }
3934 else if (ptr[length] == 'C') { /* chan */
3935 toggle++;
3936 sprintf (temp,"%s%s", target, Data);
3937 #else
3938 snprintf (temp,sizeof(temp), "%s%s", nick, Data);
3939 }
3940 else if (ptr[length] == 'C') { /* chan */
3941 toggle++;
3942 snprintf (temp,sizeof(temp), "%s%s", target, Data);
3943 #endif
3944 }
3945 else
3946 if (ptr[length] == '1'
3947 || ptr[length] == '2'
3948 || ptr[length] == '3'
3949 || ptr[length] == '4'
3950 || ptr[length] == '5'
3951 || ptr[length] == '6'
3952 || ptr[length] == '7'
3953 || ptr[length] == '8' || ptr[length] == '9') {
3954 toggle++;
3955 /* The first time around, we just store the topic in a
3956 "safe place" */
3957 if (bFirst == 1) {
3958 strncpy (crm1, topic, sizeof(crm1));
3959 bFirst = 0;
3960 }
3961 /* Each time around, get a new copy from the "safe place." */
3962 strncpy (crm2, crm1, sizeof(crm2));
3963 #ifdef WIN32
3964 sprintf (temp,"%s%s", get_word (ptr[length], crm2),
3965 Data);
3966 }
3967 else if (ptr[length] == 'H') { /* u@h of user */
3968 toggle++;
3969 sprintf (temp,"%s%s", uh, Data);
3970 }
3971 else if (ptr[length] == 'h') { /* u@h (no ident) */
3972 toggle++;
3973 if (*uh == '~') {
3974 *uh++;
3975 }
3976 sprintf (temp,"%s%s", uh, Data);
3977 }
3978 else if (ptr[length] == 'T') { /* time */
3979 toggle++;
3980 sprintf (temp,"%s%s", date (), Data);
3981 }
3982 else if (ptr[length] == 't') { /* unixtime */
3983 toggle++;
3984 sprintf (temp,"%d%s", time (NULL), Data);
3985 }
3986 else if (ptr[length] == 'W') { /* WWW page */
3987 toggle++;
3988 sprintf (temp,"http://darkbot.net%s", Data);
3989 }
3990 else if (ptr[length] == 'S') { /* server */
3991 toggle++;
3992 sprintf (temp,"%s%s", BS, Data);
3993 }
3994 #else
3995 snprintf (temp, sizeof(temp), "%s%s", get_word (ptr[length], crm2),
3996 Data);
3997 }
3998 else if (ptr[length] == 'H') { /* u@h of user */
3999 toggle++;
4000 snprintf (temp, sizeof(temp), "%s%s", uh, Data);
4001 }
4002 else if (ptr[length] == 'h') { /* u@h (no ident) */
4003 toggle++;
4004 if (*uh == '~') {
4005 *uh++;
4006 }
4007 snprintf (temp, sizeof(temp), "%s%s", uh, Data);
4008 }
4009 else if (ptr[length] == 'T') { /* time */
4010 toggle++;
4011 snprintf (temp,sizeof(temp), "%s%s", date (), Data);
4012 }
4013 else if (ptr[length] == 't') { /* unixtime */
4014 toggle++;
4015 snprintf (temp,sizeof(temp), "%d%s", time (NULL), Data);
4016 }
4017 else if (ptr[length] == 'W') { /* WWW page */
4018 toggle++;
4019 snprintf (temp,sizeof(temp), "http://darkbot.net%s", Data);
4020 }
4021 else if (ptr[length] == 'S') { /* server */
4022 toggle++;
4023 snprintf (temp,sizeof(temp), "%s%s", BS, Data);
4024 }
4025 #endif
4026 else if (ptr[length] == 'R') { /* rand */
4027 toggle++;
4028 /* The first time around, we just store the topic in a
4029 "safe place" */
4030 if (bFirst == 1) {
4031 strncpy (crm1, topic, sizeof(crm1));
4032 bFirst = 0;
4033 }
4034 #ifdef Win32
4035 sprintf (temp,"%s%s", get_rand_nick (target),
4036 Data);
4037 }
4038 else if (ptr[length] == 'P') { /* port */
4039 toggle++;
4040 sprintf (temp,"%d%s", (int) BP, Data);
4041 }
4042 else if (ptr[length] == 'Q') { /* question */
4043 toggle++;
4044 sprintf (temp,"%s%s", revert_topic (topic),
4045 Data);
4046 }
4047 else if (ptr[length] == 'V') { /* version */
4048 toggle++;
4049 sprintf (temp,"%s%s", dbVersion, Data);
4050 }
4051 else if (ptr[length] == '!') { /* cmdchar */
4052 toggle++;
4053 sprintf (temp,"%c%s", *CMDCHAR, Data);
4054 }
4055 else if (ptr[length] == 'B') { /* mynick */
4056 toggle++;
4057 sprintf (temp,"%s%s", Mynick, Data);
4058 }
4059 else
4060 sprintf (temp,"%c~%s", ptr[length], Data);
4061 }
4062 else if (ptr[length] == '~') {
4063 Tog = 1;
4064 }
4065 else
4066 sprintf (temp,"%c%s", ptr[length], Data);
4067 #else
4068 snprintf (temp,sizeof(temp), "%s%s", get_rand_nick (target),
4069 Data);
4070 }
4071 else if (ptr[length] == 'P') { /* port */
4072 toggle++;
4073 snprintf (temp,sizeof(temp), "%d%s", (int) BP, Data);
4074 }
4075 else if (ptr[length] == 'Q') { /* question */
4076 toggle++;
4077 snprintf (temp,sizeof(temp), "%s%s", revert_topic (topic),
4078 Data);
4079 }
4080 else if (ptr[length] == 'V') { /* version */
4081 toggle++;
4082 snprintf (temp,sizeof(temp), "%s%s", dbVersion, Data);
4083 }
4084 else if (ptr[length] == '!') { /* cmdchar */
4085 toggle++;
4086 snprintf (temp,sizeof(temp), "%c%s", *CMDCHAR, Data);
4087 }
4088 else if (ptr[length] == 'B') { /* mynick */
4089 toggle++;
4090 snprintf (temp,sizeof(temp), "%s%s", Mynick, Data);
4091 }
4092 else
4093 snprintf (temp,sizeof(temp), "%c~%s", ptr[length], Data);
4094 }
4095 else if (ptr[length] == '~') {
4096 Tog = 1;
4097 }
4098 else
4099 snprintf (temp,sizeof(temp), "%c%s", ptr[length], Data);
4100 #endif
4101 strncpy (Data, temp, sizeof(Data));
4102 } /* While */
4103 if (D == 1) {
4104 ptr8 = strtok (Data, "|");
4105 while (ptr8 != NULL) {
4106 if (ptr8[0] == ' ')
4107 ptr8++;
4108 if (ptr8[0] == 'B' && ptr8[1] == 'A' && ptr8[2] == 'N') { /* ban user */
4109 S ("MODE %s +b *%s\n", target, uh);
4110 }
4111 if (ptr8[0] == 'T' && ptr8[1] == 'E' && ptr8[2] == 'M' &&
4112 ptr8[3] == 'P' && ptr8[4] == 'B' && ptr8[5] == 'A' &&
4113 ptr8[6] == 'N') { /* temp ban user for 60 sec */
4114 S ("MODE %s +b *%s\n", target, uh);
4115 #ifdef WIN32
4116 sprintf (temp,"%s/%d", DBTIMERS_PATH, time (NULL) + 60);
4117 #else
4118 snprintf (temp, sizeof(temp),"%s/%d", DBTIMERS_PATH, time (NULL) + 60);
4119 #endif
4120 log (temp, "MODE %s -b *%s\n", target, uh);
4121 }
4122 ptr8[0] = tolower (ptr8[0]);
4123 ptr8[1] = tolower (ptr8[1]);
4124 if (ptr8[0] == 'p' && ptr8[1] == 'r')
4125 F = 1;
4126 if (ptr8[0] == 'k' && ptr8[1] == 'i')
4127 F = 1;
4128 if (ptr8[0] == 'n' && ptr8[1] == 'o')
4129 F = 1;
4130 if (ptr8[0] == 't' && ptr8[1] == 'o')
4131 F = 1;
4132 if (F == 1)
4133 S ("%s\n", ptr8);
4134 F = 0;
4135 ptr8 = strtok (NULL, "|");
4136 }
4137 fclose (fp);
4138 R;
4139 }
4140 if (toggle == 0) {
4141 if (A == 0) {
4142 S ("PRIVMSG %s :%s%s\n", target, rand_reply (nick), Data);
4143 }
4144 else
4145 S ("PRIVMSG %s :\1ACTION %s\1\n", target, Data);
4146 }
4147 else if (A == 0) {
4148 S ("PRIVMSG %s :%s\n", target, Data);
4149 }
4150 else
4151 S ("PRIVMSG %s :\1ACTION %s\1\n", target, Data);
4152 fclose (fp);
4153 R;
4154 } /* Subject match */
4155 }
4156 fclose (fp);
4157 if (donno == 1) {
4158 if (strlen (topic) > 3) {
4159 strlwr (topic);
4160 if (topic[0] == 'i' && topic[1] == 'l' && topic[2] == 'c') {
4161 S
4162 ("PRIVMSG %s :%s, I found no matching ILC for that channel.\n",
4163 target, nick);
4164 R;
4165 }
4166 }
4167 S ("PRIVMSG %s :%s, %s\n", target, nick, DONNO_Q);
4168 }
4169 }
4170
4171 /**
4172 * 6/23/00 Dan:
4173 * - Moved declaration of newact into #ifdef
4174 */
4175 int
main(int argc,char ** argv)4176 main (int argc, char **argv)
4177 {
4178 char temp[STRING_SHORT];
4179 struct timeval timeout;
4180 fd_set fdvar;
4181 #if (SGI == 1) || (NEED_LIBC5 == 1)
4182 struct sigaction newact;
4183 #endif
4184 #ifdef DEBUG
4185 DebuG = 1;
4186 #endif
4187 #ifndef WIN32 /* not win32 */
4188 #endif
4189 get_s ();
4190 srand (time (0));
4191 uptime = time (NULL);
4192 if (argv[1] != NULL) {
4193 if (stricmp (argv[1], "-SEEN") == 0) {
4194 SeeN = 1;
4195 printf ("\nSEEN ENABLED.\n\n");
4196 }
4197 else if (stricmp (argv[1], "-DEBUG") == 0) {
4198 DebuG = 1;
4199 printf ("\nDEBUG ENABLED.\n\n");
4200 }
4201 else {
4202 printf ("\n\n%s HELP:\n\n", dbVersion);
4203 printf ("%s (Launches Darkbot to IRC)\n", argv[0]);
4204 printf
4205 ("%s -SEEN (Enables SEEN [Even if SEEN is undefined])\n",
4206 argv[0]);
4207 printf ("%s -DEBUG (Launch in debug mode)\n", argv[0]);
4208 exit (0);
4209 }
4210 }
4211 strncpy (DARKBOT_BIN, argv[0], sizeof(DARKBOT_BIN));
4212 #if (SGI == 1) || (NEED_LIBC5 == 1)
4213 newact.sa_handler = sig_alrm;
4214 sigemptyset (&newact.sa_mask);
4215 newact.sa_flags = 0;
4216 sigaction (SIGALRM, &newact, NULL);
4217 newact.sa_handler = sig_segv;
4218 sigemptyset (&newact.sa_mask);
4219 newact.sa_flags = 0;
4220 sigaction (SIGSEGV, &newact, NULL);
4221 newact.sa_handler = sig_hup;
4222 sigemptyset (&newact.sa_mask);
4223 newact.sa_flags = 0;
4224 sigaction (SIGHUP, &newact, NULL);
4225 #else /* ----------------------- */
4226 signal (SIGALRM, sig_alrm);
4227 signal (SIGSEGV, sig_segv);
4228 signal (SIGHUP, sig_hup);
4229 #endif
4230 #ifndef WIN32
4231 #ifdef FORK
4232 if (fork ())
4233 exit (0);
4234 #endif
4235 #endif
4236 #ifdef RANDOM_STUFF
4237 get_rand_stuff_time ();
4238 #endif
4239 printf ("\n\n\n\n\n");
4240 printf (" ,-----------------------------------------------,\n");
4241 printf (" | Darkbot (C) Jason Hamilton http://darkbot.net |\n");
4242 printf (" `-----------------------------------------------'\n\n");
4243 #ifndef WIN32
4244 #ifndef DISALLOW_COUNT
4245 snprintf (temp,sizeof(temp), "lynx -source http://darkbot.net/cgi/laun.cgi?%s &",
4246 dbVersion);
4247 system (temp);
4248 #endif
4249 sprintf (temp,"echo \"%d\" > %s.pid", getpid (),
4250 DARKBOT_BIN);
4251 system (temp);
4252 #endif
4253 #ifndef WIN32
4254 db_sleep (2);
4255 #endif
4256 #ifndef WIN32
4257 #ifdef SORT
4258 printf ("\nSorting database...\n");
4259 snprintf (temp, sizeof(temp), "sort %s -o %s\n", URL2, URL2);
4260 system (temp);
4261 #endif
4262 #endif
4263 load_helpers ();
4264 raw_now ("SERVERS");
4265 raw_now ("SETUP");
4266 raw_now ("PERMBAN");
4267 gs26 ();
4268 #ifndef WIN32
4269 #endif
4270 alarm (AIL);
4271 printf ("\nConnecting to %s:%d ...\n", BS, (int) BP);
4272 socketfd = get_connection (BS, VHOST, BP);
4273 if (socketfd == -1) {
4274 exit (0);
4275 }
4276 init_bot ();
4277 while (1) {
4278 timeout.tv_sec = WSEC;
4279 timeout.tv_usec = USEC;
4280 FD_ZERO (&fdvar);
4281 FD_SET (socketfd, &fdvar);
4282 switch (select
4283 (NFDBITS, &fdvar, (fd_set *) 0, (fd_set *) 0, &timeout)) {
4284 case 0:
4285 break;
4286 case -1:
4287 if (!alarmed) {
4288 db_sleep (RECHECK);
4289 }
4290 else
4291 alarmed = 0;
4292 break;
4293 default:
4294 parse_server_msg (&fdvar);
4295 break;
4296 }
4297 }
4298 }
4299
4300 void
sig_hup(int notUsed)4301 sig_hup (int notUsed)
4302 {
4303 char temp[STRING_LONG];
4304 #ifdef WIN32
4305 S ("QUIT :Window killed - %s terminating\n", dbVersion);
4306 sprintf (temp,"sleep 2; %s", DARKBOT_BIN);
4307 #else
4308 S ("QUIT :SIGHUP - Restarting %s ...\n", dbVersion);
4309 snprintf (temp, sizeof(temp), "sleep 2; %s", DARKBOT_BIN);
4310 #endif
4311 system (temp);
4312 db_sleep (1);
4313 exit (0);
4314 }
4315
4316 void
sig_alrm(int notUsed)4317 sig_alrm (int notUsed)
4318 {
4319 alarmed = 1;
4320 alarm (AIL);
4321 check_dbtimers (); /* timers :) */
4322 AIL8 += AIL;
4323 if (AIL8 >= SEND_DELAY) {
4324 AIL8 = 0;
4325 Send ();
4326 }
4327 LastInput += AIL;
4328 if (LastInput >= 500) {
4329 LastInput = 0;
4330 #if CHECK_STONED == 1
4331 L088 (BS);
4332 #ifdef WIN32
4333 printf ("\nNo responce from %s in 5 mins, reconnecting...\n", BS);
4334 #endif
4335 gs26 ();
4336 socketfd = get_connection (BS, VHOST, BP);
4337 init_bot ();
4338 #endif
4339 }
4340 AIL10 += AIL;
4341 if (AIL10 >= 900) { /* 15 mins */
4342 AIL10 = 0;
4343 if (MARK_CHANGE == 1) {
4344 MARK_CHANGE = 0;
4345 save_setup (); /* save settings */
4346 }
4347 }
4348 AIL666 += AIL;
4349 if (AIL666 >= 60) { /* 60 sec timer */
4350 AIL666 = 0;
4351 S ("PING :%s\n", BS);
4352 }
4353 AIL9 += AIL;
4354 if (AIL9 >= 30) {
4355 AIL9 = 0;
4356 if (stricmp (s_Mynick, Mynick) != 0) {
4357 S ("NICK %s\n", s_Mynick);
4358 strncpy (Mynick, s_Mynick, sizeof(Mynick));
4359 #ifdef WIN32
4360 sprintf (NICK_COMMA,"%s,", Mynick);
4361 sprintf (COLON_NICK,"%s:", Mynick);
4362 sprintf (BCOLON_NICK,"%s\2:\2", Mynick);
4363 #else
4364 snprintf (NICK_COMMA,sizeof(NICK_COMMA), "%s,", Mynick);
4365 snprintf (COLON_NICK,sizeof(COLON_NICK), "%s:", Mynick);
4366 snprintf (BCOLON_NICK,sizeof(BCOLON_NICK), "%s\2:\2", Mynick);
4367 #endif
4368 }
4369 }
4370 if (Sleep_Toggle == 1) {
4371 AIL4 += AIL;
4372 if (AIL4 >= SLEEP_TIME) {
4373 Sleep_Toggle = 0;
4374 AIL4 = 0;
4375 L089 (sleep_chan);
4376 }
4377 }
4378 AIL2 += AIL;
4379 AIL3 += AIL;
4380 #ifdef RANDOM_STUFF
4381 Rand_Idle++;
4382 if (RAND_IDLE <= Rand_Idle) {
4383 Rand_Idle = 0;
4384 do_random_stuff ();
4385 get_rand_stuff_time ();
4386 }
4387 Rand_Stuff -= AIL;
4388 if (Rand_Stuff <= 0) {
4389 if (Sleep_Toggle != 1)
4390 do_random_stuff ();
4391 get_rand_stuff_time ();
4392 }
4393 #endif
4394 if (AIL3 >= AUTOTOPIC_TIME) {
4395 AIL3 = 0;
4396 do_autotopics ();
4397 }
4398 AIL5 += AIL;
4399 if (AIL5 >= 600) {
4400 #ifdef ANTI_IDLE
4401 S ("PRIVMSG ! :\2\n");
4402 #endif
4403 AIL5 = 0;
4404 }
4405 if (AIL2 >= 300) {
4406 AIL2 = 0;
4407 #if STATUS == 1
4408 S ("LUSERS\n");
4409 #endif
4410 S ("JOIN %s\n", CHAN);
4411 S ("MODE %s %s\n", Mynick, DEFAULT_UMODE);
4412 reset_ ();
4413 save_changes ();
4414 }
4415 }
4416
4417 void
sig_segv(int notUsed)4418 sig_segv (int notUsed)
4419 {
4420 long uptime2 = 0, p = 0;
4421 uptime2 = time (NULL) - uptime;
4422 printf
4423 ("ERROR! Aborting program. (SIG_SEGV) Uptime: %d hour%s, %d min%s\n",
4424 (int) (uptime2 / 3600),
4425 (uptime2 / 3600 == 1) ? "" : "s",
4426 (int) ((uptime2 / 60) % 60),
4427 ((uptime2 / 60) % 60) == 1 ? "" : "s");
4428 Snow
4429 ("QUIT :Caught SIG_SEGV! Aborting connection. Uptime: %d hour%s, %d min%s\n",
4430 uptime2 / 3600,
4431 uptime2 / 3600 == 1 ? "" : "s",
4432 (uptime2 / 60) % 60, (uptime2 / 60) % 60 == 1 ? "" : "s");
4433 db_sleep (2);
4434 p = getpid ();
4435 if (fork () > 0) {
4436 log ("error.log",
4437 "Caught SIGSEGV.. Sent kill -3 and kill -9...\n");
4438 kill (p, 3);
4439 kill (p, 9);
4440 }
4441 db_sleep (1);
4442 exit (0);
4443 }
4444
4445 int
get_sendq_count(long toggle)4446 get_sendq_count (long toggle)
4447 {
4448 struct sendq *c;
4449 long i = 0, x = 0;
4450 c = sendqhead;
4451 while (c != NULL) {
4452 i++;
4453 if (c->data[0] == 'P' && c->data[1] == 'R' && c->data[2] == 'I')
4454 x++;
4455 else
4456 if (c->data[0] == 'N'
4457 && c->data[1] == 'O' && c->data[2] == 'T') x++;
4458 c = c->next;
4459 }
4460 if (toggle == 1)
4461 clear_sendq (i, 1);
4462 if (toggle == 2)
4463 R i;
4464 if (i < OUTPUT1_COUNT)
4465 SEND_DELAY = OUTPUT1_DELAY;
4466 else if (i < OUTPUT2_COUNT)
4467 SEND_DELAY = OUTPUT2_DELAY;
4468 else
4469 SEND_DELAY = OUTPUT3_DELAY;
4470 if (x > OUTPUT_PURGE_COUNT)
4471 clear_sendq (x, 0);
4472 R i;
4473 }
4474
4475 void
clear_sendq(long count,long toggle)4476 clear_sendq (long count, long toggle)
4477 {
4478 long i = 0;
4479 i = count;
4480 while (i > 1) {
4481 i--;
4482 del_sendq (1);
4483 }
4484 send_tog = 1;
4485 if (toggle != 1)
4486 L090 (CHAN, count);
4487 }
4488
4489 void
init_bot()4490 init_bot ()
4491 {
4492 get_sendq_count (1);
4493 Snow ("NICK %s\n", Mynick);
4494 strlwr (UID);
4495 Snow ("USER %s %d %d :%s \2%d\2\n", UID,
4496 time (NULL), time (NULL), REALNAME, NUM_HELPER);
4497 }
4498
4499 /**
4500 * TODO: No function should ever be this long...move to the Command Pattern
4501 */
4502 void
parse(char * line)4503 parse (char *line)
4504 {
4505 char *s, *s1, *s2, *s3, *cmd, *ptr, *s4;
4506 long TOG = 0, seen_value = 0;
4507 LastInput = 0;
4508 if (DebuG == 1)
4509 printf ("IN :%s\n", line);
4510 #ifdef DEBUG2
4511 log ("darkbot_debug.log", "IN :%s\n", line);
4512 #endif
4513 stripline (line);
4514 s = strtok (line, " ");
4515 if (stricmp (s, "PING") == 0) {
4516 s1 = strtok (NULL, " ");
4517 Snow ("PONG %s\n", s1);
4518 }
4519 else if (stricmp (s, "ERROR") == 0) {
4520 s1 = strtok (NULL, "");
4521 if (s1 != NULL) {
4522 if (strstr (s1, "Excess Flood") != NULL) {
4523 socketfd = get_connection (BS, VHOST, BP);
4524 init_bot ();
4525 }
4526 else if (strstr (s1, "throttled") != NULL) {
4527 gs26 ();
4528 socketfd = get_connection (BS, VHOST, BP);
4529 init_bot ();
4530 }
4531 else if (strstr (s1, "oo many c") != NULL) {
4532 gs26 ();
4533 socketfd = get_connection (BS, VHOST, BP);
4534 init_bot ();
4535 }
4536 else if (strstr (s1, "o more c") != NULL) {
4537 gs26 ();
4538 socketfd = get_connection (BS, VHOST, BP);
4539 init_bot ();
4540 }
4541 else {
4542 S ("QUIT :Caught ERROR from %s :(\n", BS);
4543 db_sleep (5);
4544 gs26 ();
4545 socketfd = get_connection (BS, VHOST, BP);
4546 init_bot ();
4547 }
4548 }
4549 }
4550 else if (strstr (s, "!") == NULL) { /* From Server */
4551 cmd = strtok (NULL, " ");
4552 if (stricmp (cmd, "004") == 0) { /* Connected! */
4553 save_changes ();
4554 s2 = strtok (NULL, " "); /* Copy the current nick */
4555 strncpy (Mynick, s2, sizeof(Mynick));
4556 #ifdef WIN32
4557 sprintf (NICK_COMMA, "%s,", Mynick);
4558 sprintf (COLON_NICK,"%s:", Mynick);
4559 sprintf (BCOLON_NICK,"%s\2:\2", Mynick);
4560 #else
4561 snprintf (NICK_COMMA,sizeof(NICK_COMMA), "%s,", Mynick);
4562 snprintf (COLON_NICK,sizeof(COLON_NICK), "%s:", Mynick);
4563 snprintf (BCOLON_NICK,sizeof(BCOLON_NICK), "%s\2:\2", Mynick);
4564 #endif
4565 S ("JOIN %s\n", CHAN);
4566 db_sleep (2);
4567 s2 = strtok (NULL, " "); /* Got server name */
4568 printf
4569 ("%s has connected to %s! [%d pid]\n", Mynick, s2, getpid ());}
4570 else if (stricmp (cmd, "315") == 0) {
4571 #if DISPLAY_SYNC == 1
4572 s2 = strtok (NULL, " "); /*mynick */
4573 strncpy (Mynick, s2, sizeof(Mynick));
4574 s2 = strtok (NULL, " "); /* chan */
4575 S ("PRIVMSG %s :Sync with %s completed.\n", s2, s2);
4576 #endif
4577 }
4578 else if (stricmp (cmd, "311") == 0) {
4579 s1 = strtok (NULL, " ");
4580 s1 = strtok (NULL, " ");
4581 s1 = strtok (NULL, " ");
4582 s1 = strtok (NULL, " ");
4583 strncpy (g_host, s1, sizeof(g_host));
4584 }
4585 else if (stricmp (cmd, "319") == 0) {
4586 s1 = strtok (NULL, " ");
4587 s1 = strtok (NULL, " ");
4588 s2 = strtok (NULL, "");
4589 if (*s2 == ':')
4590 s2++;
4591 strlwr (s2);
4592 if (strstr (s2, "arez") != NULL)
4593 TOG = 1;
4594 if (strstr (s2, "kidd") != NULL)
4595 TOG = 1;
4596 if (strstr (s2, "hack") != NULL)
4597 TOG = 1;
4598 if (strstr (s2, "sex") != NULL)
4599 TOG = 1;
4600 if (strstr (s2, "fuck") != NULL)
4601 TOG = 1;
4602 if (strstr (s2, "porn") != NULL)
4603 TOG = 1;
4604 if (strstr (s2, "pic") != NULL)
4605 TOG = 1;
4606 if (TOG == 1) {
4607 S ("NOTICE @%s :%s is on \2%s\2\n", g_chan, s1, s2);
4608 R;
4609 }
4610 }
4611 else
4612 if (stricmp (cmd, "432") == 0
4613 || stricmp (cmd, "468") == 0) { /* Invalid nick/user */
4614 s2 = strtok (NULL, "");
4615 printf ("Server Reported error %s\n\nDarkbot exiting.\n", s2);
4616 db_sleep (2);
4617 exit (0);
4618 }
4619 else if (stricmp (cmd, "376") == 0) {
4620 raw_now ("PERFORM"); /* End of MOTD, run
4621 * perform_now() */
4622 }
4623 else if (stricmp (cmd, "482") == 0) {
4624 #if BITCH_ABOUT_DEOP == 1
4625 s2 = strtok (NULL, " "); /* mynick */
4626 strncpy (Mynick, s2, sizeof(Mynick));
4627 s2 = strtok (NULL, " "); /* chan */
4628 S ("PRIVMSG %s :%s\n", s2, BITCH_DEOP_REASON);
4629 #endif
4630 raw_now ("DEOP"); /* Deoped, run list of
4631 * commands.. */
4632 }
4633 else if (stricmp (cmd, "352") == 0) {
4634 s2 = strtok (NULL, "");
4635 parse_who (s2);
4636 #if STATUS == 1
4637 }
4638 else if (stricmp (cmd, "252") == 0) {
4639 s2 = strtok (NULL, "");
4640 parse_252 (s2);
4641 }
4642 else
4643 if (stricmp (cmd, "404") == 0
4644 || stricmp (cmd, "475") == 0
4645 || stricmp (cmd, "474") == 0 || stricmp (cmd, "473") == 0) { /* Can't join? */
4646 s2 = strtok (NULL, " ");
4647 s2 = strtok (NULL, " ");
4648 db_sleep (5);
4649 S ("JOIN %s\n", s2);
4650 }
4651 else if (stricmp (cmd, "251") == 0) {
4652 s2 = strtok (NULL, "");
4653 parse_251 (s2);
4654 }
4655 else if (stricmp (cmd, "255") == 0) {
4656 s2 = strtok (NULL, "");
4657 parse_255 (s2);
4658 #endif
4659 }
4660 else if (stricmp (cmd, "433") == 0) {
4661 s2 = strtok (NULL, " ");
4662 if (*s2 != '*') {
4663 strncpy (Mynick, s2, sizeof(Mynick));
4664 #ifdef WIN32
4665 sprintf (NICK_COMMA, "%s,", Mynick);
4666 sprintf (COLON_NICK,"%s:", Mynick);
4667 sprintf (BCOLON_NICK,"%s\2:\2", Mynick);
4668 #else
4669 snprintf (NICK_COMMA,sizeof(NICK_COMMA), "%s,", Mynick);
4670 snprintf (COLON_NICK,sizeof(COLON_NICK), "%s:", Mynick);
4671 snprintf (BCOLON_NICK,sizeof(BCOLON_NICK), "%s\2:\2", Mynick);
4672 #endif
4673 s3 = strtok (NULL, " ");
4674 }
4675 else {
4676 Snow ("NICK %s%d\n", Mynick, xtried);
4677 xtried++;
4678 if (xtried > 15)
4679 Snow ("NICK _`^%s%d\n", Mynick, xtried);
4680 if (xtried > 5)
4681 Snow ("NICK _%s%d\n", Mynick, xtried);
4682 }
4683 }
4684 }
4685 else { /* Info from user */
4686 if (*s == ':') /* Remove the colon prefix */
4687 s++;
4688 cmd = strtok (NULL, " "); /* Read in command */
4689 if (stricmp (cmd, "NOTICE") == 0) {
4690 s2 = strtok (NULL, " "); /* target */
4691 #if KICK_ON_CHANNEL_NOTICE == ON
4692 if (*s2 == '#') {
4693 s3 = strtok (s, "!");
4694 #if BAN_ON_CHANNEL_NOTICE == ON
4695 #if BAN_BY_HOST == ON
4696 s4 = strtok (NULL, "@");
4697 s4 = strtok (NULL, "");
4698 S ("MODE %s +b *!*@%s\n", s2, s4);
4699 #else /* ban just by u@h */
4700 S ("MODE %s +b *%s\n", s2, strtok (NULL, ""));
4701 #endif
4702 #endif
4703 S ("KICK %s %s :Punt\n", s2, s3);
4704 }
4705 #endif
4706 }
4707 else if (stricmp (cmd, "PRIVMSG") == 0) { /* PRIVMSG */
4708 s1 = strtok (NULL, " "); /* Target */
4709 s2 = strtok (NULL, ""); /* Rest */
4710 #if LOG_PRIVMSG == 1
4711 if (*s1 != '#' && *s1 != '&') {
4712 log (privmsg_log, "[%s] %s %s %s\n", date (), s, s1, s2);
4713 }
4714 #endif
4715 if (*s1 == '#' || *s1 == '&' || *s1 == '+')
4716 if (do_lastcomm (s, s1, s2)
4717 == 1)
4718 R;
4719 chanserv (s, s1, s2); /* Process PRIVMSG commands */
4720 }
4721 else if (stricmp (cmd, "KILL") == 0) {
4722 s1 = strtok (NULL, " "); /* Kill nick */
4723 if (stricmp (s1, Mynick) == 0) {
4724 do_quit (s1, 3); /* delete all users from ram since I'm gone */
4725 gs26 ();
4726 socketfd = get_connection (BS, VHOST, BP);
4727 init_bot ();
4728 }
4729 }
4730 else if (stricmp (cmd, "KICK") == 0) {
4731 s1 = strtok (NULL, " "); /* #chan */
4732 s2 = strtok (NULL, " "); /* Who got kicked? */
4733 if (stricmp (s2, Mynick) == 0) { /* Rejoin if I was
4734 * kicked */
4735 do_quit (s1, 2);
4736 db_sleep (5);
4737 S ("JOIN %s\n", s1);
4738 S ("PRIVMSG %s :%s\n", s1, COMPLAIN_REASON);
4739 }
4740 else
4741 delete_user (s2, s1);
4742 }
4743 else if (stricmp (cmd, "INVITE") == 0) {
4744 s1 = strtok (NULL, " "); /* Mynick */
4745 s2 = strtok (NULL, " "); /* Target */
4746 if (*s2 == ':')
4747 s2++;
4748 if (stricmp (s2, CHAN) == 0)
4749 S ("JOIN %s\n", s2);
4750 }
4751 else if (stricmp (cmd, "PART") == 0) {
4752 s1 = strtok (NULL, " "); /* Target */
4753 if ((ptr = strchr (s, '!')) != NULL)
4754 *ptr++ = '\0';
4755 strlwr (ptr);
4756 if (stricmp (s, Mynick) != 0)
4757 delete_user (s, s1);
4758 else /* I left, so delete all */
4759 do_quit (s1, 2);
4760 }
4761 else if (stricmp (cmd, "QUIT") == 0) {
4762 if ((ptr = strchr (s, '!')) != NULL)
4763 *ptr++ = '\0';
4764 do_quit (s, 1);
4765 }
4766 else if (stricmp (cmd, "MODE") == 0) {
4767 do_modes (s, strtok (NULL, ""));
4768 }
4769 else if (stricmp (cmd, "NICK") == 0) {
4770 if ((ptr = strchr (s, '!')) != NULL)
4771 *ptr++ = '\0';
4772 s1 = strtok (NULL, " ");
4773 process_nick (s, s1);
4774 }
4775 else if (stricmp (cmd, "JOIN") == 0) {
4776 JOINs++;
4777 s1 = strtok (NULL, " "); /* TARGET */
4778 if (*s1 == ':')
4779 s1++;
4780 if ((ptr = strchr (s, '!')) != NULL)
4781 *ptr++ = '\0';
4782 strlwr (ptr);
4783 if (SeeN == 1 && *s1 == '#')
4784 seen_value = save_seen (s, ptr, s1);
4785 if (stricmp (s, Mynick) != 0) {
4786 if (check_permban (ptr, s1, s) == 1)
4787 R;
4788 add_user (s1, s, ptr, 1);
4789 #if DO_WHOIS == 1
4790 strncpy (g_chan, s1, sizeof(g_chan));
4791 S ("WHOIS %s\n", s);
4792 #endif
4793 if (check_access (ptr, s1, 0, s) >= 4) {
4794 S ("MODE %s +o %s\n", s1, s);
4795 }
4796 else if (check_access (ptr, s1, 1, s) >= 1) {
4797 S ("MODE %s +v %s\n", s1, s);
4798 #if HELP_GREET == 1
4799 }
4800 else if (check_access (ptr, s1, 0, s) >= 1) {
4801 return; /* don't greet if the guy has
4802 * access (and no setinfo) */
4803 }
4804 else if (stricmp (s1, CHAN) == 0) {
4805 if (SeeN == 1) {
4806 if (seen_value == 0) /* don't show people the
4807 * notice every join */
4808 if (setinfo_lastcomm (s1) == 0) /* don't do it if you just did it! */
4809 L102 (s, s1, s, *CMDCHAR);
4810 }
4811 else {
4812 if (setinfo_lastcomm (s1) == 0)
4813 L102 (s, s1, s, *CMDCHAR);
4814 }
4815 }
4816 #else
4817 }
4818 #endif
4819 }
4820 else
4821 S ("WHO %s\n", s1); /* Check who is in the
4822 * chan */
4823 } /* JOIN */
4824 }
4825 }
4826
4827
4828 long
setinfo_lastcomm(char * rest)4829 setinfo_lastcomm (char *rest)
4830 { /* Disallows joins to more than one channel (or the same chan)
4831 * to artifically raise join counters */
4832 long c_uptime = 0;
4833 if (stricmp (rest, slc1) == 0)
4834 R 1; /* don't reply if already asked in LASTCOMM_TIME sec */
4835 if (stricmp (rest, slc2) == 0)
4836 R 1;
4837 if (stricmp (rest, slc3) == 0)
4838 R 1;
4839 if (stricmp (rest, slc4) == 0)
4840 R 1;
4841 if (*slc1 == '0') { /* init lastcomms */
4842 strncpy (slc1, rest, sizeof(slc1));
4843 slcn1 = time (NULL);
4844 }
4845 if (*slc2 == '0') {
4846 strncpy (slc2, rest, sizeof(slc2));
4847 slcn2 = time (NULL);
4848 }
4849 if (*slc3 == '0') {
4850 strncpy (slc3, rest, sizeof(slc3));
4851 slcn3 = time (NULL);
4852 }
4853 if (*slc4 == '0') {
4854 strncpy (slc4, rest, sizeof(slc4));
4855 slcn4 = time (NULL);
4856 }
4857 if ((c_uptime = time (NULL) - slcn1) > SLASTCOMM_TIME) { /* reinit old data */
4858 slcn1 = 0;
4859 *slc1 = '0';
4860 }
4861 if ((c_uptime = time (NULL) - slcn2) > SLASTCOMM_TIME) {
4862 slcn2 = 0;
4863 *slc2 = '0';
4864 }
4865 if ((c_uptime = time (NULL) - slcn3) > SLASTCOMM_TIME) {
4866 slcn3 = 0;
4867 *slc3 = '0';
4868 }
4869 if ((c_uptime = time (NULL) - slcn4) > SLASTCOMM_TIME) {
4870 slcn4 = 0;
4871 *slc4 = '0';
4872 }
4873 strncpy (slc4, slc3, sizeof(slc4)); /* no matches, move em on
4874 down */
4875 strncpy (slc3, slc2, sizeof(slc3));
4876 strncpy (slc2, slc1, sizeof(slc2));
4877 strncpy (slc1, rest, sizeof(slc1));
4878 slcn4 = slcn3;
4879 slcn3 = slcn2;
4880 slcn2 = slcn1;
4881 slcn1 = time (NULL);
4882 R 0;
4883 }
4884
4885 long
do_lastcomm(char * nick,char * target,char * rest)4886 do_lastcomm (char *nick, char *target, char *rest)
4887 {
4888 long c_uptime = 0;
4889 if (stricmp (rest, lc1) == 0)
4890 R 1; /* don't reply if already asked in LASTCOMM_TIME sec */
4891 if (stricmp (rest, lc2) == 0)
4892 R 1;
4893 if (stricmp (rest, lc3) == 0)
4894 R 1;
4895 if (stricmp (rest, lc4) == 0)
4896 R 1;
4897 if (*lc1 == '0') { /* init lastcomms */
4898 strncpy (lc1, rest, sizeof(lc1));
4899 lcn1 = time (NULL);
4900 }
4901 if (*lc2 == '0') {
4902 strncpy (lc2, rest, sizeof(lc2));
4903 lcn2 = time (NULL);
4904 }
4905 if (*lc3 == '0') {
4906 strncpy (lc3, rest, sizeof(lc3));
4907 lcn3 = time (NULL);
4908 }
4909 if (*lc4 == '0') {
4910 strncpy (lc4, rest, sizeof(lc4));
4911 lcn4 = time (NULL);
4912 }
4913 if ((c_uptime = time (NULL) - lcn1) > LASTCOMM_TIME) { /* reinit old data */
4914 lcn1 = 0;
4915 *lc1 = '0';
4916 }
4917 if ((c_uptime = time (NULL) - lcn2) > LASTCOMM_TIME) {
4918 lcn2 = 0;
4919 *lc2 = '0';
4920 }
4921 if ((c_uptime = time (NULL) - lcn3) > LASTCOMM_TIME) {
4922 lcn3 = 0;
4923 *lc3 = '0';
4924 }
4925 if ((c_uptime = time (NULL) - lcn4) > LASTCOMM_TIME) {
4926 lcn4 = 0;
4927 *lc4 = '0';
4928 }
4929 strncpy (lc4, lc3, sizeof(lc4)); /* no matches, move em on
4930 down */
4931 strncpy (lc3, lc2, sizeof(lc3));
4932 strncpy (lc2, lc1, sizeof(lc2));
4933 strncpy (lc1, rest, sizeof(lc1));
4934 lcn4 = lcn3;
4935 lcn3 = lcn2;
4936 lcn2 = lcn1;
4937 lcn1 = time (NULL);
4938 R 0;
4939 }
4940
4941 #if STATUS == 1
4942 void
parse_252(char * s)4943 parse_252 (char *s)
4944 {
4945 char *tmp;
4946 int numb = 0;
4947 tmp = strtok (s, " ");
4948 tmp = strtok (NULL, " ");
4949 sscanf (tmp, "%d", &numb);
4950 IRCOPS = numb;
4951 }
4952 #endif
4953
4954 #if STATUS == 1
4955 void
parse_251(char * s)4956 parse_251 (char *s)
4957 {
4958 char *tmp;
4959 int numb = 0, r = 0, i = 0;
4960 /*- Read and chuck useless data from line 'b' -*/
4961 tmp = strtok (s, " ");
4962 tmp = strtok (NULL, " ");
4963 tmp = strtok (NULL, " ");
4964 tmp = strtok (NULL, " ");
4965 sscanf (tmp, "%d", &r);
4966 tmp = strtok (NULL, " ");
4967 tmp = strtok (NULL, " ");
4968 tmp = strtok (NULL, " ");
4969 sscanf (tmp, "%d", &i);
4970 tmp = strtok (NULL, " ");
4971 tmp = strtok (NULL, " ");
4972 tmp = strtok (NULL, " ");
4973 sscanf (tmp, "%d", &numb);
4974 NUM_SERV = numb;
4975 G_USERS = r + i;
4976 }
4977 #endif
4978
4979 #if STATUS == 1
4980 void
parse_255(char * s)4981 parse_255 (char *s)
4982 {
4983 char *tmp, Stat[1];
4984 int numb = 0, pre_CLIENTS = 0;
4985 /* test321 :I have 1313 clients and 1 servers */
4986 strlwr (s);
4987 tmp = strtok (s, " ");
4988 tmp = strtok (NULL, " ");
4989 tmp = strtok (NULL, " ");
4990 tmp = strtok (NULL, " ");
4991 numb = atoi (tmp);
4992 pre_CLIENTS = L_CLIENTS;
4993 L_CLIENTS = numb;
4994 if (L_CLIENTS < pre_CLIENTS) {
4995 strncpy (Stat, "-", sizeof(Stat));
4996 pre_CLIENTS = pre_CLIENTS - L_CLIENTS;
4997 }
4998 else {
4999 strncpy (Stat, "+", sizeof(Stat));
5000 pre_CLIENTS = L_CLIENTS - pre_CLIENTS;
5001 }
5002 #ifdef WIN32
5003 sprintf (tmp,"%3.2f",
5004 #else
5005 snprintf (tmp, sizeof(tmp),"%3.2f",
5006 #endif
5007 (float) (((float) L_CLIENTS / (float) G_USERS) * 100));
5008 #if PLAY == 1
5009 if (pre_CLIENTS == 0 || pre_CLIENTS == L_CLIENTS) {
5010 S
5011 ("PRIVMSG %s :!SENDQ %d srvs, %d ops, %d users (%s%% of %d, %ld avg)\n",
5012 PBOT, NUM_SERV, IRCOPS, L_CLIENTS, tmp,
5013 G_USERS, G_USERS / NUM_SERV);}
5014 else
5015 S
5016 ("PRIVMSG %s :!SENDQ %d srvs, %d ops, %d users [%c%2d] (%s%% of %d, %ld avg)\37\n",
5017 PBOT, NUM_SERV, IRCOPS, L_CLIENTS,
5018 Stat[0], pre_CLIENTS, tmp, G_USERS, G_USERS / NUM_SERV);
5019 log (".ubcount", "%d\n%d\n0\n0\n", L_CLIENTS, L_CLIENTS);
5020 rename (".ubcount",
5021 "/usr/local/apache/htdocs/usage/userbase/userbase.dat");
5022 log (".glcount", "%d\n%d\n0\n0\n", G_USERS, G_USERS);
5023 rename (".glcount",
5024 "/usr/local/apache/htdocs/usage/global/global.dat");
5025 #else
5026 if (pre_CLIENTS == 0 || pre_CLIENTS == L_CLIENTS) {
5027 S
5028 ("PRIVMSG %s :\1ACTION \37(\37%2d servers\37)\37: %2d opers + \2%4d\2 users \37(\37%s%% %5d global \2!\2 %3ld avg\37)\37\1\n",
5029 CHAN, NUM_SERV, IRCOPS, L_CLIENTS, tmp,
5030 G_USERS, G_USERS / NUM_SERV);}
5031 else
5032 S
5033 ("PRIVMSG %s :\1ACTION \37(\37%2d servers\37)\37: %2d opers + \2%4d\2 users [\37%c%2d\37] \37(\37%s%% %5d global \2!\2 %3ld avg\37)\37\1\n",
5034 CHAN, NUM_SERV, IRCOPS, L_CLIENTS,
5035 Stat[0], pre_CLIENTS, tmp, G_USERS, G_USERS / NUM_SERV);
5036 #endif
5037 }
5038 #endif
5039
5040 void
load_helpers()5041 load_helpers ()
5042 {
5043 FILE *fp;
5044 char b[STRING_LONG], *user_host,
5045 *greetz, *numb_join, *chan, *w_level, *pass;
5046 long num_join = 0, i = 0, level = 0;
5047 if ((fp = fopen (HELPER_LIST, "r")) == NULL) {
5048 printf ("Unable to open %s! Aborting connection.\n", HELPER_LIST);
5049 printf ("Please run /usr/local/etc/darkbot/configure to setup your darkbot.\n");
5050 exit (0);
5051 }
5052 #ifndef WIN32
5053 printf ("Loading %s file ", HELPER_LIST);
5054 #endif
5055 while (fgets (b, STRING_LONG, fp)) {
5056 if (b == NULL)
5057 continue;
5058 stripline (b);
5059 if (*b == '/')
5060 continue;
5061 i++;
5062 printf (".");
5063 fflush (stdout);
5064 chan = strtok (b, " ");
5065 if (chan == NULL)
5066 continue;
5067 user_host = strtok (NULL, " ");
5068 if (user_host == NULL)
5069 continue;
5070 w_level = strtok (NULL, " ");
5071 if (w_level == NULL)
5072 continue;
5073 numb_join = strtok (NULL, " ");
5074 if (numb_join == NULL)
5075 continue;
5076 pass = strtok (NULL, " ");
5077 if (pass == NULL) {
5078 pass = "0"; /* duh */
5079 }
5080 greetz = strtok (NULL, "");
5081 if (greetz == NULL)
5082 greetz = "I haven't used \2SETINFO\2 yet!";
5083 if (w_level != NULL)
5084 level = atoi (w_level);
5085 else
5086 level = 1;
5087 if (numb_join != NULL)
5088 num_join = atoi (numb_join);
5089 else
5090 num_join = 0;
5091 if (strlen (pass) > 25)
5092 pass[25] = '\0';
5093 if (DebuG == 1)
5094 printf
5095 ("loading helperlist: %s %s l:%d j:%d %s\n",
5096 chan, user_host, (int) level, (int) num_join, greetz);
5097 add_helper (chan, user_host, level, num_join, greetz, pass);
5098 }
5099 printf ("done(%d).\n", (int) i);
5100 fclose (fp);
5101 save_changes ();
5102 if (DebuG == 1)
5103 db_sleep (2);
5104 }
5105
5106 /**
5107 * Add a channel helper.
5108 * 6/22/00 Dan
5109 * n now initialized where declared
5110 * All pointer arguments now received as pointer to const data.
5111 */
5112 void
add_helper(const char * chan,const char * uh,long level,size_t num_join,const char * greetz,const char * pass)5113 add_helper (const char *chan,
5114 const char *uh, long level,
5115 size_t num_join, const char *greetz, const char *pass)
5116 {
5117 struct helperlist *n = 0;
5118 n = (struct helperlist *)
5119 malloc (sizeof (struct helperlist));
5120 if (n == NULL) {
5121 log ("error.log", "AHHH! No ram left! in add_helper!\n");
5122 R;
5123 }
5124
5125 memset (n, 0, sizeof (struct helperlist));
5126 NUM_HELPER++;
5127 if (chan[0] == '#') {
5128 strncpy (n->chan, chan, sizeof(n->chan));
5129 }
5130 else {
5131 strncpy (n->chan, "#*", sizeof(n->chan));
5132 }
5133
5134 strncpy (n->uh, uh, sizeof(n->uh));
5135 strlwr (n->uh);
5136 strncpy (n->pass, pass, sizeof(n->pass));
5137 n->num_join = num_join;
5138 n->level = level;
5139 strncpy (n->greetz, greetz,
5140 min (sizeof (n->greetz) - 1, strlen (greetz)));
5141 n->next = helperhead;
5142 helperhead = n;
5143 }
5144
5145
5146 /**
5147 * 6/22 Dan
5148 * - Changed DATA to be 512 bytes, a power of 2
5149 * - DATA now initialized properly
5150 * - c is now a pointer to const, this is a read only method
5151 * - c is now initialized where declared
5152 * - Changed type of i, x to size_t, these variables should be
5153 * unsigned.
5154 * - Changed while loop to for loop.
5155 * - Changed reinitialization of DATA to use memset()
5156 */
5157 void
show_banlist(const char * nick)5158 show_banlist (const char *nick)
5159 {
5160 char DATA[STRING_SHORT] = {
5161 0
5162 };
5163 size_t i = 0;
5164 size_t x = 0;
5165 const struct permbanlist *c = 0;
5166 for (c = permbanhead; c != NULL; c = c->next) {
5167 i++;
5168 ++x;
5169 #ifdef WIN32
5170 sprintf (DATA,"%s %s:%d", DATA, c->uh, (int)
5171 #else
5172 snprintf (DATA,sizeof(DATA), "%s %s:%d", DATA, c->uh, (int)
5173 #endif
5174 c->counter);
5175 if (i > 8) {
5176 S ("NOTICE %s :%s\n", nick, DATA);
5177 i = 0;
5178 memset (DATA, 0, sizeof (DATA));
5179 db_sleep (2);
5180 }
5181 }
5182 S ("NOTICE %s :%s\n", nick, DATA);
5183 S
5184 ("NOTICE %s :End of PERMBAN list; %d ban%s found.\n",
5185 nick, x, (x == 1) ? "" : "s");
5186 }
5187
5188 /**
5189 * Output the helper list to a nickname.
5190 * 6/22, Dan:
5191 * - Changed helperlist* c to be a pointer to const data
5192 * - Changed initialization of DATA, and size to be a
5193 * power of 2
5194 * - Added initialization of c
5195 * - Changed while loop to for loop
5196 * - Changed types of i, x to size_t since they should be
5197 * unsigned.
5198 * - Added reinitialization of DATA using memset() (changed from
5199 * strcpy(DATA,""))
5200 */
5201 void
show_helper_list(const char * nick,long level)5202 show_helper_list (const char *nick, long level)
5203 {
5204 char DATA[STRING_SHORT] = {
5205 0
5206 };
5207 size_t i = 0, x = 0;
5208 const struct helperlist *c = 0;
5209 for (c = helperhead; c != NULL; c = c->next) {
5210 i++;
5211 x++;
5212 if (level == 0) {
5213 i++;
5214 #ifdef LINUX
5215 sprintf (DATA, "%s %s[%s:%d:%d]", DATA, c->uh, c->chan,
5216 c->level, c->num_join);
5217 #else
5218 snprintf (DATA, sizeof(DATA), "%s %s[%s:%d:%d]", DATA,
5219 c->uh, c->chan, c->level, c->num_join);
5220 #endif
5221 }
5222 else {
5223 if (level == c->level) {
5224 #ifdef LINUX
5225 sprintf (DATA, "%s %s[%s:%d:%d]", DATA, c->uh, c->chan,
5226 c->level, c->num_join);
5227 #else
5228 snprintf (DATA, sizeof(DATA), "%s %s[%s:%d:%d]", DATA,
5229 c->uh, c->chan, c->level, c->num_join);
5230 #endif
5231 }
5232 }
5233 if (i > 6) {
5234 S ("NOTICE %s :%s\n", nick, DATA);
5235 i = 0;
5236 memset (DATA, 0, sizeof (DATA));
5237 db_sleep (2);
5238 }
5239 } /* for() */
5240
5241 S ("NOTICE %s :%s\n", nick, DATA);
5242 S
5243 ("NOTICE %s :End of Helper Userlist; %d user%s found.\n",
5244 nick, x, (x == 1) ? "" : "s");
5245 }
5246
5247 int
match_wild(const char * pattern,const char * str)5248 match_wild (const char *pattern, const char *str)
5249 {
5250 char c;
5251 const char *s;
5252 for (;;) {
5253 switch (c = *pattern++) {
5254 case 0:
5255 if (!*str)
5256 R 1;
5257 R 0;
5258 case '?':
5259 ++str;
5260 break;
5261 case '*':
5262 if (!*pattern)
5263 R 1;
5264 s = str;
5265 while (*s) {
5266 if (*s == *pattern && match_wild (pattern, s))
5267 R 1;
5268 ++s;
5269 }
5270 break;
5271 default:
5272 if (*str++ != c)
5273 R 0;
5274 break;
5275 } /* switch */
5276 }
5277 }
5278
5279
5280 #ifndef WIN32
5281 int
stricmp(const char * s1,const char * s2)5282 stricmp (const char *s1, const char *s2)
5283 {
5284 return strcasecmp (s1, s2);
5285 }
5286 #else
5287 int
stricmp(const char * s1,const char * s2)5288 stricmp (const char *s1, const char *s2)
5289 {
5290 register int c;
5291 while ((c = tolower (*s1)) == tolower (*s2)) {
5292 if (c == 0)
5293 return 0;
5294 s1++;
5295 s2++;
5296 }
5297 if (c < tolower (*s2))
5298 return -1;
5299 return 1;
5300 }
5301 #endif
5302
5303
5304 /**
5305 * Removed trailing newline and carriage returns.
5306 * 6/22/00 Dan
5307 * Rewrote to be more efficient, reduced from O(2n) to O(n)
5308 */
5309 void
stripline(char * ptr)5310 stripline (char *ptr)
5311 {
5312 for (; ptr && *ptr; ++ptr) {
5313 if ('\r' == *ptr || '\n' == *ptr) {
5314 *ptr = 0;
5315 return;
5316 }
5317 }
5318 }
5319
5320
5321 int
Send()5322 Send ()
5323 {
5324 struct sendq *c;
5325 char output[STRING_LONG];
5326 c = sendqhead;
5327 get_sendq_count (0);
5328 if (c == NULL) {
5329 send_tog = 0;
5330 R - 1;
5331 }
5332 if (DebuG == 1)
5333 printf ("OUT: %s\n", c->data);
5334 #ifdef DEBUG2
5335 log ("darkbot_debug.log", "OUT: %s\n", c->data);
5336 #endif
5337 strncpy (output, c->data, sizeof(output));
5338 del_sendq (0);
5339 R (writeln (output));
5340 }
5341
5342
5343 /**
5344 * Write a character array to a socket connection.
5345 * 6/22/00 Dan
5346 * Method argument now pointer to const data.
5347 */
5348 int
writeln(const char * b)5349 writeln (const char *b)
5350 {
5351 return (write (socketfd, b, strlen (b))
5352 < 0) ? 0 : 1;
5353 }
5354
5355
5356 int
get_connection(const char * hostname,const char * vhostname,int port)5357 get_connection (const char *hostname, const char *vhostname, int port)
5358 {
5359 struct sockaddr_in sa;
5360 struct hostent *hp;
5361 int sckfd, f = 1;
5362 if (vhostname == NULL)
5363 f = 0;
5364 else if (strlen (vhostname) < 1)
5365 f = 0;
5366 if ((sckfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
5367 R (-1);
5368 memset (&sa, 0, sizeof (struct sockaddr_in));
5369 sa.sin_family = AF_INET;
5370 sa.sin_addr.s_addr = (f ? inet_addr (vhostname) : INADDR_ANY);
5371 if ((INADDR_NONE == sa.sin_addr.s_addr)
5372 && f) {
5373 hp = gethostbyname (vhostname);
5374 if (hp) {
5375 bcopy (hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
5376 }
5377 else {
5378 sa.sin_addr.s_addr = INADDR_ANY;
5379 }
5380 }
5381 if (bind
5382 (sckfd, (struct sockaddr *) &sa,
5383 sizeof (struct sockaddr_in)) < 0) {
5384 R (-9);
5385 }
5386 memset (&sa, 0, sizeof (struct sockaddr_in));
5387 sa.sin_family = AF_INET;
5388 sa.sin_port = htons (port);
5389 sa.sin_addr.s_addr = inet_addr (hostname);
5390 setsockopt (sckfd, SOL_SOCKET, SO_LINGER, 0, 0);
5391 setsockopt (sckfd, SOL_SOCKET, SO_REUSEADDR, 0, 0);
5392 setsockopt (sckfd, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
5393 if (INADDR_NONE == sa.sin_addr.s_addr) {
5394 if ((hp = gethostbyname (hostname)) == NULL) {
5395 errno = ECONNREFUSED;
5396 printf ("Can't find hostname: %s\n", hostname);
5397 R (-1);
5398 }
5399 memcpy (&sa.sin_addr, hp->h_addr, hp->h_length);
5400 }
5401 if (connect (sckfd, (struct sockaddr *) &sa, sizeof (sa)) < 0) {
5402 close (sckfd);
5403 printf
5404 ("\nUnable to make connection to host `%s:%d'\n\n",
5405 BS, (int) BP); R (-1);
5406 }
5407 R (sckfd);
5408 }
5409
5410 int
readln()5411 readln ()
5412 {
5413 char ch;
5414 int i = 0;
5415 do {
5416 if (read (socketfd, &ch, 1) < 1)
5417 R (0);
5418 if (ch >= 32 || ch <= 126)
5419 if (i < 524 - 1)
5420 L[i++] = ch;
5421 }
5422 while (ch != '\n');
5423 L[i] = '\0';
5424 R 1;
5425 }
5426
5427 void
log(const char * filename,const char * format,...)5428 log (const char *filename, const char *format, ...)
5429 {
5430 va_list arglist;
5431 FILE *fp;
5432 fp = fopen (filename, "a");
5433 if (NULL == fp) {
5434 /* I guess there's no sense in trying to log the error :) */
5435 return;
5436 }
5437
5438 va_start (arglist, format);
5439 vfprintf (fp, format, arglist);
5440 va_end (arglist);
5441 fclose (fp);
5442 }
5443
5444 /**
5445 * Convert a character array to all lowercase.
5446 * 6/23/00 Dan:
5447 * - Rewrote to be more compact and a bit more efficient
5448 */
5449 char *
strlwr(char * buf)5450 strlwr (char *buf)
5451 {
5452 char *ptr = buf;
5453 for (; ptr && *ptr; ++ptr) {
5454 *ptr = tolower (*ptr);
5455 }
5456 return buf;
5457 }
5458
5459 void
trailing_blanks(char * str)5460 trailing_blanks (char *str)
5461 {
5462 int i;
5463 if (str == NULL)
5464 R;
5465 for (i = strlen (str); i > 0; i--) {
5466 if (isspace (str[i - 1]))
5467 str[i - 1] = '\0';
5468 else
5469 R;
5470 }
5471 }
5472
5473
5474 void
parse_server_msg(fd_set * read_fds)5475 parse_server_msg (fd_set * read_fds)
5476 {
5477 if (FD_ISSET (socketfd, read_fds)) {
5478 if (readln () > 0) {
5479 NUMLINESSEEN++;
5480 parse (L);
5481 }
5482 else {
5483 close (socketfd);
5484 }
5485 }
5486 }
5487
5488
5489 long
f_f(char * host)5490 f_f (char *host)
5491 {
5492 int i;
5493 for (i = 0; i < fc; i++)
5494 if (!strcasecmp (ood[i].host, host))
5495 R i;
5496 R - 1;
5497 }
5498
5499 void
get_s()5500 get_s ()
5501 {
5502 char temp[20];
5503 long i = 0;
5504 i = strlen (rp391);
5505 while (i > 0) {
5506 i--;
5507 #ifdef WIN32
5508 sprintf (temp,"%s%c", dbVersion, rp391[i]);
5509 #else
5510 snprintf (temp,sizeof(temp), "%s%c", dbVersion, rp391[i]);
5511 #endif
5512 strncpy (dbVersion, temp, sizeof(dbVersion));
5513 }
5514 }
5515
5516 void
a_f(char * host)5517 a_f (char *host)
5518 {
5519 if (++fc > 100)
5520 fc = 0;
5521 fc--;
5522 strncpy (ood[fc].host, host, sizeof(ood[fc].host));
5523 ood[fc].time = time (NULL);
5524 ood[fc].count = 0;
5525 ood[fc].value = false;
5526 fc++;
5527 }
5528
5529 void
reset_()5530 reset_ ()
5531 {
5532 int i;
5533 for (i = 0; i < fc; i++) {
5534 if (ood[i].value && (time (NULL) - ood[i].time) > rt) {
5535 ood[i].count = 0;
5536 ood[i].time = time (NULL);
5537 ood[i].value = false;
5538 ood[i].kick = 0;
5539 }
5540 }
5541 }
5542
5543 char *
date()5544 date ()
5545 {
5546 time_t timer;
5547 time (&timer);
5548 strncpy (strbuff, ctime (&timer), sizeof(strbuff));
5549 stripline (strbuff);
5550 return strbuff;
5551 }
5552
5553 /**
5554 * Allocate a new character array. Copy into it at most
5555 * maxBytes bytes.
5556 */
5557 char *
db_strndup(const char * dupMe,size_t maxBytes)5558 db_strndup (const char *dupMe, size_t maxBytes)
5559 {
5560 char *ptr = 0;
5561 char *retMe = 0;
5562 /* Configure maxBytes to be the number of bytes to copy */
5563 maxBytes = min (strlen (dupMe), maxBytes);
5564 /* Allocate the return buffer. */
5565 retMe = (char *) malloc (maxBytes + 1);
5566 /* Was the allocation successful? */
5567 if (NULL == retMe) {
5568 return NULL;
5569 }
5570
5571 /*
5572 * ptr will point to the byte to which to copy the next
5573 * source byte.
5574 */
5575 ptr = retMe;
5576 /*
5577 * Continue while dupMe is valid and we are < maxBytes number
5578 * of bytes copied. This is typecase here because size_t is
5579 * unsigned, so comparing against > 0 *should* produce a
5580 * warning :)
5581 */
5582 while (dupMe && (int) maxBytes-- > 0) {
5583 *ptr++ = *dupMe++;
5584 }
5585
5586 /* Be sure to NULL terminate the array */
5587 *ptr = 0;
5588 return retMe;
5589 }
5590
5591 /**
5592 * Output information about the bot's database to a target.
5593 * 6/22 Dan:
5594 * - Changed both method arguments to be pointers to const data,
5595 * this is a read only method.
5596 */
5597 void
show_info2(const char * target,const char * source)5598 show_info2 (const char *target, const char *source)
5599 {
5600 S
5601 ("PRIVMSG %s :%s, src: %s (%d lines of code), compiled @ %s. "
5602 "I have processed %ld lines of text since startup...\n",
5603 target, source, __FILE__, __LINE__, __DATE__, NUMLINESSEEN);
5604 }
5605
5606