muhstik- irc flooding solution |
git clone git://git.acid.vegas/muhstik.git |
Log | Files | Refs | Archive | README |
print.c (12603B)
1 /* Muhstik, Copyright (C) 2001-2002, Louis Bavoil <mulder@gmx.fr> */ 2 /* 2009-2011, Leon Kaiser <literalka@gnaa.eu> */ 3 /* */ 4 /* This program is free software; you can redistribute it and/or */ 5 /* modify it under the terms of the GNU Library General Public License */ 6 /* as published by the Free Software Foundation; either version 2 */ 7 /* of the License, or (at your option) any later version. */ 8 /* */ 9 /* This program is distributed in the hope that it will be useful, */ 10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 12 /* GNU Library General Public License for more details. */ 13 14 /* {{{ Header includes */ 15 #include <pthread.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <stdarg.h> 19 #include <time.h> 20 21 #include "../include/print.h" 22 #include "../include/string.h" 23 #include "../include/lists.h" 24 #include "../include/clone.h" 25 /* }}} */ 26 /* {{{ Variables */ 27 /* {{{ External Variables */ 28 extern config_t conf; 29 extern int mute; 30 extern char *channel[]; 31 extern char *broth[]; 32 extern clone_t *cl[]; 33 extern const char *strtype[]; 34 extern char *op_nick; 35 extern int t0; 36 extern pthread_mutex_t mutex[]; 37 /* }}} */ 38 /* }}} */ 39 /* {{{ print_*() */ 40 inline void print_error(char *prefix) 41 { 42 print(1, 0, 0, "%s: %s", prefix, strerror(errno)); 43 } 44 45 void print_irc(char *buffer, int color, int sock) 46 { 47 static char *color_codes[] = { "", "\026", "\0032", "\0037", "\0035", "\00314" }; 48 49 send(sock, color_codes[color], strlen(color_codes[color]), 0); 50 send(sock, buffer, strlen(buffer), 0); 51 } 52 53 void print_privmsg(char *buffer, int color, int dest) 54 { 55 char tosend[BIGBUF]; 56 dest = -dest-2; 57 snprintf(tosend, sizeof(tosend), "PRIVMSG %s :%s", op_nick, buffer); 58 print_irc(tosend, color, cl[dest]->sock); 59 } 60 61 void print_console(char *buffer, int ret, int color, int dest) 62 { 63 int len; 64 static char *color_term[] = { "\033[0;0m", "\033[0;35m", "\033[0;34m", "\033[0;1;1m", "\033[0;31m", "" }; 65 66 if (!conf.nocolor) 67 { 68 len = strlen(buffer) - 1; 69 if (buffer[len] == '\n') 70 { 71 ret = 1; 72 } 73 if (ret) 74 { 75 buffer[len] = 0; 76 } 77 printf("%s", color_term[color]); 78 } 79 80 printf("%s", buffer); 81 82 if (!conf.nocolor) 83 { 84 printf("%s", color_term[0]); 85 if (ret) 86 { 87 printf("\n"); 88 } 89 } 90 } 91 92 void print(int ret, int color, int dest, const char *fmt, ...) 93 { 94 char buffer[BIGBUF]; 95 va_list ap; 96 97 if (dest == -1) 98 { 99 return; 100 } 101 102 va_start(ap, fmt); 103 vsnprintf(buffer, sizeof(buffer), fmt, ap); 104 va_end(ap); 105 106 if (ret) 107 { 108 StrCat(buffer, "\n", sizeof(buffer)); 109 } 110 111 if (dest <= -2) 112 { 113 print_privmsg(buffer, color, dest); 114 return; 115 } 116 117 if (!mute) 118 { 119 pthread_mutex_lock(&mutex[1]); 120 print_console(buffer, ret, color, dest); 121 pthread_mutex_unlock(&mutex[1]); 122 } 123 } 124 125 void print_prefix(clone_t *clone, int color, int dest) 126 { 127 print(0, color, dest, "[%s;%s;%s] ", clone->nick, clone->proxy ? clone->proxy : "", clone->server); 128 } 129 130 void print_desc(int out, char *com, char *desc) 131 { 132 register int i; 133 134 print(0, 0, out, "%s", com); 135 for (i = strlen(com); i < LEN_TAB; ++i) 136 { 137 print(0, 0, out, " "); 138 } 139 print(1, 0, out, "%s", desc); 140 } 141 142 void print_line(int out) 143 { 144 register int i; 145 146 if (out >= 0) 147 { 148 for (i = 0; i < LEN_LINE; ++i) 149 { 150 print(0, 0, out, "-"); 151 } 152 } 153 print(0, 0, out, "\n"); 154 } 155 156 void print_motd(int out) 157 { 158 FILE *f; 159 char buffer[BIGBUF]; 160 161 if ((f = fopen(conf.motd, "r"))) 162 { 163 while (fgets(buffer, sizeof(buffer), f)) 164 { 165 print(0, 0, out, "%s", buffer); 166 } 167 fclose(f); 168 } 169 } 170 /* }}} */ 171 /* {{{ usage() */ 172 void usage(int out) 173 { 174 char *(*p)[2]; 175 static char *desc_general[][2] = 176 { 177 { "help or ?", "print this help" }, 178 { STATUS, "print status {uptime,nicks,channels,users}" }, 179 { NULL, NULL } 180 }; 181 static char *desc_actions[][2] = 182 { 183 { "join", "JOIN or reJOIN a channel" }, 184 { "part", "PART a channel" }, 185 { "quit", "QUIT IRC and shut down the bot" }, 186 { "privmsg", "send a message or a CTCP to a nick or a channel" }, 187 { NICKS, "change all clone nicks" }, 188 { KICKBAN, "kickban a nick from a channel" }, 189 { ECHO, "make all the clones repeat what one nick says" }, 190 { TAKEOVER, "collide nicks on different servers" }, 191 { SELECT, "make one clone send something to IRC" }, 192 { NULL, NULL } 193 }; 194 static char *desc_modes[][2] = 195 { 196 { AGGRESS, "deop enemys actively and kick them on privmsg" }, 197 { PEACE, "don't automatically deop enemies" }, 198 { RANDOM, "use the wordlist to set the nicks" }, 199 { MUTE, "stop writing to stdout" }, 200 { NULL, NULL } 201 }; 202 static char *desc_env[][2] = 203 { 204 { NICKLIST, "change the active wordlist" }, 205 { CHANKEY, "set a key to be used when reJOINing a +k channel" }, 206 { LOAD, "load a clone dynamically" }, 207 { ADDPROT "/" RMPROT, "set/unset a protected nick" }, 208 { ADDJUPE "/" RMJUPE, "add/remove a nick to/from the jupe list" }, 209 { ADDOP "/" RMOP, "add/remove a pattern to/from the aop list" }, 210 { ADDSHIT "/" RMSHIT, "add/remove a pattern to/from the shitlist" }, 211 { ADDSCAN "/" RMSCAN, "set/unset a scan on JOIN" }, 212 { NULL, NULL } 213 }; 214 215 print(1, 0, out, "Available commands:"); 216 print_line(out); 217 for (p = desc_general; **p; ++p) 218 { 219 print_desc(out, (*p)[0], (*p)[1]); 220 } 221 222 print(1, 0, out, "\n- Actions:"); 223 for (p = desc_actions; **p; ++p) 224 { 225 print_desc(out, (*p)[0], (*p)[1]); 226 } 227 228 print(1, 0, out, "%s, %s, %s, %s, %s: mass{op,KICK,KICKban,deop,unban}", MASSOP, MASSKICK, MASSKICKBAN, MASSDEOP, MASSUNBAN); 229 print(1, 0, out, "{KICK,MODE,TOPIC}: IRC protocol"); 230 231 print(1, 0, out, "\n- Modes:"); 232 for (p = desc_modes; **p; ++p) 233 { 234 print_desc(out, (*p)[0], (*p)[1]); 235 } 236 237 print(1, 0, out, "\n- Environment:"); 238 for (p = desc_env; **p; ++p) 239 { 240 print_desc(out, (*p)[0], (*p)[1]); 241 } 242 243 print_line(out); 244 } 245 /* }}} */ 246 /* {{{ print_uptime() */ 247 void print_uptime(int out) 248 { 249 int uptime; 250 uptime = time(NULL) - t0; 251 print(1, 0, out, "muhstik v. %s, uptime: %d days, %02d:%02d:%02d", VERSION, uptime/86400, (uptime/3600)%24, (uptime/60)%60, uptime%60); 252 } 253 /* }}} */ 254 /* {{{ nofclones() */ 255 int nofclones() 256 { 257 register int i; 258 int k = 0; 259 clone_t **pcl; 260 261 for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl) 262 { 263 if (*pcl && (*pcl)->online) 264 { 265 ++k; 266 } 267 } 268 for (i = 0; i < MAX_BROTHERS; ++i) 269 { 270 if (broth[i]) 271 { 272 ++k; 273 } 274 } 275 return k; 276 } 277 /* }}} */ 278 /* {{{ is_empty_*() booleans */ 279 int is_empty_str(char **list, int max) 280 { 281 register int i; 282 283 for (i = 0; i < max; ++i, ++list) 284 { 285 if (*list) 286 { 287 return 0; 288 } 289 } 290 return 1; 291 } 292 293 int is_empty_scan(clone_t **list, int max) 294 { 295 register int i; 296 for (i = 0; i < max; ++i, ++list) 297 { 298 if (*list && (*list)->scan) 299 { 300 return 0; 301 } 302 } 303 return 1; 304 } 305 /* }}} */ 306 /* {{{ print_nicks() */ 307 void print_nicks(int out) 308 { 309 char nicks[BIGBUF]; 310 char **p; 311 clone_t **pcl; 312 register int i; 313 314 if (!(i = nofclones())) 315 { 316 print(1, 0, out, "- no clones online"); 317 return; 318 } 319 320 print(1, 0, out, "- %d clones online:", i); 321 322 memset(nicks, 0, sizeof(nicks)); 323 324 for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl) 325 { 326 if (*pcl && (*pcl)->online) 327 { 328 StrCat(nicks, (*pcl)->nick, sizeof(nicks)); 329 StrCat(nicks, " ", sizeof(nicks)); 330 } 331 } 332 333 for (i = 0, p = broth; i < MAX_BROTHERS; ++i, ++p) 334 { 335 if (*p) 336 { 337 StrCat(nicks, *p, sizeof(nicks)); 338 StrCat(nicks, " ", sizeof(nicks)); 339 } 340 } 341 342 print(1, 0, out, "%s", nicks); 343 } 344 /* }}} */ 345 /* {{{ nops() */ 346 int nops(int chid) 347 { 348 register int i; 349 clone_t **pcl; 350 int k = 0; 351 352 for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl) 353 { 354 if (is_op(*pcl, chid)) 355 { 356 ++k; 357 } 358 } 359 360 return k; 361 } 362 /* }}} */ 363 /* {{{ print_*() */ 364 void print_channels(int out) 365 { 366 char **p; 367 register int i; 368 369 print(1, 0, out, "- channels:"); 370 for (i = 0, p = channel; i < MAX_CHANS; ++i, ++p) 371 { 372 if (*p) 373 { 374 print(1, 0, out, "%s (%d opped) ", *p, nops(i)); 375 } 376 } 377 } 378 379 void print_scans(int out) 380 { 381 clone_t **p; 382 register int i; 383 384 print(1, 0, out, "- scans:"); 385 for (i = 0, p = cl; i < MAX_CLONES; ++i, ++p) 386 { 387 if ((*p) && (*p)->online && (*p)->scan) 388 { 389 print(1, 0, out, "[%d] nick=%s, type=%s, port=%d, server=%s, saveto=%s", 390 i, (*p)->nick, strtype[(*p)->scan->type], (*p)->scan->proxy_port, (*p)->scan->server, (*p)->scan->save); 391 } 392 } 393 } 394 395 void print_aops(int out) 396 { 397 char **p; 398 register int i; 399 400 print(1, 0, out, "- auto op list:"); 401 for (i = 0, p = conf.aop; i < MAX_AOPS; ++i, ++p) 402 { 403 if (*p) 404 { 405 print(1, 0, out, "[%d] %s", i, *p); 406 } 407 } 408 } 409 void print_jupes(int out) 410 { 411 char **p; 412 register int i; 413 414 print(1, 0, out, "- nick jupe list:"); 415 for (i = 0, p = conf.jupe; i < MAX_JUPES; ++i, ++p) 416 { 417 if (*p) 418 { 419 print(1, 0, out, "[%d] %s", i, *p); 420 } 421 } 422 } 423 424 void print_prot(int out) 425 { 426 char **p; 427 register int i; 428 429 print(1, 0, out, "- protected nicks:"); 430 for (i = 0, p = conf.prot; i < MAX_PROTS; ++i, ++p) 431 { 432 if (*p) 433 { 434 print(1, 0, out, "[%d] %s", i, *p); 435 } 436 } 437 } 438 439 void print_shit(int out) 440 { 441 char **p; 442 register int i; 443 444 print(1, 0, out, "- shitlist:"); 445 for (i = 0, p = conf.shit; i < MAX_SHITS; ++i, ++p) 446 { 447 if (*p) 448 { 449 if (strchr(*p, ':')) 450 { 451 print(1, 0, out, "[%d] %s", i, *p); 452 } 453 else 454 { 455 print(1, 0, out, "[%d] %s :no reason", i, *p); 456 } 457 } 458 } 459 } 460 /* }}} */ 461 /* {{{ status() */ 462 void status(int out) 463 { 464 print_line(out); 465 print_uptime(out); 466 print_nicks(out); 467 468 if (!is_empty_str(channel, MAX_CHANS)) 469 { 470 print_channels(out); 471 } 472 473 if (!is_empty_scan(cl, MAX_CLONES)) 474 { 475 print_scans(out); 476 } 477 478 if (!is_empty_str(conf.aop, MAX_AOPS)) 479 { 480 print_aops(out); 481 } 482 483 if (!is_empty_str(conf.jupe, MAX_JUPES)) 484 { 485 print_jupes(out); 486 } 487 488 if (!is_empty_str(conf.prot, MAX_PROTS)) 489 { 490 print_prot(out); 491 } 492 493 if (!is_empty_str(conf.shit, MAX_SHITS)) 494 { 495 print_shit(out); 496 } 497 498 print_line(out); 499 } 500 /* }}} */