Beispiel #1
0
static void get_users_from_chan(struct socket_info *sinfo, char *params)
{
	char *channel;
	char cmode;
	struct clientinfo user;

	channel = strtok(params, " ");
	channel = strtok(NULL, " ");
	channel = strtok(NULL, " ");

	user.nick = strtok(NULL, " ");
	user.ident = NULL;
	user.address = NULL;
	user.server = GetServerBySocket(sinfo);

	if (user.nick[0] == ':')
		user.nick++;

	do {
		/* if it's not a char allowed at the beginning 
		   of the nick it's probably a mode char 
		 */

		if (!isnickstartchar(user.nick[0])) {
			cmode = user.nick[0];
			user.nick++;

		}

		AddUserToChannel(&user, channel);
		botevent(EV_HERE,sinfo,user.nick,channel,NULL);
		/* next User */
		user.nick = strtok(NULL, " ");

	} while (user.nick != NULL);
}
Beispiel #2
0
void loadanopedb()
{
    char accname[50];
    char md5_pass[40];
    char email[EMAILLEN+1];
    int acclvl;
    char channelname[CHANLEN+1];
    char owner[50];
    char entrymsg[200];
    User *uptr,*owner_ptr;
    Chan *chan_ptr;
    MYSQL_RES *result;
    MYSQL_ROW row;
    char *pass;

    if (!reconnect_to_db()) {
        fprintf(stderr,"Cannot connect to db\n");
        operlog("Cannot connect to db");
        return;
    }

    mysql_query(&mysql2,"SELECT display,pass,email FROM anope_ns_core");
    if ((result = mysql_use_result(&mysql2)) == NULL) {
        printf("CRITICAL: Cannot load anope user db: mysql_use_result returned NULL !\n");
        return;
    }
    while ((row = mysql_fetch_row(result))) {
        bzero(accname,50);
        bzero(md5_pass,40);
        bzero(email,EMAILLEN);
        strncpy(accname,row[0],50);

        if (row[1][0] == '\0') {
            printf("ANOPE ERROR: User %s does not have any pass !\n",accname);
            continue;
        }
        if (me.anopemd5 == 0) {
            pass = md5_hash(row[1]);
            strncpy(md5_pass,pass,40);
            free(pass);
        } else
            strncpy(md5_pass,row[1],40);

        strncpy(email,row[2],EMAILLEN);

        if (find_user(accname))
            continue;

        uptr = AddUser(accname,1);
        uptr->lastseen = time(NULL);
        uptr->options = 0;
        uptr->timeout = TIMEOUT_DFLT;
        bzero(uptr->vhost,HOSTLEN);
        bzero(uptr->md5_pass,34);
        strncpy(uptr->md5_pass,md5_pass,32);
        strncpy(uptr->email,email,EMAILLEN);
    }

    mysql_query(&mysql2,"SELECT name,founder,entry_message FROM anope_cs_info");
    if ((result = mysql_use_result(&mysql2)) == NULL) {
        printf("CRITICAL: Cannot load anope chan db: mysql_use_result returned NULL !\n");
        return;
    }
    while((row = mysql_fetch_row(result))) {
        strncpy(channelname,row[0],CHANLEN);
        strncpy(owner,row[1],50);
        strncpy(entrymsg,row[2],200);

        if (find_channel(channelname))
            continue;

        owner_ptr = find_user(owner);
        if (!owner_ptr) {
            fprintf(stderr,"ANOPE ERROR: Cannot load channel %s with owner %s : find_user returned NULL !!\n",channelname,owner);
            continue;
        }

        chan_ptr = CreateChannel(channelname,owner,time(NULL));

        chan_ptr->autolimit = 0;
        strncpy(chan_ptr->entrymsg,entrymsg,sizeof(chan_ptr->entrymsg)-1);
        bzero(chan_ptr->mlock,50);
    }

    mysql_query(&mysql2,"SELECT channel,display,level FROM anope_cs_access");
    if ((result = mysql_use_result(&mysql2)) == NULL) {
        printf("CRITICAL: Cannot load anope channel access db: mysql_use_result returned NULL !\n");
        return;
    }
    while((row = mysql_fetch_row(result))) {
        strncpy(channelname,row[0],CHANLEN);
        strncpy(accname,row[1],50);
        acclvl = strtol(row[2],NULL,10);
        chan_ptr = find_channel(channelname);
        if (!chan_ptr) {
            fprintf(stderr,"ANOPE ERROR: Cannot load access for user %s for channel %s : find_channel returned NULL !!\n",accname,channelname);
            continue;
        }

        uptr = find_user(accname);
        if (!uptr) {
            fprintf(stderr,"ANOPE ERROR: Cannot load access for user %s for channel %s : find_user returned NULL !!\n",accname,channelname);
            continue;
        }

        if (find_cflag(accname,channelname))
            continue;

        if (acclvl < CHLEV_OWNER)
            AddUserToChannel(uptr,chan_ptr,acclvl,0);
    }

    mysql_close(&mysql);
}
Beispiel #3
0
void loadchandb()
{
    char channelname[CHANLEN+1];
    char owner[NICKLEN+1];
    User *owner_ptr;
    User *user_ptr;
    Chan *chan_ptr;
    char accname[NICKLEN+MASKLEN+1];
    int acclvl, automode, uflags;
    int options;
    char entrymsg[250];
    
    MYSQL_RES *result;
    MYSQL_ROW row;
    Cflag *cflag;

    if (!reconnect_to_db()) {
        fprintf(stderr,"Cannot connect to db\n");
        operlog("Cannot connect to db");
        return;
    }

    mysql_query(&mysql,"SELECT * FROM child_chans");
    if ((result = mysql_use_result(&mysql)) == NULL) {
        printf("CRITICAL: Cannot load chan table: mysql_use_result returned NULL\n");
        return;
    }
    while ((row = mysql_fetch_row(result))) {
        strncpy(channelname,row[0],CHANLEN);
        strncpy(owner,row[1],NICKLEN);
        strncpy(entrymsg,row[2],200);
        options = strtol(row[3],NULL,10);
        owner_ptr = find_user(owner);

        if (!owner_ptr) {
            fprintf(stderr,"ERROR: Cannot load channel %s with owner %s : find_user returned NULL !!\n",channelname,owner);
            continue;
        }

        if (vv) printf("Adding channel %s with owner %s (%p) and options %d\n",channelname,owner,owner_ptr,options);

        if (find_channel(channelname))
            continue;
        chan_ptr = CreateChannel(channelname,owner,atoi(row[6]));
        chan_ptr->regtime = strtol(row[7], NULL, 10);

        if (vv) printf("Channel %s added (%p)\n",channelname,chan_ptr);

        chan_ptr->options = options;
        chan_ptr->autolimit = atoi(row[5]);
        strncpy(chan_ptr->entrymsg,entrymsg,sizeof(chan_ptr->entrymsg)-1);
        chan_ptr->entrymsg[250] = '\0';
        strncpy(chan_ptr->mlock,row[4],50);
        chan_ptr->mlock[50] = '\0';
        strncpy(chan_ptr->topic, row[8], TOPICLEN);
    }

    mysql_query(&mysql,"SELECT * from child_chan_access");
    if ((result = mysql_use_result(&mysql)) == NULL) {
        printf("CRITICAL: Cannot load chan access table: mysql_use_result returned NULL!\n");
        return;
    }
    while ((row = mysql_fetch_row(result))) {
        strncpy(channelname,row[0],CHANLEN);
        strncpy(accname,row[1],NICKLEN+MASKLEN);
        acclvl = strtol(row[2],NULL,10);
        automode = strtol(row[3],NULL,10);
        chan_ptr = find_channel(channelname);
        if (!chan_ptr) {
            fprintf(stderr,"ERROR: Cannot load access for user %s for channel %s : find_channel returned NULL !!\n",accname,channelname);
            continue;
        }

        user_ptr = find_user(accname);
        if (!user_ptr && !IsMask(accname)) {
            fprintf(stderr,"ERROR: Cannot load access for user %s for channel %s : find_user returned NULL !!\n",accname,channelname);
            continue;
        }

        if (find_cflag(accname,channelname))
            continue;
        if (vv) printf("Adding user %s (%p) for channel %s with level %d\n",accname,user_ptr,channelname,acclvl);
        if (acclvl < CHLEV_OWNER && !IsMask(accname)) {
            uflags = strtol(row[5], NULL, 10);
            cflag = AddUserToChannel(user_ptr,chan_ptr,acclvl,uflags);
            cflag->automode = automode;
            cflag->suspended = strtol(row[4], NULL, 10);
        }
        if (IsMask(accname))
            AddMaskToChannel(accname,chan_ptr,acclvl);
        if (vv) printf("User %s added for channel %s\n",accname,channelname);
    }

    mysql_close(&mysql);
}
Beispiel #4
0
void *ClientHandler(void *arg)
{
  struct Client *client = ((struct Client *)arg);
  struct ParsedMsg msg;
  struct ThreadChanList chan_list = {
    .size = 0,
    .head = NULL
  };
  struct NamesList name_list = {
    .cnt = 0,
    .names = NULL
  };
  struct ThreadChanNode *ptr;
  union RegistrationFlags registered;
  char raw_msg[IRC_MSG_MAX_LENGTH];
  char send_msg[IRC_MSG_MAX_LENGTH];
  char nick[IRC_NICK_BUF_SIZE];
  ssize_t bytes = 0;
  int ret, index, connect = 1;

  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

  registered.clear = 0;

  memset(&raw_msg, 0, IRC_MSG_MAX_LENGTH);
  memset(&send_msg, 0, IRC_MSG_MAX_LENGTH);
  memset(&nick, 0, IRC_NICK_BUF_SIZE);

  while (registered.flags.user == 0 || registered.flags.nick == 0) {
    if ((bytes = IRCMsgRead(client->sockfd, raw_msg)) < 0) {
      printf("disconnected\n");
      registered.flags.fail = 1;
      break;
    }
    printf("raw: %s len %d\n", raw_msg, (int)strlen(raw_msg));
    FormParsedMsg(raw_msg, &msg);
    if (msg.cmd == IRCCMD_QUIT) {
      registered.flags.fail = 1;
      break;
    }
    if (msg.cmd == IRCCMD_USER) {
      registered.flags.user = 1;
    } else if (msg.cmd == IRCCMD_NICK) {
      if (registered.flags.nick == 0) {
        if (msg.cnt == 0) {
          ErrorHandler(client->sockfd, 
                      "nickname parameter expected for a command and isn’t found",
                       ERR_ERRONEUSNICKNAME);
          FreeParsedMsg(&msg);
          continue;
        }
        if (msg.params[0][0] == '#') {
          ErrorHandler(client->sockfd, "USER NICK: #nick invalid", ERR_ERRONEUSNICKNAME);
          FreeParsedMsg(&msg);
          continue;
        }
        ret = AddUser(&all_users, msg.params[0], client);
        if (ret == IRC_USERERR_EXIST) {
          ErrorHandler(client->sockfd, "NICK already exist", ERR_NICKNAMEINUSE);
          FreeParsedMsg(&msg);
          continue;
        } else if (ret == IRC_USERERR_NICK) {
          ErrorHandler(client->sockfd, "INCORRECT NICK", ERR_ERRONEUSNICKNAME);
          FreeParsedMsg(&msg);
          continue;
        } else if (ret == IRC_USERERR_CANTADD) {
          ErrorHandler(client->sockfd, "USER CANT ADD", IRC_USERERR_CANTADD);
          FreeParsedMsg(&msg);
          registered.flags.fail = 1;
        } else {
          ret = strlen(msg.params[0]);
          strncpy(nick, msg.params[0], ret);
          nick[ret] = '\0';
          registered.flags.nick = 1;
        }
      }
    }
    FreeParsedMsg(&msg);
  }

  if (!registered.flags.fail) {
    printf("successfully registered user: %s\n", nick);
    registered.flags.connect = 1;
    SendConnectMsg(&all_users, "anonimus", nick);
    while (registered.flags.connect) {
      if ((bytes = IRCMsgRead(client->sockfd, raw_msg)) < 0) {
        printf("disconnected...\n");
        break;
      }
      printf("raw: %s len %d\n", raw_msg, (int)strlen(raw_msg));
      FormParsedMsg(raw_msg, &msg);

      switch (msg.cmd) {
        case IRCCMD_QUIT:
          registered.flags.connect = 0;
          if (chan_list.size > 0) {
            if (FormSendMsg(send_msg, raw_msg, nick) == 0) {
              for (ptr = chan_list.head; ptr != NULL; ptr = ptr->next) 
                SendMsgToChannel(&all_chan, &all_users, ptr->chan, nick,
                              send_msg);
            }
          }
          break;

        case IRCCMD_JOIN:
          if (msg.cnt == 0) {
            ErrorHandler(client->sockfd, "JOIN :Not enough parameters", ERR_NEEDMOREPARAMS);
            break;
          }
          if (AddUserToChannel(&all_chan, &all_users, msg.params[0],
                              nick) == 0) {
            printf("add to channel %s\n", msg.params[0]);
            chan_list.head = ThrListAddFront(&chan_list, msg.params[0]);
            if (FormSendMsg(send_msg, raw_msg, nick) == 0) {
              SendMsgToUser(&all_users, nick, send_msg);
              SendMsgToChannel(&all_chan, &all_users, msg.params[0], nick,
                              send_msg);
              pthread_mutex_lock(&client->send_lock);
              SendChannelList(client->sockfd, &all_chan, &all_users, msg.params[0],
                              "anonimous", nick);
              pthread_mutex_unlock(&client->send_lock);
            }
            printf("TO SEND: %s\n", send_msg);
          } else {
            ErrorHandler(client->sockfd, "Cannot join channel", ERR_CHANNELISFULL);
          }
          break;

        case IRCCMD_PRIVMSG:
          if (msg.cnt == 2) {
            if (FormSendMsg(send_msg, raw_msg, nick) == 0) {
              printf("send %s \nto %s len %d\n", send_msg, msg.params[0],
                                                (int)strlen(send_msg));
              if (msg.params[0][0] == '#') {
                if (SendMsgToChannel(&all_chan, &all_users, msg.params[0], 
                                    nick, send_msg) < 0)
                  perror("SendMsgToChannel failed");
              } else {
                SendMsgToUser(&all_users, msg.params[0], send_msg);
              }
            }
          } else {
            ErrorHandler(client->sockfd, "PRIVMSG: Not enough parameters", 
                        ERR_NEEDMOREPARAMS);
          }
          break;

        case IRCCMD_PART:
          if (msg.cnt != 0) {
            RemoveUserFromChannel(&all_chan, &all_users, msg.params[0], nick);
            chan_list.head = DeleteThrNode(&chan_list, msg.params[0]);
            if (FormSendMsg(send_msg, raw_msg, nick) == 0) {
              printf("send %s \nto %s\n", send_msg, msg.params[0]);
              SendMsgToUser(&all_users, nick, send_msg);
              SendMsgToChannel(&all_chan, &all_users, msg.params[0], nick, send_msg);
            }
          } else {
            ErrorHandler(client->sockfd, "PART: Not enough parameters", 
                        ERR_NEEDMOREPARAMS);
          }
          break;
         
        case IRCCMD_NICK:
          if (msg.cnt == 0) {
            ErrorHandler(client->sockfd, 
                      "nickname parameter expected for a command and isn’t found",
                       ERR_ERRONEUSNICKNAME);
            break;
          }
          if (msg.params[0][0] == '#') {
            ErrorHandler(client->sockfd, "USER NICK: #nick invalid", ERR_ERRONEUSNICKNAME);
            break; 
          }
          printf("change nick: %s -> %s\n", nick, msg.params[0]);
          if ((ret = RenameUser(&all_users, nick, msg.params[0])) == 0) { 
            ret = strlen(msg.params[0]);
            strncpy(nick, msg.params[0], ret);
            nick[ret] = '\0';
          } else {
            if (ret == IRC_USERERR_NOTFOUND) {
              ErrorHandler(client->sockfd, "User not found", ERR_NICKNAMEINUSE);
            } else if (ret == IRC_USERERR_EXIST) {
              ErrorHandler(client->sockfd, "User exist", ERR_NICKNAMEINUSE);
            }
            perror("RenameUser");
          }
          break;
          
        case IRCCMD_PING:
          if (msg.cnt == 1) {
            FormPongMsg(&all_users, raw_msg, nick);
          } else {
            ErrorHandler(client->sockfd, "PING: Not enough parameters", 
                        ERR_NEEDMOREPARAMS);
          }
          break;
        case IRCCMD_LIST:
          pthread_mutex_lock(&client->send_lock);
          SendAllChannelsList(client->sockfd, &all_chan, &all_users,
                              "anonimous", nick);
          pthread_mutex_unlock(&client->send_lock);
          break;
      }
      FreeParsedMsg(&msg);
    }
  }
  if (chan_list.size > 0) {
    for (ptr = chan_list.head; ptr != NULL; ptr = ptr->next)
      RemoveUserFromChannel(&all_chan, &all_users, ptr->chan, nick);
    FreeThreadList(&chan_list);
  }

  close(client->sockfd);
  pthread_mutex_destroy(&client->send_lock);
  DelUser(&all_users, (const char *)&nick);
  free(client);
  printf("close... %s\n", nick);
  pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
  struct sockaddr_in ser_addr, cl_addr;
  struct Client *client;
  int listen_sock, connect;
  socklen_t len = (socklen_t)sizeof(struct sockaddr_in);
  pthread_attr_t attr;
  const int kOpt = 1;

  if (argc != 3) {
    printf("format: IP_ADDR PORT\n");
    exit(EXIT_FAILURE);
  }

  listen_sock = socket(AF_INET, SOCK_STREAM, 0);
  if (listen_sock < 0) {
    perror("socket");
    exit(EXIT_FAILURE);
  }

  if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &kOpt,
                sizeof(int)) == -1 ) {
    perror("setsockopt");
  }

  memset(&ser_addr, 0, sizeof(struct sockaddr_in));

  ser_addr.sin_family = AF_INET;
  ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
  ser_addr.sin_port = htons(atoi(argv[2]));

  if (bind(listen_sock, (struct sockaddr *)&ser_addr, len) < 0) {
    perror("bind");
    exit(EXIT_FAILURE);
  }

  if (listen(listen_sock, IRC_USERS_MAX) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
  }

  UsersInit(&all_users);
  ChannelsInit(&all_chan);
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  while (1) {
    if ((connect = accept(listen_sock, (struct sockaddr *)&cl_addr,
                          &len)) > 0) {
      client = (struct Client *)malloc(sizeof(struct Client));
      if (client == NULL) {
        perror("malloc");
        break;
      }
      client->sockfd = connect;
      pthread_mutex_init(&client->send_lock, NULL);
      if (pthread_create(&(client->pid), &attr, ClientHandler,
                        (void *)client) > 0) {
        perror("pthread_create");
      }

    } else {
      perror("accept");
      break;
    }
  }
  pthread_attr_destroy(&attr);
  pthread_mutex_destroy(&all_users.lock);
  pthread_mutex_destroy(&all_chan.lock);
  close(listen_sock);
  return 0;
}