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 /* }}} */