muhstik

- irc flooding solution
git clone git://git.acid.vegas/muhstik.git
Log | Files | Refs | Archive | README

control.c (26843B)

      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 <time.h>
     19 #include <unistd.h>
     20 #include <time.h>
     21 
     22 #include "../include/control.h"
     23 #include "../include/load.h"
     24 #include "../include/muhstik.h"
     25 #include "../include/print.h"
     26 #include "../include/string.h"
     27 #include "../include/lists.h"
     28 #include "../include/mass.h"
     29 /* }}} */
     30 /* {{{ Variables */
     31 /* {{{ External variables */
     32 extern config_t conf;
     33 extern int mass_ch;
     34 extern int mass_mode;
     35 extern char *mass_server;
     36 extern char *mass_reas;
     37 extern clone_t *cl[];
     38 extern char *channel[];
     39 extern char *chankey[];
     40 extern queue names_op[];
     41 extern queue names[];
     42 extern pthread_mutex_t mutex[];
     43 /* }}} */
     44 /*{{{ Global variables */
     45 int mute;
     46 char *target;
     47 int echo_mode;
     48 /* }}} */
     49 /* }}} */
     50 /* {{{ get*() */
     51 int getchid(char *s)
     52 {
     53      register int i;
     54 
     55      for (i = 0; i < MAX_CHANS; ++i)
     56      {
     57           if (channel[i] && !StrCompare(channel[i], s))
     58           {
     59                return i;
     60           }
     61      }
     62 
     63      return -1;
     64 }
     65 
     66 clone_t *getop(int chid)
     67 {
     68      register int i;
     69      clone_t **pcl;
     70      time_t now;
     71      now = time(NULL);
     72 
     73      for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
     74      {
     75           if (is_op(*pcl, chid) && (*pcl)->lastsend != now)
     76           {
     77                return *pcl;
     78           }
     79      }
     80 
     81      for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
     82      {
     83           if (is_op(*pcl, chid))
     84           {
     85                return *pcl;
     86           }
     87      }
     88 
     89      return NULL;
     90 }
     91 
     92 clone_t *getone(char *s)
     93 {
     94      register int i;
     95      clone_t **pcl;
     96 
     97      for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
     98      {
     99           if ((*pcl) && (*pcl)->online && !StrCompare((*pcl)->server, s))
    100           {
    101                return *pcl;
    102           }
    103      }
    104 
    105      return NULL;
    106 }
    107 
    108 clone_t *getscan()
    109 {
    110      register int i;
    111      clone_t **pcl;
    112 
    113      for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
    114      {
    115           if ((*pcl) && (*pcl)->online && !(*pcl)->scan)
    116           {
    117                return *pcl;
    118           }
    119      }
    120 
    121      return NULL;
    122 }
    123 /* }}} */
    124 /* {{{ join_delayed() */
    125 void join_delayed(char *buffer)
    126 {
    127      int delay;
    128      register int id;
    129      clone_t **pcl;
    130      time_t now;
    131 
    132      if (sscanf(buffer, "%*s %s %d", buffer, &delay) != 2)
    133      {
    134           return;
    135      }
    136 
    137      if ((mass_ch = getchid(buffer)) == -1)
    138      {
    139           return;
    140      }
    141 
    142      now = time(NULL);
    143      for (id = 0, pcl = cl; id < MAX_CLONES; ++id, ++pcl)
    144      {
    145           if ((*pcl) && (*pcl)->online)
    146           {
    147                (*pcl)->rejoin_time = now + delay * id;
    148           }
    149      }
    150 }
    151 /* }}} */
    152 /* {{{ Parsing and interpreting */
    153 /* {{{ Parsing functions */
    154 void parse_mute(char *buffer, int out)
    155 {
    156      mute = (mute + 1) & 01;
    157 }
    158 
    159 void parse_join(char *buffer, int out)
    160 {
    161      char tosend[MEDBUF+1];
    162      char parm[MEDBUF+1];
    163      int i;
    164      int delay;
    165 
    166      if (StrParam(parm, sizeof(parm), buffer, 1))
    167      {
    168           print(1, 0, out, "Usage: join <chan> [<delay>] [<key>]");
    169           return;
    170      }
    171      if (occur_table(parm, channel, MAX_CHANS))
    172      {
    173           print(1, 0, out, "rejoining %s", parm);
    174           snprintf(tosend, sizeof(tosend), "PART %s\n", parm); /* TODO: Optional PART message/reason. */
    175           send2clones(tosend);
    176           pthread_mutex_unlock(&mutex[0]);
    177           sleep(1);
    178           pthread_mutex_lock(&mutex[0]);
    179           snprintf(tosend, sizeof(tosend), "JOIN %s\n", parm);
    180           send2clones(tosend);
    181           return;
    182      }
    183      if ((i = add_table(parm, channel, MAX_CHANS)) == -1)
    184      {
    185           print(1, 0, out, "No more channel available");
    186           return;
    187      }
    188      switch (sscanf(buffer, "%*s %*s %d %"MEDBUF_TXT"s", &delay, parm))
    189      {
    190           case 2:
    191                free(chankey[i]);
    192                chankey[i] = StrDuplicate(parm);
    193                /* FALL THROUGH */
    194           case 1:
    195                print(1, 0, out, "joining %s with a delay of %d", parm, delay);
    196                join_delayed(buffer);
    197                break;
    198           default:
    199                print(1, 0, out, "joining %s", parm);
    200                send2clones(buffer);
    201      }
    202 }
    203 
    204 void parse_part(char *buffer, int out)
    205 {
    206      char parm[MEDBUF];
    207      int chid;
    208 
    209      if (StrParam(parm, sizeof(parm), buffer, 1))
    210      {
    211           print(1, 0, out, "Usage: part <chan> [:<reason>]");
    212           return;
    213      }
    214 
    215      if ((chid = remove_table(parm, channel, MAX_CHANS)))
    216      {
    217           print(1, 0, out, "%s: no such chan", parm);
    218           return;
    219      }
    220 
    221      free(chankey[chid]);
    222      chankey[chid] = NULL;
    223 
    224      clear_queue(&names[chid]);
    225      clear_queue(&names_op[chid]);
    226 
    227      print(1, 0, out, "leaving %s", parm);
    228      send2clones(buffer);
    229 }
    230 
    231 void parse_mode(char *buffer, int out)
    232 {
    233      char parm[MEDBUF];
    234      int chid;
    235      clone_t *clone;
    236 
    237      if (StrParam(parm, sizeof(parm), buffer, 2))
    238      {
    239           if (!StrCmpPrefix(buffer, "mode"))
    240           {
    241                print(1, 0, out, "Usage: MODE <dest> <StrParams>");
    242                return;
    243           }
    244           if (!StrCmpPrefix(buffer, "kick"))
    245           {
    246                print(1, 0, out, "Usage: KICK <channel> <nick> [:<reason>]");
    247                return;
    248           }
    249           if (!StrCmpPrefix(buffer, "topic"))
    250           {
    251                print(1, 0, out, "Usage: TOPIC <channel> :<topic>");
    252                return;
    253           }
    254      }
    255      StrParam(parm, sizeof(parm), buffer, 1);
    256      if ((chid = getchid(parm)) == -1)
    257      {
    258           print(1, 0, out, "%s: no such chan", parm);
    259           return;
    260      }
    261      if (!(clone = getop(chid)))
    262      {
    263         print(1, 0, out, "Error: no ops in %s", parm);
    264         return;
    265      }
    266      send(clone->sock, buffer, strlen(buffer), 0);
    267 }
    268 
    269 void parse_privmsg(char *buffer, int out)
    270 {
    271      char parm[MEDBUF];
    272 
    273      if (StrParam(parm, sizeof(parm), buffer, 2))
    274      {
    275           StrFirstToken(buffer);
    276           print(1, 0, out, "Usage: %s <dest> :<message>", buffer);
    277           return;
    278      }
    279      send2clones(buffer);
    280 }
    281 
    282 void parse_kb(char *buffer, int out)
    283 {
    284      char parm[MEDBUF+1];
    285      clone_t *clone;
    286 
    287      if (StrParam(parm, sizeof(parm), buffer, 2))
    288      {
    289           print(1, 0, out, "Usage: %s <chan> <nick> [:<reason>]", KICKBAN);
    290           return;
    291      }
    292 
    293      StrParam(parm, sizeof(parm), buffer, 1);
    294      if ((mass_ch = getchid(parm)) == -1)
    295      {
    296           print(1, 0, out, "%s: no such chan", parm);
    297           return;
    298      }
    299 
    300      if (!(clone = getop(mass_ch)))
    301      {
    302           return;
    303      }
    304 
    305      free(mass_reas);
    306      if (sscanf(buffer, "%*s %*s %*s :%"MEDBUF_TXT"[^\n]", parm) != 1)
    307      {
    308           mass_reas = NULL;
    309      }
    310      else
    311      {
    312           mass_reas = StrDuplicate(parm);
    313      }
    314 
    315      if (!StrParam(parm, sizeof(parm), buffer, 2))
    316      {
    317           kickban(clone, parm);
    318           print(1, 0, out, "kickban %s", SETON);
    319      }
    320 }
    321 
    322 void parse_mkb(char *buffer, int out)
    323 {
    324      char parm[MEDBUF+1];
    325      clone_t *clone;
    326 
    327      if (StrParam(parm, sizeof(parm), buffer, 1))
    328      {
    329           StrFirstToken(buffer);
    330           print(1, 0, out, "Usage: %s <chan> [:<reason>]", buffer);
    331           return;
    332      }
    333 
    334      if ((mass_ch = getchid(parm)) == -1)
    335      {
    336           print(1, 0, out, "%s: no such chan", parm);
    337           return;
    338      }
    339 
    340      if (!(clone = getop(mass_ch)))
    341           return;
    342 
    343      free(mass_reas);
    344      if (sscanf(buffer, "%*s %*s :%"MEDBUF_TXT"[^\n]", parm) != 1)
    345      {
    346           mass_reas = NULL;
    347      }
    348      else
    349      {
    350           mass_reas = StrDuplicate(parm);
    351      }
    352 
    353      StrFirstToken(buffer);
    354      print(1, 0, out, "%s %s on %s", buffer, SETON, channel[mass_ch]);
    355 
    356      mass_mode = !StrCmpPrefix(buffer, MASSKICKBAN) ? MKB : MK;
    357      init_massdo(mass_ch, mass_mode);
    358 }
    359 
    360 void parse_to(char *buffer, int out)
    361 {
    362      char parm[MEDBUF];
    363      char chan[MINIBUF];
    364      clone_t *clone1;
    365      clone_t *clone2;
    366 
    367      if (StrParam(parm, sizeof(parm), buffer, 3))
    368      {
    369           StrFirstToken(buffer);
    370           print(1, 0, out, "Usage: %s <chan> <server1> <server2>", buffer);
    371           print(1, 0, out, "server1 = server to get op nicks");
    372           print(1, 0, out, "server2 = server to change nicks");
    373           return;
    374      }
    375 
    376      if (!(clone2 = getone(parm)))
    377      {
    378           print(1, 0, out, "no clone online on %s", parm);
    379           return;
    380      }
    381 
    382      StrParam(parm, sizeof(parm), buffer, 2);
    383      if (!(clone1 = getone(parm)))
    384      {
    385           print(1, 0, out, "no clone online on %s", parm);
    386           return;
    387      }
    388 
    389      StrParam(chan, sizeof(chan), buffer, 1);
    390      print(1, 0, out, "takeover activated on %s", chan);
    391      mass_mode = TO;
    392      mass_server = clone2->server;
    393      init_massdo(mass_ch, mass_mode);
    394 }
    395 
    396 void parse_mo(char *buffer, int out)
    397 {
    398      char parm[MEDBUF];
    399      clone_t *clone;
    400 
    401      if (StrParam(parm, sizeof(parm), buffer, 1))
    402      {
    403           StrFirstToken(buffer);
    404           print(1, 0, out, "Usage: %s <chan>", buffer);
    405           return;
    406      }
    407 
    408      if ((mass_ch = getchid(parm)) == -1)
    409      {
    410           print(1, 0, out, "%s: no such chan", parm);
    411           return;
    412      }
    413 
    414      if (!(clone = getop(mass_ch)))
    415      {
    416           return;
    417      }
    418 
    419      StrFirstToken(buffer);
    420      print(1, 0, out, "%s %s on %s", buffer, SETON, channel[mass_ch]);
    421 
    422      if (!StrCmpPrefix(buffer, MASSOP))
    423      {
    424           force_massop();
    425           return;
    426      }
    427 
    428      if (!StrCmpPrefix(buffer, MASSDEOP))
    429      {
    430           mass_mode = MD;
    431           init_massdo(mass_ch, mass_mode);
    432           return;
    433      }
    434 
    435      send_sock(clone->sock, "MODE %s +b\n", channel[mass_ch]);
    436 }
    437 
    438 void parse_addprot(char *buffer, int out)
    439 {
    440      char parm[MEDBUF];
    441      int i;
    442 
    443      if (StrParam(parm, sizeof(parm), buffer, 1))
    444      {
    445           print(1, 0, out, "Usage: %s <nick>", ADDPROT);
    446           return;
    447      }
    448      if (!occur_table(parm, conf.prot, MAX_PROTS))
    449      {
    450           if ((i = add_table(parm, conf.prot, MAX_PROTS)) != -1)
    451           {
    452                print(1, 0, out, "[%d] %s protected", i, parm);
    453           }
    454           else
    455           {
    456                print(1, 0, out, "list full");
    457           }
    458      }
    459 }
    460 
    461 void parse_rmprot(char *buffer, int out)
    462 {
    463      char parm[MINIBUF];
    464      int i;
    465 
    466      if (StrParam(parm, sizeof(parm), buffer, 1))
    467      {
    468           print(1, 0, out, "Usage: %s <ID>", RMPROT);
    469           return;
    470      }
    471      if ((i = atoi(parm)) < 0)
    472      {
    473           print(1, 0, out, "protected nick list cleared");
    474           clear_table(conf.prot, MAX_PROTS);
    475           return;
    476      }
    477      if (i < MAX_PROTS && conf.prot[i])
    478      {
    479           print(1, 0, out, "%s not protected anymore", conf.prot[i]);
    480           free(conf.prot[i]);
    481           conf.prot[i] = NULL;
    482           return;
    483      }
    484      print(1, 0, out, "no such entry");
    485 }
    486 
    487 void parse_addop(char *buffer, int out)
    488 {
    489      char parm[MEDBUF];
    490      int i;
    491 
    492      if (StrParam(parm, sizeof(parm), buffer, 1) || !is_pattern(parm))
    493      {
    494           print(1, 0, out, "Usage: %s <pattern>", ADDOP);
    495           return;
    496      }
    497      if ((i = add_table(parm, conf.aop, MAX_AOPS)) == -1)
    498      {
    499           print(1, 0, out, "aop list full");
    500           return;
    501      }
    502      print(1, 0, out, "[%d] %s added to the aop list", i, parm);
    503 }
    504 
    505 void parse_rmop(char *buffer, int out)
    506 {
    507      char parm[MINIBUF];
    508      int i;
    509 
    510      if (StrParam(parm, sizeof(parm), buffer, 1))
    511      {
    512           print(1, 0, out, "Usage: %s <ID>", RMOP);
    513           return;
    514      }
    515      if ((i = atoi(parm)) < 0)
    516      {
    517           print(1, 0, out, "auto op list cleared");
    518           clear_table(conf.aop, MAX_AOPS);
    519           return;
    520      }
    521      if (i < MAX_AOPS && conf.aop[i])
    522      {
    523           print(1, 0, out, "%s removed from the aop list", conf.aop[i]);
    524           free(conf.aop[i]);
    525           conf.aop[i] = NULL;
    526           return;
    527      }
    528      print(1, 0, out, "no such entry");
    529 }
    530 
    531 void parse_addjupe(char *buffer, int out)
    532 {
    533      char parm[MEDBUF];
    534      int i;
    535      int idx;
    536      int mon;
    537      unsigned int j;
    538      char cmdbuf[BIGBUF];
    539      clone_t **pcl;
    540 
    541      if (StrParam(parm, sizeof(parm), buffer, 1))
    542      {
    543           print(1, 0, out, "Usage: %s <nick>", ADDJUPE);
    544           return;
    545      }
    546 
    547      if ((idx = occur_table(parm, conf.jupe, MAX_JUPES)) != 0)
    548      {
    549           print(1, 0, out, "nick already juped as [%d]", (idx - 1));
    550           return;
    551      }
    552 
    553      for (i = mon = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
    554      {
    555           if ((*pcl) && (*pcl)->online && (*pcl)->monitor_tmax != 0)
    556           {
    557                for (j = 0; j < (*pcl)->monitor_tmax; ++j) /* ``unsigned'' is not needed, stops a warning when compiled with `-Wsign-compare' */
    558                {
    559                     if ((*pcl)->jupes[j] == NULL)
    560                     {
    561                          if (idx != -1)
    562                          {
    563                               if((idx = add_table(parm, conf.jupe, MAX_JUPES)) == -1)
    564                               {
    565                                    print(1, 0, out, "jupe list full");
    566                                    return;
    567                               }
    568                               else
    569                               {
    570                                    print(1, 0, out, "[%d] %s added to the jupe list", idx, parm);
    571                                    idx = -1;
    572                               }
    573                          }
    574 
    575                          (*pcl)->jupes[j] = StrDuplicate(parm);
    576                          snprintf(cmdbuf, sizeof(cmdbuf), "MONITOR + %s\r\n", parm);
    577                          send((*pcl)->sock, cmdbuf, strlen(cmdbuf), 0);
    578                          print_prefix((*pcl), 0, 0);
    579                          print(1, 0, out, "%s added to my MONITOR list", parm);
    580                          mon++;
    581                          break;
    582                     }
    583                }
    584           }
    585      }
    586 
    587      if(mon == 0)
    588      {
    589           print(1, 0, out, "jupe list full (out of clones that could MONITOR)");
    590      }
    591 }
    592 
    593 void parse_rmjupe(char *buffer, int out)
    594 {
    595      char parm[MINIBUF];
    596      int idx;
    597 
    598      if (StrParam(parm, sizeof(parm), buffer, 1))
    599      {
    600           print(1, 0, out, "Usage: %s <ID>", RMJUPE);
    601           return;
    602      }
    603      if ((idx = atoi(parm)) < 0)
    604      {
    605           clear_table(conf.jupe, MAX_JUPES);
    606           print(1, 0, out, "jupe list cleared");
    607           return;
    608      }
    609      if (idx < MAX_JUPES && conf.jupe[idx])
    610      {
    611           clone_t **pcl = cl;
    612           char *nick = conf.jupe[idx], cmdbuf[BIGBUF];
    613           int i;
    614           unsigned int j;
    615 
    616           print(1, 0, out, "%s removed from the jupe list", nick);
    617           for (i = 0; i < MAX_CLONES; ++i, ++pcl)
    618           {
    619                if ((*pcl) && (*pcl)->online && (*pcl)->monitor_tmax != 0)
    620                {
    621                     for (j = 0; j < (*pcl)->monitor_tmax; ++j) /* `unsigned' is not needed, stops a warning when compiled with `-Wsign-compare' */
    622                     {
    623                          if (0 == StrCompare((*pcl)->jupes[j], nick))
    624                          {
    625                               snprintf(cmdbuf, sizeof(cmdbuf), "MONITOR - %s\r\n", nick);
    626                               send((*pcl)->sock, cmdbuf, strlen(cmdbuf), 0);
    627                               (*pcl)->jupes[j] = NULL;
    628                               print_prefix((*pcl), 0, 0);
    629                               print(1, 0, out, "%s removed from my MONITOR list", nick);
    630                               break;
    631                          }
    632                     }
    633                }
    634                if ((*pcl) && (*pcl)->online && (*pcl)->grabbing && (0 == StrCompare((*pcl)->nick, nick)))
    635                {
    636                     (*pcl)->grabbing = 0;
    637                     print_prefix((*pcl), 0, 0);
    638                     print(1, 0, out, "I ungrabbed `%s'", nick);
    639                }
    640           }
    641 
    642           free(conf.jupe[idx]);
    643           conf.jupe[idx] = NULL;
    644           return;
    645      }
    646 
    647      print(1, 0, out, "no such entry");
    648 }
    649 
    650 void parse_addshit(char *buffer, int out)
    651 {
    652      char parm[MEDBUF+1];
    653      int i;
    654 
    655      if (sscanf(buffer, "%*s %"MEDBUF_TXT"[^\n]", parm) != 1 || !is_pattern(parm))
    656      {
    657           print(1, 0, out, "Usage: %s <pattern> :[<reason>]", ADDSHIT);
    658           return;
    659      }
    660      if ((i = add_table(parm, conf.shit, MAX_SHITS)) == -1)
    661      {
    662           print(1, 0, out, "shitlist full");
    663           return;
    664      }
    665      StrFirstToken(parm);
    666      print(1, 0, out, "[%d] %s shitlisted", i, parm);
    667 }
    668 
    669 void parse_rmshit(char *buffer, int out)
    670 {
    671      char parm[MINIBUF];
    672      int i;
    673 
    674      if (StrParam(parm, sizeof(parm), buffer, 1))
    675      {
    676           print(1, 0, out, "Usage: %s <ID>", RMSHIT);
    677           return;
    678      }
    679      if ((i = atoi(parm)) < 0)
    680      {
    681           print(1, 0, out, "shitlist cleared");
    682           clear_table(conf.shit, MAX_SHITS);
    683           return;
    684      }
    685      if (i < MAX_SHITS && conf.shit[i])
    686      {
    687           StrFirstToken(conf.shit[i]);
    688           print(1, 0, out, "%s removed from the shitlist", conf.shit[i]);
    689           free(conf.shit[i]);
    690           conf.shit[i] = NULL;
    691           return;
    692      }
    693      print(1, 0, out, "no such entry");
    694 }
    695 
    696 void parse_addscan(char *buffer, int out)
    697 {
    698      char parm[MINIBUF];
    699      char save[MINIBUF];
    700      char server[MINIBUF];
    701      int type;
    702      int mode;
    703      int proxy_port;
    704      int server_port;
    705      clone_t *clone;
    706 
    707      if (StrParam(save, sizeof(save), buffer, 5))
    708      {
    709           print(1, 0, out, "Usage: %s <type> <scan port> <server> <port> <filename> [<mode>]", ADDSCAN);
    710           return;
    711      }
    712      if (!(clone = getscan()))
    713      {
    714           print(1, 0, out, "scan: no clone available");
    715           return;
    716      }
    717      StrParam(server, sizeof(server), buffer, 3);
    718      if (sscanf(buffer, "%*s %d", &type) != 1 || type < 0 || type > 6)
    719      {
    720           print(1, 0, out, "scan: invalid type");
    721           return;
    722      }
    723      if ((sscanf(buffer, "%*s %*s %d", &proxy_port) != 1) || sscanf(buffer, "%*s %*s %*s %*s %d", &server_port) != 1)
    724      {
    725           print(1, 0, out, "scan: invalid port");
    726           return;
    727      }
    728      if (!StrParam(parm, sizeof(parm), buffer, 6))
    729      {
    730           mode = atoi(parm);
    731      }
    732      else
    733      {
    734           mode = M_QUIT;
    735      }
    736      if (mode < 0 || mode > 2)
    737      {
    738           print(1, 0, out, "scan: invalid mode");
    739           return;
    740      }
    741      clone->scan = (scan_t *)xmalloc(sizeof(scan_t));
    742      clone->scan->type = type;
    743      clone->scan->proxy_port = proxy_port;
    744      clone->scan->server = StrDuplicate(server);
    745      clone->scan->server_port = server_port;
    746      clone->scan->save = StrDuplicate(save);
    747      clone->scan->mode = mode;
    748      print(1, 0, out, "[%d] scan activated", clone->id);
    749 }
    750 
    751 void parse_rmscan(char *buffer, int out)
    752 {
    753      char parm[MEDBUF];
    754      int i;
    755 
    756      if (StrParam(parm, sizeof(parm), buffer, 1))
    757      {
    758           print(1, 0, out, "Usage: %s <ID>", RMSCAN);
    759           return;
    760      }
    761      if (sscanf(parm, "%d", &i) == 1)
    762      {
    763           if (i < MAX_CLONES && cl[i] && cl[i]->scan)
    764           {
    765                print(1, 0, out, "[%d] scan canceled", i);
    766                free(cl[i]->scan->server);
    767                free(cl[i]->scan->save);
    768                free(cl[i]->scan);
    769                cl[i]->scan = NULL;
    770                return;
    771           }
    772      }
    773      print(1, 0, out, "no such entry");
    774 }
    775 
    776 void parse_echo(char *buffer, int out)
    777 {
    778      char parm[MEDBUF];
    779 
    780      free(target);
    781      if (!StrParam(parm, sizeof(parm), buffer, 1))
    782      {
    783           target = StrDuplicate(parm);
    784           print(1, 0, out, "echo enabled, echoing `%s'", target);
    785      }
    786      else
    787      {
    788           target = NULL;
    789           print(1, 0, out, "echo disabled");
    790      }
    791 }
    792 
    793 void parse_chankey(char *buffer, int out)
    794 {
    795      char parm[MEDBUF];
    796      int i;
    797 
    798      if (StrParam(parm, sizeof(parm), buffer, 1))
    799      {
    800           print(1, 0, out, "Usage: %s <chan> <key>", CHANKEY);
    801           return;
    802      }
    803      if ((i = getchid(parm)) == -1)
    804      {
    805           print(1, 0, out, "%s: no such chan", parm);
    806           return;
    807      }
    808      free(chankey[i]);
    809      if (!StrParam(parm, sizeof(parm), buffer, 2))
    810      {
    811           chankey[i] = StrDuplicate(parm);
    812           print(1, 0, out, "Using chankey %s on %s", chankey[i], channel[i]);
    813      }
    814      else
    815      {
    816           chankey[i] = NULL;
    817           print(1, 0, out, "Chankey disabled on %s", channel[i]);
    818      }
    819 }
    820 
    821 void parse_nicklist(char *buffer, int out)
    822 {
    823      char parm[MEDBUF];
    824      FILE *f;
    825 
    826      if (StrParam(parm, sizeof(parm), buffer, 1))
    827      {
    828           print(1, 0, out, "Usage: %s <filename>", NICKLIST);
    829           return;
    830      }
    831 
    832      if (!(f = fopen(parm, "r")))
    833      {
    834           print(1, 0, out, "Cannot open the file `%s'", parm);
    835           return;
    836      }
    837 
    838      clear_table(conf.nicks, MAX_NICKS);
    839      fill_table(conf.nicks, MAX_NICKS, f);
    840      fclose(f);
    841 
    842      print(1, 0, out, "nicklist loaded", parm);
    843 }
    844 
    845 void parse_select(char *buffer, int out)
    846 {
    847      clone_t **pcl;
    848      register int i;
    849      char parm[MINIBUF];
    850 
    851      if (StrParam(parm, sizeof(parm), buffer, 1))
    852      {
    853           print(1, 0, out, "Usage: %s <nick> :<IRC command>", SELECT);
    854           return;
    855      }
    856 
    857      strsep(&buffer, ":");
    858      if (!buffer)
    859      {
    860           return;
    861      }
    862 
    863      if (parm[0] == '*')
    864      {
    865           send2clones(buffer);
    866           return;
    867      }
    868 
    869      for (i = 0, pcl = cl; i < MAX_CLONES; ++i, ++pcl)
    870      {
    871           if ((*pcl) && (*pcl)->online && !StrCompare((*pcl)->nick, parm))
    872           {
    873                send((*pcl)->sock, buffer, strlen(buffer), 0);
    874                return;
    875           }
    876      }
    877      print(1, 0, out, "no such nickname");
    878 }
    879 
    880 void parse_load(char *buffer, int out)
    881 {
    882      int type;
    883      int proxy_port;
    884      int server_port;
    885      char parm[MINIBUF];
    886      char server[MINIBUF];
    887      char proxy[MINIBUF];
    888 
    889      if (StrParam(parm, sizeof(parm), buffer, 5))
    890      {
    891           print(1, 0, out, "Usage: %s <type> <proxy> <port> <server> <port>", LOAD);
    892           return;
    893      }
    894      if (sscanf(buffer, "%*s %d", &type) != 1 || type < 0 || type > 5)
    895      {
    896           print(1, 0, out, "load: invalid type");
    897           return;
    898      }
    899      if (sscanf(buffer, "%*s %*s %*s %d", &proxy_port) != 1 || sscanf(buffer, "%*s %*s %*s %*s %*s %d", &server_port) != 1)
    900      {
    901           print(1, 0, out, "load: invalid port");
    902           return;
    903      }
    904      StrParam(server, sizeof(server), buffer, 4);
    905      StrParam(proxy, sizeof(proxy), buffer, 2);
    906      load_host(type, proxy, proxy_port, server, server_port, NULL, NULL, NULL, M_NORMAL);
    907 }
    908 
    909 void parse_quit(char *buffer, int out)
    910 {
    911      if (!StrCmpPrefix(buffer, "quit :"))
    912      {
    913           send2clones(buffer);
    914           print(1, 0, out, "Exiting...");
    915           sleep(1);
    916      }
    917 
    918      main_exit();
    919 }
    920 /*
    921 void parse_maxconns(char *buffer, int out)
    922 {
    923      char parm[MINIBUF];
    924      int i;
    925 
    926      if (StrParam(parm, sizeof(parm), buffer, 1))
    927      {   
    928           print(1, 0, out, "Usage: %s <max_conns>", MAXCONNS);
    929           return;
    930      }
    931      else if(i = atoi(parm) > 0)
    932      {
    933           print(1, 0, out, "MAX_CONNS set to %d", i);
    934           conf.max_conns = i;
    935           return;
    936      }
    937 }
    938 */
    939 /* }}} */
    940 /* {{{ interpret() */
    941 void interpret(char *buffer, int out)
    942 {
    943      static cmd_t cmd[] =
    944           { { "join",        parse_join              },
    945             { "part",        parse_part              },
    946             { SELECT,        parse_select            },
    947             { LOAD,          parse_load              },
    948             { MUTE,          parse_mute              },
    949             { "mode",        parse_mode              },
    950             { "kick",        parse_mode              },
    951             { "topic",       parse_mode              },
    952             { "privmsg",     parse_privmsg           },
    953             { "notice",      parse_privmsg           },
    954             { KICKBAN,       parse_kb                },
    955             { MASSKICKBAN,   parse_mkb               },
    956             { MASSKICK,      parse_mkb               },
    957             { MASSOP,        parse_mo                },
    958             { MASSDEOP,      parse_mo                },
    959             { MASSUNBAN,     parse_mo                },
    960             { TAKEOVER,      parse_to                },
    961             { ADDSCAN,       parse_addscan           },
    962             { RMSCAN,        parse_rmscan            },
    963             { ADDPROT,       parse_addprot           },
    964             { RMPROT,        parse_rmprot            },
    965             { ADDOP,         parse_addop             },
    966             { RMOP,          parse_rmop              },
    967             { ADDJUPE,       parse_addjupe           },
    968             { RMJUPE,        parse_rmjupe            },
    969             { ADDSHIT,       parse_addshit           },
    970             { RMSHIT,        parse_rmshit            },
    971             { ECHO,          parse_echo              },
    972             { CHANKEY,       parse_chankey           },
    973             { NICKLIST,      parse_nicklist          },
    974 /*            { MAXCONNS,      parse_maxconns          }, */
    975             { "quit",        parse_quit              },
    976             { NULL,          NULL                    }
    977           };
    978      cmd_t *pcmd;
    979 
    980      for (pcmd = cmd; pcmd->parm; ++pcmd)
    981      {
    982           if (!StrCmpPrefix(buffer, pcmd->parm))
    983           {
    984                pcmd->function(buffer, out);
    985                return;
    986           }
    987      }
    988 
    989      if (out > 0 && (!StrCmpPrefix(buffer, "help") || buffer[0] == '?'))
    990      {
    991           usage(out);
    992      }
    993      else if (conf.nicks[0] && !StrCmpPrefix(buffer, RANDOM))
    994      {
    995           conf.use_wordlist = !conf.use_wordlist;
    996           print(1, 0, out, "using %s", conf.use_wordlist ? "the nicks" : "random nicks");
    997      }
    998      else if (!StrCmpPrefix(buffer, AGGRESS))
    999      {
   1000           conf.aggressive = !conf.aggressive;
   1001           print(1, 0, out, "aggressive mode set %s", conf.aggressive ? "ON" : "OFF");
   1002      }
   1003      else if (!StrCmpPrefix(buffer, PEACE))
   1004      {
   1005           conf.peace = !conf.peace;
   1006           print(1, 0, out, "peace mode set %s", conf.peace ? "ON" : "OFF");
   1007      }
   1008      else if (out > 0 && !StrCmpPrefix(buffer, STATUS))
   1009      {
   1010           status(out);
   1011      }
   1012      else if (!StrCmpPrefix(buffer, NICKS))
   1013      {
   1014           send2clones(buffer);
   1015      }
   1016      else if (buffer[0] != '\n')
   1017      {
   1018           print(1, 0, out, "muhstik: %s: command not found", strsep(&buffer, DELIM));
   1019      }
   1020 }
   1021 /* }}} */
   1022 /* }}} */