Merge branch 'master' into IOMultiplexer
authorpk910 <philipp@zoelle1.de>
Tue, 21 Aug 2012 23:34:06 +0000 (01:34 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 21 Aug 2012 23:34:06 +0000 (01:34 +0200)
1  2 
src/ClientSocket.h
src/IRCParser.c
src/modules/DummyServ.mod/bot_DummyServ.c
src/modules/NeonBackup.mod/bot_NeonBackup.c
src/modules/NeonFun.mod/bot_NeonFun.c
src/modules/NeonHelp.mod/bot_NeonHelp.c
src/modules/NeonServ.mod/bot_NeonServ.c
src/modules/NeonSpam.mod/bot_NeonSpam.c

diff --combined src/ClientSocket.h
index 38768b19715a154c9e76091c9b2836bb55c4b03a,ddbb60f815600d040bde2c65743f6c408fdbdcc2..f4fc57ab49b30b8951f59da950277819017a83ab
  
  #include "main.h"
  
 -#define SOCKET_FLAG_DEAD           0x01
  #define SOCKET_FLAG_CONNECTED      0x02
  #define SOCKET_FLAG_READY          0x04
  #define SOCKET_FLAG_PREFERRED      0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */
  #define SOCKET_FLAG_USE_QUEUE      0x10
  #define SOCKET_FLAG_RECONNECT      0x20
  #define SOCKET_FLAG_SSL            0x40
 -#define SOCKET_FLAG_HAVE_SSL       0x80
 -#define SOCKET_FLAG_QUITTED        0x100
 +
  #define SOCKET_FLAG_FAST_JUMP      0x200
  #define SOCKET_FLAG_SILENT         0x400
  #define SOCKET_FLAG_CHANGENICK     0x800
  #define SOCKET_FLAG_REQUEST_INVITE 0x1000
  #define SOCKET_FLAG_REQUEST_OP     0x2000
+ #define SOCKET_FLAG_SECRET_BOT     0x4000
  
  #define SOCKET_HAVE_BOTCLASSVALUE1 0x10000000
  #define SOCKET_HAVE_BOTCLASSVALUE2 0x20000000
  
  struct UserNode;
  struct trigger_cache;
 -struct SSLConnection;
 +struct IODescriptor;
  
  struct ClientSocket {
 -    int sock;
 +    struct IODescriptor *iofd;
      unsigned int flags;
 -    char buffer[BUF_SIZ*2]; //we need to store up to 2 full commands at once
 -    unsigned int bufferpos;
      char *host;
      int port;
      char *bind;
@@@ -57,6 -62,7 +58,6 @@@
      unsigned long traffic_in;
      unsigned long traffic_out;
      time_t connection_time;
 -    struct SSLConnection *sslconn;
      
      struct BotQueue *queue;
      
  
  #ifndef DND_FUNCTIONS
  /* MODULAR ACCESSIBLE */ struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname);
 -/* MODULAR ACCESSIBLE */ int connect_socket(struct ClientSocket *client);
 +/* MODULAR ACCESSIBLE */ void connect_socket(struct ClientSocket *client);
  /* MODULAR ACCESSIBLE */ int close_socket(struct ClientSocket *client);
 -/* MODULAR ACCESSIBLE */ int disconnect_socket(struct ClientSocket *client);
 -int write_socket_force(struct ClientSocket *client, char* msg, int len);
 +/* MODULAR ACCESSIBLE */ int destroy_socket(struct ClientSocket *client);
  /* MODULAR ACCESSIBLE */ int write_socket(struct ClientSocket *client, char* msg, int len);
  #ifdef HAVE_THREADS
  int clientsocket_parseorder_top(unsigned int tid);
  #endif
 -int socket_loop(int timeout_seconds);
  /* MODULAR ACCESSIBLE */ void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3);
  /* MODULAR ACCESSIBLE */ struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot);
  void init_sockets();
diff --combined src/IRCParser.c
index 156afb3c04245e7524ed5801f8bef7c05d703679,60b48d9fe342649c5436b8550feeeb42c5c4783e..f9e79e0c127c720b34a67f96db5217334d0a2738
@@@ -35,10 -35,27 +35,10 @@@ int statistics_privmsg = 0
  int statistics_network_users = 0;
  int statistics_network_channels = 0;
  
 -static void parse_line(struct ClientSocket *client, char *line);
  static void register_irc_function(char *command, irc_cmd_t *func);
  static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc);
  
 -int parse_lines(struct ClientSocket *client, char *lines, int len) {
 -    int i, used = 0;
 -    char *line = lines;
 -    for(i = 0; i < len; i++) {
 -        if(lines[i] == '\r') //just zero it out :D
 -            lines[i] = 0;
 -        if(lines[i] == '\n') {
 -            lines[i] = 0;
 -            parse_line(client, line);
 -            line = lines+(i+1);
 -            used = i+1;
 -        }
 -    }
 -    return used;
 -}
 -
 -static void parse_line(struct ClientSocket *client, char *line) {
 +void parse_line(struct ClientSocket *client, char *line) {
      int argc = 0;
      char *argv[MAXNUMPARAMS];
      #ifdef HAVE_THREADS
@@@ -99,8 -116,34 +99,34 @@@ static void parse_raw(struct ClientSock
      }
  }
  
+ static void increase_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+     struct ChanUser *chanuser;
+     
+     for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+         if(chanuser == ignore)
+             continue;
+         chanuser->visCount++;
+     }
+ }
+ static void decrease_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+     struct ChanUser *chanuser, *next_chanuser;
+     
+     for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) {
+         next_chanuser = getChannelUsers(chan, chanuser);
+         if(chanuser == ignore)
+             continue;
+         chanuser->visCount--;
+         if(chanuser->visCount <= 0)
+             delChanUser(chanuser, 1);
+     }
+ }
  static USERLIST_CALLBACK(got_channel_userlist) {
      struct ChanUser *chanuser = data;
+     
+     increase_viscount_butone(chanuser->chan, chanuser);
+     
      event_join(chanuser);
  }
  
@@@ -144,12 -187,28 +170,28 @@@ static IRC_CMD(raw_join) 
          
          event_registered(user, from);
          user->flags &= ~USERFLAG_WAS_REGISTERING;
+     } else if(!(chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+         if(!isBot(user)) {
+             DESYNCHRONIZE(cache_sync);
+             return 1; //ignore join
+         }
+         
+         chanuser = addChanUser(chan, user);
+         chanuser->visCount = 1;
+         
+         if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+             chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+         
+         get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser);
      } else if(!isUserOnChan(user, chan)) {
          //join user to an existing channel
          chanuser = addChanUser(chan, user);
          chanuser->visCount = 1;
-         if(isBot(user) && isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
-             chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+         if(isBot(user)) {
+             if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+                 chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+             increase_viscount_butone(chan, chanuser);
+         }
          
          event_join(chanuser);
          
          //user is already in the channel
          chanuser = getChanUser(user, chan);
          chanuser->visCount++;
+         
+         if(isBot(user) && !(chanuser->flags & CHANUSERFLAG_INVISIBLE))
+             increase_viscount_butone(chan, chanuser);
+         
          //if multiple bots see the user, it can't be invisible
          chanuser->flags &= ~CHANUSERFLAG_INVISIBLE;
      }
@@@ -222,6 -285,8 +268,8 @@@ static IRC_CMD(raw_part) 
          DESYNCHRONIZE(cache_sync);
          return 0;
      }
+     if(isBot(user) && user == client->user) 
+         decrease_viscount_butone(chan, chanuser);
      chanuser->visCount--;
      if(chanuser->visCount == 0) {
          delChanUser(chanuser, 0); //not free, yet!
@@@ -278,6 -343,8 +326,8 @@@ static IRC_CMD(raw_kick) 
          DESYNCHRONIZE(cache_sync);
          return 0;
      }
+     if(isBot(target) && target == client->user) 
+         decrease_viscount_butone(chan, chanuser);
      chanuser->visCount--;
      if(chanuser->visCount == 0) {
          delChanUser(chanuser, 0); //not free, yet!
@@@ -346,7 -413,7 +396,7 @@@ static IRC_CMD(raw_quit) 
      for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
          next_chanuser = getUserChannels(user, chanuser);
          chanuser->visCount--;
-         if(chanuser->visCount == 0) {
+         if(chanuser->visCount <= 0) {
              delChanUser(chanuser, 0); //not free, yet!
              event_part(chanuser, 1, argv[0]);
              if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
@@@ -382,12 -449,13 +432,13 @@@ void bot_disconnect(struct ClientSocke
          struct ChanUser *chanuser, *next_chanuser;
          for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
              next_chanuser = getUserChannels(user, chanuser);
+             decrease_viscount_butone(chanuser->chan, chanuser);
              chanuser->visCount--;
-             if(chanuser->visCount == 0) {
+             if(chanuser->visCount <= 0) {
                  delChanUser(chanuser, 0); //not free, yet!
                  event_part(chanuser, 1, "QUIT");
-                 if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
-                     check_full_rejoin(chanuser->chan);
+                 if(chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST)
+                     checkChannelVisibility(chanuser->chan);
                  freeChanUser(chanuser);
              }
          }
index 259e640bdb8d318404cf74ce15ac57e31fb325a9,3d6ac1e3d969ea95e18cdaa5b153d607b2eba88b..ade73ac809aca5a1ebbe9db5bc704260a662f992
@@@ -75,7 -75,7 +75,7 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          
          while ((row = mysql_fetch_row(res)) != NULL) {
@@@ -83,6 -83,7 +83,7 @@@
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_SILENT;
              client->botid = BOTID;
              client->clientid = atoi(row[7]);
@@@ -150,6 -151,10 +151,6 @@@ void init_DummyServ(int type) 
      set_trigger_callback(BOTID, module_id, dummyserv_trigger_callback);
  }
  
 -void loop_DummyServ() {
 -    
 -}
 -
  void free_DummyServ(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {
index b16c387eccab83927dff99e0be18866ccaba84d6,b4124269997e5c0a02f556a5ac57f64810158ffd..f9d82616d3dfe7cf613374cce9379fc747d0087e
@@@ -88,7 -88,7 +88,7 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          
          while ((row = mysql_fetch_row(res)) != NULL) {
@@@ -96,6 -96,7 +96,7 @@@
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
              client->botid = BOTID;
              client->clientid = atoi(row[7]);
@@@ -201,6 -202,10 +202,6 @@@ void init_NeonBackup(int type) 
      register_default_language_table(msgtab);
  }
  
 -void loop_NeonBackup() {
 -    
 -}
 -
  void free_NeonBackup(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {
index b0c2cae65f57d2293a66298117a5956741123082,dbef38658f651ea41d2b81b95a5c67a015b825c8..c1593221e28b44c5766042b193b35ee91d41fde7
@@@ -92,7 -92,7 +92,7 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          
          while ((row = mysql_fetch_row(res)) != NULL) {
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_SILENT;
              client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
              client->botid = BOTID;
@@@ -184,6 -185,10 +185,6 @@@ void init_NeonFun(int type) 
      set_trigger_callback(BOTID, module_id, neonfun_trigger_callback);
  }
  
 -void loop_NeonFun() {
 -    
 -}
 -
  void free_NeonFun(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {
index 7170dbd82d1c3685287e68afd70a5da93faa84da,410ad1cf0229812a8149e8372d94c4be50302fd0..e35d85b5f06c91f08023ccf706b10d231c62d86b
@@@ -122,7 -122,7 +122,7 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          
          while ((row = mysql_fetch_row(res)) != NULL) {
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_SILENT;
              client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
              client->botid = BOTID;
@@@ -567,6 -568,10 +568,6 @@@ void init_NeonHelp(int type) 
      register_default_language_table(msgtab);
  }
  
 -void loop_NeonHelp() {
 -    
 -}
 -
  void free_NeonHelp(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {
index 050e71c884e7d17e956af0dc397f0e084f2db082,477bf4f6d573ba9889291faa4b54fd726ac25814..4ba6381e6a9f0ec79b6b535a98b9420268cca46e
@@@ -359,6 -359,8 +359,8 @@@ static const struct default_language_en
      {"NS_NICKLIST_STATE", "State"},
      {"NS_NICKLIST_ACCESS", "Access"},
      {"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with %d and voiced with %d access)"},
+     {"NS_NICKLIST_ACCESS_BOT", "Bot"},
+     {"NS_NICKLIST_ACCESS_OPER", "Operator"},
      {"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */
      {"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */
      {"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, /* {ARGS: "strangeSetting"} */
@@@ -465,13 -467,14 +467,14 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          while ((row = mysql_fetch_row(res)) != NULL) {
              client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
              client->botid = BOTID;
              client->clientid = atoi(row[7]);
@@@ -522,6 -525,10 +525,6 @@@ void init_NeonServ(int type) 
      register_default_language_table(msgtab);
  }
  
 -void loop_NeonServ() {
 -    
 -}
 -
  void free_NeonServ(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {
index eace7b7071f1feb6d3c5901f650966aa674c4e87,1fd3a6fe1f33be8457b0d1a7d1439f49922edfd6..2ef3c74900d65bedee22b80a476bcf38aa2db3ca
@@@ -152,7 -152,7 +152,7 @@@ static void start_bots(int type) 
      MYSQL_ROW row;
      
      if(type == MODSTATE_STARTSTOP) {
-         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+         printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
          res = mysql_use();
          
          while ((row = mysql_fetch_row(res)) != NULL) {
              client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
              client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
              client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+             client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
              client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
              client->botid = BOTID;
              client->clientid = atoi(row[7]);
@@@ -401,6 -402,10 +402,6 @@@ void init_NeonSpam(int type) 
      register_default_language_table(msgtab);
  }
  
 -void loop_NeonSpam() {
 -    
 -}
 -
  void free_NeonSpam(int type) {
      unbind_allcmd(BOTID);
      if(type == MODSTATE_STARTSTOP) {